fix mavenized

This commit is contained in:
Branislav Stojkovic
2025-03-12 11:11:59 +01:00
parent eadcb8d81e
commit 39ba93ff2c
4 changed files with 337 additions and 290 deletions
BIN
View File
Binary file not shown.
@@ -1,281 +1,283 @@
/* /*
* *
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* *
* This file is part of DIYLC. * This file is part of DIYLC.
* *
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version. * 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 * 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 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. * Public License for more details.
* *
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
package org.diylc.netlist; package org.diylc.netlist;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDIYComponent;
public abstract class AbstractNetlistAnalyzer {
public abstract class AbstractNetlistAnalyzer {
public AbstractNetlistAnalyzer() {}
public AbstractNetlistAnalyzer() {
} public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) throws TreeException {
Map<String, Summary> summaries = new HashMap<String, Summary>();
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) for (Netlist n : netlists) {
throws TreeException { Summary s = summarize(n, preferredOutput);
Map<String, Summary> summaries = new HashMap<String, Summary>(); if (summaries.containsKey(s.getSummary()))
for (Netlist n : netlists) { summaries.get(s.getSummary()).append(n);
Summary s = summarize(n, preferredOutput); else
if (summaries.containsKey(s.getSummary())) summaries.put(s.getSummary(), s);
summaries.get(s.getSummary()).append(n); }
else
summaries.put(s.getSummary(), s); List<Summary> res = new ArrayList<Summary>(summaries.values());
} Collections.sort(res);
return res;
List<Summary> res = new ArrayList<Summary>(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) {
protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException; Tree tree = new Tree(TreeConnectionType.Parallel);
connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), new HashSet<Node>());
public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) {
Tree tree = new Tree(TreeConnectionType.Parallel); return tree;
connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), }
new HashSet<Node>());
// protected Tree removeRedundantElements(Tree tree) {
return tree; // List<Tree> children = tree.getChildren()
} // .stream()
// .map(t -> removeRedundantElements(t))
protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List<Tree> concurrentPaths, // .collect(Collectors.toList());
Tree currentPath, Set<Node> visited) { // if (children.size() == 1) {
if (nodeA == nodeB) { // Tree first = children.get(0);
concurrentPaths.add(currentPath); // return first;
return; // }
} // }
Group groupA = findGroup(netlist, nodeA); protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List<Tree> concurrentPaths, Tree currentPath,
if (groupA == null) Set<Node> visited) {
return; if (nodeA == nodeB) {
concurrentPaths.add(currentPath);
if (groupA.getNodes().contains(nodeB)) { return;
concurrentPaths.add(currentPath); }
return;
} Group groupA = findGroup(netlist, nodeA);
Set<Node> pathVisited = new HashSet<>(visited); if (groupA == null)
pathVisited.add(nodeA); return;
// First collect all immediate next nodes and their paths if (groupA.getNodes().contains(nodeB)) {
Map<Node, List<Tree>> nextNodes = new HashMap<>(); concurrentPaths.add(currentPath);
for (Node n : groupA.getNodes()) { return;
if (pathVisited.contains(n)) }
continue;
visited.addAll(groupA.getNodes());
IDIYComponent<?> c = n.getComponent();
for (int i = 0; i < c.getControlPointCount(); i++) { List<Tree> newConcurrentPaths = new ArrayList<Tree>();
int targetPoint = i;
int sourcePoint = n.getPointIndex(); for (Node n : groupA.getNodes()) {
IDIYComponent<?> c = n.getComponent();
if (targetPoint == sourcePoint) for (int i = 0; i < c.getControlPointCount(); i++) {
continue; if (i != n.getPointIndex() && c.getInternalLinkName(i, n.getPointIndex()) != null) {
TreeLeaf l = new TreeLeaf(c, i, n.getPointIndex());
if (c.getInternalLinkName(targetPoint, sourcePoint) != null) { Node newNodeA = new Node(c, i, n.getZIndex());
Node newNodeA = new Node(c, targetPoint, n.getZIndex()); if (!visited.contains(newNodeA)) {
if (pathVisited.contains(newNodeA)) // visited.add(n);
continue; Tree newCurrentPath = null;
try {
try { newCurrentPath = (Tree) currentPath.clone();
Tree newPath = (Tree) currentPath.clone(); } catch (CloneNotSupportedException e) {
TreeLeaf leaf = new TreeLeaf(c, targetPoint, sourcePoint); }
Tree newItem = new Tree(leaf); Tree newItem = new Tree(l);
if (!newCurrentPath.getChildren().contains(newItem))
if (!newPath.getChildren().contains(newItem)) { newCurrentPath.getChildren().add(newItem);
newPath.getChildren().add(newItem); // if (!currentPath.contains(l))
nextNodes.computeIfAbsent(newNodeA, k -> new ArrayList<>()).add(newPath); // newCurrentPath.add(l);
} Set<Node> newVisited = new HashSet<Node>(visited);
} catch (CloneNotSupportedException e) { connectNodes(netlist, newNodeA, nodeB, newConcurrentPaths, newCurrentPath, newVisited);
// Skip this path if clone fails }
} }
} }
} }
}
if (newConcurrentPaths.size() == 0)
// Now explore each next node return;
List<Tree> allPaths = new ArrayList<>();
for (Map.Entry<Node, List<Tree>> entry : nextNodes.entrySet()) { if (newConcurrentPaths.size() == 1) {
for (Tree path : entry.getValue()) { if (newConcurrentPaths.get(0).getConnectionType() == TreeConnectionType.Series) {
List<Tree> branchPaths = new ArrayList<>(); currentPath.getChildren().clear();
connectNodes(netlist, entry.getKey(), nodeB, branchPaths, path, pathVisited); currentPath.getChildren().addAll(newConcurrentPaths.get(0).getChildren());
allPaths.addAll(branchPaths); } else {
} currentPath.getChildren().add(newConcurrentPaths.get(0));
} }
concurrentPaths.add(currentPath);
if (allPaths.isEmpty()) return;
return; }
if (allPaths.size() > 1) { mergePaths(newConcurrentPaths, false);
// Find common prefix among all paths concurrentPaths.addAll(newConcurrentPaths);
List<Tree> commonPrefix = findCommonElements(allPaths, true, false); }
// Create a new tree for the merged result protected void mergePaths(List<Tree> paths, boolean backward) {
Tree mergedTree = new Tree(TreeConnectionType.Series); Map<Tree, Integer> uniques = new HashMap<Tree, Integer>();
for (Tree t : paths) {
// Add common prefix elements if (t.getConnectionType() != TreeConnectionType.Series)
for (Tree prefixElement : commonPrefix) { continue;
mergedTree.getChildren().add(prefixElement); Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0);
} Integer count = uniques.get(key);
uniques.put(key, count == null ? 1 : count + 1);
// Extract unique parts }
List<Tree> uniqueParts = new ArrayList<>();
for (Tree path : allPaths) { List<Tree> unmerged = new ArrayList<Tree>(paths);
Tree uniquePart = extractUniquePart(path, commonPrefix.size(), 0);
if (uniquePart != null) { for (Map.Entry<Tree, Integer> e : uniques.entrySet()) {
if (uniquePart.getChildren().size() == 1) { if (e.getValue() > 1) {
uniqueParts.add(uniquePart.getChildren().get(0)); List<Tree> pathsToMerge = new ArrayList<Tree>();
} else { for (Tree t : paths) {
uniqueParts.add(uniquePart); Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0);
} if (key.equals(e.getKey()))
} pathsToMerge.add(t);
} }
unmerged.removeAll(pathsToMerge);
// Create parallel section for unique parts
if (!uniqueParts.isEmpty()) { Tree jointStart = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
Tree parallelSection = new Tree(TreeConnectionType.Parallel); Tree jointFinish = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
parallelSection.getChildren().addAll(uniqueParts);
Tree unique = e.getKey();
// Add parallel section to series container
Tree parallelContainer = new Tree(TreeConnectionType.Series); for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) {
parallelContainer.getChildren().add(parallelSection); boolean canMerge = true;
mergedTree.getChildren().add(parallelContainer); unique = pathsToMerge.get(0).getChildren().get(backward ? pathsToMerge.get(0).getChildren().size() - i - 1 : i);
} for (Tree t : pathsToMerge) {
if (t.getChildren().size() <= i || !t.getChildren().get(backward ? t.getChildren().size() - i - 1 : i).equals(unique)) {
concurrentPaths.add(mergedTree); canMerge = false;
} else { break;
concurrentPaths.add(allPaths.get(0)); }
} }
} if (canMerge)
(backward ? jointFinish : jointStart).getChildren().add(unique);
private List<Tree> findCommonElements(List<Tree> paths, boolean fromStart, boolean backward) { else
if (paths.isEmpty()) break;
return new ArrayList<>(); }
List<Tree> common = new ArrayList<>(); for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) {
Tree template = paths.get(0); boolean canMerge = true;
int maxLength = template.getChildren().size(); unique = pathsToMerge.get(0).getChildren().get(backward ? i : pathsToMerge.get(0).getChildren().size() - i - 1);
for (Tree t : pathsToMerge) {
for (int i = 0; i < maxLength; i++) { if (t.getChildren().size() <= i || !t.getChildren().get(backward ? 0 : t.getChildren().size() - 1).equals(unique)) {
int index = fromStart ? canMerge = false;
(backward ? template.getChildren().size() - i - 1 : i) : break;
(backward ? i : template.getChildren().size() - i - 1); }
}
if (index < 0 || index >= template.getChildren().size()) if (canMerge)
break; (backward ? jointStart : jointFinish).getChildren().add(unique);
else
Tree element = template.getChildren().get(index); break;
boolean isCommon = true; }
for (int j = 1; j < paths.size(); j++) { if (!jointStart.getChildren().isEmpty() || !jointFinish.getChildren().isEmpty()) {
Tree current = paths.get(j); Tree mergedTree = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
if (current.getChildren().size() <= i || index >= current.getChildren() Tree parallelSection = new Tree(new ArrayList<Tree>(pathsToMerge), TreeConnectionType.Parallel);
.size() || !current.getChildren().get(index).equals(element)) { if (!jointStart.getChildren().isEmpty()) {
isCommon = false; mergedTree.getChildren().add(jointStart);
break; for (Tree t : parallelSection.getChildren()) {
} t.trimChildrenLeft(jointStart.getChildren().size());
} }
}
if (isCommon) { mergedTree.getChildren().add(parallelSection);
common.add(element); if (!jointFinish.getChildren().isEmpty()) {
} else { mergedTree.getChildren().add(jointFinish);
break; for (Tree t : parallelSection.getChildren()) {
} t.trimChildrenRight(jointFinish.getChildren().size());
} }
}
return common; paths.removeAll(pathsToMerge);
} paths.add(mergedTree);
}
private Tree extractUniquePart(Tree path, int prefixSize, int suffixSize) { }
if (path.getChildren().size() <= prefixSize + suffixSize) }
return null;
// try in the opposite direction for paths we haven't merged
Tree uniquePart = new Tree(TreeConnectionType.Series); if (!backward && !unmerged.isEmpty()) {
for (int i = prefixSize; i < path.getChildren().size() - suffixSize; i++) { paths.removeAll(unmerged);
uniquePart.getChildren().add(path.getChildren().get(i)); mergePaths(unmerged, true);
} paths.addAll(unmerged);
}
return uniquePart.getChildren().isEmpty() ? null : uniquePart; }
}
protected Group findGroup(Netlist netlist, Node node) {
protected Group findGroup(Netlist netlist, Node node) { for (Group g : netlist.getGroups())
for (Group g : netlist.getGroups()) if (g.getNodes().contains(node))
if (g.getNodes().contains(node)) return g;
return g; return null;
return null; }
}
protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) {
protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) { List<Node> res = new ArrayList<Node>();
List<Node> res = new ArrayList<Node>(); for (Group g : netlist.getGroups()) {
for (Group g : netlist.getGroups()) { for (Node n : g.getNodes()) {
for (Node n : g.getNodes()) { if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
if (typeNames.contains(n.getComponent().getClass() && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
.getCanonicalName()) && (nodeName == null || n.getDisplayName() res.add(n);
.equalsIgnoreCase(nodeName))) { }
res.add(n); }
} }
} return res;
} }
return res;
} protected String extractName(IDIYComponent<?> c) {
return c.getName() + " " + (c.getValueForDisplay() == null ? "" : c.getValueForDisplay());
public static List<Set<IDIYComponent<?>>> extractComponentGroups(List<Netlist> netlists) { }
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Netlist n : netlists) { public static List<Set<IDIYComponent<?>>> extractComponentGroups(List<Netlist> netlists) {
res.addAll(extractComponentGroups(n)); List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
} for (Netlist n : netlists) {
return res; res.addAll(extractComponentGroups(n));
} }
return res;
public static List<Set<IDIYComponent<?>>> extractComponentGroups(Netlist netlist) { }
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Group g : netlist.getGroups()) { public static List<Set<IDIYComponent<?>>> extractComponentGroups(Netlist netlist) {
Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>(); List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Node n : g.getNodes()) for (Group g : netlist.getGroups()) {
components.add(n.getComponent()); Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
res.add(components); for (Node n : g.getNodes())
} components.add(n.getComponent());
return res; res.add(components);
} }
return res;
protected int find(Node node, List<Group> groups) { }
for (int i = 0; i < groups.size(); i++)
if (groups.get(i).getNodes().contains(node)) protected int find(Node node, List<Group> groups) {
return i; for (int i = 0; i < groups.size(); i++)
return -1; if (groups.get(i).getNodes().contains(node))
} return i;
return -1;
protected boolean intersect(List<Group> groups, Node node) { }
for (Group g : groups)
if (g.getNodes().contains(node)) protected boolean intersect(List<Group> groups, Node node) {
return true; for (Group g : groups)
return false; if (g.getNodes().contains(node))
} return true;
return false;
protected Node intersect(List<Group> groups, Group group) { }
for (Group g : groups)
for (Node node : group.getNodes()) protected Node intersect(List<Group> groups, Group group) {
if (g.getNodes().contains(node)) for (Group g : groups)
return node; for (Node node : group.getNodes())
return null; if (g.getNodes().contains(node))
} return node;
} return null;
}
}
@@ -21,6 +21,8 @@ package org.diylc.netlist;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.util.Arrays; import java.util.Arrays;
import org.diylc.components.passive.AxialFilmCapacitor;
import org.diylc.components.passive.Resistor;
import org.junit.Test; import org.junit.Test;
import org.diylc.components.electromechanical.OpenJack1_4; import org.diylc.components.electromechanical.OpenJack1_4;
@@ -28,13 +30,8 @@ import org.diylc.components.guitar.HumbuckerPickup;
import org.diylc.components.guitar.SingleCoilPickup; import org.diylc.components.guitar.SingleCoilPickup;
import org.diylc.components.passive.PotentiometerPanel; import org.diylc.components.passive.PotentiometerPanel;
import org.diylc.components.passive.RadialCeramicDiskCapacitor; import org.diylc.components.passive.RadialCeramicDiskCapacitor;
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;
public class GuitarAbstractNetlistAnalyzerTests { public class GuitarDiagramAnalyzerTests {
@Test @Test
public void testOneSinglePickup() throws TreeException { public void testOneSinglePickup() throws TreeException {
@@ -67,6 +64,49 @@ public class GuitarAbstractNetlistAnalyzerTests {
assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s); assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s);
} }
@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);
}
@Test @Test
public void testOneSinglePickupVolTonePot() throws TreeException { public void testOneSinglePickupVolTonePot() throws TreeException {
OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
@@ -87,7 +127,7 @@ public class GuitarAbstractNetlistAnalyzerTests {
netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup); netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup);
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString(); String s = tree.toString();
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);
} }
@Test @Test
@@ -121,7 +161,7 @@ public class GuitarAbstractNetlistAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString(); String s = tree.toString();
assertEquals( assertEquals(
"((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)", "((Volume.1-2 + ((Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-)) || Volume.2-3)",
s); s);
} }
@@ -285,7 +325,7 @@ public class GuitarAbstractNetlistAnalyzerTests {
Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
String s = tree.toString(); String s = tree.toString();
assertEquals( assertEquals(
"((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)",
s); s);
} }
} }
+5
View File
@@ -20,20 +20,24 @@
10 throws / 10 positions 10 throws / 10 positions
11 throws / 11 positions 11 throws / 11 positions
12 throws / 12 positions 12 throws / 12 positions
135 degrees clockwise
180 degrees clockwise 180 degrees clockwise
1P12T 1P12T
2 throws / 2 positions 2 throws / 2 positions
2 throws / 3 positions / OFF even positions 2 throws / 3 positions / OFF even positions
225 degrees clockwise
270 degrees clockwise 270 degrees clockwise
2P5T 2P5T
2P6T 2P6T
3 throws / 3 positions 3 throws / 3 positions
3 throws / 5 positions / SHORT even positions 3 throws / 5 positions / SHORT even positions
315 degrees clockwise
3P4T 3P4T
3PDT 3PDT
3PDT (On/Off/On) 3PDT (On/Off/On)
4 band 4 band
4 throws / 4 positions 4 throws / 4 positions
45 degrees clockwise
4P3T 4P3T
4P5T 4P5T
4P5T (Super/Mega) 4P5T (Super/Mega)
@@ -598,6 +602,7 @@ Vertical Inline
Vertical Offset 1 Vertical Offset 1
Vertical Offset 2 Vertical Offset 2
View View
Virtual Multimeter
Visible Visible
Voltage Voltage
Wafer Wafer