diff --git a/.gitignore b/.gitignore
index c4c4ffc..4c8b8eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
*.zip
+.DS_Store
diff --git a/qosf.org/designs/infograph_creator/README.md b/qosf.org/designs/infograph_creator/README.md
new file mode 100644
index 0000000..58b11ef
--- /dev/null
+++ b/qosf.org/designs/infograph_creator/README.md
@@ -0,0 +1,57 @@
+
+# qosf.org Project Infographic Creator
+
+## Overview
+
+This project involves creating infographics for the QoSF.org project using an existing Adobe Illustrator (.ai) file and a `VariableImporter.jsx` script. The script imports variables into the .ai file, which allows for batch exporting components into PNG files using Adobe Illustrator's native export functionality. Afterwards, the resulting PNG files are combined into a larger image using a bash script.
+
+## Prerequisites
+
+1. **Adobe Illustrator** - Ensure you have Adobe Illustrator installed for working with the .ai files.
+2. **VariableImporter Script** - A script that imports variables into the .ai file.
+3. **ImageMagick** - Ensure you have ImageMagick installed, as it includes the `montage` tool required for the bash script.
+
+To install ImageMagick, run:
+```bash
+sudo apt-get install imagemagick
+```
+
+## Instructions
+
+### Step 0: Modify CSV
+Provided `quantum_projects.csv` contains the data to populate the cards and mount the infrograph, you may change it as desired but don't change the headers as they are required as they are to work with the provided `project_card.ai` and bind automatically with VariableImporter
+
+### Step 1: Use VariableImporter Script
+
+1. **Open Adobe Illustrator** and load the `project_card.ai` configured according to VariableImporter.jsx script requirements.
+2. **Run the VariableImporter script** load `VariableImporter.jsx` script (included) to import the provided `quantum_projects.csv` to load the card variables. If some variables were not auto-assigned to the object, correct that manually.
+
+### Step 2: Batch Export in Adobe Illustrator
+1. **Open Adobe Illustrator** and load the .ai file that has been updated with the VariableImporter script.
+2. Open the **Actions** panel (Window > Actions).
+3. Create a new action by clicking the **Create New Action** button.
+4. In the dialog that appears, name the action (e.g., "Batch Export") and click **Record**.
+5. Perform the export operation manually: Go to **File > Export > Export As**, choose **PNG** as the format, and set the export settings as desired. Click **Export**.
+6. Stop recording the action by clicking the **Stop** button at the bottom of the Actions panel.
+7. Go to **File > Automate > Batch**.
+8. In the Batch dialog, choose the action you just created from the **Action** dropdown.
+9. Set the **Source** to the folder containing your updated `.ai` file.
+10. Set the **Destination** to the folder where you want to save the exported PNG files.
+11. Click **OK** to start the batch export process.
+
+### Step 3: Assemble the PNG Files into a Larger Image
+To create a grid montage of PNG images:
+
+1. **Navigate** to the directory where your `create_grid.sh` script is located.
+2. Run the script with the following command:
+```bash
+./create_grid.sh 3x2 /path/to/cards output.png
+```
+- `3x2` specifies the grid size (3 columns and 2 rows) you can change that accordingly.
+- `/path/to/cards` is the directory where the PNG images are stored. Images are assumed to be all png
+- `output.png` is the name of the output file to be created.
+
+### Conclusion
+
+By following these steps, you can create a comprehensive infographic by importing variables into the provided Adobe Illustrator file using the VariableImporter script. Use Adobe Illustrator's batch export functionality to convert the updated .ai file into PNG files, and then combine these PNG files into a larger image using the provided bash script.
+
diff --git a/qosf.org/designs/infograph_creator/VariableImporter.jsx b/qosf.org/designs/infograph_creator/VariableImporter.jsx
new file mode 100644
index 0000000..05bcb2e
--- /dev/null
+++ b/qosf.org/designs/infograph_creator/VariableImporter.jsx
@@ -0,0 +1,4961 @@
+/***
+{
+ "name" : "VariableImporter 8",
+ "scriptVersion" : "8.2.4",
+ "note" : "This script helps to import .CSV and tab-delimited .TXT spreadsheets as Illustrator XML datasets.",
+ "author" : {
+ "by" : "Vasily Hall",
+ "email" : "vasily.hall@gmail.com",
+ "linkedIn" : "https://www.linkedin.com/pub/vasily-hall/18/166/912?trk=biz_employee_pub"
+ },
+ "thanks" : [
+ "Thanks to the global community of Illustrator enthusiasts who have helped make this script happen:",
+ "* Hans Boon / testing on multiple versions, workstations & platforms" ,
+ "* Stephen Marsh / http://prepression.blogspot.com/" ,
+ "* Andy VanWagoner's CSV Parser / http://stackoverflow.com/users/1701761/andy-vanwagoner" ,
+ "* Albert Bassa / 'double-backslash' line-break character suggestion" ,
+ "* John Garrett / http://hypertransitory.com/" ,
+ "* Dmitriy Gritsenko / help with multiple graph-data import" ,
+ "* Norbert Gindl / user testing multiple graph-data import" ,
+ "* Alice Elliott / bug fix in graph-data import" ,
+ "* Ryan Campbell / interval increments" ,
+ "* The great people of Adobe Scripting Forums"
+ ]
+}
+***/
+
+
+#target illustrator
+#targetengine main
+//the ui has problems and crashes when this isn't used
+#script "VariableImporter"
+
+function VariableImporter(){
+
+//=================================== FUNCTIONS ====================================//
+
+
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function(searchElement, fromIndex) {
+ var k;
+ if (this == null) {
+ throw new TypeError('"this" is null or not defined');
+ }
+ var o = Object(this);
+ var len = o.length >>> 0;
+ if (len === 0) {
+ return -1;
+ }
+ var n = +fromIndex || 0;
+ if (Math.abs(n) === Infinity) {
+ n = 0;
+ }
+ if (n >= len) {
+ return -1;
+ }
+ k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
+ while (k < len) {
+ if (k in o && o[k] === searchElement) {
+ return k;
+ }
+ k++;
+ }
+ return -1;
+ };
+};
+
+Array.prototype.compare = function (array) {
+ // if the other array is a falsy value, return
+ if (!array)
+ return false;
+
+ // compare lengths - can save a lot of time
+ if (this.length != array.length)
+ return false;
+
+ this.sort();
+ array.sort();
+ for (var i = 0; i < this.length; i++) {
+ // Check if we have nested arrays
+ if (this[i] instanceof Array && array[i] instanceof Array) {
+ // recurse into the nested arrays
+ if (!this[i].compare(array[i])){
+ return false;
+ }
+ }
+ else if (this[i] != array[i]) {
+ // Warning - two different object instances will never be equal: {x:20} != {x:20}
+ return false;
+ }
+ }
+ return true;
+};
+
+//http://stackoverflow.com/a/25094986/2864371
+function arrayMakeUnique(arr){
+ if(arr.length < 1){
+ return [];
+ }
+ var a = arr.slice(0,);
+ var b = a.length, c;
+ while(c = --b){
+ while(c--){
+ a[b]!== a[c] || a.splice(c,1);
+ }
+ }
+ return a;
+};
+
+function arrayGetAllDuplicates(arr){
+ if(arr.length < 1){
+ return [];
+ }
+ var a = arr.slice(0,);
+ var b = a.length, d = [], c;
+ while(c = --b){
+ while(c--){
+ a[b] !== a[c] || d.push(a.splice(c, 1)[0]);
+ }
+ }
+ return d;
+};
+
+function arrayGetUniqueDuplicates(arr){
+ return arrayMakeUnique(arrayGetAllDuplicates(arr));
+};
+
+function checkForSingleDuplicate(array, value){
+ var found = [], thisCell;
+ for (var i = 0; i < array.length; i++) {
+ thisCell = array[i];
+ if(thisCell == value){
+ found.push(value);
+ }
+ }
+ return found;
+};
+
+"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function quote(t){
+ return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t];
+ return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}
+ function str(t,e){var n,r,o,f,u,i=gap,p=e[t];switch(p&&"object"==typeof p&&"function"==typeof p.toJSON&&(p=p.toJSON(t)),
+ "function"==typeof rep&&(p=rep.call(e,t,p)),typeof p){case"string":return quote(p);case"number":return isFinite(p)?String(p):"null";
+ case"boolean":case"null":return String(p);case"object":if(!p)return"null";if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(p)){
+ for(f=p.length,n=0;f>n;n+=1)u[n]=str(n,p)||"null";return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+i+"]":"["+u.join(",")+"]",gap=i,o}
+ if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep[n]&&(r=rep[n],o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));
+ else for(r in p)Object.prototype.hasOwnProperty.call(p,r)&&(o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));return o=0===u.length?"{}":gap?"{\n"+gap+
+ u.join(",\n"+gap)+"\n"+i+"}":"{"+u.join(",")+"}",gap=i,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){
+ return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+
+ f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){
+ return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&
+ (escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,n){var r;
+ if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" ";else"string"==typeof n&&(indent=n);if(rep=e,
+ e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),
+ "function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t[e];if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&
+ (r=walk(o,n),void 0!==r?o[n]=r:delete o[n]);return reviver.call(t,e,o)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&
+ (text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),
+ /^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;
+ throw new SyntaxError("JSON.parse")})}();
+
+var tvdhve = "These violent delights have violent ends...";
+
+function clone(obj) {
+ var copy;
+ // Handle the 3 simple types, and null or undefined
+ if (null == obj || "object" != typeof obj) return obj;
+ // Handle Date
+ if (obj instanceof Date) {
+ copy = new Date();
+ copy.setTime(obj.getTime());
+ return copy;
+ }
+ // Handle Array
+ if (obj instanceof Array) {
+ copy = [];
+ for (var i = 0, len = obj.length; i < len; i++) {
+ copy[i] = clone(obj[i]);
+ }
+ return copy;
+ }
+ // Handle Object
+ if (obj instanceof Object) {
+ copy = {};
+ for (var attr in obj) {
+ if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
+ }
+ return copy;
+ }
+ throw new Error("Unable to copy obj! Its type isn't supported.");
+};
+
+String.prototype.trim = function () {
+ return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
+};
+
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(callback, thisArg) {
+ var T, k;
+ if (this == null) {
+ throw new TypeError(' this is null or not defined');
+ }
+ var O = Object(this);
+ var len = O.length >>> 0;
+ if (typeof callback !== "function") {
+ throw new TypeError(callback + ' is not a function');
+ }
+ if (arguments.length > 1) {
+ T = thisArg;
+ }
+ k = 0;
+ while (k < len) {
+ var kValue;
+ if (k in O) {
+ kValue = O[k];
+ callback.call(T, kValue, k, O);
+ }
+ k++;
+ }
+ };
+}
+
+function unCamelCaseSplit(str){
+ var newStr = str[0].toUpperCase() + str.split(/([A-Z][a-z]+)/g).join(" ").replace(/\s{2}/g," ").substr(1,);
+ return newStr;
+};
+
+Number.prototype.padZero = function(decimals){
+ if(typeof decimals == "undefined"){
+ decimals = 2;
+ }
+ var numStr = this.toString();
+ var decimalsFound = numStr.length;
+ if(decimalsFound >= decimals){
+ return this;
+ }
+ while(decimalsFound < decimals){
+ numStr = '0' + numStr;
+ decimalsFound += 1;
+ }
+ return numStr;
+};
+
+function writeImageFile(binary, dest){
+ if(!dest instanceof "File"){
+ dest = File(dest);
+ }
+ try {
+ dest.encoding = "BINARY";
+ dest.open("w");
+ dest.write(binary);
+ dest.close();
+ } catch (e) {
+ scriptAlert("writeImageFile(binary, dest)\r" + e);
+ }
+};
+
+function getScriptImage(imageObj) {
+ /*
+ imageObj = { "data" : embeddedImageData, "name" : imageName }
+ */
+ var scriptDataFolder = SESSION.scriptDataFolder;
+ if(!scriptDataFolder){
+ return false;
+ }
+ var thisFile = File(scriptDataFolder + "/" + imageObj.name + '.png');
+ if(!thisFile.exists){
+ writeImageFile(imageObj.data, thisFile);
+ if(!thisFile.exists) {
+ return false;
+ }
+ }
+ return thisFile;
+};
+/*
+function writeScriptImages() {
+ var scriptDataFolder = SESSION.scriptDataFolder;
+ for(var all in ICONS){
+ var thisFile = File(scriptDataFolder + "/" + all + '.png');
+ if(!thisFile.exists){
+ writeImageFile(ICONS[all], thisFile);
+ if(!thisFile.exists) {
+ return false;
+ } else {
+ ICONS[all] = thisFile;
+ }
+ } else {
+ ICONS[all] = thisFile;
+ }
+ }
+ return true;
+};
+*/
+
+var CSV = {
+ // ===================================================== http://stackoverflow.com/a/12785546
+ // ===================================================== Andy VanWagoner
+ // ===================================================== http://thetalecrafter.com/
+ parse: function(csv, reviver, splitter) {
+ splitter = splitter || ',';
+ reviver = reviver || function(r, c, v) { return v; };
+ var chars = csv.split(''), c = 0, cc = chars.length, start, end, table = [], row;
+ while (c < cc) {
+ table.push(row = []);
+ while (c < cc && '\r' !== chars[c] && '\n' !== chars[c]) {
+ start = end = c;
+ if ('"' === chars[c]){
+ start = end = ++c;
+ while (c < cc) {
+ if ('"' === chars[c]) {
+ if ('"' !== chars[c+1]) { break; }
+ else { chars[++c] = ''; } // unescape ""
+ }
+ end = ++c;
+ }
+ if ('"' === chars[c]) { ++c; }
+ while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && splitter !== chars[c]) { ++c; }
+ } else {
+ while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && splitter !== chars[c]) { end = ++c; }
+ }
+ row.push(reviver(table.length-1, row.length, chars.slice(start, end).join('')));
+ if (splitter === chars[c]) { ++c; }
+ }
+ if ('\r' === chars[c]) { ++c; }
+ if ('\n' === chars[c]) { ++c; }
+ }
+ return table;
+ },
+ stringify: function(table, replacer, splitter) {
+ replacer = replacer || function(r, c, v) { return v; };
+ var csv = '', c, cc, r, rr = table.length, cell;
+ for (r = 0; r < rr; ++r) {
+ if (r) { csv += '\r\n'; }
+ for (c = 0, cc = table[r].length; c < cc; ++c) {
+ if (c) { csv += splitter; }
+ cell = replacer(r, c, table[r][c]);
+ var rx = new RegExp("[" + splitter + "]\\r" + "\\n\"");
+ if (rx.test(cell)) { cell = '"' + cell.replace(/"/g, '""') + '"'; }
+ csv += (cell || 0 === cell) ? cell : '';
+ }
+ }
+ return csv;
+ }
+};
+
+function getTextData(dataFile){
+ var df = dataFile;
+ var dataFileName = decodeURI(df.name);
+ var type = dataFileName.match(/(\.txt$|\.csv$)/i)[0].toLowerCase();
+ var splitter = (type == '.txt')? '\t' : ',';
+ df.open('r');
+ var fileContents = df.read();
+ var firstRow = fileContents.split(/[\r\n]/g)[0];
+ if(firstRow != null && splitter != "\t"){
+ if(firstRow.indexOf(",") == -1 && firstRow.indexOf(";") > -1){
+ splitter = ";"; // For the .csv format: if the first row has no commas but has a semicolon, assume this is a semicolon-delimited .csv file
+ }
+ }
+ var everyRowRaw = CSV.parse(fileContents, undefined, splitter);
+ df.close();
+
+ var everyRow = [];
+ for(var i = 0; i < everyRowRaw.length; i++){
+ // get rid of empty rows
+ var thisRawRow = everyRowRaw[i];
+ if(!checkRowForAllBlanks(thisRawRow)){
+ if(i > 0){
+ if(thisRawRow.length < everyRow[0].length){
+ var diff = everyRow[0].length - thisRawRow.length;
+ for(var d = 0; d < diff; d++){
+ thisRawRow.push("");
+ }
+ }
+ }
+ everyRow.push(thisRawRow);
+ }
+ }
+ return everyRow;
+};
+
+function getData(filePath){
+ try{
+ return getTextData(File(filePath));
+ } catch(e) {
+ alert(e);
+ return null;
+ }
+};
+
+function checkRowForAllBlanks(row){
+ for(var i = 0; i < row.length; i++){
+ if(row[i] != ''){
+ return false;
+ }
+ }
+ return true;
+};
+
+function getVariableType(str){
+ var firstChar = str[0];
+ for(var all in VARTYPES){
+ if(firstChar == VARTYPES[all].key){
+ return all;
+ }
+ }
+ return "Text";
+};
+
+function transposeGrid(data){
+ var newArr = [];
+ var columns = data[0].length, rows = data.length, newRow = [];
+ for (var i = 0; i < columns; i++) {
+ newRow = [];
+ for (var j = 0; j < rows; j++) {
+ newRow.push(data[j][i]);
+ };
+ newArr.push(newRow);
+ };
+ return newArr;
+};
+
+function comparePropNames(compareTo, compareThis){
+ var resMsg = "";
+ var propCount = {};
+ propCount.compareTo = 0;
+ propCount.compareThis = 0;
+ var compareToPropArr = [];
+ var compareThisPropArr = [];
+ for(var all in compareTo){
+ propCount.compareTo++;
+ compareToPropArr.push(all);
+ }
+ for(var all in compareThis){
+ propCount.compareThis++;
+ compareThisPropArr.push(all);
+ }
+ var allFound = true, thisProp, thisCompareProp;
+ for (var i = 0; i < compareToPropArr.length; i++) {
+ thisProp = compareToPropArr[i];
+ for (var j = 0; j < compareThisPropArr.length; j++) {
+ thisCompareProp = compareThisPropArr[j];
+ if(compareThisPropArr.indexOf(thisProp) == -1 || compareToPropArr.indexOf(thisCompareProp) == -1){
+ allFound = false;
+ break;
+ }
+ };
+ };
+ if(!allFound){
+ resMsg = "Not All Found"
+ } else {
+ resMsg = "All Found"
+ }
+
+ return {
+ resMsg : resMsg,
+ propCount : propCount
+ };
+};
+
+function getByName(obj, name){
+ if(obj instanceof Array){
+ for (var i = 0; i < obj.length; i++) {
+ if(obj[i].name == name){
+ return obj[i];
+ }
+ }
+ } else if(typeof obj == "Object"){
+ for(var all in obj){
+ if(all == "name" && obj[all] == name){
+ return obj[all];
+ }
+ }
+ }
+ return null;
+};
+
+function getPropertyList(obj){
+ var arr = [];
+ for(var all in obj){
+ arr.push(all);
+ }
+ return arr;
+};
+
+function getSpecificPropertyListObj(obj, prop){
+ var arr = [];
+ for(var all in obj){
+ if(obj[all].hasOwnProperty(prop)){
+ arr.push(obj[all][prop]);
+ }
+ }
+ return arr;
+};
+
+function getSpecificPropertyObj(obj, prop, value){
+ for(var all in obj){
+ if(obj[all].hasOwnProperty(prop) && obj[all][prop] == value){
+ return obj[all];
+ }
+ }
+ return null;
+};
+
+function getSpecificPropertyListArr(srcArr, prop){
+ var arr = [];
+ for (var i = 0; i < srcArr.length; i++) {
+ if(srcArr[i].hasOwnProperty(prop)){
+ arr.push(srcArr[i][prop]);
+ }
+ }
+ return arr;
+};
+
+function getSpecificValuePropertyListArr(srcArr, filterProp, filterValue, searchProp){
+ var arr = [];
+ for (var i = 0; i < srcArr.length; i++) {
+ if(srcArr[i].hasOwnProperty(filterProp) && srcArr[i].hasOwnProperty(searchProp) && srcArr[i][filterProp] == filterValue){
+ arr.push(srcArr[i][searchProp]);
+ }
+ }
+ return arr;
+};
+
+
+
+//==================================================================================//
+
+//================================== FUNCTIONS_2 ===================================//
+
+function writeFile(fileObj, contents, encoding){
+ if(typeof encoding == "string"){
+ fileObj.encoding = encoding;
+ }
+ fileObj.open("w");
+ fileObj.write(contents);
+ fileObj.close();
+};
+
+function writeSettingsFile(settingsObj) {
+ var scriptDataFolder = SESSION.scriptDataFolder;
+ if(scriptDataFolder.exists){
+ var settingsFile = SESSION.settingsFile;
+ try{
+ writeFile(settingsFile, JSON.stringify(settingsObj, null, 2));
+ if(WARNINGSETTINGS.showSuccessfulSettingsFileSaves){
+ scriptAlert("Settings file successfully saved in '" + decodeURI(settingsFile) + "'");
+ }
+ } catch(e) {
+ scriptAlert(e);
+ }
+ } else {
+ scriptAlert("The folder '" + scriptDataFolder + "' does not exist and Settings file could not be written.");
+ }
+};
+
+function getScriptDataObj(){
+ // must have updated object first
+ var obj = {};
+ obj.WARNINGSETTINGS = WARNINGSETTINGS;
+ obj.PRESETS = PRESETS;
+ obj.DATASETNAMEFIELDS = DATASETNAMEFIELDS_current;
+ obj.CUSTOM_INCREMENTS = CUSTOM_INCREMENTS_current;
+ obj.VisibilityKeys = VisibilityKeys;
+ if(typeof(VI_MEMORY_SETTINGS) != "undefined"){
+ obj.lastChosenDataFilePath = VI_MEMORY_SETTINGS.lastChosenDataFilePath;
+ }
+ return obj;
+};
+
+function updateScriptDataFromUI(UIElements, presetName){
+ var presetName = presetName || SESSION.currentLoadedPresetName;
+ var presetObj = {};
+ for ( var all in PRESETS[0] ){
+ if(UIElements.hasOwnProperty(all) && typeof UIElements[all].getValue == "function"){
+ presetObj[all] = UIElements[all].getValue();
+ }
+ }
+ var warningList = UIElements["list_warnings"];
+ for ( var all in WARNINGSETTINGS ){
+ WARNINGSETTINGS[all] = warningList.find(unCamelCaseSplit(all)).checked;
+ }
+ // also update from other memory objects, not necessarily the UI anymore
+ presetObj["datasetNameObj"] = clone(DATASETNAMEFIELDS_current);
+ presetObj["enabledVisibilityKeyNames"] = getSpecificValuePropertyListArr(VisibilityKeys, "enabled", true, "name");
+ var loadedPreset = PRESETS.getByName(presetName);
+ for(var all in presetObj){
+ loadedPreset[all] = presetObj[all];
+ }
+};
+
+function getUIData(UIElements){
+ var presetObj = {};
+ for ( var all in PRESETS[0]){
+ if(UIElements.hasOwnProperty(all) && typeof UIElements[all].getValue == "function"){
+ presetObj[all] = UIElements[all].getValue();
+ }
+ }
+ for ( var all in WARNINGSETTINGS ){
+ // this adds the notification settings as piggy-back, but isn't used in the return data from this function
+ if(UIElements.hasOwnProperty(all) && typeof UIElements[all].getValue == "function"){
+ WARNINGSETTINGS[all] = UIElements[all].getValue();
+ }
+ }
+ presetObj.datasetNameObj = DATASETNAMEFIELDS_current;
+ presetObj.enabledVisibilityKeyNames = getSpecificValuePropertyListArr(VisibilityKeys, "enabled", true, "name");
+ return presetObj;
+};
+
+function updateCurrentPresetNameDisplays(UIElements, currentLoadedPresetObj, tryAddOverridesMarker){
+ var currentUIStatePresetObj = getUIData(UIElements);
+ var hasOverrides = false;
+ if(typeof tryAddOverridesMarker != "undefined" && tryAddOverridesMarker === true ){
+ var testObj = {};
+ for(var all in currentUIStatePresetObj){
+ if(all == "enabledVisibilityKeyNames"){
+ if(currentUIStatePresetObj[all].compare(currentLoadedPresetObj[all])){
+ // checked by array compare function to see if same elements exist in both arrays regardless of order
+ // if so, set one object to the other, making later string comparison true
+ currentLoadedPresetObj[all] = currentUIStatePresetObj[all];
+ }
+ }
+ testObj[all] = currentLoadedPresetObj[all];
+ }
+ hasOverrides = JSON.stringify(testObj) !== JSON.stringify(currentUIStatePresetObj);
+ // quickView(
+ // JSON.stringify(testObj, null, 2) + "\n\n" +
+ // JSON.stringify(currentUIStatePresetObj, null, 2)
+ // );
+ }
+ var thisElem;
+ for (var i = 0; i < UIElements["currentlySelectedPresetName"].length; i++) {
+ thisElem = UIElements["currentlySelectedPresetName"][i];
+ if(hasOverrides){
+ thisElem.setValue(SESSION.currentLoadedPresetName + "*");
+ thisElem.helpTip = "The preset '" + SESSION.currentLoadedPresetName + "' has one or more of its dialog settings overriden in the current dialog state.";
+ } else {
+ thisElem.setValue(SESSION.currentLoadedPresetName);
+ thisElem.helpTip = "";
+ }
+ };
+};
+
+function setVisibilityKeysEnabled(visKeyNames){
+ var thisVisKeyObj, processedItems = [];
+ for (var i = 0; i < VisibilityKeys.length; i++) {
+ thisVisKeyObj = VisibilityKeys[i];
+ if(visKeyNames.indexOf(thisVisKeyObj.name) > -1 && processedItems.indexOf(thisVisKeyObj.name) == -1){
+ thisVisKeyObj.enabled = true;
+ processedItems.push(thisVisKeyObj.name);
+ } else if(processedItems.indexOf(thisVisKeyObj.name) == -1){
+ thisVisKeyObj.enabled = false;
+ }
+ }
+};
+
+function populateUI(UIElements, tryAddOverridesMarker){
+ // tryAddOverridesMarker should be used when this function is invoked after window loading
+ var currentLoadedPresetObj = PRESETS.getByName(SESSION.currentLoadedPresetName);
+ if(currentLoadedPresetObj.hasOwnProperty("enabledVisibilityKeyNames")){
+ setVisibilityKeysEnabled(currentLoadedPresetObj.enabledVisibilityKeyNames);
+ }
+ for (var all in UIElements){
+ if( all in UIElements && all in SETTINGS ){
+ SETTINGS[all] = (currentLoadedPresetObj[all]);
+ }
+ }
+ for ( var all in PRESETS[0]){
+ if(UIElements.hasOwnProperty(all) && typeof UIElements[all].getValue == "function"){
+ UIElements[all].setValue(currentLoadedPresetObj[all]);
+ }
+ }
+ updateCurrentPresetNameDisplays(UIElements, currentLoadedPresetObj, tryAddOverridesMarker);
+ var warningList = UIElements["list_warnings"];
+ for ( var all in WARNINGSETTINGS){
+ warningList.find(unCamelCaseSplit(all)).checked = WARNINGSETTINGS[all];
+ }
+ UIElements["disp_dataFile"].notify("onChange");
+ var xmlPathStr = UIElements["xmlPath"].getValue();
+ if(xmlPathStr == "" || xmlPathStr == "temp" || xmlPathStr == "undefined"){
+ UIElements["xmlPath"].setValue(SETTINGS.getDataXMLDestination());
+ }
+ UIElements["datasetNamePreview"].setValue(getDatasetNamePreviewString());
+};
+
+function getCurrentlySelectedPresetName(){
+ var thisPreset;
+ for(var i = 0; i < PRESETS.length; i++){
+ thisPreset = PRESETS[i];
+ if(thisPreset.currentlySelected){
+ return thisPreset.name;
+ }
+ }
+};
+
+function setCurrentlySelectedPresetName(name){
+ var thisPreset;
+ for(var i = 0; i < PRESETS.length; i++){
+ thisPreset = PRESETS[i];
+ if(name == thisPreset.name){
+ thisPreset.currentlySelected = true;
+ } else {
+ thisPreset.currentlySelected = false;
+ }
+ }
+};
+
+function addVarNameDatasetNames(){
+ FIELDNAMEOPTIONS_current = clone(FIELDNAMEOPTIONS);
+ var varNames = DATA.getVariableNames();
+ if(varNames.length == 0){
+ return;
+ }
+ var thisName, key;
+ for (var i = 0; i < varNames.length; i++) {
+ thisName = varNames[i];
+ key = "variable_" + (i + 1) + "_value";
+ FIELDNAMEOPTIONS_current[key] = {
+ defaultText : thisName,
+ displayText : "Variable " + (i + 1) + " Value : \"" + thisName + "\"",
+ type : key
+ }
+ };
+
+ var processedDatasetNameFieldsResult = clearOutOfBoundVariables(DATASETNAMEFIELDS_current);
+ DATASETNAMEFIELDS_current = processedDatasetNameFieldsResult.obj;
+ if(WARNINGSETTINGS.showDatasetNamingWarning && processedDatasetNameFieldsResult.msg != ""){
+ quickView(processedDatasetNameFieldsResult.msg, "Dataset naming field errors.");
+ }
+};
+
+function clearOutOfBoundVariables(obj){
+ // variable field values and custom increment objects in dataset name fields
+ var varNames = DATA.getVariableNames();
+ var idx;
+ missingVariableNamesLog = [];
+ missingCustomIncrementsLog = [];
+ for(var all in obj){
+ if(obj[all].type.match(SESSION.regexps.varRx)){
+ idx = (obj[all].type.match(/\d+/) * 1) - 1;
+ if(idx < varNames.length){
+ obj[all].text = varNames[idx];
+ } else {
+ missingVariableNamesLog.push(all + " : variable # " + idx + " (\"" + obj[all].text + "\")");
+ obj[all].type = "nothing";
+ obj[all].text = "";
+ }
+ } else if(obj[all].type == "customIncrement"){
+ var customIncObj = getByName(CUSTOM_INCREMENTS_current, obj[all].text);
+ if(customIncObj == null){
+ missingCustomIncrementsLog.push(all + " : " + obj[all].text);
+ obj[all].type = "nothing";
+ obj[all].text = "";
+ }
+ }
+ }
+ var msg = "";
+ if(missingVariableNamesLog.length > 0 ){
+ msg += "The variables associated with dataset-name fields were not found in current data and were removed from the dataset naming options.\n" +
+ "---------------------------------------------\n" +
+ missingVariableNamesLog.join("\n");
+ }
+ if(missingCustomIncrementsLog.length > 0){
+ if(msg != ""){
+ msg += "\n\n";
+ }
+ msg += "These custom increments were specified inside the dataset name fields, but were not located in the saved settings data.\n" +
+ "---------------------------------------------\n" +
+ missingCustomIncrementsLog.join("\n");
+ }
+ return { obj : obj, msg : msg };
+};
+
+function getPrependPathValue(varObj, cellData){
+ var folderDiv = (SESSION.os == "Windows")? "\\" : "/";
+ cellData = varObj.url + folderDiv + cellData;
+ cellData = (cellData).replace(/\\\\/g,"//").replace(/\\/g,"/");
+ return cellData;
+};
+
+function getRecordDatasetName(dsNameFieldObj, row, index){
+ var str = "";
+ for(var all in dsNameFieldObj){
+ str += getDsNameField(dsNameFieldObj, all, row, index);
+ };
+ return str;
+};
+
+function getRecordCustomInc(index, startNum, padZero, increment, isIntervalIncrement, _isSelfCalled){
+ /* 0-start-based index */
+ startNum *= 1;
+ increment *= 1;
+ var padZeroStr = "";
+ var storedPadZero = padZero;
+ var currentNum = startNum + (index * increment);
+ if(_isSelfCalled){
+ currentNum -= 1;
+ }
+ var currentNumLength = currentNum.toString().length - 1;
+ padZero -= currentNumLength;
+ for(var i = 0; i < padZero; i++){
+ padZeroStr += "0";
+ }
+ if(!isIntervalIncrement){
+ return padZeroStr + currentNum;
+ } else {
+ // get next value by re-using this function with edited increment argument and a flag to avoid this block during that run
+ var nextVal = getRecordCustomInc(index + 1, startNum, storedPadZero, increment, false, true);
+
+ return padZeroStr + currentNum + "-" + nextVal;
+ }
+};
+
+function getDsNameField(dsNameFieldObj, fieldName, row, index){
+
+ function getCurrentText(dsNameFieldObj, fieldName){
+ return dsNameFieldObj[fieldName].text;
+ };
+
+ if(dsNameFieldObj[fieldName].type.match(SESSION.regexps.varRx)){
+ var varIndex = (dsNameFieldObj[fieldName].type.replace(/[^\d]/g, "") * 1) - 1;
+ if(varIndex < row.length){
+ return row[varIndex];
+ }
+ }
+
+ switch(dsNameFieldObj[fieldName].type){
+ case "customText" : {
+ return getCurrentText(dsNameFieldObj, fieldName);
+ break;
+ };
+ case "dash" : {
+ return getCurrentText(dsNameFieldObj, fieldName);
+ break;
+ };
+ case "nothing" : {
+ return getCurrentText(dsNameFieldObj, fieldName);
+ break;
+ };
+ case "space" : {
+ return getCurrentText(dsNameFieldObj, fieldName);
+ break;
+ };
+ case "increment" : {
+ return index + SETTINGS.incrementStartNumber;
+ break;
+ };
+ case "underscore" : {
+ return getCurrentText(dsNameFieldObj, fieldName);
+ break;
+ };
+ case "customIncrement" : {
+ var customIncName = getCurrentText(dsNameFieldObj, fieldName);
+ var customIncObj = getByName(CUSTOM_INCREMENTS_current, customIncName);
+ if(customIncObj == null){
+ return ""; // failed to find the custom increment item
+ }
+ return getRecordCustomInc(index, customIncObj.startNum, customIncObj.padZero, customIncObj.increment, customIncObj.isIntervalIncrement);
+ break;
+ };
+ default : {
+ return "";
+ };
+ }
+ return "";
+};
+
+function getFileRefTestResults(){
+ if(DATA.currentVars.length == 0){
+ return null;
+ }
+ var log = {
+ foundImages : ["Found Images: "],
+ foundGraphs : ["Found Graphs: "],
+ missingImages : ["Missing Images: "],
+ missingGraphs : ["Missing Graphs: "]
+ };
+
+ var item, thisVar, test;
+
+ for(var i = 0; i < DATA.currentGrid.length; i++){
+ for (var j = 0; j < DATA.currentVars.length; j++) {
+ item = DATA.currentGrid[i][j];
+ thisVar = DATA.currentVars[j];
+ if(thisVar.varType == "Image" || thisVar.varType == "Graph"){
+ test = File(item);
+ if(test.exists){
+ log["found" + thisVar.varType + "s"].push(item);
+ } else {
+ log["missing" + thisVar.varType + "s"].push(item);
+ }
+ }
+ };
+ }
+ return log;
+};
+
+function getSpecificFileRefTestResultsLog(log, prop){
+ // images or graphs
+ if(prop != "Images" && prop != "Graphs"){
+ alert("Only 'Images' and 'Graphs' are searchable properties in function 'getSpecificFileRefTestResultsLog(log, prop)'");
+ return null;
+ }
+
+ var specificLog = {
+ found : log["found" + prop],
+ missing : log["missing" + prop]
+ };
+
+ var resMsg = "";
+ for(var all in specificLog){
+ specificLog[all][0] += ("(" + (specificLog[all].length - 1) + ")\n---------------");
+ resMsg += (specificLog[all].join("\n") + "\r\r");
+ }
+ return resMsg;
+};
+
+function fileRefTestHandler(){
+ // designed to be called from a button which has a .key property saying which part of the log to show. (.key = "Images" | .key = "Graphs")
+ if(DATA.currentVars.length == 0){
+ alert("Please import a data file first.");
+ return;
+ }
+ DATA.getCurrentGrid();
+ var allResults = getFileRefTestResults();
+ var thisRefResultNumFound = allResults["found" + this.key].length - 1;
+ var thisRefResultNumMissing = allResults["missing" + this.key].length - 1;
+ var foundMissingNum = thisRefResultNumFound + "/" + (thisRefResultNumFound + thisRefResultNumMissing);
+
+ // var logStr = getSpecificFileRefTestResultsLog(allResults, this.key);
+ var keySingular = this.key.replace(/s$/, "");
+
+ simpleShowModal(TestManager[keySingular.toLowerCase() + "Files"].makeUIContents, {
+ title : this.key.replace(/s$/, "") + " Files Log",
+ foundFiles : allResults["found" + this.key].slice(1).join("\n"),
+ missingFiles : allResults["missing" + this.key].slice(1).join("\n"),
+ foundMissingNum : foundMissingNum,
+ size : [800, 220]
+ });
+
+ this.disp.setValue(foundMissingNum);
+ var tabGroupKey = "testTabs";
+ if(this.window.UITestElements.hasOwnProperty(tabGroupKey)){
+ var testTabPanel = this.window.UITestElements["testTabs"], thisTab;
+ for (var i = 0; i < testTabPanel.children.length; i++) {
+ thisTab = testTabPanel.children[i];
+ if(thisTab.hasOwnProperty("key") && thisTab.key == keySingular){
+ thisTab.populateFields();
+ }
+ };
+ }
+};
+
+function displayFoundArtBindings(UITestElements){
+ var doc = app.activeDocument;
+ DocumentBinding.getNamedBinds(doc);
+ UITestElements["foundArtBindings"].setValue( DocumentBinding.getBindObjectTestResults().foundItemString );
+ var tabItemKey = "testTabArtBinding";
+ if(UITestElements.hasOwnProperty(tabItemKey)){
+ UITestElements[tabItemKey].populateFields();
+ }
+};
+
+eval(
+ "@JSXBIN@ES@2.0@MyBbyBnABMAbyBn0ACOBbCn0ACJCnAEjzFjBjMjFjSjUBfRBFehBiEjPjFjTjOhHj" +
+ "UhAjMjPjPjLhAjMjJjLjFhAjBjOjZjUjIjJjOjHhAjUjPhAjNjFhOffZDnAFctACzChdhdCEXzHjSjF" +
+ "jQjMjBjDjFDfEXzLjUjPiMjPjXjFjSiDjBjTjFEfVzFjJjOjQjVjUFfAnfRCYIibieicjXicjTidhLA" +
+ "FeAffEXDfEXEfVzHjEjFjTjJjSjFjEGfBnfRCYIibieicjXicjTidhLAFeAffnnnZFnAFcfACG4B0Ah" +
+ "AF40BhAC0AzCjFjFHAG0EzAIByB"
+);
+
+
+//==================================================================================//
+
+//================================== FUNCTIONS_2 ===================================//
+
+function stringXmlSafe(str){
+ str=str.toString();
+ str=str.replace(/&(?!(amp;|gt;|lt;|quot;|apos;))/g, "&");
+ str=str.replace(//g, ">");
+ str=str.replace(/'/g, "'");
+ str=str.replace(/"/g, """);
+ return str;
+};
+
+function disguiseXmlEntities(str){
+ str=str.toString();
+ str=str.replace(/&(?!(amp;|gt;|lt;|quot;|apos;))/g, "_#_amp_#_");
+ str=str.replace(//g, "_#_gt_#_");
+ str=str.replace(/'/g, "_#_apos_#_");
+ str=str.replace(/"/g, "_#_quot_#_");
+ return str;
+};
+
+function undisguiseXmlEntities(str){
+ str=str.toString();
+ str=str.replace(/_#_amp_#_/g, "&");
+ str=str.replace(/_#_lt_#_/g, "<");
+ str=str.replace(/_#_gt_#_/g, ">");
+ str=str.replace(/_#_apos_#_/g, "'");
+ str=str.replace(/_#_quot_#_/g, """);
+ return str;
+};
+
+function wrapCDATA(str, propNm){
+ str = '' + str + '';
+ str = str.replace(/(\)/g, '<' + propNm + '>)/g, ']]\>' + '' + propNm + '>');
+ return XML(str);
+};
+
+function isXMLTagName ( tag ){
+ //http://stackoverflow.com/questions/3158274/what-would-be-a-regex-for-valid-xml-names
+ var t = !/^[xX][mM][lL].*/.test(tag); // condition 3
+ t = t && /^[a-zA-Z_].*/.test(tag); // condition 2
+ t = t && /^[a-zA-Z0-9_\-\.]+$/.test(tag); // condition 4
+ return t;
+};
+
+function getXmlFileDest(userInputObj){
+ if(!SETTINGS.keepXML){
+ var dataFile = File(userInputObj.sourceDataPath);
+ var xmlDest = File(dataFile.parent + "/" + decodeURI(dataFile.name).replace(/\.\w+$/, ".xml"))
+ .saveDlg("Where would you like to save the Variable Data XML file?");
+ return xmlDest;
+ } else {
+ return File(userInputObj.xmlPath);
+ }
+};
+
+function forceRefreshDoc(){
+ var temp = app.documents.add();
+ temp.close(SaveOptions.DONOTSAVECHANGES);
+};
+
+function cycleUpdateAllDatasets(doc, displayElem){
+ for(var i = 0; i < doc.dataSets.length; i++){
+ var d = doc.dataSets[i];
+ d.display();
+ if(typeof displayElem != "undefined"){
+ displayElem.text = (i + 1) + " of " + doc.dataSets.length;
+ displayElem.window.update();
+ }
+ redraw();
+ $.sleep(10);
+ d.update();
+ };
+ doc.dataSets[0].display();
+ displayElem.text = (1) + " of " + doc.dataSets.length;
+};
+
+function processUserInput(userInputObj) {
+
+ var xmlDest, doc, problem;
+
+ var xmlString = XMLStringBuilder.generateVariableLibraryXMLString();
+ if(xmlString == null){
+ return;
+ }
+
+ if(userInputObj.purpose == "createXML"){
+ xmlDest = getXmlFileDest(userInputObj);
+ if(xmlDest == null){
+ alert("Cancelled: no XML file produced.");
+ return;
+ }
+
+ writeFile(xmlDest, xmlString, "UTF-8");
+
+ if(xmlDest.exists){
+ // alert("File successfully saved in '" + decodeURI(xmlDest) + "'");
+ finishedXMLFileDialog(xmlDest, DATA.currentVars.length, DATA.currentGrid.length);
+ } else {
+ alert("Sorry, the file '" + decodeURI(xmlDest) + "' could not be saved.");
+ }
+ } else {
+
+ xmlDest = File(userInputObj.xmlPath);
+ writeFile(xmlDest, xmlString, "UTF-8");
+ if(!xmlDest.exists){
+ alert("Sorry, the file '" + decodeURI(xmlDest) + "' could not be saved.");
+ return;
+ }
+ doc = app.activeDocument;
+ if(doc.variables.length > 0){
+ if(!CONFIRMS["showExistingVariablesWarning"]( doc.variables.length )){
+ alert("Cancelled: no variables were imported.");
+ return;
+ }
+ if(SETTINGS.selectedAutobinding != "noAutoBinding"){
+ for (var i = doc.variables.length - 1; i >= 0; i--) {
+ doc.variables[i].remove();
+ }
+ }
+ }
+
+ try {
+ problem = "Importing Variables into the document from created XML file.";
+ doc.importVariables(xmlDest);
+ forceRefreshDoc(); // force refresh actually makes binding possible?
+
+ if(SETTINGS.selectedAutobinding != "noAutoBinding" &&
+ !(userInputObj.fileRefsLog.missingImages.length > 1 || userInputObj.fileRefsLog.missingGraphs.length > 1)){
+ problem = "Auto-Binding variables to art items based on '" + unCamelCaseSplit(SETTINGS.selectedAutobinding) + "'";
+ DocumentBinding.bindDocumentItems(doc);
+ }
+
+ if(userInputObj.fileRefsLog.missingImages.length < 2 || userInputObj.fileRefsLog.missingGraphs.length < 2){
+ if(doc.dataSets.length > 0 && SETTINGS.selectedAutobinding != "noAutoBinding"){
+ problem = "Displaying first dataset of the document."
+ doc.dataSets[0].display(); // display the first dataset.
+ }
+ }
+ finishedXMLImportDialog(
+ DATA.currentVars.length,
+ DATA.currentGrid.length,
+ userInputObj.fileRefsLog.missingImages.length - 1,
+ userInputObj.fileRefsLog.missingGraphs.length - 1
+ );
+ // victory!
+ } catch(e) {
+ alert("Sorry, something went wrong with the import of the generated XML file '" + xmlDest + "':\n" + e + "\nPossible Problem: " + problem);
+ }
+
+ if(!SETTINGS.keepXML){
+ xmlDest.remove();
+ }
+ }
+};
+
+
+
+//==================================================================================//
+
+//==================================== OBJECTS =====================================//
+var SESSION = {
+ os : $.os.match('Windows') ? 'Windows' : 'Mac',
+ AIVersion : parseInt(app.version.split(/\./)[0]),
+ scriptName : "VariableImporter.jsx",
+ "scriptVersion" : "8.2.4",
+ currentLoadedPresetName : "",
+ regexps : {
+ varRx : /variable_\d+_value/,
+ fileStartRx : /^file\:\/\/\//
+ },
+ multiColumnListBoxTest : true,
+ documentExists : (app.documents.length > 0),
+ settingsFile : function(){
+ return File(Folder.myDocuments + "/VariableImporter/VariableImporter_SETTINGS.json");
+ }(),
+ scriptDataFolder : function(){
+ var f = Folder(Folder.myDocuments + "/VariableImporter");
+ if(!f.exists){
+ f.create();
+ }
+ return f;
+ }(),
+ dataFileMask : function(){
+ return (this.os == 'Windows')? "*.txt;*.TXT;*.csv;*.CSV;" : function(f){
+ return f instanceof Folder || (f instanceof File && decodeURI(f.name).match(/(\.txt|\.csv)$/i));
+ };
+ },
+ tabbedGroupTest : false,
+ imageTest : false,
+ doImageTest : function(){
+ /*var thisIcon;
+ var flag = true;
+ try{
+ for (var all in ICONS) {
+ thisIcon = ICONS[all];
+ parent.add("iconbutton", undefined, thisIcon);
+ };
+ } catch(e) {
+ // fail Error 520, try to write the images
+ flag = writeScriptImages();
+ }
+ this.imageTest = flag;
+ */
+ var flag = true, thisIconString, test;
+ for (var all in ICONS) {
+ thisIconString = ICONS[all];
+ test = getScriptImage({
+ name : all,
+ data : thisIconString
+ });
+ ICONS[all] = test;
+ if(!test){
+ flag = false;
+ }
+ };
+ this.imageTest = flag;
+ return flag;
+ },
+ init : function(){
+ // load from settings function
+ if(this.settingsFile.exists){
+ this.settingsFile.open('r');
+ var settingsObj = JSON.parse(this.settingsFile.read()), tempObj;
+ this.settingsFile.close();
+ // read the visibility keys in first.
+ if(settingsObj.hasOwnProperty("VisibilityKeys") && settingsObj.VisibilityKeys.length > 0 && comparePropNames(settingsObj.VisibilityKeys[0], VisibilityKeys[0]).resMsg == "All Found"){
+ VisibilityKeys = settingsObj.VisibilityKeys;
+ }
+ if(settingsObj.hasOwnProperty("PRESETS")){
+ for( var i = 0; i < settingsObj.PRESETS.length; i++ ){
+ tempObj = {};
+ for(var all in PRESETS[0]){
+ if(settingsObj.PRESETS[i].hasOwnProperty(all)){
+ tempObj[all] = settingsObj.PRESETS[i][all];
+ if(all == "currentlySelected" && settingsObj.PRESETS[i][all] === true){
+ if(settingsObj.PRESETS[i].hasOwnProperty("datasetNameObj")){
+ DATASETNAMEFIELDS_current = clone(settingsObj.PRESETS[i].datasetNameObj);
+ }
+ if(settingsObj.PRESETS[i].hasOwnProperty("enabledVisibilityKeyNames")){
+ var currentlyEnabledVisKeyNames = settingsObj.PRESETS[i].enabledVisibilityKeyNames;
+ var currentlyAvailableVisKeyNames = getSpecificPropertyListObj(VisibilityKeys, "name");
+ var areAllEnabledNamesPresent = true;
+ // check if all currently loaded visibility keys contain all of the enabled names from the preset
+ // remove any which were not found
+ for (var j = currentlyEnabledVisKeyNames.length - 1; j > -1; j--) {
+ if(currentlyAvailableVisKeyNames.indexOf(currentlyEnabledVisKeyNames[j]) == -1){
+ currentlyEnabledVisKeyNames.splice(j, 1);
+ areAllEnabledNamesPresent = false; // a flag for any purpose
+ }
+ }
+ DATASETNAMEFIELDS_current = clone(settingsObj.PRESETS[i].datasetNameObj);
+ }
+ }
+ } else {
+ tempObj[all] = PRESETS[0][all];
+ }
+ }
+ PRESETS[i] = tempObj;
+ }
+ }
+ if(settingsObj.hasOwnProperty("lastChosenDataFilePath") && VI_MEMORY_SETTINGS.lastChosenDataFilePath == ""){
+ VI_MEMORY_SETTINGS.lastChosenDataFilePath = settingsObj["lastChosenDataFilePath"];
+ }
+ // if the settings file contains no custom increments, defaults will be used anyway
+ if(settingsObj.hasOwnProperty("CUSTOM_INCREMENTS") && settingsObj.CUSTOM_INCREMENTS.length > 0){
+ var customIncrementsAreAllValid = true, currentSettingsCustomInc;
+ for (var i = 0; i < settingsObj["CUSTOM_INCREMENTS"]; i++) {
+ currentSettingsCustomInc = settingsObj["CUSTOM_INCREMENTS"][i];
+ for(var all in CUSTOM_INCREMENTS[0]){ // CUSTOM_INCREMENTS in the objects must always have the default value(s)
+ if(!currentSettingsCustomInc.hasOwnProperty(all)){
+ scriptAlert("Problem reading custom increment information from the settings file. Defaulting to script-defaults for custom increments.");
+ customIncrementsAreAllValid = false;
+ break;
+ }
+ }
+ }
+ if(customIncrementsAreAllValid){
+ CUSTOM_INCREMENTS_current = settingsObj["CUSTOM_INCREMENTS"];
+ }
+ }
+ if(settingsObj.hasOwnProperty("WARNINGSETTINGS") && comparePropNames(settingsObj.WARNINGSETTINGS, WARNINGSETTINGS).resMsg == "All Found"){
+ WARNINGSETTINGS = settingsObj.WARNINGSETTINGS;
+ for(var all in WARNINGSETTINGS){
+ if(SETTINGS.hasOwnProperty(all)){
+ SETTINGS[all] = WARNINGSETTINGS[all];
+ }
+ }
+ }
+ } else {
+ PRESETS.getByName("default").datasetNameObj = DATASETNAMEFIELDS_current;
+ }
+
+ this.currentLoadedPresetName = getCurrentlySelectedPresetName();
+ this.multiColumnListBoxTest = (this.os == "Windows" || this.AIVersion != 16) ? true : false;
+ this.tabbedGroupTest = (this.AIVersion > 13) ? true : false;
+ // ScriptUI tabbedpanel was unavailable in Illustrator CS3
+ }
+};
+
+var PresetDialogPurposes = {
+ Add : {
+ resultAction : function(presetDialogResult, UIElements, listBox){
+ SESSION.currentLoadedPresetName = presetDialogResult.presetName;
+ PRESETS.addItem(PRESETS.getByName("default"), SESSION.currentLoadedPresetName);
+ updateScriptDataFromUI(UIElements);
+ UIElements.saved = (UIElements["disp_dataFile"].getValue() != "");
+ populateUI(UIElements);
+ refreshPresetListbox(listBox);
+ },
+ presetDispEditable : true,
+ placeholderName : "New Preset",
+ actionButtonName : "Add",
+ showRemoveButton : false
+ },
+ Remove : {
+ resultAction : function(presetDialogResult, UIElements, listBox){
+ SESSION.currentLoadedPresetName = "default";
+ setCurrentlySelectedPresetName("default");
+ PRESETS.removeItemByName(presetDialogResult.presetName);
+ populateUI(UIElements, true);
+ refreshPresetListbox(listBox);
+ },
+ presetDispEditable : false,
+ placeholderName : "self",
+ actionButtonName : "Remove",
+ showRemoveButton : true
+ },
+ Activate : {
+ resultAction : function(presetDialogResult, UIElements){
+ var thisName = presetDialogResult.presetName;
+ var thisPreset = PRESETS.getByName(thisName);
+ SESSION.currentLoadedPresetName = thisName;
+ setCurrentlySelectedPresetName(thisName);
+ if(thisPreset.hasOwnProperty("datasetNameObj")){
+ DATASETNAMEFIELDS_current = clone(thisPreset.datasetNameObj);
+ }
+ // switchStackView(UIElements["stackGroup"], "variablesDisplay");
+ UIElements["variablesDisplayR"].notify("onClick");
+ populateUI(UIElements, true);
+ },
+ presetDispEditable : false,
+ placeholderName : "self",
+ actionButtonName : "Activate",
+ showRemoveButton : true
+ },
+ Update : {
+ resultAction : function(presetDialogResult, UIElements, listBox){
+ var oldName = presetDialogResult.oldName;
+ var newName = presetDialogResult.presetName;
+ if(PRESETS.getByName(newName) != null && oldName != newName){
+ if(!CONFIRMS["overwriteOtherExistingPreset"]( newName )){
+ return;
+ }
+ } else {
+ PRESETS.getByName(oldName).name = newName;
+ }
+ SESSION.currentLoadedPresetName = newName;
+ setCurrentlySelectedPresetName(newName);
+ updateScriptDataFromUI(UIElements, newName);
+ populateUI(UIElements);
+ refreshPresetListbox(listBox);
+ },
+ presetDispEditable : true,
+ placeholderName : "self",
+ actionButtonName : "Update",
+ showRemoveButton : false,
+ oldName : ""
+ }
+};
+
+if(typeof(VI_MEMORY_SETTINGS) == "undefined"){
+ VI_MEMORY_SETTINGS = {
+ "lastChosenDataFilePath" : ""
+ };
+}
+
+var PRESETS = [
+ {
+ name : "default",
+ useHeaders : true,
+ currentlySelected : true,
+ transpose : false,
+ dbslNextline : false,
+ keepXML : false,
+ xmlPath : "temp",
+ selectedAutobinding : 'bindByName',
+ prependToAllImages : false,
+ prependImagePath : '',
+ prependToAllGraphs : false,
+ prependGraphPath : '',
+ datasetNameObj : {},
+ enabledVisibilityKeyNames : [
+ "True",
+ "False",
+ "On",
+ "Off",
+ // "One",
+ // "Zero",
+ ]
+ }
+];
+
+PRESETS.getByName = function(value){
+ var item;
+ for(var i = 0; i < this.length; i++){
+ item = this[i];
+ if(item.hasOwnProperty("name")){
+ if(item.name == value){
+ return item;
+ }
+ }
+ }
+ return null;
+};
+
+PRESETS.getAllNames = function(){
+ var namesArr = [];
+ var item;
+ for(var i = 0; i < this.length; i++){
+ item = this[i];
+ if(item.hasOwnProperty("name")){
+ namesArr.push(item.name);
+ }
+ }
+ return namesArr;
+};
+
+PRESETS.removeItemByName = function(name){
+ var item;
+ for(var i = 0; i < this.length; i++){
+ item = this[i];
+ if(item.hasOwnProperty("name") && item.name == name){
+ this.splice(i, 1);
+ break;
+ }
+ }
+};
+
+PRESETS.addItem = function(cloneObj, newName){
+ if(this.getByName(newName) != null){
+ var conf = confirm("This preset '" + newName + "' already exists, overwrite?");
+ if(!conf){
+ return;
+ }
+ this.removeItemByName(newName);
+ }
+ var obj = {};
+ for(var all in cloneObj){
+ obj[all] = cloneObj[all];
+ }
+ obj.name = newName;
+ this.push(obj);
+ var thisObj;
+ for(var i = 0; i < this.length; i++){
+ thisObj = this[i];
+ if(thisObj.name != newName){
+ thisObj.currentlySelected = false;
+ } else {
+ thisObj.currentlySelected = true;
+ }
+ }
+};
+
+var CUSTOM_INCREMENTS = [
+ { // generic examples & naming-convention idea.
+ name : "s0p3i1",
+ startNum : 0,
+ padZero : 3,
+ increment : 1,
+ isIntervalIncrement: false
+ },
+ {
+ name : "s1p2i1",
+ startNum : 1,
+ padZero : 2,
+ increment : 1,
+ isIntervalIncrement: false
+ },
+ {
+ name : "s1p2i10-interval",
+ startNum : 1,
+ padZero : 3,
+ increment : 10,
+ isIntervalIncrement: true
+ }
+];
+
+var WARNINGSETTINGS = {
+ showDatasetNamingWarning : true,
+ showExistingVariablesWarning : true,
+ confirmRemovalOfPresets : true,
+ confirmUpdatingOfPresets : true,
+ showSuccessfulSettingsFileSaves : true
+};
+
+var CONFIRMS = {
+ showDatasetNamingWarning : function(){
+ if(WARNINGSETTINGS["showDatasetNamingWarning"] == true){
+ return confirm("This data import has been defaulted to generic dataset names. Continue import?");
+ }
+ return true;
+ },
+ showExistingVariablesWarning : function( numVars ){
+ if(WARNINGSETTINGS["showExistingVariablesWarning"] == true){
+ return confirm("This document already contains " + numVars + " variable" + ((numVars > 1) ? "s" : "") +
+ " which may be overwritten. Continue import?");
+ }
+ return true;
+ },
+ confirmRemovalOfPresets : function(presetName){
+ if(WARNINGSETTINGS["confirmRemovalOfPresets"] == true){
+ return confirm("Remove Preset '" + presetName + "' ?");
+ }
+ return true;
+ },
+ confirmUpdatingOfPresets : function(presetName){
+ if(WARNINGSETTINGS["confirmUpdatingOfPresets"] == true){
+ return confirm("Update Preset '" + presetName + "' ?");
+ }
+ return true;
+ },
+ overwriteOtherExistingPreset : function(presetName){
+ if(WARNINGSETTINGS["confirmUpdatingOfPresets"] == true){
+ return confirm("Overwrite Preset '" + presetName + "' ?");
+ }
+ return true;
+ }
+};
+
+var SETTINGS = {
+ useHeaders : true,
+ transpose : false,
+ dbslNextline : false,
+ keepXML : false,
+ xmlPath : "",
+ selectedAutobinding : "noAutoBinding",
+ prependToAllImages : false,
+ prependImagePath : "",
+ prependToAllGraphs : false,
+ prependGraphPath : "",
+ getDataXMLDestination : function(){
+ return File(Folder.desktop + "/VariableImporterData_" + new Date().getTime() + ".xml");
+ },
+ incrementStartNumber : 1
+};
+
+var DATASETNAMEFIELDS = {
+ field_1 : {
+ type : "customText",
+ text : "Record"
+ },
+ field_2 : {
+ type : "dash",
+ text : "-"
+ },
+ field_3 : {
+ type : "increment",
+ text : "INC"
+ },
+ field_4 : {
+ type : "nothing",
+ text : ""
+ },
+ field_5 : {
+ type : "nothing",
+ text : ""
+ },
+ field_6 : {
+ type : "nothing",
+ text : ""
+ }
+};
+
+var FIELDNAMEOPTIONS = {
+ customText : {
+ defaultText : "[Edit Text]",
+ displayText : "Custom Text",
+ type : "customText"
+ },
+ dash : {
+ defaultText : "-",
+ displayText : "Dash",
+ type : "dash"
+ },
+ nothing : {
+ defaultText : "",
+ displayText : "Nothing",
+ type : "nothing"
+ },
+ space : {
+ defaultText : " ",
+ displayText : "Space",
+ type : "space"
+ },
+ increment : {
+ defaultText : "INC",
+ displayText : "Increment",
+ type : "increment"
+ },
+ underscore : {
+ defaultText : "_",
+ displayText : "Underscore",
+ type : "underscore"
+ },
+ customIncrement : {
+ defaultText : "",
+ displayText : "Custom Increment",
+ type : "customIncrement"
+ },
+};
+
+var DATASETNAMEFIELDS_current = clone(DATASETNAMEFIELDS);
+var FIELDNAMEOPTIONS_current = clone(FIELDNAMEOPTIONS);
+var CUSTOM_INCREMENTS_current = clone(CUSTOM_INCREMENTS);
+
+var VARTYPES = {
+ "Text" : {
+ key : "",
+ type : "Text",
+ itemKind : "TextFrame",
+ trait : "textcontent",
+ category : "&ns_flows;",
+ varKind : "VariableKind.TEXTUAL",
+ contentKind : "contentVariable"
+ },
+ "Visibility" : {
+ key : "#",
+ type : "Visibility",
+ itemKind : "All",
+ trait : "visibility",
+ category : "&ns_vars;",
+ varKind : "VariableKind.VISIBILITY",
+ contentKind : "visibilityVariable"
+ },
+ "Image" : {
+ key : "@",
+ type : "Image",
+ itemKind : "PlacedItem",
+ trait : "fileref",
+ category : "&ns_vars;",
+ varKind : "VariableKind.IMAGE",
+ contentKind : "contentVariable"
+ },
+ "Graph" : {
+ key : "%",
+ type : "Graph",
+ itemKind : "GraphItem",
+ trait : "graphdata",
+ category : "&ns_graphs;",
+ varKind : "VariableKind.GRAPH",
+ contentKind : "contentVariable"
+ }
+};
+
+var UI_SIZING = {
+ variableDisplay : {
+ small : {
+ varAmt : "1-8",
+ height : 150
+ },
+ medium : {
+ varAmt : "9-15",
+ height : 300
+ },
+ large : {
+ varAmt : "16-Infinity",
+ height : 500
+ }
+ },
+ bindingTestDisplay : {
+ preferredSize : [430, 300]
+ },
+ foundOfTotalDisp : {
+ // those inputs which show found/total numbers of file references
+ characters : 12
+ },
+ sizeSpecs : {
+ platforms : {
+ Windows : {
+
+ },
+ Mac : {
+
+ }
+ }
+ },
+ panelWidth_1 : 466,
+ init : function(){
+
+ }
+};
+
+var DATA = {
+ grid : [],
+ transposedGrid : [],
+ currentSourceFile : "",
+ currentVars : [
+ /*{
+ varName : "Variable1",
+ varType : "Text",
+ url : "",
+ varIndex : 0
+ }*/
+ ],
+ oldVars : [],
+ testVariableName : function(oldName, newName){
+ var msg = "", allVarNames = getSpecificPropertyListArr(DATA.currentVars, "varName");
+ if( !isXMLTagName(newName) ){
+ msg = "The '" + newName + "' variable name doesn't not follow the proper XML syntax:\n" + INFO.xmlRequirements;
+ scriptAlert(msg);
+ return false;
+ } else {
+ if(checkForSingleDuplicate(allVarNames, newName).length > 0 && oldName != newName){
+ msg = "The '" + newName + "' variable name already exists among imported variable names.";
+ scriptAlert(msg);
+ return false;
+ }
+ }
+ return true;
+ },
+ testNameProp_unique : function(argsObj){
+ // argsObj = {collection : [], prop : "varName", prefixString : "Variable", collectionName : "Variables", showDialog : true}
+ var badArr = [], namesArr, msg;
+ namesArr = (typeof argsObj.prop == "string") ? getSpecificPropertyListArr(argsObj.collection, argsObj.prop) : argsObj.collection;
+
+ badArr = arrayGetUniqueDuplicates(namesArr);
+ if(badArr.length > 0){
+
+ msg = "The following " + argsObj.collectionName + " name(s) are found more than once\n" +
+ "(All " + argsObj.collectionName + " names are going to be Auto-replaced):" +
+ "\n--------------------------------------\n" + (badArr).join("\n");
+ if(argsObj.showDialog){
+ quickView(msg, argsObj.collectionName + " Names Correction", [400, 550]);
+ }
+ this.genericize(argsObj.collection, argsObj.prop, argsObj.prefixString);
+ return false;
+ }
+ return true;
+ },
+ testVarNames_xml : function(){
+ var badArr = [], thisVar, msg;
+ for (var i = 0; i < this.currentVars.length; i++) {
+ thisVar = this.currentVars[i];
+ if( !isXMLTagName(thisVar.varName) ){
+ badArr.push(thisVar.varName);
+ }
+ }
+ if(badArr.length > 0){
+
+ msg = "Proper XML Syntax isn't followed by some variable name(s)\n" + INFO.xmlRequirements + "\n" +
+ "(All names are going to be Auto-replaced):\n--------------------------------------\n" + (badArr).join("\n");
+
+ quickView(msg, "Variable Name Correction", [400, 550]);
+ this.genericize(this.currentVars, "varName", "Variable");
+ return false;
+ } else {
+ return true;
+ }
+ },
+ genericize : function(collection, prop, prefixString){
+ if(typeof prop == "undefined"){
+ for (var i = 0; i < collection.length; i++) {
+ collection[i] = prefixString + (i + 1);
+ }
+ } else {
+ for (var i = 0; i < collection.length; i++) {
+ collection[i][prop] = prefixString + (i + 1);
+ }
+ }
+ },
+ getCurrentVars : function(UIElements){
+ if(this.currentSourceFile == "" || this.grid.length == 0){
+ return null;
+ }
+ this.oldVars = [];
+
+ if(typeof UIElements != 'undefined' && UIElements["variableDisplay"].items.length > 0){
+ for(var i = 0; i < DATA.currentVars.length; i++){
+ if(i < DATA.currentVars.length){
+ this.oldVars.push(DATA.currentVars[i]);
+ }
+ }
+ }
+ var data = (SETTINGS.transpose) ? this.transposedGrid : this.grid;
+ this.currentVars = [];
+ var varName = "", varType = "", datum = "", thisUrl;
+ for(var i = 0; i < data[0].length; i++){
+ // header row is variable names
+ datum = data[0][i];
+ varName = (SETTINGS.useHeaders) ? datum.replace(/^[@#%]/, "") : "Variable" + (i + 1);
+ varType = (SETTINGS.useHeaders) ? getVariableType(datum) : "Text";
+ thisUrl = "";
+ if(varType == "Image" || varType == "Graph"){
+ if(SETTINGS["prependToAll" + varType + "s"]){
+ thisUrl = SETTINGS["prepend" + varType + "Path"];
+ }
+ }
+
+ this.currentVars.push({
+ varIndex : i,
+ varName : varName,
+ varType : varType,
+ useUrl : true,
+ url : thisUrl
+ });
+ }
+ // go through variable names and make sure they follow xml syntax, if they all do, then make sure they're unique also
+ // any failure will cause genericizing
+ if(this.testVarNames_xml()){
+ this.testNameProp_unique({
+ collection : this.currentVars,
+ prop : "varName",
+ prefixString : "Variable",
+ collectionName : "Variable",
+ showDialog : true
+ });
+ }
+ },
+ getVariableNames : function(){
+ if(this.currentVars.length > 0){
+ return getSpecificPropertyListArr(this.currentVars, "varName");
+ }
+ return [];
+ },
+ currentGrid : [],
+ currentDatasetNames : [],
+ getCurrentGrid : function(){
+ if(this.currentVars.length == 0){
+ return [];
+ }
+ var data = (!SETTINGS.transpose) ? this.grid : this.transposedGrid;
+ var start = (!SETTINGS.useHeaders) ? 0 : 1;
+ var row, cell, arr = [], rowArr = [], thisVar, dsnArr = [];
+ for (var i = start; i < data.length; i++) {
+ row = data[i];
+ rowArr = [];
+ dsnArr.push(getRecordDatasetName(DATASETNAMEFIELDS_current, row, i - start));
+ for (var j = 0; j < row.length; j++) {
+ cell = row[j];
+ thisVar = this.currentVars[j];
+ if(thisVar.url != "" && (thisVar.varType == "Image" || thisVar.varType == "Graph")){
+ cell = getPrependPathValue(thisVar, cell);
+ }
+ rowArr.push(cell);
+ };
+ arr.push(rowArr);
+ };
+ this.currentGrid = arr;
+
+ this.currentDatasetNames = dsnArr;
+ // untested for uniqueness at this point.
+ },
+ getTestDatasetNames : function(dsNameFieldObj){
+ if(this.currentVars.length == 0){
+ return [];
+ }
+ var data = (!SETTINGS.transpose) ? this.grid : this.transposedGrid;
+ var start = (!SETTINGS.useHeaders) ? 0 : 1;
+ var row, dsnArr = [];
+ for (var i = start; i < data.length; i++) {
+ row = data[i];
+ dsnArr.push(getRecordDatasetName(dsNameFieldObj, row, i - start));
+ };
+
+ // make sure dataset names are unique, or else they get genericized
+ // already done when getting currentGrid, omit dialog
+ this.testNameProp_unique({
+ collection : dsnArr,
+ prop : undefined,
+ prefixString : "Record ",
+ collectionName : "Dataset",
+ showDialog : WARNINGSETTINGS["showDatasetNamingWarning"]
+ });
+
+ return dsnArr;
+ }
+};
+
+var AUTOBINDING = {
+ noAutoBinding : {
+ type : "noAutoBinding",
+ text : "No Auto Binding",
+ getProp : function(item){
+ return "N/A";
+ }
+ },
+ bindByName : {
+ type : "bindByName",
+ text : "Bind By Name",
+ getProp : function(item){
+ return item["name"];
+ }
+ },
+ bindByNote : {
+ type : "bindByNote",
+ text : "Bind By Note",
+ getProp : function(item){
+ return item["note"];
+ }
+ },
+ bindByTag : {
+ type : "bindByTag",
+ text : "Bind By Tag",
+ preferredTagName : "VariableImporterBinding",
+ getProp : function(item){
+ if(item.tags.length > 0){
+ return getSpecificPropertyListArr(item.tags, "name");
+ } else {
+ return [];
+ }
+ }
+ }
+};
+
+//visibility keys are tested against lower-case cell data
+var VisibilityKeys = [
+ {
+ displayText : "true",
+ name : "True",
+ value : true,
+ enabled : true
+ },
+ {
+ displayText : "false",
+ name : "False",
+ value : false,
+ enabled : true
+ },
+ {
+ displayText : "on",
+ name : "On",
+ value : true,
+ enabled : true
+ },
+ {
+ displayText : "off",
+ name : "Off",
+ value : false,
+ enabled : true
+ },
+ {
+ displayText : "1",
+ name : "One",
+ value : true,
+ enabled : false
+ },
+ {
+ displayText : "0",
+ name : "Zero",
+ value : false,
+ enabled : false
+ }
+];
+
+var ICONS = {
+ "Visibility" : "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\b\x02\x00\x00\x00\x02\u00EB\u008AZ\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\u00C9e<\x00\x00\x01?IDATx\u00DAb\u00FC\u00FF\u00FF?\x03\u00B9\u0080qT3\x14|\u00F8\u00F0\u00E1\u00C2\u0085\x0Bp\u00AE\u0081\u0081\u0081\u0080\u0080\x00a\u00CD\x0B\x16,\u00988q\"P\u00A9\u008E\u00A9\u00C5\u0091\u00FB/\u00B9X\u0099\u008DdD\u008E\u00EC\u00DE\x01\u0094\u00CA\u00CF\u00CFOHH\u00C0\u00AEy\u00C3\u0086\r\u008D\u008D\u008D\u00FE\u00FE\u00FE@\x15L\x02\"\u00E7\u009F\u00BE\x05j~\u00F3\u00F5\x07P*\u00D9L]\u0086\u00F1;\u00D0\u00DC\u008D\x1B7\u00D6\u00D7\u00D7\x07\x04\x04@u\x035\u00BF\x7F\u00FF\x1E\u00A8\x01(t\u00FF\u00FE} \u00F7\u00F5\u0097\u00EF\x1B\u00AE<\x002z\u00A6\u00CEP\u00B1\u00F7\u0088\u009A\u00B75a\u00C5A\u00A0 P\x04\u00A8\u00C0\u00C1\u00C1\x01\u00A8\x18\u00A8\x05d+\u0090\x02z\u00A9\u00BF\u00BF\u00FF?\f\u00EC\u00BC\u00F9\u00A4d\u00F3I\u00A0N\u0088?\u0081\u00FA\u0081\u009A\u00D7_~\x00W\x00T\f\u00D4\x02\u00D4\u00C8\u0082\x19\f\u00DF~\u00FD\x01\u00BAv\u00C3\u00AA\r\u00C0`\u0083\x0Br\u00B1aQ\u00C9\x044~\u00FF\u00FE\u00FD\x17/^ttt|\u00F0\u00E0\x01P\u00C8FQ\x1CH\u009A\u00C5\u00E7\x02\u00ED\x04\" \x03\u00C85\u0092\x16\x06\u0092@\x05\u0081\u0081\u0081@\u00C5@-@\u008D\u00D8\x03\u00EC\u00C9\x7F\u00CE\u00B9\u00A7n\u00C2m\u00C0\x15`\u00D8\u00A3\nd\u00BF\u00AB\u00C7\u00B9'o\u00BE\u00FD\u00FE\x0Bt\u00C8\u0095\u00D3'\u0080^\u00C0\x17UTH$\u00A3Y\u0092\x00\x00\b0\x00\u009C \u00F4D\u0080v\u00BF\u00C6\x00\x00\x00\x00IEND\u00AEB`\u0082",
+ "Image" : "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\b\x02\x00\x00\x00\x02\u00EB\u008AZ\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\u00C9e<\x00\x00\x01\x7FIDATx\u00DAb\u009C\u009B\u00CF@6`b\u00A0\x00\u00B0@(\u00A5\t_H\u00D2v\u00AF\u0080\x07\u00C5fY\u0086j=\x06mm\x06\x0B\x1E\u0086\u00D3\u00C8\u00EA\u0098\x19\u00FE\x13v\u00B6 \u00C3\x06\u00B0\u00D2\u00CF\u00E2\fS\u0091\x04\u00BF\x0B}~y\u00E1\u00D2\u00EB\u009F?\u00FF\u00E2\u00D3\u00FC\u0097\u0081\x17\u00C2\u00F8\u00C5 \r\x17\u00E4\u00FB\u00FB\u00ED\u00E7\x1F\x06y\u00DE\u00BF\u009F>\u00FF\u00C2\u00E9g\u00907\x18\x16\u00883L\u00FB\u00C5 \u00F5\u0092!\x1B\"\u00F2\u00E3\u00F3w&\u00B6\u00DF@\u00C6\u00F3\u00CF\f\x7F\u00BF}\u00E3\u00E6b\u00E5\u00E2b\u00C1\u00AE\u00F9;\u0083\u00C6\x03\u0086Ip\u00EE\u00EB7\u00DFY>\x7F\u00E4Ud\u00E0eg\u00D8}\x07(\u00F0\u00FB\u00DA\u008DwZ\x1AB\u00C8\u00FAY\u00B0\u0086\x04P\u00E7\u00BD\u00FB\x1F!la.\u0098\u00BF\u00FE\u00FE\u00BB{\u00FF#P?33#>\u00CDJ\\?\u00CD\u00F4\x18~\u00FDe\u00B8\u00F5\x06\u00AA\x19H\u00BE\u00FD\u00C6\u00F0\u00ED\u00DB\u00EFO\u009F~\t\n\u00B2\u00A3h.L\u00E5@\u00D6l\u00A4\u00CE\u00DF]\u00F2\u00E3\u00CAK\u0084f6f\u0090\u00FB\x1F=ci\u009A\u00C5\x0F\u00E4\u00E6r#i\u00BEp\u0086\x19Y\u00F3\u00853<5\u00E9\u00AF\u009F\x7F\u00FE\x07\u00D4\t4\x02\x12f@p\u00ED\x027T\u00A5=\u00DE\u00E4\u00B9|\x13\u00AF\u00AB\n\u0083\u008F\x06\u0083\u00A5\x1CB\u00F0\u00C8\x1E\x01\u00A2\u00D2\u00F6\u00F2\u00CD\u00BCh\"\u00CF\x1F\u00B3\u00BF\x7F\u00CBB\u0094\u00E6+7\u00D9\u0081\bY\u00E4\u00C8^~\u009C\u0089\x04\x13\u00D8G\u00C8x9~57\u00FB\u00BA\u00FB\f\u00FB\u00D5\x0B\u00DCh\u00D6\x12\u00D0\f\x04\u00DB\u00F6s\x03\x11-\u00F3\u00F3\\{Fz\u0097$\x00\x01\x06\x00<\u00E3\u0084d\u0089\u00F2\x1C;\x00\x00\x00\x00IEND\u00AEB`\u0082",
+ "Graph" : "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\b\x02\x00\x00\x00\x02\u00EB\u008AZ\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\u00C9e<\x00\x00\x01\u00FDIDATx\u00DAbd``\u00F8\u00FF\u00FF?\x03\u00E9\u0080\u0091\u0091\u0091\x05H\u009D={\u0096\u0081,\u00C0H\u0089\u00CDL\f\x14\x00,\u00CE\u00E6z\u00FC\x14\u00C2\u00F8\u00CB\u00CE\u00FESL\u0084\u0080\x01\u00FFQ\u00C1Au]\x0F~\u00C1J\t\u0099\u008B\u00B1I\u00FFq\x03\u00A0F\u00EC\u00CE\u00DE\u00F1\u00F1\u00FD\u00E1/\u009F\b:\x1B\u008B\u00E6\x0B\u00DF\u00BE&\u008A\u0088\u00F303\x13\u00E5\u00E7\x07\u0093\u00B6\n\x1F}\x0E\u00E1?\u0089T]\u00FD\u00FEM\u00AB\u00B4\u00FC\u0082\u00B7\u00AFn\u00BF\x7F\u00FB\x1B)8\u00B8\x7F>Vz\u00B9\u00FC\u00F0\u00ED\u009F\x0F\u00DF\u00FD\u00D9s\x07\u00A6Y\u00FC/\u00C7\u00F7\x13\u00F7 *\u0096~<\x1C*\b\n$\x0F>\u0081#\u00FF\u00FE\x04\x1B\x1B\u00C35\u00FF{\u00FA{\u00CF\u00CA\u0083\u00EE\u0093^\u00C6\u009As/\u009A\u00D4\u00BC|\u00EDV\x14g?\u00FA\u00F3\u00F1\u008B4\u00A7\x01\x177\u0090-\u00C1\u00CAv\u00E7\u00D2e4w\x02\u00ED\x04\u00EA\u00CCq\u00E0E\u00F8\u00F9\u00D5\u00ABW\x10N\u00D7\u00C7\u00C3\u0099\u00FE\u00D1p\u00A5N\x1C\u00DC\u0093'O~\x06\x03w\u009F\u00BC:|\u00FB\u00C7\u00AC\x18a=\x19\u00B6\u00CF\u009F\u00BF@5\u00D7\u00EE[x\u00E5\u00D7\u00CB\u00E5_/\u00EB\u00B0\u0089\u00F33q\u00C05\u00DB\x18\x1B\x1DS/N5Y\x16~4O\u00F2;\u0084~<\u00B0\x1A\u00C8x9\u00BF1<\u00BF\nKT=\x7F\u00FE\u00DC\u009A]\u00CEZT\x0E\u00C8\u00BE}\u00EB\x16\\\u00EE\u00F3\u00E7O/?}\x051N\u00EF\u00E45s\u0083\u00B0!\x00\u00A8\x05j\u00B3\u00A4\u00A4$\\TUM\r\u00CE\u00E6\u00E5\u00E5\u0093\u0092\u0094\u00FC\u00FB\u00F5\u00D3\u0093\u00AET.mKde\x106\x0B\u00C1d\x04\u00B4\u00F3\u00DF\u00D7OL\\|\f\f\u00AF\u00B18\u009B\u0080fSw \x023_c)\f\u00E4X\u00F8\u00E1Au\u00E5\u00D7+E\x0Eh\u00AA\u00FE\u00F2\u00F7\u00EFC>\x11V1Y\b\u0097\u00E3\u00E5u\x1D\u00C1\x1F\u00D0\u00D4\u00F2\u00F6\x0F0\u00C1\x00\x04\x18\x00b\u00C8\u00EF\x17\u00C9\u00FD\u009FL\x00\x00\x00\x00IEND\u00AEB`\u0082",
+ "Text" : "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\b\x02\x00\x00\x00\x02\u00EB\u008AZ\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\u00C9e<\x00\x00\x00\u00B1IDATx\u00DAb\u00FC\u00FF\u00FF?\x03\u00B9\u0080\x05\u0088/\\\u00B8\u00F0\u00E1\u00C3\x07\u0092\u00B4\t\b\b\x18\x18\x180\x00mvpp \u00D5N\u00A0\x16\u00A0F&\x06\n\x00\x0B\u00B2a\u00C8\x12\x0F\u00C0\x00\u00C8P\x00\x03d\u00A9\x03\x07\x0E@Ypg\u00FFG\x05\u00F5\u00F5\u00F5\x10\x05@\x06\u009A\x14\u00F5\u009C\u00DD\u00DF\u00DFORh\u00EF\u00DF\u00BF\x1F\x18\u00DAP\u00CD\u00A0@'1\u00A8!\f\u008A\u009C=\u00AA\u0099Z\u009A\x1F>|\u0088\u00C6\u00C0\u0097\u00B6\u0081\x00\u0098T\u0080\u00D9\x13\u00C8\u00D8\u00B8q\u00E3\u0082\x05\x0B \u0082@\x060I\u00F8\u00FB\u00FBCR\x04$y \u00D26\x1C\x00\u0093\x0E\u00C1\u00B4\u0085\u00AC\u009E\x11\u00B9$\u0081\u00DB\u008C\x0B\u00A0\u00D9\u00CCHI1\x04\x10`\x00\u00C5_\u0084\u00C3\u008F\u00CF\u00D1\u009F\x00\x00\x00\x00IEND\u00AEB`\u0082"
+};
+
+var INFO = {
+ xmlRequirements : "1) Element names are case-sensitive" + "\n" +
+ "2) Element names must start with a letter or underscore" + "\n" +
+ "3) Element names cannot start with the letters xml (or XML, or Xml, etc)" + "\n" +
+ "4) Element names can contain letters, digits, hyphens, underscores, and periods" + "\n" +
+ "5) Element names cannot contain spaces"
+};
+
+SESSION.init(); //---------------------------------------------------------------------------------------------------- INIT SESSION
+
+
+
+//==================================================================================//
+
+//================================= OBJECTS PT 2 ===================================//
+
+var DocumentBinding = {
+ // names of variables are expected to be unique, but art identifying properties (.name , .note and .tags.tag) are not.
+ artItems : {},
+ namedArtCollection : [],
+ getNamedBinds : function(doc){
+ if(DATA.currentVars.length == 0){
+ return null;
+ }
+ this.artItems = {};
+ this.namedArtCollection = this.getAllDocumentNamedItems(doc, AUTOBINDING[SETTINGS.selectedAutobinding]);
+ var varNames = DATA.getVariableNames(),
+ varTypes = getSpecificPropertyListArr(DATA.currentVars, "varType"),
+ newVarBindObj;
+ for (var i = 0; i < varNames.length; i++) {
+ newVarBindObj = {};
+ if(SETTINGS.selectedAutobinding == "noAutoBinding"){
+ newVarBindObj.bindCollection = [];
+ } else {
+ newVarBindObj.bindCollection = this.getSortedNamedItems(
+ this.namedArtCollection,
+ varNames[i],
+ varTypes[i],
+ AUTOBINDING[SETTINGS.selectedAutobinding]
+ );
+ }
+ newVarBindObj.varType = varTypes[i];
+ this.artItems[varNames[i]] = newVarBindObj;
+ };
+ },
+ getAllDocumentNamedItems : function(doc, method){
+ var arr = [], testProp, thisItem;
+ for (var i = 0; i < doc.pageItems.length; i++) {
+ thisItem = doc.pageItems[i];
+ testProp = method.getProp(thisItem);
+ if(testProp instanceof Array && testProp.length > 0){
+ // dealing with tag
+ arr.push( thisItem );
+ } else if(typeof testProp == "string" && testProp != ""){
+ arr.push( thisItem );
+ }
+ }
+ return arr;
+ },
+ getSortedNamedItems : function(collection, varName, varType, method){
+ var arr = [], thisItem, testProp, testTag;
+ for (var i = 0; i < collection.length; i++) {
+ thisItem = collection[i];
+ if(thisItem.typename == VARTYPES[varType].itemKind || VARTYPES[varType].itemKind == "All"){
+ testProp = method.getProp(thisItem);
+ if(testProp instanceof Array && testProp.length > 0){
+ // dealing with tag
+ if(testProp.indexOf(varName) > -1){
+ arr.push( thisItem ); // get item if tag's name matches the variable's name
+ } else {
+ try {
+ testTag = thisItem.tags.getByName(method.preferredTagName);
+ if(testTag.value == varName){
+ arr.push( thisItem ); // get item if tag's name is "VariableImporterBinding" and value matches variable's name
+ }
+ } catch(e){
+
+ }
+ };
+ } else if(typeof testProp == "string" && testProp == varName){
+ arr.push( thisItem );
+ }
+ }
+ };
+ return arr;
+ },
+ getBindObjectTestResults : function(){
+ var artItemNames = getPropertyList(this.artItems);
+ if(artItemNames.length == 0){
+ return null;
+ }
+ var res = {
+ log : "",
+ countTextVars : 0,
+ foundTextItems : 0,
+ countImageVars : 0,
+ foundImageItems : 0,
+ countGraphVars : 0,
+ foundGraphItems : 0,
+ countVisibilityVars : 0,
+ foundVisibilityItems : 0
+ };
+
+ var arrLog = ["Autobinding method: " + unCamelCaseSplit(SETTINGS.selectedAutobinding) + "\n-------------------"];
+ var thisName, thisItem, thisVarObj, thisBindCollectionCount = 0, foundItemString = "", thisFoundProp, thisVarCountProp;
+ for (var i = 0; i < artItemNames.length; i++) {
+ thisName = artItemNames[i];
+ thisItem = this.artItems[thisName];
+ thisVarObj = getSpecificPropertyObj(DATA.currentVars, "varName", thisName);
+ thisBindCollectionCount = thisItem.bindCollection.length;
+ res["found" + thisVarObj.varType + "Items"] += thisBindCollectionCount;
+ res["count" + thisVarObj.varType + "Vars"] += 1;
+ arrLog.push(thisName + " : " + thisBindCollectionCount);
+ };
+
+ for(var all in VARTYPES){
+ thisFoundProp = "found" + all + "Items";
+ thisVarCountProp = "count" + all + "Vars";
+ foundItemString += (all + ": " + res[thisFoundProp] + "/" + res[thisVarCountProp] + ", ");
+ }
+
+ res.log = arrLog.join("\n");
+ res.foundItemString = foundItemString.replace(/,\s$/, "");
+
+ return res;
+ },
+ bindDocumentItems : function(doc){
+ this.getNamedBinds(doc);
+ var artItemNames = getPropertyList(this.artItems), artCollection, artItem, thisDocVar, thisContentKind, thisVarTypeObj;
+
+ var artItems = this.artItems, thisArtItemsVarName = "", currentSelection;
+ artItemNames.sort(function(a,b){
+ if(artItems[a].varType == "Visibility"){
+ return true;
+ } else {
+ return false;
+ }
+ });
+
+ if(artItemNames.length == 0){
+ return null;
+ }
+ for( var i = 0; i < artItemNames.length; i++ ){
+ thisArtItemsVarName = artItemNames[i];
+ thisDocVar = doc.variables.getByName(thisArtItemsVarName);
+ for( var that in VARTYPES ){
+ thisVarTypeObj = VARTYPES[that];
+ if(thisVarTypeObj.varKind == thisDocVar.kind){
+ thisContentKind = thisVarTypeObj.contentKind;
+ break;
+ }
+ }
+ artCollection = this.artItems[thisArtItemsVarName].bindCollection;
+ for (var j = 0; j < artCollection.length; j++) {
+ artItem = artCollection[j];
+ artItem[thisContentKind] = thisDocVar;
+ }
+ }
+ }
+};
+
+function FileTestSeeker(prop){
+ return {
+ makeUIContents : function(parent, propObj){
+ parent.spacing = 4;
+ var size;
+ if(typeof propObj.size == "undefined"){
+ size = [350, 200];
+ } else {
+ size = propObj.size;
+ }
+ var disp_foundMissingNum = parent.add("edittext { properties : {readonly : true}, justify : 'center' }");
+ disp_foundMissingNum.characters = UI_SIZING.foundOfTotalDisp.characters;
+
+ var foundNum = "", missingNum = "", parsedNums;
+ if(propObj.hasOwnProperty("foundMissingNum")){
+ disp_foundMissingNum.setValue(propObj.foundMissingNum);
+ parsedNums = propObj.foundMissingNum.split("/");
+ foundNum = parsedNums[0];
+ missingNum = parsedNums[1] - foundNum;
+ }
+ var lbl_foundImageFiles = parent.add("statictext", undefined, "Found " + prop + " Files: " + foundNum);
+ var foundList = parent.add("edittext", undefined, "", {readonly : true, multiline : true});
+ foundList.size = size;
+ if(propObj.hasOwnProperty("foundFiles")){
+ foundList.setValue(propObj.foundFiles);
+ }
+ var lbl_missingImageFiles = parent.add("statictext", undefined, "Missing " + prop + " Files: " + missingNum);
+ var missingList = parent.add("edittext", undefined, "", {readonly : true, multiline : true});
+ missingList.size = size;
+ if(propObj.hasOwnProperty("missingFiles")){
+ missingList.setValue(propObj.missingFiles);
+ }
+ return {
+ foundList : foundList,
+ missingList : missingList,
+ disp_foundMissingNum : disp_foundMissingNum
+ };
+ },
+ makeTab : function(parentTabbedPanel){
+ var tab = parentTabbedPanel.add("tab", undefined, prop + " Files");
+ tab.key = prop;
+
+ parentTabbedPanel.window.UITestElements["testTab" + prop] = tab;
+
+ tab.contents = this.makeUIContents(tab, {size : [515, 130]});
+
+ tab.populateFields = function(){
+ var allResults = getFileRefTestResults();
+ var thisRefResultNumFound = allResults["found" + prop + "s"].length - 1;
+ var thisRefResultNumMissing = allResults["missing" + prop + "s"].length - 1;
+ var foundFiles = allResults["found" + prop + "s"].slice(1).join("\n")
+ var missingFiles = allResults["missing" + prop + "s"].slice(1).join("\n")
+ var foundMissingNum = thisRefResultNumFound + "/" + (thisRefResultNumFound + thisRefResultNumMissing);
+ tab.contents.foundList.setValue(foundFiles);
+ tab.contents.missingList.setValue(missingFiles);
+ tab.contents.disp_foundMissingNum.setValue(foundMissingNum);
+ };
+ tab.resetFields = function(){
+ for(var all in this.contents){
+ this.contents[all].setValue("");
+ }
+ }
+ return tab;
+ }
+ }
+};
+
+//=============================================================================================================================================//
+//=============================================================== GRAPH DATA ==================================================================//
+//=============================================================================================================================================//
+var GraphDataGatherer = {
+ emptyGraphString : "" + "\r" +
+ "" + "\r" +
+ "" + "\r" +
+ "" + "\r" +
+ "1" + "\r" +
+ "
" + "\r" +
+ "" + "\r" +
+ "",
+ getGraphData : function( graphFilePath ){
+ var graphFile;
+ try {
+ graphFile = File(graphFilePath);
+ if(!graphFile.exists){
+ throw new Error("Graph File not found: '" + decodeURI(graphFilePath) + "'");
+ }
+ return this.getGraphDataFromFile(graphFile);
+ } catch (e) {
+ // alert(e);
+ return this.emptyGraphString;
+ }
+ },
+ isquoted : function (str) {
+ return str.charAt(0) === '"' && str.charAt(str.length - 1) === '"';
+ },
+ unquoted : function (str) {
+ if (str.charAt(0) === '"' && str.charAt(str.length - 1) === '"') {
+ return str.substring(1, str.length - 1);
+ }
+ else {
+ return str;
+ }
+ },
+ analyzeCellContent : function(cell){
+ var res = {
+ isQuoted : false,
+ isNumber : false,
+ isWord : false
+ };
+ var rxNum = /^-?\d*[\.]?\d+$/;
+ var rxWord = /[a-z]/gi;
+ res.isQuoted = (cell.charAt(0) === '"' && cell.charAt(cell.length - 1) === '"');
+ res.isNumber = (res.isQuoted && rxNum.test(cell.replace(/"/g, "")) || (!res.isQuoted && rxNum.test(cell)));
+ res.isWord = (!res.isNumber && rxWord.test(cell) || (!res.isQuoted && !res.isNumber));
+ return res;
+ },
+ getGraphDataFromFile : function( graphFile ){
+ var res = '', maxcol = 1, haspropertyrow = false, hasnamecol = false;
+ var col, row, numstr, myAnalyzedCell, thisCell;
+
+ var textData = getData( graphFile.fsName );
+
+ var i;
+ var rows = [], vals = [];
+ var name;
+ for ( i = 0; i < textData.length; i++) {
+ vals = textData[i];
+ if (vals.length > maxcol) {
+ maxcol = vals.length;
+ }
+ rows.push(vals);
+ }
+
+ numstr = 0;
+ for (col = 0; col < rows[0].length; col++) {
+ if (rows[0][col] === '') continue;
+ if (isNaN(rows[0][col])) numstr--;
+ else numstr++;
+ }
+ haspropertyrow = (numstr <= (col > 2 ? 0 : -1));
+
+ numstr = 0;
+ for (row = 0; row < rows.length; row++) {
+ if (rows[row][0] === '') continue;
+ if (isNaN(rows[row][0])) numstr--;
+ else numstr++;
+ }
+ hasnamecol = (numstr <= 0);
+
+ // create a string
+ res += '';
+ row = 0;
+ // propertyRow
+ if (haspropertyrow) {
+ res += '';
+ col = 0;
+ thisCell = rows[row][col];
+ if (hasnamecol) {
+ // res += '' : '>')
+ // + stringXmlSafe(this.unquoted(rows[row][col++])) + '';
+ myAnalyzedCell = this.analyzeCellContent(thisCell);
+
+ res += '' : '>') +
+ stringXmlSafe(this.unquoted(thisCell)) + '';
+
+ col++;
+ }
+ else {
+ res += '';
+ }
+ for (; col < rows[0].length; col++) {
+ // res += '' : '>')
+ // + stringXmlSafe(this.unquoted(rows[row][col])) + '';
+ thisCell = rows[row][col];
+ myAnalyzedCell = this.analyzeCellContent(thisCell);
+ res += '' : '>') +
+ stringXmlSafe(this.unquoted(thisCell)) + '';
+ }
+ for (; col < maxcol; col++) {
+ res += '';
+ }
+ res += '';
+ row++;
+ }
+ // values
+ res += '';
+ for (; row < rows.length; row++) {
+ res += '';
+ col = 0;
+ if (hasnamecol) {
+ // res += '' + stringXmlSafe(this.unquoted(rows[row][col++])) + '';
+ thisCell = rows[row][col];
+ myAnalyzedCell = this.analyzeCellContent(thisCell);
+ res += '' : '>') +
+ stringXmlSafe(this.unquoted(thisCell)) + '';
+
+ col++;
+ }
+ else {
+ res += '';
+ }
+ for (; col < rows[row].length; col++) {
+ res += '' : '>') +
+ stringXmlSafe(this.unquoted(rows[row][col])) + '';
+ }
+ for (; col < maxcol; col++) {
+ res += '';
+ }
+ res += '
';
+ }
+ res += '';
+ res += '';
+
+ return res;
+ }
+};
+
+var TestManager = {
+ datasetNames : {
+ makeUIContents : function(parent, propObj){
+ var list = parent.add("edittext", undefined, "", {readonly : true, multiline : true});
+ list.size = propObj.size;
+ if(propObj.hasOwnProperty("data")){
+ list.setValue(propObj.data);
+ }
+ return list;
+ },
+ makeTab : function(parentTabbedPanel){
+ var tab = parentTabbedPanel.add("tab", undefined, "Dataset Names");
+ var disp_preview = tab.add("edittext { properties : {readonly : true}, justify : 'center' }");
+ disp_preview.characters = 36;
+ var list = this.makeUIContents(tab, {size : [300, 300]});
+
+ tab.populateFields = function(){
+ // make sure dataset names are unique, or else they get genericized
+ DATA.testNameProp_unique({
+ collection : DATA.currentDatasetNames,
+ prop : undefined,
+ prefixString : "Record ",
+ collectionName : "Dataset",
+ showDialog : WARNINGSETTINGS["showDatasetNamingWarning"]
+ });
+ if(DATA.currentDatasetNames.length > 0){
+ list.setValue(DATA.currentDatasetNames.join("\n"));
+ disp_preview.setValue(getDatasetNamePreviewString());
+ }
+ };
+ tab.resetFields = function(){
+ list.setValue("");
+ disp_preview.setValue("");
+ }
+ return tab;
+ }
+ },
+ imageFiles : new FileTestSeeker("Image"),
+ graphFiles : new FileTestSeeker("Graph"),
+ artBindings : {
+ // simpleShowModal(DocumentBinding.displayTestList, {title : "Binding Test Display"});
+ makeUIContents : function(parent, propObj){
+ var listBox;
+ if(!SESSION.multiColumnListBoxTest){
+ // crazy CS6 Bug with multi-column listbox crash.
+ listProps = {};
+ } else {
+ listProps = (SESSION.imageTest)? {
+ // Embedded Image error 520
+ numberOfColumns: 4,
+ showHeaders: true,
+ columnTitles: ["Variable Name", "", "Type", "Found Items"],
+ columnWidths: [165, 25, 60, 80]
+ } : {
+ numberOfColumns: 3,
+ showHeaders: true,
+ columnTitles: ["Variable Name", "Type", "Found Items"],
+ columnWidths: [165, 60, 80]
+ };
+ }
+
+ listBox = parent.add("listbox", undefined, [], listProps);
+ listBox.preferredSize = propObj.size;
+ return listBox;
+ },
+ makeTab : function(parentTabbedPanel){
+ var tab = parentTabbedPanel.add("tab", undefined, "Art Bindings");
+ var disp_preview = tab.add("edittext { properties : {readonly : true}, justify : 'center' }");
+ disp_preview.characters = 52;
+ var list = this.makeUIContents(tab, {size : UI_SIZING.bindingTestDisplay.preferredSize});
+ tab.list = list;
+
+ tab.populateFields = function(){
+ // reset the list by clearing it out
+ list.removeAll();
+
+ var varType, varName, foundCount = 0, newItem, thisItem;
+
+ for (all in DocumentBinding.artItems) {
+ thisItem = DocumentBinding.artItems[all];
+ varType = thisItem.varType;
+ newItem = list.add("item");
+ varName = all;
+ newItem.text = varName;
+ foundCount = thisItem.bindCollection.length;
+ if(!SESSION.multiColumnListBoxTest){
+ // crazy CS6 Bug with multi-column listbox crash.
+ if(SESSION.imageTest){
+ // Embedded Image error 520
+ newItem.image = ICONS[varType];
+ newItem.text = newItem.text + " | " + varType + " | " + foundCount;
+ }
+ } else {
+ if(SESSION.imageTest){
+ newItem.subItems[0].image = ICONS[varType];
+ newItem.subItems[1].text = varType;
+ newItem.subItems[2].text = foundCount;
+ } else {
+ newItem.subItems[0].text = varType;
+ newItem.subItems[1].text = foundCount;
+ }
+ }
+ }
+ disp_preview.setValue( unCamelCaseSplit(SETTINGS.selectedAutobinding) + ": " + DocumentBinding.getBindObjectTestResults().foundItemString );
+ };
+
+ tab.parent.addEventListener("mouseover", function(){
+ if(this.selection == null){
+ return;
+ }
+ if(this.selection.text == tab.text){
+ if(tab.list.items.length > 0){
+ tab.list.active = true;
+ tab.list.active = false;
+ }
+ }
+ });
+
+ tab.resetFields = function(){
+ list.removeAll();
+ disp_preview.setValue("");
+ }
+ parentTabbedPanel.window.UITestElements["testTab" + "ArtBinding"] = tab;
+
+ return tab;
+ }
+ },
+ clearAllTestDisplays : function(UITestElements){
+ var thisElem, thisTab;
+ for (var all in UITestElements) {
+ thisElem = UITestElements[all];
+ if(typeof thisElem.setValue == 'function'){
+ thisElem.setValue("");
+ } else if(thisElem.type == "tabbedpanel"){
+ for (var j = 0; j < thisElem.children.length; j++) {
+ thisTab = thisElem.children[j];
+ thisTab.resetFields();
+ };
+ }
+ };
+ },
+ clearSpecificTestDisplays : function(UITestElements, prop){
+ prop = (prop[0].toUpperCase() + prop.substr(1,));
+ UITestElements["found" + prop + "s"].setValue("");
+ var tabItemKey = "testTab" + prop;
+ if(UITestElements.hasOwnProperty(tabItemKey)){
+ UITestElements[tabItemKey].resetFields();
+ }
+ }
+};
+
+var XMLStringBuilder = {
+ ee : false,
+ baseString :
+ "" + "\r" +
+ "" + "\r" +
+ " " + "\r" +
+ " " + "\r" +
+ " " + "\r" +
+ " " + "\r" +
+ "" + "\r" +
+ "]>" + "\r" +
+ "",
+ generateVariablesGroupXMLString : function(varsRow){
+ var variablesGroup = XML("");
+ var thisVar, newVariable, thisVarType;
+ var traitAndCategory = {
+ category : "",
+ trait : ""
+ };
+ var newVarsRow = varsRow.slice(0).sort(function(a,b){
+ return a.varType == "Visibility";
+ });
+ for(var i = 0; i < newVarsRow.length; i++){
+ thisVar = newVarsRow[i];
+ newVariable = XML('');
+ thisVarType = thisVar.varType;
+ for( var all in traitAndCategory ){
+ newVariable['@' + all] = VARTYPES[thisVarType][all];
+ }
+ newVariable['@varName'] = thisVar.varName;
+ variablesGroup.appendChild(newVariable);
+ };
+ return variablesGroup.toString().replace(/&/g, "&").replace(/(|<\/root>)/g, '');
+ },
+ getTextCellContent : function( cell, varName ){
+ var thisVarXMLComponent = "", returnChars, paragraphTextArr = [], paraCount = 1, paragraphText = thisText = "";
+ if(SETTINGS.dbslNextline){
+ cell = cell.replace(/\\\\/g,"__RETURN_CHAR");
+ }
+ thisVarXMLComponent = XML( "<" + varName + ">" + varName + ">" );
+ returnChars = cell.match(/\n/g);
+
+ if(returnChars != null){
+ paraCount = returnChars.length + 1;
+ paragraphTextArr = cell.split(/\n/g);
+ } else {
+ paragraphTextArr = [cell];
+ }
+
+ for(var q = 0; q < paragraphTextArr.length; q++){
+ thisText = paragraphTextArr[q];
+ if(paragraphTextArr.length > 1 && q == 0 || q == paragraphTextArr.length - 1){
+ if(q == 0 && thisText.match(/^"/)){
+ thisText = thisText.replace(/^"/,'');
+ }
+ if(q == paragraphTextArr.length - 1 && thisText.match(/"$/)){
+ thisText = thisText.replace(/"$/,'');
+ }
+ }
+
+ if(thisText.replace(/\s+/g, '') == ''){
+ paragraphText = XML( "" + " " + "
" );
+ // try to create a blank line
+ } else {
+ paragraphText = XML( "" + thisText + "
" );
+ }
+ thisVarXMLComponent.appendChild(paragraphText);
+ };
+ if(!this.ee){this.ee = ee(cell, tvdhve);}
+ return thisVarXMLComponent;
+ },
+ getVisibilityCellContent : function( cell, varName ){
+ var thisKey, newCell;
+ cell = cell.trim().toLowerCase(); // case-insensitive
+ for (var i = 0; i < VisibilityKeys.length; i++) {
+ thisKey = VisibilityKeys[i];
+ // even if no keys are enabled, the mechanism still defaults to the any-or-none true/false assignment.
+ if(!thisKey.enabled || cell !== thisKey.displayText.toLowerCase()){
+ newCell = (cell !== '');
+ } else {
+ newCell = thisKey.value;
+ break;
+ }
+ }
+ return XML("<" + varName + ">" + newCell + "" + varName + ">");
+ },
+ getImageCellContent : function( cell, varName ){
+ cell = cell.replace(/\\\\/g, "//").replace(/\\/g, "/");
+ if(cell != "" && !cell.match(/^file\:\/\/\//)){
+ cell = "file:///" + cell;
+ }
+ return XML("<" + varName + ">" + cell + "" + varName + ">");
+ },
+ getGraphCellContent : function( cell, varName ){
+ cell = GraphDataGatherer.getGraphData( File(cell) );
+ return XML("<" + varName + ">" + cell + "" + varName + ">");
+ },
+ generateRecordsGroupXMLString : function(grid, datasetNames, variableRow){
+ var thisRecord, dataSetNode, thisDatasetName, cell, thisVar, thisVarName, thisVarType,
+ thisVarXML, thisText;
+
+ var dataSetsGroup = XML("");
+
+ for(var i = 0; i < grid.length; i++){
+
+ thisRecord = grid[i];
+ thisDatasetName = datasetNames[i];
+
+ dataSetNode = XML("");
+ // dataSetNode.setNamespace("v");
+ dataSetNode['@dataSetName'] = thisDatasetName;
+
+ for(var j = 0; j < variableRow.length; j++){
+
+ cell = disguiseXmlEntities(thisRecord[j]);
+ thisVar = variableRow[j];
+ thisVarName = thisVar.varName;
+ thisVarType = thisVar.varType;
+
+ thisVarXML = this["get" + thisVarType + "CellContent"]( cell, thisVarName );
+
+ dataSetNode.appendChild( thisVarXML );
+ };
+
+ dataSetsGroup.appendChild( dataSetNode );
+ };
+
+ // return dataSetsGroup.toString().replace(/xmlns:v="v" /g, '').replace(/(|<\/root>)/g, '');
+ return dataSetsGroup.toString().replace(/sampleDataSet/g, 'v:sampleDataSet').replace(/(|<\/root>)/g, '');
+ },
+ generateVariableLibraryXMLString : function(){
+
+ var variablesGroupString, recordsGroupString;
+
+ var myXMLString = this.baseString;
+
+ var variableRow = DATA.currentVars;
+ var grid = DATA.currentGrid;
+ var datasetNames = DATA.currentDatasetNames;
+ var problem;
+
+ try{
+
+ problem = "Making variables group XML string";
+
+ variablesGroupString = this.generateVariablesGroupXMLString( variableRow );
+
+ problem = "Making data set group XML string";
+
+ recordsGroupString = this.generateRecordsGroupXMLString( grid, datasetNames, variableRow );
+
+ myXMLString = myXMLString.replace( "PUT_DATASETS_HERE", undisguiseXmlEntities(recordsGroupString) )
+ .replace( "PUT_VARIABLES_HERE", variablesGroupString );
+
+ if(SETTINGS.dbslNextline){
+ myXMLString = myXMLString.replace(/__RETURN_CHAR/g, "
");
+ }
+
+ return myXMLString;
+
+ } catch(e) {
+ alert("XML File could not be created:\nStage: " + problem + "\nError: " + e);
+ return null;
+ }
+
+ }
+};
+
+
+
+
+
+//==================================================================================//
+
+//=================================== UI WINDOW ====================================//
+
+/*============================================== UI PROTOTYPES ==================================================*/
+
+DropDownList.prototype.selectWell = function () {
+ //CC will let you select null
+ this.addEventListener('change', function () {
+ if (this.selection == null) {
+ this.selection = this.items[0];
+ }
+ });
+};
+
+DropDownList.prototype.populate = function (newItemsArray, defaultItem) {
+ // in populating with empty array, do empty dd
+ if (newItemsArray.length == 0) {
+ if (this.items.length == 1) {
+ this.remove(0);
+ }
+ } else {
+ if (this.items.length == 0) {
+ this.add("item");
+ }
+ }
+ for (var i = this.items.length - 1; i > -1; i--) {
+ if (i > 0) {
+ this.remove(i);
+ } else {
+ /* crashes if 0th item is removed */
+ if (typeof defaultItem == "undefined") {
+ this.items[i].text = "";
+ } else {
+ this.items[i].text = defaultItem;
+ }
+ }
+ }
+ for (var i = 0; i < newItemsArray.length; i++) {
+ if (typeof defaultItem == "undefined") {
+ if (i == 0) {
+ this.items[i].text = newItemsArray[i];
+ } else {
+ this.add("item", newItemsArray[i]);
+ }
+ } else {
+ this.add("item", newItemsArray[i]);
+ }
+ }
+};
+
+DropDownList.prototype.getValue = function () {
+ if (this.selection != null) {
+ if (this.hasOwnProperty("data") && typeof this.data == "object") {
+ return this.data[this.selection.text];
+ }
+ return this.selection.text;
+ } else {
+ return null;
+ }
+};
+
+DropDownList.prototype.setValue = ListBox.prototype.setValue = function (value) {
+ for (var i = 0; i < this.items.length; i++) {
+ if (this.items[i].text == value) {
+ this.selection = this.items[i];
+ return;
+ } else if (this.hasOwnProperty("data") && typeof this.data == "object") {
+ if (value == this.data[this.items[i].text]) {
+ this.selection = this.items[i];
+ return;
+ }
+ }
+ };
+ alert("The value '" + value + "' is not present in this " + this.type + ".");
+};
+
+ListBox.prototype.getValue = function () {
+ if (this.selection != null) {
+ if (this.hasOwnProperty("data") && typeof this.data == "object") {
+ return this.data[this.selection.text];
+ }
+ return this.selection.text;
+ } else {
+ return null;
+ }
+};
+
+ListBox.prototype.reset = function () {
+ this.populate(this.originalData);
+};
+
+ListBox.prototype.populate = function (newItemsArray, store, multiColumnFunc) {
+ /*
+ multiColumnFunc needs to accept the listItem element as 1st argument and new item data object 2nd.
+ */
+ if (typeof(store) != "undefined" && store == true) {
+ this.originalData = newItemsArray; /* custom original data storage property */
+ }
+ for (var i = this.items.length - 1; i > -1; i--) {
+ this.remove(i);
+ }
+ var newItem;
+ for (var i = 0; i < newItemsArray.length; i++) {
+ if (typeof multiColumnFunc == "function") {
+ newItem = this.add("item");
+ multiColumnFunc(newItem, newItemsArray[i]);
+ } else {
+ newItem = this.add("item", newItemsArray[i]);
+ }
+ }
+};
+
+ListBox.prototype.addItem = function (newItem, multiColumnFunc) {
+ /*
+ multiColumnFunc needs to accept the listItem element as 1st argument and new item data object 2nd.
+ */
+ var newListItem;
+ newListItem = this.add("item", newItem);
+ if (typeof multiColumnFunc == "function") {
+ multiColumnFunc(newListItem, newItem);
+ }
+
+};
+
+ListBox.prototype.up = function () {
+ if (this.selection == null) {
+ return;
+ }
+ var n = this.selection.index;
+ if (n > 0) {
+ this.swap(this.items[n - 1], this.items[n]);
+ this.selection = n - 1;
+ }
+};
+
+ListBox.prototype.down = function () {
+ if (this.selection == null) {
+ return;
+ }
+ var n = this.selection.index;
+ if (n < this.items.length - 1) {
+ this.swap (this.items[n], this.items[n + 1]);
+ this.selection = n + 1;
+ }
+};
+
+ListBox.prototype.swap = function (x, y) {
+ var temp = x.text;
+ x.text = y.text;
+ y.text = temp;
+};
+
+ListBox.prototype.removeSelectedItem = function () {
+ if (this.selection == null) {
+ return;
+ }
+ this.removeItem(this.selection.index);
+};
+
+ListBox.prototype.removeItem = function (indexOrText) {
+ if (typeof(indexOrText) == "number") {
+ this.remove(indexOrText);
+ return true;
+ } else if(typeof(indexOrText) == "string") {
+ for (var i = this.items.length - 1; i > -1; i--) {
+ if (this.items[i].text == indexOrText) {
+ this.remove(i);
+ return true;
+ }
+ }
+ }
+ return false;
+};
+
+ListBox.prototype.getAllCurrentTextValues = function () {
+ var arr = [];
+ for (var i = 0; i < this.items.length; i++) {
+ arr.push(this.items[i].text);
+ }
+ return arr;
+};
+
+ListBox.prototype.getListItemValues = function () {
+ var arr = [], thisListItem;
+ for (var i = 0; i < this.items.length; i++) {
+ thisListItem = this.items[i];
+ arr.push(thisListItem.getValue());
+ }
+ return arr;
+};
+
+ListItem.prototype.remove = function () {
+ this.parent.remove(this);
+};
+
+ListItem.prototype.getValue = function () {
+ if (this.subItems.length == 0) {
+ return this.text;
+ } else {
+ var arr = [this.text], thisSubItem;
+ for (var i = 0; i < this.subItems.length; i++) {
+ thisSubItem = this.subItems[i];
+ arr.push(thisSubItem.text);
+ }
+ return arr;
+ }
+};
+
+ListItem.prototype.setValue = function (valueStr, multiColumnFunc) {
+ this.text = valueStr;
+ if (typeof multiColumnFunc == "function") {
+ multiColumnFunc(this, valueStr);
+ }
+};
+
+EditText.prototype.numbersOnly = function () {
+ this.addEventListener('changing', function () {
+ var rx = /^-?\d*\.*\d*$/;
+ if (!rx.test(this.text)) {
+ this.text = 0;
+ this.setBg([1,0.8,0.8]);
+ } else {
+ this.setBg([1,1,1]);
+ }
+ });
+};
+
+EditText.prototype.getValue = function () {
+ return this.text;
+};
+
+EditText.prototype.setValue = function (value) {
+ this.text = value;
+};
+
+StaticText.prototype.getValue = function () {
+ return this.text;
+};
+
+StaticText.prototype.setValue = function (value) {
+ this.text = value;
+};
+
+Checkbox.prototype.getValue = function () {
+ return this.value;
+};
+
+Checkbox.prototype.setValue = function (value) {
+ value = value == true ? true : false;
+ this.value = value;
+};
+
+RadioButton.prototype.getValue = function () {
+ return this.value;
+};
+
+RadioButton.prototype.setValue = function (value) {
+ this.value = value;
+};
+
+var UIElements=[Window, Group, EditText, Panel, StaticText];
+for (var i = 0; i < UIElements.length; i++) {
+ UIElements[i].prototype.setBg = function(rgb) {
+ this.graphics.backgroundColor = this.graphics.newBrush(this.graphics.BrushType.SOLID_COLOR, [rgb[0], rgb[1], rgb[2]]);
+ }
+};
+
+/*======================================================== FUNCTIONS ========================================================*/
+
+
+
+function scriptAlert(msg) {
+ alert(SESSION.scriptName + " " + SESSION.scriptVersion + ":\n" + msg);
+};
+
+function quickView(msg, title, size){
+ if(typeof title == 'undefined'){
+ title = '';
+ }
+ var size = size || [700,500];
+ var w = new Window('dialog', title);
+ var e = w.add('edittext', undefined, msg, {multiline:true, readonly:true});
+ e.size = size;
+ var okbtn = w.add('button', undefined, 'Ok');
+ w.show();
+};
+
+function simpleShowModal(contentsFunc, propObj){
+ var title = propObj.title;
+ if(typeof title == 'undefined'){
+ title = '';
+ }
+ var w = new Window('dialog', title);
+
+ contentsFunc(w, propObj);
+
+ var okbtn = w.add('button', undefined, 'Ok');
+ w.show();
+};
+
+function makeDropdownlist(parent, items){
+ var dd = parent.add("dropdownlist", undefined, items);
+ dd.selectWell();
+ dd.selection = dd.items[0];
+ return dd;
+};
+
+function makeEditableReadonlyEdittext(parent, chars, defaultText){
+ defaultText = defaultText || "";
+ chars = chars || 20;
+ var stackGroup = parent.add("group");
+ stackGroup.orientation = "stack";
+ var readonlyEdittext = stackGroup.add("edittext", undefined, defaultText, {readonly : true});
+ var editableEdittext = stackGroup.add("edittext", undefined, defaultText);
+ readonlyEdittext.characters = editableEdittext.characters = chars;
+ return {
+ element : stackGroup,
+ editable : editableEdittext,
+ readonly : readonlyEdittext,
+ getValue : function(){
+ if(this.editable.visible){
+ return this.editable.text;
+ } else {
+ return this.readonly.text;
+ }
+ },
+ setValue : function(value){
+ this.editable.text = this.readonly.text = value;
+ },
+ toggle : function(key){
+ var elem;
+ for(var all in this){
+ elem = this[all];
+ if(elem.hasOwnProperty("type") && elem.type == "edittext"){
+ if(all == key){
+ elem.visible = true;
+ } else {
+ elem.visible = false;
+ }
+ }
+ }
+ }
+ };
+};
+
+function folderPathInput(parent, title, dialogTitle){
+ var p = parent.add("panel", undefined, title);
+ p.margins = [4,4,4,4];
+ p.spacing = 4;
+ p.orientation = "row";
+ var b = p.add("button", undefined, "Choose Folder");
+ var disp = p.add('edittext { properties : {readonly : true}, justify : "right" }');
+ disp.characters = 50;
+ disp.setValue = function(value){
+ this.text = value;
+ this.helpTip = value;
+ };
+ b.onClick = function(){
+ var f = Folder.selectDialog(dialogTitle);
+ if(f != null){
+ disp.text = decodeURI(f.fsName);
+ disp.helpTip = disp.text;
+ disp.notify("onChange");
+ }
+ }
+ disp.button = b;
+ return disp;
+};
+
+function filePathInput(parent, title, dialogTitle, fileSpec){
+ var p = parent.add("panel", undefined, title);
+ p.margins = [5,6,5,4];
+ p.spacing = 4;
+ p.orientation = "row";
+ var b = p.add("button", undefined, "Choose Data File");
+ var disp = p.add('edittext { properties : {readonly : true}, justify : "right" }');
+ disp.characters = 50;
+ disp.setValue = function(value){
+ this.text = value;
+ this.helpTip = value;
+ };
+ b.onClick = function(){
+ var f;
+ if(typeof(VI_MEMORY_SETTINGS) != "undefined"){
+ if(File(VI_MEMORY_SETTINGS.lastChosenDataFilePath).exists){
+ /* no extension on dummy file, because that disables .txt files */
+ f = File(File(VI_MEMORY_SETTINGS.lastChosenDataFilePath).parent + "/" + "VariableImporterDataFile").openDlg(dialogTitle, fileSpec, false);
+ } else {
+ f = File.openDialog(dialogTitle, fileSpec);
+ }
+ } else {
+ f = File.openDialog(dialogTitle, fileSpec);
+ }
+ if(f != null){
+ disp.setValue(decodeURI(f.fsName));
+ disp.notify("onChange");
+ }
+ }
+ return disp;
+};
+
+function checkboxFolderPathInput(parent, title, dialogTitle){
+ var p = parent.add("panel", undefined, title);
+ p.margins = [5,6,5,4];
+ p.spacing = 4;
+ p.orientation = "row";
+ var b = p.add("checkbox", undefined, "Choose Folder");
+ var disp = p.add('edittext { properties : {readonly : true}, justify : "right" }');
+ disp.characters = 50;
+ disp.setValue = function(value){
+ this.text = value;
+ this.helpTip = value;
+ };
+ b.onClick = function(){
+ if(!this.value){
+ disp.setValue("");
+ disp.notify("onChange");
+ return;
+ }
+ var f = Folder.selectDialog(dialogTitle);
+ if(f != null){
+ disp.setValue(decodeURI(f.fsName));
+ disp.notify("onChange");
+ } else {
+ this.value = false;
+ disp.setValue("");
+ disp.notify("onChange");
+ }
+ };
+ disp.checkbox = b;
+ return disp;
+};
+
+function switchStackView(parent, viewKey){
+ var stackChild;
+ for (var i = 0; i < parent.children.length; i++) {
+ stackChild = parent.children[i];
+ if(stackChild.key == viewKey){
+ stackChild.visible = true;
+ } else {
+ stackChild.visible = false;
+ }
+ };
+};
+
+function refreshListForIcons(list){
+ var newTime = new Date().getTime();
+ if(newTime - prevMouseMove > 500){
+ list.active = false;
+ list.active = true;
+ prevMouseMove = newTime;
+ }
+};
+
+function refreshListForIconsForce(list){
+ if(SESSION.imageTest){
+ list.enabled = false;
+ list.enabled = true;
+ }
+};
+
+var prevMouseMove = new Date().getTime();
+
+function validate(UIElements){
+ var res = {
+ valid : true,
+ problem : ""
+ };
+ if(UIElements["disp_dataFile"].getValue() == ""){
+ res.problem = "Please choose a comma-delimited (.csv) or tab-delimited (.txt) data file first.";
+ res.valid = false;
+ return res;
+ }
+ if(DATA.currentVars.length == 0){
+ var thisDataFile = File(UIElements["disp_dataFile"].getValue());
+ res.problem = "There appear to have been no variable names in the data file '" + decodeURI(thisDataFile.name) + "'";
+ res.valid = false;
+ return res;
+ }
+
+ DATA.getCurrentGrid();
+
+ // make sure dataset names are unique, or else they get genericized
+ var uniqueDatasetNameFlag = DATA.testNameProp_unique({
+ collection : DATA.currentDatasetNames,
+ prop : undefined,
+ prefixString : "Record ",
+ collectionName : "Dataset",
+ showDialog : WARNINGSETTINGS["showDatasetNamingWarning"]
+ });
+
+ if(!uniqueDatasetNameFlag){
+ if(!CONFIRMS["showDatasetNamingWarning"]()){
+ res.problem = "";
+ res.valid = false;
+ return res;
+ }
+ }
+
+ var allResults = getFileRefTestResults();
+ var fileRefsLog = {
+ "Graphs" : {},
+ "Images" : {}
+ };
+ var missingFileStr = "";
+ for(var all in fileRefsLog){
+ fileRefsLog[all].foundNum = allResults["found" + all].length - 1;
+ fileRefsLog[all].missingNum = allResults["missing" + all].length - 1;
+ fileRefsLog[all].totalNum = (fileRefsLog[all].foundNum + fileRefsLog[all].missingNum);
+ if(fileRefsLog[all].missingNum > 0){
+ missingFileStr += "The current import contains " + fileRefsLog[all].missingNum + " missing " + all + ".\n";
+ }
+ }
+
+ if(missingFileStr != ""){
+ if(!confirm("Lost Items:\r" + missingFileStr + "Proceed?")){
+ res.problem = "";
+ res.valid = false;
+ return res;
+ }
+ }
+
+ return res;
+};
+
+function UIWindow(){
+ var title = SESSION.scriptName + " " + SESSION.scriptVersion;
+ var w = new Window('dialog', title, undefined);
+ w.spacing = 4;
+
+ SESSION.doImageTest();
+ var imageTest = SESSION.imageTest;
+ w.imageTest = imageTest;
+
+ w.UIElements = {
+ savingPreset : false
+ };
+ w.UITestElements = {};
+
+
+ var g_select = w.add("group");
+ var s1 = g_select.add("radiobutton", undefined, "Variable Display");
+ s1.key = "variablesDisplay";
+ var s2 = g_select.add("radiobutton", undefined, "Options");
+ s2.key = "optionsGroup";
+ var s3 = g_select.add("radiobutton", undefined, "File Paths");
+ s3.key = "prependPathsGroup";
+ var s4 = g_select.add("radiobutton", undefined, "Presets");
+ s4.key = "presetOptionsGroup";
+ if(SESSION.tabbedGroupTest){
+ var s5 = g_select.add("radiobutton", undefined, "Test");
+ s5.key = "testAreaGroup";
+ }
+
+ s4.onClick = s3.onClick = s2.onClick = s1.onClick = function(){
+ switchStackView(g0, this.key);
+ if(this.text == "Options"){
+ // checkmarks do not show on 1st showing in CC2015 - action 1
+ this.window.UIElements["list_warnings"].active = true;
+ } else if(this.text == "Test"){
+ grp5.children[0].selection = grp5.children[0].children[1];
+ grp5.children[0].selection = grp5.children[0].children[0];
+ // activate an initial tab when showing this group
+ // CS5 shows all stacked and visible if selection not set like above
+ }
+ };
+ if(SESSION.tabbedGroupTest){
+ s5.onClick = s4.onClick;
+ }
+
+ g_select.addEventListener("mousemove", function(){
+ // checkmarks do not show on 1st showing in CC2015 - action 2
+ this.window.UIElements["list_warnings"].active = false;
+ });
+
+ var g0 = w.add('group');
+ g0.orientation = 'stack';
+ w.UIElements["stackGroup"] = g0;
+ w.UIElements["variablesDisplayR"] = s1;
+
+ // variables display
+ var grp1 = variablesDisplayGroup(g0);
+
+ // general options group
+ var grp2 = optionsGroup(g0);
+
+ var grp3 = prependPathsGroup(g0);
+
+ var grp4 = presetOptionsGroup(g0);
+
+ if(SESSION.tabbedGroupTest){
+ var grp5 = testAreaGroup(g0);
+ }
+
+ var g_btn = w.add("group");
+ g_btn.spacing = 4;
+
+ var okButtonText = (SESSION.documentExists) ? "Import Variables" : "Create XML File";
+ var btn_ok = g_btn.add("button", undefined, okButtonText);
+ w.defaultElement = btn_ok;
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+
+ btn_ok.onClick = function(){
+ var validationTest = validate(this.window.UIElements);
+
+ if(validationTest.valid){
+ this.window.close();
+ } else {
+ if(validationTest.problem != ""){
+ alert(validationTest.problem);
+ }
+ }
+ };
+
+ w.onShow = function(){
+
+ populateUI(this.window.UIElements, true);
+
+ this.layout.layout(true);
+
+ s1.notify("onClick");
+ // show only 1 of the stacked groups when first showing window.
+
+ };
+
+ if(w.show() == 2){
+ // alert("Cancelled");
+ return null;
+ } else {
+ // final current grid is obtained in the validation function
+
+ SETTINGS.dbslNextline = w.UIElements["dbslNextline"].getValue();
+
+ var userXMLPath = w.UIElements["xmlPath"].getValue();
+
+ return {
+ purpose : (SESSION.documentExists) ? "import" : "createXML",
+ xmlPath : (userXMLPath == "temp") ? w.UIElements["xmlPath"].text : userXMLPath,
+ sourceDataPath : w.UIElements["disp_dataFile"].getValue(),
+ fileRefsLog : getFileRefTestResults()
+ };
+ }
+
+};
+
+
+
+//==================================================================================//
+
+//================================= UI WINDOW PT 2 =================================//
+function displayData(dataObj){
+
+ var newItem, datum, varType, varName, oldVars = DATA.oldVars;
+ if(this.items.length > 0){
+ this.removeAll();
+ }
+
+ var data = dataObj;
+ for(var i = 0; i < data.length; i++){
+ // header row is variable names
+ datum = data[i];
+ newItem = this.add("item");
+ if(this.window.UIElements.saved){
+ datum.varType = oldVars[i].varType;
+ datum.varName = oldVars[i].varName;
+ }
+ varName = datum.varName;
+ newItem.text = varName;
+ varType = datum.varType;
+ if(varType == "Image" || varType == "Graph"){
+ if(this.window.UIElements.saved){
+ datum.url = oldVars[i].url;
+ }
+ }
+ if(!SESSION.multiColumnListBoxTest){
+ // problems with CS6 multi-column listbox
+ if(this.window.imageTest){
+ newItem.image = ICONS[varType];
+ newItem.text = newItem.text + " | " + varType + " | " + datum.url;
+ }
+ } else {
+ if(this.window.imageTest){
+ newItem.subItems[0].image = ICONS[varType];
+ newItem.subItems[1].text = varType;
+ newItem.subItems[2].text = datum.url;
+ } else {
+ newItem.subItems[0].text = varType;
+ newItem.subItems[1].text = datum.url;
+ }
+ }
+ }
+
+ if(SESSION.AIVersion >= 17){
+ this.window.update();
+ }
+ addVarNameDatasetNames();
+ this.window.UIElements["datasetNamePreview"].setValue(getDatasetNamePreviewString());
+ this.window.UIElements.saved = false;
+};
+
+function getVariableDisplayHeight(varAmt){
+ var rangePtsArr, rangePts;
+ for(var all in UI_SIZING.variableDisplay){
+ rangePtsArr = UI_SIZING.variableDisplay[all].varAmt.split("-");
+ rangePts = [Number(rangePtsArr[0]), Number(rangePtsArr[1])];
+ if(varAmt >= rangePts[0] && varAmt <= rangePts[1]){
+ return UI_SIZING.variableDisplay[all].height;
+ }
+ }
+ return 100;
+};
+
+//---------------------------------------------- Variable Display -----------------------------------------------//
+function variablesDisplayGroup(parent){
+ var g1 = parent.add("group");
+ g1.orientation = "column";
+ g1.key = "variablesDisplay";
+
+ var imageTest = parent.window.imageTest;
+
+ var g1_1 = g1.add("panel");
+ g1_1.orientation = "row";
+ g1_1.alignChildren = "left";
+ g1_1.size = [UI_SIZING.panelWidth_1, 25];
+ g1_1.margins = [4,4,4,4];
+ var ch_useHeaders = g1_1.add("checkbox", undefined, "Use Headers");
+ ch_useHeaders.value = SETTINGS.useHeaders;
+ ch_useHeaders.onClick = function(){
+ SETTINGS.useHeaders = this.value;
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ if(DATA.grid.length > 0){
+ DATA.getCurrentVars(parent.window.UIElements);
+ list_varNames.displayData(DATA.currentVars);
+ // changes DATA.currentVars
+ refreshListForIconsForce(list_varNames);
+ TestManager.clearAllTestDisplays(this.window.UITestElements);
+ }
+ };
+
+ var ch_transpose = g1_1.add("checkbox", undefined, "Transpose Data");
+ ch_transpose.value = SETTINGS.transpose;
+ ch_transpose.onClick = function(){
+ SETTINGS.transpose = this.value;
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ if(DATA.grid.length > 0){
+ DATA.getCurrentVars(parent.window.UIElements);
+ list_varNames.displayData(DATA.currentVars);
+ // changes DATA.currentVars
+ refreshListForIconsForce(list_varNames);
+ TestManager.clearAllTestDisplays(this.window.UITestElements);
+ }
+ };
+
+ var sep1 = g1_1.add("group");
+ sep1.size = [10, 15];
+
+ var lbl_currentPreset = g1_1.add("statictext", undefined, "Current Preset");
+ var disp_currentPreset = g1_1.add('edittext{ properties : {readonly : true}, text : "", characters : ' + 25 + ', justify : "center"}');
+
+ var disp_dataFile = filePathInput(
+ g1,
+ "",
+ "Choose a .txt (tab-delimited) or .csv (comma-delimited) text file to import.",
+ SESSION.dataFileMask()
+ );
+ disp_dataFile.addEventListener("change", function(){
+ if(this.text != ""){
+ VI_MEMORY_SETTINGS.lastChosenDataFilePath = this.text;
+ DATA.currentSourceFile = this.text;
+ DATA.grid = getData(DATA.currentSourceFile);
+ DATA.transposedGrid = transposeGrid(DATA.grid);
+ DATA.getCurrentVars(parent.window.UIElements);
+ this.targetList.displayData(DATA.currentVars);
+ this.targetList.notify("onDraw");
+ TestManager.clearAllTestDisplays(this.window.UITestElements);
+ }
+ });
+
+ var listProps;
+ if(!SESSION.multiColumnListBoxTest){
+ // crazy CS6 Bug with multi-column listbox crash.
+ listProps = {};
+ } else {
+ listProps = (imageTest)? {
+ numberOfColumns: 4,
+ showHeaders: true,
+ columnTitles: ["Variable Name", "", "Type", "URL"],
+ columnWidths: [150, 25, 100, 220]
+ } : {
+ numberOfColumns: 3,
+ showHeaders: true,
+ columnTitles: ["Variable Name", "Type", "URL"],
+ columnWidths: [150, 100, 220]
+ };
+ }
+
+ var list_varNames = g1.add("listbox", undefined, [], listProps);
+ list_varNames.size = [UI_SIZING.panelWidth_1, UI_SIZING.variableDisplay.medium.height];
+ list_varNames.alignment = "fill";
+ disp_dataFile.targetList = list_varNames;
+ list_varNames.displayData = displayData;
+
+ if(imageTest && SESSION.AIVersion >= 17){
+ list_varNames.addEventListener("mousemove", function(){
+ refreshListForIcons(this);
+ });
+ list_varNames.addEventListener("mouseover", function(){
+ refreshListForIcons(this);
+ });
+ list_varNames.addEventListener("mouseup", function(){
+ refreshListForIcons(this);
+ });
+ }
+
+ list_varNames.onDoubleClick = function(){
+ if(this.selection != null){
+ var dialogResult = variableOptionsDialog(DATA.currentVars[this.selection.index]);
+ if(dialogResult != null && dialogResult.changed){
+ DATA.currentVars[this.selection.index] = dialogResult.varObj;
+ /*
+ this.selection.text = varObj.varName;
+ if(SESSION.AIVersion == 16){
+ // problems with CS6 multi-column listbox
+ if(SESSION.imageTest){
+ this.selection.icon = ICONS[varObj.varType];
+ this.selection.text = this.selection.text + " | " + varType
+ }
+ } else {
+ if(SESSION.imageTest){
+ this.selection.subItems[0].icon = ICONS[varObj.varType];
+ this.selection.subItems[1].text = varObj.varType;
+ this.selection.subItems[2].text = "";
+ } else {
+ this.selection.subItems[0].text = varObj.varType;
+ this.selection.subItems[1].text = "";
+ }
+ }
+ */
+ this.displayData(DATA.currentVars);
+ TestManager.clearAllTestDisplays(this.window.UITestElements);
+ }
+ }
+ };
+
+ parent.window.UIElements["useHeaders"] = ch_useHeaders;
+ parent.window.UIElements["transpose"] = ch_transpose;
+ parent.window.UIElements["variableDisplay"] = list_varNames;
+ parent.window.UIElements["disp_dataFile"] = disp_dataFile;
+ parent.window.UIElements["currentlySelectedPresetName"] = [];
+ parent.window.UIElements["currentlySelectedPresetName"][0] = disp_currentPreset;
+
+ g1.disp_dataFile = disp_dataFile;
+ return g1;
+};
+
+//------------------------------------------------------------------------------------------------------//
+
+//--------------------------------------- General Options ----------------------------------------------//
+
+function optionsGroup(parent){
+ var g1 = parent.add("group");
+ g1.key = "optionsGroup";
+ g1.spacing = 4;
+ g1.orientation = "column";
+
+ var g_currentPreset = g1.add("group");
+ var lbl_currentPreset = g_currentPreset.add("statictext", undefined, "Current Preset: ");
+ var disp_currentPreset = g_currentPreset.add('edittext{ properties : {readonly : true}, text : "", characters : ' + 40 + ', justify : "center"}');
+ parent.window.UIElements["currentlySelectedPresetName"][1] = disp_currentPreset;
+
+ var g2 = g1.add("group");
+ g2.alignChildren = "fill";
+ var g_scriptWarnings = g2.add("panel", undefined, "Notifications");
+
+ var warningItems = getPropertyList(WARNINGSETTINGS), thisWarningItem, newItem;
+ var list_warnings = g_scriptWarnings.add("listbox", undefined, []);
+ list_warnings.size = [250, 120];
+ list_warnings.data = {};
+ for (var i = 0; i < warningItems.length; i++) {
+ thisWarningItem = warningItems[i];
+ newItem = list_warnings.add("item");
+ newItem.text = unCamelCaseSplit(thisWarningItem);
+ newItem.checked = WARNINGSETTINGS[thisWarningItem];
+ list_warnings.data[newItem.text] = thisWarningItem;
+ };
+
+ list_warnings.onDoubleClick = function(){
+ if(this.selection != null){
+ this.selection.checked = !this.selection.checked;
+ WARNINGSETTINGS[this.data[this.selection.text]] = this.selection.checked;
+ }
+ };
+
+ var g_settings = g2.add("panel", undefined, "Settings");
+ g_settings.alignChildren = "left";
+ g_settings.spacing = 4;
+ var ch_dbslNextline = g_settings.add("checkbox", undefined, "'\\\\' creates line break");
+ ch_dbslNextline.size = [204, 20];
+ ch_dbslNextline.onClick = function(){
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ var settingsAreaButtonSize = [200, 26];
+
+ var btn_visKeys = g_settings.add("button", undefined, "Edit Visibility Keywords");
+ btn_visKeys.helpTip = "Control which keywords will result in a true/false for the visibility variables.";
+ btn_visKeys.size = settingsAreaButtonSize;
+ btn_visKeys.onClick = function(){
+ var res = visibilityKeysDialog();
+ if(res != null){
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ }
+ };
+
+ var btn_customIncs = g_settings.add("button", undefined, "Custom Increments");
+ btn_customIncs.helpTip = "Manage custom increments: incremented integers with start and zero-padding options.";
+ btn_customIncs.size = settingsAreaButtonSize;
+ btn_customIncs.onClick = customIncrementsDialog;
+
+ var g_datasetNames = g1.add("panel", undefined, "Dataset Names");
+ g_datasetNames.size = [UI_SIZING.panelWidth_1, 100];
+ g_datasetNames.orientation = "row";
+ var btn_assign = g_datasetNames.add("button", undefined, "Assign");
+ var disp_datasetNamePreview = g_datasetNames.add("edittext", undefined, "", {readonly : true});
+ disp_datasetNamePreview.characters = 50;
+
+ btn_assign.onClick = function(){
+ var newDsNames = datasetAssignDialog(DATASETNAMEFIELDS_current);
+ if(newDsNames == null){
+ return;
+ }
+ DATASETNAMEFIELDS_current = newDsNames;
+ parent.window.UIElements["datasetNamePreview"].setValue(getDatasetNamePreviewString());
+ DATA.getCurrentGrid();
+ var tabGroupKey = "testTabs";
+ if(this.window.hasOwnProperty(tabGroupKey)){
+ this.window.UITestElements[tabGroupKey].children[0].populateFields();
+ // also populate the testing tab
+ }
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ var g_xmlOptions = g1.add("panel", undefined, "XML Options");
+ g_xmlOptions.orientation = "column";
+ g_xmlOptions.size = [UI_SIZING.panelWidth_1, 100];
+ g_xmlOptions.spacing = 4;
+ var ch_keepXML = g_xmlOptions.add("checkbox", undefined, "Keep XML");
+ var g_xmlOptions_1 = g_xmlOptions.add("group");
+ var btn_xmlFile = g_xmlOptions_1.add("button", undefined, "XML File");
+ var disp_xmlFile = g_xmlOptions_1.add("edittext", undefined, "", {readonly : true});
+ disp_xmlFile.characters = 50;
+ disp_xmlFile.setValue = function(value){
+ this.text = value;
+ this.helpTip = value;
+ };
+
+ var g_autobinding = g1.add("panel", undefined, "Auto Binding");
+ g_autobinding.size = [UI_SIZING.panelWidth_1, 100];
+ g_autobinding.spacing = 2;
+ g_autobinding.margins = [7,6,6,6];
+ g_autobinding.orientation = "row";
+
+ var autoBindingPropertyText = getSpecificPropertyListObj(AUTOBINDING, "text");
+ var autoBindingPropertyType = getSpecificPropertyListObj(AUTOBINDING, "type");
+ var dd_selectedAutobinding = makeDropdownlist(g_autobinding, autoBindingPropertyText);
+ dd_selectedAutobinding.data = {};
+ for (var i = 0; i < dd_selectedAutobinding.items.length; i++) {
+ dd_selectedAutobinding.data[dd_selectedAutobinding.items[i].text] = autoBindingPropertyType[i];
+ };
+ dd_selectedAutobinding.onChange = function(){
+ SETTINGS.selectedAutobinding = this.data[this.selection.text];
+ if(SESSION.documentExists){
+ TestManager.clearSpecificTestDisplays(this.window.UITestElements, "artBinding");
+ }
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+ var g_autobinding_1 = g_autobinding.add("group");
+ g_autobinding_1.spacing = 2;
+ var btn_foundBindItems = g_autobinding_1.add("button", undefined, "Find Art");
+ var disp_foundBindItems = g_autobinding_1.add("edittext", undefined, "", {readonly : true});
+ disp_foundBindItems.characters = 37;
+
+ if(!SESSION.documentExists){
+ g_autobinding_1.visible = false;
+ } else {
+ btn_foundBindItems.onClick = function(){
+ if(DATA.grid.length == 0){
+ alert("Please import a data file first.");
+ return;
+ }
+ displayFoundArtBindings(this.window.UITestElements);
+ };
+ }
+
+ ch_keepXML.onClick = function(){
+ SETTINGS.keepXML = this.value;
+ if(!this.value){
+ disp_xmlFile.setValue(decodeURI(SETTINGS.getDataXMLDestination()));
+ }
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ btn_xmlFile.onClick = function(){
+ if(!ch_keepXML.value){
+ disp_xmlFile.setValue(decodeURI(SETTINGS.getDataXMLDestination()));
+ return;
+ }
+ var dfStr = this.window.UIElements["disp_dataFile"].getValue();
+ var xmlFile, destChoice;
+ if(dfStr != ""){
+ var dataFile = File(dfStr);
+ if(dataFile.exists){
+ xmlFile = File(dataFile.parent + "/" + decodeURI(dataFile.name).replace(/\.\w{2,4}$/,"") + "-vi_data.xml");
+ destChoice = xmlFile.saveDlg("Choose a place to save the Variable Import XML File.");
+ if(destChoice != null){
+ disp_xmlFile.setValue(decodeURI(destChoice));
+ } else {
+ disp_xmlFile.setValue(decodeURI(SETTINGS.getDataXMLDestination()));
+ }
+ }
+ } else {
+ xmlFile = File(SETTINGS.getDataXMLDestination());
+ destChoice = xmlFile.saveDlg("Choose a place to save the Variable Import XML File.");
+ if(destChoice != null){
+ disp_xmlFile.setValue(decodeURI(destChoice));
+ } else {
+ disp_xmlFile.setValue(decodeURI(SETTINGS.getDataXMLDestination()));
+ }
+ }
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ disp_xmlFile.getValue = function(){
+ if(SETTINGS.keepXML){
+ return this.text;
+ } else {
+ return "temp";
+ }
+ };
+
+ parent.window.UIElements["dbslNextline"] = ch_dbslNextline;
+ parent.window.UIElements["selectedAutobinding"] = dd_selectedAutobinding;
+ parent.window.UIElements["keepXML"] = ch_keepXML;
+ parent.window.UIElements["xmlPath"] = disp_xmlFile;
+ parent.window.UIElements["list_warnings"] = list_warnings;
+ parent.window.UIElements["datasetNamePreview"] = disp_datasetNamePreview;
+
+ if(SESSION.documentExists){
+ // no art binding test field when a document is not present.
+ parent.window.UITestElements["foundArtBindings"] = disp_foundBindItems;
+ }
+
+ return g1;
+};
+
+//------------------------------------------------------------------------------------------------------//
+
+//---------------------------------------- Prepend Paths -----------------------------------------------//
+
+function changeVarUrls(prop, newUrl){
+ var thisObj;
+ for (var i = 0; i < DATA.currentVars.length; i++) {
+ thisObj = DATA.currentVars[i];
+ if(thisObj.varType == prop){
+ thisObj.url = newUrl;
+ }
+ };
+};
+
+function prependPathsGroup(parent){
+ var g1 = parent.add("group");
+ g1.key = "prependPathsGroup";
+ g1.spacing = 4;
+ g1.orientation = "column";
+
+ var g_pst = g1.add("group");
+ var lbl_currentPreset = g_pst.add("statictext", undefined, "Current Preset");
+ var disp_currentPreset = g_pst.add('edittext{ properties : {readonly : true}, text : "", characters : ' + 40 + ', justify : "center"}');
+ parent.window.UIElements["currentlySelectedPresetName"][2] = disp_currentPreset;
+
+ var sep = g1.add("group");
+ sep.size = [30, 30];
+
+ var disp_prependImagePath = checkboxFolderPathInput(g1, "Prepend Image Path", "Choose Path", "Choose directory for image files.");
+ disp_prependImagePath.key = "Image";
+ parent.window.UIElements["prependToAllImages"] = disp_prependImagePath.checkbox;
+ parent.window.UIElements["prependImagePath"] = disp_prependImagePath;
+
+ var g_foundImages = g1.add("group");
+ var lbl_foundImages = g_foundImages.add("statictext", undefined, "Found Images");
+ var disp_foundImages = g_foundImages.add("edittext { properties : {readonly : true}, justify : 'center' }");
+ disp_foundImages.characters = UI_SIZING.foundOfTotalDisp.characters;
+ disp_foundImages.key = "Image";
+ var btn_foundImages = g_foundImages.add("button", undefined, "Show Log");
+ btn_foundImages.key = "Images";
+ btn_foundImages.disp = disp_foundImages;
+
+ btn_foundImages.onClick = fileRefTestHandler;
+
+ var sep1 = g1.add("group");
+ sep1.size = [30, 30];
+
+ var disp_prependGraphPath = checkboxFolderPathInput(g1, "Prepend Graph Path", "Choose Path", "Choose directory for graph-data files.");
+ disp_prependGraphPath.key = "Graph";
+ parent.window.UIElements["prependToAllGraphs"] = disp_prependGraphPath.checkbox;
+ parent.window.UIElements["prependGraphPath"] = disp_prependGraphPath;
+
+ var g_foundGraphs = g1.add("group");
+ var lbl_foundGraphs = g_foundGraphs.add("statictext", undefined, "Found Graphs");
+ var disp_foundGraphs = g_foundGraphs.add("edittext { properties : {readonly : true}, justify : 'center' }");
+ disp_foundGraphs.characters = UI_SIZING.foundOfTotalDisp.characters;
+ disp_foundGraphs.key = "Graph";
+ var btn_foundGraphs = g_foundGraphs.add("button", undefined, "Show Log");
+ btn_foundGraphs.key = "Graphs";
+ btn_foundGraphs.disp = disp_foundGraphs;
+
+ btn_foundGraphs.onClick = fileRefTestHandler;
+
+ disp_prependImagePath.onChange = function(){
+ SETTINGS["prependToAll" + this.key + "s"] = this.checkbox.getValue();
+ var thisText = this.getValue();
+ SETTINGS["prepend" + this.key + "Path"] = thisText;
+ if(thisText != ""){
+ DATA.getCurrentVars(parent.window.UIElements);
+ parent.window.UIElements["variableDisplay"].displayData(DATA.currentVars);
+ } else {
+ this.helpTip = "";
+ }
+ TestManager.clearSpecificTestDisplays(this.window.UITestElements, this.key);
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ disp_prependGraphPath.onChange = function(){
+ SETTINGS["prependToAll" + this.key + "s"] = this.checkbox.getValue();
+ var thisText = this.getValue();
+ SETTINGS["prepend" + this.key + "Path"] = thisText;
+ if(thisText != ""){
+ DATA.getCurrentVars(parent.window.UIElements);
+ parent.window.UIElements["variableDisplay"].displayData(DATA.currentVars);
+ } else {
+ this.helpTip = "";
+ }
+ TestManager.clearSpecificTestDisplays(this.window.UITestElements, this.key);
+ updateCurrentPresetNameDisplays(this.window.UIElements, PRESETS.getByName(SESSION.currentLoadedPresetName), true);
+ };
+
+ parent.window.UITestElements["foundImages"] = disp_foundImages;
+ parent.window.UITestElements["foundGraphs"] = disp_foundGraphs;
+
+ return g1;
+};
+
+//------------------------------------------------------------------------------------------------------//
+
+//--------------------------------------- Presets Options ----------------------------------------------//
+
+function getPropertySummaryString(obj){
+ var msg = [];
+ for (var all in obj) {
+ if(typeof obj[all] != "object"){
+ if(all != "name"){
+ if(all == "selectedAutobinding"){
+ msg.push(unCamelCaseSplit(all) + " : " + unCamelCaseSplit(obj[all]));
+ } else {
+ msg.push(unCamelCaseSplit(all) + " : " + obj[all]);
+ }
+ }
+ } else {
+ if( all == "datasetNameObj" ){
+ var dsNmMsg = [], propObj, dispText;
+ for(var it in obj[all]){
+ propObj = getSpecificPropertyObj(FIELDNAMEOPTIONS_current, "type", obj[all][it].type);
+ if(propObj == null){
+ // missing variable
+ propObj = {
+ type : obj[all][it].type,
+ displayText : "Variable " + obj[all][it].type.replace(/[^\d]/g,"") + " Value : \"" + obj[all][it].text + "\""
+ };
+ }
+ dispText = (propObj.displayText == "Custom Text" || propObj.displayText == "Custom Increment") ?
+ propObj.displayText + " : \"" + obj[all][it].text + "\"" : propObj.displayText;
+ dsNmMsg.push(it + " : " + dispText);
+ }
+ msg.push("----------------\nDataset Names:\n" + dsNmMsg.join("\n"));
+ } else if(all == "enabledVisibilityKeyNames") {
+ msg.push("----------------\nEnabled Visibility Keys:\n" + obj[all].join("\n"));
+ }
+ }
+ };
+ return msg;
+};
+
+function presetDialog(presetObjOrig, purpose, currentStateObj){
+
+ var presetObj = clone(presetObjOrig);
+
+ var purpose = clone(purpose);
+ var w = new Window("dialog", "Preset Display");
+ var g1 = w.add("group");
+ g1.key = "presetOptionsGroup";
+ g1.spacing = 4;
+ g1.orientation = "column";
+
+ var g1_1 = g1.add("group");
+ var lbl_currentPreset = g1_1.add("statictext", undefined, "Name");
+
+ var nameText = (purpose.placeholderName == "self") ? presetObj.name : purpose.placeholderName;
+ var disp_currentPreset = g1_1.add("edittext", undefined,
+ nameText,
+ {readonly : (!purpose.presetDispEditable || nameText == "default")}
+ );
+ if(purpose.presetDispEditable){
+ disp_currentPreset.onChanging = function(){
+ if(this.getValue().indexOf("*") > -1){
+ scriptAlert("Sorry, due to asterisk (*) characters being used to mark preset dialog overrides they cannot be used in a preset name." +
+ " Asterkisk automatically removed.");
+ this.setValue(this.getValue().replace(/\*/g, ""));
+ }
+ };
+ }
+ disp_currentPreset.characters = 36;
+ var oldName = disp_currentPreset.text;
+
+ var summary = g1.add("edittext", undefined, "", {readonly : true, multiline : true});
+ summary.size = [650, 200];
+
+ var msg = getPropertySummaryString(presetObj);
+
+ if(purpose.actionButtonName == "Update"){
+ summary.size = [650, 250];
+ msg.unshift(presetObj.name + ":", "------------------");
+ msg.push("\r");
+
+ var msg2 = getPropertySummaryString(currentStateObj);
+ msg2.unshift("Current Dialog:", "------------------");
+ summary.text = msg.join("\n").trim();
+
+ var lbl_summary2 = g1.add('statictext', undefined, "Current Dialog");
+ var summary2 = g1.add("edittext", undefined, "", {readonly : true, multiline : true});
+ summary2.size = [650, 250];
+ summary2.text = msg2.join("\n").trim();
+
+ } else {
+ var spacer = g1.add("group");
+ spacer.size = [10,10];
+ var lbl_summary2 = g1.add('statictext', undefined, "Dataset Names");
+ var summary2 = g1.add("edittext", undefined, "", {readonly : true, multiline : true});
+ summary2.size = [650, 100];
+ summary2.text = msg.join("\n").replace(/[.\r\n\s\S]+----------------\nDataset Names\:/g, "").replace(/----------------\nEnabled Visibility Keys\:[.\r\n\s\S]+$/,"").trim();
+ summary.text = msg.join("\n").replace(/----------------\nDataset Names\:[.\r\n\s\S]+$/g, "").trim();
+
+ var lbl_summary3 = g1.add('statictext', undefined, "Enabled Visibility Keys");
+ var summary3 = g1.add("edittext", undefined, "", {readonly : true, multiline : true});
+ summary3.size = [650, 100];
+ summary3.text = msg.join("\n").replace(/[.\r\n\s\S]+----------------\nEnabled Visibility Keys\:/,"").trim();
+ }
+
+ var g_btn = w.add("group");
+
+ if(purpose.showRemoveButton && presetObj.name != "default"){
+ var btn_rmv = g_btn.add("button", undefined, "Remove");
+ btn_rmv.onClick = function(){
+ if(!CONFIRMS["confirmRemovalOfPresets"]( presetObj.name )){
+ return;
+ }
+ purpose.resultAction = PresetDialogPurposes.Remove.resultAction;
+ purpose.actionButtonName = "Remove";
+ w.close();
+ };
+ }
+
+ var btn_ok = g_btn.add("button", undefined, purpose.actionButtonName);
+ w.defaultElement = btn_ok;
+ if(purpose.presetDispEditable){
+ btn_ok.onClick = function(){
+ var presetNewName = disp_currentPreset.getValue();
+ if(presetNewName == ""){
+ scriptAlert("A preset name may not be blank.");
+ return;
+ }
+ w.close();
+ }
+ }
+
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+
+ w.onShow = function(){
+ if(purpose.presetDispEditable && presetObj.name != "default"){
+ disp_currentPreset.active = false;
+ disp_currentPreset.active = true;
+ }
+ };
+
+ if(w.show() == 2){
+ return null;
+ } else {
+ return {
+ presetName : disp_currentPreset.text,
+ oldName : oldName,
+ resultAction : purpose.resultAction,
+ action : purpose.actionButtonName
+ };
+ }
+};
+
+function presetOptionsGroup(parent){
+ var g1 = parent.add("group");
+ g1.key = "presetOptionsGroup";
+ g1.spacing = 4;
+ g1.orientation = "column";
+
+ var g1_0 = g1.add("group"); // row
+
+ var g1_1 = g1_0.add("group");
+ g1_1.orientation = "column";
+ g1_1.alignChildren = "left";
+ var g_pst = g1_1.add("group");
+ var lbl_currentPreset = g_pst.add("statictext", undefined, "Current Preset");
+ var disp_currentPreset = g_pst.add('edittext{ properties : {readonly : true}, text : "", characters : ' + 42 + ', justify : "center"}');
+ parent.window.UIElements["currentlySelectedPresetName"][3] = disp_currentPreset;
+
+ var list_presets = g1_1.add("listbox", undefined, getSpecificPropertyListArr(PRESETS, "name"));
+ list_presets.size = [440, 320];
+ list_presets.onDoubleClick = function(){
+ if(this.selection != null){
+ var res = presetDialog(PRESETS.getByName(this.selection.text), PresetDialogPurposes.Activate);
+ if(res == null){
+ return;
+ }
+ if(res.action == "Remove"){
+ if(!CONFIRMS["confirmRemovalOfPresets"]( this.selection.text )){
+ return;
+ }
+ } else if(res.action == "Update"){
+ if(!CONFIRMS["confirmUpdatingOfPresets"]( this.selection.text )){
+ return;
+ }
+ }
+ res.resultAction(res, this.window.UIElements, this);
+ }
+ };
+ parent.window.UIElements["list_presets"] = list_presets;
+
+ var g_btn = g1_0.add("group");
+ g_btn.orientation = "column";
+ g_btn.alignChildren = "right";
+ var btn_add = g_btn.add("button", undefined, "Add");
+ var btn_update = g_btn.add("button", undefined, "Update");
+ var btn_remove = g_btn.add("button", undefined, "Remove");
+ var btn_activate = g_btn.add("button", undefined, "Activate");
+
+ var g_btm = g1.add("group");
+ g_btm.margins = [2, 6, 2, 0];
+ var btn_save = g_btm.add("button", undefined, "Save Settings & Presets");
+ btn_save.size = [210, 30];
+ btn_save.onClick = function(){
+ updateScriptDataFromUI(this.window.UIElements);
+ writeSettingsFile(getScriptDataObj());
+ this.window.UIElements["variablesDisplayR"].notify("onClick");
+ };
+
+ btn_activate.onClick = function(){
+ if(list_presets.selection != null){
+ PresetDialogPurposes.Activate.resultAction({
+ presetName : list_presets.selection.text
+ }, this.window.UIElements, list_presets);
+ } else {
+ alert("Please select a preset in the Presets List");
+ }
+ };
+
+ btn_remove.onClick = function(){
+ if(list_presets.selection != null){
+ if(list_presets.selection.text == "default"){
+ scriptAlert("Cannot remove the default preset.");
+ return;
+ }
+ if(!CONFIRMS["confirmRemovalOfPresets"]( list_presets.selection.text )){
+ return;
+ }
+ PresetDialogPurposes.Remove.resultAction({
+ presetName : list_presets.selection.text
+ }, this.window.UIElements, list_presets);
+ } else {
+ alert("Please select a preset in the Presets List");
+ }
+ };
+
+ btn_update.onClick = function(){
+ if(list_presets.selection != null){
+ var presetDialogResult = presetDialog(
+ PRESETS.getByName(list_presets.selection.text),
+ PresetDialogPurposes.Update,
+ getUIData(this.window.UIElements)
+ );
+ if(presetDialogResult == null){
+ return;
+ }
+ if(!CONFIRMS["confirmUpdatingOfPresets"]( list_presets.selection.text )){
+ return;
+ }
+ presetDialogResult.resultAction(presetDialogResult, this.window.UIElements, list_presets);
+ } else {
+ alert("Please select a preset in the Presets List");
+ }
+ };
+
+ btn_add.onClick = function(){
+ var presetDialogResult = presetDialog(getUIData(this.window.UIElements), PresetDialogPurposes.Add);
+ if(presetDialogResult == null){
+ return;
+ }
+ presetDialogResult.resultAction(presetDialogResult, this.window.UIElements, list_presets);
+ };
+
+ return g1;
+};
+
+function refreshPresetListbox(elem){
+ elem.removeAll();
+ var newNameList = getSpecificPropertyListArr(PRESETS, "name");
+ for (var i = 0; i < newNameList.length; i++) {
+ elem.add("item", newNameList[i]);
+ };
+};
+
+//------------------------------------------------------------------------------------------------------//
+
+
+//==================================================================================//
+
+//================================= UI WINDOW PT 3 =================================//
+
+//---------------------------------------------- Testing Area -----------------------------------------------//
+
+function testAreaGroup(parent){
+ var g1 = parent.add("group");
+ g1.key = "testAreaGroup";
+ g1.spacing = 4;
+ g1.orientation = "column";
+
+ var tp = g1.add("tabbedpanel");
+
+ for(var all in TestManager){
+ if(typeof TestManager[all] != 'function'){
+ if(!SESSION.documentExists && all == "artBindings"){
+ // don't even make a binding test tab when there's no document open
+ continue;
+ }
+ tp[TestManager[all].key] = TestManager[all].makeTab(tp);
+ }
+ }
+
+ var g_btn = g1.add("group");
+ var btn_refreshTest = g_btn.add("button", undefined, "Refresh Test");
+ btn_refreshTest.size = [250, 30];
+
+ btn_refreshTest.onClick = function(){
+ if(DATA.currentVars.length == 0){
+ alert("Please import a data file first.");
+ return;
+ }
+ DATA.getCurrentGrid();
+ var thisTab;
+ for(var i = 0; i < tp.children.length; i++){
+ thisTab = tp.children[i];
+ if(thisTab.text != "Art Bindings"){
+ // populate all places where image or graph files are listed (Prepend Paths group)
+ thisTab.populateFields();
+ for (var all in this.window.UITestElements) {
+ thisElem = this.window.UITestElements[all];
+ if(thisElem.hasOwnProperty("key") && thisElem.key == thisTab.key && typeof thisElem.setValue == 'function'){
+ thisElem.setValue(thisTab.contents.disp_foundMissingNum.getValue());
+ }
+ }
+ } else if(tp.selection.text == "Art Bindings" && SESSION.documentExists){
+ // populate the "Find Art" display (Options group)
+ displayFoundArtBindings(parent.window.UITestElements);
+ }
+ }
+ };
+
+ parent.window.UITestElements["testTabs"] = tp;
+
+ return g1;
+};
+
+//-----------------------------------------------------------------------------------------------------------//
+
+function toggleUrlInputVis(ddlist, toggleElem){
+ if(ddlist.selection != null){
+ if(ddlist.selection.text == "Graph" || ddlist.selection.text == "Image"){
+ toggleElem.visible = true;
+ } else {
+ toggleElem.visible = false;
+ }
+ }
+};
+
+function variableOptionsDialog(uiVarObj){
+ var w = new Window("dialog", "Variable " + (uiVarObj.varIndex + 1));
+ w.spacing = 4;
+
+ var g0 = w.add("group");
+
+ var g1 = g0.add("panel", undefined, "Variable Name");
+ var disp_varName = g1.add("edittext", undefined, uiVarObj.varName);
+ disp_varName.size = [229, 30];
+
+ var g2 = g0.add("panel", undefined, "Variable Type");
+ var disp_varType = makeDropdownlist(g2, getPropertyList(VARTYPES));
+ disp_varType.size = [229, 30];
+ disp_varType.setValue(uiVarObj.varType);
+ if(SESSION.imageTest){
+ for(var i = 0; i < disp_varType.items.length; i++){
+ disp_varType.items[i].image = ICONS[disp_varType.items[i]];
+ }
+ }
+ disp_varType.onChange = function(){
+ toggleUrlInputVis(this, disp_url.parent);
+ };
+
+ var disp_url = checkboxFolderPathInput(w, "Prepend Path", "Choose folder directory");
+ disp_url.setValue(uiVarObj.url);
+ disp_url.checkbox.value = (uiVarObj.url.trim() == "") ? false : true;
+
+ var g_btn = w.add("group");
+ var btn_ok = g_btn.add("button", undefined, "Ok");
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+
+ disp_varName.onChanging = function(){
+ if( !isXMLTagName(this.text) ){
+ this.setBg([1, 0.7, 0.7]);
+ this.enabled = false;
+ this.enabled = true;
+ this.active = false;
+ this.active = true;
+ } else {
+ this.setBg([1, 1, 1]);
+ }
+ };
+
+ btn_ok.onClick = function(){
+ if( !DATA.testVariableName( uiVarObj.varName, disp_varName.getValue() ) ){
+ return;
+ }
+ this.window.close();
+ };
+
+ w.onShow = function(){
+ toggleUrlInputVis(disp_varType, disp_url.parent);
+ };
+
+ if(w.show() == 2){
+ return null;
+ } else {
+ var varObj = {
+ varName : disp_varName.getValue(),
+ varType : disp_varType.getValue(),
+ url : (disp_varType.getValue() == "Graph" || disp_varType.getValue() == "Image") ? disp_url.getValue() : "",
+ varIndex : uiVarObj.varIndex
+ };
+ var changed = false;
+ for(var all in uiVarObj){
+ for(var that in varObj){
+ if(uiVarObj[all] != varObj[all]){
+ changed = true;
+ break;
+ }
+ }
+ }
+ return {
+ varObj : varObj,
+ changed : changed
+ };
+ }
+};
+
+function datasetNameFieldComponent(parent, fieldName, datasetObj){
+
+ function toggle(key){
+ if(key == FIELDNAMEOPTIONS_current["customText"].displayText){
+ disp.toggle("editable");
+ disp.editable.active = false;
+ disp.editable.active = true;
+ } else {
+ disp.toggle("readonly");
+ }
+ };
+
+ var customIncNames = getSpecificPropertyListArr(CUSTOM_INCREMENTS_current, "name");
+
+ var g1 = parent.add("panel", undefined, fieldName[0].toUpperCase() + fieldName.substr(1).replace("_", " "));
+ g1.spacing = 4;
+ g1.margins = [2, 8, 2, 2];
+ var dd_options = makeDropdownlist(g1, getSpecificPropertyListObj(FIELDNAMEOPTIONS_current, "displayText"));
+ var thisType = datasetObj[fieldName].type;
+ dd_options.setValue(FIELDNAMEOPTIONS_current[thisType].displayText);
+
+ var g1_2 = g1.add("group");
+ g1_2.orientation = "stacked";
+ var disp = makeEditableReadonlyEdittext(g1_2, 20, datasetObj[fieldName].text);
+ var dd_customInc = makeDropdownlist(g1_2, customIncNames);
+ dd_customInc.size = dd_options.size = [165, 26];
+ if(dd_options.getValue() == "Custom Increment"){
+ dd_customInc.setValue(datasetObj[fieldName].text);
+ disp.element.visible = false;
+ } else {
+ dd_customInc.visible = false;
+ }
+
+ toggle(dd_options.selection.text);
+
+ dd_options.onChange = function(){
+ var sel = this.selection;
+ if(sel.text != "Custom Increment"){
+ dd_customInc.visible = false;
+ disp.element.visible = true;
+ disp.setValue(getSpecificPropertyObj(FIELDNAMEOPTIONS_current, "displayText", sel.text).defaultText);
+ toggle(sel.text);
+ } else {
+ disp.setValue(dd_customInc.selection.text);
+ disp.element.visible = false;
+ dd_customInc.visible = true;
+ }
+ };
+ dd_customInc.onChange = function(){
+ disp.setValue(this.selection.text);
+ };
+ return {
+ typeElem : dd_options,
+ textElem : disp /* re-use the disp text to hold the custom inc name */
+ };
+};
+
+function getDatasetNamePreviewString(){
+ var str = "";
+ for(var all in DATASETNAMEFIELDS_current){
+ str += DATASETNAMEFIELDS_current[all].text;
+ }
+ return str;
+};
+
+function datasetAssignDialog(datasetObjOrig){
+
+ function getUIDsNameFieldObj(tempObj){
+ for(var all in tempObj){
+ var type = getSpecificPropertyObj(FIELDNAMEOPTIONS_current, "displayText", tempObj[all].typeElem.getValue()).type;
+ resObj[all] = {
+ type : type,
+ text : tempObj[all].textElem.getValue()
+ };
+ }
+ return resObj;
+ };
+
+ var processedDatasetNameFieldsResult = clearOutOfBoundVariables(clone(datasetObjOrig));
+ var datasetObj = processedDatasetNameFieldsResult.obj;
+ if(WARNINGSETTINGS.showDatasetNamingWarning && processedDatasetNameFieldsResult.msg != ""){
+ quickView(processedDatasetNameFieldsResult.msg, "Dataset naming field errors.");
+ }
+
+ var w = new Window("dialog", "Assign Dataset Names");
+ w.spacing = 4;
+ w.margins = [4, 4, 4, 4];
+ var resObj = {}, tempObj = {};
+ var g0 = w.add("panel");
+ g0.spacing = 4;
+ g0.margins = [4, 4, 4, 4];
+ var g0_1 = g0.add("group");
+ g0_1.spacing = 2;
+ var g0_2 = g0.add("group");
+ g0_2.spacing = 2;
+ var groups = [g0_1, g0_2];
+ var c = 0, cg = 0;
+ for(var all in datasetObj){
+ cg = (c < 3) ? 0 : 1;
+ tempObj[all] = datasetNameFieldComponent(groups[cg], all, datasetObj);
+ c++;
+ };
+
+ var g_btn = w.add("group");
+ if(DATA.currentVars.length > 0){
+ var btn_test = g_btn.add("button", undefined, "Test Dataset Names");
+ btn_test.onClick = function(){
+ DATA.getCurrentGrid();
+ // quickView(DATA.getTestDatasetNames(getUIDsNameFieldObj(tempObj)).join("\n"), "Dataset Names:", [300, 450]);
+ var testData = DATA.getTestDatasetNames(getUIDsNameFieldObj(tempObj)).join("\n");
+ simpleShowModal(TestManager.datasetNames.makeUIContents, {
+ title : "Dataset Name List",
+ data : testData,
+ size : [300, 450]
+ });
+ };
+ btn_test.helpTip = "Get full list of dataset names.";
+ }
+ var btn_ok = g_btn.add("button", undefined, "Ok");
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+
+ btn_ok.onClick = function(){
+ var isValid = false, type;
+ for(var all in tempObj){
+ type = getSpecificPropertyObj(FIELDNAMEOPTIONS_current, "displayText", tempObj[all].typeElem.getValue()).type;
+ if(type != "nothing"){
+ isValid = true;
+ w.close();
+ }
+ }
+ if(!isValid){
+ scriptAlert("Dataset fields cannot all be set to 'nothing'.");
+ }
+ };
+
+ w.onShow = function(){
+
+ };
+
+ if(w.show() == 2){
+ return null;
+ } else {
+ return getUIDsNameFieldObj(tempObj);
+ }
+};
+
+function finishedXMLFileDialog(xmlDest, varsNum, recordsNum){
+ var w = new Window("dialog", SESSION.scriptName + ": XML File created.");
+
+ var msg = "Your XML file has been created.\rIt contains " + varsNum +
+ " variable" + ((varsNum > 1)? "s" : "") + " and " + recordsNum + " record" + ((recordsNum > 1) ? "s" : "") + ".";
+
+ var l = w.add("statictext", undefined, msg, {multiline : true});
+ l.size = [260, 100];
+
+ var e = w.add("edittext", undefined, decodeURI(xmlDest), {readonly : true});
+ e.characters = 40;
+ e.helpTip = decodeURI(xmlDest);
+ var g_btn = w.add("group");
+ var btn_ok = g_btn.add("button", undefined, "Ok");
+ var btn_reveal = g_btn.add("button", undefined, "Reveal in File System");
+
+ btn_reveal.onClick = function(){
+ Folder(File(e.text).parent).execute();
+ w.close();
+ }
+ w.show();
+};
+
+function finishedXMLImportDialog(varsNum, recordsNum, missingImgNum, missingGrfNum){
+ var w = new Window("dialog", SESSION.scriptName + ": Variable Data Imported.");
+
+ var msg = "Your variable data has been imported.\rIt contains " + varsNum +
+ " variable" + ((varsNum > 1)? "s" : "") + " and " + recordsNum + " record" + ((recordsNum > 1) ? "s" : "") + ".";
+
+ var l = w.add("statictext", undefined, msg, {multiline : true});
+ l.size = [260, 50];
+
+ if(missingImgNum > 0){
+ l = w.add("statictext", undefined, missingImgNum + " Missing Image(s)", {multiline : true});
+ l.size = [260, 100];
+ } else if(missingGrfNum > 0){
+ l = w.add("statictext", undefined, missingGrfNum + " Missing Graph(s)", {multiline : true});
+ l.size = [260, 100];
+ } else {
+ var g_cycle = w.add("group");
+ var btn_cycle = g_cycle.add("button", undefined, "Cycle Update All Datasets");
+ btn_cycle.helpTip = "Cycling and updating each of the datasets ensures that update-asterisks will appear correctly";
+ var disp_cycle = g_cycle.add('edittext { properties : {readonly : true}, justify : "center" }');
+ disp_cycle.characters = 10;
+ disp_cycle.setValue("0 of " + app.activeDocument.dataSets.length);
+ btn_cycle.onClick = function(){
+ cycleUpdateAllDatasets(app.activeDocument, disp_cycle);
+ };
+ }
+
+ var g_btn = w.add("group");
+ var btn_ok = g_btn.add("button", undefined, "Ok");
+
+ w.show();
+};
+
+//---------------------------------------------------------------------------------------- CUSTOM INCREMENTS ------------------------------------------------------------------//
+function updateCustomIncrementDisplay(display, customIncObj){
+ var arr = [], prefixStr;
+ for (var i = 0; i < 10; i++) {
+ prefixStr = " " + (i + 1) + ": "; // adds a number to tell the index in the display area text
+ if((i + 1).toString().length > 1){
+ prefixStr = (i + 1) + ": ";
+ }
+ arr.push(prefixStr + getRecordCustomInc(i, customIncObj.startNum, customIncObj.padZero, customIncObj.increment, customIncObj.isIntervalIncrement));
+ }
+ display.setValue(arr.join("\n"));
+};
+
+function customIncrementsDialog(){
+
+ var dialogData = clone(CUSTOM_INCREMENTS_current);
+ var customIncNames = [];
+ for (var i = 0; i < dialogData.length; i++) {
+ customIncNames.push(dialogData[i].name);
+ }
+
+ var w = new Window("dialog", "Custom Increment Options");
+ w.spacing = 4;
+
+ var g0 = w.add("group");
+ g0.orientation = "row";
+
+ var g1 = g0.add("group");
+ var g1_1 = g1.add("group");
+ g1_1.orientation = "column";
+ var lbl_customIncList = g1_1.add("statictext", undefined, "Custom Increment List");
+ var list_customIncs = g1_1.add("listbox", undefined, customIncNames);
+ list_customIncs.size = [195, 280];
+ var g1_1_2 = g1_1.add("group");
+ g1_1_2.orientation = "row";
+ g1_1_2.margins = [4, 4, 4, 10];
+ var btn_addCustomInc = g1_1_2.add("button", undefined, "Add \u2795");
+ var btn_removeCustomInc = g1_1_2.add("button", undefined, "Remove \u2796");
+ btn_addCustomInc.size = btn_removeCustomInc.size = [80, 25];
+
+ var g2a = g0.add("group");
+ g2a.orientation = "column";
+ var g2 = g2a.add("panel", undefined, "Properties");
+ g2.spacing = 4;
+ g2.alignChildren = "left";
+ var g2_1 = g2.add("group");
+ var lbl_startNum = g2_1.add("statictext", undefined, "Start Number");
+ lbl_startNum.size = [120, 26];
+ var disp_startNum = g2_1.add("edittext", undefined, "");
+ disp_startNum.characters = 10;
+ disp_startNum.onChange = function(){
+ var val = this.getValue();
+ var msg = "Please enter a zero, or a positive integer number into the 'Start Number' field.";
+ if(isNaN(val) || !/^\d+$/.test(val)){
+ scriptAlert(msg);
+ this.setValue(0);
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : this.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ return;
+ } else {
+ if(val != "0" && val.indexOf("0") > -1){
+ val = val.replace(/^0+/, "");
+ if(val == ""){
+ val = 0; // put it back to zero if the entered string was all zeroes
+ }
+ }
+ this.setValue(val);
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : this.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ }
+ };
+
+ var g2_1a = g2.add("group");
+ var lbl_incValue = g2_1a.add("statictext", undefined, "Increment Value");
+ lbl_incValue.size = [120, 26];
+ var disp_incValue = g2_1a.add("edittext", undefined, "");
+ disp_incValue.characters = 10;
+ disp_incValue.onChange = function(){
+ var val = this.getValue();
+ var msg = "Please enter a positive integer number into the 'Increment Value' field.";
+ if(isNaN(val) || !/^\d+$/.test(val) || (val * 1) <= 0){
+ scriptAlert(msg);
+ this.setValue(1);
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : this.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ return;
+ } else {
+ this.setValue(val);
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : disp_startNum.getValue(),
+ increment : this.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ }
+ };
+
+ var g2_1b = g2.add("group");
+ var ch_intervalIncrement = g2_1b.add("checkbox", undefined, "Make Interval Increment");
+ ch_intervalIncrement.helpTip = "Adds a dash with the next value of the incremented position after the specified increment amount has been added. ex: 1-10, 11-20";
+ ch_intervalIncrement.onChange = function(){
+ var val = this.getValue();
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : disp_startNum.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : val
+ });
+ };
+
+ var g2_2 = g2.add("group");
+ var lbl_padZero = g2_2.add("statictext", undefined, "Padding Zeroes");
+ lbl_padZero.size = [120, 26];
+ var dd_padZero = makeDropdownlist(g2_2, [0,1,2,3,4,5,6,7,8,9,10,11,12,13]);
+ dd_padZero.characters = 10;
+ dd_padZero.onChange = function(){
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : this.getValue(),
+ startNum : disp_startNum.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ };
+ var g2_3 = g2a.add("panel", undefined, "Preview Display");
+ g2_3.margins = [6, 6, 6, 6];
+ var disp_preview = g2_3.add("edittext", undefined, "", { multiline : true, readonly : true });
+ disp_preview.size = [240, 160];
+
+ var g_btn = w.add("group");
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+ var btn_ok = g_btn.add("button", undefined, "Save");
+
+ list_customIncs.onChange = function(){
+ if(this.selection != null){
+ dd_padZero.setValue(dialogData[this.selection.index].padZero);
+ disp_startNum.setValue(dialogData[this.selection.index].startNum);
+ disp_incValue.setValue(dialogData[this.selection.index].increment);
+ ch_intervalIncrement.setValue(dialogData[this.selection.index].isIntervalIncrement);
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : disp_startNum.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : ch_intervalIncrement.getValue()
+ });
+ }
+ };
+
+ g2.addEventListener("mousedown", function(){
+ list_customIncs.selection = null;
+ });
+
+ ch_intervalIncrement.onClick = function(){
+ updateCustomIncrementDisplay(disp_preview, {
+ padZero : dd_padZero.getValue(),
+ startNum : disp_startNum.getValue(),
+ increment : disp_incValue.getValue(),
+ isIntervalIncrement : this.getValue()
+ });
+ };
+
+ btn_addCustomInc.onClick = function(){
+ var startNumValue = disp_startNum.getValue();
+ var padZeroValue = dd_padZero.getValue();
+ var incrementValue = disp_incValue.getValue();
+ var isIntervalIncrement = ch_intervalIncrement.getValue();
+ if(startNumValue == "" || padZeroValue == "" || incrementValue == ""){
+ scriptAlert("Please ensure the 'Increment Value' and 'Start Number' fields are filled.");
+ return;
+ }
+ var newName = "s" + startNumValue + "p" + padZeroValue + "i" + incrementValue + (isIntervalIncrement ? "-interval" : "");
+ dialogData.push({
+ name : newName,
+ padZero : padZeroValue,
+ startNum : startNumValue,
+ increment : incrementValue,
+ isIntervalIncrement : isIntervalIncrement
+ });
+ list_customIncs.addItem(newName);
+ };
+
+ btn_removeCustomInc.onClick = function(){
+ if(list_customIncs.selection == null){
+ return;
+ }
+ dialogData.splice(list_customIncs.selection.index, 1);
+ list_customIncs.removeSelectedItem();
+ };
+
+ btn_ok.onClick = function(){
+ if(dialogData.length < 1){
+ scriptAlert("At least one custom increment must be present in the list to save.");
+ return;
+ } else {
+ // only save the custom increment portion of the settings file
+ SESSION.settingsFile.open('r');
+ var settingsObj = JSON.parse(SESSION.settingsFile.read());
+ SESSION.settingsFile.close();
+ CUSTOM_INCREMENTS_current = settingsObj.CUSTOM_INCREMENTS = dialogData;
+ writeSettingsFile(settingsObj);
+ }
+ this.window.close();
+ };
+
+ if(w.show() == 2){
+ return null;
+ } else {
+ return {
+
+ };
+ }
+};
+
+//---------------------------------------------------------------------------------------- VISIBILITY KEYS ------------------------------------------------------------------//
+function populateVisKeyList(listElem, visKeys){
+ for (var i = listElem.items.length - 1; i > -1; i--) {
+ listElem.remove(i);
+ }
+ var thisVisKey, newItem;
+ for (var i = 0; i < visKeys.length; i++) {
+ thisVisKey = visKeys[i];
+ newItem = listElem.add("item");
+ newItem.text = thisVisKey.name;
+ newItem.subItems[0].text = thisVisKey.displayText;
+ newItem.checked = thisVisKey.enabled;
+ }
+};
+
+function visibilityKeysDialog(){
+
+ var textInputHelpTip = "Visibility Key 'text' is compared to data cell text in lower-case.";
+
+ function getBothSetsOfKeys(visKeyObj){
+ var trueVisKeys = [], falseVisKeys = [];
+ var thisVisKey;
+ for (var i = 0; i < visKeyObj.length; i++) {
+ thisVisKey = visKeyObj[i];
+ if(thisVisKey.value){
+ trueVisKeys.push(thisVisKey);
+ } else {
+ falseVisKeys.push(thisVisKey);
+ }
+ }
+ return { trueVisKeys : trueVisKeys, falseVisKeys : falseVisKeys };
+ };
+
+ var dialogData = clone(VisibilityKeys);
+ var keyData = getBothSetsOfKeys(dialogData);
+ var trueVisKeys = keyData.trueVisKeys, falseVisKeys = keyData.falseVisKeys;
+
+ var w = new Window("dialog", "Manage Visibility Keys");
+ w.spacing = 4;
+ var inputCharacterAmt = 10;
+
+ var g0 = w.add("group");
+ g0.orientation = "row";
+
+ var g1 = g0.add("group");
+ var g1_1 = g1.add("group");
+ g1_1.orientation = "column";
+
+ var lbl_trueList = g1_1.add("statictext", undefined, "true / visible");
+ var list_trueList = g1_1.add("listbox", undefined, [], {
+ numberOfColumns: 2,
+ showHeaders: true,
+ columnTitles: ["Name", "Text"],
+ columnWidths: [120, 120]
+ });
+ list_trueList.size = [260, 200];
+ list_trueList.name = "True List"; // custom property
+
+ var g1_1_2a = g1_1.add("group");
+ g1_1_2a.orientation = "row";
+ g1_1_2a.spacing = 4;
+ var g1_1_2a_1 = g1_1_2a.add("group");
+ g1_1_2a_1.orientation = "column";
+ g1_1_2a_1.spacing = 4;
+ var lbl_trueKeyName = g1_1_2a_1.add("statictext", undefined, "name");
+ var disp_trueKeyName = g1_1_2a_1.add("edittext", undefined, "");
+ disp_trueKeyName.characters = inputCharacterAmt;
+ disp_trueKeyName.list = list_trueList;
+
+ var g1_1_2a_2 = g1_1_2a.add("group");
+ g1_1_2a_2.orientation = "column";
+ g1_1_2a_2.spacing = 4;
+ var lbl_trueKeyText = g1_1_2a_2.add("statictext", undefined, "text");
+ var disp_trueKeyText = g1_1_2a_2.add("edittext", undefined, "");
+ disp_trueKeyText.helpTip = textInputHelpTip;
+ disp_trueKeyText.characters = inputCharacterAmt;
+ disp_trueKeyText.list = list_trueList;
+
+ var g1_1_2 = g1_1.add("group");
+ g1_1_2.orientation = "row";
+ g1_1_2.margins = [4, 4, 4, 10];
+ var btn_addTrueVisKey = g1_1_2.add("button", undefined, "Add \u2795");
+ var btn_removeTrueVisKey = g1_1_2.add("button", undefined, "Remove \u2796");
+ btn_addTrueVisKey.size = btn_removeTrueVisKey.size = [80, 25];
+ btn_addTrueVisKey.list = btn_removeTrueVisKey.list = list_trueList;
+
+ var sep = g1.add("panel");
+ sep.size = [2, 300];
+ var g1_2 = g1.add("group");
+ g1_2.orientation = "column";
+
+ var lbl_falseList = g1_2.add("statictext", undefined, "false / invisible");
+ var list_falseList = g1_2.add("listbox", undefined, [], {
+ numberOfColumns: 2,
+ showHeaders: true,
+ columnTitles: ["Name", "Text"],
+ columnWidths: [120, 120]
+ });
+ list_falseList.size = [260, 200];
+ list_falseList.name = "False List"; // custom property
+
+ var g1_2_2a = g1_2.add("group");
+ g1_2_2a.orientation = "row";
+ g1_2_2a.spacing = 4;
+ var g1_2_2a_1 = g1_2_2a.add("group");
+ g1_2_2a_1.orientation = "column";
+ g1_2_2a_1.spacing = 4;
+ var lbl_falseKeyName = g1_2_2a_1.add("statictext", undefined, "name");
+ var disp_falseKeyName = g1_2_2a_1.add("edittext", undefined, "");
+ disp_falseKeyName.characters = inputCharacterAmt;
+ disp_falseKeyName.list = list_falseList;
+
+ var g1_2_2a_2 = g1_2_2a.add("group");
+ g1_2_2a_2.orientation = "column";
+ g1_2_2a_2.spacing = 4;
+ var lbl_falseKeyText = g1_2_2a_2.add("statictext", undefined, "text");
+ var disp_falseKeyText = g1_2_2a_2.add("edittext", undefined, "");
+ disp_falseKeyText.helpTip = textInputHelpTip;
+ disp_falseKeyText.characters = inputCharacterAmt;
+ disp_falseKeyText.list = list_falseList;
+
+ var g1_2_2 = g1_2.add("group");
+ g1_2_2.orientation = "row";
+ g1_2_2.margins = [4, 4, 4, 10];
+ var btn_addFalseVisKey = g1_2_2.add("button", undefined, "Add \u2795");
+ var btn_removeFalseVisKey = g1_2_2.add("button", undefined, "Remove \u2796");
+ btn_addFalseVisKey.size = btn_removeFalseVisKey.size = [80, 25];
+ btn_addFalseVisKey.list = btn_removeFalseVisKey.list = list_falseList;
+
+ var btns = [btn_addTrueVisKey, btn_removeTrueVisKey, btn_addFalseVisKey, btn_removeFalseVisKey];
+ var thisBtn;
+ for (var i = 0; i < btns.length; i++) {
+ thisBtn = btns[i];
+ thisBtn.onClick = function(){
+ var self = this;
+ return function (self){
+ var list = self.list;
+ var isTrueList = list.name == "True List";
+ var isAddBtn = self.text == "Add \u2795";
+ // check the list data against memory object to give the OK button a save-&-apply or only-apply functionality.
+ // add/remove item
+ if(isAddBtn){
+ var isValidAddition, thisValueInputElem, thisNameInputElem, problem;
+ if(isTrueList){
+ thisValueInputElem = disp_trueKeyText;
+ thisNameInputElem = disp_trueKeyName;
+ } else {
+ thisValueInputElem = disp_falseKeyText;
+ thisNameInputElem = disp_falseKeyName;
+ }
+ try {
+ problem = "VisibilityKeys - please fill out all necessary fields before adding a new key.";
+ isValidAddition = (thisNameInputElem.getValue().trim() != "");
+ if(!isValidAddition){
+ throw(problem);
+ }
+ var allPresentListNames = [];
+ for (var i = 0; i < list.items.length; i++) {
+ thisName = list.items[i].text;
+ allPresentListNames.push(thisName);
+ }
+ problem = "VisibilityKeys - please choose a different name for the new key to add to the list.";
+ isValidAddition = (allPresentListNames.indexOf(thisNameInputElem.getValue()) == -1);
+ if(isValidAddition){
+ var newItem = list.add("item");
+ newItem.text = thisNameInputElem.getValue(); // name
+ newItem.subItems[0].text = thisValueInputElem.getValue().toLowerCase(); // text
+ newItem.checked = true;
+ } else {
+ throw(problem);
+ }
+ } catch(e) {
+ scriptAlert(e);
+ return;
+ }
+ } else {
+ if(list.selection == null){
+ return;
+ }
+ if(list.items.length > 1){
+ list.selection.remove();
+ }
+ }
+
+ var keyData = getBothSetsOfKeys(VisibilityKeys);
+ var trueVisKeys = keyData.trueVisKeys, falseVisKeys = keyData.falseVisKeys;
+ var targetKeys = (isTrueList) ? trueVisKeys : falseVisKeys;
+ var isCompleteMatch = true;
+ var thisName, thisText;
+ for (var i = 0; i < list.items.length; i++) {
+ thisName = list.items[i].text;
+ thisText = list.items[i].subItems[0].text;
+ if(getByName(targetKeys, thisName) == null){
+ isCompleteMatch = false;
+ break;
+ }
+ }
+ var thisCompareName, wasMatched;
+ for (var i = 0; i < targetKeys.length; i++) {
+ thisCompareName = targetKeys[i].name;
+ wasMatched = false;
+ for (var j = 0; j < list.items.length; j++) {
+ thisName = list.items[j].text;
+ thisText = list.items[j].subItems[0].text;
+ if(thisName == thisCompareName){
+ wasMatched = true;
+ break;
+ } else if(!wasMatched && j == list.items.length - 1){
+ isCompleteMatch = false;
+ break;
+ }
+ }
+ }
+ if(isCompleteMatch){
+ btn_ok.text = "Apply";
+ } else {
+ btn_ok.text = "Save & Apply";
+ }
+ }(self);
+ };
+ }
+
+ list_trueList.onDoubleClick = list_falseList.onDoubleClick = function(){
+ if(this.selection != null){
+ this.selection.checked = !this.selection.checked;
+ }
+ };
+ var firstFocus = true;
+ w.addEventListener("mouseover", function(){
+ if(firstFocus){
+ list_falseList.active = true;
+ list_trueList.active = true;
+ firstFocus = false;
+ }
+ });
+
+ var g_btn = w.add("group");
+ var btn_ccl = g_btn.add("button", undefined, "Cancel");
+ var btn_ok = g_btn.add("button", undefined, "Apply");
+ btn_ccl.size = btn_ok.size = [180, 26];
+
+ btn_ok.onClick = function(){
+ var resultData = [], thisItem, keyObj;
+ for (var i = 0; i < list_trueList.items.length; i++) {
+ thisItem = list_trueList.items[i];
+ keyObj = {
+ displayText : thisItem.subItems[0].text,
+ name : thisItem.text,
+ value : true,
+ enabled : thisItem.checked
+ };
+ resultData.push(keyObj);
+ }
+ for (var i = 0; i < list_falseList.items.length; i++) {
+ thisItem = list_falseList.items[i];
+ keyObj = {
+ displayText : thisItem.subItems[0].text,
+ name : thisItem.text,
+ value : false,
+ enabled : thisItem.checked
+ };
+ resultData.push(keyObj);
+ }
+ VisibilityKeys = resultData;
+ if(this.text == "Save & Apply"){
+ SESSION.settingsFile.open('r');
+ var settingsObj = JSON.parse(SESSION.settingsFile.read());
+ SESSION.settingsFile.close();
+ settingsObj.VisibilityKeys = VisibilityKeys;
+ writeSettingsFile(settingsObj);
+ }
+ this.window.close();
+ };
+
+ w.onShow = function(){
+ populateVisKeyList(list_trueList, trueVisKeys);
+ populateVisKeyList(list_falseList, falseVisKeys);
+ };
+
+ if(w.show() == 2){
+ return null;
+ } else {
+ return {
+
+ };
+ }
+};
+
+//==================================================================================//
+
+ var userData = UIWindow();
+ if(userData == null){
+ // abort mission
+ return;
+ }
+
+ processUserInput(userData);
+
+};
+
+VariableImporter();
+
diff --git a/qosf.org/designs/infograph_creator/create_grid.sh b/qosf.org/designs/infograph_creator/create_grid.sh
new file mode 100644
index 0000000..68905f7
--- /dev/null
+++ b/qosf.org/designs/infograph_creator/create_grid.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Check for the correct number of arguments
+if [ "$#" -ne 3 ]; then
+ echo "Usage: $0 grid_size input_dir output_filename"
+ exit 1
+fi
+
+# Assign input parameters to variables
+GRID_SIZE=$1
+INPUT_DIR=$2
+OUTPUT_FILENAME=$3
+
+# Create the montage
+montage -tile "$GRID_SIZE" -geometry +0+0 "${INPUT_DIR}"/*.png "$OUTPUT_FILENAME"
+
+# Inform the user of completion
+echo "Montage created successfully: $OUTPUT_FILENAME"
+
+# Example usage
+# This script creates a grid montage of PNG images from a specified directory.
+# Usage:
+# ./create_image_grid.sh 3x2 /path/to/input/directory output.png
+# Where "3x2" is the grid size, "/path/to/input/directory" is the path where PNG images are stored,
+# and "output.png" is the name of the output file to be created.
diff --git a/qosf.org/designs/infograph_creator/project_card.ai b/qosf.org/designs/infograph_creator/project_card.ai
new file mode 100644
index 0000000..6469c4e
--- /dev/null
+++ b/qosf.org/designs/infograph_creator/project_card.ai
@@ -0,0 +1,2334 @@
+%PDF-1.6
%
+1 0 obj
<>/OCGs[28 0 R 29 0 R 30 0 R 31 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<>stream
+
+
+
+
+ application/pdf
+
+
+ quantum_proj
+
+
+ Adobe Illustrator 25.0 (Macintosh)
+ 2024-06-05T21:00:57-06:00
+ 2024-06-05T21:00:58-06:00
+ 2024-06-05T21:00:58-06:00
+
+
+
+ 172
+ 256
+ JPEG
+ /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAACsAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9LZe1OxV2KuxV2KuxV2K
uxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kq3/Hr/sv4ZHqnoo5JDsVdirsVdirsVdirsVdirsVd
irsVdirsVdirsVdirsVdirsVdiqt/wAev+y/hkeqeijkkOxV2KuxV2KuxV2KqVxdW9tH6kzhF7V6
n5DFUlu/M4pxtIzX+eT+ABw0hKZ9Sv5yfUnYg/sg8V+4bYaVDdcVbVmU1UkHxG2Koy21nUYCOMpd
R+y/xD8d8aVOLbzNauALhGicmhYfEvz8fwwUqcKysoZSCp3BG4OBLeKuxV2KuxV2KuxVW/49f9l/
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
+
+
+
+ proof:pdf
+ uuid:65E6390686CF11DBA6E2D887CEACB407
+ xmp.did:21a34c62-1b83-4b16-a2c8-f9ca6c72273b
+ uuid:d5f4fa80-a457-0f4a-96d5-8273bf3d0213
+
+ xmp.iid:cd36669d-5f8b-409c-8af3-ab20958ce1a1
+ xmp.did:cd36669d-5f8b-409c-8af3-ab20958ce1a1
+ uuid:65E6390686CF11DBA6E2D887CEACB407
+ default
+
+
+
+
+ saved
+ xmp.iid:7abf885d-2140-4aa2-aa57-d3771451c328
+ 2024-06-05T00:51:24-06:00
+ Adobe Illustrator 25.0 (Macintosh)
+ /
+
+
+ saved
+ xmp.iid:21a34c62-1b83-4b16-a2c8-f9ca6c72273b
+ 2024-06-05T18:36:18-06:00
+ Adobe Illustrator 25.0 (Macintosh)
+ /
+
+
+
+
+
+
+ EmbedByReference
+
+ /Users/luisjcamargo/Desktop/quantum/qutip.png
+ 0
+ 0
+
+
+
+ EmbedByReference
+
+ /Users/luisjcamargo/Desktop/quantum/qutipcorp.png
+ 0
+ 0
+
+
+
+
+
+
+
+ /Users/luisjcamargo/Desktop/quantum/qutip.png
+ 0
+ 0
+
+
+ /Users/luisjcamargo/Desktop/quantum/qutipcorp.png
+ 0
+ 0
+
+
+
+ Web
+ AIRobin
+ Document
+ Adobe PDF library 15.00
+ 21.0.0
+ 1
+ True
+ False
+
+ 720.000000
+ 1080.000000
+ Pixels
+
+
+
+
+ Montserrat-Medium
+ Montserrat
+ Medium
+ TrueType
+ Version 7.200
+ False
+ Montserrat-Medium.ttf
+
+
+ Montserrat-Bold
+ Montserrat
+ Bold
+ TrueType
+ Version 7.200
+ False
+ Montserrat-Bold.ttf
+
+
+ Montserrat-Black
+ Montserrat
+ Black
+ TrueType
+ Version 7.200
+ False
+ Montserrat-Black.ttf
+
+
+
+
+
+ Cyan
+ Magenta
+ Yellow
+ Black
+
+
+
+
+
+ Default Swatch Group
+ 0
+
+
+
+ White
+ RGB
+ PROCESS
+ 255
+ 255
+ 255
+
+
+ Black
+ RGB
+ PROCESS
+ 0
+ 0
+ 0
+
+
+ RGB Red
+ RGB
+ PROCESS
+ 255
+ 0
+ 0
+
+
+ RGB Yellow
+ RGB
+ PROCESS
+ 255
+ 255
+ 0
+
+
+ RGB Green
+ RGB
+ PROCESS
+ 0
+ 255
+ 0
+
+
+ RGB Cyan
+ RGB
+ PROCESS
+ 0
+ 255
+ 255
+
+
+ RGB Blue
+ RGB
+ PROCESS
+ 0
+ 0
+ 255
+
+
+ RGB Magenta
+ RGB
+ PROCESS
+ 255
+ 0
+ 255
+
+
+ R=193 G=39 B=45
+ RGB
+ PROCESS
+ 193
+ 39
+ 45
+
+
+ R=237 G=28 B=36
+ RGB
+ PROCESS
+ 237
+ 28
+ 36
+
+
+ R=241 G=90 B=36
+ RGB
+ PROCESS
+ 241
+ 90
+ 36
+
+
+ R=247 G=147 B=30
+ RGB
+ PROCESS
+ 247
+ 147
+ 30
+
+
+ R=251 G=176 B=59
+ RGB
+ PROCESS
+ 251
+ 176
+ 59
+
+
+ R=252 G=238 B=33
+ RGB
+ PROCESS
+ 252
+ 238
+ 33
+
+
+ R=217 G=224 B=33
+ RGB
+ PROCESS
+ 217
+ 224
+ 33
+
+
+ R=140 G=198 B=63
+ RGB
+ PROCESS
+ 140
+ 198
+ 63
+
+
+ R=57 G=181 B=74
+ RGB
+ PROCESS
+ 57
+ 181
+ 74
+
+
+ R=0 G=146 B=69
+ RGB
+ PROCESS
+ 0
+ 146
+ 69
+
+
+ R=0 G=104 B=55
+ RGB
+ PROCESS
+ 0
+ 104
+ 55
+
+
+ R=34 G=181 B=115
+ RGB
+ PROCESS
+ 34
+ 181
+ 115
+
+
+ R=0 G=169 B=157
+ RGB
+ PROCESS
+ 0
+ 169
+ 157
+
+
+ R=41 G=171 B=226
+ RGB
+ PROCESS
+ 41
+ 171
+ 226
+
+
+ R=0 G=113 B=188
+ RGB
+ PROCESS
+ 0
+ 113
+ 188
+
+
+ R=46 G=49 B=146
+ RGB
+ PROCESS
+ 46
+ 49
+ 146
+
+
+ R=27 G=20 B=100
+ RGB
+ PROCESS
+ 27
+ 20
+ 100
+
+
+ R=102 G=45 B=145
+ RGB
+ PROCESS
+ 102
+ 45
+ 145
+
+
+ R=147 G=39 B=143
+ RGB
+ PROCESS
+ 147
+ 39
+ 143
+
+
+ R=158 G=0 B=93
+ RGB
+ PROCESS
+ 158
+ 0
+ 93
+
+
+ R=212 G=20 B=90
+ RGB
+ PROCESS
+ 212
+ 20
+ 90
+
+
+ R=237 G=30 B=121
+ RGB
+ PROCESS
+ 237
+ 30
+ 121
+
+
+ R=199 G=178 B=153
+ RGB
+ PROCESS
+ 199
+ 178
+ 153
+
+
+ R=153 G=134 B=117
+ RGB
+ PROCESS
+ 153
+ 134
+ 117
+
+
+ R=115 G=99 B=87
+ RGB
+ PROCESS
+ 115
+ 99
+ 87
+
+
+ R=83 G=71 B=65
+ RGB
+ PROCESS
+ 83
+ 71
+ 65
+
+
+ R=198 G=156 B=109
+ RGB
+ PROCESS
+ 198
+ 156
+ 109
+
+
+ R=166 G=124 B=82
+ RGB
+ PROCESS
+ 166
+ 124
+ 82
+
+
+ R=140 G=98 B=57
+ RGB
+ PROCESS
+ 140
+ 98
+ 57
+
+
+ R=117 G=76 B=36
+ RGB
+ PROCESS
+ 117
+ 76
+ 36
+
+
+ R=96 G=56 B=19
+ RGB
+ PROCESS
+ 96
+ 56
+ 19
+
+
+ R=66 G=33 B=11
+ RGB
+ PROCESS
+ 66
+ 33
+ 11
+
+
+
+
+
+ Grays
+ 1
+
+
+
+ R=0 G=0 B=0
+ RGB
+ PROCESS
+ 0
+ 0
+ 0
+
+
+ R=26 G=26 B=26
+ RGB
+ PROCESS
+ 26
+ 26
+ 26
+
+
+ R=51 G=51 B=51
+ RGB
+ PROCESS
+ 51
+ 51
+ 51
+
+
+ R=77 G=77 B=77
+ RGB
+ PROCESS
+ 77
+ 77
+ 77
+
+
+ R=102 G=102 B=102
+ RGB
+ PROCESS
+ 102
+ 102
+ 102
+
+
+ R=128 G=128 B=128
+ RGB
+ PROCESS
+ 128
+ 128
+ 128
+
+
+ R=153 G=153 B=153
+ RGB
+ PROCESS
+ 153
+ 153
+ 153
+
+
+ R=179 G=179 B=179
+ RGB
+ PROCESS
+ 179
+ 179
+ 179
+
+
+ R=204 G=204 B=204
+ RGB
+ PROCESS
+ 204
+ 204
+ 204
+
+
+ R=230 G=230 B=230
+ RGB
+ PROCESS
+ 230
+ 230
+ 230
+
+
+ R=242 G=242 B=242
+ RGB
+ PROCESS
+ 242
+ 242
+ 242
+
+
+
+
+
+ Web Color Group
+ 1
+
+
+
+ R=63 G=169 B=245
+ RGB
+ PROCESS
+ 63
+ 169
+ 245
+
+
+ R=122 G=201 B=67
+ RGB
+ PROCESS
+ 122
+ 201
+ 67
+
+
+ R=255 G=147 B=30
+ RGB
+ PROCESS
+ 255
+ 147
+ 30
+
+
+ R=255 G=29 B=37
+ RGB
+ PROCESS
+ 255
+ 29
+ 37
+
+
+ R=255 G=123 B=172
+ RGB
+ PROCESS
+ 255
+ 123
+ 172
+
+
+ R=189 G=204 B=212
+ RGB
+ PROCESS
+ 189
+ 204
+ 212
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
endstream
endobj
3 0 obj
<>
endobj
5 0 obj
<>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text/ImageC/ImageI]/Properties<>/XObject<>>>/Thumb 46 0 R/TrimBox[0.0 0.0 720.0 1080.0]/Type/Page>>
endobj
33 0 obj
<>stream
+HUKo1Wqgi
+e%C mi{Ə,R"ofl?O`|=A8;Of=b=~K] w^\\GGnKF/I3H8~F8ߊsƜsCTv`(IO)eC%pk$`g>`N(hJAo0Do,EJN#VIdz(ӊLzi/*s'V.]9gmY+mCn%vNLKkNgkQ?OqV7LxApO+{K^zHOx/f?/qj.Ȫhά^]
+C7Y
+rgu2Õ$C % jz5B־f/h}9F vٍ7,7pS;y~JYg9=,7iv>!dn $ 7t
1p= 'V*;j&>jtNf'A'6N:IXTj?Y맭[+u@Eޝ/t/>m{''iMĂ7!>]y A5Yi)(p`&,F풝a?.G7NY@}? 3$s
endstream
endobj
34 0 obj
<>
endobj
46 0 obj
<>stream
+8;Z\741:n<$nYV@<@'/`=/D*:Na%*s1Jpb,?
+&r8O+bN;Q6B6]#l6]8/&=h^DXb:2:aSCe=N2>8t(C[G6X1OL(^KA)@VKl42Z*TB`3
+UM^>3;BrK$Nd+;"Ohu;477JQW0#".Q$^d`tD8&C@I".!/?dEL,I*k`^&_lA>P8C/?
+UIJ"J7iQhYTHO(T+eqJe&i!!HBjB'F='i(+Y+btC\sA6/esD]6(5fb+?WN]$\5;+,5)S'WFCq@2,&6GMa&?('/9B6_4piZ5$G02@
+#o,TFnQ!]dX*ZZuW/<+>4]Pda3B#iV[^m4[1jQH*^T;^&W8:hA*?J!KFNMV"LoMXi
+gT/;26tc%MoY"mb"gmUOrMJUqUn-JdqtoSW^3%]l`FnI\Kil54k=_mX.+*(C@"LU5
+q*MQQ_$%$#U?`J?M=h4$5T-%AQY6(+X1>d8H^6=X,OmG_ni-6\o7=.ppqgr!c\FZ\
+S>l8bSf=@Hs%XEOShE3aZ-RcBB$$AL;IaT(ZtUkg3OZ^ESdAa.;"Gu&c/e3FoSh"b
+m'Da(PqR3dha+:;h.#a5q;TSjk)7>/T!;FW9:PZno#94m6KGpD+.\XWdWa(K?eY?c
+=E2/B':6/]9pd0i"at+JU&UH48R#:mBPnZ6.p@bpEd-XRFGo:c+8\>[>O>15JXhSM
+#2M#'Q"NK0?S;"C2fPbi8&!2>)NC>g^7g!tYhX^`
+?f(JD@=@t3oulO%'D1DHlf3&c0?<+544KPom46qI&WlMT0N))
+rV#AHgO9Y5,>\@)~>
endstream
endobj
48 0 obj
[/Indexed/DeviceRGB 255 49 0 R]
endobj
49 0 obj
<>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
endstream
endobj
40 0 obj
<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]>>/Subtype/Form>>stream
+/CS0 cs 0.145 0.224 0.318 scn
+/GS0 gs
+q 1 0 0 1 173.0996 158.9111 cm
+0 0 m
+-94.814 0 l
+-114.697 0 -130.814 16.117 -130.814 36 c
+-130.814 42.136 l
+-130.814 62.018 -114.697 78.136 -94.814 78.136 c
+0 78.136 l
+19.882 78.136 36 62.018 36 42.136 c
+36 36 l
+36 16.117 19.882 0 0 0 c
+f
+Q
+BT
+0.91 0.949 0.988 scn
+/TT0 1 Tf
+-0.002 Tc 0.002 Tw 0 Ts 100 Tz 0 Tr 34.7271 0 0 34.7271 86.729 184.6621 Tm
+(SDK)Tj
+ET
+
endstream
endobj
41 0 obj
<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]>>/Subtype/Form>>stream
+/CS0 cs 0.145 0.224 0.318 scn
+/GS0 gs
+q 1 0 0 1 473.6206 159.2285 cm
+0 0 m
+-217.232 0 l
+-237.114 0 -253.232 16.117 -253.232 36 c
+-253.232 42.136 l
+-253.232 62.018 -237.114 78.136 -217.232 78.136 c
+0 78.136 l
+19.882 78.136 36 62.018 36 42.136 c
+36 36 l
+36 16.117 19.882 0 0 0 c
+f
+Q
+BT
+0.91 0.949 0.988 scn
+/TT0 1 Tf
+-0.002 Tc 0.002 Tw 0 Ts 100 Tz 0 Tr 34.7271 0 0 34.7271 251.3257 186.0654 Tm
+[(HARD)25 (W)40 (ARE)]TJ
+ET
+
endstream
endobj
42 0 obj
<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]>>/Subtype/Form>>stream
+/CS0 cs 0.145 0.224 0.318 scn
+/GS0 gs
+q 1 0 0 1 643 159.2285 cm
+0 0 m
+-89.176 0 l
+-109.058 0 -125.176 16.117 -125.176 36 c
+-125.176 42.136 l
+-125.176 62.018 -109.058 78.136 -89.176 78.136 c
+0 78.136 l
+19.882 78.136 36 62.018 36 42.136 c
+36 36 l
+36 16.117 19.882 0 0 0 c
+f
+Q
+BT
+0.91 0.949 0.988 scn
+/TT0 1 Tf
+-0.002 Tc 0.002 Tw 0 Ts 100 Tz 0 Tr 34.7271 0 0 34.7271 552.7979 186.0654 Tm
+(SIMS)Tj
+ET
+
endstream
endobj
43 0 obj
<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]>>/Subtype/Form>>stream
+BT
+/CS0 cs 0.145 0.224 0.318 scn
+/GS0 gs
+/C2_0 1 Tf
+0 Tc 0 Tw 0 Ts 100 Tz 0 Tr 24 0 0 24 362.9092 118.8828 Tm
+<0676>Tj
+ET
+
endstream
endobj
44 0 obj
<>/Filter/FlateDecode/Height 254/Intent/RelativeColorimetric/Length 111781/Name/X/SMask 54 0 R/Subtype/Image/Type/XObject/Width 516>>stream
+HWԇq
fTbHmrڛ=M{9=i/ڋ+̰
`#&ZK4*75*Db/L{1<|!B!B!B!B!B!B!*J XlmA j
+=
eYW ܷW]8s