diff options
135 files changed, 5079 insertions, 4980 deletions
diff --git a/Master/texmf-dist/asymptote/GUI/CustMatTransform.py b/Master/texmf-dist/asymptote/GUI/CustMatTransform.py index 563907fc502..0a66807d359 100755 --- a/Master/texmf-dist/asymptote/GUI/CustMatTransform.py +++ b/Master/texmf-dist/asymptote/GUI/CustMatTransform.py @@ -1,14 +1,14 @@ #!/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 +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import numpy as numpy +import xasy2asy as xasy2asy from pyUIClass.custMatTransform import Ui_Dialog -class CustMatTransform(Qw.QDialog): +class CustMatTransform(QtWidgets.QDialog): def __init__(self): super().__init__() self.ui = Ui_Dialog() @@ -18,14 +18,14 @@ class CustMatTransform(Qw.QDialog): self.ui.btnCancel.clicked.connect(self.reject) self.ui.btnReset.clicked.connect(self.resetDialog) - self.mainTransformation = Qg.QTransform() + self.mainTransformation = QtGui.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() + validator = QtGui.QDoubleValidator() for lineInput in self.matrixLineInputs: lineInput.setValidator(validator) lineInput.textChanged.connect(self.handleUpdateText) @@ -37,7 +37,7 @@ class CustMatTransform(Qw.QDialog): def createCanvas(self): self.canvSize = self.ui.imgPreview.size() - self.previewPixmap = Qg.QPixmap(self.canvSize) + self.previewPixmap = QtGui.QPixmap(self.canvSize) tx, ty = self.canvSize.width() / 2, self.canvSize.height() / 2 self.mainTransformation.translate(tx, -ty) @@ -52,27 +52,27 @@ class CustMatTransform(Qw.QDialog): def updatePreview(self): self.previewPixmap.fill() - canvas = Qg.QPainter(self.previewPixmap) + canvas = QtGui.QPainter(self.previewPixmap) if not canvas.isActive(): return canvas.setTransform(self.mainTransformation) canvas.save() - canvas.setPen(Qc.Qt.lightGray) + canvas.setPen(QtCore.Qt.lightGray) self.drawBasicGrid(canvas) - transform = x2a.asyTransform.fromNumpyMatrix(self.getTransformationMatrix()) + transform = xasy2asy.asyTransform.fromNumpyMatrix(self.getTransformationMatrix()) canvTransform = transform.toQTransform() canvas.setTransform(canvTransform, True) - canvas.setPen(Qc.Qt.black) + canvas.setPen(QtCore.Qt.black) if canvTransform.isInvertible(): self.drawBasicGrid(canvas, False) if canvTransform.determinant() <= 0: - canvas.setPen(Qc.Qt.red) + canvas.setPen(QtCore.Qt.red) - canvas.drawRect(Qc.QRect(Qc.QPoint(0, 0), Qc.QSize(20, 20))) + canvas.drawRect(QtCore.QRect(QtCore.QPoint(0, 0), QtCore.QSize(20, 20))) self.ui.imgPreview.setPixmap(self.previewPixmap) @@ -86,17 +86,17 @@ class CustMatTransform(Qw.QDialog): 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)) + canvas.drawLine(QtCore.QLine(-9999, 0, 9999, 0)) + canvas.drawLine(QtCore.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)) + canvas.drawLine(QtCore.QLine(-9999, iterIndex * gridSize, 9999, iterIndex * gridSize)) + canvas.drawLine(QtCore.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)) + return numpy.matrix(rawMatrixNum).reshape((3, 3)) diff --git a/Master/texmf-dist/asymptote/GUI/DebugFlags.py b/Master/texmf-dist/asymptote/GUI/DebugFlags.py index 8a7eb4b282e..c8f8af897a4 100755 --- a/Master/texmf-dist/asymptote/GUI/DebugFlags.py +++ b/Master/texmf-dist/asymptote/GUI/DebugFlags.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 keepFiles = False -printFoutTranscript = False +printAsyTranscript = False printDeconstTranscript = False -forceRasterizationSVG = False diff --git a/Master/texmf-dist/asymptote/GUI/GuidesManager.py b/Master/texmf-dist/asymptote/GUI/GuidesManager.py index 5467843377a..fd317439d47 100755 --- a/Master/texmf-dist/asymptote/GUI/GuidesManager.py +++ b/Master/texmf-dist/asymptote/GUI/GuidesManager.py @@ -1,18 +1,17 @@ #!/usr/bin/env python3 -import PyQt5.QtWidgets as Qw -import PyQt5.QtGui as Qg -import PyQt5.QtCore as Qc -import numpy as np +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import numpy as numpy class Guide: def __init__(self, pen=None): if pen is None: - pen = Qg.QPen() - assert isinstance(pen, Qg.QPen) + pen = QtGui.QPen() + assert isinstance(pen, QtGui.QPen) self.pen = pen def drawShape(self, pen): - assert isinstance(pen, Qg.QPainter) + assert isinstance(pen, QtGui.QPainter) pen.save() pen.setPen(self.pen) @@ -24,19 +23,19 @@ class LineGuide(Guide): 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)) + p1 = self.origin + (9999 * QtCore.QPointF(numpy.cos(self.direction), numpy.sin(self.direction))) + p2 = self.origin - (9999 * QtCore.QPointF(numpy.cos(self.direction), numpy.sin(self.direction))) + pen.drawLine(QtCore.QLineF(p1, p2)) pen.restore() class ArcGuide(Guide): @classmethod def radTo16Deg(cls, radians): - return int(round(np.rad2deg(radians) * 16)) + return int(round(numpy.rad2deg(radians) * 16)) - def __init__(self, center=None, radius=1, startAng=0, endAng=(2*np.pi), pen=None): + def __init__(self, center=None, radius=1, startAng=0, endAng=(2*numpy.pi), pen=None): if center is None: - center = Qc.QPointF(0, 0) + center = QtCore.QPointF(0, 0) super().__init__(pen) self.center = center self.radius = int(radius) @@ -45,7 +44,7 @@ class ArcGuide(Guide): def drawShape(self, pen): super().drawShape(pen) - assert isinstance(pen, Qg.QPainter) + assert isinstance(pen, QtGui.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)) diff --git a/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py b/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py index 132969dad19..9bacd5f51fe 100755 --- a/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py +++ b/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -import PyQt5.QtCore as Qc -import PyQt5.QtGui as Qg -import xasy2asy as x2a +import PyQt5.QtCore as QtCore +import PyQt5.QtGui as QtGui +import xasy2asy as xasy2asy import PrimitiveShape import math @@ -11,9 +11,9 @@ import Widg_addPolyOpt import Widg_addLabel -class InplaceObjProcess(Qc.QObject): - objectCreated = Qc.pyqtSignal(Qc.QObject) - objectUpdated = Qc.pyqtSignal() +class InplaceObjProcess(QtCore.QObject): + objectCreated = QtCore.pyqtSignal(QtCore.QObject) + objectUpdated = QtCore.pyqtSignal() def __init__(self, parent=None): super().__init__(parent) @@ -24,10 +24,10 @@ class InplaceObjProcess(Qc.QObject): def active(self): return self._active - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None): raise NotImplementedError - def mouseMove(self, pos, event: Qg.QMouseEvent): + def mouseMove(self, pos, event: QtGui.QMouseEvent): raise NotImplementedError def mouseRelease(self): @@ -45,7 +45,7 @@ class InplaceObjProcess(Qc.QObject): def getXasyObject(self): raise NotImplementedError - def postDrawPreview(self, canvas: Qg.QPainter): + def postDrawPreview(self, canvas: QtGui.QPainter): pass def createOptWidget(self, info): @@ -55,10 +55,10 @@ class InplaceObjProcess(Qc.QObject): class AddCircle(InplaceObjProcess): def __init__(self, parent=None): super().__init__(parent) - self.center = Qc.QPointF(0, 0) + self.center = QtCore.QPointF(0, 0) self.radius = 0 - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None): x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos) self.radius = 0 self.center.setX(x) @@ -75,9 +75,9 @@ class AddCircle(InplaceObjProcess): 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) + boundRect = QtCore.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius) # because the internal image is flipped... - newPath = Qg.QPainterPath() + newPath = QtGui.QPainterPath() newPath.addEllipse(boundRect) # newPath.addRect(boundRect) return newPath @@ -87,9 +87,9 @@ class AddCircle(InplaceObjProcess): def getXasyObject(self): if self.fill: - newObj = x2a.xasyFilledShape(self.getObject(), None) + newObj = xasy2asy.xasyFilledShape(self.getObject(), None) else: - newObj = x2a.xasyShape(self.getObject(), None) + newObj = xasy2asy.xasyShape(self.getObject(), None) return newObj def forceFinalize(self): @@ -102,8 +102,9 @@ class AddLabel(InplaceObjProcess): self.alignMode = None self.opt = None self.text = None - self.anchor = Qc.QPointF(0, 0) + self.anchor = QtCore.QPointF(0, 0) self._active = False + self.fontSize = 12 def createOptWidget(self, info): self.opt = Widg_addLabel.Widg_addLabel(info) @@ -121,7 +122,7 @@ class AddLabel(InplaceObjProcess): self.anchor.setX(x) self.anchor.setY(y) - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None): if self.opt is not None: self.text = self.opt.labelText x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos) @@ -140,7 +141,7 @@ class AddLabel(InplaceObjProcess): text = self.text align = str(self.alignMode) anchor = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.anchor) - newLabel = x2a.xasyText(text=text, location=anchor, pen=None, + newLabel = xasy2asy.xasyText(text=text, location=anchor, pen=None, align=align, asyengine=None, fontsize=self.fontSize) newLabel.asyfied = False return newLabel @@ -164,11 +165,11 @@ class AddBezierShape(InplaceObjProcess): # 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.currentPoint = QtCore.QPointF(0, 0) self.pendingPoint = None self.useLegacy = False - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None): x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos) self.currentPoint.setX(x) self.currentPoint.setY(y) @@ -222,7 +223,7 @@ class AddBezierShape(InplaceObjProcess): # self.updateBasePath() def updateBasePath(self): - self.basePath = x2a.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase) + self.basePath = xasy2asy.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: @@ -237,7 +238,7 @@ class AddBezierShape(InplaceObjProcess): self.basePath.computeControls() def updateBasePathPreview(self): - self.basePathPreview = x2a.asyPath( + self.basePathPreview = xasy2asy.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()] @@ -271,16 +272,16 @@ class AddBezierShape(InplaceObjProcess): def getXasyObject(self): if self.fill: - return x2a.xasyFilledShape(self.getObject(), None) + return xasy2asy.xasyFilledShape(self.getObject(), None) else: - return x2a.xasyShape(self.getObject(), None) + return xasy2asy.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.center = QtCore.QPointF(0, 0) + self.currPos = QtCore.QPointF(0, 0) self.sides = None self.inscribed = None self.centermode = None @@ -288,18 +289,18 @@ class AddPoly(InplaceObjProcess): self.fill = None self.opt = None - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.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) + self.currPos = QtCore.QPointF(self.center) def mouseMove(self, pos, event): x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos) @@ -329,7 +330,7 @@ class AddPoly(InplaceObjProcess): else: poly = PrimitiveShape.PrimitiveShape.exscribedRegPolygon(self.sides, self.center, self._rad(), self._angle(), qpoly=True) - newPath = Qg.QPainterPath() + newPath = QtGui.QPainterPath() newPath.addPolygon(poly) return newPath @@ -350,7 +351,121 @@ class AddPoly(InplaceObjProcess): def getXasyObject(self): if self.fill: - newObj = x2a.xasyFilledShape(self.getObject(), None) + newObj = xasy2asy.xasyFilledShape(self.getObject(), None) else: - newObj = x2a.xasyShape(self.getObject(), None) + newObj = xasy2asy.xasyShape(self.getObject(), None) return newObj + +class AddFreehand(InplaceObjProcess): + # TODO: At the moment this is just a copy-paste of the AddBezierObj. + # Must find a better algorithm for constructing the obj rather than + # a node for every pixel the mouse moves. + 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 = QtCore.QPointF(0, 0) + self.pendingPoint = None + self.useLegacy = False + + def mouseDown(self, pos, info, mouseEvent: QtGui.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) + self.pointsList.append((x, y, self._getLinkType())) + + + def createOptWidget(self, info): + return None + + def mouseRelease(self): + self.updateBasePath() + self._active = False + self.pointsList.clear() + self.objectCreated.emit(self.getXasyObject()) + self.basePath = None + + def updateBasePath(self): + self.basePath = xasy2asy.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 = xasy2asy.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 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): + self.fill = False + return xasy2asy.xasyShape(self.getObject(), None) diff --git a/Master/texmf-dist/asymptote/GUI/PrimitiveShape.py b/Master/texmf-dist/asymptote/GUI/PrimitiveShape.py index c75e014079f..bbb2414866c 100755 --- a/Master/texmf-dist/asymptote/GUI/PrimitiveShape.py +++ b/Master/texmf-dist/asymptote/GUI/PrimitiveShape.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 -import xasy2asy as x2a -import numpy as np +import xasy2asy as xasy2asy +import numpy as numpy import math -import PyQt5.QtCore as Qc -import PyQt5.QtGui as Qg +import PyQt5.QtCore as QtCore +import PyQt5.QtGui as QtGui class PrimitiveShape: @@ -14,9 +14,9 @@ class PrimitiveShape: @staticmethod def pos_to_tuple(pos): - if isinstance(pos, tuple) or isinstance(pos, np.ndarray): + if isinstance(pos, tuple) or isinstance(pos, numpy.ndarray): return pos - elif isinstance(pos, Qc.QPoint) or isinstance(pos, Qc.QPointF): + elif isinstance(pos, QtCore.QPoint) or isinstance(pos, QtCore.QPointF): return pos.x(), pos.y() else: raise TypeError("Position must be a valid type!") @@ -32,7 +32,7 @@ class PrimitiveShape: @classmethod def circle(cls, position, radius): pos_x, pos_y = PrimitiveShape.pos_to_tuple(position) - newCircle = x2a.asyPath() + newCircle = xasy2asy.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. @@ -45,16 +45,16 @@ class PrimitiveShape: 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): + for ang in numpy.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) + qpoints = [QtCore.QPointF(x, y) for (x, y) in ptsList] + return QtGui.QPolygonF(qpoints) else: ptsList.append('cycle') - newPoly = x2a.asyPath() + newPoly = xasy2asy.asyPath() newPoly.initFromNodeList(ptsList, lkList) return newPoly diff --git a/Master/texmf-dist/asymptote/GUI/SetCustomAnchor.py b/Master/texmf-dist/asymptote/GUI/SetCustomAnchor.py index ad5925cddb4..e4414fecc4e 100755 --- a/Master/texmf-dist/asymptote/GUI/SetCustomAnchor.py +++ b/Master/texmf-dist/asymptote/GUI/SetCustomAnchor.py @@ -1,20 +1,20 @@ #!/usr/bin/env python3 -import PyQt5.QtWidgets as Qw -import PyQt5.QtGui as Qg -import PyQt5.QtCore as Qc +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore from pyUIClass.setCustomAnchor import Ui_Dialog -class CustomAnchorDialog(Qw.QDialog): +class CustomAnchorDialog(QtWidgets.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) + self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(self.resetDialog) - validator = Qg.QDoubleValidator() + validator = QtGui.QDoubleValidator() self.ui.lineEditX.setValidator(validator) self.ui.lineEditY.setValidator(validator) @@ -24,18 +24,18 @@ class CustomAnchorDialog(Qw.QDialog): def checkTextChanged(self, text): if str(text) not in {'.', '-', '.-', '-.'} and str(text): - self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(True) + self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(True) else: - self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(False) + self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False) def getPoint(self): xPoint = float(self.ui.lineEditX.text()) yPoint = float(self.ui.lineEditY.text()) - return Qc.QPointF(xPoint, yPoint) + return QtCore.QPointF(xPoint, yPoint) def handleBtnBoxClick(self, button): - assert isinstance(button, Qw.QAbstractButton) + assert isinstance(button, QtWidgets.QAbstractButton) if button.text() == 'Reset': self.resetDialog() diff --git a/Master/texmf-dist/asymptote/GUI/Widg_addLabel.py b/Master/texmf-dist/asymptote/GUI/Widg_addLabel.py index 776d3e02df9..a5a6503503b 100755 --- a/Master/texmf-dist/asymptote/GUI/Widg_addLabel.py +++ b/Master/texmf-dist/asymptote/GUI/Widg_addLabel.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 from pyUIClass.widg_addLabel import Ui_Form -import PyQt5.QtWidgets as Qw -import PyQt5.QtGui as Qg +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtGui as QtGui import labelEditor import xasyUtils as xu -class Widg_addLabel(Qw.QWidget): +class Widg_addLabel(QtWidgets.QWidget): def __init__(self, info): super().__init__() self.ui = Ui_Form() @@ -34,11 +34,11 @@ class Widg_addLabel(Qw.QWidget): 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() + validator = QtGui.QDoubleValidator() self.ui.txtShiftX.setValidator(validator) self.ui.txtShiftY.setValidator(validator) @@ -53,7 +53,7 @@ class Widg_addLabel(Qw.QWidget): self.updateCheck(self.ui.cmbAlign.currentText()) - def cmbFontSizeTextChanged(self, text: str): + def cmbFontSizeTextChanged(self, text: str): tryParseVal = xu.tryParse(text, float) self.info['fontSize'] = tryParseVal @@ -61,7 +61,7 @@ class Widg_addLabel(Qw.QWidget): advancedEditDialog = labelEditor.labelEditor(self.ui.txtLabelText.text()) advancedEditDialog.show() result = advancedEditDialog.exec_() - if result == Qw.QDialog.Accepted: + if result == QtWidgets.QDialog.Accepted: self.ui.txtLabelText.setText(advancedEditDialog.getText()) @property diff --git a/Master/texmf-dist/asymptote/GUI/Widg_addPolyOpt.py b/Master/texmf-dist/asymptote/GUI/Widg_addPolyOpt.py index b9b9a77f7a1..3d1e419d890 100755 --- a/Master/texmf-dist/asymptote/GUI/Widg_addPolyOpt.py +++ b/Master/texmf-dist/asymptote/GUI/Widg_addPolyOpt.py @@ -1,14 +1,13 @@ #!/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 PyQt5.QtWidgets as QtWidgets +import PyQt5.QtGui as QtGui import sys -class Widg_addPolyOpt(Qw.QWidget): +class Widg_addPolyOpt(QtWidgets.QWidget): def __init__(self, info): super().__init__() self.ui = Ui_Form() @@ -18,7 +17,7 @@ class Widg_addPolyOpt(Qw.QWidget): self.ui.chkInscribed.setChecked(self.info['inscribed']) self.ui.txtSides.setText(str(self.info['sides'])) - self.ui.txtSides.setValidator(Qg.QIntValidator()) + self.ui.txtSides.setValidator(QtGui.QIntValidator()) self.ui.chkInscribed.stateChanged.connect(self.chkInscribedUpdate) self.ui.txtSides.textChanged.connect(self.txtSidesUpdate) diff --git a/Master/texmf-dist/asymptote/GUI/Widg_editBezier.py b/Master/texmf-dist/asymptote/GUI/Widg_editBezier.py index 3a3cbab94ab..161715e0fc0 100755 --- a/Master/texmf-dist/asymptote/GUI/Widg_editBezier.py +++ b/Master/texmf-dist/asymptote/GUI/Widg_editBezier.py @@ -2,16 +2,15 @@ from pyUIClass.widg_editBezier import Ui_Form -import PyQt5.QtCore as Qc -import PyQt5.QtWidgets as Qw -import PyQt5.QtGui as Qg +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtCore as QtCore class LockMode: noLock = 0 angleLock = 1 angleAndScaleLock = 2 -class Widg_editBezier(Qw.QWidget): +class Widg_editBezier(QtWidgets.QWidget): def __init__(self, info: dict, enableCurveFeatures: bool=True): super().__init__() self.ui = Ui_Form() @@ -38,16 +37,16 @@ class Widg_editBezier(Qw.QWidget): def lockMode(self) -> int: return self.ui.cmbLockMode.currentIndex() - @Qc.pyqtSlot(int) + @QtCore.pyqtSlot(int) def cmbLockIndexChange(self, index: int): self.info['editBezierlockMode'] = index - @Qc.pyqtSlot(int) + @QtCore.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/Master/texmf-dist/asymptote/GUI/Window1.py b/Master/texmf-dist/asymptote/GUI/Window1.py index 1f7b67b1fa1..134d3cd1968 100755 --- a/Master/texmf-dist/asymptote/GUI/Window1.py +++ b/Master/texmf-dist/asymptote/GUI/Window1.py @@ -18,6 +18,7 @@ import tempfile import datetime import string import atexit +import pickle import xasyUtils as xu import xasy2asy as x2a @@ -50,7 +51,6 @@ class TransformationChanges(ActionChanges): self.transformation = transformation self.isLocal = isLocal - class ObjCreationChanges(ActionChanges): def __init__(self, obj): self.object = obj @@ -60,6 +60,18 @@ class HardDeletionChanges(ActionChanges): self.item = obj self.objIndex = pos +class SoftDeletionChanges(ActionChanges): + def __init__(self, obj, keyPos): + self.item = obj + self.keyMap = keyPos + +class EditBezierChanges(ActionChanges): + def __init__(self, obj, pos, oldPath, newPath): + self.item = obj + self.objIndex = pos + self.oldPath = oldPath + self.newPath = newPath + class AnchorMode: center = 0 origin = 1 @@ -68,7 +80,7 @@ class AnchorMode: bottomRight = 4 bottomLeft = 5 customAnchor = 6 - + class GridMode: cartesian = 0 @@ -84,6 +96,14 @@ class SelectionMode: delete = 5 setAnchor = 6 selectEdit = 7 + openPoly = 8 + closedPoly = 9 + openCurve = 10 + closedCurve = 11 + addPoly = 12 + addCircle = 13 + addLabel = 14 + addFreehand = 15 class AddObjectMode: Circle = 0 @@ -92,14 +112,15 @@ class AddObjectMode: class MainWindow1(Qw.QMainWindow): defaultFrameStyle = """ - QFrame{{ + QFrame{{ padding: 4.0; - border-radius: 3.0; + border-radius: 3.0; background: rgb({0}, {1}, {2}) }} """ def __init__(self): + self.testingActions = [] super().__init__() self.ui = Ui_MainWindow() global devicePixelRatio @@ -109,12 +130,13 @@ class MainWindow1(Qw.QMainWindow): self.settings = xo.BasicConfigs.defaultOpt self.keyMaps = xo.BasicConfigs.keymaps + self.openRecent = xo.BasicConfigs.openRecent self.raw_args = Qc.QCoreApplication.arguments() self.args = xa.parseArgs(self.raw_args) self.strings = xs.xasyString(self.args.language) - self.asy2psmap = x2a.identity() + self.asy2psmap = x2a.yflip() if self.settings['asyBaseLocation'] is not None: os.environ['ASYMPTOTE_DIR'] = self.settings['asyBaseLocation'] @@ -134,7 +156,8 @@ class MainWindow1(Qw.QMainWindow): # For initialization purposes self.canvSize = Qc.QSize() - self.filename = None + self.fileName = None + self.asyFileName = None self.currDir = None self.mainCanvas = None self.dpi = 300 @@ -165,9 +188,9 @@ class MainWindow1(Qw.QMainWindow): self.inMidTransformation = False self.addMode = None self.currentlySelectedObj = {'key': None, 'allSameKey': set(), 'selectedIndex': None, 'keyIndex': None} - self.pendingSelectedObjList = [] + self.pendingSelectedObjList = [] self.pendingSelectedObjIndex = -1 - + self.savedMousePosition = None self.currentBoundingBox = None self.selectionDelta = None @@ -177,9 +200,12 @@ class MainWindow1(Qw.QMainWindow): self.scaleFactor = 1 self.panOffset = [0, 0] + # Keyboard can focus outside of textboxes + self.setFocusPolicy(Qc.Qt.StrongFocus) + super().setMouseTracking(True) # setMouseTracking(True) - + self.undoRedoStack = Urs.actionStack() self.lockX = False @@ -211,8 +237,10 @@ class MainWindow1(Qw.QMainWindow): 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.ui.btnPan, self.ui.btnDeleteMode, self.ui.btnAnchor, + self.ui.btnSelectEdit, self.ui.btnOpenPoly, self.ui.btnClosedPoly, + self.ui.btnOpenCurve, self.ui.btnClosedCurve, self.ui.btnAddPoly, + self.ui.btnAddCircle, self.ui.btnAddLabel, self.ui.btnAddFreehand } self.objButtons = {self.ui.btnCustTransform, self.ui.actionTransform, self.ui.btnSendForwards, @@ -225,17 +253,17 @@ class MainWindow1(Qw.QMainWindow): self.currAddOptionsWgt = None self.currAddOptions = { - 'options': self.settings, + 'options': self.settings, 'inscribed': True, 'sides': 3, 'centermode': True, - 'fontSize': None, + 'fontSize': None, 'asyengine': self.asyEngine, 'fill': self.ui.btnFill.isChecked(), 'closedPath': False, - 'useBezier': True, + 'useBezier': True, 'magnification': self.magnification, - 'editBezierlockMode': xbi.Web.LockMode.angleLock, + 'editBezierlockMode': xbi.Web.LockMode.angleLock, 'autoRecompute': False } @@ -249,7 +277,7 @@ class MainWindow1(Qw.QMainWindow): # commands switchboard self.commandsFunc = { - 'quit': Qc.QCoreApplication.quit, + 'quit': self.btnCloseFileonClick, 'undo': self.btnUndoOnClick, 'redo': self.btnRedoOnClick, 'manual': self.actionManual, @@ -261,10 +289,10 @@ class MainWindow1(Qw.QMainWindow): 'commandPalette': self.enterCustomCommand, 'clearGuide': self.clearGuides, 'finalizeAddObj': self.finalizeAddObj, - 'finalizeCurve': self.finalizeCurve, - 'finalizeCurveClosed': self.finalizeCurveClosed, + 'finalizeCurve': self.finalizeCurve, + 'finalizeCurveClosed': self.finalizeCurveClosed, 'setMag': self.setMagPrompt, - 'deleteObject': self.btnSelectiveDeleteOnClick, + 'deleteObject': self.btnSelectiveDeleteOnClick, 'anchorMode': self.switchToAnchorMode, 'moveUp': lambda: self.translate(0, -1), 'moveDown': lambda: self.translate(0, 1), @@ -274,10 +302,17 @@ class MainWindow1(Qw.QMainWindow): '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), + 'scrollDown': lambda: self.arrowButtons(0, -1, True), + + 'zoomIn': lambda: self.arrowButtons(0, 1, False, True), + 'zoomOut': lambda: self.arrowButtons(0, -1, False, True), + + 'open': self.btnLoadFileonClick, + 'save': self.actionSave, + 'export': self.btnExportAsymptoteOnClick, - 'zoomIn': lambda: self.arrowButtons(0, 1, False, True), - 'zoomOut': lambda: self.arrowButtons(0, -1, False, True) + 'copy': self.copyItem, + 'paste': self.pasteItem } self.hiddenKeys = set() @@ -291,6 +326,7 @@ class MainWindow1(Qw.QMainWindow): # from xasyoptions config file self.loadKeyMaps() self.setupXasyOptions() + self.populateOpenRecent() self.colorDialog = Qw.QColorDialog(x2a.asyPen.convertToQColor(self._currentPen.color), self) self.initPenInterface() @@ -320,7 +356,7 @@ class MainWindow1(Qw.QMainWindow): def getScrsTransform(self): # pipeline: # assuming origin <==> top left - # (Pan) * (Translate) * (Flip the images) * (Zoom) * (Obj transform) * (Base Information) + # (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) @@ -366,6 +402,12 @@ class MainWindow1(Qw.QMainWindow): self.settings.load() self.quickUpdate() + def openAndReloadKeymaps(self): + keymapsFile = self.keyMaps.settingsFileLocation() + subprocess.run(args=self.getExternalEditor(asypath=keymapsFile)) + self.settings.load() + self.quickUpdate() + def setMagPrompt(self): commandText, result = Qw.QInputDialog.getText(self, '', 'Enter magnification:') if result: @@ -373,6 +415,11 @@ class MainWindow1(Qw.QMainWindow): self.currAddOptions['magnification'] = self.magnification self.quickUpdate() + def setTextPrompt(self): + commandText, result = Qw.QInputDialog.getText(self, '', 'Enter new text:') + if result: + return commandText + def btnTogglePythonOnClick(self, checked): self.terminalPythonMode = checked @@ -381,7 +428,10 @@ class MainWindow1(Qw.QMainWindow): def handleArguments(self): if self.args.filename is not None: - self.loadFile(self.args.filename) + if os.path.exists(self.args.filename): + self.actionOpen(os.path.abspath(self.args.filename)) + else: + self.loadFile(self.args.filename) else: self.initializeEmptyFile() @@ -417,14 +467,18 @@ class MainWindow1(Qw.QMainWindow): self.ui.actionRedo.triggered.connect(lambda: self.execCustomCommand('redo')) self.ui.actionTransform.triggered.connect(lambda: self.execCustomCommand('transform')) + self.ui.actionNewFile.triggered.connect(self.actionNewFile) self.ui.actionOpen.triggered.connect(self.actionOpen) + self.ui.actionClearRecent.triggered.connect(self.actionClearRecent) 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.actionKeymaps.triggered.connect(self.openAndReloadKeymaps) self.ui.actionEnterCommand.triggered.connect(self.enterCustomCommand) - self.ui.actionExportAsymptote.triggered.connect(self.btnExportAsyOnClick) + self.ui.actionExportAsymptote.triggered.connect(self.btnExportAsymptoteOnClick) + self.ui.actionExportToAsy.triggered.connect(self.btnExportToAsyOnClick) def setupXasyOptions(self): if self.settings['debugMode']: @@ -443,7 +497,7 @@ class MainWindow1(Qw.QMainWindow): self.ui.btnSave.clicked.connect(self.btnSaveonClick) self.ui.btnQuickScreenshot.clicked.connect(self.btnQuickScreenshotOnClick) - # self.ui.btnExportAsy.clicked.connect(self.btnExportAsyOnClick) + # self.ui.btnExportAsy.clicked.connect(self.btnExportAsymptoteOnClick) self.ui.btnDrawAxes.clicked.connect(self.btnDrawAxesOnClick) # self.ui.btnAsyfy.clicked.connect(lambda: self.asyfyCanvas(True)) @@ -467,7 +521,7 @@ class MainWindow1(Qw.QMainWindow): self.ui.btnAnchor.clicked.connect(self.btnAnchorModeOnClick) self.ui.btnSelectColor.clicked.connect(self.btnColorSelectOnClick) - self.ui.txtLineWidth.textEdited.connect(self.txtLineWithEdited) + self.ui.txtLineWidth.textEdited.connect(self.txtLineWidthEdited) # self.ui.btnCreateCurve.clicked.connect(self.btnCreateCurveOnClick) self.ui.btnDrawGrid.clicked.connect(self.btnDrawGridOnClick) @@ -475,6 +529,7 @@ class MainWindow1(Qw.QMainWindow): self.ui.btnAddCircle.clicked.connect(self.btnAddCircleOnClick) self.ui.btnAddPoly.clicked.connect(self.btnAddPolyOnClick) self.ui.btnAddLabel.clicked.connect(self.btnAddLabelOnClick) + self.ui.btnAddFreehand.clicked.connect(self.btnAddFreehandOnClick) # self.ui.btnAddBezierInplace.clicked.connect(self.btnAddBezierInplaceOnClick) self.ui.btnClosedCurve.clicked.connect(self.btnAddClosedCurveOnClick) self.ui.btnOpenCurve.clicked.connect(self.btnAddOpenCurveOnClick) @@ -489,16 +544,19 @@ class MainWindow1(Qw.QMainWindow): 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() + if self.currentModeStack[-1] != SelectionMode.delete: + self.currentModeStack = [SelectionMode.delete] + self.ui.statusbar.showMessage('Delete mode') + self.clearSelection() + self.updateChecks() + else: + self.btnTranslateonClick() def btnTerminalCommandOnClick(self): if self.terminalPythonMode: @@ -507,18 +565,25 @@ class MainWindow1(Qw.QMainWindow): else: pass # TODO: How to handle this case? - # Like AutoCAD? + # Like AutoCAD? self.ui.txtTerminalPrompt.clear() - def btnFillOnClick(self, checked): + def btnFillOnClick(self, checked): + if self.currentModeStack == [SelectionMode.selectEdit]: + if isinstance(self.addMode,xbi.InteractiveBezierEditor): + self.addMode.swapObjFill() #Check for crashes 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() + if self.currentModeStack[-1] != SelectionMode.selectEdit: + self.currentModeStack = [SelectionMode.selectEdit] + self.ui.statusbar.showMessage('Edit mode') + self.clearSelection() + self.updateChecks() + else: + self.btnTranslateonClick() @property def currentPen(self): @@ -544,7 +609,7 @@ class MainWindow1(Qw.QMainWindow): except Exception: pass - self.currentModeStack[-1] = None + #self.currentModeStack[-1] = None self.addMode.objectCreated.connect(self.addInPlace) self.updateModeBtnsOnly() @@ -557,7 +622,10 @@ class MainWindow1(Qw.QMainWindow): def addInPlace(self, obj): obj.asyengine = self.asyEngine - obj.pen = self.currentPen + if isinstance(obj, x2a.xasyText): + obj.label.pen = self.currentPen + else: + obj.pen = self.currentPen obj.onCanvas = self.xasyDrawObj obj.setKey(str(self.globalObjectCounter)) self.globalObjectCounter = self.globalObjectCounter + 1 @@ -576,11 +644,6 @@ class MainWindow1(Qw.QMainWindow): 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.' @@ -598,49 +661,90 @@ class MainWindow1(Qw.QMainWindow): self.ui.statusbar.showMessage(self.Hint+self.HintClose) def btnAddBezierInplaceOnClick(self): + self.fileChanged = True self.addMode = InplaceAddObj.AddBezierShape(self) self.updateOptionWidget() def btnAddOpenLineOnClick(self): - self.currAddOptions['useBezier'] = False - self.currAddOptions['closedPath'] = False - self.drawHintOpen() - self.btnAddBezierInplaceOnClick() + if self.currentModeStack[-1] != SelectionMode.openPoly: + self.currentModeStack = [SelectionMode.openPoly] + self.currAddOptions['useBezier'] = False + self.currAddOptions['closedPath'] = False + self.drawHintOpen() + self.btnAddBezierInplaceOnClick() + else: + self.btnTranslateonClick() def btnAddClosedLineOnClick(self): - self.currAddOptions['useBezier'] = False - self.currAddOptions['closedPath'] = True - self.drawHint() - self.btnAddBezierInplaceOnClick() + if self.currentModeStack[-1] != SelectionMode.closedPoly: + self.currentModeStack = [SelectionMode.closedPoly] + self.currAddOptions['useBezier'] = False + self.currAddOptions['closedPath'] = True + self.drawHint() + self.btnAddBezierInplaceOnClick() + else: + self.btnTranslateonClick() def btnAddOpenCurveOnClick(self): - self.currAddOptions['useBezier'] = True - self.currAddOptions['closedPath'] = False - self.drawHintOpen() - self.btnAddBezierInplaceOnClick() + if self.currentModeStack[-1] != SelectionMode.openCurve: + self.currentModeStack = [SelectionMode.openCurve] + self.currAddOptions['useBezier'] = True + self.currAddOptions['closedPath'] = False + self.drawHintOpen() + self.btnAddBezierInplaceOnClick() + else: + self.btnTranslateonClick() def btnAddClosedCurveOnClick(self): - self.currAddOptions['useBezier'] = True - self.currAddOptions['closedPath'] = True - self.drawHint() - self.btnAddBezierInplaceOnClick() + if self.currentModeStack[-1] != SelectionMode.closedCurve: + self.currentModeStack = [SelectionMode.closedCurve] + self.currAddOptions['useBezier'] = True + self.currAddOptions['closedPath'] = True + self.drawHint() + self.btnAddBezierInplaceOnClick() + else: + self.btnTranslateonClick() def btnAddPolyOnClick(self): - self.addMode = InplaceAddObj.AddPoly(self) - self.ui.statusbar.showMessage('') - self.updateOptionWidget() + if self.currentModeStack[-1] != SelectionMode.addPoly: + self.currentModeStack = [SelectionMode.addPoly] + self.addMode = InplaceAddObj.AddPoly(self) + self.ui.statusbar.showMessage('Add polygon on click') + self.updateOptionWidget() + else: + self.btnTranslateonClick() - def btnAddLabelOnClick(self): - self.addMode = InplaceAddObj.AddLabel(self) - self.ui.statusbar.showMessage('') - self.updateOptionWidget() + def btnAddCircleOnClick(self): + if self.currentModeStack[-1] != SelectionMode.addCircle: + self.currentModeStack = [SelectionMode.addCircle] + self.addMode = InplaceAddObj.AddCircle(self) + self.ui.statusbar.showMessage('Add circle on click') + self.updateOptionWidget() + else: + self.btnTranslateonClick() - def updateCurve(self, valid, newCurve): - self.previewCurve = newCurve - self.quickUpdate() + def btnAddLabelOnClick(self): + if self.currentModeStack[-1] != SelectionMode.addLabel: + self.currentModeStack = [SelectionMode.addLabel] + self.addMode = InplaceAddObj.AddLabel(self) + self.ui.statusbar.showMessage('Add label on click') + self.updateOptionWidget() + else: + self.btnTranslateonClick() + + def btnAddFreehandOnClick(self): + if self.currentModeStack[-1] != SelectionMode.addFreehand: + self.currentModeStack = [SelectionMode.addFreehand] + self.currAddOptions['useBezier'] = False + self.currAddOptions['closedPath'] = False + self.ui.statusbar.showMessage("Draw freehand") + self.addMode = InplaceAddObj.AddFreehand(self) + self.updateOptionWidget() + else: + self.btnTranslateonClick() def addTransformationChanges(self, objIndex, transform, isLocal=False): - self.undoRedoStack.add(self.createAction(TransformationChanges(objIndex, + self.undoRedoStack.add(self.createAction(TransformationChanges(objIndex, transform, isLocal))) self.checkUndoRedoButtons() @@ -665,7 +769,11 @@ class MainWindow1(Qw.QMainWindow): parent = selectedObj.parent() if isinstance(parent, x2a.xasyScript): - self.hiddenKeys.add((selectedObj.key, selectedObj.keyIndex)) + objKey=(selectedObj.key, selectedObj.keyIndex) + self.hiddenKeys.add(objKey) + self.undoRedoStack.add(self.createAction( + SoftDeletionChanges(selectedObj.parent(), objKey) + )) self.softDeleteObj((maj, minor)) else: index = self.fileItems.index(selectedObj.parent()) @@ -673,10 +781,10 @@ class MainWindow1(Qw.QMainWindow): self.undoRedoStack.add(self.createAction( HardDeletionChanges(selectedObj.parent(), index) )) - self.checkUndoRedoButtons() - + self.fileItems.remove(selectedObj.parent()) + self.checkUndoRedoButtons() self.fileChanged = True self.clearSelection() self.asyfyCanvas() @@ -709,8 +817,16 @@ class MainWindow1(Qw.QMainWindow): def btnUndoOnClick(self): - self.undoRedoStack.undo() - self.checkUndoRedoButtons() + if self.currentlySelectedObj['selectedIndex'] is not None: + # avoid deleting currently selected object + maj, minor = self.currentlySelectedObj['selectedIndex'] + selectedObj = self.drawObjects[maj][minor] + if selectedObj != self.drawObjects[-1][0]: + self.undoRedoStack.undo() + self.checkUndoRedoButtons() + else: + self.undoRedoStack.undo() + self.checkUndoRedoButtons() def btnRedoOnClick(self): self.undoRedoStack.redo() @@ -731,6 +847,12 @@ class MainWindow1(Qw.QMainWindow): self.fileItems.pop() elif isinstance(change, HardDeletionChanges): self.fileItems.insert(change.objIndex, change.item) + elif isinstance(change, SoftDeletionChanges): + key, keyIndex = change.keyMap + self.hiddenKeys.remove((key, keyIndex)) + change.item.transfKeymap[key][keyIndex].deleted = False + elif isinstance(change, EditBezierChanges): + self.fileItems[change.objIndex].path = change.oldPath self.asyfyCanvas() def handleRedoChanges(self, change): @@ -742,6 +864,12 @@ class MainWindow1(Qw.QMainWindow): self.fileItems.append(change.object) elif isinstance(change, HardDeletionChanges): self.fileItems.remove(change.item) + elif isinstance(change, SoftDeletionChanges): + key, keyIndex = change.keyMap + self.hiddenKeys.add((key, keyIndex)) + change.item.transfKeymap[key][keyIndex].deleted = True + elif isinstance(change, EditBezierChanges): + self.fileItems[change.objIndex].path = change.newPath self.asyfyCanvas() # is this a "pythonic" way? @@ -765,11 +893,26 @@ class MainWindow1(Qw.QMainWindow): if result: self.execCustomCommand(commandText) - def addItemFromPath(self, path): - newItem = x2a.xasyShape(path, self.asyEngine, pen=self.currentPen) + def addXasyShapeFromPath(self, path, pen = None, transform = x2a.identity(), key = None): + if not pen: + pen = self.currentPen + else: + pen = x2a.asyPen(self.asyEngine, color = pen['color'], width = pen['width'], pen_options = pen['options']) + + newItem = x2a.xasyShape(path, self.asyEngine, pen = pen, transform = transform) + newItem.setKey(key) self.fileItems.append(newItem) - self.fileChanged = True - self.asyfyCanvas() + + def addXasyTextFromData(self, text, location, pen, transform, key, align, fontSize): + if not pen: + pen = self.currentPen + else: + pen = x2a.asyPen(self.asyEngine, color = pen['color'], width = pen['width'], pen_options = pen['options']) + newItem = x2a.xasyText(text, location, self.asyEngine, pen, transform, key, align, fontSize) + newItem.setKey(key) + newItem.onCanvas = self.xasyDrawObj + self.fileItems.append(newItem) + def actionManual(self): asyManualURL = 'https://asymptote.sourceforge.io/asymptote.pdf' @@ -778,11 +921,35 @@ class MainWindow1(Qw.QMainWindow): def actionAbout(self): Qw.QMessageBox.about(self,"xasy","This is xasy "+xasyVersion.xasyVersion+"; a graphical front end to the Asymptote vector graphics language: https://asymptote.sourceforge.io/") - def btnExportAsyOnClick(self): + def actionExport(self, pathToFile): + asyFile = io.open(os.path.realpath(pathToFile), 'w') + xf.saveFile(asyFile, self.fileItems, self.asy2psmap) + asyFile.close() + self.ui.statusbar.showMessage(f"Exported to '{pathToFile}' as Asymptote File.") + + def btnExportToAsyOnClick(self): + if self.fileName: + pathToFile = os.path.splitext(self.fileName)[0]+'.asy' + else: + self.btnExportAsymptoteOnClick() + return + if os.path.isfile(pathToFile): + reply = Qw.QMessageBox.question(self, 'Message', + f'"{os.path.split(pathToFile)[1]}" already exists. Do you want to overwrite it?', + Qw.QMessageBox.Yes, Qw.QMessageBox.No) + if reply == Qw.QMessageBox.No: + return + self.actionExport(pathToFile) + + def btnExportAsymptoteOnClick(self): diag = Qw.QFileDialog(self) diag.setAcceptMode(Qw.QFileDialog.AcceptSave) formatId = { + 'asy': { + 'name': 'Asymptote Files', + 'ext': ['*.asy'] + }, 'pdf': { 'name': 'PDF Files', 'ext': ['*.pdf'] @@ -805,14 +972,14 @@ class MainWindow1(Qw.QMainWindow): } } - formats = ['pdf', 'svg', 'eps', 'png', '*'] + formats = ['asy', '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' + rawFile = os.path.splitext(os.path.basename(self.fileName))[0] + '.asy' diag.selectFile(rawFile) diag.setNameFilter(formatText) @@ -823,25 +990,107 @@ class MainWindow1(Qw.QMainWindow): return finalFiles = diag.selectedFiles() - - with io.StringIO() as finalCode: - xf.saveFile(finalCode, self.fileItems, self.asy2psmap) - finalString = finalCode.getvalue() + finalString = xf.xasy2asyCode(self.fileItems, self.asy2psmap) for file in finalFiles: ext = os.path.splitext(file) if len(ext) < 2: - ext = 'pdf' + ext = 'asy' else: ext = ext[1][1:] + if ext == 'asy': + pathToFile = os.path.splitext(file)[0]+'.'+ext + asyFile = io.open(os.path.realpath(pathToFile), 'w') + xf.saveFile(asyFile, self.fileItems, self.asy2psmap) + asyFile.close() + else: + with subprocess.Popen(args=[self.asyPath, '-f{0}'.format(ext), '-o{0}'.format(file), '-'], encoding='utf-8', + stdin=subprocess.PIPE) as asy: + + asy.stdin.write(finalString) + asy.stdin.close() + asy.wait(timeout=35) + + def actionExportXasy(self, file): + xasyObjects, asyItems = xf.xasyToDict(self.fileName, self.fileItems, self.asy2psmap) - 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) + if asyItems: + # Save imported items into the twin asy file + asyScriptItems = [item['item'] for item in asyItems if item['type'] == 'xasyScript'] + + prefix = os.path.splitext(self.fileName)[0] + asyFilePath = prefix + '.asy' + + saveAsyFile = io.open(asyFilePath, 'w') + xf.saveFile(saveAsyFile, asyScriptItems, self.asy2psmap) + saveAsyFile.close() + self.updateScript() + + openFile = open(file, 'wb') + pickle.dump(xasyObjects, openFile) + openFile.close() + + def actionLoadXasy(self, file): + self.erase() + self.ui.statusbar.showMessage('Load {0}'.format(file)) # TODO: This doesn't show on the UI + self.fileName = file + self.currDir = os.path.dirname(self.fileName) + + input_file = open(file, 'rb') + xasyObjects = pickle.load(input_file) + input_file.close() + + prefix = os.path.splitext(self.fileName)[0] + asyFilePath = prefix + '.asy' + rawText = None + existsAsy = False + + if os.path.isfile(asyFilePath): + asyFile = io.open(asyFilePath, 'r') + rawText = asyFile.read() + asyFile.close() + rawText, transfDict = xf.extractTransformsFromFile(rawText) + obj = x2a.xasyScript(canvas=self.xasyDrawObj, engine=self.asyEngine, transfKeyMap=transfDict) + obj.setScript(rawText) + self.fileItems.append(obj) + existsAsy = True + + self.asyfyCanvas(force=True) + + for item in xasyObjects['objects']: + key=item['transfKey'] + if(key) in obj.transfKeymap.keys(): + continue + obj.maxKey=max(obj.maxKey,int(key)) + if item['type'] == 'xasyScript': + print("Uh oh, there should not be any asy objects loaded") + + elif item['type'] == 'xasyText': + self.addXasyTextFromData( text = item['text'], + location = item['location'], pen = None, + transform = x2a.asyTransform(item['transform']), key = item['transfKey'], + align = item['align'], fontSize = item['fontSize'] + ) + + elif item['type'] == 'xasyShape': + nodeSet = item['nodes'] + linkSet = item['links'] + path = x2a.asyPath(self.asyEngine) + path.initFromNodeList(nodeSet, linkSet) + self.addXasyShapeFromPath(path, pen = item['pen'], transform = x2a.asyTransform(item['transform']), key = item['transfKey']) + else: + print("ERROR") + + self.asy2psmap = x2a.asyTransform(xasyObjects['asy2psmap']) + self.globalObjectCounter = obj.maxKey+1 + + self.asyfyCanvas() + + if existsAsy: + self.ui.statusbar.showMessage(f"Corresponding Asymptote File '{os.path.basename(asyFilePath)}' found. Loaded both files.") + else: + self.ui.statusbar.showMessage("No Asymptote file found. Loaded exclusively GUI objects.") def loadKeyMaps(self): """Inverts the mapping of the key @@ -865,28 +1114,147 @@ class MainWindow1(Qw.QMainWindow): def erase(self): self.fileItems.clear() + self.hiddenKeys.clear() + self.undoRedoStack.clear() + self.checkUndoRedoButtons() self.fileChanged = False - def actionOpen(self): + #We include this function to keep the general program flow consistent + def closeEvent(self, event): + if self.actionClose() == Qw.QMessageBox.Cancel: + event.ignore() + + def actionNewFile(self): if self.fileChanged: - save="Save current file?" - reply=Qw.QMessageBox.question(self,'Message',save,Qw.QMessageBox.Yes, - Qw.QMessageBox.No) + reply = self.saveDialog() if reply == Qw.QMessageBox.Yes: self.actionSave() + elif reply == Qw.QMessageBox.Cancel: + return + self.erase() + self.asyfyCanvas(force=True) + self.fileName = None + self.updateTitle() + + + def actionOpen(self, fileName = None): + if self.fileChanged: + reply = self.saveDialog() + if reply == Qw.QMessageBox.Yes: + self.actionSave() + elif reply == Qw.QMessageBox.Cancel: + return - filename = Qw.QFileDialog.getOpenFileName(self, 'Open Asymptote File','', '*.asy') - if filename[0]: - self.loadFile(filename[0]) + if fileName: + # Opening via open recent or cmd args + _, file_extension = os.path.splitext(fileName) + if file_extension == '.xasy': + self.actionLoadXasy(fileName) + else: + self.loadFile(fileName) + self.populateOpenRecent(fileName) + else: + filename = Qw.QFileDialog.getOpenFileName(self, 'Open Xasy/Asymptote File','', '(*.xasy *.asy)') + if filename[0]: + _, file_extension = os.path.splitext(filename[0]) + if file_extension == '.xasy': + self.actionLoadXasy(filename[0]) + else: + self.loadFile(filename[0]) + + self.populateOpenRecent(filename[0].strip()) + + def actionClearRecent(self): + self.ui.menuOpenRecent.clear() + self.openRecent.clear() + self.ui.menuOpenRecent.addAction("Clear", self.actionClearRecent) + + def populateOpenRecent(self, recentOpenedFile = None): + self.ui.menuOpenRecent.clear() + if recentOpenedFile: + self.openRecent.insert(recentOpenedFile) + for count, path in enumerate(self.openRecent.pathList): + if count > 8: + break + action = Qw.QAction(path, self, triggered = lambda state, path = path: self.actionOpen(fileName = path)) + self.ui.menuOpenRecent.addAction(action) + self.ui.menuOpenRecent.addSeparator() + self.ui.menuOpenRecent.addAction("Clear", self.actionClearRecent) + + def saveDialog(self) -> bool: + save = "Save current file?" + replyBox = Qw.QMessageBox() + replyBox.setText("Save current file?") + replyBox.setWindowTitle("Message") + replyBox.setStandardButtons(Qw.QMessageBox.Yes | Qw.QMessageBox.No | Qw.QMessageBox.Cancel) + reply = replyBox.exec() + + return reply + + def actionClose(self): + if self.fileChanged: + reply = self.saveDialog() + if reply == Qw.QMessageBox.Yes: + self.actionSave() + Qc.QCoreApplication.quit() + elif reply == Qw.QMessageBox.No: + Qc.QCoreApplication.quit() + else: + return reply + else: + Qc.QCoreApplication.quit() def actionSave(self): - if self.filename is None: + if self.fileName is None: self.actionSaveAs() + else: - saveFile = io.open(self.filename, 'w') - xf.saveFile(saveFile, self.fileItems, self.asy2psmap) - saveFile.close() + _, file_extension = os.path.splitext(self.fileName) + if file_extension == ".asy": + if self.existsXasy(): + warning = "Choose save format. Note that objects saved in asy format cannot be edited graphically." + replyBox = Qw.QMessageBox() + replyBox.setWindowTitle('Warning') + replyBox.setText(warning) + replyBox.addButton("Save as .xasy", replyBox.NoRole) + replyBox.addButton("Save as .asy", replyBox.YesRole) + replyBox.addButton(Qw.QMessageBox.Cancel) + reply = replyBox.exec() + if reply == 1: + saveFile = io.open(self.fileName, 'w') + xf.saveFile(saveFile, self.fileItems, self.asy2psmap) + saveFile.close() + self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName)) + self.fileChanged = False + elif reply == 0: + prefix = os.path.splitext(self.fileName)[0] + xasyFilePath = prefix + '.xasy' + if os.path.isfile(xasyFilePath): + warning = f'"{os.path.basename(xasyFilePath)}" already exists. Do you want to overwrite it?' + reply = Qw.QMessageBox.question(self, "Same File", warning, Qw.QMessageBox.No, Qw.QMessageBox.Yes) + if reply == Qw.QMessageBox.No: + return + + self.actionExportXasy(xasyFilePath) + self.fileName = xasyFilePath + self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName)) + self.fileChanged = False + else: + return + + else: + saveFile = io.open(self.fileName, 'w') + xf.saveFile(saveFile, self.fileItems, self.asy2psmap) + saveFile.close() + self.fileChanged = False + elif file_extension == ".xasy": + self.actionExportXasy(self.fileName) + self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName)) + self.fileChanged = False + else: + print("ERROR: file extension not supported") self.updateScript() + self.updateTitle() def updateScript(self): for item in self.fileItems: @@ -895,15 +1263,30 @@ class MainWindow1(Qw.QMainWindow): item.setScript(item.updatedCode) item.updatedCode = None + def existsXasy(self): + for item in self.fileItems: + if not isinstance(item, x2a.xasyScript): + return True + return False + def actionSaveAs(self): - saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save File')[0] + initSave = os.path.splitext(str(self.fileName))[0]+'.xasy' + saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save File', initSave, "Xasy File (*.xasy)")[0] if saveLocation: - saveFile = io.open(saveLocation, 'w') - xf.saveFile(saveFile, self.fileItems, self.asy2psmap) - saveFile.close() - self.filename = saveLocation + _, file_extension = os.path.splitext(saveLocation) + if not file_extension: + saveLocation += '.xasy' + self.actionExportXasy(saveLocation) + elif file_extension == ".xasy": + self.actionExportXasy(saveLocation) + else: + print("ERROR: file extension not supported") + self.fileName = saveLocation self.updateScript() - + self.fileChanged = False + self.updateTitle() + self.populateOpenRecent(saveLocation) + def btnQuickScreenshotOnClick(self): saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save Screenshot','') @@ -913,6 +1296,9 @@ class MainWindow1(Qw.QMainWindow): def btnLoadFileonClick(self): self.actionOpen() + def btnCloseFileonClick(self): + self.actionClose() + def btnSaveonClick(self): self.actionSave() @@ -933,7 +1319,7 @@ class MainWindow1(Qw.QMainWindow): self._currentPen.setColorFromQColor(self.colorDialog.selectedColor()) self.updateFrameDispColor() - def txtLineWithEdited(self, text): + def txtLineWidthEdited(self, text): new_val = xu.tryParse(text, float) if new_val is not None: if new_val > 0: @@ -985,12 +1371,12 @@ class MainWindow1(Qw.QMainWindow): def mouseMoveEvent(self, mouseEvent: Qg.QMouseEvent): # TODO: Actually refine grid snapping... if not self.ui.imgLabel.underMouse() and not self.mouseDown: - return + return self.updateMouseCoordLabel() asyPos, canvasPos = self.getAsyCoordinates() - # add mode + # add mode if self.addMode is not None: if self.addMode.active: self.addMode.mouseMove(asyPos, mouseEvent) @@ -1016,7 +1402,7 @@ class MainWindow1(Qw.QMainWindow): self.quickUpdate() return - # otherwise, in transformation + # otherwise, in transformation if self.inMidTransformation: if self.currentModeStack[-1] == SelectionMode.translate: newPos = canvasPos - self.savedMousePosition @@ -1080,11 +1466,11 @@ class MainWindow1(Qw.QMainWindow): self.pendingSelectedObjList.clear() self.pendingSelectedObjIndex = -1 self.quickUpdate() - return + return def mouseReleaseEvent(self, mouseEvent): - assert isinstance(mouseEvent, Qg.QMouseEvent) + assert isinstance(mouseEvent, Qg.QMouseEvent) if not self.mouseDown: return @@ -1124,8 +1510,7 @@ class MainWindow1(Qw.QMainWindow): keyModifiers = keyModifiers | defaultModifiers if keyModifiers & int(Qc.Qt.ControlModifier): oldMag = self.magnification - - factor=0.5/devicePixelRatio; + factor = 0.5/devicePixelRatio cx, cy = self.canvSize.width()*factor, self.canvSize.height()*factor centerPoint = Qc.QPointF(cx, cy) * self.getScrsTransform().inverted()[0] @@ -1203,7 +1588,7 @@ class MainWindow1(Qw.QMainWindow): 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 @@ -1252,7 +1637,15 @@ class MainWindow1(Qw.QMainWindow): self.addMode = None self.deleteAddOptions() - def editFinalized(self): + def editAccepted(self, obj, objIndex): + self.undoRedoStack.add(self.createAction( + EditBezierChanges(obj, objIndex, + self.addMode.asyPathBackup, + self.addMode.asyPath + ) + )) + self.checkUndoRedoButtons() + self.addMode.forceFinalize() self.removeAddMode() self.fileChanged = True @@ -1260,7 +1653,10 @@ class MainWindow1(Qw.QMainWindow): def editRejected(self): self.addMode.resetObj() - self.editFinalized() + self.addMode.forceFinalize() + self.removeAddMode() + self.fileChanged = True + self.quickUpdate() def setupSelectEdit(self): """For Select-Edit mode. For now, if the object selected is a bezier curve, opens up a bezier editor""" @@ -1270,12 +1666,20 @@ class MainWindow1(Qw.QMainWindow): # bezier path self.addMode = xbi.InteractiveBezierEditor(self, obj, self.currAddOptions) self.addMode.objectUpdated.connect(self.objectUpdated) - self.addMode.editAccepted.connect(self.editFinalized) + self.addMode.editAccepted.connect(lambda: self.editAccepted(obj, maj)) self.addMode.editRejected.connect(self.editRejected) self.updateOptionWidget() self.currentModeStack[-1] = SelectionMode.selectEdit self.fileChanged = True + elif isinstance(obj, x2a.xasyText): + newText = self.setTextPrompt() + if newText: + self.drawObjects.remove(obj.generateDrawObjects(False)) + obj.label.setText(newText) + self.drawObjects.append(obj.generateDrawObjects(True)) + self.fileChanged = True else: + self.ui.statusbar.showMessage('Warning: Selected object cannot be edited') self.clearSelection() self.quickUpdate() @@ -1359,7 +1763,7 @@ class MainWindow1(Qw.QMainWindow): # but it's much more work... newCenter = self.magnification * newCenter self.panOffset = [-newCenter.x(), newCenter.y()] - + self.quickUpdate() def selectObject(self): @@ -1410,7 +1814,7 @@ class MainWindow1(Qw.QMainWindow): def getWindowCoordinates(self): # assert self.ui.imgLabel.underMouse() return self.mapFromGlobal(Qg.QCursor.pos()) - + def refreshCanvas(self): if self.mainCanvas.isActive(): self.mainCanvas.end() @@ -1430,16 +1834,20 @@ class MainWindow1(Qw.QMainWindow): self.coordLabel.setText('{0:.2f}, {1:.2f} '.format(nx, ny)) def quickUpdate(self): + # TODO: Some documentation here would be nice since this is one of the + # main functions that gets called everywhere. self.updateMouseCoordLabel() self.refreshCanvas() - self.preDraw(self.mainCanvas) + self.preDraw(self.mainCanvas) # coordinates/background self.quickDraw() self.mainCanvas.end() self.postDraw() self.updateScreen() + self.updateTitle() + def quickDraw(self): assert self.isReady() dpi = self.magnification * self.dpi @@ -1466,7 +1874,7 @@ class MainWindow1(Qw.QMainWindow): if self.pendingSelectedObjList: maj, minor = self.pendingSelectedObjList[self.pendingSelectedObjIndex] self.drawObjects[maj][minor].draw(canvas=self.mainCanvas, dpi=dpi) - # and apply the preview too... + # and apply the preview too... elif activeItem is not None: if self.useGlobalCoords: activeItem.draw(self.newTransform, canvas=self.mainCanvas, dpi=dpi) @@ -1474,6 +1882,17 @@ class MainWindow1(Qw.QMainWindow): activeItem.draw(self.newTransform, applyReverse=True, canvas=self.mainCanvas, dpi=dpi) activeItem = None + def updateTitle(self): + # TODO: Undo redo doesn't update appropriately. Have to find a fix for this. + title = '' + if self.fileName: + title += os.path.basename(self.fileName) + else: + title += "[Not Saved]" + if self.fileChanged: + title += ' *' + self.setWindowTitle(title) + def updateScreen(self): self.finalPixmap = Qg.QPixmap(self.canvSize) self.finalPixmap.setDevicePixelRatio(devicePixelRatio) @@ -1502,6 +1921,7 @@ class MainWindow1(Qw.QMainWindow): for x in np.arange(0, 2 * x_range + 1, majorGrid): # have to do # this in two stages... preCanvas.setPen(minorGridCol) + self.makePenCosmetic(preCanvas) for xMinor in range(1, minorGridCount + 1): xCoord = x + ((xMinor / (minorGridCount + 1)) * majorGrid) preCanvas.drawLine(Qc.QLine(xCoord, -9999, xCoord, 9999)) @@ -1509,17 +1929,20 @@ class MainWindow1(Qw.QMainWindow): for y in np.arange(0, 2 * y_range + 1, majorGrid): preCanvas.setPen(minorGridCol) + self.makePenCosmetic(preCanvas) 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) + self.makePenCosmetic(preCanvas) 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) + self.makePenCosmetic(preCanvas) preCanvas.drawLine(Qc.QLine(x, -9999, x, 9999)) preCanvas.drawLine(Qc.QLine(-x, -9999, -x, 9999)) @@ -1568,6 +1991,7 @@ class MainWindow1(Qw.QMainWindow): if self.drawAxes: preCanvas.setPen(Qc.Qt.gray) + self.makePenCosmetic(preCanvas) preCanvas.drawLine(Qc.QLine(-9999, 0, 9999, 0)) preCanvas.drawLine(Qc.QLine(0, -9999, 0, 9999)) @@ -1590,13 +2014,14 @@ class MainWindow1(Qw.QMainWindow): 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] + self.makePenCosmetic(painter) if not self.useGlobalCoords: painter.save() painter.setTransform( @@ -1621,13 +2046,14 @@ class MainWindow1(Qw.QMainWindow): with Qg.QPainter(self.postCanvasPixmap) as postCanvas: postCanvas.setRenderHints(self.mainCanvas.renderHints()) postCanvas.setTransform(self.getScrsTransform()) + # self.makePenCosmetic(postCanvas) 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: @@ -1657,11 +2083,29 @@ class MainWindow1(Qw.QMainWindow): activeBtn = self.ui.btnDeleteMode elif self.currentModeStack[-1] == SelectionMode.selectEdit: activeBtn = self.ui.btnSelectEdit + elif self.currentModeStack[-1] == SelectionMode.openPoly: + activeBtn = self.ui.btnOpenPoly + elif self.currentModeStack[-1] == SelectionMode.closedPoly: + activeBtn = self.ui.btnClosedPoly + elif self.currentModeStack[-1] == SelectionMode.openCurve: + activeBtn = self.ui.btnOpenCurve + elif self.currentModeStack[-1] == SelectionMode.closedCurve: + activeBtn = self.ui.btnClosedCurve + elif self.currentModeStack[-1] == SelectionMode.addPoly: + activeBtn = self.ui.btnAddPoly + elif self.currentModeStack[-1] == SelectionMode.addCircle: + activeBtn = self.ui.btnAddCircle + elif self.currentModeStack[-1] == SelectionMode.addLabel: + activeBtn = self.ui.btnAddLabel + elif self.currentModeStack[-1] == SelectionMode.addFreehand: + activeBtn = self.ui.btnAddFreehand else: activeBtn = None - + disableFill = isinstance(self.addMode, InplaceAddObj.AddBezierShape) and not self.currAddOptions['closedPath'] + if isinstance(self.addMode, xbi.InteractiveBezierEditor): + disableFill = disableFill or not (self.addMode.obj.path.nodeSet[-1] == "cycle") self.ui.btnFill.setEnabled(not disableFill) if disableFill and self.ui.btnFill.isEnabled(): self.ui.btnFill.setChecked(not disableFill) @@ -1670,22 +2114,36 @@ class MainWindow1(Qw.QMainWindow): for button in self.modeButtons: button.setChecked(button is activeBtn) + if activeBtn in [self.ui.btnDeleteMode,self.ui.btnSelectEdit]: + self.ui.btnAlignX.setEnabled(False) + self.ui.btnAlignY.setEnabled(False) + else: + self.ui.btnAlignX.setEnabled(True) + self.ui.btnAlignY.setEnabled(True) + + 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) + if self.currentModeStack[0] in [SelectionMode.selectEdit,SelectionMode.delete]: + self.ui.btnAlignX.setChecked(False) + else: + 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) + if self.currentModeStack[0] in [SelectionMode.selectEdit,SelectionMode.delete]: + self.ui.btnAlignY.setChecked(False) + else: + self.lockX = checked + if self.lockY: + self.lockY = False + self.ui.btnAlignX.setChecked(False) def btnAnchorModeOnClick(self): if self.currentModeStack[-1] != SelectionMode.setAnchor: @@ -1704,22 +2162,31 @@ class MainWindow1(Qw.QMainWindow): self.updateChecks() def btnRotateOnClick(self): - self.currentModeStack = [SelectionMode.rotate] - self.ui.statusbar.showMessage('Rotate mode') - self.clearSelection() - self.updateChecks() + if self.currentModeStack[-1] != SelectionMode.rotate: + self.currentModeStack = [SelectionMode.rotate] + self.ui.statusbar.showMessage('Rotate mode') + self.clearSelection() + self.updateChecks() + else: + self.btnTranslateonClick() def btnScaleOnClick(self): - self.currentModeStack = [SelectionMode.scale] - self.ui.statusbar.showMessage('Scale mode') - self.clearSelection() - self.updateChecks() + if self.currentModeStack[-1] != SelectionMode.scale: + self.currentModeStack = [SelectionMode.scale] + self.ui.statusbar.showMessage('Scale mode') + self.clearSelection() + self.updateChecks() + else: + self.btnTranslateonClick() def btnPanOnClick(self): - self.currentModeStack = [SelectionMode.pan] - self.ui.statusbar.showMessage('Pan mode') - self.clearSelection() - self.updateChecks() + if self.currentModeStack[-1] != SelectionMode.pan: + self.currentModeStack = [SelectionMode.pan] + self.ui.statusbar.showMessage('Pan mode') + self.clearSelection() + self.updateChecks() + else: + self.btnTranslateonClick() def btnWorldCoordsOnClick(self, checked): self.useGlobalCoords = checked @@ -1754,24 +2221,26 @@ class MainWindow1(Qw.QMainWindow): self.quickUpdate() def btnLoadEditorOnClick(self): + pathToFile = os.path.splitext(self.fileName)[0]+'.asy' 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() - - subprocess.Popen(args=self.getExternalEditor(asypath=self.filename)); + self.actionExport(pathToFile) + + subprocess.run(args=self.getExternalEditor(asypath=pathToFile)); + self.loadFile(pathToFile) def btnAddCodeOnClick(self): header = """ -// xasy object created at $time +// xasy object created at $time // Object Number: $uid -// This header is automatically generated by xasy. +// 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') @@ -1791,6 +2260,7 @@ class MainWindow1(Qw.QMainWindow): self.asyfyCanvas() self.globalObjectCounter = self.globalObjectCounter + 1 + def softDeleteObj(self, objKey): maj, minor = objKey drawObj = self.drawObjects[maj][minor] @@ -1869,7 +2339,7 @@ class MainWindow1(Qw.QMainWindow): s = editor.split() rawExternalEditor = s[0] rawExtEditorArgs = s[1:]+["$asypath"] - + execEditor = [rawExternalEditor] for arg in rawExtEditorArgs: @@ -1881,34 +2351,37 @@ class MainWindow1(Qw.QMainWindow): def loadFile(self, name): filename = os.path.abspath(name) if not os.path.isfile(filename): - filename = filename + '.asy' + parts = os.path.splitext(filename) + if parts[1] == '': + filename = parts[0] + '.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.fileName = filename + self.asyFileName = filename + self.currDir = os.path.dirname(self.fileName) self.erase() - f = open(self.filename, 'rt') + 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) + rawText, transfDict = xf.extractTransformsFromFile(rawFileStr) item = x2a.xasyScript(canvas=self.xasyDrawObj, engine=self.asyEngine, transfKeyMap=transfDict) item.setScript(rawText) self.fileItems.append(item) - self.asyfyCanvas(True) + self.asyfyCanvas(force=True) - maxKey2 = item.getMaxKeyCounter() + self.globalObjectCounter = item.maxKey+1 self.asy2psmap = item.asy2psmap - self.globalObjectCounter = max(maxKey + 1, maxKey2) + finally: f.close() @@ -1916,3 +2389,37 @@ class MainWindow1(Qw.QMainWindow): self.itemCount = 0 for item in self.fileItems: self.drawObjects.append(item.generateDrawObjects(forceUpdate)) + + def makePenCosmetic(self, painter): + localPen = painter.pen() + localPen.setCosmetic(True) + painter.setPen(localPen) + + def copyItem(self): + self.selectOnHover() + if self.currentlySelectedObj['selectedIndex'] is not None: + maj, minor = self.currentlySelectedObj['selectedIndex'] + if isinstance(self.fileItems[maj],x2a.xasyShape) or isinstance(self.fileItems[maj],x2a.xasyText): + self.copiedObject = self.fileItems[maj].copy() + else: + self.ui.statusbar.showMessage('Copying not supported with current item type') + else: + self.ui.statusbar.showMessage('No object selected to copy') + self.copiedObject = None + self.clearSelection() + + def pasteItem(self): + if hasattr(self, 'copiedObject') and not self.copiedObject is None: + self.copiedObject = self.copiedObject.copy() + self.addInPlace(self.copiedObject) + mousePos = self.getWindowCoordinates() - self.copiedObject.path.toQPainterPath().boundingRect().center() - (Qc.QPointF(self.canvSize.width(), self.canvSize.height()) + Qc.QPointF(62, 201))/2 #I don't really know what that last constant is? Is it the size of the framing? + newTransform = Qg.QTransform.fromTranslate(mousePos.x(), mousePos.y()) + self.currentlySelectedObj['selectedIndex'] = (self.globalObjectCounter - 1,0) + self.currentlySelectedObj['key'], self.currentlySelectedObj['allSameKey'] = self.selectObjectSet() + newTransform = x2a.asyTransform.fromQTransform(newTransform) + objKey = self.currentlySelectedObj['selectedIndex'] + self.addTransformationChanges(objKey, newTransform, not self.useGlobalCoords) + self.transformObject(objKey, newTransform, not self.useGlobalCoords) + self.quickUpdate() + else: + self.ui.statusbar.showMessage('No object to paste') diff --git a/Master/texmf-dist/asymptote/GUI/configs/xasyconfig.cson b/Master/texmf-dist/asymptote/GUI/configs/xasyconfig.cson index c87f8c5b531..5f0c1abc17b 100644 --- a/Master/texmf-dist/asymptote/GUI/configs/xasyconfig.cson +++ b/Master/texmf-dist/asymptote/GUI/configs/xasyconfig.cson @@ -45,6 +45,9 @@ gridMinorAxesColor: "#dddddd" gridMajorAxesSpacing: 5 gridMinorAxesCount: 9 +# Number of pixels per bp in 3D rendered bitmaps +renderDensity: 2 + # Magnification Settings minimumMagnification: 0.01 maximumMagnification: 100 diff --git a/Master/texmf-dist/asymptote/GUI/configs/xasykeymap.cson b/Master/texmf-dist/asymptote/GUI/configs/xasykeymap.cson index 1e3e3b0a11e..867c08db7d9 100644 --- a/Master/texmf-dist/asymptote/GUI/configs/xasykeymap.cson +++ b/Master/texmf-dist/asymptote/GUI/configs/xasykeymap.cson @@ -23,4 +23,11 @@ scrollLeft: 'Shift+Left' scrollRight: 'Shift+Right' zoomIn: 'Ctrl+Up' -zoomOut: 'Ctrl+Down'
\ No newline at end of file +zoomOut: 'Ctrl+Down' + +open: 'Ctrl+O' +save: 'Ctrl+S' +export: 'Ctrl+E' + +copy: 'Ctrl+C' +paste: 'Ctrl+V' diff --git a/Master/texmf-dist/asymptote/GUI/icons_rc.py b/Master/texmf-dist/asymptote/GUI/icons_rc.py deleted file mode 100755 index e74ded8d750..00000000000 --- a/Master/texmf-dist/asymptote/GUI/icons_rc.py +++ /dev/null @@ -1,2721 +0,0 @@ -# -*- coding: utf-8 -*- - -# Resource object code -# -# Created by: The Resource Compiler for PyQt5 (Qt v5.12.5) -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore - -qt_resource_data = b"\ -\x00\x00\x04\xa2\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\ -\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x34\ -\x2e\x31\x35\x35\x35\x36\x20\x2d\x33\x39\x2e\x32\x37\x34\x35\x20\ -\x36\x2e\x39\x38\x34\x37\x33\x20\x2d\x34\x36\x2e\x31\x30\x34\x37\ -\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\ -\x39\x43\x20\x32\x37\x2e\x34\x34\x31\x31\x20\x2d\x36\x37\x2e\x37\ -\x32\x36\x39\x20\x35\x33\x2e\x33\x30\x32\x31\x20\x2d\x36\x31\x2e\ -\x35\x34\x30\x35\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\ -\x2e\x35\x30\x32\x32\x43\x20\x35\x37\x2e\x36\x32\x37\x20\x2d\x33\ -\x32\x2e\x36\x35\x31\x39\x20\x35\x30\x2e\x35\x38\x35\x36\x20\x2d\ -\x32\x33\x2e\x35\x36\x32\x31\x20\x34\x30\x2e\x36\x37\x39\x34\x20\ -\x2d\x32\x32\x2e\x35\x32\x38\x31\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\ -\x32\x2e\x35\x30\x39\x33\x37\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\x35\x38\x2e\x34\x36\ -\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\ -\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\ -\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\ -\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\ -\x27\x36\x2e\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\ -\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\ -\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\ -\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\ -\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\ -\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\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\x35\x38\x2e\ -\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\ -\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\ -\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\ -\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\ -\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\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\x35\ -\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\ -\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\ -\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\ -\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\ -\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\ -\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\ -\x3e\ -\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\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\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\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\x74\x72\x61\x6e\x73\x66\x6f\ -\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\ -\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\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\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\ -\x3e\x0d\x0a\ -\x00\x00\x01\x69\ -\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\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\x3e\x3c\x67\x20\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\ -\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\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\x67\ -\x3e\x3c\x2f\x73\x76\x67\x3e\x0a\ -\x00\x00\x03\x7c\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\ -\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\ -\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\ -\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\ -\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\ -\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\ -\x35\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\x34\x2e\x30\x31\x35\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\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\ -\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\ -\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x33\x32\x2e\x31\x32\x43\ -\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x34\x30\x2e\x34\x33\x35\ -\x33\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\x34\x37\x2e\x31\x37\ -\x36\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x31\x37\x36\ -\x32\x43\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x34\x37\x2e\x31\ -\x37\x36\x32\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x34\x30\x2e\ -\x34\x33\x35\x33\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x33\x32\ -\x2e\x31\x32\x43\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x32\x33\ -\x2e\x38\x30\x34\x37\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x31\ -\x37\x2e\x30\x36\x33\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x37\ -\x2e\x30\x36\x33\x37\x43\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\ -\x31\x37\x2e\x30\x36\x33\x37\x20\x34\x37\x2e\x31\x37\x36\x32\x20\ -\x2d\x32\x33\x2e\x38\x30\x34\x37\x20\x34\x37\x2e\x31\x37\x36\x32\ -\x20\x2d\x33\x32\x2e\x31\x32\x5a\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\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x00\x00\x02\x21\ -\x00\ -\x00\x07\xaf\x78\x9c\xdd\x55\x4d\x6f\x9c\x30\x10\xbd\xf7\x57\x4c\ -\xd5\x83\xdb\x03\xc6\xdf\x86\x28\x24\x52\x57\xea\x29\xbd\x25\x97\ -\xde\x68\xf0\x82\x9b\x5d\x58\x01\x5d\xb6\xff\xbe\x66\xd7\x60\x4a\ -\xaa\xf4\x92\x43\x15\x90\x30\xf3\x18\xbf\x99\xe7\xf1\x98\xeb\xdb\ -\xd3\x7e\x07\x47\xd3\x76\xb6\xa9\x33\x44\x31\x41\x60\xea\xc7\xa6\ -\xb0\x75\x99\xa1\x87\xfb\x2f\x51\x82\x6e\x6f\xde\x5d\xbf\x8f\x22\ -\xb8\xaf\x6c\x07\x5b\xbb\x33\x30\xe4\x1d\x94\xa6\x36\x6d\xde\x9b\ -\x02\xbe\xff\x82\xe2\x68\xbb\x63\xb9\x07\x86\x13\x88\x22\xe7\xef\ -\xac\x25\x2b\x45\xe0\xe2\xd4\x5d\x86\xaa\xbe\x3f\x5c\xc5\xf1\x30\ -\x0c\x78\xe0\xb8\x69\xcb\x98\x11\x42\x62\xe7\xef\x5d\xae\x4e\x3b\ -\x5b\x3f\xfd\xcd\x91\xa6\x69\x1a\x9f\xbf\x22\x18\x6c\xd1\x57\x19\ -\x52\x1c\x3b\x50\x1d\x7a\x04\x95\xb1\x65\xd5\x4f\x90\x1e\xa1\xa3\ -\x35\xc3\xe7\xe6\x94\x21\xa9\xb0\x20\xa9\x00\xc9\x71\x22\x13\x0e\ -\x7e\x9a\x1f\x35\x72\x09\x97\x60\x8b\x0c\x1d\xf2\xd2\xd0\x8b\xd9\ -\xb7\x79\xdd\x6d\x9b\x76\x9f\xa1\x7d\xde\xb7\xf6\xf4\x91\x38\x67\ -\xc5\x94\x00\x32\xde\x93\x31\x71\x53\xaa\x47\xf2\x4f\xe3\xec\x43\ -\xde\x57\xe0\xe8\xbe\x42\x8a\xb9\xd0\x82\x41\xc4\x38\x26\x94\xde\ -\x05\xc0\xbf\x3c\x47\x36\xcf\x90\x7f\x03\x8b\x39\x12\x53\x29\x29\ -\x05\x9a\x62\x29\x38\x85\x88\x62\x2d\x95\x54\xc0\x19\xa6\x6c\x36\ -\x37\x20\x04\x56\xa9\x4a\x83\x83\x14\x38\x49\x99\x0a\x14\x33\x30\ -\xe7\xfa\x02\x32\x09\x9c\x01\xae\xb0\xd2\x42\x6e\x02\x22\x08\x4e\ -\x94\x4a\x42\x64\xf7\xc2\x94\x14\x53\x6a\xde\xdc\x84\xdc\x27\x87\ -\x59\xdd\x44\x31\x03\x3e\xca\xdd\x7a\xa5\xbf\xa1\x71\xab\xee\x32\ -\xf4\x41\x6f\xc7\x1b\xc5\xae\x2e\x71\xf9\x8a\xa5\x0d\x42\x53\xac\ -\x29\x49\x97\x42\xdd\xbe\x22\x9c\x2d\x84\x6a\xcc\x09\xd5\xb3\xd0\ -\x8b\xb9\x14\xea\x1d\x82\x50\x4f\x11\x84\x4e\x51\x02\x22\xb1\xa4\ -\x89\x0c\x24\x17\x76\x1f\xe3\x3c\x2c\xaa\x7c\x81\x43\xd2\x7e\xf2\ -\x5a\xc5\xbc\x6e\x75\x53\x1b\x04\x5d\xdf\x36\x4f\xc6\xad\x22\x39\ -\x5f\x13\x10\xb9\x2e\x34\x8f\xf9\x21\x43\x6d\xf3\xb3\x2e\xfe\x80\ -\x7f\x34\xb6\x5e\xe3\x7b\xdb\x9b\x76\x67\xdd\xe0\x4e\x03\x82\x09\ -\xd7\x72\xfe\xe6\x5b\x99\xbb\x7c\x38\x65\xaf\x5f\xa7\xf5\x0a\xbe\ -\xe1\x1e\xf4\x0a\xdf\x5c\x09\x5f\x68\x35\xc9\x30\x4b\xf4\xe2\x4c\ -\x51\x0c\x8b\x84\xcf\x67\x8a\x37\x17\xad\x36\x39\x84\x6a\x79\x8a\ -\xf5\x46\xf9\x6f\x96\xf1\xf2\x70\xbf\xc8\x9b\xdf\xf9\x80\xe2\xe1\ -\ -\x00\x00\x04\x1c\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\ -\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\ -\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\ -\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\ -\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\ -\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\ -\x35\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\x34\x2e\x30\x31\x35\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\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\ -\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\ -\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\ -\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x33\x32\x2e\x31\x32\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\x34\x2e\x30\x31\x35\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\x35\ -\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\ -\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\x32\x2e\ -\x31\x32\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x33\x32\x2e\x31\ -\x32\x20\x2d\x36\x32\x2e\x32\x33\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\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\ -\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x00\x00\x02\xa1\ -\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\x35\x31\x32\x70\x78\x22\x20\ -\x79\x3d\x22\x35\x31\x32\x70\x78\x22\x0d\x0a\x09\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\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\ -\x69\x78\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\ -\x29\x27\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\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\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\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\x03\xf5\ -\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\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\x74\x72\x61\ -\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\ -\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\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\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\ -\x67\x3e\x0d\x0a\ -\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\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\x36\ -\x34\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x34\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\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\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\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\x05\xd4\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x35\ -\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\x43\ -\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x34\x33\x2e\x39\x30\x33\ -\x32\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x34\x37\x2e\x33\x30\ -\x31\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x33\x30\x31\ -\x37\x43\x20\x31\x39\x2e\x35\x34\x33\x31\x20\x2d\x34\x37\x2e\x33\ -\x30\x31\x37\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x34\x33\x2e\ -\x39\x30\x33\x32\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x33\x39\ -\x2e\x37\x31\x30\x39\x43\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\ -\x33\x35\x2e\x35\x31\x38\x35\x20\x31\x39\x2e\x35\x34\x33\x31\x20\ -\x2d\x33\x32\x2e\x31\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x33\x32\ -\x2e\x31\x32\x43\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x33\x32\ -\x2e\x31\x32\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x35\x2e\ -\x35\x31\x38\x35\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x39\ -\x2e\x37\x31\x30\x39\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\x33\x2e\ -\x35\x31\x33\x31\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\x35\x36\x2e\x34\x30\x39\x34\ -\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\ -\x68\x20\x64\x3d\x27\x4d\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\ -\x33\x39\x2e\x37\x31\x30\x39\x4c\x20\x39\x2e\x33\x34\x37\x34\x32\ -\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x4c\x20\x39\x2e\x33\x34\x37\ -\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x43\x20\x39\x2e\x33\ -\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x20\x39\x2e\ -\x33\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x20\x39\ -\x2e\x33\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x43\ -\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x35\x2e\x31\x35\x35\x31\ -\x31\x20\x31\x39\x2e\x35\x34\x33\x31\x20\x2d\x31\x2e\x37\x35\x36\ -\x35\x36\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x2e\x37\x35\x36\x35\ -\x36\x43\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x31\x2e\x37\x35\ -\x36\x35\x36\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x35\x2e\x31\ -\x35\x35\x31\x31\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x39\x2e\ -\x33\x34\x37\x34\x32\x4c\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\ -\x39\x2e\x33\x34\x37\x34\x32\x4c\x20\x35\x34\x2e\x38\x39\x32\x36\ -\x20\x2d\x33\x39\x2e\x37\x31\x30\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\x33\x2e\x35\x31\x33\x31\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\x35\x36\x2e\x34\ -\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\ -\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x35\x34\x2e\x38\x39\x32\ -\x36\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\x43\x20\x35\x34\x2e\x38\ -\x39\x32\x36\x20\x2d\x35\x32\x2e\x32\x38\x37\x38\x20\x34\x34\x2e\ -\x36\x39\x36\x39\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x20\x33\x32\ -\x2e\x31\x32\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x43\x20\x31\x39\ -\x2e\x35\x34\x33\x31\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x20\x39\ -\x2e\x33\x34\x37\x34\x32\x20\x2d\x35\x32\x2e\x32\x38\x37\x38\x20\ -\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x33\x39\x2e\x37\x31\x30\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\x33\x2e\x35\x31\x33\x31\x32\x27\ -\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\ -\x76\x67\x3e\ -\x00\x00\x03\xe6\ -\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\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\x74\x72\ -\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\ -\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\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\x67\x3e\x0d\x0a\x3c\x2f\x73\ -\x76\x67\x3e\x0d\x0a\ -\x00\x00\x01\x1c\ -\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\x35\x31\ -\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\ -\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\ -\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x0a\ -\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\ -\x74\x72\x69\x78\x28\x34\x38\x20\x30\x20\x30\x20\x34\x38\x20\x34\ -\x38\x20\x34\x38\x29\x27\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\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\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\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\xaa\ -\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\x32\x34\x70\x78\x22\x20\x79\ -\x3d\x22\x32\x34\x70\x78\x22\x0d\x0a\x09\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\x74\ -\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\ -\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\ -\x3e\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\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\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\x04\x4e\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\ -\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\ -\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\ -\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\ -\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\ -\x32\x38\x31\x4c\x20\x33\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\ -\x2e\x31\x32\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\x32\x2e\x35\x30\ -\x39\x33\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\ -\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\ -\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\ -\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\ -\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\ -\x32\x32\x35\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\ -\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\ -\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\ -\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\ -\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\ -\x2e\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\x36\x39\ -\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\ -\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\ -\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\ -\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\ -\x27\x36\x2e\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\ -\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\ -\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\ -\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\ -\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\ -\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\ -\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ -\x00\x00\x04\xd5\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\ -\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x32\ -\x2e\x32\x38\x39\x32\x32\x20\x2d\x33\x39\x2e\x33\x31\x31\x33\x20\ -\x36\x2e\x33\x36\x37\x30\x32\x20\x2d\x34\x36\x2e\x32\x33\x38\x36\ -\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\ -\x39\x43\x20\x32\x39\x2e\x36\x36\x38\x37\x20\x2d\x36\x37\x2e\x35\ -\x35\x36\x38\x20\x35\x35\x2e\x32\x32\x39\x32\x20\x2d\x36\x30\x2e\ -\x36\x34\x32\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\ -\x35\x30\x32\x32\x43\x20\x35\x36\x2e\x36\x31\x33\x36\x20\x2d\x33\ -\x33\x2e\x34\x33\x38\x31\x20\x34\x39\x2e\x31\x31\x33\x32\x20\x2d\ -\x32\x36\x2e\x35\x39\x35\x39\x20\x34\x30\x2e\x36\x37\x39\x34\x20\ -\x2d\x32\x32\x2e\x35\x32\x38\x31\x43\x20\x32\x35\x2e\x33\x39\x39\ -\x35\x20\x2d\x31\x35\x2e\x31\x35\x38\x32\x20\x37\x2e\x31\x39\x39\ -\x33\x35\x20\x2d\x31\x38\x2e\x31\x34\x33\x36\x20\x33\x2e\x39\x35\ -\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\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\x32\x2e\x35\x30\x39\x33\x37\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\x35\x38\ -\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\ -\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\ -\x35\x37\x33\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\ -\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\ -\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\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\x35\x38\ -\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\ -\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\ -\x39\x30\x33\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\ -\x33\x39\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\ -\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\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\ -\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\ -\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\ -\x36\x2e\x31\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\ -\x35\x30\x32\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\ -\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\ -\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\ -\x27\x34\x30\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\ -\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\ -\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\ -\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\ -\x73\x76\x67\x3e\ -\x00\x00\x02\xf2\ -\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\x35\x31\x32\x70\x78\ -\x22\x20\x79\x3d\x22\x35\x31\x32\x70\x78\x22\x0d\x0a\x09\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\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\ -\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\ -\x20\x30\x29\x27\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\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\ -\x0a\ -\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\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\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\x04\x3d\ -\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\ -\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\ -\x6f\x6e\x3d\x27\x31\x2e\x31\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\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\ -\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\ -\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\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\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\ -\x39\x39\x39\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\ -\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\ -\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\ -\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\ -\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\ -\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\ -\x32\x38\x31\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\x32\x2e\x35\x30\x39\ -\x33\x37\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\ -\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\ -\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\x79\ -\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\ -\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\ -\x32\x35\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\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\ -\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\ -\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\x79\ -\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\x6c\ -\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\ -\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\x36\x39\x20\ -\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\ -\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\x20\ -\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\x69\ -\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\ -\x36\x2e\x30\x32\x32\x35\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\x35\x38\x2e\x34\x36\x36\ -\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\ -\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\x34\ -\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\ -\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\ -\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\ -\x0a\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\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\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\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\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\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\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\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\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\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\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\ -" - -qt_resource_name = b"\ -\x00\x05\ -\x00\x6f\xa6\x53\ -\x00\x69\ -\x00\x63\x00\x6f\x00\x6e\x00\x73\ -\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\x09\ -\x0b\x9e\x89\x07\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\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\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\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\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\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\x08\ -\x08\xc8\x55\xe7\ -\x00\x73\ -\x00\x61\x00\x76\x00\x65\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\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\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\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\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\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\ -\x08\xf7\x57\x07\ -\x00\x67\ -\x00\x72\x00\x69\x00\x64\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\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\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\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\ -\x00\x08\ -\x0c\xf7\x55\x87\ -\x00\x74\ -\x00\x65\x00\x78\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\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\x08\ -\x05\xa8\x57\x87\ -\x00\x63\ -\x00\x6f\x00\x64\x00\x65\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\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\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\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\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\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\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\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\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\ -\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\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\ -\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\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\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\x08\ -\x0b\x07\x57\xa7\ -\x00\x65\ -\x00\x64\x00\x69\x00\x74\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\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\x07\ -\x0c\xf8\x5a\x07\ -\x00\x65\ -\x00\x79\x00\x65\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\x06\x10\x00\x00\x00\x00\x00\x01\x00\x00\x82\xd5\ -\x00\x00\x02\x96\x00\x00\x00\x00\x00\x01\x00\x00\x36\x4d\ -\x00\x00\x04\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x68\xdb\ -\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x33\x23\ -\x00\x00\x01\x96\x00\x00\x00\x00\x00\x01\x00\x00\x22\x76\ -\x00\x00\x00\xaa\x00\x01\x00\x00\x00\x01\x00\x00\x10\x6b\ -\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x45\x97\ -\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x54\x52\ -\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x48\xd1\ -\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x5c\ -\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x29\x2a\ -\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x29\ -\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x25\ -\x00\x00\x04\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x64\x9a\ -\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x73\xf7\ -\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf4\ -\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x50\ -\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x12\x90\ -\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x76\ -\x00\x00\x00\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x16\xb0\ -\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x77\xbd\ -\x00\x00\x02\x30\x00\x01\x00\x00\x00\x01\x00\x00\x2d\xf8\ -\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x2f\xd9\ -\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x2b\ -\x00\x00\x03\x70\x00\x00\x00\x00\x00\x01\x00\x00\x4d\x7f\ -\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xeb\ -\x00\x00\x05\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x3a\ -\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa6\ -\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x71\ -\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x41\x2f\ -\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x50\x00\ -\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x26\x6f\ -\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x40\x0f\ -\x00\x00\x06\x38\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x59\ -\x00\x00\x04\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x21\ -\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x7e\ -\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb6\ -\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x77\x4d\ -\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x19\x55\ -\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x7d\xaa\ -" - -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\x06\x10\x00\x00\x00\x00\x00\x01\x00\x00\x82\xd5\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x02\x96\x00\x00\x00\x00\x00\x01\x00\x00\x36\x4d\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x04\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x68\xdb\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x33\x23\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x01\x96\x00\x00\x00\x00\x00\x01\x00\x00\x22\x76\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x00\xaa\x00\x01\x00\x00\x00\x01\x00\x00\x10\x6b\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x45\x97\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x54\x52\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x48\xd1\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x5c\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x29\x2a\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x29\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x25\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x04\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x64\x9a\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x73\xf7\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf4\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x50\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x12\x90\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x76\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x00\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x16\xb0\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x77\xbd\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x02\x30\x00\x01\x00\x00\x00\x01\x00\x00\x2d\xf8\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x2f\xd9\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x2b\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x03\x70\x00\x00\x00\x00\x00\x01\x00\x00\x4d\x7f\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xeb\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x05\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x3a\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa6\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x71\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x41\x2f\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x50\x00\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x26\x6f\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x40\x0f\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x06\x38\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x59\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x04\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x21\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x7e\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb6\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x77\x4d\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x19\x55\ -\x00\x00\x01\x78\x33\x4a\x26\xbc\ -\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x7d\xaa\ -\x00\x00\x01\x78\x33\x4a\x26\xbb\ -" - -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/Master/texmf-dist/asymptote/GUI/labelEditor.py b/Master/texmf-dist/asymptote/GUI/labelEditor.py index 76bc8d7d0a1..7da1c5f9037 100755 --- a/Master/texmf-dist/asymptote/GUI/labelEditor.py +++ b/Master/texmf-dist/asymptote/GUI/labelEditor.py @@ -1,22 +1,22 @@ #!/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 PyQt5.QtWidgets as QtWidgets +import PyQt5.QtSvg as QtSvg +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import xasyArgs as xasyArgs +import xasy2asy as xasy2asy +import xasyOptions as xasyOptions +import xasyUtils as xasyUtils import subprocess -import xasyOptions as xo -import xasyUtils as xu import tempfile import uuid import os import io -class labelEditor(Qw.QDialog): +class labelEditor(QtWidgets.QDialog): def __init__(self, text=''): super().__init__() self.ui = Ui_Dialog() @@ -67,9 +67,9 @@ class labelEditor(Qw.QDialog): return rawText def btnPreviewOnClick(self): - path = xa.getArgs().asypath + path = xasyArgs.getArgs().asypath if path is None: - opt = xo.xasyOptions().load() + opt = xo.BasicConfigs.defaultOpt path = opt['asyPath'] asyInput = """ @@ -80,7 +80,7 @@ class labelEditor(Qw.QDialog): shipout(f); """ - self.svgPreview = Qs.QSvgRenderer() + self.svgPreview = QtSvg.QSvgRenderer() with tempfile.TemporaryDirectory(prefix='xasylbl_') as tmpdir: id = str(uuid.uuid4()) tmpFile = os.path.join(tmpdir, 'lbl-{0}.svg'.format(id)) @@ -95,8 +95,8 @@ class labelEditor(Qw.QDialog): 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)) + min_bounds = xasyUtils.listize(bounds_1, (float, float)) + max_bounds = xasyUtils.listize(bounds_2, (float, float)) new_rect = self.processBounds(min_bounds, max_bounds) self.svgPreview.load(tmpFile) @@ -106,12 +106,12 @@ class labelEditor(Qw.QDialog): self.drawPreview(new_rect) def drawPreview(self, naturalBounds): - img = Qg.QPixmap(self.ui.lblLabelPreview.size()) - img.fill(Qg.QColor.fromRgbF(1, 1, 1, 1)) + img = QtGui.QPixmap(self.ui.lblLabelPreview.size()) + img.fill(QtGui.QColor.fromRgbF(1, 1, 1, 1)) if self.svgPreview is None: pass else: - with Qg.QPainter(img) as pnt: + with QtGui.QPainter(img) as pnt: scale_ratio = self.getIdealScaleRatio(naturalBounds, self.ui.lblLabelPreview.rect()) pnt.translate(self.ui.lblLabelPreview.rect().center()) @@ -121,8 +121,8 @@ class labelEditor(Qw.QDialog): def getIdealScaleRatio(self, rect, boundsRect): - assert isinstance(rect, (Qc.QRect, Qc.QRectF)) - assert isinstance(rect, (Qc.QRect, Qc.QRectF)) + assert isinstance(rect, (QtCore.QRect, QtCore.QRectF)) + assert isinstance(rect, (QtCore.QRect, QtCore.QRectF)) magic_ratio = 0.50 idealRatioHeight = (magic_ratio * boundsRect.height()) / rect.height() @@ -139,15 +139,15 @@ class labelEditor(Qw.QDialog): p1x, p1y = minPt p2x, p2y = maxPt - minPt = Qc.QPointF(p1x, p1y) - maxPt = Qc.QPointF(p2x, p2y) + minPt = QtCore.QPointF(p1x, p1y) + maxPt = QtCore.QPointF(p2x, p2y) - newRect = Qc.QRectF(minPt, maxPt) + newRect = QtCore.QRectF(minPt, maxPt) return newRect def btnGetTextOnClick(self): - msgbox = Qw.QMessageBox() + msgbox = QtWidgets.QMessageBox() msgbox.setText('Text Preview:\n' + self.getText()) msgbox.setWindowTitle('Text preview') msgbox.show() diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/custMatTransform.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/custMatTransform.py index d0bddd46458..aeaf61f9a26 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/custMatTransform.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/custMatTransform.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/custMatTransform.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/labelTextEditor.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/labelTextEditor.py index 3cb24c9e2fe..fc35454c83e 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/labelTextEditor.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/labelTextEditor.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/labelTextEditor.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/setCustomAnchor.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/setCustomAnchor.py index 9b76e5d6d0e..ab0fc77c0b6 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/setCustomAnchor.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/setCustomAnchor.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/setCustomAnchor.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addLabel.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addLabel.py index 0412fc550d5..9b17990e6bc 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addLabel.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addLabel.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/widg_addLabel.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addPolyOpt.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addPolyOpt.py index 2c91681bce6..69cf2a4630c 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addPolyOpt.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_addPolyOpt.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/widg_addPolyOpt.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets @@ -31,11 +32,21 @@ class Ui_Form(object): self.chkInscribed = QtWidgets.QCheckBox(Form) self.chkInscribed.setObjectName("chkInscribed") self.horizontalLayout.addWidget(self.chkInscribed) + spacerItem = QtWidgets.QSpacerItem(19, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.label = QtWidgets.QLabel(Form) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) + self.label.setSizePolicy(sizePolicy) + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) 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) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem1) self.horizontalLayout_2.addLayout(self.horizontalLayout) self.retranslateUi(Form) @@ -45,5 +56,6 @@ class Ui_Form(object): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.chkInscribed.setText(_translate("Form", "Start at Vertex")) + self.label.setText(_translate("Form", "Sides: ")) self.txtSides.setToolTip(_translate("Form", "Number of Sides")) self.txtSides.setPlaceholderText(_translate("Form", "Sides")) diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_editBezier.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_editBezier.py index d39e49e4b98..4c2d90d7127 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_editBezier.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/widg_editBezier.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/widg_editBezier.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/widgetPointEditor.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/widgetPointEditor.py index a38790bdecd..0b4f5d94935 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/widgetPointEditor.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/widgetPointEditor.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/widgetPointEditor.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets diff --git a/Master/texmf-dist/asymptote/GUI/pyUIClass/window1.py b/Master/texmf-dist/asymptote/GUI/pyUIClass/window1.py index 6180d5fed3f..edf87b84c1a 100644 --- a/Master/texmf-dist/asymptote/GUI/pyUIClass/window1.py +++ b/Master/texmf-dist/asymptote/GUI/pyUIClass/window1.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'GUI/windows/window1.ui' # -# Created by: PyQt5 UI code generator 5.13.1 +# Created by: PyQt5 UI code generator 5.15.0 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets @@ -62,7 +63,7 @@ class Ui_MainWindow(object): 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) + icon.addPixmap(QtGui.QPixmap(":/icons/undo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnUndo.setIcon(icon) self.btnUndo.setIconSize(QtCore.QSize(16, 16)) self.btnUndo.setFlat(True) @@ -79,7 +80,7 @@ class Ui_MainWindow(object): 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) + icon1.addPixmap(QtGui.QPixmap(":/icons/redo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnRedo.setIcon(icon1) self.btnRedo.setIconSize(QtCore.QSize(16, 16)) self.btnRedo.setFlat(True) @@ -251,7 +252,7 @@ class Ui_MainWindow(object): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btnAlignX.sizePolicy().hasHeightForWidth()) self.btnAlignX.setSizePolicy(sizePolicy) - self.btnAlignX.setMaximumSize(QtCore.QSize(25, 25)) + self.btnAlignX.setMaximumSize(QtCore.QSize(32, 25)) self.btnAlignX.setBaseSize(QtCore.QSize(32, 32)) font = QtGui.QFont() font.setFamily("Roboto") @@ -269,9 +270,10 @@ class Ui_MainWindow(object): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btnAlignY.sizePolicy().hasHeightForWidth()) self.btnAlignY.setSizePolicy(sizePolicy) - self.btnAlignY.setMaximumSize(QtCore.QSize(25, 25)) + self.btnAlignY.setMaximumSize(QtCore.QSize(32, 25)) self.btnAlignY.setBaseSize(QtCore.QSize(32, 32)) font = QtGui.QFont() + font.setFamily("Roboto") font.setBold(True) font.setWeight(75) self.btnAlignY.setFont(font) @@ -295,6 +297,7 @@ class Ui_MainWindow(object): icon11.addPixmap(QtGui.QPixmap(":/icons/edit.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnSelectEdit.setIcon(icon11) self.btnSelectEdit.setIconSize(QtCore.QSize(16, 16)) + self.btnSelectEdit.setCheckable(True) self.btnSelectEdit.setFlat(True) self.btnSelectEdit.setObjectName("btnSelectEdit") self.horizontalLayout.addWidget(self.btnSelectEdit) @@ -312,7 +315,7 @@ class Ui_MainWindow(object): icon12.addPixmap(QtGui.QPixmap(":/icons/android-delete.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnDeleteMode.setIcon(icon12) self.btnDeleteMode.setIconSize(QtCore.QSize(16, 16)) - self.btnDeleteMode.setCheckable(False) + self.btnDeleteMode.setCheckable(True) self.btnDeleteMode.setFlat(True) self.btnDeleteMode.setObjectName("btnDeleteMode") self.horizontalLayout.addWidget(self.btnDeleteMode) @@ -646,6 +649,7 @@ class Ui_MainWindow(object): icon24.addPixmap(QtGui.QPixmap(":/icons/openpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnOpenPoly.setIcon(icon24) self.btnOpenPoly.setIconSize(QtCore.QSize(16, 16)) + self.btnOpenPoly.setCheckable(True) self.btnOpenPoly.setFlat(True) self.btnOpenPoly.setObjectName("btnOpenPoly") self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.btnOpenPoly) @@ -662,6 +666,7 @@ class Ui_MainWindow(object): icon25.addPixmap(QtGui.QPixmap(":/icons/closedpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnClosedPoly.setIcon(icon25) self.btnClosedPoly.setIconSize(QtCore.QSize(16, 16)) + self.btnClosedPoly.setCheckable(True) self.btnClosedPoly.setFlat(True) self.btnClosedPoly.setObjectName("btnClosedPoly") self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.btnClosedPoly) @@ -678,6 +683,7 @@ class Ui_MainWindow(object): icon26.addPixmap(QtGui.QPixmap(":/icons/opencurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnOpenCurve.setIcon(icon26) self.btnOpenCurve.setIconSize(QtCore.QSize(16, 16)) + self.btnOpenCurve.setCheckable(True) self.btnOpenCurve.setFlat(True) self.btnOpenCurve.setObjectName("btnOpenCurve") self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.btnOpenCurve) @@ -694,6 +700,7 @@ class Ui_MainWindow(object): icon27.addPixmap(QtGui.QPixmap(":/icons/closedcurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnClosedCurve.setIcon(icon27) self.btnClosedCurve.setIconSize(QtCore.QSize(16, 16)) + self.btnClosedCurve.setCheckable(True) self.btnClosedCurve.setFlat(True) self.btnClosedCurve.setObjectName("btnClosedCurve") self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.btnClosedCurve) @@ -710,6 +717,7 @@ class Ui_MainWindow(object): icon28.addPixmap(QtGui.QPixmap(":/icons/triangle-stroked-15.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnAddPoly.setIcon(icon28) self.btnAddPoly.setIconSize(QtCore.QSize(16, 16)) + self.btnAddPoly.setCheckable(True) self.btnAddPoly.setFlat(True) self.btnAddPoly.setObjectName("btnAddPoly") self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.btnAddPoly) @@ -726,6 +734,7 @@ class Ui_MainWindow(object): icon29.addPixmap(QtGui.QPixmap(":/icons/circle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnAddCircle.setIcon(icon29) self.btnAddCircle.setIconSize(QtCore.QSize(16, 16)) + self.btnAddCircle.setCheckable(True) self.btnAddCircle.setFlat(True) self.btnAddCircle.setObjectName("btnAddCircle") self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.btnAddCircle) @@ -742,9 +751,27 @@ class Ui_MainWindow(object): icon30.addPixmap(QtGui.QPixmap(":/icons/text.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.btnAddLabel.setIcon(icon30) self.btnAddLabel.setIconSize(QtCore.QSize(16, 16)) + self.btnAddLabel.setCheckable(True) self.btnAddLabel.setFlat(True) self.btnAddLabel.setObjectName("btnAddLabel") self.formLayout.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.btnAddLabel) + self.btnAddFreehand = QtWidgets.QPushButton(self.formFrame) + self.btnAddFreehand.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.btnAddFreehand.sizePolicy().hasHeightForWidth()) + self.btnAddFreehand.setSizePolicy(sizePolicy) + self.btnAddFreehand.setMaximumSize(QtCore.QSize(32, 32)) + self.btnAddFreehand.setText("") + icon31 = QtGui.QIcon() + icon31.addPixmap(QtGui.QPixmap(":/icons/brush.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.btnAddFreehand.setIcon(icon31) + self.btnAddFreehand.setIconSize(QtCore.QSize(16, 16)) + self.btnAddFreehand.setCheckable(True) + self.btnAddFreehand.setFlat(True) + self.btnAddFreehand.setObjectName("btnAddFreehand") + self.formLayout.setWidget(12, QtWidgets.QFormLayout.LabelRole, self.btnAddFreehand) self.horizontalLayout_7.addWidget(self.formFrame) self.imgFrame = QtWidgets.QFrame(self.mainWidget) self.imgFrame.setMinimumSize(QtCore.QSize(0, 6)) @@ -783,9 +810,9 @@ class Ui_MainWindow(object): 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) + icon32 = QtGui.QIcon() + icon32.addPixmap(QtGui.QPixmap(":/icons/social-python.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.btnTogglePython.setIcon(icon32) self.btnTogglePython.setIconSize(QtCore.QSize(16, 16)) self.btnTogglePython.setCheckable(True) self.btnTogglePython.setFlat(True) @@ -807,9 +834,9 @@ class Ui_MainWindow(object): 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) + icon33 = QtGui.QIcon() + icon33.addPixmap(QtGui.QPixmap(":/icons/subdirectory-left.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.btnEnterCommand.setIcon(icon33) self.btnEnterCommand.setIconSize(QtCore.QSize(16, 16)) self.btnEnterCommand.setFlat(True) self.btnEnterCommand.setObjectName("btnEnterCommand") @@ -820,10 +847,12 @@ class Ui_MainWindow(object): self.horizontalLayout_4.addWidget(self.mainWidget) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 29)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 26)) self.menubar.setObjectName("menubar") self.menuFIle = QtWidgets.QMenu(self.menubar) self.menuFIle.setObjectName("menuFIle") + self.menuOpenRecent = QtWidgets.QMenu(self.menuFIle) + self.menuOpenRecent.setObjectName("menuOpenRecent") self.menuEdit = QtWidgets.QMenu(self.menubar) self.menuEdit.setObjectName("menuEdit") self.menuOptions = QtWidgets.QMenu(self.menubar) @@ -869,9 +898,22 @@ class Ui_MainWindow(object): self.actionSave.setObjectName("actionSave") self.actionOpen = QtWidgets.QAction(MainWindow) self.actionOpen.setObjectName("actionOpen") + self.actionClearRecent = QtWidgets.QAction(MainWindow) + self.actionClearRecent.setObjectName("actionClearRecent") + self.actionNewFile = QtWidgets.QAction(MainWindow) + self.actionNewFile.setObjectName("actionNewFile") + self.actionExportToAsy = QtWidgets.QAction(MainWindow) + self.actionExportToAsy.setObjectName("actionExportToAsy") + self.actionKeymaps = QtWidgets.QAction(MainWindow) + self.actionKeymaps.setObjectName("actionKeymaps") + self.menuOpenRecent.addSeparator() + self.menuOpenRecent.addAction(self.actionClearRecent) + self.menuFIle.addAction(self.actionNewFile) self.menuFIle.addAction(self.actionOpen) + self.menuFIle.addAction(self.menuOpenRecent.menuAction()) self.menuFIle.addAction(self.actionSave) self.menuFIle.addAction(self.actionSaveAs) + self.menuFIle.addAction(self.actionExportToAsy) self.menuFIle.addAction(self.actionExportAsymptote) self.menuFIle.addSeparator() self.menuFIle.addAction(self.actionQuit) @@ -879,6 +921,7 @@ class Ui_MainWindow(object): self.menuEdit.addAction(self.actionRedo) self.menuEdit.addSeparator() self.menuOptions.addAction(self.actionSettings) + self.menuOptions.addAction(self.actionKeymaps) self.menuHelp.addAction(self.actionManual) self.menuHelp.addAction(self.actionAbout) self.menuTools.addAction(self.actionEnterCommand) @@ -941,7 +984,9 @@ class Ui_MainWindow(object): 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.btnAddFreehand.setToolTip(_translate("MainWindow", "<html><head/><body><p>Freehand</p></body></html>")) self.menuFIle.setTitle(_translate("MainWindow", "&File")) + self.menuOpenRecent.setTitle(_translate("MainWindow", "Open Recent")) self.menuEdit.setTitle(_translate("MainWindow", "&Edit")) self.menuOptions.setTitle(_translate("MainWindow", "Optio&ns")) self.menuHelp.setTitle(_translate("MainWindow", "&Help")) @@ -950,7 +995,7 @@ class Ui_MainWindow(object): 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.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")) @@ -958,7 +1003,11 @@ class Ui_MainWindow(object): 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.actionExportAsymptote.setText(_translate("MainWindow", "Export as...")) self.actionSave.setText(_translate("MainWindow", "Save")) self.actionOpen.setText(_translate("MainWindow", "Open")) + self.actionClearRecent.setText(_translate("MainWindow", "Clear Menu")) + self.actionNewFile.setText(_translate("MainWindow", "New File")) + self.actionExportToAsy.setText(_translate("MainWindow", "Export as Asy")) + self.actionKeymaps.setText(_translate("MainWindow", "&Keymaps")) import icons_rc diff --git a/Master/texmf-dist/asymptote/GUI/res/icons.qrc b/Master/texmf-dist/asymptote/GUI/res/icons.qrc index 50928ef9b74..5ca468acc2a 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons.qrc +++ b/Master/texmf-dist/asymptote/GUI/res/icons.qrc @@ -41,5 +41,8 @@ <file>icons/android-radio-button-off.svg</file> <file>icons/android-locate.svg</file> <file>icons/close-round.svg</file> + <file>icons/brush.svg</file> + <file>icons/undo.svg</file> + <file>icons/redo.svg</file> </qresource> </RCC> diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/brush.svg b/Master/texmf-dist/asymptote/GUI/res/icons/brush.svg new file mode 100644 index 00000000000..0c6a54340bd --- /dev/null +++ b/Master/texmf-dist/asymptote/GUI/res/icons/brush.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.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="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="M48.451,464.828c40.023-0.315,45.01-9.955,58.052-50.132c24.057-63.408,132.419,16.591,65.269,44.374
+ C104.622,486.852,8.428,465.143,48.451,464.828z"/>
+ <path d="M458.857,46.902c-19.417-15.647-51.592-7.938-71.864,17.219L181.645,355.849c-20.272,25.154-20.171,20.347-0.754,35.992
+ c19.417,15.648,14.738,16.77,35.011-8.388l241.406-262.669C477.581,95.628,478.275,62.55,458.857,46.902z M406.065,81.825
+ c0,0-3-3.5-13-11.5c15-24.5,44.5-20,44.5-20C409.565,66.825,406.065,81.825,406.065,81.825z"/>
+</g>
+</svg>
diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/bucket.svg b/Master/texmf-dist/asymptote/GUI/res/icons/bucket.svg index 4a41e9873b2..11a867ac9ff 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/bucket.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/bucket.svg @@ -1,15 +1,15 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 54.8926 -39.7109C 54.8926 -43.9032 44.6969 -47.3017 32.12 -47.3017C 19.5431 -47.3017 9.34742 -43.9032 9.34742 -39.7109C 9.34742 -35.5185 19.5431 -32.12 32.12 -32.12C 44.6969 -32.12 54.8926 -35.5185 54.8926 -39.7109Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 54.8926 24.5291C 54.8926 20.3368 44.6969 16.9383 32.12 16.9383C 19.5431 16.9383 9.34742 20.3368 9.34742 24.5291C 9.34742 28.7215 19.5431 32.12 32.12 32.12C 44.6969 32.12 54.8926 28.7215 54.8926 24.5291Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 9.34742 -39.7109L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 9.34742 24.5291L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 54.8926 -39.7109C 54.8926 -52.2878 44.6969 -62.4834 32.12 -62.4834C 19.5431 -62.4834 9.34742 -52.2878 9.34742 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 54.8926 24.5291C 54.8926 11.9522 44.6969 1.75656 32.12 1.75656C 19.5431 1.75656 9.34742 11.9522 9.34742 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/center.svg b/Master/texmf-dist/asymptote/GUI/res/icons/center.svg index 9a7cb1b17d7..6c378d1e7e7 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/center.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/center.svg @@ -1,12 +1,12 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 2.0075 -2.0075L 62.2325 -2.0075L 62.2325 -62.2325L 2.0075 -62.2325L 2.0075 -2.0075Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 2.0075 62.2325L 62.2325 62.2325L 62.2325 2.0075L 2.0075 2.0075L 2.0075 62.2325Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 47.1762 -32.12C 47.1762 -40.4353 40.4353 -47.1762 32.12 -47.1762C 23.8047 -47.1762 17.0637 -40.4353 17.0637 -32.12C 17.0637 -23.8047 23.8047 -17.0637 32.12 -17.0637C 40.4353 -17.0637 47.1762 -23.8047 47.1762 -32.12Z' fill='#000000'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 47.1762 32.12C 47.1762 23.8047 40.4353 17.0637 32.12 17.0637C 23.8047 17.0637 17.0637 23.8047 17.0637 32.12C 17.0637 40.4353 23.8047 47.1762 32.12 47.1762C 40.4353 47.1762 47.1762 40.4353 47.1762 32.12Z' fill='#000000'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/centerorigin.svg b/Master/texmf-dist/asymptote/GUI/res/icons/centerorigin.svg index ee3cca26293..cce97c373b2 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/centerorigin.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/centerorigin.svg @@ -1,15 +1,15 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 2.0075 -2.0075L 62.2325 -2.0075L 62.2325 -62.2325L 2.0075 -62.2325L 2.0075 -2.0075Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 2.0075 62.2325L 62.2325 62.2325L 62.2325 2.0075L 2.0075 2.0075L 2.0075 62.2325Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 2.0075 -32.12L 62.2325 -32.12' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 2.0075 32.12L 62.2325 32.12' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 32.12 -2.0075L 32.12 -62.2325' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 32.12 62.2325L 32.12 2.0075' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/closedcurve.svg b/Master/texmf-dist/asymptote/GUI/res/icons/closedcurve.svg index 32cf982cf1c..33de78fc383 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/closedcurve.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/closedcurve.svg @@ -1,21 +1,21 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<path d='M 3.95735 -32.12C 2.28922 -39.3113 6.36702 -46.2386 11.9036 -51.3039C 29.6687 -67.5568 55.2292 -60.642 56.1523 -42.5022C 56.6136 -33.4381 49.1132 -26.5959 40.6794 -22.5281C 25.3995 -15.1582 7.19935 -18.1436 3.95735 -32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<path d='M 6.0225 32.12C 4.35438 24.9287 8.43217 18.0014 13.9687 12.9361C 31.7339 -3.31675 57.2943 3.59797 58.2175 21.7378C 58.6788 30.8019 51.1783 37.6441 42.7445 41.7119C 27.4646 49.0818 9.26451 46.0964 6.0225 32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/closedpolygon.svg b/Master/texmf-dist/asymptote/GUI/res/icons/closedpolygon.svg index 89e2c5f2303..ce6960bb841 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/closedpolygon.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/closedpolygon.svg @@ -1,21 +1,21 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<path d='M 3.95735 -32.12L 11.9036 -51.3039L 56.1523 -42.5022L 40.6794 -22.5281L 3.95735 -32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<path d='M 6.0225 32.12L 13.9687 12.9361L 58.2175 21.7378L 42.7445 41.7119L 6.0225 32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/filledbucket.svg b/Master/texmf-dist/asymptote/GUI/res/icons/filledbucket.svg index d2197375b9f..b6b279840fc 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/filledbucket.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/filledbucket.svg @@ -1,18 +1,18 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 9.34742 -23.011L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -23.011L 54.8926 -36.6745C 54.8926 -40.8668 44.6969 -44.2654 32.12 -44.2654C 19.5431 -44.2654 9.34742 -40.8668 9.34742 -36.6745L 9.34742 -23.011Z' fill='#7f7f7f'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 9.34742 42.7472L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 42.7472L 54.8926 30.6018C 54.8926 26.4095 44.6969 23.011 32.12 23.011C 19.5431 23.011 9.34742 26.4095 9.34742 30.6018L 9.34742 42.7472Z' fill='#bfbfff'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 54.8926 -39.7109C 54.8926 -43.9032 44.6969 -47.3017 32.12 -47.3017C 19.5431 -47.3017 9.34742 -43.9032 9.34742 -39.7109C 9.34742 -35.5185 19.5431 -32.12 32.12 -32.12C 44.6969 -32.12 54.8926 -35.5185 54.8926 -39.7109Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 54.8926 24.5291C 54.8926 20.3368 44.6969 16.9383 32.12 16.9383C 19.5431 16.9383 9.34742 20.3368 9.34742 24.5291C 9.34742 28.7215 19.5431 32.12 32.12 32.12C 44.6969 32.12 54.8926 28.7215 54.8926 24.5291Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 9.34742 -39.7109L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 9.34742 24.5291L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'> -<path d='M 54.8926 -39.7109C 54.8926 -52.2878 44.6969 -62.4834 32.12 -62.4834C 19.5431 -62.4834 9.34742 -52.2878 9.34742 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> +<g transform='translate(56.4094 117.858)scale(.996264)'> +<path d='M 54.8926 24.5291C 54.8926 11.9522 44.6969 1.75656 32.12 1.75656C 19.5431 1.75656 9.34742 11.9522 9.34742 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/opencurve.svg b/Master/texmf-dist/asymptote/GUI/res/icons/opencurve.svg index 3c02ba29060..16151d7e980 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/opencurve.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/opencurve.svg @@ -1,21 +1,21 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<path d='M 3.95735 -32.12C 4.15556 -39.2745 6.98473 -46.1047 11.9036 -51.3039C 27.4411 -67.7269 53.3021 -61.5405 56.1523 -42.5022C 57.627 -32.6519 50.5856 -23.5621 40.6794 -22.5281' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<path d='M 6.0225 32.12C 6.22072 24.9655 9.04989 18.1353 13.9687 12.9361C 29.5062 -3.48686 55.3673 2.6995 58.2175 21.7378C 59.6922 31.5881 52.6508 40.6779 42.7445 41.7119' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/openpolygon.svg b/Master/texmf-dist/asymptote/GUI/res/icons/openpolygon.svg index 5386aa64332..eb38eef8c1d 100644 --- a/Master/texmf-dist/asymptote/GUI/res/icons/openpolygon.svg +++ b/Master/texmf-dist/asymptote/GUI/res/icons/openpolygon.svg @@ -1,21 +1,21 @@ <?xml version='1.0' encoding='UTF-8'?> -<!-- This file was generated by dvisvgm 2.8 --> -<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'> +<!-- This file was generated by dvisvgm 2.11.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'> <g id='page1'> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<path d='M 3.95735 -32.12L 11.9036 -51.3039L 56.1523 -42.5022L 40.6794 -22.5281' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<path d='M 6.0225 32.12L 13.9687 12.9361L 58.2175 21.7378L 42.7445 41.7119' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/> </g> -<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'> -<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/> +<g transform='translate(58.4669 117.858)scale(.996264)'> +<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/> </g> </g> </svg>
\ No newline at end of file diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/redo.svg b/Master/texmf-dist/asymptote/GUI/res/icons/redo.svg new file mode 100644 index 00000000000..a8647d7a3c1 --- /dev/null +++ b/Master/texmf-dist/asymptote/GUI/res/icons/redo.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<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"
+ viewBox="0 0 423.754 423.754" style="enable-background:new 0 0 423.754 423.754;" xml:space="preserve">
+<path d="M407.516,123.239l-27.717,11.48c18.585,44.869,18.585,94.291,0,139.159c-18.585,44.869-53.531,79.815-98.4,98.4
+ c-22.438,9.293-46.004,13.94-69.579,13.939c-23.569-0.001-47.147-4.647-69.579-13.939c-44.869-18.585-79.815-53.531-98.4-98.4
+ C13.507,200.647,34.758,118.71,90.758,68.644l60.801,60.801V7.521H29.635L69.514,47.4C5.222,105.826-18.985,200.6,16.123,285.359
+ c21.652,52.272,62.364,92.984,114.636,114.636c26.137,10.826,53.599,16.239,81.061,16.239s54.924-5.413,81.06-16.239
+ c52.272-21.652,92.984-62.364,114.637-114.636C429.167,233.087,429.167,175.511,407.516,123.239z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/Master/texmf-dist/asymptote/GUI/res/icons/undo.svg b/Master/texmf-dist/asymptote/GUI/res/icons/undo.svg new file mode 100644 index 00000000000..76a7f0d32c8 --- /dev/null +++ b/Master/texmf-dist/asymptote/GUI/res/icons/undo.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<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"
+ viewBox="0 0 423.754 423.754" style="enable-background:new 0 0 423.754 423.754;" xml:space="preserve">
+<path d="M354.24,47.4l39.879-39.879H272.196v121.924l60.801-60.801c56,50.066,77.251,132.004,46.918,205.235
+ c-18.585,44.869-53.531,79.815-98.4,98.4c-44.866,18.585-94.288,18.585-139.158,0c-44.869-18.585-79.815-53.531-98.4-98.4
+ c-18.585-44.869-18.585-94.29,0-139.159l-27.717-11.48c-21.651,52.272-21.651,109.848,0,162.12
+ c21.652,52.272,62.364,92.984,114.637,114.636c26.14,10.827,53.595,16.24,81.06,16.239c27.459-0.001,54.927-5.414,81.061-16.239
+ c52.271-21.652,92.983-62.364,114.636-114.636C442.739,200.6,418.532,105.826,354.24,47.4z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/Master/texmf-dist/asymptote/GUI/setup.py b/Master/texmf-dist/asymptote/GUI/setup.py index e49e3468d7f..a1b25d809a7 100755 --- a/Master/texmf-dist/asymptote/GUI/setup.py +++ b/Master/texmf-dist/asymptote/GUI/setup.py @@ -7,7 +7,7 @@ setup( name="xasy", version=xasyVersion.xasyVersion, author="Supakorn Rassameemasmuang, Orest Shardt, and John C. Bowman", - description="User interface for Asymptote, a vector graphics language", + description="User interface for Asymptote, a vector graphics language", url="https://asymptote.sourceforge.io", download_url="https://sourceforge.net/projects/asymptote/" ) diff --git a/Master/texmf-dist/asymptote/GUI/xasy.py b/Master/texmf-dist/asymptote/GUI/xasy.py index 7a8ee9b2f71..a078690b68b 100755 --- a/Master/texmf-dist/asymptote/GUI/xasy.py +++ b/Master/texmf-dist/asymptote/GUI/xasy.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 -import sys,signal,os -import PyQt5.QtWidgets as Qw -import PyQt5.QtCore as Qc +import sys, signal, os +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtCore as QtCore from Window1 import MainWindow1 def main(args): - Qw.QApplication.setAttribute(Qc.Qt.AA_UseHighDpiPixmaps,True) - Qw.QApplication.setAttribute(Qc.Qt.AA_EnableHighDpiScaling,True) - qtApp = Qw.QApplication(args) + os.environ["QT_LOGGING_RULES"]="*.debug=false;qt.qpa.*=false" + QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps,True) + QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling,True) + qtApp = QtWidgets.QApplication(args) signal.signal(signal.SIGINT,signal.SIG_DFL) mainWin1 = MainWindow1() mainWin1.show() diff --git a/Master/texmf-dist/asymptote/GUI/xasy2asy.py b/Master/texmf-dist/asymptote/GUI/xasy2asy.py index 12bccb453cf..1829ce436ba 100755 --- a/Master/texmf-dist/asymptote/GUI/xasy2asy.py +++ b/Master/texmf-dist/asymptote/GUI/xasy2asy.py @@ -9,12 +9,12 @@ # ########################################################################### -import PyQt5.QtWidgets as Qw -import PyQt5.QtGui as Qg -import PyQt5.QtCore as Qc -import PyQt5.QtSvg as Qs +import PyQt5.QtWidgets as QtWidgets +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import PyQt5.QtSvg as QtSvg -import numpy as np +import numpy as numpy import sys import os @@ -37,8 +37,39 @@ import xasyOptions as xo import xasySvg as xs class AsymptoteEngine: - xasy=chr(4)+"\n" - + """ + Purpose: + -------- + Class that makes it possible for xasy to communicate with asy + through a background pipe. It communicates with asy through a + subprocess of an existing xasy process. + + Attributes: + ----------- + istream : input stream + ostream : output stream + keepFiles : keep communicated files + tmpdir : temporary directory + args : system call arguments to start a required subprocess + asyPath : directory path to asymptote + asyProcess : the subprocess through which xasy communicates with asy + + Virtual Methods: NULL + ---------------- + Static Methods: + --------------- NULL + Class Methods: + -------------- NULL + + Object Methods: + --------------- + start() + wait() + stop() + cleanup() + """ + + xasy=chr(4)+'\n' def __init__(self, path=None, keepFiles=DebugFlags.keepFiles, keepDefaultArgs=True): if path is None: path = xa.getArgs().asypath @@ -59,19 +90,29 @@ class AsymptoteEngine: 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] + if xa.getArgs().render: + renderDensity=xa.getArgs().render + else: + try: + renderDensity = xo.BasicConfigs.defaultOpt['renderDensity'] + except: + renderDensity = 2 + renderDensity=max(renderDensity,1) + + self.args=['-xasy', '-noV', '-q', '-outformat=', '-inpipe=' + str(rx), '-outpipe=' + str(wa), '-render='+str(renderDensity), '-o', self.tmpdir] self.asyPath = path self.asyProcess = None def start(self): + """ starts a subprocess (opens a pipe) """ try: if sys.platform[:3] == 'win': self.asyProcess = subprocess.Popen([self.asyPath] + self.args, @@ -85,6 +126,7 @@ class AsymptoteEngine: atexit.register(self.cleanup) def wait(self): + """ wait for the pipe to finish any outstanding communication """ if self.asyProcess.returncode is not None: return else: @@ -114,10 +156,12 @@ class AsymptoteEngine: return self.asyProcess.returncode is None def stop(self): + """ kill an active asyProcess and close the pipe """ if self.active: self.asyProcess.kill() def cleanup(self): + """ terminate processes and cleans up communication files """ self.stop() if self.asyProcess is not None: self.asyProcess.wait() @@ -125,11 +169,46 @@ class AsymptoteEngine: 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""" +class asyTransform(QtCore.QObject): + """ + Purpose: + -------- + A python implementation of an asy transform. This class takes care of calibrating asymptote + coordinate system with the one used in PyQt to handle all existing inconsistencies. + To understand how this class works, having enough acquaintance with asymptote transform + feature is required. It is a child class of QtCore.QObject class. + + Attributes: + ----------- + t : The tuple + x, y, xx, xy, yx, yy : Coordinates corresponding to 6 entries + _deleted : Private local flag + + Virtual Methods: NULL + ---------------- + Static Methods: NULL + --------------- + + Class Methods: + -------------- + zero : Class method that returns an asyTransform object initialized with 6 zero entries + fromQTransform : Class method that converts QTransform object to asyTransform object + fromNumpyMatrix : Class method that converts transform matrix object to asyTransform object + + Object Methods: + -------------- + getRawCode : Returns the tuple entries + getCode : Returns the textual format of the asy code corresponding to the given transform + scale : Returns the scales version of the existing asyTransform + toQTransform : Converts asy transform object to QTransform object + identity : Return Identity asyTransform object + isIdentity : Check whether the asyTransform object is identity object + inverted : Applies the QTransform object's inverted method on the asyTransform object + yflip : Returns y-flipped asyTransform object + """ def __init__(self, initTuple, delete=False): - """Initialize the transform with a 6 entry tuple""" + """ Initialize the transform with a 6 entry tuple """ super().__init__() if isinstance(initTuple, (tuple, list)) and len(initTuple) == 6: self.t = initTuple @@ -151,14 +230,14 @@ class asyTransform(Qc.QObject): return asyTransform((0, 0, 0, 0, 0, 0)) @classmethod - def fromQTransform(cls, transform: Qg.QTransform): + def fromQTransform(cls, transform: QtGui.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): + def fromNumpyMatrix(cls, transform: numpy.ndarray): assert transform.shape == (3, 3) tx = transform[0, 2] @@ -171,8 +250,8 @@ class asyTransform(Qc.QObject): def getRawCode(self): return xu.tuple2StrWOspaces(self.t) - def getCode(self, asy2psmap=None): - """Obtain the asy code that represents this transform""" + 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: @@ -184,10 +263,10 @@ class asyTransform(Qc.QObject): 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) + return QtGui.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.""" + """ Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful """ return self.getCode() def isIdentity(self): @@ -200,7 +279,7 @@ class asyTransform(Qc.QObject): return list(self.t) == list(other.t) def __mul__(self, other): - """Define multiplication of transforms as composition.""" + """ Define multiplication of transforms as composition """ if isinstance(other, tuple): if len(other) == 6: return self * asyTransform(other) @@ -234,25 +313,88 @@ def identity(): 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.""" +class asyObj(QtCore.QObject): + """ + Purpose: + -------- + A base class to create a Python object which contains all common + data and behaviors required during the translation of an xasy + object to its Asymptote code. + + Attributes: + ----------- + asyCode :The corresponding Asymptote code for the asyObj instance + + Virtual Methods: + ---------------- + updateCode :Must to be re-implemented + + Static Methods: NULL + -------------- + Class Methods: NULL + -------------- + + Object Methods: + --------------- + getCode :Return the Asymptote code that corresponds to the passed object + + """ + def __init__(self): - """Initialize the object""" + """ Initialize the object """ super().__init__() self.asyCode = '' - def updateCode(self, ps2asymap=identity()): - """Update the object's code: should be overriden.""" + def updateCode(self, ps2asymap = identity()): + """ Update the object's code: should be overridden """ raise NotImplementedError - def getCode(self, ps2asymap=identity()): - """Return the code describing the object""" + 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""" + """ + Purpose: + -------- + A Python object that corresponds to an Asymptote pen type. It + extends the 'asyObj' class to include a pen object. This object + will be used to make the corresponding Asymptote pen when + an xasy object gets translated to Asymptote code. + + Attributes: + ----------- + color : The color of Path + options : The options that can be passed to the path + width : The path width + _asyengine : The Asymptote engine that will be used + _deferAsyfy : ? + + Virtual Methods: NULL + ---------------- + Static Methods: + --------------- + getColorFromQColor : + convertToQColor : + + Class Methods: + -------------- + fromAsyPen : + + Object Methods: + --------------- + asyEngine : + updateCode : + setWidth : + setColor : + setColorFromQColor : + computeColor : + tkColor : + toQPen : + """ + @staticmethod def getColorFromQColor(color): return color.redF(), color.greenF(), color.blueF() @@ -260,15 +402,16 @@ class asyPen(asyObj): @staticmethod def convertToQColor(color): r, g, b = color - return Qg.QColor.fromRgbF(r, g, b) + return QtGui.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) + 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""" + 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 @@ -288,8 +431,8 @@ class asyPen(asyObj): def asyEngine(self, value): self._asyengine = value - def updateCode(self, asy2psmap=identity()): - """Generate the pen's code""" + 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)) @@ -297,12 +440,12 @@ class asyPen(asyObj): self.asyCode = self.asyCode + '+' + self.options def setWidth(self, newWidth): - """Set the pen's width""" + """ Set the pen's width """ self.width = newWidth self.updateCode() def setColor(self, color): - """Set the pen's color""" + """ Set the pen's color """ if isinstance(color, tuple) and len(color) == 3: self.color = color else: @@ -313,13 +456,12 @@ class asyPen(asyObj): self.setColor(asyPen.getColorFromQColor(color)) def computeColor(self): - """Find out the color of an arbitrary asymptote pen.""" + """ 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") @@ -347,15 +489,10 @@ class asyPen(asyObj): 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 = QtGui.QPen() newPen.setColor(asyPen.convertToQColor(self.color)) newPen.setWidthF(self.width) @@ -363,10 +500,34 @@ class asyPen(asyObj): class asyPath(asyObj): - """A python wrapper for an asymptote path""" + """ + Purpose: + -------- + A Python object that corresponds to an Asymptote path type. It + extends the 'asyObj' class to include a path object. This object + will be used to make the corresponding Asymptote path object when + an xasy object gets translated to its Asymptote code. + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + 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.""" + """ Initialize the path to be an empty path: a path with no nodes, control points, or links """ super().__init__() self.nodeSet = [] self.linkSet = [] @@ -374,12 +535,14 @@ class asyPath(asyObj): self.controlSet = [] self.computed = False self.asyengine = asyengine + self.fill = False @classmethod def fromPath(cls, oldPath): newObj = asyPath(None) newObj.nodeSet = copy.copy(oldPath.nodeSet) newObj.linkSet = copy.copy(oldPath.linkSet) + newObj.fill = copy.copy(oldPath.fill) newObj.controlSet = copy.deepcopy(oldPath.controlSet) newObj.computed = oldPath.computed newObj.asyengine = oldPath.asyengine @@ -406,6 +569,7 @@ class asyPath(asyObj): def setInfo(self, path): self.nodeSet = copy.copy(path.nodeSet) self.linkSet = copy.copy(path.linkSet) + self.fill = copy.copy(path.fill) self.controlSet = copy.deepcopy(path.controlSet) self.computed = path.computed @@ -417,12 +581,12 @@ class asyPath(asyObj): def isDrawable(self): return len(self.nodeSet) >= 2 - def toQPainterPath(self) -> Qg.QPainterPath: + def toQPainterPath(self) -> QtGui.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)) + painterPath = QtGui.QPainterPath(QtCore.QPointF(baseX, baseY)) for pointIndex in range(1, len(self.nodeSet)): node = self.nodeSet[pointIndex] @@ -439,43 +603,43 @@ class asyPath(asyObj): self.computeControls() baseX, baseY = self.nodeSet[0] - painterPath = Qg.QPainterPath(Qc.QPointF(baseX, baseY)) + painterPath = QtGui.QPainterPath(QtCore.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]) + endPoint = QtCore.QPointF(node[0], node[1]) + ctrlPoint1 = QtCore.QPointF(self.controlSet[pointIndex-1][0][0], self.controlSet[pointIndex-1][0][1]) + ctrlPoint2 = QtCore.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 "::" """ + """ 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""" + """ 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""" + """ 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... + # 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""" + """ Generate the code describing the path """ # currently at postscript. Convert to asy asy2psmap = ps2asymap.inverted() with io.StringIO() as rawAsyCode: @@ -499,28 +663,28 @@ class asyPath(asyObj): return '..' in self.linkSet or self.forceCurve def getNode(self, index): - """Return the requested node""" + """ Return the requested node """ return self.nodeSet[index] def getLink(self, index): - """Return the requested link""" + """ Return the requested link """ return self.linkSet[index] def setNode(self, index, newNode): - """Set a node to a new position""" + """ Set a node to a new position """ self.nodeSet[index] = newNode def moveNode(self, index, offset): - """Translate a node""" + """ 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""" + """ Change the specified link """ self.linkSet[index] = ltype def addNode(self, point, ltype): - """Add a node to the end of a path""" + """ Add a node to the end of a path """ self.nodeSet.append(point) if len(self.nodeSet) != 1: self.linkSet.append(ltype) @@ -528,14 +692,14 @@ class asyPath(asyObj): self.computeControls() def insertNode(self, index, point, ltype=".."): - """Insert a node, and its corresponding link, at the given index""" + """ 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""" + """ Set a control point to a new position """ self.controlSet[index] = position def popNode(self): @@ -545,11 +709,11 @@ class asyPath(asyObj): self.linkSet.pop() def moveControl(self, index, offset): - """Translate a control point""" + """ 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""" + """ 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: @@ -595,9 +759,33 @@ class asyPath(asyObj): asy.stop() class asyLabel(asyObj): - """A python wrapper for an asy label""" + """ + Purpose: + -------- + A Python object that corresponds to an asymptote label + type. It extends the 'asyObj' class to include a label + object. This object will be used to make the corresponding + Asymptote label object when an xasy object gets translated to its + asymptote code. + + Attributes: + ----------- + + Virtual Methods: + ---------------- - def __init__(self, text="", location=(0, 0), pen=None, align=None, fontSize:int=None): + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + 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 @@ -610,8 +798,8 @@ class asyLabel(asyObj): self.text = text self.location = location - def updateCode(self, asy2psmap=identity()): - """Generate the code describing the label""" + 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, @@ -624,22 +812,45 @@ class asyLabel(asyObj): return '' def setText(self, text): - """Set the label's text""" + """ Set the label's text """ self.text = text self.updateCode() def setPen(self, pen): - """Set the label's pen""" + """ Set the label's pen """ self.pen = pen self.updateCode() def moveTo(self, newl): - """Translate the label's location""" + """ Translate the label's location """ self.location = newl class asyImage: - """A structure containing an image and its format, bbox, and IDTag""" + """ + Purpose: + -------- + A Python object that is a container for an image coming from + Asymptote that is populated with the format, bounding box, and + IDTag, Asymptote key. + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + def __init__(self, image, format, bbox, transfKey=None, keyIndex=0): self.image = image self.format = format @@ -648,15 +859,38 @@ class asyImage: self.key = transfKey self.keyIndex = keyIndex -class xasyItem(Qc.QObject): - """A base class for items in the xasy GUI""" +class xasyItem(QtCore.QObject): + """ + Purpose: + -------- + A base class for any xasy object that can be drawn in PyQt. This class takes + care of all common behaviors available on any xasy item as well as all common + actions that can be done or applied to every xasy item. + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + 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""" + """ Initialize the item to an empty item """ super().__init__() self.transfKeymap = {} # the new keymap. # should be a dictionary to a list... @@ -672,18 +906,17 @@ class xasyItem(Qc.QObject): 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""" + def updateCode(self, ps2asymap = identity()): + """ Update the item's code: to be overridden """ with io.StringIO() as rawCode: transfCode = self.getTransformCode() objCode = self.getObjectCode() rawCode.write(transfCode) rawCode.write(objCode) - self.asyCode = rawCode.getvalue() + self.asyCode = rawCode.getvalue() return len(transfCode.splitlines()), len(objCode.splitlines()) @@ -695,34 +928,32 @@ class xasyItem(Qc.QObject): def asyengine(self, value): self._asyengine = value - def getCode(self, ps2asymap=identity()): - """Return the code describing the item""" + def getCode(self, ps2asymap = identity()): + """ Return the code describing the item """ self.updateCode(ps2asymap) return self.asyCode - def getTransformCode(self, asy2psmap=identity()): + def getTransformCode(self, asy2psmap = identity()): raise NotImplementedError - def getObjectCode(self, asy2psmap=identity()): + 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.""" + 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 fileformat == 'svg': if containsClip: image = xs.SvgObject(self.asyengine.tempDirName+file) else: - image = Qs.QSvgRenderer(file) + image = QtSvg.QSvgRenderer(file) assert image.isValid() else: - raise Exception('Format not supported!') - self.imageList.append(asyImage(image, fileformat, bbox, transfKey=key, keyIndex=localCount)) + raise Exception('Format {} not supported!'.format(fileformat)) + 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] @@ -733,7 +964,7 @@ class xasyItem(Qc.QObject): currImage.performCanvasTransform = False # handle this case if transform is not in the map yet. - # if deleted - set transform to 0, 0, 0, 0, 0 + # if deleted - set transform to (0,0,0,0,0,0) transfExists = key in self.transfKeymap.keys() if transfExists: transfExists = localCount <= len(self.transfKeymap[key]) - 1 @@ -745,7 +976,7 @@ class xasyItem(Qc.QObject): 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, + btmRightanchor=QtCore.QPointF(bbox[0], bbox[2]), drawOrder=-1, key=key, parentObj=self, keyIndex=localCount) newDrawObj.setBoundingBoxPs(bbox) newDrawObj.setParent(self) @@ -757,7 +988,8 @@ class xasyItem(Qc.QObject): else: self.drawObjectsMap[key].append(newDrawObj) return containsClip - def asyfy(self, force=False): + + def asyfy(self, force = False): if self.asyengine is None: return 1 if self.asyfied and not force: @@ -772,7 +1004,7 @@ class xasyItem(Qc.QObject): self.userKeys.clear() self.imageHandleQueue = queue.Queue() - worker = threading.Thread(target=self.asyfyThread, args=[]) + worker = threading.Thread(target = self.asyfyThread, args = []) worker.start() item = self.imageHandleQueue.get() cwd=os.getcwd(); @@ -797,22 +1029,25 @@ class xasyItem(Qc.QObject): worker.join() def asyfyThread(self): - """Convert the item to a list of images by deconstructing this item's code""" + """ + 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()) + self.maxKey=0 fout.write("reset\n") fout.flush(); for line in self.getCode().splitlines(): - if DebugFlags.printDeconstTranscript: - print('fout:', line) + if DebugFlags.printAsyTranscript: + print(line) fout.write(line+"\n") fout.write(self.asySize) - fout.write("deconstruct();\n") + + fout.write('deconstruct();\n') fout.write('write(_outpipe,yscale(-1)*currentpicture.calculateTransform(),endl);\n') fout.write(self.asyengine.xasy) fout.flush() @@ -826,37 +1061,44 @@ class xasyItem(Qc.QObject): for i in range(len(imageInfos)): box, key, localCount, useClip = imageInfos[i] l, b, r, t = [float(a) for a in box.split()] - name = "_{:d}.{:s}".format(i, fileformat) + name = '_{:d}.{:s}'.format(1+i, fileformat) self.imageHandleQueue.put((name, fileformat, (l, -t, r, -b), i, key, localCount, useClip)) # key first, box second. - # if key is "Done" + # if key is 'Done' raw_text = fin.readline() - text = "" + text = '' if DebugFlags.printDeconstTranscript: + print(self.asyengine.tmpdir) print(raw_text.strip()) - # template=AsyTempDir+"%d_%d.%s" - fileformat = 'svg' + fileformat = 'svg' # Output format - while raw_text != "Done\n" and raw_text != "Error\n": + 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' + deleted = keydata[-1] == '2' userkey = keydata[-2] == '1' keydata = keydata[:-3] if not userkey: - self.unsetKeys.add(keydata) # the line and column to replace. + self.unsetKeys.add(keydata) # the line and column to replace. else: + if keydata.isdigit(): + self.maxKey=max(self.maxKey,int(keydata)) self.userKeys.add(keydata) - + # print(line, col) + if deleted: + raw_text = fin.readline() + continue + if keydata not in keyCounts.keys(): keyCounts[keydata] = 0 @@ -873,23 +1115,45 @@ class xasyItem(Qc.QObject): n += 1 - if raw_text != "Error\n": - if text == "Error\n": - self.imageHandleQueue.put(("ERROR", fin.readline())) + if raw_text != 'Error\n': + if text == 'Error\n': + self.imageHandleQueue.put(('ERROR', fin.readline())) else: render() self.asy2psmap = asyTransform(xu.listize(fin.readline().rstrip(),float)) else: - self.asy2psmap = identity() + self.asy2psmap = yflip() 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.""" + """ + Purpose: + -------- + A base class dedicated to any xasy item that is drawn on GUI. Every object of this class + will correspond to a particular drawn xasy item on GUI, which contains all its particular + data. + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- - def __init__(self, path, engine, pen=None, transform=identity(), key=None): - """Initialize the item with a path, pen, and transform""" + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + 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() @@ -921,7 +1185,9 @@ class xasyDrawnItem(xasyItem): 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.""" + """ 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') @@ -933,12 +1199,14 @@ class xasyDrawnItem(xasyItem): self.path.linkSet.append(link) def clearTransform(self): - """Reset the item's transform""" + """ 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.""" + """ 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: @@ -948,7 +1216,9 @@ class xasyDrawnItem(xasyItem): 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.""" + """ 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: @@ -958,13 +1228,38 @@ class xasyDrawnItem(xasyItem): class xasyShape(xasyDrawnItem): - """An outlined shape drawn on the GUI""" + """ An outlined shape drawn on the GUI """ + """ + Purpose: + -------- + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + 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' + if self.path.fill: + return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n' + else: + 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] @@ -982,63 +1277,121 @@ class xasyShape(xasyDrawnItem): key=self.transfKey) newObj.originalObj = self newObj.setParent(self) + newObj.fill=self.path.fill return [newObj] def __str__(self): - """Create a string describing this shape""" + """ Create a string describing this shape """ return "xasyShape code:{:s}".format("\n\t".join(self.getCode().splitlines())) + def swapFill(self): + self.path.fill = not self.path.fill + + def copy(self): + return type(self)(self.path,self._asyengine,self.pen) + class xasyFilledShape(xasyShape): - """A filled shape drawn on the GUI""" + """ 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""" + """ + Purpose: + -------- + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + 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) + self.path.fill=True def getObjectCode(self, asy2psmap=identity()): - return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n' + if self.path.fill: + return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n' + else: + return 'draw(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n' - def generateDrawObjects(self, forceUpdate=False): + 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 = 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) + newObj.fill=self.path.fill return [newObj] def __str__(self): - """Return a string describing this shape""" + """ Return a string describing this shape """ return "xasyFilledShape code:{:s}".format("\n\t".join(self.getCode().splitlines())) + def swapFill(self): + self.path.fill = not self.path.fill + class xasyText(xasyItem): - """Text created by the GUI""" + """ Text created by the GUI """ + + """ + Purpose: + -------- + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- - 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) + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + 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) + pen = asyPen(asyengine = asyengine) if pen.asyEngine is None: pen.asyEngine = asyengine - self.label = asyLabel(text, location, pen, align, fontSize=fontsize) + 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): + self.pen = pen + + def setKey(self, newKey = None): transform = self.transfKeymap[self.transfKey][0] self.transfKey = newKey self.transfKeymap = {self.transfKey: [transform]} - def getTransformCode(self, asy2psmap=yflip()): + def getTransformCode(self, asy2psmap = yflip()): transf = self.transfKeymap[self.transfKey][0] if transf == yflip(): # return xasyItem.setKeyAloneFormatStr.format(self.transfKey) @@ -1046,10 +1399,10 @@ class xasyText(xasyItem): else: return xasyItem.setKeyFormatStr.format(self.transfKey, transf.getCode(asy2psmap))+"\n" - def getObjectCode(self, asy2psmap=yflip()): + def getObjectCode(self, asy2psmap = yflip()): return 'label(KEY="{0}",{1});'.format(self.transfKey, self.label.getCode(asy2psmap))+'\n' - def generateDrawObjects(self, forceUpdate=False): + def generateDrawObjects(self, forceUpdate = False): self.asyfy(forceUpdate) return self.drawObjects @@ -1060,12 +1413,36 @@ class xasyText(xasyItem): def __str__(self): return "xasyText code:{:s}".format("\n\t".join(self.getCode().splitlines())) + def copy(self): + return type(self)(self.label.text,self.label.location,self._asyengine) + class xasyScript(xasyItem): - """A set of images create from asymptote code. It is always deconstructed.""" + """ A set of images create from asymptote code. It is always deconstructed """ + + """ + Purpose: + -------- + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ def __init__(self, canvas, engine, script="", transforms=None, transfKeyMap=None): - """Initialize this script item""" + """ Initialize this script item """ super().__init__(canvas, asyengine=engine) if transfKeyMap is not None: self.transfKeymap = transfKeyMap @@ -1080,7 +1457,7 @@ class xasyScript(xasyItem): self.updatedPrefix = True def clearTransform(self): - """Reset the transforms for each of the deconstructed images""" + """ Reset the transforms for each of the deconstructed images """ # self.transform = [identity()] * len(self.imageList) keyCount = {} @@ -1093,14 +1470,6 @@ class xasyScript(xasyItem): 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: @@ -1109,21 +1478,22 @@ class xasyScript(xasyItem): 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: + # unfortunately, have to check all transformations in the list. + while not all((checktransf == identity() and not checktransf.deleted) 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))) + else: + if transf == identity(): + 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]) } + return {key for key in self.transfKeymap if not all(not transf.deleted and transf == identity() for transf in self.transfKeymap[key]) } def getObjectCode(self, asy2psmap=identity()): numeric=r'([-+]?(?:(?:\d*\.\d+)|(?:\d+\.?)))' @@ -1144,7 +1514,7 @@ class xasyScript(xasyItem): return self.updatedCode def setScript(self, script): - """Sets the content of the script item.""" + """ Sets the content of the script item """ self.script = script self.updateCode() @@ -1155,7 +1525,7 @@ class xasyScript(xasyItem): def getReplacedKeysCode(self, key2replace: set=None) -> str: keylist = {} prefix = '' - + key2replaceSet = self.unsetKeys if key2replace is None else \ self.unsetKeys & key2replace @@ -1180,9 +1550,8 @@ class xasyScript(xasyItem): 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] + for i in range(len(raw_code_lines)): + curr_str = raw_code_lines[i] if i + 1 in keylist.keys(): # this case, we have a key. with io.StringIO() as raw_line: @@ -1205,11 +1574,13 @@ class xasyScript(xasyItem): 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.""" + 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 + # Id --> Transf --> asyfied --> Transf # Transf should keep the original, raw transformation # but for all new drawn objects - assign Id as transform. @@ -1246,7 +1617,7 @@ class xasyScript(xasyItem): else: self.key2imagemap[im.key].append(im) - + for key in keyCount: if key not in self.transfKeymap.keys(): @@ -1258,7 +1629,7 @@ class xasyScript(xasyItem): # while len(self.transfKeymap[key]) > keyCount[key]: # self.transfKeymap[key].pop() - # change of basis + # change of basis for keylist in self.transfKeymap.values(): for i in range(len(keylist)): if keylist[i] != identity(): @@ -1272,17 +1643,41 @@ class xasyScript(xasyItem): return self.drawObjects def __str__(self): - """Return a string describing this script""" + """ Return a string describing this script """ retVal = "xasyScript\n\tTransforms:\n" for xform in self.transform: retVal += "\t" + str(xform) + "\n" - retVal += "\tCode Ommitted" + retVal += "\tCode Omitted" 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): +class DrawObject(QtCore.QObject): + """ + Purpose: + -------- + The main Python class to draw an object with the help of PyQt graphical library. + Every instance of the class is + + + Attributes: + ----------- + + Virtual Methods: + ---------------- + + Static Methods: + --------------- + + Class Methods: + -------------- + + Object Methods: + --------------- + + """ + + def __init__(self, drawObject, mainCanvas = None, transform = identity(), btmRightanchor = QtCore.QPointF(0, 0), + drawOrder = (-1, -1), pen = None, key = None, parentObj = None, fill = False, keyIndex = 0): super().__init__() self.drawObject = drawObject self.mainCanvas = mainCanvas @@ -1302,8 +1697,8 @@ class DrawObject(Qc.QObject): self.fill = fill def getInteriorScrTransform(self, transform): - """Generates the transform with Interior transform applied beforehand.""" - if isinstance(transform, Qg.QTransform): + """ Generates the transform with Interior transform applied beforehand """ + if isinstance(transform, QtGui.QTransform): transform = asyTransform.fromQTransform(transform) return self.transform * transform * self.baseTransform.inverted() @@ -1317,25 +1712,36 @@ class DrawObject(Qc.QObject): 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) + self.explicitBoundingBox = QtCore.QRectF(QtCore.QPointF(l, b), QtCore.QPointF(r, t)) + # self.explicitBoundingBox = QtCore.QRectF(0, 0, 100, 100) @property def boundingBox(self): if self.explicitBoundingBox is not None: - testBbox = self.explicitBoundingBox + tempItem = self.baseTransform.toQTransform().mapRect(self.explicitBoundingBox) + testBbox = self.getScreenTransform().toQTransform().mapRect(tempItem) + elif isinstance(self.drawObject, QtGui.QPainterPath): + tempItem = self.baseTransform.toQTransform().map(self.drawObject) + testBbox = self.getScreenTransform().toQTransform().map(tempItem).boundingRect() 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() + raise TypeError('drawObject is not a valid type!') + + if self.pen is not None: + lineWidth = self.pen.width + const = lineWidth/2 + bl = QtCore.QPointF(-const, const) + br = QtCore.QPointF(const, const) + tl = QtCore.QPointF(-const, -const) + tr = QtCore.QPointF(const, -const) + + pointList = [testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight() + ] + + else: + pointList = [testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight() + ] + + return QtGui.QPolygonF(pointList).boundingRect() @property def localBoundingBox(self): @@ -1345,22 +1751,25 @@ class DrawObject(Qc.QObject): def getScreenTransform(self): scrTransf = self.baseTransform.toQTransform().inverted()[0] * self.pTransform.toQTransform() + # print(asyTransform.fromQTransform(scrTransf).t) return asyTransform.fromQTransform(scrTransf) - def draw(self, additionalTransformation=None, applyReverse=False, canvas: Qg.QPainter=None, dpi=300): + def draw(self, additionalTransformation = None, applyReverse = False, canvas: QtGui.QPainter = None, dpi = 300): if canvas is None: canvas = self.mainCanvas if additionalTransformation is None: - additionalTransformation = Qg.QTransform() - + additionalTransformation = QtGui.QTransform() + assert canvas.isActive() canvas.save() if self.pen: - oldPen = Qg.QPen(canvas.pen()) - canvas.setPen(self.pen.toQPen()) + oldPen = QtGui.QPen(canvas.pen()) + localPen = self.pen.toQPen() + # localPen.setCosmetic(True) + canvas.setPen(localPen) #this fixes the object but not the box else: - oldPen = Qg.QPen() + oldPen = QtGui.QPen() if not applyReverse: canvas.setTransform(additionalTransformation, True) @@ -1371,11 +1780,9 @@ class DrawObject(Qc.QObject): 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): + if 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 @@ -1383,15 +1790,15 @@ class DrawObject(Qc.QObject): self.cachedSvgImg = self.drawObject.render(dpi) canvas.drawImage(self.explicitBoundingBox, self.cachedSvgImg) - elif isinstance(self.drawObject, Qs.QSvgRenderer): + elif isinstance(self.drawObject, QtSvg.QSvgRenderer): self.drawObject.render(canvas, self.explicitBoundingBox) - elif isinstance(self.drawObject, Qg.QPainterPath): + elif isinstance(self.drawObject, QtGui.QPainterPath): path = self.baseTransform.toQTransform().map(self.drawObject) if self.fill: if self.pen: brush = self.pen.toQPen().brush() else: - brush = Qg.QBrush() + brush = QtGui.QBrush() canvas.fillPath(path, brush) else: canvas.drawPath(path) @@ -1400,14 +1807,14 @@ class DrawObject(Qc.QObject): canvas.setPen(oldPen) canvas.restore() - def collide(self, coords, canvasCoordinates=True): - # modify these values to grow/shrink the fuzz. + 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) + newMargin = QtCore.QMarginsF(leftMargin, topMargin, leftMargin, topMargin) return self.boundingBox.marginsAdded(newMargin).contains(coords) def getID(self): diff --git a/Master/texmf-dist/asymptote/GUI/xasyArgs.py b/Master/texmf-dist/asymptote/GUI/xasyArgs.py index 045f4bc6692..b9e1518f1e8 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyArgs.py +++ b/Master/texmf-dist/asymptote/GUI/xasyArgs.py @@ -1,23 +1,32 @@ #!/usr/bin/env python3 import argparse import xasyVersion -import PyQt5.QtCore as Qc +import PyQt5.QtCore as QtCore # 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', + parser.add_argument('-p', '-asypath', '--asypath', + help='Custom path to asy executable') + parser.add_argument('-v', '-version', '--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('-l', '-language', '--language', + help='language') + parser.add_argument('-x', '-mag', '--mag', + help='Initial magnification. Defaults to 1', + default=1, type=float) + parser.add_argument('-render', '--render', + help='Number of pixels per bp in 3D rendered bitmaps', + default=None, type=float) parser.add_argument( - 'filename', help='Filename to load. If empty, initializes empty xasy canvas.', nargs='?', default=None) + 'filename', + help='Filename to load (if omitted, initialize blank canvas)', + nargs='?', default=None) return parser.parse_args() def getArgs(): - return parseArgs(Qc.QCoreApplication.arguments()) + return parseArgs(QtCore.QCoreApplication.arguments()) diff --git a/Master/texmf-dist/asymptote/GUI/xasyBezierInterface.py b/Master/texmf-dist/asymptote/GUI/xasyBezierInterface.py index 0a5c689bffe..d8792d421e8 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyBezierInterface.py +++ b/Master/texmf-dist/asymptote/GUI/xasyBezierInterface.py @@ -1,16 +1,14 @@ #!/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 PyQt5.QtWidgets as QtWidgets +import PyQt5.QtCore as QtCore +import PyQt5.QtGui as QtGui +import xasy2asy as xasy2asy +import xasyUtils as xasyUtils import Widg_editBezier as Web import InplaceAddObj - import math class CurrentlySelctedType: @@ -19,16 +17,16 @@ class CurrentlySelctedType: ctrlPoint = 1 class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): - editAccepted = Qc.pyqtSignal() - editRejected = Qc.pyqtSignal() + editAccepted = QtCore.pyqtSignal() + editRejected = QtCore.pyqtSignal() - def __init__(self, parent: Qc.QObject, obj: x2a.xasyDrawnItem, info: dict={}): + def __init__(self, parent: QtCore.QObject, obj: xasy2asy.xasyDrawnItem, info: dict={}): super().__init__(parent) self.info = info - self.asyPathBackup = x2a.asyPath.fromPath(obj.path) + self.asyPathBackup = xasy2asy.asyPath.fromPath(obj.path) self.asyPath = obj.path self.curveMode = self.asyPath.containsCurve - assert isinstance(self.asyPath, x2a.asyPath) + assert isinstance(self.asyPath, xasy2asy.asyPath) self.transf = obj.transfKeymap[obj.transfKey][0] self._active = True @@ -47,10 +45,20 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): self.inTransformMode = False self.opt = None + self.obj = obj self.prosectiveNodes = [] self.prospectiveCtrlPts = [] + #The magnification isn't being set. Here I'm manually setting it to be the square root of the determinant. + self.info['magnification'] = math.sqrt(self.transf.xx * self.transf.yy - self.transf.xy * self.transf.yx) + self.parent = parent + if isinstance(obj,xasy2asy.xasyFilledShape) or isinstance(obj,xasy2asy.xasyShape): + parent.ui.btnFill.setChecked(obj.path.fill) + + def swapObjFill(self): + self.obj.swapFill() #This may end up being more in the future + def setSelectionBoundaries(self): self.nodeSelRects = self.handleNodeSelectionBounds() @@ -66,11 +74,11 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): continue selEpsilon = 6/self.info['magnification'] - newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon) + newRect = QtCore.QRectF(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)) + newRect.moveCenter(QtCore.QPoint(x, y)) nodeSelectionBoundaries.append(newRect) @@ -84,8 +92,8 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): selEpsilon = 6/self.info['magnification'] - newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon) - newRectb = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon) + newRect = QtCore.QRectF(0, 0, 2 * selEpsilon, 2 * selEpsilon) + newRectb = QtCore.QRectF(0, 0, 2 * selEpsilon, 2 * selEpsilon) x, y = self.transf * nodea x2, y2 = self.transf * nodeb @@ -96,18 +104,19 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): x2 = int(round(x2)) y2 = int(round(y2)) - newRect.moveCenter(Qc.QPoint(x, y)) - newRectb.moveCenter(Qc.QPoint(x2, y2)) + newRect.moveCenter(QtCore.QPoint(x, y)) + newRectb.moveCenter(QtCore.QPoint(x2, y2)) ctrlPointSelBoundaries.append((newRect, newRectb)) return ctrlPointSelBoundaries - def postDrawPreview(self, canvas: Qg.QPainter): + + def postDrawPreview(self, canvas: QtGui.QPainter): assert canvas.isActive() - dashedPen = Qg.QPen(Qc.Qt.DashLine) - dashedPen.setWidthF(1/self.info['magnification']) + dashedPen = QtGui.QPen(QtCore.Qt.DashLine) + dashedPen.setCosmetic(True) # draw the base points canvas.save() canvas.setWorldTransform(self.transf.toQTransform(), True) @@ -123,27 +132,27 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): canvas.drawPath(self.asyPath.toQPainterPath()) - nodePen = Qg.QPen(Qg.QColor('blue')) - nodePen.setWidthF(1/self.info['magnification']) + nodePen = QtGui.QPen(QtGui.QColor('blue')) + nodePen.setCosmetic(True) - ctlPtsPen = Qg.QPen(Qg.QColor(ctrlPtsColor)) - ctlPtsPen.setWidthF(1/self.info['magnification']) + ctlPtsPen = QtGui.QPen(QtGui.QColor(ctrlPtsColor)) + ctlPtsPen.setCosmetic(True) for index in range(len(self.asyPath.nodeSet)): point = self.asyPath.nodeSet[index] - + if point != 'cycle': - basePoint = Qc.QPointF(point[0], point[1]) + basePoint = QtCore.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: + basePoint = QtCore.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]) + postCtrlPoint = QtCore.QPointF(postCtrolSet[0], postCtrolSet[1]) canvas.drawEllipse(postCtrlPoint, epsilonSize, epsilonSize) canvas.setPen(dashedPen) @@ -152,7 +161,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): if index != len(self.asyPath.nodeSet) - 1: canvas.setPen(ctlPtsPen) preCtrlSet = self.asyPath.controlSet[index][0] - preCtrlPoint = Qc.QPointF(preCtrlSet[0], preCtrlSet[1]) + preCtrlPoint = QtCore.QPointF(preCtrlSet[0], preCtrlSet[1]) canvas.drawEllipse(preCtrlPoint, epsilonSize, epsilonSize) canvas.setPen(dashedPen) @@ -189,7 +198,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): self.asyPath.setInfo(self.asyPathBackup) self.setSelectionBoundaries() - def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None): + def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None): self.lastSelPoint = pos if self.inTransformMode: return @@ -204,13 +213,13 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): 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 + return preCtrl, postCtrl = self.getPreAndPostCtrlPts(self.parentNodeIndex) @@ -219,20 +228,20 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): self.parentNodeIndex = 0 if preCtrl is not None: - self.preCtrlOffset = xu.funcOnList( + self.preCtrlOffset = xasyUtils.funcOnList( preCtrl, parentNode, lambda a, b: a - b) else: self.preCtrlOffset = None if postCtrl is not None: - self.postCtrlOffset = xu.funcOnList( + self.postCtrlOffset = xasyUtils.funcOnList( postCtrl, parentNode, lambda a, b: a - b) else: self.postCtrlOffset = None - def mouseMove(self, pos, event: Qg.QMouseEvent): + def mouseMove(self, pos, event: QtGui.QMouseEvent): if self.currentSelMode is None and not self.inTransformMode: - # in this case, search for prosective nodes. + # in this case, search for prosective nodes. prospectiveNodes = [] prospectiveCtrlpts = [] @@ -262,32 +271,31 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): if self.inTransformMode: index, subindex = self.currentSelIndex - deltaPos = pos - self.lastSelPoint - newNode = (pos.x(), pos.y()) + newNode = (self.transf.inverted().toQTransform().map(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 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 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( + self.asyPath.controlSet[index - 1][1] = xasyUtils.funcOnList( newNode, self.preCtrlOffset, lambda a, b: a + b ) if checkPost is not None: - self.asyPath.controlSet[index][0] = xu.funcOnList( + self.asyPath.controlSet[index][0] = xasyUtils.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 @@ -302,46 +310,46 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): if self.parentNodeIndex == 0 and self.asyPath.nodeSet[-1] == 'cycle': isCycle = True - rawNewNode = xu.funcOnList(newNode, parentNode, lambda a, b: a - b) + rawNewNode = xasyUtils.funcOnList(newNode, parentNode, lambda a, b: a - b) rawAngle = math.atan2(rawNewNode[1], rawNewNode[0]) - newNorm = xu.twonorm(rawNewNode) + newNorm = xasyUtils.twonorm(rawNewNode) if self.info['editBezierlockMode'] >= Web.LockMode.angleLock: - otherIndex = 1 - subindex # 1 if 0, 0 otherwise. + 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( + oldOtherCtrlPnt = xasyUtils.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) + rawNorm = xasyUtils.twonorm(oldOtherCtrlPnt) - newPnt = (rawNorm * math.cos(rawAngle + math.pi), + newPnt = (rawNorm * math.cos(rawAngle + math.pi), rawNorm * math.sin(rawAngle + math.pi)) - - self.asyPath.controlSet[newIndex][0] = xu.funcOnList( + + self.asyPath.controlSet[newIndex][0] = xasyUtils.funcOnList( newPnt, parentNode, lambda a, b: a + b) else: if index > 0 or isCycle: newIndex = -1 if isCycle else index - 1 - oldOtherCtrlPnt = xu.funcOnList( + oldOtherCtrlPnt = xasyUtils.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) + rawNorm = xasyUtils.twonorm(oldOtherCtrlPnt) newPnt = (rawNorm * math.cos(rawAngle + math.pi), rawNorm * math.sin(rawAngle + math.pi)) - self.asyPath.controlSet[newIndex][1] = xu.funcOnList( + self.asyPath.controlSet[newIndex][1] = xasyUtils.funcOnList( newPnt, parentNode, lambda a, b: a + b) - + def recalculateCtrls(self): self.quickRecalculateCtrls() self.setSelectionBoundaries() @@ -356,7 +364,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess): self.currentSelMode = None self.setSelectionBoundaries() - + def forceFinalize(self): self.objectUpdated.emit() diff --git a/Master/texmf-dist/asymptote/GUI/xasyFile.py b/Master/texmf-dist/asymptote/GUI/xasyFile.py index eee6d69a856..54c70cf5c2b 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyFile.py +++ b/Master/texmf-dist/asymptote/GUI/xasyFile.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ########################################################################### # -# xasyFile implements the loading, parsing, and saving of an xasy file. +# xasyFile implements the loading, parsing, and saving of an asy file. # # # Author: Orest Shardt @@ -10,7 +10,7 @@ ############################################################################ from string import * -import xasy2asy as x2a +import xasy2asy as xasy2asy import io import re @@ -28,7 +28,7 @@ class xasyFileError(Exception): def extractTransform(line): """Returns key and the new transform.""" # see https://regex101.com/r/6DqkRJ/4 for info - mapString = x2a.xasyItem.mapString + mapString = xasy2asy.xasyItem.mapString testMatch = re.match( r'^{0:s}\s*\(\s*\"([^\"]+)\"\s*,\s*\(([-\d, .]+)\)\s*\)'.format(mapString), line.strip()) if testMatch is None: @@ -37,7 +37,7 @@ def extractTransform(line): return None else: key = mapOnlyMatch.group(1) - return key, x2a.identity() + return key, xasy2asy.identity() else: key = testMatch.group(1) rawStr = testMatch.group(2) @@ -46,7 +46,7 @@ def extractTransform(line): if len(rawStrArray) != 6: return None transf = [float(val.strip()) for val in rawStrArray] - return key, x2a.asyTransform(transf) + return key, xasy2asy.asyTransform(transf) def extractTransformsFromFile(fileStr): @@ -62,22 +62,58 @@ def extractTransformsFromFile(fileStr): 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 + return final_str, transfDict + +def xasy2asyCode(xasyItems, asy2psmap): + asyCode = '' + for item in xasyItems: + asyCode += item.getTransformCode(asy2psmap) + for item in xasyItems: + asyCode += item.getObjectCode(asy2psmap) + asyCode += 'size('+str(asy2psmap*xasy2asy.yflip())+'); '+ xasy2asy.xasyItem.resizeComment+'\n' + return asyCode def saveFile(file, xasyItems, asy2psmap): """Write a list of xasyItems to a file""" - for item in xasyItems: - file.write(item.getTransformCode(asy2psmap)) + file.write(xasy2asyCode(xasyItems, asy2psmap)) +def xasyToDict(file, xasyItems, asy2psmap): + fileItems = [] + asyItems = [] for item in xasyItems: - file.write(item.getObjectCode(asy2psmap)) + if isinstance(item, xasy2asy.xasyScript): + # reusing xasyFile code for objects + # imported from asy script. + asyItems.append({'item':item, 'type': 'xasyScript'}) + + elif isinstance(item, xasy2asy.xasyText): + # At the moment xasyText cannot be edited + # so we treat it the same as xasyScript + penData = {'color': item.pen.color, 'width': item.pen.width, 'options': item.pen.options} + fileItems.append({'type': 'xasyText', + 'align': item.label.align, + 'location': item.label.location, + 'fontSize': item.label.fontSize, + 'text': item.label.text, + 'transform': item.transfKeymap[item.transfKey][0].t, + 'transfKey': item.transfKey, + 'pen': penData + }) + + elif isinstance(item, xasy2asy.xasyShape): + penData = {'color': item.pen.color, 'width': item.pen.width, 'options': item.pen.options} + fileItems.append({'type': 'xasyShape', + 'nodes': item.path.nodeSet, + 'links': item.path.linkSet, + 'transform': item.transfKeymap[item.transfKey][0].t, + 'transfKey': item.transfKey, + 'pen': penData + }) + + else: + # DEBUGGING PURPOSES ONLY + print(type(item)) - file.write('size('+str(asy2psmap*x2a.yflip())+'); '+ x2a.xasyItem.resizeComment+'\n') + return {'objects': fileItems, 'asy2psmap': asy2psmap.t}, asyItems diff --git a/Master/texmf-dist/asymptote/GUI/xasyOptions.py b/Master/texmf-dist/asymptote/GUI/xasyOptions.py index 0ee1a1f1a0d..458dd9cb3c9 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyOptions.py +++ b/Master/texmf-dist/asymptote/GUI/xasyOptions.py @@ -10,25 +10,13 @@ # ########################################################################### -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 +import cson class xasyOptions: def defaultOptions(self): @@ -49,12 +37,12 @@ class xasyOptions: 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', ''] + searchOrder = ['.cson', ''] searchIndex = 0 found = False @@ -64,7 +52,7 @@ class xasyOptions: if os.path.isfile(currentFile): found = True searchIndex += 1 - + if found: return os.path.normcase(currentFile) else: @@ -99,16 +87,7 @@ class xasyOptions: 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()) + newOptions = cson.loads(f.read()) except (IOError, ModuleNotFoundError): self.setDefaults() else: @@ -130,7 +109,7 @@ class xasyOptions: 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. """ @@ -150,6 +129,72 @@ def setAsyPathFromWindowsRegistry(): registry.CloseKey(key) """ +class xasyOpenRecent: + def __init__(self, configName, defaultConfigLocation): + self.configName = configName + self.fileName = self.settingsFileLocation() + if not os.path.isfile(self.fileName): + f = io.open(self.fileName, 'w') + f.write('') + f.close() + + def settingsFileLocation(self): + folder = os.path.expanduser("~/.asy/") + + currentFile = os.path.join(folder, self.configName + '.txt') + return os.path.normcase(currentFile) + + def insert(self, path): + if not os.path.exists(self.fileName): + # make folder + thedir = os.path.dirname(self.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") + + f = io.open(self.fileName, 'r') + lines = f.readlines() + f.close() + + f = io.open(self.fileName, 'w') + f.write(path.strip() + '\n') + for line in lines: + if line.strip() != path.strip(): + f.write(line.strip() + '\n') + f.close() + + @property + def pathList(self): + self.findingPaths=True + return self.findPath() + + def findPath(self): + f = io.open(self.fileName, 'r') + paths = [path.strip() for path in f.readlines()] + f.close() + + trueFiles = list(map(lambda path: os.path.isfile(os.path.expanduser(path)), paths)) + if all(trueFiles): + return paths + else: + if self.findingPaths == False: + raise RecursionError + self.findingPaths = False + self.removeNotFound(list(trueFiles), paths) + return self.findPath() + + def removeNotFound(self, trueFiles, paths): + f = io.open(self.fileName, 'w') + for index, path in enumerate(paths): + if trueFiles[index] == True: + f.write(path + '\n') + f.close() + + def clear(self): + f = io.open(self.fileName, 'w') + f.write('') + f.close() class BasicConfigs: _configPath = list(configs.__path__)[0] @@ -157,3 +202,4 @@ class BasicConfigs: 'xasyconfig', os.path.join(_configPath, 'xasyconfig.cson')) keymaps = xasyOptions('xasykeymap', os.path.join( _configPath, 'xasykeymap.cson')) + openRecent = xasyOpenRecent('xasyrecents', os.path.join( _configPath, "xasyrecent.txt")) diff --git a/Master/texmf-dist/asymptote/GUI/xasyStrings.py b/Master/texmf-dist/asymptote/GUI/xasyStrings.py index 53f83a64f14..4f2ca0d2ed2 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyStrings.py +++ b/Master/texmf-dist/asymptote/GUI/xasyStrings.py @@ -8,12 +8,12 @@ class xasyString: def __init__(self, lang=None): s = self if lang is None: - _ = lambda x: x + _ = 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') diff --git a/Master/texmf-dist/asymptote/GUI/xasySvg.py b/Master/texmf-dist/asymptote/GUI/xasySvg.py index a5325f9bdd6..7261dc5b691 100755 --- a/Master/texmf-dist/asymptote/GUI/xasySvg.py +++ b/Master/texmf-dist/asymptote/GUI/xasySvg.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import PyQt5.QtGui as Qg -import PyQt5.QtWidgets as Qw +import PyQt5.QtGui as QtGui +import PyQt5.QtWidgets as QtWidgets import io import subprocess import sys @@ -10,13 +10,13 @@ class SvgObject(): def __init__(self, file: str): self.file=file - def render(self, dpi:int) -> Qg.QImage: + def render(self, dpi:int) -> QtGui.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.') + QtWidgets.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') + return QtGui.QImage.fromData(rawDataProc.stdout.read(), 'PNG') diff --git a/Master/texmf-dist/asymptote/GUI/xasyTransform.py b/Master/texmf-dist/asymptote/GUI/xasyTransform.py index 928e9011f0a..cb70bf1edb1 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyTransform.py +++ b/Master/texmf-dist/asymptote/GUI/xasyTransform.py @@ -1,24 +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 xasy2asy as xasy2asy +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import numpy as numpy import math class xasyTransform: @classmethod def makeRotTransform(cls, theta, origin): - if isinstance(origin, Qc.QPointF) or isinstance(origin, Qc.QPoint): + if isinstance(origin, QtCore.QPointF) or isinstance(origin, QtCore.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])) + shift = xasy2asy.asyTransform((0, 0, 1 - rotMat[0], -rotMat[1], -rotMat[2], 1 - rotMat[3])) * origin + return xasy2asy.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): + if isinstance(origin, QtCore.QPointF) or isinstance(origin, QtCore.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)) + shiftMat = xasy2asy.asyTransform((0, 0, 1 - sx, 0, 0, 1 - sy)) * origin + return xasy2asy.asyTransform((shiftMat[0], shiftMat[1], sx, 0, 0, sy)) diff --git a/Master/texmf-dist/asymptote/GUI/xasyUtils.py b/Master/texmf-dist/asymptote/GUI/xasyUtils.py index 255e8b6addc..04e327bb443 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyUtils.py +++ b/Master/texmf-dist/asymptote/GUI/xasyUtils.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import re -import typing as ty +import typing as typing import math import itertools @@ -15,12 +15,12 @@ def tryParse(val, typ=float): 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 +def funcOnList(list1: typing.Union[typing.List, typing.Tuple], list2: typing.Union[typing.List, typing.Tuple], func: typing.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))]) + return tuple([func(list1[i], list2[i]) for i in range(len(list1))]) def listize(str, typ, delim='()') -> list: @@ -39,7 +39,7 @@ def listize(str, typ, delim='()') -> list: final_list.append(typ(elem.strip())) return final_list -def twonorm(vec: ty.Iterable[ty.Union[float, int]]) -> float: +def twonorm(vec: typing.Iterable[typing.Union[float, int]]) -> float: rawSquared = sum(map(lambda x: x*x, vec)) return math.sqrt(rawSquared) diff --git a/Master/texmf-dist/asymptote/GUI/xasyVersion.py b/Master/texmf-dist/asymptote/GUI/xasyVersion.py index 3c9cd354faf..60538f74eda 100755 --- a/Master/texmf-dist/asymptote/GUI/xasyVersion.py +++ b/Master/texmf-dist/asymptote/GUI/xasyVersion.py @@ -1,2 +1,2 @@ #!/usr/bin/env python3 -xasyVersion = "2.70" +xasyVersion = "2.78" diff --git a/Master/texmf-dist/asymptote/asy-keywords.el b/Master/texmf-dist/asymptote/asy-keywords.el index a24374785be..601ff063e7a 100644 --- a/Master/texmf-dist/asymptote/asy-keywords.el +++ b/Master/texmf-dist/asymptote/asy-keywords.el @@ -2,7 +2,7 @@ ;; This file is automatically generated by asy-list.pl. ;; Changes will be overwritten. ;; -(defvar asy-keywords-version "2.70") +(defvar asy-keywords-version "2.78") (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 )) @@ -11,7 +11,7 @@ and controls tension atleast curl if else while for do return break continue str 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 Finite 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 abs2 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 bispline0 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 drawCylinder drawDisk drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawSphere drawTube 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 isometry 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 mapArray mapTemplate 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 notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory 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 phi4 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 render 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 simplexInit simplexPhase1 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 type 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 )) +AND Align 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 Finite 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 abs2 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 bispline0 bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte byteinv 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 drawCylinder drawDisk drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawSphere drawTube 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 graphwithderiv gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface importv3d 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 isometry 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 mapArray mapTemplate 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 notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory 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 phi4 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend primitive 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 render 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 simplexInit simplexPhase1 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 transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube type 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 Infinity 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 RELEASE 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 tubegranularity 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 )) +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 Infinity 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 MarkFillable 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 RELEASE 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 diamond 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 tubegranularity twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip v3dheadertypes v3dtypes version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding )) diff --git a/Master/texmf-dist/asymptote/asy-mode.el b/Master/texmf-dist/asymptote/asy-mode.el index ec3a3746d74..9f6eda793c7 100644 --- a/Master/texmf-dist/asymptote/asy-mode.el +++ b/Master/texmf-dist/asymptote/asy-mode.el @@ -110,7 +110,7 @@ Some variables can be customized: M-x customize-group <RET> asymptote <RET>." (require 'font-lock) (require 'cc-mode) -(require 'cl) ;; Common Lisp extensions for Emacs +(require 'cl-lib) ;; Common Lisp extensions for Emacs (require 'compile) (require 'wid-edit) @@ -637,6 +637,9 @@ Fields are defined as 'field1: field2.field3:field4' . Field=0 <-> all fields" (if (locate-library "two-mode-mode") (progn +;; patch two-mode-mode.el for Emacs >= 23. + (defun make-local-hook (func)) + (defvar lasy-fontify-asy-p nil "Variable to communicate with `font-lock-unfontify-region'. Internal use, don't set in any fashion.") @@ -682,7 +685,8 @@ the current mode." (setq lasy-fontify-asy-p (eq func 'asy-mode)) (funcall func) (hack-local-variables) - (two-mode-mode-setup) +;; avoid infinite loop in two-mode-mode +;; (two-mode-mode-setup) (if two-mode-switch-hook (run-hooks 'two-mode-switch-hook)) (if (eq font-lock-mode t) diff --git a/Master/texmf-dist/asymptote/asy.vim b/Master/texmf-dist/asymptote/asy.vim index 4cb897f1316..7d0983d07ce 100644 --- a/Master/texmf-dist/asymptote/asy.vim +++ b/Master/texmf-dist/asymptote/asy.vim @@ -1,7 +1,7 @@ " Vim syntax file -" Language: Asymptote -" Maintainer: Andy Hammerlindl -" Last Change: 2005 Aug 23 +" Language: Asymptote +" Maintainer: Andy Hammerlindl +" Last Change: 2022 Jan 05 " Hacked together from Bram Moolenaar's C syntax file, and Claudio Fleiner's " Java syntax file. @@ -9,132 +9,207 @@ " 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 + syn 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 +" useful C/C++/Java 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 + +" basic asymptote keywords +syn keyword asyConstant VERSION +syn keyword asyConstant true false default infinity inf nan +syn keyword asyConstant null nullframe nullpath nullpen +syn keyword asyConstant intMin intMax realMin realMax +syn keyword asyConstant realEpsilon realDigits +syn keyword asyPathSpec and cycle controls tension atleast curl +syn keyword asyStorageClass static public restricted private explicit +syn keyword asyStructure struct typedef +syn keyword asyType void bool bool3 int real string file +syn keyword asyType pair triple transform guide path pen frame +syn keyword asyType picture -"when wanted, highlight trailing white space -if exists("asy_space_errors") - if !exists("asy_no_trail_space_error") - syn match asySpaceError display excludenl "\s\+$" +" module specific keywords +if exists("asy_syn_plain") + syn keyword asyConstant currentpicture currentpen defaultpen + 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 CCW CW + syn keyword asyConstant undefined sqrtEpsilon Align mantissaBits + syn keyword asyConstant identity zeroTransform invert + syn keyword asyConstant stdin stdout + syn keyword asyConstant unitsquare unitcircle circleprecision + syn keyword asyConstant solid dotted 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 basealign nobasealign + syn keyword asyConstant black white gray red green blue Cyan Magenta + syn keyword asyConstant Yellow Black cyan magenta yellow palered + syn keyword asyConstant palegreen paleblue palecyan palemagenta + syn keyword asyConstant paleyellow palegray lightred lightgreen + syn keyword asyConstant lightblue lightcyan lightmagenta lightyellow + syn keyword asyConstant lightgray mediumred mediumgreen mediumblue + syn keyword asyConstant mediumcyan mediummagenta mediumyellow + syn keyword asyConstant mediumgray heavyred heavygreen heavyblue + syn keyword asyConstant heavycyan heavymagenta lightolive heavygray + syn keyword asyConstant deepred deepgreen deepblue deepcyan + syn keyword asyConstant deepmagenta deepyellow deepgray darkred + syn keyword asyConstant darkgreen darkblue darkcyan darkmagenta + syn keyword asyConstant darkolive darkgray orange fuchsia chartreuse + syn keyword asyConstant springgreen purple royalblue salmon brown + syn keyword asyConstant olive darkbrown pink palegrey lightgrey + syn keyword asyConstant mediumgrey grey heavygrey deepgrey darkgrey + + if exists("asy_syn_texcolors") + syn keyword asyConstant GreenYellow Yellow Goldenrod Dandelion + syn keyword asyConstant Apricot Peach Melon YellowOrange Orange + syn keyword asyConstant BurntOrange Bittersweet RedOrange Mahogany + syn keyword asyConstant Maroon BrickRed Red OrangeRed RubineRed + syn keyword asyConstant WildStrawberry Salmon CarnationPink Magenta + syn keyword asyConstant VioletRed Rhodamine Mulberry RedViolet + syn keyword asyConstant Fuchsia Lavender Thistle Orchid DarkOrchid + syn keyword asyConstant Purple Plum Violet RoyalPurple BlueViolet + syn keyword asyConstant Periwinkle CadetBlue CornflowerBlue + syn keyword asyConstant MidnightBlue NavyBlue RoyalBlue Blue + syn keyword asyConstant Cerulean Cyan ProcessBlue SkyBlue Turquoise + syn keyword asyConstant TealBlue Aquamarine BlueGreen Emerald + syn keyword asyConstant JungleGreen SeaGreen Green ForestGreen + syn keyword asyConstant PineGreen LimeGreen YellowGreen SpringGreen + syn keyword asyConstant OliveGreen RawSienna Sepia Brown Tan Gray + syn keyword asyConstant Black White endif - if !exists("asy_no_tab_space_error") - syn match asySpaceError display " \+\t"me=e-1 + + if exists("asy_syn_x11colors") + syn keyword asyConstant AliceBlue AntiqueWhite Aqua Aquamarine Azure + syn keyword asyConstant Beige Bisque Black BlanchedAlmond Blue + syn keyword asyConstant BlueViolet Brown BurlyWood CadetBlue + syn keyword asyConstant Chartreuse Chocolate Coral CornflowerBlue + syn keyword asyConstant Cornsilk Crimson Cyan DarkBlue DarkCyan + syn keyword asyConstant DarkGoldenrod DarkGray DarkGreen DarkKhaki + syn keyword asyConstant DarkMagenta DarkOliveGreen DarkOrange + syn keyword asyConstant DarkOrchid DarkRed DarkSalmon DarkSeaGreen + syn keyword asyConstant DarkSlateBlue DarkSlateGray DarkTurquoise + syn keyword asyConstant DarkViolet DeepPink DeepSkyBlue DimGray + syn keyword asyConstant DodgerBlue FireBrick FloralWhite ForestGreen + syn keyword asyConstant Fuchsia Gainsboro GhostWhite Gold Goldenrod + syn keyword asyConstant Gray Green GreenYellow Honeydew HotPink + syn keyword asyConstant IndianRed Indigo Ivory Khaki Lavender + syn keyword asyConstant LavenderBlush LawnGreen LemonChiffon + syn keyword asyConstant LightBlue LightCoral LightCyan + syn keyword asyConstant LightGoldenrodYellow LightGreen LightGrey + syn keyword asyConstant LightPink LightSalmon LightSeaGreen + syn keyword asyConstant LightSkyBlue LightSlateGray LightSteelBlue + syn keyword asyConstant LightYellow Lime LimeGreen Linen Magenta + syn keyword asyConstant Maroon MediumAquamarine MediumBlue + syn keyword asyConstant MediumOrchid MediumPurple MediumSeaGreen + syn keyword asyConstant MediumSlateBlue MediumSpringGreen + syn keyword asyConstant MediumTurquoise MediumVioletRed MidnightBlue + syn keyword asyConstant MintCream MistyRose Moccasin NavajoWhite + syn keyword asyConstant Navy OldLace Olive OliveDrab Orange + syn keyword asyConstant OrangeRed Orchid PaleGoldenrod PaleGreen + syn keyword asyConstant PaleTurquoise PaleVioletRed PapayaWhip + syn keyword asyConstant PeachPuff Peru Pink Plum PowderBlue Purple + syn keyword asyConstant Red RosyBrown RoyalBlue SaddleBrown Salmon + syn keyword asyConstant SandyBrown SeaGreen Seashell Sienna Silver + syn keyword asyConstant SkyBlue SlateBlue SlateGray Snow SpringGreen + syn keyword asyConstant SteelBlue Tan Teal Thistle Tomato Turquoise + syn keyword asyConstant Violet Wheat White WhiteSmoke Yellow + syn keyword asyConstant YellowGreen 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 "[);]" + if exists("asy_syn_three") + syn keyword asyType path3 guide3 transform3 + syn keyword asyType projection light material patch surface tube + syn keyword asyConstant currentprojection currentlight defaultrender + syn keyword asyConstant identity4 O X Y Z + syn keyword asyConstant nolight nullpens + syn keyword asyConstant unitsphere unithemisphere unitplane octant1 + syn keyword asyConstant unitcone unitsolidcone unitcube unitcylinder + syn keyword asyConstant unitdisk unittube + endif 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 +" string constants +syn region asyCString start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=asyCSpecial +syn match asyCSpecial display contained +\\\(['"?\\abfnrtv]\|\o\{1,3}\)+ +syn match asyCSpecial display contained +\\\(x[0-9A-F]\{1,2\}\|$\)+ +" double quoted strings only special character is \" +syn region asyString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=asySpecial +syn match asySpecial display contained +\(\\\)\@1<!\(\\\\\)*\zs\\"+ + + +" number constants +syn match asyNumbers display transparent "\<\d\|\.\d" + \ contains=asyNumber,asyNumberError +syn match asyNumber display contained "\d*\.\=\d*\(e[-+]\=\d\+\)\=" +" highlight number constants with two '.' or with '.' after an 'e' +syn match asyNumberError display contained "\d*\.\(\d\|e[-+]\=\)*\.[0-9.]*" +syn match asyNumberError display contained "\d*e[-+]\=\d*\.[0-9.]*" +syn match asyNumberError display contained "\d*e[-+]\=\(e[-+]\=\)*\.[0-9.]*" + + +" comments and comment strings +syn keyword asyTodo contained TODO FIXME XXX +syn sync ccomment asyComment minlines=15 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 + " A comment can contain asyString, asyCString, and asyNumber. But a "*/" + " inside a asy*String in a asyComment DOES end the comment! So we need to + " use a special type of asy*String: asyComment*String, 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 + syn match asyCommentSkip contained "^\s*\*\($\|\s\+\)" + syn region asyCommentString contained start=+"+ skip=+\\\\\|\\"+ end=+"+ + \ end=+\*/+me=s-1 + \ contains=asySpecial,asyCommentSkip + syn region asyCommentCString contained start=+'+ skip=+\\\\\|\\'+ end=+'+ + \ end=+\*/+me=s-1 + \ contains=asyCSpecial,asyCommentSkip + syn region asyCommentLString contained start=+"+ skip=+\\\\\|\\"+ end=+"+ + \ end="$" contains=asySpecial + syn region asyCommentLCString contained start=+'+ skip=+\\\\\|\\'+ end=+'+ + \ end="$" contains=asyCSpecial + syn region asyCommentL start="//" skip="\\$" end="$" keepend + \ contains=asyTodo,asyCommentLString, + \ asyCommentLCString,asyNumbers + syn region asyComment matchgroup=asyComment start="/\*" end="\*/" + \ contains=asyTodo,asyCommentStartError, + \ asyCommentString,asyCommentCString,asyNumbers else - syn region asyCommentL start="//" skip="\\$" end="$" keepend contains=@asyCommentGroup,asySpaceError - syn region asyComment matchgroup=asyCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@asyCommentGroup,asyCommentStartError,asySpaceError + syn region asyCommentL start="//" skip="\\$" end="$" keepend + \ contains=asyTodo + syn region asyComment matchgroup=asyComment start="/\*" end="\*/" + \ contains=asyTodo,asyCommentStartError 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 +" highlight common errors when starting/ending C comments +syn match asyCommentError display "\*/" +syn match asyCommentStartError display "/\*"me=e-1 contained -syn keyword asyStructure struct typedef -syn keyword asyStorageClass static public readable private explicit -syn keyword asyPathSpec and cycle controls tension atleast curl +" delimiter matching errors +syn region asyCurly transparent start='{' end='}' + \ contains=TOP,asyCurlyError +syn region asyBrack transparent start='\[' end='\]' matchgroup=asyError + \ end=';' contains=TOP,asyBrackError +syn region asyParen transparent start='(' end=')' matchgroup=asyError + \ end=';' contains=TOP,asyParenError +syn match asyCurlyError display '}' +syn match asyBrackError display '\]' +syn match asyParenError display ')' +" for (;;) constructs are exceptions that allow ; inside parenthesis +syn region asyParen transparent matchgroup=asyParen + \ start='\(for\s*\)\@<=(' end=')' + \ contains=TOP,asyParenError -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 @@ -147,56 +222,39 @@ if version >= 508 || !exists("did_asy_syn_inits") 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 - + HiLink asyCommentL asyComment + HiLink asyConditional Conditional + HiLink asyRepeat Repeat + HiLink asyNumber Number + HiLink asyNumberError asyError + HiLink asyCurlyError asyError + HiLink asyBracketError asyError + HiLink asyParenError asyError + HiLink asyCommentError asyError + HiLink asyCommentStartError asyError + HiLink asyOperator Operator + HiLink asyStructure Structure + HiLink asyStorageClass StorageClass + HiLink asyExternal Include + HiLink asyDefine Macro + HiLink asyError Error + HiLink asyStatement Statement + HiLink asyType Type + HiLink asyConstant Constant + HiLink asyCommentString asyString + HiLink asyCommentCString asyString + HiLink asyCommentLString asyString + HiLink asyCommentLCString asyString + HiLink asyCommentSkip asyComment + HiLink asyString String + HiLink asyCString String + HiLink asyComment Comment + HiLink asySpecial SpecialChar + HiLink asyCSpecial SpecialChar + HiLink asyTodo Todo + HiLink asyPathSpec Statement delcommand HiLink endif let b:current_syntax = "c" - -" vim: ts=8 diff --git a/Master/texmf-dist/asymptote/geometry.asy b/Master/texmf-dist/asymptote/geometry.asy index 420d5bdc456..9f4be8d15ca 100644 --- a/Master/texmf-dist/asymptote/geometry.asy +++ b/Master/texmf-dist/asymptote/geometry.asy @@ -6051,7 +6051,7 @@ triangle extouch(triangle t) return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/ +/*<asyxml><function type="triangle" signature="incentral(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 diff --git a/Master/texmf-dist/asymptote/graph.asy b/Master/texmf-dist/asymptote/graph.asy index 46a5d7d0647..1d4dfc1bfd3 100644 --- a/Master/texmf-dist/asymptote/graph.asy +++ b/Master/texmf-dist/asymptote/graph.asy @@ -2090,6 +2090,29 @@ guide polargraph(picture pic=currentpicture, real[] r, real[] theta, },0,0,n-1); } +// Graph a parametric function with the control points specified to match the +// derivative. +guide graphwithderiv(pair f(real), pair fprime(real), real a, real b, + int n=ngraph # 10) { + guide toreturn; + real segmentlen = (b - a) / n; + pair[] points = new pair[n+1]; + pair[] derivs = new pair[n+1]; + real derivfactor = segmentlen / 3; + for (int i = 0; i <= n; ++i) { + real t = interp(a, b, i/n); + points[i] = f(t); + derivs[i] = fprime(t) * derivfactor; + } + + toreturn = points[0]; + for (int i = 1; i <= n; ++i) { + toreturn = toreturn .. controls (points[i-1] + derivs[i-1]) + and (points[i] - derivs[i]) .. points[i]; + } + return toreturn; +} + void errorbar(picture pic, pair z, pair dp, pair dm, pen p=currentpen, real size=0) { diff --git a/Master/texmf-dist/asymptote/math.asy b/Master/texmf-dist/asymptote/math.asy index 3dde1b9dd4c..d0ce5233400 100644 --- a/Master/texmf-dist/asymptote/math.asy +++ b/Master/texmf-dist/asymptote/math.asy @@ -325,45 +325,45 @@ real interpolate(real[] x, real[] y, real 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 time(path g, real x, int n=0, real fuzz=-1) { - real[] t=times(g,x); + real[] t=times(g,x,fuzz); 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 time(path g, explicit pair z, int n=0, real fuzz=-1) { - real[] t=times(g,z); + real[] t=times(g,z,fuzz); 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) +real value(path g, real x, int n=0, real fuzz=-1) { - return point(g,time(g,x,n)).y; + return point(g,time(g,x,n,fuzz)).y; } // Return the nth x value of g at y=z.y. -real value(path g, explicit pair z, int n=0) +real value(path g, explicit pair z, int n=0, real fuzz=-1) { - return point(g,time(g,(0,z.y),n)).x; + return point(g,time(g,(0,z.y),n,fuzz)).x; } // Return the nth slope of g at x. -real slope(path g, real x, int n=0) +real slope(path g, real x, int n=0, real fuzz=-1) { - pair a=dir(g,time(g,x,n)); + pair a=dir(g,time(g,x,n,fuzz)); 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) +real slope(path g, explicit pair z, int n=0, real fuzz=-1) { - pair a=dir(g,time(g,(0,z.y),n)); + pair a=dir(g,time(g,(0,z.y),n,fuzz)); return a.y/a.x; } diff --git a/Master/texmf-dist/asymptote/palette.asy b/Master/texmf-dist/asymptote/palette.asy index 9923e5b3aaf..59cff39d729 100644 --- a/Master/texmf-dist/asymptote/palette.asy +++ b/Master/texmf-dist/asymptote/palette.asy @@ -65,7 +65,7 @@ pen[] adjust(picture pic, real min, real max, real rmin, real rmax, private real[] sequencereal; bounds image(picture pic=currentpicture, real[][] f, range range=Full, - pair initial, pair final, pen[] palette, + pair initial, pair final, pen[] palette, int divs=0, bool transpose=(initial.x < final.x && initial.y < final.y), bool copy=true, bool antialias=false) { @@ -74,6 +74,7 @@ bounds image(picture pic=currentpicture, real[][] f, range range=Full, 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); @@ -89,6 +90,21 @@ bounds image(picture pic=currentpicture, real[][] f, range range=Full, f[i]=map(new real(real x) {return T(min(max(x,m),M));},f[i]); } + if(divs > 0) { + int nx=f.length; + int ny=f[0].length; + real[][] data=new real[nx][ny]; + real incr=(M-m)/divs; + for(int i=0; i < nx; ++i) { + // Take center point of each bin + real[] fi=f[i]; + data[i]=sequence(new real(int j) { + return min(m+floor((fi[j]-m)/incr)*incr,M-incr); + },ny); + } + f=data; + } + initial=Scale(pic,initial); final=Scale(pic,final); @@ -109,13 +125,15 @@ bounds image(picture pic=currentpicture, real[][] f, range range=Full, 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) + int nx=ngraph, int ny=nx, pen[] palette, int divs=0, + 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)); @@ -125,7 +143,8 @@ bounds image(picture pic=currentpicture, real f(real, real), return f(Tinv(interp(xmin,xmax,(i+0.5)/nx)),y); },nx); } - return image(pic,data,range,initial,final,palette,transpose=false, + + return image(pic,data,range,initial,final,palette,divs,transpose=false, copy=false,antialias=antialias); } diff --git a/Master/texmf-dist/asymptote/patterns.asy b/Master/texmf-dist/asymptote/patterns.asy index 559e36cec11..de0fc02d039 100644 --- a/Master/texmf-dist/asymptote/patterns.asy +++ b/Master/texmf-dist/asymptote/patterns.asy @@ -13,7 +13,9 @@ frame tiling(string name, picture pic, pair lb=0, pair rt=0) /XStep "+format(s,pmax.x-pmin.x,"C")+" /YStep "+format(s,pmax.y-pmin.y,"C")+" /PaintProc {pop"); + gsave(tiling); add(tiling,f); + grestore(tiling); postscript(tiling,"} >> matrix makepattern /"+name+" exch def"); @@ -99,4 +101,3 @@ picture crosshatch(real H=5mm, pen p=currentpen) add(tiling,shift(H*sqrt(2))*rotate(90)*hatch(H,p)); return tiling; } - diff --git a/Master/texmf-dist/asymptote/plain.asy b/Master/texmf-dist/asymptote/plain.asy index 365aad02c74..cac6aa07222 100644 --- a/Master/texmf-dist/asymptote/plain.asy +++ b/Master/texmf-dist/asymptote/plain.asy @@ -150,7 +150,13 @@ void initdefaults() // Return the sequence n,...,m int[] sequence(int n, int m) { - return sequence(new int(int x){return x;},m-n+1)+n; + return n+sequence(m-n+1); +} + +// Return the sequence n,...,m skipping by skip +int[] sequence(int n, int m, int skip) +{ + return n+skip*sequence((m-n)#skip+1); } int[] reverse(int n) {return sequence(new int(int x){return n-1-x;},n);} diff --git a/Master/texmf-dist/asymptote/plain_boxes.asy b/Master/texmf-dist/asymptote/plain_boxes.asy index 50501a40897..9576caff554 100644 --- a/Master/texmf-dist/asymptote/plain_boxes.asy +++ b/Master/texmf-dist/asymptote/plain_boxes.asy @@ -28,7 +28,7 @@ path roundbox(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin, (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); @@ -81,7 +81,7 @@ typedef path envelope(frame dest, frame src=dest, real xmargin=0, 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) + pen p=currentpen, filltype filltype=NoFill, bool above=true) { object F; F.L=L.copy(); @@ -93,9 +93,9 @@ object object(Label L, envelope e, real xmargin=0, real ymargin=xmargin, return F; } -object draw(picture pic=currentpicture, Label L, envelope e, +object draw(picture pic=currentpicture, Label L, envelope e, real xmargin=0, real ymargin=xmargin, pen p=currentpen, - filltype filltype=NoFill, bool above=true) + filltype filltype=NoFill, bool above=true) { object F=object(L,e,xmargin,ymargin,p,filltype,above); pic.add(new void (frame f, transform t) { @@ -115,7 +115,7 @@ object draw(picture pic=currentpicture, Label L, envelope e, pair position, return draw(pic,Label(L,position),e,xmargin,ymargin,p,filltype,above); } -pair point(object F, pair dir, transform t=identity()) +pair point(object F, pair dir, transform t=identity()) { pair m=min(F.g); pair M=max(F.g); diff --git a/Master/texmf-dist/asymptote/plain_constants.asy b/Master/texmf-dist/asymptote/plain_constants.asy index 136b3540218..6cca1406cf7 100644 --- a/Master/texmf-dist/asymptote/plain_constants.asy +++ b/Master/texmf-dist/asymptote/plain_constants.asy @@ -31,9 +31,9 @@ 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 pair Align=sqrtEpsilon*NE; restricted int mantissaBits=ceil(-log(realEpsilon)/log(2))+1; restricted transform identity; @@ -108,7 +108,7 @@ void write(file file, string s="", bool3 b, suffix suffix=none) else write("default",suffix); } -void write(string s="", bool3 b, suffix suffix=endl) +void write(string s="", bool3 b, suffix suffix=endl) { write(stdout,s,b,suffix); } @@ -128,32 +128,32 @@ bool3 operator cast(bool b) return B; } -bool operator == (bool3 a, bool3 b) +bool operator == (bool3 a, bool3 b) { return a.set == b.set && (!a.set || (a.value == b.value)); } -bool operator != (bool3 a, bool3 b) +bool operator != (bool3 a, bool3 b) { return a.set != b.set || (a.set && (a.value != b.value)); } -bool operator == (bool3 a, bool b) +bool operator == (bool3 a, bool b) { return a.set && a.value == b; } -bool operator != (bool3 a, bool b) +bool operator != (bool3 a, bool b) { return !a.set || a.value != b; } -bool operator == (bool a, bool3 b) +bool operator == (bool a, bool3 b) { return b.set && b.value == a; } -bool operator != (bool a, bool3 b) +bool operator != (bool a, bool3 b) { return !b.set || b.value != a; } diff --git a/Master/texmf-dist/asymptote/plain_filldraw.asy b/Master/texmf-dist/asymptote/plain_filldraw.asy index 026f2cee6c5..eaf12571691 100644 --- a/Master/texmf-dist/asymptote/plain_filldraw.asy +++ b/Master/texmf-dist/asymptote/plain_filldraw.asy @@ -3,7 +3,7 @@ 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); @@ -88,7 +88,7 @@ void filloutside(frame f, path[] g, pen p=currentpen, bool copy=true) fill(f,complement(f,g),p+evenodd,copy); } -struct filltype +struct filltype { typedef void fill2(frame f, path[] g, pen fillpen); fill2 fill2; @@ -101,7 +101,7 @@ struct filltype 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; @@ -112,7 +112,7 @@ struct filltype void fill(frame f, path[] g, pen p) {fill2(f,g,p);} } -path[] margin(path[] g, real xmargin, real ymargin) +path[] margin(path[] g, real xmargin, real ymargin) { if(xmargin != 0 || ymargin != 0) { pair M=max(g); @@ -123,7 +123,7 @@ path[] margin(path[] g, real xmargin, real ymargin) 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; } @@ -174,7 +174,7 @@ filltype UnFill(real xmargin=0, real ymargin=xmargin) }); } -filltype FillDraw=FillDraw(), Fill=Fill(), Draw=Draw(), UnFill=UnFill(); +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. diff --git a/Master/texmf-dist/asymptote/plain_margins.asy b/Master/texmf-dist/asymptote/plain_margins.asy index fbd0163050c..c03b3a2b526 100644 --- a/Master/texmf-dist/asymptote/plain_margins.asy +++ b/Master/texmf-dist/asymptote/plain_margins.asy @@ -27,7 +27,7 @@ margin operator +(margin ma, margin mb) } margin NoMargin() -{ +{ return new marginT(path g, pen) { marginT margin; margin.begin=margin.end=0; @@ -35,9 +35,9 @@ margin NoMargin() return margin; }; } - + margin Margin(real begin, real end=begin) -{ +{ return new marginT(path g, pen p) { marginT margin; real factor=labelmargin(p); @@ -47,9 +47,9 @@ margin Margin(real begin, real end=begin) return margin; }; } - + margin PenMargin(real begin, real end=begin) -{ +{ return new marginT(path g, pen p) { marginT margin; real factor=linewidth(p); @@ -59,9 +59,9 @@ margin PenMargin(real begin, real end=begin) return margin; }; } - + margin DotMargin(real begin, real end=begin) -{ +{ return new marginT(path g, pen p) { marginT margin; real margindot(real x) {return x > 0 ? dotfactor*x : x;} @@ -72,9 +72,9 @@ margin DotMargin(real begin, real end=begin) return margin; }; } - + margin TrueMargin(real begin, real end=begin) -{ +{ return new marginT(path g, pen p) { marginT margin; margin.begin=begin; @@ -83,7 +83,7 @@ margin TrueMargin(real begin, real end=begin) return margin; }; } - + margin NoMargin=NoMargin(), BeginMargin=Margin(1,0), Margin=Margin(0,1), diff --git a/Master/texmf-dist/asymptote/plain_markers.asy b/Master/texmf-dist/asymptote/plain_markers.asy index 250e1701eb3..c6109d4e6ca 100644 --- a/Master/texmf-dist/asymptote/plain_markers.asy +++ b/Master/texmf-dist/asymptote/plain_markers.asy @@ -5,7 +5,7 @@ real legendmargin=10; real legendmaxrelativewidth=1; // Return a unit polygon with n sides. -path polygon(int n) +path polygon(int n) { guide g; for(int i=0; i < n; ++i) g=g--expi(2pi*(i+0.5)/n-0.5*pi); @@ -14,7 +14,7 @@ path polygon(int n) // 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) +path cross(int n, bool round=true, real r=0) { assert(n > 1); real r=min(r,1); @@ -41,7 +41,8 @@ path cross(int n, bool round=true, real r=0) return g--cycle; } -path[] plus=(-1,0)--(1,0)^^(0,-1)--(0,1); +path plus=rotate(45)*cross(4); +path diamond=rotate(45)*polygon(4); typedef void markroutine(picture pic=currentpicture, frame f, path g); @@ -98,9 +99,9 @@ struct marker { markroutine(pic,f,g); }; } - + marker marker(frame f=newframe, markroutine markroutine=marknodes, - bool above=true) + bool above=true) { marker m=new marker; m.f=f; @@ -147,15 +148,18 @@ real circlescale=0.85; path[] MarkPath={scale(circlescale)*unitcircle, polygon(3),polygon(4),polygon(5),invert*polygon(3), - cross(4),cross(6)}; + cross(4),cross(6),diamond,plus}; + +int[] MarkFillable={0,1,2,3,4,7}; 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[] MarkFill=sequence(new marker(int i) { + return marker(MarkPath[MarkFillable[i]],Fill); + },MarkFillable.length); -marker Mark(int n) +marker Mark(int n) { n=n % (Mark.length+MarkFill.length); if(n < Mark.length) return Mark[n]; @@ -194,7 +198,7 @@ picture legend(Legend[] Legend, int perline=1, real linelength, if(Legend.length == 0) return inset; - // Check for legend entries with lines: + // Check for legend entries with lines: bool bLineEntriesAvailable=false; for(int i=0; i < Legend.length; ++i) { if(Legend[i].p != invisible) { @@ -231,8 +235,8 @@ picture legend(Legend[] Legend, int perline=1, real linelength, totalwidth += size(pic).x; } } - // Does everything fit into one line? - if(((perline < 1) || (perline >= Legend.length)) && + // 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 @@ -285,7 +289,7 @@ 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 ? + real maxwidth=perline == 0 ? legendmaxrelativewidth*size(pic).x : 0, real maxheight=0, bool hstretch=false, bool vstretch=false, pen p=currentpen) { @@ -312,7 +316,7 @@ 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)); + real s=0.5*(dotsize(p)-linewidth(p)); if(s <= 0) return; path g=shift(z)*scale(s)*unitcircle; begingroup(f); @@ -398,4 +402,4 @@ marker dot(pen p=currentpen, filltype filltype=dotfilltype) } marker dot=dot(); - + diff --git a/Master/texmf-dist/asymptote/plain_paths.asy b/Master/texmf-dist/asymptote/plain_paths.asy index 8bb5250db5d..49d2f4ac0b5 100644 --- a/Master/texmf-dist/asymptote/plain_paths.asy +++ b/Master/texmf-dist/asymptote/plain_paths.asy @@ -51,32 +51,32 @@ path[] operator cast(guide g) return new path[] {(path) g}; } -path[] operator ^^ (path p, path q) +path[] operator ^^ (path p, path q) { return new path[] {p,q}; } -path[] operator ^^ (path p, explicit path[] q) +path[] operator ^^ (path p, explicit path[] q) { return concat(new path[] {p},q); } -path[] operator ^^ (explicit path[] p, path q) +path[] operator ^^ (explicit path[] p, path q) { return concat(p,new path[] {q}); } -path[] operator ^^ (explicit path[] p, explicit path[] q) +path[] operator ^^ (explicit path[] p, explicit path[] q) { return concat(p,q); } -path[] operator * (transform t, explicit path[] p) +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) +pair[] operator * (transform t, pair[] z) { return sequence(new pair(int i) {return t*z[i];},z.length); } @@ -93,7 +93,7 @@ void write(file file, string s="", explicit path[] x, suffix suffix=none) write(file,suffix); } -void write(string s="", explicit path[] x, suffix suffix=endl) +void write(string s="", explicit path[] x, suffix suffix=endl) { write(stdout,s,x,suffix); } @@ -110,7 +110,7 @@ void write(file file, string s="", explicit guide[] x, suffix suffix=none) write(file,suffix); } -void write(string s="", explicit guide[] x, suffix suffix=endl) +void write(string s="", explicit guide[] x, suffix suffix=endl) { write(stdout,s,x,suffix); } @@ -156,8 +156,8 @@ pair[] intersectionpoints(explicit path[] p, explicit path[] q, real fuzz=-1) struct slice { path before,after; } - -slice cut(path p, path knife, int n) + +slice cut(path p, path knife, int n) { slice s; real[][] T=intersections(p,knife); @@ -169,7 +169,7 @@ slice cut(path p, path knife, int n) return s; } -slice firstcut(path p, path knife) +slice firstcut(path p, path knife) { return cut(p,knife,0); } @@ -331,16 +331,16 @@ pair inside(path p, pen fillrule=currentpen) } // Return all intersection times of path g with the vertical line through (x,0). -real[] times(path p, real x) +real[] times(path p, real x, real fuzz=-1) { - return intersections(p,(x,0),(x,1)); + return intersections(p,(x,0),(x,1),fuzz); } // Return all intersection times of path g with the horizontal line through // (0,z.y). -real[] times(path p, explicit pair z) +real[] times(path p, explicit pair z, real fuzz=-1) { - return intersections(p,(0,z.y),(1,z.y)); + return intersections(p,(0,z.y),(1,z.y),fuzz); } path randompath(int n, bool cumulate=true, interpolate join=operator ..) @@ -349,7 +349,7 @@ path randompath(int n, bool cumulate=true, interpolate join=operator ..) pair w; for(int i=0; i <= n; ++i) { pair z=(unitrand()-0.5,unitrand()-0.5); - if(cumulate) w += z; + if(cumulate) w += z; else w=z; g=join(g,w); } diff --git a/Master/texmf-dist/asymptote/plain_pens.asy b/Master/texmf-dist/asymptote/plain_pens.asy index b8465696581..2e3a4449a38 100644 --- a/Master/texmf-dist/asymptote/plain_pens.asy +++ b/Master/texmf-dist/asymptote/plain_pens.asy @@ -8,7 +8,7 @@ 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) +pen linetype(string pattern, real offset=0, bool scale=true, bool adjust=true) { return linetype((real[]) split(pattern),offset,scale,adjust); } @@ -151,7 +151,7 @@ pen[] monoPen={solid,dashed,dotted,longdashed,dashdotted, longdashdotted}; monoPen.cyclic=true; -pen Pen(int n) +pen Pen(int n) { return (settings.gray || settings.bw) ? monoPen[n] : colorPen[n]; } @@ -161,12 +161,12 @@ pen Pentype(int n) return (settings.gray || settings.bw) ? monoPen[n] : monoPen[n]+colorPen[n]; } -real dotsize(pen p=currentpen) +real dotsize(pen p=currentpen) { return dotfactor*linewidth(p); } -pen fontsize(real size) +pen fontsize(real size) { return fontsize(size,1.2*size); } @@ -189,7 +189,7 @@ void usetypescript(string s, string encoding="") texpreamble(s); } -pen font(string name, string options="") +pen font(string name, string options="") { // Work around misalignment in ConTeXt switchtobodyfont if font is not found. return fontcommand(settings.tex == "context" ? @@ -199,7 +199,7 @@ pen font(string name, string options="") "\font\ASYfont="+name+"\ASYfont"); } -pen font(string name, real size, string options="") +pen font(string name, real size, string options="") { string s=(string) (size/pt)+"pt"; if(settings.tex == "context") @@ -207,7 +207,7 @@ pen font(string name, real size, string options="") return fontsize(size)+font(name+" at "+s); } -pen font(string encoding, string family, string series, string shape) +pen font(string encoding, string family, string series, string shape) { return fontcommand("\usefont{"+encoding+"}{"+family+"}{"+series+"}{"+shape+ "}"); @@ -316,16 +316,21 @@ real[] rgba(pen p) return a; } +pen rgb(real[] a) +{ + return rgb(a[0],a[1],a[2]); +} + 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) +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;} + real value(string s, int i) {return byteinv(hex(substr(s,2i+offset,2)));} return rgb(value(s,0),value(s,1),value(s,2)); } diff --git a/Master/texmf-dist/asymptote/plain_picture.asy b/Master/texmf-dist/asymptote/plain_picture.asy index c0c189ee691..13619e80aba 100644 --- a/Master/texmf-dist/asymptote/plain_picture.asy +++ b/Master/texmf-dist/asymptote/plain_picture.asy @@ -59,10 +59,10 @@ struct coords3 { } } } - + // scaleT and Legend <<< typedef real scalefcn(real x); - + struct scaleT { scalefcn T,Tinv; bool logarithmic; @@ -86,7 +86,7 @@ scaleT operator init() scaleT S=scaleT(identity,identity); return S; } - + typedef void boundRoutine(); struct autoscaleT { @@ -97,11 +97,11 @@ struct autoscaleT { 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(); @@ -120,7 +120,7 @@ struct ScaleT { autoscaleT x; autoscaleT y; autoscaleT z; - + ScaleT copy() { ScaleT dest=new ScaleT; dest.set=set; @@ -240,15 +240,15 @@ struct picture { // <<<1 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; @@ -267,14 +267,14 @@ struct picture { // <<<1 // 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(); @@ -283,7 +283,7 @@ struct picture { // <<<1 T3=identity(4); } init(); - + // Erase the current picture, retaining bounds. void clear() { nodes.delete(); @@ -300,7 +300,7 @@ struct picture { // <<<1 scale=new ScaleT; init(); } - + // Empty <<<2 bool empty2() { return nodes.length == 0; @@ -313,7 +313,7 @@ struct picture { // <<<1 bool empty() { return empty2() && empty3(); } - + // User min/max <<<2 pair userMin2() {return bounds.userMin(); } pair userMax2() {return bounds.userMax(); } @@ -373,27 +373,27 @@ struct picture { // <<<1 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; @@ -409,7 +409,7 @@ struct picture { // <<<1 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); @@ -419,7 +419,7 @@ struct picture { // <<<1 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) { @@ -462,7 +462,7 @@ struct picture { // <<<1 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; @@ -472,7 +472,7 @@ struct picture { // <<<1 else nodes.insert(0,node(d)); } - + // Faster implementation of most common case. void addExactAbove(drawerBound d) { uptodate=false; @@ -518,13 +518,13 @@ struct picture { // <<<1 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); @@ -618,7 +618,7 @@ struct picture { // <<<1 } void append(coords3 point, coords3 min, coords3 max, transform3 t, - bounds3 bounds) + bounds3 bounds) { // Add the coord info to this picture. if(t == identity4) { @@ -638,7 +638,7 @@ struct picture { // <<<1 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, @@ -660,9 +660,9 @@ struct picture { // <<<1 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); @@ -709,7 +709,7 @@ struct picture { // <<<1 triple m, triple M) { frame f; for(node3 n : nodes3) { - xasyKEY(n.key); + xasyKEY(nodes3[0].key); n.d(f,t,T0,pic,P,m,M); } return f; @@ -757,7 +757,7 @@ struct picture { // <<<1 frame f=fit(fixedscaling); pair d=size(f); static real epsilon=100*realEpsilon; - if(d.x > xsize*(1+epsilon)) + if(d.x > xsize*(1+epsilon)) warning("xlimit","frame exceeds xlimit: "+(string) d.x+" > "+ (string) xsize); if(d.y > ysize*(1+epsilon)) @@ -765,7 +765,7 @@ struct picture { // <<<1 (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, @@ -836,24 +836,24 @@ struct picture { // <<<1 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, @@ -880,7 +880,7 @@ struct picture { // <<<1 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); @@ -895,7 +895,7 @@ struct picture { // <<<1 // 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. + // 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); @@ -905,7 +905,7 @@ struct picture { // <<<1 } // Copying <<<2 - + // Copies enough information to yield the same userMin/userMax. void userCopy2(picture pic) { userMinx2(pic.userMin2().x); @@ -921,12 +921,12 @@ struct picture { // <<<1 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() { @@ -954,14 +954,14 @@ struct picture { // <<<1 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; } @@ -984,7 +984,7 @@ struct picture { // <<<1 dest.uptodate=uptodate; dest.bounds=bounds.transformed(t); dest.bounds3=bounds3.copy(); - + dest.bounds.exact=false; dest.xsize=xsize; dest.ysize=ysize; @@ -993,7 +993,7 @@ struct picture { // <<<1 dest.xunitsize=xunitsize; dest.yunitsize=yunitsize; dest.zunitsize=zunitsize; dest.fixed=fixed; dest.fixedscaling=fixedscaling; - + return dest; } @@ -1007,7 +1007,7 @@ struct picture { // <<<1 // 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(); @@ -1018,7 +1018,7 @@ struct picture { // <<<1 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) @@ -1026,13 +1026,13 @@ struct picture { // <<<1 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); @@ -1087,7 +1087,7 @@ void size3(picture pic=currentpicture, real x, real y=x, real z=y, pic.size3(x,y,z,keepAspect); } -void unitsize(picture pic=currentpicture, real x, real y=x, real z=y) +void unitsize(picture pic=currentpicture, real x, real y=x, real z=y) { pic.unitsize(x,y,z); } @@ -1113,14 +1113,14 @@ pair min(picture pic, bool user=false) 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(); @@ -1132,7 +1132,7 @@ pair size(picture pic, bool user=false) } // Frame Alignment <<< -pair rectify(pair dir) +pair rectify(pair dir) { real scale=max(abs(dir.x),abs(dir.y)); if(scale != 0) dir *= 0.5/scale; @@ -1161,13 +1161,13 @@ path[] align(path[] g, transform t=identity(), pair position, } // Returns a transform for aligning frame f in the direction align -transform shift(frame f, pair 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) +frame align(frame f, pair align) { return shift(f,align)*f; } @@ -1448,7 +1448,7 @@ void clip(picture pic=currentpicture, path[] g, bool stroke=false, } void beginclip(picture pic=currentpicture, path[] g, bool stroke=false, - pen fillrule=currentpen, bool copy=true) + pen fillrule=currentpen, bool copy=true) { if(copy) g=copy(g); @@ -1505,7 +1505,7 @@ void filloutside(picture pic=currentpicture, path[] g, pen p=currentpen, pic.addPath(g); } -// Use a fixed scaling to map user coordinates in box(min,max) to the +// 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) @@ -1671,7 +1671,7 @@ void begin(picture pic=currentpicture, string name, string id="", void end(picture pic=currentpicture) { if(!latex() || !pdf()) return; - tex(pic,"\end{ocg}"); + tex(pic,"\end{ocg}%"); layer(pic); } diff --git a/Master/texmf-dist/asymptote/plain_prethree.asy b/Master/texmf-dist/asymptote/plain_prethree.asy index 968ae2943a6..88663962557 100644 --- a/Master/texmf-dist/asymptote/plain_prethree.asy +++ b/Master/texmf-dist/asymptote/plain_prethree.asy @@ -76,7 +76,7 @@ struct projection { 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() { @@ -137,8 +137,8 @@ struct projection { (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); @@ -161,7 +161,7 @@ projection currentprojection; struct light { real[][] diffuse; - real[][] specular; + real[][] specular; // For PRC only pen background=nullpen; // Background color of the 3D canvas. real specularfactor; triple[] position; // Only directional lights are currently implemented. @@ -169,14 +169,14 @@ struct light { 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; @@ -213,4 +213,3 @@ struct light { } light currentlight; - diff --git a/Master/texmf-dist/asymptote/plain_scaling.asy b/Master/texmf-dist/asymptote/plain_scaling.asy index 5bed3338e9b..4c6beae655d 100644 --- a/Master/texmf-dist/asymptote/plain_scaling.asy +++ b/Master/texmf-dist/asymptote/plain_scaling.asy @@ -19,7 +19,7 @@ struct coord { coord copy() { return build(user, truesize); } - + void clip(real min, real max) { user=min(max(user,min),max); truesize=0; @@ -47,7 +47,7 @@ coord[] maxcoords(coord[] in, bool operator <= (coord,coord)) coord[] c; int n=in.length; - + if(n == 0) return c; @@ -151,15 +151,15 @@ struct coords2 { } } void xclip(real min, real max) { - for(int i=0; i < x.length; ++i) + 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) + 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; @@ -211,7 +211,7 @@ real calculateScaling(string dir, coord[] m, coord[] M, real size, // (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}); @@ -239,12 +239,12 @@ real calculateScaling(string dir, coord[] m, coord[] M, real size, 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); } } diff --git a/Master/texmf-dist/asymptote/plain_shipout.asy b/Master/texmf-dist/asymptote/plain_shipout.asy index 388a03a557b..fcc7f8e28a6 100644 --- a/Master/texmf-dist/asymptote/plain_shipout.asy +++ b/Master/texmf-dist/asymptote/plain_shipout.asy @@ -11,7 +11,7 @@ string outprefix(string prefix=defaultfilename) { return stripextension(prefix != "" ? prefix : outname()); } -string outformat(string format="") +string outformat(string format="") { if(format == "") format=settings.outformat; if(format == "") format=nativeformat(); @@ -32,6 +32,10 @@ object embed3(string, frame, string, string, string, light, projection); string Embed(string name, string text="", string options="", real width=0, real height=0); +bool primitive() { // Encode primitive objects + return settings.outformat == "html" || settings.outformat=="v3d"; +} + bool prconly(string format="") { return outformat(format) == "prc"; @@ -39,7 +43,7 @@ bool prconly(string format="") bool prc0(string format="") { - return settings.prc && (outformat(format) == "pdf" || prconly() || settings.inlineimage ); + return settings.outformat == "prc" || (settings.prc && (outformat(format) == "pdf" || prconly() || settings.inlineimage )); } bool prc(string format="") { @@ -62,6 +66,14 @@ frame enclose(string prefix=defaultfilename, object F, string format="") void deconstruct(picture pic=currentpicture) { + if(currentpicture.nodes3.length > 0) { + if(currentpicture.xsize3 == 0 && + currentpicture.ysize3 == 0 && + currentpicture.zsize3 == 0) + currentpicture.size3(hypot(currentpicture.xsize,currentpicture.ysize)); + currentpicture.size(0); + } + frame f; transform t=pic.calculateTransform(); if(currentpicture.fitter == null) @@ -95,7 +107,7 @@ void shipout(string prefix=defaultfilename, frame f, } return; } - + // Applications like LaTeX cannot handle large PostScript coordinates. pair m=min(f); int limit=2000; diff --git a/Master/texmf-dist/asymptote/plain_strings.asy b/Master/texmf-dist/asymptote/plain_strings.asy index a5158614931..2e291f102fa 100644 --- a/Master/texmf-dist/asymptote/plain_strings.asy +++ b/Master/texmf-dist/asymptote/plain_strings.asy @@ -49,13 +49,13 @@ triple gettriple(string name="", triple default=(0,0,0), string prompt="", // returns a string with all occurrences of string 'before' in string 's' // changed to string 'after'. -string replace(string s, string before, 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) +string TeXify(string s) { static string[][] t={{"&","\&"},{"%","\%"},{"_","\_"},{"#","\#"},{"<","$<$"}, {">","$>$"},{"|","$|$"},{"^","$\hat{\ }$"}, @@ -68,7 +68,7 @@ private string[][] trans1={{'\\',"\backslash "}, private string[][] trans2={{"\backslash ","$\backslash$"}}; // Convert string to TeX -string texify(string s) +string texify(string s) { return TeXify(replace(replace(s,trans1),trans2)); } @@ -93,7 +93,7 @@ string[] split(string s, string delimiter="") prune=true; delimiter=" "; } - + string[] S; int last=0; int i; @@ -130,7 +130,7 @@ string operator +(...string[] a) return S; } -int system(string s) +int system(string s) { return system(split(s)); } @@ -161,8 +161,8 @@ string italic(string s) return s != "" ? "{\it "+s+"}" : s; } -string baseline(string s, string template="\strut") -{ +string baseline(string s, string template="\strut") +{ return s != "" && settings.tex != "none" ? "\vphantom{"+template+"}"+s : s; } @@ -171,7 +171,7 @@ string math(string s) return s != "" ? "$"+s+"$" : s; } -private void notimplemented(string text) +private void notimplemented(string text) { abort(text+" is not implemented for the '"+settings.tex+"' TeX engine"); } @@ -217,7 +217,7 @@ void usepackage(string s, string options="") texpreamble(usepackage+"{"+s+"}"); } -void pause(string w="Hit enter to continue") +void pause(string w="Hit enter to continue") { write(w); w=stdin; diff --git a/Master/texmf-dist/asymptote/pstoedit.asy b/Master/texmf-dist/asymptote/pstoedit.asy index 7baccd3ed69..8bd67e09112 100644 --- a/Master/texmf-dist/asymptote/pstoedit.asy +++ b/Master/texmf-dist/asymptote/pstoedit.asy @@ -15,4 +15,4 @@ void grestore(picture pic=currentpicture) grestore(f); },true); } - + diff --git a/Master/texmf-dist/asymptote/rational.asy b/Master/texmf-dist/asymptote/rational.asy index a120c141232..aac3d5be9b1 100644 --- a/Master/texmf-dist/asymptote/rational.asy +++ b/Master/texmf-dist/asymptote/rational.asy @@ -11,7 +11,7 @@ int gcd(int m, int n) int r=m % n; m=n; n=r; - } + } return m; } diff --git a/Master/texmf-dist/asymptote/roundedpath.asy b/Master/texmf-dist/asymptote/roundedpath.asy index 1a426f91dcb..0029447327c 100644 --- a/Master/texmf-dist/asymptote/roundedpath.asy +++ b/Master/texmf-dist/asymptote/roundedpath.asy @@ -1,7 +1,7 @@ // a function to round sharp edges of open and cyclic paths // written by stefan knorr -path roundedpath(path A, real R, real S = 1) +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 @@ -9,20 +9,20 @@ path roundedpath(path A, real R, real S = 1) 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' + + 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' + 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 + // 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 @@ -36,23 +36,23 @@ path roundedpath(path A, real R, real S = 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 + // 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 + // final steps to have a correct termination if(PathClosed) { // Is 'A' cyclic? - // straight subpath towards 0-th edge + // 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); @@ -65,15 +65,15 @@ path roundedpath(path A, real R, real S = 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 + // 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; diff --git a/Master/texmf-dist/asymptote/shaders/blend.glsl b/Master/texmf-dist/asymptote/shaders/blend.glsl new file mode 100755 index 00000000000..629cc2dda5e --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/blend.glsl @@ -0,0 +1,131 @@ +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +layout(binding=3, std430) buffer fragmentBuffer { + vec4 fragment[]; +}; + +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; +}; + +out vec4 outColor; + +uniform uint width; +uniform uint M; +uniform uint r; +uniform vec4 background; + +vec4 blend(vec4 outColor, vec4 color) +{ + return mix(outColor,color,color.a); +} + +void main() +{ + uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); + uint size=count[headIndex]; + float OpaqueDepth=opaqueDepth[headIndex]; + if(size == 0u) { +#ifdef GPUINDEXING + offset[headIndex]=0u; +#endif + opaqueDepth[headIndex]=0.0; + discard; + } + + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]; + const uint maxSize=16u; + + // Sort the fragments with respect to descending depth + if(size < maxSize) { + vec4 sortedColor[maxSize]; + float sortedDepth[maxSize]; + + uint k=0u; + + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + + uint i=0u; + if(k < size) { + sortedColor[0]=fragment[listIndex+k]; + sortedDepth[0]=depth[listIndex+k]; + ++k; + i=1u; + while(true) { + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + if(k == size) break; + float D=depth[listIndex+k]; + uint j=i; + float d; + while(j > 0u && D > sortedDepth[j-1u]) { + sortedColor[j]=sortedColor[j-1u]; + sortedDepth[j]=sortedDepth[j-1u]; + --j; + } + sortedColor[j]=fragment[listIndex+k]; + sortedDepth[j]=D; + ++i; + ++k; + } + } + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + for(uint j=0u; j < i; ++j) + outColor=blend(outColor,sortedColor[j]); + } else { + uint k=0u; + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + for(uint i=k+1u; i < size; i++) { + vec4 temp=fragment[listIndex+i]; + float D=depth[listIndex+i]; + uint j=i; + while(j > 0u && D > depth[listIndex+j-1u]) { + fragment[listIndex+j]=fragment[listIndex+j-1u]; + depth[listIndex+j]=depth[listIndex+j-1u]; + --j; + } + fragment[listIndex+j]=temp; + depth[listIndex+j]=D; + } + + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + uint stop=listIndex+size; + for(uint i=listIndex+k; i < stop; i++) { + if(OpaqueDepth == 0.0 || depth[i] < OpaqueDepth) + outColor=blend(outColor,fragment[i]); + } + } + + count[headIndex]=0u; + opaqueDepth[headIndex]=0.0; +#ifdef GPUINDEXING + offset[headIndex]=0u; +#endif +} diff --git a/Master/texmf-dist/asymptote/shaders/count.glsl b/Master/texmf-dist/asymptote/shaders/count.glsl new file mode 100755 index 00000000000..dae4e51f1b7 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/count.glsl @@ -0,0 +1,11 @@ +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +uniform uint width; + +void main() +{ + atomicAdd(count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)],1u); + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/count0.glsl b/Master/texmf-dist/asymptote/shaders/count0.glsl new file mode 100755 index 00000000000..9bcb6d222e5 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/count0.glsl @@ -0,0 +1,11 @@ +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +uniform uint width; + +void main() +{ + count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)]=0u; + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/fragment.glsl b/Master/texmf-dist/asymptote/shaders/fragment.glsl index 057acbc744f..5f60a56efd3 100755 --- a/Master/texmf-dist/asymptote/shaders/fragment.glsl +++ b/Master/texmf-dist/asymptote/shaders/fragment.glsl @@ -10,25 +10,13 @@ struct Light vec3 color; }; -uniform int nlights; +uniform uint nlights; uniform Light lights[max(Nlights,1)]; uniform MaterialBuffer { Material Materials[Nmaterials]; }; -#ifdef NORMAL -#ifndef ORTHOGRAPHIC -in vec3 ViewPosition; -#endif -in vec3 Normal; -vec3 normal; -#endif - -#ifdef COLOR -in vec4 Color; -#endif - flat in int materialIndex; out vec4 outColor; @@ -38,41 +26,107 @@ vec3 Specular; // Specular tint for nonmetals float Metallic; // Metallic/Nonmetals parameter float Fresnel0; // Fresnel at zero for nonmetals float Roughness2; // roughness squared, for smoothing +float Roughness; + +#ifdef HAVE_SSBO + +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; -#ifdef ENABLE_TEXTURE -uniform sampler2D environmentMap; -const float PI=acos(-1.0); -const float twopi=2*PI; -const float halfpi=PI/2; +layout(binding=3, std430) buffer fragmentBuffer { + vec4 fragment[]; +}; -const int numSamples=7; +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; +}; + +uniform uint width; +uniform uint M; +uniform uint r; +#endif + +#ifdef NORMAL + +#ifndef ORTHOGRAPHIC +in vec3 ViewPosition; +#endif +in vec3 Normal; +vec3 normal; + +#ifdef USE_IBL +uniform sampler2D reflBRDFSampler; +uniform sampler2D diffuseSampler; +uniform sampler3D reflImgSampler; + +const float pi=acos(-1.0); +const float piInv=1.0/pi; +const float twopi=2.0*pi; +const float twopiInv=1.0/twopi; // (x,y,z) -> (r,theta,phi); -// theta -> [0,\pi]: colatitude -// phi -> [0, 2\pi]: longitude +// theta -> [0,pi]: colatitude +// phi -> [-pi,pi]: longitude vec3 cart2sphere(vec3 cart) { - float x=cart.z; - float y=cart.x; + float x=cart.x; + float y=cart.z; float z=cart.y; float r=length(cart); + float theta=r > 0.0 ? acos(z/r) : 0.0; float phi=atan(y,x); - float theta=acos(z/r); - return vec3(r,phi,theta); + return vec3(r,theta,phi); } vec2 normalizedAngle(vec3 cartVec) { vec3 sphericalVec=cart2sphere(cartVec); - sphericalVec.y=sphericalVec.y/(2*PI)-0.25; - sphericalVec.z=sphericalVec.z/PI; - return sphericalVec.yz; + sphericalVec.y=sphericalVec.y*piInv; + sphericalVec.z=0.75-sphericalVec.z*twopiInv; + + return sphericalVec.zy; } -#endif -#ifdef NORMAL +vec3 IBLColor(vec3 viewDir) +{ + // + // based on the split sum formula approximation + // L(v)=\int_\Omega L(l)f(l,v) \cos \theta_l + // which, by the split sum approiximation (assuming independence+GGX distrubition), + // roughly equals (within a margin of error) + // [\int_\Omega L(l)] * [\int_\Omega f(l,v) \cos \theta_l]. + // the first term is the reflectance irradiance integral + + vec3 IBLDiffuse=Diffuse*texture(diffuseSampler,normalizedAngle(normal)).rgb; + vec3 reflectVec=normalize(reflect(-viewDir,normal)); + vec2 reflCoord=normalizedAngle(reflectVec); + vec3 IBLRefl=texture(reflImgSampler,vec3(reflCoord,Roughness)).rgb; + vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),Roughness)).rg; + float specularMultiplier=Fresnel0*IBLbrdf.x+IBLbrdf.y; + vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl; + vec3 metal=Diffuse*IBLRefl; + return mix(dielectric,metal,Metallic); +} +#else // h is the halfway vector between normal and light direction // GGX Trowbridge-Reitz Approximation float NDF_TRG(vec3 h) @@ -122,18 +176,24 @@ vec3 BRDF(vec3 viewDirection, vec3 lightDirection) vec3 dielectric=mix(lambertian,rawReflectance*Specular,F); vec3 metal=rawReflectance*Diffuse; - + return mix(dielectric,metal,Metallic); } #endif +#endif + +#ifdef COLOR +in vec4 Color; +#endif + void main() { vec4 diffuse; vec4 emissive; Material m; -#ifdef TRANSPARENT +#ifdef GENERAL m=Materials[abs(materialIndex)-1]; emissive=m.emissive; if(materialIndex >= 0) @@ -150,18 +210,18 @@ void main() #ifdef COLOR diffuse=Color; #if Nlights == 0 - emissive += Color; + emissive += Color; #endif -#else - diffuse=m.diffuse; +#else + diffuse=m.diffuse; #endif #endif - + #if defined(NORMAL) && Nlights > 0 Specular=m.specular.rgb; vec4 parameters=m.parameters; - Roughness2=1.0-parameters[0]; - Roughness2=Roughness2*Roughness2; + Roughness=1.0-parameters[0]; + Roughness2=Roughness*Roughness; Metallic=parameters[1]; Fresnel0=parameters[2]; Diffuse=diffuse.rgb; @@ -178,50 +238,51 @@ void main() #else vec3 viewDir=-normalize(ViewPosition); #endif + vec3 color; +#ifdef USE_IBL + color=IBLColor(viewDir); +#else // For a finite point light, the rendering equation simplifies. - vec3 color=emissive.rgb; - for(int i=0; i < nlights; ++i) { + color=emissive.rgb; + for(uint i=0u; i < nlights; ++i) { Light Li=lights[i]; vec3 L=Li.direction; float cosTheta=max(dot(normal,L),0.0); // $\omega_i \cdot n$ term vec3 radiance=cosTheta*Li.color; color += BRDF(viewDir,L)*radiance; } - -#if defined(ENABLE_TEXTURE) && !defined(COLOR) - // Experimental environment radiance using Riemann sums; - // can also do importance sampling. - vec3 envRadiance=vec3(0.0,0.0,0.0); - - vec3 normalPerp=vec3(-normal.y,normal.x,0.0); - if(length(normalPerp) == 0.0) - normalPerp=vec3(1.0,0.0,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; - color += envRadiance.rgb; #endif outColor=vec4(color,diffuse.a); -#else +#else outColor=emissive; -#endif +#endif + +#ifndef WIDTH +#ifdef HAVE_SSBO + uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); +#if defined(TRANSPARENT) || (!defined(HAVE_INTERLOCK) && !defined(OPAQUE)) + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]+atomicAdd(count[headIndex],1u); + fragment[listIndex]=outColor; + depth[listIndex]=gl_FragCoord.z; +#ifndef WIREFRAME + discard; +#endif +#else +#ifndef OPAQUE +#ifdef HAVE_INTERLOCK +beginInvocationInterlockARB(); +if(opaqueDepth[headIndex] == 0.0 || gl_FragCoord.z < opaqueDepth[headIndex]) { + opaqueDepth[headIndex]=gl_FragCoord.z; + opaqueColor[headIndex]=outColor; +} +endInvocationInterlockARB(); +#endif +#endif +#endif +#endif +#endif } diff --git a/Master/texmf-dist/asymptote/shaders/offset.glsl b/Master/texmf-dist/asymptote/shaders/offset.glsl new file mode 100755 index 00000000000..5fe24e75587 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/offset.glsl @@ -0,0 +1,11 @@ +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +uniform uint width; + +void main() +{ + atomicAdd(offset[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)+1u],1u); + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/partialsum.glsl b/Master/texmf-dist/asymptote/shaders/partialsum.glsl new file mode 100755 index 00000000000..d00195bb3ae --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/partialsum.glsl @@ -0,0 +1,37 @@ +layout(local_size_x=PROCESSORS) in; + +uniform uint elements; + +layout(binding=0, std430) buffer sumBuffer +{ + uint sum[]; +}; + +shared uint sharedData[PROCESSORS]; + +void main(void) +{ + uint id=gl_LocalInvocationID.x; + sharedData[id]=sum[id+1u]; + + barrier(); + + uint index=id << 1u; + sharedData[index+1u] += sharedData[index]; + barrier(); + for(uint step=1u; step < STEPSM1; step++) { + uint mask=(1u << step)-1u; + uint index=((id >> step) << (step+1u))+mask; + uint windex=index+(id&mask)+1u; + sharedData[windex] += sharedData[index]; + barrier(); + } + uint mask=(1u << STEPSM1)-1u; + index=((id >> STEPSM1) << (STEPSM1+1u))+mask; + uint windex=index+(id&mask)+1u; + if(windex < PROCESSORS) + sharedData[windex] += sharedData[index]; + barrier(); + + sum[id+1u]=sharedData[id]; +} diff --git a/Master/texmf-dist/asymptote/shaders/presum.glsl b/Master/texmf-dist/asymptote/shaders/presum.glsl new file mode 100755 index 00000000000..5b0a8df89e0 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/presum.glsl @@ -0,0 +1,37 @@ +layout(local_size_x=1) in; + +uniform uint elements; + +layout(binding=0, std430) buffer sumBuffer +{ + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer +{ + uint offset[]; +}; + +void main(void) +{ + uint id=gl_GlobalInvocationID.x; + + uint m=elements/gl_NumWorkGroups.x; + uint r=elements-m*gl_NumWorkGroups.x; + uint row,stop; + if(id < r) { + row=m*id+id; + stop=row+m+1u; + } else { + row=m*id+r; + stop=row+m; + } + + uint Sum=offset[row]; + for(uint i=row+1u; i < stop; ++i) { + Sum += offset[i]; + offset[i]=Sum; + } + + sum[id+1u]=Sum; +} diff --git a/Master/texmf-dist/asymptote/shaders/screen.glsl b/Master/texmf-dist/asymptote/shaders/screen.glsl new file mode 100755 index 00000000000..9e8611a7270 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/screen.glsl @@ -0,0 +1,5 @@ +void main() +{ + vec2 vertices[3]=vec2[3](vec2(-1,-1),vec2(3,-1),vec2(-1, 3)); + gl_Position = vec4(vertices[gl_VertexID],0,1); +} diff --git a/Master/texmf-dist/asymptote/shaders/vertex.glsl b/Master/texmf-dist/asymptote/shaders/vertex.glsl index 4b2a54b9897..42623ccef6e 100755 --- a/Master/texmf-dist/asymptote/shaders/vertex.glsl +++ b/Master/texmf-dist/asymptote/shaders/vertex.glsl @@ -1,16 +1,22 @@ in vec3 position; -uniform mat3 normMat; - #ifdef NORMAL + #ifndef ORTHOGRAPHIC +uniform mat4 viewMat; out vec3 ViewPosition; #endif + +uniform mat3 normMat; in vec3 normal; out vec3 Normal; + #endif +#ifdef MATERIAL in int material; +flat out int materialIndex; +#endif #ifdef COLOR in vec4 color; @@ -22,9 +28,6 @@ in float width; #endif uniform mat4 projViewMat; -uniform mat4 viewMat; - -flat out int materialIndex; void main() { @@ -45,5 +48,7 @@ void main() gl_PointSize=width; #endif +#ifdef MATERIAL materialIndex=material; +#endif } diff --git a/Master/texmf-dist/asymptote/simplex.asy b/Master/texmf-dist/asymptote/simplex.asy index e6d0410b23c..3bc74635dbb 100644 --- a/Master/texmf-dist/asymptote/simplex.asy +++ b/Master/texmf-dist/asymptote/simplex.asy @@ -219,7 +219,7 @@ struct simplex { basicValues(); iterate(E,n+k,Bindices); - + if(abs(Em[0]) > EpsilonA) { case=INFEASIBLE; return; @@ -249,7 +249,7 @@ struct simplex { for(int i=0; i < m; ++i) { int k=Bindices[i]; if(k > n) continue; - Bindices[ip]=k; + Bindices[ip]=k; cB[ip]=c[k-1]; real[] Dip=D[ip]; real[] Ei=E[i]; @@ -319,7 +319,7 @@ struct simplex { ai[j]=Ai[j]; } } - + int k=0; bool phase1=false; diff --git a/Master/texmf-dist/asymptote/slide.asy b/Master/texmf-dist/asymptote/slide.asy index 9d26c680652..a6959537686 100644 --- a/Master/texmf-dist/asymptote/slide.asy +++ b/Master/texmf-dist/asymptote/slide.asy @@ -32,7 +32,7 @@ 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); @@ -55,7 +55,7 @@ real titleskip=0.5; string oldbulletcolor; string newbulletcolor="red"; string bullet="{\bulletcolor\textbullet}"; - + pair pagenumberposition=S+E; pair pagenumberalign=4NW; pen pagenumberpen=fontsize(12); @@ -90,7 +90,7 @@ bool empty() return currentpicture.nodes.length <= preamblenodes; } -void background() +void background() { if(!background.empty()) { add(background); @@ -197,7 +197,7 @@ void nextpage(pen p=pagenumberpen) firststep=true; } -void newslide(bool stepping=true) +void newslide(bool stepping=true) { allowstepping=stepping; nextpage(); @@ -264,11 +264,11 @@ void outline(string s="Outline", pair position=N, pair align=titlealign, 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) + filltype filltype=NoFill, bool step=false) { checkposition(); if(minipage) s=minipage(s,minipagewidth); - + pair offset; if(center) { if(align == 0) align=S; @@ -277,12 +277,12 @@ void remark(bool center=false, string s, pair align=0, pen p=itempen, 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); @@ -399,7 +399,7 @@ void display(string s, string caption="", pair align=S, pen p=itempen, display(new string[] {s},caption,align,p,figuremattpen, final); } -void figure(string[] s, string options="", real margin=0, +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) @@ -435,7 +435,7 @@ void multifigure(string[] slist, string options="", string caption="", firststep=false; } -void indexedfigure(string prefix, int first, int last, +void indexedfigure(string prefix, int first, int last, string options="", string caption="", pair align=S, pen p=itempen, pen figuremattpen=figuremattpen, bool step=itemstep) @@ -473,7 +473,7 @@ string cropcode(string s) void code(bool center=false, string s, pen p=codepen, real indent=0, real skip=codeskip, - filltype filltype=NoFill) + filltype filltype=NoFill) { remark(center,"{\tt "+verbatim(cropcode(s))+"}",p,indent,skip,filltype); } @@ -569,7 +569,7 @@ void bibliographystyle(string name) texpreamble("\bibliographystyle{"+name+"}"); } -void bibliography(string name) +void bibliography(string name) { numberpage(); havepagenumber=false; diff --git a/Master/texmf-dist/asymptote/slopefield.asy b/Master/texmf-dist/asymptote/slopefield.asy index e87e2cd36f9..c36ee4d9d01 100644 --- a/Master/texmf-dist/asymptote/slopefield.asy +++ b/Master/texmf-dist/asymptote/slopefield.asy @@ -16,7 +16,7 @@ picture slopefield(real f(real,real), pair a, pair b, 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); + draw(pic,(cp.x-mp,cp.y-mp*slope)--(cp.x+mp,cp.y+mp*slope),p,arrow); } } return pic; @@ -29,12 +29,12 @@ picture slopefield(real f(real), pair a, pair b, 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) +path curve(pair c, real f(real,real), pair a, pair b) { - real step=stepfraction*(b.x-a.x); + 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; diff --git a/Master/texmf-dist/asymptote/smoothcontour3.asy b/Master/texmf-dist/asymptote/smoothcontour3.asy index be6f900a4d1..c39d0a3f3d6 100644 --- a/Master/texmf-dist/asymptote/smoothcontour3.asy +++ b/Master/texmf-dist/asymptote/smoothcontour3.asy @@ -1,11 +1,11 @@ // 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. @@ -72,7 +72,7 @@ patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals, 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); @@ -217,7 +217,7 @@ patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals, + "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)); @@ -268,7 +268,7 @@ patch trianglewithnormals(path3 external, triple n1, 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}, @@ -591,7 +591,7 @@ triple projecttospan(triple toproject, triple v1, triple v2, 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); @@ -802,7 +802,7 @@ patch[] triangletoquads(path3 external, real f(triple), triple grad(triple), return new patch[] {patchwithnormals(quad0, grad), patchwithnormals(quad1, grad), - patchwithnormals(quad2, grad)}; + patchwithnormals(quad2, grad)}; } // Attempts to fill the path external (which should by a cyclic path consisting of @@ -837,7 +837,7 @@ patch[] maketriangle(path3 external, real f(triple), 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); @@ -855,7 +855,7 @@ patch[] maketriangle(path3 external, real f(triple), 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]; @@ -913,7 +913,7 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners, // 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) { @@ -948,7 +948,7 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners, return null; } } - + if (length(edgecycle) == 3) { patch[] toreturn = usetriangles ? maketriangle(edgecycle, f, grad) : triangletoquads(edgecycle, f, grad, a, b); @@ -961,12 +961,12 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners, 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; @@ -1328,7 +1328,7 @@ struct gridwithzeros { } return null; } - + currentface = XLOW; nextface = YHIGH; pushifnonnull(zdirzeros[0][1][0]); @@ -1393,12 +1393,12 @@ struct gridwithzeros { 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; @@ -1482,7 +1482,7 @@ struct gridwithzeros { 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) { @@ -1532,7 +1532,7 @@ struct gridwithzeros { }; } -// The external interface of this whole module. Accepts exactly one +// 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 diff --git a/Master/texmf-dist/asymptote/solids.asy b/Master/texmf-dist/asymptote/solids.asy index 72110d6f7aa..035a00d2fcf 100644 --- a/Master/texmf-dist/asymptote/solids.asy +++ b/Master/texmf-dist/asymptote/solids.asy @@ -5,11 +5,11 @@ 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) +real[] tangent(path p, path q, bool side) { static real fuzz=1.0e-5; - if((cyclic(p) && inside(p,point(q,0)) || + if((cyclic(p) && inside(p,point(q,0)) || cyclic(q) && inside(q,point(p,0))) && intersect(p,q,fuzz).length == 0) return new real[]; @@ -28,14 +28,14 @@ real[] tangent(path p, path q, bool side) return new real[]; } -path line(path p, path q, real[] t) +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) +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; @@ -71,7 +71,7 @@ struct revolution { 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; @@ -82,12 +82,12 @@ struct revolution { 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; @@ -114,7 +114,7 @@ struct revolution { path3 p=Arc(center,v1,v2,axis,n); return (angle2-angle1) % 360 == 0 ? p&cycle : p; } - + // add transverse slice to skeleton s; void transverse(skeleton s, real t, int n=nslice, projection P) { skeleton.curve s=s.transverse; @@ -196,7 +196,7 @@ struct revolution { 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) { @@ -238,7 +238,7 @@ struct revolution { G=sfirst.transverse.back[0]..G; } } - + skeleton slast; transverse(slast,tlast,n,P); if(dot(delta,axis) == 0 || (tlast >= L-epsilon && sign > 0)) { @@ -287,7 +287,7 @@ struct revolution { path3 p1=subpath(p,0,t); path3 p2=subpath(p,t,length(p)); if(length(p1) > 0 && - (length(p2) == 0 || + (length(p2) == 0 || abs(midpoint(p1)-P.camera) <= abs(midpoint(p2)-P.camera))) { s.longitudinal.front.push(p1); s.longitudinal.back.push(p2); @@ -300,7 +300,7 @@ struct revolution { push(t1); push(t2); } - + skeleton skeleton(int m=0, int n=nslice, projection P) { skeleton s; transverse(s,m,n,P); diff --git a/Master/texmf-dist/asymptote/stats.asy b/Master/texmf-dist/asymptote/stats.asy index be9efdfa429..6183fc18df2 100644 --- a/Master/texmf-dist/asymptote/stats.asy +++ b/Master/texmf-dist/asymptote/stats.asy @@ -287,6 +287,6 @@ linefit leastsquares(real[] x, real[] y) 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/Master/texmf-dist/asymptote/syzygy.asy b/Master/texmf-dist/asymptote/syzygy.asy index 93889b252e5..3cef2b3a750 100644 --- a/Master/texmf-dist/asymptote/syzygy.asy +++ b/Master/texmf-dist/asymptote/syzygy.asy @@ -78,7 +78,7 @@ bp.draw=new guide[] (picture pic, guide[] ins) { 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}; @@ -99,7 +99,7 @@ bm.draw=new guide[] (picture pic, guide[] ins) { 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}; @@ -442,7 +442,7 @@ struct Braid { // {{{1 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) @@ -735,7 +735,7 @@ struct Syzygy { // {{{1 bool showall=false; bool number=false; // Number the diagrams when drawn. - string lsym, codename; + string lsym, codename; bool watched=false; bool uptodate=true; diff --git a/Master/texmf-dist/asymptote/three.asy b/Master/texmf-dist/asymptote/three.asy index 5fc0d2f1096..c208f59df84 100644 --- a/Master/texmf-dist/asymptote/three.asy +++ b/Master/texmf-dist/asymptote/three.asy @@ -1,8 +1,5 @@ private import math; -if(settings.xasy) - settings.render=0; - if(prc0()) { if(!latex()) settings.prc=false; else { @@ -11,8 +8,9 @@ if(prc0()) { } } -// Useful lossy compression values. +// Useful lossy PRC compression values. restricted real Zero=0; +restricted real Single=0.000001; restricted real Low=0.0001; restricted real Medium=0.001; restricted real High=0.01; @@ -20,6 +18,27 @@ 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 interaction +{ + int type; + triple center; // position to rotate billboard objects about + bool targetsize; + static interaction defaultinteraction; + + void operator init(interaction interaction=defaultinteraction, + int type=interaction.type, + triple center=interaction.center, bool targetsize=interaction.targetsize) { + this.type=type; + this.center=center; + this.targetsize=targetsize; + } +} + +interaction.defaultinteraction=new interaction; + +restricted interaction Embedded=interaction(); +restricted interaction Billboard=interaction(1); + struct render { // PRC parameters: @@ -37,23 +56,23 @@ struct render // General parameters: real margin; // shrink amount for rendered openGL viewport, in bp. - bool labelfill; // fill PRC subdivision cracks in unlighted labels - bool partnames; // assign part name indices to compound objects bool defaultnames; // assign default names to unnamed objects + interaction interaction; // billboard interaction mode 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, - bool labelfill=defaultrender.labelfill, - bool partnames=defaultrender.partnames, - bool defaultnames=defaultrender.defaultnames) + + void operator init(render render=defaultrender, + real compression=render.compression, + real granularity=render.granularity, + bool closed=render.closed, + bool tessellate=render.tessellate, + bool3 merge=render.merge, + int sphere=render.sphere, + real margin=render.margin, + bool partnames=render.partnames, + bool defaultnames=render.defaultnames, + interaction interaction=render.interaction) { this.compression=compression; this.granularity=granularity; @@ -62,9 +81,9 @@ struct render this.merge=merge; this.sphere=sphere; this.margin=margin; - this.labelfill=labelfill; this.partnames=partnames; this.defaultnames=defaultnames; + this.interaction=interaction; } } @@ -78,9 +97,9 @@ defaultrender.tessellate=false; defaultrender.merge=false; defaultrender.margin=0.02; defaultrender.sphere=NURBSsphere; -defaultrender.labelfill=true; defaultrender.partnames=false; defaultrender.defaultnames=true; +defaultrender.interaction=Embedded; real defaultshininess=0.7; real defaultmetallic=0.0; @@ -95,7 +114,7 @@ string defaultembed3Doptions="3Dmenu"; string defaultembed3Dscript; real defaulteyetoview=63mm/1000mm; -string partname(int i, render render=defaultrender) +string partname(int i, render render=defaultrender) { return render.partnames ? string(i+1) : ""; } @@ -158,8 +177,8 @@ 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}, + {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}}; } @@ -248,7 +267,7 @@ transform3 look(triple eye, triple up=Z, triple target=O) } // Return a matrix to do perspective distortion based on a triple v. -transform3 distort(triple v) +transform3 distort(triple v) { transform3 t=identity(4); real d=length(v); @@ -410,7 +429,7 @@ projection TopView=orthographic(Z,up=Y,showtarget=true); currentprojection=perspective(5,4,2); -projection projection() +projection projection() { projection P; real[] a=_projection(); @@ -467,8 +486,8 @@ struct control { } control nocontrol; - -control operator * (transform3 t, control c) + +control operator * (transform3 t, control c) { control C; C.post=t*c.post; @@ -485,7 +504,7 @@ void write(file file, control c) write(file," and "); write(file,c.pre); } - + struct Tension { real out,in; bool atLeast; @@ -510,7 +529,7 @@ Tension operator init() Tension noTension; noTension.active=false; - + void write(file file, Tension t) { write(file,"..tension "); @@ -519,7 +538,7 @@ void write(file file, Tension t) write(file," and "); write(file,t.in); } - + struct dir { triple dir; real gamma=1; // endpoint curl @@ -561,8 +580,8 @@ void write(file file, dir d) write(file,"{curl "); write(file,d.gamma); write(file,"}"); } } - -dir operator * (transform3 t, dir d) + +dir operator * (transform3 t, dir d) { dir D=d.copy(); D.init(unit(shiftless(t)*d.dir)); @@ -596,11 +615,11 @@ struct flatguide3 { 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); @@ -650,7 +669,7 @@ struct flatguide3 { 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; @@ -705,13 +724,13 @@ guide3 operator cast(cycleToken) { }; } -guide3 operator controls(triple post, triple pre) +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); @@ -743,7 +762,7 @@ guide3 operator spec(triple v, int side) abort("invalid direction specifier"); }; } - + guide3 operator -- (... guide3[] g) { return new void(flatguide3 f) { @@ -805,13 +824,13 @@ 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; @@ -840,7 +859,7 @@ 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); @@ -860,7 +879,7 @@ private real angle(triple d0, triple d1, triple reference) // 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, +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; @@ -905,7 +924,7 @@ real[] theta(triple[] v, real[] alpha, real[] beta, 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]; @@ -917,14 +936,14 @@ real[] theta(triple[] v, real[] alpha, real[] beta, 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]); + 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])); @@ -952,18 +971,18 @@ triple reference(triple[] v, int n, triple d0, triple d1) } // Fill in missing directions for n cyclic nodes. -void aim(flatguide3 g, int N) +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; @@ -993,7 +1012,7 @@ void aim(flatguide3 g, int N) 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); @@ -1008,7 +1027,7 @@ void aim(flatguide3 g, int N) } // Fill in missing directions for the sequence of nodes i...n. -void aim(flatguide3 g, int i, int 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) { @@ -1021,7 +1040,7 @@ void aim(flatguide3 g, int i, int n) 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; @@ -1029,7 +1048,7 @@ void aim(flatguide3 g, int i, int n) 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); @@ -1175,7 +1194,7 @@ path path(path3 p, pair P(triple)=xypart) 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)); @@ -1241,16 +1260,16 @@ path3 solve(flatguide3 g) 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; @@ -1260,8 +1279,8 @@ path3 solve(flatguide3 g) 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); @@ -1278,7 +1297,7 @@ path3 solve(flatguide3 g) } } } - + // Next, resolve sequences. int i=0; int start=0; @@ -1288,13 +1307,13 @@ path3 solve(flatguide3 g) 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) + + 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; @@ -1344,7 +1363,7 @@ path3 solve(flatguide3 g) straight[n-1]=false; } } - + return path3(pre,point,post,straight,cyclic); } @@ -1385,7 +1404,7 @@ path project(path3 p, projection P=currentprojection, int last=length(p); if(last < 0) return g; - + transform3 t=P.t; if(ninterpolate == 1 || piecewisestraight(p)) { @@ -1401,7 +1420,7 @@ path project(path3 p, projection P=currentprojection, } } } else return nurb(p,P); - + if(cyclic(p)) g=straight(p,last-1) ? g--cycle : g..controls project(postcontrol(p,last-1),t) and @@ -1418,11 +1437,11 @@ 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) { @@ -1456,7 +1475,7 @@ triple normal(path3 p) 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)); @@ -1478,7 +1497,7 @@ triple normal(path3 p) } return false; } - + int L=length(p); if(L <= 0) return O; @@ -1505,7 +1524,7 @@ triple normal(triple[] p) 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)); @@ -1526,7 +1545,7 @@ triple normal(triple[] p) } return false; } - + if(p.length <= 0) return O; triple zi=p[0]; @@ -1642,7 +1661,7 @@ 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)); + L.transform(transform(u,v,O,P)); return L; } @@ -1674,7 +1693,7 @@ 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) +void write(string s="", explicit guide3[] x, suffix suffix=endl) { write(stdout,s,(path3[]) x,suffix); } @@ -1850,7 +1869,7 @@ real relative(Label L, path3 g) } // return the linear transformation that maps X,Y,Z to u,v,w. -transform3 transform3(triple u, triple v, triple w=cross(u,v)) +transform3 transform3(triple u, triple v, triple w=cross(u,v)) { return new real[][] { {u.x,v.x,w.x,0}, @@ -1915,37 +1934,37 @@ path3[] operator cast(guide3 g) return new path3[] {(path3) g}; } -path3[] operator ^^ (path3 p, path3 q) +path3[] operator ^^ (path3 p, path3 q) { return new path3[] {p,q}; } -path3[] operator ^^ (path3 p, explicit path3[] q) +path3[] operator ^^ (path3 p, explicit path3[] q) { return concat(new path3[] {p},q); } -path3[] operator ^^ (explicit path3[] p, path3 q) +path3[] operator ^^ (explicit path3[] p, path3 q) { return concat(p,new path3[] {q}); } -path3[] operator ^^ (explicit path3[] p, explicit path3[] q) +path3[] operator ^^ (explicit path3[] p, explicit path3[] q) { return concat(p,q); } -path3[] operator * (transform3 t, explicit path3[] p) +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) +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[][] operator * (transform3 t, triple[][] v) { triple[][] V=new triple[v.length][]; for(int i=0; i < v.length; ++i) { @@ -1979,7 +1998,7 @@ path3 randompath3(int n, bool cumulate=true, interpolate3 join=operator ..) triple w; for(int i=0; i <= n; ++i) { triple z=(unitrand()-0.5,unitrand()-0.5,unitrand()-0.5); - if(cumulate) w += z; + if(cumulate) w += z; else w=z; g=join(g,w); } @@ -2040,15 +2059,15 @@ path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW) 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); @@ -2102,21 +2121,19 @@ 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) +void begingroup3(frame f, string name="", render render=defaultrender) { _begingroup3(f,name,render.compression,render.granularity,render.closed, render.tessellate,render.merge == false, - render.merge == true,center,interaction); + render.merge == true,render.interaction.center,render.interaction.type); } void begingroup3(picture pic=currentpicture, string name="", - render render=defaultrender, - triple center=O, int interaction=0) + render render=defaultrender) { pic.add(new void(frame f, transform3, picture pic, projection) { if(is3D()) - begingroup3(f,name,render,center,interaction); + begingroup3(f,name,render); if(pic != null) begingroup(pic); },true); @@ -2141,7 +2158,7 @@ void addPath(picture pic, path3 g, pen p) include three_surface; include three_margins; -pair min(path3 p, projection P) +pair min(path3 p, projection P) { path3 q=P.T.modelview*p; if(P.infinity) @@ -2149,7 +2166,7 @@ pair min(path3 p, projection P) return maxratio(q)/P.T.projection[3][2]; } -pair max(path3 p, projection P) +pair max(path3 p, projection P) { path3 q=P.T.modelview*p; if(P.infinity) @@ -2157,7 +2174,7 @@ pair max(path3 p, projection P) return minratio(q)/P.T.projection[3][2]; } -pair min(frame f, projection P) +pair min(frame f, projection P) { frame g=P.T.modelview*f; if(P.infinity) @@ -2165,7 +2182,7 @@ pair min(frame f, projection P) return maxratio(g)/P.T.projection[3][2]; } -pair max(frame f, projection P) +pair max(frame f, projection P) { frame g=P.T.modelview*f; if(P.infinity) @@ -2210,7 +2227,7 @@ draw=new void(frame f, path3 g, material p=currentpen, void drawthick(path3 g) { if(settings.thick && width > 0) { bool prc=prc(); - bool webgl=settings.outformat == "html"; + bool primitive=primitive(); real linecap=linecap(q); real r=0.5*width; bool open=!cyclic(g); @@ -2256,7 +2273,7 @@ draw=new void(frame f, path3 g, material p=currentpen, } } // Draw central core for better small-scale rendering. - if((!prc || piecewisestraight(g)) && !webgl && opacity(q) == 1) + if((!prc || piecewisestraight(g)) && !primitive && opacity(q) == 1) _draw(f,c,p,light); } for(surface s : T.s) @@ -2319,7 +2336,7 @@ void draw(picture pic=currentpicture, explicit path3[] g, include three_arrows; -void draw(picture pic=currentpicture, Label L="", path3 g, +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="", @@ -2409,12 +2426,12 @@ 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); @@ -2635,7 +2652,7 @@ struct scene transform3 T=identity4; picture pic2; bool keepAspect=true; - + void operator init(frame f, real width, real height, projection P=currentprojection) { this.f=f; @@ -2644,14 +2661,14 @@ struct scene 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; this.keepAspect=keepAspect; - + if(xsize3 == 0 && ysize3 == 0 && zsize3 == 0) { xsize3=ysize3=zsize3=max(xsize,ysize); warn=false; @@ -2787,6 +2804,7 @@ object embed(string prefix=outprefix(), string label=prefix, triple orthoshift; modelview=P.T.modelview; transform3 inv; + bool prc=prc(format); if(P.absolute) { Q=modelview*P; inv=inverse(modelview); @@ -2798,12 +2816,13 @@ object embed(string prefix=outprefix(), string label=prefix, 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); + P.showtarget,P.center); + if(P.infinity) { triple m=min3(S.f); triple M=max3(S.f); triple lambda=M-m; - if(S.keepAspect) { + if(S.keepAspect || prc) { 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); @@ -2821,7 +2840,7 @@ object embed(string prefix=outprefix(), string label=prefix, inv=inverse(modelview); Q.angle=P.angle; if(settings.verbose > 0) { - if(S.adjusted) + if(S.adjusted) write("adjusting camera to ",tinv*inv*P.camera); target=inv*P.target; } @@ -2835,7 +2854,6 @@ object embed(string prefix=outprefix(), string label=prefix, 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. @@ -2868,12 +2886,12 @@ object embed(string prefix=outprefix(), string label=prefix, if(P.infinity) { triple margin=(S.viewportmargin.x,S.viewportmargin.y,0); - M += margin; + M += margin; m -= margin; } else if(M.z >= 0) abort("camera too close"); - if(settings.outformat == "html") - format="html"; + if(primitive()) + format=settings.outformat; shipout3(prefix,f,preview ? nativeformat() : format, S.width-defaultrender.margin,S.height-defaultrender.margin, @@ -2893,7 +2911,7 @@ object embed(string prefix=outprefix(), string label=prefix, 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"); @@ -2924,7 +2942,7 @@ shift"); 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); + 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; @@ -2948,7 +2966,7 @@ object embed(string prefix=outprefix(), string label=prefix, { bool is3D=is3D(format); scene S=scene(pic,xsize,ysize,keepAspect,is3D,P); - if(is3D) + if(is3D && !(settings.xasy && format == "")) return embed(prefix,label,text,S,format,view,options,script,light); else { object F; @@ -3002,7 +3020,8 @@ frame embedder(object embedder(string prefix, string format), if(light.background != nullpen) box(f,light.background,Fill,above=false); } else if(!view) - label(f,graphic(prefix,"hiresbb")); + label(f,settings.inlinetex ? + "\input{"+prefix+"}" : graphic(prefix,"hiresbb")); } return f; } @@ -3017,7 +3036,9 @@ currentpicture.fitter=new frame(string prefix, picture pic, 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)); + + if(is3D(format) || empty3) + add(f,pic.fit2(xsize,ysize,keepAspect)); return f; }; @@ -3056,7 +3077,7 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS, 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]; @@ -3076,17 +3097,17 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS, } } } - + 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) { @@ -3179,10 +3200,10 @@ frame[] fit3(string prefix="", picture[] pictures, picture all, 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; diff --git a/Master/texmf-dist/asymptote/three_arrows.asy b/Master/texmf-dist/asymptote/three_arrows.asy index b0369e6beab..35f6bc4cea1 100644 --- a/Master/texmf-dist/asymptote/three_arrows.asy +++ b/Master/texmf-dist/asymptote/three_arrows.asy @@ -37,7 +37,7 @@ 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) +void bend(surface s, path3 g, real L) { for(patch p : s.s) { for(int i=0; i < 4; ++i) { @@ -140,7 +140,7 @@ DefaultHead3.head=new surface(path3 g, position position=EndPoint, path3 r=subpath(g,position,0); path3 s=subpath(r,arctime(r,size),0); - int n=length(s); + int n=length(s); bool straight1=n == 1 && straight(g,0); real aspect=Tan(angle); real width=size*aspect; @@ -186,7 +186,7 @@ arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb) 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); @@ -198,7 +198,7 @@ arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb) 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; @@ -324,7 +324,7 @@ private real position(position position, real size, path3 g, bool center) position *= arclength(g); if(center) position += 0.5*size; position=arctime(g,position); - } else if(center) + } else if(center) position=arctime(g,arclength(subpath(g,0,position))+0.5*size); return position; } @@ -450,7 +450,7 @@ 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) + light arrowheadlight=currentlight) { pen q=(pen) p; if(size == 0) size=arrowhead.size(q); @@ -539,7 +539,7 @@ void bar(picture pic, triple a, triple d, triple perp=O, pic.addPoint(a,v-M); pic.addPoint(a,v+M); } - + picture bar(triple a, triple dir, triple perp=O, material p=currentpen) { picture pic; @@ -620,11 +620,11 @@ arrowbar3 BeginArcArrow3(arrowhead3 arrowhead=DefaultHead3, material arrowheadpen=nullpen) { return new bool(picture pic, path3 g, material p, margin3 margin, - light light, light arrowheadlight) { + 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; + return false; }; } @@ -685,7 +685,7 @@ arrowbar3 BeginBar3(real size=0, triple dir=O) }; } -arrowbar3 Bar3(real size=0, triple dir=O) +arrowbar3 Bar3(real size=0, triple dir=O) { return new bool(picture pic, path3 g, material p, margin3 margin, light light, light) { @@ -696,9 +696,9 @@ arrowbar3 Bar3(real size=0, triple dir=O) }; } -arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3; +arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3; -arrowbar3 Bars3(real size=0, triple dir=O) +arrowbar3 Bars3(real size=0, triple dir=O) { return new bool(picture pic, path3 g, material p, margin3 margin, light light, light) { diff --git a/Master/texmf-dist/asymptote/three_light.asy b/Master/texmf-dist/asymptote/three_light.asy index 46b0fef7d0e..f17a4324c90 100644 --- a/Master/texmf-dist/asymptote/three_light.asy +++ b/Master/texmf-dist/asymptote/three_light.asy @@ -1,7 +1,7 @@ struct material { pen[] p; // diffusepen,emissivepen,specularpen real opacity; - real shininess; + real shininess; real metallic; real fresnel0; // Reflectance rate at a perfect normal angle. @@ -34,7 +34,7 @@ struct material { void specular(pen q) {p[2]=q;} } -material operator init() +material operator init() { return material(); } @@ -57,7 +57,7 @@ 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 && diff --git a/Master/texmf-dist/asymptote/three_margins.asy b/Master/texmf-dist/asymptote/three_margins.asy index b6f286ee4ff..a488029573b 100644 --- a/Master/texmf-dist/asymptote/three_margins.asy +++ b/Master/texmf-dist/asymptote/three_margins.asy @@ -27,7 +27,7 @@ margin3 operator +(margin3 ma, margin3 mb) } margin3 NoMargin3() -{ +{ return new marginT3(path3 g, pen) { marginT3 margin; margin.begin=margin.end=0; @@ -35,9 +35,9 @@ margin3 NoMargin3() return margin; }; } - + margin3 Margin3(real begin, real end) -{ +{ return new marginT3(path3 g, pen p) { marginT3 margin; real factor=labelmargin(p); @@ -48,9 +48,9 @@ margin3 Margin3(real begin, real end) return margin; }; } - + margin3 PenMargin3(real begin, real end) -{ +{ return new marginT3(path3 g, pen p) { marginT3 margin; real factor=linewidth(p); @@ -60,9 +60,9 @@ margin3 PenMargin3(real begin, real 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;} @@ -73,9 +73,9 @@ margin3 DotMargin3(real begin, real end) return margin; }; } - + margin3 TrueMargin3(real begin, real end) -{ +{ return new marginT3(path3 g, pen p) { marginT3 margin; margin.begin=begin; @@ -84,7 +84,7 @@ margin3 TrueMargin3(real begin, real end) return margin; }; } - + margin3 NoMargin3=NoMargin3(), BeginMargin3=Margin3(1,0), Margin3=Margin3(0,1), diff --git a/Master/texmf-dist/asymptote/three_surface.asy b/Master/texmf-dist/asymptote/three_surface.asy index 77bdc6a998a..95f41a61817 100644 --- a/Master/texmf-dist/asymptote/three_surface.asy +++ b/Master/texmf-dist/asymptote/three_surface.asy @@ -34,7 +34,7 @@ struct patch { } path3 externaltriangular() { - return + 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; @@ -91,7 +91,7 @@ struct patch { new triple[] {Bv(1,v),z1},new bool[] {straight,false},false); } - triple point(real u, real v) { + triple point(real u, real v) { return bezier(Bu(0,u),Bu(1,u),Bu(2,u),Bu(3,u),v); } @@ -237,7 +237,7 @@ struct patch { 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) { @@ -250,7 +250,7 @@ struct patch { color(normal10(),nocolors ? m : colors[1],light), color(normal01(),nocolors ? m : colors[2],light)}; } - + triple min3,max3; bool havemin3,havemax3; @@ -332,7 +332,7 @@ struct patch { 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[], @@ -406,51 +406,65 @@ struct patch { }; } - // A constructor for a convex quadrilateral. + // A constructor for a triangle or 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; + straight=true; if(colors.length != 0) this.colors=copy(colors); - if(internal.length == 0) { - internal=new triple[4]; + if(external.length == 3) { + P=new triple[][] { + {external[0]}, + {interp(external[0],external[1],1/3), + interp(external[2],external[0],2/3)}, + {interp(external[0],external[1],2/3),sum(external)/3, + interp(external[2],external[0],1/3)}, + {external[1],interp(external[1],external[2],1/3), + interp(external[1],external[2],2/3),external[2]} + }; + planar=true; + triangular=true; + } else { + if(internal.length == 0 && planar == default) + this.planar=normal(external) != O; + else this.planar=planar; + + 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]); + } + + triple delta[]=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]); + 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]} + }; } - - 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) { + 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]; + Si[j]=t*si[j]; } - + S.colors=copy(s.colors); S.planar=s.planar; S.straight=s.straight; @@ -458,8 +472,8 @@ patch operator * (transform3 t, patch s) S.init(); return S; } - -patch reverse(patch s) + +patch reverse(patch s) { assert(!s.triangular); patch S; @@ -505,7 +519,7 @@ pair[][] coons(path p) 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) @@ -533,12 +547,12 @@ path[] regularize(path p, bool checkboundary=true) 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); @@ -574,7 +588,7 @@ path[] regularize(path p, bool checkboundary=true) if(straight) return new path[] {p}; - + pair[][] P=coons(p); // Check for degeneracy. @@ -585,12 +599,12 @@ path[] regularize(path p, bool checkboundary=true) 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}; @@ -670,7 +684,7 @@ path[] regularize(path p, bool checkboundary=true) 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); } @@ -709,7 +723,7 @@ path[] regularize(path p, bool checkboundary=true) // 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) @@ -730,7 +744,7 @@ struct surface { int index[][];// Position of patch corresponding to major U,V parameter in s. bool vcyclic; transform3 T=identity4; - + drawfcn draw; bool PRCprimitive=true; // True unless no PRC primitive is available. @@ -790,7 +804,7 @@ struct surface { 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); @@ -798,25 +812,25 @@ struct surface { int index=index.length == 0 ? U+V : index[U][V]; return s[index].normal(u-U,v-V); } - - void ucyclic(bool f) + + void ucyclic(bool f) { index.cyclic=f; } - - void vcyclic(bool f) + + void vcyclic(bool f) { for(int[] i : index) i.cyclic=f; vcyclic=f; } - - bool ucyclic() + + bool ucyclic() { return index.cyclic; } - - bool vcyclic() + + bool vcyclic() { return vcyclic; } @@ -830,7 +844,7 @@ struct surface { 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); @@ -839,7 +853,7 @@ struct surface { 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) { @@ -880,12 +894,12 @@ struct surface { 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; @@ -968,7 +982,7 @@ struct surface { 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); @@ -985,7 +999,7 @@ struct surface { } 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;} @@ -1023,7 +1037,7 @@ struct surface { } surface operator * (transform3 t, surface s) -{ +{ surface S; S.s=new patch[s.s.length]; for(int i=0; i < s.s.length; ++i) @@ -1033,7 +1047,7 @@ surface operator * (transform3 t, surface s) S.T=t*s.T; S.draw=s.draw; S.PRCprimitive=s.PRCprimitive; - + return S; } @@ -1048,7 +1062,7 @@ triple min(surface s) bound=s.s[i].min(bound); return bound; } - + triple max(surface s) { if(s.s.length == 0) @@ -1068,7 +1082,7 @@ pair min(surface s, projection P) bound=s.s[i].min(P,bound); return bound; } - + pair max(surface s, projection P) { if(s.s.length == 0) @@ -1153,13 +1167,13 @@ triple[][][][] split(triple[][] P, real u=0.5, real v=0.5) 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); @@ -1242,7 +1256,7 @@ triple[][] subpatchbegin(triple[][] P, real u, real v) {c4[2],c5[2],c6[2],c7[2]}}; } -triple[][] subpatch(triple[][] P, pair a, pair b) +triple[][] subpatch(triple[][] P, pair a, pair b) { return subpatchend(subpatchbegin(P,b.x,b.y),a.x/b.x,a.y/b.y); } @@ -1294,7 +1308,7 @@ real[][] intersections(path3 p, surface s, real fuzz=-1) 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]); @@ -1331,7 +1345,7 @@ bool overlap(triple[][] p, triple[][] q, real fuzz=-1) 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 && @@ -1346,19 +1360,6 @@ triple point(patch s, real u, real v) return s.point(u,v); } -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; @@ -1369,8 +1370,8 @@ material material(material m, light light, bool colors=false) return light.on() || invisible((pen) m) ? m : emissive(m,colors); } -void draw3D(frame f, patch s, triple center=O, material m, - light light=currentlight, interaction interaction=Embedded, +void draw3D(frame f, patch s, material m, + light light=currentlight, render render=defaultrender, bool primitive=false) { bool straight=s.straight && s.planar; @@ -1379,15 +1380,18 @@ void draw3D(frame f, patch s, triple center=O, material m, int digits=s.planar && !straight ? 12 : settings.digits; if(s.colors.length > 0) { + primitive=false; if(prc() && light.on()) straight=false; // PRC vertex colors (for quads only) ignore lighting + m=material(m); m.diffuse(mean(s.colors)); } m=material(m,light,s.colors.length > 0); - - (s.triangular ? drawbeziertriangle : draw) - (f,s.P,center,straight,m.p,m.opacity,m.shininess, - m.metallic,m.fresnel0,s.colors,interaction.type,digits,primitive); + + (s.triangular ? drawbeziertriangle : draw) + (f,s.P,render.interaction.center,straight,m.p,m.opacity,m.shininess, + m.metallic,m.fresnel0,s.colors,render.interaction.type,digits, + primitive); } void _draw(frame f, path3 g, triple center=O, material m, @@ -1417,7 +1421,7 @@ int computeNormals(triple[] v, int[][] vi, triple[] n, int[][] ni) // 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) + int[][] pi={}, light light=currentlight, render render=defaultrender) { bool normals=n.length > 0; if(!normals) { @@ -1427,13 +1431,15 @@ void draw(frame f, triple[] v, int[][] vi, if(p.length > 0) m=mean(p); m=material(m,light); - draw(f,v,vi,n,ni,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,p,pi); + draw(f,v,vi,render.interaction.center,n,ni, + m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,p,pi, + render.interaction.type); } - + // 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) + int[][] pi={}, light light=currentlight, render render=defaultrender) { bool prc=prc(); bool normals=n.length > 0; @@ -1448,7 +1454,9 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi, triple[] n=t*n; if(is3D()) { - draw(f,v,vi,n,ni,m,p,pi,light); + render Render=render(render,interaction(render.interaction, + t*render.interaction.center)); + draw(f,v,vi,n,ni,m,p,pi,light,Render); if(pic != null) { for(int[] vii : vi) for(int viij : vii) @@ -1482,12 +1490,10 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi, project(v[vii[2]],P)--cycle; pen p=color(n[ni[i][0]],m,light); fill(pic,g,p); - if(prc && opacity(m.diffuse()) == 1) // Fill subdivision cracks - draw(pic,g,p); } } } - } + } },true); for(int[] vii : vi) @@ -1502,11 +1508,11 @@ void tensorshade(transform t=identity(), frame f, patch s, if(s.triangular) { p=s.colorstriangular(m,light); p.push(p[0]); - s=tensor(s); + s=tensor(s); } else p=s.colors(m,light); path g=t*project(s.external(),P,1); pair[] internal=t*project(s.internal(),P); - pen fillrule=m.diffuse(); + pen fillrule=fillrule(fillrule(m.diffuse())); if(inside(g,internal[0],fillrule) && inside(g,internal[1],fillrule) && inside(g,internal[2],fillrule) && inside(g,internal[3],fillrule)) { if(p[0] == p[1] && p[1] == p[2] && p[2] == p[3]) @@ -1529,11 +1535,15 @@ void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1, bool is3D=is3D(); if(is3D) { bool prc=prc(); - if(s.draw != null && (settings.outformat == "html" || - (prc && s.PRCprimitive))) { - for(int k=0; k < s.s.length; ++k) - draw3D(f,s.s[k],surfacepen[k],light,primitive=true); - s.draw(f,s.T,surfacepen,light,render); + if(s.draw != null && (primitive() || (prc && s.PRCprimitive))) { + bool noprerender=settings.prerender == 0; + for(int k=0; k < s.s.length; ++k) { + patch p=s.s[k]; + draw3D(f,p,surfacepen[k],light,render,primitive=noprerender); + if(p.colors.length > 0) noprerender=false; + } + if(noprerender) + s.draw(f,s.T,surfacepen,light,render); } else { bool group=name != "" || render.defaultnames; if(group) @@ -1557,7 +1567,7 @@ void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1, 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); + draw3D(f,s.s[k],surfacepen[k],light,render); } if(group) @@ -1646,8 +1656,11 @@ void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1, 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(is3D()) { + render Render=render(render,interaction(render.interaction, + t*render.interaction.center)); + 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); @@ -1724,7 +1737,7 @@ surface extrude(explicit path[] p, triple axis=Z) return s; } -triple rectify(triple dir) +triple rectify(triple dir) { real scale=max(abs(dir.x),abs(dir.y),abs(dir.z)); if(scale != 0) dir *= 0.5/scale; @@ -1832,20 +1845,16 @@ void label(frame f, Label L, triple position, align align=NoAlign, 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(prc && render.labelfill && opacity(L.p) == 1 && !lighton) - _draw(f3,S.external(),position,L.p,light,interaction); + render Render=render(render,interaction(interaction,position)); + begingroup3(f1,name,render); + if(L.defaulttransform3) + begingroup3(f3,Render); + else { + begingroup3(f2,Render); + begingroup3(f3,Render); } + for(patch S : s.s) + draw3D(f3,centering*S,L.p,light,Render); endgroup3(f3); if(L.defaulttransform3) add(f1,T*f3); @@ -1861,10 +1870,7 @@ void label(frame f, Label L, triple position, align align=NoAlign, 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(prc && render.labelfill && opacity(L.p) == 1 && !lighton) - _draw(f,S.external(),V,L.p,light,interaction); + draw3D(f,S,L.p,light,render(interaction(interaction,center=V))); } endgroup3(f); } @@ -1894,7 +1900,7 @@ void label(picture pic=currentpicture, Label L, triple position, 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. bool prc=prc(); @@ -1903,7 +1909,7 @@ void label(picture pic=currentpicture, Label L, triple 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); @@ -1922,19 +1928,15 @@ void label(picture pic=currentpicture, Label L, triple position, shift(L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v); frame f1,f2,f3; begingroup3(f1,name,render); + render Render=render(render,interaction(interaction,v)); if(L.defaulttransform3) - begingroup3(f3,render,v,interaction.type); + begingroup3(f3,Render); 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(prc && render.labelfill && opacity(L.p) == 1 && !lighton) - _draw(f3,S.external(),v,L.p,light,interaction); + begingroup3(f2,Render); + begingroup3(f3,Render); } + for(patch S : s.s) + draw3D(f3,centering*S,L.p,light,Render); endgroup3(f3); if(L.defaulttransform3) add(f1,T*f3); @@ -1950,15 +1952,12 @@ void label(picture pic=currentpicture, Label L, triple position, 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(prc && render.labelfill && opacity(L.p) == 1 && !lighton) - _draw(f,S.external(),V,L.p,light,interaction); + draw3D(f,S,L.p,light,render(render,interaction(interaction,V))); } endgroup3(f); } } - + if(pic2 != null) { pen p=color(L.T3*Z,L.p,light,shiftless(P.T.modelview)); if(L.defaulttransform3) { @@ -1975,11 +1974,11 @@ void label(picture pic=currentpicture, Label L, triple position, 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())); @@ -2008,7 +2007,7 @@ void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign, 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); + L.align(a); } label(pic,L,point(g,position),light,name,interaction); } @@ -2063,7 +2062,7 @@ surface surface(Label L, surface s, real uoffset, real voffset, for(path g : regularize(p)) { path3 b; bool extrude=height > 0; - if(bottom || extrude) + if(bottom || extrude) b=transpath(g,0); if(bottom) s.s.push(patch(b)); if(top || extrude) { @@ -2390,7 +2389,7 @@ pair maxbound(triple[][] A, projection P) return b; } -triple[][] operator / (triple[][] a, real[][] b) +triple[][] operator / (triple[][] a, real[][] b) { triple[][] A=new triple[a.length][]; for(int i=0; i < a.length; ++i) { diff --git a/Master/texmf-dist/asymptote/three_tube.asy b/Master/texmf-dist/asymptote/three_tube.asy index 60085a7d512..5c22f4d29bb 100644 --- a/Master/texmf-dist/asymptote/three_tube.asy +++ b/Master/texmf-dist/asymptote/three_tube.asy @@ -100,6 +100,17 @@ rmf[] rmf(triple z0, triple c0, triple c1, triple z1, real[] t, triple perp=O) return R; } + +drawfcn drawTube(triple[] g, real w, triple min, triple max) { + return new void(frame f, transform3 t=identity4, material[] m, + light light=currentlight, render render=defaultrender) + { + material m=material(m[0],light); + drawTube(f,t*g,w,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0, + t*min,t*max,m.opacity == 1); + }; +} + surface tube(triple z0, triple c0, triple c1, triple z1, real w) { surface s; @@ -125,13 +136,7 @@ surface tube(triple z0, triple c0, triple c1, triple z1, real w) f(t3); s.PRCprimitive=false; - s.draw=new void(frame f, transform3 t=identity4, material[] m, - light light=currentlight, render render=defaultrender) - { - material m=material(m[0],light); - drawTube(f,t*g,w,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0, - t*min(s),t*max(s),m.opacity == 1); - }; + s.draw=drawTube(g,w,min(s),max(s)); return s; } @@ -153,7 +158,7 @@ struct tube void Null(transform3) {} void Null(transform3, bool) {} - + surface[] render(path3 g, real r) { triple z0=point(g,0); triple c0=postcontrol(g,0); @@ -174,7 +179,7 @@ struct tube pair a0=threshold(z0,c0,c1); pair a1=threshold(z1,c1,c0); real rL=r*arclength(z0,c0,c1,z1)*tubethreshold; - if((a0.x >= norm && rL*a0.y^2 > a0.x^8) || + if((a0.x >= norm && rL*a0.y^2 > a0.x^8) || (a1.x >= norm && rL*a1.y^2 > a1.x^8)) { triple m0=0.5*(z0+c0); triple m1=0.5*(c0+c1); @@ -214,7 +219,7 @@ struct tube s.append(render(subpath(p,i,i+1),r)); } } - + transform3 t=scale3(r); bool cyclic=cyclic(p); int begin=0; diff --git a/Master/texmf-dist/asymptote/trembling.asy b/Master/texmf-dist/asymptote/trembling.asy index f9f0d6a7474..6f696945af9 100644 --- a/Master/texmf-dist/asymptote/trembling.asy +++ b/Master/texmf-dist/asymptote/trembling.asy @@ -17,14 +17,14 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// COMMENTARY: +// COMMENTARY: -// THANKS: +// THANKS: -// BUGS: +// BUGS: // magnetic points are experimental... -// CODE: +// CODE: real magneticRadius=1; // unit is bp in postscript coordinates. real trembleFuzz(){return min(1e-3,magneticRadius/10);} @@ -34,7 +34,7 @@ real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2; struct tremble { static real test=5; - + real angle,frequency,random,fuzz; pair[] single(pair[] P) @@ -141,7 +141,7 @@ struct tremble 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 diff --git a/Master/texmf-dist/asymptote/v3d.asy b/Master/texmf-dist/asymptote/v3d.asy new file mode 100644 index 00000000000..5bdd0627d5f --- /dev/null +++ b/Master/texmf-dist/asymptote/v3d.asy @@ -0,0 +1,645 @@ +// Supakorn "Jamie" Rassameemasuang <jamievlin@outlook.com> and +// John C. Bowman + +import three; +import v3dtypes; +import v3dheadertypes; + +struct triangleGroup +{ + triple[] positions; + triple[] normals; + pen[] colors; + + int[][] positionIndices; + int[][] normalIndices; + int[][] colorIndices; +} + +struct pixel +{ + triple point; + real width; +} + +struct CameraInformation +{ + int canvasWidth; + int canvasHeight; + bool absolute; + + triple b; + triple B; + bool orthographic; + real angle; + real Zoom0; + pair viewportshift; + pair viewportmargin; + + light light; + + void setCameraInfo() + { + size(canvasWidth,canvasHeight); + triple center=0.5*(b.z+B.z)*Z; + + if(orthographic) + currentprojection=orthographic(Z,target=center,Zoom0, + viewportshift=viewportshift); + else + currentprojection=perspective(Z,Y,target=center,Zoom0, + degrees(2.0*atan(tan(0.5*angle)/Zoom0)), + viewportshift=viewportshift, + autoadjust=false); + light.specular=light.diffuse; + currentlight=light; + } +} + +transform3 Align(real polar, real azimuth) +{ + return align(dir(degrees(polar),degrees(azimuth))); +} + +struct v3dfile +{ + file xdrfile; + int version; + bool hasCameraInfo=false; + CameraInformation info; + bool singleprecision=false; + + triple[] centers; + material[] materials; + + surface[][][] surfaces; + path3[][][] paths3; + triangleGroup[][][] triangles; + pixel[][] pixels; + + void initSurface(int center, int material) { + if(!surfaces.initialized(center)) + surfaces[center]=new surface[][]; + if(!surfaces[center].initialized(material)) + surfaces[center][material]=new surface[] {new surface}; + } + + void initPath3(int center, int material) { + if(!paths3.initialized(center)) + paths3[center]=new path3[][]; + if(!paths3[center].initialized(material)) + paths3[center][material]=new path3[]; + } + + void initTriangleGroup(int center, int material) { + if (!triangles.initialized(center)) + triangles[center]=new triangleGroup[][]; + if(!triangles[center].initialized(material)) + triangles[center][material]=new triangleGroup[]; + } + + void initPixel(int material) { + if(!pixels.initialized(material)) + pixels[material]=new pixel[]; + } + + void surface(int center, int material, patch p) { + initSurface(center,material); + surfaces[center][material][0].s.push(p); + } + + void primitive(int center, int material, surface s) { + initSurface(center,material); + surfaces[center][material].push(s); + } + + void path3(int center, int material, path3 p) { + initPath3(center,material); + paths3[center][material].push(p); + } + + void triangleGroup(int center, int material, triangleGroup g) { + initTriangleGroup(center,material); + triangles[center][material].push(g); + } + + void pixel(int material, pixel P) { + initPixel(material); + pixels[material].push(P); + } + + void operator init(string name) + { + xdrfile=input(name, mode="xdrgz"); + version=xdrfile; + + int doubleprecision=xdrfile; + singleprecision=doubleprecision == 0; + xdrfile.singlereal(singleprecision); + } + + int getType() + { + return xdrfile; + } + + void setCameraInfo() + { + if(hasCameraInfo) + info.setCameraInfo(); + } + + pen[] readColorData(int size=4, bool alpha=true) + { + xdrfile.singlereal(true); + + xdrfile.dimension(alpha ? 4 : 3); + pen[] newPen=new pen[size]; + for (int i=0; i < size; ++i) + { + newPen[i]=alpha ? rgba(xdrfile) : rgb((real[]) xdrfile); + } + + xdrfile.singlereal(singleprecision); + + return newPen; + } + + CameraInformation processHeader() + { + CameraInformation ci; + + int entryCount=xdrfile; + for (int i=0;i<entryCount;++i) + { + int headerKey=xdrfile; + int headerSz=xdrfile; + + if (headerKey == v3dheadertypes.canvasWidth) + { + ci.canvasWidth=xdrfile; + } + else if (headerKey == v3dheadertypes.canvasHeight) + { + ci.canvasHeight=xdrfile; + } + else if (headerKey == v3dheadertypes.absolute) + { + int val=xdrfile; + ci.absolute=(val != 0); + } + else if (headerKey == v3dheadertypes.minBound) + { + ci.b=xdrfile; + } + else if (headerKey == v3dheadertypes.maxBound) + { + ci.B=xdrfile; + } + else if (headerKey == v3dheadertypes.orthographic) + { + int val=xdrfile; + ci.orthographic=(val != 0); + } + else if (headerKey == v3dheadertypes.angleOfView) + { + ci.angle=xdrfile; + } + else if (headerKey == v3dheadertypes.initialZoom) + { + ci.Zoom0=xdrfile; + } + else if (headerKey==v3dheadertypes.viewportShift) + { + ci.viewportshift=xdrfile; + } + else if (headerKey==v3dheadertypes.viewportMargin) + { + ci.viewportmargin=xdrfile; + } + else if (headerKey==v3dheadertypes.background) + { + ci.light.background=readColorData(1)[0]; + } + else if (headerKey==v3dheadertypes.light) + { + triple position=xdrfile; + ci.light.position.push(position); + ci.light.diffuse.push(rgba(readColorData(1,false)[0])); + } + else + { + xdrfile.dimension(headerSz); + int[] _dmp=xdrfile; + } + } + return ci; + } + + material readMaterial() { + xdrfile.dimension(4); + xdrfile.singlereal(true); + + pen diffusePen=rgba(xdrfile); + pen emissivePen=rgba(xdrfile); + pen specularPen=rgba(xdrfile); + + xdrfile.dimension(3); + real[] params=xdrfile; + real shininess=params[0]; + real metallic=params[1]; + real F0=params[2]; + + xdrfile.singlereal(singleprecision); + + return material(diffusePen,emissivePen,specularPen,1,shininess, + metallic,F0); + } + + triple[][] readRawPatchData() { + triple[][] val; + xdrfile.dimension(4,4); + val=xdrfile; + return val; + } + + triple[][] readRawTriangleData() { + triple[][] val; + + for(int i=0; i < 4; ++i) { + xdrfile.dimension(i+1); + triple[] v=xdrfile; + val.push(v); + } + return val; + } + + void readBezierPatch() { + triple[][] val=readRawPatchData(); + int center=xdrfile; + int material=xdrfile; + surface(center,material,patch(val)); + } + + void readBezierTriangle() { + triple[][] val=readRawTriangleData(); + int center=xdrfile; + int material=xdrfile; + surface(center,material,patch(val,triangular=true)); + } + + triple[] readCenters() { + int centerCount=xdrfile; + xdrfile.dimension(centerCount); + triple[] centersFetched; + if (centerCount>0) + centersFetched=xdrfile; + return centersFetched; + } + + void readBezierPatchColor() { + triple[][] val=readRawPatchData(); + int center=xdrfile; + int material=xdrfile; + pen[] colors=readColorData(4); + surface(center,material,patch(val,colors=colors)); + } + + void readBezierTriangleColor() { + triple[][] val=readRawTriangleData(); + int center=xdrfile; + int material=xdrfile; + pen[] colors=readColorData(3); + surface(center,material,patch(val,triangular=true,colors=colors)); + } + + void readSphere() { + triple origin=xdrfile; + real radius=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + surface s=shift(origin)*scale3(radius)*unitsphere; + s.draw=unitsphere.draw; + primitive(center,material,s); + } + + void readHemisphere() { + triple origin=xdrfile; + real radius=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + real polar=xdrfile; + real azimuth=xdrfile; + + surface s=shift(origin)*Align(polar,azimuth)*scale3(radius)*unithemisphere; + s.draw=unithemisphere.draw; + primitive(center,material,s); + } + + void readDisk() { + triple origin=xdrfile; + real radius=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + real polar=xdrfile; + real azimuth=xdrfile; + + surface s=shift(origin)*Align(polar,azimuth)*scale3(radius)*unitdisk; + s.draw=unitdisk.draw; + primitive(center,material,s); + } + + void readPolygon(int n) + { + xdrfile.dimension(n); + triple[] val=xdrfile; + + int center=xdrfile; + int material=xdrfile; + surface(center,material,patch(val)); + } + + void readPolygonColor(int n) + { + xdrfile.dimension(n); + triple[] val=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + pen[] colors=readColorData(n); + surface(center,material,patch(val,colors=colors)); + } + + void readCylinder() { + triple origin=xdrfile; + real radius=xdrfile; + real height=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + real polar=xdrfile; + real azimuth=xdrfile; + + int core=xdrfile; + + transform3 T=shift(origin)*Align(polar,azimuth)* + scale(radius,radius,height); + if(core != 0) + path3(center,material,T*(O--Z)); + + surface s=T*unitcylinder; + s.draw=unitcylinder.draw; + primitive(center,material,s); + } + + void readTube() { + xdrfile.dimension(4); + triple[] g=xdrfile; + + real width=xdrfile; + int center=xdrfile; + int material=xdrfile; + + int core=xdrfile; + + if(core != 0) + path3(center,material,g[0]..controls g[1] and g[2]..g[3]); + + surface s=tube(g[0],g[1],g[2],g[3],width); + s.draw=drawTube(g,width,info.b,info.B); + primitive(center,material,s); + } + + void readCurve() { + xdrfile.dimension(4); + triple[] points=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + path3(center,material, + points[0]..controls points[1] and points[2]..points[3]); + } + + void readLine() { + xdrfile.dimension(2); + triple[] points=xdrfile; + + int center=xdrfile; + int material=xdrfile; + + path3(center,material,points[0]--points[1]); + } + + void readTriangles() { + triangleGroup g; + + int nI=xdrfile; + + int nP=xdrfile; + xdrfile.dimension(nP); + g.positions=xdrfile; + + int nN=xdrfile; + xdrfile.dimension(nN); + g.normals=xdrfile; + + int explicitNI=xdrfile; + + int nC=xdrfile; + int explicitCI; + if (nC > 0) { + g.colors=readColorData(nC); + explicitCI=xdrfile; + } + + g.positionIndices=new int[nI][3]; + g.normalIndices=new int[nI][3]; + int[][] colorIndices; + if (nC > 0) + g.colorIndices=new int[nI][3]; + + for (int i=0; i < nI; ++i) { + xdrfile.dimension(3); + g.positionIndices[i]=xdrfile; + g.normalIndices[i]=explicitNI != 0 ? xdrfile : + g.positionIndices[i]; + g.colorIndices[i]=nC > 0 && explicitCI != 0 ? xdrfile : + g.positionIndices[i]; + } + int center=xdrfile; + int material=xdrfile; + triangleGroup(center,material,g); + } + + void readPixel() { + pixel P; + P.point=xdrfile; + P.width=xdrfile; + int material=xdrfile; + pixel(material,P); + } + + void process() + { + static bool processed; + if(processed) return; + + while (!eof(xdrfile)) + { + int ty=getType(); + if(ty == v3dtypes.header) + { + hasCameraInfo=true; + info=processHeader(); + } + else if(ty == v3dtypes.material) + { + materials.push(readMaterial()); + } + else if(ty == v3dtypes.bezierPatch) + { + readBezierPatch(); + } + else if(ty == v3dtypes.bezierTriangle) + { + readBezierTriangle(); + } + else if(ty == v3dtypes.bezierPatchColor) + { + readBezierPatchColor(); + } + else if(ty == v3dtypes.bezierTriangleColor) + { + readBezierTriangleColor(); + } + else if(ty == v3dtypes.quad) + { + readPolygon(4); + } + else if(ty == v3dtypes.quadColor) + { + readPolygonColor(4); + } + else if(ty == v3dtypes.triangle) + { + readPolygon(3); + } + else if(ty == v3dtypes.triangleColor) + { + readPolygonColor(3); + } + else if(ty == v3dtypes.sphere) + { + readSphere(); + } + else if(ty == v3dtypes.halfSphere) + { + readHemisphere(); + } + else if(ty == v3dtypes.cylinder) + { + readCylinder(); + } + else if(ty == v3dtypes.tube) + { + readTube(); + } + else if(ty == v3dtypes.disk) + { + readDisk(); + } + else if(ty == v3dtypes.curve) + { + readCurve(); + } + else if(ty == v3dtypes.line) + { + readLine(); + } + else if(ty == v3dtypes.triangles) + { + readTriangles(); + } + else if(ty == v3dtypes.centers) + { + centers=readCenters(); + } + else if(ty == v3dtypes.pixel) + { + readPixel(); + } + else + { + // abort("Unknown type:"+string(ty)); + } + } + processed=true; + } +} + +void importv3d(string name) +{ + if(name == stripextension(name)) name += ".v3d"; + v3dfile xf=v3dfile(name); + xf.process(); + xf.setCameraInfo(); + + for(int c=0; c < xf.surfaces.length; ++c) { + triple center=c > 0 ? xf.centers[c-1] : O; + render r=render(interaction(c == 0 ? Embedded : Billboard,center=center)); + surface[][] S=xf.surfaces[c]; + for(int m=0; m < S.length; ++m) + if(S.initialized(m)) + draw(S[m],xf.materials[m],r); + } + + for(int c=0; c < xf.paths3.length; ++c) { + triple center=c > 0 ? xf.centers[c-1] : O; + render r=render(interaction(c == 0 ? Embedded : Billboard,center=center)); + path3[][] G=xf.paths3[c]; + for(int m=0; m < G.length; ++m) + if(G.initialized(m)) { + material material=material(xf.materials[m]); + material.p[0] += thin(); + draw(G[m],material,currentlight,r); + } + } + + for(int c=0;c < xf.triangles.length; ++c) { + triple center=c > 0 ? xf.centers[c-1] : O; + render r=render(interaction(c == 0 ? Embedded : Billboard,center=center)); + triangleGroup[][] groups=xf.triangles[c]; + for(int m=0; m < groups.length; ++m) { + if(groups.initialized(m)) { + material material=xf.materials[m]; + triangleGroup[] triangleGroups=groups[m]; + for(triangleGroup g : triangleGroups) { + if(g.colors.length > 0) + draw(g.positions,g.positionIndices,g.normals,g.normalIndices, + g.colors,g.colorIndices,r); + else + draw(g.positions,g.positionIndices,g.normals,g.normalIndices, + material,r); + } + } + } + } + + for(int m=0; m < xf.pixels.length; ++m) { + if(xf.pixels.initialized(m)) { + material material=xf.materials[m]; + pixel[] pixels=xf.pixels[m]; + for(pixel P : pixels) + pixel(P.point,material.p[0],P.width); + } + } +} diff --git a/Master/texmf-dist/asymptote/v3dheadertypes.asy b/Master/texmf-dist/asymptote/v3dheadertypes.asy new file mode 100644 index 00000000000..fd4afe81652 --- /dev/null +++ b/Master/texmf-dist/asymptote/v3dheadertypes.asy @@ -0,0 +1,66 @@ +// Enum class for v3dheadertypes +// AUTO-GENERATED from v3dheadertypes.csv +// Generated at 2022-02-04 23:53:49.222250 + +struct v3dheadertypes +{ + int canvasWidth=1; +// UINT Canvas width + + int canvasHeight=2; +// UINT Canvas heighot + + int absolute=3; +// BOOL true: absolute size; false: scale to canvas + + int minBound=4; +// TRIPLE Scene minimum bounding box corners + + int maxBound=5; +// TRIPLE Scene maximum bounding box corners + + int orthographic=6; +// BOOL true: orthographic; false: perspective + + int angleOfView=7; +// REAL Field of view angle (in radians) + + int initialZoom=8; +// REAL Initial zoom + + int viewportShift=9; +// PAIR Viewport shift (for perspective projection) + + int viewportMargin=10; +// PAIR Margin around viewport + + int light=11; +// RGB Direction and color of each point light source + + int background=12; +// RGBA Background color + + int zoomFactor=13; +// REAL Zoom base factor + + int zoomPinchFactor=14; +// REAL Zoom pinch factor + + int zoomPinchCap=15; +// REAL Zoom pinch limit + + int zoomStep=16; +// REAL Zoom power step + + int shiftHoldDistance=17; +// REAL Shift-mode maximum hold distance (pixels) + + int shiftWaitTime=18; +// REAL Shift-mode hold time (milliseconds) + + int vibrateTime=19; +// REAL Shift-mode vibrate time (milliseconds) + +}; + +v3dheadertypes v3dheadertypes;// End of File diff --git a/Master/texmf-dist/asymptote/v3dtypes.asy b/Master/texmf-dist/asymptote/v3dtypes.asy new file mode 100644 index 00000000000..52515a14ba6 --- /dev/null +++ b/Master/texmf-dist/asymptote/v3dtypes.asy @@ -0,0 +1,34 @@ +// Enum class for v3dtypes +// AUTO-GENERATED from v3dtypes.csv +// Generated at 2022-02-04 23:53:49.158592 + +struct v3dtypes +{ + int material=1; + int transform=2; + int element=3; + int centers=4; + int header=5; + int line=64; + int triangle=65; + int quad=66; + int curve=128; + int bezierTriangle=129; + int bezierPatch=130; + int lineColor=192; + int triangleColor=193; + int quadColor=194; + int curveColor=256; + int bezierTriangleColor=257; + int bezierPatchColor=258; + int triangles=512; + int disk=1024; + int cylinder=1025; + int tube=1026; + int sphere=1027; + int halfSphere=1028; + int animation=2048; + int pixel=4096; +}; + +v3dtypes v3dtypes;// End of File diff --git a/Master/texmf-dist/asymptote/version.asy b/Master/texmf-dist/asymptote/version.asy index a5b37cb7d84..3307fb55963 100644 --- a/Master/texmf-dist/asymptote/version.asy +++ b/Master/texmf-dist/asymptote/version.asy @@ -1 +1 @@ -string VERSION="2.70"; +string VERSION="2.78"; diff --git a/Master/texmf-dist/asymptote/webgl/asygl.js b/Master/texmf-dist/asymptote/webgl/asygl.js index db8810f260f..f33ee3ef54f 100644 --- a/Master/texmf-dist/asymptote/webgl/asygl.js +++ b/Master/texmf-dist/asymptote/webgl/asygl.js @@ -1,6 +1,6 @@ /*@license AsyGL: Render Bezier patches and triangles via subdivision with WebGL. - Copyright 2019-2020: John C. Bowman and Supakorn "Jamie" Rassameemasmuang + Copyright 2019-2022: John C. Bowman and Supakorn "Jamie" Rassameemasmuang University of Alberta This program is free software; you can redistribute it and/or modify @@ -36,4 +36,4 @@ 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.*/ -let vertex="\nattribute vec3 position;\n#ifdef WIDTH\nattribute float width;\n#endif\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\nattribute float materialIndex;\n#ifdef COLOR\nattribute vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\n#endif\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\nvarying vec4 emissive;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvoid main(void)\n{\n vec4 v=vec4(position,1.0);\n gl_Position=projViewMat*v;\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n ViewPosition=(viewMat*v).xyz;\n#endif \n Normal=normalize(normal*normMat);\n \n Material m;\n#ifdef TRANSPARENT\n m=Materials[int(abs(materialIndex))-1];\n emissive=m.emissive;\n if(materialIndex >= 0.0) {\n diffuse=m.diffuse;\n } else {\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n }\n#else\n m=Materials[int(materialIndex)];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif\n#endif\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[int(materialIndex)].emissive;\n#endif\n#ifdef WIDTH\n gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\n\nfloat Roughness2;\nvec3 normal;\n\nstruct Light {\n vec3 direction;\n vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\nfloat NDF_TRG(vec3 h)\n{\n float ndoth=max(dot(normal,h),0.0);\n float alpha2=Roughness2*Roughness2;\n float denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n \nfloat GGX_Geom(vec3 v)\n{\n float ndotv=max(dot(v,normal),0.0);\n float ap=1.0+Roughness2;\n float k=0.125*ap*ap;\n return ndotv/((ndotv*(1.0-k))+k);\n}\n \nfloat Geom(vec3 v, vec3 l)\n{\n return GGX_Geom(v)*GGX_Geom(l);\n}\n \nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n float a=1.0-max(dot(h,v),0.0);\n float b=a*a;\n return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n \n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n vec3 lambertian=diffuse.rgb;\n vec3 h=normalize(lightDirection+viewDirection);\n \n float omegain=max(dot(viewDirection,normal),0.0);\n float omegali=max(dot(lightDirection,normal),0.0);\n \n float D=NDF_TRG(h);\n float G=Geom(viewDirection,lightDirection);\n float F=Fresnel(h,viewDirection,fresnel0);\n \n float denom=4.0*omegain*omegali;\n float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n \n vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n vec3 metal=rawReflectance*diffuse.rgb;\n \n return mix(dielectric,metal,metallic);\n}\n#endif\nvarying vec4 emissive;\n \nvoid main(void)\n{\n#if defined(NORMAL) && nlights > 0\n normal=normalize(Normal);\n normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n vec3 viewDir=vec3(0.0,0.0,1.0);\n#else\n vec3 viewDir=-normalize(ViewPosition);\n#endif\n Roughness2=roughness*roughness;\n vec3 color=emissive.rgb;\n for(int i=0; i < nlights; ++i) {\n Light Li=Lights[i];\n vec3 L=Li.direction;\n float cosTheta=max(dot(normal,L),0.0);\n vec3 radiance=cosTheta*Li.color;\n color += BRDF(viewDir,L)*radiance;\n }\n gl_FragColor=vec4(color,diffuse.a);\n#else\n gl_FragColor=emissive;\n#endif\n}\n";!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var a in i)("object"==typeof exports?exports:t)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(t){var e={};function i(a){if(e[a])return e[a].exports;var r=e[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,a){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:a})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=1)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setMatrixArrayType=function(t){e.ARRAY_TYPE=t},e.toRadian=function(t){return t*r},e.equals=function(t,e){return Math.abs(t-e)<=a*Math.max(1,Math.abs(t),Math.abs(e))};var a=e.EPSILON=1e-6;e.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,e.RANDOM=Math.random;var r=Math.PI/180},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.mat4=e.mat3=void 0;var a=n(i(2)),r=n(i(3));function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}e.mat3=a,e.mat4=r},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.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},e.fromMat4=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=c*s-o*l,m=-c*n+o*h,f=l*n-s*h,u=i*d+a*m+r*f;if(!u)return null;return u=1/u,t[0]=d*u,t[1]=(-c*a+r*l)*u,t[2]=(o*a-r*s)*u,t[3]=m*u,t[4]=(c*i-r*h)*u,t[5]=(-o*i+r*n)*u,t[6]=f*u,t[7]=(-l*i+a*h)*u,t[8]=(s*i-a*n)*u,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0))},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.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},e.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},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=e[9],m=e[10],f=e[11],u=e[12],p=e[13],v=e[14],g=e[15],x=i*o-a*s,w=i*h-r*s,M=i*l-n*s,b=a*h-r*o,S=a*l-n*o,P=r*l-n*h,A=c*p-d*u,y=c*v-m*u,T=c*g-f*u,R=d*v-m*p,D=d*g-f*p,I=m*g-f*v,z=x*I-w*D+M*R+b*T-S*y+P*A;if(!z)return null;return z=1/z,t[0]=(o*I-h*D+l*R)*z,t[1]=(r*D-a*I-n*R)*z,t[2]=(p*P-v*S+g*b)*z,t[3]=(m*S-d*P-f*b)*z,t[4]=(h*T-s*I-l*y)*z,t[5]=(i*I-r*T+n*y)*z,t[6]=(v*M-u*P-g*w)*z,t[7]=(c*P-m*M+f*w)*z,t[8]=(s*D-o*T+l*A)*z,t[9]=(a*T-i*D-n*A)*z,t[10]=(u*S-p*M+g*x)*z,t[11]=(d*M-c*S-f*x)*z,t[12]=(o*y-s*R-h*A)*z,t[13]=(i*R-a*y+r*A)*z,t[14]=(p*w-u*b-v*x)*z,t[15]=(c*b-d*w+m*x)*z,t},e.multiply=r,e.translate=function(t,e,i){var a=i[0],r=i[1],n=i[2],s=void 0,o=void 0,h=void 0,l=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,v=void 0,g=void 0;e===t?(t[12]=e[0]*a+e[4]*r+e[8]*n+e[12],t[13]=e[1]*a+e[5]*r+e[9]*n+e[13],t[14]=e[2]*a+e[6]*r+e[10]*n+e[14],t[15]=e[3]*a+e[7]*r+e[11]*n+e[15]):(s=e[0],o=e[1],h=e[2],l=e[3],c=e[4],d=e[5],m=e[6],f=e[7],u=e[8],p=e[9],v=e[10],g=e[11],t[0]=s,t[1]=o,t[2]=h,t[3]=l,t[4]=c,t[5]=d,t[6]=m,t[7]=f,t[8]=u,t[9]=p,t[10]=v,t[11]=g,t[12]=s*a+c*r+u*n+e[12],t[13]=o*a+d*r+p*n+e[13],t[14]=h*a+m*r+v*n+e[14],t[15]=l*a+f*r+g*n+e[15]);return t},e.rotate=function(t,e,i,r){var n,s,o,h,l,c,d,m,f,u,p,v,g,x,w,M,b,S,P,A,y,T,R,D,I=r[0],z=r[1],L=r[2],N=Math.sqrt(I*I+z*z+L*L);if(Math.abs(N)<a.EPSILON)return null;I*=N=1/N,z*=N,L*=N,n=Math.sin(i),s=Math.cos(i),o=1-s,h=e[0],l=e[1],c=e[2],d=e[3],m=e[4],f=e[5],u=e[6],p=e[7],v=e[8],g=e[9],x=e[10],w=e[11],M=I*I*o+s,b=z*I*o+L*n,S=L*I*o-z*n,P=I*z*o-L*n,A=z*z*o+s,y=L*z*o+I*n,T=I*L*o+z*n,R=z*L*o-I*n,D=L*L*o+s,t[0]=h*M+m*b+v*S,t[1]=l*M+f*b+g*S,t[2]=c*M+u*b+x*S,t[3]=d*M+p*b+w*S,t[4]=h*P+m*A+v*y,t[5]=l*P+f*A+g*y,t[6]=c*P+u*A+x*y,t[7]=d*P+p*A+w*y,t[8]=h*T+m*R+v*D,t[9]=l*T+f*R+g*D,t[10]=c*T+u*R+x*D,t[11]=d*T+p*R+w*D,e!==t&&(t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]);return t},e.fromTranslation=function(t,e){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]=e[0],t[13]=e[1],t[14]=e[2],t[15]=1,t},e.fromRotation=function(t,e,i){var r,n,s,o=i[0],h=i[1],l=i[2],c=Math.sqrt(o*o+h*h+l*l);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,h*=c,l*=c,r=Math.sin(e),n=Math.cos(e),s=1-n,t[0]=o*o*s+n,t[1]=h*o*s+l*r,t[2]=l*o*s-h*r,t[3]=0,t[4]=o*h*s-l*r,t[5]=h*h*s+n,t[6]=l*h*s+o*r,t[7]=0,t[8]=o*l*s+h*r,t[9]=h*l*s-o*r,t[10]=l*l*s+n,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,e,i,a,r,n,s){var o=1/(i-e),h=1/(r-a),l=1/(n-s);return t[0]=2*n*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*n*h,t[6]=0,t[7]=0,t[8]=(i+e)*o,t[9]=(r+a)*h,t[10]=(s+n)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=s*n*2*l,t[15]=0,t},e.ortho=function(t,e,i,a,r,n,s){var o=1/(e-i),h=1/(a-r),l=1/(n-s);return t[0]=-2*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*h,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*l,t[11]=0,t[12]=(e+i)*o,t[13]=(r+a)*h,t[14]=(s+n)*l,t[15]=1,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0));function r(t,e,i){var a=e[0],r=e[1],n=e[2],s=e[3],o=e[4],h=e[5],l=e[6],c=e[7],d=e[8],m=e[9],f=e[10],u=e[11],p=e[12],v=e[13],g=e[14],x=e[15],w=i[0],M=i[1],b=i[2],S=i[3];return t[0]=w*a+M*o+b*d+S*p,t[1]=w*r+M*h+b*m+S*v,t[2]=w*n+M*l+b*f+S*g,t[3]=w*s+M*c+b*u+S*x,w=i[4],M=i[5],b=i[6],S=i[7],t[4]=w*a+M*o+b*d+S*p,t[5]=w*r+M*h+b*m+S*v,t[6]=w*n+M*l+b*f+S*g,t[7]=w*s+M*c+b*u+S*x,w=i[8],M=i[9],b=i[10],S=i[11],t[8]=w*a+M*o+b*d+S*p,t[9]=w*r+M*h+b*m+S*v,t[10]=w*n+M*l+b*f+S*g,t[11]=w*s+M*c+b*u+S*x,w=i[12],M=i[13],b=i[14],S=i[15],t[12]=w*a+M*o+b*d+S*p,t[13]=w*r+M*h+b*m+S*v,t[14]=w*n+M*l+b*f+S*g,t[15]=w*s+M*c+b*u+S*x,t}}])}));let canvasWidth,canvasHeight,canvasWidth0,canvasHeight0,b,B,angle,Zoom0,zoom0,viewportmargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,Zoom,maxViewportWidth,maxViewportHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,viewportshift=[0,0],nlights=0,Nmaterials=2,materials=[],pixel=.75,zoomRemeshFactor=1.5,FillFactor=.1;const windowTrim=10;let lastZoom,H,zmin,zmax,size2,ArcballFactor,third=1/3,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),T=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[];class Material{constructor(t,e,i,a,r,n){this.diffuse=t,this.emissive=e,this.specular=i,this.shininess=a,this.metallic=r,this.fresnel0=n}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Materials["+e+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(t,e){this.direction=t,this.color=e}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Lights["+e+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelShader=initShader(["WIDTH"]),materialShader=initShader(["NORMAL"]),colorShader=initShader(["NORMAL","COLOR"]),transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"])}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function noGL(){gl||alert("Could not initialize WebGL")}function saveAttributes(){let t=window.top.document.asygl[alpha];t.gl=gl,t.nlights=Lights.length,t.Nmaterials=Nmaterials,t.maxMaterials=maxMaterials,t.pixelShader=pixelShader,t.materialShader=materialShader,t.colorShader=colorShader,t.transparentShader=transparentShader}function restoreAttributes(){let t=window.top.document.asygl[alpha];gl=t.gl,nlights=t.nlights,Nmaterials=t.Nmaterials,maxMaterials=t.maxMaterials,pixelShader=t.pixelShader,materialShader=t.materialShader,colorShader=t.colorShader,transparentShader=t.transparentShader}function initGL(){if(alpha=Background[3]<1,embedded){let t=window.top.document;null==t.asygl&&(t.asygl=Array(2)),context=canvas.getContext("2d"),offscreen=t.offscreen,offscreen||(offscreen=t.createElement("canvas"),t.offscreen=offscreen),t.asygl[alpha]&&t.asygl[alpha].gl?(restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes())):(gl=offscreen.getContext("webgl",{alpha:alpha}),gl||noGL(),initShaders(),t.asygl[alpha]={},saveAttributes())}else gl=canvas.getContext("webgl",{alpha:alpha}),gl||noGL(),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(t,e,i,a=[]){let r=`#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n#else\n precision mediump float;\n#endif\n #define nlights ${0==wireframe?Lights.length:0}\n\n const int Nlights=${Math.max(Lights.length,1)};\n\n #define Nmaterials ${Nmaterials}\n`;orthographic&&(r+="#define ORTHOGRAPHIC\n"),a.forEach(t=>r+="#define "+t+"\n");let n=t.createShader(i);return t.shaderSource(n,r+e),t.compileShader(n),t.getShaderParameter(n,t.COMPILE_STATUS)?n:(alert(t.getShaderInfoLog(n)),null)}function registerBuffer(t,e,i,a=gl.ARRAY_BUFFER){return t.length>0&&(0==e&&(e=gl.createBuffer(),i=!0),gl.bindBuffer(a,e),i&&gl.bufferData(a,t,gl.STATIC_DRAW)),e}function drawBuffer(t,e,i=t.indices){if(0==t.indices.length)return;let a=e!=pixelShader;setUniforms(t,e);let r=remesh||t.partial||!t.rendered;t.verticesBuffer=registerBuffer(new Float32Array(t.vertices),t.verticesBuffer,r),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a&&Lights.length>0?gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):pixel&&gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),t.materialsBuffer=registerBuffer(new Int16Array(t.materialIndices),t.materialsBuffer,r),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),e!=colorShader&&e!=transparentShader||(t.colorsBuffer=registerBuffer(new Uint8Array(t.colors),t.colorsBuffer,r),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),t.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),t.indicesBuffer,r,gl.ELEMENT_ARRAY_BUFFER),t.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:t.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(t){this.type=t||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(t,e,i=[0,0,0,0]){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(t,e,i,a=[0,0,0,0]){let r=6*t;this.vertices[r]=e[0],this.vertices[r+1]=e[1],this.vertices[r+2]=e[2],this.vertices[r+3]=i[0],this.vertices[r+4]=i[1],this.vertices[r+5]=i[2],this.materialIndices[t]=materialIndex;let n=4*t;this.colors[n]=a[0],this.colors[n+1]=a[1],this.colors[n+2]=a[2],this.colors[n+3]=a[3],this.indices.push(t)}append(t){append(this.vertices,t.vertices),append(this.materialIndices,t.materialIndices),append(this.colors,t.colors),appendOffset(this.indices,t.indices,this.nvertices),this.nvertices+=t.nvertices}}function append(t,e){let i=t.length,a=e.length;t.length+=a;for(let r=0;r<a;++r)t[i+r]=e[r]}function appendOffset(t,e,i){let a=t.length,r=e.length;t.length+=e.length;for(let n=0;n<r;++n)t[a+n]=e[n]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(t){let e=projViewMat,i=t[0],a=i[0],r=i[1],n=i[2],s=1/(e[3]*a+e[7]*r+e[11]*n+e[15]);this.x=this.X=(e[0]*a+e[4]*r+e[8]*n+e[12])*s,this.y=this.Y=(e[1]*a+e[5]*r+e[9]*n+e[13])*s;for(let i=1,a=t.length;i<a;++i){let a=t[i],r=a[0],n=a[1],s=a[2],o=1/(e[3]*r+e[7]*n+e[11]*s+e[15]),h=(e[0]*r+e[4]*n+e[8]*s+e[12])*o,l=(e[1]*r+e[5]*n+e[9]*s+e[13])*o;h<this.x?this.x=h:h>this.X&&(this.X=h),l<this.y?this.y=l:l>this.Y&&(this.Y=l)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(t){let e=this.c[0],i=this.c[1],a=this.c[2],r=t[0]-e,n=t[1]-i,s=t[2]-a;return[r*normMat[0]+n*normMat[3]+s*normMat[6]+e,r*normMat[1]+n*normMat[4]+s*normMat[7]+i,r*normMat[2]+n*normMat[5]+s*normMat[8]+a]}Tcorners(t,e){return[this.T(t),this.T([t[0],t[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],e[1],t[2]]),this.T(e)]}setMaterial(t,e){null==t.materialTable[this.MaterialIndex]&&(t.materials.length>=Nmaterials&&(t.partial=!0,e()),t.materialTable[this.MaterialIndex]=t.materials.length,t.materials.push(Materials[this.MaterialIndex])),materialIndex=t.materialTable[this.MaterialIndex]}render(){let t;if(this.setMaterialIndex(),0==this.CenterIndex?t=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],t=this.Tcorners(this.Min,this.Max)),this.offscreen(t))return this.data.clear(),void this.notRendered();let e,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();e=i}else{let t=i.length;e=Array(t);for(let a=0;a<t;++a)e[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/B[2],r=pixel*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=r*r,this.Epsilon=FillFactor*r,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(e)}}class BezierPatch extends Geometry{constructor(t,e,i,a,r,n){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.color=n,this.CenterIndex=e;let s=t.length;if(n){let t=n[0][3]+n[1][3]+n[2][3];this.transparent=16==s||4==s?t+n[3][3]<1020:t<765}else this.transparent=Materials[i].diffuse[3]<1;this.MaterialIndex=i,this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(t){let e=t[0];this.epsilon=0;let i=t.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([t[a][0]-e[0],t[a][1]-e[1],t[a][2]-e[2]]));this.epsilon*=Number.EPSILON}processTriangle(t){let e=t[0],i=t[1],a=t[2],r=unit(cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-e[0],a[1]-e[1],a[2]-e[2]]));if(!this.offscreen([e,i,a])){let t,n,s;this.color?(t=this.data.Vertex(e,r,this.color[0]),n=this.data.Vertex(i,r,this.color[1]),s=this.data.Vertex(a,r,this.color[2])):(t=this.vertex(e,r),n=this.vertex(i,r),s=this.vertex(a,r)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(t)),this.append()}}processQuad(t){let e=t[0],i=t[1],a=t[2],r=t[3],n=cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-r[0],a[1]-r[1],a[2]-r[2]],[r[0]-e[0],r[1]-e[1],r[2]-e[2]]),o=unit([n[0]+s[0],n[1]+s[1],n[2]+s[2]]);if(!this.offscreen([e,i,a,r])){let t,n,s,h;this.color?(t=this.data.Vertex(e,o,this.color[0]),n=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),h=this.data.Vertex(r,o,this.color[3])):(t=this.vertex(e,o),n=this.vertex(i,o),s=this.vertex(a,o),h=this.vertex(r,o)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(t),this.data.indices.push(s),this.data.indices.push(h)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(h),this.data.indices.push(h),this.data.indices.push(t)),this.append()}}curve(t,e,i,a,r){new BezierCurve([t[e],t[i],t[a],t[r]],0,materialIndex,this.Min,this.Max).render()}process(t){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==t.length)return this.process3(t);if(3==t.length)return this.processTriangle(t);if(4==t.length)return this.processQuad(t);if(1==wireframe)return this.curve(t,0,4,8,12),this.curve(t,12,13,14,15),this.curve(t,15,11,7,3),void this.curve(t,3,2,1,0);let e=t[0],i=t[3],a=t[12],r=t[15],n=this.normal(i,t[2],t[1],e,t[4],t[8],a);abs2(n)<this.epsilon&&(n=this.normal(i,t[2],t[1],e,t[13],t[14],r),abs2(n)<this.epsilon&&(n=this.normal(r,t[11],t[7],i,t[4],t[8],a)));let s=this.normal(e,t[4],t[8],a,t[13],t[14],r);abs2(s)<this.epsilon&&(s=this.normal(e,t[4],t[8],a,t[11],t[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,t[2],t[1],e,t[13],t[14],r)));let o=this.normal(a,t[13],t[14],r,t[11],t[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,t[13],t[14],r,t[2],t[1],e),abs2(o)<this.epsilon&&(o=this.normal(e,t[4],t[8],a,t[11],t[7],i)));let h=this.normal(r,t[11],t[7],i,t[2],t[1],e);if(abs2(h)<this.epsilon&&(h=this.normal(r,t[11],t[7],i,t[4],t[8],a),abs2(h)<this.epsilon&&(h=this.normal(a,t[13],t[14],r,t[2],t[1],e))),this.color){let l=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(e,n,l),u=this.data.Vertex(a,s,c),p=this.data.Vertex(r,o,d),v=this.data.Vertex(i,h,m);this.Render(t,f,u,p,v,e,a,r,i,!1,!1,!1,!1,l,c,d,m)}else{let l=this.vertex(e,n),c=this.vertex(a,s),d=this.vertex(r,o),m=this.vertex(i,h);this.Render(t,l,c,d,m,e,a,r,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(t,e,i,a,r,n,s,o,h,l,c,d,m,f,u,p,v){let g=this.Distance(t);if(g[0]<this.res2&&g[1]<this.res2)this.offscreen([n,s,o])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([n,o,h])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(a),this.data.indices.push(r)):(this.data.indices.push(a),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(e)));else{if(this.offscreen(t))return;let x=t[0],w=t[3],M=t[12],b=t[15];if(g[0]<this.res2){let g=new Split3(x,t[1],t[2],w),S=new Split3(t[4],t[5],t[6],t[7]),P=new Split3(t[8],t[9],t[10],t[11]),A=new Split3(M,t[13],t[14],b),y=[x,g.m0,g.m3,g.m5,t[4],S.m0,S.m3,S.m5,t[8],P.m0,P.m3,P.m5,M,A.m0,A.m3,A.m5],T=[g.m5,g.m4,g.m2,w,S.m5,S.m4,S.m2,t[7],P.m5,P.m4,P.m2,t[11],A.m5,A.m4,A.m2,b],R=this.normal(y[12],y[13],y[14],y[15],y[11],y[7],y[3]);abs2(R)<=this.epsilon&&(R=this.normal(y[12],y[13],y[14],y[15],y[2],y[1],y[0]),abs2(R)<=this.epsilon&&(R=this.normal(y[0],y[4],y[8],y[12],y[11],y[7],y[3])));let D=this.normal(T[3],T[2],T[1],T[0],T[4],T[8],T[12]);abs2(D)<=this.epsilon&&(D=this.normal(T[3],T[2],T[1],T[0],T[13],T[14],T[15]),abs2(D)<=this.epsilon&&(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12])));let I=this.Epsilon,z=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(T[12],T[8],T[4],T[0]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}else z=y[15];let L=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(x,t[1],t[2],w)<this.res2){let t=unit(this.differential(y[3],y[7],y[11],y[15]));L=[L[0]-I*t[0],L[1]-I*t[1],L[2]-I*t[2]]}else L=T[0];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(u[e]+p[e]),g[e]=.5*(v[e]+f[e]);let x=this.data.Vertex(z,R,t),w=this.data.Vertex(L,D,g);this.Render(y,e,i,x,w,n,s,z,L,l,c,!1,m,f,u,t,g),this.Render(T,w,x,a,r,L,z,o,h,!1,c,d,m,g,t,p,v)}else{let t=this.vertex(z,R),f=this.vertex(L,D);this.Render(y,e,i,t,f,n,s,z,L,l,c,!1,m),this.Render(T,f,t,a,r,L,z,o,h,!1,c,d,m)}return}if(g[1]<this.res2){let g=new Split3(x,t[4],t[8],M),S=new Split3(t[1],t[5],t[9],t[13]),P=new Split3(t[2],t[6],t[10],t[14]),A=new Split3(w,t[7],t[11],b),y=[x,t[1],t[2],w,g.m0,S.m0,P.m0,A.m0,g.m3,S.m3,P.m3,A.m3,g.m5,S.m5,P.m5,A.m5],T=[g.m5,S.m5,P.m5,A.m5,g.m4,S.m4,P.m4,A.m4,g.m2,S.m2,P.m2,A.m2,M,t[13],t[14],b],R=this.normal(y[0],y[4],y[8],y[12],y[13],y[14],y[15]);abs2(R)<=this.epsilon&&(R=this.normal(y[0],y[4],y[8],y[12],y[11],y[7],y[3]),abs2(R)<=this.epsilon&&(R=this.normal(y[3],y[2],y[1],y[0],y[13],y[14],y[15])));let D=this.normal(T[15],T[11],T[7],T[3],T[2],T[1],T[0]);abs2(D)<=this.epsilon&&(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12]),abs2(D)<=this.epsilon&&(D=this.normal(T[12],T[13],T[14],T[15],T[2],T[1],T[0])));let I=this.Epsilon,z=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(x,t[4],t[8],M)<this.res2){let t=unit(this.differential(T[0],T[1],T[2],T[3]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}else z=y[12];let L=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!d)if(d=Straightness(b,t[11],t[7],w)<this.res2){let t=unit(this.differential(y[15],y[14],y[13],y[12]));L=[L[0]-I*t[0],L[1]-I*t[1],L[2]-I*t[2]]}else L=T[3];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(p[e]+v[e]);let x=this.data.Vertex(z,R,t),w=this.data.Vertex(L,D,g);this.Render(y,e,x,w,r,n,z,L,h,l,!1,d,m,f,t,g,v),this.Render(T,x,i,a,w,z,s,o,L,l,c,d,!1,t,u,p,g)}else{let t=this.vertex(z,R),f=this.vertex(L,D);this.Render(y,e,t,f,r,n,z,L,h,l,!1,d,m),this.Render(T,t,i,a,f,z,s,o,L,l,c,d,!1)}return}let S=new Split3(x,t[1],t[2],w),P=new Split3(t[4],t[5],t[6],t[7]),A=new Split3(t[8],t[9],t[10],t[11]),y=new Split3(M,t[13],t[14],b),T=new Split3(x,t[4],t[8],M),R=new Split3(S.m0,P.m0,A.m0,y.m0),D=new Split3(S.m3,P.m3,A.m3,y.m3),I=new Split3(S.m5,P.m5,A.m5,y.m5),z=new Split3(S.m4,P.m4,A.m4,y.m4),L=new Split3(S.m2,P.m2,A.m2,y.m2),N=new Split3(w,t[7],t[11],b),E=[x,S.m0,S.m3,S.m5,T.m0,R.m0,D.m0,I.m0,T.m3,R.m3,D.m3,I.m3,T.m5,R.m5,D.m5,I.m5],O=[T.m5,R.m5,D.m5,I.m5,T.m4,R.m4,D.m4,I.m4,T.m2,R.m2,D.m2,I.m2,M,y.m0,y.m3,y.m5],V=[I.m5,z.m5,L.m5,N.m5,I.m4,z.m4,L.m4,N.m4,I.m2,z.m2,L.m2,N.m2,y.m5,y.m4,y.m2,b],C=[S.m5,S.m4,S.m2,w,I.m0,z.m0,L.m0,N.m0,I.m3,z.m3,L.m3,N.m3,I.m5,z.m5,L.m5,N.m5],B=E[15],H=this.normal(E[0],E[4],E[8],E[12],E[13],E[14],E[15]);abs2(H)<this.epsilon&&(H=this.normal(E[0],E[4],E[8],E[12],E[11],E[7],E[3]),abs2(H)<this.epsilon&&(H=this.normal(E[3],E[2],E[1],E[0],E[13],E[14],E[15])));let _=this.normal(O[12],O[13],O[14],O[15],O[11],O[7],O[3]);abs2(_)<this.epsilon&&(_=this.normal(O[12],O[13],O[14],O[15],O[2],O[1],O[0]),abs2(_)<this.epsilon&&(_=this.normal(O[0],O[4],O[8],O[12],O[11],O[7],O[3])));let F=this.normal(V[15],V[11],V[7],V[3],V[2],V[1],V[0]);abs2(F)<this.epsilon&&(F=this.normal(V[15],V[11],V[7],V[3],V[4],V[8],V[12]),abs2(F)<this.epsilon&&(F=this.normal(V[12],V[13],V[14],V[15],V[2],V[1],V[0])));let G=this.normal(C[3],C[2],C[1],C[0],C[4],C[8],C[12]);abs2(G)<this.epsilon&&(G=this.normal(C[3],C[2],C[1],C[0],C[13],C[14],C[15]),abs2(G)<this.epsilon&&(G=this.normal(C[15],C[11],C[7],C[3],C[4],C[8],C[12])));let W=this.normal(V[3],V[2],V[1],B,V[4],V[8],V[12]),U=this.Epsilon,Z=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(x,t[4],t[8],M)<this.res2){let t=unit(this.differential(O[0],O[1],O[2],O[3]));Z=[Z[0]-U*t[0],Z[1]-U*t[1],Z[2]-U*t[2]]}else Z=E[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(V[12],V[8],V[4],V[0]));j=[j[0]-U*t[0],j[1]-U*t[1],j[2]-U*t[2]]}else j=O[15];let k=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!d)if(d=Straightness(b,t[11],t[7],w)<this.res2){let t=unit(this.differential(C[15],C[14],C[13],C[12]));k=[k[0]-U*t[0],k[1]-U*t[1],k[2]-U*t[2]]}else k=V[3];let Y=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(x,t[1],t[2],w)<this.res2){let t=unit(this.differential(E[3],E[7],E[11],E[15]));Y=[Y[0]-U*t[0],Y[1]-U*t[1],Y[2]-U*t[2]]}else Y=C[0];if(f){let t=Array(4),g=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(u[e]+p[e]),x[e]=.5*(p[e]+v[e]),w[e]=.5*(v[e]+f[e]),M[e]=.5*(t[e]+x[e]);let b=this.data.Vertex(Z,H,t),S=this.data.Vertex(j,_,g),P=this.data.Vertex(k,F,x),A=this.data.Vertex(Y,G,w),y=this.data.Vertex(B,W,M);this.Render(E,e,b,y,A,n,Z,B,Y,l,!1,!1,m,f,t,M,w),this.Render(O,b,i,S,y,Z,s,j,B,l,c,!1,!1,t,u,g,M),this.Render(V,y,S,a,P,B,j,o,k,!1,c,d,!1,M,g,p,x),this.Render(C,A,y,P,r,Y,B,k,h,!1,!1,d,m,w,M,x,v)}else{let t=this.vertex(Z,H),f=this.vertex(j,_),u=this.vertex(k,F),p=this.vertex(Y,G),v=this.vertex(B,W);this.Render(E,e,t,v,p,n,Z,B,Y,l,!1,!1,m),this.Render(O,t,i,f,v,Z,s,j,B,l,c,!1,!1),this.Render(V,v,f,a,u,B,j,o,k,!1,c,d,!1),this.Render(C,p,v,u,r,Y,B,k,h,!1,!1,d,m)}}}process3(t){if(1==wireframe)return this.curve(t,0,1,3,6),this.curve(t,6,7,8,9),void this.curve(t,9,5,2,0);let e=t[0],i=t[6],a=t[9],r=this.normal(a,t[5],t[2],e,t[1],t[3],i),n=this.normal(e,t[1],t[3],i,t[7],t[8],a),s=this.normal(i,t[7],t[8],a,t[5],t[2],e);if(this.color){let o=this.color[0],h=this.color[1],l=this.color[2],c=this.data.Vertex(e,r,o),d=this.data.Vertex(i,n,h),m=this.data.Vertex(a,s,l);this.Render3(t,c,d,m,e,i,a,!1,!1,!1,o,h,l)}else{let o=this.vertex(e,r),h=this.vertex(i,n),l=this.vertex(a,s);this.Render3(t,o,h,l,e,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(t,e,i,a,r,n,s,o,h,l,c,d,m){if(this.Distance3(t)<this.res2)this.offscreen([r,n,s])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(e)));else{if(this.offscreen(t))return;let f=t[0],u=t[1],p=t[2],v=t[3],g=t[4],x=t[5],w=t[6],M=t[7],b=t[8],S=t[9],P=[.5*(S[0]+x[0]),.5*(S[1]+x[1]),.5*(S[2]+x[2])],A=[.5*(S[0]+b[0]),.5*(S[1]+b[1]),.5*(S[2]+b[2])],y=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],T=[.5*(b[0]+g[0]),.5*(b[1]+g[1]),.5*(b[2]+g[2])],R=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],D=[.5*(p[0]+g[0]),.5*(p[1]+g[1]),.5*(p[2]+g[2])],I=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],z=[.5*(g[0]+v[0]),.5*(g[1]+v[1]),.5*(g[2]+v[2])],L=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],N=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],E=[.5*(u[0]+v[0]),.5*(u[1]+v[1]),.5*(u[2]+v[2])],O=[.5*(v[0]+w[0]),.5*(v[1]+w[1]),.5*(v[2]+w[2])],V=[.5*(P[0]+y[0]),.5*(P[1]+y[1]),.5*(P[2]+y[2])],C=[.5*(A[0]+R[0]),.5*(A[1]+R[1]),.5*(A[2]+R[2])],B=[.5*(y[0]+I[0]),.5*(y[1]+I[1]),.5*(y[2]+I[2])],H=[.5*T[0]+.25*(g[0]+u[0]),.5*T[1]+.25*(g[1]+u[1]),.5*T[2]+.25*(g[2]+u[2])],_=[.5*(R[0]+L[0]),.5*(R[1]+L[1]),.5*(R[2]+L[2])],F=[.5*D[0]+.25*(g[0]+M[0]),.5*D[1]+.25*(g[1]+M[1]),.5*D[2]+.25*(g[2]+M[2])],G=[.25*(x[0]+g[0])+.5*z[0],.25*(x[1]+g[1])+.5*z[1],.25*(x[2]+g[2])+.5*z[2]],W=[.5*(N[0]+E[0]),.5*(N[1]+E[1]),.5*(N[2]+E[2])],U=[.5*(E[0]+O[0]),.5*(E[1]+O[1]),.5*(E[2]+O[2])],Z=[.5*(F[0]+W[0]),.5*(F[1]+W[1]),.5*(F[2]+W[2])],j=[.5*(F[0]+U[0]),.5*(F[1]+U[1]),.5*(F[2]+U[2])],k=[.5*(W[0]+U[0]),.5*(W[1]+U[1]),.5*(W[2]+U[2])],Y=[.5*(G[0]+_[0]),.5*(G[1]+_[1]),.5*(G[2]+_[2])],X=[.5*(C[0]+G[0]),.5*(C[1]+G[1]),.5*(C[2]+G[2])],q=[.5*(C[0]+_[0]),.5*(C[1]+_[1]),.5*(C[2]+_[2])],K=[.5*(V[0]+H[0]),.5*(V[1]+H[1]),.5*(V[2]+H[2])],$=[.5*(B[0]+H[0]),.5*(B[1]+H[1]),.5*(B[2]+H[2])],Q=[.5*(V[0]+B[0]),.5*(V[1]+B[1]),.5*(V[2]+B[2])],J=[f,N,I,W,[.5*(D[0]+N[0]),.5*(D[1]+N[1]),.5*(D[2]+N[2])],B,k,Z,$,Q],tt=[k,U,j,O,[.5*(z[0]+L[0]),.5*(z[1]+L[1]),.5*(z[2]+L[2])],Y,w,L,_,q],et=[Q,K,V,X,[.5*(P[0]+T[0]),.5*(P[1]+T[1]),.5*(P[2]+T[2])],P,q,C,A,S],it=[q,X,Y,K,[.25*(y[0]+R[0]+E[0]+g[0]),.25*(y[1]+R[1]+E[1]+g[1]),.25*(y[2]+R[2]+E[2]+g[2])],j,Q,$,Z,k],at=this.normal(k,j,Y,q,X,K,Q),rt=this.normal(q,X,K,Q,$,Z,k),nt=this.normal(Q,$,Z,k,j,Y,q),st=this.Epsilon,ot=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!o)if(o=Straightness(w,M,b,S)<this.res2){let t=unit(this.sumdifferential(it[0],it[2],it[5],it[9],it[1],it[3],it[6]));ot=[ot[0]-st*t[0],ot[1]-st*t[1],ot[2]-st*t[2]]}else ot=q;let ht=[.5*(s[0]+r[0]),.5*(s[1]+r[1]),.5*(s[2]+r[2])];if(!h)if(h=Straightness(f,p,x,S)<this.res2){let t=unit(this.sumdifferential(it[6],it[3],it[1],it[0],it[7],it[8],it[9]));ht=[ht[0]-st*t[0],ht[1]-st*t[1],ht[2]-st*t[2]]}else ht=Q;let lt=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])];if(!l)if(l=Straightness(f,u,v,w)<this.res2){let t=unit(this.sumdifferential(it[9],it[8],it[7],it[6],it[5],it[2],it[0]));lt=[lt[0]-st*t[0],lt[1]-st*t[1],lt[2]-st*t[2]]}else lt=k;if(c){let t=Array(4),f=Array(4),u=Array(4);for(let e=0;e<4;++e)t[e]=.5*(d[e]+m[e]),f[e]=.5*(m[e]+c[e]),u[e]=.5*(c[e]+d[e]);let p=this.data.Vertex(ot,at,t),v=this.data.Vertex(ht,rt,f),g=this.data.Vertex(lt,nt,u);this.Render3(J,e,g,v,r,lt,ht,!1,h,l,c,u,f),this.Render3(tt,g,i,p,lt,n,ot,o,!1,l,u,d,t),this.Render3(et,v,p,a,ht,ot,s,o,h,!1,f,t,m),this.Render3(it,p,v,g,ot,ht,lt,!1,!1,!1,t,f,u)}else{let t=this.vertex(ot,at),c=this.vertex(ht,rt),d=this.vertex(lt,nt);this.Render3(J,e,d,c,r,lt,ht,!1,h,l),this.Render3(tt,d,i,t,lt,n,ot,o,!1,l),this.Render3(et,c,t,a,ht,ot,s,o,h,!1),this.Render3(it,t,c,d,ot,ht,lt,!1,!1,!1)}}}Distance(t){let e=t[0],i=t[3],a=t[12],r=t[15],n=Flatness(e,a,i,r);n=Math.max(Straightness(e,t[4],t[8],a)),n=Math.max(n,Straightness(t[1],t[5],t[9],t[13])),n=Math.max(n,Straightness(i,t[7],t[11],r)),n=Math.max(n,Straightness(t[2],t[6],t[10],t[14]));let s=Flatness(e,i,a,r);return s=Math.max(s,Straightness(e,t[1],t[2],i)),s=Math.max(s,Straightness(t[4],t[5],t[6],t[7])),s=Math.max(s,Straightness(t[8],t[9],t[10],t[11])),s=Math.max(s,Straightness(a,t[13],t[14],r)),[n,s]}Distance3(t){let e=t[0],i=t[4],a=t[6],r=t[9],n=abs2([(e[0]+a[0]+r[0])*third-i[0],(e[1]+a[1]+r[1])*third-i[1],(e[2]+a[2]+r[2])*third-i[2]]);return n=Math.max(n,Straightness(e,t[1],t[3],a)),n=Math.max(n,Straightness(e,t[2],t[5],r)),Math.max(n,Straightness(a,t[7],t[8],r))}differential(t,e,i,a){let r=[3*(e[0]-t[0]),3*(e[1]-t[1]),3*(e[2]-t[2])];return abs2(r)>this.epsilon?r:(r=bezierPP(t,e,i),abs2(r)>this.epsilon?r:bezierPPP(t,e,i,a))}sumdifferential(t,e,i,a,r,n,s){let o=this.differential(t,e,i,a),h=this.differential(t,r,n,s);return[o[0]+h[0],o[1]+h[1],o[2]+h[2]]}normal(t,e,i,a,r,n,s){let o=3*(r[0]-a[0]),h=3*(r[1]-a[1]),l=3*(r[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[h*m-l*d,l*c-o*m,o*d-h*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,h,l],v=bezierPP(a,i,e),g=bezierPP(a,r,n),x=cross(g,u),w=cross(p,v);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,e,t),b=bezierPPP(a,r,n,s);x=cross(p,M),w=cross(b,u);let S=cross(g,v);return f=[x[0]+w[0]+S[0],x[1]+w[1]+S[1],x[2]+w[2]+S[2]],abs2(f)>this.epsilon?f:(x=cross(b,v),w=cross(g,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.CenterIndex=e,this.MaterialIndex=i}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(t){let e=t[0],i=t[1];if(!this.offscreen([e,i])){let t=[0,0,1];this.data.indices.push(this.data.vertex(e,t)),this.data.indices.push(this.data.vertex(i,t)),this.append()}}process(t){if(2==t.length)return this.processLine(t);let e=t[0],i=t[1],a=t[2],r=t[3],n=this.normal(bezierP(e,i),bezierPP(e,i,a)),s=this.normal(bezierP(a,r),bezierPP(r,a,i)),o=this.data.vertex(e,n),h=this.data.vertex(r,s);this.Render(t,o,h),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(t,e,i){let a=t[0],r=t[1],n=t[2],s=t[3];if(Straightness(a,r,n,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(e),this.data.indices.push(i));else{if(this.offscreen(t))return;let o=[.5*(a[0]+r[0]),.5*(a[1]+r[1]),.5*(a[2]+r[2])],h=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])],l=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])],c=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])],d=[.5*(h[0]+l[0]),.5*(h[1]+l[1]),.5*(h[2]+l[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,l,s],p=this.normal(bezierPh(a,r,n,s),bezierPPh(a,r,n,s)),v=this.data.vertex(m,p);this.Render(f,e,v),this.Render(u,v,i)}}normal(t,e){let i=dot(t,t),a=dot(t,e);return[i*e[0]-a*t[0],i*e[1]-a*t[1],i*e[2]-a*t[2]]}}class Pixel extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoint=t,this.width=e,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=r}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(t){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(t,e,i){super(),this.CenterIndex=0,this.MaterialIndex=t,this.Min=e,this.Max=i,this.Positions=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[t].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(t){materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,e=this.Indices.length;t<e;++t){let e=this.Indices[t],i=e[0],a=this.Positions[i[0]],r=this.Positions[i[1]],n=this.Positions[i[2]];if(!this.offscreen([a,r,n])){let t=e.length>1?e[1]:i;if(t&&0!=t.length||(t=i),this.Colors.length>0){let s=e.length>2?e[2]:i;s&&0!=s.length||(s=i);let o=this.Colors[s[0]],h=this.Colors[s[1]],l=this.Colors[s[2]];this.transparent|=o[3]+h[3]+l[3]<765,0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l)):(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[0],a,this.Normals[t[0]],o))}else 0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]])):(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[0],a,this.Normals[t[0]]))}}this.data.nvertices=this.Positions.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redraw(){initProjection(),setProjection(),remesh=!0,draw()}function home(){mat4.identity(rotMat),redraw()}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(t=[]){let e=getShader(gl,vertex,gl.VERTEX_SHADER,t),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,t),a=gl.createProgram();return gl.attachShader(a,e),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(t,e,i,a){this.m0=[.5*(t[0]+e[0]),.5*(t[1]+e[1]),.5*(t[2]+e[2])];let r=.5*(e[0]+i[0]),n=.5*(e[1]+i[1]),s=.5*(e[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+r),.5*(this.m0[1]+n),.5*(this.m0[2]+s)],this.m4=[.5*(r+this.m2[0]),.5*(n+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(t){let e=1/(Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])||1);return[t[0]*e,t[1]*e,t[2]*e]}function abs2(t){return t[0]*t[0]+t[1]*t[1]+t[2]*t[2]}function dot(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function cross(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function bezierP(t,e){return[e[0]-t[0],e[1]-t[1],e[2]-t[2]]}function bezierPP(t,e,i){return[3*(t[0]+i[0])-6*e[0],3*(t[1]+i[1])-6*e[1],3*(t[2]+i[2])-6*e[2]]}function bezierPPP(t,e,i,a){return[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])]}function bezierPh(t,e,i,a){return[i[0]+a[0]-t[0]-e[0],i[1]+a[1]-t[1]-e[1],i[2]+a[2]-t[2]-e[2]]}function bezierPPh(t,e,i,a){return[3*t[0]-5*e[0]+i[0]+a[0],3*t[1]-5*e[1]+i[1]+a[1],3*t[2]-5*e[2]+i[2]+a[2]]}function Straightness(t,e,i,a){let r=[third*(a[0]-t[0]),third*(a[1]-t[1]),third*(a[2]-t[2])];return Math.max(abs2([e[0]-r[0]-t[0],e[1]-r[1]-t[1],e[2]-r[2]-t[2]]),abs2([a[0]-r[0]-i[0],a[1]-r[1]-i[1],a[2]-r[2]-i[2]]))}function Flatness(t,e,i,a){let r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(r,unit(n))),abs2(cross(n,unit(r))))/9}function corners(t,e){return[t,[t[0],t[1],e[2]],[t[0],e[1],t[2]],[t[0],e[1],e[2]],[e[0],t[1],t[2]],[e[0],t[1],e[2]],[e[0],e[1],t[2]],e]}function minbound(t){return[Math.min(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.min(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.min(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5][2],t[6][2],t[7][2])]}function maxbound(t){return[Math.max(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.max(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.max(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5][2],t[6][2],t[7][2])]}function COBTarget(t,e){mat4.fromTranslation(T,[center.x,center.y,center.z]),mat4.invert(cjMatInv,T),mat4.multiply(t,e,cjMatInv),mat4.multiply(t,T,t)}function setUniforms(t,e){let i=e==pixelShader;gl.useProgram(e),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),e.projViewMatUniform=gl.getUniformLocation(e,"projViewMat"),e.viewMatUniform=gl.getUniformLocation(e,"viewMat"),e.normMatUniform=gl.getUniformLocation(e,"normMat"),e!=colorShader&&e!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let t=0;t<Lights.length;++t)Lights[t].setUniform(e,t);for(let i=0;i<t.materials.length;++i)t.materials[i].setUniform(e,i);gl.uniformMatrix4fv(e.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(e.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(e.normMatUniform,!1,normMat)}function handleMouseDown(t){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=t.clientX,lastMouseY=t.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(t){return Math.hypot(t[0].pageX-t[1].pageX,t[0].pageY-t[1].pageY)}function handleTouchStart(t){t.preventDefault(),zoomEnabled||enableZoom();let e=t.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=e.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=e[0].identifier,lastMouseX=e[0].pageX,lastMouseY=e[0].pageY),2!=e.length||mouseDownOrTouchActive||(touchId=e[0].identifier,pinchStart=pinchDistance(e),pinch=!0))}function handleMouseUpOrTouchEnd(t){mouseDownOrTouchActive=!1}function rotateScene(t,e,i,a,r){if(t==i&&e==a)return;let[n,s]=arcball([t,-e],[i,-a]);mat4.fromRotation(T,2*r*ArcballFactor*n/Zoom,s),mat4.multiply(rotMat,T,rotMat)}function shiftScene(t,e,i,a){let r=1/Zoom;shift.x+=(i-t)*r*halfCanvasWidth,shift.y-=(a-e)*r*halfCanvasHeight}function panScene(t,e,i,a){orthographic?shiftScene(t,e,i,a):(center.x+=(i-t)*(viewParam.xmax-viewParam.xmin),center.y-=(a-e)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let t=Math.sqrt(Number.MAX_VALUE),e=1/t;Zoom<=e&&(Zoom=e),Zoom>=t&&(Zoom=t),(zoomRemeshFactor*Zoom<lastZoom||Zoom>zoomRemeshFactor*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(t){let e=zoomStep*halfCanvasHeight*t;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(e)<i&&(Zoom*=zoomFactor**e,capzoom())}function normMouse(t){let e=t[0],i=t[1],a=Math.hypot(e,i);return a>1&&(denom=1/a,e*=denom,i*=denom),[e,i,Math.sqrt(Math.max(1-i*i-e*e,0))]}function arcball(t,e){let i=normMouse(t),a=normMouse(e),r=dot(i,a);return[r>1?0:r<-1?pi:Math.acos(r),unit(cross(i,a))]}function zoomScene(t,e,i,a){zoomImage(e-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(t,e,i,a=1){let r;switch(i){case 1:r=rotateScene;break;case 2:r=shiftScene;break;case 3:r=zoomScene;break;case 4:r=panScene;break;default:r=(t,e,i,a)=>{}}r((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(t-halfCanvasWidth)/halfCanvasWidth,(e-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=t,lastMouseY=e,setProjection(),draw()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function handleKey(t){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==t.keyCode)return void disableZoom();let e=[];switch(t.key){case"x":e=[1,0,0];break;case"y":e=[0,1,0];break;case"z":e=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders()),remesh=!0,draw();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}e.length>0&&(mat4.rotate(rotMat,rotMat,.1,e),updateViewMatrix(),draw())}function setZoom(){capzoom(),setProjection(),draw()}function handleMouseWheel(t){t.preventDefault(),t.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(t){if(!mouseDownOrTouchActive)return;let e,i=t.clientX,a=t.clientY;e=t.getModifierState("Control")?2:t.getModifierState("Shift")?3:t.getModifierState("Alt")?4:1,processDrag(i,a,e)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(t){if(t.preventDefault(),zooming)return;let e=t.targetTouches;if(!pinch&&1==e.length&&touchId==e[0].identifier){let t=e[0].pageX,i=e[0].pageY,a=t-lastMouseX,r=i-lastMouseY,n=a*a+r*r<=shiftHoldDistance*shiftHoldDistance;if(n&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(t,i,2);else if(!n){rotate=!0,processDrag(e[0].pageX,e[0].pageY,1,.5)}}if(pinch&&!swipe&&2==e.length&&touchId==e[0].identifier){let t=pinchDistance(e),i=t-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=t,swipe=rotate=zooming=!1,setProjection(),draw()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(t){let e=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=t.length;for(let r=0;r<t.length;++r){let n=6*r;zbuffer[r]=e*t[n]+i*t[n+1]+a*t[n+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let t=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,t),void transparentData.clear();if(t.length>0){transformVertices(transparentData.vertices);let e=t.length/3,i=Array(e).fill().map((t,e)=>e);i.sort((function(e,i){let a=3*e;Ia=t[a],Ib=t[a+1],Ic=t[a+2];let r=3*i;return IA=t[r],IB=t[r+1],IC=t[r+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(t.length);for(let r=0;r<e;++r){let e=3*i[r];a[3*r]=t[e],a[3*r+1]=t[e+1],a[3*r+2]=t[e+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent()}function draw(){embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let t=0;t<P.length;++t)P[t].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(t,e,i,a){let r=t/e,n=1/Zoom,s=(i/t+viewportshift[0])*Zoom,o=(a/e+viewportshift[1])*Zoom;if(orthographic){let t=B[0]-b[0],e=B[1]-b[1];if(t<e*r){let t=.5*e*r*n,i=2*t*s,a=e*n*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=b[1]*n-a,viewParam.ymax=B[1]*n-a}else{let e=.5*t/(r*Zoom),i=t*n*s,a=2*e*o;viewParam.xmin=b[0]*n-i,viewParam.xmax=B[0]*n-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}else{let t=H*n,e=t*r,i=2*e*s,a=2*t*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix()}function initProjection(){H=-Math.tan(.5*angle)*B[2],center.x=center.y=0,center.z=.5*(b[2]+B[2]),lastZoom=Zoom=zoom0,viewParam.zmin=b[2],viewParam.zmax=B[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen.width=canvasWidth,canvas.height=offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2}function setsize(t,e){t>maxViewportWidth&&(t=maxViewportWidth),e>maxViewportHeight&&(e=maxViewportHeight),shift.x*=t/canvasWidth,shift.y*=e/canvasHeight,canvasWidth=t,canvasHeight=e,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=Zoom0,absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let t=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&canvasWidth<canvasHeight*t&&(zoom0*=canvasWidth/(canvasHeight*t))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;viewportshift[0]/=zoom0,viewportshift[1]/=zoom0,setsize(canvasWidth,canvasHeight),redraw()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(t,e){if(this.center=t,e){let t=e[0],i=e[1];this.ct=Math.cos(t),this.st=Math.sin(t),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(t){return[t[0]+this.center[0],t[1]+this.center[1],t[2]+this.center[2]]}T(t){let e=t[0],i=t[1],a=t[2],r=e*this.ct+a*this.st;return[r*this.cp-i*this.sp+this.center[0],r*this.sp+i*this.cp+this.center[1],-e*this.st+a*this.ct+this.center[2]]}}function Tcorners(t,e,i){let a=[t(e),t([e[0],e[1],i[2]]),t([e[0],i[1],e[2]]),t([e[0],i[1],i[2]]),t([i[0],e[1],e[2]]),t([i[0],e[1],i[2]]),t([i[0],i[1],e[2]]),t(i)];return[minbound(a),maxbound(a)]}function sphere(t,e,i,r,n){let s,o,h,l,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,v=.996685028842544,g=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,v],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,v],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,v],[0,1,0],[0,1,m],[0,f,u],[0,p,v]],[[p,0,v],[p,a*p,v],[g,0,x],[a*p,p,v],[w,w,1],[.05*a,0,1],[0,p,v],[0,g,x],[0,.05*a,1],[0,0,1]]],b=new Align(t,n);function S(t){let e=Array(t.length);for(let i=0;i<t.length;++i){let a=t[i];e[i]=c([s*a[0],o*a[1],h*a[2]])}return e}n?(l=1,d=0,c=b.T.bind(b)):(l=-1,d=-e,c=b.T0.bind(b));let A=Tcorners(c,[-e,-e,d],[e,e,e]),y=A[0],T=A[1];for(let t=-1;t<=1;t+=2){s=t*e;for(let t=-1;t<=1;t+=2){o=t*e;for(let t=l;t<=1;t+=2){h=t*e;for(let t=0;t<2;++t)P.push(new BezierPatch(S(M[t]),i,r,y,T))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(t,e,i,r,n){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],h=new Align(t,n);let l=Tcorners(h.T.bind(h),[-e,-e,0],[e,e,0]);P.push(new BezierPatch(function(t){let i=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];i[a]=h.T([e*r[0],e*r[1],0])}return i}(o),i,r,l[0],l[1]))}function cylinder(t,e,i,r,n,s,o){let h,l,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(t,s);function m(t){let e=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];e[a]=d.T([h*r[0],l*r[1],i*r[2]])}return e}let f=Tcorners(d.T.bind(d),[-e,-e,0],[e,e,i]),u=f[0],p=f[1];for(let t=-1;t<=1;t+=2){h=t*e;for(let t=-1;t<=1;t+=2)l=t*e,P.push(new BezierPatch(m(c),r,n,u,p))}if(o){let e=d.T([0,0,i]);P.push(new BezierCurve([t,e],r,n,t,e))}}function rmf(t,e,i,a,r){class n{constructor(t,e,i){this.p=t,this.r=e,this.t=i,this.s=cross(i,e)}}let s=Number.EPSILON*Math.max(abs2(t),abs2(e),abs2(i),abs2(a));function o(r){if(1==r){let r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(r)>s?unit(r):(r=[2*i[0]-e[0]-a[0],2*i[1]-e[1]-a[1],2*i[2]-e[2]-a[2]],abs2(r)>s?unit(r):[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])])}let n=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])],o=[2*(t[0]+i[0])-4*e[0],2*(t[1]+i[1])-4*e[1],2*(t[2]+i[2])-4*e[2]],h=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],l=r*r,c=[n[0]*l+o[0]*r+h[0],n[1]*l+o[1]*r+h[1],n[2]*l+o[2]*r+h[2]];return abs2(c)>s?unit(c):(l=2*r,c=[n[0]*l+o[0],n[1]*l+o[1],n[2]*l+o[2]],abs2(c)>s?unit(c):unit(n))}let h=Array(r.length),l=[e[0]-t[0],e[1]-t[1],e[2]-t[2]];abs2(l)<s&&(l=[t[0]-2*e[0]+i[0],t[1]-2*e[1]+i[1],t[2]-2*e[2]+i[2]],abs2(l)<s&&(l=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])])),l=unit(l);let c=function(t){let e=cross(t,[0,1,0]),i=Number.EPSILON*abs2(t);return abs2(e)>i?unit(e):(e=cross(t,[0,0,1]),abs2(e)>i?unit(e):[1,0,0])}(l);h[0]=new n(t,c,l);for(let s=1;s<r.length;++s){let l=h[s-1],c=r[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,v=[f*t[0]+m*e[0]+d*i[0]+p*a[0],f*t[1]+m*e[1]+d*i[1]+p*a[1],f*t[2]+m*e[2]+d*i[2]+p*a[2]],g=[v[0]-l.p[0],v[1]-l.p[1],v[2]-l.p[2]];if(0!=g[0]||0!=g[1]||0!=g[2]){let t=l.r,e=unit(g),i=l.t,a=dot(e,i),r=[i[0]-2*a*e[0],i[1]-2*a*e[1],i[2]-2*a*e[2]];i=o(c);let d=2*dot(e,t),m=[t[0]-d*e[0],t[1]-d*e[1],t[2]-d*e[2]],f=unit([i[0]-r[0],i[1]-r[1],i[2]-r[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],h[s]=new n(v,unit(m),unit(i))}else h[s]=h[s-1]}return h}function tube(t,e,i,r,n,s,o){let h=rmf(t[0],t[1],t[2],t[3],[0,1/3,2/3,1]),l=a*e,c=[[e,0],[e,l],[l,e],[0,e]];function d(e,a,o,l){let d=Array(16);for(let i=0;i<4;++i){let r=h[i],n=r.r[0],s=r.s[0],m=n*e+s*a,f=n*o+s*l;n=r.r[1],s=r.s[1];let u=n*e+s*a,p=n*o+s*l;n=r.r[2],s=r.s[2];let v=n*e+s*a,g=n*o+s*l,x=t[i],w=x[0];w1=x[1],w2=x[2];for(let t=0;t<4;++t){let e=c[t],a=e[0],r=e[1];d[4*i+t]=[m*a+f*r+w,u*a+p*r+w1,v*a+g*r+w2]}}P.push(new BezierPatch(d,i,r,n,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(t,i,r,n,s))}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1)} +let vertex="\n#ifdef WEBGL2\n#define IN in\n#define OUT out\n#else\n#define IN attribute\n#define OUT varying\n#endif\n\nIN vec3 position;\n#ifdef WIDTH\nIN float width;\n#endif\n#ifdef NORMAL\nIN vec3 normal;\n#endif\n\nIN float materialIndex;\n\n#ifdef WEBGL2\nflat out int MaterialIndex;\n#ifdef COLOR\nOUT vec4 Color;\n#endif\n\n#else\nOUT vec4 diffuse;\nOUT vec3 specular;\nOUT float roughness,metallic,fresnel0;\nOUT vec4 emissive;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n#endif\n\n#ifdef COLOR\nIN vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nOUT vec3 ViewPosition;\n#endif\nOUT vec3 Normal;\n#endif\n\nvoid main(void)\n{\n vec4 v=vec4(position,1.0);\n gl_Position=projViewMat*v;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n ViewPosition=(viewMat*v).xyz;\n#endif\n Normal=normalize(normal*normMat);\n#endif\n\n#ifdef WEBGL2\n MaterialIndex=int(materialIndex);\n#ifdef COLOR\n Color=color;\n#endif\n#else\n#ifdef NORMAL\n Material m;\n#ifdef TRANSPARENT\n m=Materials[int(abs(materialIndex))-1];\n emissive=m.emissive;\n if(materialIndex >= 0.0)\n diffuse=m.diffuse;\n else {\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n }\n#else\n m=Materials[int(materialIndex)];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[int(materialIndex)].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#ifdef WIDTH\n gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef WEBGL2\n#define IN in\nout vec4 outValue;\n#define OUTVALUE outValue\n#else\n#define IN varying\n#define OUTVALUE gl_FragColor\n#endif\n\n#ifdef WEBGL2\nflat in int MaterialIndex;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvec4 diffuse;\nvec3 specular;\nfloat roughness,metallic,fresnel0;\nvec4 emissive;\n\n#ifdef COLOR\nin vec4 Color;\n#endif\n\n#else\nIN vec4 diffuse;\nIN vec3 specular;\nIN float roughness,metallic,fresnel0;\nIN vec4 emissive;\n#endif\n\n#ifdef NORMAL\n\n#ifndef ORTHOGRAPHIC\nIN vec3 ViewPosition;\n#endif\nIN vec3 Normal;\n\nvec3 normal;\n\nstruct Light {\n vec3 direction;\n vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\n#ifdef USE_IBL\nuniform sampler2D reflBRDFSampler;\nuniform sampler2D diffuseSampler;\nuniform sampler2D reflImgSampler;\n\nconst float pi=acos(-1.0);\nconst float piInv=1.0/pi;\nconst float twopi=2.0*pi;\nconst float twopiInv=1.0/twopi;\n\n// (x,y,z) -> (r,theta,phi);\n// theta -> [0,pi]: colatitude\n// phi -> [-pi,pi]: longitude\nvec3 cart2sphere(vec3 cart)\n{\n float x=cart.x;\n float y=cart.z;\n float z=cart.y;\n\n float r=length(cart);\n float theta=r > 0.0 ? acos(z/r) : 0.0;\n float phi=atan(y,x);\n\n return vec3(r,theta,phi);\n}\n\nvec2 normalizedAngle(vec3 cartVec)\n{\n vec3 sphericalVec=cart2sphere(cartVec);\n sphericalVec.y=sphericalVec.y*piInv;\n sphericalVec.z=0.75-sphericalVec.z*twopiInv;\n return sphericalVec.zy;\n}\n\nvec3 IBLColor(vec3 viewDir)\n{\n vec3 IBLDiffuse=diffuse.rgb*texture(diffuseSampler,normalizedAngle(normal)).rgb;\n vec3 reflectVec=normalize(reflect(-viewDir,normal));\n vec2 reflCoord=normalizedAngle(reflectVec);\n vec3 IBLRefl=textureLod(reflImgSampler,reflCoord,roughness*ROUGHNESS_STEP_COUNT).rgb;\n vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),roughness)).rg;\n float specularMultiplier=fresnel0*IBLbrdf.x+IBLbrdf.y;\n vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;\n vec3 metal=diffuse.rgb*IBLRefl;\n return mix(dielectric,metal,metallic);\n}\n#else\nfloat Roughness2;\nfloat NDF_TRG(vec3 h)\n{\n float ndoth=max(dot(normal,h),0.0);\n float alpha2=Roughness2*Roughness2;\n float denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n\nfloat GGX_Geom(vec3 v)\n{\n float ndotv=max(dot(v,normal),0.0);\n float ap=1.0+Roughness2;\n float k=0.125*ap*ap;\n return ndotv/((ndotv*(1.0-k))+k);\n}\n\nfloat Geom(vec3 v, vec3 l)\n{\n return GGX_Geom(v)*GGX_Geom(l);\n}\n\nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n float a=1.0-max(dot(h,v),0.0);\n float b=a*a;\n return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n\n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n vec3 lambertian=diffuse.rgb;\n vec3 h=normalize(lightDirection+viewDirection);\n\n float omegain=max(dot(viewDirection,normal),0.0);\n float omegaln=max(dot(lightDirection,normal),0.0);\n\n float D=NDF_TRG(h);\n float G=Geom(viewDirection,lightDirection);\n float F=Fresnel(h,viewDirection,fresnel0);\n\n float denom=4.0*omegain*omegaln;\n float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n\n vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n vec3 metal=rawReflectance*diffuse.rgb;\n\n return mix(dielectric,metal,metallic);\n}\n#endif\n\n#endif\n\nvoid main(void)\n{\n#ifdef WEBGL2\n#ifdef NORMAL\n Material m;\n#ifdef TRANSPARENT\n m=Materials[abs(MaterialIndex)-1];\n emissive=m.emissive;\n if(MaterialIndex >= 0)\n diffuse=m.diffuse;\n else {\n diffuse=Color;\n#if nlights == 0\n emissive += Color;\n#endif\n }\n#else\n m=Materials[MaterialIndex];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=Color;\n#if nlights == 0\n emissive += Color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[MaterialIndex].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#if defined(NORMAL) && nlights > 0\n normal=normalize(Normal);\n normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n vec3 viewDir=vec3(0.0,0.0,1.0);\n#else\n vec3 viewDir=-normalize(ViewPosition);\n#endif\n\nvec3 color;\n#ifdef USE_IBL\n color=IBLColor(viewDir);\n#else\n Roughness2=roughness*roughness;\n color=emissive.rgb;\n for(int i=0; i < nlights; ++i) {\n Light Li=Lights[i];\n vec3 L=Li.direction;\n float cosTheta=max(dot(normal,L),0.0);\n vec3 radiance=cosTheta*Li.color;\n color += BRDF(viewDir,L)*radiance;\n }\n#endif\n OUTVALUE=vec4(color,diffuse.a);\n#else\n OUTVALUE=emissive;\n#endif\n}\n";!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var a in i)("object"==typeof exports?exports:e)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(e){var t={};function i(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=e,i.c=t,i.d=function(e,t,a){i.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=1)}([function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=a*Math.max(1,Math.abs(e),Math.abs(t))};var a=t.EPSILON=1e-6;t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random;var n=Math.PI/180},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.mat4=t.mat3=void 0;var a=r(i(2)),n=r(i(3));function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}t.mat3=a,t.mat4=n},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=c*s-o*h,m=-c*r+o*l,f=h*r-s*l,u=i*d+a*m+n*f;if(!u)return null;return u=1/u,e[0]=d*u,e[1]=(-c*a+n*h)*u,e[2]=(o*a-n*s)*u,e[3]=m*u,e[4]=(c*i-n*l)*u,e[5]=(-o*i+n*r)*u,e[6]=f*u,e[7]=(-h*i+a*l)*u,e[8]=(s*i-a*r)*u,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0))},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=t[9],m=t[10],f=t[11],u=t[12],p=t[13],g=t[14],v=t[15],x=i*o-a*s,w=i*l-n*s,M=i*h-r*s,b=a*l-n*o,T=a*h-r*o,S=n*h-r*l,R=c*p-d*u,A=c*g-m*u,I=c*v-f*u,P=d*g-m*p,E=d*v-f*p,y=m*v-f*g,L=x*y-w*E+M*P+b*I-T*A+S*R;if(!L)return null;return L=1/L,e[0]=(o*y-l*E+h*P)*L,e[1]=(n*E-a*y-r*P)*L,e[2]=(p*S-g*T+v*b)*L,e[3]=(m*T-d*S-f*b)*L,e[4]=(l*I-s*y-h*A)*L,e[5]=(i*y-n*I+r*A)*L,e[6]=(g*M-u*S-v*w)*L,e[7]=(c*S-m*M+f*w)*L,e[8]=(s*E-o*I+h*R)*L,e[9]=(a*I-i*E-r*R)*L,e[10]=(u*T-p*M+v*x)*L,e[11]=(d*M-c*T-f*x)*L,e[12]=(o*A-s*P-l*R)*L,e[13]=(i*P-a*A+n*R)*L,e[14]=(p*w-u*b-g*x)*L,e[15]=(c*b-d*w+m*x)*L,e},t.multiply=n,t.translate=function(e,t,i){var a=i[0],n=i[1],r=i[2],s=void 0,o=void 0,l=void 0,h=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,g=void 0,v=void 0;t===e?(e[12]=t[0]*a+t[4]*n+t[8]*r+t[12],e[13]=t[1]*a+t[5]*n+t[9]*r+t[13],e[14]=t[2]*a+t[6]*n+t[10]*r+t[14],e[15]=t[3]*a+t[7]*n+t[11]*r+t[15]):(s=t[0],o=t[1],l=t[2],h=t[3],c=t[4],d=t[5],m=t[6],f=t[7],u=t[8],p=t[9],g=t[10],v=t[11],e[0]=s,e[1]=o,e[2]=l,e[3]=h,e[4]=c,e[5]=d,e[6]=m,e[7]=f,e[8]=u,e[9]=p,e[10]=g,e[11]=v,e[12]=s*a+c*n+u*r+t[12],e[13]=o*a+d*n+p*r+t[13],e[14]=l*a+m*n+g*r+t[14],e[15]=h*a+f*n+v*r+t[15]);return e},t.rotate=function(e,t,i,n){var r,s,o,l,h,c,d,m,f,u,p,g,v,x,w,M,b,T,S,R,A,I,P,E,y=n[0],L=n[1],D=n[2],O=Math.sqrt(y*y+L*L+D*D);if(Math.abs(O)<a.EPSILON)return null;y*=O=1/O,L*=O,D*=O,r=Math.sin(i),s=Math.cos(i),o=1-s,l=t[0],h=t[1],c=t[2],d=t[3],m=t[4],f=t[5],u=t[6],p=t[7],g=t[8],v=t[9],x=t[10],w=t[11],M=y*y*o+s,b=L*y*o+D*r,T=D*y*o-L*r,S=y*L*o-D*r,R=L*L*o+s,A=D*L*o+y*r,I=y*D*o+L*r,P=L*D*o-y*r,E=D*D*o+s,e[0]=l*M+m*b+g*T,e[1]=h*M+f*b+v*T,e[2]=c*M+u*b+x*T,e[3]=d*M+p*b+w*T,e[4]=l*S+m*R+g*A,e[5]=h*S+f*R+v*A,e[6]=c*S+u*R+x*A,e[7]=d*S+p*R+w*A,e[8]=l*I+m*P+g*E,e[9]=h*I+f*P+v*E,e[10]=c*I+u*P+x*E,e[11]=d*I+p*P+w*E,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]);return e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e},t.fromRotation=function(e,t,i){var n,r,s,o=i[0],l=i[1],h=i[2],c=Math.sqrt(o*o+l*l+h*h);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,l*=c,h*=c,n=Math.sin(t),r=Math.cos(t),s=1-r,e[0]=o*o*s+r,e[1]=l*o*s+h*n,e[2]=h*o*s-l*n,e[3]=0,e[4]=o*l*s-h*n,e[5]=l*l*s+r,e[6]=h*l*s+o*n,e[7]=0,e[8]=o*h*s+l*n,e[9]=l*h*s-o*n,e[10]=h*h*s+r,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,a,n,r,s){var o=1/(i-t),l=1/(n-a),h=1/(r-s);return e[0]=2*r*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*r*l,e[6]=0,e[7]=0,e[8]=(i+t)*o,e[9]=(n+a)*l,e[10]=(s+r)*h,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*r*2*h,e[15]=0,e},t.ortho=function(e,t,i,a,n,r,s){var o=1/(t-i),l=1/(a-n),h=1/(r-s);return e[0]=-2*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*h,e[11]=0,e[12]=(t+i)*o,e[13]=(n+a)*l,e[14]=(s+r)*h,e[15]=1,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0));function n(e,t,i){var a=t[0],n=t[1],r=t[2],s=t[3],o=t[4],l=t[5],h=t[6],c=t[7],d=t[8],m=t[9],f=t[10],u=t[11],p=t[12],g=t[13],v=t[14],x=t[15],w=i[0],M=i[1],b=i[2],T=i[3];return e[0]=w*a+M*o+b*d+T*p,e[1]=w*n+M*l+b*m+T*g,e[2]=w*r+M*h+b*f+T*v,e[3]=w*s+M*c+b*u+T*x,w=i[4],M=i[5],b=i[6],T=i[7],e[4]=w*a+M*o+b*d+T*p,e[5]=w*n+M*l+b*m+T*g,e[6]=w*r+M*h+b*f+T*v,e[7]=w*s+M*c+b*u+T*x,w=i[8],M=i[9],b=i[10],T=i[11],e[8]=w*a+M*o+b*d+T*p,e[9]=w*n+M*l+b*m+T*g,e[10]=w*r+M*h+b*f+T*v,e[11]=w*s+M*c+b*u+T*x,w=i[12],M=i[13],b=i[14],T=i[15],e[12]=w*a+M*o+b*d+T*p,e[13]=w*n+M*l+b*m+T*g,e[14]=w*r+M*h+b*f+T*v,e[15]=w*s+M*c+b*u+T*x,e}}])}));let Transform,canvasWidth,canvasHeight,imageURL,image,minBound,maxBound,orthographic,angleOfView,initialZoom,viewportMargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,canvasWidth0,canvasHeight0,zoom0,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,ibl=!1,viewportShift=[0,0],webgl2=!1,nlights=0,Nmaterials=2,materials=[];const pixelResolution=.75,zoomRemeshFactor=1.5,FillFactor=.1,windowTrim=10,third=1/3,pi=Math.acos(-1),radians=pi/180;let Zoom,lastZoom,xshift,yshift,maxViewportWidth,maxViewportHeight,H,zmin,zmax,size2,ArcballFactor,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),Temp=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[],IBLReflMap=null,IBLDiffuseMap=null,IBLbdrfMap=null;function IBLReady(){return null!==IBLReflMap&&null!==IBLDiffuseMap&&null!==IBLbdrfMap}function SetIBL(){embedded||deleteShaders(),initShaders(ibl)}let roughnessStepCount=8;class Material{constructor(e,t,i,a,n,r){this.diffuse=e,this.emissive=t,this.specular=i,this.shininess=a,this.metallic=n,this.fresnel0=r}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Materials["+t+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(e,t){this.direction=e,this.color=t}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Lights["+t+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(e=!1){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelOpt=["WIDTH"],materialOpt=["NORMAL"],colorOpt=["NORMAL","COLOR"],transparentOpt=["NORMAL","COLOR","TRANSPARENT"],e&&(materialOpt.push("USE_IBL"),transparentOpt.push("USE_IBL")),pixelShader=initShader(pixelOpt),materialShader=initShader(materialOpt),colorShader=initShader(colorOpt),transparentShader=initShader(transparentOpt)}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function saveAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];e.gl=gl,e.nlights=Lights.length,e.Nmaterials=Nmaterials,e.maxMaterials=maxMaterials,e.pixelShader=pixelShader,e.materialShader=materialShader,e.colorShader=colorShader,e.transparentShader=transparentShader}function restoreAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];gl=e.gl,nlights=e.nlights,Nmaterials=e.Nmaterials,maxMaterials=e.maxMaterials,pixelShader=e.pixelShader,materialShader=e.materialShader,colorShader=e.colorShader,transparentShader=e.transparentShader}function webGL(e,t){let i;return webgl2&&(i=e.getContext("webgl2",{alpha:t}),embedded&&!i)?(webgl2=!1,ibl=!1,initGL(!1),null):(i||(webgl2=!1,ibl=!1,i=e.getContext("webgl",{alpha:t})),i||alert("Could not initialize WebGL"),i)}function initGL(e=!0){if(ibl&&(webgl2=!0),alpha=Background[3]<1,embedded){let t=window.top.document;if(e&&(context=canvas.getContext("2d")),offscreen=webgl2?t.offscreen2:t.offscreen,offscreen||(offscreen=t.createElement("canvas"),webgl2?t.offscreen2=offscreen:t.offscreen=offscreen),webgl2?t.asygl2||(t.asygl2=Array(2)):t.asygl||(t.asygl=Array(2)),asygl=webgl2?t.asygl2:t.asygl,asygl[alpha]&&asygl[alpha].gl)restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes());else{if(rc=webGL(offscreen,alpha),!rc)return;gl=rc,initShaders(),webgl2?t.asygl2[alpha]={}:t.asygl[alpha]={},saveAttributes()}}else gl=webGL(canvas,alpha),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(e,t,i,a=[]){let n=webgl2?"300 es":"100",r=Array(...a),s=[["nlights",0==wireframe?Lights.length:0],["Nmaterials",Nmaterials]],o=[["int","Nlights",Math.max(Lights.length,1)]];webgl2&&r.push("WEBGL2"),ibl&&s.push(["ROUGHNESS_STEP_COUNT",roughnessStepCount.toFixed(2)]),orthographic&&r.push("ORTHOGRAPHIC"),macros_str=s.map(e=>`#define ${e[0]} ${e[1]}`).join("\n"),define_str=r.map(e=>"#define "+e).join("\n"),const_str=o.map(e=>`const ${e[0]} ${e[1]}=${e[2]};`).join("\n"),ext_str=[].map(e=>`#extension ${e}: enable`).join("\n"),shaderSrc=`#version ${n}\n${ext_str}\n${define_str}\n${const_str}\n${macros_str}\n\n\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n \n${t}\n `;let l=e.createShader(i);return e.shaderSource(l,shaderSrc),e.compileShader(l),e.getShaderParameter(l,e.COMPILE_STATUS)?l:(alert(e.getShaderInfoLog(l)),null)}function registerBuffer(e,t,i,a=gl.ARRAY_BUFFER){return e.length>0&&(0==t&&(t=gl.createBuffer(),i=!0),gl.bindBuffer(a,t),i&&gl.bufferData(a,e,gl.STATIC_DRAW)),t}function drawBuffer(e,t,i=e.indices){if(0==e.indices.length)return;let a=t!=pixelShader;setUniforms(e,t),null!=IBLDiffuseMap&&(gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,IBLbdrfMap),gl.uniform1i(gl.getUniformLocation(t,"reflBRDFSampler"),0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,IBLDiffuseMap),gl.uniform1i(gl.getUniformLocation(t,"diffuseSampler"),1),gl.activeTexture(gl.TEXTURE2),gl.bindTexture(gl.TEXTURE_2D,IBLReflMap),gl.uniform1i(gl.getUniformLocation(t,"reflImgSampler"),2));let n=remesh||e.partial||!e.rendered;e.verticesBuffer=registerBuffer(new Float32Array(e.vertices),e.verticesBuffer,n),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a?Lights.length>0&&gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),e.materialsBuffer=registerBuffer(new Int16Array(e.materialIndices),e.materialsBuffer,n),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),t!=colorShader&&t!=transparentShader||(e.colorsBuffer=registerBuffer(new Uint8Array(e.colors),e.colorsBuffer,n),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),e.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),e.indicesBuffer,n,gl.ELEMENT_ARRAY_BUFFER),e.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:e.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(e){this.type=e||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(e,t,i=[0,0,0,0]){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(e,t,i,a=[0,0,0,0]){let n=6*e;this.vertices[n]=t[0],this.vertices[n+1]=t[1],this.vertices[n+2]=t[2],this.vertices[n+3]=i[0],this.vertices[n+4]=i[1],this.vertices[n+5]=i[2],this.materialIndices[e]=materialIndex;let r=4*e;this.colors[r]=a[0],this.colors[r+1]=a[1],this.colors[r+2]=a[2],this.colors[r+3]=a[3],this.indices.push(e)}append(e){append(this.vertices,e.vertices),append(this.materialIndices,e.materialIndices),append(this.colors,e.colors),appendOffset(this.indices,e.indices,this.nvertices),this.nvertices+=e.nvertices}}function append(e,t){let i=e.length,a=t.length;e.length+=a;for(let n=0;n<a;++n)e[i+n]=t[n]}function appendOffset(e,t,i){let a=e.length,n=t.length;e.length+=t.length;for(let r=0;r<n;++r)e[a+r]=t[r]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(e){let t=projViewMat,i=e[0],a=i[0],n=i[1],r=i[2],s=1/(t[3]*a+t[7]*n+t[11]*r+t[15]);this.x=this.X=(t[0]*a+t[4]*n+t[8]*r+t[12])*s,this.y=this.Y=(t[1]*a+t[5]*n+t[9]*r+t[13])*s;for(let i=1,a=e.length;i<a;++i){let a=e[i],n=a[0],r=a[1],s=a[2],o=1/(t[3]*n+t[7]*r+t[11]*s+t[15]),l=(t[0]*n+t[4]*r+t[8]*s+t[12])*o,h=(t[1]*n+t[5]*r+t[9]*s+t[13])*o;l<this.x?this.x=l:l>this.X&&(this.X=l),h<this.y?this.y=h:h>this.Y&&(this.Y=h)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(e){let t=this.c[0],i=this.c[1],a=this.c[2],n=e[0]-t,r=e[1]-i,s=e[2]-a;return[n*normMat[0]+r*normMat[3]+s*normMat[6]+t,n*normMat[1]+r*normMat[4]+s*normMat[7]+i,n*normMat[2]+r*normMat[5]+s*normMat[8]+a]}Tcorners(e,t){return[this.T(e),this.T([e[0],e[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],t[1],e[2]]),this.T(t)]}setMaterial(e,t){null==e.materialTable[this.MaterialIndex]&&(e.materials.length>=Nmaterials&&(e.partial=!0,t()),e.materialTable[this.MaterialIndex]=e.materials.length,e.materials.push(Materials[this.MaterialIndex])),materialIndex=e.materialTable[this.MaterialIndex]}render(){let e;if(this.setMaterialIndex(),0==this.CenterIndex?e=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],e=this.Tcorners(this.Min,this.Max)),this.offscreen(e))return this.data.clear(),void this.notRendered();let t,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();t=i}else{let e=i.length;t=Array(e);for(let a=0;a<e;++a)t[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/maxBound[2],n=.75*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=n*n,this.Epsilon=.1*n,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(t)}}class BezierPatch extends Geometry{constructor(e,t,i,a,n,r){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n,this.color=r;let s=e.length;if(r){let e=r[0][3]+r[1][3]+r[2][3];this.transparent=16==s||4==s?e+r[3][3]<1020:e<765}else this.transparent=Materials[i].diffuse[3]<1;this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(e){let t=e[0];this.epsilon=0;let i=e.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([e[a][0]-t[0],e[a][1]-t[1],e[a][2]-t[2]]));this.epsilon*=Number.EPSILON}processTriangle(e){let t=e[0],i=e[1],a=e[2],n=unit(cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-t[0],a[1]-t[1],a[2]-t[2]]));if(!this.offscreen([t,i,a])){let e,r,s;this.color?(e=this.data.Vertex(t,n,this.color[0]),r=this.data.Vertex(i,n,this.color[1]),s=this.data.Vertex(a,n,this.color[2])):(e=this.vertex(t,n),r=this.vertex(i,n),s=this.vertex(a,n)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(e)),this.append()}}processQuad(e){let t=e[0],i=e[1],a=e[2],n=e[3],r=cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-n[0],a[1]-n[1],a[2]-n[2]],[n[0]-t[0],n[1]-t[1],n[2]-t[2]]),o=unit([r[0]+s[0],r[1]+s[1],r[2]+s[2]]);if(!this.offscreen([t,i,a,n])){let e,r,s,l;this.color?(e=this.data.Vertex(t,o,this.color[0]),r=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),l=this.data.Vertex(n,o,this.color[3])):(e=this.vertex(t,o),r=this.vertex(i,o),s=this.vertex(a,o),l=this.vertex(n,o)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(e),this.data.indices.push(s),this.data.indices.push(l)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(l),this.data.indices.push(l),this.data.indices.push(e)),this.append()}}curve(e,t,i,a,n){new BezierCurve([e[t],e[i],e[a],e[n]],0,materialIndex,this.Min,this.Max).render()}process(e){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==e.length)return this.process3(e);if(3==e.length)return this.processTriangle(e);if(4==e.length)return this.processQuad(e);if(1==wireframe)return this.curve(e,0,4,8,12),this.curve(e,12,13,14,15),this.curve(e,15,11,7,3),void this.curve(e,3,2,1,0);let t=e[0],i=e[3],a=e[12],n=e[15],r=this.normal(i,e[2],e[1],t,e[4],e[8],a);abs2(r)<this.epsilon&&(r=this.normal(i,e[2],e[1],t,e[13],e[14],n),abs2(r)<this.epsilon&&(r=this.normal(n,e[11],e[7],i,e[4],e[8],a)));let s=this.normal(t,e[4],e[8],a,e[13],e[14],n);abs2(s)<this.epsilon&&(s=this.normal(t,e[4],e[8],a,e[11],e[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,e[2],e[1],t,e[13],e[14],n)));let o=this.normal(a,e[13],e[14],n,e[11],e[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,e[13],e[14],n,e[2],e[1],t),abs2(o)<this.epsilon&&(o=this.normal(t,e[4],e[8],a,e[11],e[7],i)));let l=this.normal(n,e[11],e[7],i,e[2],e[1],t);if(abs2(l)<this.epsilon&&(l=this.normal(n,e[11],e[7],i,e[4],e[8],a),abs2(l)<this.epsilon&&(l=this.normal(a,e[13],e[14],n,e[2],e[1],t))),this.color){let h=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(t,r,h),u=this.data.Vertex(a,s,c),p=this.data.Vertex(n,o,d),g=this.data.Vertex(i,l,m);this.Render(e,f,u,p,g,t,a,n,i,!1,!1,!1,!1,h,c,d,m)}else{let h=this.vertex(t,r),c=this.vertex(a,s),d=this.vertex(n,o),m=this.vertex(i,l);this.Render(e,h,c,d,m,t,a,n,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(e,t,i,a,n,r,s,o,l,h,c,d,m,f,u,p,g){let v=this.Distance(e);if(v[0]<this.res2&&v[1]<this.res2)this.offscreen([r,s,o])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([r,o,l])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(a),this.data.indices.push(n)):(this.data.indices.push(a),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(t)));else{if(this.offscreen(e))return;let x=e[0],w=e[3],M=e[12],b=e[15];if(v[0]<this.res2){let v=new Split3(x,e[1],e[2],w),T=new Split3(e[4],e[5],e[6],e[7]),S=new Split3(e[8],e[9],e[10],e[11]),R=new Split3(M,e[13],e[14],b),A=[x,v.m0,v.m3,v.m5,e[4],T.m0,T.m3,T.m5,e[8],S.m0,S.m3,S.m5,M,R.m0,R.m3,R.m5],I=[v.m5,v.m4,v.m2,w,T.m5,T.m4,T.m2,e[7],S.m5,S.m4,S.m2,e[11],R.m5,R.m4,R.m2,b],P=this.normal(A[12],A[13],A[14],A[15],A[11],A[7],A[3]);abs2(P)<=this.epsilon&&(P=this.normal(A[12],A[13],A[14],A[15],A[2],A[1],A[0]),abs2(P)<=this.epsilon&&(P=this.normal(A[0],A[4],A[8],A[12],A[11],A[7],A[3])));let E=this.normal(I[3],I[2],I[1],I[0],I[4],I[8],I[12]);abs2(E)<=this.epsilon&&(E=this.normal(I[3],I[2],I[1],I[0],I[13],I[14],I[15]),abs2(E)<=this.epsilon&&(E=this.normal(I[15],I[11],I[7],I[3],I[4],I[8],I[12])));let y=this.Epsilon,L=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(I[12],I[8],I[4],I[0]));L=[L[0]-y*e[0],L[1]-y*e[1],L[2]-y*e[2]]}else L=A[15];let D=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(A[3],A[7],A[11],A[15]));D=[D[0]-y*e[0],D[1]-y*e[1],D[2]-y*e[2]]}else D=I[0];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(u[t]+p[t]),v[t]=.5*(g[t]+f[t]);let x=this.data.Vertex(L,P,e),w=this.data.Vertex(D,E,v);this.Render(A,t,i,x,w,r,s,L,D,h,c,!1,m,f,u,e,v),this.Render(I,w,x,a,n,D,L,o,l,!1,c,d,m,v,e,p,g)}else{let e=this.vertex(L,P),f=this.vertex(D,E);this.Render(A,t,i,e,f,r,s,L,D,h,c,!1,m),this.Render(I,f,e,a,n,D,L,o,l,!1,c,d,m)}return}if(v[1]<this.res2){let v=new Split3(x,e[4],e[8],M),T=new Split3(e[1],e[5],e[9],e[13]),S=new Split3(e[2],e[6],e[10],e[14]),R=new Split3(w,e[7],e[11],b),A=[x,e[1],e[2],w,v.m0,T.m0,S.m0,R.m0,v.m3,T.m3,S.m3,R.m3,v.m5,T.m5,S.m5,R.m5],I=[v.m5,T.m5,S.m5,R.m5,v.m4,T.m4,S.m4,R.m4,v.m2,T.m2,S.m2,R.m2,M,e[13],e[14],b],P=this.normal(A[0],A[4],A[8],A[12],A[13],A[14],A[15]);abs2(P)<=this.epsilon&&(P=this.normal(A[0],A[4],A[8],A[12],A[11],A[7],A[3]),abs2(P)<=this.epsilon&&(P=this.normal(A[3],A[2],A[1],A[0],A[13],A[14],A[15])));let E=this.normal(I[15],I[11],I[7],I[3],I[2],I[1],I[0]);abs2(E)<=this.epsilon&&(E=this.normal(I[15],I[11],I[7],I[3],I[4],I[8],I[12]),abs2(E)<=this.epsilon&&(E=this.normal(I[12],I[13],I[14],I[15],I[2],I[1],I[0])));let y=this.Epsilon,L=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(I[0],I[1],I[2],I[3]));L=[L[0]-y*e[0],L[1]-y*e[1],L[2]-y*e[2]]}else L=A[12];let D=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(A[15],A[14],A[13],A[12]));D=[D[0]-y*e[0],D[1]-y*e[1],D[2]-y*e[2]]}else D=I[3];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(p[t]+g[t]);let x=this.data.Vertex(L,P,e),w=this.data.Vertex(D,E,v);this.Render(A,t,x,w,n,r,L,D,l,h,!1,d,m,f,e,v,g),this.Render(I,x,i,a,w,L,s,o,D,h,c,d,!1,e,u,p,v)}else{let e=this.vertex(L,P),f=this.vertex(D,E);this.Render(A,t,e,f,n,r,L,D,l,h,!1,d,m),this.Render(I,e,i,a,f,L,s,o,D,h,c,d,!1)}return}let T=new Split3(x,e[1],e[2],w),S=new Split3(e[4],e[5],e[6],e[7]),R=new Split3(e[8],e[9],e[10],e[11]),A=new Split3(M,e[13],e[14],b),I=new Split3(x,e[4],e[8],M),P=new Split3(T.m0,S.m0,R.m0,A.m0),E=new Split3(T.m3,S.m3,R.m3,A.m3),y=new Split3(T.m5,S.m5,R.m5,A.m5),L=new Split3(T.m4,S.m4,R.m4,A.m4),D=new Split3(T.m2,S.m2,R.m2,A.m2),O=new Split3(w,e[7],e[11],b),B=[x,T.m0,T.m3,T.m5,I.m0,P.m0,E.m0,y.m0,I.m3,P.m3,E.m3,y.m3,I.m5,P.m5,E.m5,y.m5],N=[I.m5,P.m5,E.m5,y.m5,I.m4,P.m4,E.m4,y.m4,I.m2,P.m2,E.m2,y.m2,M,A.m0,A.m3,A.m5],z=[y.m5,L.m5,D.m5,O.m5,y.m4,L.m4,D.m4,O.m4,y.m2,L.m2,D.m2,O.m2,A.m5,A.m4,A.m2,b],_=[T.m5,T.m4,T.m2,w,y.m0,L.m0,D.m0,O.m0,y.m3,L.m3,D.m3,O.m3,y.m5,L.m5,D.m5,O.m5],C=B[15],V=this.normal(B[0],B[4],B[8],B[12],B[13],B[14],B[15]);abs2(V)<this.epsilon&&(V=this.normal(B[0],B[4],B[8],B[12],B[11],B[7],B[3]),abs2(V)<this.epsilon&&(V=this.normal(B[3],B[2],B[1],B[0],B[13],B[14],B[15])));let U=this.normal(N[12],N[13],N[14],N[15],N[11],N[7],N[3]);abs2(U)<this.epsilon&&(U=this.normal(N[12],N[13],N[14],N[15],N[2],N[1],N[0]),abs2(U)<this.epsilon&&(U=this.normal(N[0],N[4],N[8],N[12],N[11],N[7],N[3])));let H=this.normal(z[15],z[11],z[7],z[3],z[2],z[1],z[0]);abs2(H)<this.epsilon&&(H=this.normal(z[15],z[11],z[7],z[3],z[4],z[8],z[12]),abs2(H)<this.epsilon&&(H=this.normal(z[12],z[13],z[14],z[15],z[2],z[1],z[0])));let G=this.normal(_[3],_[2],_[1],_[0],_[4],_[8],_[12]);abs2(G)<this.epsilon&&(G=this.normal(_[3],_[2],_[1],_[0],_[13],_[14],_[15]),abs2(G)<this.epsilon&&(G=this.normal(_[15],_[11],_[7],_[3],_[4],_[8],_[12])));let F=this.normal(z[3],z[2],z[1],C,z[4],z[8],z[12]),W=this.Epsilon,X=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(N[0],N[1],N[2],N[3]));X=[X[0]-W*e[0],X[1]-W*e[1],X[2]-W*e[2]]}else X=B[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(z[12],z[8],z[4],z[0]));j=[j[0]-W*e[0],j[1]-W*e[1],j[2]-W*e[2]]}else j=N[15];let Z=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(_[15],_[14],_[13],_[12]));Z=[Z[0]-W*e[0],Z[1]-W*e[1],Z[2]-W*e[2]]}else Z=z[3];let k=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(B[3],B[7],B[11],B[15]));k=[k[0]-W*e[0],k[1]-W*e[1],k[2]-W*e[2]]}else k=_[0];if(f){let e=Array(4),v=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(u[t]+p[t]),x[t]=.5*(p[t]+g[t]),w[t]=.5*(g[t]+f[t]),M[t]=.5*(e[t]+x[t]);let b=this.data.Vertex(X,V,e),T=this.data.Vertex(j,U,v),S=this.data.Vertex(Z,H,x),R=this.data.Vertex(k,G,w),A=this.data.Vertex(C,F,M);this.Render(B,t,b,A,R,r,X,C,k,h,!1,!1,m,f,e,M,w),this.Render(N,b,i,T,A,X,s,j,C,h,c,!1,!1,e,u,v,M),this.Render(z,A,T,a,S,C,j,o,Z,!1,c,d,!1,M,v,p,x),this.Render(_,R,A,S,n,k,C,Z,l,!1,!1,d,m,w,M,x,g)}else{let e=this.vertex(X,V),f=this.vertex(j,U),u=this.vertex(Z,H),p=this.vertex(k,G),g=this.vertex(C,F);this.Render(B,t,e,g,p,r,X,C,k,h,!1,!1,m),this.Render(N,e,i,f,g,X,s,j,C,h,c,!1,!1),this.Render(z,g,f,a,u,C,j,o,Z,!1,c,d,!1),this.Render(_,p,g,u,n,k,C,Z,l,!1,!1,d,m)}}}process3(e){if(1==wireframe)return this.curve(e,0,1,3,6),this.curve(e,6,7,8,9),void this.curve(e,9,5,2,0);let t=e[0],i=e[6],a=e[9],n=this.normal(a,e[5],e[2],t,e[1],e[3],i),r=this.normal(t,e[1],e[3],i,e[7],e[8],a),s=this.normal(i,e[7],e[8],a,e[5],e[2],t);if(this.color){let o=this.color[0],l=this.color[1],h=this.color[2],c=this.data.Vertex(t,n,o),d=this.data.Vertex(i,r,l),m=this.data.Vertex(a,s,h);this.Render3(e,c,d,m,t,i,a,!1,!1,!1,o,l,h)}else{let o=this.vertex(t,n),l=this.vertex(i,r),h=this.vertex(a,s);this.Render3(e,o,l,h,t,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(e,t,i,a,n,r,s,o,l,h,c,d,m){if(this.Distance3(e)<this.res2)this.offscreen([n,r,s])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(t)));else{if(this.offscreen(e))return;let f=e[0],u=e[1],p=e[2],g=e[3],v=e[4],x=e[5],w=e[6],M=e[7],b=e[8],T=e[9],S=[.5*(T[0]+x[0]),.5*(T[1]+x[1]),.5*(T[2]+x[2])],R=[.5*(T[0]+b[0]),.5*(T[1]+b[1]),.5*(T[2]+b[2])],A=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],I=[.5*(b[0]+v[0]),.5*(b[1]+v[1]),.5*(b[2]+v[2])],P=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],E=[.5*(p[0]+v[0]),.5*(p[1]+v[1]),.5*(p[2]+v[2])],y=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],L=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],D=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],B=[.5*(u[0]+g[0]),.5*(u[1]+g[1]),.5*(u[2]+g[2])],N=[.5*(g[0]+w[0]),.5*(g[1]+w[1]),.5*(g[2]+w[2])],z=[.5*(S[0]+A[0]),.5*(S[1]+A[1]),.5*(S[2]+A[2])],_=[.5*(R[0]+P[0]),.5*(R[1]+P[1]),.5*(R[2]+P[2])],C=[.5*(A[0]+y[0]),.5*(A[1]+y[1]),.5*(A[2]+y[2])],V=[.5*I[0]+.25*(v[0]+u[0]),.5*I[1]+.25*(v[1]+u[1]),.5*I[2]+.25*(v[2]+u[2])],U=[.5*(P[0]+D[0]),.5*(P[1]+D[1]),.5*(P[2]+D[2])],H=[.5*E[0]+.25*(v[0]+M[0]),.5*E[1]+.25*(v[1]+M[1]),.5*E[2]+.25*(v[2]+M[2])],G=[.25*(x[0]+v[0])+.5*L[0],.25*(x[1]+v[1])+.5*L[1],.25*(x[2]+v[2])+.5*L[2]],F=[.5*(O[0]+B[0]),.5*(O[1]+B[1]),.5*(O[2]+B[2])],W=[.5*(B[0]+N[0]),.5*(B[1]+N[1]),.5*(B[2]+N[2])],X=[.5*(H[0]+F[0]),.5*(H[1]+F[1]),.5*(H[2]+F[2])],j=[.5*(H[0]+W[0]),.5*(H[1]+W[1]),.5*(H[2]+W[2])],Z=[.5*(F[0]+W[0]),.5*(F[1]+W[1]),.5*(F[2]+W[2])],k=[.5*(G[0]+U[0]),.5*(G[1]+U[1]),.5*(G[2]+U[2])],Y=[.5*(_[0]+G[0]),.5*(_[1]+G[1]),.5*(_[2]+G[2])],q=[.5*(_[0]+U[0]),.5*(_[1]+U[1]),.5*(_[2]+U[2])],$=[.5*(z[0]+V[0]),.5*(z[1]+V[1]),.5*(z[2]+V[2])],K=[.5*(C[0]+V[0]),.5*(C[1]+V[1]),.5*(C[2]+V[2])],Q=[.5*(z[0]+C[0]),.5*(z[1]+C[1]),.5*(z[2]+C[2])],J=[f,O,y,F,[.5*(E[0]+O[0]),.5*(E[1]+O[1]),.5*(E[2]+O[2])],C,Z,X,K,Q],ee=[Z,W,j,N,[.5*(L[0]+D[0]),.5*(L[1]+D[1]),.5*(L[2]+D[2])],k,w,D,U,q],te=[Q,$,z,Y,[.5*(S[0]+I[0]),.5*(S[1]+I[1]),.5*(S[2]+I[2])],S,q,_,R,T],ie=[q,Y,k,$,[.25*(A[0]+P[0]+B[0]+v[0]),.25*(A[1]+P[1]+B[1]+v[1]),.25*(A[2]+P[2]+B[2]+v[2])],j,Q,K,X,Z],ae=this.normal(Z,j,k,q,Y,$,Q),ne=this.normal(q,Y,$,Q,K,X,Z),re=this.normal(Q,K,X,Z,j,k,q),se=this.Epsilon,oe=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!o)if(o=Straightness(w,M,b,T)<this.res2){let e=unit(this.sumdifferential(ie[0],ie[2],ie[5],ie[9],ie[1],ie[3],ie[6]));oe=[oe[0]-se*e[0],oe[1]-se*e[1],oe[2]-se*e[2]]}else oe=q;let le=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!l)if(l=Straightness(f,p,x,T)<this.res2){let e=unit(this.sumdifferential(ie[6],ie[3],ie[1],ie[0],ie[7],ie[8],ie[9]));le=[le[0]-se*e[0],le[1]-se*e[1],le[2]-se*e[2]]}else le=Q;let he=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])];if(!h)if(h=Straightness(f,u,g,w)<this.res2){let e=unit(this.sumdifferential(ie[9],ie[8],ie[7],ie[6],ie[5],ie[2],ie[0]));he=[he[0]-se*e[0],he[1]-se*e[1],he[2]-se*e[2]]}else he=Z;if(c){let e=Array(4),f=Array(4),u=Array(4);for(let t=0;t<4;++t)e[t]=.5*(d[t]+m[t]),f[t]=.5*(m[t]+c[t]),u[t]=.5*(c[t]+d[t]);let p=this.data.Vertex(oe,ae,e),g=this.data.Vertex(le,ne,f),v=this.data.Vertex(he,re,u);this.Render3(J,t,v,g,n,he,le,!1,l,h,c,u,f),this.Render3(ee,v,i,p,he,r,oe,o,!1,h,u,d,e),this.Render3(te,g,p,a,le,oe,s,o,l,!1,f,e,m),this.Render3(ie,p,g,v,oe,le,he,!1,!1,!1,e,f,u)}else{let e=this.vertex(oe,ae),c=this.vertex(le,ne),d=this.vertex(he,re);this.Render3(J,t,d,c,n,he,le,!1,l,h),this.Render3(ee,d,i,e,he,r,oe,o,!1,h),this.Render3(te,c,e,a,le,oe,s,o,l,!1),this.Render3(ie,e,c,d,oe,le,he,!1,!1,!1)}}}Distance(e){let t=e[0],i=e[3],a=e[12],n=e[15],r=Flatness(t,a,i,n);r=Math.max(Straightness(t,e[4],e[8],a)),r=Math.max(r,Straightness(e[1],e[5],e[9],e[13])),r=Math.max(r,Straightness(i,e[7],e[11],n)),r=Math.max(r,Straightness(e[2],e[6],e[10],e[14]));let s=Flatness(t,i,a,n);return s=Math.max(s,Straightness(t,e[1],e[2],i)),s=Math.max(s,Straightness(e[4],e[5],e[6],e[7])),s=Math.max(s,Straightness(e[8],e[9],e[10],e[11])),s=Math.max(s,Straightness(a,e[13],e[14],n)),[r,s]}Distance3(e){let t=e[0],i=e[4],a=e[6],n=e[9],r=abs2([(t[0]+a[0]+n[0])*(1/3)-i[0],(t[1]+a[1]+n[1])*(1/3)-i[1],(t[2]+a[2]+n[2])*(1/3)-i[2]]);return r=Math.max(r,Straightness(t,e[1],e[3],a)),r=Math.max(r,Straightness(t,e[2],e[5],n)),Math.max(r,Straightness(a,e[7],e[8],n))}differential(e,t,i,a){let n=[3*(t[0]-e[0]),3*(t[1]-e[1]),3*(t[2]-e[2])];return abs2(n)>this.epsilon?n:(n=bezierPP(e,t,i),abs2(n)>this.epsilon?n:bezierPPP(e,t,i,a))}sumdifferential(e,t,i,a,n,r,s){let o=this.differential(e,t,i,a),l=this.differential(e,n,r,s);return[o[0]+l[0],o[1]+l[1],o[2]+l[2]]}normal(e,t,i,a,n,r,s){let o=3*(n[0]-a[0]),l=3*(n[1]-a[1]),h=3*(n[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[l*m-h*d,h*c-o*m,o*d-l*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,l,h],g=bezierPP(a,i,t),v=bezierPP(a,n,r),x=cross(v,u),w=cross(p,g);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,t,e),b=bezierPPP(a,n,r,s);x=cross(p,M),w=cross(b,u);let T=cross(v,g);return f=[x[0]+w[0]+T[0],x[1]+w[1]+T[1],x[2]+w[2]+T[2]],abs2(f)>this.epsilon?f:(x=cross(b,g),w=cross(v,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(e){let t=e[0],i=e[1];if(!this.offscreen([t,i])){let e=[0,0,1];this.data.indices.push(this.data.vertex(t,e)),this.data.indices.push(this.data.vertex(i,e)),this.append()}}process(e){if(2==e.length)return this.processLine(e);let t=e[0],i=e[1],a=e[2],n=e[3],r=this.normal(bezierP(t,i),bezierPP(t,i,a)),s=this.normal(bezierP(a,n),bezierPP(n,a,i)),o=this.data.vertex(t,r),l=this.data.vertex(n,s);this.Render(e,o,l),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(e,t,i){let a=e[0],n=e[1],r=e[2],s=e[3];if(Straightness(a,n,r,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(t),this.data.indices.push(i));else{if(this.offscreen(e))return;let o=[.5*(a[0]+n[0]),.5*(a[1]+n[1]),.5*(a[2]+n[2])],l=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])],h=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])],c=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])],d=[.5*(l[0]+h[0]),.5*(l[1]+h[1]),.5*(l[2]+h[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,h,s],p=this.normal(bezierPh(a,n,r,s),bezierPPh(a,n,r,s)),g=this.data.vertex(m,p);this.Render(f,t,g),this.Render(u,g,i)}}normal(e,t){let i=dot(e,e),a=dot(e,t);return[i*t[0]-a*e[0],i*t[1]-a*e[1],i*t[2]-a*e[2]]}}class Pixel extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoint=e,this.width=t,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(e){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(e,t,i,a){super(),this.CenterIndex=e,this.MaterialIndex=t,this.Min=i,this.Max=a,this.controlpoints=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[this.MaterialIndex].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(e){this.data.vertices=new Array(6*e.length),materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,i=this.Indices.length;t<i;++t){let i=this.Indices[t],a=i[0],n=e[a[0]],r=e[a[1]],s=e[a[2]];if(!this.offscreen([n,r,s])){let e=i.length>1?i[1]:a;if(e&&0!=e.length||(e=a),this.Colors.length>0){let t=i.length>2?i[2]:a;t&&0!=t.length||(t=a);let o=this.Colors[t[0]],l=this.Colors[t[1]],h=this.Colors[t[2]];this.transparent|=o[3]+l[3]+h[3]<765,0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h)):(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[0],n,this.Normals[e[0]],o))}else 0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]])):(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[0],n,this.Normals[e[0]]))}}this.data.nvertices=e.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redrawScene(){initProjection(),setProjection(),remesh=!0,drawScene()}function home(){mat4.identity(rotMat),redrawScene(),window.top.asyWebApplication&&window.top.asyWebApplication.setProjection(""),window.parent.asyProjection=!1}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(e=[]){let t=getShader(gl,vertex,gl.VERTEX_SHADER,e),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,e),a=gl.createProgram();return gl.attachShader(a,t),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(e,t,i,a){this.m0=[.5*(e[0]+t[0]),.5*(e[1]+t[1]),.5*(e[2]+t[2])];let n=.5*(t[0]+i[0]),r=.5*(t[1]+i[1]),s=.5*(t[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+n),.5*(this.m0[1]+r),.5*(this.m0[2]+s)],this.m4=[.5*(n+this.m2[0]),.5*(r+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(e){let t=1/(Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])||1);return[e[0]*t,e[1]*t,e[2]*t]}function abs2(e){return e[0]*e[0]+e[1]*e[1]+e[2]*e[2]}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function cross(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function bezierP(e,t){return[t[0]-e[0],t[1]-e[1],t[2]-e[2]]}function bezierPP(e,t,i){return[3*(e[0]+i[0])-6*t[0],3*(e[1]+i[1])-6*t[1],3*(e[2]+i[2])-6*t[2]]}function bezierPPP(e,t,i,a){return[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])]}function bezierPh(e,t,i,a){return[i[0]+a[0]-e[0]-t[0],i[1]+a[1]-e[1]-t[1],i[2]+a[2]-e[2]-t[2]]}function bezierPPh(e,t,i,a){return[3*e[0]-5*t[0]+i[0]+a[0],3*e[1]-5*t[1]+i[1]+a[1],3*e[2]-5*t[2]+i[2]+a[2]]}function Straightness(e,t,i,a){let n=[1/3*(a[0]-e[0]),1/3*(a[1]-e[1]),1/3*(a[2]-e[2])];return Math.max(abs2([t[0]-n[0]-e[0],t[1]-n[1]-e[1],t[2]-n[2]-e[2]]),abs2([a[0]-n[0]-i[0],a[1]-n[1]-i[1],a[2]-n[2]-i[2]]))}function Flatness(e,t,i,a){let n=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(n,unit(r))),abs2(cross(r,unit(n))))/9}function corners(e,t){return[e,[e[0],e[1],t[2]],[e[0],t[1],e[2]],[e[0],t[1],t[2]],[t[0],e[1],e[2]],[t[0],e[1],t[2]],[t[0],t[1],e[2]],t]}function minbound(e){return[Math.min(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.min(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.min(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function maxbound(e){return[Math.max(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.max(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.max(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function COBTarget(e,t){mat4.fromTranslation(Temp,[center.x,center.y,center.z]),mat4.invert(cjMatInv,Temp),mat4.multiply(e,t,cjMatInv),mat4.multiply(e,Temp,e)}function setUniforms(e,t){let i=t==pixelShader;gl.useProgram(t),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),t.projViewMatUniform=gl.getUniformLocation(t,"projViewMat"),t.viewMatUniform=gl.getUniformLocation(t,"viewMat"),t.normMatUniform=gl.getUniformLocation(t,"normMat"),t!=colorShader&&t!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let e=0;e<Lights.length;++e)Lights[e].setUniform(t,e);for(let i=0;i<e.materials.length;++i)e.materials[i].setUniform(t,i);gl.uniformMatrix4fv(t.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(t.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(t.normMatUniform,!1,normMat)}function handleMouseDown(e){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=e.clientX,lastMouseY=e.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(e){return Math.hypot(e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY)}function handleTouchStart(e){e.preventDefault(),zoomEnabled||enableZoom();let t=e.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=t.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=t[0].identifier,lastMouseX=t[0].pageX,lastMouseY=t[0].pageY),2!=t.length||mouseDownOrTouchActive||(touchId=t[0].identifier,pinchStart=pinchDistance(t),pinch=!0))}function handleMouseUpOrTouchEnd(e){mouseDownOrTouchActive=!1}function rotateScene(e,t,i,a,n){if(e==i&&t==a)return;let[r,s]=arcball([e,-t],[i,-a]);mat4.fromRotation(Temp,2*n*ArcballFactor*r/Zoom,s),mat4.multiply(rotMat,Temp,rotMat)}function shiftScene(e,t,i,a){let n=1/Zoom;shift.x+=(i-e)*n*halfCanvasWidth,shift.y-=(a-t)*n*halfCanvasHeight}function panScene(e,t,i,a){orthographic?shiftScene(e,t,i,a):(center.x+=(i-e)*(viewParam.xmax-viewParam.xmin),center.y-=(a-t)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let e=Math.sqrt(Number.MAX_VALUE),t=1/e;Zoom<=t&&(Zoom=t),Zoom>=e&&(Zoom=e),(1.5*Zoom<lastZoom||Zoom>1.5*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(e){let t=zoomStep*halfCanvasHeight*e;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(t)<i&&(Zoom*=zoomFactor**t,capzoom())}function normMouse(e){let t=e[0],i=e[1],a=Math.hypot(t,i);return a>1&&(denom=1/a,t*=denom,i*=denom),[t,i,Math.sqrt(Math.max(1-i*i-t*t,0))]}function arcball(e,t){let i=normMouse(e),a=normMouse(t),n=dot(i,a);return[n>1?0:n<-1?pi:Math.acos(n),unit(cross(i,a))]}function zoomScene(e,t,i,a){zoomImage(t-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(e,t,i,a=1){let n;switch(i){case 1:n=rotateScene;break;case 2:n=shiftScene;break;case 3:n=zoomScene;break;case 4:n=panScene;break;default:n=(e,t,i,a)=>{}}n((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(e-halfCanvasWidth)/halfCanvasWidth,(t-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=e,lastMouseY=t,setProjection(),drawScene()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function Camera(){let e=Array(3),t=Array(3),i=Array(3),a=center.x,n=center.y,r=.5*(viewParam.zmin+viewParam.zmax);for(let s=0;s<3;++s){let o=0,l=0,h=0,c=4*s;for(let e=0;e<4;++e){let t=4*e,i=rotMat[t],s=rotMat[t+1],d=rotMat[t+2],m=rotMat[t+3],f=Transform[c+e];o+=f*(m-a*i-n*s-r*d),h+=f*s,l+=f*(m-a*i-n*s)}e[s]=o,t[s]=h,i[s]=l}return[e,t,i]}function projection(){if(null==Transform)return"";let e,t,i;[e,t,i]=Camera();let a=orthographic?" orthographic(":" perspective(",n="".padStart(a.length),r="currentprojection=\n"+a+"camera=("+e+"),\n"+n+"up=("+t+"),\n"+n+"target=("+i+"),\n"+n+"zoom="+Zoom*initialZoom/zoom0;return orthographic||(r+=",\n"+n+"angle="+2*Math.atan(Math.tan(.5*angleOfView)/Zoom)/radians),0==xshift&&0==yshift||(r+=",\n"+n+"viewportshift=("+xshift+","+yshift+")"),orthographic||(r+=",\n"+n+"autoadjust=false"),r+=");\n",window.parent.asyProjection=!0,r}function handleKey(e){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==e.keyCode)return void disableZoom();let t=[];switch(e.key){case"x":t=[1,0,0];break;case"y":t=[0,1,0];break;case"z":t=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders(ibl)),remesh=!0,drawScene();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink();break;case"c":showCamera()}t.length>0&&(mat4.rotate(rotMat,rotMat,.1,t),updateViewMatrix(),drawScene())}function setZoom(){capzoom(),setProjection(),drawScene()}function handleMouseWheel(e){e.preventDefault(),e.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(e){if(!mouseDownOrTouchActive)return;let t,i=e.clientX,a=e.clientY;t=e.getModifierState("Control")?2:e.getModifierState("Shift")?3:e.getModifierState("Alt")?4:1,processDrag(i,a,t)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(e){if(e.preventDefault(),zooming)return;let t=e.targetTouches;if(!pinch&&1==t.length&&touchId==t[0].identifier){let e=t[0].pageX,i=t[0].pageY,a=e-lastMouseX,n=i-lastMouseY,r=a*a+n*n<=shiftHoldDistance*shiftHoldDistance;if(r&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(e,i,2);else if(!r){rotate=!0,processDrag(t[0].pageX,t[0].pageY,1,.5)}}if(pinch&&!swipe&&2==t.length&&touchId==t[0].identifier){let e=pinchDistance(t),i=e-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=e,swipe=rotate=zooming=!1,setProjection(),drawScene()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(e){let t=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=e.length;for(let n=0;n<e.length;++n){let r=6*n;zbuffer[n]=t*e[r]+i*e[r+1]+a*e[r+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let e=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,e),void transparentData.clear();if(e.length>0){transformVertices(transparentData.vertices);let t=e.length/3,i=Array(t).fill().map((e,t)=>t);i.sort((function(t,i){let a=3*t;Ia=e[a],Ib=e[a+1],Ic=e[a+2];let n=3*i;return IA=e[n],IB=e[n+1],IC=e[n+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(e.length);for(let n=0;n<t;++n){let t=3*i[n];a[3*n]=e[t],a[3*n+1]=e[t+1],a[3*n+2]=e[t+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent(),requestAnimationFrame(drawBuffers)}function drawScene(){embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let e=0;e<P.length;++e)P[e].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(e,t,i,a){let n=e/t;xshift=(i/e+viewportShift[0])*Zoom,yshift=(a/t+viewportShift[1])*Zoom;let r=1/Zoom;if(orthographic){let e=maxBound[0]-minBound[0],t=maxBound[1]-minBound[1];if(e<t*n){let e=.5*t*n*r,i=2*e*xshift,a=t*r*yshift;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=minBound[1]*r-a,viewParam.ymax=maxBound[1]*r-a}else{let t=.5*e*r/n,i=e*r*xshift,a=2*t*yshift;viewParam.xmin=minBound[0]*r-i,viewParam.xmax=maxBound[0]*r-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}else{let e=H*r,t=e*n,i=2*t*xshift,a=2*e*yshift;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix(),window.top.asyWebApplication&&window.top.asyWebApplication.setProjection(projection())}function showCamera(){window.top.asyWebApplication||prompt("Ctrl+c Enter to copy currentprojection to clipboard; then append to asy file:",projection())}function initProjection(){H=-Math.tan(.5*angleOfView)*maxBound[2],center.x=center.y=0,center.z=.5*(minBound[2]+maxBound[2]),lastZoom=Zoom=zoom0,viewParam.zmin=minBound[2],viewParam.zmax=maxBound[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen.width=canvasWidth,canvas.height=offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportMargin[0],viewportMargin[1])/size2}function setsize(e,t){e>maxViewportWidth&&(e=maxViewportWidth),t>maxViewportHeight&&(t=maxViewportHeight),shift.x*=e/canvasWidth,shift.y*=t/canvasHeight,canvasWidth=e,canvasHeight=t,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=initialZoom,window.top.asyWebApplication&&""==window.top.asyWebApplication.getProjection()&&(window.parent.asyProjection=!1),absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let e=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&!window.parent.asyProjection&&canvasWidth<canvasHeight*e&&(zoom0*=canvasWidth/(canvasHeight*e))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;let e=1/zoom0;viewportShift[0]*=e,viewportShift[1]*=e,setsize(canvasWidth,canvasHeight),redrawScene()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(e,t){if(this.center=e,t){let e=t[0],i=t[1];this.ct=Math.cos(e),this.st=Math.sin(e),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(e){return[e[0]+this.center[0],e[1]+this.center[1],e[2]+this.center[2]]}T(e){let t=e[0],i=e[1],a=e[2],n=t*this.ct+a*this.st;return[n*this.cp-i*this.sp+this.center[0],n*this.sp+i*this.cp+this.center[1],-t*this.st+a*this.ct+this.center[2]]}}function Tcorners(e,t,i){let a=[e(t),e([t[0],t[1],i[2]]),e([t[0],i[1],t[2]]),e([t[0],i[1],i[2]]),e([i[0],t[1],t[2]]),e([i[0],t[1],i[2]]),e([i[0],i[1],t[2]]),e(i)];return[minbound(a),maxbound(a)]}function material(e,t,i,a,n,r){Materials.push(new Material(e,t,i,a,n,r))}function patch(e,t,i,a,n,r){P.push(new BezierPatch(e,t,i,a,n,r))}function curve(e,t,i,a,n){P.push(new BezierCurve(e,t,i,a,n))}function pixel(e,t,i,a,n){P.push(new Pixel(e,t,i,a,n))}function triangles(e,t,i,a){P.push(new Triangles(e,t,i,a))}function sphere(e,t,i,n,r){let s,o,l,h,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,g=.996685028842544,v=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,g],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,g],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,g],[0,1,0],[0,1,m],[0,f,u],[0,p,g]],[[p,0,g],[p,a*p,g],[v,0,x],[a*p,p,g],[w,w,1],[.05*a,0,1],[0,p,g],[0,v,x],[0,.05*a,1],[0,0,1]]],b=new Align(e,r);function T(e){let t=Array(e.length);for(let i=0;i<e.length;++i){let a=e[i];t[i]=c([s*a[0],o*a[1],l*a[2]])}return t}r?(h=1,d=0,c=b.T.bind(b)):(h=-1,d=-t,c=b.T0.bind(b));let S=Tcorners(c,[-t,-t,d],[t,t,t]),R=S[0],A=S[1];for(let e=-1;e<=1;e+=2){s=e*t;for(let e=-1;e<=1;e+=2){o=e*t;for(let e=h;e<=1;e+=2){l=e*t;for(let e=0;e<2;++e)P.push(new BezierPatch(T(M[e]),i,n,R,A))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(e,t,i,n,r){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],l=new Align(e,r);let h=Tcorners(l.T.bind(l),[-t,-t,0],[t,t,0]);P.push(new BezierPatch(function(e){let i=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];i[a]=l.T([t*n[0],t*n[1],0])}return i}(o),i,n,h[0],h[1]))}function cylinder(e,t,i,n,r,s,o){let l,h,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(e,s);function m(e){let t=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];t[a]=d.T([l*n[0],h*n[1],i*n[2]])}return t}let f=Tcorners(d.T.bind(d),[-t,-t,0],[t,t,i]),u=f[0],p=f[1];for(let e=-1;e<=1;e+=2){l=e*t;for(let e=-1;e<=1;e+=2)h=e*t,P.push(new BezierPatch(m(c),n,r,u,p))}if(o){let t=d.T([0,0,i]);P.push(new BezierCurve([e,t],n,r,e,t))}}function rmf(e,t,i,a,n){class r{constructor(e,t,i){this.p=e,this.r=t,this.t=i,this.s=cross(i,t)}}let s=Number.EPSILON*Math.max(abs2(e),abs2(t),abs2(i),abs2(a));function o(n){if(1==n){let n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(n)>s?unit(n):(n=[2*i[0]-t[0]-a[0],2*i[1]-t[1]-a[1],2*i[2]-t[2]-a[2]],abs2(n)>s?unit(n):[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])}let r=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])],o=[2*(e[0]+i[0])-4*t[0],2*(e[1]+i[1])-4*t[1],2*(e[2]+i[2])-4*t[2]],l=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],h=n*n,c=[r[0]*h+o[0]*n+l[0],r[1]*h+o[1]*n+l[1],r[2]*h+o[2]*n+l[2]];return abs2(c)>s?unit(c):(h=2*n,c=[r[0]*h+o[0],r[1]*h+o[1],r[2]*h+o[2]],abs2(c)>s?unit(c):unit(r))}let l=Array(n.length),h=[t[0]-e[0],t[1]-e[1],t[2]-e[2]];abs2(h)<s&&(h=[e[0]-2*t[0]+i[0],e[1]-2*t[1]+i[1],e[2]-2*t[2]+i[2]],abs2(h)<s&&(h=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])),h=unit(h);let c=function(e){let t=cross(e,[0,1,0]),i=Number.EPSILON*abs2(e);return abs2(t)>i?unit(t):(t=cross(e,[0,0,1]),abs2(t)>i?unit(t):[1,0,0])}(h);l[0]=new r(e,c,h);for(let s=1;s<n.length;++s){let h=l[s-1],c=n[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,g=[f*e[0]+m*t[0]+d*i[0]+p*a[0],f*e[1]+m*t[1]+d*i[1]+p*a[1],f*e[2]+m*t[2]+d*i[2]+p*a[2]],v=[g[0]-h.p[0],g[1]-h.p[1],g[2]-h.p[2]];if(0!=v[0]||0!=v[1]||0!=v[2]){let e=h.r,t=unit(v),i=h.t,a=dot(t,i),n=[i[0]-2*a*t[0],i[1]-2*a*t[1],i[2]-2*a*t[2]];i=o(c);let d=2*dot(t,e),m=[e[0]-d*t[0],e[1]-d*t[1],e[2]-d*t[2]],f=unit([i[0]-n[0],i[1]-n[1],i[2]-n[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],l[s]=new r(g,unit(m),unit(i))}else l[s]=l[s-1]}return l}function tube(e,t,i,n,r,s,o){let l=rmf(e[0],e[1],e[2],e[3],[0,1/3,2/3,1]),h=a*t,c=[[t,0],[t,h],[h,t],[0,t]];function d(t,a,o,h){let d=Array(16);for(let i=0;i<4;++i){let n=l[i],r=n.r[0],s=n.s[0],m=r*t+s*a,f=r*o+s*h;r=n.r[1],s=n.s[1];let u=r*t+s*a,p=r*o+s*h;r=n.r[2],s=n.s[2];let g=r*t+s*a,v=r*o+s*h,x=e[i],w=x[0];w1=x[1],w2=x[2];for(let e=0;e<4;++e){let t=c[e],a=t[0],n=t[1];d[4*i+e]=[m*a+f*n+w,u*a+p*n+w1,g*a+v*n+w2]}}P.push(new BezierPatch(d,i,n,r,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(e,i,n,r,s))}async function getReq(e){return(await fetch(e)).arrayBuffer()}function rgb(e){return e.getBytes().filter((e,t)=>t%4!=3)}function createTexture(e,t,i=gl.RGB16F){let a=e.width(),n=e.height(),r=gl.createTexture();return gl.activeTexture(gl.TEXTURE0+t),gl.bindTexture(gl.TEXTURE_2D,r),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texImage2D(gl.TEXTURE_2D,0,i,a,n,0,gl.RGB,gl.FLOAT,rgb(e)),r}async function initIBL(){let e=imageURL+image+"/";function t(e){return new Promise(t=>setTimeout(t,e))}for(;!Module.EXRLoader;)await t(0);promises=[getReq(imageURL+"refl.exr").then(e=>{let t=new Module.EXRLoader(e);IBLbdrfMap=createTexture(t,0)}),getReq(e+"diffuse.exr").then(e=>{let t=new Module.EXRLoader(e);IBLDiffuseMap=createTexture(t,1)})],refl_promise=[],refl_promise.push(getReq(e+"refl0.exr"));for(let t=1;t<=roughnessStepCount;++t)refl_promise.push(getReq(e+"refl"+t+"w.exr"));finished_promise=Promise.all(refl_promise).then(e=>{let t=gl.createTexture();gl.activeTexture(gl.TEXTURE0+2),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.bindTexture(gl.TEXTURE_2D,t),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,e.length-1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MIN_LOD,0),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MAX_LOD,roughnessStepCount);for(let t=0;t<e.length;++t){let i=new Module.EXRLoader(e[t]);gl.texImage2D(gl.TEXTURE_2D,t,gl.RGB16F,i.width(),i.height(),0,gl.RGB,gl.FLOAT,rgb(i))}IBLReflMap=t}),promises.push(finished_promise),await Promise.all(promises)}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1),ibl&&initIBL().then(SetIBL).then(redrawScene)} diff --git a/Master/texmf-dist/asymptote/x11colors.asy b/Master/texmf-dist/asymptote/x11colors.asy index 77e0401f06e..eb65e5346f0 100644 --- a/Master/texmf-dist/asymptote/x11colors.asy +++ b/Master/texmf-dist/asymptote/x11colors.asy @@ -1,4 +1,4 @@ -pen rgbint(int r, int g, int b) +pen rgbint(int r, int g, int b) { return rgb(r/255,g/255,b/255); } diff --git a/Master/texmf-dist/doc/asymptote/CAD.pdf b/Master/texmf-dist/doc/asymptote/CAD.pdf Binary files differindex f55807bb30c..c9e5dc9942a 100644 --- a/Master/texmf-dist/doc/asymptote/CAD.pdf +++ b/Master/texmf-dist/doc/asymptote/CAD.pdf diff --git a/Master/texmf-dist/doc/asymptote/TeXShopAndAsymptote.pdf b/Master/texmf-dist/doc/asymptote/TeXShopAndAsymptote.pdf Binary files differindex 50759d15e8f..b585bd4ef0d 100644 --- a/Master/texmf-dist/doc/asymptote/TeXShopAndAsymptote.pdf +++ b/Master/texmf-dist/doc/asymptote/TeXShopAndAsymptote.pdf diff --git a/Master/texmf-dist/doc/asymptote/asy-latex.pdf b/Master/texmf-dist/doc/asymptote/asy-latex.pdf Binary files differindex 953b91a2a06..3e57a01df6a 100644 --- a/Master/texmf-dist/doc/asymptote/asy-latex.pdf +++ b/Master/texmf-dist/doc/asymptote/asy-latex.pdf diff --git a/Master/texmf-dist/doc/asymptote/asyRefCard.pdf b/Master/texmf-dist/doc/asymptote/asyRefCard.pdf Binary files differindex 697d5a67b89..63dc23bf577 100644 --- a/Master/texmf-dist/doc/asymptote/asyRefCard.pdf +++ b/Master/texmf-dist/doc/asymptote/asyRefCard.pdf diff --git a/Master/texmf-dist/doc/asymptote/asymptote.pdf b/Master/texmf-dist/doc/asymptote/asymptote.pdf Binary files differindex 26289f9316f..a2098dfa94c 100644 --- a/Master/texmf-dist/doc/asymptote/asymptote.pdf +++ b/Master/texmf-dist/doc/asymptote/asymptote.pdf diff --git a/Master/texmf-dist/doc/asymptote/examples/1overx.asy b/Master/texmf-dist/doc/asymptote/examples/1overx.asy index 9bbbf282aca..dfaa049efb5 100644 --- a/Master/texmf-dist/doc/asymptote/examples/1overx.asy +++ b/Master/texmf-dist/doc/asymptote/examples/1overx.asy @@ -1,16 +1,11 @@ import graph; size(200,IgnoreAspect); -real f(real x) {return 1/x;}; +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; + return x != 0; } draw(graph(f,-1,1,branch)); diff --git a/Master/texmf-dist/doc/asymptote/examples/NURBScurve.asy b/Master/texmf-dist/doc/asymptote/examples/NURBScurve.asy index 9ad121ecc65..736ff67588b 100644 --- a/Master/texmf-dist/doc/asymptote/examples/NURBScurve.asy +++ b/Master/texmf-dist/doc/asymptote/examples/NURBScurve.asy @@ -1,3 +1,6 @@ +settings.outformat="pdf"; +settings.prc=true; + import three; size(10cm); @@ -31,4 +34,3 @@ real[] weights=array(P.length,1.0); weights[2]=5; draw(P,knot,weights,red); - diff --git a/Master/texmf-dist/doc/asymptote/examples/NURBSsphere.asy b/Master/texmf-dist/doc/asymptote/examples/NURBSsphere.asy index 484e8c4cd15..e169d70343e 100644 --- a/Master/texmf-dist/doc/asymptote/examples/NURBSsphere.asy +++ b/Master/texmf-dist/doc/asymptote/examples/NURBSsphere.asy @@ -1,3 +1,6 @@ +settings.outformat="pdf"; +settings.prc=true; + import three; /* Reference: diff --git a/Master/texmf-dist/doc/asymptote/examples/NURBSsurface.asy b/Master/texmf-dist/doc/asymptote/examples/NURBSsurface.asy index 4bfafefbc33..bfa314ac66a 100644 --- a/Master/texmf-dist/doc/asymptote/examples/NURBSsurface.asy +++ b/Master/texmf-dist/doc/asymptote/examples/NURBSsurface.asy @@ -1,3 +1,6 @@ +settings.outformat="pdf"; +settings.prc=true; + import three; size(10cm); @@ -59,7 +62,7 @@ draw(P,uknot,vknot,new pen[] {red,green,blue,magenta}); // 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; +triple[][] P=scale3(20)*octant1x.P; // Optional weights: real[][] weights=array(P.length,array(P[0].length,1.0)); diff --git a/Master/texmf-dist/doc/asymptote/examples/alignedaxis.asy b/Master/texmf-dist/doc/asymptote/examples/alignedaxis.asy index 542dcb9bc60..d32c389a74b 100644 --- a/Master/texmf-dist/doc/asymptote/examples/alignedaxis.asy +++ b/Master/texmf-dist/doc/asymptote/examples/alignedaxis.asy @@ -91,7 +91,7 @@ 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})); +yaxis(pic2p,"phase (deg)",LeftRight,RightTicks(new real[] {0,50,90})); xaxis(pic2p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5)); yequals(pic2p,0,Dotted); yequals(pic2p,45,Dotted); diff --git a/Master/texmf-dist/doc/asymptote/examples/fillcontour.asy b/Master/texmf-dist/doc/asymptote/examples/fillcontour.asy index 0197386670f..b92b65ef46c 100644 --- a/Master/texmf-dist/doc/asymptote/examples/fillcontour.asy +++ b/Master/texmf-dist/doc/asymptote/examples/fillcontour.asy @@ -2,28 +2,40 @@ import graph; import palette; import contour; -size(12cm,IgnoreAspect); +size(10cm,10cm); -pair a=(pi/2,0); -pair b=(3pi/2,2pi); +pair a=(0,0); +pair b=(2pi,2pi); real f(real x, real y) {return cos(x)*sin(y);} -int N=100; +int N=200; int Divs=10; +int divs=1; +int n=Divs*divs; defaultpen(1bp); +pen Tickpen=black; +pen tickpen=gray+0.5*linewidth(currentpen); +pen[] Palette=quantize(BWRainbow(),n); -bounds range=bounds(-1,1); +bounds range=image(f,Automatic,a,b,3N,Palette,n); real[] Cvals=uniform(range.min,range.max,Divs); -guide[][] g=contour(f,a,b,Cvals,N,operator --); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); -pen[] Palette=quantize(Rainbow(),Divs); +// Major contours +real[] Cvals=uniform(range.min,range.max,Divs); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); + +// Minor contours (if divs > 1) +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); -pen[][] interior=interior(g,extend(Palette,grey,black)); -fill(g,interior); -draw(g); +xaxis("$x$",BottomTop,LeftTicks,above=true); +yaxis("$y$",LeftRight,RightTicks,above=true); palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette, - PaletteTicks("$%+#0.1f$",N=Divs)); + PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen)); diff --git a/Master/texmf-dist/doc/asymptote/examples/graphwithderiv.asy b/Master/texmf-dist/doc/asymptote/examples/graphwithderiv.asy new file mode 100644 index 00000000000..2dfd1da02d3 --- /dev/null +++ b/Master/texmf-dist/doc/asymptote/examples/graphwithderiv.asy @@ -0,0 +1,11 @@ +unitsize(2cm); +import graph; +pair F(real t) { + return (1.3*t,-4.5*t^2+3.0*t+1.0); +} +pair Fprime(real t) { + return (1.3,-9.0*t+3.0); +} +path g=graphwithderiv(F,Fprime,0,0.9,4); +dot(g,red); +draw(g,arrow=Arrow(TeXHead)); diff --git a/Master/texmf-dist/doc/asymptote/examples/imagecontour.asy b/Master/texmf-dist/doc/asymptote/examples/imagecontour.asy index d61b6148c53..18c4cb772cc 100644 --- a/Master/texmf-dist/doc/asymptote/examples/imagecontour.asy +++ b/Master/texmf-dist/doc/asymptote/examples/imagecontour.asy @@ -2,7 +2,7 @@ import graph; import palette; import contour; -size(10cm,10cm,IgnoreAspect); +size(10cm,10cm); pair a=(0,0); pair b=(2pi,2pi); @@ -11,7 +11,7 @@ real f(real x, real y) {return cos(x)*sin(y);} int N=200; int Divs=10; -int divs=2; +int divs=1; defaultpen(1bp); pen Tickpen=black; @@ -21,18 +21,17 @@ 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); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); -// Minor contours +// Minor contours (if divs > 1) 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); +draw(contour(f,a,b,cvals,N,operator --),tickpen+squarecap+beveljoin); 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)); +palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette, + PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen)); diff --git a/Master/texmf-dist/doc/asymptote/examples/interpolate1.asy b/Master/texmf-dist/doc/asymptote/examples/interpolate1.asy index 19d77449abd..10bc7ef4f6b 100644 --- a/Master/texmf-dist/doc/asymptote/examples/interpolate1.asy +++ b/Master/texmf-dist/doc/asymptote/examples/interpolate1.asy @@ -1,5 +1,5 @@ // Lagrange and Hermite interpolation in Asymptote -// Author: Olivier Guibé +// Author: Olivier Guibé import interpolate; import graph; diff --git a/Master/texmf-dist/doc/asymptote/examples/latexusage.tex b/Master/texmf-dist/doc/asymptote/examples/latexusage.tex index 07b0e56a356..9701a25af9b 100644 --- a/Master/texmf-dist/doc/asymptote/examples/latexusage.tex +++ b/Master/texmf-dist/doc/asymptote/examples/latexusage.tex @@ -21,6 +21,7 @@ \begin{asydef} // Global Asymptote definitions can be put here. +settings.prc=true; import three; usepackage("bm"); texpreamble("\def\V#1{\bm{#1}}"); diff --git a/Master/texmf-dist/doc/asymptote/examples/layers.asy b/Master/texmf-dist/doc/asymptote/examples/layers.asy index 4fe745f6a3c..3d80b31fb7a 100644 --- a/Master/texmf-dist/doc/asymptote/examples/layers.asy +++ b/Master/texmf-dist/doc/asymptote/examples/layers.asy @@ -1,4 +1,4 @@ -usepackage("ocg"); +usepackage("ocgx2"); settings.tex="pdflatex"; size(0,150); diff --git a/Master/texmf-dist/doc/asymptote/examples/legend.asy b/Master/texmf-dist/doc/asymptote/examples/legend.asy index b00cdd14e6b..246c787c833 100644 --- a/Master/texmf-dist/doc/asymptote/examples/legend.asy +++ b/Master/texmf-dist/doc/asymptote/examples/legend.asy @@ -4,7 +4,7 @@ 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), diff --git a/Master/texmf-dist/doc/asymptote/examples/markregular.asy b/Master/texmf-dist/doc/asymptote/examples/markregular.asy index ea08b952238..8c3a51040b3 100644 --- a/Master/texmf-dist/doc/asymptote/examples/markregular.asy +++ b/Master/texmf-dist/doc/asymptote/examples/markregular.asy @@ -7,11 +7,11 @@ real ymin=-2,ymax=10; real f(real x) {return x^2;} -marker cross=marker(scale(4)*rotate(45)*cross(4), +marker mark=marker(scale(4)*plus, 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); +draw(graph(f,xmin,xmax,n=400),linewidth(1bp),mark); ylimits(-2.5,10,Crop); diff --git a/Master/texmf-dist/doc/asymptote/examples/orthocenter.asy b/Master/texmf-dist/doc/asymptote/examples/orthocenter.asy index a7caaf14126..69ae5376b5f 100644 --- a/Master/texmf-dist/doc/asymptote/examples/orthocenter.asy +++ b/Master/texmf-dist/doc/asymptote/examples/orthocenter.asy @@ -2,8 +2,7 @@ import geometry; import math; size(7cm,0); - -if(!settings.xasy && settings.outformat != "svg") settings.tex="pdflatex"; +settings.tex="pdflatex"; real theta=degrees(asin(0.5/sqrt(7))); diff --git a/Master/texmf-dist/doc/asymptote/examples/secondaryaxis.asy b/Master/texmf-dist/doc/asymptote/examples/secondaryaxis.asy index 85143f7acec..b611eb4ed2e 100644 --- a/Master/texmf-dist/doc/asymptote/examples/secondaryaxis.asy +++ b/Master/texmf-dist/doc/asymptote/examples/secondaryaxis.asy @@ -11,7 +11,7 @@ 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]; +real[] susceptibleM=a[5], exposed=a[6], infectiousM=a[7]; scale(true); @@ -29,4 +29,3 @@ picture secondary=secondaryY(new void(picture pic) { add(secondary); label(shift(5mm*N)*"Proportion of crows",point(NW),E); - diff --git a/Master/texmf-dist/doc/asymptote/examples/spectrum.asy b/Master/texmf-dist/doc/asymptote/examples/spectrum.asy index 95c5f8a0d1b..c6837ec7810 100644 --- a/Master/texmf-dist/doc/asymptote/examples/spectrum.asy +++ b/Master/texmf-dist/doc/asymptote/examples/spectrum.asy @@ -1,5 +1,5 @@ import graph; -usepackage("ocg"); +usepackage("ocgx2"); settings.tex="pdflatex"; // Dan Bruton algorithm diff --git a/Master/texmf-dist/doc/asymptote/examples/strokepath.asy b/Master/texmf-dist/doc/asymptote/examples/strokepath.asy index c857150ec58..5e5b2b9a964 100644 --- a/Master/texmf-dist/doc/asymptote/examples/strokepath.asy +++ b/Master/texmf-dist/doc/asymptote/examples/strokepath.asy @@ -5,7 +5,6 @@ frame f; // Equivalent to draw(f,g,p): fill(f,strokepath(g,p),red); shipout("strokepathframe",f); -shipped=false; size(400); diff --git a/Master/texmf-dist/doc/asymptote/examples/teapot.asy b/Master/texmf-dist/doc/asymptote/examples/teapot.asy index f3328151fde..847ffd234dc 100644 --- a/Master/texmf-dist/doc/asymptote/examples/teapot.asy +++ b/Master/texmf-dist/doc/asymptote/examples/teapot.asy @@ -1,204 +1,232 @@ import three; -import settings; size(20cm); currentprojection=perspective(250,-250,250); currentlight=Viewport; -triple[][][] Q= +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)} - }, - { + }, + { + {(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)} + } +}; + +triple[][][] Q0={ + { {(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)} - } - }; + } +}; + +surface regularize(triple[][] P, real fraction=0.02) +{ + triple[][][] B=hsplit(P,fraction); + triple[][] T=B[0]; + surface s=surface(T[0][0]..controls T[0][1] and T[0][2].. + T[0][3]..controls T[1][3] and T[2][3].. + T[3][3]..controls T[3][2] and T[3][1]..cycle); + s.append(surface(patch(B[1]))); + return s; +} + +surface S=surface(Q); +for(triple[][] q : Q0) + S.append(regularize(q)); + +pen color; +real metallic; + +if(settings.ibl) { + color=white; + metallic=1; +} else { + color=blue; + metallic=0; +} -draw(surface(Q),material(blue, shininess=0.85, metallic=0),render(compression=Low)); +draw(S,material(color,shininess=0.85,metallic=metallic), + render(compression=Single)); diff --git a/Master/texmf-dist/doc/asymptote/examples/teapotIBL.asy b/Master/texmf-dist/doc/asymptote/examples/teapotIBL.asy new file mode 100644 index 00000000000..bd6afe31102 --- /dev/null +++ b/Master/texmf-dist/doc/asymptote/examples/teapotIBL.asy @@ -0,0 +1,2 @@ +settings.ibl=true; +import teapot; diff --git a/Master/texmf-dist/doc/asymptote/examples/transparency.asy b/Master/texmf-dist/doc/asymptote/examples/transparency.asy index 36e741d294d..a01a87a4545 100644 --- a/Master/texmf-dist/doc/asymptote/examples/transparency.asy +++ b/Master/texmf-dist/doc/asymptote/examples/transparency.asy @@ -1,8 +1,5 @@ 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)); diff --git a/Master/texmf-dist/doc/asymptote/examples/twoSpheres.asy b/Master/texmf-dist/doc/asymptote/examples/twoSpheres.asy new file mode 100644 index 00000000000..c043ae37315 --- /dev/null +++ b/Master/texmf-dist/doc/asymptote/examples/twoSpheres.asy @@ -0,0 +1,17 @@ +import three; +import palette; + +size(20cm); + +currentprojection=orthographic(1,1,1); + +draw(box((-2,-2,-1),(2,2,1))); + +draw(shift(-Z)*surface(box((-2,-2),(2,2))),blue); +draw(shift(Z)*surface(box((-2,-2),(2,2))),orange+opacity(0.5)); + +surface s=unitsphere; +s.colors(palette(s.map(zpart),Gradient(green+opacity(0.6),white, + green+opacity(0.6)))); +draw(shift(0.5X+0.5Y)*s); +draw(shift(-0.5X-0.5Y)*s); diff --git a/Master/texmf-dist/doc/asymptote/examples/workcone.asy b/Master/texmf-dist/doc/asymptote/examples/workcone.asy index 594758bba64..da7629c773d 100644 --- a/Master/texmf-dist/doc/asymptote/examples/workcone.asy +++ b/Master/texmf-dist/doc/asymptote/examples/workcone.asy @@ -20,7 +20,7 @@ render render=render(compression=0,merge=true); draw(scale(x1,x1,-s1)*shift(-Z)*unitcone,lightblue+opacity(0.5),render); -path3 p=(x2,0,s2)--(x,0,s+0.005); +path3 p=(x2,0,s2)--(x,0,s); revolution a=revolution(p,Z); draw(surface(a),lightblue+opacity(0.5),render); diff --git a/Master/texmf-dist/doc/info/asy-faq.info b/Master/texmf-dist/doc/info/asy-faq.info index c651d233492..bfd11cacf0b 100644 --- a/Master/texmf-dist/doc/info/asy-faq.info +++ b/Master/texmf-dist/doc/info/asy-faq.info @@ -10,7 +10,7 @@ END-INFO-DIR-ENTRY File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir) ASYMPTOTE FREQUENTLY ASKED QUESTIONS - 2021-03-15 + 2022-02-05 This is the list of Frequently Asked Questions about Asymptote (asy). diff --git a/Master/texmf-dist/doc/info/asymptote.info b/Master/texmf-dist/doc/info/asymptote.info index 89903f69102..a6d3a7fedf5 100644 --- a/Master/texmf-dist/doc/info/asymptote.info +++ b/Master/texmf-dist/doc/info/asymptote.info @@ -1,11 +1,11 @@ -This is asymptote.info, produced by makeinfo version 6.6 from +This is asymptote.info, produced by makeinfo version 6.7 from asymptote.texi. -This file documents 'Asymptote', version 2.70. +This file documents 'Asymptote', version 2.78. <https://asymptote.sourceforge.io> - Copyright (C) 2004-20 Andy Hammerlindl, John Bowman, and Tom Prince. + Copyright (C) 2004-22 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 @@ -22,11 +22,11 @@ File: asymptote.info, Node: Top, Next: Description, Prev: (dir), Up: (dir) Asymptote ********* -This file documents 'Asymptote', version 2.70. +This file documents 'Asymptote', version 2.78. <https://asymptote.sourceforge.io> - Copyright (C) 2004-20 Andy Hammerlindl, John Bowman, and Tom Prince. + Copyright (C) 2004-22 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 @@ -45,6 +45,8 @@ This file documents 'Asymptote', version 2.70. * Options:: Command-line options * Interactive mode:: Typing 'Asymptote' commands interactively * GUI:: Graphical user interface +* Command-Line Interface:: Remote command-line interface +* Language server protocol:: Help when writing code * PostScript to Asymptote:: 'Asymptote' backend to 'pstoedit' * Help:: Where to get help and submit bug reports * Debugger:: Squish those bugs! @@ -174,13 +176,17 @@ 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 'PDF', 'SVG', -'WebGL', 'PRC', and any format that the 'ImageMagick' package can -produce. You can even try it out in your Web browser without installing -it, using the 'Asymptote Web Application': +produces 'PostScript' output, but it can also generate 'OpenGL', 'PDF', +'SVG', 'WebGL', 'V3D', and 'PRC' vector graphics, along with any format +that the 'ImageMagick' package can produce. You can even try it out in +your Web browser without installing it, using the 'Asymptote Web +Application' <http://asymptote.ualberta.ca> + It is also possible to send remote commands to this server via the +curl utility (*note Command-Line Interface::). + 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 @@ -342,8 +348,8 @@ required to typeset labels. You will also need to install 'GPL Ghostscript' version 9.52 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/>. + To view 'PostScript' output, you can install the program 'Sumatra +PDF' available from <https://www.sumatrapdfreader.org/>. The 'ImageMagick' package from <https://www.imagemagick.org/script/binary-releases.php> @@ -406,7 +412,7 @@ display 3D 'WebGL' output. The default setting is 'google-chrome' under Explorer' does not support 'WebGL'; 'Microsoft Windows' users should set their default html browser to 'chrome' or 'microsoft-edge'. By default, 2D and 3D 'HTML' images expand to the enclosing canvas; this can be -disabled by setting the configuation variable 'absolute' to 'true'. +disabled by setting the configuration variable 'absolute' to 'true'. On 'UNIX' systems, to support automatic document reloading of 'PDF' files in 'Adobe Reader', we recommend copying the file 'reload.js' from @@ -971,7 +977,7 @@ 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, + 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 @@ -1257,7 +1263,7 @@ 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, +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, @@ -2016,11 +2022,11 @@ File: asymptote.info, Node: Paths and guides, Next: Pens, Prev: Data types, '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. + 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', + 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);' @@ -3018,7 +3024,7 @@ File: asymptote.info, Node: Frames and pictures, Next: Files, Prev: Transform The routine void usepackage(string s, string options=""); provides a convenient abbreviation for - texpreamble("\usepackage["+options+"]{"+s+"}"); + texpreamble("\usepackage["+options+"]{"+s+"}"); that can be used for importing 'LaTeX' packages. @@ -3436,7 +3442,7 @@ For convenience, the incremental fields 'change.user', 'change.system', and 'change.clock' indicate the change in the corresponding fields since the last call to 'cputime()'. The function void write(file file=stdout, string s="", cputime c, - string format=cputimeformat, suffix suffix=none); + 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". @@ -3451,7 +3457,7 @@ struct parent { } void write(parent p) {write(p.x);} - + struct child { parent parent; real y=3; @@ -3462,7 +3468,7 @@ struct child { } parent operator cast(child child) {return child.parent;} - + parent p=parent(1); child c=child(2); @@ -3683,13 +3689,13 @@ reference, simply enclose it in a structure (*note Structures::). 1. Variables with signatures (functions) and without signatures (nonfunction variables) are distinct: - int x, x(); + 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) + int sqr(int x) { return x*x; } @@ -3721,22 +3727,22 @@ reference, simply enclose it in a structure (*note Structures::). 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");}; + g(); // writes "hi" + + f=new void() {write("bye");}; + + g(); // writes "bye" + + void f() {write("overloaded");}; f(); // writes "overloaded" - g(); // writes "bye" + g(); // writes "bye" 6. Anonymous functions can be used to redefine a function variable that has been declared (and implicitly initialized to the null @@ -3855,7 +3861,7 @@ 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; + int total=0; for(int i=0; i < nums.length; ++i) total += nums[i]; return total; @@ -4145,6 +4151,10 @@ of type 'T[]'. if 'm >= n' returns an array '{n,n+1,...,m}' (otherwise returns a null array); +'int[] sequence(int n, int m, int skip)' + if 'm >= n' returns an array '{n,n+1,...,m}' skipping by 'skip' + (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 @@ -4606,19 +4616,19 @@ 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; -} +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) { +real det(matrix m) { from m unravel a,b,c as C,d; - return a*d-b*C; -} + return a*d-b*C; +} The command import graph; @@ -4927,6 +4937,7 @@ labels might not show up in DVI viewers that cannot handle raw \begin{asydef} // Global Asymptote definitions can be put here. +settings.prc=true; import three; usepackage("bm"); texpreamble("\def\V#1{\bm{#1}}"); @@ -5127,24 +5138,24 @@ functions such as returns the four complex roots of the quartic equation ax^4+bx^3+cx^2+dx+e=0. -'real time(path g, real x, int n=0)' +'real time(path g, real x, int n=0, real fuzz=-1)' 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)' +'real time(path g, explicit pair z, int n=0, real fuzz=-1)' 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)' +'real value(path g, real x, int n=0, real fuzz=-1)' returns the 'n'th 'y' value of 'g' at 'x'. -'real value(path g, explicit pair z, int n=0)' +'real value(path g, explicit pair z, int n=0, real fuzz=-1)' returns the 'n'th 'x' value of 'g' at 'y=z.y'. -'real slope(path g, real x, int n=0)' +'real slope(path g, real x, int n=0, real fuzz=-1)' returns the 'n'th slope of 'g' at 'x'. -'real slope(path g, explicit pair z, int n=0)' +'real slope(path g, explicit pair z, int n=0, real fuzz=-1)' returns the 'n'th slope of 'g' at 'y=z.y'. int[][] segment(bool[] b) returns the indices of consecutive @@ -5223,7 +5234,7 @@ This module implements 'PostScript' tiling patterns and includes several convenient pattern generation routines. -File: asymptote.info, Node: markers, Next: tree, Prev: patterns, Up: Base modules +File: asymptote.info, Node: markers, Next: map, Prev: patterns, Up: Base modules 8.9 'markers' ============= @@ -5290,7 +5301,7 @@ write(M.lookup("a")); write(M.lookup("y")); -File: asymptote.info, Node: tree, Next: binarytree, Prev: markers, Up: Base modules +File: asymptote.info, Node: tree, Next: binarytree, Prev: map, Up: Base modules 8.11 'tree' =========== @@ -5617,7 +5628,7 @@ following routines: 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, + 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 @@ -5746,8 +5757,8 @@ following routines: '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, + 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) @@ -5940,7 +5951,7 @@ following routines: 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), @@ -5992,7 +6003,7 @@ following routines: 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, + 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 @@ -6018,13 +6029,13 @@ following routines: marker(scale(circlescale)*unitcircle), marker(polygon(3)),marker(polygon(4)), marker(polygon(5)),marker(invert*polygon(3)), - marker(cross(4)),marker(cross(6)) + marker(cross(4)),marker(cross(6)),marker(diamond),marker(plus); }; marker[] MarkFill={ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill), marker(polygon(4),Fill),marker(polygon(5),Fill), - marker(invert*polygon(3),Fill) + marker(invert*polygon(3),Fill),marker(diamond,Fill) }; The example also illustrates the 'errorbar' routines: @@ -6179,6 +6190,26 @@ following routines: [./parametricgraph] + The function + guide graphwithderiv(pair f(real), pair fprime(real), real a, real b, + int n=ngraph#10); + can be used to construct the graph of the parametric function 'f' + on '[a,b]' with the control points of the 'n' Bezier segments + determined by the specified derivative 'fprime': + unitsize(2cm); + import graph; + pair F(real t) { + return (1.3*t,-4.5*t^2+3.0*t+1.0); + } + pair Fprime(real t) { + return (1.3,-9.0*t+3.0); + } + path g=graphwithderiv(F,Fprime,0,0.9,4); + dot(g,red); + draw(g,arrow=Arrow(TeXHead)); + + [./graphwithderiv] + The next example illustrates how one can extract a common axis scaling factor. import graph; @@ -6392,7 +6423,7 @@ following routines: 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]; + real[] susceptibleM=a[5], exposed=a[6], infectiousM=a[7]; scale(true); @@ -6410,7 +6441,6 @@ following routines: add(secondary); label(shift(5mm*N)*"Proportion of crows",point(NW),E); - [./secondaryaxis] @@ -6617,12 +6647,14 @@ these palettes to the CMYK colorspace. 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) + int nx=ngraph, int ny=nx, pen[] palette, int divs=0, + 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: +scaled according to the z axis scaling (*note automatic scaling::). If +'divs' > 1, the palette is quantized to 'divs'-1 values. A 'bounds' +structure for the function values is returned: struct bounds { real min; real max; @@ -6634,14 +6666,15 @@ 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::). +sampling interval, while 'Automatic' selects "nice" limits. The +examples 'fillcontour.asy' and 'imagecontour.asy' illustrate 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, + pair initial, pair final, pen[] palette, int divs=0, 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 @@ -6861,7 +6894,7 @@ model tree. Here material is a structure defined in 'three_light.asy': struct material { pen[] p; // diffusepen,emissivepen,specularpen real opacity; - real shininess; + real shininess; real metallic; real fresnel0; } @@ -6895,10 +6928,20 @@ transparent for all other formats. One can request a completely transparent background for 3D 'WebGL' images with 'currentlight.background=black+opacity(0.0);' + Asymptote also supports image-based lighting with the setting +'settings.ibl=true'. This uses pre-rendered EXR images from the +directory specified by '-imageDir' (which defaults to 'ibl') or, for +'WebGL' rendering, the URL specified by '-imageURL' (which defaults to +<https://vectorgraphics.gitlab.io/asymptote/ibl>). Additional rendered +images can be generated on an 'NVIDIA' GPU using the 'reflect' program +in the 'cudareflect' subdirectory of the 'Asymptote' source directory. + 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'. +'BezierSurface.asy', 'teapot.asy', 'teapotIBL.asy', and +'parametricsurface.asy'. + + The structure 'render' contains specialized rendering options +documented at the beginning of module 'three'. The examples 'elevation.asy' and 'sphericalharmonic.asy' illustrate how to draw a surface with patch-dependent colors. The examples @@ -6963,7 +7006,7 @@ 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 five choices for viewing 3D 'Asymptote' output: +There are six 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 @@ -6992,7 +7035,7 @@ There are five choices for viewing 3D 'Asymptote' output: * Ctrl Right: rotate about the Y axis * Alt Right: rotate about the Z axis - The keyboard shortcuts are: + The keyboard bindings are: * h: home * f: toggle fitscreen * x: spin about the X axis @@ -7019,11 +7062,8 @@ There are five choices for viewing 3D 'Asymptote' output: 'outformat="html"'). The resulting 3D HTML file can then be viewed directly in any modern desktop or mobile browser, or even embedded within another web page: - <div> - <object data="logo3.html" - style="width:210;height:140;position:relative;top:0;left:0;"> - </object> - </div> + <iframe src="logo3.html" width="561" height="321" frameborder="0"> + </iframe> Normally, 'WebGL' files generated by 'Asymptote' are dynamically remeshed to fit the browser window dimensions. However, the @@ -7059,34 +7099,47 @@ There are five choices for viewing 3D 'Asymptote' output: 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'. + width and height of the viewport. Some graphics drivers support + batch mode ('-noV') rendering in an iconified window; this can be + enabled with the setting 'iconify=true'. 4. 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 - module 'three' (or 'graph3') is imported. The 'media9' LaTeX - package is also required (*note embed::). The example '100d.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 PRC specification is available from + file with version '9.0' or later of 'Adobe Reader'. This requires + 'settings.outformat="pdf"' and 'settings.prc=true', which can be + specified by the command-line options '-f pdf' and '-f prc', put in + the 'Asymptote' configuration file (*note configuration file::), or + specified in the script before module 'three' (or 'graph3') is + imported. The 'media9' LaTeX package is also required (*note + embed::). The example '100d.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 PRC specification is + available from <https://web.archive.org/web/20081204104459/http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/> - 5. 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::). + 5. Output a 'V3D' portable compressed binary file for viewing with an + external viewer or conversion to an alternate 3D format with the + Python 'pyv3d' library. The 'V3D' specification and the 'pyv3d' + library are available at <https://gitlab.com/vectorgraphics/v3d>. + A 'V3D' file 'file.v3d' may be imported and viewed by 'Asymptote' + either by specifying 'file.v3d' on the command line + asy -V file.v3d + or using the 'v3d' module and 'importv3d' function in interactive + mode (or within an 'Asymptote' file): + import v3d; + importv3d("file.v3d"); + + 6. Project the scene to a two-dimensional vector (EPS or PDF) format + with 'render=0'. Only limited support for hidden surface removal, + lighting, and transparency is 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 @@ -7196,11 +7249,7 @@ These projections to two dimensions are predefined: 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 + 'up' points upwards. 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 @@ -7499,7 +7548,7 @@ 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="", + Label xlabel="", Label ylabel="", Label zlabel="", bool extend=false, triple min=(-infinity,-infinity,-infinity), triple max=(infinity,infinity,infinity), @@ -7957,13 +8006,57 @@ 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: + The next examples illustrates how contour lines can be drawn on color +density images, with and without palette quantization: import graph; import palette; import contour; -size(10cm,10cm,IgnoreAspect); +size(10cm,10cm); + +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=1; +int n=Divs*divs; + +defaultpen(1bp); +pen Tickpen=black; +pen tickpen=gray+0.5*linewidth(currentpen); +pen[] Palette=quantize(BWRainbow(),n); + +bounds range=image(f,Automatic,a,b,3N,Palette,n); + +real[] Cvals=uniform(range.min,range.max,Divs); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); + +// Major contours +real[] Cvals=uniform(range.min,range.max,Divs); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); + +// Minor contours (if divs > 1) +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(SE)+(0.5,0),point(NE)+(1,0),Right,Palette, + PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen)); + + [./fillcontour] + +import graph; +import palette; +import contour; + +size(10cm,10cm); pair a=(0,0); pair b=(2pi,2pi); @@ -7972,7 +8065,7 @@ real f(real x, real y) {return cos(x)*sin(y);} int N=200; int Divs=10; -int divs=2; +int divs=1; defaultpen(1bp); pen Tickpen=black; @@ -7982,21 +8075,20 @@ 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); +draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin); -// Minor contours +// Minor contours (if divs > 1) 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); +draw(contour(f,a,b,cvals,N,operator --),tickpen+squarecap+beveljoin); 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)); +palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette, + PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen)); [./imagecontour] @@ -8087,9 +8179,9 @@ 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, +surface implicitsurface(real f(triple)=null, real ff(real,real,real)=null, - triple a, + triple a, triple b, int n=nmesh, bool keyword overlapedges=false, @@ -8115,7 +8207,7 @@ File: asymptote.info, Node: slopefield, Next: ode, Prev: smoothcontour3, Up: 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, + 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 @@ -8170,6 +8262,8 @@ Usage: ../asy [options] [file ...] Options (negate by replacing - with -no): +-GPUindexing Compute indexing partial sums on GPU [true] +-GPUinterlock Use fragment shader interlock [true] -V,-View View output; command-line only -absolute Use absolute WebGL dimensions [false] -a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C] @@ -8194,8 +8288,8 @@ Options (negate by replacing - with -no): -devicepixelratio n Ratio of physical to logical pixels [1] -digits n Default output file precision [7] -divisor n Garbage collect using purge(divisor=n) [2] +-dvisvgmMultipleFiles dvisvgm supports multiple files [false] -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] @@ -8205,7 +8299,10 @@ Options (negate by replacing - with -no): -gray Convert all colors to grayscale [false] -h,-help Show summary of options; command-line only -historylines n Retain n lines of history [1000] +-ibl Enable environment map image-based lighting [false] -iconify Iconify rendering window [false] +-image string Environment image name [snowyField] +-imageDir string Environment image library directory [ibl] -inlineimage Generate inline embedded image [false] -inlinetex Generate inline TeX code [false] -interactiveMask Mask fpu exceptions in interactive mode [true] @@ -8217,6 +8314,8 @@ Options (negate by replacing - with -no): -l,-listvariables List available global functions and variables [false] -localhistory Use a local interactive history file [false] -loop Loop 3D animations [false] +-lossy Use single precision for V3D reals [false] +-lsp Interactive mode for the Language Server Protocol [false] -m,-mask Mask fpu exceptions; command-line only -maxtile pair Maximum rendering tile size [(1024,768)] -maxviewport pair Maximum viewport size [(0,0)] @@ -8231,7 +8330,8 @@ Options (negate by replacing - with -no): -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] +-prc Embed 3D PRC graphics in PDF output [false] +-prerender resolution Prerender V3D objects (0 implies vector output) [0] -prompt string Prompt [> ] -prompt2 string Continuation prompt for multiline input [..] -q,-quiet Suppress welcome text and noninteractive stdout [false] @@ -8261,8 +8361,10 @@ Options (negate by replacing - with -no): -viewportmargin pair Horizontal and vertical 3D viewport margin [(0.5,0.5)] -wait Wait for child processes to finish before exiting [false] -warn string Enable warning; command-line only +-webgl2 Use webgl2 if available [false] -where Show where listed variables are declared [false] --xasy Special interactive mode for xasy [false] +-wsl Run asy under the Windows Subsystem for Linux. [false] +-xasy Interactive mode for xasy [false] -zoomPinchCap limit WebGL maximum zoom pinch [100] -zoomPinchFactor n WebGL zoom pinch sensitivity [10] -zoomfactor factor Zoom step factor [1.05] @@ -8357,7 +8459,7 @@ value '(0,0)' species center alignment. '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)" +asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)" produces the output 4 0.841470984807897 @@ -8423,7 +8525,7 @@ using the symbol '%' in the next line input at the prompt. For example: > 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 @@ -8476,7 +8578,7 @@ g.clip("unitcircle") g.label("\"$O$\", (0,0), SW") -File: asymptote.info, Node: GUI, Next: PostScript to Asymptote, Prev: Interactive mode, Up: Top +File: asymptote.info, Node: GUI, Next: Command-Line Interface, Prev: Interactive mode, Up: Top 11 Graphical User Interface *************************** @@ -8536,9 +8638,99 @@ 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 +File: asymptote.info, Node: Command-Line Interface, Next: PostScript to Asymptote, Prev: GUI, Up: Top + +12 Command-Line Interface +************************* + +'Asymptote' code may be sent to the <http://asymptote.ualberta.ca> +server directly from the command line, specifying any options directly +in the URL: + + * SVG output: + + 'curl --data-binary 'import venn;' + 'asymptote.ualberta.ca:10007?f=svg' | display -' + + * HTML output: + + 'curl --data-binary + @/usr/local/share/doc/asymptote/examples/Klein.asy + 'asymptote.ualberta.ca:10007' -o Klein.html' + + * V3D output: -12 'PostScript' to 'Asymptote' + 'curl --data-binary 'import teapot;' + 'asymptote.ualberta.ca:10007?f=v3d' -o teapot.v3d' + + * PDF output with rendered bitmap at 2 pixels per bp: + + 'curl --data-binary 'import teapot;' + 'asymptote.ualberta.ca:10007?f=pdf' -o teapot.pdf' + + * PDF output with rendered bitmap at 4 pixels per bp: + + 'curl --data-binary 'import teapot;' + 'asymptote.ualberta.ca:10007?f=pdf&render=4' -o teapot.pdf' + + * PRC output: + + 'curl --data-binary 'import teapot;' + 'asymptote.ualberta.ca:10007?f=pdf&prc' -o teapot.pdf' + + * PRC output with rendered preview bitmap at 4 pixels per bp: + + 'curl --data-binary 'import teapot;' + 'asymptote.ualberta.ca:10007?f=pdf&prc&render=4' -o teapot.pdf' + + The source code for the command-line interface is available at +<https://github.com/vectorgraphics/asymptote-http-server>. + + +File: asymptote.info, Node: Language server protocol, Next: PostScript to Asymptote, Prev: Command-Line Interface, Up: Top + +13 Language server protocol +*************************** + +Under 'UNIX' and 'MacOS X', 'Asymptote' supports features of the +Language Server Protocol (LSP) +(https://en.wikipedia.org/wiki/Language_Server_Protocol), including +function signature and variable matching. Under 'MSWindows', +'Asymptote' currently supports LSP only when compiled within the +'Windows Subsystem for Linux'. + + 'Emacs' users can enable the 'Asymptote' language server protocol by +installing 'lsp-mode' using the following procedure: + + * Add to the '.emacs' initialization file: + (require 'package) + (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) + (package-initialize) + + * Launch emacs and execute + M-x package-refresh-contents + M-x package-install + and select 'lsp-mode'. + + * Add to the '.emacs' initialization file: + (require 'lsp-mode) + (add-to-list 'lsp-language-id-configuration '(asy-mode . "asymptote")) + + (lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection '("asy" "-lsp")) + :activation-fn (lsp-activate-on "asymptote") + :major-modes '(asy-mode) + :server-id 'asyls + ) + ) + + * Launch emacs and execute + M-x lsp + + +File: asymptote.info, Node: PostScript to Asymptote, Next: Help, Prev: Command-Line Interface, Up: Top + +14 'PostScript' to 'Asymptote' ****************************** The excellent 'PostScript' editor 'pstoedit' (version 3.50 or later; @@ -8557,7 +8749,7 @@ If the line widths aren't quite correct, try giving 'pstoedit' the File: asymptote.info, Node: Help, Next: Debugger, Prev: PostScript to Asymptote, Up: Top -13 Help +15 Help ******* A list of frequently asked questions (FAQ) is maintained at @@ -8591,7 +8783,7 @@ generates such segmentation faults along with your bug report). File: asymptote.info, Node: Debugger, Next: Credits, Prev: Help, Up: Top -14 Debugger +16 Debugger *********** Asymptote now includes a line-based (as opposed to code-based) debugger @@ -8657,7 +8849,7 @@ void breakpoint(code s=quote{}); File: asymptote.info, Node: Credits, Next: Index, Prev: Debugger, Up: Top -15 Acknowledgments +17 Acknowledgments ****************** Financial support for the development of 'Asymptote' was generously @@ -8673,11 +8865,13 @@ author of the program 'MetaPost' that inspired the development of 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 +Philippe Ivaldi, Olivier Guibé, Radoslav Marinov, Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, Martin Wiebusch, -Stefan Knorr, and Supakorn "Jamie" Rassameemasmuang. Pedram Emami -developed the 'Asymptote Web Application' at -<http://asymptote.ualberta.ca>. +Stefan Knorr, Supakorn "Jamie" Rassameemasmuang, Jacob Skitsko, Joseph +Chaumont, and Oliver Cheng. Pedram Emami developed the 'Asymptote Web +Application' hosted at <http://asymptote.ualberta.ca>: + + <https://github.com/vectorgraphics/asymptoteWebApplication> File: asymptote.info, Node: Index, Prev: Credits, Up: Top @@ -8727,9 +8921,9 @@ Index * ---: Bezier curves. (line 84) * -=: Self & prefix operators. (line 6) -* -c: Options. (line 195) -* -l: Options. (line 214) -* -u: Options. (line 205) +* -c: Options. (line 205) +* -l: Options. (line 224) +* -u: Options. (line 215) * -V: Configuring. (line 6) * -V <1>: Drawing in batch mode. (line 16) @@ -8742,7 +8936,7 @@ Index * 2D graphs: graph. (line 6) * 3D graphs: graph3. (line 6) * 3D grids: grid3. (line 6) -* 3D PostScript: three. (line 639) +* 3D PostScript: three. (line 655) * :: Arithmetic & logical. (line 61) * ::: Bezier curves. (line 70) @@ -8779,9 +8973,10 @@ Index * abs2: Data types. (line 65) * abs2 <1>: Data types. (line 144) * absolute: Configuring. (line 43) +* absolute <1>: three. (line 241) * accel: Paths and guides. (line 126) * accel <1>: Paths and guides. (line 132) -* accel <2>: three. (line 540) +* accel <2>: three. (line 556) * access: Import. (line 6) * access <1>: Import. (line 45) * acknowledgments: Credits. (line 6) @@ -8795,8 +8990,8 @@ Index (line 217) * add <1>: Frames and pictures. (line 231) -* add <2>: three. (line 312) -* addViews: three. (line 433) +* add <2>: three. (line 332) +* addViews: three. (line 449) * adjust: Pens. (line 123) * Ai: Mathematical functions. (line 48) @@ -8805,10 +9000,10 @@ Index * Ai_deriv: Mathematical functions. (line 48) * alias: Structures. (line 62) -* alias <1>: Arrays. (line 179) +* alias <1>: Arrays. (line 183) * Align: label. (line 12) -* aligndir: Options. (line 187) -* all: Arrays. (line 338) +* aligndir: Options. (line 197) +* all: Arrays. (line 341) * Allow: Pens. (line 363) * and: Bezier curves. (line 56) * AND: Arithmetic & logical. @@ -8820,22 +9015,22 @@ Index * animation: animation. (line 6) * animation <1>: animation. (line 6) * annotate: annotate. (line 6) -* antialias: three. (line 254) -* antialias <1>: Options. (line 157) +* antialias: three. (line 261) +* antialias <1>: Options. (line 167) * append: Files. (line 38) * append <1>: Arrays. (line 39) * arc: Paths and guides. (line 24) * Arc: Paths and guides. (line 37) -* arc <1>: three. (line 323) +* arc <1>: three. (line 343) * ArcArrow: draw. (line 26) -* ArcArrow3: three. (line 606) +* ArcArrow3: three. (line 622) * ArcArrows: draw. (line 26) -* ArcArrows3: three. (line 606) +* ArcArrows3: three. (line 622) * arclength: Paths and guides. (line 153) -* arclength <1>: three. (line 540) +* arclength <1>: three. (line 556) * arcpoint: Paths and guides. (line 163) * arctime: Paths and guides. (line 157) -* arctime <1>: three. (line 540) +* arctime <1>: three. (line 556) * arguments: Default arguments. (line 6) * arithmetic operators: Arithmetic & logical. (line 6) @@ -8849,10 +9044,10 @@ Index * arrow keys: Drawing in interactive mode. (line 11) * arrow keys <1>: GUI usage. (line 6) -* Arrow3: three. (line 606) +* Arrow3: three. (line 622) * arrows: draw. (line 26) * Arrows: draw. (line 26) -* Arrows3: three. (line 606) +* Arrows3: three. (line 622) * as: Import. (line 67) * ascii: Data types. (line 309) * ascii <1>: Data types. (line 309) @@ -8875,7 +9070,7 @@ Index * Asymptote Web Application: Description. (line 6) * asymptote.sty: LaTeX usage. (line 6) * asymptote.xml: Editing modes. (line 48) -* ASYMPTOTE_CONFIG: Options. (line 128) +* ASYMPTOTE_CONFIG: Options. (line 138) * atan: Mathematical functions. (line 6) * aTan: Mathematical functions. @@ -8889,13 +9084,13 @@ Index (line 276) * attach <1>: LaTeX usage. (line 50) * attach <2>: graph. (line 406) -* autoadjust: three. (line 398) -* autoimport: Options. (line 124) -* automatic scaling: graph. (line 690) -* automatic scaling <1>: graph. (line 690) +* autoadjust: three. (line 418) +* autoimport: Options. (line 134) +* automatic scaling: graph. (line 710) +* automatic scaling <1>: graph. (line 710) * axialshade: fill. (line 43) -* axis: graph. (line 905) -* axis <1>: graph. (line 988) +* axis: graph. (line 924) +* axis <1>: graph. (line 1007) * axis <2>: graph3. (line 66) * axis <3>: graph3. (line 82) * azimuth: Data types. (line 154) @@ -8904,11 +9099,11 @@ Index * background <1>: three. (line 97) * background color: Frames and pictures. (line 180) -* BackView: three. (line 426) +* BackView: three. (line 442) * Bar: draw. (line 19) -* Bar3: three. (line 606) +* Bar3: three. (line 622) * Bars: draw. (line 19) -* Bars3: three. (line 606) +* Bars3: three. (line 622) * barsize: draw. (line 19) * base modules: Base modules. (line 6) * basealign: Pens. (line 181) @@ -8917,30 +9112,30 @@ Index (line 6) * beep: Data types. (line 382) * BeginArcArrow: draw. (line 26) -* BeginArcArrow3: three. (line 606) +* BeginArcArrow3: three. (line 622) * BeginArrow: draw. (line 26) -* BeginArrow3: three. (line 606) +* BeginArrow3: three. (line 622) * BeginBar: draw. (line 19) -* BeginBar3: three. (line 606) +* BeginBar3: three. (line 622) * BeginDotMargin: draw. (line 42) -* BeginDotMargin3: three. (line 622) +* BeginDotMargin3: three. (line 638) * BeginMargin: draw. (line 42) -* BeginMargin3: three. (line 622) +* BeginMargin3: three. (line 638) * BeginPenMargin: draw. (line 42) -* BeginPenMargin2: three. (line 622) -* BeginPenMargin3: three. (line 622) +* BeginPenMargin2: three. (line 638) +* BeginPenMargin3: three. (line 638) * 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 118) -* Bezier triangle: three. (line 118) -* bezulate: three. (line 136) +* Bezier patch: three. (line 128) +* Bezier triangle: three. (line 128) +* bezulate: three. (line 146) * Bi: Mathematical functions. (line 48) -* Billboard: three. (line 510) +* Billboard: three. (line 526) * binary: Files. (line 80) * binary format: Files. (line 80) * binary operators: Arithmetic & logical. @@ -8948,7 +9143,7 @@ Index * binarytree: binarytree. (line 6) * Bi_deriv: Mathematical functions. (line 48) -* black stripes: three. (line 254) +* black stripes: three. (line 261) * Blank: draw. (line 26) * block.bottom: flowchart. (line 19) * block.bottomleft: flowchart. (line 19) @@ -8967,23 +9162,24 @@ Index (line 6) * Bottom: graph. (line 132) * BottomTop: graph. (line 138) -* BottomView: three. (line 426) +* BottomView: three. (line 442) * bounding box: Frames and pictures. (line 180) +* bounds: palette. (line 43) * Bounds: graph3. (line 21) * box: Frames and pictures. (line 25) * box <1>: Frames and pictures. (line 130) -* box <2>: three. (line 345) -* box <3>: three. (line 347) +* box <2>: three. (line 365) +* box <3>: three. (line 367) * bp: Drawing in batch mode. (line 23) * brace: Paths and guides. (line 51) * break: Programming. (line 48) * breakpoints: Debugger. (line 21) * brick: Pens. (line 285) -* broken axis: graph. (line 801) +* broken axis: graph. (line 821) * bug reports: Help. (line 19) * buildcycle: Paths and guides. (line 270) * Button-1: GUI. (line 6) @@ -8994,7 +9190,7 @@ Index * CAD: CAD. (line 6) * calculateTransform: Frames and pictures. (line 118) -* camera: three. (line 392) +* camera: three. (line 412) * casts: Casts. (line 6) * cbrt: Mathematical functions. (line 6) @@ -9002,7 +9198,7 @@ Index * ceil: Mathematical functions. (line 26) * Center: label. (line 60) -* center: three. (line 375) +* center: three. (line 395) * checker: Pens. (line 285) * Chinese: Pens. (line 244) * choose: Mathematical functions. @@ -9011,7 +9207,7 @@ Index (line 48) * circle: Paths and guides. (line 10) * Circle: Paths and guides. (line 18) -* circle <1>: three. (line 319) +* circle <1>: three. (line 339) * circle <2>: flowchart. (line 61) * circlebarframe: markers. (line 18) * CJK: Pens. (line 244) @@ -9034,26 +9230,28 @@ Index * colorless: Pens. (line 57) * colors: Pens. (line 54) * comma: Files. (line 65) -* comma-separated-value mode: Arrays. (line 370) +* comma-separated-value mode: Arrays. (line 374) +* command-line interface: Command-Line Interface. + (line 6) * command-line options: Configuring. (line 91) * 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 145) -* concat: Arrays. (line 175) +* complement: Arrays. (line 149) +* concat: Arrays. (line 179) * conditional: Programming. (line 26) * conditional <1>: Arithmetic & logical. (line 61) * config: Configuring. (line 74) -* config <1>: Options. (line 128) +* config <1>: Options. (line 138) * configuration file: Configuring. (line 20) -* configuration file <1>: Options. (line 128) +* configuration file <1>: Options. (line 138) * configuring: Configuring. (line 6) * conj: Data types. (line 62) * constructors: Structures. (line 91) -* context: Options. (line 157) +* context: Options. (line 167) * continue: Programming. (line 48) * continue <1>: Debugger. (line 31) * contour: contour. (line 6) @@ -9064,10 +9262,10 @@ Index * convert: Configuring. (line 74) * convert <1>: Files. (line 159) * convert <2>: animation. (line 6) -* convert <3>: Options. (line 157) -* convertOptions: Options. (line 143) +* convert <3>: Options. (line 167) +* convertOptions: Options. (line 153) * Coons shading: fill. (line 78) -* copy: Arrays. (line 172) +* copy: Arrays. (line 176) * cos: Mathematical functions. (line 6) * Cos: Mathematical functions. @@ -9082,16 +9280,16 @@ Index * cross <2>: graph. (line 480) * crossframe: markers. (line 22) * crosshatch: Pens. (line 302) -* csv: Arrays. (line 370) +* csv: Arrays. (line 374) * CTZ: Arithmetic & logical. (line 68) -* cubicroots: Arrays. (line 327) +* cubicroots: Arrays. (line 331) * curl: Bezier curves. (line 66) * curl <1>: three. (line 6) * curlSpecifier: Paths and guides. (line 408) * currentlight: three. (line 76) * currentpen: Pens. (line 6) -* currentprojection: three. (line 423) +* currentprojection: three. (line 439) * curve: slopefield. (line 20) * custom axis types: graph. (line 141) * custom mark routine: graph. (line 577) @@ -9103,7 +9301,7 @@ Index * cyclic: Paths and guides. (line 85) * cyclic <1>: Paths and guides. (line 376) * cyclic <2>: Arrays. (line 39) -* cyclic <3>: three. (line 540) +* cyclic <3>: three. (line 556) * Cyrillic: Pens. (line 237) * dashdotted: Pens. (line 102) * dashed: Pens. (line 102) @@ -9117,7 +9315,7 @@ Index * default arguments: Default arguments. (line 6) * defaultformat: graph. (line 175) * DefaultHead: draw. (line 26) -* DefaultHead3: three. (line 606) +* DefaultHead3: three. (line 622) * defaultpen: Pens. (line 49) * defaultpen <1>: Pens. (line 122) * defaultpen <2>: Pens. (line 127) @@ -9135,17 +9333,17 @@ Index * delete: Files. (line 154) * delete <1>: Arrays. (line 39) * description: Description. (line 6) -* devicepixelratio: three. (line 174) -* diagonal: Arrays. (line 312) +* devicepixelratio: three. (line 184) +* diagonal: Arrays. (line 316) * diamond: flowchart. (line 54) * diffuse: three. (line 76) * diffusepen: three. (line 66) -* dimension: Arrays. (line 375) +* dimension: Arrays. (line 379) * dir: Search paths. (line 9) * dir <1>: Data types. (line 90) * dir <2>: Data types. (line 181) * dir <3>: Paths and guides. (line 109) -* dir <4>: three. (line 540) +* dir <4>: three. (line 556) * direction specifier: Bezier curves. (line 6) * directory: Files. (line 26) * dirSpecifier: Paths and guides. (line 390) @@ -9157,14 +9355,14 @@ Index * dot: draw. (line 83) * dot <1>: Data types. (line 103) * dot <2>: Data types. (line 194) -* dot <3>: Arrays. (line 267) -* dot <4>: Arrays. (line 270) +* dot <3>: Arrays. (line 271) +* dot <4>: Arrays. (line 274) * DotMargin: draw. (line 42) -* DotMargin3: three. (line 622) +* DotMargin3: three. (line 638) * DotMargins: draw. (line 42) -* DotMargins3: three. (line 622) +* DotMargins3: three. (line 638) * dotted: Pens. (line 102) -* double deferred drawing: three. (line 297) +* double deferred drawing: three. (line 317) * double precision: Files. (line 80) * draw: Drawing commands. (line 34) * draw <1>: draw. (line 6) @@ -9172,15 +9370,15 @@ Index * draw <2>: draw. (line 113) * Draw <1>: Frames and pictures. (line 160) -* draw <3>: three. (line 144) +* draw <3>: three. (line 154) * drawing commands: Drawing commands. (line 6) * drawline: math. (line 9) * drawtree: drawtree. (line 6) * dvips: Configuring. (line 74) -* dvipsOptions: Options. (line 143) +* dvipsOptions: Options. (line 153) * dvisvgm: Configuring. (line 74) -* dvisvgm <1>: Options. (line 162) -* dvisvgmOptions: Options. (line 143) +* dvisvgm <1>: Options. (line 172) +* dvisvgmOptions: Options. (line 153) * E: Labels. (line 18) * E <1>: Mathematical functions. (line 48) @@ -9195,34 +9393,34 @@ Index * else: Programming. (line 26) * emacs: Editing modes. (line 6) * embed: embed. (line 6) -* Embedded: three. (line 510) +* Embedded: three. (line 526) * emissivepen: three. (line 66) * empty: Frames and pictures. (line 7) * EndArcArrow: draw. (line 26) -* EndArcArrow3: three. (line 606) +* EndArcArrow3: three. (line 622) * EndArrow: draw. (line 26) -* EndArrow3: three. (line 606) +* EndArrow3: three. (line 622) * EndBar: draw. (line 19) -* EndBar3: three. (line 606) +* EndBar3: three. (line 622) * EndDotMargin: draw. (line 42) -* EndDotMargin3: three. (line 622) +* EndDotMargin3: three. (line 638) * endl: Files. (line 65) * EndMargin: draw. (line 42) -* EndMargin3: three. (line 622) +* EndMargin3: three. (line 638) * EndPenMargin: draw. (line 42) -* EndPenMargin2: three. (line 622) -* EndPenMargin3: three. (line 622) +* EndPenMargin2: three. (line 638) +* EndPenMargin3: three. (line 638) * EndPoint: label. (line 55) * envelope: Frames and pictures. (line 25) * environment variables: Configuring. (line 95) * eof: Files. (line 97) -* eof <1>: Arrays. (line 352) +* eof <1>: Arrays. (line 356) * eol: Files. (line 97) -* eol <1>: Arrays. (line 352) +* eol <1>: Arrays. (line 356) * EPS: label. (line 78) -* EPS <1>: Options. (line 157) +* EPS <1>: Options. (line 167) * erase: Drawing in interactive mode. (line 11) * erase <1>: Data types. (line 257) @@ -9259,20 +9457,20 @@ Index * extension: Paths and guides. (line 246) * extension <1>: MetaPost. (line 10) * external: embed. (line 11) -* extrude: three. (line 534) +* extrude: three. (line 550) * F: Mathematical functions. (line 48) * fabs: Mathematical functions. (line 6) -* face: three. (line 646) +* face: three. (line 662) * factorial: Mathematical functions. (line 39) * Fedora: UNIX binary distributions. (line 15) * feynman: feynman. (line 6) -* fft: Arrays. (line 245) -* fft <1>: Arrays. (line 259) -* fft <2>: Arrays. (line 263) +* fft: Arrays. (line 249) +* fft <1>: Arrays. (line 263) +* fft <2>: Arrays. (line 267) * FFTW: Compiling from UNIX source. (line 62) * file: Files. (line 6) @@ -9290,12 +9488,12 @@ Index * filloutside: fill. (line 27) * fillrule: Pens. (line 164) * find: Data types. (line 242) -* find <1>: Arrays. (line 154) -* findall: Arrays. (line 159) +* find <1>: Arrays. (line 158) +* findall: Arrays. (line 163) * firstcut: Paths and guides. (line 262) * fit: Frames and pictures. (line 113) -* fit3: three. (line 310) +* fit3: three. (line 330) * fixedscaling: Frames and pictures. (line 81) * floor: Mathematical functions. @@ -9313,13 +9511,13 @@ Index * fontsize: Pens. (line 192) * for: Programming. (line 26) * format: Data types. (line 290) -* format <1>: Options. (line 157) +* format <1>: Options. (line 167) * forum: Help. (line 6) * frame: Frames and pictures. (line 7) * freshnel0: three. (line 66) * from: Import. (line 16) -* FrontView: three. (line 426) +* FrontView: three. (line 442) * function declarations: Functions. (line 79) * Function shading: fill. (line 100) * function shading: fill. (line 100) @@ -9340,8 +9538,8 @@ Index * git: Git. (line 6) * globalwrite: Files. (line 40) * globalwrite <1>: Files. (line 154) -* glOptions: three. (line 254) -* glOptions <1>: Options. (line 143) +* glOptions: three. (line 261) +* glOptions <1>: Options. (line 153) * GNU Scientific Library: Mathematical functions. (line 48) * gouraudshade: fill. (line 63) @@ -9350,20 +9548,21 @@ Index * graph: graph. (line 6) * graph3: graph3. (line 6) * graphic: label. (line 78) -* graphic <1>: Options. (line 162) +* graphic <1>: Options. (line 172) * graphical user interface: GUI. (line 6) +* graphwithderiv: graph. (line 670) * gray: Pens. (line 25) * grayscale: Pens. (line 25) * Grayscale: palette. (line 9) * grid: Pens. (line 285) -* grid <1>: graph. (line 746) +* grid <1>: graph. (line 766) * grid3: grid3. (line 6) * gs: Configuring. (line 20) * GSL: Compiling from UNIX source. (line 62) * gsl: Mathematical functions. (line 48) -* gsOptions: Options. (line 143) +* gsOptions: Options. (line 153) * GUI: GUI. (line 6) * GUI installation: GUI installation. (line 6) * GUI usage: GUI usage. (line 6) @@ -9381,44 +9580,47 @@ Index * hex <1>: Pens. (line 64) * hexadecimal: Data types. (line 306) * hexadecimal <1>: Pens. (line 62) -* hidden surface removal: three. (line 646) +* hidden surface removal: three. (line 662) * histogram: Mathematical functions. (line 39) * history: Files. (line 147) * history <1>: Interactive mode. (line 54) * historylines: Interactive mode. (line 57) * HookHead: draw. (line 26) -* HookHead3: three. (line 606) +* HookHead3: three. (line 622) * Horizontal: flowchart. (line 77) -* HTML5: three. (line 223) +* HTML5: three. (line 233) * htmlviewer: Configuring. (line 20) * htmlviewer <1>: Configuring. (line 43) -* htmlviewerOptions: Options. (line 143) -* hyperrefOptions: Options. (line 143) +* htmlviewerOptions: Options. (line 153) +* hyperrefOptions: Options. (line 153) * hypot: Mathematical functions. (line 6) * I: Mathematical functions. (line 48) -* iconify: three. (line 254) +* ibl: three. (line 104) +* iconify: three. (line 261) * identity: Transforms. (line 24) * identity <1>: Mathematical functions. (line 6) -* identity <2>: Arrays. (line 309) -* identity4: three. (line 478) +* identity <2>: Arrays. (line 313) +* identity4: three. (line 494) * if: Programming. (line 26) * IgnoreAspect: Frames and pictures. (line 63) * image: palette. (line 33) -* image <1>: palette. (line 58) +* image <1>: palette. (line 61) +* image-based lighting: three. (line 104) * ImageMagick: Configuring. (line 74) * ImageMagick <1>: animation. (line 6) -* ImageMagick <2>: Options. (line 157) +* ImageMagick <2>: Options. (line 167) * 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) +* importv3d: three. (line 308) * inches: Figure size. (line 18) * incircle: Data types. (line 120) * include: Import. (line 134) @@ -9441,7 +9643,7 @@ Index * inside: Paths and guides. (line 294) * inside <1>: Paths and guides. (line 299) * inside <2>: Paths and guides. (line 305) -* insphere: three. (line 569) +* insphere: three. (line 585) * inst: Debugger. (line 35) * installation: Installation. (line 6) * int: Data types. (line 30) @@ -9460,23 +9662,23 @@ Index * interpolate: interpolate. (line 6) * intersect: Paths and guides. (line 195) * intersect <1>: math. (line 13) -* intersect <2>: three. (line 540) +* intersect <2>: three. (line 556) * intersectionpoint: Paths and guides. (line 238) * intersectionpoint <1>: math. (line 17) -* intersectionpoint <2>: three. (line 540) +* intersectionpoint <2>: three. (line 556) * intersectionpoints: Paths and guides. (line 242) -* intersectionpoints <1>: three. (line 540) -* intersectionpoints <2>: three. (line 553) +* intersectionpoints <1>: three. (line 556) +* intersectionpoints <2>: three. (line 569) * intersections: Paths and guides. (line 206) * intersections <1>: Paths and guides. (line 213) -* intersections <2>: three. (line 540) -* intersections <3>: three. (line 546) +* intersections <2>: three. (line 556) +* intersections <3>: three. (line 562) * InTicks: graph3. (line 35) * intMax: Data types. (line 30) * intMin: Data types. (line 30) * inverse: Transforms. (line 16) -* inverse <1>: Arrays. (line 315) -* invert: three. (line 468) +* inverse <1>: Arrays. (line 319) +* invert: three. (line 484) * invisible: Pens. (line 43) * isnan: Data types. (line 35) * i_scaled: Mathematical functions. @@ -9495,7 +9697,7 @@ Index * keepAspect <1>: Frames and pictures. (line 63) * keepAspect <2>: LaTeX usage. (line 50) -* keyboard bindings:: three. (line 201) +* keyboard bindings:: three. (line 211) * keys: Arrays. (line 39) * keyword: Named arguments. (line 37) * keyword-only: Named arguments. (line 37) @@ -9508,7 +9710,7 @@ Index * label <1>: label. (line 6) * Label <1>: label. (line 14) * Label <2>: graph. (line 330) -* label <2>: three. (line 504) +* label <2>: three. (line 520) * labelpath: labelpath. (line 6) * labelpath3: labelpath3. (line 6) * labelx: graph. (line 330) @@ -9516,9 +9718,11 @@ Index * Landscape: Frames and pictures. (line 104) * language context: Pens. (line 235) +* language server protocol: Language server protocol. + (line 6) * lastcut: Paths and guides. (line 266) * lasy-mode: Editing modes. (line 6) -* latex: Options. (line 157) +* latex: Options. (line 167) * LaTeX NFSS fonts: Pens. (line 206) * LaTeX usage: LaTeX usage. (line 6) * latexmk: LaTeX usage. (line 30) @@ -9526,13 +9730,13 @@ Index * latticeshade: fill. (line 32) * layer: Drawing commands. (line 16) * leastsquares: stats. (line 6) -* leastsquares <1>: graph. (line 929) +* leastsquares <1>: graph. (line 948) * Left: graph. (line 269) * LeftRight: graph. (line 275) * LeftSide: label. (line 60) * LeftTicks: graph. (line 160) * LeftTicks <1>: graph. (line 233) -* LeftView: three. (line 426) +* LeftView: three. (line 442) * legend: Drawing commands. (line 34) * legend <1>: draw. (line 65) * legend <2>: graph. (line 424) @@ -9544,22 +9748,22 @@ Index * length <3>: Paths and guides. (line 76) * length <4>: Paths and guides. (line 373) * length <5>: Arrays. (line 39) -* length <6>: three. (line 540) +* length <6>: three. (line 556) * letter: Configuring. (line 68) * lexorder: math. (line 63) * lexorder <1>: math. (line 66) * libcurl: Import. (line 94) -* libgs: Options. (line 162) +* libgs: Options. (line 172) * libm routines: Mathematical functions. (line 6) * libsigsegv: Functions. (line 100) * libsigsegv <1>: Help. (line 27) * light: three. (line 76) * limits: graph. (line 639) -* line: Arrays. (line 352) -* line <1>: Arrays. (line 356) -* line mode: Arrays. (line 352) -* Linear: graph. (line 690) +* line: Arrays. (line 356) +* line <1>: Arrays. (line 360) +* line mode: Arrays. (line 356) +* Linear: graph. (line 710) * linecap: Pens. (line 139) * linejoin: Pens. (line 149) * lineskip: Pens. (line 192) @@ -9568,37 +9772,39 @@ Index * locale: Data types. (line 316) * log: Mathematical functions. (line 6) -* Log: graph. (line 690) -* log-log graph: graph. (line 724) +* Log: graph. (line 710) +* log-log graph: graph. (line 744) * log10: Mathematical functions. (line 6) * log1p: Mathematical functions. (line 6) -* log2 graph: graph. (line 780) -* logarithmic graph: graph. (line 724) +* log2 graph: graph. (line 800) +* logarithmic graph: graph. (line 744) * logical operators: Arithmetic & logical. (line 6) * longdashdotted: Pens. (line 102) * longdashed: Pens. (line 102) * longitude: Data types. (line 169) * loop: Programming. (line 26) -* lualatex: Options. (line 157) -* luatex: Options. (line 157) +* LSP: Language server protocol. + (line 6) +* lualatex: Options. (line 167) +* luatex: Options. (line 167) * MacOS X binary distributions: MacOS X binary distributions. (line 6) * MacOS X configuration: Compiling from UNIX source. (line 48) * makepen: Pens. (line 338) -* map: Arrays. (line 131) -* map <1>: Arrays. (line 136) +* map: Arrays. (line 135) +* map <1>: Arrays. (line 140) * map <2>: map. (line 6) * Margin: draw. (line 42) * Margin <1>: draw. (line 42) -* Margin3: three. (line 622) -* Margin3 <1>: three. (line 622) +* Margin3: three. (line 638) +* Margin3 <1>: three. (line 638) * Margins: draw. (line 42) -* margins: three. (line 303) -* Margins3: three. (line 622) +* margins: three. (line 323) +* Margins3: three. (line 638) * mark: graph. (line 480) * markangle: markers. (line 35) * marker: graph. (line 480) @@ -9613,14 +9819,14 @@ Index * max: Paths and guides. (line 279) * max <1>: Frames and pictures. (line 7) -* max <2>: Arrays. (line 226) -* max <3>: Arrays. (line 236) -* max <4>: three. (line 540) +* max <2>: Arrays. (line 230) +* max <3>: Arrays. (line 240) +* max <4>: three. (line 556) * maxbound: Data types. (line 134) * maxbound <1>: Data types. (line 205) -* maxtile: three. (line 254) +* maxtile: three. (line 261) * maxtimes: Paths and guides. (line 233) -* maxviewport: three. (line 254) +* maxviewport: three. (line 261) * metallic: three. (line 66) * MetaPost: MetaPost. (line 6) * MetaPost ... : Bezier curves. (line 70) @@ -9630,17 +9836,17 @@ Index * MetaPost whatever: MetaPost. (line 10) * Microsoft Windows: Microsoft Windows. (line 6) * MidArcArrow: draw. (line 26) -* MidArcArrow3: three. (line 606) +* MidArcArrow3: three. (line 622) * MidArrow: draw. (line 26) -* MidArrow3: three. (line 606) +* MidArrow3: three. (line 622) * 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 221) -* min <3>: Arrays. (line 231) -* min <4>: three. (line 540) +* min <2>: Arrays. (line 225) +* min <3>: Arrays. (line 235) +* min <4>: three. (line 556) * minbound: Data types. (line 131) * minbound <1>: Data types. (line 202) * minipage: label. (line 116) @@ -9649,16 +9855,16 @@ Index * miterlimit: Pens. (line 159) * mktemp: Files. (line 48) * mm: Figure size. (line 18) -* mobile browser: three. (line 223) +* mobile browser: three. (line 233) * mode: Files. (line 80) * mode <1>: Files. (line 93) * monotonic: graph. (line 36) * mouse: GUI. (line 6) -* mouse bindings: three. (line 182) +* mouse bindings: three. (line 192) * mouse wheel: GUI usage. (line 6) * Move: Pens. (line 375) * MoveQuiet: Pens. (line 381) -* multisample: three. (line 174) +* multisample: three. (line 184) * N: Labels. (line 18) * name: Files. (line 93) * named arguments: Named arguments. (line 6) @@ -9684,12 +9890,12 @@ Index * noglobalread <1>: Files. (line 40) * nolight: three. (line 76) * NoMargin: draw. (line 42) -* NoMargin3: three. (line 622) +* NoMargin3: three. (line 638) * None: draw. (line 19) * None <1>: draw. (line 26) * none: Files. (line 65) -* normal: three. (line 526) -* nosafe: Options. (line 182) +* normal: three. (line 542) +* nosafe: Options. (line 192) * NOT: Arithmetic & logical. (line 68) * notaknot: graph. (line 36) @@ -9701,23 +9907,23 @@ Index (line 140) * nullpen <2>: Frames and pictures. (line 149) -* NURBS: three. (line 402) -* O: three. (line 315) +* NURBS: three. (line 422) +* O: three. (line 335) * obj: obj. (line 6) -* oblique: three. (line 358) -* obliqueX: three. (line 365) -* obliqueY: three. (line 371) -* obliqueZ: three. (line 358) +* oblique: three. (line 378) +* obliqueX: three. (line 385) +* obliqueY: three. (line 391) +* obliqueZ: three. (line 378) * ode: ode. (line 6) * offset: Pens. (line 123) -* offset <1>: Options. (line 187) +* offset <1>: Options. (line 197) * OmitTick: graph. (line 223) * OmitTickInterval: graph. (line 223) * OmitTickIntervals: graph. (line 223) * opacity: Pens. (line 254) * opacity <1>: three. (line 66) * open: Files. (line 12) -* OpenGL: three. (line 174) +* OpenGL: three. (line 184) * operator: User-defined operators. (line 6) * operator +(...string[] a).: Data types. (line 284) @@ -9734,15 +9940,15 @@ Index * OR: Arithmetic & logical. (line 68) * orient: Data types. (line 108) -* orient <1>: three. (line 557) +* orient <1>: three. (line 573) * orientation: Frames and pictures. (line 104) -* orthographic: three. (line 375) -* outformat: three. (line 174) +* orthographic: three. (line 395) +* outformat: three. (line 184) * outprefix: Frames and pictures. (line 91) * output: Files. (line 38) -* output <1>: Options. (line 157) +* output <1>: Options. (line 167) * OutTicks: graph3. (line 35) * overloading functions: Functions. (line 55) * overwrite: Pens. (line 360) @@ -9754,7 +9960,7 @@ Index (line 186) * pair: Figure size. (line 6) * pair <1>: Data types. (line 46) -* pairs: Arrays. (line 241) +* pairs: Arrays. (line 245) * paperheight: Configuring. (line 68) * papertype: Configuring. (line 68) * paperwidth: Configuring. (line 68) @@ -9763,7 +9969,7 @@ Index * parametrized curve: graph. (line 639) * partialsum: math. (line 49) * partialsum <1>: math. (line 52) -* patch-dependent colors: three. (line 109) +* patch-dependent colors: three. (line 119) * path: Paths. (line 6) * path <1>: Paths and guides. (line 7) * path <2>: three. (line 42) @@ -9775,38 +9981,38 @@ Index * patterns: Pens. (line 271) * patterns <1>: patterns. (line 6) * PBR: three. (line 74) -* PDF: Options. (line 157) -* pdflatex: Options. (line 157) -* pdfreloadOptions: Options. (line 143) +* PDF: Options. (line 167) +* pdflatex: Options. (line 167) +* pdfreloadOptions: Options. (line 153) * pdfviewer: Configuring. (line 20) -* pdfviewerOptions: Options. (line 143) +* pdfviewerOptions: Options. (line 153) * pen: Pens. (line 6) * PenMargin: draw. (line 42) -* PenMargin2: three. (line 622) -* PenMargin3: three. (line 622) +* PenMargin2: three. (line 638) +* PenMargin3: three. (line 638) * PenMargins: draw. (line 42) -* PenMargins2: three. (line 622) -* PenMargins3: three. (line 622) +* PenMargins2: three. (line 638) +* PenMargins3: three. (line 638) * periodic: graph. (line 36) * perl: LaTeX usage. (line 30) * perpendicular: geometry. (line 6) -* perspective: three. (line 402) +* perspective: three. (line 422) * physically based rendering: three. (line 74) * picture: Frames and pictures. (line 39) * picture alignment: Frames and pictures. (line 231) * piecewisestraight: Paths and guides. (line 92) -* pixel: three. (line 629) +* pixel: three. (line 645) * Pl: Mathematical functions. (line 48) * plain: plain. (line 6) -* planar: three. (line 118) -* plane: three. (line 341) -* planeproject: three. (line 523) +* planar: three. (line 128) +* plane: three. (line 361) +* planeproject: three. (line 539) * point: Paths and guides. (line 95) * point <1>: Paths and guides. (line 379) -* point <2>: three. (line 540) +* point <2>: three. (line 556) * polar: Data types. (line 149) * polargraph: graph. (line 88) * polygon: graph. (line 480) @@ -9814,9 +10020,9 @@ Index * Portrait: Frames and pictures. (line 104) * position: three. (line 76) -* position <1>: three. (line 174) +* position <1>: three. (line 184) * postcontrol: Paths and guides. (line 146) -* postcontrol <1>: three. (line 540) +* postcontrol <1>: three. (line 556) * postfix operators: Self & prefix operators. (line 19) * postscript: Frames and pictures. @@ -9825,10 +10031,10 @@ Index * PostScript subpath: Paths. (line 23) * pow10: Mathematical functions. (line 6) -* prc: three. (line 272) +* prc: three. (line 279) * precision: Files. (line 97) * precontrol: Paths and guides. (line 139) -* precontrol <1>: three. (line 540) +* precontrol <1>: three. (line 556) * prefix operators: Self & prefix operators. (line 6) * private: Structures. (line 6) @@ -9836,15 +10042,15 @@ Index * pstoedit: PostScript to Asymptote. (line 6) * psviewer: Configuring. (line 20) -* psviewerOptions: Options. (line 143) +* psviewerOptions: Options. (line 153) * pt: Figure size. (line 18) * public: Structures. (line 6) * push: Arrays. (line 39) * Python usage: Interactive mode. (line 72) -* quadraticroots: Arrays. (line 318) -* quadraticroots <1>: Arrays. (line 323) +* quadraticroots: Arrays. (line 322) +* quadraticroots <1>: Arrays. (line 327) * quarticroots: math. (line 22) -* quick reference: Description. (line 88) +* quick reference: Description. (line 92) * quit: Drawing in interactive mode. (line 11) * quit <1>: Interactive mode. (line 54) @@ -9860,15 +10066,15 @@ Index * radians: Mathematical functions. (line 17) * radius: Paths and guides. (line 135) -* radius <1>: three. (line 540) +* radius <1>: three. (line 556) * Rainbow: palette. (line 12) * rand: Mathematical functions. (line 39) * randMax: Mathematical functions. (line 39) -* read: Arrays. (line 392) +* read: Arrays. (line 396) * reading: Files. (line 12) -* reading string arrays: Arrays. (line 362) +* reading string arrays: Arrays. (line 366) * readline: Files. (line 139) * real: Data types. (line 35) * realDigits: Data types. (line 35) @@ -9878,7 +10084,7 @@ Index * realmult: Data types. (line 100) * rectangle: flowchart. (line 34) * recursion: Functions. (line 100) -* reference: Description. (line 88) +* reference: Description. (line 92) * reflect: Transforms. (line 42) * Relative: label. (line 50) * Relative <1>: label. (line 60) @@ -9888,8 +10094,8 @@ Index (line 6) * rename: Files. (line 156) * render: three. (line 46) -* render <1>: three. (line 174) -* render <2>: Options. (line 157) +* render <1>: three. (line 184) +* render <2>: Options. (line 167) * replace: Data types. (line 270) * resetdefaultpen: Pens. (line 387) * rest arguments: Rest arguments. (line 6) @@ -9900,8 +10106,8 @@ Index * reverse: Data types. (line 266) * reverse <1>: Paths and guides. (line 183) * reverse <2>: Paths and guides. (line 382) -* reverse <3>: Arrays. (line 141) -* reverse <4>: three. (line 540) +* reverse <3>: Arrays. (line 145) +* reverse <4>: three. (line 556) * rewind: Files. (line 97) * rfind: Data types. (line 247) * rgb: Pens. (line 30) @@ -9913,9 +10119,9 @@ Index * RightSide: label. (line 60) * RightTicks: graph. (line 160) * RightTicks <1>: graph. (line 233) -* RightView: three. (line 426) +* RightView: three. (line 442) * Rotate: label. (line 36) -* rotate: three. (line 494) +* rotate: three. (line 510) * Rotate(pair z): label. (line 39) * round: Mathematical functions. (line 26) @@ -9928,7 +10134,7 @@ Index * runtime imports: Import. (line 102) * Russian: Pens. (line 237) * S: Labels. (line 18) -* safe: Options. (line 182) +* safe: Options. (line 192) * save: Frames and pictures. (line 288) * saveline: Files. (line 139) @@ -9936,21 +10142,21 @@ Index * scale: Pens. (line 123) * scale <1>: Transforms. (line 34) * scale <2>: Transforms. (line 36) -* scale <3>: graph. (line 690) -* Scale <1>: graph. (line 707) -* scale <4>: three. (line 493) -* scale3: three. (line 491) -* scaled graph: graph. (line 670) +* scale <3>: graph. (line 710) +* Scale <1>: graph. (line 727) +* scale <4>: three. (line 509) +* scale3: three. (line 507) +* scaled graph: graph. (line 690) * scientific graph: graph. (line 387) * scroll: Files. (line 113) -* search: Arrays. (line 162) -* search <1>: Arrays. (line 168) +* search: Arrays. (line 166) +* search <1>: Arrays. (line 172) * search paths: Search paths. (line 6) * Seascape: Frames and pictures. (line 110) -* secondary axis: graph. (line 833) -* secondaryX: graph. (line 833) -* secondaryY: graph. (line 833) +* secondary axis: graph. (line 853) +* secondaryX: graph. (line 853) +* secondaryY: graph. (line 853) * seconds: Data types. (line 330) * seek: Files. (line 97) * seekeof: Files. (line 97) @@ -9960,7 +10166,7 @@ Index (line 6) * sequence: Arrays. (line 118) * settings: Configuring. (line 20) -* settings <1>: Options. (line 128) +* settings <1>: Options. (line 138) * sgn: Mathematical functions. (line 26) * shading: fill. (line 32) @@ -9968,12 +10174,12 @@ Index * shift: Transforms. (line 26) * shift <1>: Transforms. (line 28) * shift <2>: Transforms. (line 46) -* shift <3>: three. (line 483) +* shift <3>: three. (line 499) * shiftless: Transforms. (line 46) * shininess: three. (line 66) * shipout: Frames and pictures. (line 91) -* showtarget: three. (line 375) +* showtarget: three. (line 395) * Si: Mathematical functions. (line 48) * signedint: Files. (line 80) @@ -9993,9 +10199,9 @@ Index * singlereal <1>: Files. (line 93) * sinh: Mathematical functions. (line 6) -* SixViews: three. (line 441) -* SixViewsFR: three. (line 441) -* SixViewsUS: three. (line 441) +* SixViews: three. (line 457) +* SixViewsFR: three. (line 457) +* SixViewsUS: three. (line 457) * size: Figure size. (line 6) * size <1>: Paths and guides. (line 81) * size <2>: Paths and guides. (line 370) @@ -10003,9 +10209,9 @@ Index (line 48) * size <4>: Frames and pictures. (line 74) -* size <5>: three. (line 540) -* size <6>: Options. (line 157) -* size3: three. (line 300) +* size <5>: three. (line 556) +* size <6>: Options. (line 167) +* size3: three. (line 320) * Slant: label. (line 42) * slant: Transforms. (line 38) * sleep: Data types. (line 376) @@ -10021,11 +10227,11 @@ Index (line 48) * solid: Pens. (line 102) * solids: solids. (line 6) -* solve: Arrays. (line 287) -* solve <1>: Arrays. (line 303) -* sort: Arrays. (line 182) -* sort <1>: Arrays. (line 186) -* sort <2>: Arrays. (line 201) +* solve: Arrays. (line 291) +* solve <1>: Arrays. (line 307) +* sort: Arrays. (line 186) +* sort <1>: Arrays. (line 190) +* sort <2>: Arrays. (line 205) * specular: three. (line 76) * specularfactor: three. (line 76) * specularpen: three. (line 66) @@ -10049,7 +10255,7 @@ Index * stop: Debugger. (line 10) * straight: Paths and guides. (line 88) * Straight: graph. (line 30) -* straight <1>: three. (line 540) +* straight <1>: three. (line 556) * strftime: Data types. (line 321) * strftime <1>: Data types. (line 346) * string: Data types. (line 208) @@ -10061,21 +10267,22 @@ Index * struct: Structures. (line 6) * structures: Structures. (line 6) * subpath: Paths and guides. (line 186) -* subpath <1>: three. (line 540) +* subpath <1>: three. (line 556) * subpictures: Frames and pictures. (line 113) * substr: Data types. (line 262) -* sum: Arrays. (line 216) +* sum: Arrays. (line 220) * superpath: Paths. (line 23) * Suppress: Pens. (line 367) * SuppressQuiet: Pens. (line 371) * surface: three. (line 46) -* surface <1>: three. (line 118) -* surface <2>: three. (line 132) -* surface <3>: graph3. (line 99) -* SVG: Options. (line 162) +* surface <1>: three. (line 104) +* surface <2>: three. (line 128) +* surface <3>: three. (line 142) +* surface <4>: graph3. (line 99) +* SVG: Options. (line 172) * system: Data types. (line 354) -* system <1>: Options. (line 182) +* system <1>: Options. (line 192) * syzygy: syzygy. (line 6) * tab: Files. (line 65) * tab completion: Drawing in interactive mode. @@ -10086,22 +10293,22 @@ Index (line 20) * tanh: Mathematical functions. (line 6) -* target: three. (line 375) +* target: three. (line 395) * tell: Files. (line 97) * tension: Bezier curves. (line 56) * tension <1>: three. (line 6) * tensionSpecifier: Paths and guides. (line 402) * tensor product shading: fill. (line 78) * tensorshade: fill. (line 78) -* tessellation: three. (line 144) +* tessellation: three. (line 154) * tex: Frames and pictures. (line 305) -* tex <1>: Options. (line 157) +* tex <1>: Options. (line 167) * TeX fonts: Pens. (line 213) * TeX string: Data types. (line 208) * texcommand: Configuring. (line 74) * TeXHead: draw. (line 26) -* TeXHead3: three. (line 606) +* TeXHead3: three. (line 622) * texpath: Configuring. (line 74) * texpath <1>: label. (line 113) * texpreamble: Frames and pictures. @@ -10111,13 +10318,13 @@ Index * textbook graph: graph. (line 360) * tgz: UNIX binary distributions. (line 6) -* thick: three. (line 156) -* thin: three. (line 156) +* thick: three. (line 166) +* thin: three. (line 166) * this: Structures. (line 6) * three: three. (line 6) -* ThreeViews: three. (line 441) -* ThreeViewsFR: three. (line 441) -* ThreeViewsUS: three. (line 441) +* ThreeViews: three. (line 457) +* ThreeViewsFR: three. (line 457) +* ThreeViewsUS: three. (line 457) * tick: graph. (line 330) * ticks: graph. (line 160) * Ticks: graph. (line 160) @@ -10132,28 +10339,28 @@ Index * times: Paths and guides. (line 220) * times <1>: Paths and guides. (line 224) * Top: graph. (line 135) -* TopView: three. (line 426) +* TopView: three. (line 442) * trace: Debugger. (line 50) * trailingzero: graph. (line 175) * transform: Transforms. (line 6) -* transform <1>: three. (line 515) -* transform3: three. (line 478) +* transform <1>: three. (line 531) +* transform3: three. (line 494) * transparency: Pens. (line 254) * transparent: three. (line 97) -* transpose: Arrays. (line 208) -* transpose <1>: Arrays. (line 211) +* transpose: Arrays. (line 212) +* transpose <1>: Arrays. (line 215) * tree: tree. (line 6) * trembling: trembling. (line 6) * triangle: geometry. (line 6) -* triangles: three. (line 144) -* triangulate: contour. (line 149) -* tridiagonal: Arrays. (line 274) +* triangles: three. (line 154) +* triangulate: contour. (line 192) +* tridiagonal: Arrays. (line 278) * trigonometric integrals: Mathematical functions. (line 48) * triple: Data types. (line 137) * TrueMargin: draw. (line 42) -* TrueMargin3: three. (line 622) -* tube: three. (line 156) +* TrueMargin3: three. (line 638) +* tube: three. (line 166) * tube <1>: tube. (line 6) * tutorial: Tutorial. (line 6) * type1cm: Pens. (line 192) @@ -10167,16 +10374,16 @@ Index (line 165) * UnFill <2>: Frames and pictures. (line 168) -* uniform: Arrays. (line 150) +* uniform: Arrays. (line 154) * uninstall: Uninstall. (line 6) * unique: math. (line 59) * unit: Data types. (line 83) * unit <1>: Data types. (line 174) * unitbox: Paths. (line 44) -* unitbox <1>: three. (line 347) +* unitbox <1>: three. (line 367) * unitcircle: Paths. (line 17) * unitcircle <1>: Paths. (line 17) -* unitcircle <2>: three. (line 315) +* unitcircle <2>: three. (line 335) * unitrand: Mathematical functions. (line 39) * unitsize: Figure size. (line 39) @@ -10186,7 +10393,7 @@ Index (line 6) * unpacking: Rest arguments. (line 39) * unravel: Import. (line 29) -* up: three. (line 375) +* up: three. (line 395) * update: Files. (line 38) * UpsideDown: Frames and pictures. (line 104) @@ -10199,47 +10406,48 @@ Index * user-defined operators: User-defined operators. (line 6) * usleep: Data types. (line 379) +* v3d: three. (line 300) * value: math. (line 34) * value <1>: math. (line 37) * var: Variable initializers. (line 55) * variable initializers: Variable initializers. (line 6) -* vectorfield: graph. (line 1004) -* vectorfield <1>: graph. (line 1043) +* vectorfield: graph. (line 1023) +* vectorfield <1>: graph. (line 1062) * vectorfield3: graph3. (line 157) -* vectorization: Arrays. (line 331) +* vectorization: Arrays. (line 335) * verbatim: Frames and pictures. (line 297) -* vertex-dependent colors: three. (line 109) +* vertex-dependent colors: three. (line 119) * Vertical: flowchart. (line 77) * Viewport: three. (line 76) * viewportheight: LaTeX usage. (line 50) -* viewportmargin: three. (line 303) -* viewportsize: three. (line 303) +* viewportmargin: three. (line 323) +* viewportsize: three. (line 323) * viewportwidth: LaTeX usage. (line 50) -* views: three. (line 272) +* views: three. (line 279) * vim: Editing modes. (line 32) * virtual functions: Structures. (line 182) * void: Data types. (line 10) * W: Labels. (line 18) -* WebGL: three. (line 223) +* WebGL: three. (line 233) * whatever: Paths and guides. (line 246) * Wheel: palette. (line 22) * wheel mouse: GUI. (line 6) * while: Programming. (line 48) * White: three. (line 76) -* white-space string delimiter mode: Arrays. (line 362) +* white-space string delimiter mode: Arrays. (line 366) * width: LaTeX usage. (line 50) * windingnumber: Paths and guides. (line 283) -* word: Arrays. (line 362) +* word: Arrays. (line 366) * write: Files. (line 57) -* write <1>: Arrays. (line 401) -* X: three. (line 315) +* write <1>: Arrays. (line 405) +* X: three. (line 335) * xasy: GUI. (line 6) * xaxis3: graph3. (line 7) * xdr: Files. (line 80) -* xelatex: Options. (line 157) +* xelatex: Options. (line 167) * XEquals: graph. (line 265) * xequals: graph. (line 278) * xlimits: graph. (line 639) @@ -10248,10 +10456,10 @@ Index * xpart: Data types. (line 94) * xpart <1>: Data types. (line 185) * xscale: Transforms. (line 30) -* xscale3: three. (line 485) +* xscale3: three. (line 501) * xtick: graph. (line 330) -* XY: three. (line 500) -* XY <1>: three. (line 515) +* XY: three. (line 516) +* XY <1>: three. (line 531) * XYEquals: graph3. (line 21) * XYZero: graph3. (line 21) * XZEquals: graph3. (line 21) @@ -10261,7 +10469,7 @@ Index (line 6) * Y <1>: Mathematical functions. (line 48) -* Y <2>: three. (line 315) +* Y <2>: three. (line 335) * yaxis3: graph3. (line 7) * YEquals: graph. (line 128) * yequals: graph. (line 278) @@ -10269,14 +10477,14 @@ Index * ypart: Data types. (line 97) * ypart <1>: Data types. (line 188) * yscale: Transforms. (line 32) -* yscale3: three. (line 487) +* yscale3: three. (line 503) * ytick: graph. (line 330) -* YX: three. (line 515) -* YZ: three. (line 515) +* YX: three. (line 531) +* YZ: three. (line 531) * YZEquals: graph3. (line 21) * YZero: graph. (line 123) * YZZero: graph3. (line 21) -* Z: three. (line 315) +* Z: three. (line 335) * zaxis3: graph3. (line 7) * zeroTransform: Transforms. (line 44) * zerowinding: Pens. (line 164) @@ -10293,158 +10501,165 @@ Index * zeta: Mathematical functions. (line 48) * zpart: Data types. (line 191) -* zscale3: three. (line 489) -* ZX: three. (line 515) -* ZX <1>: three. (line 515) -* ZY: three. (line 515) +* zscale3: three. (line 505) +* ZX: three. (line 531) +* ZX <1>: three. (line 531) +* ZY: three. (line 531) Tag Table: Node: Top570 -Node: Description7200 -Node: Installation11286 -Node: UNIX binary distributions12332 -Node: MacOS X binary distributions13455 -Node: Microsoft Windows14043 -Node: Configuring15250 -Node: Search paths19862 -Node: Compiling from UNIX source20870 -Node: Editing modes24021 -Node: Git26443 -Node: Uninstall26950 -Node: Tutorial27296 -Node: Drawing in batch mode28143 -Node: Drawing in interactive mode29019 -Node: Figure size30051 -Node: Labels31646 -Node: Paths32474 -Ref: unitcircle33090 -Node: Drawing commands34988 -Node: draw36796 -Ref: arrows37978 -Node: fill43494 -Ref: gradient shading44540 -Node: clip49154 -Node: label49903 -Ref: Label50503 -Node: Bezier curves56361 -Node: Programming60261 -Ref: array iteration62014 -Node: Data types62181 -Ref: format72949 -Node: Paths and guides77395 -Ref: circle77649 -Ref: extension87349 -Node: Pens94159 -Ref: fillrule101850 -Ref: basealign102754 -Ref: transparency106436 -Ref: makepen110030 -Ref: overwrite110914 -Node: Transforms112128 -Node: Frames and pictures114067 -Ref: envelope115225 -Ref: size116318 -Ref: unitsize117305 -Ref: shipout118378 -Ref: filltype120729 -Ref: add124142 -Ref: add about125084 -Ref: tex128114 -Node: Files129010 -Ref: cd130067 -Ref: scroll134969 -Node: Variable initializers137887 -Node: Structures140604 -Node: Operators148182 -Node: Arithmetic & logical148496 -Node: Self & prefix operators150866 -Node: User-defined operators151660 -Node: Implicit scaling152573 -Node: Functions153136 -Ref: stack overflow156278 -Node: Default arguments156560 -Node: Named arguments157316 -Node: Rest arguments159886 -Node: Mathematical functions163008 -Node: Arrays167665 -Ref: sort174954 -Ref: tridiagonal177865 -Ref: solve179096 -Node: Slices183236 -Node: Casts187144 -Node: Import189414 -Node: Static194995 -Node: LaTeX usage197881 -Node: Base modules204376 -Node: plain206853 -Node: simplex207527 -Node: math207800 -Node: interpolate210383 -Node: geometry210662 -Node: trembling211256 -Node: stats211525 -Node: patterns211784 -Node: markers212019 -Node: map213878 -Node: tree214302 -Node: binarytree214486 -Node: drawtree215153 -Node: syzygy215354 -Node: feynman215628 -Node: roundedpath215902 -Node: animation216184 -Ref: animate216605 -Node: embed217717 -Node: slide218671 -Node: MetaPost219002 -Node: babel219718 -Node: labelpath219950 -Node: labelpath3220770 -Node: annotate221081 -Node: CAD221551 -Node: graph221861 -Ref: ticks229021 -Ref: pathmarkers242746 -Ref: marker243217 -Ref: markuniform243571 -Ref: errorbars245379 -Ref: automatic scaling249858 -Node: palette261573 -Ref: images261691 -Ref: image265865 -Ref: logimage266386 -Ref: penimage267492 -Ref: penfunctionimage267755 -Node: three268527 -Ref: PostScript3D298054 -Node: obj299792 -Node: graph3300041 -Ref: GaussianSurface305324 -Node: grid3306474 -Node: solids307259 -Node: tube308251 -Node: flowchart310481 -Node: contour315124 -Node: contour3320439 -Node: smoothcontour3320751 -Node: slopefield322472 -Node: ode323962 -Node: Options324219 -Ref: configuration file331127 -Ref: settings331127 -Ref: texengines332391 -Ref: convert332391 -Node: Interactive mode335835 -Ref: history337985 -Node: GUI339288 -Node: GUI installation339839 -Node: GUI usage340572 -Node: PostScript to Asymptote341635 -Node: Help342394 -Node: Debugger344068 -Node: Credits345824 -Node: Index346932 +Node: Description7317 +Node: Installation11564 +Node: UNIX binary distributions12610 +Node: MacOS X binary distributions13733 +Node: Microsoft Windows14321 +Node: Configuring15529 +Node: Search paths20142 +Node: Compiling from UNIX source21150 +Node: Editing modes24301 +Node: Git26723 +Node: Uninstall27230 +Node: Tutorial27576 +Node: Drawing in batch mode28423 +Node: Drawing in interactive mode29299 +Node: Figure size30331 +Node: Labels31926 +Node: Paths32754 +Ref: unitcircle33370 +Node: Drawing commands35268 +Node: draw37076 +Ref: arrows38258 +Node: fill43773 +Ref: gradient shading44819 +Node: clip49433 +Node: label50182 +Ref: Label50782 +Node: Bezier curves56639 +Node: Programming60539 +Ref: array iteration62292 +Node: Data types62459 +Ref: format73227 +Node: Paths and guides77673 +Ref: circle77927 +Ref: extension87627 +Node: Pens94437 +Ref: fillrule102128 +Ref: basealign103032 +Ref: transparency106714 +Ref: makepen110308 +Ref: overwrite111192 +Node: Transforms112406 +Node: Frames and pictures114345 +Ref: envelope115503 +Ref: size116596 +Ref: unitsize117583 +Ref: shipout118656 +Ref: filltype121007 +Ref: add124420 +Ref: add about125362 +Ref: tex128392 +Node: Files129287 +Ref: cd130344 +Ref: scroll135246 +Node: Variable initializers138164 +Node: Structures140881 +Node: Operators148454 +Node: Arithmetic & logical148768 +Node: Self & prefix operators151138 +Node: User-defined operators151932 +Node: Implicit scaling152845 +Node: Functions153408 +Ref: stack overflow156525 +Node: Default arguments156807 +Node: Named arguments157563 +Node: Rest arguments160133 +Node: Mathematical functions163254 +Node: Arrays167911 +Ref: sort175350 +Ref: tridiagonal178261 +Ref: solve179492 +Node: Slices183632 +Node: Casts187540 +Node: Import189810 +Node: Static195380 +Node: LaTeX usage198266 +Node: Base modules204780 +Node: plain207257 +Node: simplex207931 +Node: math208204 +Node: interpolate210871 +Node: geometry211150 +Node: trembling211744 +Node: stats212013 +Node: patterns212272 +Node: markers212507 +Node: map214365 +Node: tree214789 +Node: binarytree214969 +Node: drawtree215636 +Node: syzygy215837 +Node: feynman216111 +Node: roundedpath216385 +Node: animation216667 +Ref: animate217088 +Node: embed218200 +Node: slide219154 +Node: MetaPost219485 +Node: babel220201 +Node: labelpath220433 +Node: labelpath3221253 +Node: annotate221564 +Node: CAD222034 +Node: graph222344 +Ref: ticks229503 +Ref: pathmarkers243225 +Ref: marker243695 +Ref: markuniform244049 +Ref: errorbars245908 +Ref: automatic scaling251037 +Node: palette262747 +Ref: images262865 +Ref: image267161 +Ref: logimage267682 +Ref: penimage268788 +Ref: penfunctionimage269051 +Node: three269823 +Ref: PostScript3D300123 +Node: obj301861 +Node: graph3302110 +Ref: GaussianSurface307392 +Node: grid3308542 +Node: solids309327 +Node: tube310319 +Node: flowchart312549 +Node: contour317192 +Node: contour3323700 +Node: smoothcontour3324012 +Node: slopefield325731 +Node: ode327220 +Node: Options327477 +Ref: configuration file335032 +Ref: settings335032 +Ref: texengines336296 +Ref: convert336296 +Node: Interactive mode339739 +Ref: history341888 +Node: GUI343191 +Node: GUI installation343741 +Node: GUI usage344474 +Node: Command-Line Interface345537 +Node: Language server protocol346979 +Node: PostScript to Asymptote348404 +Node: Help349182 +Node: Debugger350856 +Node: Credits352612 +Node: Index353837 End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/Master/texmf-dist/doc/man/man1/asy.1 b/Master/texmf-dist/doc/man/man1/asy.1 index 4ad758ce371..faa77d42b14 100644 --- a/Master/texmf-dist/doc/man/man1/asy.1 +++ b/Master/texmf-dist/doc/man/man1/asy.1 @@ -31,6 +31,12 @@ in the user's home directory using the long form: For a complete description, see the Info files. .TP +.B \-GPUindexing +Compute indexing partial sums on GPU [true]. +.TP +.B \-GPUinterlock +Use fragment shader interlock [true]. +.TP .B \-V,\-View View output; command-line only. .TP @@ -103,12 +109,12 @@ Default output file precision [7]. .B \-divisor n Garbage collect using purge(divisor=n) [2]. .TP +.B \-dvisvgmMultipleFiles +dvisvgm supports multiple files [false]. +.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 @@ -136,9 +142,18 @@ Show summary of options; command-line only. .B \-historylines n Retain n lines of history [1000]. .TP +.B \-ibl +Enable environment map image-based lighting [false]. +.TP .B \-iconify Iconify rendering window [false]. .TP +.B \-image string +Environment image name [snowyField]. +.TP +.B \-imageDir string +Environment image library directory [ibl]. +.TP .B \-inlineimage Generate inline embedded image [false]. .TP @@ -172,6 +187,12 @@ Use a local interactive history file [false]. .B \-loop Loop 3D animations [false]. .TP +.B \-lossy +Use single precision for V3D reals [false]. +.TP +.B \-lsp +Interactive mode for the Language Server Protocol [false]. +.TP .B \-m,\-mask Mask fpu exceptions; command-line only. .TP @@ -215,7 +236,10 @@ Delay before attempting initial pdf reload [750000]. Initial 3D rendering screen position [(0,0)]. .TP .B \-prc -Embed 3D PRC graphics in PDF output [true]. +Embed 3D PRC graphics in PDF output [false]. +.TP +.B \-prerender resolution +Prerender V3D objects (0 implies vector output) [0]. .TP .B \-prompt string Prompt [> ]. @@ -304,11 +328,17 @@ Wait for child processes to finish before exiting [false]. .B \-warn string Enable warning; command-line only. .TP +.B \-webgl2 +Use webgl2 if available [false]. +.TP .B \-where Show where listed variables are declared [false]. .TP +.B \-wsl +Run asy under the Windows Subsystem for Linux. [false]. +.TP .B \-xasy -Special interactive mode for xasy [false]. +Interactive mode for xasy [false]. .TP .B \-zoomPinchCap limit WebGL maximum zoom pinch [100]. diff --git a/Master/texmf-dist/doc/man/man1/asy.man1.pdf b/Master/texmf-dist/doc/man/man1/asy.man1.pdf Binary files differindex 5ad06c4775f..673db6f0a48 100644 --- a/Master/texmf-dist/doc/man/man1/asy.man1.pdf +++ b/Master/texmf-dist/doc/man/man1/asy.man1.pdf diff --git a/Master/texmf-dist/doc/man/man1/twill.man1.pdf b/Master/texmf-dist/doc/man/man1/twill.man1.pdf Binary files differnew file mode 100644 index 00000000000..fdfd6f9b516 --- /dev/null +++ b/Master/texmf-dist/doc/man/man1/twill.man1.pdf diff --git a/Master/texmf-dist/doc/man/man1/xasy.man1.pdf b/Master/texmf-dist/doc/man/man1/xasy.man1.pdf Binary files differindex 04d738b3e24..17a722d8967 100644 --- a/Master/texmf-dist/doc/man/man1/xasy.man1.pdf +++ b/Master/texmf-dist/doc/man/man1/xasy.man1.pdf diff --git a/Master/texmf-dist/tex/latex/asymptote/asymptote.sty b/Master/texmf-dist/tex/latex/asymptote/asymptote.sty index 17a05d68a3a..2deb265a80c 100644 --- a/Master/texmf-dist/tex/latex/asymptote/asymptote.sty +++ b/Master/texmf-dist/tex/latex/asymptote/asymptote.sty @@ -17,7 +17,7 @@ %% Licence: GPL2+ %% \ProvidesPackage{asymptote} - [2021/02/06 v1.36 Asymptote style file for LaTeX] + [2021/12/29 v1.37 Asymptote style file for LaTeX] \def\Asymptote{{\tt Asymptote}} \InputIfFileExists{\jobname.pre}{}{} \newbox\ASYbox @@ -31,7 +31,7 @@ \ASYkeepAspecttrue \RequirePackage{keyval} \RequirePackage{ifthen} -\RequirePackage{color,graphicx} +\RequirePackage{graphicx} \IfFileExists{ifpdf.sty}{ \RequirePackage{ifpdf} }{ diff --git a/Master/tlpkg/asymptote/asy.exe b/Master/tlpkg/asymptote/asy.exe Binary files differindex e40288876f2..94f141cfbfd 100755 --- a/Master/tlpkg/asymptote/asy.exe +++ b/Master/tlpkg/asymptote/asy.exe diff --git a/Master/tlpkg/asymptote64/asy.exe b/Master/tlpkg/asymptote64/asy.exe Binary files differindex 58f2216ff61..ea4a3360aee 100755 --- a/Master/tlpkg/asymptote64/asy.exe +++ b/Master/tlpkg/asymptote64/asy.exe |