From 99b7dbb6f3f7ac9ef280c3707f6af8270e0b1196 Mon Sep 17 00:00:00 2001 From: Branislav Stojkovic Date: Mon, 4 Feb 2019 15:15:12 +0100 Subject: [PATCH] editable label color for tubes --- .../org/diylc/components/tube/TubeSocket.java | 172 +++++++++++++----- diylc/diylc-swing/library/main.jar | Bin 576808 -> 578348 bytes diylc/diylc-swing/update.xml | 2 +- 3 files changed, 131 insertions(+), 43 deletions(-) diff --git a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java index 825eba33..e3b8560c 100644 --- a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java +++ b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java @@ -21,32 +21,36 @@ */ package org.diylc.components.tube; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Shape; -import java.awt.geom.Area; -import java.awt.geom.Ellipse2D; - -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.common.IPlugInPort; -import org.diylc.common.ObjectCache; -import org.diylc.common.Orientation; -import org.diylc.components.AbstractTransparentComponent; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.Theme; -import org.diylc.core.VisibilityPolicy; -import org.diylc.core.annotations.ComponentDescriptor; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.core.annotations.KeywordPolicy; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; -import org.diylc.utils.Constants; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Rectangle2D; + +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.common.VerticalAlignment; +import org.diylc.components.AbstractTransparentComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.utils.Constants; @ComponentDescriptor(name = "Tube Socket", author = "Branislav Stojkovic", category = "Tubes", instanceNamePrefix = "V", description = "Various types of tube/valve sockets", stretchable = false, @@ -55,10 +59,13 @@ public class TubeSocket extends AbstractTransparentComponent { private static final long serialVersionUID = 1L; - private static Color BODY_COLOR = Color.decode("#F7F7EF"); + private static Color BODY_COLOR = Color.decode("#F7F7EF"); + private static Color LABEL_COLOR = BODY_COLOR.darker(); public static Color PIN_COLOR = Color.decode("#00B2EE"); public static Color PIN_BORDER_COLOR = PIN_COLOR.darker(); - public static Size PIN_SIZE = new Size(1d, SizeUnit.mm); + public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm); + private static Size PIN_WIDTH = new Size(0.08d, SizeUnit.in); + private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in); public static Size HOLE_SIZE = new Size(5d, SizeUnit.mm); public static Size TICK_SIZE = new Size(2d, SizeUnit.mm); @@ -68,7 +75,10 @@ public class TubeSocket extends AbstractTransparentComponent { private Orientation orientation; // private Mount mount = Mount.CHASSIS; private int angle; - private Color color = BODY_COLOR; + private Color color = BODY_COLOR; + private String electrodeLabels = null; + private Mount mount = null; + private Color labelColor = LABEL_COLOR; private Point[] controlPoints = new Point[] {new Point(0, 0)}; @@ -157,7 +167,7 @@ public class TubeSocket extends AbstractTransparentComponent { break; case B9A: pinCount = 9; - pinCircleDiameter = getClosestOdd(new Size(21d, SizeUnit.mm).convertToPixels()); + pinCircleDiameter = getClosestOdd(getMount() == Mount.PCB ? new Size(21d, SizeUnit.mm).convertToPixels() : new Size(12.5d, SizeUnit.mm).convertToPixels()); hasEmptySpace = true; break; default: @@ -185,10 +195,10 @@ public class TubeSocket extends AbstractTransparentComponent { bodyDiameter = getClosestOdd(new Size(17d, SizeUnit.mm).convertToPixels()); break; case B9A: - bodyDiameter = getClosestOdd(new Size(19d, SizeUnit.mm).convertToPixels()); + bodyDiameter = getClosestOdd(new Size(3 / 4d, SizeUnit.in).convertToPixels()); break; case OCTAL: - bodyDiameter = getClosestOdd(new Size(24.5d, SizeUnit.mm).convertToPixels()); + bodyDiameter = getClosestOdd(new Size(25d, SizeUnit.mm).convertToPixels()); break; default: throw new RuntimeException("Unexpected base: " + base); @@ -199,15 +209,25 @@ public class TubeSocket extends AbstractTransparentComponent { Area bodyArea = new Area(body); int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels()); bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - holeSize / 2, controlPoints[0].y - holeSize - / 2, holeSize, holeSize))); + / 2, holeSize, holeSize))); + if (base == Base.OCTAL) { int tickSize = getClosestOdd(TICK_SIZE.convertToPixels()); double theta = Math.toRadians(getAngle()); int centerX = (int) (controlPoints[0].x + Math.cos(theta) * holeSize / 2); int centerY = (int) (controlPoints[0].y + Math.sin(theta) * holeSize / 2); bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY - tickSize / 2, tickSize, - tickSize))); - } + tickSize))); + } else if (base == Base.B9A && getMount() == Mount.CHASSIS) { + double cutoutDiameter = getClosestOdd(new Size(5.5d, SizeUnit.mm).convertToPixels()); + bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - cutoutDiameter / 2, controlPoints[0].y - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter))); + bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - cutoutDiameter / 2, controlPoints[0].y + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter))); + } else if (base == Base.B7G && getMount() == Mount.CHASSIS) { + double cutoutDiameter = getClosestOdd(new Size(4d, SizeUnit.mm).convertToPixels()); + bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - cutoutDiameter / 2, controlPoints[0].y - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter))); + bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - cutoutDiameter / 2, controlPoints[0].y + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter))); + } + body = bodyArea; } return body; @@ -246,16 +266,46 @@ public class TubeSocket extends AbstractTransparentComponent { : getColor().darker(); } g2d.setColor(finalBorderColor); - g2d.draw(body); + g2d.draw(body); + // Draw pins - if (!outlineMode) { - int pinSize = getClosestOdd(PIN_SIZE.convertToPixels()); - for (int i = 1; i < controlPoints.length; i++) { + if (!outlineMode) { + for (int i = 1; i < controlPoints.length; i++) { + Shape pinShape; + if (getMount() == Mount.PCB) { + int pinSize = getClosestOdd(PIN_DIAMETER.convertToPixels()); + pinShape = new Ellipse2D.Double(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2, pinSize, pinSize); + } else { + int pinWidth = getClosestOdd(PIN_WIDTH.convertToPixels()); + int pinThickness = getClosestOdd(PIN_THICKNESS.convertToPixels()); + pinShape = new Rectangle2D.Double(controlPoints[i].x - pinWidth / 2, controlPoints[i].y - pinThickness / 2, pinWidth, pinThickness); + double theta = Math.atan2(controlPoints[i].y - controlPoints[0].y, controlPoints[i].x - controlPoints[0].x) + Math.PI / 2; + Area rotatedPin = new Area(pinShape); + rotatedPin.transform(AffineTransform.getRotateInstance(theta, controlPoints[i].x, controlPoints[i].y)); + pinShape = rotatedPin; + } g2d.setColor(PIN_COLOR); - g2d.fillOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2, pinSize, pinSize); + g2d.fill(pinShape); g2d.setColor(PIN_BORDER_COLOR); - g2d.drawOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2, pinSize, pinSize); + g2d.fill(pinShape); } + } + + // draw labels + if (electrodeLabels != null) { + g2d.setColor(getLabelColor()); + g2d.setFont(project.getFont().deriveFont((float) (project.getFont().getSize2D() * 0.8))); + String[] labels = electrodeLabels.split(","); + double electrodeLabelOffset = project.getFont().getSize2D() * (getBase() == Base.B9A && getMount() == Mount.PCB ? 1.5 : 1); + for (int i = 0; i < labels.length; i++) { + if (i < controlPoints.length - 1) { + String label = labels[i]; + double theta = Math.atan2(controlPoints[i + 1].y - controlPoints[0].y, controlPoints[i + 1].x - controlPoints[0].x); + double x = controlPoints[i + 1].x - Math.cos(theta) * electrodeLabelOffset; + double y = controlPoints[i + 1].y - Math.sin(theta) * electrodeLabelOffset; + drawCenteredText(g2d, label, (int)x, (int)y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + } + } } } @@ -313,8 +363,46 @@ public class TubeSocket extends AbstractTransparentComponent { @Override public void setControlPoint(Point point, int index) { - controlPoints[index].setLocation(point); + controlPoints[index].setLocation(point); + body = null; + } + + @EditableProperty(name = "Electrode Labels") + public String getElectrodeLabels() { + if (electrodeLabels == null) + electrodeLabels = "1,2,3,4,5,6,7,8,9"; + return electrodeLabels; + } + + public void setElectrodeLabels(String electrodeLabels) { + this.electrodeLabels = electrodeLabels; + } + + @EditableProperty(name = "Label") + public Color getLabelColor() { + if (labelColor == null) + labelColor = LABEL_COLOR; + return labelColor; + } + + public void setLabelColor(Color labelColor) { + this.labelColor = labelColor; + } + + @EditableProperty(name = "Mount") + public Mount getMount() { + if (mount == null) + mount = Mount.PCB; + return mount; + } + + public void setMount(Mount mount) { + this.mount = mount; + + updateControlPoints(); + // Reset body shape + body = null; } public static enum Base { diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index 6cf2e4247e65d7ff7e3d776da9b65281373677c2..39f5e813a4b1120e3fc90d02866f84f5e16f6dca 100644 GIT binary patch delta 14349 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 delta 12817 zcmY+r2RxPU|3B{R+g_0wvWa9A8OgCS3X#fIc8KhCC}frq2icoQGLFoQWD7|sT4ZKM zl=>g{eZPPI&$ma9?$>#Z=k$-2wT}3f}X$C*7fi4P7ML_{jP=sdT6KO?I!Q_j4 zJSvEM>EQt{OM-{WWF~|tcvV42fmaWNB6zJroI#OelQ~gB#DoX{_#eo_Fae}8=ynsS z2D=NT-a!F0|8LzxCrz|aYA%3DrbAJIPMj!t5c3M^9C)ol2obIQ0ZR7&A$yVHfBvu& zt1&q4|BqQh*Bw~OBg<-J@NC=V8<_0yrI=*NSz~pmNs49wr;sut-gU5mZMC)LH zr6%%{4hr-Tq|_;Sg{Girq9P_*BO#BM!2o9s*X3b|%@0!}6o`s9Lt#MSf^{EcVzr}& zOahL%5QW#yTlAn$OTY=pv=UqcfGe>)y8qx0f`UQ`MKp9oa3(WEGu2E*(n4`dQAvL-bB`pCI6L^IZ0e_+B28cDSo|28QpC_I>VgE^3H z0SG4$lJuStK?k~#7TFQpU=>J|#}G4+Zb=Bi0wtR_lOdx)9^GR{iG(d2Cy_xIK~Fk! z5^|nA%X-*G5h7bWKttlo zMaY1qCYhEauxwz6bqB%WOk zWg3(dgjaSP1vmbO0IC#1PCtX1h5Q1~qNJcTo+_gvpor7PC~e3Zb_MkZvW8wqnL<6C z@w2SZLj8IW^WVB(<4{2;aBKx$o=epwSBEN@*N%&rn*$srEmnE z9EA6(4~2n-Z}2TD50X4)QP8PH>i&Ytp#ux#xPiI?CDgu+LNXlQK1khYbSt#m?^C10 z!Q+iY$A~t8knNe#Z^09lq7eX5|-Wcr+ZS;L}^Z}&Xw@3RzyQLvhYi5v>f}-#& zcp?*d9njpVB>KTt0_RhgQ;DKubg24BSO$LTPd!FnGvnjlzsV5pqnJ z5U4NpEST%iozKT>sELEz_4_FDWMDao333<~(#7K#Nhp{gfLVZOIm=--pq5*zVsarE zggWLJn(^@XbhOX7yU9)-Fj)$UGeo}QnB&9;su(8HO>GR415C@w7V{Irw6Vj?K?88X z1>*pfsP`!;R+UVn7Jb-kF=B2tz)0G=je$3T<{iu|RB4ew418w#g<#4dK*2DKI<#GH zMPT@kQyvl;@a$&cCUW4hCy7>-7#xwe7Qm6lOEAJv$iFg-2$X|ZB}NKjWAPlb4h^Bf z8w@9O+`COa~&auS&(lP29+3k((h%=2MBrU2j&kXO>SV8 zpp&2*jRhe3Bh*+PsJRG{72R+Q1qBNg(eMsNj3mN>&4PIJa9~3qgbUo*bcp2~FBSux z0;_UZRR~K;8T%QEID*GIK@p)E*e0kHDmvIA=q#DH#r}l0-i#CW0^}!l3u^`;N4aCY zL0!Ekwih~@2BNTmkef~{)(qMSrNvk;NXJu#Rfd4A+Oa;6?tLe=fc5b1P70aAzJ?al z{)|<@fx74gY%ms-DA%w;C`Pj1MH)x(z;*JT=wqOu5GA(X#;_Bm*08iC_M2Gn;f>_< z8{31UJ9Jf;y8n-xT<=(LM7fCBR5(`RS_kau zIqQSF1?kHCaLbS%k$?+?kSEoJzKi21DAegeT4ZEuqSXMvO}cRxCkFvMj>e5(Kx*y} zaeffgQX-BAveKmEIvKzY>Cn!#n~=MB98KJi#&M;N0%+1f87>rx2(7^7P=bEXhG|mg z$&Wo9tl$$T@%Au)A?erSP}H=C75uHVmwS{9<4sgGMsXcl*+_})I6erbt`m0vG4D={ zigzPFbt&MWbB*lCNLuN}MWVn}`lsbMUy{%MI2Gu*kZfikJ?X=};RI6&na6QZfgPg| zd2oxEyN)}HT)s&Bu#V#-ggmmQVUqsnw$R~o{}!oq_%r^OnI3Q|61Scg=MYn$&u9Dm zPU}`yrrA*Xr2A}JCL&GsbR>dCb0qq=;b^45xQSB2&8soSH2m7S_wO5yY6^}Q?P$lm z7V9>SlPTODHJd*3#6P5z+Wk`1`!(*%XEZ8>%v%;FQ;aNhl{S`* z64qB<$*{MS@<|pDpHwc+WU9k*qbnRldL zQ$TgId%DWKkd#|Ai{dQGR!N?8pZR~t-W;z^-1hm=w^4id)6&45NW#d!7{dtDYKtGT zC$SdK3{Ew@NJ@S&f5q|pQKOL*SxNKW_O`QsIyFw$DH3fKeiI)*S5$eND0M11n*Pm` z#e4_WDB(FVL`S&#b$#@i+sW&!iG1h_DCZJu2df)7jPj{g>*yGxKfs(_a%6Pml(8U( z+vsKW48xHdd#^6uUNt>JFpPIB)mMzl)(Tc*Gj#q;r>1QSbcT!W^XoB6e#UHuW171; zJGhNKRN1;*on;~^dg;?N)APeL`W^}BhdgIY1E#kT<~=BQ1RwF<=XaCnO8G z-UwTdFU>WXR*TM!(vC>Io=}aVZy%CUDdKx)ogweq7xzymCZ?dEv*ujihFdA{9@j`8 zxcehJ@W%^ZU&6uP9p;xxF^qs8!z-?NK|O81BM~te73F#1SZVA{rRY)5=--#@;(D&m z_gBOjvJe0A)aVeyJGzPv^H#9a#uCm?dRaWNyd9_6=`5v3Yz{D)t~n=PY#&g!o9*%< z1i$r|MRz*y!tQ`?YR;$Xewr^nHo{h4;$k_w7C7W=jdg!_hvg|mnvHw4xiy)n=|p?B zZkLzJ3^e}`)A;rBc82-nE$MNKLWA`k?ThZcK9!aBmA2!)aWQyBBh?oNkv4LKy|#D8 zrWf8OIdEK@ES=75%HqwevzWHB(f0W?yOQu+&-s9K+Jt>%wcO>`;MoxxZzC;($=!>} zk?l9jFO%jf7Hb8=la#(qDj1KrzI$$Qm=YIah4|rb3Ozg#G8YJK? zJ2>!5eJfPO1_lW)?_h4Qm0)lAdl8hAx7GK4SYS|W^Ynw;v|855uE6s`8P+U*+~e-RU7XC1P_uN$T+wq(TiMu#+v&6V`MP}q+W zJ8(L6raKnZ^PqNBgd|(aqB<+@enRW`UCsu|NV9Jrh5EH>F*_J#VIWxGp$#EvUh3Qp zg^o)Y`3F|2mlzm1Llgc|ZJ?3#3ojUM-+$L9x+1HPb@{i`{E?Fk$4A1oFJ0o|&m0Ph z^z!RwEV=ybc*ia7Q}v9uX~)XO%hgPEU>(chwMgCB%#^Lx z7rwzEvud5}v-kcNosDS<-uWBbh#7wu(vJNX{={NBbUE3CU5e=>4 z^>3$)~#o`N2qv zXw#14CgyCB?>Y3N05x%N2S-gfO)F9S;T7i<*M7mMFY$dx6y>EZho!4JyeX0GV$x$4 z)=%58qAZm^dsgXp0oQJLRA_MS_s=VnHBGZ2O%B6Vv$G+{v{ze4(0bZwU5}#p7|X+H z?0@;>nAs=y2yLk5f5kr?7EJuQnHcq&#@5^4aO{d~z|AL-msx%>3S*$}gz_ae*O-W0#+Rva6?-@Zjt{d0*L+dg6@bkAsdeAjFI zT~=}VUiO@9FMeR+sLNyBM;=T1zVD-zKhnty*BPux8<#dttBaV`aNUt}l+$y^yTAA1 zk4$rMXBUh3H_6)6pa0ezPg-syIC!j!;PY=Oq_({@SV*ug!VjGt`RRM2T&C!nzSb`4 zp*8mG2>(RkTDBw2L4<8dq;P*Ew_y~EUrz^nm7uU=N>iC<7=z#-tx{)@)5iYuf9Ays zPvg$3MBt^fKb1u}&=mD|_Oo?1$8n1EFTAG68Rq6te=@k{*4Lw!n0T)vfuLZ88mzKm z-h3rlA?KriuTB52v;f=uP`$z*^j22)mmtr(JS*D`uLA5ML#{`*mKm^r{)R|WkaRK( zQ=JuAJL=?7C>6&j6_<4SV$#V)iWTaB2aLb9IXX?Im_KyC>mkrg9RH`V9nQGO6+UX( z^^k8pH2V%>V(~;yLzaNBVqFTshpsw~Em82{XxDp2rlPW8hTTi2q;F!TRqwhUA6(*l z$2%$irLr`4eXz$}DXvjJeY1g?(fGpVz{aR>)X}mQ6}-f;c0rG$yZN6?8s}Vg6vHJ1 z*)JPuCD0|(nOrmYX0RInk5}0zw6%+>u2TmYkEj1@9r!w==cWx% z3MdI!zfA}Y+%se~EMsn0KP=gz z@y`;istNiehyP0bLC&u5?=Qd8L_dGJ;h!T%S`9LcKHo`fvLCV3`26&mZK88fbvN-> zY4{x_bD?4X(MP(MKNn0Y&01Vm`aYcX7o+imkazn zyH_(;%v&dBZbcvU>MwlpL95^IMYnj6@!+^;TFR)IV9Yg%D$`#LkuF7LTOP{4?Iy5` za(yctPVe>`q9=Oar&zkpv!1N_ekIQ(x%x?=)2;{3H(9O%uZRIoO-7WUOumWNjlympvzr2+)7kFXtcT*zioidxqe@x=prdWmwWb?(n^T z|FY^im4TNRNA>C*8URRQ(DVV;_(7 zL<*f_uDa1z_E7Unw5mY$DTZUR=Jm>Hy`~dOv&}7p*18vU+_8^+(LPu)R1;Im&ym}* zR|dbix?Io6NDZ-YX==+;R``~f_n=sUR_~~+)(zzpzB`xXud>H=$MuEqGw{T*Z}ib^ zVewZhU0vOtMYm+>|1_Nnb|5A-+Yapi4Rh>@68Mr5-7Z=1oLOH>_Pv9E&Rm-Hyxt1? z%lshSFNE8?qn9TWqtX+P4cKYj5PFAYdZSuwesD0NZMVFj)Ds+XgV!F7qU7%~{y-Oz zanP+P4BJO zd@o;PexCA;w=*N0Yzbdqm}W4_RA=-Wo_6O4mJ0}c>%*?6`MdYq|4Q<|V_%?pvZZzJ znGeP3*GM2r@rS` ze3h(daeYVhG!u&-@6F00`vr8&(4sc_Zm>ic;`iHZznGWT-aRrma=*sUgX6sKdd+6| zl4yS>D*<~Mi&K;GIJm0&oN~bHakZaXd|b8F=<{rZjM2$f%1+&hI80~cEX_72CI00I zXVjT(dVw7;8uVRcri5Pdk*JL0?P(+KJ!+9_^VBq-hL@}>KYmPLW6<5^h^Dx!+;PuU zIildyeZAwo$x`=%zl7z|+^u4qezfGOsmBOBpqeKnPE4gST8pvGjo(oJEpBK0>!)UC z{4aCgZ1IL+=Y!|Za}t6DZy%nd}$U$Cp zF_wDv^1j0IdSs}M-+Qq|&Ks8_WSAIe6ckNPCx%*&9ZiiFHZ7fY+LHOYc-$w7xLSRj zK1ktAc3ITj=X!D?+)dbu#Z%LDKBA#LLGOM<+(^z;Ci>^Tedb^%b*qHV{r)5~r9i^n z^mlq(1Xq`)FVR$qbV ze#E_vk-mE%ES#!yvZJu;3sMS$Wo{7@m^d#YbBu1~#GKhl6-W6otqFx)ShEF8SO(XHAe;hkk$F(>?_qD zsTQaH%+xamKd$|)HP1v1$oI*qb~xH`fhl6{``P7`#abPA7qhCF*6MnH{Jo3xZ|d%jw9cqmae@raWO;v5t1{HLlSqzd1 zHYsT$EQAh`q}T?OOa+TK9K2@wNzOr!he%s0Hvg_=ty!=C=9-Ppm2&oNVsn1aEqhDi zVn15rV=nuZsq|((+m&M!RPhGU#$Mt&UVoKl1!=!EKAs`o_@`O&dhrRzY{6DbP|nb9 z|5JMHweyR?VQXW*_}<>SarqKn{uW(VycnVE+*v|tQp@zx!uGDb?15Sa?w5_VP0&zM zx|Y|JuKdo?J;N*>=9F2ToRMF;X9?+T`CDIU62F{1*KReoC=$OAl+gBcD>+E}d&#ea zZoJwr+N_*;2ZoE@e}!6#HfqkE6F&X>ta8~HUx3bc_YHmyf|(=z@*ky^ye%o7uqPKE z<$8sL5oSjBMC8{2<>*fpTc~bZl@mFxu+vukfLhTjFQi`l|Rk z?Ktoy|Cm_XwAT1B7VjG>Jg(sjhJ^RL{Vf`vJuOH4^jX|HVyPFa;@zd%>u)Ld@p!|K zKV$vXJ?j~N)0oB90;*gu^+LfxQRbV<#n-+MY?KmYg@(RqU(HFV8+-L!oKfrJ=JoJr z(&FQmMpM=O>Tl1>iN6yyY1XNn)^T##cNKDRxg1Gwm~pgr?&1~=PLovRv@(k>%I_NW z(9!EO8T~AqvU|Nr&}45+=AlL?g{kM$+!}-^WykKW%%JjjWkaC-*0srB5-R>#rP4^V!KHn6|UlqwidiEZ9!TXf?OTK|Gy1-)@Q`gAvR(yQ@*L#37 zWp6{v!n{xVByvgR2+xYq5VepUv&nAxai_|)3Rgll!;PhcpJCP~*Ar+HGgg|ZryXWE zWfn~2B%N4(N#A>eue~&WGk)QXD@6pSKBL@dy8<_tO^7sZwM8{c?|* zP)>xo>aG^A)(yJ4xQuyU6-PT&*r&)9QOo&UFJJqWmQ|9XUt4Wd-`3(Ym{I)GB`rqF zL?%s&&}oFb#&hFajjBW7>i&cJsh!B5S-lU%hTLRmzFSB)((tZ6$ZI^WF=9ID-hEG0 z<)i(uwccK^E-%wU;?xjJQs|o_%w*DeuLd!0%I$tly}3tQnuv^m^@~B|Y7Q z*(7uoIWjnx6gfjj&7Vxa&Deh`FcEoWdFQ5AIn^p=7zRj%sbr<($nQ zk50yYBK-B2yJuveymp1FrqHKr>vS2{#tAgHm_e=8OS4R+1x5+6bDHKVde^ji4YSvj zbR?S_9wuG+5fq{Hm|M8egR8Udi^!hp- z1?z;}3c_{%Q45;%DC8Tvqq0Zy#iSi6f4SL3iqWaUpltc_q=W3?ffg@fG#-pIHgaE(Onjzg=)mIM|U*|0tUNv5&`i*#fpRA4go)UO)P=Ext==PPelniueCLbI z!i5e8A_~4+e@T`an%^``Le&=aF;Jlh8 zfvp{^2wQThuq(gGy-fe|gUbTywgQFd#0bx`eiFrIa%cx>QR?O9>GW--0FE6O+-~Qm zKjEH)`IXDERt5Zmf`U9_C+yukG82Kq5o)$qigpUWj?Bq(aPf?p-@kY6Zs79|+^)AZ zM72Jo^W1&#^UR*AP{Y3T%kjurCeEX=(zmNUqn_56us+PW?sQ3l{oGGVgN_cn#}eyp zs>I>j5%}N9?)~G_G=G#e#Tf)I8q^sqy>_&t4hkfs(7xZ3R*CGdIA#8J`otg1(G%Qx z(7NWp=|Q!gpWaU;F)0TB^mfRWJ==ZK4w)o*T`%i47J zTHBM4&a{;ka8;KUNYgL45xN@tt%OLCPIOXixhwLA!)W_LSJ)YfnYO~U(Z>`6X4|^^ z$G(r!HxSZ7dXA1fY)A?j(BEdJ8@;qAxz9eUwI-5QpN!l3_$eqfGk2<(Vjk(r&HXwp zlEv=*76sF@oX6EQ>f@wEld}lQ=g)>2wfWv);zp4-5l&krmvTa=8kF?g#uiNeGOG?I z>=e?r{zkZZ#Jys9U3P^huaU9*e$0XRhxNrsmi#_Kx6SoC3B@K28hr7-D=(M16TjB_ zglEjtk2T_D3v5~Q2c#?%)S1*Wv`UNe-z%#vi^s?@*f2@C4!Uy|KhZ2b5b&;8x3&4s zx7oX2a&s|~Z}Ui?mg85dVTKevspT3rtCo(-hAS7`o;kg{;l=#2dJ=no;>BCj1?J_p zfP}j&orGEq5tD^YN&~7EDeook7XcF6thTe2yfZ$nT@x!?eEG^5>?0uvjla}X8CD~* z`=-Ws+B9|k`WAlMP1u~#^4`p;jR?U{jJh+9hdhkh(PCRcspp;J>j(m@57@CP8nbz0 zQY){wNnVjdymuNI&(DuJJ+&>l+oz%)3k>E?AP90N8{`*GG88CLOw+N<1$}x$4;(W% zW#=JXnYYXRGRb63-@u`4W|v`(t9&-i&>px{UsklT%Ecc250~UFN~s3BOHU`AYi0mdD%EA3mf%eG{^Gt+la3VT{Fc zNzA91YdS(<{K%WSUqsKvm?N@TNPW&rypLTz233AYgBX zQkOg5b8mrCHaySleAJOoYsGz8zR3-$YeX@6oi!d~sq_b*HXr^{a5}9vcFtx1bL?Py zc;N+s1zUXi9lKQh;Lr&^Ec-(hHLQbQXVr>r#gt^Xv17JjieckcMXipWZgg>be8tkn zgb3<{CiN<3sG0v>4SUdhF-y#kw+EkRKSjP<>Nl~_`o>jkP)tKC?ER#7_;>wSrr#fl zu9RN;_G@l@ljZ7m`w!)ji2m0T(M!grnpuQClOAO3uu;ihR-$6!H(x-QwMyuBP%Hbx zMX8UO1xbUYk4hZMmw_^ll)d$O}Sv8a@nGhwON!< zY`M>~Z)N)|;Njn4dpYME#-+h#LCNfwD#yA$edFG>_pak>6q{ALsQ4g3vF(yFNo2Nl zA8<|P5IbXXo;z>wilMjb)EhAuN6RUL!7Zv-deIV(0*f%$CwVa`+Q*)JDtt0x88&#% z7)c2C;vK$BrF3_HEEngeQY^E{LoGja?fgnqO|pf@H^7xT@cnX$g-Z{XbFD<;G^Z{Q>-w0Z+_plQb&PyhvKA3zlpynO&&P&n`fIEgbpz==ax;zK|3 zClOx&d_RzQ)fdnQol1QHqyN0MK!GZN>}cx;h=HHTVcKB)lpk;j6hK%le;C%sA5aI? zE&hNGD3IedK*1;g0N;otCIyg9hk48f0EVC-69`-dg$IFv6)3C+0&bvS69ia*LOc2N z0R@3zSQ8!$+yFI8!7z?W2w)6qQbGVbP&fzyZh^ur0^kG+?+L(lP>>4+%t7H%C}0W- zKSF_Ppr8{5*n>h%7~l*Fymw)rfV(i&@w7jDeg}W8on4SUA7>SilCP!x0B(;~xi@ftrap*jXkXrt>HsZ~#qzK7S+5b&?4oqVp2e=3>%AE^G`Q^fke$9o6DdzzOpie>`yz%G$ z)5zz;o9SUb*>rf^e9MOcln6Z~8WoA6KJybAskP*pIpa}|7gO;^F`s6K-W zp79Lky!i~KYEcbSeOV1J!S@{AL^03deX;)>@B|ZduYs3%R|Btpx)z?pf?C)_RR?F` zSO-(>tAmRmSr4z3_@A&{51X!%V88|v9L3Q9_shEhCiboYCU))xOswh!yeMlUj1$oK zU*j5KK(!{=r>qGkhHHj%_iTopr<&mbP;G&oOIqO4(X_&gdbh%+5B~}HHrS`M4aQ-3 zNya%mXnkJ7nwgj6y>qBhY$wn2p^(&0PVi9J{!gRZL7s#|O<@OY!gi9w4>fL`{R1Y=$-Q*+XP>An_0e^PG49#AXD|TpV zdrj`(p>U!H1|;^tJ_kLpk4-PRafd!#z2sgT3W9y)+z*AAKG?L{2Rj?~!&%hy!^pe? zFmmhwY+4 IMPROVEMENT - Create a backup of config file when there is an issue with loading (cross-version) + Create a backup of config file when there is an issue with loading (for example running two DIYLC versions on the same machine) to avoid data loss IMPROVEMENT