Clazz.declarePackage("JS");
Clazz.load(["JU.BS", "$.V3"], "JS.CIPData", ["JU.Lst", "$.Measure", "$.P4", "JS.CIPChirality", "JU.BSUtil", "$.Logger"], function(){
var c$ = Clazz.decorateAsClass(function(){
this.testRule6Full = false;
this.vwr = null;
this.atoms = null;
this.bsAtoms = null;
this.bsMolecule = null;
this.bsAromatic = null;
this.bsXAromatic = null;
this.bsNegativeAromatic = null;
this.bsAzacyclic = null;
this.bsAtropisomeric = null;
this.bsHelixM = null;
this.bsHelixP = null;
this.lstSmallRings = null;
this.bsAmide = null;
this.bsKekuleAmbiguous = null;
this.bsEnes = null;
this.vNorm = null;
this.vTemp = null;
this.vTemp2 = null;
Clazz.instantialize(this, arguments);}, JS, "CIPData", null);
Clazz.prepareFields (c$, function(){
this.bsXAromatic =  new JU.BS();
this.bsNegativeAromatic =  new JU.BS();
this.bsAtropisomeric =  new JU.BS();
this.bsAmide =  new JU.BS();
this.bsKekuleAmbiguous =  new JU.BS();
this.bsEnes =  new JU.BS();
this.vNorm =  new JU.V3();
this.vTemp =  new JU.V3();
this.vTemp2 =  new JU.V3();
});
Clazz.makeConstructor(c$, 
function(){
});
Clazz.defineMethod(c$, "isTracker", 
function(){
return false;
});
Clazz.defineMethod(c$, "isSmiles", 
function(){
return false;
});
Clazz.defineMethod(c$, "set", 
function(vwr, bsAtoms){
this.vwr = vwr;
this.atoms = vwr.ms.at;
this.bsAtoms = bsAtoms;
this.bsMolecule = vwr.ms.getMoleculeBitSet(bsAtoms);
this.init();
return this;
}, "JV.Viewer,JU.BS");
Clazz.defineMethod(c$, "init", 
function(){
try {
var lstRing = this.match("[r]");
if (lstRing.isEmpty()) {
this.lstSmallRings =  new Array(0);
} else {
this.lstSmallRings = this.getList("*1**1||*1***1||*1****1||*1*****1||*1******1");
}this.bsAromatic = this.match("a");
if (!this.bsAromatic.isEmpty()) {
this.bsAtropisomeric = this.match("[!H](.t1:-20,20)a{a(.t2:-20,20)-a}a[!H]");
this.bsHelixM = this.match("A{a}(.t:-10,-40)a(.t:-10,-40)aaa");
this.bsHelixP = this.match("A{a}(.t:10,40)a(.t:10,40)aaa");
this.bsXAromatic = this.match("[r5v3n+0,r5v2o+0]");
this.bsNegativeAromatic = this.match("[a-]");
if (!this.match("[n+1,o+1]").isEmpty() && !this.bsXAromatic.isEmpty()) {
this.bsKekuleAmbiguous.or(this.match("a1[n+,o+]a[n,o]a1"));
this.bsKekuleAmbiguous.or(this.match("a1[n+,o+][n,o]aa1"));
}if (!this.bsNegativeAromatic.isEmpty()) this.bsKekuleAmbiguous.or(this.match("a1=a[a-]a=a1"));
var lstR6a = this.getList("a1aaaaa1");
for (var i = lstR6a.length; --i >= 0; ) {
this.bsKekuleAmbiguous.or(lstR6a[i]);
}
}this.getAzacyclic();
} catch (e) {
if (Clazz.exceptionOf(e, Exception)){
} else {
throw e;
}
}
});
Clazz.defineMethod(c$, "getList", 
function(smarts){
var level = JU.Logger.getLogLevel();
JU.Logger.setLogLevel(Math.min(level, 4));
var list = this.vwr.getSubstructureSetArray(smarts, this.bsMolecule, 2);
JU.Logger.setLogLevel(level);
return list;
}, "~S");
Clazz.defineMethod(c$, "match", 
function(smarts){
var level = JU.Logger.getLogLevel();
JU.Logger.setLogLevel(Math.min(level, 4));
var bs = this.vwr.getSmartsMatch(smarts, this.bsMolecule);
JU.Logger.setLogLevel(level);
return bs;
}, "~S");
Clazz.defineMethod(c$, "getEneKekule", 
function(){
if (this.bsEnes.cardinality() < 8) return;
var bsAllEnes = this.bsEnes.clone();
var bsPath =  new JU.BS();
this.bsEnes.andNot(this.bsKekuleAmbiguous);
var bsEneAtom1 =  new JU.BS();
for (var i = this.bsEnes.nextSetBit(0); i >= 0; i = this.bsEnes.nextSetBit(i + 1)) {
bsPath.clearAll();
bsEneAtom1.clearAll();
this.checkEne(bsAllEnes, bsPath, -1, i, 2, bsEneAtom1);
}
});
Clazz.defineMethod(c$, "checkEne", 
function(bsAllEnes, bsPath, iLast, iAtom, order, bsEneAtom1){
if (bsPath.get(iAtom)) return (bsEneAtom1.get(iAtom) == (order == 2) ? iAtom : -1);
bsPath.set(iAtom);
var a = this.atoms[iAtom];
var isLoop = -1;
var edges = a.getEdges();
if (order == 2) bsEneAtom1.set(iAtom);
for (var ib = a.getBondCount(); --ib >= 0; ) {
if (this.getBondOrder(edges[ib]) != order) continue;
var b = edges[ib].getOtherNode(a);
var iNext = b.getIndex();
if (iNext != iLast && bsAllEnes.get(iNext) && (isLoop = this.checkEne(bsAllEnes, bsPath, iAtom, iNext, 3 - order, bsEneAtom1)) >= 0) {
}}
if (isLoop >= 0) {
this.bsKekuleAmbiguous.set(iAtom);
this.bsEnes.clear(iAtom);
}return isLoop == iAtom ? -1 : isLoop;
}, "JU.BS,JU.BS,~N,~N,~N,JU.BS");
Clazz.defineMethod(c$, "getAzacyclic", 
function(){
this.bsAmide.or(this.match("{N}C=O"));
out : for (var i = this.bsAtoms.nextSetBit(0); i >= 0; i = this.bsAtoms.nextSetBit(i + 1)) {
var atom = this.atoms[i];
if (atom.getElementNumber() != 7 || atom.getCovalentBondCount() != 3 || this.bsKekuleAmbiguous.get(i) || this.bsAmide.get(i)) continue;
var edges = atom.getEdges();
for (var k = edges.length; --k >= 0; ) if (edges[k].getOtherNode(atom).getElementNumber() == 1) continue out;

var nRings =  new JU.Lst();
for (var j = this.lstSmallRings.length; --j >= 0; ) {
var bsRing = this.lstSmallRings[j];
if (!bsRing.get(i)) continue;
nRings.addLast(bsRing);
if (j == 0) {
this.addAzacyclicN(i);
continue out;
}}
var nr = nRings.size();
if (nr < 2) continue;
var bsSubs =  new JU.BS();
var bonds = atom.getEdges();
for (var b = bonds.length; --b >= 0; ) if (bonds[b].isCovalent()) bsSubs.set(bonds[b].getOtherNode(atom).getIndex());

var bsBoth =  new JU.BS();
var bsAll =  new JU.BS();
for (var j = 0; j < nr - 1; j++) {
var bs1 = nRings.get(j);
for (var k = j + 1; k < nr; k++) {
var bs2 = nRings.get(k);
JU.BSUtil.copy2(bs1, bsBoth);
bsBoth.and(bs2);
if (bsBoth.cardinality() > 2) {
JU.BSUtil.copy2(bs1, bsAll);
bsAll.or(bs2);
bsAll.and(bsSubs);
if (bsAll.cardinality() == 3) {
this.addAzacyclicN(i);
continue out;
}}}
}
}
});
Clazz.defineMethod(c$, "addAzacyclicN", 
function(i){
if (this.isTooFlatNitrogen(this.atoms[i])) return;
if (this.bsAzacyclic == null) this.bsAzacyclic =  new JU.BS();
this.bsAzacyclic.set(i);
}, "~N");
Clazz.defineMethod(c$, "couldBeChiralAtom", 
function(a){
var mustBePlanar = false;
switch (a.getCovalentBondCount()) {
default:
System.out.println("?? too many bonds! " + a);
return false;
case 0:
return false;
case 1:
return false;
case 2:
return a.getElementNumber() == 7;
case 3:
switch (a.getElementNumber()) {
case 7:
if (this.bsAzacyclic != null && this.bsAzacyclic.get(a.getIndex())) break;
return false;
case 6:
mustBePlanar = true;
break;
case 15:
case 16:
case 33:
case 34:
case 51:
case 52:
case 83:
case 84:
break;
case 4:
break;
default:
return false;
}
break;
case 4:
break;
}
var edges = a.getEdges();
var nH = 0;
var haveDouble = false;
for (var j = edges.length; --j >= 0; ) {
if (mustBePlanar && edges[j].getCovalentOrder() == 2) haveDouble = true;
if (edges[j].getOtherNode(a).getIsotopeNumber() == 1) nH++;
}
return (nH < 2 && (haveDouble || this.isSmiles() || mustBePlanar == Math.abs(this.getTrigonality(a, this.vNorm)) < 0.2));
}, "JU.SimpleNode");
Clazz.defineMethod(c$, "couldBeChiralAlkene", 
function(a, edge){
var b = (edge == null ? null : edge.getOtherNode(a));
switch (a.getCovalentBondCount()) {
default:
return -1;
case 2:
if (a.getElementNumber() != 7) return -1;
break;
case 3:
if (!JS.CIPChirality.isFirstRow(a)) return -1;
break;
}
var bonds = a.getEdges();
var n = 0;
for (var i = bonds.length; --i >= 0; ) if (this.getBondOrder(bonds[i]) == 2) {
if (++n > 1) return 17;
var other = bonds[i].getOtherNode(a);
if (!JS.CIPChirality.isFirstRow(other)) return -1;
if (b != null && (other !== b || b.getCovalentBondCount() == 1)) {
return -1;
}}
return 13;
}, "JU.SimpleNode,JU.SimpleEdge");
Clazz.defineMethod(c$, "getTrigonality", 
function(a, vNorm){
var pts =  new Array(4);
var bonds = a.getEdges();
for (var n = bonds.length, i = n, pt = 0; --i >= 0 && pt < 4; ) if (bonds[i].isCovalent()) pts[pt++] = bonds[i].getOtherNode(a).getXYZ();

var plane = JU.Measure.getPlaneThroughPoints(pts[0], pts[1], pts[2], vNorm, this.vTemp,  new JU.P4());
return JU.Measure.distanceToPlane(plane, (pts[3] == null ? a.getXYZ() : pts[3]));
}, "JU.SimpleNode,JU.V3");
Clazz.defineMethod(c$, "isCis", 
function(a, b, c, d){
JU.Measure.getNormalThroughPoints(a.atom.getXYZ(), b.atom.getXYZ(), c.atom.getXYZ(), this.vNorm, this.vTemp);
var vNorm2 =  new JU.V3();
JU.Measure.getNormalThroughPoints(b.atom.getXYZ(), c.atom.getXYZ(), d.atom.getXYZ(), vNorm2, this.vTemp);
return (this.vNorm.dot(vNorm2) > 0 ? 13 : 14);
}, "JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom");
Clazz.defineMethod(c$, "isPositiveTorsion", 
function(a, b, c, d){
var angle = JU.Measure.computeTorsion(a.atom.getXYZ(), b.atom.getXYZ(), c.atom.getXYZ(), d.atom.getXYZ(), true);
return (angle > 0 ? 18 : 17);
}, "JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom");
Clazz.defineMethod(c$, "getBondOrder", 
function(bond){
return bond.getCovalentOrder();
}, "JU.SimpleEdge");
Clazz.defineMethod(c$, "setCoord", 
function(atom1, atoms){
return true;
}, "JU.SimpleNode,~A");
Clazz.defineMethod(c$, "checkHandedness", 
function(a){
var atoms = a.atoms;
if (!this.setCoord(a.atom, atoms)) return 0;
var p0 = (atoms[3].atom == null ? a.atom : atoms[3].atom).getXYZ();
var p1 = atoms[0].atom.getXYZ();
var p2 = atoms[1].atom.getXYZ();
var p3 = atoms[2].atom.getXYZ();
JU.Measure.getNormalThroughPoints(p1, p2, p3, this.vNorm, this.vTemp);
this.vTemp.setT(p0);
this.vTemp.sub(p1);
return (this.vTemp.dot(this.vNorm) > 0 ? 1 : 2);
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod(c$, "track", 
function(cip, a, b, sphere, finalScore, trackTerminal){
}, "JS.CIPChirality,JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,~N,~N,~B");
Clazz.defineMethod(c$, "getRootTrackerResult", 
function(root){
return null;
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod(c$, "setRule6Full", 
function(rrrr){
this.testRule6Full = rrrr;
}, "~B");
Clazz.defineMethod(c$, "isTooFlatNitrogen", 
function(n){
var bonds = n.getEdges();
var count = n.getCovalentBondCount();
if (count != 3) return true;
var others =  new Array(3);
for (var j = 0, i = bonds.length; --i >= 0; ) {
if (bonds[i].isCovalent()) others[j++] = bonds[i].getOtherNode(n);
}
var angle = JS.CIPData.pointPlaneAngle(n.getXYZ(), others[0].getXYZ(), others[1].getXYZ(), others[2].getXYZ(), this.vTemp, this.vTemp2, this.vNorm);
return (angle < 0.1);
}, "JU.SimpleNode");
c$.pointPlaneAngle = Clazz.defineMethod(c$, "pointPlaneAngle", 
function(a, b, c, d, v1, v2, norm){
v1.sub2(b, c);
v2.sub2(b, d);
norm.cross(v1, v2);
v2.add(v1);
v1.sub2(b, a);
var angleA_CD = 3.141592653589793;
var angleNorm = JS.CIPData.vectorAngleRadians(norm, v1);
if (angleNorm > 1.5707963267948966) angleNorm = 3.141592653589793 - angleNorm;
var val = 1.5707963267948966 + (angleA_CD > 1.5707963267948966 ? -angleNorm : angleNorm);
return val;
}, "JU.P3,JU.P3,JU.P3,JU.P3,JU.V3,JU.V3,JU.V3");
c$.vectorAngleRadians = Clazz.defineMethod(c$, "vectorAngleRadians", 
function(v1, v2){
var l1 = v1.length();
var l2 = v2.length();
return Math.acos(v1.dot(v2) / (l1 * l2));
}, "JU.V3,JU.V3");
});
;//5.0.1-v7 Mon Aug 17 10:40:50 MDT 2026
