<commit_before>/**
 * @fileoverview
 * Utils method about chem objects.
 * @author <NAME>
 */

/*
 * requires /utils/kekule.utils.js
 * requires /core/kekule.common.js
 * requires /kekule.structures.js
 */

(function () {

"use strict";

var AU = Kekule.ArrayUtils;

/**
 * Util class to manipulate ctab based chem structures.
 * @class
 */
Kekule.ChemStructureUtils = {
	/**
	 * Returns median of all input connector lengths.
	 * @param {Array} connectors
	 * @param {Int} coordMode
	 * @param {Bool} allowCoordBorrow
	 * @return {Float}
	 */
	getConnectorLengthMedian: function(connectors, coordMode, allowCoordBorrow)
	{
		var lengths = [];
		for (var i = 0, l = connectors.length; i < l; ++i)
		{
			var connector = connectors[i];
			if (connector && connector.getLength)
			{
				var length = connector.getLength(coordMode, allowCoordBorrow);
				if (length)
					lengths.push(length);
			}
		}
		if (l === 0)  // no connectors at all
			return 1;  // TODO: this value should be calculated
		if (l <= 1)
			return lengths[0];
		else
		{
			// sort lengths to find the median one
			lengths.sort();
			var count = lengths.length;
			var result = (count % 2)? lengths[(count + 1) >> 1]: (lengths[count >> 1] + lengths[(count >> 1) - 1]) / 2;
			return result;
		}
	},
	/**
	 * Returns structured children of chemObj. The type of chemObj can be:
	 *   {@link Kekule.ChemObjList}: returns chemObj.getItems();
	 *   {@link Kekule.ChemStructureObjectGroup}: returns chemObj.getAllObjs();
	 *   {@link Kekule.CompositeMolecule}: returns chemObj.getSubMolecules().getAllObjs().
	 *   {@link Kekule.ChemSpaceElement} or {@link Kekule.ChemSpace}: returns all child structured objects inside it.
	 * Other types will simply return [chemObj].
	 * If param cascade is true, each childObj will also be checked.
	 * @param {Variant} chemObj
	 * @param {Bool} cascade
	 * @returns {Array}
	 */
	getChildStructureObjs: function(chemObj, cascade)
	{
		var result;
		if (chemObj instanceof Kekule.CompositeMolecule)
			result = chemObj.getSubMolecules().getAllObjs();
		else if (chemObj instanceof Kekule.ChemStructureObjectGroup)
			result = chemObj.getAllObjs();
		else if (chemObj instanceof Kekule.ChemObjList)
			result = chemObj.getItems();
		else if (chemObj instanceof Kekule.ChemSpaceElement)
			result = chemObj.getChildren().getItems();
		else if (chemObj instanceof Kekule.ChemSpace)
			result = chemObj.getChildren();
		else
		{
			return [chemObj];
		}
		result = [].concat(result);  // clone result, avoid affect properties of chemObj

		// if not returned and cascade, need future check
		if (cascade)
		{
			var newResult = [];
			for (var i = 0, l = result.length; i < l; ++i)
			{
				var obj = result[i];
				var cascadeChilds = Kekule.ChemStructureUtils.getChildStructureObjs(obj, cascade);
				if (cascadeChilds.length <= 1)  // can not find cascade children
					Kekule.ArrayUtils.pushUnique(newResult, obj);
				else  // children find, use them to replace obj
				{<commit_msg>Fix a bug in getChildStructureObjs when cascade is true<commit_after>/**
 * @fileoverview
 * Utils method about chem objects.
 * @author <NAME>
 */

/*
 * requires /utils/kekule.utils.js
 * requires /core/kekule.common.js
 * requires /kekule.structures.js
 */

(function () {

"use strict";

var AU = Kekule.ArrayUtils;

/**
 * Util class to manipulate ctab based chem structures.
 * @class
 */
Kekule.ChemStructureUtils = {
	/**
	 * Returns median of all input connector lengths.
	 * @param {Array} connectors
	 * @param {Int} coordMode
	 * @param {Bool} allowCoordBorrow
	 * @return {Float}
	 */
	getConnectorLengthMedian: function(connectors, coordMode, allowCoordBorrow)
	{
		var lengths = [];
		for (var i = 0, l = connectors.length; i < l; ++i)
		{
			var connector = connectors[i];
			if (connector && connector.getLength)
			{
				var length = connector.getLength(coordMode, allowCoordBorrow);
				if (length)
					lengths.push(length);
			}
		}
		if (l === 0)  // no connectors at all
			return 1;  // TODO: this value should be calculated
		if (l <= 1)
			return lengths[0];
		else
		{
			// sort lengths to find the median one
			lengths.sort();
			var count = lengths.length;
			var result = (count % 2)? lengths[(count + 1) >> 1]: (lengths[count >> 1] + lengths[(count >> 1) - 1]) / 2;
			return result;
		}
	},
	/**
	 * Returns structured children of chemObj. The type of chemObj can be:
	 *   {@link Kekule.ChemObjList}: returns chemObj.getItems();
	 *   {@link Kekule.ChemStructureObjectGroup}: returns chemObj.getAllObjs();
	 *   {@link Kekule.CompositeMolecule}: returns chemObj.getSubMolecules().getAllObjs().
	 *   {@link Kekule.ChemSpaceElement} or {@link Kekule.ChemSpace}: returns all child structured objects inside it.
	 * Other types will simply return [chemObj].
	 * If param cascade is true, each childObj will also be checked.
	 * @param {Variant} chemObj
	 * @param {Bool} cascade
	 * @returns {Array}
	 */
	getChildStructureObjs: function(chemObj, cascade)
	{
		var isComplex = true;
		var result;
		if (chemObj instanceof Kekule.CompositeMolecule)
			result = chemObj.getSubMolecules().getAllObjs();
		else if (chemObj instanceof Kekule.ChemStructureObjectGroup)
			result = chemObj.getAllObjs();
		else if (chemObj instanceof Kekule.ChemObjList)
			result = chemObj.getItems();
		else if (chemObj instanceof Kekule.ChemSpaceElement)
			result = chemObj.getChildren().getItems();
		else if (chemObj instanceof Kekule.ChemSpace)
			result = chemObj.getChildren();
		else
		{
			isComplex = false;
			return [chemObj];
		}
		result = [].concat(result);  // clone result, avoid affect properties of chemObj

		// if not returned and cascade, need future check
		if (cascade && isComplex)
		{
			var newResult = [];
			for (var i = 0, l = result.length; i < l; ++i)
			{
				var obj = result[i];
				var cascadeChilds = Kekule.ChemStructureUtils.getChildStructureObjs(obj, cascade);
				if (!cascadeChilds.length || (cascadeChilds.length === 1 && cascadeChilds[0] === obj))  // can not find cascade children
					Kekule.ArrayUtils.pushUnique(newResult, obj);
				else  // children find, use them to replace obj
				{
{'fraction_non_alphanumeric': 0.12526504648507583, 'fraction_numerical': 0.0047300603490458325, 'mean_word_length': 3.502202643171806, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6411038', 'n_tokens_mistral': 2257, 'n_tokens_neox': 1937, 'n_words': 579}