diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 00000000..8553a0fb
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,52 @@
+name: Java CI Tests
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Run Tests
+ run: mvn test
+
+ # Generate and report coverage without failing
+ - name: Generate Coverage Report
+ run: mvn jacoco:report
+
+ - name: Report Coverage
+ run: |
+ COVERAGE=$(mvn jacoco:report | grep -oP 'Total coverage: \K[0-9.]+' || echo "unknown")
+ echo "Current test coverage: $COVERAGE%"
+
+ - name: Upload Coverage Report
+ uses: actions/upload-artifact@v4
+ with:
+ name: coverage-report
+ path: target/site/jacoco/
+ retention-days: 5
+
+ # Optional: Comment test results on PR
+ - name: Add Test Results Comment
+ uses: marocchino/sticky-pull-request-comment@v2
+ if: github.event_name == 'pull_request'
+ with:
+ message: |
+ ### Test Results Summary
+ ✅ Tests completed
+ 📊 Coverage: ${{ env.COVERAGE }}%
+
+ Coverage report available in workflow artifacts
diff --git a/README.md b/README.md
index fe2e10a4..74634af5 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ DIY Layout Creator (DIYLC) is a specialized software tool designed for hobbyists
group components together and treat them as one, e.g. move, edit or delete
export the output to image, PDF or printer
export PCB trace mask suitable for toner transfer
- export the circuit to a SPICE compatible netlist (beta)
+ export PCB designs to Gerber for fabrication
create a Bill of Materials as a part of the project or export it to few different file formats
analyze guitar wirings and show detailed pickup configuration in each switch configuration
zoom in/out feature
diff --git a/diylc/.DS_Store b/diylc/.DS_Store
index 9caebd44..ba7e385a 100644
Binary files a/diylc/.DS_Store and b/diylc/.DS_Store differ
diff --git a/diylc/.github/workflows/test.yml b/diylc/.github/workflows/test.yml
new file mode 100644
index 00000000..0b7d7c72
--- /dev/null
+++ b/diylc/.github/workflows/test.yml
@@ -0,0 +1,28 @@
+name: Test Build
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ path: diy-layout-creator
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build with Maven
+ run: |
+ cd diy-layout-creator/diylc
+ mvn -B test --file pom.xml
\ No newline at end of file
diff --git a/diylc/.github/workflows/tests.yml b/diylc/.github/workflows/tests.yml
new file mode 100644
index 00000000..f9d01b4d
--- /dev/null
+++ b/diylc/.github/workflows/tests.yml
@@ -0,0 +1,51 @@
+name: Java CI Tests
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11' # Adjust version as needed
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Run Tests
+ run: mvn test
+
+ # Generate and report coverage without failing
+ - name: Generate Coverage Report
+ run: mvn jacoco:report
+
+ - name: Report Coverage
+ run: |
+ COVERAGE=$(mvn jacoco:report | grep -oP 'Total coverage: \K[0-9.]+' || echo "unknown")
+ echo "Current test coverage: $COVERAGE%"
+
+ - name: Upload Coverage Report
+ uses: actions/upload-artifact@v3
+ with:
+ name: coverage-report
+ path: target/site/jacoco/
+
+ # Optional: Comment test results on PR
+ - name: Add Test Results Comment
+ uses: marocchino/sticky-pull-request-comment@v2
+ if: github.event_name == 'pull_request'
+ with:
+ message: |
+ ### Test Results Summary
+ ✅ Tests completed
+ 📊 Coverage: ${{ env.COVERAGE }}%
+
+ Coverage report available in workflow artifacts
\ No newline at end of file
diff --git a/diylc/README.md b/diylc/README.md
new file mode 100644
index 00000000..3b96434f
--- /dev/null
+++ b/diylc/README.md
@@ -0,0 +1 @@
+[](https://github.com/{owner}/{repo}/actions/workflows/tests.yml)
\ No newline at end of file
diff --git a/diylc/diylc-core/.classpath b/diylc/diylc-core/.classpath
deleted file mode 100644
index ad4f9a9e..00000000
--- a/diylc/diylc-core/.classpath
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/diylc/diylc-core/.project b/diylc/diylc-core/.project
index 8ea4afa3..f030609a 100644
--- a/diylc/diylc-core/.project
+++ b/diylc/diylc-core/.project
@@ -5,30 +5,7 @@
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.jdt.core.javanature
-
-
- 1741597028960
-
- 30
-
- org.eclipse.core.resources.regexFilterMatcher
- node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
-
-
-
diff --git a/diylc/diylc-core/pom.xml b/diylc/diylc-core/pom.xml
index 65ad66a3..77b60fe1 100644
--- a/diylc/diylc-core/pom.xml
+++ b/diylc/diylc-core/pom.xml
@@ -92,11 +92,5 @@
system
${project.basedir}/../lib/java-http-proxy.jar
-
- org.mockito
- mockito-core
- 5.3.1
- test
-
diff --git a/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java b/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java
index 575b2a77..ba31063a 100644
--- a/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java
+++ b/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java
@@ -25,7 +25,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.diylc.core.AllowAllValidator;
-import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
/**
diff --git a/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java b/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java
new file mode 100644
index 00000000..64fd22f3
--- /dev/null
+++ b/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java
@@ -0,0 +1,281 @@
+/*
+ *
+ * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
+ *
+ * This file is part of DIYLC.
+ *
+ * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
+ * .
+ */
+package org.diylc.netlist;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.diylc.core.IDIYComponent;
+
+public abstract class NetlistAnalyzer {
+
+ public NetlistAnalyzer() {
+ }
+
+ public List summarize(List netlists, Node preferredOutput)
+ throws TreeException {
+ Map summaries = new HashMap();
+ for (Netlist n : netlists) {
+ Summary s = summarize(n, preferredOutput);
+ if (summaries.containsKey(s.getSummary()))
+ summaries.get(s.getSummary()).append(n);
+ else
+ summaries.put(s.getSummary(), s);
+ }
+
+ List res = new ArrayList(summaries.values());
+ Collections.sort(res);
+ return res;
+ }
+
+ protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException;
+
+ public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) {
+ Tree tree = new Tree(TreeConnectionType.Parallel);
+ connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series),
+ new HashSet());
+
+ return tree;
+ }
+
+ protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List concurrentPaths,
+ Tree currentPath, Set visited) {
+ if (nodeA == nodeB) {
+ concurrentPaths.add(currentPath);
+ return;
+ }
+
+ Group groupA = findGroup(netlist, nodeA);
+ if (groupA == null)
+ return;
+
+ if (groupA.getNodes().contains(nodeB)) {
+ concurrentPaths.add(currentPath);
+ return;
+ }
+
+ Set pathVisited = new HashSet<>(visited);
+ pathVisited.add(nodeA);
+
+ // First collect all immediate next nodes and their paths
+ Map> nextNodes = new HashMap<>();
+ for (Node n : groupA.getNodes()) {
+ if (pathVisited.contains(n))
+ continue;
+
+ IDIYComponent> c = n.getComponent();
+ for (int i = 0; i < c.getControlPointCount(); i++) {
+ int targetPoint = i;
+ int sourcePoint = n.getPointIndex();
+
+ if (targetPoint == sourcePoint)
+ continue;
+
+ if (c.getInternalLinkName(targetPoint, sourcePoint) != null) {
+ Node newNodeA = new Node(c, targetPoint, n.getZIndex());
+ if (pathVisited.contains(newNodeA))
+ continue;
+
+ try {
+ Tree newPath = (Tree) currentPath.clone();
+ TreeLeaf leaf = new TreeLeaf(c, targetPoint, sourcePoint);
+ Tree newItem = new Tree(leaf);
+
+ if (!newPath.getChildren().contains(newItem)) {
+ newPath.getChildren().add(newItem);
+ nextNodes.computeIfAbsent(newNodeA, k -> new ArrayList<>()).add(newPath);
+ }
+ } catch (CloneNotSupportedException e) {
+ // Skip this path if clone fails
+ }
+ }
+ }
+ }
+
+ // Now explore each next node
+ List allPaths = new ArrayList<>();
+ for (Map.Entry> entry : nextNodes.entrySet()) {
+ for (Tree path : entry.getValue()) {
+ List branchPaths = new ArrayList<>();
+ connectNodes(netlist, entry.getKey(), nodeB, branchPaths, path, pathVisited);
+ allPaths.addAll(branchPaths);
+ }
+ }
+
+ if (allPaths.isEmpty())
+ return;
+
+ if (allPaths.size() > 1) {
+ // Find common prefix among all paths
+ List commonPrefix = findCommonElements(allPaths, true, false);
+
+ // Create a new tree for the merged result
+ Tree mergedTree = new Tree(TreeConnectionType.Series);
+
+ // Add common prefix elements
+ for (Tree prefixElement : commonPrefix) {
+ mergedTree.getChildren().add(prefixElement);
+ }
+
+ // Extract unique parts
+ List uniqueParts = new ArrayList<>();
+ for (Tree path : allPaths) {
+ Tree uniquePart = extractUniquePart(path, commonPrefix.size(), 0);
+ if (uniquePart != null) {
+ if (uniquePart.getChildren().size() == 1) {
+ uniqueParts.add(uniquePart.getChildren().get(0));
+ } else {
+ uniqueParts.add(uniquePart);
+ }
+ }
+ }
+
+ // Create parallel section for unique parts
+ if (!uniqueParts.isEmpty()) {
+ Tree parallelSection = new Tree(TreeConnectionType.Parallel);
+ parallelSection.getChildren().addAll(uniqueParts);
+
+ // Add parallel section to series container
+ Tree parallelContainer = new Tree(TreeConnectionType.Series);
+ parallelContainer.getChildren().add(parallelSection);
+ mergedTree.getChildren().add(parallelContainer);
+ }
+
+ concurrentPaths.add(mergedTree);
+ } else {
+ concurrentPaths.add(allPaths.get(0));
+ }
+ }
+
+ private List findCommonElements(List paths, boolean fromStart, boolean backward) {
+ if (paths.isEmpty())
+ return new ArrayList<>();
+
+ List common = new ArrayList<>();
+ Tree template = paths.get(0);
+ int maxLength = template.getChildren().size();
+
+ for (int i = 0; i < maxLength; i++) {
+ int index = fromStart ?
+ (backward ? template.getChildren().size() - i - 1 : i) :
+ (backward ? i : template.getChildren().size() - i - 1);
+
+ if (index < 0 || index >= template.getChildren().size())
+ break;
+
+ Tree element = template.getChildren().get(index);
+ boolean isCommon = true;
+
+ for (int j = 1; j < paths.size(); j++) {
+ Tree current = paths.get(j);
+ if (current.getChildren().size() <= i || index >= current.getChildren()
+ .size() || !current.getChildren().get(index).equals(element)) {
+ isCommon = false;
+ break;
+ }
+ }
+
+ if (isCommon) {
+ common.add(element);
+ } else {
+ break;
+ }
+ }
+
+ return common;
+ }
+
+ private Tree extractUniquePart(Tree path, int prefixSize, int suffixSize) {
+ if (path.getChildren().size() <= prefixSize + suffixSize)
+ return null;
+
+ Tree uniquePart = new Tree(TreeConnectionType.Series);
+ for (int i = prefixSize; i < path.getChildren().size() - suffixSize; i++) {
+ uniquePart.getChildren().add(path.getChildren().get(i));
+ }
+
+ return uniquePart.getChildren().isEmpty() ? null : uniquePart;
+ }
+
+ protected Group findGroup(Netlist netlist, Node node) {
+ for (Group g : netlist.getGroups())
+ if (g.getNodes().contains(node))
+ return g;
+ return null;
+ }
+
+ protected List find(Set typeNames, String nodeName, Netlist netlist) {
+ List res = new ArrayList();
+ for (Group g : netlist.getGroups()) {
+ for (Node n : g.getNodes()) {
+ if (typeNames.contains(n.getComponent().getClass()
+ .getCanonicalName()) && (nodeName == null || n.getDisplayName()
+ .equalsIgnoreCase(nodeName))) {
+ res.add(n);
+ }
+ }
+ }
+ return res;
+ }
+
+ public static List>> extractComponentGroups(List netlists) {
+ List>> res = new ArrayList>>();
+ for (Netlist n : netlists) {
+ res.addAll(extractComponentGroups(n));
+ }
+ return res;
+ }
+
+ public static List>> extractComponentGroups(Netlist netlist) {
+ List>> res = new ArrayList>>();
+ for (Group g : netlist.getGroups()) {
+ Set> components = new HashSet>();
+ for (Node n : g.getNodes())
+ components.add(n.getComponent());
+ res.add(components);
+ }
+ return res;
+ }
+
+ protected int find(Node node, List groups) {
+ for (int i = 0; i < groups.size(); i++)
+ if (groups.get(i).getNodes().contains(node))
+ return i;
+ return -1;
+ }
+
+ protected boolean intersect(List groups, Node node) {
+ for (Group g : groups)
+ if (g.getNodes().contains(node))
+ return true;
+ return false;
+ }
+
+ protected Node intersect(List groups, Group group) {
+ for (Group g : groups)
+ for (Node node : group.getNodes())
+ if (g.getNodes().contains(node))
+ return node;
+ return null;
+ }
+}
diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java
index 7a865ddf..7503354c 100644
--- a/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java
+++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java
@@ -41,9 +41,16 @@ import org.diylc.common.IComponentTransformer;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
+
import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.annotations.*;
+
+import org.diylc.core.annotations.BomPolicy;
+import org.diylc.core.annotations.ComponentDescriptor;
+import org.diylc.core.annotations.EditableProperty;
+import org.diylc.core.annotations.KeywordPolicy;
+
import org.diylc.lang.LangUtil;
/**
diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java
index ef28e0cc..c7e38eaf 100644
--- a/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java
+++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java
@@ -36,7 +36,9 @@ import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.clipboard.ComponentTransferable;
+
import org.diylc.common.*;
+
import org.diylc.core.Angle;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml
index c4834eaf..967e8b2a 100644
--- a/diylc/diylc-core/src/main/resources/update.xml
+++ b/diylc/diylc-core/src/main/resources/update.xml
@@ -1,5 +1,5 @@
-
+
4
@@ -12,27 +12,27 @@
NEW_FEATURE
Buzzer component and symbol added (thanks M0JXD)
-
+
NEW_FEATURE
Resistor symbol now has two draw standards - ANSI and IEC (thanks M0JXD)
-
+
IMPROVEMENT
Fixed run.sh application starter for Linux and Apple OSX with M1/M2 processors when using Java 17 or newer
-
+
IMPROVEMENT
When editing Label components, default focus to the text editor
-
+
BUG_FIX
Unable to move selected components if one of them is close to being reduced to a point
-
+
BUG_FIX
Toroidal Inductor hangs the application if it doesn't have inductance value set
-
+
https://github.com/bancika/diy-layout-creator/releases
@@ -48,7 +48,7 @@
IMPROVEMENT
Upgraded JRE version of Mac builds to Temurin 17 and switched OpenGL to Metal rendering engine for improved performance
-
+
BUG_FIX
Choosing "Print" option from the menu starts printing immediately before choosing printing preferences
@@ -88,7 +88,7 @@
NEW_FEATURE
Ability to change pitch and appearance of PCB Terminal Block component
-
+
IMPROVEMENT
Better rendering of the effective circuit graph in the guitar wiring analyzer, showing series and parallel connections in a more intuitive way
@@ -188,7 +188,7 @@
BUG_FIX
'Highlight Continuity Areas' sometimes renders stale areas when clicked
-
+
https://github.com/bancika/diy-layout-creator/releases
@@ -200,7 +200,7 @@
2025-03-08 00:00:00.000 CET
-
+
BUG_FIX
Do not mirror bottom layers for Gerber export as fabrication service providers expect a top view for everything
@@ -220,7 +220,7 @@
2025-03-09 00:00:00.000 CET
-
+
NEW_FEATURE
Switched to AppImage distribution for Linux system, abandoning Flatpak as a means of distribution. DIYLC AppImage will be available alongside with other executables on the official DIYLC GitHub page.
@@ -251,11 +251,6 @@
NEW_FEATURE
- 'Virtual Multimeter' from 'Analyze' menu traces the circuit finding all possible paths of electricity between two points designated by the probe symbol.
-
-
- NEW_FEATURE
- Added ability to highlight connected switch lugs in selected position in order to illustrate how it works internally.
Configurable 'High DPI Rendering' feature which makes the diagram smoother on high-resolution displays but can affect performance
@@ -272,10 +267,11 @@
IMPROVEMENT
- Improved robustness of series/parallel graph construction code used in circuit analysis
+ Omit boards, wires, traces, terminals, etc from Spice netlist output
+
IMPROVEMENT
- Omit boards, wires, traces, terminals, etc from Spice netlist output
+ Updated the windows installer to avoid false positive virus detection
BUG_FIX
@@ -288,5 +284,25 @@
https://github.com/bancika/diy-layout-creator/releases
+
+
+ 5
+ 2
+ 0
+
+ 2025-03-20 00:00:00.000 CET
+
+
+
+ NEW_FEATURE
+ 'Virtual Multimeter' from 'Analyze' menu traces the circuit finding all possible paths of electricity between two points designated by the probe symbol.
+
+
+ NEW_FEATURE
+ Added ability to highlight connected switch lugs in selected position in order to illustrate how it works internally.
+
+
+ https://github.com/bancika/diy-layout-creator/releases
+
diff --git a/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java b/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java
index 98cf2fbd..7086d32e 100644
--- a/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java
+++ b/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java
@@ -9,6 +9,9 @@ import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import org.junit.Test;
import org.diylc.netlist.TreeAsciiUtil;
diff --git a/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java b/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java
index b0dc53f9..f8047716 100644
--- a/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java
+++ b/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java
@@ -46,6 +46,14 @@ import org.diylc.components.passive.RadialFilmCapacitor;
import org.diylc.components.passive.RadialMicaCapacitor;
import org.diylc.components.passive.Resistor;
import org.diylc.core.IDIYComponent;
+import org.diylc.netlist.Netlist;
+import org.diylc.netlist.NetlistAnalyzer;
+import org.diylc.netlist.Node;
+import org.diylc.netlist.Summary;
+import org.diylc.netlist.Tree;
+import org.diylc.netlist.TreeConnectionType;
+import org.diylc.netlist.TreeException;
+import org.diylc.netlist.TreeLeaf;
import org.diylc.netlist.Tree.ITreeWalker;
public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
diff --git a/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java b/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java
index d873b294..af46a9a2 100644
--- a/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java
+++ b/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java
@@ -27,6 +27,12 @@ import java.util.stream.Collectors;
import org.diylc.common.INetlistAnalyzer;
import org.diylc.core.IDIYComponent;
+import org.diylc.netlist.Group;
+import org.diylc.netlist.Netlist;
+import org.diylc.netlist.NetlistAnalyzer;
+import org.diylc.netlist.Node;
+import org.diylc.netlist.Summary;
+import org.diylc.netlist.TreeException;
public class SpiceAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
diff --git a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
index e2c74ed0..29fccfe8 100644
--- a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+++ b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
@@ -21,8 +21,11 @@ package org.diylc.netlist;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
import org.diylc.components.passive.AxialFilmCapacitor;
import org.diylc.components.passive.Resistor;
+========
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
import org.junit.Test;
import org.diylc.components.electromechanical.OpenJack1_4;
@@ -30,6 +33,14 @@ import org.diylc.components.guitar.HumbuckerPickup;
import org.diylc.components.guitar.SingleCoilPickup;
import org.diylc.components.passive.PotentiometerPanel;
import org.diylc.components.passive.RadialCeramicDiskCapacitor;
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+========
+import org.diylc.netlist.Group;
+import org.diylc.netlist.GuitarDiagramAnalyzer;
+import org.diylc.netlist.Netlist;
+import org.diylc.netlist.Tree;
+import org.diylc.netlist.TreeException;
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
public class GuitarDiagramAnalyzerTests {
@@ -62,6 +73,7 @@ public class GuitarDiagramAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString();
assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s);
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
}
@Test
@@ -105,6 +117,8 @@ public class GuitarDiagramAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString();
assertEquals("(((Cbleed || Rbleed || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s);
+========
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
}
@Test
@@ -127,7 +141,11 @@ public class GuitarDiagramAnalyzerTests {
netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup);
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString();
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
assertEquals("((Volume.1-2 + ((Tone.2-3 + Cap) || Pickup.North<-)) || Volume.2-3)", s);
+========
+ assertEquals("((Volume.1-2 + (Tone.2-3 + Cap) || Pickup.North<-) || Volume.2-3)", s);
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
}
@Test
@@ -161,7 +179,11 @@ public class GuitarDiagramAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString();
assertEquals(
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
"((Volume.1-2 + (Pickup1.North<- || Pickup2.North<- || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)",
+========
+ "((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)",
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
s);
}
@@ -325,7 +347,11 @@ public class GuitarDiagramAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString();
assertEquals(
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
"((Volume.1-2 + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)",
+========
+ "((Volume.1-2 + (Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2)) || Volume.2-3)",
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
s);
}
}
diff --git a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
new file mode 100644
index 00000000..29fccfe8
--- /dev/null
+++ b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
@@ -0,0 +1,357 @@
+/*
+ *
+ * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
+ *
+ * This file is part of DIYLC.
+ *
+ * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
+ * .
+ *
+ */
+package org.diylc.netlist;
+
+import static org.junit.Assert.assertEquals;
+import java.util.Arrays;
+
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+import org.diylc.components.passive.AxialFilmCapacitor;
+import org.diylc.components.passive.Resistor;
+========
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+import org.junit.Test;
+
+import org.diylc.components.electromechanical.OpenJack1_4;
+import org.diylc.components.guitar.HumbuckerPickup;
+import org.diylc.components.guitar.SingleCoilPickup;
+import org.diylc.components.passive.PotentiometerPanel;
+import org.diylc.components.passive.RadialCeramicDiskCapacitor;
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+========
+import org.diylc.netlist.Group;
+import org.diylc.netlist.GuitarDiagramAnalyzer;
+import org.diylc.netlist.Netlist;
+import org.diylc.netlist.Tree;
+import org.diylc.netlist.TreeException;
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+
+public class GuitarDiagramAnalyzerTests {
+
+ @Test
+ public void testOneSinglePickup() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2);
+ netlist.add(tipGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("Pickup.North<-", s);
+ }
+
+ @Test
+ public void testOneSinglePickupVolPot() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol));
+ Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s);
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+ }
+
+ @Test
+ public void testOneSinglePickupVolPotTrebleBleedSeries() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ AxialFilmCapacitor cap = new AxialFilmCapacitor();
+ cap.setName("Cbleed");
+ Resistor resistor = new Resistor();
+ resistor.setName("Rbleed");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol));
+ Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(resistor, 1);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1).connect(cap, 1);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2);
+ Group trebleBleedGroup = new Group().connect(cap, 0).connect(resistor, 0);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(trebleBleedGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("((((Cbleed + Rbleed) || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s);
+ }
+
+ @Test
+ public void testOneSinglePickupVolPotTrebleBleedParallel() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ AxialFilmCapacitor cap = new AxialFilmCapacitor();
+ cap.setName("Cbleed");
+ Resistor resistor = new Resistor();
+ resistor.setName("Rbleed");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol));
+ Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(resistor, 1).connect(cap, 1);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1).connect(resistor, 0).connect(cap, 0);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(((Cbleed || Rbleed || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s);
+========
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+ }
+
+ @Test
+ public void testOneSinglePickupVolTonePot() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ PotentiometerPanel tone = new PotentiometerPanel();
+ tone.setName("Tone");
+ RadialCeramicDiskCapacitor cap = new RadialCeramicDiskCapacitor();
+ cap.setName("Cap");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol, tone, cap));
+ Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(tone, 2);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
+ Group sleeveGroup =
+ new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2).connect(cap, 0);
+ Group toneGroup = new Group().connect(tone, 1).connect(cap, 1);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+ assertEquals("((Volume.1-2 + ((Tone.2-3 + Cap) || Pickup.North<-)) || Volume.2-3)", s);
+========
+ assertEquals("((Volume.1-2 + (Tone.2-3 + Cap) || Pickup.North<-) || Volume.2-3)", s);
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+ }
+
+ @Test
+ public void testTwoSinglePickupsMasterVolSeparateTone() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup1 = new SingleCoilPickup();
+ pickup1.setName("Pickup1");
+ SingleCoilPickup pickup2 = new SingleCoilPickup();
+ pickup2.setName("Pickup2");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ PotentiometerPanel tone1 = new PotentiometerPanel();
+ tone1.setName("Tone1");
+ PotentiometerPanel tone2 = new PotentiometerPanel();
+ tone2.setName("Tone2");
+ RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor();
+ cap1.setName("Cap1");
+ RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor();
+ cap2.setName("Cap2");
+ Netlist netlist =
+ new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2));
+ Group hotGroup = new Group().connect(pickup1, 1).connect(vol, 0).connect(tone1, 2)
+ .connect(pickup2, 1).connect(tone2, 2);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2)
+ .connect(vol, 2).connect(cap1, 0).connect(cap2, 0);
+ Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1);
+ Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group)
+ .add(tone2Group);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals(
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+ "((Volume.1-2 + (Pickup1.North<- || Pickup2.North<- || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)",
+========
+ "((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)",
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+ s);
+ }
+
+ @Test
+ public void testOneSinglePickupReverse() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ SingleCoilPickup pickup = new SingleCoilPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1);
+ netlist.add(tipGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("Pickup.North->", s);
+ }
+
+ @Test
+ public void testOneHumbuckerSeries() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup = new HumbuckerPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0);
+ Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 3);
+ netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(Pickup.North<- + Pickup.South<-)", s);
+ }
+
+ @Test
+ public void testOneHumbuckerSeriesReverse() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup = new HumbuckerPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 3);
+ Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 0);
+ netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(Pickup.South-> + Pickup.North->)", s);
+ }
+
+ @Test
+ public void testOneHumbuckerParallel() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup = new HumbuckerPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 3);
+ netlist.add(tipGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(Pickup.North<- || Pickup.South<-)", s);
+ }
+
+ @Test
+ public void testOneHumbuckerParallelOutOfPhase() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup = new HumbuckerPickup();
+ pickup.setName("Pickup");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 3);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 2);
+ netlist.add(tipGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(Pickup.North<- || Pickup.South->)", s);
+ }
+
+ @Test
+ public void testTwoHumbuckersSeries() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup1 = new HumbuckerPickup();
+ pickup1.setName("Pickup1");
+ HumbuckerPickup pickup2 = new HumbuckerPickup();
+ pickup2.setName("Pickup2");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0);
+ Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
+ Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
+ Group joinGroup = new Group().connect(pickup1, 3).connect(pickup2, 0);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup2, 3);
+ netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(joinGroup).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("(Pickup1.North<- + Pickup1.South<- + Pickup2.North<- + Pickup2.South<-)", s);
+ }
+
+ @Test
+ public void testTwoHumbuckersParallel() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup1 = new HumbuckerPickup();
+ pickup1.setName("Pickup1");
+ HumbuckerPickup pickup2 = new HumbuckerPickup();
+ pickup2.setName("Pickup2");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 0);
+ Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
+ Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3);
+ netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-))", s);
+ }
+
+ @Test
+ public void testTwoHumbuckersParallelOutOfPhase() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup1 = new HumbuckerPickup();
+ pickup1.setName("Pickup1");
+ HumbuckerPickup pickup2 = new HumbuckerPickup();
+ pickup2.setName("Pickup2");
+ Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
+ Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 3);
+ Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
+ Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 0);
+ netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.South-> + Pickup2.North->))", s);
+ }
+
+ @Test
+ public void testTwoHumbuckersMasterVolSeparateTone() throws TreeException {
+ OpenJack1_4 jack = new OpenJack1_4();
+ HumbuckerPickup pickup1 = new HumbuckerPickup();
+ pickup1.setName("Pickup1");
+ HumbuckerPickup pickup2 = new HumbuckerPickup();
+ pickup2.setName("Pickup2");
+ PotentiometerPanel vol = new PotentiometerPanel();
+ vol.setName("Volume");
+ PotentiometerPanel tone1 = new PotentiometerPanel();
+ tone1.setName("Tone1");
+ PotentiometerPanel tone2 = new PotentiometerPanel();
+ tone2.setName("Tone2");
+ RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor();
+ cap1.setName("Cap1");
+ RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor();
+ cap2.setName("Cap2");
+ Netlist netlist =
+ new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2));
+ Group hotGroup = new Group().connect(pickup1, 0).connect(vol, 0).connect(tone1, 2)
+ .connect(pickup2, 0).connect(tone2, 2);
+ Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
+ Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3)
+ .connect(vol, 2).connect(cap1, 0).connect(cap2, 0);
+ Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1);
+ Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1);
+ Group coilTap1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
+ Group coilTap2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
+ netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group)
+ .add(tone2Group).add(coilTap1).add(coilTap2);
+ Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
+ String s = tree.toString();
+ assertEquals(
+<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java
+ "((Volume.1-2 + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)",
+========
+ "((Volume.1-2 + (Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2)) || Volume.2-3)",
+>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java
+ s);
+ }
+}
diff --git a/diylc/diylc-swing/deploy/mac/README.md b/diylc/diylc-swing/deploy/mac/README.md
new file mode 100644
index 00000000..1c0f346e
--- /dev/null
+++ b/diylc/diylc-swing/deploy/mac/README.md
@@ -0,0 +1,166 @@
+# Setting up macOS Build Environment for DIYLC
+
+This document describes how to set up a macOS machine for building and signing DIYLC application bundles.
+
+## Prerequisites
+
+1. **macOS System**
+ - macOS 11 (Big Sur) or later
+ - Xcode Command Line Tools installed
+ ```bash
+ xcode-select --install
+ ```
+
+2. **Java Development Kit**
+ - Install JDK 17 (recommended to use SDKMAN!)
+ ```bash
+ # Install SDKMAN!
+ curl -s "https://get.sdkman.io" | bash
+ source "$HOME/.sdkman/bin/sdkman-init.sh"
+
+ # Install JDK 17
+ sdk install java 17.0.14-tem
+ ```
+
+3. **Maven**
+ - Install Maven 3.9 or later
+ ```bash
+ sdk install maven
+ ```
+
+## Apple Developer Account Setup
+
+1. **Apple Developer Account**
+ - Enroll in the [Apple Developer Program](https://developer.apple.com/programs/)
+ - You need a paid membership ($99/year) for distribution signing
+
+2. **Developer Certificate**
+ - Open Keychain Access
+ - Go to Certificate Assistant → Request a Certificate from a Certificate Authority
+ - Fill in your email and name
+ - Save to disk
+ - Go to [Apple Developer Certificates](https://developer.apple.com/account/resources/certificates/list)
+ - Create a new Developer ID Application certificate
+ - Download and double-click to install in Keychain
+
+3. **Notarization Setup**
+ - Create an app-specific password:
+ 1. Go to [Apple ID Account](https://appleid.apple.com/)
+ 2. Security → App-Specific Passwords → Generate Password
+ 3. Save this password securely
+
+ - Create a keychain profile for notarization:
+ ```bash
+ xcrun notarytool store-credentials "AC_PASSWORD" \
+ --apple-id "your.email@example.com" \
+ --team-id "YOUR_TEAM_ID" \
+ --password "app-specific-password"
+ ```
+
+## Environment Configuration
+
+1. **Set Developer Identity**
+ - Find your Developer ID in Keychain Access
+ ```bash
+ security find-identity -v -p codesigning
+ ```
+ - Set the environment variable (add to your ~/.zshrc):
+ ```bash
+ export APPLE_DEVELOPER_IDENTITY="Developer ID Application: Your Name (TEAM_ID)"
+ ```
+
+2. **Verify Setup**
+ ```bash
+ # Verify codesign is available
+ codesign --version
+
+ # Verify notarytool is available
+ xcrun notarytool --version
+
+ # Verify your identity is set
+ echo $APPLE_DEVELOPER_IDENTITY
+ ```
+
+## Building DIYLC
+
+1. **Clone the Repository**
+ ```bash
+ git clone https://github.com/bancika/diy-layout-creator.git
+ cd diy-layout-creator/diylc
+ ```
+
+2. **Build for Intel Macs**
+ ```bash
+ mvn clean package -P mac-x86
+ ```
+
+3. **Build for Apple Silicon Macs**
+ ```bash
+ mvn clean package -P mac-arm
+ ```
+
+4. **Build Both Architectures**
+ ```bash
+ mvn clean package -P mac-x86,mac-arm
+ ```
+
+## Output Files
+
+After successful builds, you'll find these files in the `diylc-swing/target` directory:
+
+**Signed and Notarized Builds:**
+- `diylc--osx-x86.zip` - Signed and notarized Intel build
+- `diylc--osx-arm.zip` - Signed and notarized ARM build
+
+**Unsigned Builds:**
+- `diylc--osx-x86-unsigned.zip` - Unsigned Intel build
+- `diylc--osx-arm-unsigned.zip` - Unsigned ARM build
+
+The unsigned builds are created before the signing and notarization process and can be useful for testing or in environments where code signing is not required.
+
+## Troubleshooting
+
+1. **Signing Issues**
+ - Verify your certificate is valid:
+ ```bash
+ security find-identity -v -p codesigning
+ ```
+ - Check certificate expiration in Keychain Access
+
+2. **Notarization Issues**
+ - Check notarization status:
+ ```bash
+ xcrun notarytool log --keychain-profile "AC_PASSWORD"
+ ```
+ - Verify entitlements are correct in `deploy/mac/entitlements.plist`
+
+3. **Build Issues**
+ - Clear Maven cache:
+ ```bash
+ rm -rf ~/.m2/repository/org/diylc
+ ```
+ - Verify JDK version:
+ ```bash
+ java -version
+ ```
+
+## Common Issues
+
+1. **"The specified item could not be found in the keychain"**
+ - Solution: Verify your Developer ID certificate is in the keychain
+ - Check the exact name matches `APPLE_DEVELOPER_IDENTITY`
+
+2. **"No account for team found"**
+ - Solution: Verify your Apple Developer membership is active
+ - Check team ID in notarytool credentials
+
+3. **"The binary is not signed"**
+ - Solution: Check that the signing process isn't being skipped
+ - Verify all dependencies are properly signed
+
+## Support
+
+For additional help:
+- Check the [Apple Code Signing Documentation](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution)
+- File an issue on the DIYLC GitHub repository
+- Contact the development team
\ No newline at end of file
diff --git a/diylc/diylc-swing/deploy/mac/README.txt b/diylc/diylc-swing/deploy/mac/README.txt
new file mode 100644
index 00000000..2e48c691
--- /dev/null
+++ b/diylc/diylc-swing/deploy/mac/README.txt
@@ -0,0 +1,17 @@
+Thank you for downloading DIY Layout Creator!
+
+This app bundle is fully functional but not officially notarized by Apple.
+To run it on your Mac, you'll need to approve it in the 'Privacy & Security' settings.
+
+Without this approval, macOS will mark it as potentially damaged and prevent it from opening.
+
+A notarized version is available, but due to Apple Developer Program costs and additional requirements,
+it is exclusively offered to DIYLC Patreon supporters. For a small monthly membership fee,
+you'll receive several benefits:
+
+- Access to the notarized version
+- Early access to upcoming features
+- Voting rights to influence the development roadmap
+- Direct developer support
+
+Join our community at http://www.diy-fever.com/patreon
diff --git a/diylc/diylc-swing/deploy/mac/entitlements.plist b/diylc/diylc-swing/deploy/mac/entitlements.plist
new file mode 100644
index 00000000..b0612d04
--- /dev/null
+++ b/diylc/diylc-swing/deploy/mac/entitlements.plist
@@ -0,0 +1,20 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-library-validation
+
+ com.apple.security.cs.debugger
+
+ com.apple.security.get-task-allow
+
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.files.downloads.read-write
+
+
+
\ No newline at end of file
diff --git a/diylc/diylc-swing/pom.xml b/diylc/diylc-swing/pom.xml
index 7e9de833..95c2456b 100644
--- a/diylc/diylc-swing/pom.xml
+++ b/diylc/diylc-swing/pom.xml
@@ -180,6 +180,17 @@
false
diylc
+
+
+ org.diylc.DIYLCStarter
+
+
+
+
+
+ *:*
+
+
*:*
@@ -190,11 +201,104 @@
-
-
- org.diylc.DIYLCStarter
-
-
+ false
+ false
+ true
+ ${project.build.directory}/dependency-reduced-pom.xml
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.6.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.6.1
+
+
+ copy-system-dependencies
+ prepare-package
+
+ copy-dependencies
+
+
+ system
+ ${project.build.directory}/system-libs
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 3.1.0
+
+
+ merge-system-jars
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sign-jar-launcher
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -304,21 +408,22 @@
compression="gzip" />
-
-
+
+
-
+
+
+
+
+ JAVA_HOME="$APPDIR/usr/lib/jre"
+ JAVA_HOME="$APPDIR/usr/bin/jre"
+
-
-
-
-
-
@@ -554,7 +659,7 @@
17.0.14_7
OpenJDK17U-jre_x64_mac_hotspot_${jdk.version.file}.tar.gz
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-${jdk.version}/${jdk.archive.osx}
- ${project.build.directory}/jre_x86
+ ${project.build.directory}/jre_x86.bundle
@@ -656,10 +761,158 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -676,7 +929,7 @@
17.0.14_7
OpenJDK17U-jre_aarch64_mac_hotspot_${jdk.version.file}.tar.gz
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-${jdk.version}/${jdk.archive.osx}
- ${project.build.directory}/jre_arm
+ ${project.build.directory}/jre_arm.bundle
@@ -698,22 +951,22 @@
-
+
-
-
+
-
-
+
@@ -779,10 +1032,158 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/diylc/lib/app-framework-1.0.jar b/diylc/lib/app-framework-1.0.jar
new file mode 100644
index 00000000..023be5c4
Binary files /dev/null and b/diylc/lib/app-framework-1.0.jar differ
diff --git a/diylc/lib/swing-framework-1.0.jar b/diylc/lib/swing-framework-1.0.jar
new file mode 100644
index 00000000..564433ab
Binary files /dev/null and b/diylc/lib/swing-framework-1.0.jar differ