wasm/wasm-sharding-js/sharding/strgen.js (625 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
"use strict";
var is_browser; // true if strgen is being used on a webpage, false if strgen is used via command line
class Strgen {
constructor() {
this.pattern = ""; // parameter, the pattern
this.allow_duplicate_characters = true; // parameter, controls whether the string can be constructed with the same character multiple times (same character at same index) or not
this.allow_multiple_instances = true; // parameter, allow the string to be constructed with the same character multiple times IF the pattern contains the character more than once
this.ignore_duplicate_case = false; // parameter, ignore the case of duplicates - i.e. 'A' and 'a' are treated the same, if this is set to true (requires allow_multiple_instances)
this.allow_logging = false; // parameter, allow the storing of events during the generation process in a list, if set to true
this.reporting_type = "full"; // parameter, controls level of basic reporting at the start and end of string generation
this.print_to_console = true; // parameter, allows the log and other output to be printed to the console
this.error_output_id = "warning"; // parameter, the default UI element where errors will be output (the reference to the element must be the ID)
this.store_errors = false; // parameter, store errors and warnings in a list of objects when they occur, if set to true
this.symbol_quantifier_max = 10; // parameter, the highest value possible when using symbol quantifiers
this.preset = [ // parameter, the character presets and the values of the presets, which can be modified
{preset_code:"w", value:"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"},
{preset_code:"p", value:"{}[](),./\\:;?!*&@~`'\""},
{preset_code:"d", value:"0123456789"},
{preset_code:"c", value:"abcdefghijklmnopqrstuvwxyz"},
{preset_code:"u", value:"ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
{preset_code:"l", value:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"},
{preset_code:"h", value:"0123456789abcdefabcdef"},
{preset_code:"H", value:"0123456789ABCDEFABCDEF"},
{preset_code:"o", value:"01234567"},
{preset_code:"s", value:" "}
];
this.version = "v1.0.0";
};
defineVariables() { // defines the non-parameter variables
this.current_index = -1; // the current pointer/index in the pattern
this.operators = "[]{}()-\\|/"; // special operator characters responsible for different behaviours TODO: fix error when this is an array
this.quantifier_operators = [":", ",", "-"]; // operators used within a quantifier, each does the same thing (create range of quantifier values)
this.symbol_quantifiers = ["+", "*", "?"] // symbol quantifiers based on the quantifiers of regular expression
this.quantifier_value = 1; // stores the value specified in the pattern within the { }
this.generated_value_list = []; // where output is stored, to be used in generation at the end of the generation process
this.temporary_value_list = [];
this.generated_output = ""; // the full output string
this.generator_log = []; // if allow_logging is true, events during the generation process will be stored in this list
this.error_list = []; // if store_errors is true, errors and warnings are stored in this list
this.error_state = false; // boolean to store whether an error has been encountered
// assign default values before generation/
// this fixes a problem with multiple generations with the same instance of the object
};
createString() { // initial method that is called to start generating a random string allow_duplicates = true, allow_logging = false, reporting_type = "full", error_output_id = "warning"
this.defineVariables();
if (this.pattern != "") {
this.checkParameters();
this.setLogger();
this.operatorComparison();
if (this.print_to_console) {
this.outputLog();
}
if (!this.error_state) {
return this.outputString();
} else {
this.error_state = false;
return "";
}
} else {
this.outputError("Pattern is not defined.");
return "";
}
};
setLogger() { // sets reporting to full if logging is enabled, will post the first log message if reporting is "full" or "less"
if (this.reporting_type != "full" && this.allow_logging == true) { // set reporting to full if logging is enabled
this.createLogEntry("Reporting set to full because logging is enabled!");
this.reporting_type = "full";
}
if (this.reporting_type == "full") { // report pattern at the start of generation, if reporting is set to full
this.createLogEntry("Starting string generation - pattern", this.pattern, true);
} else if (this.reporting_type == "less") { // report start of generation, if reporting is set to less
this.createLogEntry("Strgen-JS - start", undefined, true);
}
};
checkParameters() {
if (this.allow_multiple_instances == true && this.ignore_duplicate_case == true) {
this.outputWarning("Cannot ignore character case of duplicates, if multiple instances of characters are allowed!");
this.ignore_duplicate_case = false;
}
};
lookahead() { // return the next character in the string
return this.pattern.charAt(this.current_index + 1);
};
next() { // increment the current_index value and return the character at that value in the string
this.current_index += 1;
return this.pattern.charAt(this.current_index);
};
current() { // return the character at the current_index position in the string
return this.pattern.charAt(this.current_index);
};
last() { // return the character before the current_index position in the string
return this.pattern.charAt(this.current_index - 1);
};
operatorComparison() { // main method which is used to determine whether the current character is an operator or not
// (the first character is usually an operator if trying to generate random strings)
this.next();
this.createLogEntry("Parsing character at position " + (this.current_index + 1));
if (this.operators.includes(this.current()) == true || this.symbol_quantifiers.includes(this.current()) == true) {
this.determineOperator(this.pattern.charAt(this.current_index));
} else {
if (!this.symbol_quantifiers.includes(this.lookahead())) { // catch and process literal and call operatorComparison() again
this.getLiteral();
} else {
this.addCharToList(this.current());
}
this.operatorComparison();
}
};
determineOperator(operator) { // if an operator was found in operatorComparison, find out what operator it is and respond
if (operator != "") {
this.createLogEntry("Operator", operator);
switch(operator) {
case "[":
this.getCharacterSet();
break;
case "]":
this.createLogEntry("End of range reached", this.generated_value_list.toString());
if (this.lookahead() != '{' && !this.symbol_quantifiers.includes(this.lookahead())){
this.buildGeneratedString(this.selectValueFromList(1, undefined, this.allow_duplicate_characters));
}
break;
case "{":
this.quantifier_value = this.getQuantifier();
break;
case "}":
if (this.quantifier_value == 0) {
this.createLogEntry("End of quantifier reached", "0");
this.createLogEntry("No generation as quantifier is 0");
this.createLogEntry("Clearing values list...");
this.generated_value_list = [];
} else {
this.createLogEntry("End of quantifier reached", this.quantifier_value);
this.createLogEntry("Contents of value list", this.generated_value_list.toString());
this.buildGeneratedString(this.selectValueFromList(this.quantifier_value, undefined, this.allow_duplicate_characters));
}
this.quantifier_value = 1;
break;
case '(':
this.generateSequence();
break;
case ')':
this.createLogEntry("End of sequence reached");
if (this.temporary_value_list.length >= 1) {
this.generated_value_list = this.generated_value_list.concat(this.temporary_value_list);
this.temporary_value_list = [];
}
if (this.lookahead() != '{' && !this.symbol_quantifiers.includes(this.lookahead())){
this.createLogEntry("Contents of value list", this.generated_value_list.toString());
this.buildGeneratedString(this.selectValueFromList(1, undefined, false));
}
break;
case '/':
this.next();
this.getLiteral();
break;
case '+':
case '*':
case '?':
this.quantifier_value = this.getQuantifier();
if (this.quantifier_value == 0) {
this.createLogEntry("Symbol quantifier reached", "0");
this.createLogEntry("No generation as quantifier is 0");
this.createLogEntry("Clearing values list...");
this.generated_value_list = [];
} else {
this.createLogEntry("Symbol quantifier reached", this.quantifier_value);
this.createLogEntry("Final contents of value list", this.generated_value_list.toString());
this.buildGeneratedString(this.selectValueFromList(this.quantifier_value, undefined, this.allow_duplicate_characters));
}
this.quantifier_value = 1;
break;
default:
if (!this.symbol_quantifiers.includes(this.lookahead())) {
this.getLiteral();
} else {
this.addCharToList(this.current());
}
break;
}
this.operatorComparison();
} else {
if (this.reporting_type == 'full') { // report the full information at the end, if reporting is set to full
if (this.error_state) {
this.createLogEntry("End of pattern reached - string failed to generate due to error", undefined, true);
} else if (this.generated_output == "") {
this.createLogEntry("End of pattern reached - no string generated", undefined, true);
} else {
this.createLogEntry("End of pattern reached - final generated string", this.outputString(), true);
}
} else if (this.reporting_type == "less") { // report complete generation at the end, if reporting is set to less
this.createLogEntry("Strgen-JS - finish", undefined, true);
}
}
};
getCharacterSet() { // if the operator was the start of a character class definition, begin reading the pattern, and react according to a set of comparisons
do { // starts at the [ which was successfully read in the stage before this function
this.createLogEntry("Processing range at pattern position " + (this.current_index + 1));
var current_character = this.next();
if (this.current() == '\\') {
this.createLogEntry("Preset character at position " + (this.current_index + 1) + ", getting values for preset", this.lookahead());
this.getPresetValues(this.next());
this.generateRangeValue();
} else if (this.operators.includes(this.current()) == true && this.last() != '/' && this.current() != '/') {// if the current character is an unbroken operator, throw error
if(this.pattern.charAt(this.current_index) != "") {
this.outputError("Unexpected operator at position " + (this.current_index + 1) + ", operator '" + this.pattern.charAt(this.current_index) + "'.");
} else {
this.outputError("Character class not closed.");
}
break;
} else if (this.lookahead() == '-' && current_character != '/') { // if the next character is an unbroken '-' operator
this.createLogEntry("Unbroken operator", "-");
var character_store;
character_store = current_character; // take current character (left side of hyphen) and store it temp
this.next(); // skip hyphen
if (this.lookahead() == '/') { // if character after hyphen is / break character
this.next() // skip \
current_character = this.next(); // character after the /
} else {
current_character = this.next(); // assign the next character (right side of hyphen) and store it as the current character
}
this.createLogEntry("Range found", character_store + " , " + current_character);
this.generateRangeValue(character_store.charCodeAt(0), current_character.charCodeAt(0)); // generate_range_value(ascii value of left side , ascii value of right side)
} else if (this.lookahead() != '-' && current_character != '/') { // if the next character is not the "-" operator, and the current isn't a character break, then push current()
this.createLogEntry("Literal added to range", current_character);
this.generated_value_list.push(this.current());
}
} while (this.lookahead() != ']')
};
getLiteral() { // output a literal character, skipping any generation
this.createLogEntry("Literal", this.pattern.charAt(this.current_index));
this.buildGeneratedString(this.pattern.charAt(this.current_index));
};
addCharToList(char) {
this.createLogEntry("Adding literal '" + char + "' to values list");
this.generated_value_list.push(char);
};
getQuantifier() { // get the value within quantifier operators, if present
this.createLogEntry("Processing quantifier at pattern position " + (this.current_index + 1));
var start_value = this.current_index + 1;
var quantifier_value;
var quantifier_first_value;
var quant_range_state = false;
var symbol_quantifier = false;
if (this.symbol_quantifiers.includes(this.current())) {
this.createLogEntry("Symbol quantifier specified");
quant_range_state = true;
symbol_quantifier = true;
if(this.current() == "?") {
this.createLogEntry("Quantifier", "?");
quantifier_value = 1;
quantifier_first_value = 0;
} else if (this.current() == "*") {
this.createLogEntry("Quantifier", "*");
quantifier_value = this.symbol_quantifier_max;
quantifier_first_value = 0;
} else if (this.current() == "+") {
this.createLogEntry("Quantifier", "+");
quantifier_value = this.symbol_quantifier_max;
quantifier_first_value = 1;
}
} else {
do {
if (this.operators.includes(this.lookahead()) == false && this.quantifier_operators.includes(this.lookahead()) == false) { // if lookahead is not any operator
if (quantifier_value == undefined) {
quantifier_value = this.next();
} else {
quantifier_value+= this.next();
}
} else if (this.quantifier_operators.includes(this.lookahead()) == true && quantifier_first_value == undefined) { // if lookahead is quantifier operator i.e. , : -
quant_range_state = true;
this.createLogEntry("Quantifier range specified");
quantifier_first_value = quantifier_value;
quantifier_value = "";
this.next();
} else if (this.lookahead() == "") { // if lookahead is nothing (error case)
this.outputError("Quantifier not closed.");
break;
} else {
this.next();
quantifier_value = 1;
this.outputError("Unexpected character at position " + (this.current_index + 1) + ", character '" + this.pattern.charAt(this.current_index) + "'.");
break;
}
} while (this.lookahead() != '}')
}
if (quant_range_state == true) {
if (quantifier_first_value == undefined || quantifier_first_value == "") {
quantifier_first_value = 0;
} else if (quantifier_value == undefined || quantifier_value == "") {
this.outputWarning("Max quantifier value was not set, quantifier at position " + start_value + " set to 0.");
quantifier_value = 0;
}
this.createLogEntry("Generating random quantifier between", quantifier_first_value + " and " + quantifier_value);
quantifier_first_value = parseInt(quantifier_first_value);
quantifier_value = parseInt(quantifier_value);
if (quantifier_first_value > quantifier_value) { // swap values if the quantifier_first_value is the largest value
var store = quantifier_first_value;
quantifier_first_value = quantifier_value;
quantifier_value = store;
this.createLogEntry("Quantifier values swapped");
}
// temporary solution to getting a random quantifier from a range
var quantifier_array = [];
for (var count = quantifier_first_value; count <= quantifier_value; count++) { // populate array with every value between quantifier_first_value and quantifier_value
quantifier_array.push(count);
}
this.createLogEntry("Quantifier range values", quantifier_array.toString());
var random_value = Math.floor(Math.random() * quantifier_array.length);
var selected_quantifier = quantifier_array[random_value]; // select a value based math.random and array length
this.createLogEntry("Selected index", random_value + ", selected quantifier value: " + selected_quantifier);
quantifier_array = [];
//end of temp code
quantifier_value = selected_quantifier;
}
if (this.allow_duplicate_characters == false) {
var value_list_length = this.getValueListLength();
if (quantifier_value > value_list_length) {
this.outputWarning("Character quantifier at position " + start_value + " reduced from " +
quantifier_value + " to " + value_list_length +
". Toggle 'Allow Duplicate Characters' to generate the full amount.")
quantifier_value = value_list_length;
}
}
this.createLogEntry("Quantifier value is " + quantifier_value);
if (quantifier_value == 0 && quant_range_state == false) {
this.createLogEntry("No value was returned. Character quantifier at position " + start_value + " is 0.", undefined, true);
} else if (quantifier_value == 0 && quant_range_state == true) {
this.createLogEntry("No value was returned. Character quantifier range at position " + start_value + " generated the value 0!", undefined, true);
}
if (isNaN(quantifier_value)) {
this.outputError("Quantifier at position " + start_value + " contains invalid characters.");
}
return parseInt(quantifier_value);
};
generateRangeValue(first_value, second_value, character_index = first_value) { // generate all possible values in the user defined range (defined with '-' character)
if (first_value > second_value) { // swap values if the firstvalue is the largest value
var store = first_value;
first_value = second_value;
second_value = store;
character_index = first_value;
this.createLogEntry("Range values swapped");
}
if (character_index <= second_value && character_index >= first_value) { // if character_index is within the range specified
this.generated_value_list.push(String.fromCharCode(character_index));
this.generateRangeValue(first_value, second_value, parseInt(character_index+=1));
}
};
getPresetValues(character, count = 0) { // determine what set of pre-defined values will be used when generating with the '\' symbol, then call generatePresetValues
if (count == this.preset.length) {
this.getLiteral(character);
this.outputWarning("Invalid preset range. \'\\" + character + "\' is not a valid preset.");
} else if (this.preset[count].preset_code == character) {
this.createLogEntry("Found preset", JSON.stringify(this.preset[count]));
this.generatePresetValues(this.preset[count].value);
} else {
count = count + 1;
this.getPresetValues(character, count);
}
};
generatePresetValues(preset_values, character_index = 0) { // split the preset_characters string and push each individual character into the values array
if (preset_values != undefined && character_index < preset_values.length) {
this.generated_value_list.push(preset_values.charAt(character_index));
this.generatePresetValues(preset_values, character_index+=1);
}
};
generateSequence() { // split each value in the sequence and push it to the generated_value_list array
var string_value = "";
var last_operator = "none";
var temp_string;
this.createLogEntry("Processing sequence at pattern position " + (this.current_index + 1));
while(this.current() != ')') { // while the current character is not the end of the sequence
if (this.lookahead() == '|' || this.lookahead() == ')' || this.lookahead() == '&') { // if the next character is a closing bracket or sequence operators
if (this.lookahead() == '|' && last_operator != "&" || last_operator == '|' && this.lookahead() == ')') {
// if next character is OR operator and last_operator is not AND, or, if last_operator is OR operator and next character is end of sequence - perform OR
this.createLogEntry("OR operator - last operator", last_operator);
last_operator = '|';
if (string_value != "") {
this.temporary_value_list.push(string_value);
this.createLogEntry("OR word parsed", string_value);
string_value = "";
}
if (this.lookahead() == ')') { break; } else { this.next(); }
} else if (this.lookahead() == '&' || last_operator == '&' && this.lookahead() == ')' || last_operator == '&' && this.lookahead() == '|') {
// if next character is AND operator, or, if last_operator is AND operator and next character is end of sequence or OR operator - perform AND
this.createLogEntry("AND operator - last operator", last_operator);
last_operator = "&";
if (temp_string == undefined) {
temp_string = string_value;
} else {
temp_string += string_value;
}
this.createLogEntry("AND word parsed", string_value);
string_value = "";
if (this.lookahead() == ')' || this.lookahead() == '|') { // if next character is end or OR operator (AND operator has ended/no more ANDs yet) - split temp_string and create random word
this.createLogEntry("OR operator or end ahead");
var output_string = "";
var temp_string_length = temp_string.length;
var temp_string_array = temp_string.split("");
this.createLogEntry("Combined string character range", temp_string_array.toString());
this.generated_value_list.push(this.generateAndString(temp_string_array));
temp_string = "";
if (this.lookahead() == ')') { // if next character is end of sequence, break loop
break;
} else if (this.lookahead() == '|') { // if next character is OR operator, set last_operator to OR and move to next character
if (last_operator = '&') {
this.createLogEntry("Storing " + this.generated_value_list.toString() + " in a different list temporarily");
this.temporary_value_list = this.temporary_value_list.concat(this.generated_value_list);
this.generated_value_list = [];
}
last_operator = '|'
this.createLogEntry("last_operator set to '|'");
this.next();
}
} else {
this.next();
}
}
else if (this.lookahead() == ')' && last_operator == "none" || this.lookahead() == '') {
if (string_value == "") {
this.outputWarning("Unbroken Sequence starting at position " + (this.current_index + 1) + " does not contain any values.");
} else {
this.generated_value_list.push(string_value);
//this.outputWarning("Sequence starting at position " + ((this.current_index + 1) - string_value.length) + " only contains one value.")
}
break;
}
}
else if (this.lookahead() != '') {
this.next();
if (this.operators.includes(this.current()) == true || this.symbol_quantifiers.includes(this.current()) == true) {
if (this.current() == "[") {
this.getCharacterSet();
} else if (this.current() == "]") {
this.createLogEntry("End of range reached", this.generated_value_list.toString());
if (this.lookahead() != '{' && !this.symbol_quantifiers.includes(this.lookahead())) {
string_value += this.selectValueFromList(this.quantifier_value, undefined, this.allow_duplicate_characters);
}
} else if (this.current() == "{") {
this.quantifier_value = this.getQuantifier();
} else if (this.current() == "}") {
if (this.quantifier_value == 0) {
this.createLogEntry("End of quantifier reached", "0");
this.createLogEntry("No generation as quantifier is 0");
} else {
this.createLogEntry("End of quantifier reached", this.quantifier_value);
this.createLogEntry("Contents of value list", this.generated_value_list.toString());
string_value += this.selectValueFromList(this.quantifier_value, undefined, this.allow_duplicate_characters);
}
this.quantifier_value = 1;
this.generated_value_list = [];
} else if (this.symbol_quantifiers.includes(this.current())) {
this.quantifier_value = this.getQuantifier(this.current());
string_value += this.selectValueFromList(this.quantifier_value, undefined, this.allow_duplicate_characters);
this.quantifier_value = 1;
this.generated_value_list = [];
} else if (this.current() == "/") {
string_value += this.next();
}
} else {
string_value += this.current();
}
} else {
this.outputError("End of sequence expected at position " + (this.current_index + 1) + ".");
break;
}
}
};
generateAndString(values_array, index = 0, output_string = "", array_original_length) {
if (array_original_length == undefined) {
array_original_length = values_array.length;
}
if (array_original_length > index) {
var random_value = Math.floor(Math.random() * values_array.length);
this.createLogEntry("Sequence processing action " + (index + 1) + " - Selected sequence character", values_array[random_value]);
output_string += values_array[random_value];
values_array.splice(random_value, 1);
this.createLogEntry("Sequence processing action " + (index + 1) + " - Range after selection", values_array.toString());
return this.generateAndString(values_array, index += 1, output_string, array_original_length);
} else {
this.createLogEntry("AND string generated", output_string);
return output_string;
}
};
selectValueFromList(defined_no_of_chars, character_index = 0, allow_duplicates = false, output = "") { // pick a random value from the generated_value_list and do this quantifier_value number of times
if (character_index < this.quantifier_value) {
var random_value = Math.floor(Math.random() * this.generated_value_list.length);
if (this.generated_value_list[random_value] != undefined) {
output += this.generated_value_list[random_value]
this.createLogEntry("Selected value", this.generated_value_list[random_value]);
} else {
if (output == "") {
this.outputWarning("No value was returned. Please check the template.");
if (this.generated_value_list.length == 0) {
this.createLogEntry("<b>Ending value selection and continuing generation...</b>");
character_index = this.quantifier_value;
}
}
}
if (allow_duplicates == false) {
var value = this.generated_value_list[random_value];
this.removeValueFromList(value, random_value, true);
if (this.allow_multiple_instances == false) {
this.removeValueFromList(value);
if (this.ignore_duplicate_case == true && value.match(/[a-zA-Z]/)) {
var value_upper = value.toUpperCase();
var value_lower = value.toLowerCase();
if (value != value_lower) {
value = value_lower;
} else {
value = value_upper;
}
this.removeValueFromList(value);
}
}
}
return this.selectValueFromList(this.quantifier_value, character_index+=1, allow_duplicates, output);
} else {
this.generated_value_list = [];
return output;
}
};
removeValueFromList(value, index = 0, one_value_only = false, previously_searched = false, count = 0) {
if (this.generated_value_list.indexOf(value) != -1) {
var value_index = this.generated_value_list.indexOf(value, index);
this.generated_value_list.splice(value_index, 1);
count += 1;
if (one_value_only == false) {
this.removeValueFromList(value, 0, false, true, count);
} else {
this.createLogEntry("Removed value '" + value + "' from array", this.generated_value_list.toString());
}
} else if (this.generated_value_list.indexOf(value) == -1 && previously_searched == true) {
if (count > 1) {
this.createLogEntry("Removed value '" + value + "' from " + count + " indexes in the array", this.generated_value_list.toString());
} else {
this.createLogEntry("Removed value '" + value + "' from array", this.generated_value_list.toString());
}
} else {
this.createLogEntry("Value '" + value + "' was not found in the values list", this.generated_value_list.toString());
}
};
getValueListLength(index = 0, count_list = [], current_count = 0, allow_multiple = this.allow_multiple_instances, ignore_case = this.ignore_duplicate_case) {
if (allow_multiple == true && ignore_case == false) {
this.createLogEntry("Values array length is", this.generated_value_list.length);
return this.generated_value_list.length;
} else if (index != this.generated_value_list.length && ignore_case == true) {
if (count_list.indexOf(this.generated_value_list[index].toLowerCase()) == -1) {
if (count_list.indexOf(this.generated_value_list[index].toUpperCase()) == -1) {
count_list.push(this.generated_value_list[index]);
}
}
index += 1;
return this.getValueListLength(index, count_list, count_list.length);
} else if (index != this.generated_value_list.length) {
if (count_list.indexOf(this.generated_value_list[index]) == -1) {
count_list.push(this.generated_value_list[index]);
}
index += 1;
return this.getValueListLength(index, count_list, count_list.length);
} else if (index == this.generated_value_list.length) {
this.createLogEntry("List counted, " + current_count + " unique values. Unique values are", count_list.toString());
return current_count;
}
};
buildGeneratedString(output) { // construct the generated string as every value is selected, and store it in generated_output
this.generated_output += output;
};
outputString() { // output the completed string at the end of execution
return this.generated_output;
};
outputWarning(message) { // output a warning to the UI element, to the console, or store it in error_list
if (is_browser == true && document.getElementById(this.error_output_id)) {
document.getElementById(this.error_output_id).innerHTML += message;
} else if (this.store_errors == true) {
this.error_list.push({
msg: message,
state: "warning"
});
} else {
console.error(message);
}
this.createLogEntry("<b>WARNING</b>", message, true);
};
outputError(message) { // output an error to the console and set error_state to true, and either display the error message on the UI element, or store it in error_list
if (is_browser == true && document.getElementById(this.error_output_id)) {
document.getElementById(this.error_output_id).innerHTML += message;
} else if (this.store_errors == true) {
this.error_list.push({
msg: message,
state: "error"
});
}
console.error(message);
this.createLogEntry("<b>ERROR</b>", message, true);
this.error_state = true;
};
createLogEntry(caption, content = undefined, enabled = this.allow_logging) { // create a new log entry
if(enabled == true && this.reporting_type != "none") {
var timestamp = new Date();
var timestamp_text = timestamp.toTimeString().split(" ")[0] + ":" + timestamp.getMilliseconds();
var log_entry;
if(content != undefined) {
if(content != "") {
if(content != " ") {
log_entry = timestamp_text + " - " + caption + ": " + content;
} else {
log_entry = timestamp_text + " - " + caption + ": white space";
}
} else {
log_entry = timestamp_text + " - " + caption + ": empty";
}
} else {
log_entry = timestamp_text + " - " + caption;
}
this.generator_log.push(log_entry);
}
};
outputLog() { // output the log to the console
for (var count = 0; count <= this.generator_log.length - 1; count++) {
console.log((count + 1) + " - " + this.generator_log[count]);
}
};
printVersion() { // print strgen version
console.log("strgen-js " + this.version);
};
};
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = Strgen;
is_browser = false;
} else {
window.Strgen = Strgen;
is_browser = true;
}; // source: http://www.matteoagosti.com/blog/2013/02/24/writing-javascript-modules-for-both-browser-and-node/