diff --git a/src/Mod/Arch/InitGui.py b/src/Mod/Arch/InitGui.py index aadf378e0..afce48544 100644 --- a/src/Mod/Arch/InitGui.py +++ b/src/Mod/Arch/InitGui.py @@ -93,7 +93,7 @@ class ArchWorkbench(Workbench): "Draft_SelectGroup","Draft_SelectPlane", "Draft_ShowSnapBar","Draft_ToggleGrid","Draft_UndoLine", "Draft_FinishLine","Draft_CloseLine"] - self.draftutils = ["Draft_Heal"] + self.draftutils = ["Draft_Heal","Draft_FlipDimension"] self.snapList = ['Draft_Snap_Lock','Draft_Snap_Midpoint','Draft_Snap_Perpendicular', 'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel', 'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center', diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 5f4890700..e2e4c1605 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -83,6 +83,8 @@ if FreeCAD.GuiUp: else: print "FreeCAD Gui not present. Draft module will have some features disabled." gui = False + +arrowtypes = ["Dot","Circle","Arrow"] #--------------------------------------------------------------------------- # General functions @@ -100,12 +102,12 @@ def typecheck (args_and_types, name="?"): def getParamType(param): if param in ["dimsymbol","dimPrecision","dimorientation","precision","defaultWP", "snapRange","gridEvery","linewidth","UiMode","modconstrain","modsnap", - "modalt","HatchPatternResolution","snapStyle"]: + "modalt","HatchPatternResolution","snapStyle","dimstyle"]: return "int" elif param in ["constructiongroupname","textfont","patternFile","template","maxSnapEdges", "snapModes","FontFile"]: return "string" - elif param in ["textheight","tolerance","gridSpacing"]: + elif param in ["textheight","tolerance","gridSpacing","arrowsize","extlines","dimspacing"]: return "float" elif param in ["selectBaseObjects","alwaysSnap","grid","fillmode","saveonexit","maxSnap", "SvgLinesBlack","dxfStdSize","showSnapBar","hideSnapBar","alwaysShowGrid", @@ -141,7 +143,8 @@ def getParam(param,default=None): if default == None: default = 0 return p.GetUnsigned(param,default) - else: return None + else: + return None def setParam(param,value): "setParam(parameterName,value): sets a Draft parameter with the given value" @@ -243,24 +246,32 @@ def ungroup(obj): if grp.hasObject(obj): grp.removeObject(obj) -def dimSymbol(): +def dimSymbol(symbol=None,invert=False): "returns the current dim symbol from the preferences as a pivy SoMarkerSet" - s = getParam("dimsymbol",0) + if symbol == None: + symbol = getParam("dimsymbol",0) from pivy import coin - marker = coin.SoMarkerSet() - if s == 0: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_5_5 - elif s == 1: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_7_7 - elif s == 2: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9 - elif s == 3: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_5_5 - elif s == 4: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_7_7 - elif s == 5: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9 - elif s == 6: marker.markerIndex = coin.SoMarkerSet.SLASH_5_5 - elif s == 7: marker.markerIndex = coin.SoMarkerSet.SLASH_7_7 - elif s == 8: marker.markerIndex = coin.SoMarkerSet.SLASH_9_9 - elif s == 9: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_5_5 - elif s == 10: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_7_7 - elif s == 11: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_9_9 - return marker + if symbol == 1: + marker = coin.SoMarkerSet() + marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9 + return marker + elif symbol == 2: + marker = coin.SoSeparator() + t = coin.SoTransform() + t.translation.setValue((0,-2,0)) + t.center.setValue((0,2,0)) + if invert: + t.rotation.setValue(coin.SbVec3f((0,0,1)),-math.pi/2) + else: + t.rotation.setValue(coin.SbVec3f((0,0,1)),math.pi/2) + c = coin.SoCone() + c.height.setValue(4) + marker.addChild(t) + marker.addChild(c) + return marker + elif symbol == 3: + print "Draft.dimsymbol: Not implemented" + return coin.SoSphere() def shapify(obj): '''shapify(object): transforms a parametric shape object into @@ -615,8 +626,11 @@ def makeDimension(p1,p2,p3=None,p4=None): p3.multiply(0.5) p3 = p1.add(p3) elif isinstance(p2,int) and isinstance(p3,int): - obj.Base = p1 - obj.LinkedVertices = idx = [p2,p3] + l = [] + l.append((p1,"Vertex"+str(p2+1))) + l.append((p1,"Vertex"+str(p3+1))) + obj.LinkedGeometry = l + obj.Support = p1 p3 = p4 if not p3: v1 = obj.Base.Shape.Vertexes[idx[0]].Point @@ -625,25 +639,38 @@ def makeDimension(p1,p2,p3=None,p4=None): p3.multiply(0.5) p3 = v1.add(p3) elif isinstance(p3,str): - obj.Base = p1 + l = [] + l.append((p1,"Edge"+str(p2+1))) if p3 == "radius": - obj.LinkedVertices = [p2,1,1] - obj.ViewObject.Override = "R$dim" + l.append((p1,"Center")) + obj.ViewObject.Override = "R $dim" elif p3 == "diameter": - obj.LinkedVertices = [p2,2,1] - obj.ViewObject.Override = "Ø$dim" + l.append((p1,"Diameter")) + obj.ViewObject.Override = "D $dim" + obj.LinkedGeometry = l + obj.Support = p1 p3 = p4 if not p3: - p3 = obj.Base.Shape.Edges[0].Curve.Center.add(Vector(1,0,0)) + p3 = p1.Shape.Edges[p2].Curve.Center.add(Vector(1,0,0)) obj.Dimline = p3 + if hasattr(FreeCAD,"DraftWorkingPlane"): + normal = FreeCAD.DraftWorkingPlane.axis + else: + normal = App.Vector(0,0,1) + if gui: + # invert the normal if we are viewing it from the back + vnorm = get3DView().getViewDirection() + if vnorm.getAngle(normal) < math.pi/2: + normal = normal.negative() + obj.Normal = normal if gui: formatObject(obj) select(obj) FreeCAD.ActiveDocument.recompute() return obj -def makeAngularDimension(center,angles,p3): - '''makeAngularDimension(center,[angle1,angle2],p3): creates an angular Dimension +def makeAngularDimension(center,angles,p3,normal=None): + '''makeAngularDimension(center,angle1,angle2,p3,[normal]): creates an angular Dimension from the given center, with the given list of angles, passing through p3. ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","Dimension") @@ -655,6 +682,17 @@ def makeAngularDimension(center,angles,p3): obj.FirstAngle = math.degrees(angles[1]) obj.LastAngle = math.degrees(angles[0]) obj.Dimline = p3 + if not normal: + if hasattr(FreeCAD,"DraftWorkingPlane"): + normal = FreeCAD.DraftWorkingPlane.axis + else: + normal = Vector(0,0,1) + if gui: + # invert the normal if we are viewing it from the back + vnorm = get3DView().getViewDirection() + if vnorm.getAngle(normal) < math.pi/2: + normal = normal.negative() + obj.Normal = normal if gui: _ViewProviderAngularDimension(obj.ViewObject) formatObject(obj) @@ -678,6 +716,8 @@ def makeWire(pointslist,closed=False,placement=None,face=True,support=None): if DraftGeomUtils.isReallyClosed(pointslist): closed = True pointslist = nlist + if len(pointslist) == 0: + print "Invalid input points: ",pointslist #print pointslist #print closed if placement: typecheck([(placement,FreeCAD.Placement)], "makeWire") @@ -854,7 +894,10 @@ def makeCopy(obj,force=None,reparent=False): for p in obj.PropertiesList: if not p in ["Proxy"]: if p in newobj.PropertiesList: - setattr(newobj,p,obj.getPropertyByName(p)) + try: + setattr(newobj,p,obj.getPropertyByName(p)) + except: + pass if reparent: parents = obj.InList if parents: @@ -865,6 +908,7 @@ def makeCopy(obj,force=None,reparent=False): for prop in par.PropertiesList: if getattr(par,prop) == obj: setattr(par,prop,newobj) + FreeCAD.ActiveDocument.recompute() formatObject(newobj,obj) return newobj @@ -1378,7 +1422,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct svg = "" linewidth = linewidth/scale fontsize = (fontsize/scale)/2 - pointratio = 4 # the number of times the dots are smaller than the font size + pointratio = .75 # the number of times the dots are smaller than the arrow size plane = None if direction: if isinstance(direction,FreeCAD.Vector): @@ -1415,7 +1459,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct def getPath(edges=[],wires=[]): import DraftGeomUtils - svg ='= math.pi/2: - angle = angle-math.pi - tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),angle)) - svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' ' - svg += 'L '+str(p2.x)+' '+str(p2.y)+' ' - svg += 'L '+str(p3.x)+' '+str(p3.y)+' ' - svg += 'L '+str(p4.x)+' '+str(p4.y)+'" ' - else: - angle = 0 - tbase = tbase.add(Vector(0,-2/scale,0)) - svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' ' - svg += 'L '+str(p2.x)+' '+str(p2.y)+' ' - svg += 'L '+str(p2a.x)+' '+str(p2a.y)+' ' - svg += 'M '+str(p2b.x)+' '+str(p2b.y)+' ' - svg += 'L '+str(p3.x)+' '+str(p3.y)+' ' - svg += 'L '+str(p4.x)+' '+str(p4.y)+'" ' - svg += 'fill="none" stroke="' - svg += getrgb(obj.ViewObject.LineColor) + '" ' - svg += 'stroke-width="' + str(linewidth) + ' px" ' - svg += 'style="stroke-width:'+ str(linewidth) - svg += ';stroke-miterlimit:4;stroke-dasharray:none" ' - svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" ' - svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" ' - svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"' - svg += '/>\n' - svg += ' math.pi/2: + tangle = tangle-math.pi + elif (tangle <= -math.pi/2) or (tangle > math.pi/2): + tangle = tangle+math.pi + tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle)) + svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' ' + svg += 'L '+str(p2.x)+' '+str(p2.y)+' ' + svg += 'L '+str(p3.x)+' '+str(p3.y)+' ' + svg += 'L '+str(p4.x)+' '+str(p4.y)+'" ' + else: + tangle = 0 + tbase = tbase.add(Vector(0,-2/scale,0)) + svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' ' + svg += 'L '+str(p2.x)+' '+str(p2.y)+' ' + svg += 'L '+str(p2a.x)+' '+str(p2a.y)+' ' + svg += 'M '+str(p2b.x)+' '+str(p2b.y)+' ' + svg += 'L '+str(p3.x)+' '+str(p3.y)+' ' + svg += 'L '+str(p4.x)+' '+str(p4.y)+'" ' + + svg += 'fill="none" stroke="' + svg += getrgb(obj.ViewObject.LineColor) + '" ' + svg += 'stroke-width="' + str(linewidth) + ' px" ' + svg += 'style="stroke-width:'+ str(linewidth) + svg += ';stroke-miterlimit:4;stroke-dasharray:none" ' + svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" ' + svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" ' + svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"' + svg += '/>\n' + + # drawing arrows + if hasattr(obj.ViewObject,"ArrowType"): + arrowsize = obj.ViewObject.ArrowSize/pointratio + if hasattr(obj.ViewObject,"FlipArrows"): + if obj.ViewObject.FlipArrows: + angle = angle+math.pi + svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,obj.ViewObject.LineColor,linewidth,angle) + svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,obj.ViewObject.LineColor,linewidth,angle+math.pi) + + # drawing text + svg += getText(obj.ViewObject.LineColor,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string) + + elif getType(obj) == "AngularDimension": + if obj.ViewObject.Proxy: + if hasattr(obj.ViewObject.Proxy,"circle"): + prx = obj.ViewObject.Proxy + + # drawing arc + fill= "none" + stroke = getrgb(obj.ViewObject.LineColor) + lstyle = getLineStyle() + if obj.ViewObject.DisplayMode == "2D": + svg += getPath([prx.circle]) + else: + if hasattr(prx,"circle1"): + svg += getPath([prx.circle1]) + svg += getPath([prx.circle2]) + else: + svg += getPath([prx.circle]) + + # drawing arrows + if hasattr(obj.ViewObject,"ArrowType"): + p2 = getProj(prx.p2) + p3 = getProj(prx.p3) + arrowsize = obj.ViewObject.ArrowSize/pointratio + arrowlength = 4*obj.ViewObject.ArrowSize + u1 = getProj((prx.circle.valueAt(prx.circle.FirstParameter+arrowlength)).sub(prx.circle.valueAt(prx.circle.FirstParameter))) + u2 = getProj((prx.circle.valueAt(prx.circle.LastParameter-arrowlength)).sub(prx.circle.valueAt(prx.circle.LastParameter))) + angle1 = -DraftVecUtils.angle(u1) + angle2 = -DraftVecUtils.angle(u2) + if hasattr(obj.ViewObject,"FlipArrows"): + if obj.ViewObject.FlipArrows: + angle1 = angle1+math.pi + angle2 = angle2+math.pi + svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,obj.ViewObject.LineColor,linewidth,angle1) + svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,obj.ViewObject.LineColor,linewidth,angle2) + + # drawing text + if obj.ViewObject.DisplayMode == "2D": + t = prx.circle.tangentAt(prx.circle.FirstParameter+(prx.circle.LastParameter-prx.circle.FirstParameter)/2) + t = getProj(t) + tangle = DraftVecUtils.angle(t) + if (tangle <= -math.pi/2) or (tangle > math.pi/2): + tangle = tangle + math.pi + tbase = getProj(prx.circle.valueAt(prx.circle.FirstParameter+(prx.circle.LastParameter-prx.circle.FirstParameter)/2)) + tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle)) + print tbase + else: + tangle = 0 + tbase = getProj(prx.tbase) + svg += getText(obj.ViewObject.LineColor,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string) elif getType(obj) == "Annotation": "returns an svg representation of a document annotation" @@ -1581,7 +1711,6 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct "returns the SVG representation of an Arch Axis system" color = getrgb(obj.ViewObject.LineColor) lorig = getLineStyle() - name = obj.Name stroke = getrgb(obj.ViewObject.LineColor) fill = 'none' invpl = obj.Placement.inverse() @@ -1618,9 +1747,13 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct # setting fill if obj.Shape.Faces: if gui: - if (obj.ViewObject.DisplayMode != "Wireframe"): + try: + m = obj.ViewObject.DisplayMode + except: + m = None + if (m != "Wireframe"): if fillstyle == "shape color": - fill = getrgb(obj.ViewObject.ShapeColor) + fill = getrgb(obj.ViewObject.ShapeColor,testbw=False) else: fill = 'url(#'+fillstyle+')' svg += getPattern(fillstyle) @@ -1631,10 +1764,13 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct else: fill = 'none' lstyle = getLineStyle() - name = obj.Name if gui: try: - if obj.ViewObject.DisplayMode == "Shaded": + try: + m = obj.ViewObject.DisplayMode + except: + m = None + if m == "Shaded": stroke = "none" else: stroke = getrgb(obj.ViewObject.LineColor) @@ -2635,7 +2771,7 @@ class _ViewProviderDraftPart(_ViewProviderDraftAlt): def getIcon(self): return ":/icons/Tree_Part.svg" - + class _Dimension(_DraftObject): "The Draft Dimension object" def __init__(self, obj): @@ -2644,111 +2780,86 @@ class _Dimension(_DraftObject): "Startpoint of dimension") obj.addProperty("App::PropertyVector","End","Draft", "Endpoint of dimension") + obj.addProperty("App::PropertyVector","Normal","Draft", + "the normal direction of this dimension") obj.addProperty("App::PropertyVector","Dimline","Draft", "Point through which the dimension line passes") - obj.addProperty("App::PropertyLink","Base","Draft", - "The base object this dimension is linked to") - obj.addProperty("App::PropertyIntegerList","LinkedVertices","Draft", - "The indices of the vertices from the base object to measure") + obj.addProperty("App::PropertyLink","Support","Draft", + "The object measured by this dimension") + obj.addProperty("App::PropertyLinkSubList","LinkedGeometry","Draft", + "The geometry this dimension is linked to") obj.addProperty("App::PropertyLength","Distance","Draft","The measurement of this dimension") obj.Start = FreeCAD.Vector(0,0,0) obj.End = FreeCAD.Vector(1,0,0) obj.Dimline = FreeCAD.Vector(0,1,0) - - def onChanged(self, obj, prop): + + def onChanged(self,obj,prop): obj.setEditorMode('Distance',1) - + obj.setEditorMode('Normal',2) + obj.setEditorMode('Support',2) + def execute(self, obj): + if obj.LinkedGeometry: + if "Edge" in obj.LinkedGeometry[0][1]: + n = int(obj.LinkedGeometry[0][1][4:])-1 + if len(obj.LinkedGeometry) > 1: + c = obj.LinkedGeometry[0][0].Shape.Edges[n].Curve.Center + r = obj.LinkedGeometry[0][0].Shape.Edges[n].Curve.Radius + ray = DraftVecUtils.scaleTo(obj.Dimline.sub(c),r) + if "Center" in obj.LinkedGeometry[1][1]: + obj.Start = c + obj.End = c.add(ray) + elif "Diameter" in obj.LinkedGeometry[1][1]: + obj.Start = c.add(ray.negative()) + obj.End = c.add(ray) + else: + obj.Start = obj.LinkedGeometry[0][0].Shape.Edges[n].Vertexes[0].Point + obj.End = obj.LinkedGeometry[0][0].Shape.Edges[n].Vertexes[-1].Point + elif "Vertex" in obj.LinkedGeometry[0][1]: + n = int(obj.LinkedGeometry[0][1][6:])-1 + obj.Start = obj.LinkedGeometry[0][0].Shape.Vertexes[n].Point + if len(obj.LinkedGeometry) > 1: + if "Vertex" in obj.LinkedGeometry[1][1]: + n = int(obj.LinkedGeometry[1][1][6:])-1 + obj.End = obj.LinkedGeometry[1][0].Shape.Vertexes[n].Point if obj.ViewObject: obj.ViewObject.update() - + + class _ViewProviderDimension(_ViewProviderDraft): "A View Provider for the Draft Dimension object" def __init__(self, obj): obj.addProperty("App::PropertyLength","FontSize","Draft","Font size") + obj.addProperty("App::PropertyLength","ArrowSize","Draft","Arrow size") + obj.addProperty("App::PropertyLength","TextSpacing","Draft","The spacing between the text and the dimension line") + obj.addProperty("App::PropertyEnumeration","ArrowType","Draft","Arrow type") obj.addProperty("App::PropertyString","FontName","Draft","Font name") obj.addProperty("App::PropertyLength","LineWidth","Draft","Line width") obj.addProperty("App::PropertyColor","LineColor","Draft","Line color") - obj.addProperty("App::PropertyLength","ExtLines","Draft","Ext lines") + obj.addProperty("App::PropertyLength","ExtLines","Draft","Length of the extension lines") + obj.addProperty("App::PropertyBool","FlipArrows","Draft","Rotate the dimension arrows 180 degrees") obj.addProperty("App::PropertyVector","TextPosition","Draft","The position of the text. Leave (0,0,0) for automatic position") obj.addProperty("App::PropertyString","Override","Draft","Text override. Use $dim to insert the dimension length") obj.FontSize=getParam("textheight",0.20) + obj.TextSpacing=getParam("dimspacing",0.05) obj.FontName=getParam("textfont","") - obj.ExtLines=0.3 - obj.Override = '' + obj.ArrowSize = getParam("arrowsize",0.1) + obj.ArrowType = arrowtypes + obj.ArrowType = arrowtypes[getParam("dimsymbol",0)] + obj.ExtLines = getParam("extlines",0.3) _ViewProviderDraft.__init__(self,obj) - def calcGeom(self,obj): - import Part, DraftGeomUtils + def attach(self, vobj): + "called on object creation" from pivy import coin - p1 = obj.Start - p4 = obj.End - base = Part.Line(p1,p4).toShape() - proj = DraftGeomUtils.findDistance(obj.Dimline,base) - if not proj: - p2 = p1 - p3 = p4 - else: - p2 = p1.add(proj.negative()) - p3 = p4.add(proj.negative()) - dmax = obj.ViewObject.ExtLines - if dmax and (proj.Length > dmax): - p1 = p2.add(DraftVecUtils.scaleTo(proj,dmax)) - p4 = p3.add(DraftVecUtils.scaleTo(proj,dmax)) - midpoint = p2.add((p3.sub(p2).multiply(0.5))) - if not proj: - ed = DraftGeomUtils.vec(base) - proj = ed.cross(Vector(0,0,1)) - if not proj: norm = Vector(0,0,1) - else: norm = (p3.sub(p2).cross(proj)).negative() - if not DraftVecUtils.isNull(norm): - norm.normalize() - va = get3DView().getViewDirection() - if va.getAngle(norm) < math.pi/2: - norm = norm.negative() - u = p3.sub(p2) - u.normalize() - c = get3DView().getCameraNode() - r = c.orientation.getValue() - ru = Vector(r.multVec(coin.SbVec3f(1,0,0)).getValue()) - if ru.getAngle(u) > math.pi/2: u = u.negative() - v = norm.cross(u) - offset = DraftVecUtils.scaleTo(v,obj.ViewObject.FontSize*.2) - if obj.ViewObject: - if hasattr(obj.ViewObject,"DisplayMode"): - if obj.ViewObject.DisplayMode == "3D": - offset = offset.negative() - if hasattr(obj.ViewObject,"TextPosition"): - if obj.ViewObject.TextPosition == Vector(0,0,0): - tbase = midpoint.add(offset) - else: - tbase = obj.ViewObject.TextPosition - else: - tbase = midpoint.add(offset) - else: - tbase = midpoint - rot = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u,v,norm)).Rotation.Q - return p1,p2,p3,p4,tbase,norm,rot - - def attach(self, obj): - from pivy import coin - self.Object = obj.Object - p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj.Object) + self.Object = vobj.Object self.color = coin.SoBaseColor() - self.color.rgb.setValue(obj.LineColor[0], - obj.LineColor[1], - obj.LineColor[2]) self.font = coin.SoFont() self.font3d = coin.SoFont() self.text = coin.SoAsciiText() self.text3d = coin.SoText2() - self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER - self.text.string = self.text3d.string = '' self.textpos = coin.SoTransform() - self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z]) - tm = DraftVecUtils.getPlaneRotation(p3.sub(p2),norm) - rm = coin.SbRotation() - self.textpos.rotation = rm + self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER label = coin.SoSeparator() label.addChild(self.textpos) label.addChild(self.color) @@ -2760,200 +2871,246 @@ class _ViewProviderDimension(_ViewProviderDraft): label3d.addChild(self.font3d) label3d.addChild(self.text3d) self.coord1 = coin.SoCoordinate3() - self.coord1.point.setValue((p2.x,p2.y,p2.z)) + self.trans1 = coin.SoTransform() self.coord2 = coin.SoCoordinate3() - self.coord2.point.setValue((p3.x,p3.y,p3.z)) - marks = coin.SoAnnotation() - marks.addChild(self.color) - marks.addChild(self.coord1) - marks.addChild(dimSymbol()) - marks.addChild(self.coord2) - marks.addChild(dimSymbol()) - self.drawstyle = coin.SoDrawStyle() - self.drawstyle.lineWidth = 1 - self.line = coin.SoLineSet() + self.trans2 = coin.SoTransform() + self.marks = coin.SoSeparator() + self.drawstyle = coin.SoDrawStyle() + self.line = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.coords = coin.SoCoordinate3() - selnode=coin.SoType.fromName("SoFCSelection").createInstance() - selnode.documentName.setValue(FreeCAD.ActiveDocument.Name) - selnode.objectName.setValue(obj.Object.Name) - selnode.subElementName.setValue("Line") - selnode.addChild(self.line) self.node = coin.SoGroup() self.node.addChild(self.color) self.node.addChild(self.drawstyle) self.node.addChild(self.coords) - self.node.addChild(selnode) - self.node.addChild(marks) + self.node.addChild(self.line) + self.node.addChild(self.marks) self.node.addChild(label) self.node3d = coin.SoGroup() self.node3d.addChild(self.color) self.node3d.addChild(self.drawstyle) self.node3d.addChild(self.coords) - self.node3d.addChild(selnode) - self.node3d.addChild(marks) + self.node3d.addChild(self.line) + self.node3d.addChild(self.marks) self.node3d.addChild(label3d) - obj.addDisplayMode(self.node,"2D") - obj.addDisplayMode(self.node3d,"3D") - self.onChanged(obj,"FontSize") - self.onChanged(obj,"FontName") + vobj.addDisplayMode(self.node,"2D") + vobj.addDisplayMode(self.node3d,"3D") + self.updateData(vobj.Object,"Start") + self.onChanged(vobj,"FontSize") + self.onChanged(vobj,"FontName") + self.onChanged(vobj,"ArrowType") + self.onChanged(vobj,"LineColor") def updateData(self, obj, prop): - if not prop in ["Start","End","Dimline","DisplayMode","ExtLines","FontSize","Override"]: - return - from pivy import coin - try: - dm = obj.ViewObject.DisplayMode - except: - dm = "2D" - text = None - if obj.Base and obj.LinkedVertices: - if "Shape" in obj.Base.PropertiesList: - if len(obj.LinkedVertices) == 3: - # arc linked dimension - e = obj.Base.Shape.Edges[obj.LinkedVertices[0]] - c = e.Curve.Center - bray = DraftVecUtils.scaleTo(obj.Dimline.sub(c),e.Curve.Radius) - if obj.LinkedVertices[1] == 1: - v1 = c - else: - v1 = c.add(bray.negative()) - v2 = c.add(bray) - else: - # linear linked dimension - v1 = obj.Base.Shape.Vertexes[obj.LinkedVertices[0]].Point - v2 = obj.Base.Shape.Vertexes[obj.LinkedVertices[1]].Point - if v1 != obj.Start: obj.Start = v1 - if v2 != obj.End: obj.End = v2 - p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj) - # print p1,p2,p3,p4,tbase,norm,rot - if 'Override' in obj.ViewObject.PropertiesList: - text = unicode(obj.ViewObject.Override).encode("latin1") - dtext = getParam("dimPrecision",2) - dtext = "%."+str(dtext)+"f" - dtext = (dtext % p3.sub(p2).Length) - if text: - text = text.replace("$dim",dtext) - else: - text = dtext - if hasattr(self,"text"): - self.text.string = self.text3d.string = text - self.textpos.rotation = coin.SbRotation(rot[0],rot[1],rot[2],rot[3]) - self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z]) - if dm == "2D": - self.coords.point.setValues([[p1.x,p1.y,p1.z], - [p2.x,p2.y,p2.z], - [p3.x,p3.y,p3.z], - [p4.x,p4.y,p4.z]]) - self.line.numVertices.setValue(4) + "called when the base object is changed" + if prop in ["Start","End","Dimline"]: + + if obj.Start == obj.End: + return + + if not hasattr(self,"node"): + return + + import Part, DraftGeomUtils + from pivy import coin + + # calculate the 4 points + self.p1 = obj.Start + self.p4 = obj.End + base = Part.Line(self.p1,self.p4).toShape() + proj = DraftGeomUtils.findDistance(obj.Dimline,base) + if proj: + self.p2 = self.p1.add(proj.negative()) + self.p3 = self.p4.add(proj.negative()) + dmax = obj.ViewObject.ExtLines + if dmax and (proj.Length > dmax): + self.p1 = self.p2.add(DraftVecUtils.scaleTo(proj,dmax)) + self.p4 = self.p3.add(DraftVecUtils.scaleTo(proj,dmax)) else: - ts = (len(text)*obj.ViewObject.FontSize)/4 - rm = ((p3.sub(p2)).Length/2)-ts - p2a = p2.add(DraftVecUtils.scaleTo(p3.sub(p2),rm)) - p2b = p3.add(DraftVecUtils.scaleTo(p2.sub(p3),rm)) - self.coords.point.setValues([[p1.x,p1.y,p1.z], - [p2.x,p2.y,p2.z], - [p2a.x,p2a.y,p2a.z], - [p2b.x,p2b.y,p2b.z], - [p3.x,p3.y,p3.z], - [p4.x,p4.y,p4.z]]) - self.line.numVertices.setValues([3,3]) - self.coord1.point.setValue((p2.x,p2.y,p2.z)) - self.coord2.point.setValue((p3.x,p3.y,p3.z)) - if hasattr(obj,"Distance"): - l = p3.sub(p2).Length + self.p2 = self.p1 + self.p3 = self.p4 + proj = (self.p3.sub(self.p2)).cross(Vector(0,0,1)) + + # calculate the arrows positions + self.trans1.translation.setValue((self.p2.x,self.p2.y,self.p2.z)) + self.coord1.point.setValue((self.p2.x,self.p2.y,self.p2.z)) + self.trans2.translation.setValue((self.p3.x,self.p3.y,self.p3.z)) + self.coord2.point.setValue((self.p3.x,self.p3.y,self.p3.z)) + + # calculate the text position and orientation + if DraftVecUtils.isNull(obj.Normal): + if not proj: + norm = Vector(0,0,1) + else: + norm = (self.p3.sub(self.p2).cross(proj)).negative() + else: + norm = obj.Normal + if not DraftVecUtils.isNull(norm): + norm.normalize() + u = self.p3.sub(self.p2) + u.normalize() + v1 = norm.cross(u) + rot1 = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u,v1,norm)).Rotation.Q + if hasattr(obj.ViewObject,"FlipArrows"): + if obj.ViewObject.FlipArrows: + u = u.negative() + v2 = norm.cross(u) + rot2 = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u,v2,norm)).Rotation.Q + self.trans1.rotation.setValue((rot2[0],rot2[1],rot2[2],rot2[3])) + self.trans2.rotation.setValue((rot2[0],rot2[1],rot2[2],rot2[3])) + if hasattr(obj.ViewObject,"TextSpacing"): + offset = DraftVecUtils.scaleTo(v1,obj.ViewObject.TextSpacing) + else: + offset = DraftVecUtils.scaleTo(v1,0.05) + + # setting text + try: + m = obj.ViewObject.DisplayMode + except: + m = ["2D","3D"][getParam("dimstyle",0)] + if m== "3D": + offset = offset.negative() + tbase = (self.p2.add((self.p3.sub(self.p2).multiply(0.5)))).add(offset) + if hasattr(obj.ViewObject,"TextPosition"): + if not DraftVecUtils.isNull(obj.ViewObject.TextPosition): + tbase = obj.ViewObject.TextPosition + self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z]) + self.textpos.rotation = coin.SbRotation(rot1[0],rot1[1],rot1[2],rot1[3]) + + # set text value + l = self.p3.sub(self.p2).Length + fstring = "%." + str(getParam("dimPrecision",2)) + "f" + self.string = (fstring % l) + if obj.ViewObject.Override: + self.string = unicode(obj.ViewObject.Override).encode("latin1").replace("$dim",self.string) + self.text.string = self.text3d.string = self.string + + # set the distance property if round(obj.Distance,precision()) != round(l,precision()): obj.Distance = l + + # set the lines + if m == "3D": + # calculate the spacing of the text + textsize = (len(self.string)*obj.ViewObject.FontSize)/4 + spacing = ((self.p3.sub(self.p2)).Length/2) - textsize + self.p2a = self.p2.add(DraftVecUtils.scaleTo(self.p3.sub(self.p2),spacing)) + self.p2b = self.p3.add(DraftVecUtils.scaleTo(self.p2.sub(self.p3),spacing)) + self.coords.point.setValues([[self.p1.x,self.p1.y,self.p1.z], + [self.p2.x,self.p2.y,self.p2.z], + [self.p2a.x,self.p2a.y,self.p2a.z], + [self.p2b.x,self.p2b.y,self.p2b.z], + [self.p3.x,self.p3.y,self.p3.z], + [self.p4.x,self.p4.y,self.p4.z]]) + #self.line.numVertices.setValues([3,3]) + self.line.coordIndex.setValues(0,7,(0,1,2,-1,3,4,5)) + else: + self.coords.point.setValues([[self.p1.x,self.p1.y,self.p1.z], + [self.p2.x,self.p2.y,self.p2.z], + [self.p3.x,self.p3.y,self.p3.z], + [self.p4.x,self.p4.y,self.p4.z]]) + #self.line.numVertices.setValue(4) + self.line.coordIndex.setValues(0,4,(0,1,2,3)) - def onChanged(self, vp, prop): - self.Object = vp.Object - if prop == "FontSize": + def onChanged(self, vobj, prop): + "called when a view property has changed" + + if prop in ["ExtLines","TextSpacing","DisplayMode","Override","FlipArrows"]: + self.updateData(vobj.Object,"Start") + elif prop == "FontSize": if hasattr(self,"font"): - self.font.size = vp.FontSize + self.font.size = vobj.FontSize if hasattr(self,"font3d"): - self.font3d.size = vp.FontSize*100 - self.updateData(vp.Object, prop) + self.font3d.size = vobj.FontSize*100 elif prop == "FontName": if hasattr(self,"font") and hasattr(self,"font3d"): - self.font.name = self.font3d.name = str(vp.FontName) + self.font.name = self.font3d.name = str(vobj.FontName) elif prop == "LineColor": - c = vp.LineColor if hasattr(self,"color"): + c = vobj.LineColor self.color.rgb.setValue(c[0],c[1],c[2]) elif prop == "LineWidth": if hasattr(self,"drawstyle"): - self.drawstyle.lineWidth = vp.LineWidth - else: - if hasattr(self,"drawstyle"): - self.drawstyle.lineWidth = vp.LineWidth - self.updateData(vp.Object, prop) + self.drawstyle.lineWidth = vobj.LineWidth + elif prop in ["ArrowSize","ArrowType"]: + if hasattr(self,"node") and hasattr(self,"p2"): + from pivy import coin + + if not hasattr(vobj,"ArrowType"): + return + + if self.p3.x < self.p2.x: + inv = False + else: + inv = True + + # set scale + symbol = arrowtypes.index(vobj.ArrowType) + s = vobj.ArrowSize + self.trans1.scaleFactor.setValue((s,s,s)) + self.trans2.scaleFactor.setValue((s,s,s)) + + # remove existing nodes + self.node.removeChild(self.marks) + self.node3d.removeChild(self.marks) + + # set new nodes + self.marks = coin.SoSeparator() + self.marks.addChild(self.color) + s1 = coin.SoSeparator() + if symbol == "Circle": + s1.addChild(self.coord1) + else: + s1.addChild(self.trans1) + s1.addChild(dimSymbol(symbol,invert=not(inv))) + self.marks.addChild(s1) + s2 = coin.SoSeparator() + if symbol == "Circle": + s2.addChild(self.coord2) + else: + s2.addChild(self.trans2) + s2.addChild(dimSymbol(symbol,invert=inv)) + self.marks.addChild(s2) + self.node.insertChild(self.marks,2) + self.node3d.insertChild(self.marks,2) - def getDisplayModes(self,obj): + def getDisplayModes(self,vobj): return ["2D","3D"] def getDefaultDisplayMode(self): if hasattr(self,"defaultmode"): return self.defaultmode else: - return "2D" + return ["2D","3D"][getParam("dimstyle",0)] def setDisplayMode(self,mode): return mode def getIcon(self): - if self.Object.Base: - return """ - /* XPM */ - static char * dim_xpm[] = { - "16 16 6 1", - " c None", - ". c #000000", - "+ c #FFFF00", - "@ c #FFFFFF", - "$ c #141010", - "# c #615BD2", - " $$$$$$$$", - " $##$$#$$", - " . $##$$##$", - " .. $##$$##$", - " .+. $######$", - " .++. $##$$##$", - " .+++. .$##$$##$", - ".++++. .$######$", - " .+++. .$$$$$$$$" - " .++. .++. ", - " .+. .+. ", - " .. .. ", - " . . ", - " ", - " ", - " "}; - """ - else: - return """ - /* XPM */ - static char * dim_xpm[] = { - "16 16 4 1", - " c None", - ". c #000000", - "+ c #FFFF00", - "@ c #FFFFFF", - " ", - " ", - " . . ", - " .. .. ", - " .+. .+. ", - " .++. .++. ", - " .+++. .. .+++. ", - ".++++. .. .++++.", - " .+++. .. .+++. ", - " .++. .++. ", - " .+. .+. ", - " .. .. ", - " . . ", - " ", - " ", - " "}; - """ + return """ + /* XPM */ + static char * dim_xpm[] = { + "16 16 4 1", + " c None", + ". c #000000", + "+ c #FFFF00", + "@ c #FFFFFF", + " ", + " ", + " . . ", + " .. .. ", + " .+. .+. ", + " .++. .++. ", + " .+++. .. .+++. ", + ".++++. .. .++++.", + " .+++. .. .+++. ", + " .++. .++. ", + " .+. .+. ", + " .. .. ", + " . . ", + " ", + " ", + " "}; + """ def __getstate__(self): return self.Object.ViewObject.DisplayMode @@ -2975,11 +3132,23 @@ class _AngularDimension(_DraftObject): "Point through which the dimension line passes") obj.addProperty("App::PropertyVector","Center","Draft", "The center point of this dimension") + obj.addProperty("App::PropertyVector","Normal","Draft", + "The normal direction of this dimension") + obj.addProperty("App::PropertyLink","Support","Draft", + "The object measured by this dimension") + obj.addProperty("App::PropertyLinkSubList","LinkedGeometry","Draft", + "The geometry this dimension is linked to") + obj.addProperty("App::PropertyAngle","Angle","Draft","The measurement of this dimension") obj.FirstAngle = 0 obj.LastAngle = 90 obj.Dimline = FreeCAD.Vector(0,1,0) obj.Center = FreeCAD.Vector(0,0,0) + def onChanged(self,obj,prop): + obj.setEditorMode('Angle',1) + obj.setEditorMode('Normal',2) + obj.setEditorMode('Support',2) + def execute(self, fp): if fp.ViewObject: fp.ViewObject.update() @@ -2989,33 +3158,34 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): def __init__(self, obj): obj.addProperty("App::PropertyLength","FontSize","Draft","Font size") obj.addProperty("App::PropertyString","FontName","Draft","Font name") + obj.addProperty("App::PropertyLength","ArrowSize","Draft","Arrow size") + obj.addProperty("App::PropertyLength","TextSpacing","Draft","The spacing between the text and the dimension line") + obj.addProperty("App::PropertyEnumeration","ArrowType","Draft","Arrow type") obj.addProperty("App::PropertyLength","LineWidth","Draft","Line width") obj.addProperty("App::PropertyColor","LineColor","Draft","Line color") + obj.addProperty("App::PropertyBool","FlipArrows","Draft","Rotate the dimension arrows 180 degrees") obj.addProperty("App::PropertyVector","TextPosition","Draft","The position of the text. Leave (0,0,0) for automatic position") obj.addProperty("App::PropertyString","Override","Draft","Text override. Use 'dim' to insert the dimension length") obj.FontSize=getParam("textheight",0.20) obj.FontName=getParam("textfont","") + obj.TextSpacing=getParam("dimspacing",0.05) + obj.ArrowSize = getParam("arrowsize",0.1) + obj.ArrowType = arrowtypes + obj.ArrowType = arrowtypes[getParam("dimsymbol",0)] obj.Override = '' _ViewProviderDraft.__init__(self,obj) def attach(self, vobj): from pivy import coin self.Object = vobj.Object - self.arc = None - c,tbase,trot,p2,p3 = self.calcGeom(vobj.Object) self.color = coin.SoBaseColor() - self.color.rgb.setValue(vobj.LineColor[0], - vobj.LineColor[1], - vobj.LineColor[2]) + self.color.rgb.setValue(vobj.LineColor[0],vobj.LineColor[1],vobj.LineColor[2]) self.font = coin.SoFont() self.font3d = coin.SoFont() self.text = coin.SoAsciiText() self.text3d = coin.SoText2() self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER - self.text.string = self.text3d.string = '' self.textpos = coin.SoTransform() - self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z]) - self.textpos.rotation = coin.SbRotation() label = coin.SoSeparator() label.addChild(self.textpos) label.addChild(self.color) @@ -3027,111 +3197,205 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): label3d.addChild(self.font3d) label3d.addChild(self.text3d) self.coord1 = coin.SoCoordinate3() - self.coord1.point.setValue((p2.x,p2.y,p2.z)) + self.trans1 = coin.SoTransform() self.coord2 = coin.SoCoordinate3() - self.coord2.point.setValue((p3.x,p3.y,p3.z)) - marks = coin.SoAnnotation() - marks.addChild(self.color) - marks.addChild(self.coord1) - marks.addChild(dimSymbol()) - marks.addChild(self.coord2) - marks.addChild(dimSymbol()) - self.drawstyle = coin.SoDrawStyle() - self.drawstyle.lineWidth = 1 + self.trans2 = coin.SoTransform() + self.marks = coin.SoSeparator() + self.drawstyle = coin.SoDrawStyle() self.coords = coin.SoCoordinate3() - self.selnode=coin.SoType.fromName("SoFCSelection").createInstance() - self.selnode.documentName.setValue(FreeCAD.ActiveDocument.Name) - self.selnode.objectName.setValue(vobj.Object.Name) - self.selnode.subElementName.setValue("Arc") + self.arc = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.node = coin.SoGroup() self.node.addChild(self.color) self.node.addChild(self.drawstyle) self.node.addChild(self.coords) - self.node.addChild(self.selnode) - self.node.addChild(marks) + self.node.addChild(self.arc) + self.node.addChild(self.marks) self.node.addChild(label) self.node3d = coin.SoGroup() self.node3d.addChild(self.color) self.node3d.addChild(self.drawstyle) self.node3d.addChild(self.coords) - self.node3d.addChild(self.selnode) - self.node3d.addChild(marks) + self.node3d.addChild(self.arc) + self.node3d.addChild(self.marks) self.node3d.addChild(label3d) vobj.addDisplayMode(self.node,"2D") vobj.addDisplayMode(self.node3d,"3D") + self.updateData(vobj.Object,None) self.onChanged(vobj,"FontSize") self.onChanged(vobj,"FontName") - - def calcGeom(self,obj): - import Part, DraftGeomUtils - rad = (obj.Dimline.sub(obj.Center)).Length - cir = Part.makeCircle(rad,obj.Center,Vector(0,0,1),obj.FirstAngle,obj.LastAngle) - cp = DraftGeomUtils.findMidpoint(cir.Edges[0]) - rv = cp.sub(obj.Center) - rv = DraftVecUtils.scaleTo(rv,rv.Length + obj.ViewObject.FontSize*.2) - tbase = obj.Center.add(rv) - trot = DraftVecUtils.angle(rv)-math.pi/2 - if (trot > math.pi/2) or (trot < -math.pi/2): - trot = trot + math.pi - s = getParam("dimorientation",0) - if s == 0: - if round(trot,precision()) == round(-math.pi/2,precision()): - trot = math.pi/2 - return cir, tbase, trot, cir.Vertexes[0].Point, cir.Vertexes[-1].Point + self.onChanged(vobj,"ArrowType") + self.onChanged(vobj,"LineColor") def updateData(self, obj, prop): - from pivy import coin - text = None - ivob = None - c,tbase,trot,p2,p3 = self.calcGeom(obj) - buf=c.writeInventor(2,0.01) - ivin = coin.SoInput() - ivin.setBuffer(buf) - ivob = coin.SoDB.readAll(ivin) - arc = ivob.getChildren()[1] - # In case reading from buffer failed - if ivob and ivob.getNumChildren() > 1: - arc = ivob.getChild(1).getChild(0) - arc.removeChild(arc.getChild(0)) - arc.removeChild(arc.getChild(0)) - if self.arc: - self.selnode.removeChild(self.arc) - self.arc = arc - self.selnode.addChild(self.arc) - if 'Override' in obj.ViewObject.PropertiesList: - text = unicode(obj.ViewObject.Override).encode("latin1") - dtext = getParam("dimPrecision",2) - dtext = "%."+str(dtext)+"f" - if obj.LastAngle > obj.FirstAngle: - dtext = (dtext % (obj.LastAngle-obj.FirstAngle))+'\xb0' - else: - dtext = (dtext % ((360-obj.FirstAngle)+obj.LastAngle))+'\xb0' - if text: - text = text.replace("dim",dtext) - else: - text = dtext - self.text.string = self.text3d.string = text - self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z]) - m = FreeCAD.Matrix() - m.rotateZ(trot) - tm = FreeCAD.Placement(m).Rotation.Q - self.textpos.rotation = coin.SbRotation(tm[0],tm[1],tm[2],tm[3]) - self.coord1.point.setValue((p2.x,p2.y,p2.z)) - self.coord2.point.setValue((p3.x,p3.y,p3.z)) + if hasattr(self,"arc"): + from pivy import coin + import Part, DraftGeomUtils + text = None + ivob = None + arcsegs = 24 + + # calculate the arc data + if DraftVecUtils.isNull(obj.Normal): + norm = Vector(0,0,1) + else: + norm = obj.Normal + radius = (obj.Dimline.sub(obj.Center)).Length + self.circle = Part.makeCircle(radius,obj.Center,norm,obj.FirstAngle,obj.LastAngle) + self.p2 = self.circle.Vertexes[0].Point + self.p3 = self.circle.Vertexes[-1].Point + mp = DraftGeomUtils.findMidpoint(self.circle.Edges[0]) + ray = mp.sub(obj.Center) + + # set text value + if obj.LastAngle > obj.FirstAngle: + a = obj.LastAngle - obj.FirstAngle + else: + a = (360 - obj.FirstAngle) + obj.LastAngle + fstring = "%." + str(getParam("dimPrecision",2)) + "f" + self.string = (fstring % a) + self.string += " d" + if obj.ViewObject.Override: + self.string = unicode(obj.ViewObject.Override).encode("latin1").replace("$dim",self.string) + self.text.string = self.text3d.string = self.string + + # check display mode + try: + m = obj.ViewObject.DisplayMode + except: + m = ["2D","3D"][getParam("dimstyle",0)] + + # set the arc + if m == "3D": + # calculate the spacing of the text + spacing = (len(self.string)*obj.ViewObject.FontSize)/8 + pts1 = [] + cut = None + pts2 = [] + for i in range(arcsegs+1): + p = self.circle.valueAt(self.circle.FirstParameter+((self.circle.LastParameter-self.circle.FirstParameter)/arcsegs)*i) + if (p.sub(mp)).Length <= spacing: + if cut == None: + cut = i + else: + if cut == None: + pts1.append([p.x,p.y,p.z]) + else: + pts2.append([p.x,p.y,p.z]) + self.coords.point.setValues(pts1+pts2) + i1 = len(pts1) + i2 = i1+len(pts2) + self.arc.coordIndex.setValues(0,len(pts1)+len(pts2)+1,range(len(pts1))+[-1]+range(i1,i2)) + if (len(pts1) >= 3) and (len(pts2) >= 3): + self.circle1 = Part.Arc(Vector(pts1[0][0],pts1[0][1],pts1[0][2]),Vector(pts1[1][0],pts1[1][1],pts1[1][2]),Vector(pts1[-1][0],pts1[-1][1],pts1[-1][2])).toShape() + self.circle2 = Part.Arc(Vector(pts2[0][0],pts2[0][1],pts2[0][2]),Vector(pts2[1][0],pts2[1][1],pts2[1][2]),Vector(pts2[-1][0],pts2[-1][1],pts2[-1][2])).toShape() + else: + pts = [] + for i in range(arcsegs+1): + p = self.circle.valueAt(self.circle.FirstParameter+((self.circle.LastParameter-self.circle.FirstParameter)/arcsegs)*i) + pts.append([p.x,p.y,p.z]) + self.coords.point.setValues(pts) + self.arc.coordIndex.setValues(0,arcsegs+1,range(arcsegs+1)) + + # set the arrow coords and rotation + self.trans1.translation.setValue((self.p2.x,self.p2.y,self.p2.z)) + self.coord1.point.setValue((self.p2.x,self.p2.y,self.p2.z)) + self.trans2.translation.setValue((self.p3.x,self.p3.y,self.p3.z)) + self.coord2.point.setValue((self.p3.x,self.p3.y,self.p3.z)) + # calculate small chords to make arrows look better + arrowlength = 4*obj.ViewObject.ArrowSize + u1 = (self.circle.valueAt(self.circle.FirstParameter+arrowlength)).sub(self.circle.valueAt(self.circle.FirstParameter)).normalize() + u2 = (self.circle.valueAt(self.circle.LastParameter)).sub(self.circle.valueAt(self.circle.LastParameter-arrowlength)).normalize() + if hasattr(obj.ViewObject,"FlipArrows"): + if obj.ViewObject.FlipArrows: + u1 = u1.negative() + u2 = u2.negative() + w2 = self.circle.Curve.Axis + w1 = w2.negative() + v1 = w1.cross(u1) + v2 = w2.cross(u2) + q1 = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u1,v1,w1)).Rotation.Q + q2 = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u2,v2,w2)).Rotation.Q + self.trans1.rotation.setValue((q1[0],q1[1],q1[2],q1[3])) + self.trans2.rotation.setValue((q2[0],q2[1],q2[2],q2[3])) + + # setting text pos & rot + self.tbase = mp + if hasattr(obj.ViewObject,"TextPosition"): + if not DraftVecUtils.isNull(obj.ViewObject.TextPosition): + self.tbase = obj.ViewObject.TextPosition + + u3 = ray.cross(norm).normalize() + v3 = norm.cross(u3) + r = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u3,v3,norm)).Rotation + offset = r.multVec(Vector(0,1,0)) + + if hasattr(obj.ViewObject,"TextSpacing"): + offset = DraftVecUtils.scaleTo(offset,obj.ViewObject.TextSpacing) + else: + offset = DraftVecUtils.scaleTo(offset,0.05) + if m == "3D": + offset = offset.negative() + self.tbase = self.tbase.add(offset) + q = r.Q + self.textpos.translation.setValue([self.tbase.x,self.tbase.y,self.tbase.z]) + self.textpos.rotation = coin.SbRotation(q[0],q[1],q[2],q[3]) + + # set the angle property + if round(obj.Angle,precision()) != round(a,precision()): + obj.Angle = a def onChanged(self, vobj, prop): if prop == "FontSize": - self.font.size = vobj.FontSize - self.font3d.size = vobj.FontSize*100 + if hasattr(self,"font"): + self.font.size = vobj.FontSize + if hasattr(self,"font3d"): + self.font3d.size = vobj.FontSize*100 elif prop == "FontName": - self.font.name = self.font3d.name = str(vobj.FontName) + if hasattr(self,"font") and hasattr(self,"font3d"): + self.font.name = self.font3d.name = str(vobj.FontName) elif prop == "LineColor": - c = vobj.LineColor - self.color.rgb.setValue(c[0],c[1],c[2]) + if hasattr(self,"color"): + c = vobj.LineColor + self.color.rgb.setValue(c[0],c[1],c[2]) elif prop == "LineWidth": - self.drawstyle.lineWidth = vobj.LineWidth - elif prop == "DisplayMode": - pass + if hasattr(self,"drawstyle"): + self.drawstyle.lineWidth = vobj.LineWidth + elif prop in ["ArrowSize","ArrowType"]: + if hasattr(self,"node") and hasattr(self,"p2"): + from pivy import coin + + if not hasattr(vobj,"ArrowType"): + return + + # set scale + symbol = arrowtypes.index(vobj.ArrowType) + s = vobj.ArrowSize + self.trans1.scaleFactor.setValue((s,s,s)) + self.trans2.scaleFactor.setValue((s,s,s)) + + # remove existing nodes + self.node.removeChild(self.marks) + self.node3d.removeChild(self.marks) + + # set new nodes + self.marks = coin.SoSeparator() + self.marks.addChild(self.color) + s1 = coin.SoSeparator() + if symbol == "Circle": + s1.addChild(self.coord1) + else: + s1.addChild(self.trans1) + s1.addChild(dimSymbol(symbol,invert=False)) + self.marks.addChild(s1) + s2 = coin.SoSeparator() + if symbol == "Circle": + s2.addChild(self.coord2) + else: + s2.addChild(self.trans2) + s2.addChild(dimSymbol(symbol,invert=True)) + self.marks.addChild(s2) + self.node.insertChild(self.marks,2) + self.node3d.insertChild(self.marks,2) else: self.updateData(vobj.Object, None) @@ -3141,7 +3405,10 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): return modes def getDefaultDisplayMode(self): - return "2D" + if hasattr(self,"defaultmode"): + return self.defaultmode + else: + return ["2D","3D"][getParam("dimstyle",0)] def getIcon(self): return """ @@ -3170,6 +3437,15 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): " "}; """ + def __getstate__(self): + return self.Object.ViewObject.DisplayMode + + def __setstate__(self,state): + if state: + self.defaultmode = state + self.setDisplayMode(state) + + class _Rectangle(_DraftObject): "The Rectangle object" @@ -3417,7 +3693,7 @@ class _ViewProviderWire(_ViewProviderDraft): obj.LineColor[1], obj.LineColor[2]) self.coords = coin.SoCoordinate3() - self.pt = coin.SoAnnotation() + self.pt = coin.SoSeparator() self.pt.addChild(col) self.pt.addChild(self.coords) self.pt.addChild(dimSymbol()) diff --git a/src/Mod/Draft/DraftSnap.py b/src/Mod/Draft/DraftSnap.py index 9d68cdcce..6710901a8 100644 --- a/src/Mod/Draft/DraftSnap.py +++ b/src/Mod/Draft/DraftSnap.py @@ -860,6 +860,9 @@ class Snapper: self.selectMode = mode if not mode: self.setCursor() + else: + if self.trackLine: + self.trackLine.off() def setAngle(self): "keeps the current angle" diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index b3068b5f3..93fc43110 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1566,9 +1566,15 @@ class Dimension(Creator): def createObject(self): "creates an object in the current doc" if self.angledata: + normal = "None" + if len(self.edges) == 2: + import DraftGeomUtils + v1 = DraftGeomUtils.vec(self.edges[0]) + v2 = DraftGeomUtils.vec(self.edges[1]) + normal = DraftVecUtils.toString((v1.cross(v2)).normalize()) self.commit(translate("draft","Create Dimension"), ['import Draft', - 'Draft.makeAngularDimension(center='+DraftVecUtils.toString(self.center)+',angles=['+str(self.angledata[0])+','+str(self.angledata[1])+'],p3='+DraftVecUtils.toString(self.node[-1])+')']) + 'Draft.makeAngularDimension(center='+DraftVecUtils.toString(self.center)+',angles=['+str(self.angledata[0])+','+str(self.angledata[1])+'],p3='+DraftVecUtils.toString(self.node[-1])+',normal='+normal+')']) elif self.link and (not self.arcmode): self.commit(translate("draft","Create Dimension"), ['import Draft', @@ -1609,6 +1615,8 @@ class Dimension(Creator): if not self.altdown: self.altdown = True self.ui.switchUi(True) + if hasattr(FreeCADGui,"Snapper"): + FreeCADGui.Snapper.setSelectMode(True) snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1])) if snapped: ob = self.doc.getObject(snapped['Object']) @@ -1637,6 +1645,8 @@ class Dimension(Creator): if self.altdown: self.altdown = False self.ui.switchUi(False) + if hasattr(FreeCADGui,"Snapper"): + FreeCADGui.Snapper.setSelectMode(False) if self.dir: self.point = self.node[0].add(DraftVecUtils.project(self.point.sub(self.node[0]),self.dir)) if len(self.node) == 2: @@ -1731,7 +1741,8 @@ class Dimension(Creator): self.link = [self.link[0],ob] else: msg(translate("draft", "Edges don't intersect!\n")) - self.finish() + self.finish() + return self.dimtrack.on() else: self.node.append(self.point) @@ -2972,8 +2983,10 @@ class Drawing(Modifier): for obj in sel: if obj.ViewObject.isVisible(): name = 'View'+obj.Name - oldobj = self.page.getObject(name) - if oldobj: self.doc.removeObject(oldobj.Name) + # no reason to remove the old one... + #oldobj = self.page.getObject(name) + #if oldobj: + # self.doc.removeObject(oldobj.Name) Draft.makeDrawingView(obj,self.page) self.doc.recompute() @@ -3772,6 +3785,20 @@ class Draft_Facebinder(Creator): FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() self.finish() + +class Draft_FlipDimension(): + def GetResources(self): + return {'Pixmap' : 'Draft_FlipDimension', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_FlipDimension", "Flip Dimension"), + 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_FlipDimension", "Flip the normal direction of a dimension")} + + def Activated(self): + for o in FreeCADGui.Selection.getSelection(): + if Draft.getType(o) in ["Dimension","AngularDimension"]: + FreeCAD.ActiveDocument.openTransaction("Flip dimension") + FreeCADGui.doCommand("FreeCAD.ActiveDocument."+o.Name+".Normal = FreeCAD.ActiveDocument."+o.Name+".Normal.negative()") + FreeCAD.ActiveDocument.commitTransaction() + FreeCAD.ActiveDocument.recompute() #--------------------------------------------------------------------------- @@ -3982,6 +4009,7 @@ FreeCADGui.addCommand('Draft_SelectGroup',SelectGroup()) FreeCADGui.addCommand('Draft_Shape2DView',Shape2DView()) FreeCADGui.addCommand('Draft_ShowSnapBar',ShowSnapBar()) FreeCADGui.addCommand('Draft_ToggleGrid',ToggleGrid()) +FreeCADGui.addCommand('Draft_FlipDimension',Draft_FlipDimension()) # snap commands FreeCADGui.addCommand('Draft_Snap_Lock',Draft_Snap_Lock()) diff --git a/src/Mod/Draft/DraftTrackers.py b/src/Mod/Draft/DraftTrackers.py index 27d34ac91..10c9f6e34 100644 --- a/src/Mod/Draft/DraftTrackers.py +++ b/src/Mod/Draft/DraftTrackers.py @@ -29,6 +29,7 @@ import FreeCAD,FreeCADGui,math,Draft, DraftVecUtils from FreeCAD import Vector from pivy import coin + class Tracker: "A generic Draft Tracker, to be used by other specific trackers" def __init__(self,dotted=False,scolor=None,swidth=None,children=[],ontop=False): @@ -348,15 +349,25 @@ class bsplineTracker(Tracker): class arcTracker(Tracker): "An arc tracker" - def __init__(self,dotted=False,scolor=None,swidth=None,start=0,end=math.pi*2): + def __init__(self,dotted=False,scolor=None,swidth=None,start=0,end=math.pi*2,normal=None): self.circle = None self.startangle = math.degrees(start) self.endangle = math.degrees(end) self.trans = coin.SoTransform() self.trans.translation.setValue([0,0,0]) self.sep = coin.SoSeparator() + if normal: + self.normal = normal + else: + self.normal = FreeCAD.DraftWorkingPlane.axis + self.basevector = self.getDeviation() self.recompute() Tracker.__init__(self,dotted,scolor,swidth,[self.trans, self.sep]) + + def getDeviation(self): + "returns a deviation vector that represents the base of the circle" + c = Part.makeCircle(1,Vector(0,0,0),self.normal) + return c.Vertexes[0].Point def setCenter(self,cen): "sets the center point" @@ -384,9 +395,10 @@ class arcTracker(Tracker): "returns the angle of a given vector" c = self.trans.translation.getValue() center = Vector(c[0],c[1],c[2]) - base = FreeCAD.DraftWorkingPlane.u rad = pt.sub(center) - return(DraftVecUtils.angle(rad,base,FreeCAD.DraftWorkingPlane.axis)) + a = DraftVecUtils.angle(rad,self.basevector,self.normal) + #print a + return(a) def getAngles(self): "returns the start and end angles" @@ -408,12 +420,13 @@ class arcTracker(Tracker): def recompute(self): import Part,re - if self.circle: self.sep.removeChild(self.circle) + if self.circle: + self.sep.removeChild(self.circle) self.circle = None - if self.endangle < self.startangle: - c = Part.makeCircle(1,Vector(0,0,0),FreeCAD.DraftWorkingPlane.axis,self.endangle,self.startangle) + if (self.endangle < self.startangle): + c = Part.makeCircle(1,Vector(0,0,0),self.normal,self.endangle,self.startangle) else: - c = Part.makeCircle(1,Vector(0,0,0),FreeCAD.DraftWorkingPlane.axis,self.startangle,self.endangle) + c = Part.makeCircle(1,Vector(0,0,0),self.normal,self.startangle,self.endangle) buf=c.writeInventor(2,0.01) try: ivin = coin.SoInput() diff --git a/src/Mod/Draft/DraftVecUtils.py b/src/Mod/Draft/DraftVecUtils.py index 4edf02875..2b15d9df0 100644 --- a/src/Mod/Draft/DraftVecUtils.py +++ b/src/Mod/Draft/DraftVecUtils.py @@ -145,6 +145,14 @@ def rotate(u,angle,axis=Vector(0,0,1)): xzt - ys, yzt + xs, c + z*z*t, 0) return m.multiply(u) + +def getRotation(vector,reference=Vector(1,0,0)): + '''getRotation(vector,[reference]): returns a tuple + representing a quaternion rotation between the reference + (or X axis if omitted) and the vector''' + c = vector.cross(reference) + c.normalize() + return (c.x,c.y,c.z,math.sqrt((vector.Length ** 2) * (reference.Length ** 2)) + vector.dot(reference)) def isNull(vector): '''isNull(vector): Tests if a vector is nul vector''' diff --git a/src/Mod/Draft/Draft_rc.py b/src/Mod/Draft/Draft_rc.py index 1c9331051..3558b8e59 100644 --- a/src/Mod/Draft/Draft_rc.py +++ b/src/Mod/Draft/Draft_rc.py @@ -2,8 +2,8 @@ # Resource object code # -# Created: Fri Oct 11 10:47:50 2013 -# by: The Resource Compiler for PyQt (Qt v4.8.5) +# Created: Mon Nov 11 13:33:06 2013 +# by: The Resource Compiler for PyQt (Qt v4.8.6) # # WARNING! All changes made in this file will be lost! @@ -41485,181 +41485,192 @@ qt_resource_data = "\ \x00\x6c\x00\x6b\x00\x79\x08\x00\x00\x00\x00\x06\x00\x00\x00\x11\ \x64\x72\x61\x66\x74\x20\x43\x6f\x6d\x6d\x61\x6e\x64\x20\x42\x61\ \x72\x07\x00\x00\x00\x05\x64\x72\x61\x66\x74\x01\ -\x00\x00\x0a\xcc\ +\x00\x00\x0b\x7f\ \x00\ -\x00\x67\xf8\x78\x9c\xed\x5d\x5b\x6f\xdb\xb8\x12\x7e\xcf\xaf\x20\ -\xfc\x50\xec\x01\xb2\xf1\xa5\xb9\xb6\x8e\x17\x4d\x7a\x49\x81\x16\ -\xdb\xad\xb3\xdd\xc7\x05\x2d\xd1\x36\x4f\x25\xd1\x25\xa9\x38\x5e\ -\x9c\x1f\x7f\x86\x17\x59\x17\xcb\xb2\x65\xd9\x56\x9a\x75\x80\xc0\ -\x12\x49\x0d\x47\xc3\x99\x8f\x33\x43\xd2\xee\xfe\xf6\xe8\x7b\xe8\ -\x81\x70\x41\x59\x70\xdd\x68\x9f\xb4\x1a\x88\x04\x0e\x73\x69\x30\ -\xba\x6e\xfc\x79\xff\xfe\xd7\xcb\xc6\x6f\xbd\xa3\x6e\x48\xe3\x46\ -\xa7\xd0\xa8\x77\x84\xba\x8e\x87\x85\xe8\x7d\x08\xe9\xab\x57\x6f\ -\x29\xf6\xd8\x08\x3e\xbd\x51\x9f\x48\x09\x0f\x8b\xb7\x1c\x0f\x65\ -\xb7\x69\x1a\x41\xeb\x29\x75\x47\x44\x22\x7d\x7f\xdd\xf8\xe3\x2f\ -\x7d\xdb\x40\x01\xf6\xc9\x75\xa3\x90\x88\xea\x0c\x75\x27\x9c\x4d\ -\x08\x97\x33\xfb\xc4\x88\x30\x9f\x48\x3e\xd3\x95\xa8\xcb\x89\x23\ -\xf5\x15\xea\x3e\xf6\x5a\xdd\xe6\xa3\xbd\x99\xa9\x9b\x99\xbd\x01\ -\x16\xe4\xb8\x77\xf6\xf2\xa2\xdb\x34\x97\xa6\x78\x4c\xe8\x68\x2c\ -\x7b\x17\xad\x4e\xb7\x69\xaf\x35\xcd\x66\x44\xb4\xdb\x8c\x3a\xcf\ -\xe3\x64\x4a\x03\x97\x4d\xef\xa9\xf4\x88\x65\x46\x48\x0e\xcc\xf7\ -\xbe\x51\x11\x62\x0f\x09\xfb\x2e\xdd\xa6\x2d\x5f\xa4\xe8\xe1\x19\ -\x0b\x63\xd9\x7c\xbb\x61\x8f\x9f\x74\x91\x25\x98\xe9\x51\x4c\xb0\ -\x03\x84\x1a\x96\xff\x20\xf4\x07\x84\xf7\xce\xbb\x4d\x7b\x65\xb8\ -\x4f\xf6\xb0\x40\xc2\xc7\x7c\x44\x83\x0c\x85\xab\x42\x0a\x54\x12\ -\x3f\x16\x64\x72\x2c\x3f\x70\x16\x4e\x80\xe7\x68\x34\x47\xd1\xbd\ -\x69\xbe\xd0\xb9\x8c\x65\xb5\x28\xae\x7e\x8e\xb8\x16\xb9\x29\x14\ -\x9a\xed\x06\x14\x56\x52\x07\x7b\xa6\xf4\xef\x4e\xdc\x63\xfc\x2a\ -\x39\x84\xee\x16\x08\x8d\x19\xa7\xff\xb0\x40\xe6\x90\xca\x12\x5b\ -\x14\xce\x27\x3c\x20\x5e\x44\xc9\x53\x37\xa9\xc7\x73\xa4\x43\x1e\ -\x65\xaa\xc1\x5c\x42\x6f\xc9\x10\x87\x9e\x44\x1e\x0d\x08\x72\x98\ -\xc7\x78\x46\x48\xf9\x92\x32\x85\x86\xad\x04\xdf\xcd\x34\xe3\x0b\ -\xef\xa1\xb4\x8c\xf0\x05\x11\xf4\x75\x71\xe1\x1b\x40\x5b\x02\x4d\ -\x25\xa0\x45\xe6\x45\x08\xe8\x57\xef\x0f\xf9\xea\xd5\xdd\x9c\x5e\ -\xb7\xa9\x0b\x57\xbd\xc0\xa2\x11\xd0\x7f\xc8\x1d\x0d\x60\x90\x84\ -\x74\xc1\xc6\xae\x1b\xad\xac\xd4\xa0\x45\xaa\x24\x42\x80\xd3\x56\ -\x0a\x00\xe6\xb5\xd6\xf8\x3b\xad\x14\x0e\xc4\x6c\x65\x09\x2e\x91\ -\xb4\x11\x5c\x09\x49\xa7\x35\x46\x63\xe1\x17\x4e\x86\xb7\x6a\x84\ -\x6f\x42\x29\x41\x8c\x91\x65\xa9\xba\x09\xd4\xe9\xd1\x1f\x98\xba\ -\x42\x65\x62\xcc\xbb\xa7\x93\x7c\x7d\x92\x63\x82\x5c\xab\x53\x9a\ -\x20\x1a\xc2\x7f\x40\xa6\x88\x0d\xfe\x0b\xd8\x97\xb5\xc1\x12\xa3\ -\xa3\xc9\x65\x7a\xd5\x65\x19\x91\x73\xe2\x2a\x84\x56\x1f\xe9\x8a\ -\x11\x27\x24\x50\x55\xe6\x22\x5d\x39\xf0\x42\xa2\xea\xf4\x67\x7a\ -\x8c\x16\x3a\x59\x8f\x5f\x25\xd3\x77\x81\x9a\x4f\x96\xaa\x93\x63\ -\x65\x61\x0d\xcf\xd9\x54\x34\xaa\xab\x2f\x58\x8e\x57\xf7\xf4\x99\ -\xb9\xcd\x68\x1a\xdd\x96\x9d\x77\x9b\x06\xee\xe6\x58\x98\xaa\xae\ -\x8c\x8c\x17\xd5\x90\xf1\xe5\x36\x90\x51\x9b\x76\x6d\xc8\xb8\x02\ -\xdd\x0f\xd8\xb8\x15\x6c\xec\x4f\x68\x90\xf4\x38\x22\x5c\x14\x50\ -\x3e\x88\x3d\x8f\x5c\xe9\xac\x8d\x89\x4a\x9b\xb4\x2c\xb6\x87\x8b\ -\x0f\x18\x20\x2b\xd3\xb3\xf5\xb9\x3a\x29\xef\xab\x14\xd5\x12\xe8\ -\x35\x7f\xa7\x03\x82\xe5\x23\xd8\xcb\x6a\x08\x76\xba\x21\x82\xf5\ -\x03\x3c\x41\x62\xe6\x0f\x98\x27\x40\xac\x33\x8f\xec\x12\xc1\x96\ -\x7a\x1c\xd0\x7f\x9e\x59\x39\xaa\x02\xec\x6a\x05\xb8\xf9\x34\xa0\ -\x7e\xe8\xf7\x01\x0b\xd6\xc5\x9b\x4e\xab\x18\x70\x2a\xe1\x4d\x15\ -\x43\x11\x30\x20\x7d\x33\x0e\x4f\xd3\x50\x16\x46\x75\x1d\x75\x8b\ -\x67\x4c\xd5\x99\x51\x00\xea\x2c\x57\xb8\x65\x5d\x37\xb3\x7d\x57\ -\x62\xe6\x86\x4a\x11\x4c\x28\x71\x48\x81\xee\xaf\xcb\xca\xd6\x27\ -\xf4\x62\x93\x3e\x4c\xe8\x55\x26\xf4\x3c\x08\xbd\xdc\x10\x42\x6f\ -\x77\x1d\x11\x57\x8b\xd3\x56\x85\xfd\xe5\x23\x35\x91\x98\x33\xf6\ -\x13\xaa\x75\xce\xce\x96\x07\x6b\xba\x72\x69\xb8\xa6\x6b\x6b\x09\ -\xd8\x94\x98\x0e\x41\x5b\x81\xcb\x73\xba\xbe\xcb\x13\x2b\xfd\x98\ -\x38\xdf\x73\x5d\x05\x55\x51\xc9\x05\xd7\x14\x90\x1c\x53\x81\xe8\ -\x10\x01\x87\x68\x8a\x03\x89\x24\x43\xa1\x20\x48\x99\x82\x1e\xcd\ -\x66\xc2\x3d\xe7\xcc\xd7\x15\x8a\xee\x00\x73\x84\x45\x64\x2e\x9b\ -\xdb\x45\x81\xaf\x86\x1f\x80\x87\x90\x73\x00\x7e\x6b\x8e\x38\x70\ -\x13\xe1\x02\x76\x38\x13\x30\x95\x11\xa1\x32\xe6\x15\x6c\xb3\x8c\ -\x96\x03\x53\x2c\x20\x8f\xb4\x94\x0b\xf1\x6f\x52\xf3\x76\x89\xb4\ -\xed\xfa\x7a\xfe\x77\xbb\xbd\xb9\xaa\x83\x7e\x6b\x3a\xc4\x3d\x46\ -\x18\x59\x16\x68\xe0\x52\x07\xab\x24\xb8\x51\x76\xab\x68\x53\xc6\ -\xbf\xab\xb2\x89\x87\x03\x82\x12\x6e\x07\xc2\x93\x09\xc1\x1c\x54\ -\x3e\x54\x44\x91\xcb\xf1\x54\x7d\x2a\x36\x74\x83\x0a\x0a\x58\x60\ -\x04\x63\x36\x45\x7f\x59\x9e\xbe\x68\x9e\x24\xc7\xf0\x2a\xeb\x4f\ -\xc1\x95\xd4\x1d\xba\xd7\xbd\xde\x47\x9d\x1e\x94\x3e\x4f\xe9\x2f\ -\x77\xa2\xf3\xe7\x9b\xab\xfc\xc7\xa1\x85\x76\x11\xab\xbe\x4d\xab\ -\x80\x01\x78\x9e\xd5\x66\x05\xe1\x43\xb8\x25\x6e\x02\xcc\x4f\xd0\ -\xef\x60\x11\x7c\x4a\x05\x39\x56\xb6\x31\xcb\x3e\x31\xa5\xc0\x25\ -\x07\x26\x76\xa1\xf1\xef\x55\x5f\x11\xab\x83\x59\xf5\x19\xa6\x84\ -\xba\x2b\x51\xf8\xcc\x7d\xb2\xc1\x68\xdd\x6a\x9e\x02\xe1\x0d\x62\ -\x8e\x55\x20\xbe\x32\xf3\x0c\x3d\x02\x30\x4b\x82\xc4\x98\x90\xf5\ -\x75\x62\xeb\xc1\xea\x8a\x17\x39\x44\xab\x5b\x49\x3f\x03\x14\x90\ -\xdb\x31\x63\x82\xf0\x05\x90\x04\x53\x25\x8e\xa9\xdb\x7e\xba\xec\ -\xe5\x5e\xd3\x65\x85\x40\x7e\x9f\x88\x49\xe7\xda\x6f\x9d\xf4\xe9\ -\x98\x04\xc8\xe1\xc4\x78\x31\x58\xe7\xce\x23\xb7\xa4\x9c\x81\x54\ -\x01\xcd\x88\xab\x03\x68\xe6\x82\x66\x45\xc4\xdc\x74\xad\xee\x8d\ -\x27\x09\x0f\x94\xb2\xf4\xbf\x7d\x40\x20\x5c\x75\x2b\x90\xc7\x1c\ -\x0d\x4b\x35\x42\x67\xeb\x00\x9d\xcb\x85\xbd\x6f\xe8\x2c\x56\xaf\ -\x9f\x1b\x3a\xef\x08\x27\x3a\xb1\xe1\xe0\x00\x89\x09\x71\xe8\x70\ -\x06\x28\xe9\x52\xb5\xe3\x8c\xf1\x19\x72\x94\x12\xc1\x2b\x02\x5c\ -\x2a\x23\x51\x72\x11\xc9\xc2\x17\x9e\x7c\x3d\x31\x96\xf3\x62\x24\ -\x5f\x2b\x1c\x86\x0a\x1d\xeb\x81\x5f\x8c\xa5\x26\x3c\x20\x08\xbb\ -\x2e\x38\xd0\x00\xca\x2a\x90\x14\x12\x07\x2e\xe6\x2e\x32\xb9\x7f\ -\x68\xe6\x8c\x91\xa5\xb2\x9f\x1c\x85\xed\x4c\xa9\xc0\x01\x93\x97\ -\x38\xb2\x25\x02\xb6\x3c\x58\xbe\xd8\x10\x95\xef\x52\xda\x80\x38\ -\x11\xcc\x0b\x6b\xc6\xe3\xc3\x4e\x8a\x02\x61\xef\x69\x27\xc5\x2a\ -\x17\x16\x3f\x2a\x1c\xce\xdf\xd1\x70\xd6\xae\xb0\xa7\xa1\x60\xa7\ -\x44\xbb\x73\xb9\x97\xbd\x12\xda\x26\xac\x83\xf2\x35\x61\x10\xcf\ -\x11\xb9\xd2\x95\x29\x5a\x89\x76\x1b\x6c\x02\x8e\x27\xf2\xf5\xb6\ -\x01\x7f\xe0\xd4\xdd\xfa\xde\xdf\xd8\x99\xa8\x0e\xd0\x25\xb6\xb8\ -\x95\xc8\xa8\x55\x58\x1c\xfc\x98\x4a\x22\x8f\x40\x7e\xa9\xb4\x98\ -\x8e\xc5\x6c\xf0\xb5\x8b\xb4\xd8\x9f\x10\xef\x8d\x16\x07\xad\x04\ -\x6d\xcb\x7d\x86\xfc\x00\xde\xb9\x27\x79\x08\xae\x82\xbe\xdc\xa5\ -\xa5\x1b\xfe\x9f\xa3\x5d\x6f\x41\xe1\xcf\x76\xb3\x6c\x52\x1c\x6d\ -\x91\x00\x0f\xbc\xed\xeb\xc4\xda\x86\xa4\x1c\x66\xe3\x27\x27\x0c\ -\xca\x9b\xe2\x99\x50\x7e\xf5\x03\x15\x14\xd8\x33\xb6\x15\x37\x55\ -\x4b\x34\x03\x12\x80\x23\x45\x05\xc2\x8e\xa4\x0f\x24\x91\xb2\x46\ -\x2c\xf0\x66\xe6\x91\x50\x98\xbc\x88\xc3\x7c\x1f\x9c\xf2\x5d\x98\ -\xe5\x1b\xc3\xac\x5a\x27\xd1\x1c\xfe\xec\x26\x6a\x84\xaf\x56\x9d\ -\x3e\x1c\x8c\x75\xb9\xb1\xb6\xaa\x85\x0f\x29\x63\xdf\x9f\x55\x2e\ -\xd5\x62\x35\xd6\xc8\x9e\x77\xaa\x2f\x12\x29\x0e\xaa\x0e\x81\xc8\ -\x56\x02\x91\xb7\x2c\x04\xdd\x5a\x16\x8e\xb8\xba\x36\x0a\x4a\x8a\ -\x93\x43\x75\xcc\x1d\x2a\x1b\x6e\xf5\x14\x26\x08\x39\x25\x80\xf2\ -\x04\xc3\x4c\xa0\xa7\x0f\xb5\x35\x64\x73\xf0\x75\x89\x43\x7d\xec\ -\x89\xfc\x68\xe8\x74\xf3\x58\x28\x3f\x7a\x33\xa2\xee\x5d\xc1\xdf\ -\xc9\xd5\xe5\xd5\xfc\xef\xe2\x12\xc2\x39\x5b\xb9\x95\x70\xce\xd2\ -\x6a\x9f\xb4\xd2\x7f\x9b\xf7\x52\xd2\xe5\xeb\x47\xc0\x72\x98\x4c\ -\x72\x27\x93\x8a\x7b\xe1\xdb\xc5\xdb\x04\xf6\x3e\x99\x7c\xc6\x34\ -\xd0\xa6\x28\x10\x81\x00\x71\x56\xdf\x84\x52\xbc\xc5\xf5\x30\xa1\ -\xec\x25\xb3\x55\xbc\xaf\xbb\x8e\x49\x44\x29\xa8\xd1\x4f\x1d\x6f\ -\x40\xa0\xa1\xe2\x76\x15\x61\x50\xb5\xc7\xe9\x04\xf5\xed\x5a\xc1\ -\x58\x2d\x20\x28\xcf\x1e\xa2\x87\x19\x12\x3f\x42\xcc\x89\x98\xcf\ -\x3b\x7e\x44\xe6\x64\x27\x07\x95\xda\xad\xbd\x64\xdf\x14\x40\xbf\ -\x33\x66\xfa\x1c\xe1\x79\x77\x09\xb7\x79\x2a\x69\xbd\x84\xdb\x3d\ -\xe0\xa5\xd0\x1b\x58\x5d\xea\x93\x20\x6f\xc7\x6a\xe5\x04\xdc\xf6\ -\xd2\x6f\xe7\xd5\xa6\xa4\x15\x1b\xd7\xd6\xd8\xe6\xf3\x28\x91\x01\ -\xb7\xfa\x66\x8f\xe2\x97\x38\xcc\x1e\x7b\x0f\x47\xd6\x5a\x23\x29\ -\xb3\x56\x7d\x5e\x2c\xa3\xf6\xf9\xc5\xc5\x45\xa7\x7d\xb6\xbf\x15\ -\xeb\x48\xff\x4d\x7f\xfa\xf4\x89\x5c\x8d\x1b\x25\x7a\x2f\x88\x0f\ -\x5a\x27\x9d\x1a\xe2\x03\xf5\x7a\x91\xa1\x3f\xc7\xf9\xa7\x3a\x14\ -\x5f\x55\x83\xe2\xe2\x4c\xd3\x9a\x50\x3c\x04\x86\xea\x03\xe2\xe2\ -\x34\xc4\x01\x88\xb7\x02\xc4\x9f\xc0\x93\x7d\xe7\x52\xb9\x80\xc1\ -\xca\xc5\x25\xaa\x62\x63\x54\xbb\xb7\x1b\xd1\x93\xc7\xeb\x94\x46\ -\xe9\x67\x35\xc8\x61\x70\xc3\x4d\x6e\x3f\x0f\xee\x4e\x8e\x3e\xc6\ -\x5b\x6d\x12\x4f\x8a\xd0\x19\xab\xed\xe8\x2f\x7e\x84\x4c\xbe\x7e\ -\xc3\x29\xf6\xcc\xa5\x5a\xa0\x8b\x3a\xd2\x07\x5d\x33\x4d\x05\x0e\ -\x44\xd4\xd2\x96\x10\x4e\x87\xe6\xf2\x08\xf8\x31\x57\x3e\x0b\x58\ -\xd4\x4c\x31\x89\x86\xd8\xa7\xde\x2c\xaf\xdf\xe3\x3b\xe2\x3d\x10\ -\xe5\x8a\x1d\xc7\xc4\xcd\x43\x9a\xd5\x29\x55\xe7\x95\x0c\x33\x47\ -\x39\xcf\xbf\xba\x61\x9e\x6b\xee\x77\xb0\x4a\xd1\x2c\x4f\x0b\x7b\ -\x74\x14\xc0\x00\x2c\x10\x04\xbb\x56\x26\xf5\x46\xd5\x7f\x55\x6a\ -\xfb\xbf\xf9\xed\x3d\xc7\x14\xb4\x65\x14\x97\x7c\xbb\x05\x0a\xfa\ -\xa8\x0a\x91\xe5\x79\x98\x78\xa0\xda\x63\x10\x0c\xe1\xf7\x4b\x71\ -\xea\x63\xa0\xf7\x39\x7a\xe5\x30\xaa\xea\x94\x65\x3a\x3b\x4c\x58\ -\xb9\xf9\xac\x12\x07\x1d\x73\x66\xac\x4d\xe7\xab\x39\x5c\xa0\x17\ -\xd8\x9f\xbc\x46\x9f\x08\x06\xc5\x41\x98\x73\x08\xe0\x9f\xec\x57\ -\x3d\x14\xbe\x6d\x09\xa5\x04\xb4\x34\x47\x94\x9f\xaa\x56\x56\xfc\ -\x1e\x05\x26\xd1\x59\x7d\xdf\x9c\xa0\xba\xbf\xa8\xb7\xfb\xab\xfa\ -\xba\xbf\xa5\xdc\x81\x39\xb4\x46\xf9\x5b\x0e\x6a\x1c\x02\xcb\x41\ -\x8d\xa3\xd0\x07\x68\x19\xd7\x39\x08\x86\x81\x1a\xc7\xc0\x30\x50\ -\xe3\x10\xdc\x60\xe7\xbb\xa8\x7b\x18\x62\x26\x6a\x1c\x8a\x98\x89\ -\x4a\xc3\x51\xbb\xab\x52\x31\xcf\xd9\x2e\x5e\xdc\x58\xee\xad\x7c\ -\xb3\x79\xdb\x44\x94\x63\x22\xed\x44\x34\xfb\x14\xdd\x95\x55\x5f\ -\x1d\xb8\x6e\x18\x98\x3c\x57\xcf\x86\x26\x32\x8c\x24\x61\x63\x40\ -\xbb\xe9\x8b\x09\x92\x14\x12\xe6\x04\x45\x49\xef\x13\x14\x25\x29\ -\x80\xaa\x47\x86\xf2\x18\x1e\xa2\x66\x5b\x98\xa2\xf8\xb1\xff\xfb\ -\xfc\x34\x46\x85\x35\x9a\x72\x5e\x58\x6a\x00\x9f\xa3\x2b\xf6\x09\ -\x04\x8d\x7e\x49\xca\xf6\x3f\xf5\xe1\xd0\xd7\x65\x4b\x04\x3f\x0b\ -\x02\x75\x2a\x2e\xfe\x77\x36\x45\xa0\xc8\x74\xfa\x63\x3c\x21\x7d\ -\x5d\x86\xde\xab\xd4\x8a\x39\x36\x54\x57\xae\xef\xaa\xf0\x75\x0e\ -\xb9\xbe\x7d\x1e\x0e\x7c\xc6\x47\x03\xfb\x04\xde\x52\x46\xd9\xc4\ -\x61\x19\x95\xaf\x32\x3f\x28\x03\x7b\xbe\xc7\xf2\xca\xaf\xb5\xa7\ -\xb0\x20\x9a\xd6\xd3\x5f\x7d\xbe\x0e\x04\xc4\xd6\x1f\xf9\x55\x29\ -\xdb\x5f\x5c\x57\x2f\x61\xf1\x69\x75\x9e\x7f\x9d\x66\x56\x91\x23\ -\x1d\x3e\x5d\x50\xe2\x94\xfe\x66\x59\x49\xd9\x74\x2c\xa4\x84\x24\ -\x13\x62\xb4\xd3\xcb\x3c\xb3\x6d\xb6\xd5\x5d\x37\xce\x1b\xc8\xfc\ -\xd0\xc0\x75\xa3\xdd\x6e\xa8\x64\x6f\x77\x42\x1f\x7d\x3c\x19\x86\ -\x81\xa3\x04\xd5\xfb\xf1\x45\xdf\xbf\xe7\xcc\xff\x0c\xbe\x54\x9f\ -\x85\xdc\x01\x25\xcc\xb4\x52\x3f\x36\x11\x0a\xc9\x7c\xd3\xa3\xd0\ -\x9c\x24\x4b\x0c\x97\x89\x1f\xa4\x48\x00\x49\xfc\x1b\x14\x6a\x3c\ -\x1e\x25\x09\x5c\xd1\xb3\xbf\x3f\x01\xa3\x61\x0b\x8e\x8c\xa8\x54\ -\x66\x4e\x51\x68\x2a\x02\xe6\x07\x29\x4e\xc6\x4a\x70\xba\x42\x0b\ -\x20\xdb\x6f\x31\x23\x89\x2f\x07\xcc\x67\xe4\x4b\x28\xc6\x51\xfd\ -\x32\x66\x0c\xb3\xa2\x1a\x27\x19\x7c\xcd\xe5\x66\x51\x76\xcb\x58\ -\x52\xd4\xb6\xc6\x96\x5d\x65\xcf\x17\xd0\xbc\x72\x2f\xac\xac\x1a\ -\xaf\xc5\x41\xdd\x0f\x5b\xf6\x3c\x4d\xbe\x88\xe2\xda\x3d\xc9\xc8\ -\x04\x63\x4b\x98\x99\xd7\xee\x85\x99\x68\x79\x30\x9f\x99\xb8\x76\ -\x2f\xcc\xa4\x36\x8d\xe4\x73\x94\x69\x52\x9d\xad\x74\x81\xfe\xad\ -\x1d\x75\x7a\x5b\x01\xa9\xd0\x90\xeb\xb0\x20\x20\x1a\x48\xd5\x7d\ -\xb7\x19\xd2\xde\xd1\xff\x01\x15\x62\x88\xbe\ +\x00\x76\x5d\x78\x9c\xed\x5d\x5b\x93\xda\xb8\x12\x7e\x9f\x5f\xa1\ +\xe2\x21\x75\x4e\x55\x76\x80\xc9\x5c\x13\x86\xad\xdc\x27\x55\x49\ +\x6d\x36\xcc\x66\x1f\xb7\x84\x2d\x40\x67\x6d\x8b\x48\xf2\x30\x6c\ +\x9d\x1f\x7f\x5a\x17\x63\x1b\x8c\xc1\x17\x30\x99\x43\xaa\x52\x63\ +\x5b\x76\xab\xd5\xea\xfe\xd4\xdd\x6a\x9b\xde\xaf\x8f\xbe\x87\x1e\ +\x08\x17\x94\x05\xb7\xad\xee\x69\xa7\x85\x48\xe0\x30\x97\x06\xe3\ +\xdb\xd6\x1f\xf7\x1f\x7e\xb9\x6e\xfd\xda\x3f\xe9\x85\x34\xbe\xe9\ +\x1c\x6e\xea\x9f\xa0\x9e\xe3\x61\x21\xfa\x1f\x43\xfa\xf2\xe5\x3b\ +\x8a\x3d\x36\x86\xbf\xde\x78\x40\xa4\x84\x87\xc5\x3b\x8e\x47\xb2\ +\xd7\x36\x37\xc1\xdd\x33\xea\x8e\x89\x44\xfa\xfc\xb6\xf5\xfb\x9f\ +\xfa\xb4\x85\x02\xec\x93\xdb\x56\x2e\x11\xd5\x19\xea\x4d\x39\x9b\ +\x12\x2e\xe7\xf6\x89\x31\x61\x3e\x91\x7c\xae\x1b\x51\x8f\x13\x47\ +\xea\x23\xd4\x7b\xec\x77\x7a\xed\x47\x7b\x32\x57\x27\x73\x7b\x02\ +\x2c\xc8\x49\xff\xe2\xc5\x55\xaf\x6d\x0e\xcd\xe5\x09\xa1\xe3\x89\ +\xec\x5f\x75\xce\x7a\x6d\x7b\xac\x69\xb6\x23\xa2\xbd\x76\xd4\x79\ +\x16\x27\x33\x1a\xb8\x6c\x76\x4f\xa5\x47\x2c\x33\x42\x72\x60\xbe\ +\xff\x9d\x8a\x10\x7b\x48\xd8\xb1\xf4\xda\xf6\xfa\x2a\x45\x0f\xcf\ +\x59\x18\xcb\xe6\xfb\x1b\xf6\xf8\x59\x5f\xb2\x04\x97\x7a\x14\x53\ +\xec\x00\xa1\x96\xe5\x3f\x08\xfd\x21\xe1\xfd\xcb\x5e\xdb\x1e\x19\ +\xee\x93\x3d\xac\x90\xf0\x31\x1f\xd3\x60\x89\xc2\x4d\x2e\x05\x2a\ +\x89\x1f\x0b\x32\x39\x97\x1f\x39\x0b\xa7\xc0\x73\x34\x9b\xe3\xe8\ +\xdc\xdc\xbe\xd2\xb9\x8c\x65\xb5\x2a\xae\x41\x86\xb8\x56\xb9\xc9\ +\x15\x9a\xed\x06\x14\x56\x52\x07\x7b\xe6\xea\x5f\x67\x71\x8f\xf1\ +\x50\x32\x08\xdd\xad\x10\x9a\x30\x4e\xff\x61\x81\xcc\x20\xb5\x4c\ +\x6c\x55\x38\x9f\xf1\x90\x78\x11\x25\x4f\x9d\xa4\x1e\xcf\x90\x0e\ +\x79\x94\xa9\x1b\x16\x12\x7a\x47\x46\x38\xf4\x24\xf2\x68\x40\x90\ +\xc3\x3c\xc6\x97\x84\x94\x2d\x29\x73\xd1\xb0\x95\xe0\xbb\x9d\x66\ +\x7c\x65\x1c\x4a\xcb\x08\x5f\x11\xc1\x40\x5f\xce\x1d\x01\xdc\x4b\ +\xe0\x56\x09\x68\xb1\x34\x10\x02\xfa\xd5\xff\x5d\xbe\x7c\x79\xb7\ +\xa0\xd7\x6b\xeb\x8b\x9b\x06\xb0\x6a\x04\xf4\x1f\x72\x47\x03\x98\ +\x24\x21\x5d\xb0\xb1\xdb\x56\x67\x59\x6a\x70\x47\xea\x4a\x84\x00\ +\xe7\x9d\x14\x00\x2c\x5a\xad\xf1\x9f\x75\x52\x38\x10\xb3\xb5\x4c\ +\x70\x8d\xa4\x8d\xe0\x0a\x48\x3a\xad\x31\x1a\x0b\xbf\x72\x32\x7a\ +\xab\x66\xf8\x4d\x28\x25\x88\x31\xb2\x2c\xd5\x36\x85\x36\x3d\xfb\ +\x43\xd3\x96\xab\x4c\x8c\x79\xf7\x74\x9a\xad\x4f\x72\x42\x90\x6b\ +\x75\x4a\x13\x44\x23\xf8\x1f\x90\x19\x62\xc3\xff\x00\xf6\x2d\xdb\ +\x60\x81\xd9\xd1\xe4\x96\x7a\xd5\xd7\x96\x44\xce\x89\xab\x10\x5a\ +\xfd\x49\x37\x8c\x39\x21\x81\x6a\x32\x07\xe9\xc6\xa1\x17\x12\xd5\ +\xa6\xff\xa6\xe7\x68\xa5\x93\xed\xf8\x55\x32\x7d\x1f\xa8\xf5\x64\ +\xad\x3a\x39\x56\x16\xd6\xf0\x9c\xb2\xa2\x51\x5d\x7d\xc5\x72\xb2\ +\xb9\xa7\x2f\xcc\x6d\x47\xcb\x68\x5d\x76\xde\x6b\x1b\xb8\x5b\x60\ +\x61\xaa\xb9\x32\x32\x5e\x55\x43\xc6\x17\x75\x20\xa3\x36\xed\xc6\ +\x90\x71\x03\xba\x1f\xb1\xb1\x16\x6c\x1c\x4c\x69\x90\xf4\x38\x22\ +\x5c\x14\x70\x7d\x18\x7b\x1e\x99\xd2\xd9\x1a\x13\x95\x36\x69\x59\ +\xd4\x87\x8b\x0f\x18\x20\x6b\xa9\x67\xeb\x73\x9d\xa5\xbc\xaf\x42\ +\x54\x0b\xa0\xd7\x62\x4c\x47\x04\xcb\x46\xb0\x17\xd5\x10\xec\xbc\ +\x24\x82\x0d\x02\x3c\x45\x62\xee\x0f\x99\x27\x40\xac\x73\x8f\xec\ +\x12\xc1\xd6\x7a\x1c\xd0\x7f\x96\x59\x39\xaa\x01\xec\x6a\x03\xb8\ +\xf9\x34\xa0\x7e\xe8\x0f\x00\x0b\xb6\xc5\x9b\xb3\x4e\x3e\xe0\x54\ +\xc2\x9b\x2a\x86\x22\x60\x42\x06\x66\x1e\x0e\xd3\x50\x56\x66\x75\ +\x1b\x75\x8b\x57\x4c\xd5\x99\x51\x00\xea\xac\x57\xb8\x75\x5d\xb7\ +\x97\xfb\xae\xc4\xcc\x1b\x2a\x45\x30\xa5\xc4\x21\x39\xba\xbf\x2d\ +\x2b\xb5\x2f\xe8\xf9\x26\x7d\x5c\xd0\xab\x2c\xe8\x59\x10\x7a\x5d\ +\x12\x42\xdf\xee\x3a\x22\xae\x16\xa7\x6d\x0a\xfb\x8b\x47\x6a\x22\ +\xb1\x66\xec\x27\x54\x3b\xbb\xb8\x58\x1f\xac\xe9\xc6\xb5\xe1\x9a\ +\x6e\x6d\x24\x60\x53\x62\x3a\x06\x6d\x39\x2e\xcf\xf9\xf6\x2e\x4f\ +\xac\xf4\x13\xe2\xfc\x9d\xe9\x2a\xa8\x86\x4a\x2e\xb8\xa6\x80\xe4\ +\x84\x0a\x44\x47\x08\x38\x44\x33\x1c\x48\x24\x19\x0a\x05\x41\xca\ +\x14\xf4\x6c\xb6\x13\xee\x39\x67\xbe\x6e\x50\x74\x87\x98\x23\x2c\ +\x22\x73\x29\x6f\x17\x39\xbe\x1a\x7e\x00\x1e\x42\xce\x01\xf8\xad\ +\x39\xe2\xc0\x4d\x84\x0b\xd8\xe1\x4c\xc0\x52\x46\x84\xca\x98\x57\ +\xb0\xcd\x22\x5a\x0e\x4c\xb1\x80\x3c\xd2\x42\x2e\xc4\xff\x93\x9a\ +\x77\x0b\xa4\x6d\xb7\xd7\xf3\xbf\xba\xdd\xf2\xaa\x0e\xfa\xad\xe9\ +\x10\xf7\x39\xc2\xc8\xb2\x40\x03\x97\x3a\x58\x25\xc1\x8d\xb2\x5b\ +\x45\x9b\x31\xfe\xb7\xba\x36\xf5\x70\x40\x50\xc2\xed\x40\x78\x3a\ +\x25\x98\x83\xca\x87\x8a\x28\x72\x39\x9e\xa9\xbf\x8a\x0d\x7d\x43\ +\x05\x05\xcc\x31\x82\x09\x9b\xa1\x3f\x2d\x4f\x5f\x35\x4f\x92\x63\ +\x18\xca\xf6\x4b\x70\x25\x75\x87\xee\x75\xaf\xf7\x51\xa7\x47\xa5\ +\xcf\x52\xfa\xeb\x9d\xe8\xfc\x65\x79\x95\xff\x34\xb2\xd0\x2e\x62\ +\xd5\xb7\x69\x15\x30\x00\xcf\xb3\xda\xac\x20\x7c\x04\xa7\xc4\x4d\ +\x80\xf9\x29\xfa\x0d\x2c\x82\xcf\xa8\x20\xcf\x95\x6d\xcc\x97\x9f\ +\x98\x51\xe0\x92\x03\x13\xbb\xd0\xf8\x0f\xaa\xaf\x88\xd5\xe1\xbc\ +\xfa\x0a\x53\x40\xdd\x95\x28\x7c\xe6\x1e\x6c\x30\xda\xb4\x9a\xa7\ +\x40\xb8\x44\xcc\xb1\x09\xc4\x37\x66\x9e\xa1\x47\x00\x66\x49\x90\ +\x98\x10\xb2\xbd\x4e\xd4\x1e\xac\x6e\x18\xc8\x31\x5a\xad\x25\xfd\ +\x0c\x50\x40\xde\x4e\x18\x13\x84\xaf\x80\x24\x98\x2a\x71\x4c\x5b\ +\xfd\xe9\xb2\x17\x7b\x4d\x97\xe5\x02\xf9\x7d\x22\x26\x5d\x68\xbf\ +\x75\xd2\x67\x13\x12\x20\x87\x13\xe3\xc5\x60\x9d\x3b\x8f\xdc\x92\ +\x62\x06\x52\x05\x34\x23\xae\x8e\xa0\x99\x09\x9a\x15\x11\xb3\xec\ +\x5e\xdd\x6b\x4f\x12\x1e\x28\x65\x19\x7c\xff\x88\x40\xb8\xea\x54\ +\x20\x8f\x39\x1a\x96\x1a\x84\xce\xce\x11\x3a\xd7\x0b\x7b\xdf\xd0\ +\x99\xaf\x5e\x3f\x37\x74\xde\x11\x4e\x74\x62\xc3\xc1\x01\x12\x53\ +\xe2\xd0\xd1\x1c\x50\xd2\xa5\xaa\xe2\x8c\xf1\x39\x72\x94\x12\xc1\ +\x10\x01\x2e\x95\x91\x28\xb9\x88\xe4\xc5\x67\x9e\x7c\x35\x35\x96\ +\xf3\x6c\x2c\x5f\x29\x1c\x86\x06\x1d\xeb\x81\x5f\x8c\xa5\x26\x3c\ +\x24\x08\xbb\x2e\x38\xd0\x00\xca\x2a\x90\x14\x12\x07\x2e\xe6\x2e\ +\x32\xb9\x7f\xb8\xcd\x99\x20\x4b\x65\x3f\x39\x0a\xdb\x99\x52\x81\ +\x23\x26\xaf\x71\x64\x0b\x04\x6c\x59\xb0\x7c\x55\x12\x95\xef\x52\ +\xda\x80\x38\x11\xcc\x0b\x1b\xc6\xe3\x63\x25\x45\x8e\xb0\xf7\x54\ +\x49\xb1\xc9\x85\xc5\x8f\x0a\x87\xb3\x2b\x1a\x2e\xba\x15\x6a\x1a\ +\x72\x2a\x25\xba\x67\xd7\x7b\xa9\x95\xd0\x36\x61\x1d\x94\x6f\x09\ +\x83\x78\x8a\xc8\x95\x6e\x4c\xd1\x4a\xdc\x57\xa2\x08\x38\x5e\xc8\ +\xb7\x2b\x03\xfe\xc8\xa9\x5b\x7b\xed\x6f\xec\x4c\x54\x07\xe8\x02\ +\x25\x6e\x05\x32\x6a\x15\x36\x07\x3f\xa5\x92\xc8\x63\x90\x5f\x2a\ +\x2d\xa6\x63\x31\x1b\x7c\xed\x22\x2d\xf6\x07\xc4\x7b\xe3\xd5\x49\ +\x2b\x40\xdb\x72\xbf\x44\x7e\x08\x63\xee\x4b\x1e\x82\xab\xa0\x0f\ +\x77\x69\xe9\x86\xff\xa7\x68\xd7\x35\x28\xfc\xc5\x6e\xb6\x4d\xf2\ +\xa3\x2d\x12\xe0\xa1\x57\xbf\x4e\x6c\x6d\x48\xca\x61\x36\x7e\x72\ +\xc2\xa0\xbc\x19\x9e\x0b\xe5\x57\x3f\x50\x41\x81\x3d\x63\x5b\xf1\ +\xad\x6a\x8b\x66\x48\x02\x70\xa4\xa8\x40\xd8\x91\xf4\x81\x24\x52\ +\xd6\x88\x05\xde\xdc\x3c\x12\x0a\x93\x17\x71\x98\xef\x83\x53\xbe\ +\x0b\xb3\x7c\x6d\x98\x55\xfb\x24\x9a\xc3\x9f\xdd\x44\x8d\xf0\xd5\ +\xae\xd3\xc7\xa3\xb1\xae\x37\xd6\x4e\xb5\xf0\x21\x65\xec\xfb\xb3\ +\xca\xb5\x5a\xac\xe6\x1a\xd9\xf7\x9d\x9a\x8b\x44\xf2\x83\xaa\x63\ +\x20\x52\x4b\x20\xf2\x8e\x85\xa0\x5b\xeb\xc2\x11\x57\xb7\x46\x41\ +\x49\x7e\x72\xa8\x89\xb5\x43\x65\xc3\xad\x9e\xc2\x02\x21\x67\x04\ +\x50\x9e\x60\x58\x09\xf4\xf2\xa1\x4a\x43\xca\x83\xaf\x4b\x1c\xea\ +\x63\x4f\x64\x47\x43\xe7\xe5\x63\xa1\xec\xe8\xcd\x88\xba\x7f\x03\ +\xff\x4e\x6f\xae\x6f\x16\xff\xae\xae\x21\x9c\xb3\x8d\xb5\x84\x73\ +\x96\x56\xf7\xb4\x93\xfe\x57\xbe\x97\x82\x2e\xdf\x20\x02\x96\xe3\ +\x62\x92\xb9\x98\x54\xac\x85\xef\xe6\x97\x09\xec\x7d\x31\xf9\x82\ +\x69\xa0\x4d\x51\x20\x02\x01\xe2\xbc\xb9\x05\x25\xbf\xc4\xf5\xb8\ +\xa0\xec\x25\xb3\x95\x5f\xd7\xdd\xc4\x22\xa2\x14\xd4\xe8\xa7\x8e\ +\x37\x20\xd0\x50\x71\xbb\x8a\x30\xa8\xaa\x71\x3a\x45\x03\xbb\x57\ +\x30\x51\x1b\x08\xca\xb3\x87\xe8\x61\x8e\xc4\x8f\x10\x73\x22\x16\ +\xeb\x8e\x1f\x91\x39\xdd\xc9\x8b\x4a\xdd\xce\x5e\xb2\x6f\x0a\xa0\ +\xdf\x1b\x33\x7d\x8a\xf0\xbc\xbb\x84\xdb\x22\x95\xb4\x5d\xc2\xed\ +\x1e\xf0\x52\xe8\x02\x56\x97\xfa\x24\xc8\xaa\x58\xad\x9c\x80\xab\ +\x2f\xfd\x76\x59\x6d\x49\xda\x50\xb8\xb6\x76\xe9\xd0\x42\x6a\x6e\ +\xbd\xc8\xf7\x77\x8f\xeb\x45\xdd\xaf\xa0\xe4\x47\xc1\xeb\xd5\x64\ +\x04\x22\x6e\xe0\x0d\x94\xcf\x00\xf6\xef\x5d\x2a\x57\x96\x3a\xb5\ +\x0a\x10\xd5\x90\x1b\x05\x1c\xfa\x5b\x7b\x1b\x02\x2f\x53\x4c\x9a\ +\x7c\x45\x46\x4d\x83\x7e\x56\xbf\x26\x83\x61\x29\x35\xf9\x39\x99\ +\x01\x75\xa7\x27\x9f\xe2\xed\xf2\xc4\x93\x22\x84\xe0\x0d\x0b\xf4\ +\xec\x47\xc8\xe4\xab\xd7\x9c\x62\xcf\x1c\xaa\x24\x7b\xd4\x91\x7e\ +\x59\x6d\xe9\x56\x81\x03\x11\xdd\x69\xaf\x10\x4e\x47\xe6\xf0\x04\ +\xf8\x31\x47\x3e\x0b\x58\x74\x9b\x62\x12\x8d\xb0\x4f\xbd\x79\x56\ +\xbf\xcf\xef\x88\xf7\x40\x14\x9c\x3e\x8f\x89\x9b\x87\x34\xab\x33\ +\xaa\xde\x39\x30\xcc\x9c\x64\x3c\xff\xf2\x0d\xf3\x5c\x73\xbe\x83\ +\x4c\x63\xbb\x38\x2d\xec\xd1\x71\x00\x13\xb0\x42\x10\x8c\x41\xa1\ +\xd5\x6b\xd5\xfe\x4d\xe9\xcf\x7f\x17\xa7\xf7\x1c\x53\x50\xe7\x71\ +\x7c\xe5\xfb\x5b\xa0\xa0\xcb\xcd\x89\x2c\xce\xc3\xd4\x03\xd4\x98\ +\x80\x60\x08\xbf\x5f\x6b\xcf\x9f\x02\x5d\xab\xe4\xa1\x42\x86\x5d\ +\xad\x66\xed\x51\x9a\xce\x7e\x52\xa7\xa7\xd4\x07\x71\xf2\xf7\x02\ +\xd6\xe3\xad\xc2\x93\x06\xf0\xb6\x48\xaa\x6a\xab\xfd\xf3\x22\xd8\ +\x7b\x99\x0f\xbd\xdd\xcb\xab\xab\xab\xb3\xee\xc5\xfe\x10\x38\x2a\ +\x81\x36\xfd\x69\xc8\xcd\x02\xda\x7a\x63\x11\x9b\x21\xea\x9c\x9e\ +\x35\x90\x3b\x52\xc3\x33\xa3\xfd\x69\xcd\x74\xd7\xa9\xa3\x02\xef\ +\x14\x66\x20\x42\xd9\x62\xfc\x85\xb2\x21\xcc\x39\x9b\x35\xe8\xb1\ +\xe7\x7b\x90\x47\x8f\xbd\x6e\x8f\xbd\x5b\xb6\xf0\xed\x60\xbf\xb5\ +\x91\x3b\x9e\x02\x60\x05\x08\x6c\xde\x11\x3f\x54\xac\xaa\xf8\x21\ +\x0b\x96\xe9\x98\xad\xeb\xaa\xde\x0f\x57\xbc\xa5\xdc\x69\xf2\xc3\ +\x19\xaf\x15\xca\xed\xf9\x63\x19\x9b\x6d\xf1\xe6\xc9\x7a\x73\xe5\ +\x8b\xb4\x92\x6f\xcb\xa8\x71\x22\x36\x2a\xba\x46\x15\xf3\x8b\xba\ +\x0d\xf8\x45\x66\x40\x7a\x16\x0f\x13\x6a\x9a\x76\x8b\x6e\x2a\x79\ +\x45\x9b\x6a\xa6\xb6\x72\x8c\xf4\xc6\x40\x83\x45\xdd\xc7\x54\x66\ +\x8e\xb0\x77\xe0\x18\x9d\x95\x7d\xb3\xf5\x60\x1d\xa3\x0d\x1b\x77\ +\x25\xd2\x99\xdd\x43\xfd\x08\x99\xf2\xdd\x9e\xee\x37\xc8\x54\x13\ +\xc2\x43\xf6\xd0\xa0\x07\xa5\x79\xa0\x80\x8d\xee\xbe\x3f\x3a\xb6\ +\x05\xdc\x97\xfd\x12\xd6\xe1\x3b\x52\x9b\xbe\x93\x58\xd4\x95\x8a\ +\xd3\x4c\x08\xa4\x62\x0e\x0b\x2e\x75\xc5\xdc\xab\x17\x0d\xb8\x57\ +\x30\x32\x3b\xa4\xc3\x44\x83\xa6\xbd\xab\x6e\xc5\xcd\xe1\xee\x06\ +\xa5\xdc\xc6\xbd\x52\x37\x35\xe7\x5d\xe5\x6f\x6f\x1f\x9d\xab\xda\ +\xb3\x4e\x65\x43\xdd\xc4\x54\x1c\xa4\x8b\xb5\xe1\xe5\xfe\x6d\x37\ +\x64\x93\x5f\xa9\x62\x23\xb3\x47\x1b\xd9\x8a\xdd\x24\xb0\xaf\x50\ +\x30\x41\x92\x20\x8e\x39\x41\x51\x09\xc9\x29\x8a\x76\x18\x80\xaa\ +\x47\x46\xf2\x39\x3c\x44\xcd\x4b\x16\x8a\xe2\xa7\xc1\x6f\x8b\x77\ +\x9b\x2b\x54\x3c\x15\x73\xcb\x52\x13\x78\x98\x70\x5c\xcd\x31\xfa\ +\x0c\x82\x46\xff\x4a\xca\xf6\xdf\xcd\x79\x69\xdf\xcc\x5e\xcb\xa1\ +\xf9\x67\x65\x7f\xc8\x63\x0f\x2f\x34\xd4\xe0\xa2\x6d\x28\x82\xd9\ +\xa6\x1a\x9e\x2c\x6a\x12\xd3\xa6\xaf\xbf\xd3\xaf\xb6\x07\x57\x11\ +\x61\x47\xfe\x5a\xe7\x62\xff\xfe\x9a\x8a\xde\x8e\x15\xe6\xb9\x3f\ +\xa4\x53\xb1\xc2\xfc\xac\xb4\xc7\x66\x57\x94\xc1\x04\x4f\xc9\x40\ +\x5f\x43\x1f\x54\xed\x8f\xf9\x36\x45\x53\xfe\x5b\xbe\x3b\x71\xf4\ +\xdf\xf6\xf9\x05\x9a\xba\x93\x4c\x07\xf4\xfd\x99\x01\x81\x51\xca\ +\xa8\xdc\x6d\x54\x44\xe5\xab\xe0\xa1\x32\xb0\xa7\xfb\xed\x97\xe2\ +\x05\xdd\x29\x2c\x88\xbc\xdd\xf4\xef\x6b\x6d\x03\x01\xb1\xf5\x7f\ +\xb7\x34\x52\xb6\xbf\x5a\xbc\x5d\xc0\xe2\xd3\xea\xbc\xa8\xfe\x5c\ +\x56\xe4\x48\x87\xcf\x57\x94\x38\xa5\xbf\xcb\xac\xa4\x6c\x3a\x16\ +\x52\x42\x92\x09\x31\xda\xe5\x65\x91\xf9\x31\x2b\xeb\x6d\xeb\xb2\ +\x85\xcc\xaf\xd9\xdd\xb6\xba\xdd\x96\xaa\x46\xec\x4d\xe9\xa3\x8f\ +\xa7\xa3\x30\x70\x94\xa0\xfa\x3f\xbe\xea\xf3\x0f\x9c\xf9\x5f\xc0\ +\xd7\x18\xb0\x90\x3b\xa0\x84\x4b\x77\xa9\x5f\x34\x0c\x85\x64\xbe\ +\xe9\x51\x68\x4e\x92\x57\x0c\x97\x89\x5f\x3d\x4c\x00\x49\xfc\x43\ +\x87\x6a\x3e\x54\x06\xca\x15\x7d\xfb\x23\x87\x30\x1b\xf6\xc2\x89\ +\x11\x15\x76\x61\xc8\x40\xa1\xad\x08\x98\x5f\x3d\x3c\x9d\x28\xc1\ +\xe9\x06\x2d\x80\xe5\x7e\xf3\x19\x49\x7c\x81\x3e\x9b\x91\xaf\xa1\ +\x98\x44\xed\xeb\x98\x31\xcc\x8a\x6a\x9c\x2c\xe1\x6b\x26\x37\xab\ +\xb2\x5b\xc7\x92\xa2\x56\x1b\x5b\xd6\xe9\xcd\x16\xd0\xa2\x71\x2f\ +\xac\x6c\x9a\xaf\xd5\x49\xdd\x0f\x5b\xf6\xa3\x0d\xd9\x22\x8a\x5b\ +\xf7\x24\x23\x93\xa3\x58\xc3\xcc\xa2\x75\x2f\xcc\x44\x05\xf6\xd9\ +\xcc\xc4\xad\x7b\x61\x26\x15\xc3\x65\x73\xb4\x74\x4b\x75\xb6\xd2\ +\x17\xf4\x0f\xba\xaa\x4f\x84\x29\x20\x15\x1a\x72\x1d\x16\x04\x44\ +\x03\xa9\x3a\xef\xb5\x43\xda\x3f\xf9\x1f\xcb\x82\x89\x26\ \x00\x00\x0a\x77\ \x00\ \x00\x54\x26\x78\x9c\xed\x1c\x5d\x73\xdb\x36\xf2\xdd\xbf\x02\xa3\ @@ -52686,6 +52697,282 @@ qt_resource_data = "\ \x7e\xff\xd9\xa7\x47\x7f\xd1\xef\xb1\x57\xf9\x55\xc6\x4e\x64\xe3\ \x6c\x43\x97\x89\x7c\x79\x4a\x5e\x7e\x26\xff\xde\xed\x2a\x5d\x6e\ \xe2\xd7\x1b\xba\x8c\x7d\xfb\xea\xff\x00\x22\xbe\xdd\x46\ +\x00\x00\x11\x18\ +\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\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\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\x0a\x20\x20\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\x0a\x20\x20\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\x0a\x20\x20\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\x20\x20\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\x0a\x20\x20\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\x0a\x20\x20\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\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x36\x34\ +\x70\x78\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\ +\x34\x70\x78\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\ +\x37\x33\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x33\x32\x22\x0a\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\x34\x20\x72\x39\x39\x33\ +\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\ +\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x54\x72\x65\x65\x5f\x44\x69\x6d\ +\x65\x6e\x73\x69\x6f\x6e\x2e\x73\x76\x67\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6f\x75\x74\x70\x75\x74\x5f\x65\ +\x78\x74\x65\x6e\x73\x69\x6f\x6e\x3d\x22\x6f\x72\x67\x2e\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x2e\x6f\x75\x74\x70\x75\x74\x2e\x73\x76\ +\x67\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\ +\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x3e\x0a\x20\x20\ +\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ +\x65\x66\x73\x32\x37\x33\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x65\x72\x73\x70\x65\x63\x74\ +\x69\x76\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x74\x79\x70\x65\x3d\x22\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x65\x72\x73\x70\x33\x64\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x70\x5f\x78\ +\x3d\x22\x30\x20\x3a\x20\x33\x32\x20\x3a\x20\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x70\ +\x5f\x79\x3d\x22\x30\x20\x3a\x20\x31\x30\x30\x30\x20\x3a\x20\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x70\x5f\x7a\x3d\x22\x36\x34\x20\x3a\x20\x33\x32\x20\ +\x3a\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x65\x72\x73\x70\x33\x64\x2d\x6f\x72\x69\ +\x67\x69\x6e\x3d\x22\x33\x32\x20\x3a\x20\x32\x31\x2e\x33\x33\x33\ +\x33\x33\x33\x20\x3a\x20\x31\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x70\x65\x72\x73\x70\x65\x63\x74\x69\x76\x65\x32\ +\x37\x34\x33\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x64\x65\x66\x73\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x62\x61\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x32\x2e\x37\x35\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x32\x36\ +\x2e\x30\x34\x38\x37\x38\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x37\x2e\x31\x39\ +\x37\x38\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\ +\x72\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x64\x6f\ +\x63\x75\x6d\x65\x6e\x74\x2d\x75\x6e\x69\x74\x73\x3d\x22\x70\x78\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x67\x72\x69\x64\x2d\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x32\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x35\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x32\ +\x37\x34\x30\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\ +\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\ +\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\ +\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\ +\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\ +\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ +\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x67\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6c\x61\x79\x65\x72\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x6c\x61\x62\x65\ +\x6c\x3d\x22\x4c\x61\x79\x65\x72\x20\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x72\x6f\x75\x70\x6d\ +\x6f\x64\x65\x3d\x22\x6c\x61\x79\x65\x72\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x74\x79\x70\x65\x3d\x22\x73\x74\x61\ +\x72\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\ +\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x64\x66\x30\x30\x3b\x66\x69\ +\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\x69\x6c\ +\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\x6e\x6f\x64\x64\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x35\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3a\x62\x75\x74\x74\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\ +\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\ +\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\ +\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x6f\x66\x66\ +\x73\x65\x74\x3a\x30\x3b\x6d\x61\x72\x6b\x65\x72\x3a\x6e\x6f\x6e\ +\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x64\x69\x73\x70\x6c\x61\x79\x3a\x69\x6e\x6c\ +\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3a\x76\x69\x73\ +\x69\x62\x6c\x65\x3b\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\ +\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\x75\x6d\x75\x6c\x61\x74\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x32\x36\x34\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x73\x69\x64\x65\x73\x3d\x22\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x3a\x63\x78\x3d\x22\x35\x31\x39\x2e\x36\x34\x32\x38\x38\x22\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\ +\x3a\x63\x79\x3d\x22\x39\x2e\x39\x32\x38\x35\x37\x30\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x72\x31\x3d\x22\x33\x31\x2e\x34\x33\x36\x36\x38\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\ +\x32\x3d\x22\x31\x35\x2e\x37\x31\x38\x33\x34\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x61\x72\ +\x67\x31\x3d\x22\x2d\x31\x2e\x35\x37\x30\x37\x39\x36\x33\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x61\x72\x67\x32\x3d\x22\x2d\x30\x2e\x35\x32\x33\x35\x39\x38\x37\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x66\x6c\x61\x74\x73\x69\x64\x65\x64\x3d\x22\x74\x72\ +\x75\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x72\x6f\x75\x6e\x64\x65\x64\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x72\x61\x6e\x64\x6f\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x35\x31\x39\x2e\x36\ +\x34\x32\x38\x38\x2c\x2d\x32\x31\x2e\x35\x30\x38\x31\x31\x37\x20\ +\x32\x37\x2e\x32\x32\x34\x39\x37\x2c\x34\x37\x2e\x31\x35\x35\x30\ +\x33\x32\x20\x2d\x35\x34\x2e\x34\x34\x39\x39\x34\x2c\x2d\x31\x65\ +\x2d\x36\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ +\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\ +\x2c\x2d\x30\x2e\x35\x39\x30\x36\x39\x33\x32\x36\x2c\x30\x2e\x33\ +\x37\x33\x33\x32\x34\x31\x39\x2c\x30\x2c\x31\x36\x2e\x37\x39\x38\ +\x34\x39\x35\x2c\x33\x32\x37\x2e\x32\x34\x35\x38\x39\x29\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x78\x64\x70\x69\x3d\x22\x32\x38\x2e\ +\x39\x30\x39\x39\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x79\ +\x64\x70\x69\x3d\x22\x32\x38\x2e\x39\x30\x39\x39\x35\x36\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x74\x79\x70\ +\x65\x3d\x22\x73\x74\x61\x72\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x66\x66\x64\ +\x66\x30\x30\x3b\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\ +\x3a\x31\x3b\x66\x69\x6c\x6c\x2d\x72\x75\x6c\x65\x3a\x65\x76\x65\ +\x6e\x6f\x64\x64\x3b\x73\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\ +\x30\x30\x30\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\ +\x3a\x35\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\ +\x70\x3a\x62\x75\x74\x74\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\ +\x6e\x65\x6a\x6f\x69\x6e\x3a\x6d\x69\x74\x65\x72\x3b\x73\x74\x72\ +\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3a\x34\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\ +\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\x68\x61\x72\x72\ +\x61\x79\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\ +\x61\x73\x68\x6f\x66\x66\x73\x65\x74\x3a\x30\x3b\x6d\x61\x72\x6b\ +\x65\x72\x3a\x6e\x6f\x6e\x65\x3b\x76\x69\x73\x69\x62\x69\x6c\x69\ +\x74\x79\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x64\x69\x73\x70\x6c\ +\x61\x79\x3a\x69\x6e\x6c\x69\x6e\x65\x3b\x6f\x76\x65\x72\x66\x6c\ +\x6f\x77\x3a\x76\x69\x73\x69\x62\x6c\x65\x3b\x65\x6e\x61\x62\x6c\ +\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x61\x63\x63\ +\x75\x6d\x75\x6c\x61\x74\x65\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x70\x61\x74\x68\x32\x36\x34\x34\x2d\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\ +\x73\x69\x64\x65\x73\x3d\x22\x33\x22\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x63\x78\x3d\x22\x35\x31\ +\x39\x2e\x36\x34\x32\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x63\x79\x3d\x22\x39\x2e\x39\ +\x32\x38\x35\x37\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x72\x31\x3d\x22\x33\x31\x2e\x34\ +\x33\x36\x36\x38\x37\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x72\x32\x3d\x22\x31\x35\x2e\x37\x31\ +\x38\x33\x34\x34\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x61\x72\x67\x31\x3d\x22\x2d\x31\x2e\x35\ +\x37\x30\x37\x39\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x61\x72\x67\x32\x3d\x22\x2d\x30\ +\x2e\x35\x32\x33\x35\x39\x38\x37\x38\x22\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x66\x6c\x61\x74\x73\ +\x69\x64\x65\x64\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x72\x6f\x75\x6e\ +\x64\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x72\x61\x6e\x64\x6f\x6d\x69\x7a\ +\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x6d\x20\x35\x31\x39\x2e\x36\x34\x32\x38\x38\x2c\x2d\x32\x31\ +\x2e\x35\x30\x38\x31\x31\x37\x20\x32\x37\x2e\x32\x32\x34\x39\x37\ +\x2c\x34\x37\x2e\x31\x35\x35\x30\x33\x32\x20\x2d\x35\x34\x2e\x34\ +\x34\x39\x39\x34\x2c\x2d\x31\x65\x2d\x36\x20\x7a\x22\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\ +\x6d\x61\x74\x72\x69\x78\x28\x30\x2c\x30\x2e\x35\x39\x30\x36\x39\ +\x33\x32\x36\x2c\x2d\x30\x2e\x33\x37\x33\x33\x32\x34\x31\x39\x2c\ +\x30\x2c\x34\x36\x2e\x34\x39\x35\x36\x37\x34\x2c\x2d\x32\x38\x36\ +\x2e\x36\x35\x33\x32\x29\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x65\x78\x70\x6f\x72\x74\x2d\x78\ +\x64\x70\x69\x3d\x22\x32\x38\x2e\x39\x30\x39\x39\x35\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x65\x78\x70\x6f\x72\x74\x2d\x79\x64\x70\x69\x3d\x22\x32\x38\x2e\ +\x39\x30\x39\x39\x35\x36\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x66\x69\x6c\x6c\x3a\x23\x30\x30\x39\x32\x66\x66\x3b\ +\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\ +\x74\x72\x6f\x6b\x65\x3a\x23\x30\x30\x30\x35\x33\x32\x3b\x73\x74\ +\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3a\x32\x2e\x38\x34\x38\ +\x34\x37\x32\x31\x32\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\ +\x65\x63\x61\x70\x3a\x72\x6f\x75\x6e\x64\x3b\x73\x74\x72\x6f\x6b\ +\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3a\x72\x6f\x75\x6e\x64\ +\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\ +\x69\x74\x3a\x34\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\ +\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x64\x61\x73\ +\x68\x61\x72\x72\x61\x79\x3a\x6e\x6f\x6e\x65\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x36\x30\x2e\x36\x30\x39\x39\ +\x39\x31\x2c\x33\x38\x2e\x33\x39\x35\x34\x37\x37\x20\x2d\x31\x38\ +\x2e\x36\x34\x36\x36\x31\x39\x2c\x2d\x31\x2e\x38\x37\x36\x39\x37\ +\x38\x20\x32\x2e\x39\x36\x38\x36\x38\x32\x2c\x35\x2e\x35\x39\x30\ +\x31\x38\x20\x63\x20\x30\x2c\x30\x20\x2d\x35\x2e\x38\x37\x30\x35\ +\x37\x32\x2c\x37\x2e\x38\x31\x33\x31\x31\x20\x2d\x31\x36\x2e\x38\ +\x38\x35\x39\x38\x32\x2c\x34\x2e\x39\x31\x31\x32\x31\x33\x20\x43\ +\x20\x31\x39\x2e\x31\x37\x33\x36\x36\x31\x2c\x34\x34\x2e\x36\x38\ +\x32\x35\x34\x35\x20\x31\x34\x2e\x39\x30\x38\x39\x30\x36\x2c\x33\ +\x32\x2e\x36\x37\x38\x34\x30\x31\x20\x31\x34\x2e\x39\x30\x38\x39\ +\x30\x36\x2c\x33\x32\x2e\x36\x37\x38\x34\x30\x31\x20\x4c\x20\x34\ +\x2e\x36\x33\x38\x32\x38\x35\x35\x2c\x33\x39\x2e\x39\x31\x33\x39\ +\x36\x34\x20\x63\x20\x30\x2c\x30\x20\x36\x2e\x33\x33\x31\x33\x34\ +\x38\x35\x2c\x31\x34\x2e\x39\x32\x39\x33\x39\x35\x20\x31\x39\x2e\ +\x37\x37\x38\x36\x39\x34\x35\x2c\x31\x38\x2e\x35\x36\x36\x30\x31\ +\x36\x20\x31\x32\x2e\x39\x37\x32\x35\x31\x31\x2c\x33\x2e\x35\x30\ +\x38\x32\x20\x32\x35\x2e\x34\x35\x35\x31\x34\x38\x2c\x2d\x36\x2e\ +\x32\x37\x33\x34\x30\x36\x20\x32\x35\x2e\x34\x35\x35\x31\x34\x38\ +\x2c\x2d\x36\x2e\x32\x37\x33\x34\x30\x36\x20\x6c\x20\x32\x2e\x34\ +\x32\x30\x32\x33\x33\x2c\x34\x2e\x35\x38\x37\x38\x30\x39\x20\x7a\ +\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x30\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x20\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\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\x22\x63\x63\x63\x73\x63\x63\ +\x73\x63\x63\x63\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ \x00\x00\x0a\x7e\ \x00\ \x00\x39\x49\x78\x9c\xe5\x5b\x59\x6f\xe3\xba\x15\x7e\xcf\xaf\x50\ @@ -54152,6 +54439,11 @@ qt_resource_name = "\ \x00\x53\ \x00\x6e\x00\x61\x00\x70\x00\x5f\x00\x44\x00\x69\x00\x6d\x00\x65\x00\x6e\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2e\x00\x73\ \x00\x76\x00\x67\ +\x00\x17\ +\x04\x0e\xae\x07\ +\x00\x44\ +\x00\x72\x00\x61\x00\x66\x00\x74\x00\x5f\x00\x46\x00\x6c\x00\x69\x00\x70\x00\x44\x00\x69\x00\x6d\x00\x65\x00\x6e\x00\x73\x00\x69\ +\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x12\ \x0d\xee\x82\xc7\ \x00\x44\ @@ -54180,8 +54472,8 @@ qt_resource_name = "\ qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ -\x00\x00\x00\x10\x00\x02\x00\x00\x00\x03\x00\x00\x00\x5b\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x3a\x00\x00\x00\x21\ +\x00\x00\x00\x10\x00\x02\x00\x00\x00\x03\x00\x00\x00\x5c\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x3b\x00\x00\x00\x21\ \x00\x00\x00\x38\x00\x02\x00\x00\x00\x05\x00\x00\x00\x1c\ \x00\x00\x00\x1a\x00\x02\x00\x00\x00\x17\x00\x00\x00\x05\ \x00\x00\x01\xb4\x00\x01\x00\x00\x00\x01\x00\x04\x13\x04\ @@ -54212,66 +54504,67 @@ qt_resource_struct = "\ \x00\x00\x00\x64\x00\x01\x00\x00\x00\x01\x00\x00\x0a\xf1\ \x00\x00\x00\x96\x00\x01\x00\x00\x00\x01\x00\x00\x13\x00\ \x00\x00\x00\x7c\x00\x01\x00\x00\x00\x01\x00\x00\x0f\x23\ -\x00\x00\x06\xfa\x00\x01\x00\x00\x00\x01\x00\x0b\x0c\x42\ -\x00\x00\x04\xa8\x00\x00\x00\x00\x00\x01\x00\x0a\x69\x2b\ -\x00\x00\x09\x8e\x00\x01\x00\x00\x00\x01\x00\x0b\xef\xaa\ -\x00\x00\x0c\x4a\x00\x01\x00\x00\x00\x01\x00\x0c\xdb\x58\ -\x00\x00\x05\xb2\x00\x01\x00\x00\x00\x01\x00\x0a\xa8\xd6\ -\x00\x00\x07\x70\x00\x00\x00\x00\x00\x01\x00\x0b\x35\xfe\ -\x00\x00\x08\x84\x00\x01\x00\x00\x00\x01\x00\x0b\x9e\xac\ -\x00\x00\x0b\x80\x00\x01\x00\x00\x00\x01\x00\x0c\xa2\x72\ -\x00\x00\x07\xe4\x00\x00\x00\x00\x00\x01\x00\x0b\x5f\xcd\ -\x00\x00\x0a\x28\x00\x01\x00\x00\x00\x01\x00\x0c\x30\x4b\ -\x00\x00\x0c\x9a\x00\x01\x00\x00\x00\x01\x00\x0c\xf7\x7c\ -\x00\x00\x04\xee\x00\x01\x00\x00\x00\x01\x00\x0a\x82\x4d\ -\x00\x00\x09\x36\x00\x00\x00\x00\x00\x01\x00\x0b\xcd\x50\ -\x00\x00\x08\xaa\x00\x01\x00\x00\x00\x01\x00\x0b\xa4\x70\ -\x00\x00\x07\x4a\x00\x00\x00\x00\x00\x01\x00\x0b\x23\x68\ -\x00\x00\x07\x1c\x00\x01\x00\x00\x00\x01\x00\x0b\x16\xf6\ -\x00\x00\x05\x12\x00\x01\x00\x00\x00\x01\x00\x0a\x87\xcc\ -\x00\x00\x07\xb8\x00\x01\x00\x00\x00\x01\x00\x0b\x4e\xc3\ -\x00\x00\x04\xca\x00\x01\x00\x00\x00\x01\x00\x0a\x77\xe1\ -\x00\x00\x0b\xa8\x00\x00\x00\x00\x00\x01\x00\x0c\xad\xe1\ -\x00\x00\x04\x28\x00\x01\x00\x00\x00\x01\x00\x0a\x43\x99\ -\x00\x00\x06\x02\x00\x01\x00\x00\x00\x01\x00\x0a\xc3\xf5\ -\x00\x00\x0b\x38\x00\x01\x00\x00\x00\x01\x00\x0c\x8b\x43\ -\x00\x00\x0b\x5a\x00\x01\x00\x00\x00\x01\x00\x0c\x98\xde\ -\x00\x00\x05\xe0\x00\x00\x00\x00\x00\x01\x00\x0a\xb1\xdc\ -\x00\x00\x03\xf6\x00\x01\x00\x00\x00\x01\x00\x0a\x3b\xe0\ -\x00\x00\x09\x14\x00\x01\x00\x00\x00\x01\x00\x0b\xc5\xfc\ -\x00\x00\x0a\x82\x00\x00\x00\x00\x00\x01\x00\x0c\x40\x93\ -\x00\x00\x06\x56\x00\x01\x00\x00\x00\x01\x00\x0a\xd5\x65\ -\x00\x00\x0a\xa6\x00\x00\x00\x00\x00\x01\x00\x0c\x57\x46\ -\x00\x00\x08\x3e\x00\x00\x00\x00\x00\x01\x00\x0b\x77\x80\ -\x00\x00\x05\x64\x00\x01\x00\x00\x00\x01\x00\x0a\x97\xcc\ -\x00\x00\x0c\x6a\x00\x00\x00\x00\x00\x01\x00\x0c\xe6\x06\ -\x00\x00\x06\xb0\x00\x00\x00\x00\x00\x01\x00\x0a\xec\xa4\ -\x00\x00\x04\x54\x00\x00\x00\x00\x00\x01\x00\x0a\x4b\xa0\ -\x00\x00\x0c\xca\x00\x00\x00\x00\x00\x01\x00\x0d\x03\x55\ -\x00\x00\x0a\xee\x00\x00\x00\x00\x00\x01\x00\x0c\x74\xcd\ -\x00\x00\x04\x78\x00\x01\x00\x00\x00\x01\x00\x0a\x60\xc0\ -\x00\x00\x0b\x16\x00\x01\x00\x00\x00\x01\x00\x0c\x83\xf4\ -\x00\x00\x09\xb0\x00\x01\x00\x00\x00\x01\x00\x0b\xf8\x53\ -\x00\x00\x0b\xce\x00\x01\x00\x00\x00\x01\x00\x0c\xb6\x6e\ -\x00\x00\x06\xd8\x00\x01\x00\x00\x00\x01\x00\x0a\xfe\xe3\ -\x00\x00\x08\x16\x00\x01\x00\x00\x00\x01\x00\x0b\x6d\xcf\ -\x00\x00\x0a\x06\x00\x00\x00\x00\x00\x01\x00\x0c\x1b\xba\ -\x00\x00\x05\x88\x00\x01\x00\x00\x00\x01\x00\x0a\x9e\x95\ -\x00\x00\x08\x64\x00\x00\x00\x00\x00\x01\x00\x0b\x89\x38\ -\x00\x00\x06\x36\x00\x01\x00\x00\x00\x01\x00\x0a\xcf\xe6\ -\x00\x00\x0a\x52\x00\x01\x00\x00\x00\x01\x00\x0c\x36\xc0\ -\x00\x00\x08\xec\x00\x01\x00\x00\x00\x01\x00\x0b\xba\x8a\ -\x00\x00\x09\x66\x00\x01\x00\x00\x00\x01\x00\x0b\xdf\xd4\ -\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x0c\xd0\xd6\ -\x00\x00\x0a\xca\x00\x01\x00\x00\x00\x01\x00\x0c\x6a\x1d\ -\x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x0a\x8f\xaa\ -\x00\x00\x0b\xf4\x00\x01\x00\x00\x00\x01\x00\x0c\xc1\x33\ -\x00\x00\x08\xcc\x00\x00\x00\x00\x00\x01\x00\x0b\xaa\xb8\ -\x00\x00\x06\x84\x00\x00\x00\x00\x00\x01\x00\x0a\xdd\x4a\ -\x00\x00\x07\x98\x00\x01\x00\x00\x00\x01\x00\x0b\x45\x4f\ -\x00\x00\x09\xd4\x00\x00\x00\x00\x00\x01\x00\x0b\xff\xa4\ -\x00\x00\x03\xa2\x00\x01\x00\x00\x00\x01\x00\x0a\x27\x25\ -\x00\x00\x03\xce\x00\x01\x00\x00\x00\x01\x00\x0a\x31\xa0\ +\x00\x00\x06\xfa\x00\x01\x00\x00\x00\x01\x00\x0b\x0c\xf5\ +\x00\x00\x04\xa8\x00\x00\x00\x00\x00\x01\x00\x0a\x69\xde\ +\x00\x00\x09\x8e\x00\x01\x00\x00\x00\x01\x00\x0b\xf0\x5d\ +\x00\x00\x0c\x7e\x00\x01\x00\x00\x00\x01\x00\x0c\xed\x27\ +\x00\x00\x05\xb2\x00\x01\x00\x00\x00\x01\x00\x0a\xa9\x89\ +\x00\x00\x07\x70\x00\x00\x00\x00\x00\x01\x00\x0b\x36\xb1\ +\x00\x00\x08\x84\x00\x01\x00\x00\x00\x01\x00\x0b\x9f\x5f\ +\x00\x00\x0b\x80\x00\x01\x00\x00\x00\x01\x00\x0c\xa3\x25\ +\x00\x00\x07\xe4\x00\x00\x00\x00\x00\x01\x00\x0b\x60\x80\ +\x00\x00\x0a\x28\x00\x01\x00\x00\x00\x01\x00\x0c\x30\xfe\ +\x00\x00\x0c\xce\x00\x01\x00\x00\x00\x01\x00\x0d\x09\x4b\ +\x00\x00\x04\xee\x00\x01\x00\x00\x00\x01\x00\x0a\x83\x00\ +\x00\x00\x09\x36\x00\x00\x00\x00\x00\x01\x00\x0b\xce\x03\ +\x00\x00\x08\xaa\x00\x01\x00\x00\x00\x01\x00\x0b\xa5\x23\ +\x00\x00\x07\x4a\x00\x00\x00\x00\x00\x01\x00\x0b\x24\x1b\ +\x00\x00\x07\x1c\x00\x01\x00\x00\x00\x01\x00\x0b\x17\xa9\ +\x00\x00\x0c\x20\x00\x00\x00\x00\x00\x01\x00\x0c\xd1\x89\ +\x00\x00\x05\x12\x00\x01\x00\x00\x00\x01\x00\x0a\x88\x7f\ +\x00\x00\x07\xb8\x00\x01\x00\x00\x00\x01\x00\x0b\x4f\x76\ +\x00\x00\x04\xca\x00\x01\x00\x00\x00\x01\x00\x0a\x78\x94\ +\x00\x00\x0b\xa8\x00\x00\x00\x00\x00\x01\x00\x0c\xae\x94\ +\x00\x00\x04\x28\x00\x01\x00\x00\x00\x01\x00\x0a\x44\x4c\ +\x00\x00\x06\x02\x00\x01\x00\x00\x00\x01\x00\x0a\xc4\xa8\ +\x00\x00\x0b\x38\x00\x01\x00\x00\x00\x01\x00\x0c\x8b\xf6\ +\x00\x00\x0b\x5a\x00\x01\x00\x00\x00\x01\x00\x0c\x99\x91\ +\x00\x00\x05\xe0\x00\x00\x00\x00\x00\x01\x00\x0a\xb2\x8f\ +\x00\x00\x03\xf6\x00\x01\x00\x00\x00\x01\x00\x0a\x3c\x93\ +\x00\x00\x09\x14\x00\x01\x00\x00\x00\x01\x00\x0b\xc6\xaf\ +\x00\x00\x0a\x82\x00\x00\x00\x00\x00\x01\x00\x0c\x41\x46\ +\x00\x00\x06\x56\x00\x01\x00\x00\x00\x01\x00\x0a\xd6\x18\ +\x00\x00\x0a\xa6\x00\x00\x00\x00\x00\x01\x00\x0c\x57\xf9\ +\x00\x00\x08\x3e\x00\x00\x00\x00\x00\x01\x00\x0b\x78\x33\ +\x00\x00\x05\x64\x00\x01\x00\x00\x00\x01\x00\x0a\x98\x7f\ +\x00\x00\x0c\x9e\x00\x00\x00\x00\x00\x01\x00\x0c\xf7\xd5\ +\x00\x00\x06\xb0\x00\x00\x00\x00\x00\x01\x00\x0a\xed\x57\ +\x00\x00\x04\x54\x00\x00\x00\x00\x00\x01\x00\x0a\x4c\x53\ +\x00\x00\x0c\xfe\x00\x00\x00\x00\x00\x01\x00\x0d\x15\x24\ +\x00\x00\x0a\xee\x00\x00\x00\x00\x00\x01\x00\x0c\x75\x80\ +\x00\x00\x04\x78\x00\x01\x00\x00\x00\x01\x00\x0a\x61\x73\ +\x00\x00\x0b\x16\x00\x01\x00\x00\x00\x01\x00\x0c\x84\xa7\ +\x00\x00\x09\xb0\x00\x01\x00\x00\x00\x01\x00\x0b\xf9\x06\ +\x00\x00\x0b\xce\x00\x01\x00\x00\x00\x01\x00\x0c\xb7\x21\ +\x00\x00\x06\xd8\x00\x01\x00\x00\x00\x01\x00\x0a\xff\x96\ +\x00\x00\x08\x16\x00\x01\x00\x00\x00\x01\x00\x0b\x6e\x82\ +\x00\x00\x0a\x06\x00\x00\x00\x00\x00\x01\x00\x0c\x1c\x6d\ +\x00\x00\x05\x88\x00\x01\x00\x00\x00\x01\x00\x0a\x9f\x48\ +\x00\x00\x08\x64\x00\x00\x00\x00\x00\x01\x00\x0b\x89\xeb\ +\x00\x00\x06\x36\x00\x01\x00\x00\x00\x01\x00\x0a\xd0\x99\ +\x00\x00\x0a\x52\x00\x01\x00\x00\x00\x01\x00\x0c\x37\x73\ +\x00\x00\x08\xec\x00\x01\x00\x00\x00\x01\x00\x0b\xbb\x3d\ +\x00\x00\x09\x66\x00\x01\x00\x00\x00\x01\x00\x0b\xe0\x87\ +\x00\x00\x0c\x54\x00\x01\x00\x00\x00\x01\x00\x0c\xe2\xa5\ +\x00\x00\x0a\xca\x00\x01\x00\x00\x00\x01\x00\x0c\x6a\xd0\ +\x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x0a\x90\x5d\ +\x00\x00\x0b\xf4\x00\x01\x00\x00\x00\x01\x00\x0c\xc1\xe6\ +\x00\x00\x08\xcc\x00\x00\x00\x00\x00\x01\x00\x0b\xab\x6b\ +\x00\x00\x06\x84\x00\x00\x00\x00\x00\x01\x00\x0a\xdd\xfd\ +\x00\x00\x07\x98\x00\x01\x00\x00\x00\x01\x00\x0b\x46\x02\ +\x00\x00\x09\xd4\x00\x00\x00\x00\x00\x01\x00\x0c\x00\x57\ +\x00\x00\x03\xa2\x00\x01\x00\x00\x00\x01\x00\x0a\x27\xd8\ +\x00\x00\x03\xce\x00\x01\x00\x00\x00\x01\x00\x0a\x32\x53\ \x00\x00\x03\x76\x00\x01\x00\x00\x00\x01\x00\x0a\x1c\x55\ " diff --git a/src/Mod/Draft/InitGui.py b/src/Mod/Draft/InitGui.py index d19048f8b..8dfabdf95 100644 --- a/src/Mod/Draft/InitGui.py +++ b/src/Mod/Draft/InitGui.py @@ -117,7 +117,7 @@ class DraftWorkbench (Workbench): "Draft_SelectGroup","Draft_SelectPlane", "Draft_ShowSnapBar","Draft_ToggleGrid"] self.lineList = ["Draft_UndoLine","Draft_FinishLine","Draft_CloseLine"] - self.utils = ["Draft_Heal"] + self.utils = ["Draft_Heal","Draft_FlipDimension"] self.snapList = ['Draft_Snap_Lock','Draft_Snap_Midpoint','Draft_Snap_Perpendicular', 'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel', 'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center', diff --git a/src/Mod/Draft/Resources/Draft.qrc b/src/Mod/Draft/Resources/Draft.qrc index a4115ac39..802231c41 100644 --- a/src/Mod/Draft/Resources/Draft.qrc +++ b/src/Mod/Draft/Resources/Draft.qrc @@ -58,6 +58,7 @@ icons/Draft_Ellipse.svg icons/Draft_ShapeString.svg icons/Draft_Facebinder.svg + icons/Draft_FlipDimension.svg patterns/concrete.svg patterns/cross.svg patterns/line.svg diff --git a/src/Mod/Draft/Resources/icons/Draft_FlipDimension.svg b/src/Mod/Draft/Resources/icons/Draft_FlipDimension.svg new file mode 100644 index 000000000..05f9ab96d --- /dev/null +++ b/src/Mod/Draft/Resources/icons/Draft_FlipDimension.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/Mod/Draft/Resources/ui/userprefs-visual.ui b/src/Mod/Draft/Resources/ui/userprefs-visual.ui index 091a21fbb..0217cf0f7 100644 --- a/src/Mod/Draft/Resources/ui/userprefs-visual.ui +++ b/src/Mod/Draft/Resources/ui/userprefs-visual.ui @@ -543,12 +543,12 @@ - Default text height + Texts - + Qt::Horizontal @@ -560,6 +560,51 @@ + + + + font + + + + + + + + 200 + 0 + + + + This is the default font name for all Draft texts and dimensions. +It can be a font name such as "Arial", a default style such as "sans", "serif" +or "mono", or a family such as "Arial,Helvetica,sans" or a name with a style +such as "Arial:Bold" + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Internal font + + + textfont + + + Mod/Draft + + + + + + + size + + + @@ -585,16 +630,16 @@ - + - + - Default text font + Dimensions arrows - + Qt::Horizontal @@ -607,38 +652,9 @@ - - - This is the default font name for all Draft texts and dimensions. -It can be a font name such as "Arial", a default style such as "sans", "serif" -or "mono", or a family such as "Arial,Helvetica,sans" or a name with a style -such as "Arial:Bold" - + - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - Internal font - - - textfont - - - Mod/Draft - - - - - - - - - - - Dimensions & Leader arrow style + style @@ -652,66 +668,124 @@ such as "Arial:Bold" - Dot 5 + Dot - Dot 7 + Circle - Dot 9 + Arrow + + + + + + + + size + + + + + + + The default size of arrows + + + 0.100000000000000 + + + arrowsize + + + Mod/Draft + + + + + + + + + + + Dimensions lines + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + style + + + + + + + + 100 + 0 + + + + dimstyle + + + Mod/Draft + + + + text above - Circle 5 - - - - - Circle 7 - - - - - Circle 9 - - - - - Slash 5 - - - - - Slash 7 - - - - - Slash 9 - - - - - Backslash 5 - - - - - Backslash 7 - - - - - Backslash 9 + text inside + + + + size + + + + + + + The default size of dimensions extension lines + + + 0.300000000000000 + + + extlines + + + Mod/Draft + + + @@ -719,7 +793,27 @@ such as "Arial:Bold" - Vertical dimensions text orientation + Dimensions text + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + orientation @@ -746,6 +840,29 @@ such as "Arial:Bold" + + + + spacing + + + + + + + The space between the dimension line and the dimension text + + + 0.050000000000000 + + + dimspacing + + + Mod/Draft + + + diff --git a/src/Mod/Draft/WorkingPlane.py b/src/Mod/Draft/WorkingPlane.py index 10d444ae2..25a0c3f69 100644 --- a/src/Mod/Draft/WorkingPlane.py +++ b/src/Mod/Draft/WorkingPlane.py @@ -36,16 +36,16 @@ This module provides a class called plane to assist in selecting and maintaining class plane: '''A WorkPlane object''' - def __init__(self): + def __init__(self,u=Vector(1,0,0),v=Vector(0,1,0),w=Vector(0,0,1),pos=Vector(0,0,0)): # keep track of active document. Reset view when doc changes. self.doc = None # self.weak is true if the plane has been defined by self.setup or has been reset self.weak = True # u, v axes and position define plane, perpendicular axis is handy, though redundant. - self.u = Vector(1,0,0) - self.v = Vector(0,1,0) - self.axis = Vector(0,0,1) - self.position = Vector(0,0,0) + self.u = u + self.v = v + self.axis = w + self.position = pos # a placeholder for a stored state self.stored = None @@ -325,6 +325,23 @@ class plane: if self.axis != Vector(0,0,1): return False return True + + def isOrtho(self): + "returns True if the plane axes are following the global axes" + if round(self.u.getAngle(Vector(0,1,0)),6) in [0,-1.570796,1.570796,-3.141593,3.141593,-4.712389,4.712389,6.283185]: + if round(self.v.getAngle(Vector(0,1,0)),6) in [0,-1.570796,1.570796,-3.141593,3.141593,-4.712389,4.712389,6.283185]: + if round(self.axis.getAngle(Vector(0,1,0)),6) in [0,-1.570796,1.570796,-3.141593,3.141593,-4.712389,4.712389,6.283185]: + return True + return False + + def getDeviation(self): + "returns the deviation angle between the u axis and the horizontal plane" + proj = Vector(self.u.x,self.u.y,0) + if self.u.getAngle(proj) == 0: + return 0 + else: + norm = proj.cross(self.u) + return DraftVecUtils.angle(self.u,proj,norm) def getPlacementFromPoints(points): "returns a placement from a list of 3 or 4 vectors"