UNPKG

kekule

Version:

Open source JavaScript toolkit for chemoinformatics

1 lines 72.8 kB
!function(){"use strict";var e=Kekule.ArrayUtils;Kekule.GraphElement=Class.create(ObjectEx,{CLASS_NAME:"Kekule.GraphElement",initialize:function(){this.tryApplySuper("initialize"),this._data={}},initProperties:function(){this.defineProp("storedData",{dataType:DataType.HASH,getter:function(){return this._data},setter:function(e){this._data=e||{}}})},getData:function(e){return e?this._data[e]:this._data},setData:function(e,t){return e&&(this._data[e]=t),this},removeData:function(e){return this._data[e]&&delete this._data[e],this}}),Kekule.GraphVertex=Class.create(Kekule.GraphElement,{CLASS_NAME:"Kekule.GraphVertex",initialize:function(){this.tryApplySuper("initialize"),this.setPropStoreFieldValue("edges",[])},initProperties:function(){this.defineProp("edges",{dataType:DataType.ARRAY,serializable:!1,setter:null})},getEdgeCount:function(){return this.getEdges().length},getNeighbors:function(){for(var t=[],r=this.getEdges(),n=0,o=r.length;n<o;++n){var i=r[n].getVertexes();e.pushUnique(t,e.exclude(i,this))}return t},getNeighborOnEdge:function(e){for(var t=e.getVertexes(),r=0,n=t.length;r<n;++r)if(t[r]!==this)return t[r]},getEdgeTo:function(e){for(var t=this.getEdges(),r=0,n=t.length;r<n;++r){if(t[r].getVertexes().indexOf(e)>=0)return t[r]}return null},doAppendEdge:function(e){return Kekule.ArrayUtils.pushUnique(this.getEdges(),e),this},doRemoveEdge:function(e){return Kekule.ArrayUtils.remove(this.getEdges(),e),this},doClearEdges:function(){for(var e=this.getEdges(),t=e.length-1;t>=0;--t)this.removeEdge(e[t]);return this}}),Kekule.GraphEdge=Class.create(Kekule.GraphElement,{CLASS_NAME:"Kekule.GraphEdge",initialize:function(){this.setPropStoreFieldValue("weight",1),this.tryApplySuper("initialize"),this.setPropStoreFieldValue("vertexes",[])},initProperties:function(){this.defineProp("vertexes",{dataType:DataType.ARRAY,serializable:!1,setter:null}),this.defineProp("weight",{dataType:DataType.NUMBER})},replaceVertex:function(e,t){var r=this.getVertexes(),n=r.indexOf(e),o=r.indexOf(t);n<0||o>=0||(r.splice(n,1,t),e.doRemoveEdge(this),t.doAppendEdge(this))}}),Kekule.GraphTraverseMode={DEPTH_FIRST:0,BREADTH_FIRST:1},Kekule.Graph=Class.create(ObjectEx,{CLASS_NAME:"Kekule.Graph",VISITED_KEY:"__$visited__",initialize:function(){this.tryApplySuper("initialize"),this.setPropStoreFieldValue("vertexes",[]),this.setPropStoreFieldValue("edges",[])},initProperties:function(){this.defineProp("vertexes",{dataType:DataType.ARRAY,serializable:!1,setter:null}),this.defineProp("edges",{dataType:DataType.ARRAY,serializable:!1,setter:null})},addVertex:function(e){return Kekule.ArrayUtils.pushUnique(this.getVertexes(),e),this},newVertex:function(){var e=new Kekule.GraphVertex;return this.addVertex(e),e},removeVertex:function(e){if(Kekule.ArrayUtils.remove(this.getVertexes(),e))for(var t=Kekule.ArrayUtils.clone(e.getEdges()),r=0,n=t.length;r<n;++r)this.removeEdge(t[r])},addEdge:function(e,t,r){return Kekule.ArrayUtils.pushUnique(this.getEdges(),e)&&(e.setPropStoreFieldValue("vertexes",[t,r]),t.doAppendEdge(e),r.doAppendEdge(e)),this},newEdge:function(e,t){var r=new Kekule.GraphEdge;return this.addEdge(r,e,t),r},removeEdge:function(e){for(var t=e.getVertexes(),r=0,n=t.length;r<n;++r){t[r].doRemoveEdge(e)}return Kekule.ArrayUtils.remove(this.getEdges(),e),this},traverse:function(t,r,n){for(var o=[],i=e.clone(this.getVertexes()),a=0,l=i.length;a<l;++a)i[a].setData(this.VISITED_KEY,!1);for(;i.length;){var s,u={vertexes:[],edges:[]};s=n&&i.indexOf(n)>=0?n:i[0];var c=this._doTravers(t,r,s);u.vertexes=u.vertexes.concat(c.vertexes),u.edges=u.edges.concat(c.edges),i=e.exclude(i,c.vertexes),o.push(u)}return o},_doTravers:function(e,t,r){var n={vertexes:[],edges:[]},o=r;o.getData(this.VISITED_KEY)||(n.vertexes.push(o),o.setData(this.VISITED_KEY,!0),e&&e(o,!1));for(var i=o.getEdges(),a=[],l=t===Kekule.GraphTraverseMode.BREADTH_FIRST,s=0,u=i.length;s<u;++s){var c=i[s],d=o.getNeighborOnEdge(c);if(!d.getData(this.VISITED_KEY))if(n.vertexes.push(d),n.edges.push(c),d.setData(this.VISITED_KEY,!0),e&&(e(c,!0),e(d,!1)),l)a.push(d);else{var g=this._doTravers(e,t,d);n.vertexes=n.vertexes.concat(g.vertexes),n.edges=n.edges.concat(g.edges)}}if(l)for(s=0,u=a.length;s<u;++s){var h=a[s];g=this._doTravers(e,t,h);n.vertexes=n.vertexes.concat(g.vertexes),n.edges=n.edges.concat(g.edges)}return n}}),Kekule.globalOptions.add("algorithm.molToGraph",{expandSubStructures:!0,ignoreBondedHydrogen:!0}),Kekule.GraphAdaptUtils={ctabToGraph:function(e,t,r){var n=Object.extend(Object.extend({},Kekule.globalOptions.algorithm.molToGraph),r||{}),o=e,i=Kekule.ArrayUtils,a=null,l=n.expandSubStructures;if(o){for(var s=n.nodeFilter||function(e,t){if(n.nodeClasses){var r=e.getClass();if(!ClassEx.isOrIsDescendantOfClasses(r,n.nodeClasses))return!1}if(n.ignoreBondedHydrogen&&e.isHydrogenAtom&&e.isHydrogenAtom()&&!e.getCharge()){var o=e.getLinkedConnectors();if(t&&(o=i.intersect(o,t)),1===o.length){var a=o[0];if(!a)return!1;if(a.isSingleBond&&a.isSingleBond()){var l=e.getLinkedObjsOnConnector(a);if(1===l.length){var s=l[0];if(!s.isHydrogenAtom||!s.isHydrogenAtom())return!1}}}}return!0},u=n.connectorFilter||function(e,t){if(n.connectorClasses){var r=e.getClass();if(!ClassEx.isOrIsDescendantOfClasses(r,n.connectorClasses))return!1}return!(e.getBondType&&n.bondTypes&&n.bondTypes.indexOf(e.getBondType())<0)},c=(a=t||new Kekule.Graph,l?o.getAllContainingConnectors():o.getConnectors()),d=l?o.getLeafNodes():o.getNodes(),g=[],h=new Kekule.MapEx,f=0,v=c.length;f<v;++f){var C=c[f];if(u(C))for(var p=[],S=l?C.getConnectedObjs():C.getConnectedSiblings(),x=0,k=S.length;x<k;++x){var O=S[x];if(d.indexOf(O)>=0&&(s(O,c)?p.push(O):i.pushUnique(g,O),p.length>=2)){for(var E=i.exclude(p,g),K=0,m=E.length;K<m;++K){(b=a.newVertex()).setData("object",E[K]),h.set(E[K],b)}a.newEdge(h.get(p[0]),h.get(p[1])).setData("object",C),i.pushUnique(g,p);break}}}var y=i.exclude(d,g);for(f=0,v=y.length;f<v;++f){var b,N=y[f];if(s(N,c))(b=a.newVertex()).setData("object",N)}h.finalize()}return a},molToGraph:function(e,t,r){Kekule.ArrayUtils;if(!e||!e.hasCtab())return null;var n=e.getCtab();return n?Kekule.GraphAdaptUtils.ctabToGraph(n,t,r):null},chemObjToGraph:function(e,t,r){for(var n=Kekule.ChemStructureUtils.getAllStructFragments(e,!0),o=t||new Kekule.Graph,i=0,a=n.length;i<a;++i)Kekule.GraphAdaptUtils.molToGraph(n[i],o,r);return o}},Kekule.GraphAlgorithmUtils={SEQ_KEY:"__$seq__",RESD_DEGREE_KEY:"__$resdDegree__",VISIT_EDGE_DEGREE_KEY:"__$visitedEdgeDegree__",TYPE_KEY:"__$type__",TYPE_CYCLE:"cycle",TYPE_BRIDGE:"bridge",VISITED_KEY:"__$visited",createSpanningTrees:function(e,t){return e.traverse(null,t)},calcMinDistances:function(e,t){var r,n,o=e.getVertexes();DataType.isSimpleValue(t)?r=o[n=t]:(r=t,n=o.indexOf(r));for(var i=[],a=[],l=0,s=o.length;l<s;++l){var u=o[l];if(l===n)i[l]=0,a[l]=r;else(C=r.getEdgeTo(u))?(i[l]=C.getWeight(),a[l]=r):(i[l]=1/0,a[l]=null)}var c=[n];for(l=0,s=o.length;l<s;++l)if(l!==n){for(var d,g=1/0,h=-1,f=0,v=o.length;f<v;++f)f!==n&&c.indexOf(f)<0&&i[f]<g&&(g=i[f],h=f,d=o[f]);c.push(h);for(f=0,v=o.length;f<v;++f)if(c.indexOf(f)<0){var C,p=g+((C=d.getEdgeTo(o[f]))?C.getWeight():1/0);p<i[f]&&(i[f]=p)}}return i},findCycleBlocks:function(t){for(var r=[],n=Kekule.GraphAlgorithmUtils,o=n.SEQ_KEY,i=n.RESD_DEGREE_KEY,a=n.VISIT_EDGE_DEGREE_KEY,l=n.TYPE_KEY,s=n.TYPE_CYCLE,u=n.TYPE_BRIDGE,c=t.getEdges(),d=0,g=c.length;d<g;++d)c[d].removeData(o);var h=t.getVertexes();for(d=0,g=h.length;d<g;++d)h[d].removeData(l);var f=1,v=1,C=[],p=[],S=[];for(t.traverse(function(e,t){t?(e.setData(o,f),p.push(e),++f):(e.setData(o,v),++v,C.push(e))}),d=0,g=C.length;d<g;++d){var x=C[d],k=x.getEdges();x.setData(i,k.length);for(var O=0,E=0,K=k.length;E<K;++E){k[E].getData(o)&&++O}x.setData(a,O),O<k.length&&S.push(x)}for(var m=function(e,t){if(t&&e.getData(o)<=1)return null;for(var r=e.getEdges(),n=null,i=null,a=0,l=r.length;a<l;++a){var s=r[a].getData(o);s&&(i?s<i&&(n=r[a],i=s):(n=r[a],i=s))}return n||null},y=function(e){for(var t=e.getEdges(),r=0,n=t.length;r<n;++r)if(!t[r].getData(o)&&!t[r].getData(l))return t[r];return null},b=function(t){var r=[],n=[],o=t.getData(a),u=(h=t.getData(i))-o;if(u>0){t.setData(l,s),e.pushUnique(r,t);for(var c=0;c<u;++c){t.setData(i,h+1);var d=y(t);if(d){d.setData(l,s),e.pushUnique(n,d);var g=t.getNeighborOnEdge(d);for(g.setData(i,g.getData(i)+1),g.setData(l,s),e.pushUnique(r,g);;){var h;if((o=g.getData(a))<(h=g.getData(i))){var f=b(g);e.pushUnique(r,f.vertexes),e.pushUnique(n,f.edges)}var v=m(g,!1);if(!v)break;v.setData(l,s),e.pushUnique(n,v);var C=g.getNeighborOnEdge(v);if(C.getData(l))break;C.setData(l,s),e.pushUnique(r,C),g=C}}}}return{vertexes:r,edges:n}},N=C.shift();N;){if(N.getData(l));else{var _=N.getData(a);if(N.getData(i)-_>0){var A=b(N);r.push(A)}else{N.setData(l,u);var D=m(N,!0);D&&D.setData(l,u)}}N=C.shift()}return r},findEndChains:function(e){for(var t=Kekule.ArrayUtils,r={vertexes:[],edges:[]},n=t.clone(e.getVertexes()),o=[],i=0,a=n.length;i<a;++i){var l=n[i],s=l.getEdgeCount();l.setData("__$currConnectivity__",s),s<=1&&o.push(l)}if(o.length){var u=o.pop();for(t.remove(n,u),r.vertexes.push(u);n.length;){var c=!1,d=t.exclude(u.getEdges(),r.edges);if(d.length){r.edges=r.edges.concat(d);var g=u.getNeighborOnEdge(d[0]);s=g.getData("__$currConnectivity__")-1;g.setData("__$currConnectivity__",s),s<=1&&(u=g,t.remove(n,u),r.vertexes.push(u),c=!0)}if(!c){if(!o.length)break;u=o.pop();t.remove(n,u),r.vertexes.push(u)}}}return r},removeEndChains:function(e){for(var t=Kekule.GraphAlgorithmUtils.findEndChains(e),r=0,n=t.vertexes.length;r<n;++r)e.removeVertex(t.vertexes[r]);return t},findBridgeChains:function(t){for(var r=t.getVertexes(),n=t.getEdges(),o=Kekule.GraphAlgorithmUtils.findCycleBlocks(t),i=0,a=o.length;i<a;++i)r=e.exclude(r,o[i].vertexes),n=e.exclude(n,o[i].edges);return{vertexes:r,edges:n}},removeBridgeChains:function(e){for(var t=Kekule.GraphAlgorithmUtils.findBridgeChains(e),r=0,n=t.vertexes.length;r<n;++r)e.removeVertex(t.vertexes[r]);return t},findAllRings:function(t){var r,n=Kekule.GraphAlgorithmUtils,o=[];r=t instanceof Kekule.Graph?n.findCycleBlocks(t):[t];for(var i,a=function(e,t){var r=e.vertexes,n=r.length;return n&&(r[0]===t||r[n-1]===t)},l=function(t,r,n){var o=e.clone(t.vertexes),i=e.clone(r.vertexes),a=e.clone(t.edges),l=e.clone(r.edges);o[0]===n&&(o.reverse(),a.reverse()),i[i.length-1]===n&&(i.reverse(),l.reverse()),o.pop();var s=o.concat(i),u=a.concat(l);return{vertexCount:t.vertexCount+r.vertexCount-1,vertexes:s,edges:u}},s=function(t){for(var r=[],n=e.clone(t.vertexes),o=t.edges,i=0,s=n.length;i<s;++i){var u=n[i],c=e.intersect(u.getEdges(),o);u.setData("__$vertextPartDegree__",c.length)}n.sort(function(e,t){return e.getData("__$vertextPartDegree__")-t.getData("__$vertextPartDegree__")});var d,g,h,f,v=[];for(i=0,s=t.edges.length;i<s;++i){var C=t.edges[i],p=C.getVertexes();v.push({vertexCount:p.length,vertexes:[p[0],p[1]],edges:[C]})}for(;n.length;){var S=n.shift(),x=null;for(i=v.length-1;i>=0;--i){var k=v[i];if(a(k,S)){x=k;for(var O=i-1;O>=0;--O){k=v[O];if(a(k,S)&&(d=x,g=k,h=void 0,f=void 0,h=e.clone(d.vertexes),f=e.clone(g.vertexes),h.shift(),h.pop(),f.shift(),f.pop(),!(e.intersect(h,f).length>=1))){var E=l(x,k,S),K=E.vertexes;K[0]===K[K.length-1]?(K.pop(),r.push(E)):v.push(E)}}v.splice(i,1)}}}return r},u=0,c=r.length;u<c;++u){var d=r[u];if((i=d).vertexes.length===i.edges.length)o.push({vertexes:e.clone(d.vertexes),edges:e.clone(d.edges)});else for(var g=s(d),h=0,f=g.length;h<f;++h){var v=g[h];o.push({vertexes:e.clone(v.vertexes),edges:e.clone(v.edges)})}}return o},findSSSR:function(t,r){var n,o=Kekule.GraphAlgorithmUtils,i=[];t instanceof Kekule.Graph?(n=o.findCycleBlocks(t),r=null):n=[t];for(var a=function(t,r){var n=[],i=t.edges.length-t.vertexes.length+1;if(i<=0)return[];var a=r?e.clone(r):o.findAllRings(t);a.sort(function(e,t){return e.vertexes.length-t.vertexes.length});var l,s=function(e){n.push(e)},u=[],c=Kekule.RingVectorUtils;c.prepareConvertRingToVector(t);var d=a.shift();for(s(d),l=c.convertRingToVector(d,t),u.push(l);n.length<i&&a.length;)d=a.shift(),l=c.convertRingToVector(d,t),c.isLinearDependant(l,u)||(u.push(l),s(d));return n},l=0,s=n.length;l<s;++l){var u=a(n[l],r);i=i.concat(u)}return i},analysisRings:function(e){for(var t,r=Kekule.GraphAlgorithmUtils,n=[],o=0,i=(t=e instanceof Kekule.Graph?r.findCycleBlocks(e):[e]).length;o<i;++o){var a=t[o],l=r.findAllRings(a),s=r.findSSSR(a,l);n.push({vertexes:a.vertexes,edges:a.edges,allRings:l,sssrRings:s})}return n}},Kekule.RingVectorUtils={MAX_INT_BITNUM:23,EDGE_INDEX_FIELD:"__$index__",prepareConvertRingToVector:function(e){for(var t=e.edges,r=0,n=t.length;r<n;++r)t[r][Kekule.RingVectorUtils.EDGE_INDEX_FIELD]=r},convertRingToVector:function(e,t){var r,n=t.edges.length,o=e.edges;if(n<Kekule.RingVectorUtils.MAX_INT_BITNUM){r=0;for(var i=0,a=o.length;i<a;++i){r+=1<<o[i][Kekule.RingVectorUtils.EDGE_INDEX_FIELD]}}else{r=[];for(i=0,a=o.length;i<a;++i){r[o[i][Kekule.RingVectorUtils.EDGE_INDEX_FIELD]]=!0}}return r},vectorNotNull:function(e){if(DataType.isSimpleValue(e))return!!e;for(var t=0;t<e.length;++t)if(e[t])return!0;return!1},getVectorLength:function(e){return DataType.isSimpleValue(e)?e.toString(2).length:e.length},ringVectorAnd:function(e,t){if(DataType.isSimpleValue(e))return e&t;for(var r=[],n=Math.min(e.length,t.length),o=0;o<n;++o)r[o]=e[o]&&t[o];return r},ringVectorAndAll:function(e){if(e.length<2)return e[0];for(var t=Kekule.RingVectorUtils,r=t.ringVectorAnd(e[0],e[1]),n=2,o=e.length;n<o;++n)r=t.ringVectorAnd(r,e[n]);return r},ringVectorOr:function(e,t){if(DataType.isSimpleValue(e))return e|t;for(var r=[],n=Math.max(e.length,t.length),o=0;o<n;++o)r[o]=e[o]||t[o];return r},ringVectorOrAll:function(e){if(e.length<2)return e[0];for(var t=Kekule.RingVectorUtils,r=t.ringVectorOr(e[0],e[1]),n=2,o=e.length;n<o;++n)r=t.ringVectorOr(r,e[n]);return r},ringVectorXor:function(e,t){if(DataType.isSimpleValue(e))return e^t;for(var r=[],n=Math.max(e.length,t.length),o=0;o<n;++o)r[o]=!!(e[o]^t[o]);return r},ringVectorXorAll:function(e){if(e.length<2)return e[0];for(var t=Kekule.RingVectorUtils,r=t.ringVectorXor(e[0],e[1]),n=2,o=e.length;n<o;++n)r=t.ringVectorXor(r,e[n]);return r},ringVectorNot:function(e){if(DataType.isSimpleValue(e))return~e;for(var t=[],r=0,n=e.length;r<n;++r)t[r]=!e[r];return t},isLinearDependant:function(e,t){var r=Kekule.RingVectorUtils,n=r.ringVectorOrAll(t),o=r.ringVectorAnd(e,r.ringVectorNot(n));if(r.vectorNotNull(o))return!1;for(var i=t.length,a=function(e){for(var t=[],r=0;r<e;++r)t[r]=e-r-1;return t},l=function(e,t,r){var n=e[t],o=++n;if(o>=r-t)return!(t>=e.length-1)&&l(e,t+1,r);e[t]=o;for(var i=o,a=t-1;a>=0;--a)++i,e[a]=i;return!0},s=!1,u=2;u<=i;++u){for(var c=a(u);;){0;for(var d=[],g=0,h=c.length;g<h;++g)d.push(t[c[g]]);var f=r.ringVectorXorAll(d);if(!r.vectorNotNull(r.ringVectorXor(f,e))){s=!0;break}if(!l(c,0,i)){s=!1;break}}if(s)break}return s},isLinearDependant_wrong:null}}(),function(){"use strict";Kekule.ChemStructObjContainer=Class.create(ObjectEx,{CLASS_NAME:"Kekule.ChemStructObjContainer",initialize:function(){this.tryApplySuper("initialize"),this.setPropStoreFieldValue("nodes",[]),this.setPropStoreFieldValue("connectors",[])},initProperties:function(){this.defineProp("nodes",{dataType:DataType.ARRAY,serializable:!1,setter:null}),this.defineProp("connectors",{dataType:DataType.ARRAY,serializable:!1,setter:null})},clear:function(){return this.getNodes().length=0,this.getConnectors().length=0,this},add:function(e){var t=null;return e instanceof Kekule.ChemStructureConnector?t=this.getConnectors():e instanceof Kekule.ChemStructureNode&&(t=this.getNodes()),t?Kekule.ArrayUtils.pushUnique(t,e):Kekule.error(Kekule.$L("ErrorMsg.CANNOT_ADD_NON_NODE_NOR_CONNECTOR_TO_STRUCT_CONTAINER")),this},remove:function(e){var t=null;return t=e instanceof Kekule.ChemStructureConnector?this.getConnectors():this.getNodes(),Kekule.ArrayUtils.remove(t,e),this}})}(),function(){Kekule;var e=Kekule.ArrayUtils;Kekule.BondType;Kekule.CanonicalizationIndexer=Class.create(ObjectEx,{CLASS_NAME:"Kekule.CanonicalizationIndexer",initialize:function(){this.tryApplySuper("initialize")},execute:function(e){var t=e instanceof Kekule.StructureFragment?e.getCtab():e;return t?this.doExecute(t):null},doExecute:function(e){}}),Kekule.CanonicalizationNodeSorter=Class.create(ObjectEx,{CLASS_NAME:"Kekule.CanonicalizationNodeSorter",execute:function(e){var t=e instanceof Kekule.StructureFragment?e.getCtab():e;return t?this.doExecute(t,t.getNodes()):null},doExecute:function(e){}}),Kekule.CanonicalizationConnectorSorter=Class.create(ObjectEx,{CLASS_NAME:"Kekule.CanonicalizationConnectorSorter",execute:function(e){var t=e instanceof Kekule.StructureFragment?e.getCtab():e;return t?this.doExecute(t,t.getConnectors()):null},doExecute:function(e){}}),Kekule.CanonicalizationConnectorConnectedObjsSorter=Class.create(ObjectEx,{CLASS_NAME:"Kekule.CanonicalizationConnectorConnectedObjsSorter",execute:function(e){var t=e instanceof Kekule.StructureFragment?e.getCtab():e;return t?this.doExecute(t,t.getConnectors()):null},doExecute:function(e){}}),Kekule.CanonicalizationCustomExecutor=Class.create(ObjectEx,{CLASS_NAME:"Kekule.CanonicalizationCustomExecutor",execute:function(e){var t=this.doExecute(e);return t&&this.doCanonicalizeConnectedObjs(t),t},doExecute:function(e){return e},doCanonicalizeConnectedObjs:function(e){e&&(new Kekule.CanonicalizationGeneralConnectorConnectedObjsSorter).execute(e)}}),Kekule.CanonicalizationGeneralConnectorSorter=Class.create(Kekule.CanonicalizationConnectorSorter,{CLASS_NAME:"Kekule.CanonicalizationGeneralConnectorSorter",doExecute:function(t){var r=new Kekule.MapEx;try{for(var n=0,o=t.getConnectorCount();n<o;++n){for(var i=t.getConnectorAt(n),a=i.getConnectedObjs(),l=[],s=0,u=a.length;s<u;++s){var c,d=a[s];d instanceof Kekule.ChemStructureNode&&(c=t.indexOfNode(d),l.push(c))}l.sort(function(e,t){return e-t}),r.set(i,l)}t.sortConnectors(function(t,n){var o=r.get(t),i=r.get(n),a=e.compare(o,i);return 0===a&&(a=-(t.getConnectedObjCount()-n.getConnectedObjCount())),a})}finally{r.finalize()}}}),Kekule.CanonicalizationGeneralConnectorConnectedObjsSorter=Class.create(Kekule.CanonicalizationConnectorConnectedObjsSorter,{CLASS_NAME:"Kekule.CanonicalizationGeneralConnectorConnectedObjsSorter",doExecute:function(e){var t=new Kekule.MapEx;try{for(var r=0,n=e.getConnectorCount();r<n;++r){var o=e.getConnectorAt(r);if(2===o.getConnectedObjCount()){var i=o.getConnectedObjAt(0),a=o.getConnectedObjAt(1),l=e.indexOfChild(i),s=e.indexOfChild(a);(l<0||s<0)&&(l=(i.getCanonicalizationIndex?-i.getCanonicalizationIndex():0)||0,s=(a.getCanonicalizationIndex?-a.getCanonicalizationIndex():0)||0),l>s&&o.reverseConnectedObjOrder()}else o.sortConnectedObjs(function(t,r){var n=e.indexOfChild(t),o=e.indexOfChild(r);(n<0||o<0)&&(i=((n=(t.getCanonicalizationIndex?-t.getCanonicalizationIndex():0)||0)||0)-((o=(r.getCanonicalizationIndex?-r.getCanonicalizationIndex():0)||0)||0));var i=e.indexOfChild(t)-e.indexOfChild(r);return i})}}finally{t.finalize()}}}),Kekule.CanonicalizationMorganIndexer=Class.create(Kekule.CanonicalizationIndexer,{CLASS_NAME:"Kekule.CanonicalizationMorganIndexer",doExecute:function(e){var t=this.doCalcGraphAndEcResult(e);this.doExecuteOnGraphEcResult(t.graph,t.ecMapping,t.vertexGroup)},doCalcGraphAndEcResult:function(e){var t=Kekule.GraphAdaptUtils.ctabToGraph(e,null,{expandSubStructures:!0,ignoreBondedHydrogen:!0});if(!t)return null;var r=this._calcGraphFinalECs(t);return{graph:t,ecMapping:r.ecMapping,vertexGroup:r.vertexGroup}},doExecuteOnGraphEcResult:function(e,t,r){var n=this._sortNodeByEcMapping(e,t,r);this._setCanonicalizationIndexToNodeGroups(n),this._fillSpanningTreeInfo(e)},_fillSpanningTreeInfo:function(e){if((n=e.getVertexes())&&n.length){n.sort(function(e,t){var r=e.getData("object"),n=t.getData("object");if(r||n){if(r){if(n){var o=(n.getCanonicalizationIndex()||-1)-(r.getCanonicalizationIndex()||-1);if(0===o&&r.hasCoord3D(!0)&&n.hasCoord3D(!0)){var i=Kekule.CoordUtils.substract(n.getAbsCoord3D(!0),r.getAbsCoord3D(!0));o=i.z||i.y||i.x}return o}return-1}return 1}return 0});var t=e.getEdges();if(t&&t.length){var r=function(e,t){for(var r=t.length,n=[],o=e.getVertexes(),i=0,a=o.length;i<a;++i){var l=t.indexOf(o[i]);l<0&&(l=r),n.push(l)}return n.sort(),n},n=e.getVertexes();t.sort(function(e,t){var o=r(e,n),i=r(t,n);return Kekule.ArrayUtils.compare(o,i)})}for(var o=0,i=(n=e.getVertexes()).length;o<i;++o){n[o].getEdges().sort(function(e,r){return t.indexOf(e)-t.indexOf(r)})}}this._setSpanningTreeIndexToNodeOfGraph(e)},_sortNodeByEcMapping:function(e,t,r){return this._doSortNodeByEcMapping(e,t,r)},_doSortNodeByEcMapping:function(t,r,n){for(var o=this._doSortNodeByEcMappingDirectly(n),i=this._doSortNodeBySortedNodeList(o),a=[],l=0,s=i.length;l<s;++l){var u=i[l];e.isArray(u)&&1===u.length?a.push(u[0]):a.push(u)}return a},_doSortNodeByEcMappingDirectly:function(t){for(var r=[],n=t,o=0,i=n.length;o<i;++o){var a=n[o],l=this._vertexesToNodes(a.vertexes);if(1===l.length)e.pushUnique(r,l[0]);else{var s=this._groupNodesWithSameEcValue(l,r);r=r.concat(s)}}return r},_doSortNodeBySortedNodeList:function(e){var t=(r=this._doSortNodeBySortedNodeListCore(e)).length;do{var r,n=r,o=t;t=(r=this._doSortNodeBySortedNodeListCore(n)).length}while(t>o);return n},_doSortNodeBySortedNodeListCore:function(t){for(var r=[],n=[],o=0,i=t.length;o<i;++o){var a=t[o];if(e.isArray(a)){var l=function(t,r){for(var n=0,o=r.length;n<o;++n)if(e.isArray(r[n])){if(r[n].indexOf(t)>=0)return n}else if(r[n]===t)return n;return-1},s=function(e,t,r){for(var n=[],o=0,i=t.length;o<i;++o)n.push(l(t[o],r));return n.sort(function(e,t){return t-e}),n},u=e.group(a,function(o,i){var a=e.intersect(o.getLinkedObjs(),n),l=e.intersect(i.getLinkedObjs(),n);if(0==(d=a.length-l.length)&&a.length>0){var u=s(0,a,r),c=s(0,l,r);d=e.compare(u,c)}if(0===d){var d;a=e.intersect(o.getLinkedObjs(),t),l=e.intersect(i.getLinkedObjs(),t),0==(d=a.length-l.length)&&(u=s(0,a,t),c=s(0,l,t),d=e.compare(u,c))}return d});r=r.concat(u),n=n.concat(a)}else r.push([a]),n.push(a)}return r},_setCanonicalizationIndexToNodeGroups:function(t){for(var r=0,n=t.length;r<n;++r){var o=r+1,i=t[r];if(e.isArray(i))for(var a=0,l=i.length;a<l;++a)i[a].setCanonicalizationIndex(o);else i.setCanonicalizationIndex(o)}},_setSpanningTreeIndexToNodeOfGraph:function(e){for(var t=Kekule.GraphAlgorithmUtils.createSpanningTrees(e,Kekule.GraphTraverseMode.DEPTH_FIRST),r=0,n=t.length;r<n;++r){var o=t[r];if(o.vertexes)for(var i=o.vertexes.length,a=0;a<i;++a){var l=o.vertexes[a].getData("object");l&&l.setCanonicalizationAssocIndex&&l.setCanonicalizationAssocIndex(i-a)}}},_vertexesToNodes:function(e){for(var t=[],r=0,n=e.length;r<n;++r){var o=e[r].getData("object");t.push(o)}return t},_processECs:function(t,r,n,o){if(o)return this._initECs(t,r);for(var i=[],a=[],l=t.getVertexes(),s=0,u=l.length;s<u;++s){var c=l[s],d=this._usePrimeECs?1:0;if(this._usePrimeECs)var g=this._getPrimeArray();for(var h=c.getNeighbors(),f=0,v=h.length;f<v;++f)this._usePrimeECs?d*=g[n.get(h[f])-1||0]:d+=n.get(h[f])||0;e.pushUnique(i,d),a[d]?a[d].push(c):a[d]=[c]}i.sort(function(e,t){return e-t});var C=[];for(s=0,u=i.length;s<u;++s){var p=i[s];a[p]&&C.push(a[p])}return this._setECValueByVertexGroup(C,r),C.length},_initECs:function(t,r){for(var n=[],o=0,i=(u=t.getVertexes()).length;o<i;++o){var a=u[o],l=a.getEdgeCount();n[l]?n[l].push(a):n[l]=[a]}var s=[];for(o=0,i=n.length;o<i;++o){var u;if(u=n[o])if(1===u.length)s.push(u);else for(var c=e.group(u,function(e,t){var r=e.getData("object"),n=t.getData("object"),o=(r.getLinkedNonHydrogenConnectors()||[]).length-(n.getLinkedNonHydrogenConnectors()||[]).length;return o||(o=r.compareStructure(n))||(o=(r.getHydrogenCount?r.getHydrogenCount(!0):0)-(n.getHydrogenCount?n.getHydrogenCount(!0):0)),o}),d=0,g=c.length;d<g;++d)s.push(e.toArray(c[d]))}return this._setECValueByVertexGroup(s,r),s.length},_setECValueByVertexGroup:function(e,t){for(var r=0,n=e.length;r<n;++r)for(var o=e[r],i=0,a=o.length;i<a;++i)t.set(o[i],r+1)},_getPrimeArray:function(){return Kekule.CanonicalizationMorganIndexer.primes||(Kekule.CanonicalizationMorganIndexer.primes=Kekule.NumUtils.getPrimes(1e4)),Kekule.CanonicalizationMorganIndexer.primes},_calcGraphFinalECs:function(e){var t=[new Kekule.MapEx,new Kekule.MapEx];try{e.getVertexes().length<this._getPrimeArray().length?this._usePrimeECs=!0:this._usePrimeECs=!1;for(var r,n,o=0,i=t[0],a=t[0],l=0,s=[],u=this._processECs(e,i,a,!0),c=!0;c;)l=u,r=n,a=i,i=t[++o%2],u=this._processECs(e,i,a),n=null,c=u>l,u===l?(n=this._groupVertexesByEcValue(e,i),!r&&a&&(r=this._groupVertexesByEcValue(e,a)),s.push(r),c=!this._hasVertexGroup(n,s)):s=[]}finally{i.finalize()}return{ecMapping:a,ecCount:l,vertexGroup:r||this._groupVertexesByEcValue(e,a)}},_groupVertexesByEcValue:function(t,r){for(var n=[],o=[],i=t.getVertexes(),a=0,l=i.length;a<l;++a){var s=i[a],u=r.get(s);e.pushUnique(o,u),n[u]||(n[u]=[]),n[u].push(s)}o.sort(function(e,t){return e-t});var c=[];for(a=0,l=o.length;a<l;++a){var d=n[o[a]];c.push({ecValue:o[a],vertexes:d,vertexesCount:d.length})}return c},_hasVertexGroup:function(e,t){for(var r=0,n=t.length;r<n;++r)if(0===this._compareEcVertexGroup(e,t[r]))return!0;return!1},_compareEcVertexGroup:function(t,r){var n=t.length,o=n-r.length;if(0===o)for(var i=0;i<n&&(0===(o=t[i].vertexes.length-r[i].vertexes.length)&&(o=e.exclude(t[i].vertexes,r[i].vertexes).length),0===o);++i);return o},_groupNodesWithSameEcValue:function(t,r){var n=function(t,r){for(var n=e.flatten(r),o=t.getLinkedObjs(),i=e.intersect(o,n),a=[],l=[],s=0,u=i.length;s<u;++s){var c=i[s],d=e.indexStackOfElem(c,r);a.push(d)}a.sort(function(t,r){return e.compare(t,r)});for(s=0,u=a.length;s<u;++s){(c=e.getElemByIndexStack(r,a[s]))||console.error("not found",c,a[s]);var g=t.getConnectorTo(c);l.push(g)}return{nodeIndexValues:a,connectors:l}};return e.group(t,function(t,o){var i=t.compareStructure(o);if(0===i){var a=n(t,r),l=n(o,r);i=e.compare(a.nodeIndexValues,l.nodeIndexValues);for(var s=a.connectors,u=l.connectors,c=0,d=s.length;c<d&&0===(i=s[c].compareStructure(u[c]));++c);if(0===i){var g=t.getBelongedSssrRings&&t.getBelongedSssrRings()||[],h=o.getBelongedSssrRings&&o.getBelongedSssrRings()||[];if(0===(i=g.length-h.length)){var f=[],v=[];for(c=0,d=g.length;c<d;++c)f.push(g[c].nodes.length),v.push(h[c].nodes.length);f.sort(),v.sort(),i=e.compare(f,v)}}}return i})}}),Kekule.CanonicalizationMorganNodeSorter=Class.create(Kekule.CanonicalizationNodeSorter,{CLASS_NAME:"Kekule.CanonicalizationMorganNodeSorter",doExecute:function(e){var t=this._getNodeSortedArray(e),r=t.length,n=this;e.sortNodes(function(e,o){var i=t.indexOf(e),a=t.indexOf(o);i<0&&(i=r),a<0&&(a=r);var l=i-a;return 0===l&&i===r&&(l=n._getNeighborNodesMinIndex(e,t)-n._getNeighborNodesMinIndex(o,t)),l})},_getNeighborNodesMinIndex:function(e,t){for(var r=e.getLinkedChemNodes(),n=t.length,o=0,i=r.length;o<i;++o){var a=t.indexOf(r[o]);a>0&&a<n&&(n=a)}return n},_getNodeSortedArray:function(t){var r=function(e,t,r,n){var o;if(0===(o=(t.getCanonicalizationIndex()||-1)-(r.getCanonicalizationIndex()||-1))){if(e){var i=e.getConnectorTo(t),a=e.getConnectorTo(r);o=i.compareStructure(a)}if(0===o)if(n)o=(n.get(t)||1/0)-(n.get(r)||1/0);if(0===o)o=(t.getCanonicalizationAssocIndex()||-1)-(r.getCanonicalizationAssocIndex()||-1);if(0===o&&t.hasCoord3D(!0)&&r.hasCoord3D(!0)){var l=Kekule.CoordUtils.substract(t.getAbsCoord3D(!0),r.getAbsCoord3D(!0));o=l.z||l.y||l.x}}return o};try{for(var n,o=e.clone(t.getNodes()),i=0,a=o.length;i<a;++i){var l=o[i];c?r(null,l,c)>0&&(c=l,n=i):(c=l,n=i)}o.splice(n,1);var s=[],u=[];c&&s.push(c);for(i=0;i<s.length;++i){var c=s[i];if(0!==i){var d=o.indexOf(c);d>=0&&(s.push(c),o.splice(d,1))}var g=c.getLinkedObjs();if((g=e.intersect(g,o)).length){g.sort(function(e,t){return r(c,e,t)});for(var h=g.length-1;h>=0;--h){var f=g[h];if((d=o.indexOf(f))>=0){var v=f.getCanonicalizationIndex();Kekule.ObjUtils.isUnset(v)?u.push(f):s.push(f),o.splice(d,1)}}}}return s=s.concat(u)}finally{}}}),Kekule.Canonicalizer=Class.create({CLASS_NAME:"Kekule.Canonicalizer",initialize:function(){this._executorClasses={},this._executorInstances={},this._defExecutorId=null},registerExecutor:function(t,r,n){e.isArray(r)?this._executorClasses[t]={indexer:r[0],nodeSorter:r[1],connectorSorter:r[2]||Kekule.CanonicalizationGeneralConnectorSorter,connectorConnectedObjsSorter:r[3]||Kekule.CanonicalizationGeneralConnectorConnectedObjsSorter}:this._executorClasses[t]={customExecutor:r},n&&(this._defExecutorId=t)},getExecutor:function(e){if(!e)return null;var t=this._executorInstances[e];if(!t){var r=this._executorClasses[e];r&&(t=r.customExecutor?{customExecutor:new r.customExecutor}:{indexer:new r.indexer,nodeSorter:new r.nodeSorter,connectorSorter:new r.connectorSorter,connectorConnectedObjsSorter:new r.connectorConnectedObjsSorter},this._executorInstances[e]=t)}return t},canonicalize:function(e,t){e.beginUpdate();try{var r=t||this._defExecutorId,n=this.getExecutor(r);if(n){var o=e instanceof Kekule.StructureFragment?e:null,i=o.getCanonicalizationInfo();if(i&&i.id===r)return e;var a=e.getCtab?e.getCtab():e;if(!a||a.isEmpty())return e;var l=a.getParent();n.customExecutor?n.customExecutor.execute(a):this._doDefaultCanonicalize(n,a,l),o.setCanonicalizationInfo({id:r})}else Kekule.error(Kekule.$L("ErrorMsg.REGISTERED_CANONICALIZATION_EXECUTOR_NOT_FOUND"))}finally{e.endUpdate()}return e},_doDefaultCanonicalize:function(e,t,r){var n=r.getFlattenedShadowFragment();(t=n.getCtab()).beginUpdate();try{e.indexer.execute(t),e.nodeSorter.execute(t),e.connectorSorter.execute(t),e.connectorConnectedObjsSorter.execute(t)}finally{t.endUpdate()}if(!r.getFlattenedShadowOnSelf()){r.beginUpdate();try{this._sortSrcStructBaseOnShadow(r,n),e.connectorConnectedObjsSorter.execute(r.getCtab())}finally{r.endUpdate()}}},_sortSrcStructBaseOnShadow:function(e,t){var r=function(e){return e.__$flattern_index$__},n=function(e,t){e.__$flattern_index$__=t},o=function(t,i,a,l){n(i,a);var s=i.getParent();if(s.isChildOf(e)){var u=r(s),c=a+l;(Kekule.ObjUtils.isUnset(u)||u>c)&&o(t,s,c,l)}},i=function(e){e.beginUpdate();try{e.sortNodes(function(e,t){return r(e)-r(t)}),e.sortConnectors(function(e,t){return r(e)-r(t)});for(var t=0,n=e.getNodeCount();t<n;++t){var o=e.getNodeAt(t);o instanceof Kekule.StructureFragment&&i(o)}}finally{e.endUpdate()}};e.cascadeOnChildren(function(e){e&&n(e,null)});var a=t.getChildCount();e.beginUpdate();try{for(var l=0;l<a;++l){var s=t.getChildAt(l);if(s instanceof Kekule.ChemStructureNode){var u=s,c=e.getFlatternedShadowSourceObj(u);c&&(o(e,c,l,a),c.setCanonicalizationIndex(u.getCanonicalizationIndex()))}else if(s instanceof Kekule.ChemStructureConnector){var d=s,g=e.getFlatternedShadowSourceObj(d);n(g,l)}}i(e)}finally{e.endUpdate()}}}),Kekule.ClassUtils.makeSingleton(Kekule.Canonicalizer),Kekule.canonicalizer=Kekule.Canonicalizer.getInstance(),ClassEx.extend(Kekule.ChemObject,{canonicalize:function(e){for(var t=Kekule.ChemStructureUtils.getAllStructFragments(this,!0),r=0,n=t.length;r<n;++r)t[r].canonicalize(e);return this}}),ClassEx.extend(Kekule.StructureConnectionTable,{canonicalize:function(e){return Kekule.canonicalizer.canonicalize(this),this}}),ClassEx.extend(Kekule.StructureFragment,{canonicalize:function(e){return Kekule.canonicalizer.canonicalize(this),this}}),ClassEx.defineProp(Kekule.ChemStructureObject,"canonicalizationIndex",{dataType:DataType.INT,serializable:!1,scope:Class.PropertyScope.PUBLISHED}),ClassEx.defineProp(Kekule.ChemStructureObject,"canonicalizationAssocIndex",{dataType:DataType.INT,serializable:!1,scope:Class.PropertyScope.PUBLISHED}),Kekule.canonicalizer.registerExecutor("morgan",[Kekule.CanonicalizationMorganIndexer,Kekule.CanonicalizationMorganNodeSorter],!0)}(),function(){"use strict";var e=Kekule.ArrayUtils,t=Kekule.GraphAlgorithmUtils,r=Kekule.ChemStructureUtils,n=Kekule.BondType;Kekule.globalOptions.add("algorithm.ringSearch",{bondTypes:[n.COVALENT]}),ClassEx.extend(Kekule.StructureConnectionTable,{getGraph:function(e){var t=Class.create(e);return t.connectorClasses=[Kekule.Bond],Kekule.GraphAdaptUtils.ctabToGraph(this,null,t)},extractStructObjs:function(e){for(var t=e.edges,r=e.vertexes,n=[],o=[],i=0,a=r.length;i<a;++i){(l=r[i].getData("object"))instanceof Kekule.BaseStructureNode&&n.push(l)}for(i=0,a=t.length;i<a;++i){var l;(l=t[i].getData("object"))instanceof Kekule.BaseStructureConnector&&o.push(l)}return{nodes:n,connectors:o}},findCycleBlocks:function(){var e=this.getRingInfo();return e?e.cycleBlocks:[]},findAllRings:function(){var e=this.getRingInfo(),t=[];if(e)for(var r=0,n=e.cycleBlocks.length;r<n;++r){var o=e.cycleBlocks[r].allRings;t=t.concat(o)}return t},findSSSR:function(){var e=this.getRingInfo(),t=[];if(e)for(var r=0,n=e.cycleBlocks.length;r<n;++r){var o=e.cycleBlocks[r].sssrRings;t=t.concat(o)}return t},analysisRings:function(e){var r=Object.extend(Object.extend({},Kekule.globalOptions.algorithm.ringSearch),e),n=this.getGraph(r);if(n){for(var o=[],i=t.analysisRings(n),a=0,l=i.length;a<l;++a){var s=i[a],u=this.extractStructObjs(s);o.push(u),u.allRings=[];for(var c=s.allRings,d=0,g=c.length;d<g;++d){var h=c[d],f=this.extractStructObjs(h);u.allRings.push(f)}u.sssrRings=[];var v=s.sssrRings;for(d=0,g=v.length;d<g;++d){h=v[d];var C=c.indexOf(h);if(C>=0)u.sssrRings.push(u.allRings[C]);else{f=this.extractStructObjs(h);u.sssrRings.push(f)}}}return{cycleBlocks:o}}return null}}),ClassEx.defineProps(Kekule.StructureConnectionTable,[{name:"ringInfo",dataType:DataType.HASH,serializable:!1,getter:function(e){var t=this.getStructureCacheData("ringInfo");return t||e||(t=this.analysisRings(),this.setStructureCacheData("ringInfo",t)),t},setter:null}]),ClassEx.extend(Kekule.StructureFragment,{findCycleBlocks:function(){return this.hasCtab()?this.getCtab().findCycleBlocks():null},findAllRings:function(){return this.hasCtab()?this.getCtab().findAllRings():null},findSSSR:function(){return this.hasCtab()?this.getCtab().findSSSR():null},analysisRings:function(e){return this.hasCtab()?this.getCtab().analysisRings(e):null}}),ClassEx.defineProps(Kekule.StructureFragment,[{name:"ringInfo",dataType:DataType.HASH,serializable:!1,getter:function(e){return this.hasCtab()?this.getCtab().getRingInfo(e):null},setter:null}]),ClassEx.extendMethod(Kekule.StructureFragment,"_copyAdditionalFragmentInfo",function($origin,e,t,r){var n=function(e){for(var r={nodes:[],connectors:[]},n=0,o=e.nodes.length;n<o;++n){(i=t.get(e.nodes[n]))&&r.nodes.push(i)}for(n=0,o=e.connectors.length;n<o;++n){var i;(i=t.get(e.connectors[n]))&&r.connectors.push(i)}return r};$origin(e,t,r);var o=this.getRingInfo(!0);if(o){for(var i={cycleBlocks:[]},a=0,l=o.cycleBlocks.length;a<l;++a){for(var s=o.cycleBlocks[a],u={allRings:[],sssrRings:[]},c=s.allRings,d=0,g=c.length;d<g;++d){var h=c[d];u.allRings.push(n(h))}var f=s.sssrRings;for(d=0,g=f.length;d<g;++d){h=f[d];u.sssrRings.push(n(h))}i.cycleBlocks.push(u)}e.setPropStoreFieldValue("ringInfo",i)}}),ClassEx.extend(Kekule.ChemStructureObject,{getBelongedSssrRings:function(){var e=[],t=this.getParent();if(t&&t.findSSSR)for(var r=t.findSSSR(),n=0,o=r.length;n<o;++n){var i=r[n];this instanceof Kekule.BaseStructureConnector?i.connectors.indexOf(this)>=0&&e.push(i):i.nodes.indexOf(this)>=0&&e.push(i)}return e},getBelongedRingMinSize:function(){var e=null,t=this.getBelongedSssrRings();if(t&&t.length)for(var r=0,n=t.length;r<n;++r){var o=t[r].nodes.length;e=e?Math.min(e,o):o}return e},isInRing:function(t){var r=t&&e.toArray(t);if(!r){var n=this.getParent();n&&n.findSSSR&&(r=n.findSSSR())}if(r&&r.length){for(var o=0,i=r.length;o<i;++o){var a=r[o];if(this instanceof Kekule.BaseStructureConnector){if(a.connectors.indexOf(this)>=0)return!0}else if(a.nodes.indexOf(this)>=0)return!0}return!1}return!1}}),ClassEx.extend(Kekule.ChemObject,{findCycleBlocks:function(){for(var e=r.getAllStructFragments(this),t=[],n=0,o=e.length;n<o;++n){var i=e[n].findCycleBlocks();i&&(t=t.concat(i))}return t.length?t:null},findAllRings:function(){for(var e=r.getAllStructFragments(this),t=[],n=0,o=e.length;n<o;++n){var i=e[n].findAllRings();i&&(t=t.concat(i))}return t.length?t:null},findSSSR:function(){for(var e=r.getAllStructFragments(this),t=[],n=0,o=e.length;n<o;++n){var i=e[n].findSSSR();i&&(t=t.concat(i))}return t.length?t:null},analysisRings:function(e){for(var t=r.getAllStructFragments(this),n=[],o=0,i=t.length;o<i;++o){var a=t[o].analysisRings(e);a&&(n=n.concat(a))}return n.length?n:null}})}(),function(){"use strict";var e=Kekule.ObjUtils,t=Kekule.ArrayUtils,r=Kekule.BondType,n=Kekule.BondOrder,o=Kekule.ChemStructureUtils,i=-1,a=-16,l=-32;Kekule.AromaticTypes={NONAROMATIC:0,EXPLICIT_AROMATIC:1,ANTIAROMATIC:-1,UNCERTAIN:64},ClassEx.extend(Kekule.Atom,{isSulfoneOrSulfoxideSulphur:function(){if("S"===this.getSymbol()){var e=this.getLinkedMultipleBonds();if(e.length>=1)for(var t=0,r=e;t<r;++t)for(var n=this.getLinkedObjsOnConnector(e[t]),o=0,i=n.length;o<i;++o){var a=n[o];if(a instanceof Kekule.Atom&&"O"===a.getSymbol())return!0}}return!1},isEsterCarbon:function(){if("C"===this.getSymbol())for(var e,t,o=this.getLinkedBonds(r.COVALENT),i=0,a=o.length;i<a;++i){var l=o[i];if(l.isBondBetween("C","O")&&(t||l.getBondOrder()!==n.SINGLE?e||l.getBondOrder()!==n.DOUBLE||(e=!0):t=!0,t&&e))return!0}return!1}}),Kekule.globalOptions.add("algorithm.aromaticRingsPerception",{allowUncertainRings:!1}),ClassEx.extend(Kekule.StructureConnectionTable,{_getPossibleRingNodePiElectronCounts:function(e,r,n){var o=function(e,r,n,o){var s=e,u=Kekule.IsotopeFactory.getIsotope(s),c=r.getCharge();if(!(r.isSaturated&&r.isSaturated())){var d,g,h,f=r.getLinkedMultipleBonds();if(r.isSulfoneOrSulfoxideSulphur&&r.isSulfoneOrSulfoxideSulphur())return l;if(r.isEsterCarbon&&r.isEsterCarbon())return a;if(o?h=(g=t.intersect(f,o)).length:(g=null,h=1),h)if(2===h&&g[0].getBondOrder()===Kekule.BondOrder.EXPLICIT_AROMATIC)d=u.isHetero&&u.isHetero()?[1,2]:1;else if(1===h&&g&&g[0].getBondOrder()===Kekule.BondOrder.DOUBLE)d=1;else{if(1!==h||g)return-1;d=1}else if("C"===s){for(var v=!1,C=0,p=f.length;C<p;++C){var S=f[C],x=r.getLinkedObjsOnConnector(S);if(1===x.length)if(x[0].getPrimaryIsotope().isHetero()){v=!0;break}}d=v?0:1}else d=1;if(t.isArray(d)){for(C=0,p=d.length;C<p;++C)d[C]=Math.min(Math.max(d[C]-c,0),2);return d}return Math.min(Math.max(d-c,0),2)}return r.getRadical&&r.getRadical()===Kekule.RadicalOrder.DOUBLET?1:u.isHetero()?Math.min(Math.max(2-c,0),2):"C"===s?c>0?0:c<0?2:i:0};if(e instanceof Kekule.VariableAtom){var s=e.getAllowedIsotopeIds();if(s&&s.length){for(var u=[],c=0,d=s.length;c<d;++c){var g=s[c],h=Kekule.IsotopeFactory.getIsotopeById(g).getSymbol();t.pushUnique(u,o(h,e,0,n))}return u}return[0,1,2]}var f=e.getPrimaryIsotope();return f?o(h=f.getSymbol(),e,0,n):[0,1,2]},_checkRingAromaticType:function(e,r,n){if(r){for(var o=n&&Kekule.ChemStructureUtils.isInRings(e,n),i=e.nodes,a=i.length,l=a>6&&a<16,s=[],u=[],c=i.length,d=0;d<c;++d){var g=i[d],h=r.get(g);t.isArray(h)?s.push(h):s.push([h]),u[d]=0}var f,v=function(e,t){var r=t[e],n=++r;return n>=s[e].length?!(e>=t.length-1)&&(t[e]=0,v(e+1,t)):(t[e]=n,!0)},C=null,p=null;do{0;var S=0,x=null;for(d=0;d<c;++d){var k=s[d][u[d]];if(!(k>=0)){x=Kekule.AromaticTypes.NONAROMATIC;break}S+=k}if(null===x){var O=parseInt(S/4),E=S%4;O<=5&&(2!==O||!(l&&o))&&(2===E?(x=Kekule.AromaticTypes.EXPLICIT_AROMATIC,p=t.clone(u)):E||(x=Kekule.AromaticTypes.ANTIAROMATIC))}if(null!==C){if(x&&C!==x&&(C===Kekule.AromaticTypes.EXPLICIT_AROMATIC||x===Kekule.AromaticTypes.EXPLICIT_AROMATIC)){f=Kekule.AromaticTypes.UNCERTAIN;break}}else C=x}while(v(0,u));if(f||(f=C),p)for(var K=new Kekule.MapEx,m=(d=0,p.length);d<m;++d)K.set(i[d],s[d][p[d]]);return{result:f,eMap:K}}},_calcPossibleRingNodesPElectronCounts:function(e,r,n){var o=[],i=[],a=[];if(n){for(l=0,s=n.length;l<s;++l)t.pushUnique(o,n[l].nodes),t.pushUnique(i,n[l].connectors);for(l=0,s=r.length;l<s;++l)t.pushUnique(a,r[l].nodes)}else{for(var l=0,s=r.length;l<s;++l)t.pushUnique(o,r[l].nodes),t.pushUnique(i,r[l].connectors);a=o}for(l=0,s=a.length;l<s;++l){var u=a[l],c=u.getStructureCacheData("piElectronCount");if(Kekule.ObjUtils.notUnset(c))e.set(u,[c]);else{var d=this._getPossibleRingNodePiElectronCounts(u,o,i);e.set(u,d)}}},_storeAromaticCacheToRingInfo:function(e,t,r){if(e.aromaticType=t,t===Kekule.AromaticTypes.EXPLICIT_AROMATIC)for(var n=e.nodes,o=0,i=n.length;o<i;++o){var a=n[o];if(Kekule.ObjUtils.isUnset(a.getStructureCacheData("piElectronCount"))&&r){var l=r.get(a);Kekule.ObjUtils.notUnset(l)&&a.setStructureCacheData("piElectronCount",l)}}},perceiveAromaticRings:function(e,t){Kekule.ObjUtils.isUnset(e)&&(e=Kekule.globalOptions.algorithm.aromaticRingsPerception.allowUncertainRings);var r=this.findSSSR(),n=t||r,o=[],i=new Kekule.MapEx;try{this._calcPossibleRingNodesPElectronCounts(i,n,null);for(var a=0,l=n.length;a<l;++a){var s,u=n[a];if(Kekule.ObjUtils.notUnset(u.aromaticType))s=u.aromaticType;else{var c=this._checkRingAromaticType(u,i,r);s=c.result,this._storeAromaticCacheToRingInfo(u,s,c.eMap)}(s===Kekule.AromaticTypes.EXPLICIT_AROMATIC||e&&s===Kekule.AromaticTypes.UNCERTAIN)&&o.push(u)}return o}finally{i.finalize()}},findAromaticRings:function(e,t){return this.perceiveAromaticRings(e,t)},getRingAromaticType:function(e,t){if(Kekule.ObjUtils.notUnset(e.aromaticType))return e.aromaticType;var r,n=this.findSSSR();t||(t=n);var o=new Kekule.MapEx;try{this._calcPossibleRingNodesPElectronCounts(o,[e],t);var i=this._checkRingAromaticType(e,o,n);r=i.result,this._storeAromaticCacheToRingInfo(e,r,i.eMap)}finally{o.finalize()}return r},getHucklizationChanges:function(e,t){for(var r=t&&t.allowUncertainRings,n=Kekule.BondOrder,o=[],i=(this.getParent(),this.findAromaticRings(r)),a=0,l=i.length;a<l;++a)for(var s=i[a].connectors,u=0,c=s.length;u<c;++u){var d=s[u];if(!e||e.indexOf(d)>=0){var g=d.getBondOrder&&d.getBondOrder();g!==n.SINGLE&&g!==n.DOUBLE||d.setBondOrder&&o.push({bond:d,bondOrder:Kekule.BondOrder.EXPLICIT_AROMATIC})}}return o},hucklize:function(e,t){t&&t.allowUncertainRings,Kekule.BondOrder;var r=[],n=this.getParent();n.setAutoClearStructureCache(!1),n.beginUpdate();try{var o=this.getHucklizationChanges(e,t);if(o)for(var i=0,a=o.length;i<a;++i){var l=o[i].bond,s=o[i].bondOrder;l.setBondOrder&&(l.setBondOrder(s),r.push(l))}}finally{n.endUpdate(),n.setAutoClearStructureCache(!0)}return r},getKekulizationChanges:function(e,t){var r,o=Object.extend({doAromaticTests:!1,includingSubFragments:!0,expandSubFragments:!1,useShadow:!0},t||{}),i=[],a=this.getParent();if(o.doAromaticTests&&this.perceiveAromaticRings(),o.useShadow){var l=a.createShadow();r=l.getShadowFragment()}else r=a;try{var s;if(o.expandSubFragments&&o.useShadow&&r.unmarshalAllSubFragments(!0),e)if(s=[],o.useShadow)for(var u=0,c=e.length;u<c;++u){var d=l.getShadowObj(e[u]);d&&s.push(d)}else s=e;else s=o.includingSubFragments&&!o.expandSubFragments?r.getAllContainingConnectors():r.getConnectors();var g=[];for(u=0,c=s.length;u<c;++u){var h=s[u];h.getBondType()===Kekule.BondType.COVALENT&&h.getBondOrder()===Kekule.BondOrder.EXPLICIT_AROMATIC&&2===h.getConnectedChemNodeCount()&&g.push(h)}r.setAutoClearStructureCache(!1),r.beginUpdate();try{var f=this._splitConnectorsToContinuousParts(g)||[];for(u=0,c=f.length;u<c;++u){var v=f[u];if(this._kekulizeContinousBonds(v,l,r,a))for(var C=0,p=v.length;C<p;++C){var S=v[C].getBondOrder();if(S!==n.EXPLICIT_AROMATIC){var x=o.useShadow?l.getSourceObj(v[C]):v[C];i.push({bond:x,bondOrder:S})}}}}finally{r.endUpdate(),r.setAutoClearStructureCache(!0)}}finally{o.useShadow&&l.finalize()}return i._useShadow=o.useShadow,i},kekulize:function(e,t){var r=[],n=this.getKekulizationChanges(e,t);if(n&&n._useShadow){var o=this.getParent();try{o.setAutoClearStructureCache(!1),o.beginUpdate();for(var i=0,a=n.length;i<a;++i){var l=n[i];l.bond.setBondOrder(l.bondOrder),r.push(l.bond)}}finally{o.endUpdate(),o.setAutoClearStructureCache(!0)}}return r},_kekulizeContinousBonds:function(r,n,o,i){for(var a=[],l=0,s=r.length;l<s;++l){var u=r[l].getConnectedChemNodes()||[];t.pushUnique(a,u)}var c=new Kekule.MapEx(!1);for(l=0,s=a.length;l<s;++l){var d=a[l],g=n?n.getSourceObj(d):d,h=g&&g.getStructureCacheData("piElectronCount");e.notUnset(h)&&c.set(d,{cachedPiElectronCount:h})}return this._doKekulizeContinousBondSys(0,r,a,c)},_doKekulizeContinousBondSys:function(r,o,i,a){var l=this,s=function(t){var r,n=a.get(t);return n?r=n.bondOrder:o.indexOf(t)<0&&(r=t.getBondOrder()),e.notUnset(r)?r:null},u=function(e){var t=s(e);return t>n.SINGLE&&t<=n.QUAD},c=function(r){var i=a.get(r),u=i&&i.cachedPiElectronCount;if(e.isUnset(u)){var c=r.getLinkedBonds(Kekule.BondType.COVALENT);if(function(e){var r=t.intersect(e,o),n=!r||!r.length;if(!n){n=!0;for(var i=0,l=r.length;i<l;++i){var s=r[i];if(!a.get(s)){n=!1;break}}}return n}(c)){var d=t.toArray(l._getPossibleRingNodePiElectronCounts(r,null,null));return!d||!d.length||d[0]<0?-1:d[0]}for(var g=0,h=0,f=c.length;h<f;++h){var v=c[h],C=s(v);e.notUnset(C)&&(C===n.DOUBLE||C===n.TRIPLE||C===n.QUAD?++g:0)}g&&(u=1===g?1:-1)}return u},d=o[r],g=d.getConnectedChemNodes(),h=[];if(!a.get(d)){if(function(e){for(var t=e.getNeighboringBonds(),r=0,n=t.length;r<n;++r)if(e=t[r],u(e))return!0;return!1}(d))h=[n.SINGLE];else{var f=function(t,r){for(var n=0,o=0,i=0,a=r.length;i<a;++i){var l=c(r[i]);e.notUnset(l)&&(l>=2?++n:++o)}return n>0||!(o>=2)&&null}(0,g);h=f?[n.SINGLE]:null!==f?[n.DOUBLE]:[n.DOUBLE,n.SINGLE]}for(var v,C=0,p=h.length;C<p;++C){v=!0;var S=h[C];a.set(d,{bondOrder:S}),d.setBondOrder(S);for(var x=0,k=g.length;x<k;++x){var O=g[x];if(c(O)<0){v=!1;break}}if(v){if(!(r<o.length-1)){v=!0;break}if(v=this._doKekulizeContinousBondSys(r+1,o,i,a))break}}return!!v||(d.setBondOrder(n.EXPLICIT_AROMATIC),a.remove(d),!1)}},_splitConnectorsToContinuousParts:function(e){if(!e||!e.length)return null;for(var r=function(e,t){var n=t.indexOf(e);if(n<0)return[];t.splice(n,1);for(var o=[e],i=e.getNeighboringConnectors(),a=0,l=i.length;a<l;++a){var s=i[a];t.indexOf(s)>=0&&(o=o.concat(r(s,t)))}return o},n=[],o=t.clone(e);o.length;){var i=o[0],a=r(i,o);a&&a.length&&n.push(a)}return n}}),ClassEx.extend(Kekule.StructureFragment,{perceiveAromaticRings:function(e,t){var r=this.hasCtab()?this.getCtab().perceiveAromaticRings(e,t):[];return this.setAromaticRings(r||[]),r},findAromaticRings:function(e,t){return this.perceiveAromaticRings(e,t)},getRingAromaticType:function(e,t){return this.hasCtab()?this.getCtab().getRingAromaticType(e,t):null},getHucklizationChanges:function(e,t){return this.hasCtab()?this.getCtab().getHucklizationChanges(e,t):[]},hucklize:function(e,t){return this.hasCtab()?this.getCtab().hucklize(e,t):[]},getKekulizationChanges:function(e,t){return this.hasCtab()?this.getCtab().getKekulizationChanges(e,t):[]},kekulize:function(e,t){return this.hasCtab()?this.getCtab().kekulize(e,t):[]}}),ClassEx.extend(Kekule.ChemObject,{perceiveAromaticRings:function(e,t){for(var r=o.getAllStructFragments(this),n=[],i=0,a=r.length;i<a;++i){var l=r[i].perceiveAromaticRings(e,t);l&&(n=n.concat(l))}return n.length?n:null},findAromaticRings:function(e,t){return this.perceiveAromaticRings(e,t)},_groupActualTargetBondsOfKekulizationOrHucklization:function(e,t,r){var n=[];if(t)for(s=0,u=t.length;s<u;++s)for(var o=t[s],i=0,a=e.length;i<a;++i){var l=e[i];o.isChildOf(l)&&(n[i]?n[i].bonds.push(o):n[i]={structFragment:l,bonds:[o]})}else for(var s=0,u=e.length;s<u;++s)n.push({structFragment:e[s],bonds:null});return n},getHucklizationChanges:function(e,t){for(var r=[],n=o.getAllStructFragments(this),i=this._groupActualTargetBondsOfKekulizationOrHucklization(n,e,t),a=0,l=i.length;a<l;++a){var s=i[a];s&&(r=r.concat(s.structFragment.getHucklizationChanges(s.bonds,t)||[]))}return r},hucklize:function(e,t){for(var r=[],n=o.getAllStructFragments(this),i=this._groupActualTargetBondsOfKekulizationOrHucklization(n,e,t),a=0,l=i.length;a<l;++a){var s=i[a];s&&(r=r.concat(s.structFragment.hucklize(s.bonds,t)||[]))}return r},getKekulizationChanges:function(e,t){for(var r=[],n=o.getAllStructFragments(this),i=this._groupActualTargetBondsOfKekulizationOrHucklization(n,e,t),a=0,l=i.length;a<l;++a){var s=i[a];s&&(r=r.concat(s.structFragment.getKekulizationChanges(s.bonds,t)||[]))}return r},kekulize:function(e,t){for(var r=[],n=o.getAllStructFragments(this),i=this._groupActualTargetBondsOfKekulizationOrHucklization(n,e,t),a=0,l=i.length;a<l;++a){var s=i[a];s&&(r=r.concat(s.structFragment.kekulize(s.bonds,t)||[]))}return r}})}(),function(){"use strict";Kekule.globalOptions.add("algorithm.molStandardization",{cleanStructure:!0,clearHydrogens:!0,unmarshalSubFragments:!0,doCanonicalization:!0,doAromaticPerception:!0,doStereoPerception:!0}),Kekule.MolStandardizer={standardize:function(e,t){var r=Object.extend({},Kekule.globalOptions.algorithm.molStandardization),n=e,o=Object.extend(r,t);return o.unmarshalSubFragments&&n.unmarshalAllSubFragments(!0),o.cleanStructure&&n.clean(),o.hucklizeStructure&&n.hucklize(),o.doCanonicalization&&Kekule.canonicalizer.canonicalize(n,o.canonicalizerExecutorId||null),o.doAromaticPerception&&n.perceiveAromaticRings(),o.doStereoPerception&&n.perceiveStereos(null,!0,o),o.clearHydrogens&&n.clearExplicitBondHydrogens(!0),n}},Object.extend(Kekule.ChemStructureUtils,{compareStructFragment:function(e,t,r){var n=e.clone(!1),o=t.clone(!1);n.setCanonicalizationIndex(null),o.setCanonicalizationIndex(null);var i=Object.create(r||{});return void 0===i.hucklizeStructure&&(i.hucklizeStructure=!0),n=Kekule.MolStandardizer.standardize(n,i),o=Kekule.MolStandardizer.standardize(o,i),i.doStandardize=!1,i.extraComparisonProperties=["canonicalizationIndex"],n.compareStructure(o,i)},isSameStructure:function(e,t,r){return 0===Kekule.ChemStructureUtils.compareStructFragment(e,t,r)}}),ClassEx.extend(Kekule.ChemObject,{standardize:function(e){for(var t=Kekule.ChemStructureUtils.getAllStructFragments(this,!0),r=0,n=t.length;r<n;++r)t[r].standardize(e);return this}}),ClassEx.extend(Kekule.StructureFragment,{standardize:function(e){return Kekule.MolStandardizer.standardize(this,e)},isSameStructureWith:function(e,t){return Kekule.ChemStructureUtils.isSameStructure(this,e,t)}}),ClassEx.extendMethod(Kekule.StructureFragment,"compa