Source

DuESF.jsxinc

// ==================== |-------| ====================
// ==================== | DuESF | ====================
// ==================== |-------| ====================

// ==================== |------| ====================
// ==================== | core | ====================
// ==================== |------| ====================

/* License
	DuESF - Duduf ExtendScript Framework

	Copyright (c) 2021 Nicolas Dufresne, RxLaboratory

	https://rxlaboratory.org

	This file is part of DuESF.

        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * The Duduf ExtendScript Framework.<br />
 * by {@link https://rxlaboratory.org RxLaboratory} and {@link http://duduf.com Duduf}.<br />
 * WARNING: all objects marked deprecated will be removed in the version 1.1.0 of the framework.
 * @example
 * // Encapsulate everything to avoid global variables!
 * // The parameter is either undefined (stand alone script) or the panel containing the ui (ScriptUI)
 * (function(thisObj)
 * {
 *      // Include the framework
 *      #include "DuESF.jsxinc";
 *      
 *      // Running the init() method of DuAEF is required to setup everything properly.
 *      DuESF.init( "YourScriptName", "1.0.0", "YourCompanyName" );
 *      
 *      // These info can be used by the framework to improve UX, but they're optional
 *      DuESF.chatURL = 'http://chat.rxlab.info'; // A link to a live-chat server like Discord or Slack...
 *      DuESF.bugReportURL = 'https://github.com/RxLaboratory/DuAEF_Dugr/issues/new/choose'; // A link to a bug report form
 *      DuESF.featureRequestURL = 'https://github.com/RxLaboratory/DuAEF_Dugr/issues/new/choose'; // A link to a feature request form
 *      DuESF.aboutURL = 'http://rxlaboratory.org/tools/dugr'; // A link to the webpage about your script
 *      DuESF.docURL = 'http://dugr.rxlab.guide'; // A link to the documentation of the script
 *      DuESF.scriptAbout = 'Duduf Groups: group After Effects layers!'; // A short string describing your script
 *      DuESF.companyURL = 'https://rxlaboratory.org'; // A link to your company's website
 *      DuESF.rxVersionURL = 'http://version.rxlab.io' // A link to an RxVersion server to check for updates
 *      
 *      // Build your UI here, declare your methods, etc.
 * 
 *      // This will be our main panel
 *      var ui = DuScriptUI.scriptPanel( thisObj, true, true, new File($.fileName) );
 *      ui.addCommonSettings(); // Automatically adds the language settings, location of the settings file, etc
 *
 *      DuScriptUI.staticText( ui.settingsGroup, "Hello world of settings!" ); // Adds a static text to the settings panel
 *      DuScriptUI.staticText( ui.mainGroup, "Hello worlds!" ); // Adds a static text to the main panel
 *      
 *      // When you're ready to display everything
 *      DuScriptUI.showUI(ui);
 *
 *      // Note that if you don't have a UI or if you don't use DuScriptUI to show it,
 *      // you HAVE TO run this method before running any other function:
 *      // DuESF.enterRunTime();
 *  
 * })(this);
 * @namespace
 * @author Nicolas Dufresne and contributors
 * @copyright 2021 Nicolas Dufresne, RxLaboratory
 * @version 1.0.0
 * @license GPL-3.0 <br />
 * This program is free software: you can redistribute it and/or modify<br />
 * it under the terms of the GNU General Public License as published by<br />
 * the Free Software Foundation, either version 3 of the License, or<br />
 * (at your option) any later version.<br />
 *<br />
 * This program is distributed in the hope that it will be useful,<br />
 * but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
 * GNU General Public License for more details.<br />
 *<br />
 * You should have received a copy of the GNU General Public License<br />
 * along with this program. If not, see {@link http://www.gnu.org/licenses/}.
 * @category DuESF
 */
var DuESF = {};

/**
 * The Current DuESF Version
 * @readonly
 * @memberof DuESF
 * @type {DuVersion}
 */
DuESF.version = new DuVersion('1.0.0');
/**
 * Set to true and enable debug mode if you're a developper
 * @memberof DuESF
 * @type {Boolean}
 */
DuESF.debug = false;
/**
 * The name of the script using this instance of DuESF. Must be set by {@link DuESF.init}.
 * @memberof DuESF
 * @type {string}
 * @readonly
 */
DuESF.scriptName = "DuESF";
/**
 * The version of the script using this instance of DuESF. Must be set by {@link  DuESF.init}.
 * @memberof DuESF
 * @type {DuVersion}
 * @readonly
 */
DuESF.scriptVersion = new DuVersion('0.0.0');
/**
 * An icon for this script
 * @type {string}
 */
DuESF.scriptIcon = '';
/**
 * The url for the forum about the script
 * @type {string}
 */
DuESF.forumURL = '';
/**
 * The url for a chat server about the script
 * @type {string}
 */
DuESF.chatURL = '';
/**
 * The url for reporting bugs
 * @type {string}
 */
DuESF.bugReportURL = '';
/**
 * The url for donations, support, like...
 * @type {string}
 */
DuESF.donateURL = 'http://donate.rxlab.info';
/**
 * The url about the script
 * @type {string}
 */
DuESF.aboutURL = '';
/**
 * The url to the documentation of the script
 * @type {string}
 */
DuESF.docURL = '';
/**
 * The text about the script
 * @type {string}
 */
DuESF.scriptAbout = '';
/**
 * The name of the company/organisation/individual developping this tool
 * @type {string}
 */
DuESF.companyName = 'RxLaboratory';
/**
 * The URL to the company's website
 * @type {string}
 */
DuESF.companyURL = 'https://rxlaboratory.org';
/**
 * An icon for this company
 * @type {string}
 */
DuESF.companyIcon = '';
/**
 * The URL to a rxVersion server used to check for updates
 * @type {string}
 */
DuESF.rxVersionURL = '';
/**
 * Is this script a prerelease version? This info is used when checking for updates.
 * @type {bool}
 */
DuESF.isPreRelease = false;
/**
 * The current DuESF File
 * @readonly
 * @memberof DuESF
 * @type {File}
 */
DuESF.file = new File( $.fileName );
/**
 * Enum for states.
 * @readonly
 * @enum {int}
 */
DuESF.State = {
    NOT_SET: -1,
    INIT: 0,
    RUNTIME: 1
};
/**
 * The current state of the script
 * @type {DuESF.State}
 * @default DuESF.State.NOT_SET
 */
DuESF.state = DuESF.State.NOT_SET;
/**
 * True if the script is run for the first time (new or the version has changed since last run)
 * @type {boolean}
 * @readonly
 */
DuESF.scriptFirstRun = true;
/**
 * The applicatiosns DuESF can be used with.
 * @readonly
 * @enum {string}
 */
DuESF.HostApplication = {
    AFTER_EFFECTS: 'aftereffects',
    ILLUSTRATOR: 'illustrator',
    PHOTOSHOP: 'photoshop',
    INDESIGN: 'indesign'
}
DuESF.hostIsBeta = false;
/**
 * The host application
 * @type {DuESF.HostApplication}
 */
DuESF.host = null;
/**
 * The version of the host application
 */
DuESF.hostVersion = new DuVersion();
/**
 * The list of functions to run with {@link DuESF.init}. You can add your own methods here.
 * @type {function[]}
 */
DuESF.initMethods = [];
/**
 * The list of functions to run with {@link DuESF.enterRunTime}. You can add your own methods here.
 * @type {function[]}
 */
DuESF.enterRunTimeMethods = [];
/**
 * This method has to be called once at the very beginning of the script, just after the inclusion of DuESF <code>#include DuESF.jsxinc</code>
 * @param {DuESF.host} hostApplication - The host application of the script.
 * @param {string} [scriptName="DuESF"] - The name of your script, as it has to be displayed in the UI and the filesystem
 * @param {string} [scriptVersion="0.0.0"] - The version of your script, in the form "XX.XX.XX-Comment", for example "1.0.12-Beta". The "-Comment" part is optional.
 * @param {string} [companyName="RxLaboratory"] - The name of the company/organisation/individual developping this script.
 */
DuESF.init = function( scriptName, scriptVersion, companyName )
{
    var host = BridgeTalk.appName;

    if (host.indexOf('beta') == host.length -4) {
        DuESF.hostIsBeta = true;
        host = host.slice(0, host.length - 4);
    }

    DuESF.host = host;

    DuESF.hostVersion = new DuVersion( BridgeTalk.appVersion );
    if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS) {
        DuESF.hostVersion = new DuVersion( app.version );
    }
    
    DuESF.state = DuESF.State.INIT;

    scriptName = def( scriptName, "DuESF" );
    scriptVersion = def( scriptVersion, "0.0.0" );
    DuESF.scriptName = scriptName;
    DuESF.scriptVersion = new DuVersion(scriptVersion);
    DuESF.companyName = def( companyName, "RxLaboratory" );

    // Everything which needs to be initialized once we have our info
    for( var i = 0; i < DuESF.initMethods.length; i++) {
        DuESF.initMethods[i]();
    }

    // check if this script has already been run once
    // Check the version from latest run
    if ( DuESF.settings.data.version !== 'undefined' )
    {
        var prevVersion =  DuESF.settings.data.version;
        if ( prevVersion == scriptVersion ) DuESF.scriptFirstRun = false;
    }

    // Create a debug log
    if (DuESF.debug) DuDebug.debugLog = new DuDebugLog();
}

/**
 * This method has to be called once at the end of the script, when everything is ready and the main UI visible (after any prompt or setup during startup).
 */
DuESF.enterRunTime = function()
{
    DuESF.settings.data.version = DuESF.scriptVersion.fullVersion;
    DuESF.settings.save();
    DuESF.state = DuESF.State.RUNTIME;

    // Everything which needs to be run once
    for( var i = 0; i < DuESF.enterRunTimeMethods.length; i++) {
        DuESF.enterRunTimeMethods[i]();
    }

    DuDebug.log( "DuESF: Runtime!" );
}

/**
 * Removes all DuESF parts from memory. Call this if you've updated before you reload DuESF.
 */
DuESF.delete = function()
{
    delete tr;
    delete def;
    delete jstype;
    delete DuBinary;
    delete DuColor;
    delete DuDate;
    delete DuDebug;
    delete DuDebugLog;
    delete DuESF;
    delete DuFile;
    delete DuFolder;
    delete DuList;
    delete DuMath;
    delete DuNumber;
    delete DuOCA;
    delete DuPath;
    delete DuProcess;
    delete DuProcessQueue;
    delete DuRegExp;
    delete DuRSS;
    delete DuRSSChannel;
    delete DuRSSItem;
    delete DuSettings;
    delete DuSystem;
    delete DuString;
    delete DuTranslator;
    delete DuTranslation;
    delete DuVersion;
    delete DuXML;
    delete DuXMP;
    delete DuZip;
    delete DuESF;
}

/**
 * Assigns a default value to a var if it's undefined.
 * @global
 * @param {object} val - The variable to set
 * @param {object} defaultVal - The default value
 * @return {object} The var
 * @example foo = def( foo, 12 ); // if foo was undefined, it is now 12, else it's unchanged.
 * @category DuESF
 */
function def( val, defaultVal )
{
	return isdef(val) ? val : defaultVal;
}

/**
 * Checks if a value is defined. Convenience replacement for `typeof val !== 'undefined`
 * @param {any} val The value
 * @return {boolean}
 * @category DuESF
 */
function isdef(val) {
    return typeof val !== 'undefined';
}

/**
 * Improved typeof which returns the type of object instead of 'object'
 * @global
 * @param {any} exp - The expression to check.
 * @return {string} The type always in lower case.
 * @category DuESF
*/
function jstype(value) {
    var type = typeof value;

    if (type == 'object') {
        try {
            type = value === null ? 'null' : Object.prototype.toString.call(value).match(/^\[object (.*)\]$/)[1].toLowerCase();
        } catch (e) {}
    }

    return type.toLowerCase();
}// ==================== |--------| ====================
// ==================== | system | ====================
// ==================== |--------| ====================

/**
* System tools
* @namespace
* @category DuESF
*/
var DuSystem = {};

(function()
{
    /**
        * The current OS, true if we're on Mac OS
        * @memberof DuSystem
        * @readonly
        * @type {boolean}
        */
    DuSystem.mac = $.os.toLowerCase().indexOf( "mac" ) >= 0;
    /**
        * The current OS, true if we're on Windows
        * @memberof DuSystem
        * @readonly
        * @type {boolean}
        */
    DuSystem.win = !DuSystem.mac ;

    /**
        * A string identifying the version of the OS; may vary depending on the host application
        * @memberof DuSystem
        * @readonly
        * @type {string}
        */
    DuSystem.osVersion = $.os.toLowerCase()
        .replace('windows/','')
        .replace('windows','')
        .replace('win', '')
        .replace('mac os','')
        .replace('macintosh','')
        .replace('mac','');
})();

/**
 * Opens a URL in the default browser.<br />
 * @param {string} url - The URL
 * @method
 */
DuSystem.openURL = function ( url )
{
    if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
    {   
        if ( DuSystem.mac )
        {
            system.callSystem( 'open "' + url + '"' );
        }
        else
        {
            system.callSystem( 'explorer "' + url + '"' );
        }
        return;
    }
    var timestamp = Date.now();
    var shortcut = new File(Folder.temp + '/duesf_shortcut_' + timestamp + '.url');
    shortcut.open('w');
    shortcut.writeln('[InternetShortcut]');
    shortcut.writeln('URL=' + url);
    shortcut.writeln();
    shortcut.close();
    shortcut.execute();
    shortcut.remove();
}

// ==================== |------| ====================
// ==================== | path | ====================
// ==================== |------| ====================

/**
	* Paths related methods
	* @namespace
	* @category DuESF
*/
var DuPath = {}

/**
 * Units to use for sizes.
 * @readonly
 * @enum {string}
 */
DuPath.SizeUnit = {
	BIT: "b",
	BYTE: "B",
	KB: "kB",
	MB: "MB",
	GB: "GB",
	TB: "TB"
}

/**
	* Joins multiple paths togetther.
	* @param {string[]}	 [parts]	- The parts to join togehter
	* @param {String}	[sep="/"]	- The separator to use. If not defined, will look for the first sep in the path.
	* @return {String} The final path
*/
DuPath.join = function(parts, sep)
{
   var separator = sep || false;
   if(!separator)
   {
       // Find first "/" or "\"
       if(parts[0].indexOf('/') != -1) separator = '/';
       if(parts[0].indexOf('\\') != -1) separator = '\\';
   }
   if(!separator) separator = '/';
   var replace   = new RegExp(separator+'{1,}', 'g');  // Replace ///// with /
   return parts.join(separator).replace(replace, separator);
}

/**
 * Converts a number of Bytes to kB or MB or GB or TB
 * For conversion to bits, a Byte is considered to be 8 bits.
 * @param {int} size The size in Bytes to convert
 * @param {DuPath.SizeUnit} [to=DuPath.SizeUnit.MB] The unit to convert to, one of: b, kB, MB, GB, TB
 * @param {int} [decimals=2] The number of decimals to round the result
 * @return {float} The result of the conversion
 */
DuPath.sizeFromBytes = function(size,  to, decimals )
{
	to = def(to, DuPath.SizeUnit.MB);
	decimals = def(decimals, 0);

	var result = size;
	if (to == DuPath.SizeUnit.BIT) result = result * 8;
	if (to == DuPath.SizeUnit.KB || to == DuPath.SizeUnit.MB || to == DuPath.SizeUnit.GB || to == DuPath.SizeUnit.TB) result = result / 1024;
	if (to == DuPath.SizeUnit.MB || to == DuPath.SizeUnit.GB || to == DuPath.SizeUnit.TB) result = result / 1024;
	if (to == DuPath.SizeUnit.GB || to == DuPath.SizeUnit.TB) result = result / 1024;
	if (to == DuPath.SizeUnit.TB) result = result / 1024;
	var round = 1;
	for (var i = 0; i < decimals; i++)
	{
		round = round * 10;
	}
	result = Math.round(result*round)/round;
	return result;
}

/**
	* Returns the name of the given path or file, as displayed by the filesystem
	* @example
	* DuPath.getName(new File("D:\\code\\open\\Duik\\shape test.test")) // "shape test.test"
	* DuPath.getName("D:/code/open/Duik/other shape.test") // "other shape.test"
	* @param {String|File|Folder}  [pathOrFile]	- The file or the path
	* @return {String} The basename
*/
DuPath.getName = function(pathOrFile)
{
    if (pathOrFile instanceof File || pathOrFile instanceof Folder) pathOrFile = pathOrFile.fsName;
	else {
		//make sure it's the fsName we use
		pathOrFile = new File(pathOrFile).fsName;
	}
    var name = pathOrFile.split("/").pop();
    name = name.split("\\").pop();
    return name;
}

/**
	* Returns the basename of the given path or file
	* @example
	* DuPath.getBasename(new File("D:/code/open/Duik/shape.test")) // "shape"
	* DuPath.getBasename("D:/code/open/Duik/shape.test") // "shape"
	* @param {String|File}	 [pathOrFile]	- The file or the path
	* @return {String} The basename
*/
DuPath.getBasename = function(pathOrFile)
{
    if (pathOrFile instanceof File) pathOrFile = pathOrFile.fsName;
	else {
		//make sure it's the fsName we use
		pathOrFile = new File(pathOrFile).fsName;
	}
    var name = pathOrFile.split("/").pop();
    name = name.split("\\").pop();
    if(name.lastIndexOf(".") > 0) return name.slice(0, name.lastIndexOf("."));
    return name;
}

/**
	* Returns the extension of the given path or file
	* @example
	* DuPath.getExtension(new File("D:/code/open/Duik/shape.other.test")) // "test"
	* DuPath.getExtension("D:/code/open/Duik/shape.test") // "test"
	* @param {String|File}	 [pathOrFile]	- The file or the path
	* @return {String} The extension
*/
DuPath.getExtension = function(pathOrFile)
{
	if (pathOrFile instanceof Folder) return '';
    if (pathOrFile instanceof File) pathOrFile = pathOrFile.absoluteURI;
    var name = pathOrFile.split("/").pop();
    name = name.split("\\").pop();
    if(name.indexOf(".") > 0) return name.split(".").pop();
    return '';
}

/**
	* Switch the extension of the given path. Create a new path from a given path and a given extension.
	* @param {String|File}	 [pathOrFile]	- The file or the path
	* @param {String}	     [newExtension]	- The new extension
	* @return {String}  The new path
*/
DuPath.switchExtension = function(pathOrFile, newExtension)
{
	// Remove leading .
	if (newExtension.indexOf('.') == 0) newExtension = newExtension.substring(1);
    if (pathOrFile instanceof File) pathOrFile = pathOrFile.absoluteURI;
    var point = pathOrFile.lastIndexOf(".");
    if (point == -1) return pathOrFile + "." + newExtension;
    return pathOrFile.slice(0, point) + "." + newExtension;
}

/**
 * Generates a new unique name for a file
 * @param {string} newName	- The wanted new name
 * @param {Folder} folder 	- The folder
 * @param {boolean} [increment=true] - true to automatically increment the new name if it already ends with a digit
 * @return {string}	The unique name, with a new number at the end if needed.
 */
DuPath.newUniqueName = function ( newName, folder ) {   
	var file = new File(folder.absoluteURI + "/" + newName);
	while (file.exists)
	{
		file = new File(folder.absoluteURI + "/" + DuPath.incrementName(file) );
	}
	return DuPath.getName(file);
}

/**
 * Increments the last number before the extension in a filename
 * @param {File} file The file
 * @return {string} The incremented fileName
 */
DuPath.incrementName = function (file) {

	var ext = DuPath.getExtension(file);
	var baseName = DuPath.getBasename(file);

	var regex = /(\d*)$/
	var match = baseName.match(regex);
	var num = '_01';
	var numDigits = 0;
	if (match) {
		var n = match[0];
		numDigits = n.length;
		var n = parseInt(n);
		if (!isNaN(n)) {
			n++;
			num = DuNumber.toString(n,numDigits);
		}
	}

	return baseName.substring(0, baseName.length - numDigits) + num + '.' + ext;

}

/**
 * Removes all forbidden characters from a string to be used as a filename
 * @param {string} name - The filename to fix
 * @param {string} [placeholder='.'] - The string used to replace the forbidden characters
 * @return {string} The fixed filename
 */
DuPath.fixName = function (name, placeholder ) {
	placeholder = def( placeholder, '.');
	
	return name.replace( /([\/\\:*?"<>|])/g, placeholder);
}

/**
 * Checks if the given path represents an existing file
 * @param {File|Folder|string} path The path to check
 * @return {bool}
 */
DuPath.isFile = function(path) {
	if (jstype(path) == 'string')
	{
		path == new File(path);
		if (path.exists) return true;
		return false;
	}
	if (path instanceof File) return path.exists;
	return false;
}

/**
 * Checks if the given path represents an existing folder
 * @param {File|Folder|string} path The path to check
 * @return {bool}
 */
DuPath.isFolder = function(path) {
	if (jstype(path) == 'string')
	{
		path == new Folder(path);
		if (path.exists) return true;
		return false;
	}
	if (path instanceof Folder) return path.exists;
	return false;
}// ==================== |--------| ====================
// ==================== | folder | ====================
// ==================== |--------| ====================


/**
 * Folder related methods
 * @namespace
 * @category DuESF
 */
var DuFolder = {};

/**
 * Recursively remove all content from folder and the folder itself. Warning, this does not move files to the recycle bin and can not be undone.
 * @param {string|Folder} folder - the path or Folder object to wipe.
 */
DuFolder.wipeFolder = function(folder)
{
	if ( jstype(folder) == 'string' && folder != '') folder = new Folder(folder);
	if ( !folder.exists ) return;

	//get content and remove 
	var files = folder.getFiles();
	var it = new DuList(files);
	it.do(function (file)
	{
		if ( jstype(file) == 'folder' ) DuFolder.wipeFolder(file);
		else file.remove();
	});
	folder.remove();
}

/**
	* Recursively gets all files in a folder using a name filter
	* Returns an array of File objects.
	* @param {Folder}	folder	- The Folder
	* @param {string|function}	[filter="*"]	- A search mask for file names, specified as a string or a function.
	* A mask string can contain question mark (?) and asterisk (*) wild cards. Default is "*", which matches all file names.
	* Can also be the name of a function that takes a File or Folder object as its argument. It is called for each file or folder found in the search; if it returns true, the object is added to the return array.
	* @return {Array}	The files found.
*/
DuFolder.getFiles = function (folder,filter)
{
	function isFolder(f) { return f instanceof Folder; }

	if (!isdef( folder )) return [];
	if (!(folder instanceof Folder)) return [];

	var files = folder.getFiles(filter);
	if (files === null) files = [];

	var folders = folder.getFiles( isFolder );

	for (var i = 0, num = folders.length ; i < num ; i++)
	{
		files = files.concat(DuFolder.getFiles(folders[i],filter));
	}
	return files;
}

/**
 * Tests if a folder can be read
 * @param {Folder|string} folder The folder
 * @return {bool}
 */
DuFolder.canRead = function (folder) {
	if ( jstype(folder) == 'string' && folder != '') folder = new Folder(folder);
	if ( !folder.exists ) return false;

	function isFile(f) { return f instanceof File; }

	// Try to list files
	try {
		f = folder.getFiles( isFile );
		/*if (f.length > 0) {
			if (f[0].open('r')){
				f.read();
				f.close();
				return true;
			}
			return false;
		}//*/
		return true;
	}
	catch (e) { return false; }
}

/**
 * Tests if a folder can be written
 * @param {Folder|string} folder The folder
 * @return {bool}
 */
DuFolder.canWrite = function (folder) {
	if ( jstype(folder) == 'string' && folder != '') folder = new Folder(folder);
	if ( !folder.exists ) return false;

	var content = 'test-write-access';
	var f = new File(folder.absoluteURI + '/' + content);

	if (f.open('w')) {
		try {
			f.write(content);
			f.close();
			f.remove();
			return true;
		}
		catch(e) { return false };
	} else return false;
}

// Low-level undocumented function. Called by DuESF.init()
DuFolder.init = function()
{
	DuFolder.duesfData = new Folder( DuPath.join( [
		DuFolder.userData.absoluteURI,
		DuESF.companyName,
		'AdobeScripts',
		DuESF.scriptName
		] ) );

}
DuESF.initMethods.push( DuFolder.init );

/**
 * The default user data folder.<br />
 * Replaces the Folder.userData provided by ESTK which does not work properly with mac network sessions.<br />
 * In windows, the value of %APPDATA% ("C:\Documents and Settings\username\Application Data")<br />
 * In Mac OS, "~/Library/Application Support"
 * @type {Folder}
 */
DuFolder.userData = Folder.userData;
if (DuSystem.mac) DuFolder.userData = new Folder('~/Library/Application Support');
// We absolutely need write access... If not, use a temp folder
if (!DuFolder.canWrite(DuFolder.userData)) DuFolder.userData = Folder.temp;

DuFolder.duesfData = new Folder( DuPath.join( [
		DuFolder.userData.absoluteURI,
		DuESF.companyName,
		'AdobeScripts',
		DuESF.scriptName
		] ) );
// ==================== |--------| ====================
// ==================== | object | ====================
// ==================== |--------| ====================

/**
 * JS Objects related methods
 * @namespace
 * @category DuESF
 */
var DuJSObj = {};

/**
 * Sorts object keys and returns a new sorted object.
 * @param {object} obj The object to sort.
 * @param {bool} [reverse=false] Set to true to sort in the reverse order.
 * @param {function} [compareFn] Specifies a function that defines the sort order. Note that this parameter is ignored if reversed is true.<br />
 * If omitted, the keys are converted to strings, then sorted according to each character's Unicode code point value.
 * @return {object} The new sorted object.
 */
DuJSObj.sort = function( obj, reverse, compareFn ) {
    reverse = def(reverse, false);

    if (reverse) {
        compareFn = function(a, b) {
            if (b > a) return 1;
            if (b < a) return -1;
            if (b == a) return 0;
        }
    }

    var newObj = {};
    var tempArray = [];
    for (i in obj) {
        tempArray.push(i);
    }

    if (isdef( compareFn )) tempArray.sort(compareFn);
    else tempArray.sort();

    for (var i = 0, n = tempArray.length; i < n; i++)
    {
        var key = tempArray[i];
        newObj[key] = obj[key];
    }

    return newObj;
}

/**
 * Deletes all properties from an object, except a predefined list.
 * @param {object} obj The object to clear.
 * @param {string[]} [ignoredProperties] The properties to keep
 */
DuJSObj.clear = function( obj, ignoredProperties ) {
    ignoredProperties = def(ignoredProperties, []);
    // Remove existing items
    for (i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        // ignore properties
        var ok = true;
        for (var j = 0, n = ignoredProperties.length; j < n; j++)
        {
            if (i == ignoredProperties[j]) {
                ok = false;
                break;
            }
        }
        if (ok) delete obj[i];
    }
}

DuJSObj.equals = function( obj1, obj2 ) {
    for( key in obj1 ) {
        if (obj2[key] !== obj1[key]) return false
    }
    return true;
}// ==================== |-------| ====================
// ==================== | debug | ====================
// ==================== |-------| ====================

/**
* Tools for debugging
* @namespace
 * @category DuESF
*/
var DuDebug = {};

/**
 * Set this attribute to a DuDebugLog you have created to automatically add some debug infos to the log (like catched errors).
 * @type {DuDebugLog|null}
 */
DuDebug.debugLog = null;

/**
 * The log levels
 * @enum {int}
 * @readonly
 */
DuDebug.LogLevel =
{
	VERBOSE: 0,
	DEBUG: 1,
	WARNING: 2,
	CRITICAL: 3,
	FATAL: 4,
	NO_DEBUG: 5
}

/**
 * Logs a message to DuDebug.DuDebugLog if it has been set.
 * @param {string} message - The message to log
 * @param {DuDebug.LogLevel} [level=DuDebug.LogLevel.DEBUG] - The level of the message
 */
DuDebug.log = function (message,level)
{
	if ( DuDebug.debugLog != null ) DuDebug.debugLog.log( message,level );
}

/**
 * This methods shows an alert with an error thrown if DuESF.debug is set to true, and logs it in DuESF.debug.DuDebugLog if it has been set.<br />
 * The error is actually thrown only if JS Debugging is enabled in the host application, otherwise it is just shown in an alert.
 * @param {Error|string} error - An error thrown and catched
 */
DuDebug.error = function (error)
{
	var file = new File( error.fileName );
	var errorString = 'An error has occured in file\n\n' + file.name + '\n\nlocated in:\n' + file.parent.fsName + '\n\nat line ' + error.line + '\n\n' + error.description;
	DuDebug.log( errorString, DuDebug.LogLevel.WARNING );
	if ( DuESF.debug )
	{
		alert( errorString );
		// Throw if debugger enabled
		if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
			if (DuAE.isDebuggerEnabled()) throw error;
	}
}

/**
 * Runs a method/script safely, i.e. enclosed in a try...catch, and logs any error thrown.<br />
 * arguments can be added after the first parameter, they will be passed to the callback.<br />
 * The callback is enclosed in a function to make sure it does not create global variables.
 * @param {function|string} callback - The method to run, or a script as a string
 * @return {any} The return of the callback, null if it fails.
 */
DuDebug.safeRun = function (callback)
{
	if (!isdef( callback )) throw "Error: DuDebug.safeRun(callback): Invalid parameter: callback cannot be undefined";
	if (callback == '') throw "Error: DuDebug.safeRun(callback): Invalid parameter: callback cannot be an empty string";
	var call = '';
	if (jstype(callback) != 'string' && arguments.legnth > 1)
	{
		var args = [];
		for (var i = 1, num = arguments.length; i < num; i++)
		{
			args.push(arguments[i]);
		}
		var params = args.join(',');
		call = 'var result = callback(' + params + '); result;'
	}
	else if (jstype(callback) == 'string') call = callback;
	
	try
	{
		if (call != '')
		{
			(function(){
				return eval(call);
			})();
		}
		else 
		{
			return callback();
		}
	}
	catch ( error )
	{
		DuDebug.error(error);
		return null;
	}
}

/**
 * Inspects a javascript object and outputs all of its attributes
 * @param {object} obj - The object to inspect.
 * @param {boolean} [ownProperties=true] - Whether to inspect only the own properties of the object.
 * @return {string} The report. 
 */
DuDebug.inspect = function(obj, ownProperties)
{
	ownProperties = def( ownProperties, true );

	var report = "";
	for (var key in obj)
	{
		if (ownProperties && !obj.hasOwnProperty(key)) continue;
		report += key + " | type: " + typeof(obj[key]) + " | value: " + obj[key].toString() + "\n";
	}
	return report;
}

/**
 * Alerts a nice TypeError description, if {@link DuESF.debug} is true, and logs it if there's a log.<br />
 * Note that it does not actually throws an error.
 * @param {any} variable The failing argument
 * @param {string} varName The failing argument name
 * @param {string} varType The expected type
 * @param {string} [functionName] The name or description of the function throwing the error.
 * @return {string} The (multiline) description for the error
 */
DuDebug.throwTypeError = function (variable, varName, varType, functionName)
{
	functionName = def (functionName, '');
	if (typeof functionName === 'Function') {
		functionName = func.toString().split('\n')[0];
	}

	var e = 'TypeError:\n';
	if (functionName != '') e += "in function " + functionName + "\n";
	e += "\n" + varName + " should be of type " + varType + "\n";
	e += "but it is of type " + jstype(variable);
	if (isdef( variable )) try { e += " and has value: " + variable.toSource(); } catch(e) {};

	//ADD stack trace
	e += '\n\nStack:\n' + $.stack;
		
	DuDebug.log(e, DuDebug.LogLevel.CRITICAL);

	if ( DuESF.debug )
	{
		alert( e );
		// Throw if debugger enabled
		if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
			if (DuAE.isDebuggerEnabled()) throw e;
	}

	return e;
}

/**
 * Alerts a nice UndefinedError description, if {@link DuESF.debug} is true, and logs it if there's a log..<br />
 * Note that it does not actually throws an error.
 * @param {any} varName The name of the arg which should not be undefined
 * @param {any} [functionName] The name or description of the function throwing the error.
 * @return {string} The (multiline) description for the error
 */
DuDebug.throwUndefinedError = function( varName, functionName )
{
	if (!DuESF.debug) return;

	functionName = def (functionName, '');
	if (typeof functionName === 'Function') {
		functionName = func.toString().split('\n')[0];
	}

	var e = 'UndefinedError:\n';
	if (functionName != '') e += "in function " + functionName + "\n";
	e += "\n" + varName + " cannot be undefined.";

	DuDebug.log(e, DuDebug.LogLevel.CRITICAL);

	if ( DuESF.debug )
	{
		alert( e );
		// Throw if debugger enabled
		if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
			if (DuAE.isDebuggerEnabled()) throw e;
	}

	return e;
}

/**
 * Alerts a nice Error description, if {@link DuESF.debug} is true, and logs it if there's a log..<br />
 * Note that it does not actually throws an error.
 * @param {any} message The message to show
 * @param {any} [functionName] The name or description of the function throwing the error.
 * @param {Error} [error] A JS error.
 * @param {Boolean} [neverThrow=false] If true, will prevent actually throwing the error even if the debugger is enabled.
 * @return {string} The (multiline) description for the error
 */
DuDebug.throwError = function( message, functionName, error, neverThrow )
{
	functionName = def (functionName, '');
	neverThrow = def(neverThrow, false);
	if (typeof functionName === 'Function') {
		functionName = func.toString().split('\n')[0];
	}

	var e = 'Error:\n';
	if (functionName != '') e += "in function " + functionName + "\n";
	e += "\n" + message;

	if (isdef( error ))
	{
		var file = new File(error.fileName);
		e += '\n\nIn file\n\n' + file.name + '\n\nlocated in:\n' + file.parent.fsName + '\n\nat line ' + error.line + '\n\n' + error.description;
	}

	DuDebug.log(e, DuDebug.LogLevel.CRITICAL);

	if ( DuESF.debug )
	{
		alert( e );
		if (!neverThrow)
		{
			// Throw if debugger enabled
			if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
				if (DuAE.isDebuggerEnabled()) 
				{
					if (isdef( error )) throw error;
					else throw e;
				}
		}
	}

	return e;
}

/**
 * Checks if the given variable has the correct type,<br />
 * alerts a nice error if not using {@link DuDebug.throwUndefinedError()} or {@link DuDebug.throwTypeError()}.
 * @param {any} variable The variable to check
 * @param {string} argName  The variable name
 * @param {string} [argType] The expected type name (as return by {@link jstype()}). If not provided, checks only if the var is undefined
 * @param {any} [functionName] The name or description of the function throwing the error.
 * @return {string|bool} The (multiline) description for the error if any and {@link DuESF.debug} is true, false if there's an error and {@link DuESF.debug} is false, true if everything is ok.
 */
DuDebug.checkVar = function ( variable, varName, varType, functionName )
{
	// Check if undefined
	if ( !isdef( variable ) )
	{
		if (DuESF.debug) return DuDebug.throwUndefinedError( varName, functionName );
		else return false;
	} 
	if (isdef( varType ))
		if ( jstype( variable ) != varType )
		{
			if (DuESF.debug) return DuDebug.throwTypeError( variable, varName, varType, functionName );
			else return false;
		}
	return true;
}

/**
 * Constructs a new debug logger
 * @class DuDebugLog
 * @classdesc A logger for debugging purposes: writes debug messages to a file, with date and type
 * @param	{string|File} [pathOrFile] - The log file. By default, located next to the script settings file
 * (if constructed <strong>after</strong> {@link DuESF.init()}).
 * @param	{boolean} [clear=true] - Whether to clear the previous log file before starting
 * @param	{DuDebug.LogLevel}	[logLevel=DuDebug.LogLevel.DEBUG] -  The log level.
 * @param	{boolean}	[enabled=DuESF.debug] -  true to enable the log and start recording
 * @property {boolean}	running - true if the timer is running, false if it is stopped.
 * @category DuESF
 */
function DuDebugLog(pathOrFile,clear,logLevel,enabled)
{
	/**
	 * The log file.
	 * @memberof DuDebugLog
	 * @readonly
	 * @name file
	 * @type {File}
	 */
	this.file = null;

	if (!isdef( pathOrFile ))
	{
		var folder = DuESF.scriptSettings.file.parent;
		pathOrFile = new File( folder.absoluteURI + '/' + DuESF.scriptName + '_debug_log.txt');
	}

	if (!(pathOrFile instanceof File)) this.file = new File(pathOrFile);
	else this.file = pathOrFile;
	this.file.encoding = 'UTF-8';

	/**
	 * The log level.
	 * @memberof DuDebugLog
	 * @type {DuDebug.LogLevel}
	 * @name level
	 * @default DuDebug.LogLevel.DEBUG
	 */
	this.level = def (logLevel, DuDebug.LogLevel.DEBUG);

	/**
	 * true to enable the log and record logs.
	 * @memberof DuDebugLog
	 * @type {DuDebug.LogLevel}
	 * @name enabled
	 * @default DuESF.debug
	 */
	this.enabled = def( enabled, DuESF.debug );

	clear = def (clear, true);
	var append = !clear && this.file.exists;

	if (this.level <= DuDebug.LogLevel.DEBUG)
	{
		var currentDate = new Date();
		DuFile.writeln (
			this.file,
			'[' + currentDate.toString() + '] == Debugger started. ==',
			append );
	}

	this.elapsed = 0;
	this.running = false;

	this.log( "\n=========== NEW LOG =============\n=================================" , DuDebug.LogLevel.NO_DEBUG);
}

/**
	* Logs a message
	* @param {string} message - The message to log
	* @param {DuDebug.LogLevel} [level=DuDebug.LogLevel.DEBUG] - The level of the message
	*/
DuDebugLog.prototype.log = function (message,level)
{
	level = def( level, DuDebug.LogLevel.DEBUG );

	if (!this.enabled) return;
	if (level < this.level) return;

	var currentDate = new Date();
	var levelString = " || Debug info || ";
	if (level == DuDebug.LogLevel.WARNING) levelString = " || Warning || ";
	else if (level == DuDebug.LogLevel.CRITICAL) levelString = " || Critical || ";
	else if (level == DuDebug.LogLevel.FATAL) levelString = " || Fatal || ";

	DuFile.writeln (
			this.file,
			'[' + currentDate.toString() + ']' + levelString + message,
			true );
}

/**
	* Starts the debugger timer.
	* @param {string} [message] - A message to display in the log
	* @param {DuDebug.LogLevel} [level=DuDebug.LogLevel.VERBOSE] - The level of the message
	*/
DuDebugLog.prototype.startTimer = function(message, level)
{
	if (!this.enabled) return;

	level = def(level, DuDebug.LogLevel.VERBOSE );
	message = def (message, '');

	if (level >= this.level)
	{
		DuDebug.safeRun( function()
		{
			if (this.file.open('a'))
			{
				var currentDate = new Date();
				this.file.writeln('[' + currentDate.toString() + '] == Timer started. == ' + message);
				this.file.close();
			}
		});
	}

	if (!this.running) this.elapsed = 0;
	this.running = true;
	$.hiresTimer;
}

/**
	* Stops the debugger timer.
	* @param {string} [message] - A message to display in the log
	* @param {DuDebug.LogLevel} [level=DuDebug.LogLevel.DEBUG] - The level of the message
	*/
DuDebugLog.prototype.stopTimer = function(message, level)
{
	if (!this.enabled) return;
	if (!this.running) return;

	level = def( level, DuDebug.LogLevel.DEBUG );

	this.elapsed += Math.round($.hiresTimer/1000);

	if (!isdef( message )) message = '';

	if (level >= this.level)
	{
		DuDebug.safeRun( function()
		{
			if (this.file.open('a'))
			{
				var currentDate = new Date();
				this.file.writeln('[' + currentDate.toString() + '] == Timer stopped == Time elapsed | ' + this.elapsed + 'ms | == ' + message);
				this.file.close();
			}
		});
	}

	this.elapsed = 0;
	this.running = false;
	$.hiresTimer;
}

/**
	* Checks the time elapsed since the timer has started<br />
	* If the timer is not running, it will be started.
	* @param {string} message - A message to display in the log
	* @param {DuDebug.LogLevel} [level=DuDebug.LogLevel.DEBUG] - The level of the message
	* @return {int} The time elapsed in milliseconds
	*/
DuDebugLog.prototype.checkTimer = function(message, level)
{
	level = def( level, DuDebug.LogLevel.DEBUG );

	if (!this.running) this.startTimer();
	this.elapsed += Math.round($.hiresTimer/1000);

	if (!this.enabled) return -1;

	if (level >= this.level)
	{
		DuDebug.safeRun(function()
		{
			if (this.file.open('a'))
			{
				message = def(message, '');

				var currentDate = new Date();
				this.file.writeln('[' + currentDate.toString() + '] == Time elapsed | ' + this.elapsed + 'ms | == ' + message);
				this.file.close();
			}
		});
		
	}

	return this.elapsed;
}
// ==================== |------| ====================
// ==================== | list | ====================
// ==================== |------| ====================

/**
 * Constructs a new DuList object
 * @class
 * @name DuList
 * @classdesc DuList helps manipulating JS Arrays and After Effects Collections the same way. It is faster than converting a Collection to an Array.<br />
 * Other specific Adobe Lists in other Applications may be supported later.<br />
 * The first item of a DuList is always at index 0, the last at index length-1.<br />
 * Accessor is the {@link DuList#at DuList.at()} method instead of <code>Array</code>.<br />
 * List length is given by the {@link DuList#length DuList.length()} method instead of a property.<br />
 * DuList does not reimplement methods to add or remove items, use the source list instead with the {@link DuList#list DuList.list()} property
 * and the original methods (from the <code>Collection</code> instance or <code>Array</code>).<br />
 * DuList can also be used as an iterator with iterator-like methods like {@link DuList#next DuList.next()}.<br />
 * You can also run a function on each item with {@link DuList#do DuList.do()}.
 * @property {boolean} isCollection - true if the original list is an After Effects Collection, false otherwise
 * @property {boolean} isArray - true if the original  list is an Array, false otherwise
 * @category DuESF
 */
function DuList(obj) {
    obj = def(obj, []);
    var newList = obj;
    // Copy constructor
    if (obj instanceof DuList)
        newList = obj.list;

    /**
     * True if the original list is an After Effects Collection, false otherwise.
     * @memberof DuList.prototype
     * @name isCollection
     * @readonly
     * @type {Boolean}
     */
    this.isCollection = false;
    /**
     * True if the original list is an Array, false otherwise
     * @memberof DuList.prototype
     * @name isArray
     * @readonly
     * @type {Boolean}
     */
    this.isArray = true;

    //check if list is an Array or a Collection
    if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS) {
        if (
            newList instanceof ItemCollection ||
            newList instanceof LayerCollection ||
            newList instanceof OMCollection ||
            newList instanceof RQItemCollection
        ) {
            this.isCollection = true;
            this.isArray = false;
        }
    }

    //if not a list, store it as a one-item array
    if (!(
            newList instanceof Array ||
            newList instanceof ItemCollection ||
            newList instanceof LayerCollection ||
            newList instanceof OMCollection ||
            newList instanceof RQItemCollection ||
            newList instanceof DuList
        )) {
        newList = [newList];
    }

    /**
     * The original list, an Array or an After Effects Collection.
     * @memberof DuList.prototype
     * @name list
     * @readonly
     * @type {Array|Collection}
     */
    this.list = newList;
    /**
     * The current index of the iterator.
     * @memberof DuList.prototype
     * @name current
     * @readonly
     * @type {int}
     */
    this.current = -1;
    /**
     * True if the iterator is at the start.
     * @memberof DuList.prototype
     * @name atStart
     * @readonly
     * @type {Boolean}
     */
    this.atStart = false;
    /**
     * True if the iterator has reached the end.
     * @memberof DuList.prototype
     * @name atEnd
     * @readonly
     * @type {Boolean}
     */
    this.atEnd = false;
    /**
     * True if the iterator is between 0 and length-1. Note that on creation, the iterator is always invalid, but calling {@link DuList#next DuList.next()} moves it to the beginning and makes it valid.
     * @memberof DuList.prototype
     * @name valid
     * @readonly
     * @type {Boolean}
     */
    this.valid = false;
}

/**
 * Returns the number of items in the list
 * @return {int} The number of items.
 */
DuList.prototype.length = function() {
    return this.list.length;
}

/**
 * Alias for {@link DuList#length DuList.length()}
 * @alias DuList.length()
 * @name count
 * @memberof DuList.prototype
 * @function
 */
DuList.prototype.count = DuList.prototype.length;

/**
 * Accessor. First item is always 0, last is always length()-1<br />
 * Does not move the iterator to the index; to move the iterator use {@link DuList.goTo} instead.
 * @param {int} index The index of the item. If it is out of range (negative or > length()-1), returns null
 * @return  {object} The item at the given index.
 */
DuList.prototype.at = function(index) {
    var count = this.length();
    if (count == 0) return null;

    var min, max;

    if (this.isCollection) {
        min = 1;
        index++;
        max = count;
    } else {
        min = 0;
        max = count - 1;
    }

    if (index < min) return null;
    if (index > max) return null;

    return this.list[index];
}

/**
 * Gets the first index of a value, or -1 if not found
 * @memberof DuList
 * @param {*}	value	- The value to find. Must be compatible with the == operand if you don't provide a comparison function
 * @param {function}	[comparisonFunction]	- A function which compares two values which returns true if the values are considered the same.
 * @return {int}	The index of the value, -1 if not found
 */
DuList.prototype.indexOf = function(value, comparisonFunction) {
    if (DuDebug.checkVar(value, 'value', undefined, 'DuList.indexOf( value, comparisonFunction )') !== true)
        return -1;

    var useFunction = isdef( comparisonFunction );

    for (var i = 0, n = this.length(); i < n; i++) {
        if (!useFunction && this.at(i) == value) return i;
        else if (useFunction && comparisonFunction(this.at(i), value)) return i;
    }
    return -1;
}

/**
 * Checks if the list contains the item
 * @memberof DuList
 * @param {*}	value	- The value to find. Must be compatible with the == operand if you don't provide a comparison function
 * @param {function}	[comparisonFunction]	- A function which compares two values which returns true if the values are considered the same.
 * @return {Boolean}	
 */
DuList.prototype.contains = function(value, comparisonFunction) {
    return this.indexOf(value, comparisonFunction) >= 0;
}

/**
 * Checks if the list has duplicated values
 * @memberof DuList
 * @return {boolean}	true if the list has duplicated values. Always false for Ae Collections as they can't have duplicated items.
 */
DuList.prototype.hasDuplicates = function() {
    for (var i = 0, n = this.length(); i < n; i++) {
        for (var j = i + 1; j < n; j++) {
            if (this.at(i) === this.at(j)) return true;
        }
    }
    return false;
}

/**
 * Returns all duplicated values found in the list
 * @memberof DuList
 * @return {DuList}	The duplicated values. An empty list for Ae Collections as they can't have duplicated items.
 */
DuList.prototype.getDuplicates = function() {
    if (this.isCollection) return new DuList();

    var duplicates = [];

    for (var i = 0, n = this.length(); i < n; i++) {
        for (var j = i + 1; j < n; j++) {
            if (this.at(i) === this.at(j)) duplicates.push(this.at(j));
        }
    }

    duplicates = new DuList(duplicates);
    duplicates.removeDuplicates(duplicates);

    return duplicates;
}

/**
 * Removes all duplicated values from the list, and returns them.<br />
 * The internal list may be converted to an Array if needed.<br />
 * The iterator invalidated.
 * @memberof DuList
 * @param {function}	[comparisonFunction] - A function which compares two values which returns true if the values are considered the same.
 * @return {Array}	The duplicated (and removed) values. An empty list for Ae Collections as they can't have duplicated items.
 */
DuList.prototype.removeDuplicates = function(comparisonFunction) {
    // Convert to an Array
    this.convertToArray();

    var useFunction = isdef( comparisonFunction );
    var removed = [];

    for (var i = 0, n = this.length(); i < n; i++) {
        for (var j = n - 1; j > i; j--) {
            if (!useFunction && this.at(i) == this.at(j)) {
                removed = removed.concat(this.list.splice(j, 1));
            } else if (useFunction && comparisonFunction(this.at(i), this.at(j))) {
                removed = removed.concat(this.list.splice(j, 1));
            }
        }
    }

    this.valid = false;
    this.current = -1;

    return new DuList(removed);
}

/**
 * Compares two arrays.<br />
 * The items in the arrays must be compatible with the == operand if you don't provide a comparison function
 * @memberof DuList
 * @param {Array|Collection|DuList} other - The other list
 * @param {int} [floatPrecision=-1] - The precision for (float) number comparison, number of decimals. Set to -1 to not use.
 * @return {boolean} true if the two arrays contain the same values
 */
DuList.prototype.equals = function(other, comparisonFunction, floatPrecision) {
    var useFunction = typeof comparisonFunction === 'function';

    if (!DuList.isList(other)) return false;

    other = new DuList(other);

    if (this.length() != other.length()) return false;

    var originalIndex = this.current;

    this.reinitIterator();
    var ok = true;
    var item1;
    while (item1 = this.next()) {
        var item2 = other.at(this.current);

        // A list, recursive
        if (DuList.isList(item1)) {
            var test = new DuList(item1);
            if (!test.equals(item2, comparisonFunction, floatPrecision)) {
                ok = false;
                break;
            }
            continue;
        }

        // Comparison function
        if (useFunction) {
            if (!comparisonFunction(item1, item2)) {
                ok = false;
                break;
            }
            continue;
        }

        // Numbers
        if (jstype(item1) == 'number') {
            if (!DuMath.equals(item1, item2, floatPrecision)) {
                ok = false;
                break;
            }
            continue;
        }

        // Other
        if (item1 != item2) {
            ok = false;
            break;
        }
    }

    // Restore original iterator index
    this.goTo(originalIndex);
    return ok;
}

/**
 * Returns true if the list is empty
 * @return {boolean}
 */
DuList.prototype.isEmpty = function() {
    return this.length() == 0;
}

/**
 * Gets the last item in the list
 * @return {*} The last item, null if the list is empty.
 */
DuList.prototype.last = function() {
    if (this.isEmpty()) return null;
    return this.at(this.length() - 1);
}

/**
 * Gets the first item in the list
 * @return {*} The first item, null if the list is empty.
 */
DuList.prototype.first = function() {
    if (this.isEmpty()) return null;
    return this.at(0);
}

/**
 * Converts the stored list to an Array if it was a Collection.<br />
 * This enables the modification of the list, but changes in the list will not be reflected in the application (if a layer is removed from the list, it is not removed in the application).
 */
DuList.prototype.convertToArray = function(index) {
    // Nothing to do
    if (!this.isCollection) return;

    // The new array
    var arr = [];
    for (var i = 1, n = this.list.length; i <= n; i++) {
        arr.push(this.list[i]);
    }

    this.isCollection = false;
    this.isArray = true;
    this.list = arr;

}

/**
 * Removes the item at the given index. The internal list may be converted to an Array if needed.<br />
 * The iterator invalidated.
 * @param {int} index The index.
 */
DuList.prototype.remove = function(index) {
    // Convert to an Array
    this.convertToArray();
    this.list.splice(index, 1);

    this.valid = false;
    this.current = -1;
}

/**
 * Removes the first value from the list. The value must be checkable with the <code>==</code> operator if no <code>comparisonFunction</code> is provided.<br />
 * The internal list may be converted to an Array if needed.<br />
 * The iterator invalidated.
 * @param {int} index The index.
 * @param {function} [comparisonFunction] A function which compares two values which returns true if the values are considered the same.
 */
DuList.prototype.removeOne = function(value, comparisonFunction) {
    // Convert to an Array
    this.convertToArray();

    var index = this.indexOf(value, comparisonFunction);
    if (index >= 0) this.remove(index);

    this.valid = false;
    this.current = -1;
}

/**
 * Removes all occurences of the value from the list. The value must be checkable with the <code>==</code> operator if no <code>comparisonFunction</code> is provided.<br />
 * The internal list may be converted to an Array if needed.<br />
 * The iterator invalidated.
 * @param {int} index The index.
 * @param {function} [comparisonFunction] A function which compares two values which returns true if the values are considered the same.
 * @return {int} The number of items removed.
 */
DuList.prototype.removeAll = function(value, comparisonFunction) {
    // Convert to an Array
    this.convertToArray();

    var count = 0;
    var index;
    do {
        index = this.indexOf(value, comparisonFunction);
        if (index >= 0) this.remove(index);
        count++;
    }
    while (index >= 0);

    this.valid = false;
    this.current = -1;

    return count;
}

/**
 * Reimplements the Array.sort() method.<br />
 * The internal list may be converted to an Array if needed.<br />
 * The iterator is invalidated.
 * @param {function} compareFunction Specifies a function that defines the sort order. If omitted, the array elements are converted to strings, then sorted according to each character's Unicode code point value.
 * @return {Array} The sorted array. Note that the array is sorted in place, and no copy is made.
 */
DuList.prototype.sort = function(compareFunction) {
    // Convert to an Array
    this.convertToArray();

    if (!isdef( compareFunction )) this.list.sort();
    else this.list.sort(compareFunction);

    this.valid = false;
    this.current = -1;

    return this.list;
}

/**
 * Adds one or more elements to the end of the list and returns the new length of the list.<br />
 * The internal list may be converted to an Array if needed.
 * @param {any} element0 The element(s) to add to the end of the array.
 * @param {any} element1 The element(s) to add to the end of the array.
 * @param {any} element... The element(s) to add to the end of the array.
 * @param {any} elementN The element(s) to add to the end of the array.
 * @return {int} The new length of the list.
 */
DuList.prototype.push = function() {
    this.convertToArray();

    for (var i = 0, n = arguments.length; i < n; i++) {
        this.list.push(arguments[i]);
    }

    return this.list.length;
}

/**
 * Mergeserge two lists.<br />
 * This method does not change the existing list, but instead returns a new list. 
 * @param {Array|DuList} other The other list.
 * @return {DuList} The new list.
 */
DuList.prototype.concat = function(other) {
    // Make copies to not modify existing lists
    other = new DuList(other);
    current = new DuList(this);
    // Convert to arrays
    other.convertToArray();
    current.convertToArray();
    return new DuList( current.list.concat(other.list) );
}

/**
 * Adds one or more elements to the end of the list and returns the new length of the list, only if the value is not already in the list<br />
 * The internal list may be converted to an Array if needed.
 * @param {function} [comparisonFunction] A function which compares two values which returns true if the values are considered the same.
 * @param {any} element0 The element(s) to add to the end of the array.
 * @param {any} element1 The element(s) to add to the end of the array.
 * @param {any} element... The element(s) to add to the end of the array.
 * @param {any} elementN The element(s) to add to the end of the array.
 * @return {int} The new length of the list.
 */
DuList.prototype.pushUnique = function(comparisonFunction) {
    this.convertToArray();

    var args = [];

    for (var i = 1, n = arguments.length; i < n; i++) {
        var arg = arguments[i];
        if (this.indexOf(arg, comparisonFunction) >= 0) continue;
        this.push(arg);
    }

    return this.list.length;
}

/**
 * Alias for {@link DuList#push DuList.push()}
 * @alias DuList.push()
 * @name append
 * @memberof DuList.prototype
 * @function
 */
DuList.prototype.append = DuList.prototype.push;

/**
 * Alias for {@link DuList#pushUnique DuList.pushUnique()}
 * @alias DuList.pushUnique()
 * @name appendUnique
 * @memberof DuList.prototype
 * @function
 */
DuList.prototype.appendUnique = DuList.prototype.pushUnique;

/**
 * Merges the new array to the current list.<br />
 * Note that to the contrary of the <code>Array.concat()</code> method, this does not create a new list, but modifies the current one in place.<br />
 * The internal list may be converted to an Array if needed.
 * @param {any[]} arr The other array.
 * @return {int} The new length of the list.
 */
DuList.prototype.merge = function(arr) {
    this.convertToArray();

    this.list = this.list.concat(arr);

    return this.list.length;
}

/**
 * Merges the new array to the current list.<br />
 * Will only add items if they're not already in the list.<br />
 * Note that to the contrary of the <code>Array.concat()</code> method, this does not create a new list, but modifies the current one in place.<br />
 * The internal list may be converted to an Array if needed.
 * @param {any[]|DuList} arr The other array/list.
 * @param {function} [comparisonFunction] A function which compares two values which returns true if the values are considered the same.
 * @return {int} The new length of the list.
 */
DuList.prototype.mergeUnique = function(arr, comparisonFunction) {
    arr = new DuList(arr);
    this.convertToArray();

    for (var i = 0, n = arr.length(); i < n; i++) {
        this.pushUnique(comparisonFunction, arr.at(i));
    }

    return this.list.length;
}

/**
 * Reimplementation of the <code>Array.join</code> function.<br />
 * For collections, the name of the item will be used, or any other property which makes sense as a string list.
 * @param {string} separator The separator to use
 * @return {string} The new length of the list.
 */
DuList.prototype.join = function(separator) {
    if (this.isArray) return this.list.join(separator);

    // Collection without "name" property
    if (this.list instanceof RQItemCollection) {
        var str = '';
        this.do(function(item) {
            if (!this.current == 0) str += separator;
            str += item.comp.name;
            if (item.status == RQItemStatus.WILL_CONTINUE) str += ' (will continue)';
            else if (item.status == RQItemStatus.NEEDS_OUTPUT) str += ' (no output)';
            else if (item.status == RQItemStatus.UNQUEUED) str += ' (disabled)';
            else if (item.status == RQItemStatus.QUEUED) str += ' (ready)';
            else if (item.status == RQItemStatus.RENDERING) str += ' (rendering)';
            else if (item.status == RQItemStatus.USER_STOPPED) str += ' (stopped)';
            else if (item.status == RQItemStatus.ERR_STOPPED) str += ' (rendering error)';
            else if (item.status == RQItemStatus.DONE) str += ' (done)';
        });
        return str;
    }

    // Other collections have a "name" property
    var str = '';
    this.do(function(item) {
        if (!this.current == 0) str += separator;
        str += item.name;
    });
    return str;
}

/**
 * Replaces all occurences of a value with another value.<br />
 * The internal list may be converted to an Array if needed.
 * @param {any} what The current value
 * @param {any} with The new value
 * @param {function} [comparisonFunction] A function which compares two values which returns true if the values are considered the same.
 * @returns {int} The number of occurences which were updated.
 */
DuList.prototype.replace = function(previousValue, newValue, comparisonFunction) {
    this.convertToArray();

    var useFunction = isdef( comparisonFunction );

    var count = 0;

    for (var i = 0, n = this.length(); i < n; i++) {
        if (!useFunction && this.at(i) == previousValue) {
            this.list[i] = newValue;
            count++;
        } else if (useFunction && comparisonFunction(this.at(i), previousValue)) {
            this.list[i] = newValue;
            count++;
        }
    }

    return count;
}

/**
 * Removes the last element of the list and returns it.<br />
 * The internal list may be converted to an Array if needed.
 * @return {any|null} The last element or null if the list is empty.
 */
DuList.prototype.pop = function() {
    this.convertToArray();
    return this.list.pop();
}

// ================ ITERATOR METHODS ================

/**
 * Reinits the iterator, i.e. go to index -1 so that the next call to {@link DuList.next} returns the first item.
 */
DuList.prototype.reinitIterator = function() {
    this.goTo(-1);
}

/**
 * Sets the iterator on the index
 * @param {int} index - The index
 * @return {*} The item at index, or null if the index is invalid
 */
DuList.prototype.goTo = function(index) {
    this.current = index;

    var count = this.length();

    if (this.current < 0 || this.current >= count) this.valid = false;
    else this.valid = true;

    if (this.current == 0) this.atStart = true;
    else this.atStart = false;

    if (this.current == count - 1) this.atEnd = true;
    else this.atEnd = false;

    if (this.valid) return this.at(this.current);
    else return null;
}

/**
 * Goes to the end of the Iterator
 * @return {Object} The item at the end, or null if length is 0
 */
DuList.prototype.goToEnd = function() {
    if (this.isEmpty()) return null;
    return this.goTo(this.length() - 1);
}

/**
 * Goes to the start of the Iterator
 * @return {Object} The item at the start, or null if length is 0
 */
DuList.prototype.goToStart = function() {
    if (this.isEmpty()) return null;
    return this.goTo(0);
}

/**
 * Increments the Iterator<br />
 * Must be called at least once to validate the iterator
 * @return {any} The next item, or null if there isn't
 */
DuList.prototype.next = function() {
    if (this.isEmpty()) return null;

    if (!this.valid) {
        return this.goToStart();
    }

    if (this.current < this.length() - 1) {
        return this.goTo(this.current + 1);
    }

    this.goTo(this.current + 1);
    return null;
}

/**
 * Decrements the Iterator
 * if it's called while valid is false, goes to the end
 * @return {Object} The previous item, or null if there isn't
 */
DuList.prototype.previous = function() {
    if (this.isEmpty()) return null;

    if (!this.valid) {
        return this.goToEnd();
    }

    if (this.current > 0) {
        return this.goTo(this.current - 1);
    }

    return null;
}

/**
 * Executes a function on each item of the List
 * @param {function} callBack - The function to execute, which takes one parameter: an item of the list
 * @param {Bool} [reverse=false] - Set this to true to iterate from the end.
 */
DuList.prototype.do = function(callBack, reverse) {
    if (this.isEmpty()) return;

    reverse = def(reverse, false);

    // Keep the current index
    var current = this.current;

    if (reverse)
    {
        for (var i = this.length() - 1; i >= 0; i--) {
            this.valid = true;
            this.current = i;
            callBack(this.at(i));
        }
    }
    else
    {
        for (var i = 0, n = this.length(); i < n; i++) {
            this.valid = true;
            this.current = i;
            callBack(this.at(i));
        }
    }
    
    // Restore the current index
    this.goTo(current);
}


// ================ STATIC ==========================

/**
 * Checks if this is an Array or an After Effects collection type or a {@link DuList}
 * @static
 * @param {Array|Collection} list - The list to check
 * @return {boolean} true if this is a Cllection or an Array or a {@link DuList}
 */
DuList.isList = function(list) {
    return (
        list instanceof Array ||
        list instanceof ItemCollection ||
        list instanceof LayerCollection ||
        list instanceof OMCollection ||
        list instanceof RQItemCollection ||
        list instanceof DuList
    );
}

// ================ DEPRECATED ======================


/**
 * A function to compare two elements in an array
 * @callback DuList.indexOf~comparisonFunction
 * @memberof DuList.indexOf
 * @param {*} elementInArray The element in the array
 * @param {*} value The value to compare
 * @return {bool} true if the two values should be considered the same
 */

/**
 * Gets the first index of a value in an Array, or -1 if not found
 * @memberof DuList
 * @static
 * @deprecated
 * @param {Array}	arr	- The array
 * @param {*}	value	- The value to find. Must be compatible with the == operand, or provide a comparison function
 * @param {function}	[comparisonFunction]	- A function which compares two values which returns true if the values are considered the same.
 * @return {int}	The index of the value, -1 if not found
 */
/*DuList.indexOf = function(arr, value, comparisonFunction) {
    if (value == undefined) throw "Value can not be undefined";
    var useFunction = typeof comparisonFunction === 'function';

    for (var i = 0; i < arr.length; i++) {
        if (!useFunction && arr[i] == value) return i;
        if (useFunction && comparisonFunction(arr[i], value)) return i;
    }
    return -1;
}//*/

/**
 * Checks if the array has duplicate values
 * @memberof DuList
 * @static
 * @deprecated
 * @param {Array}	arr	- The array
 * @return {boolean}	true if the array has duplicate values
 */
/*DuList.hasDuplicates = function(arr) {
    for (var i = 0; i < arr.length - 1; i++) {
        for (var j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) return true;
        }
    }
    return false;
}//*/

/**
 * Returns all duplicated values found in the array
 * @memberof DuList
 * @static
 * @deprecated
 * @param {Array}	arr	- The array
 * @return {Array}	The duplicated values
 */
/*DuList.getDuplicates = function(arr) {
    var duplicates = [];
    for (var i = 0; i < arr.length - 1; i++) {
        for (var j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) duplicates.push(arr[j]);
        }
    }
    DuList.removeDuplicates(duplicates);
    return duplicates;
}//*/

/**
 * Removes all duplicated values from the Array, and returns them
 * @memberof DuList
 * @static
 * @deprecated
 * @param {Array}	arr	- The array
 * @param {function}	[comparisonFunction] - A function which compares two values which returns true if the values are considered the same.
 * @return {Array}	The duplicated (and removed) values
 */
/*DuList.removeDuplicates = function(arr, comparisonFunction) {
    var useFunction = typeof comparisonFunction === 'function';
    var removed = [];
    for (var i = 0; i < arr.length - 1; i++) {
        for (var j = i + 1; j < arr.length; j++) {
            if (!useFunction && arr[i] === arr[j]) removed = removed.concat(arr.splice(j, 1));
            if (useFunction && comparisonFunction(arr[i], arr[j])) removed = removed.concat(arr.splice(j, 1));
        }
    }
    //sometimes the two last items may still be the same (for a reason I don't understand)
    if (!useFunction && arr[arr.length - 2] === arr[arr.length - 1]) removed.push(arr.pop());
    if (useFunction && comparisonFunction(arr.length - 2, arr.length - 1)) removed.push(arr.pop());

    return removed;
}//*/

/**
 * Compares two arrays.<br />
 * The items in the arrays must be compatible with the == operand
 * @memberof DuList
 * @static
 * @deprecated
 * @param {Array|Collection} array1 - The array
 * @param {Array|Collection} array2 - The array
 * @param {int} [floatPrecision=-1] - The precision for (float) number comparison, number of decimals. Set to -1 to not use.
 * @return {boolean} true if the two arrays contain the same values
 */
/*DuList.compare = function(array1, array2, floatPrecision) {
    if (!DuList.isList(array1) && !DuList.isList(array2)) {
        if (typeof array1 == 'number' && typeof array2 == 'number') {
            return DuMath.equals(array1, array2, floatPrecision)
        } else return array1 == array2;
    }
    if (DuList.isList(array1) && !DuList.isList(array2)) return false;
    if (!DuList.isList(array1) && DuList.isList(array2)) return false;
    if (array1.length != array2.length) return false;

    var it = new DuList(array1);
    var ok = true;
    it.do(function(item1) {
        var item2 = array2[it.current];
        if (!DuList.compare(item1, item2, floatPrecision)) {
            ok = false;
            return;
        }
    });

    return ok;
}
//*/// ==================== |-------| ====================
// ==================== | color | ====================
// ==================== |-------| ====================

/**
 * Constructs a new color object
 * @class
 * @name DuColor
 * @classdesc A simple class to manage colors and convert them.
 * @param {float[]} [floatRGBA=[0,0,0,1]] An [R,G,B,A] float Array.<br />
 * Negative values are clamped to 0.<br />
 * Alpha > 1 is clamped to 1.<br />
 * Colors are stored in 32 bit float to keep the maximum precision.
 * @property {float} red The red value
 * @property {float} green The green value
 * @property {float} blue The blue value
 * @property {float} alpha The alpha value
 * @category DuESF
 */
function DuColor( floatRGBA )
{
	floatRGBA = def(floatRGBA, [0,0,0,0]);
	
	this.red = floatRGBA[0];
	if (this.red < 0) this.red = 0;
	if (!jstype( (this.red ) == 'number') ) this.red = 0;
	if ( isNaN(this.red) ) this.red = 0;

	this.green = floatRGBA[1];
	if (this.green < 0) this.green = 0;
	if (!jstype( (this.green ) == 'number') ) this.green = 0;
	if ( isNaN(this.green) ) this.green = 0;

	this.blue = floatRGBA[2];
	if (this.blue < 0) this.blue = 0;
	if (!jstype( (this.blue ) == 'number') ) this.blue = 0;
	if ( isNaN(this.blue) ) this.blue = 0;

	if (floatRGBA.length > 3) this.alpha = floatRGBA[3];
	else this.alpha = 1.0;
	if (this.alpha < 0) this.alpha = 0;
	if (this.alpha > 1) this.alpha = 1;
	if (!jstype( (this.alpha ) == 'number') ) this.alpha = 0;
	if ( isNaN(this.alpha) ) this.alpha = 0;
}

/**
 * Returns the color as a float Array with alpha
 * @param {bool} [clamped=true] Set to false to keep the values > 1.0
 * @return {float} an [R,G,B,A] Array.
 */
DuColor.prototype.floatRGBA = function(clamped)
{
	clamped = def( clamped, true );

	var col = this.floatRGB();

	var alpha = this.alpha;
	if (clamped) alpha = DuMath.clamp( alpha );

	col.push(alpha);

	return col;
}

/**
 * Returns the color as a float Array without alpha
 * @param {bool} [clamped=true] Set to false to keep the values > 1.0
 * @return {float} an [R,G,B] Array.
 */
DuColor.prototype.floatRGB = function(clamped)
{
	clamped = def( clamped, true );

	var col = [
		this.red,
		this.green,
		this.blue
	]

	if (clamped) return DuMath.clamp( col );

	return col;
}

/**
 * Returns the color as an 8-bit int Array with alpha
 * @return {int} an [R,G,B,A] Array.
 */
DuColor.prototype.intRGBA = function()
{
	var col = this.intRGB();
	col.push( parseInt( this.alpha * 255 ) );
	return col;
}

/**
 * Returns the color as an 8-bit int Array without alpha
 * @return {int} an [R,G,B] Array.
 */
DuColor.prototype.intRGB = function()
{
	return [
		parseInt( this.red * 255 ),
		parseInt( this.green * 255 ),
		parseInt( this.blue * 255 )
	]
}

/**
 * true if [R,G,B,A] in the range 0.0 ... 1.0
 * @return {boolean} true if the color is valid
 */
DuColor.prototype.isValid = function()
{
	if (this.red > 1) return false;
	if (this.green > 1) return false;
	if (this.blue > 1) return false;
	return true;
}

/**
 * Returns the hexcode for this color
 * @return {string} The hex code, without the leading '#'.
 */
DuColor.prototype.hex = function()
{
	var red = this.red*255;
	var green = this.green*255;
	var blue = this.blue*255;
	var hexR = red.toString(16);
	var hexG = green.toString(16);
	var hexB = blue.toString(16);
	if (hexR.length == 1) hexR = "0" + hexR;
	if (hexG.length == 1) hexG = "0" + hexG;
	if (hexB.length == 1) hexB = "0" + hexB;
	
	return hexR+hexG+hexB;
}

/**
 * Returns the hexcode for this color, including the alpha (at the end)
 * @return {string} The hex code, without the leading '#'.
 */
DuColor.prototype.hexA = function()
{
	var alpha = this.alpha*255;
	var hexA = alpha.toString(16);
	if (hexA.length == 1) hexA = "0" + hexA;

	return this.hex() + hexA;
}

/**
 * Returns the HSL values
 * @return {float[]} the HSL
 */
DuColor.prototype.floatHSL = function()
{
	var r = this.red;
	var g = this.blue;
	var b = this.green;

    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min)
	{
        h = s = 0; // achromatic
    }
	else
	{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max)
		{
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }

    return [h, s, l];
}

/**
 * Returns the HSLA values
 * @return {float[]} the HSL
 */
DuColor.prototype.floatHSLA = function()
{
	var hsla = this.floatHSL();
	hsla.push( this.alpha );
    return hsla;
}

/**
 * Creates a new color darker than the current one
 * @param {int} [ratio=200] A percentage: 200 means twice darker, 50 twice lighter
 * @returns {DuColor} The new color
 */
DuColor.prototype.darker = function( ratio )
{
	ratio = def(ratio, 200);
	ratio = ratio / 100;

	return new DuColor([
		this.red/ratio,
		this.green/ratio,
		this.blue/ratio,
		this.alpha,
	]);
}

/**
 * Creates a new color lighter than the current one
 * @param {int} [ratio=200] A percentage: 200 means twice lighter, 50 twice darker
 * @returns {DuColor} The new color
 */
DuColor.prototype.lighter = function( ratio )
{
	ratio = def(ratio, 200);
	ratio = ratio / 100;

	return new DuColor([
		this.red*ratio,
		this.green*ratio,
		this.blue*ratio,
		this.alpha,
	]);
}

/**
 * Compares two colors
 * @param {Boolean} [ignoreAlpha=false] Set to true to consider colors to be equal if they differ only by their alpha.
 * @param {int} [precision=4] The precision to use (the number of decimals to compare).
 * @return {Boolean} true if the colors are the same.
 */
DuColor.prototype.equals = function( other, ignoreAlpha, precision )
{
	if (!DuMath.equals( this.red, other.red, precision )) return false;
	if (!DuMath.equals( this.green, other.green, precision )) return false;
	if (!DuMath.equals( this.blue, other.blue, precision )) return false;
	if (!DuMath.equals( this.alpha, other.alpha, precision )) return false;
	return true;
}

/**
	* Creates a JSON string representation of the color; Actually an RGBA float Array.
	* @return {string} The JSON
	*/
DuColor.prototype.toJSON = function ()
{
	return '[' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ']';
}

/**
 * Creates a color adjusted according to the brightness setting of the application.<br />
 * For now, works only in After Effects
 * @return The new color
 */
DuColor.prototype.adjusted = function( )
{
	if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS)
	{
		//gets the main application color
		var q = app.themeColor( 78 )[ 0 ];
		//the darkest one is 0.15000000596046
		q = q - 0.15000000596046;
		var newColor = this.floatRGBA() + [ q, q, q, 0 ];
		return new DuColor( newColor );
	}
    return this;
}

// ============== STATIC ===============

/**
	* Enum for predefined colors. float [R,G,B,A]
	* @readonly
	* @static
	* @enum {DuColor[]}
	*/
DuColor.Color =
{
	TRANSPARENT: new DuColor([0,0,0,0]),
	BLACK: new DuColor([0,0,0,1]),
	WHITE: new DuColor([1,1,1,1]),
	OBSIDIAN: new DuColor([.082,.082,.082,1]),
	ABYSS_GREY: new DuColor([0.109,0.109,0.109,1]),
	VERY_DARK_GREY:new DuColor([0.199,0.199,0.199,1]),
	DARK_GREY: new DuColor([.262,.262,.262,1]),
	LIGHT_GREY: new DuColor([.65,.65,.65,1]),
	VERY_LIGHT_GREY: new DuColor([.85,.85,.85,1]),
	RAINBOX_RED: new DuColor([.925,.094,.094,1]),
	ORANGE: new DuColor([.925,.471,.094,1]),
	YELLOW_ORANGE: new DuColor([.925,.655,.094,1]),
	YELLOW: new DuColor([.925,.839,.094,1]),
	GREEN: new DuColor([.094,.925,.094,1]),
	LIGHT_GREEN: new DuColor([.541,.925,.569,1]),
	LIGHT_BLUE: new DuColor([.471,.847,.925,1]),
	LIGHT_PURPLE: new DuColor([.471,.471,.925,1]),
	AE_DARK_GREY: new DuColor([0.199,0.199,0.199,1]),
	AFTER_EFFECTS_BLUE: new DuColor([.1764,.5490,.9215,1]),
	RX_PURPLE: new DuColor([.7411,.1843,.7686,1]),
	APP_BACKGROUND_COLOR: new DuColor([0.199,0.199,0.199,1]),
	APP_HIGHLIGHT_COLOR: new DuColor([.7411,.1843,.7686,1]),
	APP_TEXT_COLOR: new DuColor( [ 0.6941, 0.6941, 0.6941, 1]),
	AE_ORANGE: new DuColor( [ .7804, .5725, 0, 1])
};

// Get the app colors
DuColor.init = function() 
{
	// ScriptUIGraphics object does not contain foreground & background colors in After Effects...
	if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS) 
	{
		DuColor.Color.APP_TEXT_COLOR = new DuColor( [ 0.6941, 0.6941, 0.6941, 1]);
		var bgColor = app.themeColor(78) - [0.0127, 0.0127, 0.0127];
		bgColor.push(1);
		DuColor.Color.APP_BACKGROUND_COLOR = new DuColor( bgColor );
		DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.AFTER_EFFECTS_BLUE;
		DuColor.Color.DARK_GREY = new DuColor( [.2, .2, .2, 1] );
		DuColor.Color.OBSIDIAN = new DuColor( [.0862, .0862, .0862, 1] );
	}
	else if (DuESF.host == DuESF.HostApplication.PHOTOSHOP)
	{
		DuColor.Color.APP_TEXT_COLOR = new DuColor( [ 0.6941, 0.6941, 0.6941, 1]);
		DuColor.Color.APP_BACKGROUND_COLOR = DuColor.Color.VERY_DARK_GREY;
		DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.DARK_GREY;
		DuColor.Color.DARK_GREY = new DuColor( [.2, .2, .2, 1] );
		DuColor.Color.OBSIDIAN = new DuColor( [.0862, .0862, .0862, 1] );
	}
	else
	{
		// create a label to (try to) get the color
		var dummyWin = new Window( 'palette' );
		var dummyLabel = dummyWin.add('statictext', undefined,'text');

		var textPen = dummyLabel.graphics.foregroundColor;
		var bgBrush = dummyWin.graphics.backgroundColor;

		if (textPen) DuColor.Color.APP_TEXT_COLOR = new DuColor( textPen.color );
		else DuColor.Color.APP_TEXT_COLOR = DuColor.Color.LIGHT_GREY;
		if (bgBrush) DuColor.Color.APP_BACKGROUND_COLOR = new DuColor( bgBrush.color );
		else DuColor.Color.APP_BACKGROUND_COLOR = DuColor.Color.DARK_GREY;
		
		DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.RX_PURPLE;
	}
	
}
DuESF.initMethods.push( DuColor.init );

/**
	* Creates a new DuColor from a hex code/array
	* @static
	* @memberof DuColor
	* @param {string|int[]} hexColor	- The hexadecimal color
	* @return {DuColor}	The color
*/
DuColor.fromHex = function( hexColor )
{
	var isString = jstype( hexColor ) == 'string';

	if (isString)
	{
		if (hexColor.indexOf("#") == 0) hexColor = hexColor.replace("#","");
		var red = parseInt(hexColor.substr(0,2),16)/255.0;
		var green = parseInt(hexColor.substr(2,2),16)/255.0;
		var blue = parseInt(hexColor.substr(4,2),16)/255.0;
		return new DuColor( [red,green,blue,1] );
	}
	else
	{
		var r = hexColor >> 16;
		var g = (hexColor & 0x00ff00) >> 8;
		var b = hexColor & 0xff;
		return new DuColor( [r/255,g/255,b/255,1] );
	}
}

/**
 * Creates a new color from HSL(A) values
 * @static
 * @param {float[]} hsl the HSL(A) values
 * @return {DuColor} the color.
 */
DuColor.fromHSL = function( hsl )
{
	var r, g, b, a;
	var h = hsl[0];
	var s = hsl[1];
	var l = hsl[2];

    if(s == 0)
	{
        r = g = b = l; // achromatic
    }
	else
	{
        function hue2rgb(p, q, t)
		{
            if(t < 0) t += 1;
            if(t > 1) t -= 1;
            if(t < 1/6) return p + (q - p) * 6 * t;
            if(t < 1/2) return q;
            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        }

        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }

	if (hsl.length > 3) a = hsl[3];
	else a = 1;

    return new DuColor( [r, g, b, a] );
}

/**
 * Creates a new color from an 8-bit int RGB(A) array
 * @static
 * @param {int[]} source The 8-bit int RGB(A) array
 * @return {DuColor}
 */
DuColor.fromInt = function( intRGB )
{
	var floatColor = [];
	for (var i = 0, numChannels = color.length; i < numChannels; i++)
	{
		floatColor.push( color[ i ] / 255.0 );
	}

	return new DuColor( floatColor );
}

/**
	* Creates a color from a JSON string; Actually a JSON RGBA float Array.
	* @static
	* @param {string} json The JSON string
	* @return {DuColor} The color
	*/
DuColor.fromJSON = function (json)
{
	return new DuColor( JSON.parse(json) );
}

/**
 * Generates a random color, with the alpha == 1.0
 * @static
 * @return {DuColor} The color
 */
DuColor.random = function()
{
	var color = [0,0,0,1];
	for (var i = 0 ; i < 3 ; i++)
	{
		color[i] = DuMath.random();
	}

	return new DuColor(color);
}

// ========= DEPRECATED ==============

/**
 * Checks if this color is valid ([R,G,B,A] in the range 0.0 ... 1.0)
 * @static
 * @deprecated
 * @param {float[]} color - The floatRGBA color to validate
 * @param {boolean} [ignoreAlpha=false] - Will return true even if the array does not have any alpha value
 * @return {boolean} true if the color is valid
 */
DuColor.isValid = function (color, ignoreAlpha)
{
	ignoreAlpha = def( ignoreAlpha, false, false );
	if ( !jstype(color) == 'array' ) return false;
	var numChannels = color.length;
	if ( numChannels != 4 && !ignoreAlpha ) return false;
	if ( numChannels != 4 && numChannels != 3 ) return false;
	for (var i = 0, numChannels; i < numChannels; i++)
	{
		var c = color[i];
		if (isNaN(c)) return false;
		if (!jstype(color) == 'number') return false;
		if (c < 0) color[i] = 0;
		if (c > 1) color[i] = 1;
	}
	return true;
}

/**
	* Generates a random color
	* @static
	* @deprecated
	* @memberof DuColor
	* @return {float[]}	The color as an [R,G,B,A] Array with float values between 0.0 and 1.0
*/
DuColor.randomFloatRGBA = function ()
{
	var color = [0,0,0,1];
	for (var i = 0 ; i < 3 ; i++)
	{
		color[i] = DuMath.random();
	}
	return color;
}

/**
	* Converts an hexadecimal color to a floatRGBA Array
	* @static
	* @deprecated
	* @memberof DuColor
	* @param {string|int[]} hexColor	- The hexadecimal color
	* @param {boolean}	[isString=true] 	- Whether hexColor is a string or an Array of int of base 16
	* @return {float[]}	The color as an [R,G,B,A] Array with float values between 0.0 and 1.0
*/
DuColor.hexToRGB = function (hexColor,isString)
{
	if (isString == undefined) isString = true;
	if (isString)
	{
		if (hexColor.indexOf("#") == 0) hexColor = hexColor.replace("#","");
		var red = parseInt(hexColor.substr(0,2),16)/255.0;
		var green = parseInt(hexColor.substr(2,2),16)/255.0;
		var blue = parseInt(hexColor.substr(4,2),16)/255.0;
		return [red,green,blue,1];
	}
	else
	{
		var r = hexColor >> 16;
		var g = (hexColor & 0x00ff00) >> 8;
		var b = hexColor & 0xff;
		return [r/255,g/255,b/255,1];
	}
}

/**
	* Converts an RGB color to a hex string
	* @memberof DuColor
	* @deprecated
	* @static
	* @param {float[]} rgbColor	- The rgb color
	* @return {string}	The color as an hex string
*/
DuColor.rgbToHex = function (rgbColor)
{
	var red = rgbColor[0]*255;
	var green = rgbColor[1]*255;
	var blue = rgbColor[2]*255;
	var hexR = red.toString(16)
	var hexG = green.toString(16)
	var hexB = blue.toString(16);
	if (hexR.length == 1) hexR = "0" + hexR;
	if (hexG.length == 1) hexG = "0" + hexG;
	if (hexB.length == 1) hexB = "0" + hexB;
	var hex = hexR+hexG+hexB;
	return hex;
}

/**
	* Converts an HSL color to RGB
	* @deprecated
	* @static
	* @param {float[]} color - The RGBA color array
	* @return {float[]} the HSLA color array
*/
DuColor.hslToRgb = function (color)
{
    var r, g, b;
	var h = color[0];
	var s = color[1];
	var l = color[2];

    if(s == 0)
	{
        r = g = b = l; // achromatic
    }
	else
	{
        function hue2rgb(p, q, t)
		{
            if(t < 0) t += 1;
            if(t > 1) t -= 1;
            if(t < 1/6) return p + (q - p) * 6 * t;
            if(t < 1/2) return q;
            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        }

        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }

    return [r, g, b, color[3]];
}

/**
	* Converts an RGB color to HSL
	* @deprecated
	* @static
	* @param {float[]} color - The HSLA color array
	* @return {float[]} the RGBA color array
*/
DuColor.rgbToHsl = function (color)
{
	var r = color[0];
	var g = color[1];
	var b = color[2];

    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min)
	{
        h = s = 0; // achromatic
    }
	else
	{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max)
		{
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }

    return [h, s, l, color[3]];
}

/**
 * Converts an 8bpc color array to a 32bpc float color array
 * @deprecated
 * @static
 * @param {int[]} color - The RGB(A) color array in 8bpc (0-255 range)
 * @return {float[]} the RGBA color array
 */
DuColor.eightBpcToFloat = function (color)
{
	var floatColor = [];
	for (var i = 0, numChannels = color.length; i < numChannels; i++)
	{
		floatColor.push( color[ i ] / 255 );
	}
	return floatColor;
}
// ==================== |----------| ====================
// ==================== | settings | ====================
// ==================== |----------| ====================

/**
	* Constructs a new DuSettings instance.
	* @class DuSettings
	* @classdesc A class to manage settings.<br />
	 * Warning: DuESF stores the settings in json files and needs the right to write files, but it does not check if it has write access on the files, you should check that first using methods specific to the host application.
	* @param {string}	  [namespace=DuESF.scriptName]     - A namespace to group your settings.
	* @param {File|string}    [file=Folder.myDocuments/namespace/namespace_settings.json]    - The file to store the settings
	* @property {string}	  namespace	- A namespace to group your settings.
	* @property {File}		file	- The file to store the settings
	* @property {Object}	data	- The settings as a js object
	* @category DuESF
	*/
function DuSettings( namespace, file, dontSavePath )
{
	dontSavePath = def(dontSavePath, false);
	namespace = def(namespace, DuESF.scriptName);
	if ( DuDebug.checkVar( namespace, 'namespace', 'string', DuSettings ) !== true ) throw "Sorry, an error has occured in `new DuSettings()`.";

	if (namespace == "") throw "new Dusettings( namespace, file ): error\n\nnamespace can not be an empty string";

	// Get path from duesf settings
	if ( !isdef( file ) )
	{
		var filePath = DuESF.settings.data.scriptSettingsFile;
		if ( isdef( filePath ) ) file = new File( filePath );
	}

	// Generate default path
	if (!isdef( file ))
	{
		if (DuFolder.canWrite(Folder.myDocuments))
			file = new File( Folder.myDocuments.absoluteURI + "/" + namespace + "/" + namespace + "_settings.json" );
		else
			file = new File( Folder.temp.absoluteURI + "/" + namespace + "/" + namespace + "_settings.json" );
	}

	this.namespace = namespace;
	if (file instanceof File) this.file = file;
	else this.file = new File(file);
	this.file.encoding = 'UTF-8';
	this.folder = this.file.parent;
	
	if (!dontSavePath)
	{
		DuESF.settings.data.scriptSettingsFile =  this.file.absoluteURI;
		DuESF.settings.save();
	}
	

	this.data = {};
	this.load();
}

/**
 * loads data from the settings file
 * @memberof DuSettings
 */
DuSettings.prototype.load = function()
{
	//load file
	if (this.file.exists)
	{
		this.data = DuFile.parseJSON( this.file );
		if (!this.data) this.data = {};
	}
}

/**
 * Saves data to the file.<br />
 * Warning: DuESF does not check if it has write access on the files, you should check that first using methods specific to the host application.
 * @memberof DuSettings
 * @return {boolean} true if the file has been correctly written
 */
DuSettings.prototype.save = function()
{
	try 
	{
		if ( !this.folder.exists ) this.folder.create();
	}
	catch (e)
	{
		DuDebug.throwError("Can't create folder", 'DuSettings.prototype.save', e);
		return false;
	}
	return DuFile.saveJSON(this.data, this.file);
}

/**
 * Sets the file to be used to save the settings
 * @param {File|string} file The file or path to the file
 */
DuSettings.prototype.setFile = function(file, dontSavePath)
{
	if (file instanceof File) this.file = file;
	else this.file = new File(file);
	if (file.exists) this.load();
	else this.save();
	if (!dontSavePath) {
		DuESF.settings.data.scriptSettingsFile =  this.file.absoluteURI;
		DuESF.settings.save();
	}
}

/**
	* Reset the settings to their default values (removes the settings file!)
	*/
DuSettings.prototype.reset = function()
{
	this.file.remove();
	this.data = {};
}
// Low-level undocumented function. Called by DuESF.init()
DuSettings.init = function() {
	DuESF.settings = new DuSettings( 'DuESF', DuFolder.duesfData.absoluteURI + '/duesf_settings.json', true  );
	
	/**
	 * The settings to store the script specific settings.
	 * @type {DuSettings}
	 * @memberof DuESF
	 * @static
	 */
	DuESF.scriptSettings = new DuSettings( DuESF.scriptName );
	
	// Load defaults
	var common  = def(DuESF.scriptSettings.data.common, {});
	var highlightSelection = def( common.highlightSelection, -1);
	var highlightColor = new DuColor( def( common.highlightColor, DuColor.Color.APP_HIGHLIGHT_COLOR ) );
	var debug = def( common.debug, false);

	// Debug mode
	DuESF.debug = debug;

	// Highlight color
	if (highlightSelection == 0) DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.AFTER_EFFECTS_BLUE;
	else if (highlightSelection == 1) DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.RX_PURPLE;
	else if (highlightSelection == 2) DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.RAINBOX_RED;
	else if (highlightSelection == 3) DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.AE_ORANGE;
	else if (highlightSelection > 3) DuColor.Color.APP_HIGHLIGHT_COLOR = highlightColor;
}
DuESF.initMethods.push( DuSettings.init );// ==================== |------------| ====================
// ==================== | translator | ====================
// ==================== |------------| ====================

/**
 * Creates a new string translation.
 * @class
 * @classdesc An translation for a string.
 * @param {string} source - The source string
 * @param {string} [translation=''] - The translated string
 * @param {string} [comment=''] - A comment to explain what needs to be explained
 * @param {string} [context=''] - The context where the string is used
 * @param {int} [contextId=0] - A unique id for the couple source/context
 * @category DuTranslator
 */
function DuTranslation(source,translation,comment,context,contextId)
{
	translation = def(translation, tr(source) );
	comment = def(comment, '');
	context = def(context, '');
	contextId = def(contextId, 0);
	/**
		* The source string
		* @memberof DuTranslation.prototype
		* @name source
		* @type {string}
	*/
	this.source = source;
	/**
		* The translated string
		* @memberof DuTranslation.prototype
		* @name translation
		* @type {string}
	*/
	this.translation = translation;
	/**
		* A comment to explain what needs to be explained
		* @memberof DuTranslation.prototype
		* @name comment
		* @type {string}
	*/
	this.comment = comment;
	/**
		* The context where the string is used
		* @memberof DuTranslation.prototype
		* @name context
		* @type {string}
	*/
	this.context = context;
	/**
		* A unique id for the couple source/context
		* @memberof DuTranslation.prototype
		* @name contextId
		* @type {string}
	*/
	this.contextId = contextId;
}

/**
 * The ExtendScript translator part of the Dutranslator Framework<br />
 * see {@link https://github.com/Rainbox-dev/Dutranslator}
 * @namespace
 * @category DuTranslator
 */
var DuTranslator = {};

/**
 * The current language id (fr, en, ..)
 * @memberof DuTranslator
 * @readonly
 * @type {string}
 */
DuTranslator.current = '';

/**
 * The current language name
 * @memberof DuTranslator
 * @readonly
 * @type {string}
 */
DuTranslator.currentName = '';

/* low-level, undocumented
 *
 * A map containing available languages.
 * There is a language name and a file name for each language id.
 * languages["fr_FR"] ["name"] is "Francais" for example.
 * Will be filled when executing Dutranslator.getAvailable().
 */
DuTranslator.languages = {};

/* low-level, undocumented
 * The translated strings  of the current language
 * An array of compounds containing the source, the translation and the context
 */
DuTranslator.localizedStrings = [];

/**
 * Some Settings for the translator
 * @namespace
 * @memberof DuTranslator
 * @category DuTranslator
 */
DuTranslator.Settings = {}

/**
 * The folder containing the translation files
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default DuESF.scriptSettings.file.parent
 *
 */
DuTranslator.Settings.folder = File($.fileName).path + "/";

/**
 * The prefix in the translation filenames
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default "thisScriptFileName_"
 */
DuTranslator.Settings.prefix = File($.fileName).name.substring(0,File($.fileName).name.lastIndexOf('.')) + "_";

/**
 * The suffix (including file extension) in the translation filenames
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default ".json"
 */
DuTranslator.Settings.suffix = ".json";

/**
 * The application name (root of the json translations)
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default "duesf"
 */
DuTranslator.Settings.name = "duesf";

/**
 * The original languageId
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default "en"
 */
DuTranslator.Settings.originalLanguageId = "en";

/**
 * The original language name
 * @memberof DuTranslator.Settings
 * @type {string}
 * @default "English"
 */
DuTranslator.Settings.originalLanguageName = "English";

/**
 * The list of strings which have been translated.<br />
 * This can be used to easily generate a new empty translation file.
 * @type {DuList}
 * @memberof DuTranslator.Settings
 */
DuTranslator.originalStrings = new DuList();

/**
 * Load the list of available languages.<br />
 * <br />
 * If the language id and or the language name can't be found in the file, the file name will be used<br />
 * to determine the language id and the name will be set as the id.<br />
 *
 * @return {int} A success code<br />
 * 0	Success<br />
 * 1	One of the file haven't been correctly opened
 */
DuTranslator.getAvailable = function ()
{
	DuTranslator.languages = {};
	//Add original language
	DuTranslator.languages[DuTranslator.Settings.originalLanguageId] = {
		"name": DuTranslator.Settings.originalLanguageName,
		"file": undefined
	};

	var folder = new Folder(DuTranslator.Settings.folder);

	// Get the list of translations
	var languageFiles = folder.getFiles(DuTranslator.Settings.prefix + '*' + DuTranslator.Settings.suffix);

	for (var i = 0 ; i < languageFiles.length ; i++)
	{
		  var fileName = languageFiles[i].name;
		  var langId = "";
		  var langName = "";

		  // Determine the language name and the language id by reading the file
		  // Values are stored at the top so it should be fase
		  var file = new File(folder.absoluteURI + "/" + fileName);
		  if(!file.open("r")) return 1; // Unable to open the file

		  // Line by line reading
		  while(langName == "" || langId == "" && !file.eof )
		  {
			  var line = file.readln();
			  var indexName = line.lastIndexOf("languageName");
			  var indexId = line.lastIndexOf("languageId");

			  var index;
			  if(indexName != -1 && langName == "") index = indexName;
			  else if(indexId != -1 && langId == "") index = indexId;
			  else continue;
			  // ..... "lang" : "value"
			  line = line.substring(index, line.length);
			  // .lang" : "value"
			  line = line.substring(line.indexOf("\"") + 1, line.length);
			  // : "value"
			  line = line.substring(line.indexOf("\"") + 1, line.length);
			  // value"
			  line = line.substring(0, line.indexOf("\""));
			  // value
			   if(indexName != -1 && langName == "") langName = line ;
			  else if(indexId != -1 && langId == "") langId = line ;
			  else continue;
		  }

		  file.close();

		  if(langName == "") continue;

		  if(langId == "") langId = fileName.replace(DuTranslator.Settings.prefix, "").replace(DuTranslator.Settings.suffix, "");

		  DuTranslator.languages[langId] = {
			  "name": langName,
			  "file":  DuTranslator.Settings.folder + "/" + fileName
		  };

	}

}

/**
  * Returns the pretty name of a given language
  * @param {string} langId - The id of the request language
  * @return {string}
 */
DuTranslator.getPrettyName = function(langId)
{
	if(!DuTranslator.languages[langId]) return 1;
	return DuTranslator.languages[langId]["name"];
}

/**
  * Returns the language id of a given language name
  * @param {string} prettyName - The pretty name of the request language
  * @return {string}
 */
DuTranslator.getLanguageId = function(prettyName)
{
	for(var langId in DuTranslator.languages)
	{
		if(DuTranslator.languages[langId]["name"] == prettyName) return langId;
	}
	return '';
}

/**
  * Returns a list containing pretty names of all languages
  * @param {string} langId - The id of the request language
  * @return {string[]}
 */
DuTranslator.getPrettyNames = function()
{
	var res = [];
	for(var langId in DuTranslator.languages)
	{
		res[res.length] = DuTranslator.languages[langId]["name"];
	}

	// Order the list by name
	res.sort ();
	return res;
}

/**
 * Set the current language
 * @param {string} languageId - The id of the language to set
 * @return {Boolean} Success
 */
DuTranslator.setLanguage = function (languageId)
{
	for (var langId in DuTranslator.languages)
	{
		if (langId == languageId)
		{
			DuTranslator.current = languageId;
			DuTranslator.currentName = DuTranslator.getPrettyName(languageId);

			// Reinit
			DuTranslator.originalStrings = new DuList();
			DuScriptUI.String.Original = def( DuScriptUI.String.Original, [] );
			for (key in DuScriptUI.String)
			{
				if (DuScriptUI.String.Original.hasOwnProperty(key))
				{
					DuScriptUI.String[key] = DuScriptUI.String.Original[key];
				}
			}

			// Load translation file
			if (languageId == DuTranslator.Settings.originalLanguageId)
			{
				DuTranslator.localizedStrings = [];
			}
			else
			{
				var fPath = DuTranslator.languages[langId]["file"];
				var file = new File(fPath);

				var jsonData = DuFile.parseJSON(file);

				if(!jsonData[DuTranslator.Settings.name] ||
					jsonData[DuTranslator.Settings.name].length != 2 ||
					!jsonData[DuTranslator.Settings.name][1]["translations"]) return 2; // Wrong json format

				var translations = jsonData[DuTranslator.Settings.name][1]["translations"];
				DuTranslator.localizedStrings = translations;
			}

			// Translate UI
			for (key in DuScriptUI.String)
			{
				if (DuScriptUI.String.hasOwnProperty(key))
				{
					var str = DuScriptUI.String[key];
                       if (jstype(str) != 'string') continue;
					DuScriptUI.String[key] = tr(str, key);
					DuScriptUI.String.Original[key] = str;
				}
			}

			return true;
		}
	}
	return false;
}

/**
 * Set the current language with a given pretty name
 * @param {string} languageName - The pretty name of the language to set
 * @return {Boolean} Success
 */
DuTranslator.setPrettyLanguage = function (languageName)
{
	var langId = DuTranslator.getLanguageId(languageName);
	if(langId == '') return false;

	return DuTranslator.setLanguage(langId);
}

/**
 * Creates a file for translation with the given base strings.
 * @memberof DuTranslator
 * @param {DuTranslation[]|DuList.<string>|string[]} [translations=DuTranslator.originalStrings] - The translations or source strings to be included in the translation file.
 * @param {File|string} file - The file or URI
 * @param {string} [appName=DuESF.scriptName] - A name for the app using this translation file.
 * @param {string} [version=DuESF.scriptVersion.fullVersion] - A version (as a string) for this translation file or app.
 * @param {string} [languageId=DuTranslator.current] - A version (as a string) for this translation file or app.
 * @param {string} [languageName=DuTranslator.currentName] - A version (as a string) for this translation file or app.
 * @param {Boolean} [mergeScriptuiStrings=true] - Merges the strings declared in DuScriptui to the translations.
 */
DuTranslator.generateTranslationFile = function (file,translations,appName,version,languageId,languageName,mergeScriptuiStrings)
{
	if (!(file instanceof File)) file = new File(file);
	translations = def(translations, DuTranslator.originalStrings);
	appName = def( appName, DuESF.scriptName);
	version = def(version, DuESF.scriptVersion.fullVersion);
	languageId = def( languageId, DuTranslator.current);
	languageName = def( languageName, DuTranslator.currentName );

	if (translations instanceof DuList) translations = translations.list;
	if (translations.length == 0) return;

	//if translations is an array of strings, convert to translations
	translations = DuTranslator.generateTranslations(translations, mergeScriptuiStrings);

	var data = {};
	data[appName] = [];
	var metaData = {};
	metaData.languageId = languageId;
	metaData.languageName = languageName;
	metaData.version = version;
	data[appName].push(metaData);
	var translationsObject = {};
	translationsObject.translations = translations;
	data[appName].push(translationsObject);

	DuFile.saveJSON(data,file);
}

/**
 * Converts an Array of strings to an Array of empty translations
 * @memberof DuTranslator
 * @param {string[]|DuList.<string>} strings - The base strings to convert.
 * @param {Boolean} [mergeScriptuiStrings=true] - Merges the strings declared in DuScriptui to the translations.
 * @return {string[]} The translations
 */
DuTranslator.generateTranslations = function (strings,mergeScriptuiStrings)
{
	mergeScriptuiStrings = def(mergeScriptuiStrings, true);
	strings = new DuList(strings);
	var translations = new DuList();

	function compareTranslation(trA, trB)
	{
		if (trA.source != trB.source) return false;
		if (trA.context == '') return true;
		if (trB.context == '') return true;
		return trA.context == trB.context;
	}

	if (mergeScriptuiStrings)
	{
		// Collect registered strings, add them to the list
		for (key in DuScriptUI.String)
		{
			if (DuScriptUI.String.hasOwnProperty(key))
			{
				var str = DuScriptUI.String[key];
				var trnltn = new DuTranslation(str);
				trnltn.context = key;
				translations.pushUnique( compareTranslation, trnltn);
			}
		}
	}

	for (var i = 0, num = strings.length(); i < num ; i++)
	{
		var str = strings.at(i);
		if (typeof str === 'string')
		{
			var trnltn = new DuTranslation(str);
			if (typeof str.context !== 'undefined') trnltn.context = str.context;
			if (typeof str.args !== 'undefined') trnltn.comment = "{#} placeholder: " + str.args.join(', ');
			translations.pushUnique(compareTranslation, trnltn);
		}
		else translations.pushUnique(compareTranslation, str);		
	}

	return translations.list;
}

/**
 * Translate a given string based on the current language<br />
 * see {@link DuTranslator} for more details about the translation framework.
 * @function
 * @global
 * @param {string} str - 		The text to be translated
 * @param {int|string} context - 	Can be an integer or a string which is related to contextId or context in a translation file
 * @param {string[]} args -	Args to format into the translated string, default is []<br />
 * For example, when calling <code>tr("Welcome {#}", -1, "Paul")</code>, the output will be <code>"Welcome Paul"</code><br />
 * If too many args are given, they're ignored<br />
 * If not enough args are given, <code>"{#}"</code> is replaced with <code>"?"</code>
 * @return {string} The translated text or the original string if nothing is set or available
 * @category DuTranslator
 */
function tr(str, context, args)
{
	context = def(context, -1);
	if ( DuDebug.checkVar( str, 'str', 'string', "DuTranslator::tr()" ) !== true ) return str;
	if (str == '') return str;

	DuTranslator.originalStrings.pushUnique( undefined, str );

	var useContextId = true;
	if (typeof context === 'string' || context instanceof String) useContextId = false;
	else if (context < 0) context = -1;

	var languageNumber = -1;
	var res = str;

	//a function to get the translation id from a given string
	function getTranslationId( stri, noCapsNorSpaces )
	{
		noCapsNorSpaces = def (noCapsNorSpaces, false);

		for (var i = 0, n = DuTranslator.localizedStrings.length ; i < n ; i++)
		{
			var localizedString = DuTranslator.localizedStrings[i];
			var testString = localizedString["source"];
			if (noCapsNorSpaces) testString = testString.replace(/[\s\n\r]+/g,'');

			if (testString != stri) continue;

			if (context === -1) return i;
			// Check context
			if (useContextId && localizedString["contextId"] === context) return i;
			else if (localizedString["context"] === context) return i;
		}

		return -1;
	}

	// If a language is set, search for the translation
	if (DuTranslator.current != DuTranslator.Settings.originalLanguageId)
	{
		// Get the translation
		var stringNumber = getTranslationId( str )
		
		// If a translation is found, set it to res
		if (stringNumber > -1) res = DuTranslator.localizedStrings[stringNumber]["translation"];
		if (!res) res = str;
		if (res == "") res = str;
	}

	// Args process
	res = DuString.args(res, args);

	return res;
}

// Low-level undocumented function. Called by DuESF.init()
DuTranslator.init = function() {
	DuTranslator.Settings.name = DuESF.scriptName;
	DuTranslator.Settings.folder = DuESF.scriptSettings.file.parent.absoluteURI + '/';
	DuTranslator.Settings.prefix = DuESF.scriptName;
}
DuESF.initMethods.push( DuTranslator.init );// ==================== |------| ====================
// ==================== | JSON | ====================
// ==================== |------| ====================

/**
 * JSON parser.
 * @name JSON
 * @see {@link http://www.JSON.org/js.html|Json2}
 * @license Public-Domain
 * @category DuESF
 * @subcategory Third Party
 */

JSON = {};

 (function () {
     "use strict";

     var rx_one = /^[\],:{}\s]*$/;
     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

     function f(n) {
         // Format integers to have at least two digits.
         return (n < 10)
             ? "0" + n
             : n;
     }

     function this_value() {
         return this.valueOf();
     }

     if (typeof Date.prototype.toJSON !== "function") {

         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;
         };

         Boolean.prototype.toJSON = this_value;
         Number.prototype.toJSON = this_value;
         String.prototype.toJSON = this_value;
     }

     var gap;
     var indent;
     var meta;
     var rep;


     function quote(string) {

 // If the string contains no control characters, no quote characters, and no
 // backslash characters, then we can safely slap some quotes around it.
 // Otherwise we must also replace the offending characters with safe escape
 // sequences.

         rx_escapable.lastIndex = 0;
         return rx_escapable.test(string)
             ? "\"" + string.replace(rx_escapable, function (a) {
                 var c = meta[a];
                 return typeof c === "string"
                     ? c
                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
             }) + "\""
             : "\"" + string + "\"";
     }


     function str(key, holder) {

 // Produce a string from holder[key].

         var i;          // The loop counter.
         var k;          // The member key.
         var v;          // The member value.
         var length;
         var mind = gap;
         var partial;
         var value = holder[key];

 // If the value has a toJSON method, call it to obtain a replacement value.

         if (
             value
             && typeof value === "object"
             && typeof value.toJSON === "function"
         ) {
             value = value.toJSON(key);
         }

 // If we were called with a replacer function, then call the replacer to
 // obtain a replacement value.

         if (typeof rep === "function") {
             value = rep.call(holder, key, value);
         }

 // What happens next depends on the value's type.

         switch (typeof value) {
         case "string":
             return quote(value);

         case "number":

 // JSON numbers must be finite. Encode non-finite numbers as null.

             return (isFinite(value))
                 ? String(value)
                 : "null";

         case "boolean":
         case "null":

 // If the value is a boolean or null, convert it to a string. Note:
 // typeof null does not produce "null". The case is included here in
 // the remote chance that this gets fixed someday.

             return String(value);

 // If the type is "object", we might be dealing with an object or an array or
 // null.

         case "object":

 // Due to a specification blunder in ECMAScript, typeof null is "object",
 // so watch out for that case.

             if (!value) {
                 return "null";
             }

 // Make an array to hold the partial results of stringifying this object value.

             gap += indent;
             partial = [];

 // Is the value an array?

             if (Object.prototype.toString.apply(value) === "[object Array]") {

 // The value is an array. Stringify every element. Use null as a placeholder
 // for non-JSON values.

                 length = value.length;
                 for (i = 0; i < length; i += 1) {
                     partial[i] = str(i, value) || "null";
                 }

 // Join all of the elements together, separated with commas, and wrap them in
 // brackets.

                 v = partial.length === 0
                     ? "[]"
                     : gap
                         ? (
                             "[\n"
                             + gap
                             + partial.join(",\n" + gap)
                             + "\n"
                             + mind
                             + "]"
                         )
                         : "[" + partial.join(",") + "]";
                 gap = mind;
                 return v;
             }

 // If the replacer is an array, use it to select the members to be stringified.

             if (rep && typeof rep === "object") {
                 length = rep.length;
                 for (i = 0; i < length; i += 1) {
                     if (typeof rep[i] === "string") {
                         k = rep[i];
                         v = str(k, value);
                         if (v) {
                             partial.push(quote(k) + (
                                 (gap)
                                     ? ": "
                                     : ":"
                             ) + v);
                         }
                     }
                 }
             } else {

 // Otherwise, iterate through all of the keys in the object.

                 for (k in value) {
                     if (Object.prototype.hasOwnProperty.call(value, k)) {
                         v = str(k, value);
                         if (v) {
                             partial.push(quote(k) + (
                                 (gap)
                                     ? ": "
                                     : ":"
                             ) + v);
                         }
                     }
                 }
             }

 // Join all of the member texts together, separated with commas,
 // and wrap them in braces.

             v = partial.length === 0
                 ? "{}"
                 : gap
                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
                     : "{" + partial.join(",") + "}";
             gap = mind;
             return v;
         }
     }

 // If the JSON object does not yet have a stringify method, give it one.

     if (typeof JSON.stringify !== "function") {
         meta = {    // table of character substitutions
             "\b": "\\b",
             "\t": "\\t",
             "\n": "\\n",
             "\f": "\\f",
             "\r": "\\r",
             "\"": "\\\"",
             "\\": "\\\\"
         };
         JSON.stringify = function (value, replacer, space) {

 // The stringify method takes a value and an optional replacer, and an optional
 // space parameter, and returns a JSON text. The replacer can be a function
 // that can replace values, or an array of strings that will select the keys.
 // A default replacer method can be provided. Use of the space parameter can
 // produce text that is more easily readable.

             var i;
             gap = "";
             indent = "";

 // If the space parameter is a number, make an indent string containing that
 // many spaces.

             if (typeof space === "number") {
                 for (i = 0; i < space; i += 1) {
                     indent += " ";
                 }

 // If the space parameter is a string, it will be used as the indent string.

             } else if (typeof space === "string") {
                 indent = space;
             }

 // If there is a replacer, it must be a function or an array.
 // Otherwise, throw an error.

             rep = replacer;
             if (replacer && typeof replacer !== "function" && (
                 typeof replacer !== "object"
                 || typeof replacer.length !== "number"
             )) {
                 throw new Error("JSON.stringify");
             }

 // Make a fake root object containing our value under the key of "".
 // Return the result of stringifying the value.

             return str("", {"": value});
         };
     }


 // If the JSON object does not yet have a parse method, give it one.

     if (typeof JSON.parse !== "function") {
         JSON.parse = function (text, reviver) {

 // The parse method takes a text and an optional reviver function, and returns
 // a JavaScript value if the text is a valid JSON text.

             var j;

             function walk(holder, key) {

 // The walk method is used to recursively walk the resulting structure so
 // that modifications can be made.

                 var k;
                 var v;
                 var value = holder[key];
                 if (value && typeof value === "object") {
                     for (k in value) {
                         if (Object.prototype.hasOwnProperty.call(value, k)) {
                             v = walk(value, k);
                             if (v !== undefined) {
                                 value[k] = v;
                             } else {
                                 delete value[k];
                             }
                         }
                     }
                 }
                 return reviver.call(holder, key, value);
             }


 // Parsing happens in four stages. In the first stage, we replace certain
 // Unicode characters with escape sequences. JavaScript handles many characters
 // incorrectly, either silently deleting them, or treating them as line endings.

             text = String(text);
             rx_dangerous.lastIndex = 0;
             if (rx_dangerous.test(text)) {
                 text = text.replace(rx_dangerous, function (a) {
                     return (
                         "\\u"
                         + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
                     );
                 });
             }

 // In the second stage, we run the text against regular expressions that look
 // for non-JSON patterns. We are especially concerned with "()" and "new"
 // because they can cause invocation, and "=" because it can cause mutation.
 // But just to be safe, we want to reject all unexpected forms.

 // We split the second stage into 4 regexp operations in order to work around
 // crippling inefficiencies in IE's and Safari's regexp engines. First we
 // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
 // replace all simple value tokens with "]" characters. Third, we delete all
 // open brackets that follow a colon or comma or that begin the text. Finally,
 // we look to see that the remaining characters are only whitespace or "]" or
 // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.

             if (
                 rx_one.test(
                     text
                         .replace(rx_two, "@")
                         .replace(rx_three, "]")
                         .replace(rx_four, "")
                 )
             ) {

 // In the third stage we use the eval function to compile the text into a
 // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
 // in JavaScript: it can begin a block or an object literal. We wrap the text
 // in parens to eliminate the ambiguity.

                 j = eval("(" + text + ")");

 // In the optional fourth stage, we recursively walk the new structure, passing
 // each name/value pair to a reviver function for possible transformation.

                 return (typeof reviver === "function")
                     ? walk({"": j}, "")
                     : j;
             }

 // If the text is not JSON parseable, then a SyntaxError is thrown.

             throw new SyntaxError("JSON.parse");
         };
     }
 }());
// ==================== |--------| ====================
// ==================== | Matrix | ====================
// ==================== |--------| ====================

/*!
  2D Transformation Matrix v2.7.5 LT
  (c) Epistemex.com 2014-2018
  License: MIT
*/

/**
	* 2D transformation matrix object initialized with identity matrix.
	* @class
	* @name Matrix
	* @classdesc 2D Transformation Matrix.
	* @prop {number} a - scale x
	* @prop {number} b - shear y
	* @prop {number} c - shear x
	* @prop {number} d - scale y
	* @prop {number} e - translate x
	* @prop {number} f - translate y
	* @author Epistemex
	* @version 2.7.5
	* @license MIT license (header required)
	* @copyright Epistemex.com 2014-2018
	* @category DuESF
    * @subcategory Third Party
 */
function Matrix() {

	var me = this, _el;
	me._t = me.transform;

	me.a = me.d = 1;
	me.b = me.c = me.e = me.f = 0;
}

 /**
  * Create and transform a new matrix based on given matrix values, or
  * provide SVGMatrix or a (2D) DOMMatrix, WebKitCSSMatrix or another
  * instance of a generic matrix.
  *
  * @example
  *
  * var m = Matrix.from(1, 0.2, 0, 2, 120, 97);
  * var m = Matrix.from(domMatrix, ctx);
  * var m = Matrix.from(svgMatrix);
  * var m = Matrix.from(matrix);
  *
  * @param {*} a - number representing a (scale x) in [a-f], or a Matrix object containing properties a-f.
  * @param {*} [b] - b property (shear y) if a is not a matrix object, or optional canvas 2D context.
  * If vector is input this will be pre-translate for x.
  * @param {number} [c] - c property (shear x)
  * @param {number} [d] - d property (scale y)
  * @param {number} [e] - e property (translate x)
  * @param {number} [f] - f property (translate y)
  * @param {CanvasRenderingContext2D} [context] - optional canvas context to synchronize
  * @returns {Matrix} - new Matrix instance
  * @static
  */
Matrix.from = function(a, b, c, d, e, f, context) {

	var m = new Matrix(context), scale, dist, q;

	if (typeof a === "number")
	 m.setTransform(a, b, c, d, e, f);

	else {
	 if (typeof a.is2D === "boolean" && !a.is2D) throw "Cannot use 3D DOMMatrix.";
	 if (b) m.context = b;
	 m.multiply(a)
	}

	return m
 };

Matrix.prototype = {

	/**
	* Short-hand to reset current matrix to an identity matrix.
	* @returns {Matrix}
	*/
	reset: function() {
	 return this.setTransform(1, 0, 0, 1, 0, 0)
	},

	/**
	* Rotates current matrix by angle (accumulative).
	* @param {number} angle - angle in degrees
	* @returns {Matrix}
	*/
	rotate: function(angle) {
	 angle = DuMath.toRadians(angle);
	 var
		cos = Math.cos(angle),
		sin = Math.sin(angle);

	 return this._t(cos, sin, -sin, cos, 0, 0)
	},

	/**
	* Converts a vector given as `x` and `y` to angle, and
	* rotates (accumulative). x can instead contain an object with
	* properties x and y and if so, y parameter will be ignored.
	* @param {number|*} x
	* @param {number} [y]
	* @returns {Matrix}
	*/
	rotateFromVector: function(x, y) {
	 return this.rotate(typeof x === "number" ? Math.atan2(y, x) : Math.atan2(x.y, x.x))
	},

	/**
	* Scales current matrix accumulative.
	* @param {number[]} s - scale factor [x, y]. 1 does nothing, any third value (Z) is ignored.
	* @returns {Matrix}
	*/
	scale: function(s) {
	 return this._t(s[0], 0, 0, s[1], 0, 0);
	},

	/**
	* Apply shear to the current matrix accumulative.
	* @param {number} sx - amount of shear for x
	* @param {number} sy - amount of shear for y
	* @returns {Matrix}
	*/
	shear: function(sx, sy) {
	 return this._t(1, sy, sx, 1, 0, 0)
	},

	/**
	* Apply skew to the current matrix accumulative. Angles in radians.
	* Also see [`skewDeg()`]{@link Matrix#skewDeg}.
	* @param {number} ax - angle of skew for x
	* @param {number} ay - angle of skew for y
	* @returns {Matrix}
	*/
	skew: function(ax, ay) {
	 return this.shear(Math.tan(ax), Math.tan(ay))
	},

	/**
	* Set current matrix to new absolute matrix.
	* @param {number} a - scale x
	* @param {number} b - shear y
	* @param {number} c - shear x
	* @param {number} d - scale y
	* @param {number} e - translate x
	* @param {number} f - translate y
	* @returns {Matrix}
	*/
	setTransform: function(a, b, c, d, e, f) {
	 var me = this;
	 me.a = a;
	 me.b = b;
	 me.c = c;
	 me.d = d;
	 me.e = e;
	 me.f = f;
	 return me._x()
	},

	/**
	* Translate current matrix accumulative.
	* @param {number[]} t - translation [x, y]. Any third value (Z) is ignored.
	* @returns {Matrix}
	*/
	translate: function(t) {
	 return this._t(1, 0, 0, 1, t[0], t[1]);
	},

	/**
	* Multiplies current matrix with new matrix values. Also see [`multiply()`]{@link Matrix#multiply}.
	*
	* @param {number} a2 - scale x
	* @param {number} b2 - skew y
	* @param {number} c2 - skew x
	* @param {number} d2 - scale y
	* @param {number} e2 - translate x
	* @param {number} f2 - translate y
	* @returns {Matrix}
	*/
	transform: function(a2, b2, c2, d2, e2, f2) {

	 var
		me = this,
		a1 = me.a,
		b1 = me.b,
		c1 = me.c,
		d1 = me.d,
		e1 = me.e,
		f1 = me.f;

	 /* matrix column order is:
	  *	a c e
	  *	b d f
	  *	0 0 1
	  */
	 me.a = a1 * a2 + c1 * b2;
	 me.b = b1 * a2 + d1 * b2;
	 me.c = a1 * c2 + c1 * d2;
	 me.d = b1 * c2 + d1 * d2;
	 me.e = a1 * e2 + c1 * f2 + e1;
	 me.f = b1 * e2 + d1 * f2 + f1;

	 return me._x()
	},

	/**
	* Multiplies current matrix with source matrix.
	* @param {Matrix|Matrix|DOMMatrix|SVGMatrix} m - source matrix to multiply with.
	* @returns {Matrix}
	*/
	multiply: function(m) {
	 return this._t(m.a, m.b, m.c, m.d, m.e, m.f)
	},

	/**
	* Get an inverse matrix of current matrix. The method returns a new
	* matrix with values you need to use to get to an identity matrix.
	* Context from parent matrix is not applied to the returned matrix.
	*
	* @param {boolean} [cloneContext=false] - clone current context to resulting matrix
	* @throws Exception is input matrix is not invertible
	* @returns {Matrix} - new Matrix instance
	*/
	inverse: function(cloneContext) {

	 var
		me = this,
		m  = new Matrix(cloneContext ? me.context : null),
		dt = me.determinant();

	 if (dt === 0) throw "Matrix not invertible.";

	 m.a = me.d / dt;
	 m.b = -me.b / dt;
	 m.c = -me.c / dt;
	 m.d = me.a / dt;
	 m.e = (me.c * me.f - me.d * me.e) / dt;
	 m.f = -(me.a * me.f - me.b * me.e) / dt;

	 return m
	},

	/**
	* Decompose the current matrix into simple transforms using QR.
	*
	* @returns {*} - an object containing current decomposed values (translate, rotation, scale, skew)
	* @see {@link https://en.wikipedia.org/wiki/QR_decomposition|More on QR decomposition}
	*/
	decompose: function() {

	 var
		me		= this,
		a		 = me.a,
		b		 = me.b,
		c		 = me.c,
		d		 = me.d,
		acos	  = Math.acos,
		atan	  = Math.atan,
		sqrt	  = Math.sqrt,
		pi		= Math.PI,

		translate = {x: me.e, y: me.f},
		rotation  = 0,
		scale	 = {x: 1, y: 1},
		skew	  = {x: 0, y: 0},

		determ	= a * d - b * c,	// determinant(), skip DRY here...
		r, s;

	 // Apply the QR-like decomposition.
	 if (a || b) {
		r = sqrt(a * a + b * b);
		rotation = b > 0 ? acos(a / r) : -acos(a / r);
		scale = {x: r, y: determ / r};
		skew.x = atan((a * c + b * d) / (r * r));
	 }
	 else if (c || d) {
		s = sqrt(c * c + d * d);
		rotation = pi * 0.5 - (d > 0 ? acos(-c / s) : -acos(c / s));
		scale = {x: determ / s, y: s};
		skew.y = atan((a * c + b * d) / (s * s));
	 }
	 else { // a = b = c = d = 0
		scale = {x: 0, y: 0};
	 }

	 return {
		translate: translate,
		rotation : rotation,
		scale	: scale,
		skew	 : skew
	 }
	},

	/**
	* Returns the determinant of the current matrix.
	* @returns {number}
	*/
	determinant: function() {
	 return this.a * this.d - this.b * this.c
	},

	/**
	* Apply current matrix to `x` and `y` of a point.
	* Returns a point object.
	*
	* @param {number[]} pt - the point to transform ([x, y]).<br />
	* If an optionnal Z value is provided, it will be kept without transformation.
	* @returns {number[]} A new transformed point [x, y]. If pt had a third value, it is returned too, as it was without transformation.
	*/
	applyToPoint: function(pt) {
	 var me = this;
	 var x = pt[0] * me.a + pt[1] * me.c + me.e;
	 var y = pt[0] * me.b + pt[1] * me.d + me.f;
	 var result = [x,y];
	 if (pt.length == 3) result.push(pt[2]);
	 return result;
	},

	/**
	* Returns true if matrix is an identity matrix (no transforms applied).
	* @returns {boolean}
	*/
	isIdentity: function() {
	 var me = this;
	 return me.a === 1 && !me.b && !me.c && me.d === 1 && !me.e && !me.f
	},

	/**
	* Returns true if matrix is invertible
	* @returns {boolean}
	*/
	isInvertible: function() {
	 return !this._q(this.determinant(), 0)
	},

	/**
	* The method is intended for situations where scale is accumulated
	* via multiplications, to detect situations where scale becomes
	* "trapped" with a value of zero. And in which case scale must be
	* set explicitly to a non-zero value.
	*
	* @returns {boolean}
	*/
	isValid: function() {
	 return !(this.a * this.d)
	},

	/**
	* Compares current matrix with another matrix. Returns true if equal
	* (within epsilon tolerance).
	* @param {Matrix|Matrix|DOMMatrix|SVGMatrix} m - matrix to compare this matrix with
	* @returns {boolean}
	*/
	isEqual: function(m) {

	 var
		me = this,
		q = me._q;

	 return  q(me.a, m.a) &&
			 q(me.b, m.b) &&
			 q(me.c, m.c) &&
			 q(me.d, m.d) &&
			 q(me.e, m.e) &&
			 q(me.f, m.f)
	},

	/**
	* Clones current instance and returning a new matrix.
	* @param {boolean} [noContext=false] don't clone context reference if true
	* @returns {Matrix} - a new Matrix instance with identical transformations as this instance
	*/
	clone: function(noContext) {
	 return new Matrix(noContext ? null : this.context).multiply(this)
	},

	/**
	* Generates a string that can be used with CSS `transform`.
	* @example
	*	 element.style.transform = m.toCSS();
	* @returns {string}
	*/
	toCSS: function() {
	 return "matrix(" + this.toArray() + ")"
	},

	/**
	* Generates a `matrix3d()` string that can be used with CSS `transform`.
	* Although the matrix is for 2D use you may see performance benefits
	* on some devices using a 3D CSS transform instead of a 2D.
	* @example
	*	 element.style.transform = m.toCSS3D();
	* @returns {string}
	*/
	toCSS3D: function() {
	 var me = this;
	 return "matrix3d(" + me.a + "," + me.b + ",0,0," + me.c + "," + me.d + ",0,0,0,0,1,0," + me.e + "," + me.f + ",0,1)"
	},

	/**
	* Returns a JSON compatible string of current matrix.
	* @returns {string}
	*/
	toJSON: function() {
	 var me = this;
	 return '{"a":' + me.a + ',"b":' + me.b + ',"c":' + me.c + ',"d":' + me.d + ',"e":' + me.e + ',"f":' + me.f + '}'
	},

	/**
	* Compares floating point values with some tolerance (epsilon)
	* @param {number} f1 - float 1
	* @param {number} f2 - float 2
	* @returns {boolean}
	* @private
	*/
	_q: function(f1, f2) {
	 return Math.abs(f1 - f2) < 1e-14
	},

	/**
	* Apply current absolute matrix to context if defined, to sync it.
	* Apply current absolute matrix to element if defined, to sync it.
	* @returns {Matrix}
	* @private
	*/
	_x: function() {

	 var me = this;

	 if (me.context)
		me.context.setTransform(me.a, me.b, me.c, me.d, me.e, me.f);

	 return me
	}
};
// ==================== |------------| ====================
// ==================== | SeedRandom | ====================
// ==================== |------------| ====================

/**
 * Adds a new Math.seedRandom() method, used as a workaround for a bug in Math.random() with After Effects on Mac OS
 * @name seedRandom
 * @author David Bau
 * @copyright David Bau
 * @license MIT
 * @category DuESF
 * @subcategory Third Party
 */

!function(a,b){function c(c,j,k){var n=[];j=1==j?{entropy:!0}:j||{};var s=g(f(j.entropy?[c,i(a)]:null==c?h():c,3),n),t=new d(n),u=function(){for(var a=t.g(m),b=p,c=0;q>a;)a=(a+c)*l,b*=l,c=t.g(1);for(;a>=r;)a/=2,b/=2,c>>>=1;return(a+c)/b};return u.int32=function(){return 0|t.g(4)},u.quick=function(){return t.g(4)/4294967296},u["double"]=u,g(i(t.S),a),(j.pass||k||function(a,c,d,f){return f&&(f.S&&e(f,t),a.state=function(){return e(t,{})}),d?(b[o]=a,c):a})(u,s,"global"in j?j.global:this==b,j.state)}function d(a){var b,c=a.length,d=this,e=0,f=d.i=d.j=0,g=d.S=[];for(c||(a=[c++]);l>e;)g[e]=e++;for(e=0;l>e;e++)g[e]=g[f=s&f+a[e%c]+(b=g[e])],g[f]=b;(d.g=function(a){for(var b,c=0,e=d.i,f=d.j,g=d.S;a--;)b=g[e=s&e+1],c=c*l+g[s&(g[e]=g[f=s&f+b])+(g[f]=b)];return d.i=e,d.j=f,c})(l)}function e(a,b){return b.i=a.i,b.j=a.j,b.S=a.S.slice(),b}function f(a,b){var c,d=[],e=typeof a;if(b&&"object"==e)for(c in a)try{d.push(f(a[c],b-1))}catch(g){}return d.length?d:"string"==e?a:a+"\0"}function g(a,b){for(var c,d=a+"",e=0;e<d.length;)b[s&e]=s&(c^=19*b[s&e])+d.charCodeAt(e++);return i(b)}function h(){try{if(j)return i(j.randomBytes(l));var b=new Uint8Array(l);return(k.crypto||k.msCrypto).getRandomValues(b),i(b)}catch(c){var d=k.navigator,e=d&&d.plugins;return[+new Date,k,e,k.screen,i(a)]}}function i(a){return String.fromCharCode.apply(0,a)}var j,k=this,l=256,m=6,n=52,o="random",p=b.pow(l,m),q=b.pow(2,n),r=2*q,s=l-1;if(b["seed"+o]=c,g(b.random(),a),"object"==typeof module&&module.exports){module.exports=c;try{j=require("crypto")}catch(t){}}else"function"==typeof define&&define.amd&&define(function(){return c})}([],Math);
// ==================== |-------------| ====================
// ==================== | colorPicker | ====================
// ==================== |-------------| ====================

;(function(){
/**
 * @classdesc ColorPicker v2.0 for Adobe scripting.<br />
 * 2016-5-11 -> 2016-7-24<br />
 * This is a rebuilt color picker for Adobe scripting.<br />
 * Support all Adobe softwares such as PS,AI,PR and so on.<br />
 * See usage on {@link http://github.com/Smallpath/AdobeColorPicker}
 * @class
 * @name colorPicker
 * @author smallpath
 * @copyright smallpath
 * @license MIT
 * @link https://github.com/Smallpath/AdobeColorPicker
 * @category DuESF
 * @subcategory Third Party
 */
function colorPicker(inputColour,options){
    if(!(this instanceof colorPicker))
        return new colorPicker(inputColour,options)

    this.options = {
        name : "Adobe Color Picker ",
        version : "v2.0",
        shouldUpdateCursor: false,
        backupLocation : [],

        windowType:"dialog",  // "dialog","palette" and the reference of Panel
    }

    if(options && colorPicker.isType(options,"Object")){
        for(var i in options)
            this.options[i] = options[i];
    }
    
    this.inputColour = colorPicker.parseColor(inputColour);
    this.outputColour = this.inputColour.slice(0);
    this.initSetting();
    return this.showColorPicker();
}

colorPicker.parseColor = function(inputValue){
        if(!inputValue)
            return [1,1,1];
            
        if(colorPicker.isRgb(inputValue))                   //[0,0,0] - [1,1,1] 
            return colorPicker.parseRgb(inputValue);
        else if(colorPicker.isLargeRgb(inputValue))    //[0,0,0] - [255,255,255]
            return colorPicker.parseLargeRgb(inputValue);
        else if(colorPicker.isHex(inputValue) )            //FFFFFF
            return colorPicker.parseHex(inputValue);
        else if(colorPicker.isShortHex(inputValue))     //FFF
            return colorPicker.parseShortHex(inputValue);
        else if(colorPicker.isHsb(inputValue))             //[0,0,0,'hsb'] - [360,100,100,'hsb']
            return colorPicker.parseHsb(inputValue);
        else
            return [1,1,1];
}

colorPicker.prototype.showColorPicker =  function(){
        var win = this.initWindow();
        if(win.type == "dialog" ||win.type == "palette" ){
            if(this.haveSetting ("location")){
                win.location = this.getSetting ("location").split(",");
                if(win.location.length != 2)
                    win.center();
                else if(win.location[0]<0 || win.location[1]<0)
                    win.center();
            } 
            win.show();
            this.saveSetting ("location", win.location);
        }else if(win.type == "panel"){
            win.layout.layout(true);
        }
        if(!this.isSmallMode){
            this.outputColour.hex = colorPicker.RgbToHex(this.outputColour);
            this.outputColour.hsb = colorPicker.RgbToHsb(this.outputColour);
            this.outputColour.rgb = this.outputColour.slice(0);
            
            return this.outputColour;
        }else{
            return {
                window:win, 
                colorPicker:this
            };
        }
}

colorPicker.prototype.initWindow = function(){
            var _this = this;
            var type = this.options["windowType"];
            if(type=="palette"){
                    var win = new Window("palette", this.options["name"] + this.options["version"], undefined, {
                            maximizeButton: false,
                            minimizeButton: false,
                        });
                    this.size = this.options["size"] = 90;
            }else if(type instanceof Panel){
                    var win = type;
                    this.size = this.options["size"] = 90;
            }else{
                    var win = new Window("dialog", this.options["name"] + this.options["version"], undefined, {
                        maximizeButton: false,
                        minimizeButton: false,
                        closeButton:false
                    });
                    this.size = this.options["size"] = 130;
            }
        
            var isSmallMode = this.isSmallMode = this.size != 130;
            var targetImage = isSmallMode ? this.options["smallColorWheel"]:  this.img ;
            var targetSize = this.size*2;

            var colourGroup = win.add('group');
            	colourGroup.orientation = "stack";
                    
	    		win.image = colourGroup.add("image", undefined,targetImage);

	    		var colourCursorGroup = this.colourCursorGroup = colourGroup.add('customBoundedValue',[0,0,targetSize+2,targetSize+2]);
		    		colourCursorGroup.fillColour = [0,0,0,0];

                 var colourSelectCursor = this.colourSelectCursor = colourCursorGroup.colourSelectCursor = {};
                        colourSelectCursor.size = [12,12];
                        colourSelectCursor.strokeWidth = 1;
                        colourSelectCursor.strokeColour = [0,0,0];
                        
                        this.setCursorLocation (this.inputColour);
                        
                colourCursorGroup.onDraw = function () {
		                this.graphics.drawOSControl();
		                this.graphics.newPath();
		                this.graphics.ellipsePath(0,0,this.size[0],this.size[1]);
		                this.graphics.fillPath(colourCursorGroup.graphics.newBrush(colourCursorGroup.graphics.BrushType.SOLID_COLOR, colourCursorGroup.fillColour));
                        
		                this.graphics.newPath();
                        
		                this.graphics.ellipsePath(this.colourSelectCursor.location[0]+this.colourSelectCursor.strokeWidth/2+1,
                                                                        this.colourSelectCursor.location[1]+this.colourSelectCursor.strokeWidth/2+1,
                                                                        this.colourSelectCursor.size[0]-this.colourSelectCursor.strokeWidth,
                                                                        this.colourSelectCursor.size[1]-this.colourSelectCursor.strokeWidth);
		                this.graphics.strokePath(this.graphics.newPen(this.graphics.PenType.SOLID_COLOR, 
                                                                   this.colourSelectCursor.strokeColour, this.colourSelectCursor.strokeWidth));
		    		};  


            win.brightGroup = win.add("group");
            win.staticBright = win.brightGroup.add("statictext",undefined,"Bright:");
            win.editBright = win.brightGroup.add("edittext{text:'0',characters:3,justify:'center',active:1}");
            win.slider = win.brightGroup.add("slider",undefined,100,0,100); 
            if(!isSmallMode){
                win.slider.size = "width:160,height:20";
                var spacing = 10;
                var character = 4;
            }else{
                win.slider.size = "width:100,height:20";
                win.brightGroup.spacing = 2;
                win.spacing = 5;
                win.margins = 2;
                var spacing = 0;
                var character = 3;
            }


            var editor = win.add('group');
                editor.orientation = 'column';

                editor.gulu = editor.add('group');

                    editor.gulu.uni = editor.gulu.add('group');
                    editor.gulu.uni.spacing = spacing;

                        editor.gulu.uni.Ed = editor.gulu.uni.add('statictext', undefined, '#');
                        editor.gulu.uni.unicode = editor.gulu.uni.add('edittext', undefined, 'FF0000')
                        editor.gulu.uni.unicode.characters = 6;
                        editor.gulu.uni.unicode.justify = 'center';

                    editor.gulu.color = editor.gulu.add('customBoundedValue', undefined, 'Redraw original image');
                    editor.gulu.color.size = [80, 25];

                editor.colorHolder = editor.add('group');
                editor.colorHolder.orientation = 'row';

                    editor.colorHolder.colorCol1 = editor.colorHolder.add('group');
                    editor.colorHolder.colorCol1.orientation = 'column';

                        editor.colorHolder.colorCol1.hGroup = editor.colorHolder.colorCol1.add('group');
                        editor.colorHolder.colorCol1.hGroup.spacing = spacing;

                            editor.colorHolder.colorCol1.hGroup.hRad = editor.colorHolder.colorCol1.hGroup.add('statictext', undefined, 'H:');
                            editor.colorHolder.colorCol1.hGroup.hValue = editor.colorHolder.colorCol1.hGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol1.hGroup.hValue.characters = character;
                            editor.colorHolder.colorCol1.hGroup.hValue.justify = 'center';
                            editor.colorHolder.colorCol1.hGroup.hValue._index = 0;

                        editor.colorHolder.colorCol1.rGroup = editor.colorHolder.colorCol1.add('group');
                        editor.colorHolder.colorCol1.rGroup.spacing = spacing;

                            editor.colorHolder.colorCol1.rGroup.rRad = editor.colorHolder.colorCol1.rGroup.add('statictext', undefined, 'R:');
                            editor.colorHolder.colorCol1.rGroup.rValue = editor.colorHolder.colorCol1.rGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol1.rGroup.rValue.characters = character;
                            editor.colorHolder.colorCol1.rGroup.rValue.justify = 'center';
                            editor.colorHolder.colorCol1.rGroup.rValue._index = 0;

                    editor.colorHolder.colorCol2 = editor.colorHolder.add('group');
                    editor.colorHolder.colorCol2.orientation = 'column';

                        editor.colorHolder.colorCol2.sGroup = editor.colorHolder.colorCol2.add('group');
                        editor.colorHolder.colorCol2.sGroup.spacing = spacing;

                            editor.colorHolder.colorCol2.sGroup.sRad = editor.colorHolder.colorCol2.sGroup.add('statictext', undefined, 'S:');
                            editor.colorHolder.colorCol2.sGroup.sValue = editor.colorHolder.colorCol2.sGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol2.sGroup.sValue.characters = character;
                            editor.colorHolder.colorCol2.sGroup.sValue.justify = 'center';
                            editor.colorHolder.colorCol2.sGroup.sValue._index = 1;

                        editor.colorHolder.colorCol2.gGroup = editor.colorHolder.colorCol2.add('group');
                        editor.colorHolder.colorCol2.gGroup.spacing = spacing;

                            editor.colorHolder.colorCol2.gGroup.gRad = editor.colorHolder.colorCol2.gGroup.add('statictext', undefined, 'G:');
                            editor.colorHolder.colorCol2.gGroup.gValue = editor.colorHolder.colorCol2.gGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol2.gGroup.gValue.characters = character;
                            editor.colorHolder.colorCol2.gGroup.gValue.justify = 'center';
                            editor.colorHolder.colorCol2.gGroup.gValue._index = 1;

                    editor.colorHolder.colorCol3 = editor.colorHolder.add('group');
                    editor.colorHolder.colorCol3.orientation = 'column';

                        editor.colorHolder.colorCol3.lGroup = editor.colorHolder.colorCol3.add('group');
                        editor.colorHolder.colorCol3.lGroup.spacing = spacing;

                            editor.colorHolder.colorCol3.lGroup.lRad = editor.colorHolder.colorCol3.lGroup.add('statictext', undefined, 'B:');
                            editor.colorHolder.colorCol3.lGroup.lValue = editor.colorHolder.colorCol3.lGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol3.lGroup.lValue.characters = character;
                            editor.colorHolder.colorCol3.lGroup.lValue.justify = 'center';
                            editor.colorHolder.colorCol3.lGroup.lValue._index = 2;

                        editor.colorHolder.colorCol3.bGroup = editor.colorHolder.colorCol3.add('group');
                        editor.colorHolder.colorCol3.bGroup.spacing = spacing;

                            editor.colorHolder.colorCol3.bGroup.bRad = editor.colorHolder.colorCol3.bGroup.add('statictext', undefined, 'B:');
                            editor.colorHolder.colorCol3.bGroup.bValue = editor.colorHolder.colorCol3.bGroup.add('edittext', undefined, '0');
                            editor.colorHolder.colorCol3.bGroup.bValue.characters = character;
                            editor.colorHolder.colorCol3.bGroup.bValue.justify = 'center';
                            editor.colorHolder.colorCol3.bGroup.bValue._index = 2;


                win.editor = editor;
                if(win.type == "dialog"){

                    
                    editor.oc = win.editor.oc = win.add("Group{ok:Button{text:'Ok'},can:Button{text:'Cancel'}}");
                    
                        editor.oc.ok.onClick = function(){
                            win.close();
                        }

                        editor.oc.can.onClick = function(){
                            colorPicker.copyArr(_this.outputColour,_this.inputColour);
                            win.close();
                        }
                    
                    }

            editor.gulu.color.onDraw = function(draw){
            	var targetColour = _this.outputColour;

                var gfxs=this.graphics;
                gfxs.newPath();
                gfxs.rectPath(0, 0, this.size[0], this.size[1]);
                gfxs.fillPath(gfxs.newBrush (gfxs.BrushType.SOLID_COLOR, targetColour));
            };




        
            this.updateCursor(win);

            this.setDefaultValue(win)

            this.bindingKeydown(win);

            this.bindingHandler(win);

            return win;

}

colorPicker.prototype.setDefaultValue = function(win){
        var pi = win.editor;
        var startColour = this.outputColour;


        pi.gulu.uni.unicode.text= colorPicker.RgbToHex (startColour);
        pi.gulu.uni.unicode.active = true;



        pi.colorHolder.colorCol1.rGroup.rValue.text=Math.round(startColour[0]*255);
        pi.colorHolder.colorCol2.gGroup.gValue.text=Math.round(startColour[1]*255);
        pi.colorHolder.colorCol3.bGroup.bValue.text=Math.round(startColour[2]*255);

        var hsbHere= colorPicker.RgbToHsb([
                                        startColour[0]*255,
                                        startColour[1]*255,
                                        startColour[2]*255
                                    ]);
                                    

        pi.colorHolder.colorCol1.hGroup.hValue.text=hsbHere[0];
        pi.colorHolder.colorCol2.sGroup.sValue.text=hsbHere[1];
        pi.colorHolder.colorCol3.lGroup.lValue.text=hsbHere[2];

        win.slider.value=hsbHere[2];
        win.editBright.text=hsbHere[2];
        
        this.colourCursorGroup.fillColour[3] = 1 - (hsbHere[2])/100;
        this.colourCursorGroup.notify("onDraw");
}

colorPicker.prototype.bindingHandler =  function(win){
           var _this = this;

          win.editor.colorHolder.colorCol1.hGroup.hValue.onChange =
          win.editor.colorHolder.colorCol2.sGroup.sValue.onChange =
          win.editor.colorHolder.colorCol3.lGroup.lValue.onChange = function(){
                    _this.options.backupLocation.length = 0;
                    this.text=Math.round(this.text);

                    if(this._index ==0 ){
                        if( this.text<0 || this.text>360 || isNaN(this.text)==true ){
                                this.text= colorPicker.RgbToHsb([
                                                                                    _this.outputColour[0]*255,
                                                                                    _this.outputColour[1]*255,
                                                                                    _this.outputColour[2]*255,
                                                                                ])[this._index];
                       }
                    }else{
                        if( this.text<0 || this.text>100 || isNaN(this.text)==true ){
                                this.text= colorPicker.RgbToHsb([
                                                                                    _this.outputColour[0]*255,
                                                                                    _this.outputColour[1]*255,
                                                                                    _this.outputColour[2]*255,
                                                                                ])[this._index];
                       }
                    }
                    var hsbArr = [
                                          Math.round(win.editor.colorHolder.colorCol1.hGroup.hValue.text),
                                          Math.round(win.editor.colorHolder.colorCol2.sGroup.sValue.text),
                                          Math.round(win.editor.colorHolder.colorCol3.lGroup.lValue.text)
                                        ];

                    var rgbArr = colorPicker.HsbToRgb (hsbArr);
                    var hexStr = colorPicker.RgbToHex ([rgbArr[0]/255,rgbArr[1]/255,rgbArr[2]/255]);
                    win.editor.gulu.uni.unicode.text = hexStr;
                    win.editor.gulu.uni.unicode.notify("onChange");
                     
          }


           win.editor.colorHolder.colorCol1.rGroup.rValue.onChange  =
           win.editor.colorHolder.colorCol2.gGroup.gValue.onChange =
           win.editor.colorHolder.colorCol3.bGroup.bValue.onChange = function (){
                    _this.options.backupLocation.length = 0;
                    this.text=Math.round(this.text);

                    if( this.text<0 || this.text>255 || isNaN(this.text)==true ){
                            this.text=Math.round(_this.outputColour[this._index]*255);
                   }

                    if(this._index ==0)
                        win.editor.gulu.uni.unicode.text= colorPicker.RgbToHex ([this.text/255,_this.outputColour[1],_this.outputColour[2]]);
                    else if(this._index ==1)
                        win.editor.gulu.uni.unicode.text= colorPicker.RgbToHex ([_this.outputColour[0],this.text/255,_this.outputColour[2]]);
                    else if(this._index ==2)
                        win.editor.gulu.uni.unicode.text= colorPicker.RgbToHex ([_this.outputColour[0],_this.outputColour[1],this.text/255]);
                     win.editor.gulu.uni.unicode.notify("onChange");
                     
               }

           win.editBright.onChange = win.editBright.onChanging = function () {
                    _this.options.backupLocation.length = 0;
           		if (this.text < 0)
           			this.text = 0;
           		if (this.text > 100)
           			this.text = 100;
           		if (isNaN(this.text)==true)
           			this.text = 100;

           		win.slider.value = parseInt(this.text);
                    if(isNaN(win.slider.value))
                        return;
           		win.slider.notify('onChange');
           };

           win.slider.onChange = win.slider.onChanging = function(){

                    var thisColor= colorPicker.HsbToRgb ([
                                                            Math.round(win.editor.colorHolder.colorCol1.hGroup.hValue.text),
                                                            Math.round(win.editor.colorHolder.colorCol2.sGroup.sValue.text),
                                                            Math.round(this.value)
                                                        ]);
                    if(this.value != 0){
                        if(_this.options.backupLocation.length != 0 && _this.options.shouldUpdateCursor == true){
                            _this.getColor({
                                    type:"mouseup",
                                    clientX: _this.options.backupLocation[0]+6,
                                    clientY: _this.options.backupLocation[1]+6,
                            });
                            _this.options.backupLocation.length = 0;
                            _this.colourCursorGroup.fillColour[3] = 1 - (this.value)/100;
                            _this.colourCursorGroup.notify("onDraw");
                            return;
                        }
                    }                
                                             
                    colorPicker.copyArr(_this.outputColour,[thisColor[0]/255,thisColor[1]/255,thisColor[2]/255]);

                    _this.setDefaultValue(win);
                    _this.notifyColor(win);
                	_this.updateCursor(win);
                    
                    _this.setCursorLocation (_this.outputColour);

                    if(this.value == 0){
                        _this.options.shouldUpdateCursor = true;
                    }else{
                        _this.options.shouldUpdateCursor = false;
                    }
                            
                            
                    if(_this.options.backupLocation.length == 0){
                        colorPicker.copyArr(_this.options.backupLocation,_this.colourSelectCursor.location);
                    }

                    _this.colourCursorGroup.fillColour[3] = 1 - (this.value)/100;
                    _this.colourCursorGroup.notify("onDraw");
                     
               }

            win.editor.gulu.uni.unicode.onChange= function(){
                    var hexHere="0x"+this.text;
                    var eV=0;
                    if(colorPicker.isHex (this.text) == false && colorPicker.isShortHex(this.text) == false){
                        this.text = colorPicker.RgbToHex (_this.outputColour);
                        eV=1;
                    }
                    if(eV==0){
                            var rgbHere= (this.text.length == 6) ? colorPicker.parseHex (this.text): colorPicker.parseShortHex (this.text);
                            colorPicker.copyArr(_this.outputColour,rgbHere);
                            _this.setDefaultValue(win);
                            _this.setCursorLocation(rgbHere);
                            _this.notifyColor(win);
                        }
                }

}

colorPicker.prototype.updateCursor = function(win) {
    if (colorPicker.arraysEqual(this.colourSelectCursor.strokeColour,[1,1,1])) {
		if (win.slider.value > 63)
	    	this.colourSelectCursor.strokeColour = [0,0,0];
	} else if (colorPicker.arraysEqual(this.colourSelectCursor.strokeColour,[0,0,0])) {
		if (win.slider.value <= 63)
			this.colourSelectCursor.strokeColour = [1,1,1];
	}
};

colorPicker.prototype.notifyColor = function(win){
    win.editor.gulu.color.notify("onDraw");
}

colorPicker.prototype.setCursorLocation= function(inputColor){
     this.colourSelectCursor.location = (function(_this){
            var hsb = colorPicker.RgbToHsb(inputColor);  
            hsb = colorPicker.convertHsbToKulerHsb(hsb);
            var angle = Math.round(hsb[0]); 
            var length = Math.round(hsb[1]/100*_this.size);
                            
            var point = [length*Math.cos(angle*2*Math.PI/360),length*Math.sin(angle*2*Math.PI/360)];

            return [point[0]+_this.size,_this.size-point[1]]
      })(this)
    
      this.colourSelectCursor.location = [this.colourSelectCursor.location[0]-this.colourSelectCursor.size[0]/2,
                                                         this.colourSelectCursor.location[1]-this.colourSelectCursor.size[1]/2];    
};

colorPicker.prototype.bindingKeydown = function(win){
    var _this = this;


    var keyDownHandle1 = function(k){
        if (k.keyName == "Up") {
            if (k.shiftKey == false) {
                this.text = parseFloat(this.text) + 1;
            } else {
                this.text = parseFloat(this.text) + 10;
            }
        } else if (k.keyName == "Down") {
            if (k.shiftKey == false) {
                this.text = parseFloat(this.text) - 1;
            } else {
                this.text = parseFloat(this.text) - 10;
            }
        }
    }

    win.editor.colorHolder.colorCol1.rGroup.rValue.addEventListener('keydown', keyDownHandle1);
    win.editor.colorHolder.colorCol2.gGroup.gValue.addEventListener('keydown', keyDownHandle1);
    win.editor.colorHolder.colorCol3.bGroup.bValue.addEventListener('keydown', keyDownHandle1);
    win.editBright.addEventListener('keydown', keyDownHandle1);

    win.addEventListener('keydown', function (k) {
        if (k.keyName == "Escape") {
            win.close();
        }
    });

    var leftPressed = false;

    var getColor = this.getColor = function (k) {
        _this.options.backupLocation.length = 0;
        
        if(k.type == "mouseup"){
                leftPressed = false;
        }else if(k.type == "mousemove"){
                if(leftPressed == false)
                    return;
        }else if(k.type == "mousedown"){
                leftPressed = true;
        }
        var point = [k.clientX, k.clientY];
        if(!_this.isInCircle(point)) return;

        var thisColor = _this.getColorFromPoint(point);
        thisColor = colorPicker.RgbToHsb(thisColor);
        thisColor[2] = win.slider.value;
        thisColor = colorPicker.HsbToRgb(thisColor);

        colorPicker.copyArr(_this.outputColour ,[
                                            thisColor[0]/255,
                                            thisColor[1]/255,
                                            thisColor[2]/255
        ]);
        _this.setCursorLocation (_this.outputColour);
        _this.setDefaultValue(win);
        win.editor.gulu.color.notify("onDraw");
    }

    this.colourCursorGroup.addEventListener ('mouseup', getColor)
    this.colourCursorGroup.addEventListener ('mousemove',getColor)
    this.colourCursorGroup.addEventListener ('mousedown',getColor)
}

colorPicker.prototype.isInCircle = function(point){
    return Math.pow (point[0]-this.size, 2) + Math.pow(point[1]-this.size,2) <= Math.pow(this.size,2);
}

colorPicker.prototype.getColorFromPoint =  function(point){
    var transformedPoint = this.transformPoint(point);
    var hAndS =  this.getAngleAndLength(transformedPoint);
    return this.CoreGetColorFromPoint(hAndS[0],hAndS[1]);
}

colorPicker.prototype.getAngleAndLength = function(point){
        var angle,length;
        var x = point[0],y=point[1];
        length =Math.sqrt( x*x + y*y);
        angle = Math.atan2(y,x)/Math.PI*180
        if(angle<=0)
            angle += 360;
        return [angle,length/this.size];
    }

colorPicker.prototype.transformPoint = function(point){
        var x = point[0];
        var y = point[1];
        return [x-this.size,this.size-y];
    },


colorPicker.prototype.CoreGetColorFromPoint = function(h,s){
    var i;
    
    var f, p, q, t;
    var r=1,g=1,b=1;
    var v = 1;
    if( s == 0 ) {
        v = Math.floor(v*255);
        return [v,v,v];
        }
    var originHeight = h;
    var condition;
    var tempI
    
    if(originHeight<45 && originHeight>=0){
        i = 0;      
        f = originHeight/90; 
    }else if(originHeight<120 && originHeight>=45){ 
        i = 1 
        f = (originHeight-45)/(120-45); 
    }else if(originHeight<180 && originHeight>=120){ 
        i = 2 
        f = (originHeight-120)/(180-120); 
    }else if(originHeight<220 && originHeight>=180){ 
        i = 3 
        f = (originHeight-180)/(220-180); 
    }else if(originHeight<275 && originHeight>=220){ 
        i = 4  
        f = (originHeight-220)/(275-220); 
    }else if(originHeight<320 && originHeight>=275){ 
        i = 5  
        f = (originHeight-275)/(320-275);
    }else if(originHeight<360 && originHeight>=320){ 
        i = 6
        f = (originHeight-320)/(360-320)
    }

    p =  1 - s ;
    q =  1 - s * f ;
    t =  1 - s * ( 1 - f );
    
    switch( i ) {
        case 0:r = v;g = t;b = p;break;        
        case 1:r = v;g = 0.5+t/2;b = p;break;   
        case 2:r = q;g = v;b = p;break;     
        case 3:r = p;g = v;b = t;break;      
        case 4:r = p;g = q;b = v;break;        
        case 5:r = t;g = p;b = v;break;         
        case 6:r = v;g = p;b = q;break;         
        
    }
    return [r,g,b];
}

colorPicker.copyArr =  function(defaultArr,otherArr){
    while(defaultArr.length!=0){
        defaultArr.pop();
    }
    defaultArr.push(otherArr[0]);
    defaultArr.push(otherArr[1]);
    defaultArr.push(otherArr[2]);
    return defaultArr;
}

colorPicker.HexToRgb =  function(hex){
            var ccolorhex = hex.toString(16);
            ccolorb = parseInt(ccolorhex.substr(-2), 16);
            ccolorg = parseInt(ccolorhex.substr(-4).substr(0, 2), 16);
            ccolorr = parseInt(ccolorhex.substr(-6).substr(0, 2), 16);
            return [ccolorr / 255, ccolorg / 255, ccolorb / 255];
}

colorPicker.RgbToHex =  function(rgb){
                var a=(rgb[0]*255).toString(16);
                var b=(rgb[1]*255).toString(16);
                var c=(rgb[2]*255).toString(16);
                if(a.length!=2){
                    a="0"+a;
                    }
                if(b.length!=2){
                    b="0"+b;
                    }
                if(c.length!=2){
                    c="0"+c;
                    }
                return (a+b+c).toUpperCase();
}

colorPicker.HsbToRgb =  function(hsb){
        var rgb = [];
        hsb = [hsb[0], hsb[1] / 100, hsb[2] / 100];
        for (var offset = 240, i = 0; i < 3; i++, offset -= 120) {
            x = Math.abs((hsb[0] + offset) %360 - 240);
            if (x <= 60) {
                rgb[i] = 255;
            } else if (60 < x && x < 120) {
                rgb[i] = ((1 - (x - 60) / 60) * 255);
            } else {
                rgb[i] = 0;
            }
        }
        for (var i = 0; i < 3; i++) {
            rgb[i] += (255 - rgb[i]) * (1 - hsb[1]);
        }
        for (var i = 0; i < 3; i++) {
            rgb[i] *= hsb[2];
        }
        return [rgb[0], rgb[1], rgb[2]]
}

colorPicker.RgbToHsb = function(rgb){
        rgb = colorPicker.parseColor (rgb);
        rgb = [rgb[0]*255,rgb[1]*255,rgb[2]*255]
        var hsb = [];
        var rearranged=rgb.slice(0);
        var maxIndex = 0;
        var minIndex = 0;
        var tmp;
        rearranged.sort(function(a, b) {
            return a - b;
        })
        for (var i = 0; i < 3; i++) {
            if (rearranged[0] == rgb[i]) minIndex = i;
            if (rearranged[2] == rgb[i]) maxIndex = i;
        }
        if(rearranged[2] !=0 ){
            hsb[2] = rearranged[2] / 255;
            hsb[1] = 1 - rearranged[0] / rearranged[2];
            if(hsb[1]!=0){
                hsb[0] = maxIndex * 120 + 60 * (rearranged[1] / hsb[1] / rearranged[2] + (1 - 1 / hsb[1])) * ((maxIndex - minIndex + 3) % 3 == 1 ? 1 : -1);
                hsb[0] = (hsb[0] + 360) % 360;
            }else{
                hsb[0] =0;
            }
        }else{
            hsb[2]=0;
            hsb[1]=0;
            hsb[0]=0;
        }
        return [Math.round(hsb[0]), Math.round(hsb[1] * 100), Math.round(hsb[2] * 100)];
}

colorPicker.convertHsbToKulerHsb =  function(hsb){
    var originHeight = hsb[0];
    var s = hsb[1], b = hsb[2];
    var i,f,h;
    if(originHeight<30 && originHeight>=0){
        
        h = (originHeight-0)/(30-0)*(45-0)+0;
        
    }else if(originHeight<60 && originHeight>=30){ 
        h = (originHeight-30)/(60-30)*(120-45)+45;
        
    }else if(originHeight<120 && originHeight>=60){ 
        h = (originHeight-60)/(120-60)*(180-120)+120;
        
    }else if(originHeight<180 && originHeight>=120){ 
        h = (originHeight-120)/(180-120)*(220-180)+180;
        
    }else if(originHeight<240 && originHeight>=180){ 
        h = (originHeight-180)/(240-180)*(275-220)+220;
        
    }else if(originHeight<300 && originHeight>=240){ 
        h = (originHeight-240)/(300-240)*(320-275)+275;
        
    }else if(originHeight<360 && originHeight>=300){ 
        h = (originHeight-300)/(360-300)*(360-320)+320;
        
    }else{
      return hsb;
    }

    return [h,s,b];

}



colorPicker.isType =  function(content,type){
    return Object.prototype.toString.call(content) == "[object "+type+"]"
}

colorPicker.isRgb =  function(rgbArr){
    if(!rgbArr) 
        return false;
    
    if(!colorPicker.isType(rgbArr,"Array")) 
        return false;
    
    if(rgbArr.length != 3)
        return false;
    
    for(var i =0,len = rgbArr.length;i<len;i++){
            if(rgbArr[i]>1 || rgbArr[i]<0)
                return false;
    }
        
    return true;
}

colorPicker.isLargeRgb =  function(rgbArr){
    if(!rgbArr) 
        return false;
    
    if(!colorPicker.isType(rgbArr,"Array")) 
        return false;
        
    if(rgbArr.length != 3)
        return false;
    
    for(var i =0,len = rgbArr.length;i<len;i++){
            if(rgbArr[i]>255 || rgbArr[i]<0)
                return false;
    }

    return true;
}


colorPicker.isHex = function(hexStr){
    if(!hexStr)
        return false;
        
    if(!colorPicker.isType(hexStr,"String")) 
        return false;
        
    if(hexStr.length != 6) 
        return false;
        
    
    var arr = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
    var isHex = true;
    hexStr = hexStr.toUpperCase();
    for(var i=0,len = hexStr.length;i<len;i++){
            if(this.arrayIndexOf(arr,hexStr[i]) == false){
                    isHex = false;
                    break;
                }
        }

    return isHex;
}


colorPicker.isShortHex =  function(hexStr){
    if(!hexStr)
        return false;
        
    if(!colorPicker.isType(hexStr,"String")) 
        return false;
        
    
    if(hexStr.length != 3) 
        return false;
        
    var arr = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
    var isShortHex = true;
    hexStr = hexStr.toUpperCase();
    for(var i=0,len = hexStr.length;i<len;i++){
        if(colorPicker.arrayIndexOf(arr,hexStr[i]) == false){
            isShortHex = false;
            break;
        }
    }
        
    return isShortHex;
}

colorPicker.isHsb =  function(hsbArr){
    if(!hsbArr)
        return false;
        
    if(!colorPicker.isType(hsbArr,"Array")) 
        return false;
        
    if(hsbArr.length!=4)   
        return false;   
        
    if(hsbArr[3] !="hsb") return false;
    if(hsbArr[0]>360 || hsbArr[0]<0) return false;
    if(hsbArr[1]>100 || hsbArr[1]<0) return false;
    if(hsbArr[2]>100 || hsbArr[2]<0) return false;

    
    return true;
}

colorPicker.parseRgb =  function(inputValue){
    return inputValue;
}

colorPicker.parseLargeRgb =  function(inputValue){
    var arr = [inputValue[0]/255,inputValue[1]/255,inputValue[2]/255];
    return arr;
}

colorPicker.parseHex =  function(inputValue){
    return colorPicker.HexToRgb("0x"+inputValue);
}

colorPicker.parseShortHex =  function(inputValue){
    inputValue = inputValue.toUpperCase();
    var hex = "0x"+inputValue[0].toString() + inputValue[0].toString() 
                            +inputValue[1].toString() +inputValue[1].toString()
                                +inputValue[2].toString() +inputValue[2].toString();
    return colorPicker.HexToRgb(hex);
}

colorPicker.parseHsb =  function(inputValue){
    var hsb = [inputValue[0],inputValue[1],inputValue[2]];
    return colorPicker.parseLargeRgb(colorPicker.HsbToRgb (hsb));
}

colorPicker.arrayIndexOf = function(arr,str){
    for(var i=0,len = arr.length;i<len;i++){
        if(arr[i] == str)
            return true;
    }
    return false;
}
    
colorPicker.arraysEqual = function(a, b) {
    if (a === b) return true;
    if (a == null || b == null) return false;
    if (a.length != b.length) return false;

    for (var i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) return false;
    }

    return true;
}

colorPicker.prototype.initSetting = function(){
    this.img ="\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x01\x04\x00\x00\x01\x04\b\x06\x00\x00\x00\u00CE\bJ\n\x00\x00\x00\tpHYs\x00\x00\x00\x01\x00\x00\x00\x01\x018\"\u00F4@\x00\x00\x00$zTXtCreator\x00\x00\b\u0099sL\u00C9OJUpL+I-RpMKKM.)\x06\x00Az\x06\u00CEjz\x15\u00C5\x00\x00 \x00IDATx\u009C\u00EC\u00BD{\u00BCeWU&\u00FA\u008D\u00B9\u00F6>\u00E7T*\x02I\u0088\x04A\u00D4hLT\u00BC\b-\bb\x0B\x11[\u00EDn\x04\u00FBj\u00BC\u00F8k\x105\u00B7\u00EDn\x1Ft\u00B7^_\r\u00AD\x17\u00C5\u00A6\x01\u00DB\u009F\u00B7\u00B1\x1BE\u00BD`@\x1E\"\u00D7\u0080\u00A1\u0095\u0097B\b\x10\f\x1D\b\t\x18\b\x04\b\u00AF<I\u00AAR\u008Fs\u00CE\u00DEk\u008E\u00FB\u00C7\x18\u00DF\x18c\u00EDS\u0095\u00A4\u008A$\u0095\u0084\u009ApR{\u00EF\u00B5\u00D6\\s\u00CD5\u00C7\x18\u00DFxN\u00C1\u00F1v\u00AFn\u00AA\u00FBw\u00A3\u00DF\u00F8\u00B5\u0090\u008F}\r\u00B6\u00AE}\u00D8\u00E6\u0081[\x1E\u00D2\u00C6\x1B\x1F\u00DC\u00967\u009E\u00A6\u00BA\u00E7T\u00F4}\u00A7\u00E88\u009C\u008C>\u00DEO\u00C6[\x06\u00E8\u008D\u0090\u00C5-h\u008B\u00BD\u0090\u00BE\x1F2\u008E\u00806\x00\x02@\x01\b\u00BA\u009C\x00\u009D\u00ED\u0086\u00B6\x07`9<\x10\u0083\u00EC\x1E\u0081\u008D\u00BD\u00E3\u00AC\x7F\u00B1\u00C9\u00EE\u009B\u00BA|\u00C5\r\u00D2\u00BE\u00F2Zi\u00A7~a~\u00E2\u00FD>'\u00F7\u00FB\u00AAk0\u00FF\u00FAO\u008F\u00FA\u00D0O\u00CD\u0086]\u00FB\u008F\u00F1\u0094\x1Co_B\u0093c=\u0080\u00E3\u00ED\u008E\u00B5\u00DE?\u00F5 \x197\u00BFu\\^\u00FE\u00F0\u00BE\u00F5\u00C1o\u0092\u00C5\u00CDg\u00E9\u00F2\u008630\u00DEx\u009An\u00DE \u00C3\u00E2F\u00A8\u00DE\x02\u00C56\u00A0\u008A\u00D6gh\u00AA\x10\u0085\u00D19:\u00A0\x02h\x07\x7F\x12\x00\u00D2\u00FD\u008B\u008A\u00FD\u00A2\u0080\u00EA\b\u0085@\u00B4\x01\u00BDC\u00BA\x02*PQ(\x06@;D\u00ED\u00B2\u00A5\u00AE\x01r?\u00C8\u00FCd\f\u00B3Su\u00B9~\u00EA\u00B5m~\u00D2U2\u00BF\u00FF\u0095\u008B\u00FB\u009F\u00F9\x0F\u00EB\x0Fx\u00CC\x152?\u00E5r\u0091\u00AF\u00B9\u00EEX\u00CD\u00DD\u00F1v\u00C7\u00DBq\u0086p\x0Fl\u00AA\u00B7<P\u00F5\u00EF\x1F+\x07\u00AEy\u00F4x\u00F0#\u00DF\u00DE\u00FB\x17\x1E%\u00DB\u009F9M\x16\u009F\u00C4\u00B8\u00BC\x193l\x03\u00B2\u0084\u008Cpb\u00E7kT@\u00C4\u0088\u00BB7\u0088*T\u009DrU\u00ED\u00AC`\x00~\u009D\u00AA\u00FDu\x01\u00A4\u00F9\u00B5\u00A3\u00FD\x16\x03r\u00F4\u00D0\u00F3^\u00DD\u00FBU\x00\u00AD[\u00BF\x12\u00C7\x05\u00A36\u008Ch\u00C0\u00B0\x1B\u00BA\u00FB\u00EB\u00D0\u00D6\u00BE\u00E1\u00DA\u00E5\u00C6)\u0097\u00CEv\u009D\u00FE\u00FE\u00F9i\u00DFr\t6\u00BE\u00FDb\u0091\u00AF\u00BC\u00F1\u00AE\u009E\u00CB\u00E3\u00ED\u00C8\u00DAq\u0086p\x0Fh\u00AAW?\f\u00CB\x1B\u009F\u00B8\u00DC|\u00F3\x13d\u00F3\x0B\u00DF\u00D5\u00C7\u008F\u009E\u00A1\u008B\u00ABd\u00B6}=\x1A\u0096\x00:\u00D0;T\x05]\x14\u00A2\x02\u0081K\u00FF.\u00DE\u0087N\u00FA\u0094n\u008C\u00A1\u00BB4\x07\x0Fk\u00B3\u00EFPC\tD\x07\n'x\x04\x03a\u00BF\u0093\u00EB\x01h\u00CF\u00AF\u00810\u00BA3\rm\u00CE|$\x18\u008F\u00F5!q\u00ED8;\t\u00F8\u008A\u00B3\u00B4\u00AF\u009Fq\x15v=\u00F8\u00A2\u00F9\u0083\u00FF\u00F1;\u00E5\u00FEg\u00BDC\u00DA\u00E9\u00D7\u00DCi\u0093z\u00BC\x1DU;\u00CE\x10\u008EAS\u00DD{\u00A2\u00F6\x0F=i{\u00EB\u00B2\u00EF\u009Fm_\u00FA\u00BD\u00D8\u00FE\u00F8\x19}\u00FB\u0083\x10=\x00\u00C1\x12\u00AD\u00CF\u00A1:\u00A2\x05\u00B1\x1ACX\x11\u00D2.\u0099\x1D\x11\u00A8B\u00A5R- *\u00E8\u00DD~\x13%\x1Ahf-P\u00A3V\u00FB]\u0092\th^\x0F\x15\u00A8vg\"\u00C9\x15\u00B4\u00E7m\u00D0\u00ADoU\u00C4qh2\u00A4`4\u0093\u008B\x00\u008C\u00E2\u00C0\u00C4m\x16\u00BB\u00BF\t\u00FD\x01_\x7F\u0095\u00EC\u00FE\u00A6\u00B7\u00AD?\u00F8\u00F1o\u00D6]\u008Fz{\u009B\u009D\u00BC\u00EFN\u0099\u00F0\u00E3\u00ED\x0E\u00B7\u00E3\f\u00E1nj\u00DA?\u00FD\u00D0qq\u00D9Se\u00EB\u00A2\u00A7\u00E8\u00F8\u0091'\u008C[\u0097\u00AF\u008B~\x1Es\u00C2\u00F3\x15\t\u008F.P'(C\x02\u00C6\x10H\u00D7\x00\u00D0\u00D4\u00E8L\x0Eq\u00B9\u00DD\u00B4\x15\u00E9,\u00E8\u00DD\u0098\u00CC\u00E4\u00FC\u00EE\u008B@\x04\u00E8\u0085!t^\u00DF\u00ED\x18\x00\u00ED\u008A\u00D6\u00A7\u00F72\x1E\u00D4\u00FC\x11\x12\u008D\u0088#\u0097\u00E8\u00B32\x1Ax\x1F\u00CA\x05(\u0086:D\u00A0P\u008Cr\x1A\u00DA\u00C9\u008F\u00D8\u00D2\u00DD\u00DF\u00F8N|\u00E5\u00B7\u00BDq\u00FE\u00A0\u00EF~\u0083\u00B4o\u00F8\u00EC\u0091\u00CF\u00FA\u00F1v\u00A4\u00ED8C\u00B8\x0B\u009B\u00EA\u00E7\x1F\u00A6\u00E3\u00C5\u00E7\u00F4}\x17\u009E#\u00FD\u0083\u008F\u00D1\u00ED\u00F7\u008B\u00E8\x01\u0093\u00EC\nhs8n'\x17\u00E3\x1E\u0092\u0088*J \u00BD\u00FA\u00BFBf\u00A1I`\u00D3\x01\x14\u0086\u0082f\u00EACg\x07\u0085`A\x04\u0081r\x03\u00DA\"4\f\u0090\u00DAs\u00BC\x13\x06\u00B4\u008A0t\u00B5?8\u0083\tS\u00A6\u00DB6\u00AA:\"9|\x15H\x17ho\x18e\x06}\u00C0\u00B7h\x7F\u00C0#\u00FE~v\u00D2\u00E3^'\x0Fy\u00FC\u00EB\u0086\u00F97\x1DW-\u00EE\u00A2v\u009C!\u00DC\u00C9M\u00F5\u00B3'a\u00FC\u00F0\u008F\u00EA\u00E6\u00DB\u009F\u00DE\x17\u0097<\x1E[\u0097\u0089\u00C8^4\b:\x16\u00C1\fr\u00F5K\u00BD\x18\u00E8-\u00A9-\u0088L\u00F28\x7Fr\x04\u00DE\u0082Z\u0091\u00A8\x02T\x07\u00F8\u00D1\x11\u0082\u00A3\x05\u00A2\x06\u0081\u00A2Ol\x11\u00E2\u00E8\u0081\u00D7\u00B6D/ac\u00D0\u00B0E\x06_\u00F1c\u00D5\u00D6`*\x03\u009F\u00CB\u00FB\u00D7\x0E\u00A09\u00CFQc\x01\u009C\x0F\x01\u00B4O\u00E7B|.\u0094\fMf\x18\u00BF\u00E2\u00E1:\u009C\u00F4\u00A8w\u00E3k\u00BE\u00F7\u0095\u00C3\u00C9\u008F\u00FAs\x19\u00CE\u00B8\u00F9(_\u00D5\u00F1v\u0088v\u009C!\u00DC\tm\u00B9\u00D8\u00D7\x06\\\u00F6\u00A4\u00AE\x17\u009E\u00DB\u00B7/~j\u00DBz\u00D7\u0086\u00F4\u00BD\x10\x1D\u00FD\u008CJP(\x04\u00CC/~\u0096\x16\u00A3\\X\u00FC\x10\u00C4j\x12Z\x0F\u00CF\x10T\x12\u00E6\x17\u00B8@\u00C2\u00A2\u00B4\u00AF\u00E8\u00A2\u00A3\x10\u00B28C\x18\x15\u0082\x06\u00A0%3Pu\u0095@\u00CAE\u00C0\u00A8H5$\u00DC\u0096\u008A6J\x1D\u0082\u00DD{\u0082*\u00A8\na\u00C2\x10\u00BAx\x7F\u00BD2GI\u00A68\u008EP\x05\u00C6a7\u0096\x0F|\u00DC&N\u00F9\u008E7\u00AC\x7F\u00ED\u00D9\x7F\"\u00BB\x1F\u00FFv\x19v\u00AD\x18*\u008E\u00B7#m\u00C7\x19\u00C2\u0097\u00D0T\u00AF:\u00B5/\u00DE\u00FFS\u00BAx\u00C7O\u00CB\u00E2\x1D\u00A7k\u00FF\x14\u009A*\u0080\u00D1\u008CpA\x01+\f\x01HB\u00A8\f\u00A1\u00FC^\u00ED\u0083\u008C\x0F q\u00AA\u00EB\u00E5\u00EA\u00E7E\x0Fa\u00C9\u009F\u00EA\x0ER\u008D{\u00D0T/(\u00DE\u00DD0!$\u00BC\u009E\u00D0~\u00CA\x10\u00EC\u00B3t\u0089\x01\u00F6^\u00EF\u00EF\x06F\x1F\x1F\u008D\u008D\x02^o\u00F7\u0094 \u00F2|&\x1Bw\u00CE\x07c\x1Fv\u00B8H\u00F9\u00EC\u00BD\u00C5\u00B9\u00DBk\x0F\u0081<\u00F8\u00B1W\u00B7\x07=\u00F6\u00A5\u00B3\u00D3\x7F\u00F8\u00FF\x15\u00F9\u009A\x1Bn\u00E7\u00D5\x1Do\u0087i\u00C7\x19\u00C2Q\u00B4\u00BE\u00FC\u00C0#\u00D1/|\u0096.\u00DE\u00F64]\u00BC{\u00A3\u00F5\u00BD\x10\u008CyB\u00D1\u00A5\u00A7\x17\x02\u0080\x13\x1C!\u00F5\u00EA\x1B\u00A8\u00C4\x1A\u00FC\u00A4X\x12\x01wA\u00DA\u00EF\u00AA\u008A\u00A6\u00D4\u00CB{\u00DC~\u0095\u00A1H\x10\u00BA\u008D\u0083h$\"\x18h_\u00D06}\u0086\x18SJx\x19WPM\x19\u00BBT\u00A3\u00A3\x1B5\u009B\u00E6\u00B9\u0081VB\r\u00EAq\u00ADj2\u00AFP[\u00F8\u00FC\x00z\u00D7psNb*`\u00F6\u0086e\u00DB\u0080\u009E\u00F4\u00E8M<\u00F81\u00AFY\u00FB\u00FA\x7F\u00F1\u00DF\u00E4+\x1E\u00F7\x01\x1CoG\u00D4\u008E3\u0084;\u00D8T\u00AF\x17\u00E8U?0.\u00DE\u00F8K\u00B2x\u00D7\u00D9\u00B2|?\x04K\u00A4B\u008D)\u00D1R\x02\u00F6\x02\x0B\u00C8\x10&F8\u00CD\u00F3\u00E3^\u00E9\x19\u0098\u00A0\n\x12\u00D2\nC\x00\u00DC\u0095\u0088\x1E\u009E\u0087\x1D\u00CC\b\b\u00E9\u00CE\u00A0\"\u00C2|\t\u00C9\u00EF\u00E3\u0090\x12\u00B0\x14\u0092\u00DC\u00A5}Hz\u009D0\x1D%R\u00E0e\n\u00A0\u00B7\x15\u00C2V\u008F~\u009C\"\x04u\u00DD\u00C5\u00AE\u0097\x00TfG\u00F0>\u0091\u00F7\u0097\u008E\u00F0\u00AELl1*\u00E8\x1E\u0086\u00BD}\u00E27b8\u00ED\u00BB\u00FF\u00AE\u009D\u00FE/^4<\u00F0\u00B1\x7F#\u00ED~\u0087\u009A\u0091\u00E3m\u00A5\x1Dg\b\u00B7\u00D3Tu\u00D0\u00E5[\x7Fd\u00EC\x17\u00FC\u009A.\u00FE\u00FA\x11\u00D2?\u0085\x06E\u00EB\u0087\u0080\x00U\u00AA\x020\u0082.Q<\x13\u0098\u008E\t\u00EC\u008F\u00F3\u00E1\f\u00A1\u00C2w\u0091 \x10\u00B3\u00C0\x17\u0086\u00D0\u008D!Xs\u0086\u00B0\u00AA\u009E\u0094\u00E1I7\u00D7^\u00C4\x0F\u0088\x13\x1D\x10\u00FF\u00D2\u00E2OF\x116\fu\x1BF\u00C0w\u00F7Hja\b(\fI\x0BC\x0B&\u0092\f&\x18\u0082O\u0090I})\u00FCU\u008B'%\u00BD/\u00DA\x01\x14\u00B4\u0090\x0F\u00E8j\u0084\x02\x18\u00E7PUl\u009Ep\n\u00F0\u00E0\u00EF\u00B9l\u00FEuO~\u00FE\u00EC\u00C1\u00FF\u00E4/d8\u00A5@\u00B9\u00E3m\u00B5\x1Dg\b\u0087i\u00AA\u00D7\x0F\u00D0\x0F?M\x17\u00AF\x7FN_\u00BE\u00F1\u00AC\u00A1_\x0B\u00C8\u00B6/H\u0087\u00E0h\x00z\x12+\u00CA\u0084V=~\x07\u00E4OF\u00D0\x1D\u00FE\u008AN\u00AE\u009E\u00C2k0\u008F\u00C0m\x06\u00BD\x10g\u0091\u00DE\u00ADx!v\u00A8,D\x1C\x107\u00D8\u00F9u\x18w\u00BA\x12\x15\x19i\u00B8\u00D4\u00B8n\u00E2\u00FA\u00F4F\u00F5\u0081\u00AAC\u00C48L\u0090\u008D\u00DB\x1DbNJ|D\x18:]\u00B5\u00D0\x16@H\u00DCf\x10h\u00896\x14\u00F5\u00F9%##\u00E3\u0099\u00DC3U.\u00ED\u00C0b~\n\u00F0\u0090\u00B3\u00AF\x1C\u00BE\u00FE\u009F?o\u00F8\u00EA\x1F|\u008D\u00C8\u00C9\u00C7\x19\u00C3!\u00DAq\u0086\u00B0\u00D2TU\u00FA\u00F8\u008E\x1F\u00D6\u00F1\u0082\u00E7\x02\u00AF\u00FDf\x19o@\u00EB\u00DB)\u00C6}\u00D1\u0086qK\u00A6D\u00DC\u0082Z\x14\x13\u00A3Xa\b\n\x14(\\\u00AC\u00ED\u00AB\u00AF\u00A3\u00B8(\u00ABI\u0081\u00C4%+\f \rx\u00E5F;`u\u00D1\u00F3\u00CB\u00B8\u00C4\u00EFA\u00DBF\u00C0w\x12\u00F1\x04\u00D9PUQg\b9\u008E\n\u00E3\u0095\u00FF\u00E9S7\u00A4B\u0092\u00D0\u00E3\u00F9z\u00AA,Z\u0080E\u00D7\u00F0b\u00D49RG(D:\u0093\u00A0\u00AA\x1A}\u00C9\u0081i\x03\u00C6\u008E\u00ED\u00F9\x03\u00D0\x1F\u00F6O?2\u00FF\u00FA\x1F\u00FC\u008D~\u00EA\u00F7\u00BD~m\u00D7)\u00C7U\u0089\u00D2\u008E3\u0084\u00D2\u00C6\u00F1\u00D2\u00B3u|\u00D5\x0B\u00B4\u00BF\u00E1\u00D1\rW\u00FB\u00E2\x1E'\u00BA\u00B2-22\x04\u0087\u00CFe\u0091N\x18\x02m\x00\u00AB\fA\u009C!t\u00B1K\u008B\u00B4\u009B\u00BC\x12^W \u00B3\u00B2\u0083\u00C2\x10\u00E0\u00A7u]\u00F5: u\u00ED\u00C9\u0083\u008A\u008F\u00DD\u00CE\u00A9\u00C6;\t\u00D5\x00\u00888\u0084\u00A2\u00E2\u0098+\x12\u0080v'J\u0089\u0090\u00A2\u00C9\u00BD\u009COtOz\u0092\x12c@\x04!\u00D5\u00CB\u0081>\u0091\u00F0]\u00BD\u00D7C1\x04\u00D1D!=\x19\u00E4\x04\u00BA\u00F4\u00B6\u00C2\x10`>RiP\fX\u00CENA\u00FF\u00EA\u00EF\u00BF\x04\u00DFr\u00CE\u00AFl<\u00E8\u00C9\x7F\u0087\u00E3\r\u00C0q\u0086\x00\x00\u00E8\u00FA\u00E13\u00FB\u00F8W\u00BF\u0083\u00EDW=\u00B9\rW\x01\u00D8\u0086\u00D0\u00FAM\x1D\u00BEH\u00D2$\x14\u0093`\u00D5\x18\x16m\u0095\bU\u00A0\u00BDO\u0088\x15\u00B1\u00C8W~\u00B3;\u00D9OaX+\x04\x15\u0092\u00BE\x01\u00BA\u00F4\u00F3\u008C \u00D3\u00A2O\u0082\u00F3{\u00D7\x1B\x15\u00EB?\x01\u00800\nq\x15U\u00D0\u00C0X=\x10\u00B4a\u00DC\u00CE\u00B3P\u00B5\u0089\u009F\x14h+\u00AAC\x18]\u00FBT\u00AD\u00D22\u009F\u0093x\x05m\u00C6a\u00C2\u00FD\u0088dj<\u00DE\u0089X\u008C\u00D9H\u00A7\u00E7\x04\u00C1\u00C8\u00CC%\u00DA\u00B0\u00BD\u00FBk\u00A0_}\u00F6\x05\x1B\x0F\u00FF\u00F1\u00FFKN~\u00C2G\u00F1e\u00DE\u00BE\u00AC\x19\u0082\u00EA\u00A7\u00EE?\u008Eo\u00FB\r\u00ED\u00AF\u00FD\u00B9\u0086w\u00CE\x1B:\u0080\x11\x1A\u00BEr$\u00E1\u00C3\u008Cq\u0093\u00EC@\u0097\u00E0i\u00F4\u0092\u00C95\u00AB\fbjq/\u00FFR\bWi]\u00FB\u00AA\u00F7\u008C\u00B1\u008B\u00DF\u0097H\x05\u00A0:0\u0085\u00CE\u00DEw\u00B9\u0098\f\u00A5Q(ke\b+\u00CF0\u0089E :\u00C8\u0098\x04E\u00BA\nWU\u0098I\u00CE\u0084\x16\u0086\u0080\u00D2\x1F\x19\x02\u009F\u00BF\u00CC\x17m#S\u0082'\u00F4\u00D0\u00B8\x06\u00F5\u009C\u00BE\u00C2\x10 \u00AE\u00D6\u00D0k\u00D3\x11\x01Vj\u0091\u009D#\u0080\u00F1\u00E4oY\u00C8\u00D7\u00FD\u00E0\u00EF\u00AF}\u00EB\u008F?W\u00D6\u00CF\u00DC\u0083/\u00D3\u00F6e\u00C9\x10\u00C6qK\u009A\u00BE\u00ED\x19\x1D\x7F\u00FE\u00C2\u00AEox\u00D0L\u00F6B\u00A5\u00E7\"\u00EE2\u00CD1\x00\u00A0\u00AD\u00A1\u00FB\u00E2m!\x11\u009DI8\u0094\x15\x14\t*\u0098\x12\u00BF\x1B\x00W\u00E1;\u00D5\x07\x1DI\\\u00F6\u00BB\x14D\u0090\x12\u00D8\x16\u00B8\rK]\u00EFoa|c\u00EB\x0E\u00C7\x05\u0088 \u00A1\t3q\u0084\u00DE\u00BA\u00A07u\u00C8\r\u0084[\x10\u0080\u00D6\u00EC\u00C4\u009A\x13\u00A1\u0080\u00A2\x01}\u00CCHG\u0097\u00EE4\u00A70@s5\u0089\u008A\f!\u00DC\u008C\u0095!`\u00FA\u00FC6^\u0081\u008EN\u00D4\u0095\u00A1\x16\u00DBF\f\u0093Lal\u0089J\u0098\u00A7\u00C1\u00CC\u00CB`\bD\b\u00D3\u00F7\u00B1\u00A5s\u00E8iO\u00BC\u00AE\u009Du\u00CE/\u00EB\u00D7\u00FE\u00D0+66N]y[\u00F7\u00FD\u00F6e\u00C7\x10\u00B4_qV\u00D7\u00BFx\t\u00FA+\u009E\u0088\u00E1\u0093\u0096[P\u00CD\u00EC\u00AB\b .\u00AC\x04M\u00A3\u0095QVD\u00F0\u00D5\u00A0\x1E\u0094\u00EB\x15\x0E\u00BD\u00D9w1pS\x1D \u0095\u00C6}\x0FaK\u0088\u00CF2\u00FDL\u0094P\u00A5\u00AA\u009FP\u00DDv\t\u00DF\u0093@\u00A4{\x05%WM\u00EATD\u00CA4\u00C7\u00C2\u0080*\u00B1\u00AAI\u00F0k\u00D9\u00A8\u00DA\u00D4\u00FBs\u00CE\u0098CAU\"]\u00B45_B\u00A6\u00CF\n\u0089\u00E8E\x16{YuA\u00C2]\u0090;T\u0096.1\u0096L\u00E8B0>\u00DE&\f\u009B\u0081Z\x06\u008C\u00EDT,N\u00FF\u00A7\u00EFX\u00FF\u00DF\u009E\u00FEo\u0087\x07=\u00E9J|\x19\u00B5/\x1B\u0086\u00A0\u00BAw\u00DE\u00FB\x1B~u\u00C4\u009F>[\u00E5]\u00EB\x03\u00B6\u00C3\x1C\u00B8#\u00E30\u008C\u0081\u00E9\u00DF?$CpW\u009C\u00C6\"n\t\u00E3\u0081)C\u00A1\x1B/\u00EE\u00B3B\u00E0\u00BCn\u00C2\u0088n\u00DB\u00C08\u00D5\u00F7ih3\u00C2\u00AB\b\u00A5\x05\u00A1\u00EEd\b\u00E1Jt\u00A9)u\f\u00D5]*\x00F\u00DE{\u0088\u00EB\u008C!\u00FA)\u00E5>\u00BC\u00FF\u00E1\x19B\u00CE\x19B\x05Xa\b\x13\u00E6\x027\u00A4\u0096\u00E7\u0087\u008F\u00A9\u0097w\x13\u0088$\x19B\u00A83\u00EC\u00BB\x0B\u00BA[U\u009A\u00A3\u008DV\u00E7s\\G\u00EFKl\u009D\u00F2\u00AD[\u00C3YO\u00FB\u00ED\u00B53\u00FF\u00E5\x7F\u0091\x13\u00BFz\u0081/\u0083\u00F6e\u00C1\x10T/}\u00E4v\x7F\u00F9\u00CB\u00C6\u00FE\u00DAG\u00CCf7`\x00Cy:F\u00E4\u0082\x05\x17q\r\u00ACA\u00EA\u00C6\u0094\u0096\u00D5\x16\u00C0\f=\u00E1a^3\u0089C\u00C0\u00E4z\u0088CeU\u00FBL\u00C8\u00DF\u00F34\u00A9\u00D7y\u00F4\u00A0z\u0090S\u00B5\u00D8\x1Bn\u0097B\u00D4\u0085\u00DFh\u009E2\u00D1\u00C5\u00EB\u00DC\u0090\u0089\x157\u00E0\u00A4\u00C2\x11k\x1C\u0084-A\x10\u00B6\x04\u009B\u0080D'%8\u00A9\u00D7{\u00D5\u00FB\x1F\u00C2\u00E3\u00C0\u00FB'\u0093J\u0086Y\u00F3\x1Bb\u00DE\u00BB\u00E4\u00C2-\f!\u00CE\x1B=\u009C\u00DB\u009F\u00C5\u0090P\u00CE\u0087M\u00A33\u00A7C1\u0084\u00CE\u00C7j\u00E8\u00B2\x0B\u008B\u00D3\u00FF\u00D9e\u00B3o>\u00E7'\u00D7\u00BE\u00EEG\u00EF\u00F3\u00A1\u00D0\u00F7i\u00860\u00EA\u00FE\u00D9\u00F6\u00F2u\u00FFq\u00D9^\u00F6\x1C\u0095w\u00CF\u009B\u008C\u0098\x01\u0098\u00C1\x18\u0082\u00D0\u00D4\u00A6\f4*R\u00A4\"\x05\u00B6j4\u00F3\u0096\u00C4\u00E6zt@\u00D0\u00DB20\u00D6E_\u00EE;1\b\u00A2\u00F4#y\u0080\x16\x7F\u00F6\x13\u00FD!\u00FA\\5\u00E4\u00ED0\u0084N\f\n-$(\x0F\u00D1\u00F7_\u0087/\x15\u0095T\u00AF\u0087GlV\x064E.+\u00DF\u00CB_\u00CD\u00AF\u00A8\u00E3\\5\u00BE\u00F2\x1D\u00C5\u00FD\u0082\u00D9H\x06$\u00D1\u00C8\x19\u008Cg\u0085!\u00F8\u009C\u00D7w\x156\u0099nk\x01\u00CEl8\x07\u00E8\u00E6\u00A1\u00E8\u00DA\u00B0}\u00CA7.\u00E4\u00E1?\u00FA\u00BC\u00F5\u0087\u00FF\u00EB\u00FF,\u00EB\u00A7-q\x1Fm\u00F7Y\u00860\u008E\u0097\u009F\u00B1\x1F\x7F\u00F6\u008A\x03\u00F2\u00F2\u00EFX\u00C3u\x18\f\x00`\x06\u00C5\f\x02\u00F3F{\u008B\u0090W\u00EA\u00F0\u0085\u0088\u008B\u00D4?\x1CC\x00\x1C)L\x16\u00F2a\u00EC\t\u00F0\u00FE\x0E\x15\u00FA\x1C\u00F6\x04\u009D\u00DE\u00B72\x04 u\u00E6\x18W\u00C6\x06L\x18\x02\u0092\u00D0\x12\u00A6\u00AF\u00BA \u0093Xz\x19+m\x0F;\x19\u0082\x06\u00D1\u00C4X\u0090C\x16\x7F\u008EP\x11\u00D8\u00DF\u00E1\\\u0090\u0085\u0090s.W\u0090\u008C\x02\x1Ah\ra\u00EF\b5\u008C\f\u00A1\x04rU\u00A6\x15\u00B6\x02\u00C0S\u00C8\x0BCX\u00AD\u00F9@d\u00D1\x01\x19\u00ED\u00B7\u008E\x01\u00AA\x02\u00C5.\u008Cg<\u00E5}k\u00FF\u00E8'\u009F\u00D1\u00BE\u00EA{\u00AF\u00C2}\u00B0\u00DD'\x19\u00C2\u00A6\u00FE\u00E5O\u00EC\u00D5\u0097\u00BEx\u0081\u00B7\u009F8\u0093%\x06tg\x02\u0086\fLeP\u00CC\x14hu\x06V\nt\u00C4B\u00ED\u00AB\u00D3\u00B4s\x11\u00D7H\u00BE\u0094v\u00A5\u00D8I\u00B94\u00FA\u00C7\u008A\u0095\u00BD\x10!\u00EF\u00A8\u00BD\x10c\u009C\u00A7IP\u0093\x03\u0094\u008A\x19\u00E4\u0093:|J\u00CFU>\x04PZ\u00D3X\u00DA\u0083\u00B8\u00E9\u00CB\u00AF\u00EAG\u00CC\u00D5\u00A4\b\u008AzAW/\u00D3\u00EE\x07\u00E8\x05\u0088\u00BA\u008B\n0\u0097\u0082\x1E\u0087\f=&GX\u00B5%\u00DC\x06C\x00\u0092A\u00B2\n\u00F5\u00EAs\u0086\u0097\u00E1(\x18\u00C2d^\x15\u00AA\r\u009B\x0F|\u00CC\u00BE\u00D9\u00B7\u00FD\x1F?\u00BF\u00FEm\u00FF\u00E1\u00E5;g\u00F2\u00DE\u00DD\u00EES\f\u00A1\u00EBU'\u00DE\u00DA\u00DF\u00F4\u0092\u00BD\u00F2\u00E2\u00A7\u008F\u00F8\x14\x06\u00E9\u0098A1\u00A8\u00AB\t\x02\fh\u00CE\x10z0\u0084\u00A9\u00DE[\u00F4SMC\x1DP\u00A5\u0096\x11\u0089\u00ADWM\u00F8\u00AA\u00E5\x1A\x05\u00CC\u00C8\u00A8+\u00E8 \u00FB\x06\x122\u00F3\x10m\x18S\u0086\u00E0\u00FD\u00C7y\u008A\u00ACPT\u0099\x18\u008D\u00A1=nQ\x19B\u00DC\u00B6\u008E\u00B7\\+\u008E4*\u00CC\u00D6J,X\u00C9\u00C2\f\x02\"#\u00EC\u00F1]\u00DC\u00A8\u00A2\u0085\u00C8\x15E\u00A5\u00F2\u00F1\u00F3\u0099'\u0092\x1E8D\u00A0\x12\u00C7\u0088T)\u00F8\x1C4*\u00D6|\x06\u008Em\u00C5-\x19\f\u0096\u00CF\u00B5\u00C2\u00D4\u00AA\u00CA\x10\u00C9^nS`\u009F\x1D\r\u00E3\u00DA)\u00C07=\u00E3\u0095k\u00DF\u00F5o\u00FE\u00AD\u009Cp\u00C6}\u00A6\x18\u00EC}\u0086!l\u00E9\u00DF?\u00FC\u0096\u00F1O_w\x13^q\u00D6l\u00B8\x15\r\u00C0\\\u00A9\"\x00\x03\x04\u0083\x003/f&P\u00AC)m\t\u00B0\x1A\u00A3\x00@\u00E9L?\u00FE\u008A\u00E4\u0098X\u00B2U\u00D0\u00D1\u00C3S\u00D1'\x0B\u0096\u00BA?\u00AF)\u00D4W\u00BFW\x1BE=\u00CE\\\u0087\u0090\u00CC+\u00AFj\u0087\u00DA\u00C01\u00EA\u008E{\u00A9\x1B\x02E\x07\u00C0]y\u0082\x16L\u00CDG\t\u00BA?\u00ED7~\u00F6\x10\u00E9\u00F8k;\u00EF\u00EB\f*m\x18|\u00B6\u009E\u008C\b\u00F4\x04\u00D896\u00C7\u009A\u00CF\x11:|_\u00E9\u00BF0\u0085\u00A2\u008AL\x18\x02\u0099X\u00ECSAC\u00E5j\u0090\u0092\u00A3\u00BD.9\u00CE\u0082\u00B22\u00E9+\u00E7\u00D3\x18\u0083\x04C\u00A0\u00F1R\u00D1\u00A0}\u008E\u00ED\u00AF\u00FB\u009E+7\u00BE\u00FD'\u00CE\x19N?\u00E7\u008AC\u00BC\u00C9{]\u00BBO0\u0084}\u00FD\u008D?v}\x7F\u00C9\x1F\u00ED\u0093\u00B7\u00EC\u009EA14\u00B3\x0F\u00CC\u00D4U\x03\x18Ch\x02\u00CC\u0091L`\u00EEv\u0084\u00AC\u00BDS\u00BC\x055\x18\u00C6\u008F)-\u00E4Q/\x00\x18\u00A1\u0093\x12b;\u00A5j\u00EA\u00E8\u00D1\u00AAd\x0E=\u0098\x18\x7F\u00A5@I\u00FC[\u00CE\u009F\x1Co\u00D9\x15\x17q,\u00FE9h\u00B57\x1B\u00C7\x00\u00E8,\u009F\u00CF\u00AF\x11\u00DE7\u00AE_a@\u0094\u00AE!\u00A5\u00D5C&\u0082\u00DA\u00D3\u00D7\x0Fx0T\u00CEA\x10?\f1\u00D8\u009C*DGG\x15=\u00BD*\u009C\x06g&\u00AB\u00F3\u009F^\u0088\u00A9\u00B1\u0094j\x14\x19\u0085\u00A1\u0085\x12\u00A4\u00C4k<\u0098,\x10\u00C5\u00B8\u00CA\x10\u00AA\r\u00A7\u0099g\u00A7\u00A3xr\u00CA\u00BCu@\u00BB`\u00FB\u0094o\u00DD\u008FG\u009F\u00FB\u00AF6\x1E\u00F5\u00F3\u00AF\u00C6\u00BD\u00BC\u00DD\u00AB\x19\u00C2Ro\x1En\u00EE\u00AFz\u00E1u\u00FD\x0F~a{v\x15\x1A\u00B6ME\u0080\x18C\u0080\u00BA\u00CD@\\= s\u00B0s\x1A\x14s\u00FF\u0097d\x15\f\u00A1 \x04JPJ\x0B4\u0087\u00FA\u00AAQ^\u00B02\x04(-\u00F6\\\u00B8\u00AB\u00F0\u00BC|\x16\u00B8>~\x1B\f\u0081\u00D7P\"\u00FAw\x052N\x1F\u00CD\t\u00BE\x19\u00E1\u0088B\u00FAZH}\u00AA0\u00CCc\u00A8\x03\u0091p%\u0096sw\u008CYr\fa|M\u00E1n\x04R~<\u00DC\u00F8u4\"#aw\u00AF\u00D5\b\u00B7\u00F4w\u0086\u008F\u008F\u00A0\u00CA!\u00D0\u00A9[\u00D7\u00FB]\rR\u00EA\u00BD\x04b9\x11O\x1E\u00D5\u0089\u00B8\u00FB\u00FC\u00EEd\b\u0098x,\u00A6\bA\u00C1P\u00E7\f\u00F62T\u00A2\x10,\u00D7O\u0083~\u00FB\u00D3\x7Fw\u00ED\x1F?\u00EB\u0097ex\u00E8\u00BD6\u00B5\u00FA^\u00CB\x10\x0E\u00EA'O\u00BA\u00BE\u00BF\u00EC5\u00D7\u00EB\x7F\u00FF\u00BE\u00DE\u00F6\u00B8}\u00A0\u00FB\u009F`\x0E\u00C1\u00CC%\u00D1\x00\u00C1\f\u0082A\u00D4\u0098\u0084\u00C2\u00D5\x07\t\u00840\x14\u00A6p(\u00E2c\u00E8\u00AD\u00D9\x05\u00AA\u0095\u00DE\u00FF\r]\u00B9\u00F8\u00E8A\x1D\u00FA0(A\u00F3\x16v\u008F\u0095\u00E3E\u008FN\u00D4\u00C2\u00E2\u00A7\u00FC\u00D7\u00EEi\u00F9\tm\u0082\x00Z$#\u00B5\u00F2<\u00AD\u00D4\\\u00A4-\u00C0\u00F5\u00FE\x18\u00BF\u0096gpc\u009C3\u008B\u0088\u00AF\u00A0z\x00E\u00A6\u0083\u00AF$H\u00A1F\x17\u00F22\u008D\u00E8H\x06\x1A1\u0095\x1APHw\u008F^\x1F\u00BD\u00EF\x0EQ\u00CB?P\u00EF\u00AFi\u0086N\u00C7s\u0089\u0098\u00CA0\u00F6\t\u00D2\u00C8\u00B9l\u008E \u00EC\u00DA(#\x07\u0084=\u00C3\u00C2\u00B0Q\x10\x06\x19\u00BFLl!\u0093\u00EC\u00CA\u00D2\u00C7\x12\u00BB\u00B1x\u00F8\u008F\u00BCe\u00E3;\u00FF\u00DD\u00D3\u00DAW>\u00EA^Y\r\u00FA^\u00C9\x106\u00F5\u00B2o\u00F8\u00F4\u00F8\u00E2\x0B>\u0083W\u009E9o\u00DB\u0098\u00A1\x192\x10\r\u00860\u0080\u00EA\u0081\x19\x15\x07\x11\fP\u00FB\u00CD\x19\u0082\u009D\u00A7\u00E9\u0081P\u00844\u009A2\u0084b`(\u008B\u00DB\u008E\x15\t\u00C8s\u00AB\u00F4\u009C\x14,\x05d\u0095)H\u00E9s\u00D5\u009E@F\u00E4\u00A3\u00B2HB\u00C38F\u00B8\u00CD\u0089}\u00F0\u00FE\u00E9G\u00A1E\u00DF\x18\u00C2\u0084p*\x13@\u00F3b\u00A5q\u00A3x\u00D6\u0088\u00CB\x00b\u00EC\u00D3}\"\u008DP\u00BA\u00DF\u00C7\u00A4\u00B2)\u00F1B\u00D8@&\u00B7\x03)\u0088\u00A3\u008C\u00D1\u00C7\u0099\u00D7di4\u00BAPml\u00A2#\x14\x0B\u00A8v\u00B4b\u00A7\u0090\u0092\u00DF\u0081\x11\x11\u00BCU\u00FFjH\u00B5\u00A83\u008E\u0089\u00AD\u00E30\fa\x15!\u00F8\u00FB\u00AD\f!\x12\u00DE:\u00A0\u00E3\u0080\x0E\u00C1\u00F2\u00F4\x1F\u00F8\u00E8\u00FAc\u00FF\u00CF'\u00CB\x19?\u00F4q\u00DC\u00CB\u00DA\u00BD\u008E!\u00EC\u00D1\u008B\u00BE\u00EB\u00EA\u00E5\u00EF\u009E\x7F\u00ED\u00F0\u00A6S\x06,\u00B0\u00AE\u00DD<\x07\u008D\u00AA\u0080\u00D9\x05\u00A6\x7Fb\u00AA\u0082*f\u0082\u00C2 \u00D2\x0598S\x18T\u00D1\\0\u0087\x1E\x1D\u0095\u008B\u00FCo\u00E2\u00EE#\u00E5\u00AFD0N\u00A2\u00FE\u00EC8\u00ED\x12\x13\u00A4P\u0098L\u00E8\u00C0q\u00C8\u0089^\x07'\u00FA6\u00FDW\u00C5\u00C7F\u0086\x01\x7F\u009A\u00FCl\u00E3ru\u00A0,^2\u0090\u0090\u00D4\x00\x18\u0085\x18F\u00D1\t!3\u00BEA1\u0089\u00E0,\u00EED\u00D0\x00\t>\u00B7&\u00DA\u0098\x140\u00D1\u00F2\x07\u00D4B\u00AB\u0093\u00DF\u00B4g\u00BC\u0086.m\u00EA\u00B5\u00A31\\\u00DA\u00D1\x03\u009Ci\u00A0\u00AB\u00AB#\u00F9\u00FEt\u00A4\x1A\u00C1\u00F7\u00E3hf\x05!\u00A4\n\u0086\u009D\f\u0081\b\u00C1\u0099\u00D9\u00E1\x18\x02T\u00D0G`\u00D4\u0086\u00E5\u0083\x1FyS{\u00DCO\u00FE\u00D0\u00C6#~\u00F6\u00A2\u009D\u00AB\u00F8\u009E\u00DB\u00EEU\f\u00E1\u00DA\u00F1/\u00CE\u00B9\u00BA\u00BF\u00F8\u00BC\x1B\u0087wm4\u0098+q\r\u00DD\u0088\u00BC\u00D8\x04\u008C\u00D0i/\x00\x06m\x18\u00C4T\x05C\x12<\u00D7Hf\u00A6\u0082A\x1A\x1Az\u00D8\x1381]=\u00DE\u009DR\r\u00C8p\u00E5\x15\u00A4P\u00E9<\u00F7L\\\u0085\u0096\u0094\u00C8\u00BC.\u00AEp}\u00BA!\u00CA\u00B3\x05\u00F1\u00CF\u00CBg\u00AA\n\u0082\u00D4\u009F\u00AB\u00E5\u00BF\u00D4\x15\fd\u00D0\x10~\u00FC\x12\u00A0d\u00D7\u00A69\u00B5\u00C6\x1Cd\u00E0\x0F\t\u0099\u00CFa\f\u0083?5'\u008A\u0089\u00A4\u00AFAW\x135bu.4%\u00B5\u00C7.h\t\x0E\u00CB\u00A4$'>\x1D\u00C1\u00BD.\u00B42\x03\u00ED\u00E8:\u00A2\u00C5\x1E\u0098Z\u0090\t\u00E7\u0096]\u00B14\u009D\u00A1\x1B\u00E9c\x18\x18\u00A5\u00BA\u0081i\u0083`\u00DC\x02]\u008F\u009C\u00C3\u008A|z\u00F6\u00CFu\u00A0\u00E3\u0080\u00C5Ign\u00EAw\u00FE\u00C4\u008F\u00EFz\u00DC/\u00BF\x0E\u00F7\u0092v\u00AFa\b\u00D7\u008D\u00E7\u00FD\u00FCe\u00FA_\x7Fo\u00DFpEk\x1Ehd\u0084\u00DF=\x1C9\u0089<U\x01`-\u00BE\x1B\x01O\u008C\u008D\u00C2\u00EFfc\u0090@\x17I\u00B0\u00944\u00A1F(\u008B\u008C\u00DA\u00F7i\u009A4\u00F5\u00ED\u0095\u00BA\t<\u00EE\x04\u0095\u00E7\u00B3Q\u00A5\x10\u00A0\u00CF\x00]+\u00A8\u0080\u00CC\x01 #\u00982\u008DrmA\x05S\u00D8,\u00B9\u0098\u00D1V\x02\u00B0\u00CA\u00FD\u00B9\u0093tx\tVT\x0E\u008F3PZ\u00F8V\u009E\u009Fi\u00D7\x13\x04\u00E0\u00C7\u00CC`\u00A8\u00D1\x7F\u0086\n;S\b\u00B5e\u008C\u00DF'\u00E1\u00D2N\u00F8\u00DCNN1B\u00B0\u00F49\u00EB\u00CE,\u00C8 Fg\f\u00FC~\u00FB\f\x01d\u00FC+\f\u00A1\u00D3\u0090\\\u0098\u00FB\u00ED1\x04\x00\u00BE\u0099\u00ED\u0080\u00ED\u00DD\u00A7\u00F5\u00F6\u00D8s\u00FF\u00FD\u00DA\u00D9\u00CF}1\u00EE\x05\u00ED\x1E\u00CF\x10\u00C6q\x0B\u009F\u00EB\u00AF\u00FE\u00CD\u00CB\u00F0\u00BC\u00FF\u00B4o\u00B8\u00DA\r\u0083\u00A6\x02\u0098\u0087\u00A0O\u00BC\x06\u00F6\u00BB\u0091\u00851\u0083\u00E9\u009F\u00A1\u0081\u00AA*0\u00B7\u00A1M\u00BEG\u00A4\x1D\x10\u00903'K\u00BD\u00F2\u00EF*Rh~\u00AC\u00F8\u00DF\t3\u0085\u0084\u00D6L\x12Q\u00EA\u00C9\u00CC\t\x7Fpb\u009A\u00D9_ \x04)\u00D6\u00F2J\u00FC\x02\u00F4\x01\"m\u00B2X\u00AB\rAz=\u009F\x03j\u00A5/8Q\u00AF\u00F6QS\u00A9i\u00BB\u0088\u0087\u0099.\u00FC\u00F2\u0099nA\u00EE0U\u0099\u00C2\u0084q2\u0090\u00A8|\u0087\u00AAmu\u00DFG\x1F\x13\x19\u00883Z\u00BF\u00B7\u008E\u00DD\u00FB\x1B\u00E1~``tOE\x07\u00C8T\fu,\u00D2\u00F8\u00C8\u00CDr'\fAK\x05\u00EB\u00C33\x04\u009Bk7\u00BC\x1E\u008E!8?\u008B\u00B9\u00F0>{o\u00D0\u00F5\u00D3\u00D0\u00FF\u00D13\x7Fk\u00EDI\u00BF\u00F4\u00EB\u00B2~\u00F2!\u00D7\u00F9=\u00A5\u00CD\u008E\u00F5\x00n\u00AB\u008Dz\u00B3\\\u00D3_\u00FE{\u00EF\u00D7\u00E7=k\u00FF\u00EC\u00B3\u0098\u00F9\u00E2h\x10\u00F3\u00FF\u009B\u00AC\u00B6\u0080\u00A0X\u00DF\u0096\u00DA*H\x1B\u009D/I\u00C0\t\u009E\u00EF\u0090\u00E0]\u00CBy\u00BE\u00EC\x02\x11\u00D4H\u00C6z\u0092\x00n\u0089\u00AA\u00D2\u0096w\u00948Y\u00D8\u0091\u00A64\u00B7\u00FB\u00B9\u00D2\u00A3\u00FCwf\u00BA>\x1A,\x03\u00D2q\u008D#\x01\u00BB_G\u00E8\u00FD\u00D2 \u00E2\fC\u00A4\u00D0\u008C\u00E4\u00F8\u009Am`\"~\u008E\x11\u00A1\u00D7M$\u008A\u0080B\u00C5~\u00A3\u00C8\u00D7\u00CE\u00F9l\u00E1N\u00E5V\u00F3\u00A2\u00CD9$\u00E2\u00FA` \u00E2\bA(\u00F5;l{8I\u00CD\u00A4\u00DAb8\u00F1\u00CD~o]\x1D\u00BB)\u0080\u00D1\u00F5\x11\u008E\u0093\u00CA}\u00DAa\u00B3o5\u00C6\u00E5\u00FFF\u009C\b\u00D4\u009F\u00DB\u00DC\u009A\u00D6\x15\u00DF\u0089\u0097\u00ACG\u00B0Y\u00F0\u00D2\u00AA\u00C61\x01N@F$\x01\u00AA\x025\x06\u00B7[\u0091\u00AF]0t\u0085\u00EE\u00BF\x0E\u00FD\u00BD/\u00FEO[\u00BA\u00E7\u00FE\u00BA\u00BC\u00F6\u00DF\u00CB\u00EC4\u00C5=\u00B4\u00DDc\x19\u00C2R\x0F\u00B6\u00AB\u00C7\u0097\u00BF\u00F4\u00DD\u00FD\u00B7\u00CE\u00DD\u009A]\u008B9\x14\x0B8\u0087\u00F7\u0085\u00EB\u00B5}<\x1F\u00C1\x16\x12]\u00C9\u00A2\u00C0R\u0082\u00EC\u00D0}\u00A9\x19\x13w\x15\u00C2\u00A1\u00EF\u00E8o\u00B6\u00A9\x1A\u00B3\u00F1\u00F7\x1A\u00B6\u0084\u00A4ooE\u00E2N\x1A\u0097W\u00ADG\u00E00\u009CT\u00AA\u00F4\x10x\u00DEex\x06\u0086\u00F2\u00AF r2\u00E3\u00D9\x04*\u00CD\u00D8a!\u00A4P\x1Fj\x1C\x01\u00F2\u00BE\x12{:\u00B8\u008E\u00EC\u00A3\u00B1\u00E7\u00F2\u00B1\u00D2&\x00\u00EBK\u00A4\u00F4#:}\u00FCbK\u00B1\x1F]4J\u0092\x16\u00DF\u008F\bc\x1E\u008A\u00EA\u0084\x0Ei@\u00D4\u009F\u00AF\u00AEVa\u00C5&\u0085\x15a\u0081\x13\u00B3\u0082\t\u00EB\x12o\u00B8\u0099\u009A\u00E0oU\u00D0,/\x02\n\u00C5h\u00F3\x0F\x010\x022B\u00C5\u00FBq\u00F7\u00A5\u0084\u009A\u00A2\u00ABd<\u0099\u00BF\u00E0\u0093\u00A8\u00AF\u00BF0\u00B3rN=i\x12{\"\u008A6\u00EEG\x7F\u00EFy\u00CF:\u00B8\u00DC\u00DE\u00AD\u00E3M?-\u00C3)\u0087\u008AQ=\u00E6\u00ED\x1E\u00C9\x10\u0096\u00BAg\u00B8r|\u00F1\u009F\\\u00A8/zf\u009F}\x11\x03\u0080\u00A5\u00BB\r;\u0080\u00AE\u00CA\u00EA\u0087q\rQ\u00C1\b_:\u00B1 \u0092I(\u0080%\u00CC\u00A8(\x10\u008C\x10\u0080\x0B\u0085D\f\u00BBX\\\u0092\u00F4\u00E8\u008F\u0092\u0082\x12\b&\x05\u0093n@\u0098\u00C2u\u00A1\x11E\u00D8\u00A0b\u0084/\u00E1\u00E4\u009C\u00C5\u00EF\n\u00B7\x17\u0088\u00A3\x01f_F\u0092v\x04X\u00DBgJb\u00C0T\x06\u008E)\f\u0081\x1C\u00A3\x11\u0097LV\u00EA\n\u0083PJA\u0081\u008A\u00AB\b1\x7F6{\u00C67\u008D\u00C3\u00A9\u008B\u00D2`.\x05I\x00$\u00AF,\u00A7\u00C6\u0098\u008D\u00C8\u00B0\u0094\x01\u00E1NQMi^)\u008Eh\u0086\x1AO \x11\u00F8\u00DC\u008D\x10\u00C9\u00E0&\u00F1\u00B8b\u00CD\u00B2'\u00C68\u00B4\u008A\u0083\x0E\u00C5\x12\r\x1D\u0090%\u00B4\u0099\u00D12\u00EC!\x13\n\u00BF\u00BDv\x18Dp\u0098&\x10\u00CCT\u00A0\u00DB\u00FB\u0080\u00F7\u00BE\u00F2\u00DC\u00ADq>S\u00DDs\u00AE\u00C8\u00FD\u00EFq\x01L\u00F78\u0086\u00B0\u00A5\x07\u00DB\u0087\x17\u00BF\u00FF'\x7F+/x\u00E6r\u00D8\u008B\u00B9sc\n \u0093\x07d\f\u00F6\u00EA\x15U\x05\u00B0%\u00EC\u00CB\x12\u00C5\\er\u00C4\x17XG\u00B7eSP\u00BFi\x00\x1A\u00B0\u00DAH\u0092\u008C\u00C0\u009Ae\u00E7\u00F1\x07\u00814\u00B7*\u00A3\u00D4a\u00CC\u00C30\u00CC\u00E1\u008EO\u009D#\u00AB1\u00E4_\u00E4a\nU\x04\u0087\u00F8\u00F08\u0083\u0080\u00F9\u00EC\u00D9\u0088\u00D7\u00B2%+s\x00\"\u00BC*\u00F0o2\u0096\u00C9\u00D8\u009C\x19$\u00AD\u00B9\x11\u00AF0\u00BB\u00C9\u00D9b\u00E8\f\"@\x1B\u00C2//\u00BC\x17\u00FB\x10\u009B\u00F1@H\"6\u00F3\u00AC\u00D5\u0088\x02>2\u00DA\x0B\x14\u00C3\u00EA8>\u008C\u008E\u00BC>E/R\u00DD\u00E8\u00C6H\u00A1P,\u0091f\u00E1\x0ES\u00A9J\u00FF\x02Ge\u00BD\u00A0\x1CgD\u00BE7\u00DC4\u00A2tU-J\u00E45\u00F1.\u00DD\u00D1\u00E6hqm{\x0B\u00CB\u008B\u00FF\u00F4\u0099\u009B\u00E3\x12z\u00F0s?%\u00BB\x1Er\u008FB\n\u00F7(\u00860\u00EA\u00ADr\u00E9\u00F2\u008F_\u00FA\x0E\u00BC\u00E8\u0099\x07\u00DB\x1E\u00ACa\u0089\u00A6\u00E4\u00F7)\u00E7T\u009C!\u00888X\x04\x00\r\u00E2\x1E\u00E1h\u00D4\u00DFn\u0087\u00A9\u00A3K\u00AA\x06\u00E29\f\u00CA\u00FB\u00DA\u00BF\x12L\u0085\u00CC\u0084\u00EB\u00A3\u00FE\u00B7\u0090\x16\u00E1\u00A4\u00B8J\u0090+\x1D\u00E9\x02\u009CC1\u00F7\u0080\u00A2\u0099\x11=\x04i'pI.\u00E9Q \u00A9I\x1B\\b\x1398t\x0E\u00D1I\u00DD\u00DCg\u00A0\u00AA(\u00BE\u00B5;%xz7\u009A\x11\x00!@\x18Z\u00B4\x1COB\u0097B\x18R\u00E7Bh\x18,\u0093G\x03\u00A2T\x17\u00AC\u00C2\u00D4 \u0083\u00EB9\u0089!\u009E\x1D\x11\u00B8\u00F1\x12\x1AR{\u00BA\u00AD=\x19\u00A11l\u00A5\u00FBQ\u009A\x1Fi@\u00EF\x10LK\u00DA\x01\x1D\u00AC\u00A2\u00CD\u00BC\t3\u00DCv@\x17\u00BEz\x16\u00C6\u00C0V=\x05\u00AB\u00A8a\u00F2Uv\x1E?ls&\u00D7\x01H\u00C3l\u00DC\u00C2\u00F8\u00F7\x7F\u00F6\u00CC\u00ADa\u00B6\u00D4\u00C5-\u00FFJ\u00E6\x0F8\x1A\x16s\u0097\u00B4{\fC\u00D0\u00AD\x11\u0097-_\u00FE{\x7F\u0083\u00DF>\u00F7\u00C0\u00FCzxZ\x0E\x06 \u00F6U\u00E6\u00FA]\u0080\u0081\u0083\u00B1Ja\u0084\u009E\u00F2\u0090\u0088\x00\u00FEy\u0094\u00A9\u00A4\x17X\x18;\rl\u009DF# P\u0085\u008B\u00F8\u00EC7`B\u00ED\u00C9\u00FB\x13\u00B8ZA?\u0085\u00FB5t\x0E\u00E1w)\x01E\u0081\x10\u00F8\u0094D\t\x04\u00E3$b\x0F:\u00A2>\x1E^\x05J\u00B3\u00A2R\x04s\u00A0\u00B4GJ\u00D9\u0096q\x06\u00C6\u009C\\\x01j\u00AE\x0E\x18lr\x06\u00E0\u00E2]\u0087\u0088\u00E1\x07\u00ABR\u00C3\u008E9y\"8bw\x1C\u00A6\u0085\u00B7\u00C0&-=\f-$\u00B3\u00EA\x00\u00B4fx\u00AE'\u00A22\x17\u00A5]-\u0092\x18M\u00BDc\u0081@\u00DBhs\u00C2\u0098\x0E\u00D1\u009C\u0093@\\\u009E8%\x03\u00C4sO\x04n\x10E\u0087\u0088[\u0095\u00B4\x032\x03t\x01\u0095\x11\"N\u00B9\u00BD2#\x7F\u009A\u0098\u00CF\u00FC\u00E9h\u00DB\u00FAr\x13\u00DB\u00EFy\u00D9\u00B9\u00FBe}\u00BF.n\u00FDw2\u00FF\u008A\u00A3\u00EF\u00ECNl\u00F7\x18\u0086\u00F0\u00A1\u00F6\u0087\u00BFy~\x7F\u00FE\u00B3n\u009E\u00DF\u0080\r\u0095p\u00ED.\u008B\u0084\x18\x1C\u00D2Sr\u008Dj\u00CB\u00C5\b\u00DE\u00DE\u00D3\x120i@\u00FA0`\x1A\u008B\u008C\u009F\u0093i\u00E4yD\x15\u00FCNx\u00ABJ\u00C9d\u00AD;\u00BD\u00ACj\u0090*\u00E2\x10v\u00CD\u0099@a\x04\u00D5X\x18\u0084\u00DB\u00CC\u00CE\u00E0\u00C7\r\r{\u00CC\u00814\u0087\u00BD\u00C2\u00CE!\u00AD\x01}@\u00D8\x01\\\u0095\u0080\x1B\x013i\u00A9\u00C4\"\u00F8yS\u0089V\u00D4\u0089\bT2\u00C9n\u00F7*\u00B1\x16\x01\u00CB\u00DA\u00B4o\u00F4\u0082\u0084\u009C\u0088\u0088.B\u00C2W\x1D\u008AP_\u00CAW\u0093\u00DC\x12F\u00C9\u00A2\x0Ex\x1F\u0089*\u009C\u00E1\u00C0\x18\u00958S\u0096\u00F0&\u00901\u00E43ReP\u00FF\u00ACq/z|L\u00BD\x10\x1A\x1A\u00A5\u0085\u00FA\u00E0b\x04\u0081\x15w\u00A8\x0FD\u008De\x0F\u008F\u00BA\x16@\u00DBMY%\x02\u00EF\u00BBA\x1B0loB\u00DF\u00F5\u00B2g\x1D\x18\u0096{\x00\u00FC\u00FA\u008EN\u008EA[]\u00D3\u00C7\u00A4]\u00BE|\u00FD\u00CF\u00BF\u00B6\u00FF\u00DA\x7F\u00BBi\u00F6q\u00CCDqB\x17\u00CC\x04\u0098\u0089bM\x1531S\u00DC\x1AJ$\u00A2*\u00E6\u00B0c\x19ld\tM$\u00C5\u00994Ot\u00B2\u0090f\u00F1\u00F3\"&\x01-\n\u00A8X\u00BD\u0084\x15\u00F9\u00AE\x04\u00FDN\u00BE\u0092\u00E5\u00BB\x01\u0094\u00C0\x19z\r\x06\u0088\x0E@\u00F7\b\b\u009D\u0095\u0085G\"u\u00CF\u00C2J\"\u00920\u00F8(\b/%^\u00A2\x01z(d\u00B2\u00F0\u00E3\u009C\x12\u00C5[\u00C3\u00A5\u00F3\u00BCr\x0E\u0088\x16\u00A8~\u00A0\x04\u00D7\u00F8aU\b}s\u00B5`IHc\u008D\u0090]\u0085Z^A\u00A0\x01\u009D0\u0085\u00DCI\u00DA\u00FF\u008D\x18\x05\u00F6\u00AB\u00C8\u009D\u00B2=\u00A7\u00C13\x1FA/\u0088\u00C7\r\x00\u00DEOw\u0086\u00C1\u00A6c\u00C44\u00D89\x16\u00AB\u00A0,\x19\u00DF\x01\x19\x1D7v5\u00B5\u00A3\u00BBQR\u0097\x1E\u00CB\u00D03\u00A6A\x17\u0088 \u00A7\u00D1\u00E7\u00A3\u00FA\u00B2\u00BB\u00F8\x1E\x1E\x1C\x0B\u0091\u0092]\x16\u0099\u00A8\u00BD\u008C7\n\u00B2\u00F8s/\x05\u00DB\u00EB\u00A7B\u00BF\u00FB'\u009F\u00B5\u00F1\u0094\u00FFr\u00CC\u0083\u0097\u008E9C\u00B8r\u00FC\u00FF\u00CEy\u00F5\u00F8\u00BC\u00D7|j\u00FE\u0081\u00B6\u00A6\u00C0\\\x04\x1B\u00AAX\u0093\u0086\x19:\u00D6\u009C\u0080\u00E7h\u00CE\x10j$\u00A2\x05)\x19(\u00AF\u0084\u00CE\u00C2(\u00CD\u00CDy\x1A\u00D9\u008C5\u00A4\u0099\u00A9\u00CF3\u0098\x15XD'\u00C7\u00C3\x1F\u00A0\u0099\u00E3\x00\u00A0\u00ACaIu@\u00E7\x16e\u0088\u0099\u00A5\x1DC\u0090a\u00C65\u00A2\u0090\u00C1D\u00E6YP\u00FF]\"\b\u00C8n\x10j\u0080\u00BA\u00D7\u00A1J\u00E8\x12D\x14)\u00D7\u0090\b\u00CCc\x1F\u00D3\u00AD\u00DC\u00E0\u00C4\u00E9\u00B1\x05N\u0090\u0096\x1198\u00F1J\b\u00FE\u00E4|I\u008C\n\u0084\u00E1\u008D\x12>\u00F7\u00A4@\u00BA\x10W\u0082\u0092\u00F2\u00B7<F=?j\x1E\u0094\x00%\u00F0\u00FE\u00BE\u00A9\u008A\u00E16\x1B\u008B\u00D594\u00E6\u0091\u00F5\x12$\u00CE7\x061\x16\u00A6\u00B0\u00B4>z\u00B7\u00FEGEl\u00E7\x16\x01T~~Wg\"dN#\u00B4/\x01\u00ED\u0090\t\x03I&\u00F9%3\u0084Q\u00A1}\u00C0b\u00F7\u0083\u00FB\u00F2\u00EC\u009Fy\u00DA\u00EE\x1F\u00F8\u008F\u00C74\u00CC\u00F9\u0098\u00AA\f\u009F\u00D3\u008B\u00BF\u00EB\u008F\u00B7\u00FE\u00C6\u0092\u00E1\u00EF\x00\x00 \x00IDAT\u00C3yW\u00CD.kM\u00CD)\u00D4`j\u0082 \u00EB\u00FA\x01\u00AE\x1A\u00B8\u00BBQ\\\u00CF^\"d+\u00A8y\u008B\u009A\u0083\u00C9T\b3E\u00A6\fQ\u00F7J\u00A8\u00DB\"XhUC\u0093W\x15\u00F74\u00D0\u00ADiq\t*\u0099/A\u00B7\u00A6b\x06\u00E8:\u0098U\u00D1\x18G\x10*\x02\u00D5\x04\u00EF]\x05\u00E6I\x18,~`\"\u00C1\u00DBDUI\u0086R\u00EC\x0B<7\x14\u00EE\u00C2h\u00AAB\x1Bq\x04U\u00E9\u0095\u00BC\u00954\u0097\u00E6\u00E5\u00B8\u00B8\u009F\u00BF\u00B1\u00D0\b\u00FB\x0F\u00B8\x10s\u009C0\u00A2\u008E\u009B\u0090}\u00F58\u00A6\u00D7(h\x11\u0088w<a\x1E\u00E5_\u0083\u00FA\u0080\u00A2\u0083\x1B\u00B5\u0084j\u00D1X\u00DE\u008E(AA\u00E3j\u00DE\u00DE\u0099\x1C:,\u0094\u008Dc\u00F2\x10i~\u00A7\u00D7abL\u0094\u00F2G\u00F5\u0081\u00ABB\u00CB\u00AAJ\u00A5\u00F3\u0088\u009B\u00C2\u00E7]1\u00DB\u00FB\u00F9\u00B6\u00BC\u00E8e\u00E7m\u00BD\u00FB\u00C5_X\x7F\u00FC\u00CF\x1F\u00B3\u0084\u00A8c\u00C6\x10n\u00D2+\u00BF\u00E1\u00A5[\u00BFr\u00FE\u00C5k\x7F\u00BF\u00B1K\x15k*\x18\u009A@\u00DD\u00BC\u00D7U1\u008A\u00ED\u00BBg\u009E\x063&\u009A\u0085\u00D9\u00D6|Ss\x1F\u009A\u00C6\u00D7\u00CC\u00A5(\u00D5\u00CB`\u00CB`\x12\u009D\x17\u00CBB\u00E2\u00DB\b\u00AF\u0087\u00E0:0e\x12\u00ED\f\u00C2\u00FB\u0082\u00C6\u00B4\u00E6\u00ACa\u00DD0\x0BC\u008D#\f\u00D9\u0089\t\u00E5\u00B3x\u009C\u0081\u00CE|\u00BD6\u00D8\u00FE\x02$j\x06!\u0099\u0094\x11\u00A1m\u00C1\u008E\u00F1\u00CEP\u0084\u00B5\x1A\u0092L\x04>'\u00A1\x02x_\u00E1*\u00F49H\u00BF}\x03Z\u009B\u0084s\u00B2/\u00EA\u00E7\u009C\u008B\u00EC\u0093\u00A4?\u0086\u00E7f\u00E2\u0082\u00F3/v\u00F5\n: \x1Bh0\u00C9,\u00FE\u00CE\u00F8@\u00A4A\u00AA(\u00D4aD\u0081n\x1E\x16\u0086 \u00AB\u00F4\x18\u008BMFs\u0091L&\u00EA\x04\u00CE\u00F7\x1EF\u00D8\u009E\u00B6\x07\x7F\u008E\x12B\u0089p\u00B9b\u00CC\u00B9\u00E7\"@2D-\u00CC@\u00F8\u00DC+<ygc\u00DF-\x19`\u00D7x\u0087\x02\u00C5\u00DA\u008D\u009F\u00DC\u00D8z\u00FB\x1F\u009E?^\u00F6\u00CA\u00C7\x0E\u008Fx\u00FA1I\u009D>&\fa\u00AF~\u00EE\u00A4\u0097m\u00FD\u00E6\x05\x17\fo:eC:\u00EA\u00B2o\u00BE2m\u008E-\u0085\u00A5I\u00C6\u00A9\u0091\u0088\x07h\x18\u00F7\u00962\u00F5\u00D2\x03\u00C9\u00D3k\x135oC:0=b1z\x15\u008C*\u00E8b\tSc\u00C82.\u00AD\u00E6\u0098\u00C3c\nt#z\x00\u0086\b>\u0082\x1B\x17Y\u00C3\u0090\u00A8\u00A0Ju\x01\u00DD\u008A\x1A\x18\x07\u00EA\x01L\u00E4l\u009A\u00AB,\u00D0\u0083\f\u00D0F4T$\x13\u00E3\x12\u00FCX\u00EC\u00CD\u00C8\u00D8\u0086\u009E\u00BD$zh\x11\u0092L\b\x1BFJ\u00E1y\u00D5MN\u00F68\u00C0\u0082\u0094\u00C4\r\u0091\u00CE\u00CC\u009C\u00F0\x05\x1A\u009Fsl\u00894\u00D2;+\x1E\x04\u00A2P\u00A9o\u00CB\u0098\u0096\x05]u\u00A7}I\u0081\u009D\u00AC\x0B\u008AE\x12\u009A \x11\u0084\u0088{\n\u008A\u00DB\u00D6v\u0089\x01\u00BDS;\u0098\u0099\u00ABTTO\u00AA\u0091R\u00FD\x02\x11q\u0086\u00BA\u00F4a\u00F4\u00C9{:\u00E2V\u009C\x193U\f\u009F\u00FB\u00C8)\x07\u00DE\u00FC\x07\x17\u00E8\u00E7.|\u009C<\u00E4\u00BB\u00EF\u00F6\"+w;CX\u00E8bx\u00CD\u00F6\u00EF\u00BC\u00E6\u00E5\u00F8\u00B33g2\u00A2\u00F9\"\u00A4\u0083\u008D\u0084_u\u00FE\u00D1\x7F#`\u00B3(C\x7F\u00FF\x0E\u00B9\u00C4\t\u00BC9q\u0093\u00EB2\x1C\u00BEC\u00B0\u0094\u00EE\u00A1\u00B9\u00F6\x06\u00E8\u00A10\x15\u00C3\u00A4\u00E9\f\x04\u0086\u00F4\u00E33/\u00C2=\x01X\x03\x03\u008DDf\u00E6\u00C2\x13\u00D3\u00F15P\u0082\u00BB\u00BE\x1A\u00F5\u00FD\u00C1\b\u0093\u00CC\u0080D\u00A4\u00A6\u00B0$K\u00F4\u0085.-\u00FC\u00F2\u00D3\u00A0\"\u0097xe\u009FH\x1B\"\u00CFQ\u0097l\u00B47\x18\u00D22\x15'\u0099L\u008F\u00D9\u00B3\x19h\u00AE\u00D3\u00D6\u00A8g\u00A6?\x13_\x01pz\u00A6;\u00D0\u008C\r]Z\u00BC3;\u00E6~\u00FF \u0094\u00AA\u00BD\u00D8{\u00EA\u00EE\u009ElE'Tm%\u008F\u00A0\u00A8\x0F\u00E2\u00DF\u0093\u0087#\u00FCF\u00AA\u0080\f\u00E6.D\x0BI\x1E\x1E\u0087\u0098\x13G!\u009D\u00F3I\x1F@\u0089\u00C9\b\u00A2v/\x00Fgl\u00CD\u00C3\u009CGD\x15Ww\u00C9&|PL\u00F6\u00EB\u00BC\u00CDv(Uj\u00FA\u00DC\u00F3\u008F\u00BF\u00E7\u00CC\u00AD7\u00FD\u00FEk\u00F4\u00C0g\u00FF\u0099\u009Cp\u00F7\u0096c\u00BB\u00DB\x19\u00C2\u009B\u0097\x7F\u00F6\u00C2g\u00E3w\u00BF\u00EF\u00E0\u00DAA\u009C\u00EC\u00849\u00F8+\x1E\u00A1Xz\u00ED\u0082\x11\u0082\u00B1\u00DBk\u00A0\u00CD`\u008Cs\u00D5\u00ED\x07\u00BEdI\x1F\u00C8 $\u00F5\x05\u00DE\u00C5Q\u0087;\x14M\u00E6\u00FB\u00A2piU\u00DD\u008F\u00DD\r\u008B\nE\x17[4\x1A\u00BE\u00865\x003\u008C:G\u0093\x19\u0086\u0082\x06B\x12\u00AB\u00D9\x10\u00CC\u00D8\u00C7p\u00E4\u0082\x10\u0084z\u00AE\u00A9\x11\u00A2\u00EAIJ-\x17\x1A\u00C3\u00FC\u00DA\u00AA\u00AB\x0F\u00A6fpM5\u00F3L\u00A8C\x7F\u0091b\u00C0\u00F4\u00C8\u00BB\x18#<\u00BB\x0F\u0080\u0088Ey\u00A4\u00844\u0082\u00A0\u00A1\x0F\u00C1^}\u00A8\u00E2\u00D2X\x11\u00CCT(\u0091\u009B'\x16\u00C5~\x07\u00AErHs;\u00A8\"\n\u00B0\b|\u00F6\x07W;\u008C\x15B\x05\u008D\u00B9\x0BN\x14\x16p\u00A4\u00B0\u00C2(+\u00E2\u00DC\x19S\x07\u00D0d\x16H\u00C2\u00E2@<\u00AA\u0091h\u0081U\u0099\x18\u008F\u00A0\u008C\u00A7\u00F0't&b\u00D6%\u008F[@)\u00A4\"#\u0088R\u00C2;\u0083f\u00B9\x11tO\u00EA\x12io\u00F1\x19%wsf\u009B\u008C$\u00BF\u00FA\x0BE\u0085+\u00D2\x05k]\u00B1\u00BC\u00E4\u0082\u00EF\u00DB\u00DE\u00F5U/\x04\u00F0\u008B\u00B8\x1B\u00DB\u00DD\u00CA\x10.\x19\u00FF\u00E6\u00C7~v\u00F9\x0B\u00BFp\u00DD\u00B0\x17\u00A2\x1Dk\x10\u00CC\x05\u0098k\u00C7\u00DC%Q\u00A4&\u008B\x04B\u00E0,\u008A\u0087\r\u00AB\x18\u00D1\x0F\n,]\x124\x15\u008C\u00CE8Dh1\u0090@\u008F\u0084\u00B1\x1D\rcx\f\b\u0093\u00BD\x1F!\u00BA \u0082\x00:\x064\u009D\u00A3\u00CB:\u00809\u00BA\x17r763\u00A0\u00D68\u00AC5\u0098\x02\u00C2\u00F3)\u00C2\u0088\u0098\nR\x1A\u00C1\u00F8\u0099\u00AB\u00858\u00C5\u00C7\b\u00AA\x01\u0094\u00CE\x1C;|!\u00931%2\b\u0098Mb\x17\u00FFQ\u00A4\u00AC[\x0F\u00EEqF\x10\u0091\u00CE\u008AHpj\u00E1\x1D\x002\x00\bH\u00DF\u00A63\x10i\u0099\u00D9Y\u00D4\u009C0\x04R{\bJ\u00A8\x19\x16\u00DD\x19MB\u00F4tw\u00F8|uC%6\fC Lz\"\u0083\x17\u00D0>\u00B2,\x04\u0097R<\u00A2\u00B9+\u00BB\u008B\u00B1y\x16L\u00B5)\x04\"\u00E0@MY\r\u00F1\u00A4\u00DD\u00D1\u0089\u00A0\u0084\u00CB\u00A1\u00DC\u00FC0\u00AD\u00B2\u00DBC\x1F\u009E\u008D[\u00D8|\u00DF+~a\u00F3M/x\u00FF\u00C6?\u00FF\u0095\u00BB\u00AD\u009A\u00F3\u00DD\u00C6\x10\u00AE\u00EE\x1F|\u00F8\u00AFn\u00FF\u00EA\x1F]\u00BA\u00F6\t\u00A8,\x00\x15\u00EC\u0083b\x03\u0082\r\u00C0+\x1AYu\u00E49\u008C\u00B8G\u00E9\x18\u00FD}\u008C\u00A2\x1E\u0098\u0084\x00oKAl\u00D1f 8\u0093\u009E\x04\x12\u00A1\u00C9U\u00F5\u00A4i\u00D1\x12\u009B8:;q\u00F4\u00C5lK\u00B0ad\u00D8\u00B1\u00B1.d9\x16E:>[2\x05\x1A\x0F\x03\u00C2\u00B3\u00B2Bs\u0098O\u00C8\u00EF\x06A\u00F5\u00DF\u009D\u0098\u00A3\u00CAR\u00E8\u00C3\u00FC\u00EE\f\u00C1Q\u008Ee<\x0E\u00C8\u00D0b\u00B1\u00AC\u00C6@\x0F\u008A\u0089\u0087\u00C3\u00C5\u009BiW\u0092nG\u00CE\u008E\u00DF+\u00A6\u00C3\u00A0\x12\nwp~\u00A5N[\u00DE\x7F\u00C4&9Y7\u00A60k\u008C\u0083\u00C6X{\x00'\x04\u00CD\u00F7\u00D1\u00DD(\u00C8B\u00AB\u0089@\u00FC9\u00AA\u009D$xM\x03\u00D5\u008F\u00A9\u008D\u00C3\u008Fu\u008F\u00C4t&ch\u008D\u00CA:W\u0089\u00C6<\u00C7|\u00A2;\"(\x0B\u00C6\u00DF\u0087B\u0090\u00E9\u00E9\u00DD\u0099l\u00F7\u009A\x13#B\u00D2+\x19Im\u00B7\u00C7 \x0E\u00D1\u00A4c\u00E3\u00C0\x17q\u00F0\u009D/\u00FF\u00A3\u00E5%\u00E7]>{\u00F4\u008F\u00DF-\u00FB>\u00DC-\f\u00E1:\u00BD\u00F6\u00C4\u00FFg\u00EB\u00FF~\u00DD\u00EBgo\u00DB=zv\u00A1\n\u00B0\x1F\u008A\r\x00\u00BB\u009D\u00D8\u00E7\u00A2\u0098\u00AB\u00B9\x13\u00E1\u0084\u00EBk\x18J\u00F0\u00AEf7\x1B\u0085\x0E/\u00F7\x06\u0088\u0086l\u00CF?_L\u00AA\u00EE\u00FEe-\u0085\u0089\u00DD\u00DE\u0092\u00A4\u00C4\u00E4\u00CF\x00\u00AF\u00C7\u00A4\x16\u00E1\x00Y\u0087\u00CA\x1C\u00AAV@\u00B3\u0083\u009E\u0081\u00E6\f\x01\x0E3kHr\u00F54\u0098\x112\f\u0080\"\u00A9\u00F3\u00ABDxn\u00D4i\u00A2\u00FB/\u0098\x03\u00E2\\\u00B7\u00C9\u0083\u0099\u0089\u00ADY_\u00EA1\f\x00\x11j\u0089\u0092s\u00C8*\u00AB\u00C8\u0080\u00A9\u00C6\x0EL\f\u0095;\u00EA\u0098l\u00B0\"\u00FE\f\u00E2\b\u00A20R\u008F\x11`\u00BD\u00C2\u00A6-\u008D\u0099\x1C\r\u00D1\x19\u00BF\u00A7Ng$\u00E9\u0086K\u00A6`k\u00F3\u00D4\u00E4\x0E3\nJ\x0B[\u008E\u00BD,\u00CE\u0087\x02\u00DA\u00ED\u00B9\u009A\u00D9\x07\u0094\f\u0085\u00CCK\u00C9\u00E0\u008DX5\u0090\u00D2\x10\u00C7L\u00CDr\x13\u00B4$Z\u00E2\u00D8\u00B5\u00D3q=:j\"\u009B$\u00D4\u00A7w\u00C8\u00D5\x0BzL\u0094\u00C7{\u00BC\u0083T\x1FJ+?O7\u00E31\u00E6\u00B5~\u00DD\u0095\u00BB\u00B7\u00DF\u00FA\u00B2\u00D7\u00E9\u008DW>Z\x1Ex\u00D6]\u00BEC\u00D4\u00DD\u00C2\x10\u00DE\u00BC|\u00FD\x1F\u00FC\x0Fy\u00C5Y\u00E3@\u008E\r\x00f\x07\u00D8\x03`\x17\f\u00A22\u00B8\u00A8\t\x17\u008B\u00BB\x1A\u00D5\x10\x04\u00E3:h?`_\x16\u00A3 XJz\u0088=\u0080\x0Es\x00py>\u00C0\u00FA0f\u00C2Q$\u00CA\u00B0W?@\u00B0\u008E\u00E6\u00EA\x01\u00D3\u0095\u00BB'\x1FY1\u0096\x01c\u00893hn`J\u0095\u0080jDa\f\u008CjR\u00C2{\tn\u00A7\u0091P4\u00F89dU\u00C3!\x16Q\u00DA\x13\u00D4\u00A5;},\x12\u00C7\u0081\u00F0\u00CD\x16\u00C6B\u00A1\x17\u008B\u0090\u00D2\u0096C\u00F3'Hwg\u0089\u00E2H|\u009F\\:\x16;\u00BB\u0090\u00A2\u00D2\u00F8\u00AF$\u008C\u00F8\u00C9G*H\u00C4`\u00D4\u00E0\u00844P\u00A6\u00DB\x7F\u00C5\u00C2\u00C6\u008D\x10\u009D\x00\u00B9\u00D7]\x10ZU\u00B7\u00AA4\u00EE9\u00E7\u00EA1)\u00EAy\f\u0081\u008A\u00A8\u00D2\x144F5\u00C9\u0089\\\u00C3`H\u00C6\u00C2\u00ACI+\u00D3#D\x04\u00E1\u0095I\u00C7\u00F74\u00AA\u00B4\u00BEK\u009D\u00FE\u00A4\u0089\u00A7j\u00D3\u00A6\u0098]y\u00D1Y\x07\u00CE\x7F\u00FEK\x00<\x03wqk\u00B7\x7F\u00CA\u0097\u00D6\u00FEn|\u00DBO<\u00BF\u00FF\u00DE\u00BF\u00BCem\u00D3\x7F\u0099.\u0098-\x007w\u00C1\x01\x05\u00B6\u00E1\x7F*X@\u00B0\x00\u00B0\x10S\r\u009605b\u00E1\u009F\u0097Hc \u00D5\u0087\u00B12\x03\x18\u00BB\u00E8\u00E5\u00BC\u00E2\u00E1\t\u0090\u0097\x7F\u0086\f:\u00D61b\rK\u0099\u00FBw\u00EE\u00F6\u00D0\u00CC\u00D0)3\u008C\x180\u00A2a\u0084\u0095e\u00EDbj\u0080\u00B6\x01*\x03\u00D0\u00D2\u008E\u00E0\u009A-hs\u00C8\u0090ff?\u00CE\u00D2\u00A8\b\x01\u00CB\u00A9A\x06\u00A0\u0089\u00B9\x18K\x1A\u00B3\u00D9\x0BL5\u00D1\u00E6\u00FF\u008A\u00C7gj\u00AA\t*\u0083\x1Fs\x06\u00E4}(\x1A\u00BA\u00D7`0\x17g\u00B3\u00F1\u008A\u00A9/v\x1DK\u00B8!\u00CB\x12\u00C2\u00A4\u00AB\u00D9,\u00FD\u00D9\u00A4\u00F9\u00BD%\u00FAS\u0099#b=e\x06\u00C8\u00DC\u00FF\u00EC\u00B3\u00CA\x1C\u00C6\u00A6\x1D\u00811\x03\u00D4\u009F\t\u008E\u00C0\x04\x16\u00D1\u0099\u00CFkc\x17&j\u0089\u00C4\u00BCU4e\u00CF\u00E0\u00CF\x1B\u00CF\u00E4\u009F\u0083i'\u00A3\u00CF\u0087J[\u00D0\x0E;\u008Fr<\u00F6\u00A7\u008E\x14w2\x7F\u00FE1\u00CD}\u0096(5\u00DA\u0091\u00A9\x0FV\x1D\u00BC\u00A3\u00BD\u00EF\u008DO?\u00F8\u00C6\u00DF\u00FE\u0089#\u00BA\u00F8(\u00DA]\u008A\x10>\u00AB\u009F>\u00E3Y\u00DB?\u00F3\u00E2\u008F\u00AD]\u008D\u009D\u00BA^B\u00DC}M\u00B1\x0B\u0082u\b\u00E6\u00A2\u00E6\u008F\u0085\x05\x05/\u00E0S\u00AE,u!\x1Epd\x10\u00BF\x03\u00F1]\u00DCX\u00D8\u00E2\x18\x19D\u00AA\x07K\u00CFGH\u00B3\x1D\u00E3\x0B\u00E6\u00E8:\u00C3(\u00EB`\u00D4!\x03\u009E\x15\x03\u00BA641\x06\u00D0\u00D4\u0088\u00CA\u00CD\u00A0h\u0093\u0085\u00D4\u00A0\x13\u008F\u0082\x13\u00B2\x0ENX-~\u0097N\u00E3\u00A3K?\u00D8B\u008E\u0094gM\u0087l\u00CC\x19\u00DDs!\u00D6K>\x02]h\u0094\u009A\u008A\u00D0\u00C9\u00AD\u00C0\t2\u00AC9R\u00A8{~\u00DF\x11\u00D7\u0080@6R~WwwB\u00A8Z\fn\u008F-\u00EA\x04u\u0082bhS\u00A2\x02A\tSN4\x02\u00B1\u00DC\t\u00D6Q\u0088x\u00D40Lj\x10\u00B0\u0094d&cVn\u0098,v\u008A\u0090\u00F6\x00Pl\b6_\u008CTl\u00B9\x1CUa\u00F5.V\u0095N\x12\u00FD\u0098\u00EF\u00C4\u008B\u00C1\u008A\u00BB)s\u00DE\u00DD\u00D8\b\u0081H\t\u00A1\x0E\u0083K\u00A6=\x11D\u0088j<\u00E2\u00A4)\x02\u00B5l\x1C\u00B8\x05\u00FB\u00DE\u00F9\u008A\x17/\u00AEx\u00CD\u00BB\u00E7\x0F\x7F\u00DA]\u00B6\x15\u00FD]\u00C6\x10\x0E\u00EA\u00DE\u00D9\u008B\u00B6^\u00F8\u008A\x0B\u00E6o9\u00D1\u00EA\u00F0\u00D5$f\u00FE\u00D9bQ\x00\u00B7\u00C0\u0098\u00C2\u00CC'\u00A5\u00A9\u00D9\x15\u00C8\u0087\x07\u00A4\u00FA\u00D0\u00C4\u00C3\u0093\x15\u0090\u00F0F \u00EA#0]vt\u00AB|\u00B5g7G\u00D2\u00B6<\x1A\u0080\x19T-K\u00A23\u00BE\x00n/\x10+\u00BD\u00DAK\u00A6b\u00C3\f#\u00A5\u0086\u00B8g\u0081\u00AE\u00BE *'\u00FA0k\u00D3\u00ED\bp\u00F1h,\u00FA\"\u0091\u008A\u00AB*\u00AD\u00D9T18}\x1E\u009D\x18\x1E\u0085JT.\u00AD\u00C3bo\u00F3\u00AD\u00939\u00AFYx\u0084\u00EE|/pI\fD\u0090R\x10\u00B9C\u00F5\u00D0M\u00CC\x06aR\u009BC\u0099\u00E8\x0F9\u0086J\u0097\u00F5p\u00B42\x16\x0E\u00A8\u00FA\u0092\u00C3\x1E\u00C0\u009C\x06'\x1E\u00B7#\u00D8}\x06\u00EFi\u0084\u00EA2\u0099G0\u00A4\u00F46\x04*\x10\u0080\u00D9\u0087\u00D9\u00F7\u0088(\u0082\x13\u009E\u008E2\u00C7\u00D2<\u00F1\u00C9\\\u0094\x18\x07c\x022&\x12\u00D3% \u00DD\u008D\u0090\x03R\x1D\u00CA\u00F5\x1E\u008F\u00E9?L\u0083\u00A4\u0080Pa\x14f\x10m\u0082]\u009F\u00FF\u00F8\u0089\x07\u00DF\u00F4\u00A7\u00AF\u00D0[>\u00F3]\u00F2\u0080\u00AF^\u00EE\u0098\u00C6;\u00A1\r\u00B7\x7F\u00CA\u00D1\u00B5o\x7F\u00CE\u00A3\u009E\u00F3\u009Bx\u00DE\u00D3o\u009D\u00DD\n\u0095\u008E|\u00DE\u00E9\u00E2\u0084\u00FF\u00D7\u00DC\u00C1\u008254/q\u00A6\u00BE=\u009B3\x04\x117vk\u00AC\x1D\u00BA\x0E\x05\x00\u008B\u0087\u0088\u00A4\u00DB0\u00D5\u00D9B\x02\u00C2o\u00C6\f\u00809D\u00D6\x00Y\u0083A\u00E5L\u009F\u00CA\x14\u00E6\u0099\u00FB\u00EE\u00FDw\u0087\u00AB\u0082\x01\u0083\u00E7.\b\x04M\x04\x01u\u00A5\u00C0^G\f\u00BC&\u00E11\u00AD\u00D6\u008E\x06\u00DC\u00C0H\u0098ly\u009A\u00CE\u00D0\b\u00AB\u00A3\u009E\u0082\u00CFeQ'\u00D8\u00AF\u0090\u00D1DNE+4\u00CF-i\x1C\u00867\u00EF[[<\u0087\x05<\u0091\u00B90\u00D8\u00AB\u00F2\r\u00BBg\u00D4\\\u00F0\u00E3\u00B9\u00E35]\u0081-\u0098\u009E\x10\u00AE\x0B \u00EEuI\u00ECA\u00A3g\u00FE\u00C6O\x11v,\x16\u00C5\u00D9d%~\x02\u00EE\u00E5q\u00E9+\u00F0\u00C5\u00C4\u00D4q\u00A6\u00AD\x07s\u00A1\u00DA@\u00E4\u0094\u00C4\x18k\u0083a\u00D2<Ki\u00BE\u00AE\u00AB\u00B8\u00A8*\u00BC\x01\u00EFA\x01\u00E2L+7\u00BD\u00C9>'\u008C \u008EI\u009EP\u008D\u00CA\n\u00A0+Z\u00EFh7\\\u00F3\u00D0\u0083\x1D\u00E3\x7F\u00FE\u00CB\u00F7\u00BC\x13wA\u00BBKl\b\u009F\u00D2+\x1E\u00F9?\u0096\u00BF\u00FF\u009C\x1B\u00E6_\u00F4_\x0E\u0089\u0085&\u00BFt\x00\u00B7\u008Ab/\u0080\u0083*\u00D8\x12`\u00E16\u0083\x11\u0096\u00A46\"\u00ED\x07\u00F69\u0099I\u00A8\x10\n\x0B?\u008Ec\u00F4<\u00A4}\u00816\u0083\x11st\u00DB\u00EA\u00C5m\b\f\u009E\u009E\u00C1\u0092\u00AB\u00D7L\u0095\u0088|\u00C9T!\u00EA\u00F7\x0E\u00C1\u00E8\u00EA\u00C4\u00A4\u00E8{\u00842\u00A7\u009A\u0090\u00B5\x15\u00CB\u00B1\u00D5]\u0099\u0088(\u0088@\"\u00CA1\u00ED\x01\u00A9\u00BFS\x0F\u0097<G\x19Z\u00CD])\u008C)\u0089\u009A\u009D!k46H\u009FC:\x170%\u00DA\u00E0\u00C4T\u00C6\tVy\u00AE\u00EE\u00CC\u0086d\u009E\u00ABI]\u00E5Y\u00CA\x1F\u00B7\u00A2c\u00D2z-&cP|6\u00BD\x07\u00EF\x13\u00C4\u00BA\u00F3\x1E\u00E9\u008F\"cL\u009B\f\u00CD\u00C9\u00B9\x7FW\u00CB>\u0094\u00D7S%\u0090$F\u00BE\x0F/{\u00C7\u00C4x\u0089=1\x1C\u0091M\u00E2MZ\u008C]&\u00E3\u00A4\u00F0\u00E1\u00B3\u00DFN\u00A3As\u0095n\x04\u0098\u008DK\u00B4\u00F7\u00BE\u00F19[\u00EF\u00FE\u00E3G\u00DE^7G\u00D3\u00EEt\u0095a\u00EF\u00C1/\u00CC\u009F\u00BF\u00FD\u00C2\u0097\u00BDc\u00ED]\u00F31\u0092]\x0E5\x05\u00AB\x18\u00C9\u0088z\u00AF\x00\u00BBT\u00B1\x0E\u00C16\u00CA\u0094\u008A\u00A1\x00\u00BE\u00E6\u00EEn\u00AA\u00A5d\u00A6\u00E2\b\u00DA\x10\f&\u00AF\u0094\u00D8\x07m\u00B8\x1D\x03D\u00E7hn8\x1C}\u0081Z\u00C2\u00B5%M's\u0090\u00C2\x04\u009C\u00A8\u00C1\x1D \u009A\u00D9\u0097}\u0081\u008Chh\\\x10\u00AE2\u00984pi\\-\u00D9~\u008E(\x17\u00BCd\u0096\u00A1b\"\u00C5s\u00BA\b\u008D)\u0095|\u00EE(]C\u00CAH^\u00EBY\u008DR\u00CF\u00ED\u00D3\u00EAQ$\u009C\u0094\u00F6~\r\u00AD\u00F1 |e?\u00E9y\u0090IG:\u00F9\u0087'\u00D9)\u009E\u0090\x14\u00FA9\u0093\u00C5\x04\u008C/\u00A7\u00A4\u008F-\u00E3\u00A3\u00E2r\u00C4\u0091z\u00DF-\u00FAQ\u00F4\x12\u00C8H\u00BB\u0089\u00C3v\x00\u00A1\u0086\u00E5\u00E3\u00DB\u00DD\u00F9\x1EZ\u00B3~\x18g\x15\u00EB\u00B1\u008CSl\u00E3\\\u009B^\u00CD\u00E35\u00A9\u00C9k;\u009A\u00AA\u0090o!m\x14\u00EA\u00FE\u00F2\x05b'\u00A8\u00FA^W\u009B\u00A3\u0082\u00A2\u008F\u00F9.b\x1D\u00B3\x1B?1_\u00BC\u00E3\u00CF_\u00A6\x07>\u00FFh9\u00E1\u00AB\x16;/>\u00FAv\u00A7\u00AB\f\u008F\u00FD\u008Do{\u00F6\u00AF\u00CB\u008B~l\u00FFl\x13\u00AB.\u0094;\u00D2FX\x04\u00E2L|\u00F7f\u00E1r\u00A5\u00AD\u00A0\u0085<`H-\u00A1(\u00E1s\u00FC\u00D7\u00ED\x0BI?\u00ACz\u00BC\u00E6\x7F\u00EBP\u00B1\x12*\u00C9\u00BD\u00D3B\x1CP\u0097\u00B9\t\x10'x\u00C2\u00DFT\x0B\u00E0\x16\u00E8p\x1DJIv\x02%.s \u00AA\x04\u00F3\x01\u00B2\x1F0X\u0089\u00D2:\u00F7U\u0088x\u0085\x12\u00B0\u0094\u00C9\u00DF\u0084\u00AF\u0094\u00D4\u00DE\x187\x10(\u00C5\u00A5ZQeR\u00DA\u00C3\u008D\u00A5\r\x11\x06\x1DR\u00CF\u00E1\x7F\u0098&\b\u00EB\u0093\u00F9X\u00F0N\u00C2t\u008B]\u00E0\u0082vD\u00C2\u008F@a|dB~P\u00CBx\u00A9\x12Q\rb\f\x07\u00D5+M\x0BId\u00B4P\u00D2\x07\u00DDfNF\u00A2sJ\u00F1\u00A2\x06\x043\u00B6\x0B\x15,\u00F0\u00E2\u00EA\x11U\t\u008FgH\u00B8\u00EF6\x0EWIb\u00F3[\u00DA!\u00AAJ@B\u00E7\u00F3\u0087zP&\u00A6\u00AA\x11aK\u00D1`4\x03\x04\u00B8\u00EE\u00DA\u00D3\x0E.\x16\u008B\u00E7\u009F\u00FF\u009E\x0Bq'\u00B6;\x15!\\\u00ADW\u009D\u00F53[\u00FF\u00E6\u00D9{\u00E77\u00E3\u0090\\\u00EF\x0E4\x05\u00B0G\x14\u00BB0`\x1D\u0096x3\x13C\x0B\x16s\u00D2\u0083A\x00S\u00B0F\u00B3Q\u0087\u00E7@\u00C4\x12\u00F0\x00\x18ihj1\x06\u0090\x19D-`\u00BA\u00EB\x1C\"t-\u009A\u00E4\x17w-\x02\n\u0096J\x1F\u00FC.44j%F\x1F\u0095\x11T\u00A6+\x19\u0081\x0Fe:x\r\u00B7p\u00F7\u00E5\\\u00F4\u00EF\\\u00CD<\u00C6\u00DE\u00AA\u00FF\u00DD\u0089^\u00F3Nv\u00AC\u0095\u00FB\u00D8\u008C\x06yN\x02_lB#\u00F7S\u0090\u00CC,F@\u00E9\u00E6\u00BF\u00A8\u00AF\u00DD@\nH\u00B1Z\u00B3))\u00C1\u008B\u00FF=\f\u009D \x120\u008FBTb\"qNR\u00AF5\u0098\u009C1\u00A2\x1A\u009D\u00C8\u00FE\u0086\u00F2\u0099\u00CF\u00DB\x1D\u00BD$\u00E7!+\u00A8\u00BE\u00A7@\\\u009A\u0088\u0083\u00E5\u00D32\u00EF\u00C5v\u009B\u00AE\u0088!\u0099W\u00CFk\u00F9\u00BD\u009E\u00A7\u00FE\u00DE\u00D5\u009D\u00DC\u00EA\u00F1\t\f\u0080\u00C2\u00EA5\u0085)\u00D6\u00B9\u00F5\u0093\x03\u00EC(0\x1B\x0F`\u00F3\u00E27>{\u00F3\u00D27\u00BEn\u00E3QO\u00B9\x12wR\u00BB\u00D3\x18\u00C28\u008E\u00F2\u0082\u00AD\u00E7\u00BE\u00E4\u00EF\u00E6\x17\u00AE/\u009AW\u00C4=\u008A~\x14f;\u00B8\tK\u00AC\u0089\u00A1\u0085Z:mA\u00A9\u00EA\u00FFI\u00CD\u0091\x1E\u00FF\u00EA\x04R41\u00F2\\\u00CA\u0080\x01\u00A6&\bf\u0098\u00D3\x06\u00A03LU\x02\u0097\u00D2\u00FE\u00D7\u0089\n\u00C2\u00E8f\u00DC\u009F\x06\u00C0\x0E\u00A0\u00EB\f\u00CD!\u00BF\u00A5d\u009B+R\u00A4\u00EC\u00B1P!\u00AA\u00A6\u00B1\r\x00\u00B4{\u00A4\u009FL\x19\fd\x06\u00ED\x1DQA\u00D9\u00F5\u00DC\u00C8] \u00BBc\u00E0Q\x18\x18\u00EB\u0084\u0096\u00F3}\u00CEr\x0Bu\x12\t\u00E7\u00DE\u00C3\u00BD]\x1AUo&\u0085X\x0B\u00B4\u00C4.z\u00B9\x1A\u00C82\u00EC4\x14\u00BA:@f&\x00\u0098?\x01&$y\u00DF\u00A2\u00CE\u00F3\u009C\x00v \x07\u008E\u0094L\u00B3\u0097\u00CFD\u008D\u00B5\u00B0\x0E\u0099M\x12\u009C\u00B8\u0084\u00AE\u00E6K\u008B\u0094d\u00D7bN\x035\u00C5\u00D3J\u00F4\x17OE\r228\u0092\u00DFc>*c\u00D7r\u00CC\u00D7\u00816\x00\u00BEq\u00AD\u00F2=\x10\tHv\u00ED*\x16Yz\u00DE\u00D7\u00C6\x7F\u00E2\x17>\u00B1~\u00F0m/\x7F\u0089\x1E\u00B8\u00E1{\u00E4\u0084S\u008FN\x02\u00AF\u00B4;\u008D!\\\u00A4o\x7F\u00C6Kq\u00DE\x13\x17mt\u00B9\u00FC\u00A5\u008D\u00EF \u0080[`\u00B5\x15\u00D7\u0094\x1A{\u00A9\x1F\u00A4fN\u00EBPw72\x1B\x12\x1E\u008DH\u00DB\u0082I\u00F3\x063\u00B2)\u00E6P\x190b\x0E\u00C1<\u0082_\f\x11T\u0083VZ\u00E3G'*\u00D1\u00861`,\u00F7[\x10tF.\n3\r\u00FC\u009E\u00DA\u00FC}K\x10p\x1A\u00A4\u009C\u008D\t,\x0BO\u0080\u00DC\u00D8\x05\u00A0e;\u00B6k\u008B\x05V\x10\x01\u00FB\u0093\u00B2\u0088\u00B8\u00B0\u00C85\u00E9\u00EB\u00E7\x16l\n\u00B0\u00A4\u00BDAz\"\u00D2\u00BA\u00E8\u00BC?Z\u00D0\u00C3\r\u00C7G\u0091X\u00E7\x14[\u00CA\u00F8\x01\u00B8\x1F\u009F\u00CC\u00A7\u00C0nk\u00FE\x1C\u0082\x18w\x12>Q\u0090F\u00FF\u00E1\u00C5U\u00B8*\u00A5EpV\x06\u00E8\u00F51z\u009B\u00C2y\u00A2\x0E\u00A5\u0094\u0095\u0098\x16a\u00DDu\u00E5\x1E\x0EH\x06J\u00A6\x14\u00CC\u00C8\x11\u0094(\u00AC\u00DC;%}\u00F7q\regm\u00A2\x1C\u00CDg\u00ED\u0092\u00CC\"\u00F6\u00A8(s>)9\x7F\u00C7\u009A@1\\\u00F2\u00F6'n\u00BE\u00E5%\u00CF\x00p\u00DE\x11]|\u0098v\u00A70\u0084\u00EB\u00FA\x17\u00EF\u00FF\u008B[\u00BF\u00F8\u00C2k\u00D6?\u00F3%\u00B2\u0081l\x02\u00E0V\x00\u00BB\u00B4a\x1D\x1D3\u00A1\u00F4\u00CF\x05\u00D0\u0080\x02%\u0093\x0El\u00BD\x12\u00B8[(\u00B2`\x06\u0088%)\u0089G\u00AAu\u00C9(\u00C4\u00B4t\u00DBw\u0093i)y\u00BB6,\u00C5l\x10<wBX\u00E5\x7F\u0090\x06fDr\u00B9G\t\u00B5B\x18\x1D\u00E2\u00E8\u00B8\u00A1(7\u0091\x19\u00C9\u00B5(a\rG\u00CC@\u00CAP2\t'V\u0095\u00E9y\u00A2\u00C9\u0084\u0094k^b\u009D\u009A\u00CB\u00B1O$}\u00BE\x03\x12~\u00D1\u00F3\u0085\x05N\u00A8'\u00BB\u00E4\u00E5Eua\u00FB\u00F1\u00D8+\u00A1\u00CA9-\u00E7\u00C65\u0096\u00BB\u00B0J\x18\u0081\u00C8\u00E1\u00B1\x0F\u00CC\u00D5\x10^\u00EBs\x13\u00B0\u00BF2P.\b~V'\u00E4)\x1C7\u00F2\x1A\x0B\u00A1[\u00DF\u00A6\u00DA1/\u00A1>\u009F\x1B\u008D\u00B5\x01\u00BAD\u0098H\u00E39\x15\u00901\u0088?\u008D\u00A0\x1C\u008E\x0B\x04H\u00B8\u00CCw\x06\u00EF\u00DD\x1E\u008BP\u00ACm\u00ED\u00C3\u00FE\x0B\u00CF\x7F\u00A1\u00DEt\u00E5\x1B\u00E4\u0094\u00B3\u00F6\u00DC\u00E6\u00E9w\u00A0\u00DD)F\u00C5oy\u00F6\u0099\u00CF\u00FF\u00DD\u00E1\u00F7\u00BEw9l}\u00C9\u00C8\u0080-\u00C2C\x05X\x070\x17/v*40j\u0098\u00F7X-\u00B9z\u00BC\u00F9m\u00C0\x1C\u00A2s\fX\x03d\u008E\x06n\x1C\u00DF\x1C\u00DA'\u00A4\u0096\u00E8\x01.\u00E7\u008D\x014\x1D\u00D0\u00E8\u00BE\u00E39\u008E\x12Z\x04\x10\u00F1~t\u00AF\u00F9\u00B9\u00D2\u00DC\u00D8\u0098\u00D7\x00\u00F4\u00EFs\u00C7\u00E74\u00E0\u0089G\"\u00DA\u00F9\u00C5\u00855qw9k\u009C\u00C4\x01\u00B0\u00FF!\u00C6\b\u00BF?&\u00A8\u00C6\u009E*~W\u00B2\u00B5\u00EA\u00E2\u00F4\u00F1G<\u0085\u00DB;\u00C2\rI#f+\u0092^\x12\u00E6\u0086J\u00E1\u00E8\u00A5DuJ\u00B8M\u0081\u00AA\u00FAX\u00FA\u00B5\x11\x19\u00B8\u00FD:\u00EC\u00DFF5-\u00882\u00E3\x14r\u00B5p(I\u00E0t\u00EBN\u00EC\x0EZ\u00C6\u00AB\u00CEP'(\u00A0el\x02\u00A3;\u00A3w2 )\u00E7\u0093q\u0092)\u00FA\u00C8\u0098\x19\n\u00A4\x1A@\x04\u00E5\u00EFN\u00E2>\u00D8\u00C9\x1Ci\u00A7\u00E9Ts\u00C4\x02\u00A2F\u00AAa\u00A9\u00A2\r_\u00BC\u00FE\u00C4\u00ED}\u00DB\u00EB\u00BF\u00FD\u00D7\u00FF\u00EB\u00CDw\u009C\u00C2\x0E\u00DD\u00DA\u00ED\u009Fr\u00DB\u00ED\x1F\u00F4cg\u009E\u00D7_\u00F9s\u009B\u00B3}w\x1A:\u00A8\u00EDV(n\x05\u00B0\t\u008BM\u00D8V\u008BI\u00E8\u00EA\u00F1\tb\u00DF\u0097\u009A\u00A1\u00CC\u00A33\u0093\x0ES\rF\u00CC\u00B1\u0088X\u0082\u0099\u00C7\x15\u00CC\u00D0\u00A5a\u0094\x01\u00A3\u00D0\u0097M\u00A16\u00B3\u00ECF\u00CF9P\f\u00A6\x16\u0088\u00A9\f\u008C\u0088\u00E4\u00BD\u0098\u00D7`\x7F\u0083\u00E7<\u00D8_\u00C4A\x04\u00E1f\u00AEBz!$\x18R\u00AEl\u0093\u00E4\u0096#\u00C0`&\u00DA\x02<F\u00BF%\u00B2\u0099\u00C61T+\u008AD\u00FF\u00D3\u0080(\x1E/)\u00D8q\x0E\u00CF+}\u00FB\u00EF\u008C\x7FPa\u00EEB\u00BAg%\u009E\u00A7x'\u00D4\u00C7\u00A5\x19\u0097\u00A1\u00931\u00D6\x7F[\u00B9\x7F\u00F9\u00C3\u00CA\u0098\"\x7F\u0083\u00B1\f~\x1F2\u00A9\u00959\u00B0V\u00ECC\u00BAz^\u00AAaL\u00E5\u008E\x1C\b\u00CE\u0081\u00AE\u008E\u00D7\x19\x1B\u0099%\u008FM\u00EC\x04\u009C\x03\u00FB\x0B&Z\u00FB\u00AA\u00DF'\f\x1F\t\x0Fn\u0087\u00B0\x06U\u00E8\u00A5o\u00F9\u00B9\u00F1\u0083\u00AF:\u00F3\u00B6\u00CF\u00BC\u00FD\u00F6%\u00AB\f\u00E7o\u009D\u00FF;\x17\x0E\u00EF\u00993d\u00F8\u00CEl\u009C\u009A\u00BD\x10\x0Bk\u0086o\u00C3\u00A6\u00BEc\u00A2\u00D6\x18\x05C\x10\u00A3\b\x06\x15\u008C\u0098a\u00C0\x1A\u0096\x1E\u0081(\x18\u00B0\u00C4\fC\u0091\u00A0\u00DD=\t\u008CAXj\u0091\u0082\u00FEoS)v\x062\u0082D\n,\u00EF\u00A6\u00E5\u00BB8\u00E1'\u00AA\x00\x02f\u0092\u00F0(\u00F9]\u008F\u00B6\u00A2\u00AE\x02\x0B\x1C2\u0083\\D\u00E0\x11U\x14\x1B\u0082\x04\u00E4,\u00FAz\u00A0\u008D\x0E\x15\u00F7\u008E\u00F8\\M\u00D0\u0084\x12BK\u0098\x16\u00A0\x16\u00FA\u00DD4\u0080\u00AD\u009B\x07\\Jz\u00DC\x07\x04\u00B1\u00FF\u0082\b#L]b\u00D1\u00C5\u00C8\u00EB\u008A\x14\u00A7}C\u00E3\x1B_2\u00E7\u00DC\u009FS,t\u0098u\u00AD\u00C2\u00D7F{\u00C0\x04\u00EE\u00FB=z\u0095\u00DE\u008A\u00CC6\u00F4\u00CF>'\u00A0F\x11\u0092\u00BD\u0095k\x1C]u@\u00B1\u008D\u009D\x16\u0095\u0096\u00D7\x07\u00E2\u00A8\u00CFE$\u00E2\u0089W\x05E\u00D8\u0089\u0082pG\u00A2\u00C3\x18E\u00A5x\u00CF\u00A0\u008C\u00F1W\x1BFm\u0087\u00A6\u00B1\u00B5\u00EB?3?\u00F87o\u00F8\x1D\x00?x\u00C8\x13\u00EE`\u00FB\u0092\x10\u00C2\x07\u00FB\u00A5g\u009F\u0087\u00F3\u009E\u009C\u00BBW\u00DC\u00B9\u008D\x12\x7FS\u0080/B\u00B1\t`\u00A1\u008A\u0085\u00A2dC\u00AA\u00A3\x03\u008FPT\u00C5(\x03\x14\x1B\u00E8X\u00F3D#\u00F3&\u008ChX\u00AAI\u00F1\u00AE\u00CD\u00AB\u00E6\u0099d_\u00C2\u00D1\x02f\u00FEo\u00C3\x12\u009Em\t\u00BE*\u0093\u00D8d\n\u00E9\x04#q\u00D2n\u00D1\u00CAw\u00B8\x141cf\u0084\x15O$\u00B3\u00C3u\f\u00E1\u00E2\u00D4\bw\u0096\u008C\x1Ad\u00B90\x15\u0087\u009C\x02f\u00E0e\u00B5&\x01\u00EB34\u0088\u00BB[%$9\x17\u00AC6\u0097\u00F4T\u00BE\u00C2x\u00C9\u00F0\u00EC6E1B\u00D5\b\u00B6!\u00AB\x0B\u00C3\u00E6cD\u0093\u00AC\u00A9\u00E2F\u00B6\u0088\u00D6\x14\u00AA?\u00B0g\u00F2{(w\u00DE\u0085\u00C0jQ\x02\u00DC\u00B7\u00A2\u0081\u0090\u00DC\u00A0}\u0087\u00A1\x11{n\x1F\x0B\x03\u0083\u009A#\u009BT\"\u008Da\x07\u0083*\u00E3\u00C1`\u00E5\u00DA|\u00AE\x12\u00AD\u00C0\u00BC\"\u0082xV\u00DA\u00A8\u00A6.a\u00F6O\u0081\u0091q*LG\u00B7\u00E7\u00E1x\u00D8\nbp\u00C4\u00A1b\x1E.D\u0086)\u00EDSE\u0088\x04_\u00A2\r\u00C4\u009F\u00A7\u00B9\u00DD\u00A4\x03\u00E8&\u00DA\u00E4\u00D2\u00BF}\u00F2\u00D6\u009B\u00FF\u00E8\u00EC;H^\u0087lG\u008D\x10\x0E\u008E\x07\u00E4\u00B9[\u00BF\u00F5\u0082O\u00CC>j\x05*\nG\u00BD3\x1B\u00F9\u00E1>(\u00F6B\u00AC\u00AA\u00A1\u00B8\u009C\u008C\u00C9O\u00AE\u00D9\u009D\x19\u00A8\u00AC{\u00AC@\u00C2\u00CC\x0E\u009B\u00F8\u00CE\u0097\u0080\x06`\u00869\u00A6)\u00CAF\u0090N\u00ECB\u009Em\x0B!\u00CBm\u00B0z\x12\x1Cm\u00D0\x1A\u00C1\rh\u00D3(\u00D9\u009D<c\u008E\u00DC\x1D\u00A9\x13\u0088h\x12\u00DDBw\u00B12\u009F\u00BE\x18\x05\u0098d;\u00D6\u00B8\x02\nD\u00B1\u0085\x12\u00F1\u00F9P\u00E4vq\u00D4\u00975\u00AE\u00B5\u00FA\u0086\u009Cg\u00FF$(\u00E7\u00DAYI\u00AC\u00BD\u00E8\u00F7\u00C5\x10\u00A6\u00D9\u008B\u00DDXR\u00DF\x16 \u00B6z\u00AB\u0083\u00D3\x01\u00AA\u00CC\u0098\u00D4r\r\u00AF\u00BF\r\u00C4\x19\x1E\u0099\u009A\u00EC.ak\u00C8\u00AAH%N\u0081\tv%\u00EE\u0080\u0086X\u0080\u0092\x1Fn\u00D4\u00E5\u00A4\u00F2\u00F9\u0090\u00F3=\x19W\u00DA\x14\x18\u00BC\u0094\b\u00AC\u00B8E\u00A5\u00CCQE\r\u0081\u00FA,z\u00C6\u00FA`\u00CE\u00F9r\u00BA\fx\x19\u00F8\u00BA\u00D3\u0088\u00A9\x006n\u00BD\t\x07.\u00FC\u00CB\x17\u00E8\u00BE\u00EB\u00BECN|\u00D0Q\u00C1\u00F5\u00A3f\b\u00EF\u00D3\u00CB\x7F\u00F8\u00D5\u00F2\u00BAG/fGu\u00DF#j\u00ACy\u00FBE\u00B5\u0092k.K1Sc\x0E#hS\x104]\u00C7\fs\u00ABQ\u0080\u00E6q\x063\u00E4\u009E\t\x06\u00D3US\u00BFVm\x18\x1B\u00F3\u00E5\u0093\u00C97'\u00F4\u0091\u00FA\u00B9KK\x0Bc\u00B5\u0085>\x03C\u00A5\bBSG\x16g4\r4P\x02\u00DC\x1E\x1E\u0080I\u00E1\u00CE\u0085H)\u009C\x069\u00B35y\u00AD(\u00C9\u00FEke\u009F\u00EE\u00C93\u00A2\u00CD%\u00AE\u00C4\u009A3)J\x15\u00C5I\u00A6y\x1C\x02\x17Z\u00B7\u00E3\u00DD-i\x1D\u00E2^\u008D\x18\u0086\u00AF\u00E3\x1EFK\u00B0\u00B2\u00B2G7\u009AV\u00A3\x163\u0081\u00B2\u0086=\x07\u00A1\u0086\u00E0\u008Ad\u0081\x1CSm\x1AI\u00D9\x18E\x17Xm\u0087\f&\x120%\u00D9\u00C3\u009F#\x18\u00AA\u00C2n\u00EF3\u00EEns\u00C1\u00CA\u00CA*K \b\x1D\u00A0\u0092F:\u00CFRh\u00DE\x07\x03\u00A6\u009C\u0099\u0091\x17\u0084\x17\u00C1\u00A3E3\u00A2\u0081\f\u00D7\u0082\u00E8\u00C9\u00BC\u00CD9>B=5]\u00F8n'\u00A8\u00C3\u0099e\u00A8\"\u00FC\u00CC\u00E7+\u00AA\u0085\u00BFwn\u00C2\u00CB\u00B9#\x0F\u009F}\u00E8\u009D\u008F\u00DE|\u00DB\x1F\u00FD0\u0080\u00BF\u00C0Q\u00B4\u00A3R\x19\u00B6t\u00FF\u00F0\u00DA\u00C5\u00AB\u009E\u00FB\u0099\u00B5O\u0082\u00E9C\u0099Nt\u00D7\u00B5-\u00B1\nK\u009B\"\u00D8tMo\u00E9\u008C`[\x1A\x16\u00B2fFDI5`!\x16\u0094\u00B4\u0080`)\u00E2\u00C7\u00868Gai\u00CE\x195oU\u0091\u00BA\x0E\x18\u00B5E\u00D2\x13\u00D0\u00D0\u00B5\u00A1\u00AB\x17\x19\u00E1y@\u00E6=\u00A8\u00B8\x1Ab\x7F\u00A32\u00B8)\u00D5\u0089\f\u009Dr\u00C4\u00D0\f\u00B5\u00D0gR\"-\x10!\u00C4\u00C5\u0086\u0091(\x03\u00F9\u00BB\x1B\x1D\u0099xcp\u00D9\u00D5\x00I\u0088*Q\u00C4\u0083Q\x1D\u00EC\u00CEJ\u008F%\u00C6)\u0085[\u00985\u00D8\u00A8>P\x1D\u00A9R\u00D4\u00FF\u00FC|\u00A5\u00AD$\x1A\u00D5\x02S-x?\u0086\u00A5\u00F3\u0098\u00F8^\x16i\x0Ba\x02\u0092\u0087\u0093s_L^\x13\u00A1\u00DA\u0086\u00DC\u00C2\u00A8\u00E9\u0089E5iI&\x04\u0098\u00FFf9\u00BCz\x7F2f\u009E7\u00E4\u00BB\u00E0\u00EFJ^\u00C4\u00F7\u00C5\u00C7\u00F4\u00F7\u00C1\u0094xJpE2\u00E7\u0089\u00D4\u00F7\u00FB3\u0097#\f\u00B1+\x06O\u00E5\u00F6w\u00AE*Z\u00AF`\f\x07\u00C3\u00BB\u00D6\u00B6\x0E\u00A0\u00BF\u00FBo\u009F\u00AB{\u00AE=*\x0F\u00E2Q!\u0084\u008B\u0097\u0097<\u00ED|\u00FD\u008Bo\u00F6G=\u009A.\u008E\u00BA\u00ED\u0085b\u00B7\u0096\u00DC1q\t\u00ACs,\u00B1\u0086\x19\u00E6X\u00AAW\u00E8\u00C1\f\x03f\x18\u00A9\u0097\u00AAy\x00\u00A8\u00C7\x0BfX\u00C0\u00CB\u00A3\u00A9\u00EB\u00B5B\u00C8_\u0089\u00D9\u00EC\x0BT\x03h-\u00CE\u00CC\u00C9d\x02\u00AA\u00D6\u0087*U\x10[l#\u00A6.Q\u0084\u00A4\u00A1^\u00AF\u00C8\x1C\u0087\x1E\u0092H\u0084\u008B5-\u00D8*\u00C4\x14\u00B9\u00A0\x01\u00F8\ne\u00BCCK\u00D5W\u00E9\u00EB&a\x02\u00DA\u00E7\u0081dW\u00DF\u00A1]\u00E7\x12H\x11\u0084\u00CB\x05\u00E9g\u00D9\u00FF]\u00C2\u00C7\u00BD\u00BA\u00DF\u00A7\u00BB\u00C2TC\x1EaRXH\u00CC\u00A1\u00AC\u00B4<\x17\u00FC\u009DF\u00BB\u0094\u00C1\u00C4R\u00A6n1\u00B88\u008Dyv\u00FD8\u0091K\x19\u00FCS=\x00<\u00CFK\u00AE\x03\u00A6b\u00B0\u00A8\u00CC$\u009C\u0098\u0090\u00DF\u00DF\u0099\b \u00A3\u00DB\"+\u00E2(\u00A8\u00CB\u00E3\x13\u00D2\u0080\u00E8\u00EF\x03\x00d,9\x14n\x00\u00AE\u008C\u00BE\u00C4P\u00A8_?\u00D9\u0087\u00C2_M<#U\x11g>\u0082\u0086\u00F9\x15\u0097|\u00F3\u00D6\u00DF\u009E\u00F74\x00\x7F\u0086#lG\u00CC\x10Tu\u00F8\u00D9\u0083?\u00FB\u009C\u00EB7\u00AEu\x18tH5\u00E7.i\n\u00DB\u00A5\u00E9F\u00B0(+\u00A3\x18\x07\fXC\u00935\u00CCt\x0E\x11&'\u00CD0b\u0086&&\u00D1Fa\u00DC\u0080y\x00F\u00D0\u00AFN\x1F\u00FEDi\x00`\x1E\x0B\x11[z45\u00D1\x7F^\u00D1\u00C1\b7zQ\u00AATKsi#\u00EF\u00D7`\u00BEeg\n\u00E1U\u00D8\x01\u00DA$\x18\x15\x02\u0086*\u009A[\u00F0\u0094\x12<\x16\x14U\"\u00E4o\x023B1b\u00AF\x19\u00B3b\u00982O\u00C9O$\x07z\x16\u00C8P\x00\u0090qu~v5@5rv\u0092\u00D1\u0095\u00A8\u00C3\u00B8~\x063B\x1B4\u00AE~\u0087\u00D8iZ\x19\u00AF\u0090\u00CCJ\u0099\x02\u00DD\u00FD\u00DF\u00D8\u009B\u00D1G-\u0095\u00C1\u0098\u00AD\u00C0\u00C2\u008E\r-51U'\u008B\u00A0:\u00E3\u00B5\u00CEB\u00FD\tB\rX\u00CF\u00C2|~\u008C\u0084\u00A7\fX\"\u00D3HT\u00A4|n\u00C9\u00FB\u0090)\u0088o\u00FAjU\u0092\u00B8;\x15\u00D5\u00A0\u00CA8\u00874\u008D\u00F5\u00C1\x18\u00EC\u00A4\u0080\u00AD\u008F\u00A8\u00DA,\u00BA1\u00B3\u00F9\u00D6\u00AD8\u00F8\u008E\x0B\u009E\u00A3\u00DB7\u00BEF\u00D6\x1ExD\x1B\u00BD\x1C1Cx\u00DB\u00F2\u00A2\x1Fy\x03\u00DEpV/n\u0097\u00BB\u00BBmA\u00B0G\u00D4\x03\u0096\u00B2\u00CAQ\u00D3\x01s\u00CF#\u0098\u00C1\u00CA\u009C\u008D\n/\\\".\u00F7\u00FD|e\u0088q\x03\u00D3\u0091\b\u00EBI\u009C\u00DDa\"\x11C/\x7F\u00B4*\u00AB\u00AB\x12Le\u00EEE\u00D7\x0F\x1D\x15\u00A9Tqy4\u0080\u00C2\u00DA\u009B\u00BB\u00ABVtT.\u008E\tq3\\9\"\x1A+|\u00AF\f\u00C5\u00DF\u008E\u00D6s)I\u009Cx\x18z\\\u0089\x19(v\u00DA\u00B0F\u00F8\u0093d\u00B7\u00F1\u00C5C\t[q\u00EDY3\u00A2\x11.\u00F6\u00C8\n\u0094\t\u00AA\u0091\u00B8\x7FYM\u00D2\u009Cq\u0090\u00E0Sb&\u00FB\u00E2x\x14\x19i\u00C99\u00F0-\u00E0\u00E8^-Oa\u00FD\u00F9y\u00B1\u00E9m+D\u00C9q4\u00C4N\u00CF1A\u00EE2\u008C\u0099R\u00D8\u0096\u00F1d\u00C8\u00EA\u00F3\u00CBq8\u00EAP\u00B1\u00F3\u00C2>\u00C0s<\u00E9I\u00C9D\x15i\u00F4\u00E4\u00A9\u00E5])\x19d\u00FE\f\u00AA\x12Dm\x00p\u00E5\u00FB\u00CF\u00DA\u00FC\u00AB?\u00FE\x11\x00\u00AF\u00C5\x11\u00B4#b\b\u00B7\u00EA\u00A6\u00FC\u00D2\u00E6\u00AF\u00FD\u00DA\u00B5\u00EB\u00D7q\u00CAA\x18ww5\u00F5\u00FB\u00EE\u0085`C\x05\x1BX\u00C3\u00809\u00E6\u0098a\x01\u00C16\x18\x13g:\u00F3\u00E8\u008C\u00C2T\x06\u008F\x13\x103\u00D4u\u00D0v\u0090\u00CC\u0080\fB\u00C5\\\x7FZ\u00CEcP\r=\n\u00C6\f\\\u00CE021\x10\u0085\u00DB\x1E\u0094\u00B5\x18m\u00C1\u00D8\u00B5\u008C5pfA\u00D7\u00A0/\u00A4\u0088\u00D8\u00A3\u00F4p\u00C6\u00A4Z\u00B2\u008Cb<izk\\\u00E4\u00B1\u0080\u00AB\u00C4\u00A1k\rf\u00A8\u00F4Eg\u00C2%\u00D3\u0095c\u0092)\u00D0\u00F3c\u00F9\u00C4\u00B0j\u0085p\u00FF\u00C4\x02\u0084\x18\x1A\u00ADN\u00C4y\u00CC\x19B-G\u00C4\u00BD\x16\u00E3\u0086\x03\"\u009BR\u00B8\x1D\u00BC\u00C6b\u00CF\u00C1\f\u00C8\u00A2\x02\u00F4| \x18\u008D\u00D0c!\u0085q\u0088\x13\u00BD{J\u008CQ\x15C\u00A2\x1FWe\u009C\u00AC1\u00AExVN\b\u00FC\x19B\u00FD\u00D0\x1CK\u00BC\x1FH\u00CF|h\x00\x00 \x00IDAT2)\x7F\x7F\x1C<\u00BD\b\u00BC'g\u00D9kn\u00E6\x032\u00E4\u00DC\u00FB\x0EF?\u00B5\u00D5I\u00E9)z\x14`}q\x10\u00FB\u00DF\u00FD\u00E6_\u00D3\u00CD[\u00FE\\6\x1Ep\u0087I\u00F4\u0088\x18\u00C2\u00C7\u00FA'\x7F\u00E0\u00AF\u00DB_=bl\f\u00C79vm\u0084`\x0F\x04\u00BB\u00C4\u00EA\x1C\u00CE0\u0083e32'\u00C1\fg\u00AD\x18\u00EBf\x10c\x10\u00C8=\x16\u00AC@\u00AB1\u0091\x11\u00E9\x11\u00C8\u00FA\x04<f\u009F\u00C7X\u00E0R\x00/\u00E2Md\u00C0\u00921\u00A4\u00D0\u00FF\x1D9\u00B0\u00CA\u00D3\f\u0082\u0081Y\u008F\u00D5_\u00AE\u00E2{\x01\u00B4\u0082\x10\\\u00AD\u00E0\u00FD\x1A\u00DC5V\u00AC\u00FC(\u008CB\u0090P\x14\u00F9\u009B\u00AAB:\u00DD\u0096\x1A\u00BF\x1B:\u00F1\x05\u00C8 \x1F\u00C2__\u00BC\x11\u00DE\u00CFE/.\u00F5\u008A\u00CBW\u00D1\u0080\u00D6c\x1Cy<%\\\u00F0\u0083\u00C2{\u00F2\u00FA\u00CA\u00EC\u0090D\u00EEscS(\u00C9T\u00C4\u00C4Q\u00E8\u00E4\u00A1V\u00A1\u00F4SB\u0096i\u0083\u00C12\u0099\x02\x00f\x1F\x16\u00A3K\x19\u00D8*j`\u00BF\u00C5\u00E5\n\u00F3\x10\u00E5\u00FE\u008E\u0095<\u00CBg\u00AA\x0F\x15!\u00C5\u00F7\u00BE\u00D2o\u00B9'\u00DD\u00B5\u00DEO0\u00DA\u0095Qq\u00B8\u00CCg\u0099\x7F\u00E4\u0092Gl\u00BE\u00F5U?\x00\u00E0\u00AFWO;\\;\"\u0086\u00F0\u00EA\u00CD\u00D7\u00FE\u00D2\x17v}z\x02\u00BD\u008E]k8 k\u00D8\u00A3s\u00CCd\u00869\x1A\u00E6\x180s\u00A8O/\u00C2\u00A8\x1E\x13\u00E0\u00DF\u00850^\u008C`\u00C3=\t\x16S\u00B5z\u00CC3\u00A4=\u00A0*\x1C\u00F4H\u0088\u0087(CX\u008E\u00ADM\x18\u0087@0J\u0095\u00E3l\u00CC\u00A5\u00ABe\u00C1\u00EDy\u00F2\u00AF\u00C0X\u00BF\u0086\u00E7\b\u00A6n\u00CEC.< \u0098\u00CB\u00E4\u00FA\u00D2'\u00A5\x1E\u00C7\x1A;9\u00C5@\u009D\u0089q\x0B5Bog&\u00C9\x07\u008A\u008A\"\x15\x0Ep1S\x15J\u00C8\x1D\u00DF\x05\u0098\u00D6\x13 %\u0093\u00C0c\u00A0S\u00E6P\u00FA\u00B1\u00CAHb\x04\u00C9\u00B4n2\u008D\u0089\u00C4\u00ADh\u0096(\u00CA\\\u008F\x10xl\x1D\u00E7\u00A3>W%\u00E0\u00AA\u0096\bl\u00AD\u00AC\x14\x0FV\x1ASW\u0086\u008BJ\u00F0\u00E5\u0084>\u0094gc\u00FF3djt\u00B9\x07U\x03E\u00B9o\u00B6:C\r\u0082\u00F5\u00AD\u00FD\u00B8\u00F5\u00A2\u00F3\x7F\tG\u00C0\x10\u00EE\u00B0\u00DB\u00F1\u00E3\u00FD\u00EAG\u00BEux\u00D3\u00D9KYB\u00CB\u00FF\u008EE3\x0B\u00FE\x00\u00C5:\u00F6\u00A0a?f8\u0088\x01\u00DB\x10l\u00A3a[\x1A\u00B6\x01l\x01\u00D8\u0086E$.\x01l\x0B\u00F7o\u00F0hEa\u00F8\u00B2\u00FD\u00D1\u009E\u00ABJ\u0097\u00A2\u00AB\x12d2\u00A8\u00C1K\u00B5fB\u008D^l\u0081:\u00F2x+\u00E7\x0F\x18\u00DD\u00DB\x11\x05R\"\u00B1I\\j\t\u00D0\u009C i0\u00EC\u00EE\u0092r\x03\u00A9%\u00FA\t\u00CCHg.B\u00EE\r\u00D1\u0099\u00F3\u00D0\u00FC\u00CFU\x17\t\u00B7\u00A0\u00F5),\x0E\x02\t\u00F7&\u00C2\u00AB\u00A7N\u0093\x19\u0089g\x11\u0084\u008C\u00A9\u00F0\u00F14\u00AB\u00C0\u00C4\u00F8\nV\u0084b\u00A2T\u00BAS\x19\u0088\u00D5\u00C2\u00E8\u00CB\u00F8~i\rh\x12\x02^buq\u00FC\u00C0D\u00AD a\u0085\u00EE\u00EF\x7F\u00F1y\u00C8\u00F9\u00EC\x00m.dzT\u00EF\x10\u00EB\u00C8\u009F\u0085\u00E4P\\\u0083\fI'z\u008A\u00F8\x01\u0097\u00DA\x1A\u00E7\x0Bv\u00D6\u0093l\u00D8\u00C1\u0094\u00E3\u00B3\u00C4\u00DC\x07\x02,\x11\u00A8\u00F9\"xIA\u008C\u008C\u008E\u00E4\u00B9\u00EA\u00E3\u00AA\u0081Sn\u00BC\x1C>|\u00F9\u00D9\u00E3\u00BB^}\u0087\u00EB/\u00DEa\u0084\u00F0\u009A\u0083\u00AF{\u00D6G\u00D6?\u00E4\u0093w\u00D7\u0084*\u00DF\u00B1F\u00AEi\x05D\u00972\u00C7\x1E\x15l`\u00C0L\u00E6\u00B0\u00C0\u00A1\x19\x06\x190x\u00CA\u00F2\u00B6\u00FB\u00B3\x1B\x06,]\u00CF\x1EP\u008D\u0084%\u00B6\u00C0\u0089\x19\x11b\u00EC/\u00CB?\u00B7\u00A4\u0098\u00F2?#\x06\u00BB\u00D6j9u4,]M\u00D1bl\x14HT\u008B\u00EER\u00FAP&\u00D3\u00F8\u00BD\u00B9(\x14\u00BE\u00D8J\x04\u00A2\u0087\u00AE\u00DA\x16WC\u00AA\u00B3\u00CD\u00B3\x02C\u00FAJ\\_\u00AB;\u00D9\u00FE\u00D9U\x1E\u00DAB\u00CA\u00FD\x1E\u00FDwJ\u00FBf\u00C4\u00A4]3.H\u00D2\u00A1G_\u00F8\u00A1\u00E5\u0083\u0093\u00B8 \u00A1~Qv\x15\u00D5\u0080\u00D6\fvG\u00BEB\u00CFc\u0085\b\x01@\x19\u00A4t8\u0099\u00E4\u00E1\u00DE\fr\u009A\")\x1F\u00B5\u00D8;\u00B0@\u00DB\x15[\x06\u00EF)\u00E4'R\x0EW\x14\u00B4\u0082\u00CC\u0082\u00C9{\u00B5\u00A4\u0089)\u00B9\u008Ew\u008Ax\u00D4\x03\u00CCRm\u00C9\u00B9\u00CBHF\u00AEI\x18\u00BA\u00D1j[\u00C8!e\u00AE\x06\u00B0~\u00CB\r\u00D8\u00F7?\u00DF\u00F4,\x00?y\u0098\u0099\u009A\u00B4;\u0084\x10>\u00A7\u009F9\u00F5\u00A2\u00E1\u00A2\u00A7\u00F5\u00B6<D\u00B2\u00C5\u00DD\u00DD\x1A,P\u00C5j()\x1A\u00F6\u00A3a\x0F\x06\x1CD\u00C3\u00A64l\u00A2a\x1B\rK\u0098\u0091q[\x04\x0B4,\u00D0\u00B0\u00D4!*7/a;D-1\u00D81\u00FF\x1Ba\u009E\u0083Q%\u00BE\u00DB\x06\u00B3\u00E2N(\x1A!3\x16>\u00AB0\u00F38\x02Ce\\\u0082\u00EC@\x12,\u00E3\u0082\u00F8\f3 \u008A@=?\u00A03\u00AB\u0090\x01+2\x00\u00ADAZ#]\u00D9\u00F9\u00B1x\x1A,\x04\u009A\u00EAAap\u00DE\x17\x19]\u0081\x04N\u009C)\u00BD#8F\u009A#\x11{F\"+\u008D\u00BE\u00AC\u00D8LV\u008F\u00AE\u00FD\x16U\u00A8d;\u00C6_0\u00AB\x1A4\u00C51\u0094\u00B1\u00C0\u0088\u009B\u00D7\u00B115|zO\u009F\u0094*\u00A9\u00CBsR\u00C5\u00D06C\u00A8\x07\u00BC>\u00E2=*\u00E3\u00F79.\u00EF{\u0095\u00A0\x03\u00ADL\u00A4\u00BB\u008F!\u00CA\u00B4U\x02'\x1AA9\u00B7\u00F1e\u0096\u00E7\u00A9\u0081JD\x00\u00F5y\x15\u0099FM\x04\u0091c\x12\fh\u009F\u00FC\u00C0\u00D3\u00F4\u00AA\u00CBO\u00C5\x1Dhw\b!\u00FC\u00ED\u00F6\u00C5?ua{\u00D7F\u0096!96\u00CD\u008Cj\x1E=\u00C7\x04\x19X\u00C5\"C\t\u00CD}\x0E\x19\u00C1\u00D8\\j\u00E7&.$\u00CC\u00C1\u00A59\u008D\u0089\bb\u00A6\rB\u00D4\u00E0q]\b\u00A6B\b\u0096\x0E\u00E1\u00E8A\x10 \f\u008E)u\x1D\x11\u00B8[\x12\n4\u0087\u00EC\u00A3/\u009C\u00EER\u00D8\x02\u00AC\u009C0Cof\u008C\u0081C\u00C4\u0080\u00A5\u00BE\t\u008D\u00B2\u00EC\x1A\r\u00A1@\u00C1\u00DD\u00DE\u0097\u00BA\u00F7.%\u008F\u00C8\u00E0k\u0089\x12\u00DB\u00A0u\u00F3\u00EB\x1DX\x17\u00C9\u00ED\u00A8#\x10\u0093\u00AD\u0082Fh\x1A\x02\u00D8-\u00FF\u00F5\u009D\u00B5\u009Ee\u00D1\u00C4;\u008B\u00BF\x0E\u00D1\u00B9I\u00BBncQ\u00D7\u00FFm\u00F8\r\u00DA\u00DDU\u00E7\u00AB^\u00D0l3Z\x12\x1F\u0091\x07\u00FC\u00DF \u008AUi\u00EF\u00CF\u00AD<\u00DF\u00F2\x1D\u00C2\u00DB\x02\u0084qR\u00DD0\u0087.\u00E6\u00FB\u00F7\u00AEl\u0095\u008C\u00D0\u0088_h\u0085\x10]4\u00A3\u00C16m\u00B1\u00F1\u0087]#\b\u00DE\u00CFS\x18Qw\u00D8<0N\u0082\u00E7\u00F0\u009A\u00E2\x16\x15\u00F5\u00FE\u00B8\u00DB\x16\u008D\u00C0\u00BD\u00C73\x11aj\x17HW\u00B4q\u0081\u00F5O\x7Flc\u00FF\u009B\u00FE\u00F8\u00A7\x00\u00BC\u00E00\u00A4\x15\u00EDv\x19\u00C2\u00D6\u00F2@\u00FB\u00D7\u008B_\u00F8\u00E9\u00AD\u00B5\u00BDH\x7F\u00F7\u00B1jU\u0082\f\u0093\u00BFmi\u00B8Q\x15\u00EB\u00DA0\u0097\u0086-\u00D7y)M\u00A2\u00DC\u0089\x13\u00961\u008A\x04\u00D1\u0091\u0081H\u00E2\u00F2\u00F3\u00A8\x0E\u00D4\u00C2 \u00EA\u00C46\u0080\u00B6\x06\x7F\tN\u00B0\n\u00EE\x1C\u00E8\u0088@H\x10\u008C9K)\u0093\u009E\x02\u00C5\x10\u009B\u00C6\x12\u0099\u00B2\x10k\x03\x03\u009D\u00D2Ah\u008B\u009D\u00C7\x03\u00E2\u00FB\u00FAa\u0090S\b\u00A0p\x11\u00B8z\x000\x04\x01\u0088s\x10\u00C7\x11gec\u00E4\u00BCS\x07b\u00B7e\u00EA2A\x1C@\u00D8\u0097\x18OP\x02\u009BHaY-\u00C8]\u0080\x11}\u00C8-\u00D58\x1E#B\u00EB;\x0B\u00BA\u00A0\u00E4E\x04\u00C3!\u008C.\x1B\u00D1N\x1F'\x1F:B\u00A4\u00C3\u00E0gk,\\\u0084\u0084\u00FB\u00CED\u00ECJF \u00FA\\2\u00DD\\\u00BB\x07Ka\u00F2{DG\x06\u00AA\u00F1\u00BE\u00AB1\u0095\u00EE\u00CBp3R-(\u0088F+\u00B3@\u009E\x17\u00C6S\u00FF\u008Dh!fE1h\x07>|\u00E9O\u00EB\u00DE/\u00BEH\u00EEw\u00F2m\u00EA\u00FB\u00B7\u00CB\x10\u00AE\x18>\u00F1\u00A4\u00BF[\u00BC\u00F5\u00F4\u00DE\x00\u00A0\u00EF\u0098\u00E3\u00BB\u00AFQ:\u00CE\x01\u009D\u0081\u00A9\u00BB\u00B99\u00EA\f\x0B\x01n\x15\u00B3.\x18A\x0E\u0098\x17\u0083\u00E0\u0082\u0084\u00AA\x1E\u00B4\u00E4}2\u008Dut\u00A2[B\u00C0-\u00E0\x1A\u00EAn\u00D3\u00FE\u00AA\u00D4<\b\u00CB\u0088\x104\u00F7\u00E6\x00\x17dRC\u00953\x17\"\u00D3PZ\b7[BL[\u00CE\u00BA\u00C7\x11\u00B5X\x16\x14mF\u00CCW0\u00B4Rc\b\u00A8\x1Ad\x16\u009F\u00F9\u00D4\u009B\u00AB\u00A1I$<>\r \x00i}:\u00EFQ\u00E3P\u00DD\u0080\u00EF\u0096tqw%\u00D1\u0086\u00EAd\u00B9F?\u00E2\x01J<&d-\n\x0B\u0097\u00E4\u00D8\u008C\u00E0+\u00E1\u009A\u00FA\u00E4\u00DE\x00h\u00CE\x0BLR\u00AA\u00BB\x1Fm\u0088C\u00DC\u00DD\u00EE\u00C5 \u00A2\u008E\u00F0\u00FD\x0B\u0090\u00AEK\u00B7~T\u00C3\u00DF!9e\x12\u00A5\u00ACfY2\"\u00B1\u00AF\u009C\x1B\u00AB\u00A5\u00A0\x178\u0093\u0088w\u00CE\u00E1\u0092q\x14\u0084\x03gT\u0093\u00EFd4dF<V]\u00AB|\x17\x1C\u008F\u00A1\u00BB\u00E1\u00C3\x1F<}\u00EB\u009D\u00E7?\t\u00C0[q\x1B\u00EDv\x19\u00C2_\x1D\u00B8\u00E0\u00DC\u00CF\u00AD\x7F\n\u00C7\u00CA\u00A3\u0090-\u00E3\x0B&\u00BB(\x17i\u00DB!\u00B8\x19\u008A\u00B96\u00CC\u00BC\u00E8\x063\u00D7\x07\x15\f\u00D2\u00B0\u00D4\u00C8\u0096\u008FpUb\x00\x06+\u008D\u0092\u00B6\u00F4\u008E\x16D\x1D\u00DF\u0085F\u00C3|\u00F9\u00E6\u00AC\u00E4&\u00B0\fE1o\u0086p\u00FB\u00B5\u00E6\u00EA\u00853\u008D\x0E&#Y7m\u00B2\u00A0\x04f\u0085\x07ha6!\u00CB@\x19;G\u00DD\x00\u0099\u00B1\u00F3\u00D6\u0099]\u00A7\x11Al\u008Bgp:3\u00A6\u0091&\u00A96]\u00C7\u0094\u0080nL\x14\x1D\u009C\u00E2\u00B8\u00D0lQ\u00A6+\u00D1\u00CEW\x12\u00B8z\u00BF\u00CCk\u00F0p\u00E90\x12v\u0089\u00F8 \u00BB\u00B4\u0085!\u00CC\x1Em4\x03\u00A7\u00C0\r\u009D\u0083=\u00B5\u00AA1\u008E\b\x02\u0082\u00ABt\f\u00A1\u0097\u0082\x12lL\u0089\u00A5\u00EA\u00D4:\x1AQ\u00CFbd9\u00F8|\x14\u00FE'\u0099\u00F8\u00A4\u0093\x16\u00CFaII\u00EA|\u0095\u00BFs\u00D2\u00F3\u00A6\u0096\u00DA>\u00C6\x1C\n\t\u009EHG\u0099\u00B3A\u00A9\u00AFN\u00E3\u00BD\u0080\u00AA\u00D5~\u00BD\u00BE$#\x1C+\u008D\u00BA\u00AA\u00C8\u009A\u00A3\u00EB\u00CB\u00FD\u00B8\u00E5\u00C27\u009D\u008B/\u0085!\\\u00A3\u00D7\u009Dt\u00EE\u00E6\u00B9O\u00EDm5\u0093\u00F1\u00EEW\x1C\x04\u00BE=\x19\u00B7>\u008F\u00B7\u009B\u00C6 \u0095\u0086\x05\x06|\x11\x03v\u00A1\u0099r!3\u00CB\u00CD\u00F3\u00AAI\u0083\u00DB\x06b\x03\x14\"\x044\u00B0\u00B8i\x0B\u0084\u0090\x0E\u00B6\u00E0\u00C3*\u008E$\u00CC\u00E0\u00A3j/\u00BBF;\u00DA\u00B9C \x03\u00AB\u00C8l\u00E3\u00ED\u00A0{\u008D9\x11\u0088gY\u00F2\u00EEb(fbd\u00E2i\u00A17\x0B&\x1B\u00BF\u0086[\u008D~\u00F4B\u00E1d\x1E\r\u0099\x0B\x00\u0097\u00AE\x15\u0089D\u00D3\u0089\n\x10\u00D6mF\u00FD)-\u00FCIx\u00B9:8>\u00EFg\u00D2\u00AF\x13\x06\u00C7O\u00A9\x06M\u00A9\x1D\x1D\u00D5<\x01B\u00EC\u00ACM\u00C0\u00E4&S\u0097\u00B4\u009C\u00EB\u00F7Q\x14\u0086UU\u00AD\u00D2\u00BF\x02\u00CAd#\x12\u00DFd\u00D1\u0089?\x7FM\u00BEb\u00AA\u00B2\u00A3\u0096\n\u00D7\x0F\x19qE\"g\u00FF2\u00F9=\n\u00B8\x06\u00A6j\u00E5x\u0099\u00A7\u00C9q&b9\u00E3\b\u00F5&\u0091\u008D\"U\x07\u00AA8kW\x7F\u00F8\u00A9\u00FA\u00F9\u008F\u009D$_\u00F5\u008D7\u00E30\u00ED6\x19\u00C2\u00FF\u00DA\u00BE\u00E2G\u00DF\u0087\u00F7l\u0088\u00CE\x00\u00B9Sw\u008C:\u00C2f\x15\u008F\u00B8\x11+K\u00A21;P\u0095\u00B6\x02\u00B3\u00E8n\u008Ab\u008F6\u00AC\u00C9\u00CC\u00E2\x15\x15\x18$}\x01\x10\u00B5]\u00A0}\u00F1\u00B2@\u00C6L@\u00EC\x00q\u00D4\u00D0a\x1E\x07\x06%\u008D\u0092R\u00A3\x01\x101\u00CF\x04\u00B9;\u0097g\u0087y(\x06\u00B4\u00A0\u0091\u0080\u00F9HGT\u00DE\u00D1\x18\u00C4\b+Y\u00A2M`{1j\u00BA#\t\u00FF\u0095R\u00CF1\u0085\x1B\u00B7\u00B4\x19R\u00E0\x1Aa\u00B5\u00A4\u0088e\u0080\u0086kR\u0089>J\u00B3{\"U\x0B\u00A1\u00DE\u00CCPe\x01\x0B\x1D\u0087\u00FBs\u0082\x12J#4'\u00DD\x13\u00DD\u0088B\u0086\u00F2\u00A3\u00DFk\"1\u00C3m\u00D7\u0091\n[\u0081\u00F0\u00D2`%\u00D4\u00FD\u009C\x1D1\n\u00F53\\\u00AD \u00F3\x17d\u00895\u0087\u00E0\u00F5\u00BB]Q\u00FE\u00F1\u00C8N\u009A\u00F2\u0083\u00D1\x19^\u00A4*S\u00DFh\u00BD\u00F7\u00E4_\u00A2\u00B4\x18\u009F\u00AFY q\u00CC\u00AA\u00CA0Q\x1D\x14\u00C9\u00DC\u00E2\u00E9l\u008D\u0094\u00BD&\x0E\u00D5T\x15\u00C35\u009F\u00DC\u00B8\u00F5/\u00CF\u00FBQ\x00\x7Fx\u00B8\u00F3n\u0093!\u00BCe|\u00EB\u00D3\u00F7m\u00DC\u008A.U\u008B\u00BE\u00BB\x1B_d\rr\u00A9\u0093\u00E6\u00A4F\x03\u009C\u00BB\u00DFn\x11\u00C5\t\u00AE&\f\u00D20\u0087\u00A55\u00CD\u00B5\u00C4\x1C\u0088\u00A4\u00FB\u00AC\u00FC\u00AE\x1E\x13\u0090\x11\u0088TQ\x10\u00D2\u00DD\x18\u00D1,\u00DCf\u00D3\u0094ic2\u00CD\u00EF\u00D1\u008A\r!\u00AB)Q\u00EE\u00D4c\u00F463\x10\u0088l$\tz\x12\u00AB\x0F8<\u00A5A3\u0099\x1B\u00AB\x1B\x07\u00C4wv\u00C4\u00FC\u0088\u0080\u00C1&\u00FA|\u00AE)R(\u0095\u00ED\u00B70\u00A4z\u00EE\u0083m6\u0083P\t4\u00A4\u00A3&\u00BC\u00ADR\u009F\u00F7\u0086\x16T\u00E1\u00C3\u00EA\u00E5^\u00E1?K\u00F4!A@=\u00C7\x05\u00D7/te\u00DC\x05N\u00A7\u00BF>\u00F36R\u00F7N\u00C9\u009E\u00DB\u00B7\u00AD\u00A2`#D\u00FA\u009F\x02\u00B2+@+\x7F\u00C6\u00E4Ti^\u00A4\u00BDq\u00D1r\x1FC9\u00E6\x1D\u00A0\u00FA@\u00A3$\u00C7\u00E1\u008CC\u00810pr>\u00CB\u00BA\u00B7\u0090mu E\u00EF\u008E3\x07N\u00A3??\u00A7k\u00DE\x17\u00D8\u00FA\u00D0%O\u00C7\u00D10\u0084\u00EBu\u00DF\u00C3~x\u00F3\u00A9\u008F\u00EF\u0093\u0082\u0095\u00C7\u00A25\u00E4\u008E\u00C0\u00B5\u00EA\x11an\u0081\u00D6\u0085\u00E3.z\u00C3\r\u00E2\u00FB.\u00A9:B\u0080o5_!\u00B9\u00873\u00D3\u00BD\x07I}0\u008EcBLD#\u00AC\u008A<C\u00CD\u008Bp\t\\\u00DC\u0091D\f-\u00A4\u00A4\u00F8{\u009A\x16+\u00B1:\x07\u0095\u00E1\u00A1\u00C0k\u00FF]\u00A6\x0B-\x17_e\x1E\u0088\u00B1&\x13\u0091\x102\u00A1s\u009Ae\u0091O\u0097:\u00BD\u00F0?\u0089\x00\u00EC\u00D2\u008C\u00DD'I0/B\u00BB)H\x13)jGR\u00FA\u00F5d\x1A\u00B1\u009A\x1A\"<:\u009FSs\u00C9\x15t\x13\x03\u00E9\x1E\u00A4\x15\u00DC\u0087\u00CF\u008A$|Jc\x1Da\u00A9\u00C6\u008A\u00C8W\u00E0\u00C6\u00ACT7xM/\u0088\u00A3zE&\u00C9H\u00F5\u00CF\x07\x14\u00F5\rP\x1E\u00AC0\u00AENU\u0087\b!\u0099\"\u00ED?vz\u00EEx&\u00D1\u00EF0\u00ED\u00DBm*\u0093\u00A4,\u00AE}\u009D\u00868\u0093\u00FF\u00A6\u00EA \x18>\u00F9\x0F\u008F\u00D7\u00CB\u00DF\u00F30\u00F9\u00D6\u00EF\u00BC\x06\u0087h\u0087e\b\x17,\u00DE|\u00CE\u00A5\u00B8\u00F4X\u00C1\u0082\u00D2\x06\x00\u00EB\u00B0\u0082'T\x0B\u008CP\u00E9\u00C3O\u0089@\u00A9`\u00BA\u00EAAi\u00D8\u008B\x01\u00BB X\u00D3\u00C1\u00B3!\r1\u0088\x133\u00C9\u0088\fB\u0085\u0092:\u00E3\x16F\u00CF\u0094\u00CC<\u0082V\u00CE\u0099\x02Nj\u00DC\u0095M\x13\u0094\x0E\x18\x10!\u00F3\u00B0\u00D4lH\u008F1\x18w\u00EFf\u0098\u0094d\x02M\u00B88\x04\x16PC\u00AEoz}x.T3\u00E8\u00C8\u00E7\u00A5\u0092s\u00A0\x064wo8\u00D1\u00BA$\x0F\u0095As+\u00B6j\u00C0\u008B0\u00E7p\x0F\u00E6\u00ECW\u009BB\u008F\x1C\t\u00D8\u00EFf|q\u00E3\u00DD\f\u00DDk\x1B\u00C6NG\u0085iA\u0096\u0080\u0088mQ/\n\x1DK=o\x0E?f\u00D5\u00F3\"\u009C\u0089\x18O44\x1B\u008E\u00826\x00\u00A3\u00BF\u00A5\u0089\x04w\u00A2\u009A0\u00D7\n\u00D5\u0081\u0084\u00E9\u00D3\x16\x01\u00A0$\u00BC\u00B0\u00C1tT\u0094\u0092\u00E8\u008CL\x0B\u0098\u00AA\x15~\u00A6\u00B62\u009B\u00FE,\u00AAa\u00C7\u009DVkv\u0083\u00EC\u00C4\u00C0Xb\x14z\u00BE\u00F5\u00C9\u00F8; :b\u00D7\u00F5\u009F\u0093[\u00DF\u00FC\u00FAs\x00\u00FC\u00D7\x1D\x03\u00C1m0\u0084\u008B\u00B7\u00DFs\u00CE\u00D6\t{o3:\u00F4\u00AEo3\b\u00E6\u0080\u00B8\u00ED\u00A0J\u00CFp\u0099\u00D5(?\x12\u008E\u009D\u00D7\u00B5a\u00AF4\u009C\u0080\u0086\u00990\u00A2\u00C0\\\u0091\u0083\u00D7JX\u008A\u0095Z_\u0082\u0081A\u00FE_\x157\u00EE\x05\u00B9\x01ji\u00D5]\u00C4K\u00A9\u0099ps\u00F9\x1E\u00B2p\x14\u00C6\u00C8\x0F\u00CEt<\u0091I\u00AA\u00CA\x00\u008F\u00F8K5\u0083\u00F5\x12\u00C9\"\u00FC\u0097\u0088S\u0097\u00F2\u00FCA\x17\u0093\b\u00C5\u009E\x04\x16\x11n\\\u00EE\u00C5\u00AFO\u00AA\u00AA\u00EE5!\u00CA@\u00FE6! \u00F5s|\u00F1\u0092\"\nl\u00CF\u00CB\u00C9A\u00EA8y.k\fT\t\u00CC\x11\u008E\x10\f&\u00CDc+xx?V\u0090\x154hv\u0092\x10359\u00DE\x01;\u00A4\u00BB\u00F8\u00F5A\u0098\u009C\u00A7\x01,r\"Er[\u00A1\u009B\u00AA\n ?\u00C7\u00FC\u00F3\u0098\x14T\u00E2\u00FDO\u00EA\x19\u00F8\u00F3\u00D1\u009B\u00A4\u00D9\u00C7\x04Y\u00F0;]\u0090q\u00E3D\x7F\u00C9|\u00C6@\x01Y\u00AF\u00A1\u00A2\x14\u00C5\u0084\u00F1P\u008DTE\x1B;\u00DAG/?,Ch\u0087\u00FA\u00F1\x1A\u00BD\u00FE\u00A1\x1F\x1A.}L\u008F\u009B\x1C\x1B\u0096 \u00A8nE\u00FF<\t\u00D6\u00A0\u0091h\n\u00B3Eh\x12\u00B4R\u00EA7\x03\u00D8\u00AF\u0082\u00ED>`\u00A1V\u009Bq\x01\u00DF\u00E8E\u008Dq\u00A8\n\x16RB\u009A\u00DDE\u00B9\u0084y\x15\x16\u00C2\u00D8\x03\x0Fe\u0096\u0086\u00A50\u00F4\u00D9\u00A2!\u0097:\u00F3$)\u00BAH[\u00B8}\x00\r\u00C4A\x06\u00C6d\u009F\u00F8\u008E\x06\u00AB\u00C1\u00C0Me2\u00CC\u00B9BCF\u00C9\u00E5\u00C6-\u0096\u00AA\x1D\u00B1\u008E%\u00ECX\u00A4\u0095\u0099\u00F1F\u009F\u00B94d\u00D9u\x0F\u00BE\u00F2MP\x04Y\u008A\u00CDB\u00A5g\u00906\u00C45\u0093\u00C4%\u008F\u008B\u00C8$##\u00CCI\rB\u008E=\u00DE\r\u00AB@\re\x0EL\u0085\u008A\u00E7\u00AD*a\u009C\u0097HP\u00B50! %\u00A7r>\u00B9\\\u008C\tN\x0B\u009B\x165\n\u00E2\u00F3\u009Eu\x18i\u0093\u00D1\u0080\u00DF-\u00FE\x15w%KOi\u00AE\x11\u00B1\u00C9\u00A45^\u0087\u00BCg\u008Dw\u00F0\u00B9\u00B3\rar\u00C5\u00C7\u00F9\u00BA\u00F2\u00D6\u00D8/\u00F2x\u0084\u00B2\u00ABL\u00E9\x02b\u00B6\x19gJ\u00E1\x1C\u00F1Ml\u00F5\u00EA\u008F>F\u00AF|\u00EFCq\u0088vH\u0084\u00F0\u00FE\u00AD\u00CB\u009E\u00FA\u00A1\u00E1\u00FD\u00A2my\f\u00D1A\u00F1\x1C\u00AC,\u00AA\u0086\x06\x15\"\u0083\u00BA\u00E8\x10\u00E7\u00E4\u00AEH\r\u00FB\u00C5\\\u00913X|\u00C2L\x1B\u00E6\u00F0\u009D\u00A4=\x18H`Kq\tF X\x12\x12\u00F3\x17\u008C\u00B9\u00A4\u008C\x1E}<FF\u00A6\u008E\f\u00B5\u00A0\tG,\b\u0082Q\x0F\u00BD\rP')o\u00A8\\t\u0091\u00E8\u009F\u00FF\u0083H\u00EE\f]\x02\u0095\b\u008D\u00CD\u00B6$h\u00AD\u0081U\u0094\u00F9TF4\u00D58\u00D5\u00F2\u00C6\u00FC\u00B7\u00B3\u0090\u0089\u008F:\u00F2\u00ED\x05\u00A5.\x1A\u00A0c\u00A8\x1D\u0099.\u00DDL\x15PK\u00CEQt\u00CB^,\u00E89z\x10xucJ\u00E9\"\u00CD\u00A9\u00D2(\u00D0\x18\u00B4#\x007aM\u00D5\u0087L\u00DF\u00CEQ\u00ED\u0089\u00CD\u009A\u008D\u00B7\u00EE:\r4\u00D7\u00E1}N\u0094\x03+h\x01\x05)9Q**J\u00E0q\u00A2\x01DH\u0085\u00C6\u0088\u00B0B\u0094\u00AD\\#\u0098n\x01\u00E7\u00CFD\x06S\u00DD\u00AD\u0081.\u0088,r\x0E%\u00D4\u00E5\x11\u00B9[H\u0099O\u009B\u00C5\x12I\u00D9,\u00D6\x02\u00B5\t\u00D6\u00AE\u00FB\u0082\u00EC\u00F9\u009F\u00E7?\x15\u00C0\x7F\u00C7J;$Cxk\x7F\u00FBS\u00B6\u00E6\x07\u008F!3 \u00F4\u00F3\u00D4^\x12~$xP\u008A\u0090a\u00AC\u00A0\x04\u00F7\u00CBW\u008Ey+\x14'H\u00C7\u00BA\u00D2\u00F9d5\x17\x15\u0088JC\u00AA&)c\u00C7\u00C7P%l'gi\fF\u00F2\u0080\"\u00C9\u00F0d\u00D6C`\u00BA\u00F3\u00E8\u008Ce\x04\x00\u00E1\x1E\r\u00F4Z\u00D83f\u00D5&\u0080L\u0084\u009E\b\u00EA\u0085M&\u00EC\x05N%\u00C8\x04\u0097l\x1Dno\u0090\u00B2\x10\u00FD^\\\u00B8\u0091\u00E8T\x16\u009B\u00D9!\u00D4\b\x14(\u0090;.B\x12\x10\x10*G\u00FC\u00EE\u008C\u0085\u00CCj\x02Y\u00B5tT\u0089\u00A2\u00EA\u00D6\x0E\u00DB'>w\u00EF/\u008Cg<\u00B7\u009E#\u00C6\u00A4xn0\u0097\u00D1\u00CF*\u00F7v\x0FCT7V\u00C4oY^\x0E\u00D1w\u00A3\u00F1N\u0081Iy6\u0091\x12\u00C4\u00A4\u00E6\x1A\u00F6\u00D4\u00B7\u00BCW\u00CE\u00F7\u00C4\u0086\x10\u00DE\x0E\u0081j\u00DDQJP\x19\u0081\u00D0u\u00CC\u00F9\u00E2\u0098{QM\u00B49\n\x00&5\x19BUi\u00C1\u0084\u00AA%\t\u00DA1W\u00C5\u00F2\u008A\x0F>\x05\u0087`\b;T\u0086\u00EBu\u00CF\u0089\x1F\u0097\u008F>\u00A1\u00B7#\u00AA\u00CDx'6\u00BE\u00F8\x1606e8\x00pwf\u00FA\u00FE\u008B\u00B4\x04w0\x02\u00A6j\u0086\u00A1\u008D\u00BD*\u00D8'\x03\x0E\u00C8\u0080M\x01\u00B6\u00A0\x18;0v\u00C1B\u00ADL\u00BB\x11\u00B7\x0B\x01\x11\u00DF!\u00DA\u00D2\u00A8\u00BB\u00C34F3\u009A\u00CF\u00BF\u00B9\u00CAQ\u00BE\u00D3.\u00A04P\u00DA\u00A6.\u00DD\u00EB p\x03\u0099t5f\u00F6\x1F\u00F7\u0098P(zx\x1D\u00CA_0:>\u00A63&\u00F1\x04*i\u00E6\x16\u0094f\x06\u00B5\u00C6\u00D0*GU~N\x17Af;\u00BA\u00B7#j\txt%\u00B8\u00AFd\u00E6\u00F8\u0087\u009A#T\t\u00CAq\u00AA.m\u0080xv\u00A41\u00F4\u0096\u00EF\u00D1\u00C7FH\x0E(\x10\u00AACaR\u00C1\u00D0\u008A\u00AA ^\u0086\u00DD\u00E1\x15\u008D\u00C1\u00B6#t\u0081\u00CD\u00C5\u00B5Ji\u00A9\u0091.\u00EC}\u0093=\u00F6Da\x02\u0098\u00C14\u00F4~7\u00D6\u00F9|\u00D3\x13\x05\u0087~\u00A9\u00A6\u00B1\u00BE\u0082\u00A2\x06k\u00E5\u00C6\u00ADpDAAW\x18\u009B?\u008B\r\u00B3\u00AC\u00E5b\x06I\u00A3\u00ADf2Y\u00D7\x12z\u00CE\u00E3\u00E2\u00D1\u0093\x151#\u00F9g\u00ED\u00F3\u00BA\u00CF?A\u00BF\u00F0\u00F1\x13\u00B1\u00D2v \u0084\u00CB\u00F5\u00D3O\u00FA\x00\u00DE\u00BB~\u00CC\u00D1\u0081\u00EBsf\f\x02rQ &\u00B1\u00EA\u0082)u\u00EAb\u00B3\u00F3\x18SpP\x047\u00A9\x15g\u009D\t0\x13\u00AB\u008C\u00C4x\x01\u00C0\u00F6\u008B\x14\x01\x18\u00A3\u00D8`\u00F6\x03\u0086\u00D6r\u00A9\u00D9\u00F6b\u0099\u00B3\u0090\u00A8@\x10\u008BQh=f\u00F2\u008D\u00A2a\u00C0\u00A8\u008C\u00844\u00CE?\u0082\u00BA\u00B7\x19\x11\u00AD\u00D2\u0092\u00E5G0\u00C6\u00813\u00C0\bE\u00A2\u0084L\x00\u00F2\u0081\u00C3\t&\u0082\u0099\u0098\x1D\u008A \b\x03\x0E\x1E;Q|\u00F21cQ\u00FD\x18\u00C8\u0083\u009Ak\u0098\u0096f\u00F1\u00DF\u0095\u00F7\u00F6]\u00A2\u00E0\u0086<\u00BE\u00AB\u00A8oP\u00DF[\x05\u00DBD\x0F<w,\u00E7M\u00C3\u00B8\x12\x1DQ\u00ADa_c>{\x18\u00F7xOw/JJ\u00CB\u0098\u009B\u008A\u00C9\u00B5\u008E\u008B\u0086\u00C7\u00D2\u008F\u00C3\u00EF\u00A9\u0085\u00BF0\"~\u00A6D\u00AFT\u00C8\u0089\u00F7\u00ECE\x06\u00A9\u00D9\x14\u00B6\u008C\u00AA\u00D4\u00B2\u00D9M \u00AE\x1CN\u00AE\u00EC\u0082|\u0094/\u00B5E\x1F\u00C1l&\u00C75\u009EE\u00AF\u00FE\u00C4\u00FA\u00D6\u00DB\u00DE\u00F8$\x00o@i;\x18\u00C2\u0085\u009Bo\u00FD\u00FE\u009B7n\u00C2\u00A0\r\u00E3]\u00B4g\u00E3\u00ED6ui\u00E00\u00DE\x16\t\u00E3\x10l\"\n\bBr|\x0F\u008D]\u00F9\r>\u00F9#\x04\u00FBD\u00B0\x07\x16\u00CE<\u0087{\x1F\x14\u00BEAl\x1A\x1A\u00B7\x0B\u0083\u00E8jD\u00CA\u00A4\u00A7\u00E0\u00C8(\u00DE\rg\x02\u0099\u00F3`)\u00CE,\u009C\u00D2\u00C5\x7F\u00F7B-\u00AA-<\x14D<\u00BC\u008E\u00EEM\x16de<\x03\u00C3\u009E\u00E1\u00E7X \x14\u00A1v\u00DA/\u008Cp\u00D3hF\u008B8\x19YX\u009D\u00A1\u00E9%\u00D1:gH\u00CB}e\b\x10\u00C0c\u00E7\u0095:.\u0095i0\u00A8\u00AA\x07dV?\x1Fp/M,b }3F\x1A\u0091\u00BC\u00B4\u00CA\x00\u00F89\x18\u0097\x07(\u0085NNX]\u00C0n\u00C0e\x12%R\u0090\u0094J\u00CEq@K\u00B2UxH\u00FCZ\u00E3\x00\u00E5\u0092U\u00C3\b\u009B\u00CF;\u0098R\u00BDb\x7F\u0098\u00CC\u00AF3\u00F3`\x18\x1C+\u0092\u0080s\u00C0E\u00C2\u00F37\u00CEe\u00B9\u008FGv\n4\u00DFq\\\u00A7\u00F9\u00DD\u00EF\u00B11.\u00B0\u00EF\u00E2\u00F7}\x1Fn\u008F!\\\u00D5>\u00FA\u00BD\u0090\x05\u00D2\u00A2y76Up\u00E7\u009B\u00A6^\fClkv\u0080\u00D0\u0089\u00E8\u00A10\x035\b\u009B\u00CC\u0080\x05V\x1D1\u00805\r\u00CC\u0092\u00FDE\u00ED\u0098K\u00C3\x1C\u00DD\\\u0090hh\x1Eq8hn\u009BjD\u00ED\u0089NJw\u00A3\u0085/\x13\x15\u00C4\x06\u00AA\u0090\u00D8\u00A2\u009ED\u00DB0x\u00A4b\u00B8\u0088\u00C1\u00ADAX\u00B9\u00B9C#\u00E6\u0080\u009E\x06\u00CA\u00B14\x13\u0099\x04\u00B1\u00BB\rf`t&\u00C0 *\u0085\u00D7=\bfe\u0086\u00BD\u00E6?q\u0091\u008B\u0087,\u00B3\u009Aql\x0B\x07\u009D\u00D2\u00E0\u00AA\x0F^\u00C4\u00E2\x14\\\u008F\u008D:\x01\x00\u0098\x04\u00D5\u0088^\u00D0\x1C\u00D2\u00F2\t`\u00EF\u008D\x0BS\u0080\u0088\u00E0\x10\u00C0\u00AA\x1F\u00F9Vq$l\u00D2\u0082.!\u009E\u00A4\u00C5\u00ED\u00CB\u00C8PRS\u00AF\u0084\u00E6\u00918\u00EAv'I\x17]\x18J\x0B\u0086\u00E6\u009E\x1BtcN\x10\u0087x\x1A\u00B6\u00F9\u0088\u00D3\u00F6@q=r\r\u0092y\u00F0\u00F9\u0097\u00F6\u00AC4\u00A0\u00F6\u00CA\u0084$\u009F/~\u00CE=\x1E\x04j\u00A5\u00F1T2i\u00CD\x14I\x0B\u00C4\u00EA\u00D6\u00AF\u00F6\x16\x15\u00AF\u00C3\u00FE`\u00D5t\u008A7Y\u00C0\x04,u\u0084\u00D7F\u00F1\u00F7\u00DC\u00D1\u00AE\u00BB\u00E6\u009F`\u00A5M\x18\u00C2g\u00F5\x0B\x0F\u00FB\u00C1\u00CD\u00FF\u00FD\u008Cx\u0089\u00C7\u00A4\u0091\u00E0\u0087 b\u00E3\u0084\u0083?(\u00D3\u0080\x0BD\x02\u00BF\u00A7\u0084\x03\x10\u00D2;\u00FD\u00F469[\"\u00D8\u0083\u008E\r\f^\u0098\x04`Y\u00B1&\u00D5^\u00A1h\u00A2Pt_\u0087\\\u0084\u00B5w.\"c^)\u008F\x19\u00FC\u00E4\x05Q\u00A4\u0085\u00DCqYm\u00D7\u00BA\u00EA0\u0082\u0092\u0094s/\u0091\u0084\u00D5\u00D1|\u00D3\u00D9L\u00D1\u0099\u00F8\u00C1\u00E1\u00EAIC\u00EA\u00BC\x13)\u0083$T\u00F7\x00d`\u0091f)7\u00E3\x14\u00B6\u00A8\u009C<\u00C4\x17\x12{\u00CB\u00D8d1\u00EFB\u00CF\u00F9\u00A8\u00FF\n\u00D3\u0082I@~M\u00C6\fp\u00F85B\x11\u0087\x18;+W\u00F7\u00A2\x1E\u00D5V%&\u00FB\t|\x12\u00F3c\u00EF\u009E^\u0086:^)\u00BF\u00D5.I\u0094TCh\u00FC#\x04/\u008C+\u00F6e\u00A8\f\x02\x05Y\x1C\u008A\u009A$\u00EEa\u00CC\u0093\f\u00B3\x04Eiy\x1E\u00AAAPLj8h\u00C3\u00B4\u00FC\u00DA\u008A\u00A1\x12H\u00E4S\u008C\u00CC\u00ADw\u00CC>\u00FD\u00E93\u00F4\u00A3\x1Fx\u0098\u009C\u00F9\u00C8k8\u00AA\tC\u00B8b\u00F9\u0089'^9\u00BB\u00FC\x182\u0083\x06\u00F3,x\u00C9\u00B0\t\u00C1\u00D7i\u009DB\u00AF\u00E9wJ\u00C8zM\x1Ecb\u00D2>4\u00DF\u00F8m\u00865\u00D5\u00D8\x12n\x11\u008ED\u00F3,4'\u00CA\u009A|D\u0092\u00A4'\u00A11\u00E6\x00@W#~2\x06\x120\u0097iw\t9e`F\u00ACV\u00C9\u0099\u00B5\u008F2Yetd\u0090\u0091\u0092\u00E6a3?x\u00E9\u008B\u00A1\u00D5A\u00C3+\u00C6\u00A50\u008A\x11-\x18\u00B3\u00A3\u00D1\u00AA7w\x1DR\u00DA\u00C75(\x0B{*a\x11Q\u0093\\t+\u00EF\u00D3\u00BB\bD\u00A2\u00F5\u0098\u0096\u0085[\u00FB>\x04Q\u0093(+\u0093\x03\x10\u00B5\x0B\u00AB\x00\u00D6\x12\u00EB\u00CF\u0083\u00F4(D\u00DFTE\x10\u00F9\x1Fe\u00A2\u00CA\u00B9\u00E9\u00DAS\u00E6!T\u00E3e\x04\x12\u00F1>u-\u00E6\u00D4\u00C9\u00EA\u00B8\u00E3\x1C\u00FD\u00FF\u0089{\u00B7^\u00DB\u00B2\u00E3<\u00EC\u00AB1\u00E7\u00DE\u00E7\u009C\u00BE\u00F2*6E\u009ATD5E\u00C5V\b\u00EB\x02:1\x1D\u00CB@\"8\u0092\x03%A\x12+\x01b\x04A\x00\u00FF\u0080<\u00E5=\u0081\x1F\x14 \u0080\u00DFb\u00C0\x0E\u0090\u00F8\u00C1\u0090^L#\x12\x02\u00CB\u0092%@\u0092\x05\u00CA\u00B2@\u008B&e\u00D1\u00A1\u00A9\u00B6D5\u00D9d\u00F3\u00D6\u0097s\u00CE^sT\x1E\u00EA\u00FB\u00AAj\u00CC\u00BD\u009Bl\u00C1\u00BA\u00AC\u00EEu\u00D6\u00DAs\u00CD9\u00E6\x18c\u008E\u00AA\u00FA\u00EA:\x1AZ\u00A8u\u00D3\u00EF\u00EF\u00B29\u0088\u00F0\u00DB\u00DC:=\fr\u00B3\u00F6\u00A2\u00AB*>\u0083d\x18\u00FD\u00F6\u0086\u00ED\u00E5/\u00E0k?\u00F3\u0093?\x04\u00E0\u00FF\u00D2\u00E1\u0085!\u00FC\u00C2\u00CD\u00CF\u00FF\u00C5\u009B\u00FB\u00AF\u00E1O\u00EC\u0095\u00FE\u00F3^\u00B8\u009C\u00E4\u00A4\x00\u008E\x1CT,\u00A4\u00DA\u00E0\x13-\u00D0\u00A5$\u008E\u00A9-\u00B7<\u00D7\x11\u00EE\u00C3\u00AF\u00BB\u00E3I\u00F3,\u009A\u00B2a\u00C3\x05\u00B1\u00ED\u00D7cJ\u00DD*\u00B0*\u00A3\u00DF`\u00AB\u0083\u00E9\u00CA\f\x7F\u0096\u00A1P\u00D26U\u0080-\u009FwH\u00FA\u008A\\<\u00F2\u00CC\u00AA\u00B1X\t\u00B2\u0081\u0084\u00C2\u00F0\x17\u00C1Q\u00A5npd\x06\u00A4;\x0B\u0096\u00B6\u0084\u00A0{/\u00A9\u00E5c\u00A5#\u00931-\u00DA\u00AE\u009CF\u00E9\u00C1*)\u00D6\u009E\r\x17\u00AE\u00A0'\u00CCs[2\u009E\u0080Jr\u00C2\u0089\x18\u00A5\x1C\x11\u00F6fX\u00F7\u00A0JO\x1B\x01\u008B78\u009D\u00BBz\u00CCI\u00C0mw\u00EB5:\u00D0\u00D9n\u00D93\x14\u00F7Q\u008C@s\u00A5\x10f\u0084\u00E0\x11\u00F7t\u00A1+\x05\x18X\u008D\t\u009D\u00BDw\u009B\x06\x0B\u009F\x0E\x00\x07%\u00F5l\f\x03\u00D1'\u00F3\x1E\x14\u00C5y\u00F4\u00AE\u00947\u00CE1\u00F9\u00BC\u00BCv\u00D3\u008A{7\x17hhX\u00C9\x002\u00D5\"\x19\u00A3\x10\u009E\u00AF\u00E8!\u00D5\n\x07&\u00B0\u00CF\u0089\u00FD\u0093\u009F\u00FE\u008Bx#\u0086\u00F09{\u00E9\u00A3\x07zG\u00FF\u00B8_\x03\u00EB\u00AE\u00BDUG \t;\u00A5\x7FI\u00D6\u00EE\u00AE\u00A97\u0090aD^@_\u00D7\u008Eix4\u0080\u0097\u00DC\u00C3\u0086\x000\u00AE\x00\u00D8\u00DC#\x12\x11*\u0093\x16\u00F1\u00F9\x13\x1E\u00AED\u00AB\u00D2i\x07\u00E2\u00FA\u0083\u00EBj\u0098\x12\u009Dr[SXJwp\u00A9g\u0089\x16DmGY\x01\u00C2 T\x1B\u00CEV\u0088\u00B3l\x16\u00950\u00C5\u00D2ln9\u00CE\u00B4\u00FEC\u008CA\u0088i,\u008B\x05\u00C9H\x10-\u00E5z\u008C\\\b\x11I\u00AE\u0083D\x07]\x14#\u0088\u00DA.1\u00BF\u008C\x7F\u00D0B\x0F\u00E2G#\u00AC\u00B6\u00AAD\u00C8\x16*A\x1C;?\u00D7\u008E(\u00C4\u00CDJ\u00FDK\u00F5&\u00D5\u0091\x16\u00A4\u00E3\u0086\u00C5\u00D2\u00AE\u00B5\u00D5\u0099\x14\u00DB\u008C\x023rm\u0093\u00D0\u009B\x07\u00A1\x03\u008F\u00EA\x7F\x19\x1Cm1\x1E\nI\u00E8J#\u0081w&\u00D1Q\u0087\u00B5{\u00F5;\u00E9\u009C\u0086j\\;II\u00ED\u00A9\u00B0\x00\u00AD\u0087\u00A5\u008DTi\u00BA\u00D7\u00C2k\u00F8\u00D3\u0082\u00A9|\u00F1\u00C5\u008F\u00F6\u00A1%&\u00FF\u00DA|\u00F5\x1D\u009F\x1B\u009Fz\u00BE\u00FC\u00F8\x7F\u00DC\u00AFB\x07\u00F1\u008E\u00A0\u00A4[*\x01\u00CF\u00AD\u00CFB\x03\u00BD\u00AD\u0080\u008D\x15\x11x~\x05\u00DA\x0EW\u00E4\u00D71\u00F0\u009A\u00EDx\u00E4\u0086G\u0088J\u00CD7\x0E\\(\u00AB.\x16\x01J\x17\u00C6*\x1C\u0088\u00B0\u00E5xo\u00B8Al/\u00DF\u0093\u009D\x0E\"\u0080x\u00EBX1\x11\u00C5\u009A\x1D\u0098\u00BC.v\u00A9\u008E}#\u0090^\x06\u00B93\x0F\u00AF\u00EBj\u00D7\u00A9\u0088-P\u00C5\u00E5x\u00CE\u008Dq\u009A\u0085\u00CD@s\u00AA8\x03#\u00A3\u00D5\u00DF\u0083\u009F\fWVT\u00E4\u00F2V[ryj\u00F1\u00DB\x0E_\u00FC\u00F1#\u00ECzz.C\u00EA\x1F\u0090\u00D9{\u00EA\x1B\x14\u00B6\u00CB6\u00B9`U\u00C9\u00CA\x19Ay\u00FB!\u00B6>\x01\u0090\x01\u00B1b6\x001\u00BA\b1n\u00EB(\u00C3}G;fi|C\u009F;\u00FD\u0086\u0090\u00E8\u00BDL}_g\u00C8$\u00ADF\u00F8\u00F2\u00F2\u00F4k\x14f\u00CC\u00FE'\u009F\u00D5gB|\u00B5\u0081BD4l\u00D6\u00AB\u00D90Z?S\x006&\x14\u00CC 6\u00DBq\u00AAO9\u009E\x17_|\u00DE\u00FF\u00D5\u00AF\u00BFC\u00AD&B\u00F8\u00B8}\u00F6\u00CF\u00FD\u00D6\u00FC\u00B4\u00C1\u00FE\u00A4\x02\u0092\u00A2|I1\x05@\u008B\u00C0\u00F3\u00BB\x1E8\x07\u00DA\u0085N\x0B\u00D81J\u00CB5\x07@\u00EF*\u0098\x1Ar\u00CC\u00F1U\x00\u00F7\u00A6c\x1B\u00B1I\u00EC\u00EE\u00AC\u00A3\u00C0H\u00C1\r!E6T\u00AC\u00C1\u00C0\u00A0\x07b\u00E3.Q(\u0082 \u00E2P\u0090\u0093\x1EK\x14M\u00A9\x07w\u0085\nb\u00BA``\u00E3\x18\u00D4~\u00EE3\t\u00ED\u00E1P5\x15\x00\u0085k)@K#\u00D7Bi\u00D2\u00B2Gmv]\u00D24\u00BB\u009C\u00B7\u00F4U\u0083\u00F7j\u00B3o\r\u00E66\u009F\u00F9j\u008B\u0088\u00A6,\u00A1=c\u00FC\x01\x06,90\u008F`>)\u00C1%\u00C1\x06\u00BB7\u00B9\u00CB\u00DA@l\x0Bg\u00C8\u009D\u009E\u00A8\u00AFgr\u00D4t\x12/J\"\u00C2q\u00CE?\u008D\u00B1\x15a\u00BA\u00EA\u00CA\x11B;\u00A1w\x15ia\u00D7Dd9g\x16v\u0084\x05o\u00A6u\u00E8\u008E\u00F8\x042@?\b\u00ED=\x04\u00D5\u00AD\u00E2\u00AB\u00CD\x0B\u00E1=Q\u008B\u00EA\u00C0\u00ECc\u00D15\u0097\u0094\u00F4\u00B9\u008B8\u0091Dz`\u00BA\u00BB\u00D1\u00DB\u00E3NDh\x18/}\u00C1\x1E\u00FD\u00FC?\u00FAs\x00\u00FE\x1F\u00A01\u0084\x7F\u00FE\u00E8\u009F\u00FC\u00E0\u00D7\u00EF\u00BDae\u00A5?\u00E2\u0097\x16eS\x17\u00806ae\u00F3\u0086o\u0094H\u008Al\u00B3\u00C6\f\u00EA\u00FC7\u00FF\u008E<\u0084/Z\x04)_aFz4{f^E\u00D6v'\x02\u00B0\u0088O\u0088\u00A5\u00E7\u0084\u00FB[\u00EC\u00F0d\u00D1\x03\u00ED\u00F3\u00AB\u00D8\u0082\u00D5\u00D5\x18\u008B\u00EF\u00E0&\u00B4\x07\u00C7\x11*\u00CBF\x15O\u0089Ib\u008A}?\u0083x\u0098!P\x14\x04\u00A3\u0099\u00ECsUR1\u00D5fI\x1E\u00A0\b\u00A9UN.\u0097{ \b\x11t\u00FC|R\x19\u00B4\u00F0\x10\u00C5>XG\x19J\u008ENv\u009E\u00CA0\u0099\u0093\x03k\x1E\u00836\u008E\x19dJ\"\u00AA\r\u0081k\u00AD5#)Z\u00AB<\u00F8X\u0093\u00BC^\u00B3\x10]\u00E0\u008C\u00E8\u0092D\b\u0092\u0096\u00D9H\u00B47\u00EB\u00DC\u0094\u00D4yO\u00F5`\u00B6\u00F6\u0089h\u00D3C\u00D0\u00D5\x1D}\u00F7;l\f\x03\u0085\nd\u00B4\u00CC\x07\u0089\x1E\u00C8\u0094\u00E7&\u0081\u00B7k\u00F5\u00AC;\u00A3\u00F6\u0081,\\\u00DBJ\u00CF\u00F5\u0097\x01\u00B8w\u00B9\u00E0\u00CB\u009F\u00FA\u00E4\x0F\u00E2\x16C\u00B8\u00F9\u009D\x1F\u00C0\u00F5\u009FP \x12\ts%f\u00A0\u00A0n{(\x0B\u00E1\u00F7\u00D78]\x7Fn\u00AB\u00D3\u00C1\u008A6\u00DC\f\u008Fp\x0F/;p\u00C5\u00E8E\u00B3H\u00BE~\u00DC\u0096x\u00B46K\u00EAzd\u00DBE\u00CEC\u00DCJ\u00E8c\u00A0\x1B\tU\u00E19z\u0093\u00DF[.\u0084\u00BA9\u00E0\x11\x19\u009981\u00FAY\u008A\\\u0090\u00DA\u00C6\u00B3{]FS%\u00EA\u00A9\u00FD\rF\x0E\u00DA\u00BC\u00E6Bkd\u00B8\u0095\u00A1\u00AE\u0095G7\u0080\u00BEk\x00C\u0090\x13\u00B0\u00D12\u00FB\u00E0\u00B0a\x19>k\x18\u0098\u00D4\u00E9\x1D\u0091\x04\u00E5\u0083\u00D2\u00CE\u0082\u00C8\u00E7\u009C\x19\u0093\u009F\u0088\u009C\x022\u00E0\u00BD\x10\u00CA\u00A8\u0085\u009FO\u00CE\u00B1\u00DA\x01,\x17\u00BD\u00B9a\u00FAAb\u0092~/\x0E\u00A2ur\u00D2\u00F5s=9\x0B\u00D7\u00D0;C\u00F5!\x18\b\r\u0082\x1A\u0082m\u00E9\u00FAt\u00868\u00CB\u00BA\u00EFS\u00F1\n\u0088\u00FB\x1E\u0081`l\"7\u00EF\x1D\u00B0@\x0B\x1CG\u00DAc'\u00DA\u00EA\u00908\u00C9\u00C5\x1A\u008F\u00E7\u00F0\x005'\x03\u00A2\u00C2\u00AC\u00DDQ\u00FBo\u00A4\u00C1\u00D5\u00D8\x1Fk\u00E7\u0098,\u00DC\tL\u009E\u00F8\u00D7\u009F\u00FD\x01\u00DD.\x19\u00C2W\u00AE_\u00F8>7e7\x16\x11\u00FD\u00D1\u00BE\b\u00A9\u00B0\x01\u00B8\u008FH6:\x13<\u00FF\u00EE\u00BA\u00B1\u008C\u008D~\u009B\u00E8MF\u00B4s\x1B\u00E7\x1C\u0080\u00BC?-\u00B5\x06\u00BC\u0086\r_\u0081\u00E1\u00BEE\u00DD\x04\u00ED\x13\x14F\u00C3\u00C8\u00D6?\u00BCX\u008D\u008C\u0086\u00B1wdH7\x19\x15o\u00C8\u00E4\x14\u0087\u00A0\u00FEt\u00AFB\u00A6\u00E8\u0082Q\u0088\u00A88\u00BDH\u0085\x0E\u00AF\u0084\u00E4pW!\u009C\u008C\u00CC]\u00E5\u00DDc\u009C\\\u00E2\bT\u00A7@\u008A\x04\x00\x00 \x00IDAT\u00C5\u00DF\u00C8\u00BC\u00CAR\x0E\u0098\u0095A-\u00E6\u0087\u0090\\sfB\x04E\u0098\u00AE2iMj\u00E7K\x014\u008E\u008Cp\\\x11E\u0087\u00F4Hi&tcy\u00E1@\u00ED\u00A9\x10\u00CF\u00D8\x16\u00C9[\u00CC\u00DEM\u0086\u00CB\x16U\u0099\u00AE\u00CF2\u00FC%\u0093I\u00DF\u00BD\u00C6eK4\u00A6\u00DD)}i\u00DA\u00F5\u0089\u00AA=\u0080ZK\x1Ak[S\u0096\x15\u0099t\x02\x11\u0080DA\u0081\u009B\u00BA\u00D72\u00CE\u00D6\u00B6\u00B71%\u00D3\f\x06\u009B\u00EB\u00CA\u00DB\u00F8rA\t\u0089\u008Cv\u00BD\x15(\u00CB>O\x1C\u00AF\u00BE\u00FE}\u00D5{\x00\u009F\u00F3\x17\u00DE\u00F5{\u00F3w\u009E\u00FB\u00E3-\u00B5\u00BE\x01\u00FE\x00\u00C3\u009F\u0086\u00F9\u00D3\x00\u00EE\u00C3\u00F1\x00\u00F0\x07\u0080\u00DF\x03\u00FC\n\u00C0\u008E\u009E?\x7F\u00CB\u00AF\x0E\u00E0\u008C\x18j\u00F1\u00B7W\u00B3\u00C4\u00AF\f\u00A4?\u00B4\u00A8B\u00FC\r\x07\u00BE\u00E2\u0086G\u00BE\u00E3\u00B1ox\u00E8\x1B\x1E\u00FB\u008E\u00C7\u00D8\u00F1\bWxl;nl\u00E4\u00FB\u0082\u0081\x1B\x03n\fx\u00CC\u00BF\u00C3\x18H\x15\x02R\x17D\u00C8\x15\u0096\u00AC2\u00ED\x077\u009F\t\u00B5\u0083oh\u00A7i\u00C5\u00B0\u00A9\u00DEc\u00B0\u00A8If\x13F\u00C60\n.IDRXZ\u00A8\u00B5\x18\u0089I\x1D\x11\u00E3L\u00D5\u008CjX\x1A\x0E\x17VKU\u00AD\u00BBV\u00DB|\x12%X\x12Z\x19\u00EEn\u00D9r\u00DA\u00F4\u00C7\u00B3Q\u0082\u0094-\u00A7\x14hQ\x1F\u00D9\u008Fdt]\u00A0\u0088)\u00CE$\x00\u00CD\u00F7*\x10\x1A\u00D1\u00E7\u00F76\x07\u00D2\u00C7\u00BB\r&\tJ\u00EB\u0085B\u00C99\x1F\u00DEB\u00E0\f\u00D5\u00EE\u00C2\u00A6\x151hK$\u00A2\x1C\u00CF+\u0083U\u00BF\u00C44\u00E2\u009Fr\u0082\u00AA\u00D5Q\u00FD\u00F0& [\u009F\u00A5\":\u0099\u0081/\u00F7\u0089\u0095\u00B9\x7F\u00E1\u00F3\u00CF\u00F9\u00EF\u00FC\u00E6\u00BB\x00\"\u0084\u0087\u00B0\u00EF\u00FD\u00ED\u00F1/\u00D1\u00CE\u00FC#zQ\"c\x0B\u00E2\u00B7k\u00A8(H\u00EE\u00E3\u0097\u00BB2\r.\u00E2^$\u00A5G\x11\x02\u0099}\u00D6\u008F\u00A1\u00AD\u009D;_Z\x18*\u00CB\u00D5$\x0E\u00C2{\u00F0\u00B2\x03O\x00\u00D8|`\u00B3\u0089G\u0092\u00B2\by\u00D1\x1F\u00B4\x02\u009D6\u008FH\u00D6\x1B(\u00847\u00D0x\u009C!5\"\u00DE\u008A?\u0088\u00AC\u00CAZ\x10[\u00BB\u008F\u00BC\x0B\x002\x19*\u00AA@\u00D7\u00EB\u00E0\x1C\x1D}n=T\x07\x10\u00F5\u00C0\u009C\u00D2b\u00A3\u00E6\u00D5\x12\u00AE\\\u00BBJ\u0099\u00A2}\u00A1-\u00E7\u00AA\u0090\u0091\u00E5\u00BC\u00C6\u009C\u008F\u0092\u00AAF\u00FD\u009B\u00D5\u0099cj\u0084H8\u00B7Q\u00C6y\u00F1\u00AFG T\u00E8\t\x11\u008E;\u0097\u00A5\u00E7Z\u00C8w2\x7FO\x02\u009Es\u00B6\u00E71\x1A\x11\x11s\u00B9\u00B2\x1CWC]Iw\u00AD)\u0086P\u00BB\u00A3\u00D4S\"\u00A4\u00CC\x00=\u00EA\u00BAY\u00D1\u0096\u00B5U\u00DE\u0089v\u00C8@\u00B4\u00A5\x1A\x1C-\u00E6\u00A3\u00ADC\u0097*@&1i\u00B8\u0094\u00BDb\u00DA\x1Dm7u@1\u00F1\u009Da-\u00A7\x13\u00E5P\u00BD\u00F0\u00D9\u00F7y\u0088\u00F3\u00B7\u0097^\u00C2+?\u00FF\x0B\u00DF\x0B\u00E0\x0B;\x00\u00FC\u00C2k\u00BF\u00F9g^\u00BB\u00FAFM\u00F8\x1F\u00EAK\u00D0kC\u0096Q\u00C7\x15\f\x0F\u00E0\u00B8\u00E2X\u00E3\u00D8`\x1A\u00EE\\\u00D4\u0081\u00BD]_AG\u00EE\u0092b\u00FD\u00DD\f\u0092}\u00E2\u00AD,\x00+B\u00E8RC\u00B6\u008A\u0081G\x06|\x15\x07\u00AE1\u00B01\x1FrO\u00B7\u00DFl[\u00C7\x07A\x1D\u00EE\u00B8 \x16\u00C9D\u00B8\b\x07\u0099\u008B\u0081y\x10$p[\\z\u00C0\x15\u009Ca\u00CBA\x02e#\x0E\u0089\u00A2\u00FA\u008AR)\x0E\u0084\u00F4\u009D)\u00917\x14\x18\u008Ex\u00C6\u0090\u00D6X$_n\x06K\u00A3\u009DBr\u00E5\u00E2\u00CB\u00B8\x00o\u00D3\u00E3[-\u0089\u00E4\b\u00FA\u0083\u00C4\u00BE$\u00FE\x14Z\u00A86\u009B\x1D#\u00F5x\x05\u00F6\u00B4\u0086]\u00D9\u008AvZ\u00D4\u00DD\x1F_\u00CC<\bL\x12\u00D1C\u00A0\u00F8\rR\u00AC\u008A\x01e\x1B\u0093:\u00B4\x18\x07\u008D\u00A0KVb{;Pp\u00BB\u008D9a\u00BD<\x1E\u0082\u00EA\rI\u00E8\u00EC;\u00D0M \u00A2 h\u00CF\u00FC\b19\u00E54\u00A8\x1B1\u00DE<\x078uSk\u00DE\u00D7{w\u008FI\u00F7\u00AE\u00A8O\x1A\u009F\x0F`\x02W\x07\u00F0\u00F0\u00E3\u00BF\u00F2g\x00\u00FC\u00A3\x1D\x00>5~\u00FD{\x06.\u0098\u00EE\u00DFB\u00BA\u00FEA_\u00E4N\u00D8`\u00B8_\u00D2\u00DE\u00AF\u00E1\x16;8'\u00B13\u00AB1\u00BD\fK\u00C9,\x11\u00AC~\u00EB\u0088Ae\u00BCF\u00BB^\x13\u00C2\u00AA:X\u00890^\u00CA\u00A3\u00EF\u00A8\u0083\x10\u00D3\u0081\u0097\u00CD\u00B1Q\u00F2\u00EDn\u00B8\u00C2\u0086*\u008C\u00A6jM\u00D1\u00CEN\u00C6\u00A0`\u00A4\u00D8N>\u00DA\u00DB\u0081T\x19\u00CA\u008E#\u00DB\u00C1m;B &1\x1B\u00C1W\x16\x7Fu\x05>\x11q\u00E88\u00F5\u00DCn\u00AF\ba\u00DD\x18\x1D\u00CAh\u00B6\x14%\x05\u00FD\x01\x14\u00DA\x19\u00C8\x04TT!\u0098\u00D3\u0091\u00AA\u00D8\u00D0\u00CA\u00AA\u009C\u0085|\u00E4\u00AA\u009B03h\u00C7\u00A4#s\u0091\x062St!8\u00FA\u00C1\u00C9\t\u00A3[FD\u0082\u00AAJc<q\u0098s\u00ACtb\x0F\u00C7\u00E7H~!&2\u00A0\nE\u00F1\u00CC\u00E86\x14\u00A3S\u00F0\u0096\u00A3\x11'\u00FB4y\u00B7i\u00E5y\u00A0\u009B/\u00CFI\u0084y4\u00A9my?\u00C8V3k\u0085\u0095tv\u0094\u00FB\u00B5\u00FA\u00DB\u0099Vy\t\u0082\u0089\u009Av\x7FR\u00B1\x14M\u0088Y\u00B5\u00D3\f\u0089\x1D5\u00C4\u00DE\r\u00C8u\u00A0\u00DF\x07\x1C\u00E3\u008B_\u00F9\x1E\u0080*\u00C3\u0097\u00F1\u00E5\x0F]\u00B6\u00CB\x1F23\x00\u0082 \u00AFQ\u00AA\u00C0\x15\u009C\u00C7\u00ACm\u00D8\u00AA\x1D\u009Dg\x12{ \x03k\f!\u00D4\x03]\u00A3\u0087\u00A0\u009A\u008A'f\u0092\u0088\u00E2\u00AE\x01u4q\u00F7K\x15\u0099\u00BF\x06\u00E0\t8\u00AEp\u00C1\x0E\u0099\x03\u00D5g\u00B5\u0094\u00C1\u00CBI\u00D8\n\x1C5\u008E\u00D6\u00CDi\u00BD\u00B5\u00BCF\x06\u00C6s\u00BF\u00B2\u00EC\u008BEf%\u00AC\u00DB\x01\x1C=>M{Q&\u00E3t\u00F5R\u00B0\\h\u00AA\u00A4vx\x19K\x1B\u00F5d\u009A\x0E\u008C\x16\u00E6Jf\x01x\u00C6\x00,`\x00\u0092\u0080\u00CDXg\n\u00B7\x15w\u00D1\u0089d \u00B9\u0093\u00B2\u00AEQk\u00A6\u0089\u008Fs'PQ\u0083\u008E\x15%\u009C\u008F\u00E9\u00A5\u00E8E\x1A6\u00C9\b|\n\x05\u00A0\u00FA\u00C9\u00A1\u0099\u00DCz\u0082\u00E5\u00A9\u00877\x15&\u00F7\u0087\u00B0UJ\u00AB\u00DF\x1A\u00EFb\u00DD?\u008D\u00EB\u0096T\x17\u00DAh\b\u0087\u00E7\u00D6\u009E\u009E\u009Dq\u00A0\u0098L\u00A2'\u00DE\u00A3\u00AB\fh\u00E7\u00F4\bI\u00AA\x16b\x06\x19\u00E3\x00\u00CF8\u008C\u00F9\u00CA7>\x04\u0090!\u00BC\u008C\u00AF<\u00EF\u00D6&\u00EB\u00DF\u00FA\x15\x04\x19j\u00C1u,:\x17s\u00D8`\u00B8\u0086\u00F2\u00FC\u00CB^\u00D0\u00A5\u00FE\u009A?Pp\u00BF3\x04\x19\u0092J\u0095X\u00CA\u00AC-\x05>\u00CF\u00AFv\u00DE\u009D}\u008FE\u00F7\b\u0086/9\x03\u008F-\u00AE\u0089\u00AB&\u0086E]\u00C6\x0B<\u00F7\u0082\x149\x1B\x03i\x06\u00A2&\u00C2`\x1E\u0086B\u009F\x0F[\u00FB\u00A2\u00B1.\u00EEI\u00E2;\u0095\u0089\u00A9\u00A8\u0086b'\x15\x1E\u00CD\x14%sd\u00BC\x03U\u008A\x10\u00FEc\x11&\x159X\u008C\x06\u00D2\u009F\u00D1\u00C8\u00D4\u00FB\n,\u00DB\x03l6\u00B4P\u00BE\u00EE\u00CC\u00C30Gn\u00C0\"\u00D6(co\u00BA\x16\u00CFs?0\u00CD\u00D3`Y\u0084?\x1A!PZ\u00BA\x18\u00C2\u00FA\u00DC*\u00F6b\r\u00F4)\u0082U\u009B\t# F\u00AC\x04\u00A2\u00BAg\u00F5\u00BD\u00A4m\u00BB\u00DD\"\u0081\u00C5\u00FA\u00F5\u00F4\u00CE\f(\u00DA\x121.F\u00CB\u00F4+\u0089\u00C1\u0096\u00A8)\x06\u00D2\u00EF\u00D9\u00A6\u00D5\u0085\u008386\u00A7\u00AD\x06\u008D\u00A9\t\x1D\u00F8\u00CA\x104<\u00B3\u00E0\u00A1W\u00AF\u00BC\u00F6<\x00\u00EC\u0097\u00E3\u00F1\u0093\x7F\u00FE\u00F2\u00A3\u00CF\u00E1\u00DF\u00FA%\"e\u00E9\u00F4D\x05\u00C1\x04`\x1B\u00DC\u00AFQq\u00FD\x0600\u00C7\u0093\t\u0088\u00E8\u008BQ\u00DC\u0096\u00FA!\u00A5\u00B5o\u00E2\\\u00EE]\b#c\u00DEq\u00F60lm\u0092\u00AD\u00DE\u00A7\u00C2*bB\u00AF\u00C2\u00F1\x15l\u00DC@\u00D6\u00B2^\u00C2\x15\f\x17\x1F\x186pL\u0095/\u0093V\u00CF\u00BD\x1C`\u00B8\u00B4 \u00AA\u00D1\u00A4\u00FAX\u00D4\u0085JZR\u00C4\u00E3A\u00DB\u0083\u009B\u00EA5\u00D6\u00F9\u00CA\u00A84DN\u00C5A\x06\u00A0\u00EF\u009B\u00957!^#-\u00E1\u00AB\u00FB5\x16\u00C6\u0098\u0083,%\u00DC\u00B9\u0086Iz\u0093\u00B4s\u00C0\u009Ar\u00E3\x05}'\u00801\x1C8\x18\u00DB\u00D8k d\u00CC\u00FF\u0084\u00CD\x19\u00CAB/\u00BCB\u00C9\u00EDd2c\u00C6\u00B9KYu\u00DB\u00A1\u00A8<\u00CB\b\u00BF#\bx\x0E\x1A\u00C9\u00C8 &\u00EF)~\u00C1\u00C8\u00C0,\u00B2\u00EA\u00CC\x15q\u0083Mn\u00E1\x0Ea6\u008B\u00F32\u00D0\u00D0\u009A\u00DF\x7F\u00D6\u00D85\u00A7\u008B\x04\x17\u0083\u00E3\u00BD\u00D2\u0088\u0089\u00AC\x1F\u00A1 #\u00D5V\u0080\u00EA\x19\u00F0o;\u00C8\\foS\u00E8,\u00C6#\u00E3\u00A4\"+\u00E5\u00EAM\x16\u0097\u00A8Gv\x1B\u00CF6\u00CD\u00A5\u0092]\u008Aq\u00CC\u0098{\x1B\u008E\u00F1\u00F5\u00AF>\u00E7_\u00FC\u00EC\u0093\u00FB\u00A7\u00C7\u00A3\u00EF\u00F8\u00A2\x7F\u00FE\x0F\x01\x1A\u0088\u00F8w \u008A\u0094\u00C1\u00A9&\u00C8m\u00A8\u00B0\u00DEr\x05m(/B#j\x18b\u00CB\u00F7b\x06Ys\x00\u00C5@\u00EA:\x1A\u00A3\u00D2\u00EE\u0080\u00DB\u00BF/oq`\u00E9\u00D7\u00FD\u00BC\u00D5\x009\u00CD\u00F05\x18\x1E\u00D0\u008E\u00B0\u00DBZ\u00A9\u00C1a\u00F4&\u00C4\u00FB\u00B2\u00DCE\u009E\u0085 \u00F2KJ!\u00D9\x1F\u00C4\u0088\u008AY\x053(r\u0096\x17#\u00A2t\x15\u00B6\x1Cm\u008B\x11\u0084\u00CD!\u00C6=\u00DB}\x13\x05\u0084\u00D9\u00BEIP=\u00EE8\u00ABB\u00AE:\u00FE\x00\u00C4\bJ\u00B4\u0080\x0B^\u0092-\u00B6\u009F)\u0089\u00DD\u00C5\u0097\u00B5\b\u00C2\u00F0\u00B4D\u00A0\u00A2\x16\u00BB\u00AE\u00EBbW\u008B\u00BC!\u0080\u00F4\u00B1c\u00E9w1\x1E\u009D\u00DFavk/\tx\"\u00ED\x05]2w\u00C2\u00D6Ks\u0096(b\u00A0vE\u00EA\u00C7\x1A\u008A\u00C8\u00FEKZ{^n\u00D9\u00DE\x1D\u00AF\u00C5`\u00D8\u00D1\u0088\u00A4|\u00FD\u00AD\u00FD\u00BA\r\u00ED\x19L\u00F6M]!#\x17\u00D3H\u008FMGG\u0099\u00F8D\x0F\u00C8\x04n\u00BE\u00F0\u0092\u00DD\u00FF\u00C4\u00A7\u00BFc\u00FF<>\u00FB\u00FE/\u00F9\x17\u00EF\u00EE\u00EC\u00B7|IrQ\x1D\u00F0\x07\u008D\u00C8O6\x02/\u0089\x1F:q7\b6\u00EF\u0081\b$\u0089[\u0099\u0081\"\u00D6\x1E\u00DELF\u0090\x0F\u00BE\x18B\u00A1\u0082~\u00AEBxuNg\x06\u009C\u00F8\u008C\x1D\u00AD\u00C5t\u00C0\u00F1\x12.\u0098\u0088\u008A\u00CCW\x1E[\u00C2)\x1D9\u008Dv\u0090\u00F6^\u00FDm\u00A4\u0085^\x19\u00C9@wb\x12\u00A1X\u0091\u00DA\x03\u00C3\u00A6\u0091\u00C7\f(\u0086\u00E0#\u00C3\u009E\x15\u00E2\u00EC(\u0086\x03\x18v\u00EF\x006\u0098\u008Fc\u00CBEb\u00CAl\u00D4\u00FAu\u00D4\x02\x1A\u0088]\u0093\u0086\u0091/H\u00E4\u00B5\u00CAG1\u008A6\x7F\u00BC\x0F\u00A5tm\u00D3.\x04\"f\u00AF2\u00B6@\x11~\u00BF^\u00F3\x0F\u00DA\x00R\x06V\u00FB\u00BA\u00D6\x00WPOJ\u00EC\u00B6D\r\u00D0\u00EEN\u00B9;\u00B6\u00B7D\u00A6\u0084\u00DE\u00ED>\u00CD\x1EP\x04\u00AD\u00A0\x1E\x06f\u00BB\u0096JS\u008D\x1C\u00C9^\x01@\tDRE\\\x1E\u0086[/^\u0091\u00FDg\x1Fd\u00D4\u00F4B\u00BC\u00F5;r\f\u00C6s+\u00C7\x03\u00AB\u0087#\x19R\u00C4\u00B1\x18Z\u00B1\x19\u00A2\u008E\u00ABG7x\u00F5W\x7F\u00ED\u00FD\u00FBg/\u00BF\u00FD\u00BE\u0087\u00FBk\u00B9\b\u00DF\u00D4\u00CB\u00B50\u00AE\x11U\u00826D \u00D1\x15\u00E0\u00D7X\u00F5w\x12~\x0B\"\u00A9\u00C1\u00B5\x1D\u009C\u0093\x19\u00A8\\Z@\u00ED\u00DA\x01I\u0093/\u00D5\"\u00CE\u00ED{2\u0096\u0085\u00BDK\u00DD\u00CEpl\u00F1,\u00B8\x01*d\u00EAP\u00AAu\u009A\u00F5\u00EAA!\n\u00A7|\u00CD\x1DO\u00C0\u00B1g\u0089\u00B6\u00E8\u00C5\u00EE\x11\u00BA\u00AC\u00F4\u00E9\b\x16r\x1C\u00A0\u00C7\u00C0T\u00CE\u00BDBe&\u00FFR:u\u0094/pL\u00D7\u00B6\u00B1u\u00B6\u00DESnH\x10\t\u00CC\u00B0mD\u00FE\x04\u00F3\b,\u0097'\u00F9\u009B!\u00C2\u008Fe)7\u00AA7q\u0082\x10\u00861\u00F0 G\u00ED@n7\u009F-\u00D2\u00C2\u00DD\u00D2\u00A9\u00C52k\u00FD\u0094\u00F45\u00B7Zx\u0090\x7F}\u00A2j\":\r\u00E8R#\u0088\u00D1\x13:\u00D3\u00BB`\x07b\u00EF\b\x0F\u0089\u0096(\u00B0\u00A0yA\u00E4r\u00DB%\u00E9Ir6\u00D8\x1D\u00C7\u00E2|m\u00C9\u00EE\u00C3aG\u00EB\x03\u00DD\u008AF\u0088mB\nn\x11\u00ADi\u00CE*\u00F1TA&\u00A0\x023\u00C6\u00EF\u0091\u00BB0\u00819\u00A9Ry\u00FE\x1DoKFU\u00B1\x131\u00E42$\u00F2\u00F9%\u00C3\u0098\u00A7\u00B1\u00AB_\u0089;\u00D7E\u00C0\u0083>g\u00C4\u00C8\u00A4Z\u00E59?\u00F7\u00E6\r^\u00FE\u00FC\u00E7\u00DE\u00B7?|\u00FC\u00D2{\u00E6\u00BD?\u00C8V\u00EF\u0082\u00D9\u00D7\x00\x1E Kx\u00F3m\u00A6\u009D\u009Ae\u00DD\u00BE\x02\x16\u0098\u00DF\u00DC\u00840\u0094j\u00D0Q\x03\u00DA\u00B9=B\u00B1\u009F\u00D7\u00A2\u00D0\u00F2S\u008B\u00E5\u00BC\u00CB\u0093\u00D4\rk\u00F7\u00B76\u0096\u00DEn\x1B\u00A7\x10\u008AK\u00C2\u0084A\u00F0u\u00D3]Fco\u00AB\u0084\x16\u0083\x1A\u0088b\u00AE\x0E\u00A4\u00FD\u00E1b%\u00F5uMh\u0083\x03\u00C3\x02\x11\u00A9\u00A2s~w\u00E6G4\u00B5\u00C3\u00C8\f\u00A2\u00D2\x12U2\u00DA\x1D\u00E4\u00BA4\u009B\u0090)tAD\t\u009D\u00C1\u00C5\x16+\u00A8\u008B\u0085UD4h\u00DC\u0092\u00A9j\u00DEY\x7F0\x11B${\u00AF\u00D7\u0091\u009F\u00F4\\\u0085^\fU\x0B\u00B5\u00FB\u00FE;\u00B17Cb\u00EA\u00D0\u00DD\u00AA/i\u0098]n\\!\u00F5\u00F8Q\u00B6\x05\u009F\u00CD\u00D0\u00D7\u00AF\u00EF#W\u00FF\x1B\u008CR{b~D\n\u00A6\u00A4\"U\u008D\u00EE\x1E\u0083\u00DE\u00C6R#\u00A1\u00882\u00E7\u00B3\u00CF\x031G\u00CD\u0099~\x17s\u00E1\u00FD\u00D2\u00D5\u00D8\u00E6LjKc\u0088\u0098-Xj2/\u0085v\u008EG/\u00FD\u00FE{\u00F6O\u00F9+\u00EF\u009Eo:\u00E5yC0\x01\x1A\rMq\x04\n8\"3p\u00C1\u00FA\r\u00A6\u0092h9!\u00A3P\u00C1\u00ADHD\u009D\x13\u00F0vv\u0086\u0090\u008Bp\u00AC\u00ED5\u0082\u00B7\u00EC\u00E3\u008E\u0082\u009D\u00B4\x00\u00F7\u00FC\u0086\u0096\x058\u009B11\u00F5{\u0097\u00F7b\u00B57h\u0087\u0081\u00CD\u0081a\u00DCW\u0081B\u00E2\u0086\u0090~\u00A3WasK\u009D\u00D9\x11\u00A6\u00D6\r\u00ABGA\u00F7\x1CP\r\u0082\x0E\u00FD\u00F5\u00AB\u00E5\\\u00E9\u00E5\u00CE]\u00A2\u00BA\u00BB\n\u008EK\u009Eb\u0080\u0089\u00DCc\x1E\x07\u008C\x05\u0089\u009A\u009D\u00C5-\u0093\x1D\u00E5%Lz\u0092\u0094\x06\x00G\u00ED\u00C6\u00C4\x13K75\x04\x02\u00EBk\u00C8\u00D9\x16\u008D\u0096\u00EAS\u00E1\u008F|\u0096f\x1B\u00A15Z\u009C\u00FE\u0089\x19d\u0092\x16W6\u00F5\u00DE\u00E9\u009EO\u00BD\u0090\t\u00E1\u00F4\u00D4\u00B3t:Q\x18\u00B5\bo\u00FD\x11CQ\f\u0081%a)y)\u00F7A\u00D05\u00D4\u00C5}\u0081\u00E9\u00BC\u00F5\x1C\u00C0lR\u00DE\x03\x04X\u00CF\u009E\u00F4>\x0FA\u00C0\x15\u00F5\u00D8\u00C7_\u00F7*\u00E2/\u00F5\x05\u00ED\x1E]\u00B5(\u00A60\u00D9?2\u00C1\u00F4\u00864\u00A6\u00A6\u00A7\u00C1\u00B6\u009E\u00FA\u00CA\u00D7\u00DE\u00BD;^~\u008E\u00A7}\u008B\u00D7\x15\x02\x15\u0084\u00C10\u0088\u00EE\x1A\u00A5\u00E7Sjg\u00ECz\x10\u00A6\u00DBJ\u00EC\u00B5\u00AF_?n\u00AD\u009DA\u00C9\u00B9\u00EA\u00FEk\u00C2R\x19\x19\u00E3\u00D5\u0099\x06\u00D3\u00A3\u00CD\u00DA\x02\x13Zimb\u0090n\u00D4\u00AE\x16\u009C\u0098A\u008D)\u00C8\r,\u00DE\u00EE\u00DCR\u00BET\u0097\u0091\x12W\x11\u0086b\u00C6m\u009Bx\u00D3Vp\u00C6\rdK\u00BD\u00E831\x01\x19\u00B811\u00D3\u00AD(\u00CF\u00CC$\u00F3\u00C8\u00E4\u00A6T-\u00E2)N\u008F\u0080\u009F0:V\u0095\u00E7$\u0083\u00AC\u00D8\u00CC\x05\u00A1\x07o\r\u0096\u0082\u00D9\u0092,\u00A2*\x0B{2\x01\u0084z\u00E4\u00A6\x055P\x16q\x11P,J-8x\u0099I]\u0090\x17\bk\u00BB\x18\u00CA\u00C9\u00D3#\u00E5K\u00CC\u00A1\u00EA\x19\x02n\n\u00C1\u00F5bJ\u009D\u0099\u00F9d\u00DB^\u00DE\u0089\u00DE\u0097DH\"\u00E8\u00D9$7\u00C8\x14\x1A\u0081\nb\u0093I\u0098\u0098\u008ES\u0086\u00BB\u00E7\u00DC\x01\u00C5X\u00D2\u008A\u00D4\x19\x0F\u00E7\u00ABl\x00\u00EDY8\u00D0\x0B\u00A1\u0094\x04G1\x13\u00CECg$\x19T\x06+F!f\u00E1\u00F5N\x03\u00E7\u00D43\x15rr\u00EC\u00AF\u00FBs\u00FB\u00EF]\u00BF\u00FC\u00CE76\x1F\x18$\u00DB\"\u00A6`Gls\u00B2\u00C2\u00FF5\x16\u00A0\u00DB\x0B\u00E8BL\u00CB\u00B6\u00AE\x0BY\u00EB\u009D\u00A0}\u00A06\x10\u00ED\u0092\\\u00FC\u00BC\x1B\x13\x0B\x15tDQjDW\x11\u00C4\u0088\u00F4\u0080\u00E3>\u00B5z\u00D4\u00AF\"\u00FE\u0090\\T=\x04\x07\u00CD\u00B1\u00DB\u0086\u00E1\u008E\u00E1{\u00C9x\x0B\u00F7\u00E0P\u00A6\x1E\u00F6\b-\u0086\x12\u009AT;1<\x10]!\u009A\u00C6\u008D^|\u00D0Uit\x0F\x1A.\u00AD?\x1A\u0091\u0092\u00A2\u00B8\u0099z\u00FC\u00E2\u00D1\x7F7\u009A_\u008D\u00BA;\u00E3<\u00CC\u0094!IF\u00BA\x18\x05{\u00F0\u0090\u00DA\u0094e\x1A\u00F0\u00BE\u00A2\u00F2\u00FC&\u00C1\r%m\u00D2(\u0088|\u00E6\u00B1(e\x11\x07R\u00DA\u0081\x16\x7F\u00BD8\u0086\u00D2\u00DD5C\u0088s\x17c\u009F\u00EENt\u00E0\u00FDw\x11\x1A\u00AF\u00EF}\u00C3\u00865kR\u00C7G\x0EG\x03H\u00EF~\x0F\x06\"\u0083\u00ABk\u00D5w\u0096L\u00A3\u00A1T\u00C6<'s,5\r\u00C8\x1C\u0085\u008Cv\x14\u0083\u00CB\u00C6\u009AAP\x03\u00ED\u008CVcT\x07t\f\u00E8\u008CF\u00CC\u00CCN}-F\x11c\u00A9jN\u00C1\\\u00E6\u00CD\u00F1\u00CE}\u00C7\u00E5\u00ED\u00B1L/X_\u0086@\x03\x0F\u0090\u009B\u00A4`\x07p\x1F]\u00E7\u00D6\u00C6\u00ABE\u00C8*E.c\u00A3\x16,?\u00DB\u00E2\f\u00E9ZFG\u00B9\u00CE\u00C2\u00D8\u00D8\u0089\u00FCl/\u00E8de\u00E8\u00E1\u00C7J\x7F.\u00EB\u00FF\u00DE\u00AE\x03\u00D6\u008AI\rnz\u00DB\u00AD\u00B8\u00E5>8\t\u00E5\n\x03W\u00D8\u00B1\u00D9\u00C4\u00E6;v\u00CC\u0088K\x00\u00F7uH\u0099OF\u0097\x1E\x05\u008DA\u00C9O\u00F1\u00BA\u00A9\x1E\u0087\u00E1\f\u0091\u00FC\u00DD\u0093\u0087\u00D6 \x1D=\u00D7b\u0086\u0096\u00AADy+\u00C2\u00EB \u00B7c\u0095Z\u0093d\u009F\u00EE\x18C\u00F3\u00D7\u0088\u00D85_\u00B1\u00D0Ls\t@\u00F5\x12\u00D9@#\u00D87R5\u009B$C\u00A4\u00FDj\u00E1f\u00FD\u00C2)\u00E2'#\u00CD\u00E2\u00A7lw!\u008AQ\u00DF\u00F5\u00C4\u00D2-W\u00AB]\u00F6\u0080,4\u0092HH\u00E3\u0092pJ\b\u00B7H_\u00C5(\u00C0Uu\u00BA\u00F5\u00A7\u00EE\u009CR5U\u00A6\u00C9\x1D\u00AB\u00E4\nmFI\u00F5\u00AD\f\u00A5\u00D5W\u0099I\u00CC{_\u00BC\u008D\u00B53\x13\u00CEIG\x0BT\u009D\u0084\x0E\u00DC\u00F5]H\u00AE1\x1C?\u00BD\u00F9|=\u00D5$\u00C7\u00E5\u00F1\u00ABo\u00DF\u00E1\u008F\u00DE6M\u00C0\u00D4['\u00AE\x11\u00F9\x07\x11[\x10\u008B\u00BC\u00D2k\u009Dh`\u00A2\x16h7\u00C4I\u00C2gFb\u00CBE(\u008F\u00C0\u00EA\u0092\u00AC\x1A\x07\u00E5\u00BE\u00F3\u00A5\u00FD\u0093n/\x0EkM\u00A5\u00B0\u0086,Nj\u00C6\u00AAj\b\u0095\u00F4\u0089\u00D7\u00BD\u00E3X!\u008C\u008Dx'R\u009D\u00E2\u0092\u00D8E\u00CAhK\u0080\u00CB\u00FDW)\u00C0\u00D0o\u00F9x\u009AM\x00\u00E1a\u00F0\f(*5\u00E2B\x06(\u0095\u00C5x.,f\u00EF@\u00CDc\n\u00EAT\x1F\u00E45Q\u00B95@EZ\u00D4\u00BB\"\u0094Q\u0084\u0092\u0084\x03\u0094\x18N\u00F1X\u0084)I\u00B9\\\u00D7(5\u00D1\x03\x19\u008C\u00AF\u0086\u00CA\u0080\u00D3\u0092\u00CA\u008A\u0082hm5x[\x018\u008D\u00B8\u00FA\u00EBdsX\n:'\x1C\u00A7\u00D1o\u00F6q7\u00A9\u009C\x12\u00D6\x01g0X7\u00DA-p\x1Dd\x06\u00EC-\u00DB\x15sr\x12\u00ECZ7\x01\u0089\br]pU\u00F4\u00B1v\u00E9\u00DE\u00D1A\u00ADs!\x1EM\u00CE<\u009DKD\u00A09\u009B\u00A76\u00DB\u009E\u0090i\x7F\u0098\u0086\u00AE\u00E6\u0099\u00FB\u00DB\u00F6/\u00CEG\u00CF\u0098S2I\u00BF\u00C7= \u0093\u009168\x17\u00FF\u00C0\u0086HS\u00EE.\u00C2\"P[\u00D4\x04\u00C2\u00C0\u0085\u00D8*\"\u00D1\u0093\u00F8\u00B6\u00F5\u00BC\u00D4\u00F3\u00B1\u00A0\u0082$d/\u00E2N\u00A2\u00F5-\u00D5\u0080\u0094\u00A2\u00D9\u00BF\u00CE\b\u0080\u0085\x19\u00F4\u00E3V\u008C\u00C8\u00FBy\x00\u0080-\x1D\u008D\u00AB_\u00A0\u00F7GD\x1A\u00D7f\u00FEA{\u00F70%\u00CD\u0091\u0082\u0081\u00B6\u00A6\u00E6D\u0095e@E\u00C9\u00E2X\\3\u00C1 %\u00AE3c\u00D8\u00F4\u00C4\u00A0\u00AA2pX\u00CD\u00CD\u0086\u00B2Y$\u00EAZ\f[T\x03d\u00B8\u00E0K\u00E5\u00D0\u0082\u00A8\u009C\x0BZ\u00BA>o\u009E\u00B0\\\u0084v\u00BB\u00D2OJ+;/p\u00A1\u0093\ri\x02o\u0084\u0094a\u00D2\u00A9\x1B\u00FBz\u00DDd\u00F8\u00B4\\\u0098$ \u00DDf)E\u0096\u00D1\x7FXxWyV\u00E4\u00C6\x0B\u00C2\u00B3D\x19\u009Di\x18\x19\u00C5\u0091\u008Cx\u0089*\u00840\u0098l-\r\u00D1\u00A4\u00CE\u00DE\x11C!D\u009F#*\"\u009D\u008C\u0082\u00B59-n3F\x11\u00BDxs3\u00B6\u00BE\u0091\u00B7!\x19JC\x12u=\u00B0=\u00BCyf\x7F\x1D\u00AFmS\u00FA2\u00EEC\tIB\x06)\u00BDIx\u008EkT\u00F8k\u00CFV\u0094\u00B4\x152\u00E8\x04\u00D9\t]a\u00C7\u00ED\u00BA\u0085iti~\x1B}\u0094zPRX\u00DF\u00CDV\u00BB\u00C1\u00DA\u0086\x18\x14\u00892\u0083\u00A3\u0092_\u00C7\u00C3\u00B9C51\f\u00EC\x0En\u00CDN7$\u0089+\u00D2\u009B\u00AB\u00ACz\u00B4\u00AAH\u0082\u00DA\u00C2E\x7F[~G\u00A8\x04&\u00B5\u00A9\u0098h\u00852\u008B\u00D8\x01\x05\u00CF\u00EA\u00BAD\bdB\"\u00BA\u00B346p\u00E3\u0098&ae\x14\u008DS\u00A4\u00D6y<&\u00D7\u0095y6\u009F\u009F\bVL`\u00A2\x16<\u009F{\u00A78Z\u00F4\u00D3\n>u\u008E\u00EC\x10\u0094\u0094\\\u00A8\u00DE$kAi=\u00E7\u00F5xy\x02f\u009E\u00A7\u0082\u00A8\u00F2(\u00A8\u00ED@\x19\u00B3]\x1F\fN<$\u00CF\u00F7\u00D6\x17Il\x00\u00C9\u00A8\x14c\u0080fsX\u00D4\u008D\u00D6_(\x00\u00C8\u008B\u00B1\b\u00BDt\x067\u00AB?\u0080\u00FA\u00AA9\u00AD\u00FE\x04\u00A1\u00CF\u00AAe\u00C0P\u0089\u00B2\x07\u00F8\x12\u00B3\u00B00\x1E\x04\u0093\u00AB@\u00ACv^\u00DA\x10\u00E25^\x7Fe\u00DB_\u00B5\u0087\x18\u00B8\u008F\u00E9\x0F`\u00B8\n\u0088\u00EF*\u0081\u00BE\"\u0080i\"\u00E0\u0093\u00E4\u00F7\u00FA\u00F4,(q:\u00AF\x1B\x16\u0097\u00CDTn\x13lq\u00DB\u00C6\f\u00BC3\x17\x0END\u00DDR|;C\u00A9\u00EF\u00DD\u009Eayn\u00FAw\r\u00B8\x1D\u00D3\u00B0\"\f\u00E5\x11\x02\u0083EXO\u009E\x0E\x03\u008A\x01\u009D\u00D1\u00C0\u00E0}*\u00EAR5\x04\x07\u0090\u00C7\u00F5\u00F0:Z\u0091\n\u0093\u00FB4x\u0086\u00D10OB\u0085\u00B9\u00E8\u0089p\u0087<\x06\u008CIc\u00EC\u0082\x18\x07\u0099\u0092\u00F5\x05\u00AC\u0085\u00C4\u00A1\u00A8\u0084Y\x1E\u00D2\"\x12%\u0088X\n\u00C2\x06AtH+\u00F8Z\u00A5W\u00EB\u0092\u00C6\u00B6|\x04\u00CCNHOi\u009B\x0B\u0096Ld1\u0080\x19\x1Cs%\bJ\u00CC4\u0094y\u00BF\u00D7@\u00A6'/\u00F7\u00D6\u0083\x0BE\u00AC\u00FA.b\u00B3\u00A6\u00DE\x00\u00DAt%!7\f\u00C9YZ\u00CA\u00B2\u00A1\u00D56\u00E2\u009Cx\x1F\u00BB\x1B\u00B2^C\u00AB\u0095X.E1N_\u00AE1\x18\u0094\u009D)\u00E6$1\x11\u00ED\x0B\u00BDx\u00A9\x06sf\u00FE\u0084\u00EB\u00BE\u009C\u00A7\u00F0\u00C0\x14\u00F3\u00D8_\x7F\u008C\u00FDw\u00AF^\u0081\u00F9\x13\u0088\u00A8C\x11\u00FC\u0080T\u0083a\u00FBj'\u00B0\u00C6$(\u0095a\u00BDv`\u00A0\r\u00E5.\u0088\u00F0|\u00D1\u00E7\x1B\u0083H\u00BBBG\x07\u00FA\x04\x16\u0084\u00A2\u00C5`\u00E5\u00BD0\u0093\u00C1\x12\u0089\x0En\u0087-\u00F3X\x0BB\u00EA\u00F9\n\u00C5Pz`T\u00FF\u00BD\b\u00BC\b^\u00E3\u00E3\u00B9\x0E\u0084aT\u00FD\u00DC2\u00A48\u00E2\u00F8k>\u00AC1\u00A5\u00F5\x1C}\u00E3\u00BD|5\x1A\x02\u008A\u00F2'Q\u00FB\u00A4\u00ED \u0096\\\u00C4\u00DC\x05\u00E3\u00AB:\t@\u00B7'\fhWjFCz\u00A9\x06\u008B\u00C4`\u0084`\u00FD\u008Ez^\u008Cjt\u009F\u00CDY \u00C2\u00D4\u009F\u00C6\"\u00AE[$\u00F1\u00A4\u00D8g\u00DB<\u00A4'w\u00FB\u009B\b\u00A3\u00FAd4\u00AC\u0095*\u0082$H1\u0087\u00B9\u0094!?Z\u009F\u0094\x03\u0080\u00B4'd$\u00A1\u00A2\x1Fy\u00BE\u00A9#\t\u00BFQL\u00C0CZg\u00A2\u0091\u00E6M\u00F7\u0091Q\u00CF\u00C1\u0098\x04\u00A4\u00E1\u00CF%\u00E53\u00DD\u00BAT\u009DDI\x19\u00FB1\u00A2\u00AD\u00E3(\x03\u00A8n \x14\u0093%\u00E4\u00C5L\x06\u00E0\x17\u009E\x1F\u00CCL\u00F75%y\u00B1\x7F\u00A3\x1B.i\u00D0\u00B4\u00CB\r\u00F6\u008B=\u00C2a\x0F\u0082\u0087\u009B$\u00F1\u0080\u00BC\x04k\u00E0\u00D0\u008E\x0E\u00E3k\u00FF\u00C5N\u00CC\x05\u0092\x01y\x0E\x1Aq)\u00A2\u00CE\u00BA\x0E\u00AFs\x1C+\u00C3 Ax\u009A\u00C3Je\u00F0\x1E\x06-\x02VnEh\u00CFKTbC\x05\u00F5\u00A9\u00DC\u0086\u008E\b\u00C6\u00D2\u009E\u00D6c\x10\u00E9\u00C6\u00C5\u00A2\u00F6\n\u00AEG\u00BD\u008E\u00DA\u00EA\u00CD\u00BAjs\u008Ai\u00E8o\x15N\u00D5}\u00CB0\u00B9\u00A1*\x1A\u0097$7\x14\u00A3\t\u00A3\\\u008D'\u00CA\u00C0\u00C7\u00DF\x17\u0088}X\u00CE\u00EC\u00EE#\u00B20\u00AD\x10G\x19@\u0081\u00B2\tt$P\u00C5<s\u00EC\u00F97\x17\u0099`3F\x0B\u00CA\u00D1\x02\u00AD\u00DF\u0093i\u00A0\u00AA7\u00F7\u00D0c\u00A7\x0B/\b\u00A8\x13\x0B\u00AA\u008D<f\u008B\u00E1\u00CC\u0093({\u009B\u00D6\u00FC\u00F1\u00A1&\u0088\x18\u0095\u00F8\u0093\bB:~\u0087\u00D3\x0B\x02A\x12\u00F7\u00DA\u00973\u00C3\u00A0\x17\u00E2T\x7F\u00A0\f\u00A7\u009A\x07\u00AA\x15\u00CD8X*\u0092\u00DA$\u0083\u00EC\u00A8g\u009E\u00FA4\u0085b\u008A\u00F9\u00D5\u00FC\u0083\u00FD\u00E6:\u00CE\x00%\u0090\u0099pL\b\x01\u00B2=\u00BA`\u009F\u00CAX\u00C3N\u00F8\u00AA]n\u0094C w\u00E3\n\u0081\x157P\x7FK\u00DAWA\u00D4\n\x15n\u00E7`\x00g\u00FBB\x12 \u0089\u00B8[\u00C1\x13\u00F2\u0091\u00D0\\y\r\u00ED\x1C\x11\u0093\u0088z\u00AA/\u00EB9kt\u00E3\x1B\u00A3\x15,\x0B\u009F\u00BD\u00B3\u009D\u00FE}\x1A\u00B2\u009A\u00814\u00CE\x0F\u00D5Cd\u00E6\u00E8h\u00A2#\u0095\"`\u00CF\u00BE5\x14\u00E0;\u0096\u0082\u00A3}n\u00BC\u0098^0\u00C9\u00F5zEN\u0086}\u00B0R\u008B\u00A6\x01\u00C3\u0099\u0086D\u00FB\u0087\u00B6\u0085\x1B\u008C\u00B0L\bl'b\u00D0k1\u00EC\r.\u00E03\u00C1\u00B3\u00AF\u00AEg7sQ\u00EAx,p\u00AC\u00ED\u00B3\u00CDe3\u00D5\u00B6\u00A0W\u00F8o0\x12\u00B7\u00A0\u00B57\u0086\x10L\u00CB\u00D7\u00EB:u\t6\u0083L\u0081\u00C7M\u00CF\x10b\x14\"\u00DD\u00AE\u00CB[#*1\t\u00F5U\u0081F@\u00D6V\u0090\x04\u00AFU\u00C4\u00F6W&\u00E7\u009C\u00AF*\u00ED\x1E(b\r|j\u00ED\u00B2?\u0099ZM&QQ\u0099\x14\x1E\u00ECS\u0096^\u00CF\u00FE\u008A9\u00D5\x031\x18ps\u00C1\u00EE\u00B8\x00\u00CEb\u00A7\u00A9\x16\u0094\u00C7\u00C0Z\x1ArL\u00F7~\"\x1E\x12\x07\u00FF\x1E\x103\u00E9D\u00A1v\u0081\u00DBR\u00BD\x13\u00BC\x18@\u008B\x12\x1Bb.h\u00F7)\u0089\u00BEz\x0F\u00A2\u00CD\u00AA(\u00DCT\x16\u00FE\u00BE0\x05\u0096m[\u0092\u00B1\u00BC\u00DA\u0089\u00B6hg\u00C0\u008EaLP\u009A\u00D6\u0098\u00A1\u00D5=Q\u00BB*\r\u0096\u008AO\u00B5\u00A91\u00C3\u00D4\u00E7\u009B\u009B\u00D2NsR*\u0084\u0088I\x06H2\x03\u00AA8\u0092*1\u00E6bH#\u00DB\u00D2\u00DA#\u00A2\u00CBHR\u00CD\tK|i\u00CDJ\u00FA\u00BAQ\u00CA\x19J\u009F\x15aI\u00BA\u00D1\u00FF>\x0F\u00C0\x0F\u00E6\u00F4\u00CB\u0088\u00E7\u00CB\"\u00CD\u00EF\u00DC\u00AF\x00\u00CE'6\u008F<W\u00D08K\u00C9&\u008C\u009E\u0081D\u00E0'\u00F7\u00A1\u00B7MU\u00D8\u00EF\u00C3\u0088<\u00A8\u0098\u00A3\u00FA\u00A1k\u00CA\"o\u00D5\u00B6\u00AA+\x1DF\u00D5\u0084\u00E3\u00CF\u00B1\x10\u008E\u00FB\u008C\u0080\x12\u00F7\u00E8\u00FB4hC\x141\u00BA\u00D1\u00D0\u00CB\u0098\x06\u009FG0\u0092y\u00B0M\x12\u00FA\u00BC@\u009B\u00AFV\u00F5\u00A6\u009A\u008Bs\u00B4\u00A1\u00B5\u00D8\u0089\u00AA\u00B3\x00\u00C8\u00C0kto\x0E=\x13\u00DEO6\x05\u00B9#=\r\u0090\u009A\u008B\u00B2\u00D1\u00EC1\u00B5W\u009C*\u00AA\f2,\u00B6x\u0082[\f@n;\u00DB\x1A\u0091U\u00E1\u0092U\u008D\u00E8\u00D6\u00FB3t\u00D6=\u00E46\u00E4\u00C3V\x1F\u009A\x11\u00B3\u00EC\x10w\u00BD[\u00DF\u00DA1_>\u00B1\u00DE\u00B338 \u00C7\u00B4\u00B6\u00D9\u0088\u009E\x10ZRZ\u00A1\u00B8\u00BA\u00B7\b\u00BBB\u0089;\u00F3\u00AA\u00F7\u00D9\x13R\b\n\u00ED\u009CB\x1F\x15\u00E2\u00DA\u00E6\"\u00D5#$\u00C3\x0En\x7F\u00F7\u00DCd\u009F\x18tu\u00B4\u00DF\u00B6\x06\x04\x16\u00E9\u00DA\u0099A\u00FEnPH\u00B2R}\u009D\u00AB'\u00A5?\ne\u0094\u00BB\fm#\x11\u0090N9&\u00EA\u00D3\u0096\u00CC\u00C3\u00E0MeX\u00AA&w}\x1D\u00E5A(C\x1C\x19\u00BF\x0B\u00B2{k\u00B7\u008FO\u00D0\u00B9\u0090Cm\u00F7&)\u00DA\u00FA+i\n\u00ACs\"i\u00DB\x11M\u008B\x17.\u0084\u0081\u00EAgJ\u00E8\r\u00E5Z\u00D4\u00F9\x1AKC4hm\u00A7\u00D1\u0091\u00F7q\u00CF\u00AB\x01\u00CE7\u00D6\u0082\u00ED\u00D5\u00D7\x1Ag=\u00ABz\u0099;\u00F6\u00F2&\x10\u00EAZ\u008B3\u00F0N\u00C0\u00D2\u00C9iSh6\u0080\u0095\u00D8\u008B8V\x03\u00DEh\u00BF\u00AD\u0086\u00C2(\u00FE\u00C0\u00EF=\u00F3q\u00F1\u0099\u00DF\u0086\u00DD+\u00D3i\u0086IC\u00B6}\u009B\u00F8\x1A\u00D3\u00D0\u00BD\x16\u00B8\x1B\bia\u0080\u0086\u00C6\x14\u0089\x1A:C\u00B0>\u00B6\u0090\u00D6JbN\u00C6`\x1D\t4\u00B5\u00C4:\u00E3\x00\u00AA\u00DEC\x11\u00B4[p\u00FE2\u00A06\u00F4chc\u00D4\u00B8\u00CFh\u00A7\x10\u009B\u0082\u0094\u0092q%\u00E1\x17iW\u009F<\x17J\u00FCNK\u00BC$\u00E0ls;\u00AFR\"{JAk\u00EE\u00B0\x18\u00AF\u0082~R=\u00C88\x04C\u00E8\u00C1\u00A3I\u00C7\tO\u00EF\u0092\x0E\x02i'\u0090;S)\u00C6\x1D\x0E{\u00FB\u008D\u00D22\u00E3\u00F6\x1BS0\u00CE\u0099{\u00B5+\tj\u00D9_\u00D6\u0093\u00CCpl\u009E3\x0F,AH\u0089\u008A\u0090\u00CC\u00A8\x18\x0E\u00C0\x1D\u0086O\u00CCc *@\u00A9oV\u00F7Y\bY\u00E7\x04\u00E37\u00DEn\u0099\x07^\x13)\u00E5\x03!\u00D4{\u00D4g\x13n\u00CB<i\u00ED8vw\u00C5\x12h\u0091U\u00A8\u00AF\u00A5\u00AA\u00D0\u00A5\u00AF\u00D4\x02!\u0082\u00BA\u00B6\x16{\u008F\u00D0[\u0099\u00C3\x1A\u00C5\u00C8c\u00860\u00C6,\u008CB\u00C4X\u008B\u00AEt\u00F1.\u0095O\u00CC\x05\x15\u00E5\u00D8\u008D\x7F8\u008D\u00A1\x18A\x11h$\u00ECt\u00E2\u00D6y1\u0092\u00C8h\x17\u00C4\x16r\"Wn\f\u00F2\u00B6G\u00A2\u00A2\x0E\u00B3O.oB\u008B\x1E\u00EC*\x06\u00D6h\u00C58\u00E5\u008C\u00BAb\u0087)\x03U\u0092\u00C5\x00I\x0FPcrg\u00C6\x1C\u00BC\u00C0\u00B2\u0084\x00\x18\u00B9\u00B6\u00FA\u00B8k\u00A1I\u0092\u008B\u00F9\u0088\u00A0#Ym\u00C2\u00EC@5\u00D6\x18m\n\u00DBH\u00B5\u00A2\u00F9\u009C\u00CF\u00A8\x11\u00B2\u0091Xl@n\u00C2|\u008Eb\n\u00D5X;\x1E\fhbFb\u0097\u00F8\x17\x06\u00EB\x16\u00C4\u00F8-#,\u00E3\u00FE%\u00B0jL\u0080lD\u00E9\u0093\u00E1X\u0088\u008A\\\x1E\u00A6\u00F8\u00DD\u00AD\u00DC\u0099i8t\x07\x18\u009B\u00E2\u00D9g>\u00F7I\u00E9\u009D\x15\u00A3f\u00CCa\"\u008B\x18gHp\u00AA1I\u0093\u00AA\x18=\u0081\u00A9m\u0083\u00F5,jz\u00CA\u009D|i\u00AA\u0092\u00CE\u00A5\x10rC\u00D6\x0172\x06\x18v\u00C3\u00D3p\u00BC\u0086\u00F2\u00D5\u008BH\u00EFH42Y\u00F6\u00CF\x04\u00A6\u00C9\u00EC\f\u00E4,\u0095\u0081\u00D5hhK\u00DB\u00D9\u00A6\u00A4Z+\u0096R\u008Cde(\u008B\u0094O\"9Cr\u00D4\u00B8\x14\x1F\u00B1\x18\fW\x02[s\x1Ft}\u00EB;\x1CU\u00C6M\u00C7\u0081u\u008C\u008D\u0090\u00DB\u00B1@\u0081M\u0092g\u0088\u00F5y>8\u00FF\u008B\u00AA\u00D6\u00C7X\u00FD^\r\u00B75\u008En\u00C8\\6\u00B4q\u00A5\u009DG;\u00C7\x04F\u00A3\u0087\u00DA\x01\b)\u00D5\u00D7\u00A4\x1EJq8*\u00E3\u00B0\u00E5\x0E$\u0081s\u00B1q\u00E1\u00BB_P6\u0088\u008E8\u008Cs\u00AAx\u0085K.\u00CE0\x18N\u00C4\u00EE\u00C9$R\x17c\u00D0b\u0096\u009D \u00CE\u008B>6\u00FB\x01\u00A3'=\tJ\u00D7n\u00F5\u00BB\x18\u009D\u0088\u00D4[\u00FB\x18\b\u00DB\u0081\u0098{C!b`\u00CE\u00FD,\u00F3\u00DE[\u00EB\u00CFl\u00ED\u00F5\u00ECM\u00D9I.\u00EC\u00D3V\u00EB\u00C0\u00F5tf\u00FE\u00BD0\x10\u00D5[H\u00E9?\u0090\u00B9HY_\x02\u0081\x10\u00CE\u00F3\u00A5k0\u00E1Y\u00B3\u00E2&\u00E6\u00D1\f\u00BB\u00F9\x13p{\u008C\u00C8](\"\u00A8\x14f-Z\u00E9\u00AC\u00DDfp&\u009A\nI^\u00A0q?\u00B7\u00BB\x13\u00B5\u0098E\u00FC\x0Bt\u00D7\x04\x01\u00E9\u00AAL\x03\u009A&n\u00CFI\x14\x1F\\\u00DC\u008A-7\x02\x19\x07\u00B0\u00A1x\u00A61\u00BAqE\x18\u00854jl\u00B91K\u00FE\u00C6\u00BE\u00B8\u0082BH\u0084\u00E7LJG\u008EC.AW\u00F2V\x1B\u008B\u00E7\u00F9\u00B4\x0Bd\x7F\u00DA+\x11\u008F^\u009DY\u00C4\u00F5\x13*\u00ED62\x0EA\u00F1\f\u0086\b\u0081\u008E\u0080,\u0086\x0ByT\u0082\x0E\u00C1S9\u00F6\x15\u00B02\x1A\u00A1Sh\u0098\u00C7b\u00B2\x03>[\u00A5\u00E1\u00D4\u00ED\u00D1\u00E6R\x12-qs|\u00FA\u008E\u0089\r\u00C3\x0E\u00C08\u00B3\x0E8v>\u008A\t\u008C\u0090\u00E21\u00C7A\u0094Q\u00D2\u00ED\u00C8\u00F1$\u00F15Cd>\u00CBD8!\u00AB]\f\u00C0\x0E\u00B8\u008A\u00C6\u009A%\u008A\u008859\u00AB\u00DF\"H\u00F5'%\u00BA\x18\u00CFF\u00E8\u00ADJ\u009AD\x15\u00D6\u00F7\u00FE>\u00C88\x1D*\x18\u00EBv\u00C4F\u00B9\u00A9rq\u00D2\u00FDB\x06G\u00D5,\x11\u00DFd7\u00CE\u008CH\u00EA\x16\u00E9t\x1C\u00A8\u00CAI\u009C\u00F7dH\u00D1\u008Fb\u00A2\u0091n\u00EE\u0089\u00D4.\u00F0}\u00C3>\u00FC-\u0098x5&\u009A\x0F\u00B2$J!\x04[\x18A\u00FD\u00DEc\u00F3o\u00FF~\u0092\u00D0:O\x12\u00C0z\u00FB\u008DI\x106.\u0081?\"\x1EB\u00B1\x18\f\u008A\u0090\x00\u00DCfT\u0092\u00BEg\u00E6e\u00F9\u00DB\u0099\x19h_e\u00EFR\u00D7\x10\u00D2\u009AR>\u00FAM\"\u00B0\u00B0$[O\u00AA\x02\u008A\u00DB7\u00A8\x1E\x0B\u009E\f\u00D1\u00BB\u00F1Q\u00F3R\u0084\u00AB\u00E7057h\u0086A\u0097qp\u009C$\u00FEj\u00D0T\u00F9\u0090\u00F2\x12\u00898L\u0086g\u00C0\u008D\u009F\x01\u00BBG\u00D2m\u00E8\u009CA_q\u009F\n\u00F6!JH.\u00ACE}\u00C0\u0099~-\t\u00CF\t\u00E3\u00B3\u0093t\u00F3x\u00B6)M/(\b/D\x00\u0082\u0089\"pK\u00E9\bd\u008CC\u00C2l\u00AD_y\x05\u00D8'!\u0097\u00A6n\u00B8\fo6I\u00E7b\u0090Z\x1B\u00ABj\x14\x0B@\u00C6\u00CB#\u009E\x7F\u00D6\u0085\u009C\u00C8\u00F8\x1C!\u0082\u00F6\u0092Z\x06\u00CCl-\u00C7\u0092\b\u00A4I}Ix\"\x15\u00B7\u00A6\x1A\u0098\u00A4;\u009F\u0089]\u00F8y \u00D3\f\u009C\u00CFhr\x1E\u008D\u00B9'\x14\x02\u00EA\u00A3\x00\u00DF\u00A2\u00E6\u00EF\u00D7\u00D8\u00DF=\u009F\u00C5\u00BF\u00D9_\u00E4$(W\x00(\u0088,\u00F8\u00D9\u00D0\x02\f&c\u00CF\u009D\u0085N\u0080\u00B2G4x\u009F\u008FD\u00AAC\u00AB\u00B8l\u00ED:\u00C3\u00C2hV5\u00A11\x1C\u008B\u00F3K\u0092\u00EB\u00DCv\u008D\u00EE\u0097\u00D2U\u00D7v\u00C4\"\u0086s\x1B\u009E/\u00E3q\u00A9\f[\u00B9\x11\u00B3\x1FE\u00A4\u0082\u00BF1w\u00C5XJ\u00BF\u008F\x07\x1ALA\u009F\u0080v|\u00CE\u00D4i\x17\u00E3;\u00ABa\u00BC\x1F\x06k,\x0E\u00DA\u00F9d\u00C8\u00EC\u00DF\u0089N@\u00C9\u00CF\u00AD\u00D8\u00C5\f\u00E0\u00F2\u00E8\x19\u00B4\x11\u00CB\u0096\x06C\u00DEILB\u00EA\u0084k>\u009C\u00CF\u00F0\x12\x12\x06@\u00AE4\x12\u00A0t\u00E8\u00B5\u009C\u009A$\x17\u0089/\u00E1{\u00F4:R\u0090\u00C5t\x1C\u00A52 \u00EE\u00B3\u0084\u00F6\x1E@\u00AFS\u00ED\u0092\u00B0\u00C6\u00CF=\u00A4\u00A0\u00E2\x07\x16Uc\u00C0-$\u00B1\u00A2'\x0BY\x18\u00F9\t\x05\u0094ww\u00A8\u00D6\u00D6\u0081\u00CEF\u0096\u00D2f\u0098|\u00AE\u00CC$\u00A6\u009B\x16\u0086e\x0F\u009BZ\u0093\u009CS1\x0E\u00F7Z\u009F2V\u00E2\x06\u00B5?x\u00F7Nh\x1E/\x10b\u00E8q0\x19\x0B1\u00D5\u00FF\x15\u00D5\u00C7<\x1D\u00B8\\=\u0089\u00FD-\u0097\u00A7\x1E\u00DDN\u00DE\x00\x00 \x00IDAT\u00F1\u00BB\u00BB\fL\u00B5\x11J\u00ED\u00B8\u00AC\x12\u00DF\u00AB\u00E4W}\u0083U\u00BA\u008E[\u00C7\u0096\x14hM&\u008D<\x0Bj\x00P\x04\u00D3\u00A5z\u00F5\x07\u00AD\x1D\x11\u00D0mD\u00D2uz\u00DD\x13y^\u00D5*\u00A0\u00AE\x7F\u0087\r\u00E2\u008Cp\x1C\u00C0AC\u00CC\u00E4#\u009BV*\x04\u00CBg\x06\u00E1\u00F2\u00BCE\u00F2C^\x07\u00E4xT|uRzn\u00A97\u00F7\u00F9C\u00F6\u00C5y\u00CF-\u008F\x15\n\u0098\x10\u00BB)\u00A4T\x1E\u0085x2\rNaN`\x10\x19d\u0099/\u0099\b<l\n\u00A9:\u00F4k'\u008A!\u00A4>k\u0094L\"\u00A4\u00C9\u00D3\u00A5\x1B\u00EBaI\u00AF\u00F6\u00D6\u00F7\u00F8{\u00A9]`\u0093\u00F5!b\u0081\u0097QO\u00C7b-\u00B8]\u00E0C#\x0F\u00E2\u00B4\u0083\x062\x11\u00B8\u00ED!ai$\u00B4\u00B4\u00BC\x1D\u00C0T\x7F\u00D0\u0088\u0098\x10\u00DC\x1C>\u008E\u00C83@\u0084\u009D\u00C3z\u0081\u00FD\u0099\u00E0#\u00B4\x0B\u00A3\u00BCi6\x020\u008E\u00C4\u00E5Z<\u00F2:]\u00EC\x12~\u00C3\u00E3^D\n\u00B1\u008E\u008Ed \u0081\x00\x0E\u00C0\u00E9\u00C9i\u00AE\u00D6\u00F0\u00D6\x1C\b;\x00i$\u00A8\u00BF\x18\u00B8\u0091\u00F1\u008DIM\u0081\u00E3\u00CD\x02\u00AF1\u00AEy\u00EF\x19\u00EC\u00D7v\u00EF0\u00EC[-\u00BC2\u00AA-F\u00C5\u0093\u00AAp\u00F7q\u00CEPOD\"\u00F2H\x04 \u00A2N\u00E9p&@\u00B5S\tI\u0096H\u0080\u00CB\u00DB5\u00E8\u008E\x04z\u00DF\u00F8\u00DB\x12dt\u008A\u009C\u00F4\u00DB\u00CC\u00E0.t 2;<vh\u008A\x1C>\u00E4\u00A2V\u00C4\u009F\x02\u0092\x02\u00F6#!\u00BE\u00F2\x0E\u00BC3\r\u008D\u00B3y'\u0082\u009E\x14\u00845R\u00AD\u00AA\x10k\u00A9\b\x1Di\u00E9\u00DFb@\x07F\u00DA\x10\u0084\u009CD\u00F8\"tAqkLAE\u0084\u008D\u00F41g\u009B\t\u00AD\u00F1\u0094\u009C\u0092Z$\u00EA\u009CoI5\u00B9\x1D\x19\u00B0\u00B4\u00B8\u00E6\u00AER\u00EA\u0097>n\u00EA\x14*\u00ED8\"h5\u00D7\u00850t/\u00F5g\x12\x1E\x13\u00C63mX^\x12\u00EBF5\x0F\u00C4\x12*X\u00D5\u009DR\u00AB]\x00\x14\u0092\u00A1\u00B0\u00B2=\u00DAm\x06\u00DAtK\u009E\u00FBF\u009D\u00BFl/D8\u0089z\u009A\u00D1\u00D1UR.\u0098\u0099LD\u00B2\x1D$\"\u00A0\u00D1/\u00D7h\u00A2\u00B3\u00A62\u00A5q\u00F4\u00E0:\u0092\x11Q\u00CF\u00A6\f\u0099I\u00A3i\x006\x1C\u00D7\u00F7\u008F\u00FDm\u00E3\u00FE\u00D7\u00CD\u00F6\u00B7\n\u00A2O\u00EC)a\u00CE\u0092>\r%-\u0087\u00A1\u00A4\u00FAI\u00B2\u00B1\u00BE\u0082+\u00966\t\u00B1!\x04=X\u00EB\u00B6\bU\\\u0092*\u00D1\t\u00B4\x19\x0BA\u0083\u00DEyS\u00D8\u009C\u009C\x13a\u00AB\u00CF\u00DE\x1F\u00A6E\u00F1\u00D0&Y\u00CF\x16{\u00F5\u00E3\u00B0\u00C9\u00EB\u00A92\u0088\u00E0\u008C\u00BBG\u00D9`\u00C1\u0093\u00D2\u00F5E\u00DC\u00F2\u00F9O\u0093{\u0090\x0B\u00DD\u00CB6\u00A0\u00B1U\u009D\bd\x1B\u0089\x10P\u00F5\x1A\u00A6\u00D3]i{\u00DE/\u00B2\x0E\u0082a\u008E6\u00BF\u00EE\u00E1M\x00\u0099\x02\u00BC\u0098\u0084+j\u0090\u00BE\u00F7aB\x10|4\x0E\u008C\u008C\u008C\x03\u00FBY\u00D1vK5\u00E0)\u009D\u00DC\u00A1\u00F8yo\x121\u00D6\u0085\u00D3\x1F/\u009B\u0080`>\tc\x16\u00B3\u00E9B&\u00B2\x1B=\x16s\u00EA\u00DE`?6\u00C0o\u0088j:\u0081\n\u00F6\u0084\u008A\u00E0\u00C9h\u00DA\u00DA\x13\u0094O\x042\x11\u00C8Dc\u00D5\u00B3!\u00D7\u00C4\u0085\u00CB\u008B\x0Ec\u00F7\u0088sp!\u0088#\u00EF\u0095\u00C8\u0085\u00AB+.\x14S\u00B8\u00D4\u00FD\u0098\u00C3a|\u00E6\u00F5)b\u00A7A\u00D7y\u00FF\u00B4?hN\u00B5\u0084\x1Bs6Gz>8V\u00938cL\u00CB\u00E4\u00D6\u00C4\u00C4\u0090\u00C0\u00FD{_\u00DF\u00AFa/O\u00C7[{|\u00FEm\x02+i\u00EAw\x11\u00DFI\u00C7\u0097q0 \u00D5\u00C6\x07\x06fF\u009E\u00DC\u0082\u00E9{o\u00EDf\u00C1\u00CC\x15\u00A9\x14\u0091i\u00D0gTq\x1B\x15\u00E8\u00BC\x1E<e\u00B0X\u00F9I\u008C\u00B85\u00DEU\u0082\x0F\u00DC \u00F6V\u00B8\u00B1`\u009A]]\x00\x1F\u00E0a\u00F2P\u00AFLAEP\u00E2A7\u00E3`{\u00A2\u0093s,\u00D5\u00C2\u00A9N\u008Cv\x0F\u00C0p\u00B18\x16\u0089J\x01\u009F\u0095\x04\u00EB\u0090-\u009D}\u0093\u0094\u00CF\u00C5&[\u0082\x07\u00C1\u00CB\u00FEFUH\x06\u00C5\x0B\u00E9w\u00F0zxEU\u0084p\u00B7\n\u008AIUAL\u00987rC\u00BA\u00BD2\u00848\u00CEq\u009B\u00D4\u00A9%\u00A1(=\x11\u008B\u00BA\u009E\tPu\x1D\u0095\u00B4\u00D6\"\u00FF\x00\u00A4\u00A5\u009D\x0B>\u00E3\x1B\u0092hX\x17\u00D3I\u00B4\u00DE\u00CA\u009D\u00A5\u00BD\u00A33\u0083b\x14\u00E9\u00E2K&\u00A3u\u00DDvJ\u00EA\u0082\u008A\x04I\u00B3-\u00A5:\u00D7\u0092\u00A9\x1D\u00A9%Z\u00F74n\u0082\u00D0\u00DFG\u00EB\u009F\u00DEZ\u009B\u00B2\u00BBL\u0084\x01\u00B7?U\u00F5Qs\u00A0\u00B1\r\x18.\u00E4\u00FEuO\u00F8\rF\x06\u0085\x05Z\u00BBl\u00F7_\u00DE_\u00C3\u0093_\x06\u00AE?P\u0092\u00AC\x11\u0099w\u0082\u00EAj@'\"\u0085\x17sj\u00F3\x1A>hS\u00C4\u00E1\u0099P%%\u00BA\u00F1O\u00EA\x06\u00D6~t&\u00B0\u00F4\u00A1\u00A9/KlA\u00FB-\u00FB\u00D1\b\u00DE\u00CE}\u00E9\u00E39\u00C7\x15\u00C42<|\u00CFi\u008E\u00E2\u00A8\u00A1.\u00B8\u008F\u00F6H\f\u00B7J\u0098\u00F9\u00A0\u00B4\x16\u009D\fLZ\u00A53\u00C1\b\u00C5(tLRbM+\u00AF\nK\u00B2\u00F9%\x12O\u00A6\u00B0G\x7F&p\u0099\x1C\u0085P\x01b\u008D\u008Eiw \x044\"\u00E3gg(\u0084\u00E0~\u00BAq\u00EEUH\u00C4\u00B5Z\u00F7\u00E99\u00C8\u0085\u00ED\u0094\u00C8\x07Ty\u00B9\x16\u00B2\x18\u0087\u00A4\u00DC\u00D1\u009E\u00A9\u008ESM\u00A1\x1A\u00E2i\u00C7\u00E8*CAe\u00F3~\u009D\f\u0097V\u009F\u00B2\u00A2j0\x0B\u0083j\u00C4\u00A8\u00BE\u00CF\u00F2\u00B0\x18&\u00D2\u00DB``_\x19\u00F3\u0090\u00A8\u00A3o\u008A\u00AB\u0095D\u00F4#\u00A3\u00B4;\u00C7\u00D2\u008C\u00A8\u008D\u00B0\u008B1\u00A9\u00EFV\u00E3\u00C9{L\u00D8\u0094\u00D7\u00E3\u0080\u00D3\u00F6bhh\u00AB#\u0092|\u00C6\u00CEg\u00B4\x018\u00B0\u008F\u00AB/\u00EF\u00CF\x1D\u00CF\u00BE\u0084k-b$A\u0084kO\u0092\u00F9.\u00DD\u00FA\u00C44`\t{\x04\u0095\u00CBp\x18\u0084\u00E9\u00CB\u00B5'i\f\x04sH$\x02t\u00C8v\u008B\x01\u00F4\u00F7\u0089\u00D9X\u008F\u00CA\u00F3\u00B1\u00DE\u00D3\u00B0\x10Xg\b\u00E3\x1C\u00F5\u00A8\u00E8C\u00DFh\x00Dn\u00A8\u00AA\u008DP\u0090S<\u00A0\u00AD\u00BC\u008B8\u00B38W\u008E%=\n\r\u00B5\u00F4c=\x0E\u00C1\u00AD3\u0083\u00EEv\u00C4\u0082\u00C2\n(\x0E\x1C\u00EE\u00B4bKN:\u00B6T\x11\f\u00F3@Z\u00B9\x0F\t1G\u00E6\x0E\u0089\\<\u00AFAJd\x03\u00DD\u0092\u00B31\u0088\u00B4\x17\x00KJq\u00C0\u00C3\u00B6\u0090I\u00C8$\u0088\u009C\u00B9<\x0F\x15m\u00A7\x05\u00EB\x06k\u00C4\u00E9\u00E9q\x10\x10\u009E\\\u00E8\u008C%@\u00B3\u00EF\u00B0\u00BF\u00D2\u00F1\u00B5\"B\"\u0087\x0F\u00DE\u009A\u00C4\u00F5|\u009A\x16\u00C6\u00C7\u008C\x13\u00E1\u00BArURB\u00F5=\u0091\x02\u00BDn\\\u00EB.\"%\u00B3*$\u00A8I\u00EE\u00F3\u00E6\u00C1\x14\x18\u009E^\u00ABFj\u0091T\x1C\u008E\u00D7d_:`\u00B8\u00D0\u0088\u00ED9'A\u00B3\u00B3\u00BE\u00AB\x1Ax\u00AAb\x07*\u00F6 tC\u0085D_\u00AE\u00AF_\u00DA\u00AFn\x1E\u00BC\u00E8\x0F\u009Ad\u00CC0\u00D7\u00AE\x1A\u009CR\u009F\x11\u00D0\x1B\u00BEU,Q\u00BA\u00C86J\u0095-\u00F4\u00FBn\b\u00C9\x7F\u008B\u00DB\u00AD\b\u00A1\x11\u008E\u00EE\u00D1\u008E\u00DF\u00A5\u00CA\u00DC\u008Az\u00ECD\u00E4\u00AD\u00AF\u00C9\u00A7\u00EFj\u00E7\u00AE7\u00E7\u0084D>\x01<\x060\u00AD,\u00FEQ\x12\u00BDvY\u00DA\u00B1a\u00D2\u0096\u00A09\x14$\x17*qF \u00A6G\x02\u008A7\u00A0\u009B\u00D0\u0094\u00C2\\\u00E5\u00D3\u00CBKA\u00C3\u00A1\u009E=\x1F\u00AD\x02i\u00E1\u00C0&\u00A2\x04m\x01\b\u00C2\u00DF(\u00D9e\n\x18\x0El\"b\tQ\u00A7\u00B1\u009BD,\u00CF\u00C3\u00C1\u00DF\u0086\x18\x04\u0080J8\x02\u00E9\u00DA\u0080\u00C6\x1C\n\r\b-\x00\u008Bz\u00B0d#\u008A0\u00B5\u0096t\u00AE\x0E\u0088\u00F17\u00BD9\u00D7P#\u0080\u00FCI\u00C2J\u00C4E+}\u00CC\x00*\u00BA\u00F0\u00EC\u00AAT\u00BBjC(eFP\u00CF\u0082\x1E\x1A\u00EA\u00F5\u00AD\u00AC\u00F5\x1C\u00D7r_\u00D7\u00BA\u00EE\u0091\u0092\u00ECKC'1\u00A2f\x07\u00D0\x10\x15\u00C0\u0094FC!\x06y\u00E0@\u00B4\u00A3\u00DF\u0091\u00CCW\u008C\u00CE\u00C7\b\x1B\x0F\x06r\x1F\f\x06@E\x0F6\u00F8\u00F6\u00C4\u008B\u00FB\x07\u00F6g~?R\u009C\u00F9\x10\u00D2g\u00DF\u00A5q'\x1E1\x0E\u00E35\u008D\u0098\x15\u00DA\u00ECa\u00B4P6^\u00A9\x07\u00FA\u00DEl\x0E\u00B6\x12\u00BD/\u00D7\u0094G\u00A0$\u00B6\u00CEGNtF56w\u00E2\u00A2B$\u00B3\u00AA\u00BET\u00FB\u008E\u00BB\u0099\x03%2%\u0084\u00C1\u00F0\u00C8\x1D7VL\x00\u00B0|\u00C4Q\u0081\u00BA\n\u00A4H\u008FW\t\u0095\u00A8\u00B1\u00D7\u00BC\x05yN\u00F3\x17\u00EBoC^\u00BFVP6-aLlY\u00A99%7%v\u00D8\t\"\x02^\u00C1E\u0092n\x13M\u00E2\u008B&[j\u00EC\x007{\u00C9\u00A7\u00E2i\u0080\u00D55\u0083\u00CC@9\u00FB\u0099\u00DF\x0Fkk\\\u008CA\u00CFI\u00CF\u008C\u00CF]\u009D\u00F2\x1B\x14,\x16\u00B3\x00J\u008D\u00B8\x0B\u00CA\u00AB\u00DD\u00A6\u00E3\u00E7w]\u00D3U\x11\u009D/\u00EB~\u00BDs\x13Z\u00A9\x1C\u0099\n,\u00F4\u00B2\u00BA\u0090\x13\u00B1\u00A0$7\u00D0}Ozi\u00DD\u00CA \u00DA\u00D5\x10\u00A0\u0082\u00B1\u00D2\u0090\u00C3\u00F9ij\x16,\u00CE3\u00CD\u00CBy.v\u00C0/0y\x1B\u00D2{\x13\u00F3\x1CZ\u00C1%\u00FB\u00EB\u0090%KQ\u00C1D\x0ED:\u00AF>\u00F3\u00CC\u00EF\u00EFo\x1Do\u00FB=;\u00EE\x01\u00FB\r\u00BA\u00AD\u00A0b\nDDEL\u00B91\u00AA\x1B\"vAS1\u00928\x0Ba\u00E8\u00D7Fhs0\x7F\x7F;\u00B5\u00DBU\x04\x12\u00A9:\u00DE\u00F5\u00FE\\`\u00F4\x1E\u009Cb\u00F5\x03\u00EA\u00D5\u00FD\x15\x1B\u00B0\x04?\u00F1\u00FCq\u00BE\u009F\x18\u0081\x16\u00B8U<\u00C6a\u00A5\u009D\x1D\x1E\u00B1\t{\u00DA\x11\x14\u00C9\u00B9%\u008C\u00B7\u00BC\u00F7\u0096\f$\u0090\u00C1\u00C6\u00CA\u00C9e#0\u00A2\x101\x14A\u00D6\u00BEE{\u00CD#\u00AD\u00D2\x19\u00F3 \u00A1a\u0090\u00A4\u00EF\u00C2\x07m\u009D\b\u009A\u00BB{,\x11\x0F\u008F\u008B\u00BC\x03a\u00EF\u008A67g\u008F\u00E9\u00B3\u00CE\u00B6\u00A6P\x02\x19\x11\u0089.\u00DC\u00F0Z\u00D8:\u009F\u009F\x07\u0090\u00A9\u00CE\b\u00B9d\u00CE\u0080\u00A1\u00B6\u00D7b\u00BDF\u00DD,\t\u00B0\u0090e\u00D4/\x10\u008A\u00E9\u0088\u00B3\u0090\u0087\u00DB\u00803\tHi\u00C1u\u009FK\u00AD%\u008E\u00B3\u008C\x7FL.b\u0096TT\u00AF:\u00E0\u0098\u00E4\u00A2\x1A[1\r\u00A3@\u008D0\u00E8\u0089\u00A8\nMF\u00C15l\u00A6:V\x13\u00DA\u00C0x\u00D8`\u00D7\u00C94l\x0B{\u0082]8O\u00D71Of\u0088pkn\u0098\u00CB\u0087\u0091\u00D0_\u0091\u0093\u008AC\u00B0#<C\u00B6sLV\u00AB\u00D2\x1CU\\76\x1Fr\\\u00B0\u00BD\u00ED\u00A9\u00DF\u00DB\u00BF\u00FD\u00FE{_x\u00E2\u00F1\x03\u00BC\u009AK\u00B8\u00A9\t\u00A9\x12T\u00F6b\x11\u00FEz\u00EEB\u00BC\x0B$\u00EF\\3\u00A2\x13C\u0098\x17Q\u00BFQ.ATG:!\u0094\u00C5^\x10\x7F/a\u00CF\u00A7w\u00A2\u0082S\u008A\u00F2z\u00AF\u00BE\b\u009B\u00FD\u00A3y7\f\u00C0\r\x06\x1Ec\u00C3\x05Q#cR\u00A5p7\x1C#\u008A\u0099N_4@T\u00ACB\u00F4\u00F3 \x132\u008B\u009A\u0083\u00DAXe\u0082\u00AEPp\x07'\u00C8\u00C3P\u00FDL\u009DX\u00B9\x11\x1E\x15q\u00B4.\u00E5.T\u009D\u008D\u008B\x03\u00BB#\u00AB\u009C\r\u00A1\u0082&\u00E1\u00C1:~\u00E3\u00E0\x1D\u00A8\x1A\x00\u00B41\u00A4\u0084\u008D\u00CF1\u00A3\u00ED\u00EE\u00A50\u00D1dJ9^C\u00DA\\\u00EB\x01\u00F0\u0099M1\u0099.\u00B5\u0081\u008AS\u00F0\u0092\u0092\u00D9\u00BET\u008B\u00A6[\u00DF\u00B2\u00C87\u00E2\u00F0\u00C95\u00C7\u00F5\u00D2\u0082\u009B\u00A2=qI\x14\u00B1hM\u00A5$\u0096Z#\u00E4\u00A1k.\u00C8\u00BD\u00B8Z\u00C0\u00D5\x12\u0086\u00AC\u00BE\x13\u00CE\x07\u00F3\u0092\x17\u0084B$m\r\x1A\u008B\u00C6\x15\u00EDZ\u00BA@\u0085\x12\u00B8\x1E;\u00D7\u00B7\u00AE\u00FE\u008C\u008A\u008F`\u00BF\u009C\u0088\u00C3\u0096\u0084+C\u0097\x1A\u0097ax\u00EA=\u00EF\x7Fa\x7F\x1F\u00BE\u00EDw\u009E\u00F5\u00A7\u00F1*^\u00BFE\u00F4\u00D2qW&\u00A0A\nz\u0090\u00D0,\u00A4\u00A9\u0088\u00D5\x16b\u0093NG)\u00B7\x18+\u00D1\u00E0XIF\u00F3\u00B6_d2\x1B=\u00D8\u0091\u00E7\u00B9m\u00B1\u00E1\x04\x1A\u00AC3k\u00E7\u00B5\u00FB\u008B\u00D1,6\u008B\u00C6\u00D4\x18Gp\u009B9IZ\x03\u008F)\u00D1\x0F>\u00AA\x1BD$\u00FBt\u00EE\u00DDh\u00B1\u00D1\u00AB\u00B6n\u008F}\x12\u00AA\x16B\u00EE\u00A1\u0080\u00F0V\u00C8\u00AD(\u00BB\u00C4\u00C1\u00FB\x1E\u009C7\u0095r\x17\u00969\u00E0\u00DCg!\u0088+\u0089\u0093\u00EFd\n$\u00A2\u00C3\u0081\u00CD\u009D\u0085sbQ\u0087!\u00D1\u00C3\u00AD\u0098UxCj\u008F\u0089\u00F4r\x04c\x18!\u00F4e\u0088\u009ChFJ\u0084\u0097\u0082k>\u00E8\u00AA\x13\u00F0\u0099\x19T;\u00B9\u0096\u00F4|\u00FC\u00B22\u0095\u0084\u00FB\u009D0\u00BB\u00FE\u00AC6$\u00F5\u008F:\x1FjG\u00D7v\u00C8\u00DDaw\u00CFI\u00A0\x14\u009DB&\u0092\u00EC\x1D\u00D2\u008Bi\u00CC\u0090\u00BC\u008DH\u00B3?i_`\x1E\u00C1\f}\u00DDR\u00E7\u00AF\x1C\u00880\u00B0^\x1A\u0093\u00E9\u00CC\u00AE\"K\x16\u00E9\u009EL\u00D2s\u00CD\u008A)\u00AE^\u008C\x1E\u0089\x19\u00F1\x06\u00DER\u00B9\u00CBs\x11\u00DF_\u00BF\u00DE\u00F0\u00CC\u00F7\x7F\u00FF\u00EF\u00EC\u00DF\u00EDW\u009F{\u00CE\u00DE\u00E6\u009F\u00C7\u0097\u00CCN\u0084\x13\u00D2WD\u00B2\u0086\x0E\u00DF\u0085\b\u00ECD@uLL\x03\u00D9~\u00A9\x07\u00C8\u00F3U\u009C\x05\u00BAg\u00DA)Z\u009B>\u0080q\"\u00EEqF\x05\u00EC\u00D7\u00A2\"4{DC'\u00A9\u00E6\u00C0V;Vcj\u00F2\x1A\x18\x19\u00C0\u008D\x1B\u00EE\u0091x\x0F\u00C4\u00CE\u00CF\u00831\b\u00E5k\x0FUBh\u00C1A\u0081\u00E8H\x15&\u0093\u0094,\x18\u008AQ\u00D5: i-\u00E6\u00A6\u00D8t0\x0F\u00A1\fz\u0087;\u00B6\\\u00B3\u0096h =j$z\u00B9\u00E9\u00B2|V\u00EA\u00FE\u00D1\u00A9\u0083\x06\u00C19-#\x7F\x01_\u0099MC\x06b6zml3\u00D1\u0082\u00D6\u00BD\u00DE@\x11\u00F2\u00B4\u008A~<t\\\u00F6\u00AA\u00B8\u0099\u00EA\x07\u00CA;\u00B2\x18\u00FF\u00FC@\x16N\u00C9E\x1D$\x14j\x14\u00B1!\u008B\u008Ff\u00B2\x15]*!\u0090.A \x19\x0E\f(\u00A6\u00A1\u008C\x7FB\x17\"`1\x0B\u00ADI\u00D1\u0084\u00A4/\u00EA\u00B7d.\u0092\u00C6JO\u0096\u00B4\u0096\u00FA$\x15qk\u00E7\"\u00DBKuqr\u00B51\u00932\x12\u00B38o\x1E\"\u00AAB\u009F\u00DBs\u0080W\u00BF\x01\u00AA\x1D\u00A2\u0083x\x00\x0E\u0083\u00BD\u00FDi\u00C7G?\u00FC\u00B9\u00FD\u00D91^\u00FD\u00E1\u0087\u00FF\u00C7\u008B\x06{wZ\u00F6\u0097\u00D0c\u0094\u00C7`\u00D1\u00E1Hp\u009A\u0098v~}?\u00878\u00EB\u00B7\u00DB\u009E\u0085z\u0097[Q\x06\u00BDx\u00F5\u0089\x13\u00DA8\x13w;o\u00B9\x7F\u00DD\u00A7\u00F4q\u00E3\"\x12\u00E3\u00A0\u009DA\u008CF\tF\u00A7>>\x06\u00F0:\f\u00F71p\x10\x05\u0084aMR~\u00B0\u00F4=U\x05\u00E5<\u00B8\u00BC\x04\u008C3\u00B0\u00B6\u009B3\u00DBQ\u00C9\x14\x00\u00A9JH\u00CD\u00D0k\u008A\u00F0\b\u00DF\u0093&$\u00C4\u00B8\x10f IHJ\u008FYR?a<\u0089\u00D1\x0E$c\u00B0Yl0\u00D7\u00BE\u00DA\x012\x11j\u00B0\u00AD\u0083\u00C7\u00D3\u00D8\u00B8TH\x02\u00D6\u008E\u00C7\u00FD\u00E2\u00FE\u00D6\x10\u00EBh\u009FM\x1A\u00EB\x128l\u0091\u00EC\u0082\u00C3\u00DD\u00D0\u00A6k\x1Ba&\u00D4\u0097\x14\u00A7\u0084\x16\x03\u00CA\u00F9\x1Ad\x1E4\u00BEI\u00E7\u0097\u00AD&\u008D\u0094\u0092\u00BE\r\u008E{\u00CB\x02\u009D\u00DDS1\u00B0\u00D8=|o\u00E3\u00D2\u00B5^\u008CA\u00EAH\u00F6U\u00A2\u00A4\x19/S]Rx6\u00DB\u00C8\u0089\u008A\u00F9\u00B1^/a\u00A1Y\u00A9&\u00BE\u00B4mp\u00DC{\u00F2\u0099\x17\u00ED\x03O\u00BD\u00BA\x03\u00C0\u0093\u00FE\u00E03\u00C0\u00FE\u00EE\u00AA/\u00D0uvC\x05\u00F5H\u0097m\u00A5\u00BC\u00A8\x0B\x17\u00F1\u00DC\u00A5\u00A7\x17\u00F2\u00E8\x16\u00F6\u0085\x11\u009C\u0083\u0087\x12\u0081\u0088@\u00CBh\u00B7\u00A8.K;w\u00C3\u00FD*w\x06\u00F4\u00E2\u00A8\u00F34\u00A6\u00BE\u00FDZ\u00E9y\u00C5\u00C5\x1D\x03\x17\x00\u008F\u00A0\u00C8\u00C5\u00B0\u00F4\x1FV\u00D1\u0081\u00B1\u00ED\u00FBP\u00AF\u00A1\u00E0\u00A2d\f\u00A6\u00DD\u0098\u00C2V\x10\x19\u00F3UeIp\u00DD\u00C4,\u00C0\u00D0hg0\u00AB\u00ECZ)\u00B1=\u0093\u0093\u00FA\x1Bn\x18s\u00F2\u00B1S\u00DEM\u00C31\x01;\u0082\u00C0\u00E6\u0094\"C\u00B67\r\u00F3p\u00C0,\u008Dp\u00CA\u008A\x17})U\u009A]\nd\u00E0\u0080O\u00C3\u00D1\u0098\u0081\u00D8\u00B3\u008B1\u00F1\u00FA\u00CE\u00B4\u00C4p\u0096\u00C8CHB\n\x0E\u008B\u00E8\u0081e\u00B3\x15\u00BD\u009B\x1B\u00B1\u00CEkR\x1F\u0088\u00B5\u00EA\u00CA\"\x14\x01v\u00DB\u0085\u00B8\u00A3\u00DA\u0094\rB\u008C\u00CA\u00EB\\\u00AD\u00AB\fzj*L2 \u00ED\u0092\u00E1\u0080_\u00C1z\u00DFx\u009DCi\u00C84\u0084v.\u00DA\u00ED\"BF\x0B\x13\u008C\u00B9P\x1B5\u00EE\x01\u00D8\rJ\u00BDo\x13\u009ELS\u00C7\x15P\x15(\u00E6\u00F1\u00BDg?\x03D\u00E2\x00\u00DE\u00E6\u00EF\u00FC-\u00F3\u00AB\u00FF0Cd\u00E5Ah\u00D23\u009E\\\u00AF\u008B\u00D0\u00B8\u00A8e`k\x12TO:\u00EA1\rk\u00AArSQ\u00EEHG\u00EE\u00E9\u00CA\u00E5%(\u00CF\u0084e;\u009D\u00C1(\u00B0\u00AA\b_\x0E\u00CFz\x15cZ34\u0089\u0088\u00B2=\u00DC\u00D9\u00A7G6p\u00E3\u0083\x06\u00C4 \u00E8\u00C3\u00C2\u0096p\u00806\x04>\u00E6\u0083\f \u00C3M<\u00A2\f\u00E5a\u0098\x1EhA\u00A6&\x19\x1DG_&'\u00EFA\u00B7\u00B9i\u008DM\x12a\u00DA\u00C0P\u00814N\x06Q\u0081F\u0096\u00C1E\u00DD\u00B8\u00A8\bF\u00E7q-\u00D1\f\x04Jf\x13m\x0F\x00\u0098\u0091\u00A9)\u00D4!\x17dn 2{\x1F\u00B40k\u00ED\u00C7\u00EF\u00BC\u00D9\u0082.\u0082p\u0087[X\u00EByN\x19\u00FBZ[\\\u009F\u0095\x1BA7\u00AF+\u009DZ\u00D7!t\u00FA\u0094\u00C6\x17(|+\u0089\u0099\u00CF_\u008CB\x15\u00A1J=\u0096\x0E\u00CF\u0088\u00C5\u00B4A\u0088V\u00C4\u00B1\x15)(D\u00A2\u00F3\u0080>\u00FE\u00A4\u00B5zp\u00CB\u00BA\u008E99\u008A\x1E\u0092\u00A1\u0095\u00D8P\u0088\u00B4\u00FB%b\fR\u00E7\x13s\x0Btc4>z\u00B8|8\u00CE`]7\u00CF\u00DC\u00FB-\u0080\f\u00E1;\u00E7;?\u00BDM\u00C3\u00DC|!\u00DE\u00D0\u00D7\u00B7\u009C\u00A8\u00D5#\u00D0\u00E3\x15z~\u0082-\u00C7o\x13l'4C\u00ED\x04e\u00ED>\u00D4\x053\u00F3\u00B23\u00A0\u0080\u00F6\u0096i\u009Et\u0083\u009E\x19L\x12\u00BB\u00DA\u0094\u00AAQ\u00F6\x02\u00F5S[\x7FW\t\x00\u00E3sk*Q\x1A\u008E\u0080G\x03x\u00DD\f\x0F\u00B0\u00E1\u00C6\"\u009B\u00E0\u00A0\n\u00B1\u00A11\u0083\u0094\u00F0\u00F1\x1EtgM(\u00E2@\u00F9\b\u00F4@44\u0096\u00E6+\x1A\t\x1DXlj\u00D3\u00C1\u00EC\u00C5\u0090\u00FA\u009E\u0092\f\u0099\u0093 \"\u00E8\u0086\u00C79\u00B5f\u00A9v\u00A0\u00CE\u009D\u00EE8<\\\u0089\u0083\u00F4\x19\f\u00C8\x0B\u00B9\u00CC\u0098\u009F\u00C1\u00FEH5\u0091w\u00C2i(I\x06\u00A0\u00CDX\u00D2 \u00BE2\u0084[\x04\u0082bH\u009A{m\u00BE\u00BA0\x00\x11rJz\x11qAi\u00C1{KI\u00DA\u00A5\u00BC>\u00BD\u00AD\u00BDhgIv\u00D2\u009AHBT8qC\x12\x1C\u0084\u0083kR\u0097\u0085o\u00B8\u00EE\u00D5=\x10\u00EA[2\x02\u0096i[<,\x13\u00BEx\x19\u00E2\u0098a\u00D6\u00FCr\f\u00F1\u00DF\u0080\u00C9H\u0099\u00E8b\u00AF\u00FB\u00BAvyo\u00F3\u00CE\u00CE\u008Eg\u009E\u00FD4@\u0086\u00F0\x1F=\u00F9\u0081O\u00FE\u00AF7\u00F7\u00F1x<B\u00AA\f\u00D6\u00D0\u0081\u0095\u00B4\u00CF\u00E4 \u00D4\u00E2\x15\x11e\u00D4aJv$d\x06\u00D6sW\x14\u00C1cM]Y\x19\u00C8\u00D6R\u0095\x01\x1B\u00CD\u009D\u00D8\x19\x14\u0099\u00C2\u00B8u\u00AFB\x1F\u00B3\u00A1\u008E5\u00FD\u00B9Im\x04\u00C20\u00A9\f9\u0083\u0080\u00A2\n\x1F\"\\\u0090W>p\x05\u00C7Aubs\u00C3f#5\u00BF\u00CDA\u00A2G\x04k%\u00BC\u008C{o\\\\\u00B1\u00D6=\x17Q\x12\u009F\u00D7\x1A\u00E9\u00DB\x13\x18\u00D7\u00CC\u00CC\u008E\u00AD#\u008E5\x15\u008B\u00DD\u00A7\u00D5\u00B9\u00B2\x1F\u00E82\u00D2HT\u00D5\u00B2(\u00A3\u00D6\u00DA\x01=\x14\u00C2Y\u00DDk \u00C4\u0090\u00F6\nh\f\u0084\u00C2D\t[g\x02\u00B3}vt\u00A0\u009BNp\x7F\u0087\u00FA\u00BB$\u00BC\x04\u008E\x17gL\u00A8\u008F *T\u00FF\ny\x04AL\u00D6h\u00A814\"\x17SH\u0095A\u00F7\u00E9u\t\u00F5\u00DCnP5 \u00AC\u00EE\u0093\u00D1\u008E\u0086\u00CA5\u00B8\u00E8\u0089\u00C4\u00BA2\u00E1ON\u0082_h{\u00D8\u00D6{\u00E78v\u00DC\u00AE\u00C4\x14\u00A82B\u00FDew\u00F0\u00D6\u00FFH\u00EFN\x1BC\u00DA=\x06\x1C\x17\u00A2\u00BET\u00EApc\x13\u00C7\u00F7}\u00D7'\u00F13d\b\u00EF\u00C03\u00BF\u00F9\x1D7\u00EF\u00C7\u00A7\u00F7\u00CFB\u00D5{\u0093\u008B%\u0091v\u0088]Du\u0097\u008D\u00C1s9\u00E9\u00A6g\u00DD\u00BE\u00C1\u00F0;U\u0084~^cP9\u00D9\u00FD\u00DC\u00BB\u00FAV\x13\u00A7\x18\nW\u00FB\x19\u00B8THe\n-,}U\u00BB^\x7F\x1B\u00B2\u00FD\u0087\u00EEx\b\u00E0\n\x03;\x0E\u00EE\u0095\x1D}r\u00A7aQ\x01Q\nU\u00E6xB\u00C8\t\t\u00B0\u0090\x06,\u00F4u\u00EA\u00AD}\u00CD\u00A7\u008B\u00AF3\x07.\x11\u00E5\x16\x00@\u00ED\x1C\u0084\"\u00E2N\u00C0\\d\u00B9\u00A1\u00C8A\u00A6\u00E1\u0096R\x1E\u00B3?\u00E1\u00F8\u00ED\u00F0\x16SI/D!\u0094b\n\u00EE\u00CE$)2X\x17r\b\u0082It\u00D0R\u00A9\u00B9&qr\u00F1\u00D4wO<\u00A2A\"P\u0080H\u008CD\r\u00CD\u009D\u0092x\u00BC\u008E#\u00D0\u0082y\u0095\u008AO\u00FBDN^\u00BBq\x164\u00E5D'z\u0090\u00E4\u00BEB&\x1E\u00A5\u00B7@\u00C8\x04\u00C8\u00BC\x01\u00F6\u0081\u00D6\u009F\u00EAS\u0089wT\u00AC\u00CBD\x16\u0083\u0091\n\u0092O\u0099\u00E8\x07\u00ED\u009D\u00AE\u00C3\"\u00EC\\\u00AB\u00F2\u00CA\u00A4-\u0084c\u00B4`p\u0096\u00DE\u0094(U\u00E7\u00CF<\u00C0\u00DB~\u00EC\u0087~\x13\u00FF\x0B\x19\u00C2\x07l\u00FB\u00C2\x7F\u00FC\u00E8\u00FF~\u00F1S6\u009E+X]\u009DM}\u00C5\u0094\x11)\"!|o\u00D2\u00F6\u0096\u008D`a0\u0094\u00E4Y\x0Fad\u00DBqE\u00E9\u00F6\u00D9\x0F2\u009CE\u00A7\u00CF\u00F6\u00D7D\u00A7\u00F2 \u00D4\u00C3Mf\u00C0v\u00D4\u00CF\u00C8\x06\u0095\u00E5c\x14?pF?vx\u00DA\u00CA\u0094\u00C9xz\u00B1@\t\u00F7a\u00B8\u00F1\u0081\u00C7\x00\u0086\u00E7\u00EE\u008F\u00D0>\f7\u00ECS\u0094 \u00A7\u00A11\x13\u0093b'\u00E92>\x16\u00D1\x06\u00D4\u00F7\u00ACc\u00A0\u009D\u00A2S\u00A0\u00BA\u00B6fkk\u0086k\u00ED\u00A0\u009A\u00A1\u009A\u009AZ\u0087\u00C9<x\u00A2)\u00EBq\u00D6\u00B9\u00AA$\x16\u00EAD\u00F4I\u00B1\f\u008Ep[N\u008B\u00DF\u008F\u0089B\r\u00B3\b>J\u00A2\u00F3)\u0092QT@\u00945B\u00D5X\u00AD\u00EC\x16\u00CB\x1E\u008B\x1C\u00BB\u00C60\u0089\x14\u00B8\u00D3r\u008D\u00CF\u00B1\x06(\u00A1\x11\x0F\u009Fa&Tu\x1D\u00BC\u00C1x\x07!\u00B7\u0084@\u00B4\u00A5\f\u00CE\u00B0E\u00CCbP\u00BAG\u0086]k\u00ECr\u00FF\u0089\u00F0\u00F7\u00EC\u0097\u00A5\u008A \u0098$\u009Ap0\u00C2\x04f\x17z\x0ED\u00C4m]\u00B4\u00B5\u00BE\u00BC\x1C\u00A8\u00BD34~]\u00A1\u00B9\u00E6\u00DF\u0099y{pz\x1C\u0097\u00E7\u00DE\u00F6\u00A2\u00FD\u00E0\u00BB\u00BE\x00\u0090!\x00\u00C0[\u008E\u00A7\u00FE\x19\x1C?\x12\u00C4z\u00CA(4\u0085\u00C6D\x03=y\u00C8F\u00C5\x1AT\x1E\x02\u0089\u00D3\u00B5\u00F8)m[\u00F4\u00DF\u0082\f\u00B2\u00EB\u00ABZb\u0094\u00EAk\u0080\u00D4\u008AHFg K{\n'\u00E6\u00FDN\x1E\u0084\u00F4\"\u00901 \u00ED\x12\u00A3\x18x2.\u00E4\u00B8\u0090\u00E3\x1A\u00F8\x06\u0080\u00FB\x00\u00AEh\x14\u00BC\u00B1\u0081\u00DD\u00A3'\x1B\u0098\u0080jat\u009BpL\u0097\x0B\u0091nJ\u00B3&\x17\u00BCT\u0082\u00C6\x1AK\u00A8\u009C\u00A2\x12i\u00F0R4\u00A1\u00898I\u00DC\u0092\u00E0\u00A0\x17B%\u00D3\u00CAR\x191\x07\x00Je\u00F0\u0088n\u00DCH\u009C\\^\u008C\u00A0\u0094j\u00C0\u00CC\u00BC\u0086\n\u00DC\u00A3\x0E\u00E3\u0080\u00A5\u00BD\u00C3y\u00FF\u00890\u00A4f\u00F1V\u008E.\x11\u0081\u0090\u00BF\x16\u00F6lK\u00B8\u008D\u00DB\u008EB6\u00EB\u00F3n\u0093\u0084\x01\u00CCk6\u00AA\u0098\u00FE\u0093\u00C4o\u00E1\u00C6\u00D1\u0087\u00EE~l\x1DZB\u00A6;\u00A1q\u0080\"\u00F4d}\u008A \x04\u00D2;\u00A1~\u00E4}*V\u00A0{A\u00D2\x16\u0092\f\u00E2R\u00E3\u00C9\u00F6\u00B6\u00B5_\u00E9\u00A2T\x1F\u00B5P\u0080\u00F2\u00B2\u0088\u00F9\u0089\u00C9\t5\x1C\x00\u00A3\u0080\u00DD.\x18O\u00DC\u00FFg\u00EAI2\u0084\x0F\u00D8;\u00FF)\u00FC\u0089\x1F\x01<c\u00D9\x0B\u008A+0\u00E4\u0094\u00C7\u0090l\u00A2\u0095\x05\u00E3#\u00AF2\u00EE+\u00AC\u00EF\u00B5\x13\u00E2o\x11,\u00EF\u00D7\u008A\u00B7\u00BA\u00D4\u0084\x16\u0099\u00B8\"\u0083\u00B3\u008A\u00A0>K%9\u00AB<\u00FA\u00DD\x1B\u0093i\u00EA\x0BP\x0BU\u00FD[\x18M\u00FD-\x17\u00E4+nx\x02\x03\u008F\x11Pzo\u00E1]Y\x18\u0085\x06V\u00A5\u00D2z\"\u00AA\u00E8S_\u00F8\x11X\x14=\u008B-\x07-U\x00\u00BD\u00E1h\x01C\x1EL\u0081D\u00E73\u00A4\u00F9\u0090\u008B\u0091\u00D27\u00A4\u00BFC1\f\u00EE\u0091\u008F\u0091u\x10BH\u00E1\u00D2\u00DA\u008F$\u00A7r\u0083&AK\u00BD`;)\u00AD\u00D5gt4\u0092\u0082\b\u00B2\u00DAo\u00F4r\u00A0\u00D3\x04\u00C7R\u008C\u00C2\u0093a \u00CB\u00C3[ \u0088Ts\u00880s\u009F\u00C3T\u00A4\u00C2\u009B\u00C0D\u00A5\u00A8\u009F\u00D0`F\x0E\x18$\x1C\u00D9\x03\x1C\x151Y\u00CC\u00DF\\\u009CZD\u0086F\u00D4'\x06\u0092\u00D1gg\u00E6\u00B3J\u00EA\\\x07\u00A9z\u00B4k2UY\u0084\u00DF\u00DAj\u00C6\u00C1X\u00BB=\u00A1K\x13&f\b\x1E\x13\ni\u00B4\u0091\u008Cd\u00E0\u0095\u00E7\u009E\u00FE\u00A7z\f\u00C9\x10\u00BE\u00FF\u00DE\u009F\u00FE\u00B5'\x1F\u00FD\"^\u00BB\u00F7\b\u009D\u00D0\u008B\u00FB!\u00A1\u00AE\u00A1\x13h/\x03\x06,\u00C4z\u00B2-\u00DC\u0082<\u008A\u00CE\x13\u008C\x17\u00B19\u0090Qg@#jMB\x1C\x1B\u00D96\u00D6\u00B6=\u0098\u0089'\u00A7\u0096\u00CD\u00A0\u00A3\x07\u00DDCVlF\u00EE\x199\u00BE\n\u00BB\u00C8\u00D8\u00E3\x00\u0088\u0086BPD\u00DF\x1E\u009A\u00E1U\u0084\u00FD\u00E0\u00CA\u00C3\u00D2;\x19y\u00B8A5\f*\bIy\n\u0086\u00B2\u00E6\u00870\u00A1\u00B4\u00D6:\u00A5\u00D5_H \u0098BA|\x07R\u00FF\u0097\u00B4\x06%\u00BB\"\x01\u00A3b\u0092W`\u00D2$\x13\u00A0%}6bN\u0095\u00D9\u00CB\u00FD\x18\u00A8\t\x19\u00B5(\x04\u00A2\u00E5\bGl\u00DE\n\u00D1d\x10\u00BAT\x1B\u00A5_\u0097A3\u00C6\u009Cq\x13<oU9$\u00E5x\u00FF\\\u00D8m|I\u00CC\ri\u00E4w1\u00D9 \"\u00CFMV\u009A\u00AA\u00C0|n[,\u00FB\u00FA\fx\u00E53\x18\u00CE\u00B2n\u0092Q\u00E8S\tR\u00B3\u00FA\u0098\u009D\x173\u0090Z\\\u00CF\u00AA\u00CC\u00B6\u00DAcq\u00B2?RA\u00F4\u00BB\u00D6\u00FC\u00C15\u00D1\u00A2\f5\u00D6Y\x04n\x19\u00D6\u00CC\u00F5\u0094\u00EA\u0088\u00A1\u00B2(c\u00E2\u009D\u008B\u00EDf8\u009E|\u00FE\u00BD\u00BF\u00C6\x1B\x16C\u00F8\u0088\u00BD\u00E5W?8\u00DE\u00E5\u009F\u00B0\x17\u00AC\u0092\u0099Dl\u00E5ehql(\u0086p&v]\u00BB\u00DA \x12\u00B2K:\u00B7\u00DA\u008C\u008B\u00AB\u0092ha\u00CD|l\f\u00C1\u00CE\x06\u00C4Vl\u00846\n[\u0098\u0080P\f h'\u00A4\x11\u0084\u00C0\u0087\x10YWXb\"\f\u00EDo2\u00C5\u00B6H.\x18\u00F8:\u0080k\f\\Y\x18\x19eS\u00B1Y\u00FDH\u0094\u00C5o\x1B\u0098\u00AA\u00EC\x01\u00B5'J\u00D8\f1E\u00E5\x19\u00A0\b\u00B6\u00DB\u00A4\u0084(\f\u0096\u00B1\b\u0092\u00DC\x17\x0Fc\u00DE\u00F0b\x0E! \u009D\u00E7[&*eD#\u0085\u00E0D\u0085%\x1B\x17\u00F0>\u0085\x1A,\u009F<fx\x10\u0084\x00D\u00EC\\kdZ\u00B9\x06oy(R5\u00E9j\u00B5\u00D4\u00FE4@\u00B6\u00DF\u0092\u00F0\u00C5\u00E8\u00FB\u00B1\u00F8\u00D4\u00E6\u00A9\u00C6uQ\u00D2\x7FV\u00870\x11!\u00CB\x1B-\u00FC\u0095_\x00\u00BF\u00C6\u00A2.t}&p[\u00DD;\x13\u009B\u00B8\u00862h\u00A8\u00A1\x01G\u00B5\u00DF\u0098VV\u008D\u00EA\x12\u00BC\u0095\u0083\u00CB\x01\u00A7\u0084\u00E0\x18\u00D6\u0081c\u008D\u009C\u00A4\x1A\x012\u00AB\u00DEN\u00D2a\u00ACu#3{\u00FC\u00F6k\x7F\u00FA\u00C7\u00FF\u00F2\u00AF\u00E2\x7F\u008FV\u0093!\u00BC\u00CF\u00ECK?\u00F6\u00FA\u00DF\u00FF\u00CC'\u00F0\u00E2\x07ej+H\u00CD`\u009F;\tL\u00D3\u00AF:\t\"^\u00C5y\u00EBw\u00BEO^\u008B\u0085q\u00E4\u00EF\u00FD}\x0E\u008B\u0096\u00DD\x00K\x1BI\u00E4\u00B9+\u00D2\u00AA\u009A\u0094\u00FF\u00B5\u00A3\x15qo\u00E3\u00FFb\x16=\x1A\u0092D\u00BC\u00A8Qu\u00DF\t\u00C3C\x07^\u00B7\r\u00D7pl\x1E\u00EE\u00A0a\u00A1>l\x1E6\x02\u00DE\"\u00D9B\x1A-\u00D3&\u0090\b\u00B7\u00D4\u0082F\u00E4\"0\u00C5\x14\u00A4t\u00A7Tw\x0F\x02\u00DFR\x1A\u00C7=\u00BA\u00EBR\u00A877Q:\x1AA\u00F2S\u00C6\u00BF\u00AA\x1F\u00C4>\u008B05\x16\u00E7\u00BD:\"H)Y}\u00D6\u00BDG\u00BB\x0F\u009C*\u00D5\\\u008F\u00F5\u009D\u0098\u00D3\u008E#U\u00A71\u00C1\u00BE\u00A3t\x11\x14\u008A\u00B97\u00D5\u00C3\x16b\x01\u0096*\u00C4\u00A9\x16\u00E8\x1C\u00BD%}\x19\u00AE\u009F\u00FAz\u00D3\u00FDS\u009A\u00AB\u00B8js\u00EF\u00E1\u0092\u00F7\u00EF\x10]\u00F5!Cu\u00DB`\u00CE\u00CDl\u00BB\x0BuQA4\x0E\x11\u00B9\u0090\u0081~\x13\u00C7\u00F4\u00EC\u00C3:6\u00A9\x1B\u00CD~!\u00E6#Zy\u00FB[?c\x1Fy\u00CB\u0097D)\u00C9\x10\x00\u00E0\u00BD\u00FE\u00F6_2\u00B7\x0F\u008Ah3\u008A\u00CFD\b@\u00A1\x07 \u00FD\u00F4\u00A0\u00CF\u0099\x06\u00C9\u0099\u0093`yM\u00955\x0B\u00FEtk\x0F\u0087[\x05L\u008A \u0097\u00D0\u00E3\x055D{\u00B3\u009D\u0087\u0093j\u00D0c\x0B:\u00C3pI\u0096\u00AC\x16\u00B2\u0096+\x13*\u00E8\u00C6\u00C7\u008A\u0094\u00F4\u00E5\u00FE\u0087\x01\u00AF\u00B8\u00E3\u00DA\f\u00BB\x19v\x0F\u00C6p\x03$:\x00h\u00AD\u00EFk\x7Fz\u00956s\x12\u00E2\u008C~\u00DA\x01\u00AA\f\"\x18K\u00AF\u00C2\u00A1.O\u00A1\u00DFF\u00B0d\x12\x10s\u00F0 \u00A8\u0083D\u0099\x16}\u009E\u00DFK\u00B0\u00FBD\u00C4\x00\u00E8\u00E5\u00C0\u00B0\u00C6\u0090<l\u00E1rM\u00CEYL+\u0097dcf@yBrW\u00B1\u00C6\u00D8\u00D4\u00D7286\x15A\u00CC\"\u009F\x1BNo1\u00D4\u00FA-\u00E3+d\u00A3\u00E8\u00E7\u0083*\u00E1\u00E4:q\x12:\u00AA\u00AD\u008A\u00AF\u00D9B\u0082J\u00D7q\x0B5,\u0083\u00DB\u00C44\u00E4.\u00D4+\b\u00CE'\u00C5\x0F\u00ED\x01\f\\\u0084\b\u00D1\u00DD\u0083V\u00BC%9e\x0E\u00C3\u0085\u00B5\x15\u00A4\u00E7\u008Bx\u00D5H#\u00F4\u009C\u00F5\u0081^\u00DD\u00A9\x06m\u00C5h$\u009CY/\u00CF\u00E0p\x03.\u00CF=\u00F5K\u00F8T=\u00F2\u0085!|\u009F}\u00C7/\u00DE\u00BB\u00F9\u0095\u00FF\u00E1\u00D1\u0095\u00A3\u0082\u0091\u00F8@nA\u00EE\u0095p\u009D\u00C5V\u00ED\u00D6o\u00ED\u00A1v\u0082KH\u00DE8_2\u009E&\u0099\u00FB\u00F9\u00F9\u00E2\u00C4*A\u00A5\u00D5:\x18\u00D4!\u00D7\u00ED\u00CD8\u00C1\u0089\"z\u00BF\u00C6r}\u00D9(\u00AA\u00DF\u00B1\u009EVd\u0091\u00F5\x13\u00B9j_7\u00E05\x18\u00EEa`\u0087\u00A5;\x11*)\u0097\u00FD\x103X\u00AD\u00EF!\u00C1\u00ED\x14{\x10v\u0084\u0084\u00E3(\u00E8\u009F\u00926\x19\u0081S\u0087\u00AFLHy\x16\x04\u00E5\u00C3\u00F2\u00EFI0\u009D(\u0085\x0Ez^\u00C1\u0092F\r \u00CAzX\u00D9\u00BF\u00BCl\u00EC\u00AA\u00C3\x004\x1E\u008B\"\u00F8\u00AE\u00CEt\u00C4\u00D0]\u00E4\u0098\x1E\u00DC\u00B5\u00F5\u00A1\u008F\u00D5[\x1B\u0089\x0E\u00A4\u0097\u00CF:&\x06\\\u008C\u0083\t{\x0E\u00944\u00E6\x059wh\u0086G\u00E7\u00F9#\u00CE\u00CB\u00F5\u00A2\u008E4\"\u00CE\u00AD\u00E8[\u00DB\u008B\u00D1\u008E\x1C\u00D0\x07\u00A0\u008D\\\x12>\x01\x05\u00BB\u00B8\u00BEr\\\u00FCM\u00ED\u00E6\u00EF\u00CD\u00CE\u0090\u00A8\u00C2\u00EA\x1Egd\u00A1\u00F3'\u00DA\u0084\u0087 \x7F\u00BC\x01\u00F6\u00FEw\u00FFb#\u0086\u0095!|\u00F4\u00FE\u00BB~\u00E1}\u00AF\u00BF\x03\u00BF}\u00F5\u00E5vt\u0095\u00C6\u009E\u00C7:\u00DC\x1F\u00C8-\u00C7\u00FC\u00FC;\u00FFn\u00C4\x1F>\u00DD \u00CC,n\u0092\u00CC\u00E0\u008D\x18\u00C2\u008A\x1ATqF\u00D7\u00A4m\u00C3\n\u00AA\u00A9\n\u00D1r\u00AD\u00B7<\u0085\u00B4\x17l\u00B7\u00EE\x1B\u0083\x1D\u008D\x19l\u00CB\u00FD\u00FB\u00F6\u00EF\u00B1L\f\u00DFp\u00E0\x1Evlp\u00EC\x18\u00D8<\u0082\u008D.\x1E\u00E5\u00CC\u00A4\x16\x04\u0093\u008E\u00E4\"-M\u00D5\x18H\x15\x01Z\u00ABA\u00D4\x07\x17\u00D0\u00D1\u00A4\u00A2\b9\u00D2\u009A\u00D9e\x14\u0081\u00E4\u008ELd\x00Z\u0087C\u00D2\u00B7\u00A1\n\x1D\u00D3\u0086\u00AFB$\u00C3%\u0093\u00C2\u00FBdIG\u00B1\u008F\u00C2\u0086-=\x1E:\u00B7\u00EE\u00CB>u\u00D5g\x16\"\u00A8\u00BC\b>=\x07\"\u008B\u008F\ts\x0B\u00E1\u00AB\u00CF'\u00A2!1;\x12_\u00AC\u00AF<O\u00CFT\u008C\u00E1\u00A8\u00CF)\u0089?Q;:\u00B5\u00CE\u00FB\u00A5\u00D94\u00F8w\x12\u00B4\u0088\x10+\u00A3\x01\u00EF\u0099\u00F0\u009D\u008Cb\nRq2\u00BA1S\b\u00C3\u00B5\x07EW\x11f1\"\u00B9%\u0093qh\u00CD{1\u00B1T\u00EB/\u00A8jQU\x0F\u00C1|\u00E0\u00F2\u00F4\u008Eg\u00FF\u00AB\x1F\u00FC\x05\u00FC\u009F5]\x0BC\u00F8n\u00BB~\u00E1G\x1E\u00FE\u00F4g\u00FE%^~\u00BE\u00D7\x02\u00C0\u00F2\x1Dy\u00B3\u0090\u00EA\u008D\u0098\u0092\u00936I\u00DC\u00F6?\u00E8j\u0082\u00BC\x0B\u0095r\u00DC\x19\f\u009A\u009A\u00D0\u00B9\u00F3\u0086\u00D9\u00C3\u009D\u00A5\u00A64\u0086\u00E1\u00E9\u00D6T@\u0087\f\u008E\u00C0Rm)\u0099A\u00BF?\u00ED \u00C9TP\b\u00A6\u00A3\u0083\u00A5_\x15\u00DCt\u00B1\u0081\u00AF\u00C33\x16\u00C1\f,f\u00CA\x18\x03\x00GZ\u00DA-\u0098\x02\u00AF\u00EF\u00D0^~\u00FF1[P\x10\u00AF\x1F\u00D3\x1B\u0081\u0095\x0BQQ\u0081Z\u0093\u00DDX\x18\u00C2\u00C4)\u0095-\u00897\u0089qz\"\u008F\u00E1\u0096\u00CCE\u00C2-\x10\u0080\u0095\u0080rP\u00ED\x1A\u008B\u00E4\u00EFu\x1A\u00A09\u00C8\u00BFcN7\u00ADc/\u0084\u00B2%\u00BA\u0089\u00B5\u00B5\u00A0\u0080\u00E6r\u00ACc\u00D5\u00DEtz\x04H\u00A0v\u00CB\x18\x19\u0081tB+\u0091\u00F4E\u00CC\u00E6\u00DA\u00EBA\u0091\u0084\u0094\u00BC\u00F3dO\u00A0\u00A2\u0097\tV\x18pS\u00A1\x19I`\u00C6Kx\u00EC\u00BF\u00AD\n\u00CA\u009AD\u00F3\u0083\u0091\u0092\u00E5F\u008C\u00BC\u00A8\u009Dm4\u00FA\u00E9\u008C\x105VU\u00D3\u008Cc\u00EA\x1F\u00DAuz\u00F8\u00FA\u00EE\u0088\u00BD-\u0095\u00D8\u00C4\u00B9\u0085a\u009A\x03\u00DF\u00FE\u00F6\u00CF\u00D8\u008F\u00BC\u00FF\x05\u00B4\u00D7\u00C2\x10\x00\u00E0{\u00E6;~\u00F6gl</\u00E2\u008C.u\u00B8>8\u0091\u009D\x10[\u00A7:\u00F1t(\u009E\u00E9\u00CD\u00BD\u00AD\u008E\"\u00B6\u00D3\u00F1\u00DB\u00EF\u00DB\u009B\u00C4\u00C4\u00F7\u00E1\u0083s\u00C6\u00A4%\u00FD\u00A6\u00CC/-\u00A6\x1E1\u0099{ET?\u00D3^\u0080vn2\u0081\r\u0089.\u00AC\u0098\u00CD:f\u00C7C\x18\u00BEj\x03\u00FB\x04\u00EE9\x0B\u00A5R\u008A\u00B1FN\x12\u00F4\u00A4J\u00A0\u00C8>\u00C0\u00D2((&!\u00D5\u00C2\u0088\u00DD\u008F\x19.\u00D2M\u00FA\u00BF\x0Bq`\u00B1!dfb'tIq\u00AE\u00A5(\u0092\u00EA\u00CC\x1Dp8\u0089o\u00CCbJ{5Q\x11\u008D a\u00B1\u008Fi\u008Bh\u00FD\u00D7\u00A2\u00B6\u00F6]R\u00DE\t\u00D5\x1Dq\u009F\u0091q5\u0085|\u00DC\x11a\u00FAn,\x04\u0082$t\u009F\u0091\u00BE\u00ED\u00D2\u00ED3\x14:\u00A4q\x06Z\u00E5\u00B9\u0096L\u00B1\u0092\u00AB(\u00A4\u00BA\u0084NC]\t\u0084 rI\u00EA\u00BBb\x06&m#\u009D@\u00DBy\u00B7tz\u00D4y\u00ECo\u00ACC]\u0083Z\u00AF\u00F9\u00BD\u00DFW*\u00C2D\u00EE\u00A9\u00B0\u00C4\"\u00F4s\r\u00E6\x17T\u00887\u00F2\x1E\u00E6\x1B\u008Eo{\u00FAgqz\u008D\u00F3\u0081\u00FF\u00E0\u00FEw\u00FD\u00C3g\x1F\u00DD\u00C7\u0098w\u00D4QDd&\u009A]a\u00D8\x0E\x187iI\u00FD\u00BC%7\u0099\u00D0C\u0087\u00E3\"\u00C8\u00E4\x1B\u00B5A\x00\x00 \x00IDAT*\u00E6\x1A.\u00C2\u00BD\u00A1\x07\x15\r\u00EBz}\u00B4\u00E3\u00CB\u00DF\u00CDGl\x1CJ\u00BAU\u00E4\u00FA\u00B3\u00E6\u00A9!\u00E13|9\u008C\u00A0[\"\x1C\u00A91\u00E9eX\u00DE,^\u00D2B\u009F\u0085z\u00AA\u00F2\u0093\u008C\u0097\x03\u00AF{\x04*\x1Dn\u00B8x\u00F8\u00FB\u00C3F\u00E0\u008B'\u00A1\u00DE\u008E\u00C9E\u00ADu\")/f//\u00C1\u009C\u0091[p\u00F0\u009A9\u0083\u0090\u00E7\u00E9\u00AD\u00B5\u00AAuz\u00F0^B\u00C8\x19\u00DF3\x19\u00EF0\u0091\x04\x16*J]w\u00CC~\u008DS\u00F5\u0089\u00C0\u00A7c:n\u00DC\u0097\x02IP\x7FI\x0E\x1D!\u00EB\u00DA\u00E9V(\u00A9\u00CD\u0083\u00CF@I*\u00FD\u00BE@b\u00D7*%\u0093\u00F6\n\u009A\x1A@\u0096\u0083[\u00DD\u009B\u0085\x18neZfM\u00C7\r\u00F0\x1D\u0098;07\u00F8l\u00C7\u00F2S\x1B!\u00C7\u00DF\u00A6\u00E8A\u00EC\u00A8\u00AD\u00D8u\u00DEu\u009E\x17\u00EE\u00CD\u00ABjK\x05\u0088\u00F4\u00EE\u00D7\u00EB\x1A\u00EDk\u00BA\u00D0^[\u00FB\u00DA}\u00BA\u00F5\u00CF\u00FB\u00F5\u00DE\u00CE\u00CF\u00FB_5Z\x1C\u00B8l\x03\u00E3\u00FB\u00DF\u00F7\x0F\u00CF\u00F4\x7F\x0B!\u00FCy{\u00F6\u00E7\u00FE]\u00BC\u00E7\u00D1\u00AF\u00DA\u00EF\u00DE\u00EB\u00B0\u00B8\u0088zG\x16\u00FAL\x02\x04\x1F\u008B\u00A1P\u0085\u00A44P\u00D27\u00AEY\u00C2\u0099\u00F9\u00C0+\u00D9H\u009F\u00ED\u00E1;\u00D1\u00C1\u00B2\x07\u00A4\u00E5\u00B92\x1C\u00F6\u00C0\u00A9RE\u00D8Fk?@b\x0F\u00A1V7\u00FA\u00C4\x03\u00C5\\\u00BA\u00BA\u00A4>j\f\u008E\u00B6$\u0089\x13\x1C\x17g\x1E\u0085#\u00BD\tA\u00DC\u00D4yi\x1B\u0088JJ\n>\u00F2B\x04\u0094\u0094\u0087\x16\u00F8\u008C\b?\u009Fq\u0097\u00CE$J\u00AA:#\x15u\x1FKB\u00CC\x1C\x05\u009D?\u00CB \u00A9\u00DC\x07\u0097D%\x172X\u00AA1Q\u0088K^\x10!\x02\u00B2E\u00A7\u00AD]\u0089Y3f\x19^\x06\u00C5\u0090\u00B4\u00D1\t\u00C1\u00F7\u00C12\u00EE\u00E9\x01\u00A14W\u0094\u00A3\x10s\"\u009DE\x05\u00AA\u00EFe\u0098;3\u008E\u00F6J&P\u00DF\u00EB\u0089\u00EA:\u00A3T\u00D5X\x1CY*=\u00DB\x10\u00F4\u00E8\u00A1\u00C4\n\x18\x02T\u00D2,\u008D\u0094\u00D3\u00E1\u00C9@\u0094:}\u00E4*\u00F2D%\u00CCjT?:\u00A2\u0080\u00A4\u00BF\x10E\x1B\u00A3;j\u00C3]\u00F6\x07\u00EC'\u008D\u008F\u00F2x\u0098\u00E0\u009A9n\u00DE\u00FB\u00F4\u00A3\u00A7\u00FE\u00BB\u00BF\u00F0s\u00F8\u0089u\u009An1\u0084\u00E7l\x7F\u00E5\u00BF|\u00F8s\u00BF\u00E86~\u00B8\u008E\x0E\u009E*C\u00C5\u00A8\x0E\u00A5\u00CAP\u00C5RB\u00B7\u00E7r\u00D1\u0080\u0086\u008C~\u00DDx\u00A7c\x01\u00BFWVP\u00F5\x0B\u009C\u00C3Z`?V\x02\u00F7$\u00EE\x16\u00FF\u0090\u00C8@j\u0081\u00AE\u00DB\u00E0]e\u00C8qX\u009B\x12\u00E3\u00BF\u00C5\u00F4\x16F\u00D7\x18agnN\x11yxHP\x11\u00BD\x13*O!\x06\x1A\x15\u00A7\x1E\x19\u00AF\u00D5nJ\u00C3\x11\u00D5\u0090\u00C8\x14@\u00B5A\x19\u0086\u008E\u00D2\u00FB\x15\u008E\u009C;(u&\u00D1\u0088\u00DD\u0080\u00DC\u00D9I\x11\u008D8\u00BC\u00DC\u009E-\u00F3\u00D1!b\u00B6\x1Ce\u00E4^h\u00B1\u00B3\r\x0B\u00C2\x0E\x1E\x12\u008B0\u0092\u0098|\u0089\u00A3\b&`\x00fTnj\u00AE\u00C1n\u00EB0\u00F6\u00CFip\u00D5\x18\x143\u00A1\x07\x11\f\u00816\u008B\u0084\u00DE\u00FC\u009C\u00F5\u00B7\u00C3\x19\u00E2\u008Cb*qi2\u009Ae\u00D3\u0099\u00CC\u00C2\u00CD\u0089F\u0096Ws\u008B\u008E\u00E4\u00C6\u00AB\u0084\u00ED\u00D3\u00B1Z\u00F8y.K\u00B1+\u00DE!\u0093\u00962\u00B0J6\x01^\u00DF\u00C2\u00AD\u0093\u00DB\u00FB\x01\u00CCKk\u00B7\u00F5#!%\x10\x1B\bKl\u00B5\u00E8Z8*J\u00F1\n\u00C0\u0084\u009B\u00E3x\u00F7\x13\u00BFh\u00FF\u009E\u00BD\u0082\u00D3\u00EB\x16C\x00\u0080\u00BF\u00E0\u00DF\u00F5\x0F>v\u00F9\u00FF~\u00F8f\u00D7\u00CD\u00A5\u00FF\x17\u00A1\u00E8e\u00F2\u00DF\u00B3F`\x11\x19\u0089\u00C4\u0080\u008A18C 0\u0083\u00F2.\u00BB\x02=\t\u008B~\u00DF\u0091\n+\x17\u00C7\u00D2E7\x1E\u00CAJ^5\x1D\u00A4N\u00C4\u00C4\u00DD2&.\u0086I\u00B4\u00F6;\u00E3\x11S\x18\u00CB1Y\u00B6\u0095\u00C9\u00E7,2\u00F8h\x1An\x1ATO\u00D8\u00EC\u0096\x06F\x00\u00CCh\f5@\u0086\u00C0L0\x02\x16\x03\u009A\b\u00C4dg\u0090\u00AE\u00CF\u00B5\u0093\u00C4\u00E4\x15\u00B9\u00E8It\u008C\x18\u0099u\x1D\u00846\u00DA\u00B1@3\u00B1\u00FD\u00DB!\x15\u008A\u008B.\ri\u009C\u0081m\x063\u00BF\u00C0\u00B1\x13\u008EOg\u00D19\x0Fu \u00D9*\u0089=\x19\x1B<m#\x19k!\u0083\u00AB\u008C\u00A5\x1A/\u00AF\u00DD\u009A\u008D!dh\x10\u00BD\u00F2lJ\x1D\u0090@\u00A0\u00B4\u00EFK+\x16\r2\u00D8\t\u0086\u00B21\x00UC\u0080s?\u0085\x16J\u00F0E\x04\u00E9\x01LUS\u008E\u0095\u0091\bb\x1A,a}/\u0088\u0082\u00C6H\u00FA\u00C2h5\rP\u00CD\u0095\u00ADA\u008B\u00FA\u00A8\u00BE$s\u00D2\u00B9^c'zq\x16e\r\u00C0\x11\u0093f>p\x19\u00C0\u00CDw\u00BE\u00FD\x1F\u00E0\u009F\u00E0\u00D6\u00EB\u0096\r\x01\x00\u00FE\u0093\u00FB\u00EF\u00FD\u00D8\x07\u00E6;|\u00CCU\u008F\u00AE\b>\x12ZfE\u008E;\u00DE\"\u00C0~\u00AB\u00B3M\u00A1\b\u00AA\u00AE\u00DB\x11[\u00D2K\u00AF:\x13&JE\u00A0\u00B1/\f~\u00E2\u00EC\u00D4\u00B1ny\x10\x06\u00A2tv\u00BB\u00FF9\u00FE u\u00C4\u00DB\u009E\u0084*\u00F4\u00D2\u00DA\u00CB{\u00C6;\u009F\u00E74\\(\u00D9\u00F5\u00CC\u00F3;\u00A5c\u00EA\u00CF\u0093L\u00C1\u0095Oa\u00A9\u00EE$\u00E4\u00EF\u00C2Az\u00BD\x17\u00C1\u00CF\u00A3\u00E9\u00E6\u00A9\u00DB\u00CB\u00E6@\u009B\x02\x17N!\u0096B\x1F\u0093\u00E7\x1FG\u00BC'\u00EB#\u00CAF0\u00B3-\u00ABX\u0089n\x0F\u0098#\u008D\u009D\u00C1\u008C\u00C8\u0090P\u00B6\u0082 \u00A2\u00F8\u009C\x138\x0Ek}\u00D4\u00FCx\u00DA=\x0E\tH\u00BD\x1D\u00CB8\u009C\u00C6\tsh\u0093\u008C|{\x12\x1B\u00EEx'w\x03\u00AB\u00E1\u009E\u00D4\x11\u00CB\x18\u0093e-S\u008D\u0090g\u00A7J\u00B9\u00C5zr\u00A1S\u00DFB\u00D27;\u0081\u00B9\u00EC\x0E\u00D7\u0080_\x03\u00F3:\u00EC\x15\u008B\u00DE\u00AF\u00B2\u00EE\u00ED\u009D\u00F7\x1E\u00ED<}\u00B2\x1D\u00D9\x07\u00E65l\u00B6\u00F6}\x0F\u00BA\u0090\u00DD\x0F;l\u00EEp\f\u00DC\u00BC\u00E5\u00CA\u009F\u00F9o>\u00FC\u00B1\u00BBh\u00FFN\u0084\u00F0A\u00DB~\u00F7\u00BF~\u00F8K\x1F\u00FFW\u00FE\u00D5\u008F\u00CC\u00A5nA\x10\u00AEe\x0EB\u00B9%m!\u00B23\f/+\u00FDZ\u00DB\u00E0,\u00F5\x19l\u0094\x04\u00DC\u00EB&\u00A2\u00A1\x00\u009D\x1B&HG\x11\x11 \u0097\u00A6\u00FA\u008D\u00ECWff\u00BA\x173XB\u00A9\u00FB8\u00D1\u00EE\u00D3\x19K\u00EF;\u009A\x0BO\x12&\u00A4\u00CD\r3\x07':J\u00B0\u008A\u00CEu\u00E0\u009C\u00C9\x18Q\u0088\u0094\u00F2\u00D0o\x11\u0085\u0098\u0082%\u00D1E;N\u00E2\u00A9\x00$\u00CF\u00F6A\u00C4\u0090:\u00F3\u008C\bFg\x00P\u00EE\u00FE\u00EC\u008C\u00E4\u00F3\u00AA\u00BB\x10\u00B6\x03/\u00CF\x01\u00CA\u00D87\u00E0\u0090{V\u0099\u0091@\u00FB\x1B\u00CA\u00B3@Ju\x17\u0082\u0090\u00CA\u00D2\u00E6m\u00B4\u00B9\x03\u00D1VO\u00BA\u0082\u00AB&\u00A4\u00B7\x18\x05e?\u00A2\u00A9\x1D\u00D1`\x0F\u00DB\u00C6\u00F2\u00DB\u00E9\u00D8<}w\u00F0\u0081\u0090\u00C1\x1B#\x0F}T\u00C9x\u00D9\r\x14\u00A3 \u00AEE\u008B\u00BFv\u00A7\x06c*\u00EAw\u00D9\x11\u00C8\u00B4R\u00FA\u00CB\u00BE\u00E2\u0088HJM\x16\u00E0SnI\u00B95\u00E3\u00D9G\u00ACB<\u00D0r[:J\r\t\u00E1\x1A\u00DB\u00BC\u00D5\u00F6\u00F06\x07\u00E6\u009Fz\u00FA\u00E3W\x7F\u00E5\u00B9\u00DF\u00C5\x1D\u00AF;\x19\x02\x00\u00FC\x00\u00DE\u00F9S\x1F\u00B3\x7F\u00FD\u0091\u00AAfUDy[\u00C2\x07\u0087\u00B4\u00D4\u00CBA\u0082\x04:\u0087\x1DY\x7FQ\u00EDm\u00D9\u00AE\u009F\u0099\u00C1be\rh;{{I\u00DC@VC\u0082\x01v\u00F2\u008E\x18\x00\u00A2\b=\u00E0\u00DB\u00DB\u00C1\u00F7\u00B2pg\x15\x01\u00D5Vg^\r\u00A2NJ*\u0083\u00D5\u00A2\x02p\x03\u00C7\r\u0089T\u0096{\u0085/\u008B\t\u008CR7\u00C38\u00D7\bG>{\x05\u00FA\fG\x06\x0B\x01\u00F1\u00DB\u0085\u0084\u00B4\u00CFb*N5\u00C3\u00F8\u0099q\x0B@\u00EA\u00F5\x1A\u009C\u0098\u0098\u00F4v\x19\x1F\u00BB\u00F1o\u00BAs\u0099\u00D5\u0098\u00C3U\u00CA4m\u00AF1\u009B\u00CF\u00A62 \u00F5~#\u00C3\x19\u008C\x19\x18d\f\x19\u00FC$\u00E64G\u00AA\n@\u00AF\u00CD\u00C0\x152\u0095m\u008A\u00AA\u00CE\u00D4\b\u00BE\x04\u0083\x06\u00D9\u00C6\u00AAx\u0085\u00C6\u00BC\u00CE\u00E7d\u00ECB\u00DA'\u0082).\u00A1\u00D2\x13\u008D\u00B9lM\u00AD\u00F0\x12(\u00F9}\u00AE7\u00E8\u00AEE\u00D9 \u00A4\u00DFg\u00CE\x01 [\u0081)\x122C\u0093\x072E[}N\u009BF\u00CF]\x10zi\u00CC\u00C2\x01\u00C7\u00C4\u00FCw\u009E\u00FA)\u00FC:\u00EE|\u00DD\u00A92\x00\u00C0\u008F\u00DE\u00FB\u00E0O}\u00F0\u00E6-\u00BE\x10\u0081`\u00B3 \u00CCbl$l61\x03\x11<\u00DF\x19\u00C0\u00D4a7\u00BB\u00E0;\u0099A\x18\x11\u00ED\u00D69\u00E7p\u00E9jG\u008B#N;K\u00F2\u00DEO;\u00FD^\u00FD\u00B1\u00E5\x1A\u00AC}\u00EB\u00EA\u0092\u00EE+#\x1E%SE\u00F9\u00A1`\u00EB\x04\x1EM\u00C7\r@\x17\u00A1\u0098\u0080K\u00FDL{\u00D4\u00CC\u009C\x16K\x1B\u0083O\u00C3<,az\u00BEy\u00CC\u008F\u0080\u00F5B\x1D\u00F9NhO(~4\u00F5\u00E1\u00A0\n\u0090\u00AA\u0081G{\x07\u00DD\u009ErW\u00EAw^{L\u00F0\u00BE\u00C5\u00A0\x0E\u00DA\x1Az\u00DF|:\u00D5\u0085~\u00CC\u00B8e\u0081T\u008F\u00F35\u00D5\u00EF\u00EE\x02\u009D\u00D3\u00DB=J]\u0099\u00AE~G\u00BFr\u00D76\u0097:ABey\u00B8\u0088\u00AD\u00A8\u00DFJ\r\u0093\x04\u00D6\x066\u00BC\u0096\u00EB\u00C9\u00D4Tz]\u0096\u0085F\u00C6P\u00AA\u00A6\u00DDrU\u0096*\u00E0R\t\u00F2-\u0098\u00AF\u00BF\u00EFP\u00B9\u00FD\u00B4\u0096{\u00DBrUN\u00B9\x14\u00AF\x01\u00BF\u00C7\u00F75\x7F\u0097\u009BQ;\u00A0E\u00B1\u00A0\u00D7\u00DF\u00BE\u00F93\u00FF\u00C5\u009F\u00FD\u00A97 \u00FB7F\b\x7F\u00DA\u00EC\u0085\x1F\x7F\u00FDW~\u00F9_\u00E0\u0095\u008F\u00C2YJ\u00AAy\nn\u0085\x14\u00B7\u00FA\u0081\u00E7\u00A2$\u008A:\\#\x1D\x01\u00E9\u00EB\u00B3\u00B9\x0B\u00D3H\t\u00B9\x07\u0085 4I\u008Ct\u0084\u009E\u009D5\u00A9/]\x0B\u00AD\x0F@\x1A\x18\u00D1\u008E\u0091)\u00DC\u00AE\u00C3\u00B8A\u008F>$\u00A4T\x0B.\x07.\x0EA\u00D9\n\rnp\u0094R\u00F6r8\x0Es\u00CC9\u00B8\u00CFb\x15AI\u0084\u00C0\u00CB\u00F2;%|W#F;\u0096\x05Mx\u008D<\x12\x12|K*q\u00EB\u00A3\u00DC\u0097F\"\u00DCH\u0080\u0092z\u0087\u00EE\u00D5\u00AE-\u00A3=U\x01\u008D\x1F\u0092\u00F8H\u0097\u00A190\x19\u00DA,dQ\x11\u00C0U\x02\u00DE=\"\x13\u00D30*\u00F4\u0091\u00F7\x1F\x10\x021_\u00C7\u00BCTt\u0086\u00B3\u00DC\u00BDW(\u00F4\"\u00F5%\u00A9\u00DB|\b9,\u00A8\u00A2\u00A9*\u0089\u00F0|}\u00B62\u00C0\u00E6\u009C\u00B6\u00B61\u008A\u0091\u00A4\u00D1C\u00AE\u00C7\u0086\x0E\x16\u0086R\u00D0$\u009E\u0097\u00D0\u0085\u00AE\x15\u00E4?\u00A0\u00DCu\u00CF\u00FCu\u00F5O\u00E8ChH.M\u00A1W\"\x03\u00C5\x04\u00F9\u00C4\x1C\u00F7p\u00F3\u009DW\u00BFl\u00FF\u00ED;_\u00C0\x1B\u00BC\u00DE\u0090!\x00\u00C0G\u00ECO\u00FD\u00DD\u00BF\x7F\u00F3{\x1F}\u00BC]\x16\"\u00AF=\x12:q\u00F5c\u00C5\u00D9\u00AA\x0E\u00C0*\u00F5\u00B3\u00E8\u00E8\u00A9\\\u009B\u00B6\u00DD\u00AA\u0088\u00C0j#\u00A7\u00B1\x0F\u00B4\u00DF\u00FF.$\u0090v\u008B\u0095!\f\x17\u0091\u009FQAj[q\u00EF\u00BE/E.\x12\u00AC\x0BD\u00D0U\u00DFy\u00F8\u0082\u0081\u00C3A\x03c\x04\u00EF\x1C$\u00AC\u00E9U\u009D\u00C8QD==\x12j\x05SwJho\u00E7ed\u00A0W\u00E6\u00E3\u00A51\x0F\u00E88\u00FD\u00FAJ3\x16\u00C1\u00F7\u00A8FL\u00CE\u009A$hk[\x0B\u00FF\u00A0\u00E7@%\u00C2&G\u00E8\u008D\u00C8\u009D\u00E3rxf:b\x02\u009BE\u00F4\"\u00FA9\u00C9\u0080\x14\u00EBPm`\"c\x17\u00E4M\u00E8\u00CC\u00AD\u00CF\u00BDP\u0095\u00C6\t1D\u00AC\u00E3[?m\u00B5\x1B\u00DCq\u00CE\u00CA\u00ECQ\x04\u00B8x2\u00B8fRU\x00\u00B2&\x02\b\u00D1U\x1C\u008F\u00B1\x07\u0091'b\u00A8m\u00DF\u00FA\u00F5z\u00C8\u0082\u00FD:F\x18\u00E4\x07\u0096\u00ED\u00E0 \x15aba\x10d\x04A?\u00CC\u00A6\u00E4\u00E0|8\u00F0\u00DD\u00EF\u00F8\u00BB\u00F88\u00DE\u00F0\u00F5\u0086*\x03\x00\u00FC\u00A7\u00F7\u00DE\u00FB\u0093\x1F\u009E\u00EFx\x18\u00C4Qq\b\ti8 opz\u00F8\u0086\u00D1\u00AC\u00F4+\x1C\u0097\x0E\u00B4\u009F\u00DA\u00D3y\u0081\x16n\x1B\u00F1h\u0094LuE\u00CFF\u0088A\u00D1]c=\u0097\u0086\u00C9\u00DBpl\u0087\u009B\u00FA\u008D\u00EC\x03\u00D2h)\u00A4\u00D1l\x1Cm!\u00F4\u00A2\u009F\t==\u00D4\u0081\\\u00B03\u00DCv\u008F\x0E\u00C3\u008Dw\u00CF\u00C2\u00EA%\u0098h\x7F\x0B\u00E6;\u00D5\u0081YB'\u00ED\x10\u00B3\u009D\u00D7>/^P^P\u00DB\x1D8\u00E6\f\u0082\x16\u00C3Q{\u00BA\x7F\u00FB\u00EE\u00ED\u009E\u00A1J \u00A3\n\u00D3s\u00A0hH\u00AA\x15\x19U\u0098\u00D0\u009Fj\u008FGM\u00C9\u009B\u00D6\u00DF\u00F3\u00BB\u00E6\u00C4\u009AJ\u00C2m\u00D4\u00BDy7\u00BC\u00F7\u00B7\f\u00C8a\u00E0l\u00A5\u00E7\u00F8\u00EE\x04\u00EEd\u008Cg\u0086\u0082~\x1C\u00ED\u00B7\u00E4L\u00BE0)\u009D\u00B3\u00A8%\u00C9\x14\u00F8\u0096-`^#\u00EA\x1AF\u0084\u00A2\u00F9\x06\u00CC+\u00B8\u0087\u00F5\x7FQ\u00A53\u00E2\u00F1\u00A4\x0E\u00EBxF4n\u0080\u00BC\x14\u008A\u00AA<\u00AB\"\u00E9\u00B9 \u00CAV\u008A\x01\u00D5\u008C\u0087\u00DF\u00BE=|\u00F6\u00AF\x7F\u00EFO~3\u009A\u00FF\u00A6\f\u00E1\u00BB\u00CC\u00BE\u00F2!\x7F\u00EB\u00C7`{K\"\u00A2\u00F1P\u0095\u00833\b(\f\x19\u00D3\x00U,\u00AAP\u00A3u\u00A0\u00B2H\x1BTL\u00B5\u00D0\u00831\u00F6 \x02\u0087\u00C2]\x02l\u0084\u00AD\u00BC\u00EF8\u00D9#\\L\u0083;K\u00A5j\u00D1\u0099\x00\u00F2\u00F7^\u00E8%\u00D3\u00A5q\u00DB\u00FB\u0091\x15j\u00B5\u00C8\u00A6g\u00DC|H\u00E30\u0092i\u00B1\u0098\u00BE\u00F3Ca\u00BF\u00C7\u00F4 X\u00EF\u00E1\u00C5\u0080\u00C2\u008E1'\u00E6\x11\x15\u0096/\x13\u00B418\x0E\u00BE/\u00D4\u00EDU\u00C2_\x06\u00CA\u00EE\u00A1\x10\u00B1\x1E\u008D\u0080\u0093\u00A9t[@cHB\x1E\u00E1Z\u009C\u00D0\u00FE\u00C1\u00D3\u008D\f\u00AAl\n\u00EA\u00B3\u0098\u0095\x18\u0090\u00B3\u00E0\u0090\u00BE;\u00EF\u0083\u00A3\u00C6z\u0099\u009EnWW_$\f\u00B3]\u00B5QL\u00A2\u00E6O\u008C\u00C1\u00E9\u00A2\u008Dy\n\u0082\u00ED;\\\x05u\u008B\u0088+l]' \u00E3y4qFA[\u00BB\u00A2ibi\u00D0\u0093K\u0093}\u00CDm\u00EC\u00B5\u00EE\x16w+\u0088^\f\u0098#\x18\u00C1\u00B1\u00F1;\u00D5\u008EcPE\bB\u00CF\u00CD\u0088f\u00B9+\u00FD\x0E\u00B7\u00A5\u00DE>7\"\x0EC\x0F[\u008E>\u00D0\u00A6g;\x06\u00AE`\u00B6\u00C3,\u00B6]\u00F4a\u00C0{\u009F\u00FE\u0098}\u00F4\u00C1W\u00BE\x19\u00CD\x7FS\u0095\x01\x00\u00FE\u00CA\u00F5\x07\u00FE\u00F6O_\u00FE\u00CD_\u00FD\u00F2\u0095f\u00B7$wF\x1D\u009E\u0092\u0084\n~\u00F7\u0097\u0091\u00E8\u00B68\u00F5\u0096\x1A\x11\u00D7\u00CC\u00A4\u00A8R\x01\u0094*\r2\x1B\u00E49D*M\u00ED\b\u00A6}R!h8\u00CC\u009A\x04@\x12\u00FF\u00BC\x15\u00AFP\x0F\u00DB\x05Y\u00C5\x10\u00A8:\u00C8\x00%\x1D\\\u00D0\u00B9K\x0EG,\u0080\u00C7\x1E\u00BBCk\u00D7\u00E8\u00DD=k\x1B\u00CE\x19\u00FBB\x0E\u00BA\u00B8X\u00AEcI.\u00F2l\x0F\u00F2D\u00C59 \u00F4O\u0083\x19\x16U\"\u0089APZ\u00C7f\u00D9$\u00B2\u00BF\x13\t\u00A5\u009Djk\x1E\u00E3l\x01\u0080\u009B\u00A0i\u00CC\u00E8\u009C\u00C8=\x1A\u00A4\u00EF'\u00CC\u009F\u00B6\u00F6\u0093\u00CDHmI\x01-\u00FB\u0084#\x03\u0092\u00A4\u00C2H\u00F5H;Bs\u00D3f\u00FD\x05G\x1Av\x0F\u00D9r\u00A0:\x13~z>\u00D5\u008F86\u009A\u00A4oCms^\u0093\u00DF\u00D4\u00A8\u009Cs[\u00ED\n\u00D3s\u00BE\u00E3\u00D2\r\x19\u00D7\u0090\u0081G\x1E\u0084O.S\u00D5\u00A0f[{\u00EC\u00A07\u009AKw\u00B8\u00D4\f\u00A9%\x13\u0085\u00D69\u00B1T\u00DE\u00CA\u00E2z\u00C1\u00E3\u00AB\x1B\u00F8\u00BF\u00FFm\x7F\x1B\u00BF\u008Co\u00FA\u00FA\u0096\f\u00E1/\u008F\u00A7~\u00EE#7\u00EF\u00FC\u00EC\u00CF\u00E0\x0B\u00DF\u00D9\u0089\u00BFB\u0090\x15\x04\x04\f\u009C\x19\x02\x7F\u00A7\x04w%\x17%0\u00E9\u009F\u00F2\x18P\u0085PI\u00F4\u00D9\u009E\u00D6\x1B\u00DA-Z\u00FEB\u00DA::\f\u00B3\u00AC\\\u00E4\u00FDZ\u009C\u0083\u008D\u00F40\u00F5p\u0083\u00B0\u00B3\u00BA\x10\u00D0\u00A4\x0BO\u00F5R!\u00D2G,\x1F\u009F\x03\u008F\u00A7\u00E3\x06e\u0080;\u00DC\x18\x05\x18\u009Bt\u00D9\x01\u00EC\x13\u0094\u00CCqMU:\n\u00A9X\u0099\u008B\u00B18\u00E6\u00AC\u00C2*e{h\u00BA8U\x16K\x1Ff[\u00B8\u0094\u009C\u00C6v#Z\u00B06\u008C\x15\u00D2\u00B0\u00C9(B\x032C\u00E3\u00E4R3\tK1\"\u0080FB\x16f\u00E1\u00A9\u00AA\u00C4l@\u00DA3z\u00AD\x05w\u00CD\x01\x055\u00C7\u00A5\x10\u00EA\u00CA\u00DA\u008C\x1B\u00AAv\x04\x10\u00C7\u00D3\u0095\u00AAq\u00A3\x13\u00AC\u0097\u008A\u0090\u0084^\u0084\u009BL\u009F\u00EDed\u00A3\x18Bc\u00AAu\u008D-mZg\x06\u00B3\x11\u00B0\x03\u00ABZ\u00A0\x10dU[\u00AE\u00B9L\u00A9C\u00FB@\u00C6)\u00CC\u0081\u00AA\u00D1\u00A02h\u008D\u0089\u00B86wU5%\u00B4\u00DF\u00C4\x18\u00AEp<\x7F\u00FD\u00D9\u00A7\u00FF\u00A7\u00E7\x7F\x0E\u00FF\x1B\u00BE\u00E9\u00EB\u009B\u00AA\f\x00\u00F0\u00B4\u00D9\u00FC\u00C8|\u00EEo]\x1F\x01Q\x12\u00CE/\u00C4n\x18\u00BDNA\u00B2\u00C8P\x11\u00A2\x12\u00B1&\u00D4\u00DA\u00EF\x1A\u0082\n\u00B1m\u0091\u0081\u0088\u0088kp\x05\u00E0\u00A7\u009A\u00D0\u00F4\u00AE\u00B4\x1D\u00F0\x1E\u00CE\u00F3\u0096~\u00C4\x1D\u0082\x118f\u00E2\x0F*4\u00BEg\u00D4\u00D9\u00F2\u009F\u008E\u00F9Z\u009A\u00AC\u00A2NipL\u00A9\u00D1\u00E3\x10h\x01\u00A1;\u00EB\u00E2\u008EG\u0097\u0089\u008B\u00D4\u0080\u0093\u00CA\u0090P\u009Cn9\x1C\u00A5\u0093w\u0097\\@\u00E6\u00E6\u00AA\x13\u00FCOH\u00ED\u00B4\x1F\u0094}\u00E2\u00E2H\u00DD\x7F\u0085\u00DD\u00D4\u00DF\x1D\u00CD\u0085\x17\u00EE@EX\u008A\u0081\u00F5\u00FBkM*\x1AR\u00EE\u00D3y\x04\u0084?\u00A8\u00F6\u0094\u00AB\u0092\u00EA\u008A\u009F\u00FA\u009B}C\u00DA\u00CB\u00CE\u0091\u0089]\u008D\u0088\u00EF\u009E.V\u0085y\u00CFv^Fn\u00CA.\u00E1\u0096c\u00C5a\x01\u00F9\u00C5m\x14\u008F\u0080\u00CElPB\u0080j\u0080\x1D\u00FA\u00EE\u008BJ\u00D2\u00F1o\u00DA\x0E\u00C5\x00L\u00EB;\u00B8M\u00AA\x18\x13\u00E5\u009A\u0094^?\u00B7\"\u00F8)w\u00A4\u00D4\x04\u00ED4%\u00D5A\u00E7m\u00B0\u00B977\u00E75lR\u00A5P\u0096\u00A4m\u0080\u00B2\u0091m\u00C0\u0087\u00E1\u00D1w=\u00F1\u00B7\u00EC\u00DDU\u0094\u00EE\u008D^\u00DF\u0092!\x00\u00C0\u008F?x\u00DF\u00DF\u00F9\u009E\u009B\u00B7?,\x12\x161vC\u009F\u009D~\u00BB\u0082\u00FB\x0EW\n\u00F4\x1D\u0086\u0093\nF\u00EA\u00BA\u00BE8\u00EA\u00C9\u00D8\u00B2\u00F8j\u00E3\u00DE\u00A6{\u009F\u00DD\u008E\u00A8{\u00DA\u00E9\u009E]=\u00A9\u00FEJ5)\u00A2\u00EF\u00D24%\x0F\to\u00958\x12%\u00A0O[a\u00BA\x00\u00A8\x0F?\u0086\u00E1\x11\"\u00E6\u00FFp\x11\u008Dt\u00FC\u00B1\u0084!\u00CB\u00B7~\u00D1Bg\u00A8\u00F3b\u0094$\u00A38\x1C\x19\u0097p\x1CE 3u\u00FA5\u0094Y\be:\u00D5\u00E6\u00C6h\u0082\u0090*m\u00BA\u00EE\u00AF\u00F3\u00C2\u00C8\u00B8\x18&\u00F3\u00FA\u0095a-\u0084\u00DD\u0098[o\u00FB\x1C#\u00B1\u00F4\u009F\f\u00A9\u00DBJd+\u0088\u00A9/uj\u00E6\u00EF\u00EDoh\u00BC\u00B4\u00A7\u00F07x\u0095\u0099\u008B\x07\u0086\u00E5\u00B7\u00C5\u009B\u00C0\u009BIUY\x10\u0083\u00C8\u00CA\u009D5\x1B$\u00B1\u00F5\u00AEPmE\u008E\u0096\u00910\b\u00DB\u00E7\x06?\x18\u0082,C\u00A3\u008C\u0082\u00F9\u00EE\u00EB\u009E\u00B6\u0083\u009E6\u00ED\u00BAFo\x1A3q\x05\u00D9\x12\u00E0;\x1E}\u00FB\u00FE\u00F0\u00D9\u00BF\u00F6\u00A1\u00BF\u00F3fh\u00FD[\u00AA\f\x00\u00F0A\x1B/\u00FD\u00F5\u00D7>\u00F9\u00F7\u00FE9\u00BE\u00FA\u00DF\u009F\x0B\u00A3\u008C;\u00F6^\u00C8\u00ECC\u00EE\u00F8\u00B4\u0086 \u0087\x14\u008E9\u00ED\u00A9\u00D2[\u00D9\n\u00A42\u00C0\u00A8:\u008D<\x1E\u00BFm|v]E8C\u00FF^\u00BB@\u00CF\u009F\u00AA\u008B\u008EY\u00FBu6i\u0081\u00A6G\u00FBz\\a\u00B3g\u00BD]\r*\u00DC\u00B6*\x00\x01\u008F\u00CC\"\u0094\x19\u0086\u00CB\x04vI\u00B9i\u00B5A\u00AC\u0087\u00F1m\u00D3\"d\u00CFv\x07z\u00D5\u00E1\u0088;\u00A8\u0084&\u00A1\x13\u009F\u00EB\u00B6lZ\u00E3\u0087G\u00A8o\u00BA#\u00D9\u00BFHk\u00B6$\x06\u009B\u0081\u0086\u00E4\u0096\u008C\u0094f\u00A2\x1E\u00B6\x0B\x04mt\u00FD]\u0084\u0092\u00FB\x1A:\u00FB\u009E\u00E8)'\u00BF!\u00AA8t\x00-6A*R\u009D\u00A3B(\u0080e\\B\u00CE/\u0090\u00E3U\u00FF\u00F4\u009B!\u00FA8\u00C8p\u00C0\u00F6\u00C11\u00AEj@t\u00CE\u00F9\u00BB\u00EE\u00DD\u00ABUk\u008E\u00D3k\u0091s\u00A6\u00E7oy\u00AC\u00E7\u00B4\u00E4\u00B2\u00E8\u00F7\u009A\u00DA\x12N\u00C2\u00D49_\u00E2\u0098\x1Bl\x0E8\u00EB5z\"\x1A\n?fP\u00AArs\u00C6.\u00A4RF\u00F5.V+\u00DC&.\u00EF\u00BF\u00F7\u00F7\u009E\u00F8\u00CF\u009Fx\to\u00E2\u00F5\u00A6\x10\x02\x00\u00FC\u00C8\u0083\u00F7\u00FF\u00CD\u00F7\u00DF<\u0085\b\fVRQW\x11\u00A2C\u00DE\n\u0099\u00ACII\u00F5\u00D9\u00A3\x0E3\x01#\u008D&N\u00FA\u0097~\u00DF#\x1D{\br\u00B7\x13\x14\x17U\u00BF\u00AA\u00BE\u0082\u00F3\u00DF\u00D1\u00EE\u00D9\u00E2#\x16\u00CE\x0E41T\x0B\u00DEyXPu\u0091,@F\u00BFI\u00C5\u009B\u0088\u00AD\u00C7\u00F8\u00FD8\u0080\u009B\x19\u00EFC\u0089m\u00CDr\x1FR\u00D3R\x15\u00C9\u009C\u0087\u0094\u0098k\u00F4\u009FP\u0080\x13\u00D2V\x04\x1Fc\x1E\x1C\u0098\u0097RC\u00E6,(/F2\x19A\x18\u00EB\u00D0Jb\x1F\u00CA\u0083@F\x18\x1E\x07\u008B\u0096\u00A8\u009D\x03\u00B7\" \u00FD\u00F0j\u00CB;\u008C/\x17h\u00CE\u00A5\u00BC-\u00BE\u00BAC\u0085~\u00D2\u00BD\u00E9B\x1D5\u00B7\u00D3\x03a\\\u009A\u00E7\u00A4\u008F\u00CD\u0081\u00F4\\4 \u00B0\x18g\u00B1\x100\u009F\u00D7\u00AC\u00AC\u00C7s\u00BD\u00C9d\u008Ah\u00F8\u0092\fd\u00AA\u00ED\u00E9\u00CB}t}\u00A8\u00A3\u00DE:'\x06\u00D2\u00EA.\u00CC\u00EEy\u0090\x0B\u00F1\x1A\u00E6\u00D7Eg\x1E\u0095\u00CA\fJ\u0096:#k\u00EER\u00ED\u00FCN\u00DAx\u00F5\u0099k\u00DC\u00FF\u00D1\u00F7\u00FC\u00CD7K\u00E7o\n!\x00\u00C0\u008F\u00D9\u00D3\u00BF\u00F1W_\u00FF\u00C4?~a\u00DE\u00FC%\x1BgO\u0082ES^\u00F6\u0085\u00D0\u00C5\x03\x19\u00A4z\u0095\u00E8\u00A1\u00A9\x19D\x0F.\u00C9\u00D2\u0083\u008AT\u0084%#\x19\u00CF\f&\x18R$p\u00F4k\u00FB\u00EB\u00B6\u00E1Pq\x0E2\x02\u00F6\x12\u00E1\x19\u00BF\u00DE$\u0095\u00A4V\x04\u009E\u0085\x14\u0088`\u0098Z\x1C\u00A5n\u00B4\u00DCz\x18\u00C2\x1B\x11\u00DE\u0086\x0B\u00DF74,\u00CE\u00C9uC\x1D\x1A@\u00A9'(\t\u00D8%\u00B2\u00E0\u00B4\u00A4a\x1A\u00D3\u00DA\u00F7\u00F4&L\u00CB\u00FE\u00A9M\u00B5\u008FI\u0097)\u00BF\u0087\x0Bn4\u00A4TFC\u00ED\u00D1\bXz\f\f\u00C1%g\u00DAR\u00A2\u008C]&?9\x18x\u00E4u]RL\u00A1\u0085\u00990\u009D\u00FD\u00E4\u00E7\u0098\u008D\b\u009Bd\u009Em\u00ECzV\u00D3#ZQ\x06[m\u00A7&/P\u009FG]\u00A7<\u008F\u0090\u00FE\u0096\u00EDg9\u00B6Y\u0092\u00BE\u0090\x04\u008A\u00D0i[\u00B0\u00BE\u00DE\u00D2\u00B8\u00A8\u00F9+\u0086S\fA\u00CC\u00A0\u00AFQ\u00A9\u00C9\u00E2\u00C4\u00E2nz~jw\u00B6s$\u0081,\u00C7\x11\u00D6\u00E2cY\u00C0\u00F6\u0081\u00ED\x1F_\u00FF\u00CF\u00DF\u00F6\x1Bx\u0093\u00AF7\u00CD\x10\x00\u00E0?\u00DB\u00DF\u00F7\x13?{\u00F3\u00D5\u00BF\u00F4\u00D5{\x05M\u00E2E\u0097b\u00D6.\u00E8jD\f\u00C8\u00AC%'5\x17\u008A\u00AC\u00C1\u0090\u00F1\u00F0\x1CD\x04$\u00F3\u00A80\u00E5\u009E\x04E\u00E6c\u00AA\u00B0\u00DC_2\u00FEu\u00B7(\u00EF-\t\x00\u0084\u008E7\u00FB\u0083m\u00C4\x02-@\u00BF\u00E3\u00FB\u00AA>\u00A4\u00CB\u00AF?|\u00B6\u00F3\x18\u00C1\x14\x1E\x1C\x01\u0095/\u0088<\x07\u00A3\u00CF_\u00D6\u00F1\u00D4\u00A3\x1B\u00F1az\u00EE\u0087xq`\u009B\u008E\u008B\u00DC\u00A2\x1E\u00A1\u00C088#\u00B3\u00AEs\u00AB\u00FE\u00C8\u0095\u0089\u00C9\u00DD\u009C\u00DCr\u00BE\u00D4\u00CE\u0098m\u0083\x16W%\u00E75:q\u00A2\b\u00E5jJ\u00AD\u0088\u00F1O\u0094:\u00A3\u00E4\u00A0,\x18\u00CB{\x1Cd\u0092\u00C1P\x18\u00AB\u0092\u008C\u00AC\u0092\u00A5\u00AE\u008EZa\x07}\u00FC\x06\u0086\\\u0093\x01\\<\u0098\u00D5v\u00A86eA\u00FB!\u00BF?j\u0099\u00CA})\x0F\u00CC\u0098\u0094\u00FE\u00C9\x04\u009D0\u009D\u00CF]\u008C \u0099G\u00FB{A\u0091d\u00A8\u00CD\u00D8,\u00A6\u00D0\u00ED\n\u00B9\u00BC4g\u00BC\u0097\u00EADD?\u0085\u00BA'\u00B2|\u00FA\x042\x14Y.\x1BeWB\u00A8@\x0B\u0091\u00DE\f\x00\u008F\u00AE\x1E\u00C3\x7F\u00E8\u0099\u009F@\u00EE\u00DC\u00F8\u00AD_gq\u00FAM__p\u00B7\u00FF\u00F1\u00E1\u00BF\u00F8\u008D\u009F\u00BE\u00FF\u00F2\u0087c\u008EE\u00A8\x1D\u008E\u009F\u008Cx\u0092\u0094}#\x14\u00D9\x03\u00BAo\u00F5\rK\u00A2\u00A3\u00CEK/\x02\x11\x01\u00CF\u00A9\u00A8\u00C8\u00AC\u00AF\u008B\u008E\x04\u00EA\u009ChK\x10/\u0082\u008BJ:\u00A0\x11\u00B3\u00A4d\u00D7\x19\u0081UZ\u00A9\u00A8\u0088\fG\u00E5\x1A\u00E4\u00EF\u00ED\u0081\x0E\x07\u009Eq\u00E0-\u0087\u00E3\x01\u0080{0\u00DC\u009F\u00C0\u00B5\x03\u00F7\u008E\u00B0\x15\u00EC\b\u00F7\u00DB\u00EE\u00F1\u00B9\u0091HwJ\u00DC}rvf\x10\u00C66\u0099\x10>\u0083I\u0084W\u00C4*L9\t=\u00DAQ.\u00C38(\u00BD\x13-\x00v8\u00FD\u00F9\u0096\x12iL\u00C7\u0086\x11\u0095\u00A3\x01dL*\u00DDd\u00D7\u00B3\x14\u00C3m\x02c \u00E3\b6\u008Fcz\u008A;\u00DD\u0085\x0EVS\u00E28\x06\u00DB\u00AF\u009D\u009D\u0082\u00D8\u00AFy\u00AD\u00F3\x19mm,Q`\u00A5\u00C68fI\u00FD\u00A5\u00F8\u00AC\u00BE\u00EB^\u00B3\u00EE\u0093L\u0081RX\u00A8\u00A9\u00F6@Q\u00B6(V\u00E2g\x00S\u00E9\u008E\x03r9\u00CA\u00DD\u009B\x06\u008E\u00A3\u00AEW\x1E\u0086\x1D1\u00B7i\u00B3\u00D09\u00D2K\u0099b\x1D\u00C5o\u00BDt2\u00EA@~\u00A8D\u00FB\x05e\u00DD\u00E5\u00FD\u00A2Q8\u00E1\u00EE\u00EB\x1F~\u00F4\u0089'~\u00F6\u00F9?k\u00EF\\\u00F1\u00C87{\u00BDi\x1B\x02\x00\u00BC\u00CB\u00CC\x7Fx\u00FF\u00B6\u00BF\u00F1\u00E4\u00A5\u0092\u0095\x14\x15\u00A8B%\u00A1&4\u00A2dm\x02w\u00C3R\u00CC\u00C4\u008BX\u00A1b\u00A7\u00EDx\u0096a\u00EF\u00E7\u00C9\x0B\u0081\u00D2\u00BFz\u00B0\u0091\u00AE\u00CB<\u0089\u0093\u00CD\u00A0\u00B6O\u00F3|\u00C0\u0081\u00C4\u00BC8\u00B1\"\u00D6\u00E6\u00CA(\u00F4\u00C0U\u0088T\u00EF\u0092\u0086\r\u00EDH?\u00CC\u00C5\x13\u00F7y\x1D\u00C0CC\u00BA\u00F6z\x01\u0095\u00D9\u008E\u00F5\u00D0by\n\u00E0Ul\u00E4\u00A0\x15;P\"\u00ED\x0B\u00C7H\x17\u00E3\"\u00B8\u00B2-E0\x06\u00C4\u00CE(F\u008D+\u00C3\u0096U\u00B8\u00C5\u00E9\u00D9\u00C0\u00E2\x06\u00D4y\u00EE\u00A3\u00DC{i\u00C3P_*\x13\u00D3a\u00E5\u00D9`?\u009Czs\u00B4\u0081\u00C5~\u0090\x1E\u008F\u00E5]\u00E3\u0090\u009A$\u00D5\u00A9\u00FF\u00DD\u00DD\u009A\u00B7\u008A\u00D3\u009C\u00BC\x185'm\u00AE\u0093p\u0091\x02\u00A0G?:\t\u00B5\u00EF@\u009D\u009E%/4V\u00D9\u0095\u00ED=\u00D1\x10C\u00AC\u009D\u0085yt\u00C6##\"6D\x14\u00A2\u00EC\x02\u00F1vlp\u00BF\u0082\u00DFU\x00\u0096\u0086\u00FC\u009Bk\u00C7\u00CDG\u009E\u00FA\x1B\x7F\x10f\x00\u00FC\x01\x11\x02\x00|\u00D9}\u00FBk\x0F\x7F\u00FB\u0093\u00FF\u00EF\u00F5W>t\f@\u0084*&0\u00E8\x06\u009CwH\u00E8\u0098$\u00C1w\u00D9\b\u0090D,\u0084`\u00A7k\u00AB\u009B\u00C1|\x06\u00B4\tK\x1C\u00F7\u0085\u00AF\u009D\u00BC\r\x10\u00E3@F\u00E7\t\u00CA\u00A6\u00DE\u00CA\x18\u0091\u00E4\u00E6\u00FC.\tu\u00F66T<\u0082PC\u00B5\u0095\u00C5R\x1A\u00AC\u00D4b\x1A0\u00BC\u00D5\u0081g'\u00F0\u0084\x03\x0Ff8\u0088\u00EEM\u00E0j\x06L\x1E\b\u00E98< \u00F9\x15\u0083\u00906\u0084D\u00DB&35\u0088\x18\x14\u00F7puXIZ/\x14\u00E1\u00EE\u00D8\u008E\n\u00D0\u00D9fH(\x13b8\x06\u00B6\u00A3\u00A4\u00D98\x1CR\u00E5\u00C6\u00E1\u00CDL\x0B\fL\\90h\x19\u00DF<\u009E\u0086\x01\u00D8|\u0086\u00A9\u00B9\u00F5as`X\u00AC\u008C}VV\u00E2F\u0084`>R\u00C2\u0083c:\u00BFAuG\u0088 \x11\x00b,\u008AR\x14JP\u00E99!\x00\u00A9Q\u00FD\u00F7\u00B4\u00D3\u00B4~voEHr\u00AA;\u00ED\u00B8\u0093\u00AB\u0099PT\u00DA\b\u009A\x1A\u00AAR\x05D]\u0081*\u00EC\u00842<U\u00C9\u00FF\u00BF\u00BDo\u008F\u00BA\u00F4\u00AC\u00EA\u00FB\u00ED\u00E7=\u00E7\u00FB\u00BE\u0099df2\u0099\u00DC\x00\t\u0082@\u00B8#wQ,\u00B1,\u00AC\b\u0088\u00B5\u00A6\x0B\u00A8\u00B4R\u0090.\u00DAJ\u00ADE\u00B0\u00DAbU\u00BCVY\n\u00AC\u00A5b\u00B5\x15X\u008A\u008D-\u00A2(\u0082J\u00B1R*\x17A@0\x01\u008A\x10\b\u00B9\x13&s\u00F9.\u00E7\u00BC\u00CF\u00EE\x1F{\u00FF\u00F6\u00DE\u00EF\u0099Q\u0099\u00CC$\u0099$\u00F3\u00CC\u00FA\u00D6\u00F7\u00CD9\u00EF\u00FD}\u00F6\u00ED\u00B7\x7F{?\u0093\u00F0\u00A3\u00FE\u009F\u009C\t\u0085e\x15\u00C6\u00B1P\u00A7\u00D5\u00BD\u00881\u00BD\x05^\u008B\u00EF|\u00F4\u00E1\u00E3\x15\u00BB\x7F\u00E7^\x0F\u0093\u00FB\x10T\u00F8\u00F2\u00C6\ta\b\x00p@d\u00FC\u00A9\u00C5\u00F5\u00AF|w?\u00F8\u00C6[D\u00A12mJ:u\u00D5Kh %|\x00\x10x\u0081\x00\\oO+-\u00B9\u0080\u0089S!?\x1E\u009F\x00Hg\u00E7X\u00AE\u00C1\u00B4BQR\u00F8G\u00FFC\u00A7\u0096>\u00C3\x07\u00B8\"H+\x10\u00BD-\u00A9\u00E9I9\u00E5\u00A4)\u00E7b,J\u00C5a\u00BC~\u0099\u00E4\u00F8E\u00DC\u00DD\u00A6\u00FB\u00DA\u00FD\u00B2h\u00ADy\u00AEn\u00E9\u00C9UPMz.\u00B1\u00CE\u00EB\u0092\u00B2O(3\x07\u00B9\u00A4+0f\n/\u00C2\x06\u009F\u00D8\u00AAE\x10z}\u00AF\u0080\n\x1B\u00B1\u00F8\u0092!\u009Ao\u00A4\u00FB\u00BB%\x00\u00DA\u00FC\u00D1v\x17l\u00A68\u00A3\x0B3\u00F2\u00B92M\u008A\u00F2}Z\u00D6\x12\u0087\x03\u0093\u00F2\u00EAi\u00F5\u00A6WN\u00D6\u0090A\u00CB\u00B3\u00F1wA\u00F7\u00BAi\u00A6 \u00A3\u0081L(\x043I\u0083\u00F2\u00C6\x11\u009EA\u00D3:\u00E7$CE\x1A\x01\u00E2\x01\u00EEm\u00C4w|/~\u00F3\u0089\x1Bh\u00CC\u009Fc\x7F\u0088\u00E7\u0090\u008BS^jP\u009D)W|\u0089\x03\u0096\u00F3\u008E\u00C5c\u00F1\u00CA\x13U\x06\u00D3\u00B7}\x02\u00E3\x0B\u00BA\x18^\u00B4\u00F9\u00E9\u008F\u00BC}\u00FD\u0096\u0087,\u009B\u00A5\x19\u00DD?\u0080\u00A0\u00D9\u0082\u00A0H\u00D7\u00DF\u0098\u0084\u00C5\u00CA\u00B7\"\u00B4\u00D1)\u0099\\\u0085\u00BA\u00B0j\u00C1\n\u00FC\u00B3\u00D5^\u0087\u0088\u00F0@\u00FC\u0081\x14\u00BC\u00A0\x1B\u00AA\x10\u008A`Uh\u00FD%M\u0084?0\u0080\u00E2:\x16w/\u00F6\x05\u00C2\u00D7\u00CC\x05;}\x7F\x0F\x1B\x02\u00E7\u00E9y\u009E55\x0Fa\u008F*vw\u00C1\x1A\u00CCCX\u00EF6\x01\u00D7F\u00D8\u00DA\u0090\u00DD,\u00E9\u009Ag\n\u0086\x11\u0098+-\u00A4\u00FA\u008APn\u00FD\u00FC\u00F3\x16\u00F7c\x13w\u00E6!K\u00C4\u00CDj\u00C7i%\u00B6m]18\u00D3\u00AE{\u008CKv\u00A68.1\u0083\u00BD\u00B2\x06\u00BB\u009E\u00D65\u00B1\x03\u00A0`\f\u00C9'\x18\u0090\u00D6\u009A\u00D7e\u009EB\u00BE9Z\u00E7Yw\u00E6\u008A\u008Ay0\u00E58\u00D2\u00BB\x0B\u00AF\u00C4\u00B1\x1A\u00EF\u009Fx\u0089\u00DF[S5\u0080U\u00E1\u00CA\u0095\x19\u0090\x04\x1C\x07\u00EF\u00B7@\x0FJ\u00CA\u00BBi\u00E5o>\u00F3\u00C8.-\u00F9~\u0085\u00DAob\u00FDY6~\u008C\u00B5WD\x19\u0083yd\u00A6\u0090c\u009B\u00C0\x10\u00CA>\u00AB\u009F\u00BB\u00B7`J\u00BAC\"^r\u00ED\u00989h\x00\u00C0\u00D1\u0087\u008E\x1F\u00DF\u00FD\x1B\x07\x1E!\x0F;q\u0085p\u00C2\x1E\x02\x00\u00DCS\u00E6\u00E3kw\x0E\u00FE\u00D0\u00FF\x19\u008F^~s\u00AB\x00\u009E\u00CB-\u00B9\x02\u00E5sS\x04\u00C5\u00DA\u00D3k(\x05Q\x1A\u00D9\u0086\n.\u00C2~\u00C7*\u00CA\u00AB\u00CA\u00A0z#\u00A5i+s\u00CAD\u009Bu\u00E5\u0085izY\u0093\u0094\x1C\u00B5\u00B8 4=_\u00A0\u00D2\u008CUE2A\u0092\u00E1J\b\u00F1\u0082\u00EB9\u009B\x02;\u00AA8\u00D2\x15k\x00\u00E6\x0E\u0096Y\u0097e\u00EF]\u00E0\u00E7\u00E9n!\u00BA\u00FA\x1D\u00AAF\u00AE=\u00D2gL\u00CDi\u00C6\u00D7\u0083O(\u00C6\u00CESo\u00C2~:\u0080\u00ACe\u00E0\u00F5i(\u00CC\b\x7F\u00FC\u00F3.\x06~u!\u00C5Y\u00CB\u00DB\u00A1\x153o\u00A7\u00BB{\u00DF\u00F9\x19\u00CA\u00F9a\u00E0'\x1F\u00CF\u00A4E\x1C\u00DC;p7\x7F\u00D4$\x13\u00B1AK\u00EC\u00D8\u00D3\u0083\u00A9\u00DE\u0082yq\u00DE8\u00A5\u00A3x\x13\x02\u00AEX=IwvL<\u0085\u00CE\u00E7\u00A7\u00E4\x14\x14\u00B7\u009Es\u0089\u0083\u00DFQ\u0081\u00AC\u0086\x0F\u00FE\\\u00DD9,D'\u00C99\u00C1\u00FD15\x1C\u00AA9\x1F'\u00DE\u0082\x02\x1AM[\u00A9\u00A9\x04\u00C0\u00C2\x1D\x13\u00C1\u00CE\u00DA\x02x\u00FC\u00EC\u0087n\u008D2\u00C8\u00B7y+\u00C6-\u00AA\u00F2\u00DC\u009DO\u00BC\u00F7\u00F7\u00D6\u00B6\x1E\u0097\u0082\u00EF\u00F1:\u00D7l\u008C\x07\u00E8\u0082\u00DD\u00DC\u00A6(\u00C3\u0085\u00B2H+\u0095D`\t5T\u00A8\u00DD\u0099\u00EDxZ\u0095E\u0080\u0087vK\u00C7\u00B8g=_^6\u00D0\u00F0\u0085T\u0090/+&KW\u00D0E\u00D3N\u00E4\x1D`<g\u00FB\u00DB\x04\u00E9\u00A3\u009D\u0093\u0096yBs-\u00EE)]JU`C;\u00CE\u00E9\u0082\u00B3 \u00D8\u00D5\u0081uu\x1CA\x15k\u00A3+\u008Anw9Wz\x02\u00863\x04\u00B2\u00AE\u00F6\x7FNh\u00C6\u00D7\u009C\u00D0\u00D2\u00BD1\t\u00F9\x06\u00AE\x00fK\u00BB\u00DE(\x1E\x1A\u0081\u0099s\u00A7\r\bM7wX\u00BA%\u0096\\Lf\u00EEnx\x13s\u00D1\u0087\u009E\u00DE@\x13\x04\u0086\u00D0\u0080(^b\u00E6A\u00A0\u0098\u008D\u00E5\u00AD\u00BA\u00C0\u00F2\u00FEV\u00BD\u0089yX\u00F0\u00E4S\u00D0\x1B\u00AAx\x020\u00C5\x11f\u008E;\u00B0n\u0086a\x15\u00D4\u00EE5\u00B1\x03Stl:\x03\x0F\x13\u00E8\u00E5\u00CD\u00AA\x07\u00C2y\u00A3H\f@\u0091\u00C0\u00B1\u0083\u0089\u00B6,^z\r\u00AB\u009E\x00\u009Fy(\x12b6,\u00AF.JH\u008A'\u0097\u00D8U\tk\u00BB?tGL\x15\x1D\x07\x1F\u00B9\u00F5\u00FEs~k\u00DF\x13\u00E4\u00FE'\x06&r\u00DC*\x0F\x01\x00\u00F6\u008A\u00E8\x1B\u00B7o|\u00F9\u0087v\u00AE{\u00E75su*\u0081e\f\"\u00D4\u0081\u00C0HLH|@\x05\u00D3\u00E5\u00D3\u0080\u00C4\x13*F@\u00F2\u0092\u008FP\u00BC5dhHI\u00CD\u00E6\u009C\u00B1\u00EE_<\u00B8bE\u0080\u00D0\u00A6\u00E15\x10h\x04s\u00EC\u00C4\x04\u00FC\u00C5\u00FAY \bB\u008A\t]sk\u00CD^\u00FE\u0092\u00D5\u0099\u00DD\u00F7GN\x0E\u0085\u009Dk\u00D4\u0086m(\u00D6\u00BBy\x07\u00B3\u00EE\x14\u00E3n\u00B1v\x02j\u00B6^\x03'\u00D2\u00E8B`\u00C8=2\x06.\x7F\u00F3\u00BA\u00B3S\u00F3\u00D4\u0083ag\u00E5\u00D1\x05\b=\x17\u0098%\u00D0H\u00CB\u00D8\x1C\u00C3\u0080p\u00AD\x05\u00BF\u00D7\x15\u008F\u0090\x1E\t\x04\u00B1\u00B8\u008C\u00DDj\t\u00F0\u00BA=_\x12\u0091\u00F8.hY\u0089]\u00D0]\x17\u00B5y\u009Ex@z\x1B\u00DD\x15\u00DF\u0088\x14T\u00A1\u00DB\u00DE\u00E9aK(\x05\u00BB&\u00C7g\u00A8@\u00B9\u00AF&\u0081\u0089\u00EF\u009F\u00CA\u00A6\u00FB\u00FDFj\x12\u00F6\u00BC\u00A4(\x03\x1E\u00C3\u009E{\u00CBgM%BY\u00A8\u009F\u0097\u00BF9?\u00E8\u0081PaLZ\u00E1\u00D1\u00B0Q\x10(\u00EA\u008D\u00A1\u00F4\x004\u00E0\u00E8\u00EE\x05\u0086\u00AF\u00C7\u00CBo\u00AD2\x00\u00EF\u00F1d\u00C6e\u009B\u009F\u00F9\u00DD7\u00AF\x1Dz\u00C62\u00AC\x7FI\x15\u00D2\u00D2\u00D76d%\u00930\u00C5\x0B8u\n\u00E9\u00C8\u00A5\u00D0X\u00C8l\u00A1\u00B6\u009AE\x00\u00B2\u0097\x1C\x02M\u009F<h>\\\x00\\\u00D04<\u008A\u00F0\"\u00F8}\u00BA\u00E15\u0093\u00C0\x14\u0093L44\u0095\x032^\u00E4dA\u00F1\f&\u00B9f\x13\u00F85(\u00CE\u00E9\u00C0Y*\u00D8\u00E8\u008A\u00F5\u00AEX\u0083`\u00DE\x05kjX\u0082hf\x10fj\u0096tN\u00A1W\u00B3\u00A0D\u00C8E\u00BD\x0E\u00C2\x05\u00BB\u008D\u0088\u009C\u00BD\u0091\u009A\u00E8!\u00F8z\u00C7=\x17Y\u00CD<>-\x1C\u0080\u00D1\u00B3\f\u009A\u00A8\u008C\u00C00\x10Q\u00F3\x10\u00CC30\u00A0\u0091*bp\x014k\u00EFX\u0083\u00FA[\u00F5{h\u00F4P\u0090\u0082>\u00A3\u0087\u00D0\u00E3\u00ED\u009B\x07\u00E4\u00CF\u0095\u00DB\u00E7=\u00E5s\u0080oKk\u00CF\u00E3\x0Eu\u00DF>\u00DD\u00DE\u00E9^\u00CF\x00\x00 \x00IDAT\u009F\u009C\u0084\x00\x18\u00C19\u00A2Q\u0092NrS\u00DD?\u0095\x00\u009C\u009EN+\u00C3\u00F0\u0092\u00F3`E!\u00F0\u00EFR\u00C1\x1C\u00DC\x07-\x1C\u0086\u0092\u00AAF1.\x18\u00CD\u00DBY\x05Y}\u00D2\u00A2Cq\u00F81\u0087\u00DE\u00BA\u00EF}\u00FB\u009F\u0089\u0093\x18'\u00C4C8\u00DE\u00F8Gk\x17\u00BE\u00F4\u00BE\u00CB\u00B5E\u00AE\u009E\u00E3\u0082\u00DA\u00DC\u00F5\u00AF\u0099\u0082P\x06\u00B9P\u00EA\u00DF\u00DC\u0087\u00D1\u00D8\u008DT\x06S%P\u008E\u00C9\u00C53\u00F8\x10'\x0F\x14\u00A1\u00A9\u00834T\u00E3\u00C2\u00F2\u00BD\u00D22N4\u00BA+\x17\x02I\u00DD\u00CC\x0FIK\x00\u00F2\u009E' Vz\x17S\x1C\u0081q \u00B0\u00E8\u008A\u00EDn\u00F5\r\u00CBnU\u008D\x0B5\u008EYt4\u00F2Sv\u00D5\u00B85\u00B6u\u00CF\u00D2h.\u00F6Z\u00F2\u00EF\u00AC'\x00\u00B9\n\u00AC3\x00\u00D8M\u00A9\u00E6\u00F5\u00AD{\u0091:\x7F@\u00A3\u00CEbY\u00AE\u0081\u00CF\u0084\x19\u00CA\u00B1\x1CgT\u00A0\u00C3R\u00CD\u00C6\u00AB\x11_\t\u00C0+(\x15\u00D3\u009F>\u00BD\u0087z\u00AF\u00BC\u00CE\u00E8\x1EU\x7F\u00C6\u00E9\u00F7<V\u00E5I\u00F0\u00F9\u00F5\u00E3\u009D+\u00EA/4\u00CE]\u00AF\u00A9\u00FE\u009Ep\x14\u00FA\u00CA\u00F5i\nu\u00E0\x06uN\u00B9A\u00E0\n\u00D9\u00F5\u00DE#4\u00AD\u00FBW\u00A3\u00B5b`\u00C0PZs\u00FE\x00\u00F5xv\u0096\u00ED\x03\u008B\u00C5\u00C67o\u00BC\u00F4$D\x19\u0094\u00B4\u0093\x1A\u00CF\x1Ev]\u00F9\u00D4q\u00EFk7\x16\u00D6\u009AL\u009Ada\u0091\n\u00A6e\u00CB\u00ECe \u00F9\u00FF\u00F2S3\u00DE6\u00DC\u008B\b\u00CC`JY&\x01\u00A8>\u00ECI\u0098@+0\u0099\u0090\u009E\u009ErA\x11>tz\x14\x14\u00F8\u00D1[\u008AGx\u0080p\x1Dc\u0081\u0095\u00A2\u00E9'/\x18\u0098Z\x06?\u008FY'\u00EFu\u00A8\u0082E\u00B7~\t#\n\u00C1\u0087\u0093\u0096\n\u00CA\u00BD\u0094\u00DA+1\n\u0086z\u00AE\u0094\\\u00E3L+\f\u0092\u0089\u00B0\u0090t\x13-\u00E1W~\u0082\u00E8\u00A4t\u00EB\u00CD\u0085\u00ED\u00FEy\u00F6&pr\u00CE\u0098\u0082be\u00D8\be\u00ECd;?&\tS\u0095p\u0084\x00=\u00B34\u00DA\x15\u009Bf\u008F\u0088\u00C9J\u00D5\x14\u00FA\u009E\x02?!v\x01HR\u0090N\u00AF\u00ADk(\u00CFT\x06\u009A\u008A\u0096\u00C2>\x02\x18]\u00D1)&\n\u00A1\u00D7s\u00B9qQ\u00E5\u00CA\x14\u00F9\u00EE9\u00C7\"\u00E4\\\t{\x10j\u00C24\u00CBj\u00B3\x15\x14\x0F\u00B3*\u008C8\x07\u0087\u0094\x10B\x04\u00CBG._\u00BB\u00FE\u009Fv]y\"\u00B2{\u00BCq\u00D2!\x03\x00|Hu\u00DF\u00BF\u00D8\u00FA\u00EC\u0095\u00EF__^h\x12C:3\u008B\u008E\u008A\u00DEQS\x1C\x13&!\u009B\u0099\u00CA\u00AA~\u00E2\u00A2+\u00A9 \u00C8\x17G\b5L`+\u00D0B\u00CE\u0080\u00A7\u00C7\u00A6\u00F1\u00B3_\u009F\x0B9\x00LR\u008AT\x12\u00AE(\u00A84\u00E2<NJQ`\u0092\x1A\u0092z\x0E\u0086\x1D\u00D5\u009DT\u00EE\u008F\u0088o\x07\u00ED\u00D8\u00A7\rg+\u00B0\u00BB\u009B\u00DB\u00BB\u00A6FL2r\u0092Ze\u00BB\u0083\u008C\x02\u00A35\u00B7Q\u0093\u00CA\u00ACL\u00A1I(@*\u00A8A\u00E1\u00EE\u00AFZ\b\x00\u00C7\t\u00E85\u0095<y\x0BE\u0098\u008A\u00ABy\u00F8@\u0095-\u00F0\u00B0\x04\u00A6\u00BEg0\x07P\u00B4\u00D0\u00AA\u00D5B[\u00BA\u00EC\u00E6\u00C2\u00DB\u00C2,\x06N\u0096\x18^\x13\u00C4\u008A\u00B2\u00EF\u00CE7.Q\u00CF@ u\u00F57\x14\u00C1\x15\u0098\u00D1\x00\u00F0\u00D8\x05Le(E\u00F7?0\x1A\u00C0(\u00DB*\x18\u00C6\fC\u00E0\u00F7He_\u00C3\u0096\u00D6\u0093\u00E2M\u00CC%:a\u008F\u0089A\u0098\u00C6*\x1Eg7U\u0080Q \u00DD\u00975\u00E8bD'*\u00FE\x12\u008E\u00847\u00CB\u00FD\u00F9\u009Bb\u00C49\x0F\u00E0\u00E8}\x0E_\u00B7\u00FB\u00A7v_\"\u0097\r\x07\u008F+\u00A0'0N\u00DAC\x00\u0080G\u0089\x1C|z;\u00FBe\u00FB\u0096|\t9\u0085\x12?p\u0090P\u00ACDzZ\u00BA,\u00DE\u00BB\u0080\u00A3x\x01!\u00FC\u00CD\x18\u008A<\u009E?d{!R\u00C2\x02{\u0088\u008D\u0093\u0080Z;\b!\u0080\u00E5\u00E9\u008F\u00E3\u00DA\u00F7\u009Cp\u00D5\u00F2s\x02\u00B4\u00E8e\u0097aH\x02\u0080~\u00E5.d,&\u00AAu\u00FCV7!\u00A1\u00FC\u0097*\u00D8T\x0B\x03v\u00BA\u00FD^\u00AA7[U\u0096\x1C\x0B\u0096]\u00AD5\u00FB\u00E8n\u00B3\u00B2\x11*i\u00C1i\u00D1\u00AA+l\u00EE\u00BD\u00AFD\rZ\u00C5\\@%\u00D6R\x1Ck\u00B92\u00BC)\u00AAL\u00AD\u00A3{\x11<\u0087*\u00DD\u00FD\u00F4X\u0096\f3\u00E8Eh^\x0B\u008F\u00BBpO\u00C7<0\u00C5rDt\u0093\u008A\u00B5\x1B\u00FD\u009A\u0096\u009D\u00E1TV\u008AF\u00EB\u00FA\u00D1\x1B\u00C3\u008E\x1A%\u00DA\u00CB\u00DE1\u00F6\x11}\u00EC\x16V@'tk^\u00EF\u0092\u00D7L\u00CF\u00C8\u00BF[\u00F2\u009E\u00B0\x12\u00D2\u00C0\u00BD\x0E\u00D5\u00A0k/\u00E1+Oi\u00E9\u00FE\u00A4\u00D5S,\u00B1~\u00CC\u00A7t\u00FDWC\u0086jT2T\u00C0\u00B1\u00A1\b\u0095\u0085{:\u008B\u00D9\x02\u00CB'\u00F6\u0097\u009D\ne@\u00C9;%\u00E3FUy\u00E1\u00E65\u00EF\u00FC\u00DD\u00F5\u00EDK;\u00BCu\u00D3J\u0083\x12\u00B7q\u00A8\u00C2^C\x04\u0083M\u00ECs\u009D\u0084\x0E\u008E\x15\u00F8\u00FF\x02\u0094\u00D1\u00D4\u00AE\u00F9\u00B0\u00FCyF\ff\u00BF\u0089\u00FEWaO\u00B7\u0098\x1A\x17H '\u0081\u00C3\u00E9q\u00CA\u00B1\x1D\u0081\u008E\u0090\u00A5W\u00AF\x00\u0088\u0082\u0096\u00F2\u00B2\u00FB\x04\u00F5W\u00CC;\f\\\u00EC\u0096\u0082\\S{Bk\u00DD\x00\u00C49L\u00B9\u00CC\x14\u0098\u00B9\x15\x0B\u00F2O'\u00F8\u0095)8\x16.\rE1\u0091hD\u008F!\u00AC\u009E\u0093~\u00C8\u00AB\u009F\x14;u?\x16\u0098J\u00B4{\u00ADA\x1ES\u0089\r~\x1D\x0E\u00D4\u00F2\x1A-\u00EF\u00EF\u00C0\u00A4\u00A7kE\u00C5\u0080H\x07k\u009B+\u00CC$Z\u00B99\u00F0l\u008B\u00C4\u00FD\x12\u00A8,\u00DBQ\u00A9\u00C7\u00B6Z\u008A\u009D\u00DC\u00A1\x1E\u008D\x02^{\x1D4\u0094\u00F3\u00D4\u00E7\u0081L\u00DBFS\u0099\u00EE\u00E7.\u00DB\x13\x0F2\x0FF\u00D33\u00E9E\u00E8;J\u00E1\x12&\u0085N\u00D5\u00E2OR\u008D\u0095\u00AE\\\u008F\u00E5\u0099\u0099\u009C\u0084\u0082\u00EE\u00FF6\x1Fy\u00F4]{~\x7F\u00EF\u00DF\u0097\x0Bo}f\u00A1\u008E[\u009Dv\\\x1D\u00E7\u0089\u00E8ol\x1Dy\u00F1\x15\u008B\x1B\u00FF\u00E2\x13k\u00C3:S\u0088\u00B6\u00B0ju\u00FB\x07\x00\u0080h.#\u00AF0\u00D5@g\u00D1\u00A7\u008AoO\x1C\u00A2\n:\u0085\u008E\x05E\u00F9P\u00D9\u0094\u00B4\u0096\u009BN\u00E20\u0086\x07\u00FER\x02W`\x16\u0081\u00AC\u00C3\u00AE\u0088\u00BAz\u0086'\u00AA\u00EE\x06Z\u00B6\u0081<\u0086\x04+5\u00D1`\u009F\u00AC$\u0093\u00992\x00\u00A6\u00EE\u009F`\x1C\x15G\x15X\u00EB\x14\u009C\u00A4\u00DB\u0092\u009CC\x04\u009A\u00CDE+\u00C9\u0088\x1D\u0098\u0082\u00F8\x12\x13S\x03l\x1D\u00CB\u00F7\u00CD\u00D3f\u00DA\u0081\u00A6\rc'o?\u008F\u00CB\u00A0|B\u00BD\u00F5\u00A0\u00D5h\u00C8\u00F9\\\x05VF\u00DD\u00BA\u00BD*\u0092\u0092\u00C2\u00EAy\u0098\x12\n\u009D\u008F\u00D6\u00FF\u00DF\u0095\u00E9L\x04-\u00BB\u00BE\u00E6\u00A8u\u00F00mB\u00C2\u00F2\u00FB\r\u00BAs\u0080\u00A8\x19\x12\u00A47h;\r\u00DE\x7F\u0093\u00D7\u00CC\u0095\u00A78?\u009A\x1B\u0081\u00BC\x07z\u00BD|\u0087I\u00B5S\u009FO\u009C\u0083q\x1C\u00DE;\u00FF^\u00F1\x0624-\u00C6\u00C1o\u0098i\u00E1\u00C8Z\u00F9|V\u0097\u00F7 G\t\u00B0\u00D8?n\u008F\u00DF,/>U\u00CA\x008E!\x03\u00C7s6\u00CE\u00BA\u00E2Y\u00D8\u00FBc\x1BK\x00\u008C\u0093\u00A4\u00F6_\u00B40\u00A2a@\u0093\u00A1\u0084\t\u0099u\u0098b\x06\u00E9a0\u00BE\u0095N\u00A2IZ\u00B5\u00DA\u00BB\u00A0E\u00A6#'9=\x01\u00EE\u0093\x15\u008D^f\u00EA\u00FB\u00D3\u00D2X|\u00D8\u00C0.:A&\x19\x052r-\u0086V\u00E2K\u0099Z\u00A5n\u0084\x17\u00B3\u00C6\x0E\u00A8\u00D1\u00B2\u00F07\u00EC\u00DA\x15\u0082-(\u00B6\u0094\x19\x07kz\u00BADv?\u00A2\x0B;]\u00E6\x1D\u0093,\x00\x01?\x02rK\u00B5\u0086\u00A9\x0B\u0094\u00EDK(\u00A0\u00B1\u009F$J\u00EF\u00F7\u00C9NL\x04\u00F9\u00CC\u00CDv\u00D7\x1D\u00D6\u00CBa\x02\u00DA\u00B9\x10N\u00D7\u009C\u00C8\u00AAN.\u00C2R\u00AF\u0093\u008CG-?]5\u00DC\u00FC\u00E8\u0084\u00E4 \u00AB}\u00EE l\x00\u00AA\x1Aa\u0084e!,|X\u00F6\x1E\u008DX\u00A7\u009D\u00A6\u00B2'\u00E5\u00B2#\u00C0\u00CC\u009A\u00E5\u00B0\u00BF\u00F3\u00D8\u00B9N&\u00AF7\u00DF\u00A7u\u00D4f\x18\"Xj\u0086Y\x15\u00E8\u00A6\u00FD\x02\x10^J0h\x1DxL%\u00E2Y3\x0F\x19\u00B8\u0092Y\u00E0\f~\u00E0\u008E\x11;\u008F\u00DE\u00FA\u00B1\u00FD?\u00BA\u00F7\u008AS$\u00BE6'O\u00E5\u00C1\x00\u00E0\u00AFT\u00E7/\u00D9\u00BE\u00E9\u00FD\u00EF\u009C/\x1E9\n[\u00B4W6\u00E1qx\x04\u00A5\x1E\u00C1:\u00EFL\u00AD;5ih~j\u00D4\x0Et\u00A4\u00A6\u00D5\x00\u00FDP,T\u00D9\u00DE\x7F\u00F7\u0089\x16w\u008D\x1CV\u00D4\u00DF\x1E\u00E9\u00B1(\u00C7u\u00E5a\u0096\u00CD&G\u00E4\u00AF\u00FD\u00FA\u008C\u0080\u00A38\u00A6\u00F6\u00C1'\u00C9j\u00ECh\x16@\u00B1\u00A1\u0082}#\u00B0\u00A1\u0082\r\u00F5>\t\u00DD~7\u00B5pa\u00EE\u00AE\u00EC\u008C.\u00AA[\u00C9\u00F9\u00D2\u009FfO\u00E0\u008B!\u0083\u00A8s\u00F2\u00B9\u00BD\u00BB\u00B2\u00D5\u00CB\u00A0G\x01\x15\fK\u008D\u00EB\u0095\u00B1\u00D4\x0F !\u00DE\x01F\u00B9f\u009F\x06\u0081_\x1B$\u00F8\x06\u00AB\u00F5\x0B\u00B6\x1F\u00C2Z[\x1F\u00C9\fI\u0092\u00DA\u00EC3B\x11\u00E7&\u00DD\x19J\u009EC\u0086\r\u0080fX\u00C1\u00D0G\u0093[ \u009D\u00E0\u00A6i.\u00D6J@\x05k\u00ACr\u00EDy\u00CD\u00E4.0\x1Ce\u00BDC\u00E5j\u00B4\u008Aa\u00F1\u0099\u00FB\u00F3\x1C\u00C8\u00ED\u00E0\u00F5\u00F5\u00E2u\u00A9=\u00D3I\u00DDC\u0084\x12\u00F6\u00BD\u008E9\u00DF'\u009E-\x10\u00F3\x11\u00D2\u00B1y\u00C9\u0091\x0F\u00EF\u00FE\u00CF{\x1E'\u00DF,\u008B\u00BFM\x1EOt\u009C\u00B2\u0090\u0081\u00E3\u00C1\"\u008B\u00FF\u00B2s\u00F4\u00F9W.\x0F\u00BE\u00F7\u00AA9\u00E6!\u00F8\u008A\u00B2b\u0092\u00BB\x7F@\u00FC_\u00948B*\u008Ax\x00\u00F1\u00920\x11\u00EC\x10*d,\t\u008F5k\x05c\u00C5\x02&\u00DDp\u00F8\x12\"\x04IA\x0E\"\x13?sO T\u00952\u008C\u0098^\x13\u00DB{GM<\u00EC\u00DC\u00E1\u00A9\u00F8i\u0098\u00BD\x10\u00FF~\u0084Yu\u0082T\u0083\u00DAa\u0097\x14\u00E2\u009ETa\u008C\u00D3x\u009Bno^O\u00D2\u0099\x19\u00AAD\x15`\u00B9\u00D6\u00DAX$Z\u0096\u00F1Z{y\u00FE\u00AA\x1E\x1AH\u0084\x04\u0093\u00D0\x05\u00D99it\u00E5A\u00A4^a\x169\\\u00D1nX\u00C3\u00E8\u00D7\x16\u00F5\x05\u00BE\x7F,\u00CE\x02\x0F\x05\u0090\u00EF^|Nt\u0098\u00C5\u009E9[\u009FF\u0082\u008A@\u00CA\u00BB\u00E1\u00EF\u00DE\u00F33\u00DE\u00D7\x18\u00F7\u0087l\x13\u00E7.:\u00B3.\u009D\u00DFu*\u00DD\x14V>'\x1A\x18q\u00EF\u008FF\u0088\u0082\u00DFz\u00EEW\rD\u0086\x0B\x1AaB8\u00FF+\u00CA \u00E6\x0E\x14[\u00E7\x1E]\u00C8S\u00DB\u00F3O\u00B52\x00Nq\u00C8\u00C0\u00F1\u00C2\u00B5\u00DD\x1F\u00FA\u0096\u00BE\u00EB\u0095k\u009D \u00A2\u00AD\u00B7\u00D0&\u00DEA\u00F2\x0B\u00AC\u00FD\x1A`@d\n\u00AE\x1C\u00EFg\u00CC\u00BFc\x02\u00BB&\x0E\x16\x19y\u00E3\u00AE$X\x0F_\u00B5\u00BC\u00F6\u00EE8\x02\u00BFg\u0098\u0080|\x11.(\x15\u00C0\"\u00FA|<r\u0093x\u00BC\u0099EG99\u00E9\u0081D\u00BF\u00C3:1F`\x1C\x15[\u00AA\u0081\u00ACGSVE!\t\u00E9\u00D4\x15W\u00C4\x12p\u00C7\u0086\x0E\u00C5\x05F\n\u0082\x03\u00FC6\x1F\u00B9=VHP\u009D\u00C74\u00D7\u00DE\u0090~\u00C5r\u00EC\u0091\u00E9\u00C0\b\u008CK\u00B8\u00EB\u00CF\u0090C3\x1Cpa:\u00F6\u0087\u00CDUK8R\u00CE_\u00FF\u00D6\bA\u009CX5\u0096\u00B0\u0084\u00C6\u00A0\u00FCp\t:\u0086CyO\u00AE\u00A0;\u0082W\u00C1%\u00E1j\x16\u0084Y\x18.\u00CB\u00C6F\u00B0I\u00C6\u00B2\u00D0e\x1Ar\u00E51T\u00F3\u00BE\u00EB\u00B3\x185\u00C3\x12\u00BE\x07\u00E5\x01\x148^F\u0082#\u008C\x15L\x19\u008C\u00B2\u00C0\u00D1\u00C7\x1Cz\u00E5\u00EE\u009F;\u00FB\u00CB\u00EE\u0093x\"\u00E3\u0094\u0087\f\x1C\x1FS\u009D\u00BDt\u00EB\u0096w\u00BF}\u00AD=A\u00A5Y\u00BE\x1A4\u00BC\u00B5\u00A3\x11\u0087c\u00D4\u009A\u00B9\u00DC\u00E8\x17Y\u00B4i\u00F0\u00CF\u00FDAR\u00E3\u00D6\u009A\x04`\u00DA\u00BB +\u00CD\x00\u00C0;\u00DE\u00B8\u00E57\u00FE:{\x05\x00\u00D1\u00F7\u00A0x\x0Bm\u00B2?\u00D2DN\u00BC\x04f)r\x7F\u00D5\u00A95\u00A1\u0092c\u0098\u00A0Tf<?\x04\u00FB:\u008C\u00CA\u00EC\u00A1\u00C3z\u00F7\u00B6j\u00DD\\t\x16\u00FCX\u008B2\rD\x7F6V\x1E\u0082b\u00D6\u00B3\u008AO\u00D4B\u008E\u00D6\u00DDj\u00BA\x0B>_\u00DA\u00FDR\u00A1\u00B6\x0E\u00B4\u00A5\u0086%&\u008D\u0099\u00DC\x03\x16[\u00D1\u009D\u009F\u00A9`\u0090\u0092\u00F9@\u00F2\x02\u0086\u00F2w4x\u0081_3\u00B3\x11\u00B4\u00BA\u009A\u00D9\u0083\b\x1DT\u0093\u009E\f\u00CD,\u008A\u00B6\u00B0\u00A2k\u00A3=K\x16R!0\u00A0\u00F4\u0098\u00E2\u00FF=\u00C9a\u00E8\x02\u0095\u00CC\u00D0\u00D8sS\x10\u009C\x1E\u00BA\u0084\u00EB\x0F\x14O(\u008E\u0085r\u00ACr\u00BE\u008E\u00C825\x05\u00DA\u0092\u00F3/\u0097\u0096\u009B4\u00A8!\u0088\u00DDK\x18\u00E1\u008A\u0085\x18B\u00E5\x1Btt\x1Cy\u00C8\u00E1\u00F7\u00EE\u00F9\u00A5\u00BDO\u0092\u00AF\u0095\u00E5\t\u0088\u00E3\u0097=Ny\u00C8\u00C0\u00F1P\u0091\u00E5\x1B\u00FA\u00E2y\u009FYn~\u00F0\u00CA\u00B9\u009E\u009D\u00CEv\u00A5*#?#xR\u0084\x7F\"\u00EC>y\u00BA:\u00D3\u008B\u009AT\u00B2\x12\u00CE\u00F6\u00F1\u00E3\u00D6*\u00B4\x0E\u0098\u0092\u00D0xA\x14\u00C2\u00EE\u00BF\x03\x04*iC\u00BAp\u0091)p\x173\u00B2\x18n\r\u00A8\fX\u008D\x06\u0094}9\u00C9c;qE\u00E3\u00E7u\u009FX}\u00E2o\u00BA\u00E0\x0Fn\u0099\x07\x17\u00D8@\u00C4{*(\u00F1,\b\u0095^\u0084\t]\u0082\u00DA\x1B\n\u00B1kL\u00DAT\u00AEN\u00CEr\u00E5A\x0B\x16\u009F\u00F93\u00ECJw\u00D5\u00AC\u00B0\x02V\u00B8\u00EA\u00F7\u00DCk\x00\u00D83t\b\f\x07)\u00F8\u00D1\u0097B\\A!\u0089`\u0082L5*\u00A4\u0084,F\u0081\u00B6\x10\u00C2\u00F1\x1Ca\u00F6$[\u00A13\x05\u00D8\u00E9\u00F9i\u00A58O\u00E7\t\u00C3\x01zk\u00DC\u00C7\x04\u00DD\u00F8\x06@n\u00CBP\u0086\u00EB<D\u00F8\u00EA\u00CF\u00BD\u00C7v\u0099\u0091\u00EA\u00E1\x1D\u0092\u0091\u00C8\u00FBp/\u00C4\u00B1\x14z\u008D\u009D\u00CFbr\u009D\u00AE,\x04\u00D8\u00BC`\u00E7p\u00FB\u00B6\u00D9\u00F3n+e\x00\u00DCF!\x03\u00C7\u00F3\u00DA\u00FC\u0093\u00FFP\u00DBw\u00EF]v\u00A86t\u00E7 d\u00C5\u00A2)\x07f\x00\b\u00BCU\u00D2\u0091\u00BDD\u00CD\x17\u00A0\x12\x02\r\u00D0\r/\u00F1\u00BA\x02Q@\u00E2\u009E@-@\u00AA\u00AE\u00BA\u00F6\x16\x02$t\u00F5\u00FD\u00A7\u00E6\u00E4\x03{\u0088\u00FD`\u00EB\x10\x04XG7S\u00F2\u00FA\u0098\u00B9(\u00FB\u00D52\u00EC\u00F0S\u00C1\u00FB\x15`\x14\u00EC\u00A8`\u00A7{\u00D8\u00E0!DE\u00C6\x17=\u00DD\u00EF$\x05\u00C1;9\u00BBP\u00BB\u00EBonrG\u00AC\x7F\u00D03\u00E41\u0097:q\u0096\u008Et\u008F{\u00D9\u0096n\u00EF\u00B2\u00AB\u00AD)\u00E1J\u00C3B\x17\u008D\u00CCE\u00D4\x1Dhn\u00C3\u00DB\f\u00C5\u00A1\u00B9\r3\b\u00B9\u008C\u009CN~/\u00BBb\u00A1\x1A\u0099\u0083\\\r;\u00D7\u00A5X\u00D6c)\u008E\u00C9\u0098L\u00B2\x03\f\u0085\u00F8\u00CC\u00EA\u00F5\u00F6\u00BCft\t\"W\r)\u00F8\x7F\x1A\u0081\u00B1\u00DCk\u00BE\u008FZ\u008B\"\u00E55K\t\x192\x1C\u0089\u00F7\u00E1\u00D3 C\u00CCcA\u00C5\u00ED\u00F5m\u00E0\u00EF-\u00BE\u00FB\u00EC\x1F>\u00EB\u0093\u00A7L@\u008F3n\u00B3\u0090\u00A1\u008E\u00E7\u00EE\x1C~\u00C3o\r\u00F2\x1D\x0BY\x07 \x13\u008A@\u00E4\u00A7)<@\u00B8O\u00B5\u00F5y\x05\x05iU\u00A8\u00E5\u00CD\x05v\u00F7\u00BF\u00A2\u00B6.p\u00E6v\u00B5\u00CCR\u00C4\x04(\x00\u00A2z>\u009CV\u00A9\u00E7\u00DFD\u00E0#\u00DB\u00E0\u0096(\x1A\u009A\x14\u00AB\x1B\u00C0\x10\x15\u0089j\u00B8\u00B3\u00DA}\u00A5g\u00B0\\\u009Ai,\u00C0L\u009EY\u00B15U\u009C=\x02\x1B\n\u00EB\u00AA\u00D4\u00D3\u00BD\u009DuC\u00F4\x07\x18]\u00D9:+%uwp\x0F\u00A3uX\x7FD\u00BA\u00C1c>\u00C7\u00EC`\u00ACAUV\u009F\u00D9m\x14\f\u008E\u00A5p-D\u00D1\u00CC,\u00CC\x15IM\u0086F\x06\u0082\u00FD\x14\u008D\u00ACna\u00C1\u008C\u00E7\u0081\u00B9\u00E4\u00E1\u00C2{\x16imi/7\u00C3\x04\u00C1L\u00D3\u00927d\u0086 i\u00C2\x12\f\u00D4\x19\u00AD(\x18\u008E\u00AC\x10\u008B:\u00C3\u0081\u00E9\u00F9\u00E9\u00C50\u00A5<\u00F4\u009CO\u00B1\u0096Ex\\\u00C9\u00E7\x10d\x17%\u0086\u00B4\u00ADO)\u00CF|\x07@\u0086\x12\u00B5B2B\u00B7\u009E-\u00F3\u00F8\u008Cj\u0088R\u00A9\u00CB\u00A3(\x0E\x7F\u00ED\u00E17\u009E\u00F3\u00EE\u00BD\u00CF;!\u00C1\u00BB\x15\u00E36\x0B\x19\u00EA\u00F8W\u00F3\u00B3^\u00FC\u00D9\u00A3G\x1E\u00FB\u009E\u00F5\u00FE \x1Df\u00E1~\u00CAD \u00FD\x01\x14\u0081\u008A%\u00D1\u00FDe\u00A8\u00C9}\u0080v\u00DD_\u00BC\u00C2\u00E22z\x17&l\x1D\x19&4\x10\u00F5\u00B6\u00EF\u008B;\u00C8\u00F3\x15mL\u00AB\u0096D\u0093\u0095\u00EB\u00F4c\u00F0\u00DA\x18J\u00A4G\u00A0yl^\x7F\u00B7\u00C9l\nM\u008A\u00D2h\x06r\u0096s,\x14\u00D8D\u00C7L\x1B\u0096\u009C\u0098>\u0081:\u00CC\u00FAL\x14O\u00F9;p\nZ\x1E\u008F_\u00B53\u00BE6\u00EB\u00D8 \u00C17\u00E8\u00BCV\u00FE\u00BF\x1C\u0087\u00E4,q%\u00BC\x14\u00AF\u00C3\x00B0\u00FDQ\x068I\u00AF\u008EY\u0099\x16\u008A\x02\t\u00AA\u00C1\u00EEk\u00E6\x19'\u00C0\u00DE\u00E7RS\u00F0\u00C5-.\u00DB\u00A5Y\u00C8 \x11>VRQ5\x0E\x04\x7F\u00C5\u00CF\u00A3\u00FE\u00BE\x18\u00C2\u0091u)\u009D\u00DEN*\u0081t\u00D5\u00B3n\u0085\u0099\u0086\u00C8\u00C8h\u00F1|4\u0085\u009D^%\u00C3\x07Z\u00FFZc\u00D1\x03[r\x03\x03\u00F8j\u00E0\x00$C&\u009B\u00E8@oKl\u00DE\x7F\u00F3\u008A}\u00FFr\u00CF\u008B\u00F1\u00EE[#}'6n\x17\u0085\u00F0u\"\u0087\x7Fe\u00B1s\u00D9\u00F5\u00CB\u00F1\u00CF\u00FEZfg\u008D\u00E4\x19\u00C4\x0BP\u00B0\u00F5\u0098\x14\u00CD\u00C8\u0087\x1E3\u00A6hb0\u0096\u00F4\u0097\x17}\b\b\u00EE\u0085\u00DB\u00E5\x0F\u009F/'\x00I\u00A4\u00A7@\u0081\x02\u0092J\x1A\u00E7\u00D7\x10\n\u00F8$\u0099\u0080\u008BeB&\b\u0084\u00D8?\u00D9\x7F~\x1BJ\u00EFG\u00E2>\u00AA\u00A2\u00A1\x17\u00B4\u00A3\u0082-L\u00EB\u00FE[U\x1C\u00DA]\u00C1(\u00E0\u008D9\x06\u00BF\u009F\u00A5\u00D2\u009B\u0090P6\u00E1\u00C6\x17w\u0094q,\u00C3%\u0082\u00AA|\u008E=\u00C22o\u0094\u0082d\u00E9Q \x15\t\x1A\u00F2s\n.i\u00C2\u00E6r'\u00AD\u0099\x19\u0082\u00DE\u0081\u00D11\u00A0\u008A\x1B\u0090?\x10\u0082\u0085\x14n\nce\x05N\x18\u0081\u00E4\u0086\u00F0\u00F9#\u00BDB\n}\x02\u00C79\x07\u00EA1L\u00A1I\u0080\u00B044\u00AD\\;\u0085\u009Fn\x7F\u00E0AZK\u00E0\u00D3\u009B\u0088g\u00DE\u0099X\u00D7\u00C8@\u0091UY\u00E7\u00BB\u00DD\u00ABb\u00FB\u00DC\u00C5\u0091\u00E5S\x16\u0097\u00C9s\u00E5\u00F0\u00DF,a\u00A7n\u00DC.!\x03\u00C7\x0Fnm?\u00E7u\u00D2\x7F\u00FD\u00C6\u00F9FX\u00B5\u00C0\f\\\u00F8d\u00B4K\u009A(\u0083\u00D5\x1F`j\x195_\\Xh\x07\x07M\u00D8[\x1E\x0FSl\x00e\x7F\u0081B\u00DDm\u00A7\u00F5\bBIy\u00A1q}\u00E58i\u00A1\u008BBb&\u00A2O\u00CF3Qvq\x1F\u00EA\x12F\x0Bh\u00C4\u0099\u00B3\x15\u00D8\u00A5\u008A\u008D\u00D1\u009B\u00AC\u00AA-\f;S\u0089\u00D0 \u00C2\u00841\u00D1\u00FA\u00E6U\u008E\u008D\u00D5t>\u00F9\x06'1\x11\u009C\u00D4n\u00A1E\x00\u008C\u00DA\u00CC\u009A\u0095n@<\u00AE\u00887\u0080\u00D5\u00CC:\b\u009C(\x05\u00ADkrg}\x054\u00DB\u00B1\u00FBs\u008A\u0090E\u0081Ah\u00B1\x11\u00A1C\u00A0\u00FFE\u00A0'\u00D5\u008E\u00E5\u00F8\u00F1\u00B9\u0083y<6\u00CA\u00FE\f%\u00F8^\u00E9\u00FD\u00CDz\u00BE\x076\u009A\u0099Tb\u008Ei,\u009A{}\fE\x18:@\u00E9=tW\x12-\u00CE3x\u0096LF\u0086oTh\x06(G\u0095\u00AAf\u00D8C\x1EK\u0083b\u00B9k\u0081\u009D\u00A7\x1F}\u00EE\u00BE\u00DF<\u00F77n\u00BD\u00D4\u009D\u00D8\u00B8]\x15\x02\x00<\x7F\u00FB\u00C8\u00CF\u00FE:\u00D6\u00BEw\u00C4,d\u0086\x16i\u00E2~\x13\u00A1\x05Bp&\u00CB\u0083\x15aLP\x06\u0091t'\u00BAkB\u00DC\u008A@j\u00E0\x11t\x0B\u00AD-\u0098\u009F\u00D3\u0089\u00FA6\x11<\u00EE\x0F\r\u00EE\u00A9BZ\u0098\u00E3\b|]\u00E3\u0081\x16\u00825\u00FF\u00C7x:\x1E\u009F*\u0089\x02\x1DY2\u00EB\x13\u00DE\u00D6oP[\u00C3A\u00815\u00C7\x00\u00E6H\u00C1\x1F\u00D4\u00D2r\u00C3\b\u00B0\x0BsS\u00EF\u00BAT\u0094&\u00D4R\u008D\u0099\u00A5\u00F0\u00F3,M!\u00D4\u00C5C\u0086\u0091\x1E\u0083F\u00B8bBo1|\u0093d\x1E\u00CE\u00BA\u00E1\n\r\u00885\x17\x06%k1k4\x04H\\\u0081\u00CA\x01S\u00C1W\u00E4\u00CAUA`\u00D7\u00F4\b\u00A2;SG4\u00A6\u00AD\x05R\u00A1H4\u0085\u00BBi.e\x17)Cn\u00E7\u00F3mV\u00B8+\u00C1:,\u00EFp\u00D2]\u00C9\u009F\u00B5\"=\x05\u00D1\x1E\u00CF\u009E\u00F8R%\u0083\u00D5\u00B4%\rY\u00AClU\u0094W\u00CC\u00F96b\u00F3\u00D2\u00A3\u00AF\u00DA\u00FFG{\u00FF\u00DD\t\t\u00D8I\u008E\u00DB%d\u00A8\u00E3%k\u00BB_v\u00DD\u00D1\u00AD\u0087\u00BD}\u00C07J\u00B7\u00D3'\x1BP\x01\u00C6\u00D7!p\u0098\u00B8\u0086\x15\u00B5N\u00E5\x01D6!\x18a\u00C7\u00D2\u0098\u00A3\x1E=\u008E\u00EFB^\u00D2C\u00D9\tI\u00D3\u00F2\u00C3<\x03U\u0098\u00C0\n\u00DD\u00C5\u008C\u00FB'\u00E9\u00A5r\u008DUq\u00F0\u00B0qo\u00DC?\u00E8\u00AA\\\u00C6\u00DB\u008E?*\u00B0\u00A5\u00E6-4\u00A4\x0B-=Kn-\u00A4\x10g\u00C9\u00E9\x04\u008Cb\u00E8P'!3\x05\u00E1\u00CAr\u00E1\x11\u00AF\u00924\u00CCAb\u00DD\u00C4\u00C0\x12\u00EC\u00AA\x02=wq0\u00D7\u00B6\u00E7k`\u00EB{\x03N1q\u00DF\u009B8k\u00D1\u00DFE\u008D\u00FF\x13W\x02\x14\x12\u00E4\u00A9\u00DA\u00E0&R\u00BB\f\u00954\u00D7\u0086\u00ACJ/\x04]3L\u00E0\x1C\u00C1X\u00D6\u008EPs\u00F7!EI\u00F2Zy\u00FF\u00FE\u009B\u0085i\u008A\u00A2\u00DC\u008B\u00B0\x0F\u00DA\u00B28\u00AB\\3\x15}4\u0084\u00F5w\u00D3\u00D4l\x17\u00D9\u0098\x13\u0082\u00BF(\u00B6\x1F\u00BE\u00F3\u008Es^\u00B5\u00E7ex\u00C4\u00DF)R\u00A7t\u00DC\u00EE\n\u00E1Q\"\u00E3\u00DBT\u009F}\u00F3\u00E1\u00CD\u00FF\u00FB\u0081\u00D6.\x01$\x1E\x12 \u00FE\u00F0s\u00A5\u0087hP\u00C2\x17\u00EFnX\u00C4\u00DD\x10D\x1FEmeR\u00C81\x02\x1A\u00AC\u00C1\u00F0,\u00F2\u00E50\u00A5\u00A9\u00F5E\u00FB66\u00D15C\x04\u009E\u00DA5<\u00CA\u00FE\u00D3x\u00B6\u00A4<y\u00FD\x1EVT:sN\u009E\x04\u00BAx\x1D\u008B\u00B1cP\u00C1\\\r\x0FX\u00F85\u00AF\u00F1\u00FE+8V\u00EE1Ro\u009A\u00CDGxL\u00F2\nH\u00A9%\u00B8%\u00CE\u00D8\u00E4\u00C4fZ\u008D(x\u008F\u00DF\u00EA\u009C\x01\u0085\u008A\u00E3\x0B\u00DA-\u00CF\u00E3\n,dA\u00DD\x13So\u00E7\u00EE\u00CF\u00A6Y\u0080\x16B\u00AF\u00AE\x11\u00D8<\u0095\u00D9\x19>\x0B\u0086\n\u00CB\u009Ea\u0081\u00A5\x05{\u009C\u0093\u0095\u00A2y\u00BF%\u00C3\u00E3/\u008D^\b\u00A7E\u00BC\u00BF\u00FA\x1E\u00FC\u00DE\u00C7\u00E2\u00E1q\x15(f\u00B4\u0080\u00F4`b>h\u00C1\x18\x14\u00A1\u009C[7\u00E6\u00A7\u0091\u00E0\u00FC\x19z\u00A6F\u00CBo\x00\u00E8}\u00C4\u00E2+\x0F_\u00B9\u00EFE\u00BB\u009F-\u008F\u00B8u\u00AD\u00D4Of\u00DC\u00EE\n\x01\x00\u009E&r\u00F3\u00AB\x17\u00DB\u00CF8tt\u00FB\u00CF>\u00D66\x0E\u00F0%\u0085\u00E0\u00A2Z\u00F6\u00D2\u0085\u0086\x13$\u00B6\u00D5\u00B0\u00C4\u00B4x\u00B5 )\u00ADr\x11\u00C0\x12f\u00C4q'\x1A_CYh9G\u0086\x19+\u00D6\u00C8\x15\x05_\u00F6$\x05\x19\u00D7\u00AFay\u00C8w\u00AF\x13PBy \t4\x11\x12\t\u0096\u00A3b\u00E1\x13)]\u00DE\u00AC\u00C3\u00E7\u00FA\x0B\u00A1\u00D8\u00FA\u00D4%>\u00E6\x1E\u00A9\u0098\u00A2\x17\u0080\x04:\x1F\x18\u0088\x13\u0093\b4Z\u008D\u0082#\u00EE*\u00DE\u00EC\u00C7\u0098\u008A\u00BD\x03\u00A1\u00F0\nV0bZ\u008A\u00DEt\u00F5=\u00DA\u00E7,~\u00A2\u00D5\u00B6\u00F7;}\u00DEI\u00FCq\u0090\u00D1\u00FF\u008E\u008CMy\u00E7\u00E4<4'-Qqg\u00EF\x0BW\u0088@d<\u0096\u009A \x1FT\x03\u0093H\x0F\u0086\x041;\u0099\u00FAs\x1F\u00E8\u0089N\u00DE\u00A9\u00960\u00C1\u008D\x12\x14u\u00DE\u00F1\u00B8\u00EE\u00A0\u00D8\u00B9\u00A4cy\u00AF\u00AD\u009B\u00E4\u0099\u00B3g\f/^\u00BB\u00F9\u00C4%\u00EB\u00E4\u00C7\x1D\u00A2\x10\x00\u00E0%\u00F3\u00F5O\u00FD\u00A7\u00AD\u009Do=\u00BC\u00B9\u00FC\u00C3\u00AB\u0086\u00D9F\x15\u009E\u00AC\t\u0097I\x18\u00C0\u0087m\u0093\u008FT\u00E3d~U%\u00C1c\x01\u00B0\t\u00E1\u009A=\x15\u0086\u00BB\u00C8\x13\u00C4\u00B9f\b4\u00CEy\u00BC\u00E2$(_6{(\u00F8\u00A9\x03\u0084\u00AC\u0093D&\u00C4\u00A6\u008ADW`r\u00F2\u00D3\u00F3X]\u009B)\x04\u00B5\u00DC\u00FF\u008E\x0Bt\u00E3*K\u00CA\"\u00A8\u00E3\x1C\u0097n/\x05h\u00AC\u00CA\u0082J\u00A0\u00D6kHxC\u00D1\u00ECe4\u00C1\u00E3\u00E3\u00A5@\u00AA\"V\u00C3c\u00A8\u00C7\u00EF\u00CC\u00BF\u00CB\f\u0082\u00F8kc\u00F8Q\u00F1\u00A1d$\u00A6\x17\x12\u0082\x03D\u00E8U?\u00D7r\x1E\x14%BA\u00E5\u00FD\u00A8\x7F\u00CF\u00D0#\u00C2.Me\u00AC\u00D0\u00C8\x14X\u00EC\u00EF}%}\u00DE\r\u00AE4l.\u00E5<\x0BP\u00B1\bx\u00ADUi\u00E5\u00BD\u00B7\be\u00F3\x19\u00D9\u0083H\x0Fa{\u00EF\u00E6\u00D6\u00DAS\u0096\u00DF\u00BA\u00FF\u00E7\u00CF\u00F9\u00D4\u0097#C\u00B7\u00C5\u00B8\u00DDA\u00C5\u00D5\u00F1\u00FD\u0087\u00B6.\u00FB\u00E5\u00A5\u00BC\u00E9\u00A0\u00CCm\u009D\u00D1\u00D1\\\u00C9I\x1F\u0082x\u00F1\u009A\x02\u00DD;Zw\u00A7\u00AD\u0082|\u00A5\u0096`\u00D5\u00AA\x0B\u00DC\u009A\u0085\u00D0\u0090R\u00AA\u00A1\x1CZ)~\u00A1\u00D5;f\u00B9-N\x06W2\u00ADX%\u009D\x1C\u00FF\u00D8\u00BF'\u00BF;\u008E\u00F1(2\u00BB\u0091\u00F1\u00A8\u00AA-\u00CD\u00BE\u00A6\u00C0n\x15\u00CC\u00D5\u0097\x7F\x1B\u00B9X\u008B\u00F74\u00EC$)e1W\x05\u00C2*:.\u008A\u00E0\u00DA\u00B3i\u008A\u00A8\u0081\u0094\u00EA\u00CAbX\u00A6\u0095c91\x17ba[\\\x02\u0085\\\u00C8e\x10\u0099\u00D46\u0088f\u00BBvZ\u00E5\u0086\\\u008A\u008E\u00E0\x1AC\x02\u00DBOJ\u00A9\u00F4\nP\u00E8\u008AAx\u00DD\u00FCL\u00E9A\u00D1\u00DBI\u00F4>j\x19\u00C0X\u00BE\u0086\u008A\x1A\u0099\u008D\n(\u00D6mf|\x0F\u00DD\u00B2;Tj\u00CC\u00D8X&\u00C6\u0095\u00DF\u0098\x00&\x17\u0096\u00D5r\u008D\u00F5>\x04\u0096e\u0081*\x16g\u00ED\u00F4\u00E1\x1F,\u009E}\u00D1\u00E5{.?I\u0091:\u00A9q\u0087+\x04\x00x\u00E1\u0097\u00B6\u00BF\u00FB\u00F2e{\u00F5!\f\u00E9\t\u00C0\u0080.s\u00B3\u00BD\u00E0\u0086BJ\u00A1\u00EC\x00\u00AAu\u00F6mk'\u00A5t\u00913\u00F4\u0098\u0084\x02L\r\u00ADz%\u008AH1\u00D6\u00F4&\u00B1\u0081\x10\u00F4\u00C2YXm\u00B0\x1Ay\u00FD*\u00F4+\u00C7Ze9\u00C66=\u00F3\u00DA4Om\u00EC\u00D8\u00E8\u0082]\x00\u00D6\u00BB`}\u00CC\u0095\u00A2C!t\x16>\u00D5\u00F0\x02\u0099\u0092\x1CY\u0091\u0089\u00F81\u00A5\u0090?P@GE[d\u00A3R\u00AE\u00CD\x10\u00A4$\u0098\u00A0\u00CF\u00D0r\u00B2\u00C3W\u008Bv\u0090\u00CEX\u0089\u00DE\x10\u0096\n\u00C1\u00B7#\x0BQ\u00B4d\x1E\u00E0\x19\x12\u0094^\x04(\b\u00BF\u0094\x15\u00AE\u00B9?\u00AC\x1E\u0080\u00AC\u00C2X\x03\u0092\x1E\x0F\x18\x16\u00A5r\x10?\x16\u0095\n\u00C0\u00E7u,\u0087\u0080d.\u00BE\u00F3\x19\u008B\u00AB\u00D4\u00FB4\u0094U\u00B7\u00C9n\u00E4\u00DFdM\u0082\u00D7\x00\u00DEg^[\u0083\u00A0\u00AF\u00ED\x00\u0097\x1E}\u00C9\u00BD\u00DE\u00B6\u00FF5\u00A7B\u009ENf\u009C\x16\n\x01\x00^t\u00CB\u00E6\u008F\u00BC\u00E1\u00A8\u00FC\u00C7\x1D\u0099\x03hnm]h]\u00E3G\u00E5\x17\x1F\u00B43\u00C9\u00C2\u00E5W$\u00E8X\x05?\u00D2i\u009A\x02\x16\u00F1&\x17T\u00B1s\x19kM#\u00ED\x18 b(!)\u00D7\x04\x18\u0093\u00AD\x1C\u00D7'\u0098)\u00A6\u00964l*\x11fS\u00FC\u00D8t\u008B\u00E9E\u00E4\u00F2]~\x7F\x00\u00D8[AF[\u00EAm\u0097\n6\u00C4R\u0090\u00EBN\u0085\u00AD\u009E\x02\u00C3\x03\u00AB\u0086\u0094\u00E8\u00B3h\u00FC\x02\x13\u009A\u00A1TG\u00D2#hK$\u00FBpt\x0FA\u0081X\x17\x11\u00DE=\u00D9\u0085w\u00A6\u00E6\x11\u0090\x1A\x1C\u00A9G\u0094&&\u00C8\u00CA\u00C7\x14bL<\u0084\u00B0\u00FA\u00FC\u00BC\u00E7\u00B6L\u00F9\u00F2\u00BBJC\u00B6\u00FD\u00F3\\\u00D0\u00E9\u00F1\u00AB+?I7\u00F6\u0082\u00E8\u008F+\u00DE\x06\u0089CE\u00B0M\u00C8\u00ED\u009D5\u008F\u0093\x04l\u009E\u0092\u00FD\x17\u00E3<\u009DJ\u00C8\x19\u009E\u00C8P\u00C9\u00B2\b\x12\u00F7\u00A0\u00C3\b\u00BDt\u00F3G/~\u00C7\u00BEW\u009C\x021:\u00E9q\u0087a\b\u00AB\u00E3\u00C7\u00F7l\u00BC\u00E2\u00D0\u00CE\u00E1}o\u00DEi/YHKk\t\x14a\u00AB(~\u0092\u008D\"\u00C5\u00E4\u00FFW\u00D4\u00CF+O@\u0082\u00F1\x16e\u00BF!\u00F4\x068\x11\u0095\u00AE\u00E0cZ\u008C\u00FC\u00DC\u0080.\x05J\u0096\u0084\n\u00C2\u00BC\u0085\u00CCC\x13S\u00C8\u00D0A\u00F2:QB\u0083h\u00B2\u0099%\u00AFZ\u00D8\u0089\u00B6\x00\n\u00B0\u00ADe;\u00AFu0\u00DE\u008B\x1D18\u00FE%nm^*\u00CC~\u008A\x1D)X\u00E2iO\u00A3\u0082k2\u00F4 N\u00DE\u00E9\x01\u00C4\x01\x1E\x1B\u00FB3dzp\x1E\u008AQ!\u00AE_\u0089\u0098\x11$n\u00AE\u0088#{\x00\u00A0\u00C9\u00B4\u0084=>\u00E7\u00ABG\u0089\u00FF\u0081\u00D8\u00D6\u0096Z\u0093\u00C9<!\x01\u0096\u008B\u00C8\u008E\u00E5\u00DD\x05\u00B0\u00D8\u00ED\u0099\x1A\u00CC'\u0091\u0089`\u00DF\u00C9\u00CA\u0094\u00ED\u00A1\u0098\u00E1\u0098\x05\u0095t-\u00A5\u00F6K\u0098xZ\u00CC\u008C\x15\u00E5\u0094\u00CE\u00A6\u009F[\u00D1\u0087\x1D\u00B4'\u00ED\u00BC\u00FA>\u00AF\u00DF\u00F7\n\\\u00F4\u00E5H\u00C9m?N\x1B\u0085p\u009E\b>\u00AD\u00FA=;7n\u009D\u00F5;\u00DB\u00ED\x05#Z\bRX]\n\u00BC\u00CF\u008C\u0089;\u00DEsB1\u00EE>&\u00B3\u0080\u00F4\x1A\u0098R\u00C4X?\u0087\u0083K\u00C7Q2=\x15\r4\x17\x04\u00A9^G\u00E0\x18\u009A.y\x02\u0096\u00B9\x7F%)\u00D5\u00ED\u00ECo\x07HyM\u00BC\u00EF\x0E`4%\u00B4tr\x14\u00BB.\u008F\u008E\u00EC\t\x10\u0098K\u00F3\u0090c\u00E8Rp\r\x16\x0E\u0089O|\u0086\x04\u00F4V$B\"[\u008CE\x03\u00EB\u00B0\u0094\u00A2\u00ED\u00CF&\u00ABK8\x1E\u00E0\u00BC\u0081P\u00A6\u00C8\u00F6e$\x18(\x15\u0096\u00AA\x0B\u0097\x1Dz\x06\n^\n\x0F\u0095\x11\u0090\u00EF\u008E\u00E0!\u008Fk\u00AE\u00BD)N\u00AB\u00F0\u00B40 C1\r\u0081\x1CF\u00D8\\(\u00C7Su\u00E2TyG\u00CD\u00EB8\u00F8^\u009A\x1B\n\x05\"$\u00B1\x05]\u00EDb\u0082\u00A7\x10\u00FB\u00C3\u00B1$g\"\u00A24^u\u00D0U\x01H\x13`Xb\u00FE\u00D8\u00E5\u00AF\u00DC\u00FB\u00F5\u00FB\u00BEG.:m\x1C\u00F5\u00D3G!\x00\u00C0\u00FDD\u00F4\x13\u00AA/\u00C2\u00F5\u009B\u00B3\u00B7\u00EC\u00AC\u00FD\u00B3Q\u0087\u0089P\u00860u\u009F0\x13eP8\x07\x00&H>\u0090\u0093\u008A\u00E9\u00BD\u00C2O\u00E0\u00F7S \u00CF\u00AD\x050\u00C9\x04hy\u00C1\x14\u0094p\u00FD;\u00A2b1\u00EA\x17\u00A8m\"\u00FCI\u00A6\u00A3\u00E1\x04\u00D3\u00FB`\u00B8`\u00BB\u0099\u00B0NR\u0095]\u00C2\u009A-4\u009B\u0090p1\x17\u00E6\u00BCSY\u00B2\u00CE\u00C3\u00EEw\u00E6\u00A5\u00C49y\x19#'\u0088\u00DB=\u00AC!\u00EE\u00C24\x1A\u00DB\u00A7\u00C5\u00F4us\u00DEDaEGt\r\x10\u00D9\x18\u00EA\u00C8 \u0091\x05W\u0081\u00E8\u00BD\x1D-:L\u00F3=#\u00AD\u00BC\u00BA\u00F0\u00C7\u00F9\x19\u00EA\u00F8{k\u00AE\u00EC\u0098\u008D\u0088\u00E5\u00E74\u0081F\u00B6@\u00B3y\u0090\\\x0BhR\u00AD\u00BB\u00A6W\x11s\x00\u00A9\u00B4\r_\u00EA!\u00D8\u00AD\x18+\u00DE{\x16|\u00D1\u008B\u00F2g\x03x\u0093 {\x18k\u008F\u00DA\u00FE\u00B5{\u00FF\u00CC\u00DE\x17\u00C9W\u00C4\f=-\u00C6i\u00A5\x10\x00\u00E0\u0081\"\u00FDJ\u00D5\x17,\u00AF;\u0082?\u00D8\u00DA\u00F8g\u008B>L,\u00FCd\u00B1\u00CB\u0089\x15\u00972\u00F9\u00D3\u00BD\u009B\u00E0\x0B+J\u00A3\u00BA\u00AA5\u00E7\u009C_f\u0098\u0090\u00C7\u00D1\u00DC\u00AE\u00B8\u00E4\u00D5KY\u00BD\u00B6\u00C95\x04\u00FB\u00D2\u00FB'\x14\u0092R\u00E0\x14\u00A1\u0090|?\u00BA\u00FBE\u00B8G\x05\u00B6\u00DD\x1BI\u00A5S\x14\x1A-\u00BB[|z\x19\u00F4\u0080jX\u00D3\u00BBD\u00F6\u0081\u009E\u0085\u00B8\u00E2\x19\x01_,\u00D6n7\n|\u00F8l@\\6\u009F\u0097\x02\x18]pjHe>\u00BD\u00DD?\u008B\u009CF ,wM\u00E3\u00C5\u00A3.\u009Fu \u0084\u00D1X\u009A\u00C5\u0093\u00A2\x07\u00E6\u00F7\u00DD\u00F8\x1DX\u0081\u00E9\u00D6\u009A\u009EB=n}\x7F\u00F1\u00DE40\x1C\u00E2\x0E\u00E9\u00B1\u009AR\u0089\u00CAN\u00BF\u00F6\u00DE\u00F9\u009D\u008D\x0EWr>UZ\x17,gK\u00CC\x1E{\u00F4\u00D7\u00BE\u00EAU\u00FB^ _\u0093\x1C\u00D0\u00D3e\u009Cv\n\x01\x00.\x11\x19\u00FFJ\u00F5\u009F\u00CF\u00AE9\u00B2|\u00EB\u00D1\u008D\x17,\x1C\u009C\u009B\u00F4\u009E+\x13(x\x0B\u008A\u00A8E\u0088\u00859B\u00D0r\u00FF*\u00A0\f=\x18&\x103\u00E0[\u00D4\u0095s\u00C5Lu+\x1C` \u0090@ \x05\u00CEc\u00D5\u0089\u00F5\u00E7D\u009Bx\f\u0088I\x18\x1Dr\x14e\u00D5\u00E8\u00B4fp\u00D0\u00B3wk\u00FB\u00CD%\u00CB\u0088\u0092s\u009DG\u00A6\x1C\u0087\u0091\x16\u00DA\u00CEC\u00F6\x1D\u00A0\u008E5H\u00C6\u00D8\u008APR\u00B4\u0088\x00\u00A2\u009E\u00BFAc\x01Y*h+k\u00EE\u00FE\x7Fs\u0095\x15F)\x1E;\u0082\u0081G\u00EC\u00C6\x18zL\u00ED\u009A\u008E`\u00980*\u00CA3\u00F6\u00FB\x06\u009FM\u00E8\u00E8t\u00C3Kz\x11\u00C0D\u00A0\u00B9\u009Dm\u00A6\u00A9$\u00CB\\!+\u0096\u00FBV\x12\\cM\f\x10\rZ9\u0087\u00D8\u0099\u00B9\u00BB\u00C2\u0093\u00F2n#3\x05\u0080\u00AB86X\u00EB4\u009Dob\u00FE\u0098\u009D_\u00B9\u00E4g\u00F6\u00BD\u00E8tT\x06\u00C0i\u00AA\x10\x00\u00E0\u00C1\"\u00FDj\u00D5\u00EF\u00DA\u00F5\u0085\u00C3G\u00DErd\u00FD%Gd\x0E\x00\u00C1\u00AD\u009FZQ\u00BE\u00C8\u00ACy\x0F\u00A1\fSC\u00F4\x1C9\u00E1\u00A0E ]1\u0084\u00A0\u00A2\b\t\u00D2}t7\x1E\u00C0D\u0090\u00A3n\u0081\u00D7\u00E4\u00E7\u00B1\u00D3\u0088#\u00D3\u00F99S\u0092\u00AB\u0093{r^*\u00BB:\u00D1\u00FD~\u00F9=\u00BB\x15-YX\x13}(\u00AD\u00E0i\u008Cs\u00E5\u00BD\x18*\u00EF\u00E7Z\u00DA\u00BD\u00F7\u00A2\x18\u00E0\x1EB\\\u0087c\x17\u00BC\u0084\u00C8\x0E\u0080:\u00C3\x1A\u00AA\u00F0\u00B6'\u00E9XI\u00AF\u00AB\u00C3\u0094V,\u00D9\u00A3EX\u0091\u00F7\x1Cy\x7F R\u0085\u00A3k\x03k\u00A3.q\x1Ef\x0EB\u00A1\u00F8>ld\u00CA\u00FD\u00ADn\u0081\u00CA\u009F\u0082n7\u00C0\u00BA\x02\u008A\u00B2({*d\u00D1\x14i\u00DCCxY\x1A\u00A1\x0F\u00FB)\u0088\u00DA\u00C9D\u00E9=\u00D9\u009DvU\u00B4\u00D9\x0Ef\u008F\u00DFy\u00F5%\u00BF\u00B4\u00EF{\u00E4!\u00A7W\u0098P\u00C7i\u00AB\x10\x00\u00E0^\"z\u0093\u00EA\u00BF\u0099}a<\u00F8\u00DB\x07\x17\u00FF\u00F1\x16\u0099E\u00E3O\x00\x13W\u00DE\u00F4mZh s\u00EA=P}M\u00ABW'\u00AD\u00BA\x00(\u00AB\x19\x01\u0086\x06\u00D5\u009B\u00E0\x04\u00A5`\u00AE\u00B6U\u00CB\u00F0\u00A5\u00DC\x043\x1B]b\u00D2\u00F3\u00DCU\x19To$Zz\u00D5T\u00A5\x0B\u00F3\x04XuA\u00D9!\u00FB\u00D0\u00D3}v\x1C\u0089u\x10\u009B\u00DF\b\u00C9G\u00A3zO\u0088\u00D5\u00F5\x19\u00E2Z\x10a\x06\u00E3o\u00ED\x02\x11\u008D\u009A\x06>n\"\u00FBl\u00B5\x1E\u0082\u00C1\u00EF\u00B9m}vq\u00DF\u00E6UPY\x11w\u00A0+\u00CFc\u00D9\u00BB%(g\u0099\x10\b\u00A2U\u00BA\u0096sq\u00DB\u00C6k.\u00F3\u0084\u00CF\u0087\u00E7'\u008E\u00A0\u00E5\u00BC\n\x03!\u00C7\u009E\u00A9\u00C4j \u00B8O\u009C\u00CB\u0081\u00CC\x16\u00D7\u009F|\x0B^\u0094\u00ACw\fO<\u00F4\u00A3\x0F\u00FA\u008D\u00F3^!\x17\u009E>\x00\u00E2\u00F1\u00C6i\u00AD\x10\x00\u00E0\u0080\u00CD\u00B8W<\u00EF\u00BA\u009Box\u00DBM\x1B?\u00F7%]o\x14\u00F0\u009CX\u00EAVS\u00FF\u00F5_]\x00\x00\x17\u00F9IDAT\u00F2\u00ED\u00BAPL\u00B6\u00C3\u00CA\u00FF\u00EB$r!\u00AD-\u00D4\u00E8Y(_.\u00B2\u00ECZ'B\u0094\x05F5\u00AC\b\u00F7\u009F\x16\u008F\x13k%\u00F4\u0099\u00AC\x05A\x0B\u00AF\x1A\u0093p\x12\u00C6\x14e@\u0080t\u00A9\u00B6X,\u00AD\u00F9\x1ASe\u00BE\u00AD5\x01\x15\u00B4\u0091\u00F8@GG\x0BO\u00C0\u00D6\u0082t\u008B\u00D7\u00BD\u00A0\u00CC\x19\x7Fl_\u00AE\u00DD\u00B2\t|<K8\u00F1\u0086R\u00EE\u00D8\u0081\t\u00B1\u0086pwL=\x05*\u00E5P\u00E4R\x14\u009D\x1F\u008A\u00AF\u0083\\\u0083\u00AEi\u00BD\u00B5\u00D3\x13\u00B0\u00FBi\u00E5\x12\u0082e\u00E8!\u00D5*]\x19\u00AE\b\t\u00C4\u00F6\u00E3.\u008Ab\u00BD\x17\u00D9\x1Eo\u00A6\u00C8\x0ERT\u00A2H\u00EF\u0084J\u0084\u00AB\u008A\fPp\u00E1AQ@\u00F6l\u00F6\u008D\u00AF\u00DD\u00FC\u009E\u0087\u00BF\u00ED\u00FC\u00D7\u00E0\u00C2\u00BFs\u00BA\u00DF\u00E1\u00E3\u00F4VW+\u00E3\u00E5Wo^\u00F6\u00EB7\u00EB\u00EB??\u00AEo\u0090\u0087\u00C0:\u00FE\x10p\u00C6\u0084@\u0096'\u00BB\u00B0\x05\u009E\x10\x02\u00CA\u009C\u00B8\x1FC*\u00E2_\u008E\x0B\u00A40\u00AAZ&\u00A1\u00A3\u009C\x13)\u00A8\u00DCF\u008B\u00DB]\u00B6\u00D58\u00AE\u00FA$N\u00A5\u00C1\u00B5\b\x00\u00BF\u00DE\u00BA\u00BCx\u00D9_\u00D8~<\u00BC\n\u008Bk\u00D7\u00BAb\u00AD\x1B\u008B1\u00DA\u00B3w`>&+p\bwW0_$\u00F9\u0086\u00CC\u00CA\u00B6D(\x06\x02\u0092\u00CD;\u008C\n\x043\u00B6\u00F9\x12o\r\u008FB\u00F2Q\u00EF\u00B9\b\u00F6D\u00D0d\x1F\x164?[\u00B2#Rs\x14\u00B2\fG$HIl\x04c\u00C0\u00A0\u00C4\x020\u00B6\u00F2R\u0092\u0094jk4R\u0087\u00E9\u00F2\u00B3\f;\u00FB$:\u0089\u00ABg\u00F8G\u00A5\u00D4\x1C\u0097\u0099\u00B0\x1By\u00AC\u00CEtd\u0092\u00A6\u0082<\u00C5s\u00B9\u00F2k\u00FB\u008El\u009D}\u00E9\u0091\x7F\u00FA\u00F07_x\u0087\u00D2\u0091Od\u00DC\u00A9\x14\x02\x00\u00BC\u00FC\u00DACOz\u00F3\r\u00ED\u00B7?\u00B5\u00D88\u00A0*e\u00E9+Mp/\u00C8A\u009A\u009E\u0082\u00BFD\x19i\u00C9\u00B5\u00E0\x05\u008E\x0BHZy\u0089NCi\u00D9\x05fU\u00A8\\\b\x0B\u00A5\u00AB?U\"\u0093~\x02.\u00E8:\u00F2$\u0098(\rZ\u00E1\u00C0;|RO\u00C3\x04E\u00AC\x10\f\u00B7\u00E6\u00B1\u00F8l\u00AE\u00DD\u00B0\u00E1\na\u00D6\u0081\u008D\u00A2\f\u00B8\x04\x1C\\1\u00CC\u0096\u00C5\u00AA2L\u00F0&+V<\u00C5\u00CF\u00F8l\x053\u00B8K,y>*\u0084\x01N\u00A1\u00F6YE\u0081d5#k!\x06\u0099\njU\b\u00F3\u009E\x7F\u00F3\u00F3`'\u0082M]\u00CD\x06\u00AF\u0095\u00DE\x0EA\u009D\u00EE^c\x11J$\u00EF\u008F\u00D4kT\u0085@\u00D4\u00B3\u00F3<\u00A9$\u00EB\u00B2r\u00F0k\u00E5\u00B3\f\x05\u0081\fw\u00E2Z\x05\x18/<t\u00D3\u00DE\u00A7\u00F6o}\u00F4\u00AF\u009Ds;tB<u\u00E3N\u00A7\x10\x00\u00E0g\x0Fn\u00DD\u00FFM\u009F[\u00BE\u00F5\u00C3G6.Y(\u00EB\x1F\u00B2\u00A6\u009Fn\\6(Y\u0089\x05\u00B5\x14'\x15R\u008E\u00B9\u00B9\u00DE\u00D8c\u00C5\u00BB\b`\u00B1\u00A7'\u00C0\u00C5U4\u0094L9\x17\u00BD\u0082\u0091\x15\u0085\x00S\u00A3\x00\u00F7\u0097\u00B2~\u00C4T\u00A1d\u00E7\u00E9\u009C\u00A0\u00DA\x11\u008D\f\u00ED\u00BC\\\u00ECEC\u00F14\x00\u00BB\u009C\u00BD8/\u00B5\x0E\f\t\u00B8V\u00E1\u00AC\x1B\u00A5\u0099\u00DC~\x02am\u00F4\x02\u00A8\u00D2pE\u00DCCh\x10/^\u00CA8\u0099\x1E\x02=\u0083\u0099c\r& \x12kLL\u00FE\u008F$\x185)\u0082\u00DF\u00FF&\u0085\u00A0Q<%\u00B0f$\x02\x07\x1F{\u00CF\u0085Z:=\x05\x0B\x1F\u00AB\x05\u00E7\u00FD\u00C7\u00FD\u00C2\x00J6X\u0081j\u00D4\u0081\u00E4\u00FA\f\x14|\u008D9c\u00CA\u00AF\x15E5U\b\x02\u00C5p\u00F1\u0091+/x\u0086<\u00E3\u00C1\u00AF9\u00FB\x0E\u00ABZ\u00BC\u00B5\u00E3N\u00A9\x10\x00\u00E0\x7F\x1E\u00D5\u00FD\u00BF\u00FC\u0099\u00AD7\u00BD\u00F3\u00E0\u00F0\u008D\x0B\x1D\u008C_\x00)18B\u00D0B@\u0081@\u00C4\u00A8\x104\u008A\u00A3\x14\u0088\x14\u00D2\u00B4\u00DB\u00D2$\u00CC\u0088\x10\u00C0YkhSP\u0090\u00C5R\u00BE\u009Dj\x0F\u0082O\u00C6\u00AA\u00D9\u00DC\u0094\u00EEzz\x19\u0092\u00D7Lo\u00A5x\x10R\u0094\x18F6YEx:\x02`\u00BD[\u00CD\u00C3Z\x07\u00E6]\u00AC\u00B7\"h\x15]\u00E8\u008B\x17@!\u0081\u00FF\x7F\u00E8~,\u00B6v\x1B\u00CD\u008D\u00B6\u00B6h^; \u00C5\u00A2\x02\u0098Ac}o\x13Pq\u00E1e\x1D\u0083F\u00ABv\u00B6M\u009B\x15\u00E1\u009Fx\bj!\u00C9P>\x1FT\u00DDKH\u00EBl!G\u009B\u00B4Q\u00A7\x07\u0093L\u00C3\u00A9\u00E0\u00D6\u00B6h\u00ACFl\u00E59\u00B3\u00FE\"i\u00CC\u00A6\x10\"\u00E4\x00\\\x1D kF,\x7F\u0082&K\u00AC=\u00EC\u00C8;\x1E\u00F8\u009D\u00EB\u00CF\u00BE\u00E8\u00DF\u00EE\u00BEC\u00FA\x19\u009C\u00EC\u00B8\u00D3*\x04\x00\u00F8\u00A0\u00EA\u00F0\u0093\u009F\u00D9\u00FA\u00E9\u00B7]/\u00DF{x\u00B1\x06@&\u00D6VV\u0084+R\u0088.\u00D0\u0093\u00BC\u00B1\x0B\u00AA\x05\u00F2\u00E4\x17\x14\u00B0/\x14\nR\x00\u00A9H\nEZ\u0099\u00FB\u00EA\x05\x1FP\u00B2#\u00BDwB\u00D7\u0089\u0092\u00A9\u00FC\u00F9\u00D5\u00AEM\x01,v\x05z\x07\u00D7\u0097Hfa\u00D6\u00E5\u00F3x\u00B3nK\u00BB\u00CD}\u0082ot\n\x0F\u00AD\u00AA\u00F5\x10\x14\x05\u00DAR}\u00CD\x066\u00F5\u0090P\b\u00F5Y\x0EK\u00B3\u00FE\x112\u00C0\u00AB\x14Qp\x04\n\u009C\u00A4`\u00B1z\u00B1\u00A9\u00C6\u00DA\x0E\u00EC\u00930\x1F33\u00C1T\u00E4\u00DC\x15j\u0093\x04\u00FF\u00A2h\u008Ba_Q$3L\u00DDx*\x11\n+\u00F7\u009F\x14\x1F\u00D5\u00FFs\u00BB\u00A2d&\u00E9\u00CC\u00AE\u00A1\x042{P\u00CF\u00E5+J\u00ED\u00DA\u00C6\u00FE\u00AF9\u00FC\u00AA'\u00FE\u00E4y/\u0093\u00C7\u00DF\u00FE\u009D\u008EN\u00D5\u00B8S+\x04\u008E\u0097|\u00F6\u00D0s\u00DE\u00FA\u0085\u00D9/\x7Ff{\u00FD,\u00A2\u00DA\x13\u00E6\x1B\u0095\x000\t\x19\u00A2G>\x15\u0087\x7F\x1Fi\u00B0\u00A8<DZ\u00F7\x1A\x1E\u00F0<\u00DC/\u00BC\u0087\u00E2\u00F2W\u0090\x10\x05/\u00F0N\u00C7\u00F6]6x\t\u00E5\u00C5\u00E3D\u00C1\x13\u00CF'\u00A9\u0094\u00E850\u00B5\x19\u00F8\u0083\t\u00F7Z7\u00A5\u0090\u00EBCf'\u00A0\u00A1x\x033\u00F6Sw\u00AF\u0083\u00DFE\u00C8\u00E3\n\u00A3)0\x0F\x0F\u00C1\u009B\u008DR\u00F8\x1D\x17\u0098\u008F\u00A6\x10R\x19\u00F0\u00EF\u00EE\u00DEE\u00BA\u00F2\u00F3\u00DE\u00AD\u00C3\x12\x12p\u009Cw@\x1D\u0094\u009C\x05\u00DF\u00C3Vz\u00E6~\u0083\x16.\u0083\u00DF\x17y\"\x14~\u00AE\u00E3\x00\u00AC(\x04\u00CD{\u0089\u009E\tE\u0099\u00B0d\u00D9\u00C2FSb\x00\u0095\u0096\x1F\u00B3\u00A7\u00A7\u00D2\u00DA\x12\u00B3\u00FD[G.x\u00F2\u00F6w=\u00F6\x7F\u009C\x7F\u00BBuG\u00BE\u00AD\u00C6]B!\x00\u00C0\u00CF}q\u00EBa\u00AF\u00FF\u00D4x\u00F9\u0087\u008F\u00CC\x1F\u00A4:\u009F\u00BA\u00EF\u00A3N\u00AC\u00BDW\n\u0098\u00D0BV\u00B2\x11\x1A\u00827\x11N*\x14\x12\u008E\u00FC'\u0094Fx%\bkO\f \x04\x0B\x00\x17x\u00E5JI\u0093\u00C2\"*\u0084\x10\u00F8\f%\u00C2\x0BXN;N\x13\u00DC4\u00AF\u00A7\u009Brq/\u00A7u\u00C1\u00C6\u0098\u008A\u0081V\u0096\x15\u008D\u00CD=\u0089!\u00C2(S&\u00C3h)=fHH\u00B42\u00CC@\"S\x10\u0099\x04\u00CD\u0086)\u00D9\u00A2}U! \u009A\u009Ed\u00F6@#\u0086\u00E763\u00CF16\u00D5\u00E8\u0093`\u00F8\u0082\u00E4\u00F1\u00AA\x10\u00C3\u00DB\u00A5\u00A3X|5\u00EF\u00AC\u0082\u0082\x15\u00A7\b\u0085\u0080T\n$/\u00F1\u00FA\u00BB+\x0E\u00B6\u0095\x17\u0098\u00A2\u00E3\u00FB!\u00C8\u00B9v\u00FF\u0083W\u00DC\u00F7i\u00F3\u00CB\x1E\u00FA\u00EA=\x7FyJ&\u00F2\x1D<\u00EE2\n\x01\x00\u00FE\u00F7B\u00CF\u00FE\u00D9\u008F\x1D\u00FA\u0085w\u00DD\u00B4\u00F1\x1D\u00B7\u00F4\x19\x02\u00C4\x1B\x11\u0084&3\u00CA\u00DE!\u00A9\x03\u0082\u0096\u008C\u00C6b\u00E1\u0083W\u0080\"p\u00C4\x05P0\n\n\u00AB\x0Bo\u0086\tU\x19\u00F8\x0E\u00C5s@\u00F7\u00B5!\u00A5M\x04\u009CJ,\u00D6i\u00A7\x07SHJ5L\u0088\u00A2\u009E^\u00F7\u00F1\u00FDF`\u00CDC\u0087y7\u00EB\u00CD\u00CC@\b\x14ADNtv\u00FC\u00F1g&.\x18\u00FC{\u0086bM\u0091B^\u00B3\r\x12\x16\x1E\u00C7\u0082\u0089U8\u0091x\x02\u00E3yz\x1B\u0083+-\u00EE\u00DF\u00CAv\u0091*\u00D5\u00F4*\u0080\u00A2\x10x\x1E\x7F\x16\u0091\u00EA<\u00C6C \x00Y\x15\t\x1C\\Ne\u00C4\u00B0\u0088^\x01T\u00D1\u00D6vp\u00EEW\x1F}\u00E3W\u00BFt\u00FF\u008B\x0F|\u00FB\u00ED\u00B3\u0088\u00CA\u00ED1\u00EER\n\u0081\u00E3\u00A5\u009F<\u00FA\u009Do\u00F9<^\u00F3\u00FF\u00B67\u00CE\u00A6\x15\u00AF\u00BD\x01\u00D2\u00B5\u00B6\u00EDW\u00DBj\u00C7\u00DFE\u00A0\u0093c\u00E0\x0F\u008D\u009E\x02)\u00C7E\u00A1P\u0091T\u0097~\u008A\x17\u00F8u\u008C@\u00E0\x1E\u00FD\u00D8\u00F3S\thm\x1D?vpm\u00888\u00D7\u0088HY\u0092\x12\r\u00CF>\u00C8h\u00AE73\x0E\u00F3\u009Em\u00C0\x18O\u00CF\u0096\u009Aq\u00F4\u00D2-\u00F1X\x04\u008A<\x04ZL5\u00F7\u0099\u00D8\u00C1\f+\u00DE\x00hm\u00D5+\u00FC\u009C\x0BQ\x05\u00DB\u00EE|B\u0083\u00E6o\n\u00FD\x04\x13@\u00F9\u00BF&\x1F\u00C1\u00C2\x03{\u00DC5\x14 \u00EE\u00C0\u0090\u00AEr\x1F\b$\u009A\"\u00C8\f\u00CB\u00F1\u00D2\u0088@*\u00B2A\x15\u00DA:\u00DA\u00B9\u009B\u0087\u00EF\u00F1\u00A4\u00ED\u00EF~\u00F2\u00FF<\u00EF\u00BF\u009D\u00E4T=\u00ED\u00C6]R!\x00\u00C0/_\u00B7|\u00C0\u00AF\u00FF\u00F5\u00D6\x1B\u00DE}\u00E3\u00DA\x13F\u009D\u0085\u00B55,\u00C1-\u00A9\u00F3\x0F\u0092\u00FC\u00A3\u0089'\u00ACX\u00F8\u008A\x1B\u00D4\u00B4bd\b\u0082;\u0090\u00DB\u008A+\u0092\x001\u0091\u008A\u0089\x1EB\u00ACVCE\u0080<N*\x1D*\n\u008D\u00EB\u00E65t\x0F-\u00B2\u0083S+\u00DC\x07\u00C3*\u00B8(\u00EC\u009AZ\x1F\u00C6A\x0B\u00B8\u00E6\x18BcX0\u00A6\u00B2`\x11\x0FF\u00CD\u00AEKZ\u00C3\x02c\u00E6\u00B1=Z\b\x0E3\x10\u00DD\u00B1\x05\u0098[\u009F\x19\b\u00EE\u009F\u0096:\x17l\u00F1\x15\u00A9\\\u00A9\u00D6~\u008B\u00E1! \x15\x02\u00F1\x10\u0085\tw\u00AC\u00D0\u00A4\u00C0|\u0094\u0088\u00F7\x1B\u00D2\x13\x10\u00CD>\x05\u00D5[R\u0092\u00AE\u0090\u00A1\x03x\u00CD\x00\x1A\u00B6\u00B0\u00EBA\u00B7\u00BC\u00F7\x01\u00DF6<\u00EF\x11?z\u00DEm\u00BA\n\u00F3\x1D5\u00EE\u00B2\n\x01\x00nP\u009D}\u00DF\u00C7\x0F\u00FF\u00C0;\u00AEn\u00FF\u00E1\u00BA\u00CD\u00B59tf2\u00E7\x02\u00CE\u00BC\u00BE\x1CO\u00A0};\u00A0\u0084\t\u009E^\u00A40\x06\u00BF\u00A0\u00B8\u00AC\u00BD\u0097\u00E3\u00AD\n4\u00A6\x1E@\u00BA\u00FAT2=\u00F0\u0087)x\u00A8\x01v\u00C2\u00BD\u008A\x00,\u00A9\f\bL\u00B2\u00D6\u00A3S!e\x0F\u00C59\x14\u00EBKKCJ\u0097X1\u009A\u00B8\u0082t\u00B16jc\n\u00B4:S\u0091\u00D7\u00CD\\\u00BD\u0088uIb\u00CFDZ\u00FF\u009AV\u00AC`\u00E3\u00CC\u00D3\u0096)\\\u00CE\u008B\u0080L\x04\x1E\u00F0%\u00EBz\x11H\u00CD\u0098\x7F\u00E8\u0092<\x06\u00F7\u00A8\"\u00E4P\u00A3`\u00DBwb\u0085P\u00BA\x12\u00A6(\u008F\u00B9\x12&(\x00\u0099z\"\u00D6\u00EE\f\x10\u008C\u0098\u00ED\u00DBY\u00EC\x7F\u00C2\u00D1W>\u00FDG\x0E\u00FC\u00B8<N\u0096'=9O\u00D3q\u0097V\b\x1C?\u00F5\u00D9\u00A3\u008Fz\u00CBU\u00FD\u00BF~\u00E0\u00C6\u00B5G\u00F6>\u00CF\u00EE\u00C8$\u00F90\u00D5\x17\u00C2\u00AA\u00A8\u008B\u00AE\u00AC2\x11\u0089\x01\u00D4\u00DC\u00FF\u0094\x15\u00A9\u00A1\x10Hf\u008A,Fa\u00D7\u0099\x05\u00F7\u00CF\u0095\x1C\u00FA\u00E45\u00D0\u00C3\u00A0\u00F5'M\u00B9\u0086\x14\u00E4!\x18\u00960\u00CD@\u00ACfI\u0086n\na\u00DE\u00E9\x19 \u0080\u00B6\x16\u00D4e\t\u00E5\x10k\x1BF\x16B-\u0095)m\u0082\x11Tl\u0080L\u00C4\u00CAQ\u00E0\u00B6\u00C1+\u00A8\u00FB\x00\x13\u00AB\u00CE\u00EF\u00AAg@\x16\"\x15B+\u00E7k\u00FE\x1E\u00B2\u0083sV\x1E\u0092;0\u00A10k\u009EG\u00FC\u00B8\x11>\u0094\u0085g\x07\u00D8\x1F3Yb\u00EF\x03\u00B6>|\u00CF\u00A7.\u009F\u00FF\u00A4\u009F?\u00F7C\u00A7|r\u009Ef\u00E3n\u00A1\x10\x00\u00E0}\u00AA\u00F3\u00D7\u00FE\u00F9\u00C1\u00EF\u00FF\u0093k\u00D7\x7F\u00F0\u00AA\u00A3\u00EB\u00EBY\u009C$S\u008F \\w\x14\u00C1C\u00C4\u00E9\u00AB}\x15\x01W\x14\x10T\u00A6a\x05\"Y\u00E84\u00E14\x14A\u0095n=\x04\u00C2\u00D2\x17\u00A1\u00D61\u00AB\x14\u00B9\u00EC\\\x1E\u0087\u00A9KR\u0098\u00CB=\u00B8\u00D0O\u00C0\u00CF\u00AE\u0098\u008F&\u00E8\u00A46\x1BkQ\u00A39h[z7\u0083n\u00EB@\x06\x0E\u00E2\u00CAf\u00EE\u00AE\u00BF\u00C8T!DCUMjr\u0082\u008A\u0096Q \u00A5\u0098.9=\u0089\u00B9[gvB\u00AA\x1EF\u00C4\u00F5<NG\u00F4P\x18\x14Q\u00EE=\u00F8s\u009C\x00\u0091\u00FE\u00FEV\u00BD\u0081\u00BA\u009E$\u0090\u008A\u00878\x03`D\u00AE\u00E1\u00C0\u00C1\u00ED{>Z\x7F\u00EC\u00E9?p\u00EEO\x0E\x7FO\x16'5\x01\u00EF$\u00E3n\u00A3\x108~\u00ED\u00BA#\x0Fz\u00FD\u00C7\x17\u00BF\u00F0\u00DE\u00EBw]\u00BA=\u00CE0\u00F6\x16a\u00C4\u00B4W\x02\x02\u00B4\u00E3:\u0082(\u0082\x01wc\u00ED\u00CF\u00A9e\x060\u00C9XT\x1E\u00C3jQT4Q\u00ED\u00A4!\u0097\x10\u00C3\u00BD\t\u00BA\u00B9q-%L\u00806\u00AF\u00E7\u00C8\u00FDB\u00D9uW\"]\u0081nB>\u0090{\u00D0\u00D3\n\u00CF:0\u008C\u009EI\u00A0@\u008DV\u00EB\x10)Wz\b\u00A3\x1CCH2k\u00EF\u0099\x05\u00CB\u00DB\u0080]\u0099i\u00A5\u00C5\u00D3\u0088\x03$)\u00CB\u0098\u00A6\u00FA\x02\u00F4\u00C3\u00B1\u00C0b\u00F3d\u00B1-\x02+\u00A1\x1C\u00E8m\u00CDz\x12\u0099\u00C0\u00EBQ@\u00A4\u00B6s/\u00FC\x03\x14O\x01E\u00B9\u00A9B\u00E6Gq\u00EEC\u0097\u00EF\u00BA\u00E4i\u00FD\u00C5\u008F\u00F9\u00F1s\u00AF8\x15\u00F3\u00EE\u00CE2\u00EEv\n\x01\x00\u00BE\u00A8*?\u00F1\u00B1#\u00CF\u00FB\u0083\u00BFn?\u00FD\u00F1\u009B\u00D7.\u00EC:\u0084\u0090O*\x1C\u00DD\n\u009B[_\u00C0>n\u00AB@\x10\u00A1h\u00991\r\x07\"\u009E\u00D7\x12>\u0084\u0087a\u008Af\u00B5\u00A4\u009A\u00CDM'\u00A5\u00B9\u00A0\u00C7\u00D1#$\u0091\u00DE&\u00DEDz\x02\u00C80#>\u0097\b#\b\u00C4\u00CD\u00C7$\u00E3\u00CC\u00D8\x15i\x04\x00\u009D(\x04*\x1Cx\x18\x11\u0085L\u00A8\x1EBw\u00901\u0089C\u0095\u00AF\x00\u00FF\u009Bt\u00E5\u008A\x03$\u00BBP\u00A7t\u00E5n\u00DD\u00A1b\u0089w0\u00F4(\u00ACAw\u00EF\u00E8\u00F5\u00A4\u0090'\u00EE@B\u0091\u00F8\u00B5\x05\u00B7\x01\u00F6\x0E\x1B\x18\u00E6t\u00EC\u00BE\u00F7\u00E6u_\u00F1\u00B5\u00CB\u0097=\u00FD\u00D5\u00E7\u00BCA\u00CE\u00E7Y\u00EF>\u00E3n\u00A9\x108\u00FEd[\u00F7\u00FD\u00E2\x07\x0E\u00FF\u00D0\u00BB>/\u00FF\u00FA\u00BA\u00C3\u00BB\u00E7Q\u00D3O\u00CB\u00CAJ\u00CAb\u00E9\x05\u00C8\u00AC\x00$\x1B\u0088v+t\u008A\u00B4\u00A2\x0Ba\u00E57\u00B0Y)\u00AD\u00ADhK\u00A0\u0090\u00FB\u008C+a\t*\u0086\u00D1\u00CB\u00B1\u00E4\u00B8\u00C0c\u00D0\u00B5\u00EB\u00825\x04\x05\u00A9\u00A4\\A\u0091\u0097\u00C0\u00D4]\u00EB\u00C0\u00B0T\u00A0[\u00FD\u00C5|l\x19~\u00F85\u00B6\u009E\u00A1A-}\x1E\\\x00\t0r\u00C5\u00A6Y\u00B0\n\u00CDk\u0098\u00BB\u00CB\x1Fk5(\u00A6\u0098\u0080\u00D7\u00944X\u009AT\\\u00F1\u00D6\u00E5\u00E4#EI\x0F\x04\u00CC\u009A\u00E8\u00E4\u00FC\u00C2\u00CC\x0E\u008F/\u0080h\x0B\u00CA\u00B1\u00A83%\u00A5cc\u00FF\u00F6\u00E2\x1E\x0F\u00DF~\u00ED\u00D7\u00BFp\u00DF\x0F\u00DF\u00FB\u00B9\u00B3\u0083\u00A7|\u00B2\u00DDI\u00C6\u00DDZ!p\u00BC\u00F6\u00FA\u00EDK~\u00EFC;?\u00F3\u009Ekf\u00CF8\u00B2\u00B3\u00EE\x0B\u0082f\u009DCm'\u00C6N\u00C9\u00C7\u00C4\u00F3>q3\u00AD\u0088\u00E47L\u00C2\x07\u00AE\x07\u00E9\u00DD\u0097+n\u00A1\u00F0\u0096f\u00E9Q\x00\b,\u00C1x\x06\r\u00AC\u00C1\u0098tm\u00A6w\u00C0\u009E\u0092\u00A5\u00ACz\u00EAAx\x1B\u00B1\u00D1\u00AC*\x19\u008B\\\u00E8\u00A5-5\u0084kXz\u00B1\u00D7\u0098@j\u00AC\f%iy#\u00DD\b\u00B7\u00F2\u00C5\u00A5O\x0F\u00C1\u00DA\u00A4\u0093Dd\u00C0\u00A1\x06\u00907\x14\u0085@\u00AB\x1E\u0085N\u00C8\u00F0\u0081J \u0084\\\u00A7\u00DBP\u00B9\u00F9z\u00CF\u00B1\u00DA\u0093(\n\u00A5ZC\u00F1\f\u00BB\x0E\u00E3\u00A2\u0087\u00E2\u00AD_\u00FD\u008C\u00E1\u00A5\u008F}\u00C5YW\u009E\u00D2\u0089u'\x1Cg\x14B\x19?\u00F1\u00C9\u00A3\u00DF\u00F0\u00FBW\u00F4\u009F\u00FA\u00E0\u00D5\u00F3\u00C7m\u00F6\x19b\u00E5\u00A4\x11`S\u0093\x00\u00FD\\\u0080k\u00A7\u00E4\f\x0F\u00B2%x\u0084\x0F\u0091\u0095(\u00E1\x00\u00BB\x13\u0091\u00BE\\\u00B3\x18\u00A1h\u00E0a\x02\u00CF;\u00F5X\u00D8\u00BA\u00D8\u00CE\u00A9%\u009C\u00E01\u00BB\x0B\u00B4/Q\u00C7\u00E6.%Dh=\u00B3\x00\u00ACoh]\u00D1\u0096\x12\u00CA\u008C\u0095\u008F\u008D\n\u00C1\u00C3\x03\"\u00F2\x0348\x04\x04\u00FD,#\u0091\x02[C\u0086Ua\u00AE\u00DF\u00D1k \x1FaU!\u0084W\x01\u00842\u00A1sOO`\u0082K\u00F0oq\u008C\x00\x00f[\u00B8\u00F0\u0081[\u00EF\u00BF\u00FFS\u00F1\u00F2o|\u00D5\u00B9\u00FF\u00EB6\u009ARw\u00BAqF!\u00AC\u008Ck\x16*\u00BF\u00F0\u0097\u009B\u00FF\u00E8\u00ED\u009F\u00DA\u00FE\u00E1\u008F\\\u00BB\u00EB!\u00DB}\u00EE\x02\u00ECe\u00D2\u0085\u00B5\x18\u00AE?\x00\u00AE\t\u00D9\u00BADCNV\u00DB\x05\u0093\x10\u00E9Ap)\u00F6\u009A\x05\u00A8\u00A0\u00A3N\u0094H*\u0099)\u0093q\x1A\x02\u00C0\u00C3\x04\u0092\u0089\u00A8p\u00F2s\x01\nP\u00A8T\b\u009AJ\u0080$&\x19\u0093\u00E5\u0088\x0EH,\u00EBV\u00D2\u0088@\x10\u0091\x06e\u0097$\t\u0081\x1C:\u00A2\u00DF\x01\u00BA\u0085\x10s\u0095\u00E8\u00C6\x1E\x0B\u00BA\x02\u0098\u00ABN\u00AD=Jz\u00B1\u00F3\u00F8\x12a\x14\x0B\u00AB*\u00C7@\u0080Ia\x15y\x10\u00E6U\x18(9\u00C76\x0E<x\u00E7\u00E3\u00F7y\u00E2\u00F8C\u00FF\u00F0\u00A7\u00F7\u00FF\x0F\u00D9\x7F\u00F7\u00C3\t\u00FE\u00B6qF!\u00FC\r\u00E3\u00F3\u00AA\u00C3\u00AB>p\u00CB\u00B3\u00DF\u00F3\u00A9\u00F6\x1F>t\u00ED\u00ECA;}\x1D\u00D10\u0095`!\u00A6 \u00A1\u0096\u00DF\u00ABl\u00C6\u00E43\u00ACd$\u00A8\x1C\u008E\u00F1\ntE\u00F10l\u00D1\u00F8;\u00EB+\u00E8\x150\u0084\u00D0\u00C0\x13t\u00B5\u00D4ztO\u00C3\x15\x12\u00AF\u00DFV\u0086\u00F6\u0085Y\u00F9\u00DD\u0098+\x18K\u00C1!fj\u00EC\u00C4\x106a\u0083\x14Zo\u00EF\u009D\x10\x02\u00C9\u00E6\"\u00CE\u0081\u00F0g\u00CC0\x03\u0092\u008D\\(\u00D8\u0095\u00C7P3\x0E\u0099\u0086,m\u00DA\x14\u0096fDvs\u008A\u00F0\u0081\ni\u00D8\u00C4E\u0097l^\u00F1\u0095\u008F\u00D7W~\u00DB\x0F\x1Ex\u0093|\u00D5\u009D\u00B7D\u00F9\u00B6\x1Cg\x14\u00C2\u00DF1nP\x1D~\u00E6\u00CF\x0F}\u00FB\u00FF\u00FE\u0084\u00FE\u00FB\u00BF\u00B8z\u00E3\u0091[\u00E3\x1C\u00D1\u0099\u00B9g#US\x04:\u00C1\x10\b\u0088u-K\u00A6\x05\rZ\x0B~0\r\x13&MO\"\u00A5Y\u00D6J(\u00E7\u00AAaB\x0B\x0ECn\x1B\u00DC\u0088\u00DE}?\u00C9\u00DA\x0E*\u0095\u00D1\u00B6\x1F\u00BA@F5\u00D7\u00DD\u008B\u009B\x06 J\u00A0\u00A1@s%1\u00D7\u00E4#\b\u008C\x16m\u0096=-t\u00F6IP\u00F7\b$\u00B0\u008A\u00E0\x00\u00F8\u00CF\u00BC\n\u00BB \x17\u008E\u0091\u00A2\x10\u0090^\u0085\u00BAWR\u00B9\x0E\x02\t\x16\u00A5\u00A5\x1C;\u00E6\u00F3M\u009C\u00F3\u00A0\u00C5\u0087\u00EF\u00F7\u0084\u009D\u009F\u00F8'?v\u00C1o\u00C9yg\x14\u00C1\u00DF6\u00CE(\u0084/s\u00DC\u00A4*\u00BF\u00F8\u0091[\u00BE\u00E9\u008F>\u008E\u00EF\u00FB\u00F0\u00E7\u00E7\u00DFpp{\u00CD\u00AC\u00EF8K\x10\u00B0\x02\u0089,o\x06\u009CX$\u00D30A1\u00E5\x19\u00D0\u00C3\u0088B\u00A5\u00C2\u0094t\u00A1]]T%HC\x05\x1F\b2\u0093V\u00A6c\u00CF~\x10\u00A3D\u00E5'\u0097\u0088\u00AB\u00EBA\u00A2K\u00B4P\u0093\u00DEm\u00F9s\u00E7h\u0088Z(1\u00C0:1\u0091\u00C8\x13\x1E\u0082\x0B4-4\u0097\u008D\u00E7\u008A\u00CA\u0086\x13h\bpM\x1F2Kaq\u00BEd\u00FA\u0091\u00C7*\n#AE-\u00D8\u0080g\x19\x00\u00B4\x06\u00CCv\x1F\u00C2=/\u00D9\u00FE_\x0F\u00FFz\u00FC\u00E7g\u00BE\u00EC\u0082?\u0090\u008B\u00CE\u0084\x06_\u00CE8\u00A3\x10n\u00C5x\u00DD\u00A7\u00B7\x1Eu\u00F9\u00FB\x0F\u00BF\u00E4\u0093\u00D7\u00AC=\u00FBs7\u00ED\u00DE\x18\u00D1\f\u00D5\x1E%\u0080H\u0096CG\u00DD\u00C3\u0098\x169\u0081\u00C8\u009A\u00A5pE\x10\u00DC\u0085Z\u00E1X>\u00AF\u00A0\u00A2f/\u00C5\x00\x1DGWD\u00DD\u0081E\u00ED\b\u00A6%$\u00AE#\u0088OU\u00C1x3\x16\u00E9ITj\u00DEg1\x14\u00D1h\u0085E\u00F3\x1A\u00A3\u00A3T<V\u00AB\x0ED\x01\u00D3\u00E0\u0084%\u00F6<\u009C\u00D4\x17\u00C0B\x00\u00B3\u00FE2\u00A15\x1B&P\u008B\u00A0\u00A4(\tE\u0093\x0E\u00A0y\u00B8\u00D0\u00B1\u00FF\u0082\u00A3[\u00E7\u00DDw\u00E7MO|\u00D6\u00AEW\u00FF\u00FD\u0097\u00EF\u00BE\u00CBS\u008DO\u00F58\u00A3\x10Nb\u00BC\u00E7\u0090\u009E\u00FF\u00BA?\u00BD\u00E5\u009F\u00FF\u00E5\u00D5x\u00D1\u00C7>7\u00BB\u00DF\u00D6\u00F6\x06 \u00CD\u0090} \u00847]t\u00F5\u00EAD\u0084\x070\u00A9U`\x16\u00C1\u00853j&jj\u00D2\u00C1\u00CB\u00BA\u00D2S\u00E0\x02+!\u0087Q\u0097uJ`\u00A2\u0097r\x1C\u0085@\u009C@\u00C7\u00EE]\u0093\u00DA\x04?\x10\x05\u00DA\u00C8\u00B6\u00E7\x12\x1D\u0096\u00A3\x7F\x01d\n\u00E4)\u00D0\u009A\u0096\u00BE\u008A\x12\u00D6~V\u0094\x070\r5\u00C87\b<\x00\u00EC\u00A7\u00E8\u00CA\u00C23\x17\u00B3\x0EH\x1B1\f\x0B\u00DC\u00E3\u0092\u00FE\u00E9\x0B\u00EEw\u00E4u\u00DF\u00FC\u00C2\u00F3\x7F\u00F5\u00C1\u00CFl7\u00DC>3\u00E0\u00AE7\u00CE(\u0084S0nPm\u00BF\u00FA\u00C1\u00AD\u00A7\u00FC\u00D1G7_p\u00E5\u00B5\u00C3\u00B3\u00AE\u00BEq\u00D7F\u00979d\u00EC\u00D0\u009E\u00E5\u00C8\u00E6\x01$m6\x00H\u00EF\u00F8\u00B3\u00DA\u0082\u00AD\x15\u00C1\r\u008F\u00A2\u0084\t\x13\u009EAaE\u00B2{R\x1B\u00C5\u00D6.\u00EC\x19&P\u00C0'@\u00A8\u00EF\u009B\n\u00C1\x0B\u009DF\u00C9\u00BF\u00BB@tD\x1B\u00CD\u00E1\u00B7\u00B4\u00A2U;\x1A\x01)\x05\u00BAIV5\x0E\u00A2\u0091%\u00A8\u00B5\fMR\u00A1\x10,\u0094\u00A6%4(U\u008D\x00\x04=k%\u009Ab\u00AE#\u00F6\u00DEck\u00EB\u00C2\u008B\u00FB[\x1E\u00F1u\u00F2+\u0097}\u00EF\u00BE?\u0096{\u00B0\u00A6\u00F4\u00CC\u00B8\u00B5\u00E3\u008CB8\u00C5\u00E3\u00A3\u00DB\u00BA\u00FFu\u00EF8\u00F4\u008F?x\u00D5\u00F8\x1D\u009F\u00B9v\u00F6u_\u00B8e]0\x0E%\u00BB\u00E0\u008F\u00FC\x18\x001]y\u00F5X=\x0B\u00A4\u00DC\u009B\x00\u0080\u00B1\u00B4U\u00EB2\u00B5\u00F8\u009E\u0081`wf\u00E9\r\u00DD\u00B9\x13Qe\u00E9\x05KUy\u00C4Z\x15\u00A3\u00A5!\u0089u\u0084\u0097\u00C2f)\u00DD\u00BEg\u00E5!\x15B\u0083Z\u00B3S\u0086\x02\u0092\u00C2L\u009As\u00E5\x05\x10+`\u00B6\x02\u00D2]\t\u00B4l\u00AC\u008A\u00C4 \u00C4=\u0084&\u0082=\u00FB\u008E\u00E8=\u00BEj\u00FC?\u00F7{X{\u00E37}\u00E7\u00DE\u00FF\u00FE\u00C0K\u00E5N\u00D9\u00DD\u00F8t\x1Dg\x14\u00C2m8\u00DEv\u0093^|\u00F9;o\u00BC\u00EC\x13\u009F\u00DB}\u00D9g\u00AE\u00E9\u008F\u00BF\u00E1K\x1B\u00B2h\u0080\u00F6Y\u00A4\x13\u00938d\x19\x00x#\u0092\x1A&\u00E4\u0092\u00F4Z\u00D2\u0089\u0098x\x05LSF\x1B\u00F9\u00B1\u00B4V+\x00c\u00F5\x0Ejed\u00FDa\u00F6\u00A3\u0091\u00E30j\\#y\x0B@\x12\u0092\x06\u00F1\u00DF\x10\u00D4\u00F6\u00EB\u0081/\x1400\u00BD\b\x0F%JS\x12\x02\u008F\u00CC.4\x05\u00B4m\u00E3\u009C\u00FDK\u00BD\u00E7}v\u00DEw\u00AF\u008B\u00FB\u00E5O\u00BB\u00EC\u00C0\u00E5\u008F~\u008E\\u\u00DB\u00BF\u00BD\u00BB\u00E78\u00A3\x10n\u00A7\u00F1\u00A7\u00D7\u00EAW\u00BC\u00FEO\u00BF\u00F8\u00AC+>7|\u00CBu7\u00CC\u009E\u00FC\u00E9\u00EB\u00DB\u00BA\u00F6\r\u00F4>B\u00FAP\\\u00FF$\x16\u00B1\u00D1\u00CA$\u00ADY]\u00FF\x122\u00B0\u0085Z\x1Bk\u00AAq\u00CAy\u0098\u0084!\x05C\u00A0\x17\u0090\u00C5U\u00E4!\u00A4\x12!\u0086 E!4'\x18\u00AD\u00B9R\b\u008C@\x10\x1D\u008BY\u00B7\x10\u009C\x02$.@\u00C6c\u0093\x1E\x15\u0088\u0096\u00A5\u00D8\u00C2E_\u00B1\u00D8>\u00FF\u00C2\u00FE'\x17\u00DF\u00B7\u00FF\u00CE3\u009F\u00B7\u00E7-\u008Fx\u00FA\u00DA\u00E7o\u00CF\u00F7uw\x1Dg\x14\u00C2\x1D0>\u00BE\u00D0\u00B3\x7F\u00F3O7\u009F\u00F2\u00BE\x0Fo~\u00E3\u00F57\u00F7\u00A7^u\u00ED\u00EE\x07\u00DC|x\u008E\u00DEg\u00C1\u0084\u00AC\u009C\u0083\u00EA\x1D`d\x1A\u00D3>\u00EF$*\u00D5\x02&\x0F\x13j\x0B\u00B7\u00C8\x12\x14\u00E5\x10\u00D8\u00C3q?K\u00E5\x12e\u00D1\x1E\u00CAp\u00DA\x18\u00E3P\u00B1\x06\u00F1\u00DA\u0086\x04\n[\u00CFjH\u0092\u0093\u00A2\u00AB\u0092\u00A470\x03 \u00B2\u0085\u00B3\u00F6\u00EE\u00E0\u009E\u00F7\\~\u00F2\u00FC\u00F3\u00C7?|\u00F0c\u00E7\u00EFx\u00CE\u00F3\u00CF\u00F9\u00E3\x03\x0F\u00B9\u00EB4/\u00BD\u00B3\u008C3\n\u00E14\x18\x1F\u00B8Q/~\u00FD\x1F|\u00F1\u00D2+\u00AF\u009A?\u00F9\u00FA\u0083\u00FDI_\u00B8\x01\x0F\u00B8\u00F1Kk\u0082\u00E5\x06\u00FA\u00D8\x01VE\u00BA\u0092hZ\u00D8\u0087U\u00E0'!@\u0082\u008E\u00D19\tn\u00FD\u00C9+\b\u00D0R\u00DD\x13\u00D1LK\u008E\u0088B\u00AB\u00C8Bxf@\u00FD\x070\u00D7\x7F\x069\u0086\x1D\u00C8\u008E\u00CC\x19\x06X\u008ApP\u00C5 K\u009Cs\u00EE\u00B6^x\u00E1\u00E2\u0093\u00FB\x0F,\u00DF}\u00DF\u00FB\x0F\x7F\u00F2-\u00CF=\u00FF]\u008Fy\u00CA\u0099P\u00E0\u008E\x1Eg\x14\u00C2i8>pT\u00CF{\u00F3\u00DB\u008F|\u00CDG>q\u00E4q7\u00DC8\x7F\u00EC\u00E6Qy\u00F4\u00E7\u00AF_\u00BB\u00E8\u00E6\u0083\u0082\u00D6\u00D7c\t\u00B7\u00DE-o?\u00EAh\u00DE\u00C08K*uu\u00F9)\u00C4\u00A55[\u00A65\u00E1\u0095\u0094\x1E^,\u00CB\u00BET$c\u00F6\x16`\u00898\u00E0J\x02\u008A\u00D6\x14M\u009B\t|o\u0096Y\x000H\u00C7\\\x17\u00D8\u00BBg\u00C4\x05\x17m_{\u00F6Y\u00F3\x0F\x1E\u00B8\u00E0\u00E0\x07\x1E\u00F2\u0088s\u00DE\u00FF\u00DC\x7Fz\u00F6\u009F]\u00FCP\u00B9\u00F1\u00F6\x7F\u00BAg\u00C6\u00DF6\u00CE(\u0084;\u00C9\u00F8\u00C4!\u00BD\u00F0w\u00FE\u00E8\u00E6\u0087\u00BF\u00E7\u00A3\u00FA\u00B0\u009B\u00BE\u00D8\x1E|\u00F0\u00E8\u00F8\u00A0qs\u00FD\x01_:\u0084\u008B\u00AE\u00F9\u00E2R\u0096\u00DB\u00EB\u00C0\u00B8\x11K\u00C8G\u00C6\u0080)\u00BD\x0Et_\x1C\u00D6\u00BAC\x19zo\x1C\x05\u008D\x05`\u00C4S\u00A3p\u00CFA<,\x19\u00E0\u00D4kXH\u00A2\u009EZ\x1C\u00A0\x18t\u0089\u00F9p\x14\u00E7\u009E\u00DFt\u00FF\u00DE\u00E1\u00DA=\u00B3\u00ADO\u009E\u00BDG\u00AF\u00D8\x7F`\u00FC\u00ABG>\u00BA\u00FF\u00E5\u00B7?\u00E7\u00A2\u008F\u00DE\u00EF\u00C1r\u00DD\x1D\u00F8\u00F8\u00CE\u008C/s\u009CQ\bw\u00F2q\u00D5\u00A8g\u00BD\u00FFS\u00F8\u00CA\u00F7\u00BD\u00EB\u00E6\u00FB\\\u00FD\u00B9\u00E5\u00C5\u009F\u00BFe\u00F3^\u0087\x0F\u00EE\u00B9\u00C7\u00F6\u0091\u00D9E}G\u00CE_.\x16\x07\x16\u0090s\u0097\u00DB\u00B3\u00BD[Gt\u00D8\u00DC\u009Ec\u00B15\u00C3r{\u0080.\x15:6\u00E8\u00C2\u00B3\x1A\u00EA\x1D\u008A\u00A0\u0098\r#\u00D6\u00D0\u00B1\u00BE\u00B6\u00C4\u00AE\u008D>\u00CEf\u008B[f\u00D0/\x0Em\u00FD\u00A6a\u00BE\u00BCa>\u00C7\u00B5{\u00F6}\u00F1\u009A\u008B\u00F6\u00AE_}\u00EF\u008B\u00CF\u00BA\u00EA\u00D2'\u009F\u00F3\u00D9\u00C7=\x11\u009F\u00B9\u00F0^r\u00E4\u008E~&g\u00C6\u00AD\x1F\u00FF\x1F\x00\u00F3\u00AA\r=e\u0082\u0081\x00\x00\x00\x00IEND\u00AEB`\u0082" ;
    this.slash = "/"
    var targetFolder = new Folder(Folder.userData.fullName +this.slash+ "Aescripts"+this.slash+"colorPicker");
    !targetFolder.exists && targetFolder.create();

    this.settingFile = new File(targetFolder.fullName + this.slash + "colorPicker.xml");
    if(!this.settingFile.exists){
            this.settingFile.open("w");
            this.settingFile.write("<setting></setting>");
            this.settingFile.close();
    }

    this.haveSetting = function(name){
            this.settingFile.open("r");
            var content = this.settingFile.read();
            this.settingFile.close();
            return content.toString().indexOf("<"+name+">") !=-1;
        }

    this.getSetting = function(name){
            this.settingFile.open("r");
            var xml= new XML( this.settingFile.read() );
            this.settingFile.close();
            return xml[name].toString();
        }

    this.getSettingAsBool = function(name){
            var result = this.getSetting(name);
            return  result == "true" ? true:false;
        }

    this.saveSetting = function(name,value){
            this.settingFile.open("r");
            var xml= new XML( this.settingFile.read() );
            this.settingFile.close();
            var isOk = true;
            try{
                xml[name] = value.toString();
            }catch(err){
                isOk = false;
            }
            this.settingFile.open("w");
            this.settingFile.write(xml);
            this.settingFile.close();
            return isOk;
        }

}
    $.global.colorPicker = colorPicker;
    return colorPicker;
})();
// ==================== |---------| ====================
// ==================== | version | ====================
// ==================== |---------| ====================

/**
 * Constructs a new version object
 * @class
 * @name DuVersion
 * @classdesc Informations about the version of an application.<br />
 * The version is in the form: Major.Minor.Patch#Build. Example: <code>17.0.0x557</code> or <code>17.0.0-Alpha1</code> or <code>17.4</code><br />
 * The only required part is the Major version.
 * @param {string} [version='1.0.0'] The version in the form Major.Minor.Patch
 * @property {string} fullVersion The complete version name
 * @property {string} versionString The Major.Minor part as a string
 * @property {float} version The Major.Minor part as a float
 * @property {int} major
 * @property {int} minor
 * @property {int} patch
 * @property {int} build The build is -1 if it cannot be parsed as an int, like "alpha".
 * @property {string} buildString The build as a string
 * @category DuESF
 */
function DuVersion( version )
{
	if (!isdef( version )) version = '';
	
	var reV = /^(\d+)\.?(\d*)\.?(\d*)\D?(\S*)/i;
    var v = version.match( reV );

	if (version == '' || !v)
	{
		this.fullVersion = '1.0.0';
		this.versionString = '1.0';
		this.version = 1;
		this.major = 1;
		this.minor = 0;
		this.patch = 0;
		this.build = -1;
		this.buildString = "";
		return;
	}

	if (!v[ 1 ]) v[ 1 ]  = '1';
	if (!v[ 2 ]) v[ 2 ]  = '0';
	if (!v[ 3 ]) v[ 3 ]  = '0';
	if (!v[ 4 ]) v[ 4 ]  = '';

	this.fullVersion = version;
	this.versionString = v[ 1 ] + '.' + v[ 2 ];
	this.version = parseFloat(this.versionString);
	if ( isNaN(this.version) ) this.version = parseFloat(v[ 1 ]);
	if ( isNaN(this.version) ) this.version = 0;
	this.major = parseInt( v[ 1 ] );
	if ( isNaN(this.major) ) this.major = 0;
	this.minor = parseInt( v[ 2 ] );
	if ( isNaN(this.minor) ) this.minor = 0;
	this.patch = parseInt( v[ 3 ] );
	if ( isNaN(this.patch) ) this.patch = 0;
	this.build = parseInt( v[ 4 ] );
	if ( isNaN(this.build) ) this.build = -1;
	this.buildString = v[ 4 ];
}

/**
 * Checks if this version is higher than another.
 * @memberof DuVersion
 * @param {DuVersion|string} otherVersion The version to compare with.
 * @return {bool} true if this version is more recent than otherVersion
*/
DuVersion.prototype.higherThan = function( otherVersion )
{
	return DuVersion.compare(this, otherVersion);
}

/**
 * Checks if this version is higher than or equals another.
 * @memberof DuVersion
 * @param {DuVersion|string} otherVersion The version to compare with.
 * @return {bool} true if this version is more recent than or the same as otherVersion
*/
DuVersion.prototype.atLeast = function( otherVersion )
{
	if ( this.equals(otherVersion) ) return true;
	return DuVersion.compare(this, otherVersion);
}

/**
 * Checks if this version is the same as another.
 * @memberof DuVersion
 * @param {DuVersion|string} otherVersion The version to compare with.
 * @return {bool} true if this version is the same
*/
DuVersion.prototype.equals = function( otherVersion )
{
	if (! (otherVersion instanceof DuVersion) ) otherVersion = new DuVersion( otherVersion );

	return this.fullVersion == otherVersion.fullVersion;
}

/**
 * Compares two versions of an application
 * @static
 * @memberof DuVersion
 * @param {string|DuVersion} vA - The first version
 * @param {string|DuVersion} [vB=DuESF.scriptVersion] - The other version
 * @return {boolean} True if vA is more recent than vB (strict, if they're equal it will return false)
*/
DuVersion.compare = function (vA, vB)
{
	vB = def(vB, DuESF.scriptVersion);

	if (! (vA instanceof DuVersion) ) vA = new DuVersion( vA );
	if (! (vB instanceof DuVersion) ) vB = new DuVersion( vB );

	//compare major version
	if ( vA.major > vB.major ) return true;
	if ( vA.major < vB.major ) return false;

	//minor
	if ( vA.minor > vB.minor ) return true;
	if ( vA.minor < vB.minor ) return false;

	//patch
	if ( vA.patch > vB.patch ) return true;
	if ( vA.patch < vB.patch ) return false;

	//build 
	if ( vA.build >= 0 && vB.build >= 0 )
	{
		if ( vA.build > vB.build ) return true;
		if ( vA.build < vB.build ) return false;
	}

	//build as a string
	if ( vA.buildString == vB.buildString ) return false;
	if ( vA.buildString == '' && vB.buildString != '') return true;
	if ( vA.buildString != '' && vB.buildString == '') return false;

	var vABuildString = vA.buildString.toLowerCase();
	var vBBuildString = vB.buildString.toLowerCase();

	if ( vABuildString.indexOf('rc') >= 0 )
	{
		if ( vBBuildString.indexOf('rc') < 0 ) return true;
		return vABuildString > vBBuildString ;
	}

	if ( vABuildString.indexOf('gamma') >= 0 )
	{
		if ( vBBuildString.indexOf('rc') >= 0 ) return false;
		if ( vBBuildString.indexOf('gamma') < 0 ) return true;
		return vABuildString > vBBuildString ;
	}

	if ( vABuildString.indexOf('beta') >= 0 )
	{
		if ( vBBuildString.indexOf('rc') >= 0 ) return false;
		if ( vBBuildString.indexOf('gamma') >= 0 ) return false;
		if ( vBBuildString.indexOf('beta') < 0 ) return true;
		return vABuildString > vBBuildString ;
	}

	if ( vABuildString.indexOf('alpha') >= 0 )
	{
		if ( vBBuildString.indexOf('rc') >= 0 ) return false;
		if ( vBBuildString.indexOf('gamma') >= 0 ) return false;
		if ( vBBuildString.indexOf('beta') >= 0 ) return false;
		if ( vBBuildString.indexOf('alpha') < 0 ) return true;
		return vABuildString > vBBuildString ;
	}

	return vABuildString > vBBuildString;
}

/**
 * Information got from an update query on a RxVersion server, as returned by {@link DuVersion.checkUpdate DuVersion.checkUpdate()}.
 * @typedef {Object} DuVersion~UpdateReply
 * @property {Boolean} update Whether this script needs an update.
 * @property {string} version The available version.
 * @property {string} name The name of the script.
 * @property {string} description A description of the version.
 * @property {string} downloadURL The link to download the current version.
 * @property {string} changelogURL The link to the changelog.
 * @property {string} donateURL The link to make a donation.
 * @property {string} date The date of the version, in the form "yyyy-MM-dd hh:mm:ss".
 * @property {string} message Information about success/errors.
 * @property {Boolean} success false if the query failed and the version could not be retrieved.
 * @property {Boolean} accepted false if the query was wrong or the server did not recognize it. Should always be true.

/**
 * Checks if a new version is available for the current script,<br/>
 * using the DuESF.rxVersionURL if it is set.
 * @returns {DuVersion~UpdateReply|null} An {@link DuVersion~UpdateReply} or null if the server could not be reached.
 */
DuVersion.checkUpdate = function()
{
	if ( DuESF.rxVersionURL == '' ) return null;
	var co = new Socket;
	co.encoding = 'UTF-8';
	// No need for more than 5 seconds for just checking updates.
	co.timeout = 5;
    var url = DuESF.rxVersionURL.replace('http://','').replace('https://','').split('/');
    var baseUrl = url.shift();
	var fullUrl = baseUrl  + ':80';
    if ( co.open( fullUrl ) )
    {
        // Build request
		var os;
		if (DuSystem.mac) os = 'mac';
        else os = 'win';

		var args = {
			"getVersion": "",
			"name": DuESF.scriptName,
			"version": DuESF.scriptVersion.fullVersion,
			"os": os,
			"osVersion": DuSystem.osVersion,
			"host": DuESF.host,
			"hostVersion": DuESF.hostVersion.fullVersion
		}
		if (DuESF.isPreRelease) args["prerelease"] = '';
        var request = DuURL.buildGET( baseUrl, url, args );
		var reply = '';

		DuDebug.log( "Version check - Sys Info\r\n" +
			"Script: " + DuESF.scriptName + '\r\n' +
			"Script Version: " + DuESF.scriptVersion.fullVersion + '\r\n' +
			"OS: " + os + '\r\n' +
			"OS Version: " + DuSystem.osVersion + '\r\n' +
			"Host: " + DuESF.host + '\r\n' +
			"Host Version: " + DuESF.hostVersion.fullVersion + '\r\n\r\n' +
			"Request: " + request
			);

		if ( co.writeln( request ) ) {
			// Wait for the closing } or timeout
			// timeout in 2 seconds
			var now = new Date().getTime();
			var timeout = now + 2000;
			while ( (reply == '' || reply.lastIndexOf('}') < reply.indexOf('{') ) && now < timeout)
			{
				$.sleep(100);
				now = new Date().getTime();
				reply += co.read();
			}
    	}

		co.close();

		// Sanitize reply (strip http headers, and parse)
		DuDebug.log( "Version check - Reply\r\n" + reply );
		reply = reply.substring( reply.indexOf('{'), reply.lastIndexOf('}')+1 );

		try {
			reply = JSON.parse(reply);
		}
		catch (e) {
			if (DuESF.debug) alert(e);
		}
		
		return reply;
    }

	return null;
}// ==================== |--------| ====================
// ==================== | string | ====================
// ==================== |--------| ====================

/**
 * JavaScript String related methods
 * @namespace
 * @category DuESF
 */
var DuString = {};

/**
 * Counts the number of occurences of item in string
 * @memberof DuString
 * @param {string} string - The string where to count
 * @param {string} item - the string to search
 * @return {int} the number of occurences
 */
DuString.occurences = function(string, item) {
    return (string.split(item).length - 1);
}

/**
 * Parses the string as a boolean.<br />
 * The following strings are falsy:<br />
 * 'false', '0', '', 'null', 'undefined', 'NaN'.<br />
 * Note that any string consisiting only in any number of 0 will be falsy.
 * @memberof DuString
 * @param {string} string - The string to parse
 * @param {boolean} [caseSensitive=true] - When false, 'FALSE', 'nan', 'UNdefined'... for example will be falsy too.
 * @return {boolean} The resulting boolean
 */
DuString.parseBool = function(string, caseSensitive) {
    caseSensitive = def(caseSensitive, true);

    if (!caseSensitive) string = string.toLowerCase();
    var nan = 'NaN';
    if (!caseSensitive) nan = 'nan';

    // test if string is only zeroes
    var reZeroes = /^0+$/g;
    if (reZeroes.test(string)) return false;

    return string !== 'false' && string !== 'null' && string !== '' && string !== 'undefined' && string !== nan;
}

/**
 * Replaces <strong>all</strong> occurences of a substring by another and returns the new string.
 * @memberof DuString
 * @param {string}	string			- The original string
 * @param {string}	find			- The substring to replace
 * @param {string}	replace			- The new substring to insert
 * @param {boolean}	[caseSensitive=true]	- Optionnal. Do a case sensitive search of substring.
 * @return	{string}	The new string
 */
DuString.replace = function(string, find, replace, caseSensitive) {
    if (caseSensitive == undefined) caseSensitive = true;
    var re = new RegExp(DuRegExp.escape(find), caseSensitive ? 'g' : 'gi');
    return string.replace(re, replace);
}

/**
 * Replaces all occurences of "{#}" in the string by the args.
 * @memberof DuString
 * @param {string}	string			- The original string
 * @param {string[]|string}	args			- The arguments
 * @return {string}	The new string
 */
DuString.args = function(string, args) {
    args = def(args, []);
    if (typeof args === 'string' || args instanceof String) args = [args];

    var str = string;
    while (str.indexOf("{#}") !== -1) {
        // While there is stuff to format
        if (args.length < 1) break;
        var arg = args.shift(); // Take the first arg and remove it
        str = str.replace("{#}", arg);
    }
    return str;
}

/**
 * Checks if a string ends with a given suffix
 * @memberof DuString
 * @param {string}	str 	The string to check
 * @param {string}	suffix	The suffix
 * @return {bool}	Whether the string ends with the given suffix or not
 */
DuString.endsWith = function(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

/**
 * Checks if a string starts with a given prefix
 * @memberof DuString
 * @param {string}	str 	The string to check
 * @param {string}	suffix	The suffix
 * @return {bool}	Whether the string ends with the given suffix or not
 */
DuString.startsWith = function(str, prefix) {
    return str.indexOf(prefix) === 0;
}

/**
 * Generates a new unique string (numbered)
 * @param {string} newString	- The wanted new string
 * @param {string[]} stringList 	- The list of strings where the new one must be generateUnique
 * @param {boolean} [increment=true] - true to automatically increment the new name if it already ends with a digit
 * @param {boolean} [isFile=false] - when generating name for files, setting this to true will add the increment before the extension
 * @return {string}	The unique string, with a new number at the end if needed.
 */
DuString.generateUnique = function(newString, stringList, increment) {
    increment = def(increment, true);
    if (!increment) newString += ' ';

    //detect digits
    var reg = "( *)(\\d+)([.,]?\\d*)$";
    //clean input
    var regexClean = new RegExp(reg);
    newString = newString.replace(regexClean, "");
    //go!
    var regex = new RegExp(DuRegExp.escape(newString) + reg);
    //The greatest number found
    var greatestNumber = 0;
    //The number of digits for the number as string
    var numDigits = 0;
    var spaceString = "";
    for (var i = 0; i < stringList.length; i++) {
        var currentNumberMatch = stringList[i].match(regex);
        if (stringList[i] === newString && greatestNumber == 0) greatestNumber++;
        else if (currentNumberMatch !== null) {
            //if its a decimal number, keep only the integer part
            var numberAsString = currentNumberMatch[2];
            //convert to int
            var numberAsInt = parseInt(currentNumberMatch[2], 10);
            if (isNaN(numberAsInt)) continue;
            if (numberAsInt >= greatestNumber) {
                greatestNumber = numberAsInt + 1;
                spaceString = currentNumberMatch[1];
            }
            //check if there are zeroes before the number, count the digits
            if (numberAsInt.toString().length < numberAsString.length && numDigits < numberAsString.length) numDigits = numberAsString.length;
        }
    }

    //add leading 0 if needed
    if (greatestNumber > 0) {
        //convert to string with leading zeroes
        if (greatestNumber == 1) {
            greatestNumber++;
            spaceString = " ";
        }
        newString += spaceString;
        greatestNumber = DuNumber.toString(greatestNumber, numDigits);
        newString += greatestNumber;
    }

    if (!increment) newString = newString.substr(0, newString.length - 1);

    return newString;
}

/**
 * Returns a copy of the string without leading and trailing white spaces.
 * @param {string}	 str	- The string to trim
 * @return {String} The trimmed string
 */
DuString.trim = function(str) {
    return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
}

/**
 * Returns a copy of the string without leading white spaces.
 * @param {string}	 str	- The string to trim
 * @return {String} The trimmed string
 */
DuString.leftTrim = function(str) {
    return str.replace(/^[\s\uFEFF\xA0]+/, '');
}

/**
 * Returns a copy of the string without trailing white spaces.
 * @param {string}	 str	- The string to trim
 * @return {String} The trimmed string
 */
DuString.rightTrim = function(str) {
    return str.replace(/[\s\uFEFF\xA0]+$/, '');
}

/**
 * Returns a copy of the string without leading and trailing white spaces, and without any new line, leaving only standard spaces.
 * @param {string}	 str	- The string to trim
 * @return {String} The trimmed string
 */
DuString.fullTrim = function(str) {
    var newStr = str.replace(/[\s\uFEFF\xA0]+/g, ' ');
    return DuString.trim(newStr);
}

/**
 * Returns a copy of the string without trailing white spaces and numbers.
 * @param {string}	 str	- The string to trim
 * @return {String} The trimmed string
 */
DuString.trimNumbers = function(str) {
	return str.replace(/[\s\uFEFF\xA0\d]*$/g, '');
}

/**
 * Converts a size in Bytes to a human-readable string with a fitting unit automatically chosen<br />
 * Note that the conversion uses 1024 Bytes per kB.
 * @param {int} size The size in Bytes
 * @return {string} The stringified size
 */
DuString.fromSize = function(size) {
    if (size < 1024) return size + " B";
    if (size < 1048576) return DuPath.sizeFromBytes(size, "kB") + " kB";
    if (size < 1073741824) return DuPath.sizeFromBytes(size, "MB") + " MB";
    if (size < 1099511627776) return DuPath.sizeFromBytes(size, "GB") + " GB";
    else return DuPath.sizeFromBytes(size, "TB") + " TB";
}

/**
 * Generates a camel case text from a snake case or standard one
 * @param {string} text The source text
 * @return {string} The camelCase version of the text
 */
DuString.toCamelCase = function(text) {
    text = text.split(" ");
    if (text.length == 0) return "";
    text[0] = DuString.unCapitalize(text[0]);
    for (var i = 1, n = text.length; i < n; i++) {
        text[i] = DuString.capitalize(text[i]);
    }
    return text.join("");
}

/**
 * Sets the first character of the text to be capital case if it's a letter.<br />
 * Note that the string is left trimmed first: any leading white space is removed.
 * @param {string} text The source text
 * @return {string} The new text
 */
DuString.capitalize = function(text) {
    var newText = DuString.leftTrim(text);
    var firstChar = newText.substring(0, 1);
    firstChar = firstChar.toUpperCase();
    return firstChar + newText.substring(1);
}

/**
 * Sets the first character of the text to be lower case if it's a letter.<br />
 * Note that the string is left trimmed first: any leading white space is removed.
 * @param {string} text The source text
 * @return {string} The new text
 */
DuString.unCapitalize = function(text) {
    var newText = DuString.leftTrim(text);
    var firstChar = newText.substring(0, 1);
    firstChar = firstChar.toLowerCase();
    return firstChar + newText.substring(1);
}// ==================== |------| ====================
// ==================== | file | ====================
// ==================== |------| ====================

/**
	* File related methods
	* @namespace
	* @category DuESF
*/
var DuFile = {};

/**
	* Checks if the given path exists
	* @param {string}	 [path]	- The file path
	* @return {boolean} True or false
*/
DuFile.exists = function(path)
{
	var file;
	if (path instanceof File) file = path;
	else file = new File(path);
	return file.exists;
}

/**
	* Reads the first line of a file and return its content
	* @param {File|string}	 file	- The file
	* @return {string} The content
*/
DuFile.readFirstLine = function(file)
{
    if (jstype(file) == 'string') file = new File(file);
	//open and parse file
	if (!file.open('r')) return '';
	var data = file.readln();
	file.close();
	return data;
}

/**
	* Reads a whole file and return its content
	* @param {File|string}	 file	- The file
	* @param {string}	 [encoding='UTF-8']	- The text encoding
	* @return {string} The content
*/
DuFile.read = function(file,encoding)
{
    if (jstype(file) == 'string') file = new File(file);
	encoding =  def(encoding, 'UTF-8');
	//open and parse file
	file.encoding = encoding;
	if (!file.open('r')) return '';
	var data = file.read();
	file.close();
	return data;
}

/**
	* Writes a text file
	* @param {File}	 file	- The file
	* @param {string}	 content	- The content to write
	* @param {boolean}	 [append=false]	- Appends instead of replacing
	* @param {string}	 [encoding='UTF-8']	- The text encoding
    * @return {boolean} true if the file has been correctly written
*/
DuFile.write = function(file, content, append, encoding)
{
	append = def(append, false);
	encoding = def(encoding, 'UTF-8');
	//open and parse file
	file.encoding = encoding;
	var mode = 'w';
	if (append) mode = 'a';
	
	try
	{
		if (!file.open(mode)) return false;
		file.write(content);
		file.close();
		return true;
	}
	catch (e)
	{
		DuDebug.throwError( "Can't write file" , 'DuFile.write', e);
	}
	
    return false;
}

/**
	* Writes a line in a text file
	* @param {File}	 file	- The file
	* @param {string}	 content	- The content to write
	* @param {boolean}	 [append=false]	- Appends instead of replacing
	* @param {string}	 [encoding='UTF-8']	- The text encoding
    * @return {boolean} true if the file has been correctly written
*/
DuFile.writeln = function(file, content, append, encoding)
{
	append = def(append, false);
	encoding = def(encoding, 'UTF-8');
	//open and parse file
	file.encoding = encoding;
	var mode = 'w';
	if (append) mode = 'a';
	
	try
	{
		if (!file.open(mode)) return false;
		file.writeln(content);
		file.close();
		return true;
	}
	catch (e)
	{
		DuDebug.throwError( "Can't write file" , 'DuFile.write', e);
	}
	
    return false;
}

/**
	* Parses a JSON file
	* @param {File}	 file	- The file
	* @return {Object|null} The content or null if the file couldn't be parsed
*/
DuFile.parseJSON = function(file)
{
	if (!file.exists) return {};
	//open and parse file
	var json = DuFile.read(file);
	if (json == '') return null;
	var data = {};

	try { data = JSON.parse(json); } catch (e) { if (DuESF.debug) alert(e.description + '\n\nJSON DATA:\n\n' + json); }
	return data;
}

/**
	* Saves a js object to a JSON file
	* @param {Object} obj - The object to save
	* @param {File|string} file - The file or URI
	* @return {boolean} true if the file has been correctly written
*/
DuFile.saveJSON = function (obj,file)
{
	if (!(file instanceof File)) file = new File(file);
	var data = JSON.stringify(obj,null,4);
    return DuFile.write( file, data );
}

/**
	* Parses a CSV file
	* @param {File}	 file	- The file
	* @param {string}	 [delimiter=',']	- The delimiter used
	* @param {string}	 [textSeparator='"']	- The separator for texts
	* @return {string[]|null} The content (a two-dimensionnal Array) or null if the file couldn't be parsed
*/
DuFile.parseCSV = function(file,delimiter,textSeparator)
{
	if (!isdef( delimiter )) delimiter = ',';
	if (!isdef( textSeparator )) textSeparator = '"';
	var reQuoted = new RegExp("(" + textSeparator + ")((?:\\\\\\1|(?:(?!\\1).))*)\\1");
	//open and parse file
	var data = DuFile.read(file);
	if (data == '') return null;
	data = data.split('\n');
	for (var i = 0, num = data.length; i < num; i++)
	{
		//get quoted values
		var quotedValues = [];
		var line = data[i];
		var quoted = reQuoted.exec(line);
		while (quoted)
		{
			quotedValues.push(quoted[2]);
			line = line.replace(quoted[0],'%%');
			quoted = reQuoted.exec(line);
		}
		data[i] = line.split(delimiter);
		for (var j = 0, numJ = data[i].length; j < numJ; j++)
		{
			data[i][j] = DuString.trim(data[i][j]);
			if (data[i][j] == '%%')
			{
				data[i][j] = quotedValues.shift();
			}
		}
	}
	return data;
}

/**
	* Shows the default save file dialog and returns the file selected by the user.<r />
	* If the user ommits the extension, the default extension will be appended (Mac OS fix).
	* @param {string}	 prompt	- The prompt text, displayed if the dialog allows a prompt.
	* @param {string}	 [filter='']	- The file type filter (windows only)
	* @param {string}	 [defaultExtension='']	- The default extension
	* @return {File|null} The file or null if the user cancels
*/
DuFile.saveDialog = function(prompt, filter, defaultExtension)
{
	defaultExtension = def( defaultExtension, '' );

	var saveFile = File.saveDialog(prompt, filter);
	if (!saveFile) return null;

	if (saveFile.name.indexOf('.') < 1 && defaultExtension != '')
	{
		if (defaultExtension.indexOf('.') != 0) defaultExtension = '.' + defaultExtension;
		saveFile = new File(saveFile.parent.absoluteURI + '/' + saveFile.name + defaultExtension);
	}

	return saveFile;
}

/**
	* Gets the number of a frame from an file/image sequence<br />
	* The number must be right before the extension.
	* @param {string}	path	- The path of the frame
*/
DuFile.getSequenceNumber = function(path)
{
	var string_noExt = path.substring(0,path.lastIndexOf('.'));
	var numberi = 0;
	var namei = 0;
	for(var i = string_noExt.length-1;i>=0;i--)
	{
		if(isNaN(parseInt(string_noExt.charAt(i))))
		{
			numberi = i+1;
			break;
		}
	}
	number = string_noExt.substring(numberi,string_noExt.length);
	return number;
}

/**
 * Moves a file to a new location
 * @param {string|File} file The file
 * @param {string|File} newURI The new URI/Path (including file name)
 * @return {File|null} the new file object, or null if it could not be moved
 */
DuFile.move = function(file, newURI) {
	if (!(file instanceof File)) file = new File(file);

	if (!file.exists) return null;

	if (file.copy(newURI)) {
		file.remove();
		var f = new File(newURI);
		if (f.exists) return f;
		else return null;
	}
	return null;
}// ==================== |--------| ====================
// ==================== | regexp | ====================
// ==================== |--------| ====================

/**
	* JavaScript Regular Expression related methods
	* @namespace
	* @category DuESF
*/
var DuRegExp = {};

/**
	* Escape reg exp reserved characters from a string to build a regular expression compatible string
	* @memberof DuRegExp
	* @param {string}	string		- The string to escape
	* @return	{string}	The escaped string
*/
DuRegExp.escape = function (string)
{
	return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

/**
 * The set containing javascript symbols ( +, -, [, etc.). Useful when parsing javascript code.
 * @readonly
 */
DuRegExp.javascriptSymbols = "[\\s=!/*\\-+%()[\\]{};:.]";

/**
 * The set containing javascript symbols ( +, -, [, etc.) except the dot. Useful when parsing javascript code.
 * @readonly
 */
DuRegExp.javascriptSymbolsNoDot = "[\\s=!/*\\-+%()[\\]{};:]";

/**
 * The set containing authorized characters for javascript variable. Useful when parsing javascript code.
 * @readonly
 */
DuRegExp.javascriptVarChars = "[a-zA-Z0-9_]";// ==================== |--------| ====================
// ==================== | number | ====================
// ==================== |--------| ====================

/**
	* Number related methods
	* @namespace
	* @category DuESF
*/
var DuNumber = {};

/**
 * Converts a number to a string, adding optionnal leading zeroes
 * @param {Number} num	- The number
 * @param {int} numDigits 	- The number of digits in the string. Adds leading zeroes
 * @param {int} [base=10]	- The conversion base
 * @return {string}	The number as a string
 */
DuNumber.toString = function (num, numDigits, base)
{
	if (base == undefined) base = 10;
	var result = num.toString(base);
	while(numDigits > result.length)
	{
		result  = "0" + result ;
	}
	return result;
}
// ==================== |------| ====================
// ==================== | math | ====================
// ==================== |------| ====================

/**
 * Math related methods
 * @namespace
 * @category DuESF
 */
var DuMath = {};

/**
 * Enum for locations.
 * @readonly
 * @static
 * @enum {int}
 */
DuMath.Location = {
    TOP: 1,
    TOP_RIGHT: 2,
    RIGHT: 3,
    BOTTOM_RIGHT: 4,
    BOTTOM: 5,
    BOTTOM_LEFT: 6,
    LEFT: 7,
    TOP_LEFT: 8,
    CENTER: 0
}

/**
 * Checks if the given location is on the right side
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
DuMath.isLocationRight = function(location) {
    if (location == DuMath.Location.TOP_RIGHT) return true;
    if (location == DuMath.Location.RIGHT) return true;
    if (location == DuMath.Location.BOTTOM_RIGHT) return true;
    return false;
}

/**
 * Checks if the given location is on the center on the horizontal axis
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
 DuMath.isLocationHCenter = function(location) {
    if (location == DuMath.Location.TOP) return true;
    if (location == DuMath.Location.CENTER) return true;
    if (location == DuMath.Location.BOTTOM) return true;
    return false;
}

/**
 * Checks if the given location is on the left side
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
 DuMath.isLocationLeft = function(location) {
    if (location == DuMath.Location.TOP_LEFT) return true;
    if (location == DuMath.Location.LEFT) return true;
    if (location == DuMath.Location.BOTTOM_LEFT) return true;
    return false;
}

/**
 * Checks if the given location is on the top side
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
 DuMath.isLocationTop = function(location) {
    if (location == DuMath.Location.TOP) return true;
    if (location == DuMath.Location.TOP_RIGHT) return true;
    if (location == DuMath.Location.TOP_LEFT) return true;
    return false;
}

/**
 * Checks if the given location is on the center on the vertical axis
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
 DuMath.isLocationVCenter = function(location) {
    if (location == DuMath.Location.LEFT) return true;
    if (location == DuMath.Location.CENTER) return true;
    if (location == DuMath.Location.RIGHT) return true;
    return false;
}

/**
 * Checks if the given location is on the bottom side
 * @param {DuMath.Location} location The location
 * @returns {boolean}
 */
 DuMath.isLocationBottom = function(location) {
    if (location == DuMath.Location.BOTTOM_RIGHT) return true;
    if (location == DuMath.Location.CENTER) return true;
    if (location == DuMath.Location.BOTTOM_LEFT) return true;
    return false;
}

/**
 * Generates a random integer between minimum and maximum
 * @memberof DuMath
 * @param {int}	[min=0]	- The minimum value
 * @param {int}	[max=1]	- The maximum value
 * @return {int}	The randomly generated integer
 */
DuMath.random = function(min, max) {
    if (min == undefined) min = 0;
    if (max == undefined) max = 1;
    var rng = null;
    $.sleep(10);
    var date = new Date();
    var rng = new Math.seedrandom(date.getTime())();
    //rng = Math.random();

    if (!rng) return 0;
    return rng * (max - min) + min;
}

/**
 * Generates a random integer between minimum and maximum.<br/>
 * The results are distributed along a gaussian (bell) curve.<br/>
 * Note that a few (< 10%) values may be outside of the range. Set the <code>bounded</code> to true to avoid that.
 * @memberof DuMath
 * @param {int}	[min=0]	- The minimum value
 * @param {int}	[max=1]	- The maximum value
 * @param {Bool} [bounded=false] - When this is false, a few values may be outside the range. Set it to true to make sure all values are between min and max.
 * @return {int}	The randomly generated integer
 */
DuMath.gaussRandom = function(min, max, bounded) {
    min = def(min, 0);
    max = def(max, 1);
    bounded = def(bounded, false);

    var u = 0, v = 0;
    while(u === 0) u = DuMath.random(); //Converting [0,1) to (0,1)
    while(v === 0) v = DuMath.random();
    var num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
    num = num / 10.0 + 0.5; // Translate to 0 -> 1
    if (bounded && (num > 1 || num < 0)) return DuMath.gaussRandom(min, max, true); // resample between 0 and 1
    num *= max - min; // Stretch to fill range
    num += min; // offset to min
    return num;
}

/**
 * Measures the vector length between two points
 * @param {int[]} value1 - The first value
 * @param {int[]} value2 - The second value
 * @return {float} The length
 */
DuMath.length = function(value1, value2) {
    if (typeof value1 !== typeof value2) {
        return null;
    }
    if (value1.length > 0) {
        var result = 0;
        for (var dim = 0; dim < value1.length; dim++) {
            result += (value1[dim] - value2[dim]) * (value1[dim] - value2[dim]);
        }
        result = Math.sqrt(result);
        return result;
    } else return Math.abs(value1 - value2);
}

/**
 * Compares two numbers
 * @memberof DuMath
 * @param {Number|Number[]} value1 - The first value
 * @param {Number|Number[]} value2 - The second value
 * @param {int} [floatPrecision=-1] - The precision for (float) number comparison, number of decimals. Set to -1 to not use.
 * @return {boolean} true if the two values are equal
 */
DuMath.equals = function(value1, value2, floatPrecision, test) {
    floatPrecision = def(floatPrecision, -1);
    value1 = new DuList(value1);
    value2 = new DuList(value2);

    if (value1.length() != value2.length()) return false;

    var item1 = value1.next();
    while(item1 !== null)
    {
        var item2 = value2.at(value1.current);
        if (jstype(item1) !== jstype(item2)) return false;
        if (jstype(item1) === 'array') return DuMath.equals(item1, item2, floatPrecision);
        if (jstype(item1) !== 'number') return false;

        if (floatPrecision >= 0) {
            var mul = Math.pow(10, floatPrecision);
            var num1 = Math.round(item1 * mul) / mul;
            var num2 = Math.round(item2 * mul) / mul;
            if (num1 != num2) return false;
        } else  if (item1 != item2) return false;

        item1 = value1.next();
    }

    return true;
}

/**
 * Calculates the log10 of a number
 * @memberof DuMath
 * @param {float}	w	- The number
 * @return {float}	The result of log10(x)<br />
 * i.e. Math.log(x)/Math.LN10
 */
DuMath.log10 = function(x) {
    return Math.log(x) / Math.LN10;
}

/**
 * Calculates the average value in a list
 * @memberof DuMath
 * @param {Number|Number[]}	values	- values
 * @return {float}	The average value
 */
DuMath.average = function(values) {
    if (!(values instanceof Array)) return values;
    var sum = 0;
    var total = values.length;
    if (total == 0) return 0;
    for (var i = 0; i < total; i++) {
        sum += values[i];
    }
    return sum / total;
}

/**
 * Alias for {@link DuMath.average}.
 * @memberof DuMath
 * @function
 */
DuMath.mean = DuMath.average;

/**
 * Clamps the value
 * @memberof DuMath
 * @param {Number|Number[]}	values	- values
 * @param {Number}	[min=0] - The minimum value
 * @param {Number}	[max=1] - The maximum value
 * @return {Number|Number[]}	The clamped values
 */
DuMath.clamp = function(values, min, max) {
    if (!isdef( min )) min = 0;
    if (!isdef( max )) max = 1;

    if (max < min) {
        var t = max;
        max = min;
        min = t;
    }

    var isArray = true;
    var result = [];
    if (!(values instanceof Array)) {
        isArray = false;
        values = [values];
    }
    for (var i = 0, num = values.length; i < num; i++) {
        var v = values[i];
        if (v < min) v = min;
        if (v > max) v = max;
        result.push(v);
    }
    if (isArray) return result;
    else return result[0];
}

/**
 * Converts the number from degrees to radians
 * @memberof DuMath
 * @param {number} value - the value
 * @return {float} The value in radians
 */
DuMath.toRadians = function(value) {
    return value * Math.PI / 180;
}

/**
 * Converts the number from radians to degrees
 * @memberof DuMath
 * @param {number} value - the value
 * @return {float} The value in degrees
 */
DuMath.toDegrees = function(value) {
    return value * 180 / Math.PI;
}

/**
 * The logistic function (sigmoid)
 * @param {Number} value The value
 * @param {Number} [midValue=0] The midpoint value, at which the function returns max/2
 * @param {Number} [min=0] The minimum return value
 * @param {Number} [max=1] The maximum return value
 * @param {Number} [rate=1] The logistic growth rate or steepness of the function
 * @return {Number} The result in the range [min, max] (excluding min and max)
 */
DuMath.logistic = function(value, midValue, min, max, rate) {
    if (!isdef( midValue )) midValue = 0;
    if (!isdef( min )) min = 0;
    if (!isdef( max )) max = 1;
    if (!isdef( rate )) rate = 1;
    var exp = -rate * (value - midValue);
    var result = 1 / (1 + Math.pow(Math.E, exp));
    return result * (max - min) + min;
}

/**
 * The inverse logistic function (inverse sigmoid)
 * @param {Number} v The variable
 * @param {Number} [midValue=0] The midpoint value, at which the function returns max/2 in the original logistic function
 * @param {Number} [min=0] The minimum return value of the original logistic function
 * @param {Number} [max=1] The maximum return value of the original logistic function
 * @param {Number} [rate=1] The logistic growth rate or steepness of the original logistic function
 * @return {Number} The result
 */
DuMath.inverseLogistic = function(v, midValue, min, max, rate) {
    if (!isdef( midValue )) midValue = 0;
    if (!isdef( max )) max = 1;
    if (!isdef( min )) min = 0;
    if (!isdef( rate )) rate = 1;

    if (v == min) return 0;

    return midValue - Math.log((max - min) / (v - min) - 1) / rate;
}

/**
 * The gaussian function
 * @param {Number} value The variable
 * @param {Number} [min=0] The minimum return value
 * @param {Number} [max=1] The maximum return value
 * @param {Number} [center=0] The center of the peak
 * @param {Number} [fwhm=1] The full width at half maximum of the curve
 * @return {Number} The result
 */
DuMath.gaussian = function(value, min, max, center, fwhm) {
    if (!isdef( max )) max = 1;
    if (!isdef( min )) min = 0;
    if (!isdef( center )) center = 0;
    if (!isdef( fwhm )) fwhm = 1;
    if (fwhm === 0 && value == center) return max;
    else if (fwhm === 0) return 0;

    var exp = -4 * Math.LN2;
    exp *= Math.pow((value - center), 2);
    exp *= 1 / Math.pow(fwhm, 2);
    var result = Math.pow(Math.E, exp);
    return result * (max - min) + min;
}

/**
 * A "reversed" gaussian function, growing faster with low value
 * @param {Number} value The variable
 * @param {Number} [min=0] The minimum return value
 * @param {Number} [max=1] The maximum return value
 * @param {Number} [center=0] The center of the peak
 * @param {Number} [fwhm=1] The full width at half maximum of the curve
 * @return {Number} The result
 */
DuMath.reversedGaussian = function(value, min, max, center, fwhm) {
    r = -value - fwhm + 1;
    return gaussian(value, min, max, center, r);
}

/**
 * The inverse gaussian function
 * @param {Number} v The variable
 * @param {Number} [min=0] The minimum return value of the corresponding gaussian function
 * @param {Number} [max=1] The maximum return value of the corresponding gaussian function
 * @param {Number} [center=0] The center of the peak of the corresponding gaussian function
 * @param {Number} [fwhm=1] The full width at half maximum of the curve of the corresponding gaussian function
 * @return {Number[]} The two possible results, the lower is the first in the list. If both are the same, it is the maximum
 */
DuMath.inverseGaussian = function(v, min, max, center, fwhm) {
    if (!isdef( max )) max = 1;
    if (!isdef( min )) min = 0;
    if (!isdef( center )) center = 0;
    if (!isdef( fwhm )) fwhm = 1;
    if (v == 1) return [center, center];
    if (v === 0) return [center + fwhm / 2, center - fwhm / 2];
    if (fwhm === 0) return [center, center];

    var result = (v - min) / (max - min);
    result = Math.log(result) * Math.pow(fwhm, 2);
    result = result / (-4 * Math.LN2);
    result = Math.sqrt(result);
    return [result + center, -result + center];
}

/**
 * The inverse of the reversed gaussian function
 * @param {Number} value The variable
 * @param {Number} [min=0] The minimum return value of the corresponding gaussian function
 * @param {Number} [max=1] The maximum return value of the corresponding gaussian function
 * @param {Number} [center=0] The center of the peak of the corresponding gaussian function
 * @param {Number} [fwhm=1] The full width at half maximum of the curve of the corresponding gaussian function
 * @return {Number[]} The two possible results, the lower is the first in the list. If both are the same, it is the maximum
 */
DuMath.inverseReversedGaussian = function(value, min, max, center, fwhm) {
    r = -value - fwhm + 1;
    return inverseGaussian(value, min, max, center, r);
}

/**
 * The linear function
 * @param {Number} value The variable
 * @param {Number} [min=0] The minimum input value
 * @param {Number} [max=1] The maximum input value
 * @param {Number} [targetMin=0] The minimum output value
 * @param {Number} [targetMax=1] The maximum output value
 * @param {Boolean} [clamp=false] Whether to clamp the output value to the target or not.
 * @returns {Number}
 */
DuMath.linear = function(value, min, max, targetMin, targetMax, clamp) {
    min = def(min, 0);
    max = def(max, 1);
    targetMin = def(targetMin, 0);
    targetMax = def(targetMax, 1);
    clamp = def(clamp, false);

    // Handle stupid values
    if (min == targetMin && max == targetMax) return value;
    if (min == max) return value;
    if (targetMin == targetMax) return targetMin;
    if (value == min) return targetMin;
    if (value == max) return targetMax;

    var result = targetMin + (value - min) / (max - min) * (targetMax - targetMin);
    if (clamp) result = DuMath.clamp(value, targetMin, targetMax);
    return result;
}

/**
 * Checks if a point is located inside given bounds
 * @param {float[]} point The point
 * @param {float[]} bounds The bounds. The number of bounds must be at least twice the number of dimensions, in this order : [a1, a2, ..., x1,x2,y1,y2,z1,z2]
 * @return {Boolean} true if the point is inside the bounds
 */
DuMath.isInside = function(point, bounds) {
    for (var i = 0, n = point.length; i < n; i++) {
        var c = point[i];
        var c1 = bounds[i * 2];
        var c2 = bounds[i * 2 + 1];

        if (c < c1) return false;
        if (c > c2) return false;
    }
    return true;
}

/**
 * Checks the sign of a number
 * @param {Number} num The number to check
 * @returns {int} 1 if num is positive, -1 if negative, 0 in other cases (0, NaN...)
 */
DuMath.sign = function(num) {
    if (num < 0) return -1;
    if (num > 0) return 1;
    return 0;
}

/**
 * Gets the bounds of the values
 * @param {Number[][]} values A list of values
 * @return {float[]} The bounds, for N dimensions: [min1, min2, ..., minN, max1, max2, ..., maxN]
 */
DuMath.bounds = function(values) {
    var mins = [];
    var maxs = [];

    for (var i = 0, n = values.length; i < n; i++) {
        var v = values[i];
        for (var j = 0, d = v.length; j < d; j++) {
            if (typeof(mins[j]) === 'undefined') mins[j] = v[j];
            else if (v[j] < mins[j]) mins[j] = v[j];

            if (typeof(maxs[j]) === 'undefined') maxs[j] = v[j];
            else if (v[j] > maxs[j]) maxs[j] = v[j];
        }
    }

    return mins.concat(maxs);
}

/**
 * Checks if the direction changes (if the point is at an extreme value). If the values have multiple dimensions, checks each axis individually.
 * @param {Number|Number[]} previousValue The value just before the point.
 * @param {Number|Number[]} point The point to check.
 * @param {Number|Number[]} nextValue The value just after the point.
 * @param {int} [precision=1] The precision for floating point comparisons; number of decimals.
 * @return {Boolean} 
 */
DuMath.isExtremePoint = function(previousValue, point, nextValue, precision) {
    previousValue = new DuList(previousValue);
    point = new DuList(point);
    nextValue = new DuList(nextValue);

    for (var i = 0, n = point.length(); i < n; i++) {
		var p = point.at(i);
		var pv = previousValue.at(i);
		var nx = nextValue.at(i);
		if (DuMath.equals(p, pv, 1) && DuMath.equals(p, nx, 1)) continue;
        // Get the dif
        var pDif = p-pv;
        var nDif = p-nx;
        // If the sign is the same, this is an extreme
        if (pDif >= 0 && nDif >= 0) return true;
        if (pDif <= 0 && nDif <= 0) return true;
		// If one of the two is 0, this is an extreme
        if (DuMath.equals(pDif, 0.0, 1)) return true;
        if (DuMath.equals(nDif, 0.0, 1)) return true;
    }
	return false;
}

/**
 * Checks if the point is an inflexion point.
 * @param {Number|Number[]} previousVelocity The derivative (speed) of a point just before the point.
 * @param {Number|Number[]} pointVelocity The derivative (speed) at the point to check.
 * @param {Number|Number[]} nextVelocity The derivative (speed) of a point just after the point.
 * @return {Boolean} 
 */
DuMath.isInflexionPoint = function(previousVelocity, pointVelocity, nextVelocity) {
    previousVelocity = new DuList(previousVelocity);
    pointVelocity = new DuList(pointVelocity);
    nextVelocity = new DuList(nextVelocity);

    for (var i = 0, n = pointVelocity.length(); i < n; i++) {
		var p = pointVelocity.at(i);
		var pv = previousVelocity.at(i);
		var nx = nextVelocity.at(i);
		if (p == pv && p == nx) continue;
		if ( p >= pv && p >= nx) return true;
		if ( p <= pv && p <= nx) return true;
    }
	return false;
}// ==================== |---------------| ====================
// ==================== | interpolation | ====================
// ==================== |---------------| ====================

/**
 * Interpolation methods
 * @namespace
 * @category DuESF
 */
var DuInterpolation = {};

/**
 * Linear (extra/inter)polation
 * @param {Number} value The variable
 * @param {Number} [min=0] The minimum input value
 * @param {Number} [max=1] The maximum input value
 * @param {Number} [targetMin=0] The minimum output value
 * @param {Number} [targetMax=1] The maximum output value
 * @param {Boolean} [extrapolate=true] Whether to extrapolate outside the target.
 * @returns {Number}
 */
DuInterpolation.linear = function(value, min, max, targetMin, targetMax, extrapolate) { 
    extrapolate = def(extrapolate, true);
    return DuMath.linear(value, min, max, targetMin, targetMax, !extrapolate)
};

/**
 * Interpolates a value with a bezier curve.
 * @param {number} t The value to interpolate
 * @param {number} [tMin=0] The minimum value of the initial range
 * @param {number} [tMax=1] The maximum value of the initial range
 * @param {number} [value1=0] The minimum value of the interpolated result
 * @param {number} [value2=1] The maximum value of the interpolated result
 * @param {number[]} [bezierPoints=[0.33,0.0,0.66,1.0]] an Array of 4 coordinates wihtin the [0.0, 1.0] range which describes the Bézier interpolation. The default mimics the native ease() function<br />
 * [ outTangentX, outTangentY, inTangentX, inTangentY ]
 * @return {number} the value.
 */
DuInterpolation.bezier = function(t, tMin, tMax, value1, value2, bezierPoints) {
    tMin = def(tMin, 0);
    tMax = def(tMax, 1);
    value1 = def(value1, 0);
    value2 = def(value2, 1);
    bezierPoints = def(bezierPoints, [0.33,0.0,0.66,1.0]);

    if (arguments.length !== 5 && arguments.length !== 6) return (value1+value2)/2;
    var a = value2 - value1;
    var b = tMax - tMin;
    if (b == 0) return (value1+value2)/2;
    var c = DuMath.clamp((t - tMin) / b, 0, 1);
    if (!(bezierPoints instanceof Array) || bezierPoints.length !== 4) bezierPoints = [0.33,0.0,0.66,1];
    return a * h(c, bezierPoints) + value1;

    function h(f, g) {
        var x = 3 * g[0];
        var j = 3 * (g[2] - g[0]) - x;
        var k = 1 - x - j;
        var l = 3 * g[1];
        var m = 3 * (g[3] - g[1]) - l;
        var n = 1 - l - m;
        var d = f;
        for (var i = 0; i < 5; i++) {
            var z = d * (x + d * (j + d * k)) - f;
            if (Math.abs(z) < 1e-3) break;
            d -= z / (x + d * (2 * j + 3 * k * d));
        }
        return d * (l + d * (m + d * n));
    }
}

/**
 * Interpolates and extrapolates a value with an exponential function.
 * @param {number} t The value to interpolate
 * @param {number} [tMin=0] The minimum value of the initial range
 * @param {number} [tMax=1] The maximum value of the initial range
 * @param {number} [value1=0] The minimum value of the interpolated result
 * @param {number} [value2=1] The maximum value of the interpolated result
 * @param {number} [rate=1] The raising speed in the range [0, inf].
 * @return {number} the value.
 */
DuInterpolation.exponential = function(t, tMin, tMax, vMin, vMax, rate)
{
	tMin = def(tMin, 0);
    tMax = def(tMax, 1);
    vMin = def(vMin, 0);
    vMax = def(vMax, 1);
    rate = def(rate, 1);
   
    if (rate == 0) return DuInterpolation.linear(t, tMin, tMax, vMin, vMax);

    // handle tMax < tMin
    var rev = false;
    if (tMax < tMin) {
        var temp = tMax;
        tMax = tMin;
        tMin = temp;
        rev = true;
    }

	// Offset t to be in the range 0-Max
	tMax = ( tMax - tMin ) * rate;
	t = ( t - tMin ) * rate;
	// Compute the max
	var m = Math.exp(tMax);
	// Compute current value
	t = Math.exp(t);
	var result = DuInterpolation.linear(t, 1, m, vMin, vMax);
    if (rev) result = DuInterpolation.linear(result, vMin, vMax, vMax, vMin);
    return result;
}

/**
 * Interpolates a value with a gaussian function.
 * @function
 * @param {number} t The value to interpolate
 * @param {number} [tMin=0] The minimum value of the initial range
 * @param {number} [tMax=1] The maximum value of the initial range
 * @param {number} [value1=0] The minimum value of the interpolated result
 * @param {number} [value2=1] The maximum value of the interpolated result
 * @param {number} [rate=0] The raising speed in the range [-1.0, 1.0].
 * @return {number} the value.
 */
DuInterpolation.gaussian = function( t, tMin, tMax, value1, value2, rate )
{
    tMin = def(tMin, 0);
    tMax = def(tMax, 1);
    value1 = def(value1, 0);
    value2 = def(value2, 1);
    rate = def(rate, 0);

    // handle tMax < tMin
    var rev = false;
    if (tMax < tMin) {
        var temp = tMax;
        tMax = tMin;
        tMin = temp;
        rev = true;
    }

    // fix small bump at first value
    if (t != tMin)
    {
        var newValue1 = DuInterpolation.gaussian( tMin, tMin, tMax, value1, value2, rate );
        var offset = newValue1 - value1;
        value1 = value1 - offset;
    }
	if (rate < 0) rate = rate*10;
	rate = DuInterpolation.linear(t, tMin, tMax, 0.25, rate);
	var r = ( 1 - rate );
    var fwhm = (tMax-tMin) * r;
    var center = tMax;
	if (t >= tMax) {
        if (rev) return value1;
        return value2;
    }
    if (fwhm === 0 && t == center) {
        if (rev) return value1;
        return value2;
    }
    else if (fwhm === 0) {
        if (rev) return value2;
        return value1;
    }
	
    var exp = -4 * Math.LN2;
    exp *= Math.pow((t - center),2);
    exp *= 1/ Math.pow(fwhm, 2);
    var result = Math.pow(Math.E, exp);
	result = result * (value2-value1) + value1;

    if (rev) result = DuInterpolation.linear( result, value1, value2, value2, value1);

    return result;
}

/**
 * Interpolates and extrapolates a value with a logarithmic function.
 * @function
 * @param {number} t The value to interpolate
 * @param {number} [tMin=0] The minimum value of the initial range
 * @param {number} [tMax=1] The maximum value of the initial range
 * @param {number} [value1=0] The minimum value of the interpolated result
 * @param {number} [value2=1] The maximum value of the interpolated result
 * @param {number} [rate=1] The raising speed in the range [0, inf].
 * @return {number} the value.
 */
DuInterpolation.logarithmic = function(t, tMin, tMax, vMin, vMax, rate)
{
    tMin = def(tMin, 0);
    tMax = def(tMax, 1);
    vMin = def(vMin, 0);
    vMax = def(vMax, 1);
    rate = def(rate, 1);
    
    if (rate == 0) return DuInterpolation.linear(t, tMin, tMax, vMin, vMax);

    // handle tMax < tMin
    var rev = false;
    if (tMax < tMin) {
        var temp = tMax;
        tMax = tMin;
        tMin = temp;
        rev = true;
    }

    // Offset t to be in the range 0-Max
    tMax = ( tMax - tMin ) * rate + 1;
    t = ( t - tMin ) * rate + 1;
    if (t <= 1) {
        if (rev) return vMax;
        return vMin;
    } 
    // Compute the max
    var m = Math.log(tMax);
    // Compute current value
    var v = Math.log(t);
    var result = DuInterpolation.linear(v, 0, m, vMin, vMax);
    if (rev) result = DuInterpolation.linear(result, vMin, vMax, vMax, vMin);
    return result;
}

/**
 * Interpolates and extrapolates a value with a logistic (sigmoid) function.
 * @function
 * @param {number} t The value to interpolate
 * @param {number} [tMin=0] The minimum value of the initial range
 * @param {number} [tMax=1] The maximum value of the initial range
 * @param {number} [value1=0] The minimum value of the interpolated result
 * @param {number} [value2=1] The maximum value of the interpolated result
 * @param {number} [rate=1] The raising speed in the range [0, inf].
 * @param {number} [tMid] The t value at which the interpolated value should be half way. By default, (tMin+tMax)/2
 * @return {number} the value
 */
DuInterpolation.logistic = function( t, tMin, tMax, value1, value2, rate, tMid )
{
    tMin = def(tMin, 0);
    tMax = def(tMax, 1);
    value1 = def(value1, 0);
    value2 = def(value2, 1);
    rate = def(rate, 1);
    tMid = def(tMid, (tMin+tMax)/2);

    if (rate == 0) return DuInterpolation.linear(t, tMin, tMax, value1, value2);
    t = DuMath.logistic( t, tMid, tMin, tMax, rate);
    
    // Scale to actual min/max
    var m = DuMath.logistic( tMin, tMid, tMin, tMax, rate);
    var M = DuMath.logistic( tMax, tMid, tMin, tMax, rate);

    return DuInterpolation.linear( t, m, M, value1, value2);
}
// ==================== |------| ====================
// ==================== | date | ====================
// ==================== |------| ====================

/**
	* Date related methods
	* @namespace
	* @category DuESF
*/
var DuDate = {};

// low-level undocumented list. Use getMonth and getMonthName
DuDate.MonthNames = [
	tr("January"),
	tr("February"),
	tr("March"),
	tr("April"),
	tr("May"),
	tr("June"),
	tr("July"),
	tr("August"),
	tr("September"),
	tr("October"),
	tr("November"),
	tr("December"),
];

/**
	* Gets the month number from a literal localized name. 0 is january, 11 is december
	* @memberof DuDate
	* @param {string} string - The month name
	* @return {int} The month number
*/
DuDate.getMonth = function (string)
{
	string = string.toLowerCase();
	for (var i = 0; i < 12; i++)
	{
		if ( DuDate.MonthNames[i].toLowerCase().indexOf(string) >= 0 ) return i;
	}

	return 0;
}

/**
	* Gets the month name from an index. 0 is january, 11 is december
	* @memberof DuDate
	* @param {int} string - The month index
	* @return {string} The month name
*/
DuDate.getMonthName = function (index)
{
	if (index >= 0 && index < 12) return DuDate.MonthNames[i];

	return "";
}

/**
	* Returns a pretty formatted string representing the date
	* @todo format option
	* @memberof DuDate
	* @param {Date} date - The date
	* @return {string} The date
*/
DuDate.toString = function (date)
{
	var hour = date.getHours();
	var minute = date.getMinutes();
	var second = date.getSeconds();
	var day = date.getDate();
	var month = date.getMonth();
	var year = date.getFullYear();

	return year + "-" + (month+1) + "-" + day + " " + hour + "-" + minute + "-" + second;
}// ==================== |--------| ====================
// ==================== | binary | ====================
// ==================== |--------| ====================

/**
 * Constructs a new string representation of a binary file
 * @class DuBinary
 * @classdesc Represents a binary file as a string and a filename.
 * @param	{string}	binAsString			- The string representation.
 * @param	{string}	fileName			- The name of the original file.
 * @param	{string}	[category='']			- A Category for the file, will be used as a subfolder to extract files. Can have subcategories like "category/subcategory".
 * @category DuESF
 */
function DuBinary( binAsString, fileName, category)
{
    /**
        * The string representation of the binary file.
        * @memberof DuBinary
        * @type {string}
        * @name binAsString
        */
	this.binAsString = binAsString;

	fileName = DuString.replace(fileName,'%20','_');
    /**
        * The name of the original file.
        * @memberof DuBinary
        * @type {string}
        * @name fileName
        */
	this.fileName = fileName;

	if (category === undefined) category = '';
    /**
        * A Category for the file, will be used as a subfolder to extract files. Can have subcategories like "category/subcategory".
        * @memberof DuBinary
        * @type {string}
        * @name category
        */
	this.category = category;
}

/**
 * Returns a string representation of the {@link DuBinary} which can be written in a jsxinc file.
 * @returns {string} The source.
 */
DuBinary.prototype.toSource = function ()
{
    return 'new DuBinary( "' + this.binAsString + '", "' + this.fileName + '", "' + this.category + '" )';
}

/**
 * Writes the file.
 * @param {string}			[outputFileName=DuFolder.duesfData/category/binaryfilename]	- The output filename.
 * @param {boolean}			[onlyAtFirstRun=true]	- Does not extract the file if it already exists and this is not the first time this version of the script is being used.<br />
 * The file will be extracted only if the script is new or has just been updated (the version changed).
 * @return {File|null} The file created, null if the file could not be written.<br />
 * If the file is not written, check user permissions, and check if the file and network access preference is checked.
 * @example
 * //First, include the text representation of the file (Add a # before the include word)
 * include executable.exe.jsxinc
 * // Now, a variable called `executable` (the original file name without extension) is available, it's an instance of DuBinary.
 * var execFile = executable.extract();
 * //Now, the file exists in the file system, and execFile is an ExtendScript File object.
 * // The `DuBinary.extract()` method extracts the file to the Application Data folder by default.
 * execFile.fsName; // C:\users\duduf\appData\Roaming\RxMaboratory\AdobeScripts\DuESF\icon.png (Example on Windows)
 * @example
 * //You can specify the output file name. (Add a # before the include word)
 * include preset.ffx.jsxinc
 * var presetFile = preset.extract("C:/test/test_preset.ffx");
 * presetFile.fsName; // C:\test\test_preset.exe");
 */
DuBinary.prototype.toFile = function( outputFileName, onlyAtFirstRun )
{
    onlyAtFirstRun = def( onlyAtFirstRun, true );

    var rootFolder = DuFolder.duesfData.absoluteURI;
    outputFileName = def( outputFileName, rootFolder + '/' + this.category + '/' + this.fileName )

    var file = new File(outputFileName);

    // performance
    // do not extract if the file exists and we're not in the first run (or debug mode)
    if (file.exists && !DuESF.scriptFirstRun && !DuESF.debug && onlyAtFirstRun)
    {
        return file;
    }

	if (!file.exists)
	{
		var folder = new Folder(file.path);
		if (!folder.exists)
		{
			folder.create();
		}
	}

    DuFile.write( file, this.binAsString, false, 'BINARY');

    return file;
}

/**
 * Writes the DuBinary to a jsxinc file
 * @param {string} outputFilePath  - The file path for the output.
 * @param {any} [varName=File name without extension]	- The name of the variable used to store the javascript object.
 * @returns {File} the new jsxinc file.
 */
DuBinary.prototype.toJsxincFile = function( outputFilePath, varName )
{
    var fileName = DuPath.getBasename(outputFilePath);
    varName = def (varName, fileName.replace(/\..+/,'') );
	varName = DuString.replace(varName,'%20','_');

    var jsString = 'var ' + varName + ' = ' + this.toSource() + ';\r\n' + varName + ';\r\n';

	var outputFile = new File( outputFilePath );
	outputFile.encoding = 'UTF8';
	if (outputFile.open("w", "TEXT", "????"))
	{
		outputFile.write(jsString);
		outputFile.close();
	}
    
    return outputFile;
}
// =============== STATIC =====================

/**
 * Creates a {@link DuBinary} object from an existing file
 * @static
 * @param {File}    file      - The File to convert
 * @param {string}  [category]  - A Category for the file, will be used as a subfolder to extract files. Can have subcategories like "category/subcategory".
 * @return {DuBinary} The {@link DuBinary} object containing the file as a string
 */
DuBinary.fromFile = function ( file, category )
{
    var content = '';

    file.encoding = "BINARY";
    if (file.open("r"))
    {
        content = file.read().toSource();
        content = content.substr(content.indexOf("\"")+1, content.length);
        content = content.substr(0, content.lastIndexOf("\""));
        file.close();
    }

    return new DuBinary(content,file.name,category);
}

/**
 * Converts a file to a jsxinc file
 * @static
 * @param {File}    file      - The binary file to convert
 * @param {string}  [category]        - A Category for the file, will be used as a subfolder to extract files. Can have subcategories like "category/subcategory". Default is the name of the folder containing the file.
 * @param {string}  [outputFilePath=Same folder, same name with .json extension]  - The file name for the output.
 * @param {string}	[varName=File name without extension]	- The name of the variable used to store the javascript object.
 * @return {File} The jsxinc file created
 */
DuBinary.toJsxincFile = function(file,category,outputFilePath,varName)
{
    category = def (category, file.parent.name );
    outputFilePath = def (outputFilePath, file.absoluteURI + '.jsxinc' );
	var duBinary = DuBinary.fromFile(file,category);
	return duBinary.toJsxincFile( outputFilePath, varName );
}

// ============== DEPRECATED ==================

/**
 * Creates a file from a DuBinary object representation.
 * @static
 * @deprecated
 * @param {DuBinary}	DuBinary  	- The DuBinary object containing the string representation.<br />
 * This object will be replaced by the File object created.<br />
 * If a file object is provided (the file has already been extracted), does nothing.
 * @param {string}			[outputFileName=DuFolder.duesfData/DuAEF/scriptName/category/binaryfilename]	- The output filename.
 * @param {boolean}			[onlyAtFirstRun=true]	- Does not extract the file if it already exists and this is not the first time this version of the script is being used.<br />
 * The file will be extracted only if the script is new or has just been updated (the version changed).
 * @return {File|null} The file created, null if the file could not be written.<br />
 * If the file is not written, check user permissions, and check if the file and network access preference is checked.
 * @example
 * //First, include the text representation of the file (Add a # before the include word)
 * include executable.exe.jsxinc
 * // Now, a variable called `executable` (the original file name without extension) is available, you can pass this object to the `DuBinary.toFile()` method to extract it and get an ExtendScript File object representation of it.
 * // Note: This object is an instance of a `DuBinary` class, which contains all information and a string representation of the original binary file
 * var execFile = DuBinary.toFile(executable);
 * //Now, the file exists in the file system, and execFile is an ExtendScript File object.
 * // The `DuBinary.toFile()` method extracts the file to the Application Data folder by default.
 * execFile.fsName; // C:\users\duduf\appData\Roaming\DuAEF\icon.png (Example on Windows)
 * @example
 * //You can specify the output file name. (Add a # before the include word)
 * include preset.ffx.jsxinc
 * var presetFile = DuBinary.toFile(preset,"C:/test/test_preset.ffx");
 * presetFile.fsName; // C:\test\test_preset.exe");
 * @category DuESF
 */
DuBinary.toFile = function(DuBinary,outputFileName,onlyAtFirstRun)
{
    onlyAtFirstRun = def( onlyAtFirstRun, true );
    if (!isdef( DuBinary )) return;
	if (DuBinary instanceof File) return;
    var rootFolder = DuFolder.duesfData.absoluteURI;
    if (DuESF.scriptName != '') rootFolder += '/'  + DuESF.scriptName;
	if (!isdef( outputFileName )) outputFileName = rootFolder + '/' + DuBinary.category + '/' + DuBinary.fileName;
	var file = new File(outputFileName);

  // performance
  // do not extract if the file exists and we're not in the first run (or debug mode)
  if (file.exists && !DuESF.scriptFirstRun && !DuESF.debug)
  {
    return file;
  }

	if (!file.exists)
	{
		var folder = new Folder(file.path);
		if (!folder.exists)
		{
			folder.create();
		}
	}

	file.encoding = 'BINARY';
	if (file.open('w'))
	{
		success = file.write(DuBinary.binAsString);
		file.close();
	}

	DuBinary = file;

	return file;
}

/**
 * Converts a JS file to a binary file
 * @deprecated
 * @static
 * @param {File}    jsFile        - The JS file to convert
 * @param {string}	[outputFileName=DuFolder.duesfData/category/binaryfilename]	- The output filename.
 * @return {File} The binary file created, or null if failed
 * @example
 * //If you don't want to include the file in the script. (Add a # before the include word)
 * var stringFile = new File("C:\test\image.jpg.jsxinc");
 * var jpgFile = DuBinary.convertToBinaryFile(stringFile);
 * // Warning, this method uses `$.eval()` which is a bad security issue.
 * // Do not use this method for anything else than debugging and testing.
 */
DuBinary.convertToBinaryFile = function(jsFile,outputFileName)
{
	//TODO parse instead of eval
	var obj = $.eval(jsFile);
	return this.toFile(obj);
}

// ==================== |---------| ====================
// ==================== | process | ====================
// ==================== |---------| ====================

/**
    * Constructs a new DuProcess instance
    * @class DuProcess
    * @classdesc A class to launch and manage processes, using the system command line.
    * @param {string}	  processPath     - The path to the process executable binary
    * @param {string[]}    [args]            - The common arguments used to run the process. You can append arguments each time you run the process with start(args)
    * @param {int}      [timeout=0]         - Waiting timeout after process start, in ms, 0 to avoid waiting, -1 for infinite.
    * If the process times out, process will not be killed, the script will just stop waiting.
    * @category DuESF
*/
function DuProcess( processPath, args, timeout ) {
    processPath = def( processPath, "");
    args = def( args, []);
    timeout = def( timeout, 0);

    /**
     * The path to the process executable binary
     * @type {string}
     * @name processPath
     * @memberof DuProcess
     * @readonly
     */
    this.processPath = processPath;

    /**
     * The common arguments used to run the process. You can append arguments each time you run the process with start(args)
     * @type {any[]}
     * @name args
     * @memberof DuProcess
     */
    this.args = args;

    /**
     * Waiting timeout after process start, in ms, 0 to avoid waiting, -1 for infinite.<br />
     * If the process times out, process will not be killed, the script will just stop waiting. Default: 0
     * @type {int}
     * @name timeout
     * @memberof DuProcess
     */
    this.timeout = timeout;

    /**
     * True if the process path leads to an application package (.app folder containing at least "/Contents/MacOS") on mac. False otherwise.
     * @type {Boolean}
     * @name isAppPackage
     * @memberof DuProcess
     * @readonly
     */
    this.isAppPackage = DuProcess.isAppPackage( processPath );

    /**
     * An Array of arguments array.<br />
     * Arrays of arguments in the queue will be processed one after each other.<br />
     * Update the Array and launch the queue with startQueue()
     * @type {string[][]}
     * @name queue
     * @memberof DuProcess
     */
    this.queue = [];

    /**
     * The latest command which has been run.
     * @type {string}
     * @name latestCommand
     * @memberof DuProcess
     * @readonly
     */
    this.latestCommand = '';
}

/**
 * Starts the process
 * @memberof DuProcess
 * @param {Array}  args  - Args to append to {@link DuProcess.args} before starting
 * @param {int}		[timeout] 	- Overrides the default timeout.
 */
DuProcess.prototype.start = function ( args, timeout ) {
    timeout = def(timeout, this.timeout);

    var cmd = this.buildCmd( args );

    this.startCmd( cmd );
    this.latestCommand = cmd;
    if (timeout > 100) this.waitForFinished( timeout );
}

/**
 * Starts the queue
 * @memberof DuProcess
 * @param {int}		[timeout] 	- Overrides the default timeout.
 */
DuProcess.prototype.startQueue = function ( timeout ) {
    if ( timeout === undefined ) timeout = this.timeout;

    var cmd = this.buildQueueCmd();

    this.startCmd( cmd );
    this.latestCommand = cmd;
    this.queue = [];

    this.waitForFinished( timeout );
}

/**
 * Waits for the process to finish
 * @memberof DuProcess
 * @param {int}		[timeout] 	- Overrides the default timeout.
 */
DuProcess.prototype.waitForFinished = function ( timeout ) {
    if ( timeout === undefined ) timeout = this.timeout;
    //wait
    var wait = true;
    var currentDate = new Date();
    var timeout = currentDate.getTime() + timeout;
    var checkTime = new Date();

    var checkCmd = '';
    var processName = new File( this.processPath ).name;
    if ( DuSystem.mac ) checkCmd = 'ps -A | grep "' + processName + '"';
    if ( DuSystem.win ) checkCmd = 'tasklist /FO TABLE /NH /FI "Imagename eq ' + processName + '"';

    //wait
    while ( wait ) {
        var test = system.callSystem( checkCmd );
        if ( test.indexOf( processName ) < 0 ) break;
        $.sleep( 100 );
        checkTime = new Date();

        if ( this.timeout >= 0 ) {
            wait = checkTime.getTime() < timeout;
        }
    }
}

/**
 * Builds and returns the command line
 * @memberof DuProcess
 * @param {string[]}  [args]  - Args to append to DuProcess.args before starting
 * @return {string}	The command
 */
DuProcess.prototype.buildCmd = function ( args ) {
    if ( args === undefined ) args = [];
    //build command
    //make sure to use fsName
    if ( this.processPath.indexOf( '/' ) >= 0 || this.processPath.indexOf( '\\' ) >= 0 ) {
        var processFile = new File( this.processPath );
        this.processPath = processFile.fsName;
        if ( this.processPath.indexOf( ' ' ) > 0 ) {
            this.processPath = '"' + this.processPath + '"';
        }
    }
    var cmd = "";
    // if it's an app package, prepend "open -n " and append " --args"
    if (this.isAppPackage)
    {
        cmd = "open -n " + this.processPath;
        if (args.length > 0 || this.args.length > 0)
        {
            cmd += " --args";
        }
    }
    else
    {
        cmd = this.processPath;
    }

    //args
    for ( var a = 0; a < this.args.length; a++ ) {
        var arg = this.args[ a ];
        if (jstype(arg) != 'string') arg = arg.toString();
        if ( arg.indexOf( ' ' ) > 0 ) {
            arg = '"' + arg + '"';
        }
        cmd += ' ' + arg;
    }
    for ( var b = 0; b < args.length; b++ ) {
        var arg = args[ b ];
        if (jstype(arg) != 'string') arg = arg.toString();
        if ( arg.indexOf( ' ' ) > 0 ) {
            arg = '"' + arg + '"';
        }
        cmd += ' ' + arg;
    }
    
    return cmd;
}

/**
 * Builds and returns the command line to launch the current queue
 * @memberof DuProcess
 * @return {string}	The command
 */
DuProcess.prototype.buildQueueCmd = function () {
    var cmd = '';

    if ( this.queue.length == 0 ) {
        return this.buildCmd();
    }

    for ( var i = 0; i < this.queue.length; i++ ) {
        if ( i > 0 ) {
            if ( DuSystem.mac ) cmd += ' && ';
            if ( DuSystem.win ) cmd += '\r\n';
        }
        cmd += this.buildCmd( this.queue[ i ] );
    }
    return cmd;
}

/**
 * Starts a command (in another thread).
 * @memberof DuProcess
 * @param {string}  cmd  - The command to start
 */
DuProcess.prototype.startCmd = function ( cmd ) {
    //Start
    if ( DuSystem.mac ) {
        //add ' &' at the end to start detached
        cmd += ' &';
        system.callSystem( cmd );
    }
    if ( DuSystem.win ) {
        //create batch file
        var batName = 'DuProcess_' + new Date().getTime() + '.bat'
        var bat = new File( DuFolder.duesfData.absoluteURI + '/' + batName );
        bat.encoding = "CP437";
        cmd += '\ndel "' + DuFolder.duesfData.fsName + '\\' + batName + '"';
        bat.open( 'w' );
        bat.write( cmd );
        bat.close();
        bat.execute();
    }
}


// ================ STATIC =====================

/**
    * Runs a command with some arguments.
    * @static
    * @param {string|File} process - The process or a path to the process.
    * @param {string[]} [args=[]] - The arguments to pass to the command.
    * @return {string}	The output from the command.
    */
DuProcess.run = function( process, args ) {
    var p;
    if (process instanceof File) p = new DuProcess(process.absoluteURI);
    else p = new DuProcess(process);
    var cmd = p.buildCmd(args);
    return system.callSystem( cmd );
}

/**
 * Checks if a given path leads to an Application package on Mac, i.e. it's a path ending with <code>.app</code> containing at least <code>Contents/MacOS/</code>.
 * @static
 * @param {string|Folder|File} path - The path to the file or folder to check.
 * @return {bool} true if path is an application package.
 */
DuProcess.isAppPackage = function (path) {
    if (DuSystem.win) return false;

    if (path instanceof File || path instanceof Folder) path = path.absoluteURI;
    if (!DuString.endsWith( path, ".app")) return false;
    var testFolder = new Folder(path + "/Contents/MacOS/");
    return testFolder.exists;
}

/**
 * Constructs a queue of different processes
 * @class DuProcessQueue
 * @classdesc A class to launch several processes
 * @param {DuProcess[]}	  [processes]     - The DuProcess Array
 * @category DuESF
 */
function DuProcessQueue( processes ) {
    /**
     * The DuProcess list
      *@name processes
     * @type {DuProcess[]}
     * @memberof DuProcessQueue
     */
    this.processes = def (processes, []);
}

/**
 * Starts the processes
 * @memberof DuProcessQueue
 */
DuProcessQueue.prototype.start = function () {
    if ( !this.processes.length ) return;
    var cmd = '';
    for ( var i = 0; i < this.processes.length; i++ ) {
        var p = this.processes[ i ];
        if ( i > 0 ) {
            if ( DuSystem.mac ) cmd += ' && ';
            if ( DuSystem.win ) cmd += '\r\n';
        }
        cmd += p.buildQueueCmd();
        p.queue = [];
    }

    this.processes[ 0 ].startCmd( cmd );
}
// ==================== |-----| ====================
// ==================== | xml | ====================
// ==================== |-----| ====================

/**
* XML tools
* @namespace
* @category DuESF
*/
var DuXML = {};

/**
 * Parses the value of the XML object.<br />
 * If this object length is not 1, an Array is returned
 * @memberof DuXML
 * @param {XML} xml - The xml to parse
 * @param {string} [type='string'] - The type, one of 'string', 'bool', 'int', 'float' or 'date'.
 * @return {any[]|any} The value or an Array of values
 */
DuXML.getValue = function (xml,type)
{
	type = def(type, 'string');
	var value;

	if(xml.length() > 1)
	{
		value = [];
		for (var i = 0 ; i < xml.length() ; i++)
		{
			var val = DuXML.getValue(xml[i],type);
			value.push(val);
		}
	}
	else
	{
		var xmlString = xml.toString();
		if (type.toLowerCase() == 'float')
		{
			value = parseFloat(xmlString);
		}
		else if (type.toLowerCase() == 'int' || type.toLowerCase() == 'integer')
		{
			value = parseInt(xmlString);
		}
		else if (type.toLowerCase() == 'boolean' || type.toLowerCase() == 'bool')
		{
			value = DuString.parseBool(xmlString);
		}
		else if (type.toLowerCase() == 'date')
		{
			var reDate = /(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d{1,2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d)/gim
			var matches = reDate.exec(xmlString);
			var year = parseInt(matches[4]);
			var month = DuDate.getMonth(matches[3]);
			var day = parseInt(matches[2]);
			var hours = parseInt(matches[5]);
			var min = parseInt(matches[6]);
			var sec = parseInt(matches[7]);
			value = new Date(year, month, day, hours, min, sec);
		}
		else
		{
			value = xmlString;
		}
	}

	return value;
}
// ==================== |-----| ====================
// ==================== | xmp | ====================
// ==================== |-----| ====================

/**
 * XMP tools
 * @namespace
 * @category DuESF
 */
var DuXMP = {};

DuXMP.initialized = false;

/**
 * Loads the XMP library if it has not been loaded yet. There is no need to call this function as it's called automatically by DuESF methods if needed.<br />
 * Call it once if you plan to use XMP without the methods in DuESF.<br />
 * Note that the XMP library is added statically as <code>ExternalObject.AdobeXMPScript</code>.
 */
DuXMP.init = function ()
{
    if (DuXMP.initialized) return;
    
    // load the library
    ExternalObject.AdobeXMPScript = def ( ExternalObject.AdobeXMPScript, new ExternalObject( "lib:AdobeXMPScript") );

    DuXMP.initialized = true;
}// ==================== |-----| ====================
// ==================== | zip | ====================
// ==================== |-----| ====================

/**
    * Zip methods. This lib needs the 7zip command line tool <code>7za.exe</code> to be located next to the script on Windows.
    * @namespace
    * @category DuESF
    */
var DuZip = {};

if ( DuSystem.win ) DuZip.processArgs = ['a', '-mx9'];
else DuZip.processArgs = ['-r', '-X'];

/**
 * The path to 7za.exe or 7z.exe (windows only, mac uses the internal command 'zip')
 * @memberof DuZip
 * @type {string}
 */
DuZip.processPath = '';

if ( DuSystem.win ) DuZip.processPath = DuESF.file.parent.absoluteURI + '/7za.exe';
else DuZip.processPath = 'zip';

/**
 * Compresses the content of a folder
 * @memberof DuZip
 * @method
 * @param {Folder} folder The folder to zip
 * @param {string} [archiveName=folder.name + ".zip"] The archive name
 * @param {boolean} [wipeFolder=false] Set to true to remove the original folder as soon as the zip is ready
 * @return {File} The zip file
 */
DuZip.compressFolderContent = function (folder, archiveName, wipeFolder) {
    wipeFolder = def (wipeFolder, true);
    archiveName = def(archiveName, DuPath.getName(folder) + ".zip");
    if (archiveName == '') archiveName = folder.name + ".zip";

    var folderPath = folder.fsName;
    if (DuSystem.win) folderPath += "\\*";

    var args = DuZip.processArgs.concat( [folder.parent.fsName + "/" + archiveName, folderPath ] );

    if ( DuSystem.win && !new File(DuZip.processPath).exists ) {
        alert("7zip not found. Cannot zip folder: " + folder.fsName);
        return null;
    }

    var processes = [ new DuProcess(DuZip.processPath, args) ];

    if (wipeFolder) {
        var wipeProcessPath = '';
        var wipeProcessArgs = [];
        if (DuSystem.win) {
            wipeProcessPath = 'rmdir';
            wipeProcessArgs = [ '/Q', '/S', folder.fsName];
        }
        else {
            wipeProcessPath = 'rmdir';
            //TODO test on mac. For safety, set to interactive mode. change the flags to '-rf' when tests are run succesfully
            wipeProcessArgs = [ '-ir', folder.fsName];
        }
        processes.push( new DuProcess( wipeProcessPath, wipeProcessArgs ) );
    }

    var processQueue = new DuProcessQueue(processes);
    processQueue.start();

    return new File( folder.parent.fsName + "/" + archiveName );
}// ==================== |-----| ====================
// ==================== | oca | ====================
// ==================== |-----| ====================

/**
 * @class
 * @name DuOCADocument
 * @classdesc An Open Cel Animation document<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuOCA.load} to create an OCA object.
 * @property {string} ocaVersion - The version of OCA used to export this document
 * @property {string} name - The name of this project
 * @property {int} width - The width, in pixels
 * @property {int} height - The height, in pixels
 * @property {int} frameCount - The duration, in frames
 * @property {float} frameRate - The frame rate, in frames per second
 * @property {float} pixelAspect - The pixel aspect ratio
 * @property {OCALayer[]} layers - The layers
 * @property {int} startTime - The frame number at which the animation starts
 * @property {int} endTime - The frame number at which the animation ends
 * @property {DuOCA.colorDepths} colorDepth - Bits per channel used in the document
 * @property {float[]} backgroundColor - The background color
 * @property {string} originApp - The application name from which the document was exported.
 * @property {string} originAppVersion - The version of the origin application.
 * @property {Folder} folder - The folder containing the oca files.
 * @property {string} path - The URI to the folder containing the oca files.
 * @category DuOCA
 */

/**
 * @class
 * @name DuOCALayer
 * @classdesc An OCA Layer<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuOCA.load} to create an OCA object containing the layers.
 * @property {string} name - The layer name
 * @property {OCAFrame[]} frames - The keyframes of the animation for this layer.
 * @property {OCALayer[]} childLayers - The child layers if this layer is a group.
 * @property {DuOCA.LayerType} type - The type of the layer. See the Layer Types section below
 * @property {string} fileType -  The type of the files used for the frames. The file extension, without the initial dot.
 * @property {DuOCA.BlendingModes} blendingMode - The blending mode of the layer
 * @property {bool} inheritAlpha - The inherit alpaha option (preserve transparency)
 * @property {bool} animated - Whether this layer is a single frame or not.
 * @property {int[]} position - The coordinates of the center of the layer, in pixels [X,Y] in the document coordinates. 
 * @property {int} width - The width, in pixels.
 * @property {int} height - The height, in pixels.
 * @property {int} label - A label for the layer.
 * @property {float} opacity - The opacity, in the range 0.0-1.0
 * @property {bool} visible - True if the layer is visible
 * @property {bool} reference - Whether the layer is a guide or reference, and should not be rendered.
 * @property {bool} passThrough - Whether the layer is in pass through mode. Only for grouplayer.
 * @category DuOCA
 */

 /**
 * @class
 * @name DuOCAFrame
 * @classdesc An OCA Frame<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuOCA.load} to create an OCA object containing the layers.
 * @property {string} name - The layer name
 * @property {string} fileName - The path and name of the file of the frame. It is the absolute path from the root of the OCA folder.
 * @property {int} frameNumber - The frame in the document at which the frames starts to be visible
 * @property {float} opacity - The opacity, in the range 0.0-1.0
 * @property {int[]} position - The coordinates of the center of the layer, in pixels [X,Y] in the document coordinates.
 * @property {int} width - The width, in pixels.
 * @property {int} height - The height, in pixels.
 * @property {int} duration - The duration of the frame, in frames.
 * @category DuOCA
 */

/**
 * Open Cel Animation interchange tools
 * @namespace
 * @category DuOCA
 */
var DuOCA = {};

/**
    * The different layer types
    * @readonly
    * @enum {string}
    */
DuOCA.LayerType = {
    PAINT: 'paintlayer',
    VECTOR: 'vectorlayer',
    GROUP: 'grouplayer'
}


/**
 * Loads an OCA document from a json file
 * @param {File|string} file - The .json file or its path
 * @return {DuOCADocument|null} The OCA document or null if the file could not be parsed or opened
 */
DuOCA.load = function ( file )
{
    if (!DuDebug.checkVar( file, 'file', undefined, 'DuOCA.load(file)') !== true) return null;

    if ( typeof file === 'string' ) file = new File( file );

    if (!DuDebug.checkVar( file, 'file', 'File', 'DuOCA.load(file)') !== true) return null;
    
    if ( !file.exists ) throw "DuOCA.load(file): file does not exist.";

    var data = DuFile.parseJSON( file );

    //add containing folder
	data.folder = file.parent;
	data.path = data.folder.absoluteURI;

	return data;
}

// ==================== |-----| ====================
// ==================== | url | ====================
// ==================== |-----| ====================


/**
 * Methods to manage URLS
 * @namespace 
 * @category DuESF
 */
var DuURL = {};

/**
 * The list of escaped characters in URLs
 */
DuURL.EscapedChars = {
    "%": "%25",
    " ": "%20",
    "#": "%23",
    "$": "%24",
    "&": "%26",
    "@": "%40",
    "`": "%60",
    "/": "%2F",
    ":": "%3A",
    ":": "%3B",
    "<": "%3C",
    "=": "%3D",
    ">": "%3E",
    "?": "%3F",
    "[": "%5B",
    "\\": "%5C",
    "]": "%5D",
    "^": "%5E",
    "{": "%7B",
    "|": "%7C",
    "}": "%7D",
    "~": "%7E",
    "\"": "%22",
    "‘": "%27",
    "+": "%2B",
    ",": "%2C"
};


/**
 * Escapes common characters from a string to be included in a GET request URL.
 * @param {string} str The string to escape.
 * @returns {string} The escaped string.
 */
DuURL.escape = function( str )
{
    for( ch in DuURL.EscapedChars )
    {
        str = DuString.replace(str, ch, DuURL.EscapedChars[ch] );
    }
    return str;
}

/**
 * Builds a query, made of "key=value" pairs.
 * @param {Object} arr An associative array with key/value pairs. Values will be escaped.
 * @returns {string} The query, with the leading ?.
 */
DuURL.buildRequest = function( arr )
{
    var q = '?';
    var first = true;
    for( key in arr )
    {
        if (!arr.hasOwnProperty(key)) continue;
        if (!first) q += '&';
        first = false;
        q += key;
        if (arr[key] != '') q += "=" + DuURL.escape( arr[key] );
    }
    return q;
}

/**
 * Builds a HTTP GET request. The user-agent is named after DuESF.scriptName.
 * @param {string} host The host, without port, without http part; for example: "duduf.com" or "version.rxlab.io"
 * @param {string[]} [subfolders] The subfolders.
 * @param {Object} [argsArray] An associative array with key/value pairs. Values will be escaped.
 * @param {string} [httpVersion="1.1"] An associative array with key/value pairs. Values will be escaped.
 * @returns {string} The query ready to be posted with a socket
 */
DuURL.buildGET = function( host, subfolders, argsArray, httpVersion )
{
    subfolders = def(subfolders, []);
    httpVersion = def(httpVersion, "1.1");

    var request = 'GET ';
    
    // add subfolders
    for (var i = 0, n = subfolders.length; i < n; i++)
    {
        request += '/' + subfolders[i];
    }
    request += '/';

    // query
    if (isdef( argsArray ))
    {
        request += DuURL.buildRequest( argsArray );
    }

    request += '  HTTP/' + httpVersion + '\n';

    // Build user agent
    var userAgent = 'User-Agent: ' +
        DuESF.scriptName +
        '/' + DuESF.scriptVersion.fullVersion +
        ' (' + DuString.trim($.os) + ') AE/' +
        DuESF.hostVersion.version;

    request += userAgent + '\nHost: ' + host + '\n';

    return request;
}// ==================== |------| ====================
// ==================== | core | ====================
// ==================== |------| ====================

/**
    * Methods related to ScriptUI
    * @namespace
    * @category DuScriptUI
    */
var DuScriptUI = {}

// ==================== |---------| ====================
// ==================== | strings | ====================
// ==================== |---------| ====================

/**
 * The list of strings used by the UI.
 * @enum {string}
 */
DuScriptUI.String = {
    ABOVE: "Above",
    ABOVE_SHORT: "Ab",
    ADD_ITEM_OR_CAT: "Add new item or category",
    AE_BLUE: "After Effects Blue",
    AE_BLUE_TIP: "The After Effects highlighting blue",
    AE_ORANGE: "After Effects Orange (CS6)",
    AE_ORANGE_TIP: "The After Effects highlighting orange from good ol'CS6",
    APPLY: "Apply",
    APPLY_ALL: "Apply all",
    APPLY_SETTINGS: "Apply changes to the settings.",
    APPLY_SETTINGS_ALERT: "You may need to restart the script for all changes to take effect.",
    ARM: "Arm",
    ARTHROPOD: "Arthropod",
    AUDIO: "Audio",
    AXIS: "Axis",
    BACK_PREVIOUS: "Back",
    BACK_LOCATION: "Back",
    BACK_LOCATION_SHORT: "Bk",
    BIRD: "Bird",
    BODY: "Body",
    BONE: "Bone",
    BUG_REPORT: "Bug report",
    BUG_REPORT_TIP: "Bug report\nFeature request\n\nTell us what's wrong or request a new feature.",
    CAM: "Cam",
    CAMERA: "Camera",
    CANCEL: "Cancel",
    CALF: "Calf",
    CATEGORY: "Category",
    CHARACTER: "Character",
    CHANNEL: "Channel",
    CHECK_UPDATE: "Check for updates",
    CIRCLE: "Circle",
    CLAWS: "Claws",
    CLEAR_LIB_TIP: "Clears the current search and category",
    CLOSE: "Close",
    COLOR: "Color",
    COLOR_HIGHLIGHT_TIP: "Set the highlight color.",
    COPY: "Copy",
    CREATE: "Create",
    CUSTOM: "Custom",
    CUSTOM_COLOR_TIP: "Select a custom color.",
    CLOSE_SETTINGS: "Close settings",
    DEFAULT: "Default",
    DEV_MODE: "Dev and Debug mode",
    DEV_MODE_TIP: "Use at your own risk!",
    DIGITIGRADE: "Digitigrade",
    EAR: "Ear",
    EDIT: "Edit",
    EDIT_ITEM_OR_CAT: "Edit selected item or category",
    EDIT_SETTINGS: "Edit settings",
    EFFECTS: "Effects",
    EXPERT: "Expert",
    EXPERT_UI_TIP: "The smallest UI, for expert users.",
    EXPORT_TRANSLATION: "Export translation file",
    EXPORT_TRANSLATION_TIP: "Export a translation file to be edited with DuTranslator.",
    EYE: "Eye",
    EYES: "Eyes",
    EYEBROW: "Eye",
    FEATHER: "Feather",
    FEATHERS: "Feathers",
    FEATURE_REQUEST: "Feature request",
    FEATURE_REQUEST_TIP: "Feature request\nRequest something new.",
    FILE: "File",
    FIN: "Fin",
    FINGERS: "Fingers",
    FISH: "Fish",
    FISHBONE: "Fishbone",
    FISHBONES: "Fishbones",
    FISH_SPINE: "Fish spine",
    FOOT: "Foot",
    FOREARM: "Forearm",
    FRAME: "Frame",
    FRAMES: "Frames",
    FRONT: "Front",
    FRONT_LEG: "Front leg",
    FRONT_SHORT: "Fr",
    FUNDING_BAR_TIP: "Thank you for your donations!",
    FUNDING_BAR_TIP_DETAILS: "This month, the {#} fund is ${#}.\nThat's {#}% of our monthly goal ( ${#} )\n\nClick on this button to join the development fund!",
    GROUPS: "Groups",
    HAIR: "Hair",
    HAND: "Hand",
    HEAD: "Head",
    HEEL: "Heel",
    HELP: "Help",
    HELP_TIP: "Get help.",
    HIPS: "Hips",
    HOMINOID: "Hominoid",
    HOOF: "Hoof",
    INVERT: "Invert",
    INVERTED: "Inverted",
    ISOLATE: "Isolate",
    ITEM: "Item",
    LANGUAGE_TIP: "Set the language of the interface.",
    LAYER: "Layer",
    LAYERS: "Layers",
    LEFT: "Left",
    LEFT_SHORT: "L",
    LEG: "Leg",
    LIMB: "Limb",
    LOCATION: "Location",
    LOCATION_SHORT: "Loc",
    MAGIC: "Magic is happening",
    MAIN: "Main",
    MASKS: "Masks",
    MAXIMUM: "Maximum",
    MIDDLE: "Middle",
    MIDDLE_SHORT: "Md",
    MINIMUM: "Minimum",
    MORE_OPTIONS_TIP: "[Shift]: More options...",
    MOUTH: "Mouth",
    NAME: "Name",
    NECK: "Neck",
    NEXT: "Next",
    NONE: "None",
    NORMAL_MODE: "Normal mode",
    NOSE: "Normal mode",
    NULL_OBJECT: "Null",
    OK: "OK",
    OPACITY: "Opacity",
    OPEN: "Open",
    OPEN_FOLDER: "Open folder",
    ORIGINAL: "Original",
    PATH: "Path",
    PAW: "Paw",
    PENIS: "Penis",
    PINCER: "Pincer",
    PIN_TIP: "Keeps this panel open",
    PLANTIGRADE: "Plantigrade",
    PREVIOUS: "Previous",
    POLYGON: "Polygon",
    POSITION: "Position",
    PROPERTIES: "Properties",
    RANDOM_TIP: "Set a random value.",
    RECTANGLE: "Rectangle",
    REFRESH_LIB: "Refresh library",
    REMOVE: "Remove",
    REMOVE_ITEM_OR_CAT: "Remove selected item or category",
    RESET_SETTINGS: "Reset the settings to their default values.",
    RIGHT: "Right",
    RIGHT_SHORT: "R",
    ROOKIE: "Rookie",
    ROOKIE_UI_TIP: "The easiest-to-use mode, but also the biggest UI.",
    ROTATION: "Rotation",
    ROUNDED_RECTANGLE: "Rounded rectangle",
    RUN_EXECUTE: "Run",
    RX_PURPLE: "RxLab Purple",
    RX_PURPLE_TIP: "The RxLaboratory Purple",
    RX_RED: "Rainbox Red",
    RX_RED_TIP: "The Rainbox Productions Red",
    SAVE_AS: "Save as",
    SCALE: "Scale",
    SCRIPTING: "Scripting",
    SELECT_LAYERS: "Select layers",
    SELECT_GROUPS: "Select groups",
    SET_QUALITY: "Set quality",
    SETTINGS: "Settings",
    SETTINGS_FILE: "Settings file",
    SETTINGS_FILE_TIP: "Set the location of the settings file.",
    SHOULDER: "Shoulder",
    SHOULDERS: "Shoulders",
    SHOULDERS_AND_NECK: "Shoulders & neck",
    SIDE: "Side",
    SIZE: "Size",
    SNAKE: "Snake",
    SPINE: "Spine",
    STANDARD: "Standard",
    STANDARD_UI_TIP: "The standard not-too-big UI.",
    START_TYPING_CMD: "Start typing something...",
    TAIL: "Tail",
    TAIL_SHORT: "Tl",
    TARGET: "Target",
    TEXT: "Text",
    TEXTURE: "Texture",
    THIGH: "Thigh",
    TIMELINE: "Timeline",
    TIP_BONE: "Tip",
    TRANSFORM: "Transform",
    TOES: "Toes",
    TORSO: "Torso",
    TYPE: "Type",
    UI_MODE_TIP: "Select the UI mode.",
    UNDER: "Under",
    UNDER_SHORT: "Un",
    UNGULATE: "Ungulate",
    VERTEBRAE: "Vertebrae",
    VULVA: "Vulva",
    WING: "Wing",
    WORKING: "Working...",
    X_POSITION: "X Position",
    Y_POSITION: "Y Position"
}

// OS Specific strings
if (DuSystem.win) {
    DuScriptUI.String.CTRL_KEY = "Ctrl";
    DuScriptUI.String.SHIFT_KEY = "Shift";
    DuScriptUI.String.ALT_KEY = "Alt";
}
else {
    DuScriptUI.String.CTRL_KEY = "Cmd";
    DuScriptUI.String.SHIFT_KEY = "Shift";
    DuScriptUI.String.ALT_KEY = "Alt";
}

DuScriptUI.String.CTRL_KEY_TIP = "[" + DuScriptUI.String.CTRL_KEY + "]";
DuScriptUI.String.SHIFT_KEY_TIP = "[" + DuScriptUI.String.SHIFT_KEY + "]";
DuScriptUI.String.ALT_KEY_TIP = "[" + DuScriptUI.String.ALT_KEY + "]";// ==================== |-------| ====================
// ==================== | icons | ====================
// ==================== |-------| ====================

// very small 18px
// ==================== |------------| ====================
// ==================== | w8_ae_blue | ====================
// ==================== |------------| ====================

var w8_ae_blue = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\b\x00\x00\x00\b\b\x06\x00\x00\x00\u00C4\x0F\u00BE\u008B\x00\x00\x00\tpHYs\x00\x00\x03\u00B0\x00\x00\x03\u00B0\x01'\u00C4\x0F\u00AD\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\x16IDAT\x18\u0095c\u00D4\u00EDy\u00FD\u009F\x01\x0F`\u00C2'9|\x14\x00\x00\u00B9|\x02\u00B3i>m(\x00\x00\x00\x00IEND\u00AEB`\u0082", "w8_ae_blue.png", "w8" );
w8_ae_blue;
// ==================== |--------------| ====================
// ==================== | w8_rx_purple | ====================
// ==================== |--------------| ====================

var w8_rx_purple = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\b\x00\x00\x00\b\b\x06\x00\x00\x00\u00C4\x0F\u00BE\u008B\x00\x00\x00\tpHYs\x00\x00\x03\u00B0\x00\x00\x03\u00B0\x01'\u00C4\x0F\u00AD\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\x16IDAT\x18\u0095c\\\u00AAv\u00E4?\x03\x1E\u00C0\u0084Or\u00F8(\x00\x00\u00A4\u009D\x02\u009E=\u008C7\u00F7\x00\x00\x00\x00IEND\u00AEB`\u0082", "w8_rx_purple.png", "w8" );
w8_rx_purple;
// ==================== |-----------| ====================
// ==================== | w8_rx_red | ====================
// ==================== |-----------| ====================

var w8_rx_red = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\b\x00\x00\x00\b\b\x06\x00\x00\x00\u00C4\x0F\u00BE\u008B\x00\x00\x00\tpHYs\x00\x00\x03\u00B0\x00\x00\x03\u00B0\x01'\u00C4\x0F\u00AD\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\x16IDAT\x18\u0095c|#!\u00F1\u009F\x01\x0F`\u00C2'9|\x14\x00\x00/\u00DE\x02+f\u00E7\x16^\x00\x00\x00\x00IEND\u00AEB`\u0082", "w8_rx_red.png", "w8" );
w8_rx_red;
// ==================== |--------------| ====================
// ==================== | w8_ae_orange | ====================
// ==================== |--------------| ====================

var w8_ae_orange = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\b\x00\x00\x00\b\b\x06\x00\x00\x00\u00C4\x0F\u00BE\u008B\x00\x00\x00\tpHYs\x00\x00\x03\u00B0\x00\x00\x03\u00B0\x01'\u00C4\x0F\u00AD\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\x16IDAT\x18\u0095c<>\u0089\u00E1?\x03\x1E\u00C0\u0084Or\u00F8(\x00\x00n?\x02h(Q\u00FBI\x00\x00\x00\x00IEND\u00AEB`\u0082", "w8ae_orange.png", "w8" );
w8_ae_orange;
// small 12px
// ==================== |---------------| ====================
// ==================== | w12_bugreport | ====================
// ==================== |---------------| ====================

var w12_bugreport = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x014IDAT(\u0091u\u008F\u00BF.\x04a\x14\u00C5\x7Fwf\u00D6D\u0096B\x14\u00A2C\u00B3\x14\x12\u00AF@#\u0091\u00EC\u00CEWH\u0088^\u00A2Rl/\"\u00E8E\u0094z2b\u00B3_au\u00E2\r\x04\r\u008DG\x10\u009D,3s\x1462&\u00D9\u00D3\u009D\u009C{\u00CF\x1F\u00A3\x02\u00EF}\x1Bh\x03\u00A1\u00A43\u00E7\u00DCqY\u00B72\u00E9v\u00BBkfv\u00F3\u00EF\u00C0l\u00A3\u00D5j\u00A5\x7F\u00BC\u00D3\u00E9LFQt\u009Ae\u00D9Q\x18\u0086\x0B\u00C0j\u00E5\u00E1\u00DE\u00CC\x1E$\u00EDeY\u00B6\x1B\x01HZ\x0E\u00C3p\u00C5\u00CCv\u008A\u00A2\u00B8\u00AA<\u00D4\u008B\u00A2\u00B8\u00FBW\u00C9{\u00DF\x00\x1E\u0081\u00B8\u00BAi\u0080~\x10\x04K\u00CDf\u00F3\u00E5o\u0083\u00F7\u00FE\x1D\u0098\x18\u00B8\u009EK\x12\u00B0=\u0090?\u0092$\u00F9\u00D5\u00BC\u00F7O\u00C0b\u00D9NR\u00DB\u00CC\n\u00E0\u00A4\u0092\u00F4\x1C\x01\u0087f6'i\x1F\x18\x1DR\u00E9\u00D3\u00CC\x0E$\u00BD\u0095+\u00BD\x00\u008D!\t\u00AFI\u0092\u00CC\x03\x04\x00i\u009A\u008E\x01_C\u00DC\u0091\u00F4\u00ED\u00BD\x1F\x07\b\u00D24\x1D\u0089\u00E3\u00F8\x16\u0098\u0097t\r\u00E4\u00A5\u00DB\\\u00D2\u00B5\u00995\u0080\u00DB^\u00AF\x17\x07\u00F5z}\x1A\u0098\u0095\u00B4\u00E5\u009C[\u00CF\u00F3|\u00AAV\u00AB]\x00\u0097y\u009EO9\u00E7\u00D6\u0081M`\u00A6\u00DF\u00EFO\u00FF\x00\x1F\u00ED}\u0096\u00BB}\u00F8+\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_bugreport.png", "w12" );
w12_bugreport;
// ==================== |-------------| ====================
// ==================== | w12_feature | ====================
// ==================== |-------------| ====================

var w12_feature = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00A3IDAT(\u0091\u009D\u00CF!\x0E\u00C2P\f\u00C6\u00F1\x7F\u00E1eO\u00A0`H\x12N\u00C1%0s\u00CFq\x02\x04\x1E\u0081\u00E7\x18$\u00A8\u00C9\x19n\u0081\u00E6\x0E\u00C8a&h1\u0088\u0097B\u00B6@U\u00D3\u00AF\u00BF\u00A4\x15\\5M\u00B31\u00B3\x13 \u00C0\u00A5\u00AA\u00AAu\u009E\u008F<P\u00D5\u00E9{\x19\x11)}\u00FE\x01\u00806\u00C3\u00AD\x0F{\u0081\u00EB\u00BF\x03\x11y\u00FC\x04\u00F2%\u0087\u00FF;)\u00F8A\u00D7u\u00B7\x18\u00E3\u00C1\u00CC&!\u0084\u00F3 \x00\n\u00A0\x04\x16fV\f\u0082\x18\u00E3\x1E\u00D8\u0089\b\u00AA\u00BA\x02\u0096C?\u00CC\u00B3~V\u00D7\u00F5\u00B8\x17\u00A8\u00EA\x11\u00B8\x02w3\u00DB\u00A6\u0094\u009Ey\u00FE\x02\u00AA34\x1FQ\u00E27e\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_feature.png", "w12" );
w12_feature;
// ==================== |----------| ====================
// ==================== | w12_help | ====================
// ==================== |----------| ====================

var w12_help = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FDIDAT(\u0091\u008D\u00901J\x04A\x10E_\u00D5\u0088\u00A7\u00D0\u00CCx\x05\u00CD60\u00DAH\x19\u00BA\u00C1\u008B\u0098\u0098\x18\x18\u00AC\u00A8\u00A0\u0089\u0081\x18\u0089`b:\u00DDtf&\u0088\u00D9b\u00B0\x17P\u00CC\x14\x13\u00E3\u00A1\u00CB\u00C0\u0099e\x1CW\u00F4GU\u00FD\u00DF\u00A7\u00BAJ\u00E8\u00A8\u00AA\u00AAuU\u00DD\x07\u0086\u00C0\"\u00F0\u00A8\u00AAGeY\u00DE\u00B6\u008C\u00B4E\baSD\u00AA\x06\u00ECk\u00CF9w\f\u00A0\u00ED\u008B\u00AA\u008E\x1B\u00F8CD\x0EEd\f\u00BC7\u00F6A\ba\x19`\u00A1\r\x14E\u00B1]\u00D7\u00F5\u00A9\u0099\u009D9\u00E7\x1E\u009A\u00A9\u00AF\"r\x0E\x14\u00AA\u00BA\x06\u00BC\u00CC\u00BE\u00D4W\ba(\"\u00D7\u00C0\n\u0080\u0099\r\u00BC\u00F7S\u009D\x07\u00C7\x18OD\u00E4\u00BE\x03_x\u00EF\u00A7\u00DF\u0096\u00EE\u00C0\x1B\u00C0]\u00D3\u00BE\u0099\u00D9\u008E\u00F7\u00FEf\u00B6k?`fK\u009Dv\u00B7\x0B\u00FF\u00AA\u0094\u00D2j\u008Cq0\u00CF\u00FB1!\u00A5\u00E4s\u00CE\x13`\x12c\u00DC\u00FA3\u0090s\x1E\x01\x05_'\x1F\u00FD'pif\u00CF\u00C0\u0093\u0099]\u00F5\u00FDO3\u0095[g\u00AAB\u00A3I\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_help.png", "w12" );
w12_help;
// ==================== |--------------| ====================
// ==================== | w12_settings | ====================
// ==================== |--------------| ====================

var w12_settings = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x03IDAT(\u0091}\u00D0\u00A1N\u00C4@\x10\x06\u00E0\u00FFo\u00AFl5\u0086\u00A7@\u00B0\x1E\u0085C5}\x03Np\u0084\u0080E\u00AF\u00C6@\u00E0\x02\u0082#\x01[\u00D5\u00B4\u00C1\u009C\u00E4\x01:\u00EB\u00F0\b\x14\u00C1P\x10\\\u00E8`z\u00E4\u00B8k\x19\u00B7;\u00DF\u00CC\u009F\f\u00D1Sy\u009Eo\u0093<\x05\u00B0\u00A5\u00AA'I\u0092\\\x00\u00C0\u00A0\x07o\u0092\u009C\x02\u0088\x01\u00DC{\u00EF\u00C7\u00F3^\u00E7\x00\u00C9\u00A3\x16\u00BF\u0088\u00C8\u00D09\u00D7dY\x16\u00C6q|\u00CC\u00AE\u0081\u00A2(\x1ETu\x17\u00C0w\x14E\u00EBu]\x7F\x18c\u00EE\x00$+\t\u00CE\u00B9@U\u00D7\u00DAg8\u009B\u00CD\u00DE\u008C1\u00AF\x006\x00<r\x19[k'\u00AA\u00BA\u00D7\x11\u00FCIr\u0087\u00FFaU\u009D\u0092\u00FCR\u00D5\u00E7\u00A6i\u00C6i\u009A>\r\u00DA\x06\u00CB\u00B2\u00BCZ\u00DA|\u00EB\u00BD\u00DFw\u00CE5\x7F\x0E\u00D2\u00E2kU\x1D-b\x11Y\u00C1\x00\x10Zk/\x01\x1C.\u00FC\u00DD\u0088\u00C8\u00A8\x0B\x03@\x00`\u00F8\x1BGND\u00E4\u00A0\x0F\x03@\u00A0\u00AA\u00E7\x00\u00DEI\u009EUU\u00D5\u00BBy^?WT\x7F\u00BAa\u009Ae\u0093\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_settings.png", "w12" );
w12_settings;
// ==================== |----------| ====================
// ==================== | w12_back | ====================
// ==================== |----------| ====================

var w12_back = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u008EIDAT(\u0091\u008D\u00CF\u00B1\x11\u00C20\f\u0085\u00E1\x1F\u00D5\u00CC@K\u00C1\x0E)\u00E8\u008D\\\u00B2\x1D3\u00C8w9\u008A\f\u00C0\x00t\u00D4\u00EC@'Q\u00A5\b\u00B1\x1DTJ\u00EF\u00BB{\u00DA\u00D1\u0099R\u00CA9\"n\"rM)=\x00\u00A4\x156\u00B3!\"\f8D\u00C4q\u00DEW\u0081\u0099\r\u00C0\b\u00EC\x7Fo+\u00D0\x0B\u00AF\u00C0Vx\x01J)'\u00E0\u00DE\x0B/\u0080\u00BBK\u00ADb\x13\u00E4\u009C\u009F\u00C0\x05\u00F8\u00FC\x05\x00Tu\x02\u00B4\u0087V\x15\u00B6P\u00B5s\x0F5\u009FT\u00D5ID2\u00F0v\u00F7\u00D7\u00BC\u00FF\x02}\u009C3\x19\u00CA?SM\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_back.png", "w12" );
w12_back;
// ==================== |-----------| ====================
// ==================== | w12_close | ====================
// ==================== |-----------| ====================

var w12_close = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x1FIDAT(\u0091m\u0090\u00BDJ\x03Q\x10F\u00CFL,\u008C(\u0088\u00CF\u00E0\x13h)h!b\x11w\u00EF\u00DE\u00C6F\x10R\u00E9KI*\u00EBp\u00B3\x06\u00C5\b\x11\u00B4\x12|\u0082\u00D8Z\u008B\u009A\x1F\"\u00EC\x1D\u009BMX\u00C2~\u00E5\u0099o\x0E\u00CC\b@\b\u00E1\x04\u00E8\x00m\u00E7\u00DC\u0080Jz\u00BD\u00DE\u0091\u0099\u00DD\u008A\u00C8u\u009A\u00A6wR\u0096\x03\u00D0\x04ff\u0096fY\u00F6T\u008A\x0E\u0080{`\x0B\u00F8\x13\u0091s\t!\u008C\u0080\u00DD\u008At*\"\u0089\u0099\u00CD\u0081\x07`\u00B32\u00FBTU\u00BD\x04~*p\u00C3\u00CC\u00F2\u00D2\\-OD\u00E4B\x00\u00BA\u00DD\u00EE~\u00A3\u00D1x4\u00B3\x1D\u00EA3\x01\x12\u00E7\u00DCP\x16$\u00CF\u00F3=3\x1B\u00D4,Mb\u008Cg\u00DE\u00FBg\x00]\u00D0\u00A2(\u00D6\u00CDl\u00AD\u00C6.\"\u00B2\u00E4R\u00F3\u008D\u00BA,\u00BF'!\u0084C\u00A0\u00BFr\u00E0/P\x00\u00DB\u00D5%\u00C0)p\u00B3R\x1E\u009BY+\u00C6x\n|Wx\x13\u00E8\u00A8\u00AA\u00B6\u0081q\t\u00A7@\u009Ae\u00D9\u008B\u00F7\u00FE-\u00C6x\f|\u0095\u00B39p\u00A5I\u0092\u00BC\u00C6\x18\x13\u00E0#\u00C6\u00D8r\u00CE\r\x17J\u00EF\u00FD\u00BB\u00AA\u00B6\u0080\u0091\u00AA\u00A6\u00CE\u00B9\u00FE?q\u00EB}\u00EF\u00EA$\u00F9\u00F7\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_close.png", "w12" );
w12_close;
// ==================== |---------| ====================
// ==================== | w12_pin | ====================
// ==================== |---------| ====================

var w12_pin = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x13IDAT(\u0091\u0085\u008F\u00B1J\u00C3p\x18\u00C4\u00EF\u00FE\t\u0084\u00D2\u0087pt\x17\u00E9C\u0088$iT\u00DC\x1C\u0082\x0E...\u00F5\r\u009C\x15\u009D\\\x14AZ\u0084|)\x18\b\"]\u00DC\x1C\u00FA\x04\u00BE\u0080\u008E.M\u009A\u00E4s\n\u00A66\u00D6\u009B>\u00EE\u00FB\x1D\u00DC\x11+\x14\u00C7\u00F1\u00BA\u00AA\u00A6\u00C6\u00983\u00D7u\x1F\x00\u00C0\u00FC\x05O&\x13\u009B\u00E4\x1D\u00C95U\u00BD\x17\u0091C\x00\u00E0o0M\u00D3n\u0096e\u009B\u00AA\x1A\x028h\u00BC\u0094dh7a\x11\u00B9\u0098\u00CDf\u00C7\x00\x16\u00FCZUUu\x17*Y\u00965\x00\u00F0\u00D2\u00C2~\u0091\u00DC\u00F3}\u00FFj\u00A9R\u0092$\u00CE|>\x1F\x02\u00F0\x1A\u00F6\u00B6\u00E7yO@\u00CB\u00E8<\u00CF\u00B7H\u009E\x03\u00B8\u00AD\u00BD\u00B2,\u00DF\u00EA{! \"\u00BB$\u0087\x006\u00A6\u00D3iH\u00F2\x06\u00C0g\x10\x04\x1FK%\u00C7\u00E3\u00F1N\x1C\u00C7\u00B9\u0088\u009C\u00D4\u009E\u00AARD\u00F6\u009B\x1C\x01 \u008A\u00A2\u009E1\u00E6\u0095\u00E4\u00A9\u00EB\u00BA\u0097-\u00A3\x7F\x02\u00A3\u00D1\u00C8r\x1C\u00E7YU\u00AF}\u00DF\x7F\\\x05\x03\u0080\u00DD\u00E9tzEQ\x1C\u00F5\u00FB\u00FD\u00F7\u00FF`\x00\u00F8\x06Nlb'\u00CF\u00F9\u00A5W\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_pin.png", "w12" );
w12_pin;
// ==================== |------------| ====================
// ==================== | w12_pinned | ====================
// ==================== |------------| ====================

var w12_pinned = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00ADIDAT(\u0091\u008D\u0091\u00BB\r\u00C20\x10\u0086\u00BF\u00B3\u008C\x14\tQd$:\u00AA\u00B8d\x04\u00F6\u00A1\u008A\x18\u0080\u0082\n\u009B\x19\x18\x02\u0089\x1D(\u00A0r\u0084\u008F&AN\x14K\u00F9\u00AB\u00D3\u00FF\u00B8\u0087N\u00C8\u00E0\u00BD\u00DF\x017\u00C0\u00F6T\x07l\u009Ds\u00F7\u00C1c\u00F2\u0080\u0088Hf\x06X\u00A9\u00AA\u00E6\u009EQ\u00C0\x18\u00F3`\u0082\u0094\u00D2\u00B3\x18\u00881~\u0080\u00BCc\u00AA\u00AA\u00AA<\u00C1Z{\x04$\u00D7c\u008C\u00A7\u00D1\u00DAC\x11Bp\u00AAz\u009D\u00AE\x04 \"\u00FB\u00A6i.0>\u00B0\x16\u0091\u00C3\\\x00\u00F8\x16\u00F8\u00FF\u00B46\u0084\u00D0\u00CEiv\u008ET\u00D5u\u00A9\u0099)\t%H\u00FF\u00DD\u00CDB\u00FF\u00DB\x02g\u00A0^\x18x\u00FD\x00x\u00860\u00D4\r`O\u00AE\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_pinned.png", "w12" );
w12_pinned;
// ==================== |-------------| ====================
// ==================== | w12_options | ====================
// ==================== |-------------| ====================

var w12_options = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01$IDAT(\u0091\u0095\u00901J\x03a\x10\u0085\u00BFI~V#\u00EC\x11\u00B2v\u0082\u00C6\x03X(\b\x166j\u00B7\u00D1raC\u00BA\x14+\x1E`\x11\u00BCBX\u00C8O\u0090m\u00B7\x12\u00B5\u0091\u00E0\rl\u008D\u00E0\r\x04\u008B\x10\x02\x1A\u0092\u008C\u00CD&dc\u0095W\r\u00F3\u0086\u0099o\x1E\u00AC)Ym\x04A\u00B0i\u008C\u00B9\x06\u00CA\u00E3\u00F1\u00B8\u009D\u00A6\u00E9\u00F7\u00B2_\u009A\x17\u00ADVk\u00C3\u00F7\u00FD\u00B21\u00A6\x06\u00DC\x01\u00B7\u008E\u00E3\x1C\x02\u00D2l6\u00B7\u00FE]\b\u00C3\u00F0ADv\u0080m\u00A0\u0092\u00B7'\u00C0\x07\u00F03\x18\f\x0E\u00B2,\u009B\x1A\u0080F\u00A3\u00B1\x0B\\,\u00B6\u0088<\u00AB\u00EA\b\u00F0\u0081}\x00\u00D7uO\u0080\u0097\x12\u0080\u00B5\u00B6\u009Fc\x00\u00F4:\u009D\u00CE\u0099\u00B5\u00F6\x12H\x01T\u00F5\u00DE\u00F3\u00BC^\u00E1\x07\x11\u0099\u00AE\x06\u00A0\u00AA\u009A{\x1A\u00C7\u00B1.~\u00C8\u0091\u00DE\u0097f\x1FUu$\"\u00F5\u00F9\u00D2\u00D9lv\u00DA\u00EDv\x0BHO\u00AA\u00FA\t\u00FC\x02\u00E7\"r\x05(\u00D0\x07\u00DE<\u00CF{- \u00B9\u00AE[\u00AFV\u00AB{\"r\u00B4t\u00A9n\u00AD\u00AD9\u008Es\x1C\u00C7\u00F1\u00A4\x10\u00EB\\Q\x14U\u0086\u00C3\u00E1\rP6\u00C6\u00B4\u0093$\u00F9Z\u009DYK\x7F\x10\u00FB^\x18\u0080\u00E9g\u009B\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_options.png", "w12" );
w12_options;
// ==================== |-----------| ====================
// ==================== | w12_check | ====================
// ==================== |-----------| ====================

var w12_check = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00BFIDAT(\u0091\u0095\u0090\u00C1I\u00C4P\x14E\u00CF\u009D7=\x04+\x18lA{\u00C8\u00C7 n\x06\x14\x04;\x18,\u00C2\x16\x04w\u00A2\u00FCExI\x03)c\n\u00B0\u008D|\u009E\u009B0d\x06\x1D\u00E3]\u009F\u00F3\u00B8\u00F7\u00C1?\u00A3%P\u00DB\u00B6\u0097f\u00F6\x1A\x11\u00CF\x7F\n\x13<\x00\x15\u00F0uV\u00E8\u00BAn\x03\f\u00C0\x05P\"\u00E2~\u00ED\u00EEW\u0092^J)OM\u00D3\u00EC\u00E7\u0097'\u00B8\x02FI\u00DB\u0094R^I\u00FA\x04\u00AE\u00CDl\u0098\u00A0\u00D3\x1A\u00A3\u00A4m]\u00D7\x19`%i\x07\u008C@ef\u0083\u00BB\u00DF\u00FC\x06\x1F\u00BE\u00E4\u00EE\u00B7\u0092>\u0080\u00F5lB\x01\x1ERJ\u00EF\u00F3]\u0087\u00D1'\u00D2\u008F\u00F0\u0091\x00\u00D0\u00F7\u00FD]D\u00BCIz\u009C\u00D78\u009B\u009C\u00B3-\x02\u0097\u00E6\x1B\u0085\u0087H\x14\u00BC\u0092~\u00E6\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_check.png", "w12" );
w12_check;
// ==================== |-----------| ====================
// ==================== | w12_reset | ====================
// ==================== |-----------| ====================

var w12_reset = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01'IDAT(\u0091\u008D\u008F\u00BFK\x02a\x1C\u00C6?\u00EF\u00F7\u00DE\u00C3\u00A6\x02\x17q8j/\u0088\u00A0\u00BD$\u00A8\x10IIp\u00A9\u00A1\u00C9\u00EB\x0F\u00E8\u00AF\u00A9\u00B5\u00C9I=r=\u00B21P\x1A\x1CZj\u0089\u009B\u009A\\\u00C2|\u00BBoCG\u0098P\u00F6\u00D9\x1Ex~\u00F0\u0098(\u008A\u00F6\u0092$\u00E9\x07A \u00CE\u00B9\u00A6\u00AA\u009E\x00\x1B\x00\u00C6\u0098\x11pm\u00AD\u00BD,\u0097\u00CB\x13\x00\u00D3\u00E9t\x1Cp\x03\x04\u00C0\x16_|\x00)\u00E0g\u00FA\u00C19W\u00A9\u00D7\u00EB/\x02\bp\u0094\u0099G\"r \"\u00CB\u00C3\u00E1p\u00C9\x18\u00B3\x0B\u00DC\x03\u009B\u00D6\u00DA\u00A8\u00D7\u00EB\u00E5,?yL\u0092$\x0E\u00C3p\u009A\u00E9\u00DBV\u00AB\u00B5\u0093\u00CB\u00E5\u00FA\u00C0\u00B6s\u00AE)\u00C0\u00EBL\u00E0\u00B8P(\x1C\u00CE64\x1A\u008D7c\u00CCE&O\u00C5\u00F7\u00FD\u00C0\u00F3\u00BC\u00BC\u00E7yy\u00DF\u00F7Wj\u00B5Z4\u00B7\u00CA`0\u00B8\x03\u00DEUu\u00DDf\u00EF'\u00F3\u00A6Y\u008A\u00C5\u00A2\x07\x18@\u00E6?\u00FC\u008A\u0088T\u00D24\u00DD7\x00\u00DDn\u00F7JU\u00D7\x16d\u009E\u00AA\u00D5jh\u00E38\u00B6\u00E3\u00F1\u00F8\fX\u00B46U\u00D5s[*\u0095\\\u00BB\u00DD\u00AE\u0088\u00C8\u00EA_nU}6\u00C6\u00E8\x7F/|\u00F3\t'\u00ADc\x01\u008D\u00A7\u00A0@\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_reset.png", "w12" );
w12_reset;
// ==================== |------------| ====================
// ==================== | w12_update | ====================
// ==================== |------------| ====================

var w12_update = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01%IDAT(\u0091\u0095\u0091\u00B1J\x03q\f\u0087\u00BF\u00C4\u0083StP\u00D0gp\u00AE\u008B\u00F8\x02.r-t8p\x16\u009F@\u00C1\"\u008AU'\x17Wuu\x11\u00EAP\u008E\x1B\u00C5]\u0097>\u0082\x0F\u00A0\u008B\u00A2\x16\u00AE\\\u00FEq\u00B9+\u00A5\u00BA\u00F8\u009B\u0092\x1F\u00F9\u0092\u0090\u00C0?%\u00D3F\u009E\u00E7\u00CB!\u0084\x060gfO\u00EDv\u00FB\u00F5O\u00A0\u00DB\u00EDj\u00A3\u00D18\x05\u00F6\u0081\u00D9\u00CA\x1E\u0089\u00C8\u00A5\u00BB\u00AF\u00A8\u00EA]\u0092$\u008FQ\rT\u00C5\u0087\u00C0\u0099\u0088\u00DC\u00BA\u00FB\f\u00B0\u00EB\u00EE\x1D\x003{\x00\u0088\x00\u00FA\u00FD\u00FEb\u00D5\u00F9\u00BC\u00D5j\u009D\u00D6M\u00B2,[\u00AAcU\u00F51\x10E\u00D1|\b\u00E1\u00A4(\u008A\u009B\u00C9}U\u00F5\u00DA\u00CCzU\u00FA\f\u00A0\x00eY~\u00BB\u00FBK\x1C\u00C7\u009By\u009Eo\u00D4@\u0092$\u0083\u00D1h4\x10\u0091\u00B5\u00B2,\x17\u00C6\u0080\u00AAn\u0089\u00C8=\u00D03\u00B3\u00ED\u00C9)q\x1Cw\u0080c3\u00FB\x1C\u00AF4u\u00DEa\u0096e\u00AB\u00AA\x1A\u00CCl\x07\u00D8w\u00F7\u00C34M\u00BF\u00C6\u0080\u00BB\u00BF\u0089\u00C8\x15\u00F0.\"{\u00C0A\b\x01\x11\x19\u008A\u00C8Q\u00B3\u00D9\u00BC\u00F8\u00F5\u0087Z\u00D5\u00E3\u00D6\u0081aQ\x14\u00834M?\u00A6k\u00FE\u00A5\x1FC\u00C1x\u00DC\u00FA\u0087\r\u0095\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_update.png", "w12" );
w12_update;
// ==================== |-----------------| ====================
// ==================== | w12_box_checked | ====================
// ==================== |-----------------| ====================

var w12_box_checked = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00C7IDAT(\u0091\u008D\u00D0=J\u00C4`\x10\u00C6\u00F1\u00FF\u00F3\"\u0093\u00C2\u00EC\u00A6[O`#X\u00D8Z\u00D8\t\u00DB[\u00E4\x00\u00B9\u0084\u00E7\u00F0\"j\u00E7G\u00AD7\u00B0\x10\u00C1\x03\u00D8\u00C94I0\x19\u00AB\u0095\x10^\u00DC<\u00F5o\u0098yFM\u00D3\u00BCI:aA$}\u00A4\u00A5\x18 \"\u008E\u00D3R\u00BC\u00CB\u00DE\x01Iw\u00C0\x15\u00D0\x01\x1C\u00EC\u00F1\u00B7\u0092\u00EA\u00AE\u00EB\u00D6f\u00F6\rlv\x1BB\u00D25\u00F0:\u00C5)\u00A5\u00BAm\u00DB\u00B5\u0099=\x03\u009B\u00E9I_eY\u00DE\u008C\u00E3\u00B8\x05^2\u00F8l\u00DE\u00E1\u00C8\u00DD\u00EF\u00AB\u00AA\u00FA1\u00B3mJ\u00A9\x1E\u0086a5\u00C7\u00F3\u00D2\u0097\u00EE\u00FE\u00E0\u00EE\u00D1\u00F7\u00FD\u00A1\u00A4\u00C79\u00CE\u0095\u00BE(\u008A\u00E2\tX\x01\u00A7\u00B9/\u00E4\u00BEt\u009E\u0083\x7F'E\u00C4\u00FB\x7F`\u009A\u0088\u00F8\u00FC\x05\u0080\u00F3=\u00A5\u0097\u009B\u00CD\u00FD\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_box_checked.png", "w12" );
w12_box_checked;
// ==================== |-------------------| ====================
// ==================== | w12_box_unchecked | ====================
// ==================== |-------------------| ====================

var w12_box_unchecked = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00lIDAT(\u0091\u00ED\u0091\u00B1\r\u00C2@\x10\x04g\u00AD\u00EF\u00C7\u00D4CBr\u00DF\u0087\u0089)\u00E1%RK\u00D0\x0291\u00CD8\u00BCuB\u0086tr\x01L<#\u00AD\u00B4\u008A\u0088;p\x01&j\x12x6\u00E0\f,\u0092\u00DE\u00A5\u009Dy\u0092tk\u00C0$\u00E93\u00C6xUAD$\x07f\u00FC\u00F0\x0F\u008E\u00D0\u0080\u00B4=\u00F7\u00DE\u00B7J\u00FC\x1EG\u00B3\u00BDJ\u00BA\u00DAV\x15H2\u00F0\u00D8\x01\u0082\x05!+\x1F\u00A2 ^\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_box_unchecked.png", "w12" );
w12_box_unchecked;
// ==================== |------------| ====================
// ==================== | w12_folder | ====================
// ==================== |------------| ====================

var w12_folder = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00C7IDAT(\u0091\u00AD\u008E=j\x02a\x14E\u00CF{3\u0089\u00B8\u0094@z\u00DBt\u0081i\u0086Y\u0080k\u00B0s\x05)\u0092\u00DA=\x04\u00AC\u0086\u00D9AH\x11\x10\\@H\u00A7 \u00D66\u00C2\b\u00EF\u00BB)t\u0082\b\u0093\x1F\u00C8i\x1E\\\u00CE}\\\u00F8#V\u00D7\u00F5]\u0096e\u00A3.\u0088\u0088EUU/\u00BD\u0085\u00A6i\u00F6\u00C0\u00F0,;\u0098\u00D9\u00D8\u00DD\u0097]\u00E0\u00EE\u009B\u00A2(Z\u0080\u00FCB\x06\u00B8\u00964\u008F\u0088\u00AF \"\u00DE\u0081\u009B\u00AE\u00D0\u0091\u0080\u00F5\u00E9^ru>I\u00C0\u009B\u0099=H\u00BA53\u00EF\u00DB\u009FR\u00DA\u00E6\u00C0\u00FE$\u00D7\u00C0@R\u009F\u008F\u0099-\x1Cx\u00944\x01\x06\u00BD\u00E6\x11\x01S\u0097\u00F4\x01\u00DC\u00FF \x03<\u0097e\u00F9\u009A\u00BB\u00FB*\u00A5\u00F4\u00F4\u009Dif\u00BB\u00B6mg\u00BFx\u00FA\x0F|\x026hF\u00C5\u00D3$\u00AB\u00BF\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_folder.png", "w12" );
w12_folder;
// ==================== |----------| ====================
// ==================== | w12_file | ====================
// ==================== |----------| ====================

var w12_file = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0085IDAT(\u0091cd```\u00D8\u00B0aC5##c\x0B\x03*\u00D8\u00C2\u00C0\u00C0p\u0081\u0091\u0091\u00F1\u009A\u009F\u009F\u00DFr\u0098 \x13\u0094\x16g\u00C0\x02\u00FE\u00FF\u00FF\u00CF\u00F1\u00FF\u00FF\u00FF\u00C5\x1B7n\u008CA\u00D7\u0080\x0F0300,\u00D8\u00B4i\u0093\x13!\rj\u00CC\u00CC\u00CC\u00EB\u00FE\u00FD\u00FBg\u00F2\u00EF\u00DF?sff\u00E6k\x045\u00FC\u00FB\u00F7\u00EF\x18\x13\x13\u00D3\x19&&\u00A63\u00BF\x7F\u00FFN \u00D6I(`\u00E4j`dd\u00FCHH!##\u00E3\x07\x06\x06\x06\x06\x000a&\x1B\u00F7\x01\x10\u00DE\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_file.png", "w12" );
w12_file;
// ==================== |----------| ====================
// ==================== | w12_next | ====================
// ==================== |----------| ====================

var w12_next = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0084IDAT(\u0091\u008D\u00CD\u00B1\r\u00C20\x10F\u00E1w'*\u0086\u00A0\u00CD\x18(\x0387\x01\u00CB\u00B1\u00C1\x19\u00A4T4,\u0081\u00E8\u0099!\u009De\x1A\u0082\"\u0094\x0B\u00FE\u00AB\u0093\u00F5>Y\u00F8,\u00E7|\u00AC\u00B5\u009E\u0081\u0093\u0099\u00DD\t\u00A6\u008B\u00BB\x03\x0E\u00C0\u00E8\u00EE}\x0B\u0098\u00B7\x07\u00AE\x11Z\x03\u009B(\x02!\u00DA\x023\u00BA\u00B8{\u00D7\n\x00\u00A4\u0094\u00F2\u00EDv\x7F\u00E2IU\x073{\u00B4\u00FC0\u00A9\u00EA\u0090R\u00BA-\x1F#\u00B0\x1AG \u008C\x7F\u00C1\x13x\u0089H\u008Ab\u00807\x0E\u00C1*\x1A<\x1B\u00A2l\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_next.png", "w12" );
w12_next;
// ==================== |----------| ====================
// ==================== | w12_goto | ====================
// ==================== |----------| ====================

var w12_goto = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FBIDAT(\u0091\u0085\u00D0\u00BDJ\u00C4@\x10\u00C0\u00F1\u00FF,\t\"\u00EA\u00B5\u00BE\u0089\"\u0082 6\u00DEB\u00B2y\x0F{\x1B\x11\u00E1\u00B0\u00D1\u00A7\u00F0\x116'\x06Si\u00E3\u0081\x0F\u00E0;\u0098\u00F6\x0EdI\u008A\u00B1\u00D9H\u00A2\u00C79\u00E5\u00CEov>\u0084\rQ\u0096\u00E5\x1E\u00D0\x00\u00DB\u00F1\u00E9S\u00CA\u00B2<\x15\u0091\u0083!T\u00D5\x07\u00E7\\\x13\u008B.\u0081\u00BB>\u0095\x00^U'c\u00AF\u00AF@SU\u00D5\u00A4m\u00DBBD~\u0092\t\u00B0+\"\u00B3<\u00CFo\u0086]\"~\x16\u0091#\u00E0\r\u0098\x03\u00D7f\u00DD\u00ECk\u00F0\u00D49wo\u008C\u00D9\u00FFSP\u00D7\u00F5N\u00D7u\u008F\x11/\"^\x01dY\u00F6\u0095\u00FC\u00C6!\u0084\n8\x01\x16i\u009AN\u00AD\u00B5\u00AB\u00A1\x19u\b!<\u00F5\x188\u00B7\u00D6.\x01\u00BC\u00F7W\u00DE\u00FB\u00C3~\u00E9\u00E1y>\u008C1\u00AA\u00AAy?\x06\u0080\u0088\u00DC\x02)\u00F0>*(\u008A\u00E2b\u00DD\x11\u0086\u0091\u00C4\u009F\u00CF\u00BC\u00F7[\u00FFX\x05HTu.\"ND\u008E7\u00E0%\u00F0\x02\u00F0\rs\u0080j\x1B\u00F2\t\u0097\u00B9\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_goto.png", "w12" );
w12_goto;
// ==================== |-----------------| ====================
// ==================== | w12_eye_dropper | ====================
// ==================== |-----------------| ====================

var w12_eye_dropper = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00F2IDAT(\u0091\u008D\u0090\u00ADN\u00C4P\x10\u0085\u00BFsoy\x03\u0092\u00CA\u00D5\x18\x1Cj\u00DF\u0080\u00A4\u00A1\x04r\u00E5&<\x03\u008A\x00\x02\x12\x16\x03XR\u0087\x02\u00D7\u00E4\u00D6\u00E01($\u008A\u0084\x04\x0B\t\u00BA\x15\u00DD\u00C1\u00B0\u00A4[\u00CA\u00CF\u0091\u00E7|g23\u00E2\x17\x15E\u00B1\u0094\u00A6\u00E9\u00B9\u00A4\t\u00F0\u00EC\u009C\u00DB\u00D1\x1F\u00F0\u008D\u00A4\u00AD\u00B9'\u00E9\u00E1[!\u00C6\u00B8jf\u0095\u00A4W`\u00AD\x17\u00BF%\x03\u00C3/%\u008D\u0080\u00D1@v\u00E5\u00FA\u008E\u00A4]I\u00EF\x03\u00FEu\u00D34{\x0B\u0085\x18\u00E3\u00B1\u0099\u009D\u0099\u00D9f\u00B7df\u00F7u]OB\b\u00AD\u00EB\u00C2\u00C0!0\x06\u00A6\u00DD\u0092\u00A4\u00E5\x10B\x0B\u00E0\x00\u00AA\u00AA:\u00FA\u0084\u00E7\x1A\x03\u00D3\u00D9l\u00B6\x0E\u00DC\u00B5m\u00BB\u00F1\u00B5ZY\u0096+\u00DE\u00FBG`\u00E1cfv\u0090\u00E7\u00F9I\u00FF\x16')\u00FD/\f\u00908\u00E7\u00B6\u00BB,\u00B0\u009F\u00E7\u00F9\u00E9\x10\f\u0090\x00)paf\u00B7\u00DE\u00FB\u0097,\u00CB\u009E~\u0082\x01>\x00G\u00B9W6\x14\u00F7K\u0085\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_eye_dropper.png", "w12" );
w12_eye_dropper;
// ==================== |----------| ====================
// ==================== | w12_menu | ====================
// ==================== |----------| ====================

var w12_menu = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0082IDAT(\u0091\u0095\u008E=\n\x021\x10\u0085g&\x13E\b\u00AC\u008D6{3\u00DB\x04\x0Fce\u00E3\u00E5\u00BC\u0084\b\x11v\\\u00C8\u00B3\x14\u00BB\u00E7W\x7F\u00EFG\u00E4O\u00B4\u00D6z3\u00B3\x03#\x03x\u00BA\u00AA\u009E\x00\u00EC\u00C9\u0081\u00C5\u00CDlN)m\x19\u00BB\u00F7\u00FEv\x11\u0099\"b\u00C7\x04r\u00CE\u008B\u008F1\u00EEfV\u00C8K\u00AB\x03\u00B8\u00AA\u00EA\u0091\u00B1\x01<\u00C8\u00E2/\u00DAZ\u00BB\u0088\u00C8D\u00C9\u00AA/\x17\u00913\x1B\x00\x10\x1E\x11s)eC.\u00AC\u008C\u00F7\u00C3\x07<\u00B8*\"Z\u009E\x14h\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_menu.png", "w12" );
w12_menu;
// ==================== |-----------| ====================
// ==================== | w12_heart | ====================
// ==================== |-----------| ====================

var w12_heart = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x00X\x00\x00\x00X\x01x\u00DAKb\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FFIDAT(\u0091\u0095\u008F\u00BDJ\u00C3`\x14\u0086\u009Fs\x1AH\u0083\u008BtU';z\rR\x05\x07M\u00BF!K\x06\u00F1N\u00EA\x15\u0088\u00B7\u00A1\u00C3\u00B7\u00C4\x10\x10\x1C{\x0F\x16\x05\x11\u00D4\u00E2\u00AE $\u0085$\u009FK\x02\u00A5\u00C6\u00BFgzy\u00DF\u00E7\fGhH\u00D3t\u00A8\u00AAky\u009E\u00DF\u00C6q\\\x01Xk{A\x10\u00EC\u0094e\u00F9\x11E\u00D1#\u0080$I\u00B2\u00AE\u00AA\u0097\u00C0as;\x07N\u009A|\x01l\x02\u0088\u00C8uQ\x14\u00C7\u009E\u00AA\u009E/\u00C9\x00[\u00C0M\u0093\u00FBm\u00E9\u009C;\u00F2}\u00FF\u00CC\x03\u00C6|\u00A5\u00DF\u00D1\x01\u008C\x15\u00A8\u00BF\x19\u00BB\u00A8\u00D59\u0097\u00FC\u00E3\u00E0J\u009Ds\x13`\u00F6\x07y\u00B6X,N5\u008A\u00A2\u00B7\u00AA\u00AA\u00F6E\u00E4\u00EE\x07\u00F9\u00A1,\u00CB\u00838\u008E\u00DF\u00A5m\u00B2,\u00DB\u00A8\u00EBz\nl\u00AF\u00C8/\u009E\u00E7\u00ED\u0086a\u00F8\f\u00A0mk\u008Cyu\u00CE\u00ED\x01OK\u00F2\\DF\u00AD\f \u00AC\u0090\u00A6\u00E9\x10\u0098\x02=U\x1D\x19c\u00EE\x7F\u00FD\u00CEZ;\u00B0\u00D6\x0E\u00BA\u00B6Ob\u00A5U3X1\x7Fs\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_heart.png", "w12" );
w12_heart;
// ==================== |----------| ====================
// ==================== | w12_more | ====================
// ==================== |----------| ====================

var w12_more = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u009CIDAT(\u0091\u009D\u00901\n\u00C2@\x10E\u00DF,\u008B\u00A2\u00C4X\u00A8E\u00AEf\u009D`i\u00EF\x15,,-\u0092\u00A3\u00D9\x0BJ\u00BA\x10X!\u00FBm\u0083D\x12}\u00E5|\u00DE\u00CCg\u00E0Glh\u0098\u00E7\u00F9\u00D5\u00CC6\u0092\u00EEUU\x1D\u00FB\u0099\x1F\u00DCb\u00B6\u0097\u0094\x02\x0F`\u0092\u0090y\u00EF\u00E7]\u00D7\u0085\u00CFlP\x00\u00D6!\u0084E\u008C\u00B1\x05\u00DAQ!\u00C6xs\u00CE-\u009Ds5\u00B0\u009Dr\u00E1\x02\u00EC\u0080\u00FB\u0097|:\u0083o-\u008A\u00E2,)5\u00B3\u00BA,\u00CB\u00D3h%I\x07`%\u00E9\t\u008C\x0B!\u0084,I\u0092Y\u00D34\u00AF\u00FF\u008A\u00F7x\x03\r\x1D67@\u00C0\x1B6\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_more.png", "w12" );
w12_more;
// ==================== |------------| ====================
// ==================== | w12_search | ====================
// ==================== |------------| ====================

var w12_search = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01)IDAT(\u0091\u0085\u0091\u00AFO\x03A\x10\u0085\u00BF\u00B79(\x02\x12\x12\x1C(D%\u00E0\u00EA1\b\u0092\u00F6*\u0090\x15\u0090\x00\u00A6\u00E1\x1F\u00A8&X\x1C\tI% 0\u00DC\u00B5\u0086\u0084\x10\x04\x02P5848~\x04\u00D4]\u00B8\x1D\u00CC^\u00D3\u009C\u00E1\u0099\u009D\u00CC\u00BE/\u00F3vV\x04\u00A5i\u00DA\u0091t`f+@\x0E\u00DC\u009B\u00D9a\u00BB\u00DD~bB\n\u00E6S`?\u00F4\u00BE\u0081\x19`\x1A\u00F8\x05v\u00E28>+\x01\u0097\u00A6i'\u0098\u00DF\u0080\u008DV\u00AB5\u009Fe\u00D9\u009C\u00A4.`@\x7F0\x18,\u0097@\x04tC\u00BD\x1D\u00C7\u00F1M\u00A8s\u00E0$I\u0092%I=3\u00DB\x03z\x00\x0EX\x05~F\u00A3\u00D1-\x15I\u00BA\n\u00E7\u00DA8\x12\u0090\x01\u00B5F\u00A31U\x05\u00BC\u00F7\u00B3\x00f\u00F69\t\u00DC\x03\u00D3y\u009E\u00EFV\x01\u00E7\\\x19\u00F7q\u00FC\x063;\u0092\u00B4)\u00E98I\u0092EIW\u00DE\u00FB\u00D9`\u00DE\u0092\u00F4\u00E1\u009C;\u00AF\u00AE\u00B5\x03\u00F4\u0081Ze\u00C8;\u00B0\x00\u00BC8\u00E7\u00D6\u009B\u00CD\u00E6\u00AB\u00CA\u009B\u00B0\u00BA\u00FD\u00F0q_f\u00F6\x10E\u00D1EQ\x14O@\u00BD\u0084\u00C4?\x1A\x0E\u0087K\u00DE\u00FB;\u00A0nf\u00CF\u00FF\x02%T\x14\u00C5\u00B5\u00A4\u00CB?E\u00CCr9\u00B0B\u00A2h\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_search.png", "w12" );
w12_search;
// ==================== |------------| ====================
// ==================== | w12_parent | ====================
// ==================== |------------| ====================

var w12_parent = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00EEIDAT(\u0091\u0095\u008F1K\u00C4@\x10\u0085\u00DF\u00CC.h\u0095\u00E2\x14\x14[AP\u00AE;\x0BK\u0083}6\x04l\u00FD\t\u0082\u00BD\u00BD\u00BD\u00FE\x04\u00E1\u00AE\u00DB\x10\x16b/\u0096V\"\u00F8\x0F,\x0E\x04+\u00C1\u00C4\u00CC\u00D8\u009C\u00CD\u00BAA\u009Cjx\u00EF}\u00F3\x18\u00E0\u009FC\u00DE\u00FB}c\u00CCt\x18\u0086\u00E7\u00AA\u00AA^\u00C6\u0082M\u00D3\u00EC0\u00F3\u00B6\u00B5\u00D6>\u00A8\u00EA\u00C4\x18\u00F3\x06`3\x0E\u00B6m\u00BB\u00D6u\u00DD\x05\u0080K\x11Q\u00AB\u00AA\u0093\u0095\u00B7\x11\u0087C\b'}\u00DF_\x13\u00D1\u00C1\u008FfS\u00F5u]\u00EF2\u00F3\u0095\u0088\u009C\u00C6\u00DE/ \u0084P\u008A\u00C8\x02\u00C0z\u00EA\x18\u00C7\u0082\u00AA~\x02\x18R\u00E1$P\x14\u00C5\x1D\u0080=U\u00BD\x05\u00A0\x7F\x02\x00\u00E0\u009C{-\u00CB\u00F2\f\u00C01\u0080\u00A7\x18X\u00AE\u00F6e\u00C4\u00C19w\u009Fe\u00D9\u008C\u0088\u00CE\x01\u00BC\x03\u00F8\u00B0Dt\u00A4\u00AA\u0087D\u00F4\u0098j\u00CB\u00F3\u00FC\x0B\u00C0\u008D\u00F7~\u00CE\u00CC[c\u00BF\u008D\u00CE7Q\x7FM\u00B8\u00BA\x06dZ\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_parent.png", "w12" );
w12_parent;
// ==================== |-------------------| ====================
// ==================== | w12_folder_closed | ====================
// ==================== |-------------------| ====================

var w12_folder_closed = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0080IDAT(\u0091c` \x110n\u00DA\u00B4)\u00F6\u00FF\u00FF\u00FF>\f\f\f\u008C\f\f\f\f\u008C\u008C\u008C\u00FF\u00FE\u00FC\u00F9S\x17\x14\x14t\x0B\u00AB\u0086\u008D\x1B7~b``\u00E0E\x13\x7F\u00C6\u00C8\u00C8\x18\u00CC\u00C4\u00C4\u00F4\nY\u00F0\u00DB\u00B7o\u00CFY\x18\x18\x18X\u00B1\x18$\u00F5\u00FF\u00FF\u00FF\u00E3\x7F\u00FF\u00FEE\x11dgg\u00BF\u00CCD\u00A2\x17tI\u00D5\u00C00H5|&A\u00FDg\u0096\u00FF\u00FF\u00FF\x07011\u00D9\x12\u00A3\u00FA\u00DF\u00BF\x7F\u00C7Hu\x11\x03\x00\u00B3\u00AD&C\u00C5\u00F7F\u009C\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_folder_closed.png", "icons" );
w12_folder_closed;
// ==================== |---------| ====================
// ==================== | w12_run | ====================
// ==================== |---------| ====================

var w12_run = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00E4IDAT(\u0091\u008D\u008E=N\u00C3@\x10\u0085\u00DF\u00B3\f\u00AEpmQCI\x05\x17p\u008F<\u00B2\u00DCs\x04\u00A4H \u00AE\u0080\u0094\u008A#\u00A4\u00C4\u00D5\u00EE:tH\u00A4JK\u0087\u00F8I\u0083D\u00E1\x13 \u0090\u00D9\u009DT\u0091,Hb^\u00F9\u00CD|\u00F3\u0086u]\u00EF&I\u00F2H\u0092\u00AAz)\"w\u00D8\x12Zk\x0F\x00\u00BC\u00F5\u00D8\x14\u00C0HD\x16\u00EB\u0084(\u008A\"\u00FEb\u00A7\x00\u009E\u009Cs7\u00D6\u00DA\u00BD?\u00C2\u0086\u00E6\x1DU=\x07\u00F0l\u008C9SU\x0E\t\u00AB\u00EC\u0093\u009C8\u00E7\x1E\u008C1G\x00\u00C0\u00A6i\x0EC\b\u00AF\x03\"\x00|\u0093<\x1Ej\u00E8\u00C7\u00AB\u00EA\u00CF\x7F\u0085{\u00EF\u00FD\u0089\u0088\u00BC\u00C4\x03\u008B\x0B\u0092\u00A3\u00A2(\u00A6+\u00B0I\u00F8\x040N\u00D3\u00F4:\u00CF\u00F3\u00AF\u00FE \x0E!h\x1F\u0090\u00BC\u00ED\u00BA\u00EE\u00A2\u00AA\u00AA\u008Fu\u0097\u00E2\u00B6m\u00DF\u00B3,\u009B\u0093\u008C\u00BD\u00F7WeY\u00CE\u00B6\u00FD\u00B8\x04\u00AD\u0088P\bP\u0083\u00FB\u00B9\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_run.png", "icons" );
w12_run;
// ==================== |----------| ====================
// ==================== | w12_edit | ====================
// ==================== |----------| ====================

var w12_edit = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00BEIDAT(\u0091\u0085\u00CE\u00B1M\u00C4P\x10\u0084\u00E1\x7F\u00DE\x11\u00D1\u00C3\u00C5G\x11\u00D4\u00E0]\x11Q\x00\t\x05\u0080\u0091\b8BKdD\b\n B\u00B6\u009B\u00B8\u0094\u0094\x02\u0088\u00A0\u0087!1\u0092\x05\u00B6\u00DEd;\u00FA\u00B4\u00BB\u00A2\u0092\u00BE\u00EFo%]\u00D9n3\u00F3I\x15|!\u00E9y\x1Am\u00FBr\u00B3\u0086\u0087a\u00B8\x06\u00DE\u0081\x13I[@\u0092N\u00CB\n\u00DE\x03\u009D\u00A47\u00A0\u00B5}\u0098N<\u00FC{i\u00C2w\u00B3\u00EA\u00DB\u00F6\x19\u00B0\u00CB\u00CC\u0097M\x05\x03\x1C\u0097R>\"\u00E2\x11\u00A0T0\u00B6\u00BB\u00A6i\u00BA\u00DFY5\u009C\u00997\u00F3\u00AE\u008C\u00E3\u00D8.a\u00E0\u00FE/\x06(\u00B6\u00CF\u00976G\u00C4~a\t\x05\u00D8\u00D6\u00DE\u0098\u00E7\b0\u00F0\x05|Jz\u008D\u0088n\r\x03\u00FC\x00\u00E1\u00B1T\u00C0\u00EC\u008A\u0080\u00CF\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_edit.png", "icons" );
w12_edit;
// ==================== |---------| ====================
// ==================== | w12_add | ====================
// ==================== |---------| ====================

var w12_add = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00B8IDAT(\u0091\u00BD\u00901\n\u00C2P\x10Dg\u00B2\u00BFW\u00BC\u0080\u0085DKA\x1B/`\x15\u0084\u00DC\u00C6\x03Xy\u009B\x1F\u00D3z\x00A\u00B0\u0096\x14\u0082\u0095\u0095'\b\x7F\u00D7\u00C6h\u00F8\"\u0092\u00C6\u00ADv\u00F6\u00ED\f\u00CB\x12Q\x15E1\x01p \u00A9\"2\u00CB\u00B2\u00EC\u00DA\u00E6Il0\u00B31\u0080\u00BE\u0099\r\u00EA\u00BANc\u00FEa\u00F8U\u009D\r\u00AE,\u00CB4\u00840l\x06$\u00A7\u00AD~\u00E6\u00BD\x7F/;wq\u00AAz$\u00D9\u00FB\x12\u00B8%\u00F9\x12!\u0084[\x02@;\\d\u008E\u00E4\\UG\u00AD3\x16\x006O\u00B96\u00B3S\u00C3D\u00A4b\x1C\u00E1\u00BD_\u0091\u00DC\x01\u0080\u0099-\u00F3<\u00DF\u00B7\u00F9\x1F\u00DE\x1A\x0FD\u00E4\u00AC\u00AAw\x00AD\u00AA\u0098?\x00\rZ:Hg\x16\u008E\u00A1\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_add.png", "icons" );
w12_add;
// ==================== |------------| ====================
// ==================== | w12_remove | ====================
// ==================== |------------| ====================

var w12_remove = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x003IDAT(\u0091c`\x18\u00FA\u0080q\u00E3\u00C6\u008D\u00A9\f\f\f&D\u00AA?\u00CF\u00C2\u00C0\u00C00\u0099\u0081\u0081\u0081\u009DH\r\x7F\u0099\x18\x18\x18\u008E\u0092\u00E0\u00A2c$\u00A8\x1D>\x00\x00\u00BE\u00ED\x06\u00A5?G4\x19\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_remove.png", "icons" );
w12_remove;
// ==================== |----------| ====================
// ==================== | w12_sort | ====================
// ==================== |----------| ====================

var w12_sort = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01 IDAT(\u0091\u008D\u00911K\x03A\x10\u0085\u00BF\x1D.\u00B7Uj#\x16\u0081\u0090NR)Z\u00C76\u00C5\\e\u00A7?\u00C0\u00D2\x1F\x10\u00ACLeaei\x7F\u0082aO\u00EC\x04K\u00AB`\x17\x10\u00C1\u00C6\u00C6\u00C6.\x04C\u0096;\x0B\u00F7`9\x14|\u00F0`gfg\u00E6\u00F1\u00C6\x00\u00E4y\u009E\u00A6i\u00DA\u00CF\u00B2l\x0E0\u009DN\u00F7D\u00A4\u00CB\x0F\u0096\u00AAz\x1F\u00DE\b\u0080\u00B5\u00F6\u00CA\x18\u00F3T\x14\u00C56\u0080\u0088L\u0080<\u00B0 \u0082q\u00CE\u009D\x02\x17!~\x13\u0091}\u00C0z\u00EF;\u00A1y\u00A1\u00AA/\u00F1\u0086>0\x0F\u00F1\u00AC,\u00CB\u0081\u00F7~KDz\u00C0g\u00FC\x19@T\u00F5\x04\u00B8\x01P\u00D5CU}\u00AC%\u0089\u00C8\x11\r$\u00CDD\u0090q\u00EC\u00BD\u00EFXk_\u00FF\u00D5\x10$u\u00D7\u00EBu\u00CF9\x17\u0097\u0096\x7Fm\u0098\x00\x07\u00BF\u0094J\u00E3\u009C\u00BB\x03v\u0080Mc\u00CC\f83\u00C6<\u00D7.5\x06-\x04\u00B8\x066\x00\u00AA\u00AA\u00F2\u00EDv\u00FB\u00A1v)&\u00C11Q\u00D5\u00DB\u00AA\u00AA\u00C6\u00C0{\u0092$\u00D9p8\u00FCj\x1C.'rL\x00T\u00F5|\u00B5Z\rF\u00A3\u00D1G\u00EDRY\u0096\u00BB1[\u00AD\u00D6%\u00C07\u0093eo,\u00FFz&S\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_sort.png", "icons" );
w12_sort;
// ==================== |-------------| ====================
// ==================== | w12_sort_up | ====================
// ==================== |-------------| ====================

var w12_sort_up = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00F5IDAT(\u0091\u008D\u0090\u00B1J\x041\x14E\u00CF<w&\u00BF\u00B0`\u00B1\u00B0l'Zjo#\u008CEf>@?\u00C2\x0FPa\u008B\u00AD,\u00AC\u00FC\u00874\u00C3\u009B\u00DE\u00DABl\u00B7Y\x10\u00BFA\x16\u009B\u00C4`\u0093\u00C08\u00E8\u00EA\u00ADr_r\u00B9\u00E7\u00A5\x00p\u00CEUUU-\u009A\u00A6Y\x03t]w,\"\u00B3\x18\u00E3s\u00DB\u00B6o\f$\x00\u00C6\u0098\u0087\u00A2(\u009E\u00FA\u00BE?\x00\x10\u0091\x15\u00E0D\u00E4\u0082\u0091\nU\u00BD\x02\u00EE\u0092\x7F\x15\u0091\x13\u00C0\u0084\x10\u00A6\u00C6\u0098M]\u00D7\u00EF\u00E3\u0086\x05\u00B0N\u00FE%\u00C6x\x18B\u00D8\x17\u0091\u00B9\u00F7\u00FELU\u00CF\u00BF5\x00\u00A8\u00EA-pc\u00AD\u00CD\u00FE\x118Mo\u00A2\u00B5v/\x07&c\u00C6\u00B4\u00C3e\ba\u009A\u00CE\u00DB\u00E1\u00DD\u008F\u0081\u00844\u00CB^U\u008F\u00F2\u008F\u00FD\u00D6\u00B0\x1A \u00E5\u00D95\u00B0\u00FC\x13)\u00CB\x18\u00B3\u00F97\x12\u0080\u00F7~\u00AE\u00AA\x1F9\u00F0\t\u00C4]HIq\x02P\u0096\u00E5\u00BD\u00F7\u00DE\u00EDBJ\u00F3\u00ED\x17F{]\u009A\u00992\u00D4f\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_sort_up.png", "icons" );
w12_sort_up;
// ==================== |---------------| ====================
// ==================== | w12_sort_down | ====================
// ==================== |---------------| ====================

var w12_sort_down = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00EFIDAT(\u0091\u008D\u00D0\u00B1J\u00C4@\x10\u0080\u00E1\x7F\u00C7\r\u00A9R+X\u0088\u0096\u0082\u0095b\x1F\u00DB\x14\u00E3\x0Bx\u008Fr\x1C\bZ\u00DF\x13\u00D8[\x18\u00B2b\u00E7\x1B\u00E8\x0B\u0088\u008D`ccw\x1C\x06\u0096\x1D\u009B\u00DC\u00E1%9p\u00ABe\u00D8\x7F\u00F9\x18\x07\x10B84\u00B3cU}\x02\u00A8\u00EB\u00FA\\D\x0E\x18\u009E\u00A5\x070\u00B3\t0\x03\x1C\u0080\u0088\u00DC\x02\x17#A\u00F2\u00DD\u00C5\u00FD\u009D\u008A\u00C8$\u00C6\u00B8\u00D7\x7F-\"\x0B\u00DF\x1F\x02\u00C4\x18\u00F7\u00FB\u00A4\u0094\u00D2\u008B\u00AA~\u008C\x06c$\x11\u0099\x02\u00D7\u00DB\u0082\x01)\u00CF\u00F3w\u0080\u00FF\u0090\u0096\u00AB\u00EDm\rz\u00A4\x04\u00EC\u00AC\u0083\u00A6i\x1E\u0081S\u0080\x10\u00C2+0s\u00CE\u00ADI\"\u00B2\u00D8\u00F8\f\u00B8\x03v\x01\u00CC,\x16E\u00F1\u00DC\u0091\u008E\u0080oU}\u00DB\bT\u00F5\u00C1\u00CC\u00A6\u00C0\u00A7\u00F7\u00FE\u00B2,\u00CB\u009F\u008Et/\"W\x03.\u0080\u00AA\u00DE\u00B4m{RU\u00D5\u00D7jK)\u00A5\u00B3,\u00CB\u00E6\u00FD\u00E0\x17\u00D8\u00F2U\u00A0\u00FB \u00A6,\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_sort_down.png", "icons" );
w12_sort_down;
// normal 16px
// ==================== |--------------| ====================
// ==================== | w16_language | ====================
// ==================== |--------------| ====================

var w16_language = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x11IDAT8\u008D\u00ED\u0090\u00BDJ\u00C4`\x10E\u00CF|\u009B\u00FD@\u008B\u00B5[{\u00D1\u00DA\x05\u00C1\u009F\u00CAJ\x0BKA\u00EC,\x04\x1FA\u00D6\u00C6G\u00B0\x12}\x02m\u0082\u00A0\u00C1\u00CA\x07\x10\u00844vZ\u00BA,\"VQ\x0BCB\u00C8\u00B5\u0089KX\u00A2/\u00A0S\u00DE;s\u00EEe\u00E0\x7F,\u008A\u00A2W\u00A0\u00FB\u0083\x7F\x02L\x00\u00BBM\u00A6\u00A4\u0081\u00AB\x1D\x7F\x02G\u00C0\u00F0\u0097\u00C0\x14\u00B8\x18\u00A5\u009Bu]\u00CD\u00BC\u00CC\u00B2\u00EC\x108n8,\u00CDl\u00C39\u00B7\u009Ee\u00D9\u008E\u00A45\u00A0\x0FP\x07\u0084\u00DE\u00FB\u00BD \bB@c\x00'\u00A9/i\u00CB{\x7F\u009A\u00E7\u00F9-\u00B0Y\x07\u00BC\u00B5\u00DB\u00ED\x1B\u00E7\u00DCs\x1C\u00C7CIw\r-V\u00CB\u00B2\u00BC6\u00B3\x03\u00EF\u00FD>\u00B0\x04\x10T\u00CF\u00B8*\u008AbV\u00D2v\u00AF\u00D7K\u009Ds\u00A1\u00A4\u00951\u00C0{\u00AB\u00D5\x1AH\u009A\x04\x1E\u00BE\u00C5\u00A0z\u00C6\u00B2\u00A4s`\x1EX\u0094\u00F4\u00D2\u00D0`J\u00D2\u0099\u00A4\x053\u00BB\u00974\x02<\x02\u00D3\u00D5Rbf\x1D\u00A0\x03$\u0092R3\x13\u0090TM\u00E7\u0080\x0FI3\u0095\u00F6\u00D4\x10\u00F4\u00E7\u00E6\x0B\u009C7p\u0085\x04}\f\u00FE\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_language.png", "w16" );
w16_language;
// ==================== |-------------------| ====================
// ==================== | w16_settings_file | ====================
// ==================== |-------------------| ====================

var w16_settings_file = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01JIDAT8\u008D\u0095\u0092=K\x03A\x10\u0086\u009F9\x0E\x16s\u0095]\u00B4\x10,\u00B4\u00B5\u00B1\x16R\tB\u00B2]\u008AT6\"VZ\u00F8'l\x15A\u00FC\t\u0081\u00C0\r1\u00B6~T\u00B6\u0096b\nA\u00A2\u0085\u0082\u0090\"p\u00C7\u0085\u00B5HN.\u00F1\u00F2\u00F5V\u00B3\u00B3\u00EF<\u00CC\f#\x00\u00F5z}\u00C9\x18\u00D3\x06V\u00F9\u00AF\u009F(\u008A\u00D6\u008D1\x0F\u00C0\u009E\u00B5\u00F6#\u00FB\u00E9\x01\x18c\u0096'\x14g\u00B5\x05\u00DC\u00AB\u00EA\u0088\u00CF\u009BQ4\u00AE\r\u00E0.\x0BY\x14\x00\u00B0\t\u0084\u00E9\u00C3\u009F`ze0R\x00\x04\u00C6\u0098\u00C0Z+yF\x01\x18\u00B6\u00D4\x19\u00E6\x12\x11\u00D9\x15\u0091\u00A7~\u00BF\x7F)\"\u00FB9u=km\u00907\u00C23\u00E0;\u00E7\u009A\u00C0Z\x1C\u00C7\u0087\u00C0\u00F7\u00B4yF\x00\u00CE\u00B9\x1Ap\u00E5\u009C\u00FBr\u00CEE\u00D5j5\x06\u00DE\u00A6\x01\u00C6wP\u00B2\u00D6\x1E\u008D\u00E5\x1E\u0081\u00ED\u00B9:\x10\u00913U=h\u00B5Z\u00C5F\u00A3\u00B1\x02P\u00A9TN\u009Ds\x17s\x01\x18l\u00FD:I\u0092O\u00DF\u00F7\u00DB\u00AAZ\x12\x11g\u00AD=\x16\u0091\u00F3y\x00Y\x15\u0080\u009B\x14R.\u0097O\u00F2 \u00B3\x0E\u00A9\x004Uu'\u0085\x00/Y\u00C3\u00A4C\u00CA*\x00nU\u00B5\x16\u0086a\u00C7\u00F3\u00BC\u00E2\u00A2\u0080\x14\u00A2\u009E\u00F7\u00D7p/\r<\u0080(\u008A\u00BA@wN\x18\u00C0{\x1A\u00FC\x02\x17\x16i\u0080-\u00A9W\u00C4\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_settings_file.png", "w16" );
w16_settings_file;
// ==================== |----------| ====================
// ==================== | w16_user | ====================
// ==================== |----------| ====================

var w16_user = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x1BIDAT8\u008D\u009D\u0092?K\u00C3@\x18\u0087\u009F\u00F7\u0092\u008F\u00D0\x16\u00C1Epw\u00D5\u008E.\u008A\u00C14$\u009FE\x10\x1CT\x1C\u00A4\u00F4\u00C3\x044\u0090A\x14\x1C\u00DD\u00C4\u00D5\u00A9\u008B\u00A0\x16\x04\u0087\x0E\u00CD\u009F;\x07\u00DB\x1A\u00D2\u00D4\u00B4\u00F9\u00C1-\u00EF{\u00CFs\u00C7\u00DD+T$\u008A\u00A2\u0096\u00D6\u00BA\x0F\x1C\x02\"\"w\u00B6m\u009F:\u008E3*\u00EF\u0095r!\u008E\u00E3v\u009A\u00A6\u00CF\u00C0f\u00A9\u00F5\u00AE\u00B5\u00EE\u00FA\u00BE?,\x16UY\u0090$\u00C9\u00A0\x02\x06\u00D8PJ]\u0097\u008B\x0B\x02\x119\u00AA\u0080g9\u00A8\x15\x00\u00D6?\u0082\u0085^\u0095\u00E0~\x19m\u008Cy\u00A8\x15(\u00A5ND\u00E4\u00AB\u0082\u00FF\u00D6Z\u009F\u00D5\n\\\u00D7}\u00CB\u00B2\u00AC\x0B\u00DC\x00\u00E3\u00E9\u00BAUJ\u00ED\x05A\u00F0\u00BA\u00ECv\u008D3\u009F\u00830\f;\u00B6m_\x19cz@\u00C7\x18\u00F3(\"/\u0080\x01v\u0080}`\x04D\u00C0\u00B9\u00E7y\x1Fs\u00C1t\u00F2\u009E\u0080\u00ED\x15\x0F\x1E\u00E6y\u00BE\x1B\x04\u00C1\u00A7\x02\u00D0Z_\u00AC\x01\x03lY\u0096u\t\x7F\u008Fx\u00BC\x06<K\u00AF(h5\x10\u00B4\u008B\u0082I\x03\u00C1\u00A4(\x18\u00F0\u00FB\u00DF\u00ABf,\"}\u0080\x1Fd3T}\u0091\u009Et \x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_user.png", "w16" );
w16_user;
// ==================== |---------| ====================
// ==================== | w16_bug | ====================
// ==================== |---------| ====================

var w16_bug = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\u009BIDAT8\u008D\u008D\u0092\u00B1\u008B\x13Q\x10\u00C6\x7F\u00F3\u00DE.\u00C6\u00E6\u00AC\x14\u00AC\x15,$J\"\u00D8\u00E8\u00A1x\u00DD\u00EE\u00C5\u0084-\u00F2Oha#X\u00A6\u00F4/\u00D0\u00BF\"\u0081\u0087\u00F2\x04\u00D1\u00A0\u00DC]\u00A5\u008D\u00DC\x156\u0087\u00D8\x1D\u008A\u00CD\u0081hn_\u00DE\u00D8\u00E4\u0096\u00B0\u00EC\u00E1~\u00D503\u00DF\u00F7\u00CD\f#4\u00C0{\u00BFQ\u0096\u00E5s\u00E0!`E\u00E4M\b\u00E1iQ\x14\u00BF\u00EA\u00BDROL&\x13\u00D3\u00EB\u00F5\u00E6\u00C0\u00BDZ\u00E9\u00CBb\u00B1\u00B8=\x1E\u008FO\u00D6\u0093\u00A6.\u00D0\u00EF\u00F7\u00EF7\u0090\x01nv:\u009DA\u00E3\x04\u00CE\u00B9\x1D\x119\x1FB\u00C8\u00D24\u00BD\u00B2\\.\u0087M\u00AB\x19c\u00DE\u0086\x10\x0E\u0092$\u00F1\u00AA\u00FAg8\x1Cn&\u00AB\u00DA9U\u00BDe\u00AD\u009D\u00C7\x18\u00B7F\u00A3\u00D1\u00B3&\u0081\u00D9lv\u00C9Z;W\u00D5\u00EB\u00C0g\u0080\x04 M\u00D3\u00BC,\u00CB\u00F7@\x178r\u00CE5\u00F1\u00D7\u00F15I\u0092\x01\u00ACn\u0090e\u00D9O\x11y\u00F2?\u00D6\u00DA*\u008F\u00F3<?\u00AA\x04VX\u00D6\x1BU5\x17\u0091\u00AC\u009E\x0F!T\u00BD\u00E2\u009C\u00DB\x01\u00EE\u009Ea\u00F6@D\u00A2\u00AA~8\u00A3\u00BEgD$\u00B4\x1D\u00BD\x01\u00A1z$\u00E7\u00DC\x1D`\u00B7\u00CD\x04\u00C6\u0098\u00CD\u00C1`\u00B0\x0Bk7\b!|\x07\u00B4\u00A5\u00F3\u00B7J\u00EC4\x10\u0091\x13\u00E0\u00B8\x05\u00F98\u00C6X\u00ADm\x00\u00BC\u00F7\x17\u00AD\u00B5\u00EF\u0080\x0B-\x046\u0080\u008F\u00D3\u00E9\u00F4r%P\u0096\u00A5\x07\u00BA\u00AAz\u00A0\u00AA7T\u00F5\x05p(\"1\u00C6\x18\u0081C\u00E0\u00A5\u00B5\u00B6\x0B\u00EC\x03\u00D7\u00D24}\x05\u00ABO\x04~\x03\u009Fb\u008C\u00DBEQ\u00FC\x00\x1E\u00D5\\\u00AF\u009E\x06\u00DE\u00FB\u00AD\x10\u00C2kU\u00FD\x0B\u00F0\x0Fk\u009B\u00A0\x10\u009B\u00CE\u00DB\u00A2\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_bug.png", "w16" );
w16_bug;
// ==================== |------------| ====================
// ==================== | w16_rookie | ====================
// ==================== |------------| ====================

var w16_rookie = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00F5IDAT8\u008D\u00DD\u00921N\x031\x10E\u00FF\u008C\u00B1\u00BD\x12\x1D\x14\u00D4Pp\x05n@\u00B4\u00ABu\u00EB\u00823\u00E4N\u00D0\u0081\\lOI.\u00C0\x01\u0090(\"%\r\x01\u00CA\u0095!\u008CiR$Y\u009Bl\u00CD/\u00FF\u00BC\u00F9\x1A\u00CD\f\u00A1\u00A0\u00AE\u00EBN\u0095R\u00CF\x0043_9\u00E7\u00E69\u008EK\x01UU1\x11\x1D\x03\u00B0\x00~J\\1\u00A0\u00AE\u00EB\u0095\u0088\u00CCRJOm\u00DB.K\x1C\u00E5\u00CC\x10\u00C2\u00891\u00E6\u009E\u0088\u00AE7\u00D6c\u008C\u00F1\u00C6{\u00FF1j\x02c\u00CCt\u00AB\x19\x00&\u00C6\u0098i\u008E=*L\u00F6\x0E\u00E03\u00E3\u008D\x0B\x10\u0091\x07\u00AD\u00F5BD4\x000\u00F3w\u00DF\u00F7\u00B3\x1C;\u00D8A\bAYk_\x00\u009C\u00EF\u0095^c\u008C\u0097\u00DE\u00FB\u009D\u008B\fv`\u00AD=\u00CB4\x03\u00C0\u00C5\u00A6\u00B6\u00A3A\x003g/S\u00AA\x15\u00FF`\u00AC\u00FEc\u0080R\u00EA\u00EB\x0F>\x1E\fh\u009A\u00E6-\u00A5t\x07`\u00BDe\u00AF\u0089\u00E8\u00D69\u00B7\u00DA\u00E7\x7F\x01\u008D\u00CA@c^Wf\u00EE\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_rookie.png", "w16" );
w16_rookie;
// ==================== |--------------| ====================
// ==================== | w16_standard | ====================
// ==================== |--------------| ====================

var w16_standard = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x14IDAT8\u008D\u00AD\u0090\u00B1J\u00C4P\x10E\u00EF\r/E\x14\x11\u00EB\u00E0G\u00F8\x07j\u00A3\u00A4H\u00D2+X\u00A6\x10\x11\u00B5\u00B1L-\b\x16\"\x04\u00ACm\u0084%oI\u00E1\x0Fh\x15\u00F4\x03,l\u0084\u00D4\u00E2\u0082\x04\u0097\\\x1Bw\u00D9,\u00C8n\u00D4\u00A9f\x06\u00CE\u0099\u00CB\x00\x7F,\u008E\u009A,\u00CB\\\u00DF\u00F7Wg\x01M\u00D3\u00A8\u00AA\u00AA\u00D7$I>[\x02k\u00ED9\u0080\u00E39\x0F\u00D7\x00\u00AE]\u00D7=1\u00E3(\u00E4\u00A2\u00A4Y\u00A0$\u009D\x01X#\u00B9?\x1C\x0E\u00DF\u00CD,bZ\x10\u00C7\u00F1\u00A9$Zk\u00EF\x01\u00EC8\x1D\x05\u00A3\u00B4\"\u00F9\x01`\u00B9k\x02\u00E6y\u00BE\u00E58\u00CE\u00BA\u00A4M\u00927\u009D\x05$\u00EF\u00BE\x7F\u00F5@\u00F2p,\u00904\u0098C0\x00\u00B0\x07\u00E0%\u008A\u00A2'\x00\u0098\x14\u00F4H\x1E\x01\u00F8\u00F1/$o\u00C30\u00EC\u00B5v\u0093\u0083\u00B5v\x03\u00C0.\u0080\u00A5)V$\x1F\u008D1\x17A\x10\u00D4-A\u00BF\u00DF?\x00\u00B00G\u00FC\u00B6QR]\u00D7WFR\x00`\u00BB\u00AB\x00\u00C0\u00B3\u00E7y\u0097\x04\u0080\u00A2(V\u00BA\u00D2eY\u00BE\u00A5i\u00DA\u00FC\u00E2\u00F0?\u00D7\x17=\x05_\u00E7\u00F7_.`\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_standard.png", "w16" );
w16_standard;
// ==================== |------------| ====================
// ==================== | w16_expert | ====================
// ==================== |------------| ====================

var w16_expert = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07`\x00\x00\x07`\x01G\u0084ZR\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x00IDAT8\u008D\u00C5\u0092\u00B1J\u00C4@\x14E\u00CF\x0B\u008B\u0084\u00FD\b;;k\u00F1\x03,l\x02CZ+\x0B+\x0B+E\u00D1\u00D2Fp\u00F1\x07\u00FC\x02\u00AB$*\u00C8\u00B6\u0082\u00B0`)h\u00A1\u009D\u009D\u00F5J\u009A\u00CC\u00B5I`v@6\u00B1\u00F1V\u00EF\u00DD\u00CB=\u00BC\u0081\u00B1\u00AA\u00AAf\u00926X\u00AEoI\u00DB\u00CE\u00B9\u00C7\u00D0Lz\u0096\x01\u00C6f\u00B6\x1E\u009BV\u0096\u00A5z\x02\x00\u00DE\u0080O\u00E0+I\u0092\u009B,\u00CB\u008A\x05\u0080\u00A4\u00A9\u0099%\u00C0\x160\x07\u00AE\u0081\u0083\u00DFhf\u00B6\u009FD\u00C6-p\u00D7\u00AE\u00EFi\u009A\u009E\u0086\u00B9\u00A4\u00A9\u00A4\x0B\u00E0\x19\u00C0{\x7F\u00B4\x00X&3+\u009Cs\u00C7\u00C0\u00A4\u00DDW\x07\x01\u0082K\u00BAg\u00DB\u009F\x00\u00A1\u00FE\x1D\u00A0\u00D1\u00C0\u00C2JQ\x14\u00BBfv\u00D2\u00EE\x1FC\x01\u0097f\u00D6u\u00BC\u00A4\u00B3\x18\u00B0\x03X;\u00AF\u00D5u}\x15\u00E5#@\u00C0\u0083\u00A4s\u00E7\u00DCS\f\u00D8\f\u00E61\u00B0\x17\u00E5\u00F7M\u00D3\x1C\u00E6y\u00FE\u00DA\x19C?R\x15\u0096;\u00C0\u00ACg\x7F\u00EE\u00BD\x7F\u0089\u00CD\x1FA\x0EY\u0090\u00AEi\u0085\u009B\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_expert.png", "w16" );
w16_expert;
// ==================== |-----------------| ====================
// ==================== | w16_placeholder | ====================
// ==================== |-----------------| ====================

var w16_placeholder = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x017IDAT8\u008D\u0095\u0093AN\x021\x14\u0086\u00BF\u00D7\u00E2\x19p\b\t;0\u009C\u00C0\u009D\u008A\x1E\u00C0\x13hf`H\u00E0B\u00930q\u00B8\u0088\u00A2\u00EE<\u0081\x11v$\x06\u00C2!\u00A6u\u00D3!\u00A5 \u0084\u00B7j\u00DA\u00FE_\u00FF\u00FF\u00BDT\u00FA\u00FD\u00FE\u00A3\u0088d\u00C0%\u00E7\u00D5\x1A\x18\u00D5\x02\u00F1/\u00B09!\u00AC\x03M \x02\u00B2Z\u00F0\u00F2EY\u0096O\u00D3\u00E9\u00F4\u00FB\u00902M\u00D3\u00B6\u00B5\u00F6\u00DD\u00DB\u008A\u0094[,\u009D\u00A5\u00BA\u00D6\u00FA5I\u0092N(\x1E\x0E\u0087W\u00D6\u00DA\x0F\u00A0\u00E1\u00EE.\x01*\u00C0ZDn\u0081\x15\x10)\u00A5>\u00E38\u00EE\u00FA/\x1Bc\u00DE\u009C\u00EDMY\u0096\x0F\x0E\u00B2\x05\u0090\u00E7\u00F9BD\u00EE\x1C\u00A4\u00AE\u00B5\u009E\u00C5q\u00DC\u00F5l7\u009C\u00B8\u00E7G\u00DC\x02*\u00881\u00A6\u00E7\u00C7\u00F1m\x1Bcn\u00C2\u00FE\u00EC\x00\x00\u008A\u00A2\u0098\u00FBq|\u00DBEQ\u00CC\u00C3\u00FB{\u0080sk\x0F\u0090$I'\u00E8\u00F6\u00D1\u00E9\u00EC\x00\u00D24m+\u00A5f\u00BE\u00EDc\u00D3\x01\u0090\u00C1``\u0081/\x11y\u00FE\u00AF\u00DB\u0087&\u00A1\u00B5~\x01\u00AE+\x07\u00D1\u00B1n\u00E7y\u00BEPJ\u00DD\u00FBq\u009C\u00CBm\u0084\x16'\u00BA=\u0099L~\u0082\u00E9\u00B4\u00AA\b\u00D5\x06\u009C\u00F7\u0099\x00V5`\x04d\x0E\u00D2\u00F4\x0EO\u00D5\x1A\x18\u00FF\x01 \x03\u00A8.\u00A9X\u00C8\t\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_placeholder.png", "w16" );
w16_placeholder;
// ==================== |--------------| ====================
// ==================== | w16_download | ====================
// ==================== |--------------| ====================

var w16_download = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x0FIDAT8\u008D\u00DD\u0092=N\u00C30\x18@\u009FqEB\x15%\x0B\u00E2\x0E\u0094\x03\u00D0\u00D5\u00EA\x16\t\u0085\b)\x03;\u00A7\u00E2\x06\x11K\x12\x162\u00B1 \u00B8\x00\u00D9\u00B8\x00b.5\u0092m\u0096\x04\x15\u0093\u00A2\u00B0\u00F2-\u00DF\u008F\u00BE\u00F7lK\x16\u00EC\u0088\u00AA\u00AA\u009E\u0081E\u00DFvY\u0096\u009D\u008C\u00ED\u00ED\u00ED\x12l\u00C1~=Y0)\u00FE\u0081@\fE\u00D34+km;Aj\u00AD\u00B5\u00AB<\u00CF\u00EF\u00BF\u00DD \u008A\u00A2\x07\u00A0\u009Dph\x1B\x04\u00C1\u00E3\u00D0|\t\u0094R\x1B\u00ADu\x06\u00DC\u00FE\x02\u00DF\u00C5q\u009C\u00A7i\u00AA\x7F\b\x00\u008A\u00A2\u00F8\u00D0Z_\b!\x1A\u009Ft\u00CE\u00B5q\x1C\u009F+\u00A56\u00DBs\u00E1/\x02\u0094e\u00B9\x1F\u0086\u00E1\u008Ds\u00EEl\u0080\u0093$\u00C9|\x18@\u00D4u\u00DD9\u00E7\u008E\u00BD\u00F9\u00931&\u0093R^\x03\x18c\u00AE\u00A4\u0094\x15\u00B0\u00F4\u00F6\u00BA\u00D9\b\f\u00B0\u0094R\u00D6R\u00CA\u00CB\u00BE\x1F\u0083\x01\x16\u00B3\u00B1'\u00F4qj\u008Cy\u00F1f\u00EF\u00C0\u00C1V\u00FE\u00D3GZk\u00AD\u008F\u0080\u00B7>\u00AF\x07A7Q0\x0F\u0082\u00E0\x158\u00EC\u00F3\x1C\u00E8>\x01\u00D4u]l6\u00FC\u00EA\u00B8\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_download.png", "w16" );
w16_download;
// ==================== |----------| ====================
// ==================== | w16_list | ====================
// ==================== |----------| ====================

var w16_list = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01NIDAT8\u008D\u00AD\u0092\u00BDJ\x03Q\x10\u0085\u00BF\u00B9\u00DC]\x05+\u00FF@l\x04Q\x1B\u00F5\x01\x04kAp\t\u00C1*h\u0099G\b\u00A6\u00B1\x13\u00C1\u00C62/`%\u00C1\u00E2&&El\u00D2\u00D9\u00F8\x12\u0082\u0088X\x05\u0092&\u00D9\u00DD\u00BBc\u0093\u0088V\u00BB\u00A0\u00A7\x1A\u00CEp\u00E6\u009C\x19\x06\u00FE\b\u00E9t:{\u00DE\u00FBk`\u009CeY\u00BD\\.\u00BFv\u00BB\u00DD\u008D8\u008EW\u00F2\u00C4A\x10\f\u00AC\u00F7\u00FE\x1E\u00D8\x050\u00C6,\x02Gi\u009A>\x1Bc\u00D6\u00F3\x06x\u00EF\u00C7\x06X\u00FB\u00C1\u00CD\u00EA\u00B9\u0082\x1B\u00CC[\x11\u00A9\u00ABj\x03H\u0080K\x00\x11\u00A9gY\u00B6\u009D\u00A76\u00C6\u00BC\x03\u00D0l6\u0097z\u00BD\u00DEBA\u00D7_\x10\u00E7\\UD\x1A@b\u008C9\u008F\u00A2\u00C89\u00E7\u00AA\u00C0V\u0091\x04VDn\u0080\x10\b\u00BD\u00F7W\u0080\u009Br\u00CBy\x03T\x15\u00A3\u00AA\x1F\u00DFqDf\u00F5\u00A4\u00E0\x06ck\u00AD\u00AD\u00CC\u00FE\u00C0Z{1\u008Dv\u0090\u00A6\u00E9j\u009E:\b\u0082\u0081\u00F4\u00FB};\x1A\u008DJ\u00C0$\u008A\u00A2\u00AE\u0088hAw\x00\u00ECp8\u00BC\x03*\x00\u00EDv\u00FB\x16\u00A8\u00B5Z-\x07\u00EC\x17\u00D0\u00BFY\u00E0\u00E4\x07\x11\x015\u00E0\u0090\x02G\x046\u00AD\u00AA>\u0089\u00C8)\u0080\u00AA\u00F6\u00A6\u008D\x17`'O\u00AD\u00AA\u009F6\f\u00C3\u00B3$I\x1EUu\x1C\u00C7\u00F1\x03@\u00A9T:.\u00E0\u00FE?\u00F8\x023\u009D}\u00CA\u0097\u009C\u00BE\u00A0\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_list.png", "w16" );
w16_list;
// ==================== |-------------------| ====================
// ==================== | w16_language_file | ====================
// ==================== |-------------------| ====================

var w16_language_file = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\u00AFIDAT8\u008D\u008D\u0093\u00BF\u008B\x13A\x1C\u00C5\u00DF\u00F7\u009B%\u00B9\u00B5H\x1A\x11\u009B\x13\x7F\x1D\u008A\u008D\u00E4\u00AE\x11\u00F4\bil\u00CE\u00CCv\u00F1/\u00B0\u00B0VKq\u00AD\u00AE\x10\x15\x1B\u00FD\x03\u00EC<%\u00CC\u00AE\u008D\u00A0\x06\x0B\x11\u00AC-\x14\u00C1\x1F\u00E0\u00C1q)\u0084\u0080\u00C9\u00C6]\u00E6Y\x18a]\u00C7\u00E8\u00EBf\u00DE\u00F7}f\u00DE\u00C0\b\x00\u00C4q\u00AC\u00EDv\u00FB-\u0080\x15xd\u008C\u00D1$I\u00DE\u0088\u00C89c\u00CC\u00C7\u00B2\u00A7\x00\u00D0\u00E9t\u00EA\x7F\x0B\u0097t\u008C\u00E4\u008B\u00C1`p\u00E4\x0F@E\u00DF\x00\u00DC\x04\u00F0\u00D4\u00E3-\u00AB\u00EA\u00F3$I\x0E-\x02<4\u00C6\\q\u00CE]\x00@\u008F\x7F\u0080\u00E4\u00938\u008E\x15\x00\x04\x00\u0086\u00C3\u00E1\u00D2x<\u009E\x02\x00\u00C9\rUUc\u00CCck\u00ED+\x00\u00A7\x00\x1C\u008F\u00A2\u00E8\u009D\u00AFW\x15\u00F0u6\u009B\u00EDo4\x1A\u00F7I^W\u00D5\u00B3$o\u00FB\u0082\u00CDf3\u00ECv\u00BB\u00D9o\x15D\u00E4Q\u00BF\u00DF\u00FF^\x14\u00C5\u00A50\f?\u008B\u00C8\x16\x00\u00E7\x03x\u00DF\u0080\u00E4\u00834MW\u0083 \u00B85\u009DN\u00AF\u00F6z\u00BDm\x00/\x17\x01\u0082\n`\u00CD9w\x06\u00C0\u0086\u0088\u00E4\u00D6\u00DA/\u00F3C\u00EE\x00X\x05\u00B0\u00BE\x10 \"\u009B\u00A5\u00E5.\u00C9\u00F7\x00\u00E2z\u00BD\u00FE:\u00CF\u00F3}$\x0F\u008A\u00C8\n\u0080\u00BB\u00DE\n\x155\x00\u00B4Uu\u00AD(\u008A\u008B\x00NDQ\u00F4\u008C\u00E4\u00E1\u00F2\u00D0\"\u00C0^\x11\u00D9$\u0099\u0091\fk\u00B5\u00DA\u00874M\u008D\u0088\\\u00FE_\u00C0\u00AFZ'\u00A3(\u008A'\u0093\u00C9'\u0092\u00F7\u00AA\u00FE\u00BF\x00\u0099s\u00EE\u009A\u00B5\u00F6h\u00AB\u00D5\u00A2\u0088\u00C4\u00D5\u0081\u00C0\x13*kIUo\u0090\u00ECeY\u00B6\r`\u00D7{\u0083\u00D1h\u0094\x03\u00D8\u00F1\x11H\u009E\x07\u00B0\x07?\x7F\u00EB\u00E9\u00F9\u00F6\u00CE<\u0083\x1F\r\u0084\u00AE\u00AD\u00A7\u008B\x19\u00DD\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_language_file.png", "w16" );
w16_language_file;
// ==================== |------------| ====================
// ==================== | w16_random | ====================
// ==================== |------------| ====================

var w16_random = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\u00B1IDAT8\u008D\u00BD\u0093?kTA\x14\u00C5\x7Fwf]\u00FF\u00B4\",\u00C1\u00D6\u00C6\u00C6\"_ B\u008A\u0080\u00FB\u00DE3\u00AC\u00BER,\u00D4-$\x16b\u0093\u00A0\u008DH\u00CA\u00A06\u00B2\u008D\u00A0M\u00C2\x12x\u00CC[XP\u00B0\u00B4\x10R\u0089\x16\u00B6\"\u00FA\x05B\u00C2\u00DBq\u00E6Z\u00E4\x05w\u0097]D\x0BOw\u00EF\u009C{\u00EF\u0099;g\u00E0\x7F\u00A3,\u00CB;\u00CE\u00B9\u00F5\u00E3\u00D8\u00FCC\u008F\u0093\u00C0\u00A6s\u00EE\x11\u00808\u00E7*\u00A0\t\x1C\x02\x1FE\u00E4Y\u009A\u00A6\u00DB\x00\u00C3\u00E1\u00F0\u009C\u00F7\u00FE1\u0090\x00\x0B\u0080L5\u00DB\x10\u00E7\u009C\u00CE\u0098\u00F2\u00C4Z\u00BB\x15B\u00F8\x00\\\u0098'EU\u00DF6b\u008C\u0097E\u00A4\x01\u009C\x15\u0091[\u00C0\u00B2\u0088\\\n!<\u00AF\u008B\x0F\u0081M`OU\x7F\u008A\u00C8U\u00E0\u00AE\u00AA\u00BE\u00B3\u00D6\u00AENH\u00EA\u00F5z'Z\u00AD\u00D6{\u00E0%\u00F0\u00A2N\u00DF\u00CC\u00B2\u00EC\u00D51\u00A7,\u00CB\u00B5\x18cf\u00ADM\u0093$9\u0098Xb\u00B7\u00DB\u00F5\u00C6\u0098UU]\u00AES\u009F\u00D34}=\u00CE\u00F1\u00DE\u00EF\u008EF\u00A3$I\u0092\x03\u0080\u00C6\u00F4\u00BDb\u008C\u00A7k\u0099\u00A8\u00EAS\x11\u0099\u00D8Q\u00A7\u00D3\u00F91\x1E\u00CFz\u00C6\u0087\u0080\x05\u00BE\x01\x0BEQ,\u008E\x1F:\u00E7n\u00CF\u00F4\u00C1`08\u00E3\u009C\u00BB\x0F\u00DC\u00A8\u00A7o\u0089\u00C8=c\u00CCvQ\x14\u008B\u00AA*\x00\"r\u008A#\x1F\u00AC\u00C3\u00A4\x0F\u00C6\u00F1\u00C6Z\u00FB \u0084\u00B0\u00C7\u0091q\u00E6a\u00C3L\x15G`\x07\u00B8\u00DEn\u00B7?\u00A9j\x1B\u00F8:\u00AFZU\u0097\u00A4(\u008A%\x11i\u0088H\x00\u00BEdY\u00F6}\u009C\u00D4\u00EF\u00F7m\u00B3\u00D9\u00BCh\u008C9\x0FXU]\u00E1\u00B7\x0F\u00D2ik\u00FE\x11eY\u00AE\u00A9\u00EA\u00B5\u00AA\u00AA\u00AE\u00E4y\u00BE\u00FF\u00D7\u009F\u00C9{\u00BF[U\u00D5J\u009E\u00E7\u00FB\x00\u00BF\x00\u0081\u00B4\u00AF\u008D(\u008C\x1F\u00E1\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_random.png", "w16" );
w16_random;
// ==================== |-----------------| ====================
// ==================== | w16_eye_dropper | ====================
// ==================== |-----------------| ====================

var w16_eye_dropper = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01[IDAT8\u008D\u0095\u0091/L\u00C3@\x14\u00C6\u00BF\u00F7h:\u00E4\x04\x02\u008D%\u0081\u00D4\x132\x10\u00A0\u00BAsud\u00B8\u008AI23B2\u00C6\x02\t\x02\u008B \x19\n\x1C\u00A2\u0095\u0090\u00B0`\x118\u00D4\fS+\tf\u008A\\X\u00FA0W\u00D2\u0094]\x19\u009F\u00B9{\x7F~\u00DF\u00BB?\u008495\x18\f\x16'\u0093\u00C9\t\x11\u00ED\x01H\u0089\u00A8?\x1E\u008F\u008F\u00E9\x1FpDD;\u00F9<\x11u\u00AD\x06\u009DN\u0087=\u00CF\u00DB\u00D0Z\u00BF\u00B8\u00AE{W\u0084\x01@DFN\t\u00DC\x07\u00D0\u00A8T*\x1F\x00\u0096l\u0083xV\u00D2\u00F3\u00BC}\x00\r\x13Za\"\u00BA\u009Ei \"\x0F\"2\u00B2\u0081FQ\u0092$\u00A73\r\u0098y\u009D\u0099\u00B7JL\"\u00ADu\x10\u0086\u00E1\u00D7B\u00B1\x12\u00C7qOD.\x018\u00CC\x1C\x02P\x00\u00AA\u00B9\u0096Dk\u00BD\x19\x04\u0081\x06\no`\u00E0C\x136E\u00E4\u0080\u0088\u00B6\x01\u00BC\u00E5\u00DA\u0096]\u00D7]\u00CB\u0082\u009F_\u0088\u00A2\u00A8\u009B\u008335E\u00C4u\x1C\u00A76\u009DN\x1F\x01\u00AC\x00\u00B8RJ=g\rd\u00E0\x16\u0080s\u00CB}\u00C1\u00CC\u00BB\x00^\u00D34\u00AD\u00D5\u00EB\u00F5[\"\u0092\u00E2\t\u00DA6\x18@\u00DB\u00F7\u00FD{\u00B3\u00BF\u00F9en\u00D6j\u00B1`t\u00A4\u0094:+1\x07\u00C7q\u00BCj\u009B\u00AC\u0094\u00EA\u0095\u00C1\x00\u00C0i\u009A^\x14r\u00EFD\u00D4\u00FCkr&\u0087\u0099\u009FD\u00E4\u0093\u0099[\u00BE\u00EF\x0F\u00E7\u0081\u00F2\u00FA\x06n\n\u0081\u00C01\x12\x16f\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_eye_dropper.png", "w16" );
w16_eye_dropper;
// huge
// ==================== |---------------| ====================
// ==================== | w320_progress | ====================
// ==================== |---------------| ====================

var w320_progress = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x01@\x00\x00\x00\f\b\x06\x00\x00\x00\x13}d\t\x00\x00\x00\tpHYs\x00\x00\x0E\u00C3\x00\x00\x0E\u00C3\x01\u00C7o\u00A8d\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x04GIDATh\u0081\u00ED\u00DBQ\u0088TU\x1C\u00C7\u00F1\u00EF\u00FF\u00EC\u00E4\u00D8\u00AEhnV\u0096\x05E\x05\x15FB\x11\u0088\u00A2\u00AD\u00B0\u00A0ms\u00CFL\x1B\u00EB\u00FAf`ld&\x04B\u008B\u00F8\x12eBH\u00E1\u0083\u0094`\x10&\u00C9\u00E2\u00CC\u00EC\u00DD\u00BB\u00AEm`Z\b\x06>\b\u00F5\u0092\u00A4$\x158[`\u00B9-8\u00B1s\u00CF\u00BF\u0087\u0099\u0085\u00C9v\u00B7\u00BD\u00A3/M\u00E7\u00F3t\u00EF\u00B9g~\u00FC\u00EF\u00CB\u009Fs\u00E7\u009E+4 \u008A\u00A2%\x0B\x16,\u0098\u0098\u0098\u00980\u00CE\u00B9\u00BD\u00C6\u0098\u00A3\u0099L\u00E6D#YCCC\u009B\u00CB\u00E5r\u00B1\u00A7\u00A7\u00E7*\u00C0\u00E8\u00E8h[\u00B9\\\u00CE\x03-\u00C0\u00F3\u00D6\u00DA?\x1A\u00C9\u00F5<\u00AF9\u00E4\u00F3\u00F9\u00BB\u00BB\u00BB\u00BB/\x03\u0084a\u00F8\u00A9s\u00EE\u00C3\\.w\u00EAfdK\u00D2\x1F\f\f\f\u00DC\u009AN\u00A7\u00F7Zk_\u00A9\x15\u00F4\x10pZDN\u00C5q\u00FCr.\u0097\u00FB}.9\u00AA*a\x18n\x12\u0091\u00F7\u00813\u00CE\u00B9\u00D7[[[K\u00E5ry\x04x\x18p\u00C0%`\u0083o\u0082\u009E\u00F7\u00FFt\u00EC\u00D8\u00B1\u00A5\u0095J\u00E5\x02\u00B0\x02x\x00\u00F8\\D\u00F6\x05A\u00B0\u00BD\u00D6Cz\u008C1\u00F7\u00D7\u00A6\x7F\x13\x04\u00C1\u00F1$\u00F9&iA\u00E9t\u00BA_U\u00BF\u009F:\u00B7\u00D6^\x10\u0091\u00B7Uu\u00A31\u00E6d\u00A1P\u00B8}.9\"\u00A2\"\u00F23pMD~I\u00A5R\u0093S\u00CD\u00CF\x18\u00B3.\u008E\u00E3uTozo\u00D2\x1A=\u00CFk\x0Eq\x1Cw\x02m\u00C0A\u00A0\x02\u008C\u00A9\u00EA\u008Ba\x18\u00DE\x13EQ\u00BF\u0088\x1CQ\u00D5=\u00AA\u00BA'\u008E\u00E3kI\u00F3\x137@\u00E0\u00A5\u0096\u0096\u0096\u00B3\u00F5\x03\u00CE\u00B9\u00B6\u00DA\u00E1\n\u00E0\u00CE\u00B9\x06Yk\u00BF\x12\u0091\u00AD\"\u00D2\u00EF\u009C;\x04\u00AC1\u00C6\u00F4d2\u0099\u00EFZZZ\u00FA\u0080y\"2\u00D4@\u008D\u009E\u00E75\x01\u00E7\u00DC\u00B2\u00DA\u00E1\x1A\u00E0M\u00A0\x1B\u00F8@U\u009Fu\u00CE\u00AD\x03~\x02\u008E\x034\u00F2X\u009C\u00A8\x01\u0086ax\x17\u00B0\x14\x18\u00AB\x1B[/\"\u00BBk\u00A7\u009AJ\u00A5\x0E\u0085a\u00F8\u00E5\\W\u0082\u00E9t\u00FA\u00A4s\u00EE(\u00D5\x1B\u00C49\u00B7?\f\u00C3\u00FD\u00C06\u00A07\b\u0082\u00E1$5z\u009E\u00D7<\u008C1W\u00EANW\x03_\u00A8\u00EA\x1D@,\"K\u0080\u00FB\u0080\r\r\u00E7'\u0099\x1C\u00C7\u00B1\x02\u00A8\u00EAc\x00\u0083\u0083\u0083[Dd\u00A7\u00AA~\"\"+\u0081\u00D7T\u00F5I\u00AA+\u00B9\x1D\u00FF\u0096\x17EQk\u00B9\\\u008E\u0080\u00B5u\u00C3\u008F\x03[Tu\u00A3\u00B5\u00B6\u0090\u00A4>\u00CF\u00F3\u009AK\x1C\u00C7'\x00\u00AD\x1B\u009A'\"\u009BE\u00E4#\u00E0\u0089\x1B\u00CDO\u00D4\x00s\u00B9\u00DC\u00AF\u00C0%U\u00DD\x1EE\u00D1\u00D3\"r@U\u0097\x03\u00EF\x06A\u00F05\u00F0[\u00AD\u00D8\u00C2\u00D8\u00D8\u00D8\u00AE\u00D9\u00B2FGG\u00DB\u009Cs#@\u00C7u\u0097&\u0081\u00DEE\u008B\x16%\u00FA3\u00D3\u00F3\u00BC\u00E6\u0093\u00CB\u00E5.\x02\u00C59L\u00D5\x7F\u009F\u00F2O\u0089\x1A\u00A0\u0088(\u00F01\u00D5\u00A6\u00F5\x02\u00D5g\u00F2\u00CEl6\u00FB-\u0080\u00B5\u00F6\u00B0\u00AA>W*\u0095z\u00FB\u00FA\u00FA&g\u00CA\u0099a\u00E5\x0709\u00B5\u00F2\x1B\x1F\x1F\x7F\u00A3X,>\u0093\u00A4>\u00CF\u00F3\u009AO*\u0095\u00DAJuG\u00C8l.7\u0092\u009D\u00F8%H*\u0095\u00CA\x03\u00E7\u009Ds;\u0080\u00A7T\u00F5\u00CF\u00FA\u00EB\u00D9lvd\u00B6\u00E67000o\u00B6\u0095_6\u009B-\u0086a\u00B8\x0B\u00D8i\u008C)\u0086a\u00B8>i\u008D\u009E\u00E75\u008F\u00AE\u00AE\u00AE\x12\u00D0I\u00DD\u00BB\u0087i\x1Ch$;\u0095d\u00F2\u00E0\u00E0`_\u00A5R\u00D9'\"[\u009CsVD\u00BAE\u00A4+\f\u00C3\u008B\u00C0\x0F\u00B5i\x07\u00AD\u00B5Gf\u00CA\u0098?\x7F\u00FE2U]u\u00DD\u00F0$\u00D0;\u00F5\u009F\u00DF\u00C2\u0085\x0B\u00DF\x19\x1F\x1F_.\"\u00A7\u0083 \u00F8,I\u008D\u009E\u00E75\u0087\u0091\u0091\u0091\u0085\u0095J\u00E5U\u00E7\u00DCZ`\x15\u00D5\u00ED0\u00D3\x19(\u0095J\u00BBg\u00B86\u00AB9o\u0084.\x16\u008B\u00B7\x19c\u00CES\u00FDB\u00A3\u00D3Z{\u00AEP(<j\u008C\u00B1\"\u00B2RDV\u00ABj;0\u00E6\u009C{d\u00B6\r\u00D1CCC=\u00AAz\u0098j\x03\u00FE[\u00F3\u009B\u0092\u00CF\u00E7\u00EFmoo/uttT\x1A\u00B91\u00CF\u00F3\u00FE\u00DB\u0086\u0087\u0087\x17\u00C7q|\x16x\u00B0n\u00D8\x01\x07U\u00F5\u008A\u0088\\u\u00CE\u009D\u00B9\u0091\u00AFB\x12}\t2<<\u00BC<\u008E\u00E3[\u00AC\u00B5\u00E7\u00A6+\u00B6R\u00A9\u00BC%\"+\u008C1\u009B2\u0099\u00CC\u008F\u00B3e\u00D5\u009A\u00E0{\u00C06\u00FF\u00B6\u00D7\u00F3\u00BC\u00E9DQ\u00B4\u00C49\u00D7\x0Fd\u0080\u00C5@\u00DF\u00CD\u00EC\x17\x7F\x01\u00D0\u00BB\u00C9\u0082\u0095bR\u00F1\x00\x00\x00\x00IEND\u00AEB`\u0082", "w320_progress.png", "w320" );
w320_progress;

/**
 * The list of available icons.
 * @enum {DuBinary}
 * @static
 * @memberof DuScriptUI
 */
DuScriptUI.Icon = {
    ADD: w12_add,
    AE_BLUE: w8_ae_blue,
    AE_ORANGE: w8_ae_orange,
    BACK: w12_back,
    BOX_CHECKED: w12_box_checked,
    BOX_UNCHECKED: w12_box_unchecked,
    BUG: w16_bug,
    BUG_REPORT: w12_bugreport,
    CHECK: w12_check,
    CLOSE: w12_close,
    DOWNLOAD: w16_download,
    EDIT: w12_edit,
    EXPERT: w16_expert,
    EYE_DROPPER: w12_eye_dropper,
    EYE_DROPPER_BIG: w16_eye_dropper,
    FEATURE: w12_feature,
    FILE: w12_file,
    FOLDER: w12_folder,
    FOLDER_CLOSED: w12_folder_closed,
    GO_TO: w12_goto,
    HEART: w12_heart,
    HELP: w12_help,
    LANGUAGE: w16_language,
    LANGUAGE_FILE: w16_language_file,
    LIST: w16_list,
    MENU: w12_menu,
    MORE: w12_more,
    NEXT: w12_next,
    OPTIONS: w12_options,
    PARENT: w12_parent,
    PIN: w12_pin,
    PINNED: w12_pinned,
    PLACEHOLDER: w16_placeholder,
    PROGRESS: w320_progress,
    RAINBOX_RED: w8_rx_red,
    RANDOM: w16_random,
    REMOVE: w12_remove,
    RESET: w12_reset,
    ROOKIE: w16_rookie,
    RUN: w12_run,
    RX_PURPLE: w8_rx_purple,
    SETTINGS: w12_settings,
    SETTINGS_FILE: w16_settings_file,
    STANDARD: w16_standard,
    UPDATE: w12_update,
    USER: w16_user,
    SEARCH: w12_search,
    SORT: w12_sort,
    SORT_UP: w12_sort_up,
    SORT_DOWN: w12_sort_down,
};

// ==================== |----------| ====================
// ==================== | titleBar | ====================
// ==================== |----------| ====================

/**
 * @class
 * @name DuTitleBar
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A title bar.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.titleBar} to create  title bar.<br />
 * The itle bar inherits the <code>Group</code> object from ScriptUI and has all of its properties and methods.
 * @property {Boolean} pinned True when the title bar has been pinned and the corresponding panel should not be hidden.
 * @property {DuTitleBar~onClose} onClose - The function to execute when the close button is clicked
 * @property {DuTitleBar~onPin} onPin - The function to execute when the pin button is clicked
 * @category DuScriptUI
 */

/**
 * The function to execute when the close button is clicked
 * @callback DuTitleBar~onClose
 * @memberof DuTitleBar
 */

/**
 * The function to execute when the pin button is clicked
 * @callback DuTitleBar~onPin
 * @param {Boolean} pinned Wether the bar has been pin or not
 * @memberof DuTitleBar
 */

/**
 * Creates a titlebar
 * @param {Panel|Window|Group} container The ScriptUI Object which will contain and display the titlebar.
 * @param {string} [title=""] The title.
 * @param {Boolean} [closeButton=true] Wether to add a close button
 * @param {Boolean} [pinButton=true] Wether to add a pin button
 * @returns {DuTitleBar} The titlebar
 */
DuScriptUI.titleBar = function( container, title, closeButton, pinButton ) {
    // Defaults
    title = def(title, "");
    closeButton = def(closeButton, true);
    pinButton = def(pinButton, true);

    // Creates the title bar
    var titleBar = container.add( 'group' );
    titleBar.margins = 0;
    titleBar.spacing = 0;
    titleBar.orientation = 'row';
    titleBar.alignment = ['fill','top'];
    DuScriptUI.setBackgroundColor( titleBar, DuColor.Color.DARK_GREY );

    titleBar.onClose = function() {};
    titleBar.onPin = function(p) {};

    // Pin button
    if(pinButton) {
        titleBar.pinButton = DuScriptUI.checkBox(titleBar, '', w12_pin, DuScriptUI.String.PIN_TIP, '', w12_pinned);
        titleBar.pinButton.alignment = [ 'left', 'center' ];
        titleBar.pinButton.onClick = function() {
            titleBar.pinned = titleBar.pinButton.checked;
            titleBar.onPin(titleBar.pinned);
        };
    }

    // Title
    if (title != "") {
        titleBar.titleLabel = titleBar.add('statictext', undefined,  title);
        titleBar.titleLabel.alignment = [ 'center', 'center' ];
    }

    // Close
    if (closeButton) {
        titleBar.closeButton = DuScriptUI.button(titleBar, '', w12_close, 'Close');
        titleBar.closeButton.alignment = [ 'right', 'center' ];
        titleBar.closeButton.onClick = function() {
            titleBar.onClose();
        };
    }

    return titleBar;
}// ==================== |-------| ====================
// ==================== | panel | ====================
// ==================== |-------| ====================


/**
 * @class
 * @name DuPanel
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Panel or Window.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.mainPanel} to create a Panel.<br />
 * The DuPanel inherits the Panel or Window object from ScriptUI and has all of its properties and methods.
 * @category DuScriptUI
 */

/**
 * The ScriptUI group where the new controls must be added. Do not add any control directly inside the DuPanel.
 * @name content
 * @type {Group}
 * @memberof DuPanel.prototype
 */

/**
 * A function to reload a script in this panel.
 * @method refreshUi
 * @param {File} file - The script to reload. 
 * @return {boolean} true on success, false otherwise.
 * @memberof DuPanel.prototype
 */

/**
 * Creates the main panel for a script
 * @param {Panel|null} container - The container ('this' in the root of the calling script), either a Panel (when launched from the 'Window' menu) or null (when launched from 'file/scripts/run...')
 * @param {string} [scriptName=DuESF.scriptName] - A name for this UI
 * @param {string[]} [contentAlignment=DuScriptUI.defaultColumnAlignment] - The alignment of the content in the panel
 * @param {string} [borderless=false] - When true, creates a borderless window if container is not a panel
 * @return {DuPanel} The panel created, either a ScriptUI Panel or a ScriptUI Window.
 * @example
 * var ui = DuScriptUI.mainPanel(this,"Test Script");
 * var refreshButton = ui.content.add('button',undefined,"Refresh");
 * refreshButton.onClick = function() { ui.refreshUI( new File($.fileName) ); }; //reloads the current script
 * DuScriptUI.showUI(ui);
 */
DuScriptUI.mainPanel = function( container, scriptName, contentAlignment, bless )
{
    scriptName = def(scriptName, DuESF.scriptName, false);
    contentAlignment = def(contentAlignment, DuScriptUI.defaultColumnAlignment, false);
    bless = def (bless, false);

    scriptName = tr( scriptName );

    var myPal = null;

    var winType = 'palette';

    if (DuESF.host == DuESF.HostApplication.PHOTOSHOP)
    {
        bless = false;
        winType = 'dialog';
    }

    container instanceof Panel ? myPal = container : myPal = new Window( winType, scriptName, undefined,
    {
        resizeable: true,
        borderless: bless
    } );

    if ( myPal == null ) throw "Failed to create User Interface.";

    myPal.margins = 0;
    myPal.spacing = 0;

    //create margins to dim buttons
    var topMargin = myPal.add( 'button' );
    topMargin.onDraw = function() {};
    topMargin.minimumSize.height = DuScriptUI.defaultMargins;
    topMargin.alignment = [ 'fill', 'top' ];
    topMargin.maximumSize.height = topMargin.minimumSize.height = topMargin.preferredSize.height = DuScriptUI.defaultMargins;

    var mainRow = myPal.add( 'group' );
    mainRow.alignment = contentAlignment;
    mainRow.alignChildren = contentAlignment;
    mainRow.margins = 0;
    mainRow.spacing = 0;

    var leftMargin = mainRow.add( 'button' );
    leftMargin.onDraw = function() {};
    leftMargin.maximumSize.width = leftMargin.minimumSize.width = leftMargin.preferredSize.width = DuScriptUI.defaultMargins;
    leftMargin.alignment = [ 'left', 'fill' ];

    myPal.content = mainRow.add( 'group' );
    myPal.content.margins = 0;
    myPal.content.spacing = DuScriptUI.defaultSpacing;
    myPal.content.alignChildren = DuScriptUI.defaultColumnAlignment;
    myPal.content.orientation = "column";
    myPal.content.alignment = ['fill', 'fill'];

    var rightMargin = mainRow.add( 'button' );
    rightMargin.onDraw = function() {};
    rightMargin.maximumSize.width = rightMargin.minimumSize.width = rightMargin.preferredSize.width = DuScriptUI.defaultMargins;
    rightMargin.alignment = [ 'right', 'fill' ];

    var bottomMargin = myPal.add( 'button' );
    bottomMargin.onDraw = function() {};
    bottomMargin.maximumSize.height = bottomMargin.minimumSize.height = bottomMargin.preferredSize.height = DuScriptUI.defaultMargins;
    bottomMargin.alignment = [ 'fill', 'bottom' ];

    myPal.addEventListener( "mouseover", DuScriptUI.dimControls );
    topMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    leftMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    rightMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    bottomMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
//*/
    return myPal;
}

/**
 * @class
 * @name DuPopup
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A borderless popup, to be tied to a ui control.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.popUp} to create a Popup.<br />
 * The DuPopup inherits the Window object from ScriptUI and has all of its properties and methods.
 * @property {Group} content - The ScriptUI group where the new controls must be added. Do not add any control directly inside the DuPopup.
 * @property {boolean} pinned - true if this popup is "pinned", which means it won't hide when the user clicks outside of the window.
 * @property {DuPopup~build} build - You can use this callback to add a function which builds the UI of the popup, it will be called on first display.
 * @category DuScriptUI
 */

/**
 * You can use this callback to add a function which builds the UI of the popup, it will be called on first display.<br />
 * This allows a faster startup of your script by delaying the creation of the tabs which are hidden at startup.<br />
 * You can add controls in the <code>this.content</code> object.
 * @callback DuPopup~build
 * @memberof DuPopup
 */
/**
 * Ties the popup to a ui control. The popup will be shown just above the control when it is clicked.<br />
 * The control must have an addEventListener method.
 * @method
 * @memberof DuPopup
 * @name tieTo
 * @param {ScriptUI} [control] - The control
 * @param {Boolean} [onShift=false] - If set to true, the popup is tied on Shift + Click only
 * @param {boolean} [alwaysBlock=false] If true, the popup will never be automatically shown. Call show() to show it.
 */

/**
 * Pins the popup (it won't be hidden anymore when deactivated).
 * @method
 * @memberof DuPopup
 * @name pin
 * @param {boolean} [pinned=true] - true to pin the popup, false to un-pin it.
 */

/**
 * Hides the popup.
 * @method
 * @memberof DuPopup
 * @name hidePopup
 */

/**
 * Hides the popup (alias for {@link DuPopup.hidePopup}).
 * @alias DuPopup.hidePopup
 * @method
 * @memberof DuPopup
 * @name cancel
 */

/**
 * Sets this parameter to <code>true</code> to prevent the next show of the popup.<br />
 * This will prevent it from showing once (and only once).
 * @type {Boolean}
 * @memberof DuPopup
 * @name block
 * @default false
 */

/**
 * Creates a borderless popup
 * @param {string} title The title of the popup
 * @param {string[]} [alignment=[ "fill", "top" ]] The alignement of this window
 * @param {boolean} [modal=false] Set the popup to a modal dialog
 * @return {DuPopup} The popup, a ScriptUI Window which is borderless, with a 'tieTo(control)' method.
 * @example
 * var popup = DuScriptUI.popUp( );
 * var popupButton = DuScriptUI.button( myUI, "My Buttton for the popup" );
 * popup.tieTo( popupButton ); // will show the popup when the button is clicked, just above it.
 */
DuScriptUI.popUp = function( title, alignment, modal )
{
    modal = def(modal, false);
    alignment = def( alignment, [ "fill", "top" ] );
    title = def (title, "");
    title = tr( title );
    
    var type = 'palette';
    if (modal) type = 'dialog'; 
    var popup = new Window( type, title, undefined,
    {
        resizeable: false,
        borderless: true
    } );

    DuScriptUI.setBackgroundColor(popup, DuColor.Color.OBSIDIAN);

    popup.margins = 0;
    popup.spacing = 0;
    popup.pinned = false;

    //add stroke around
    function drawBorder ( drawState ) {
        /*var g = this.graphics;
        var c = DuColor.Color.DARK_GREY;

        var pen = g.newPen( g.PenType.SOLID_COLOR, c, 1 );

        g.newPath();
        if (this.side == 0) {
            g.moveTo (0, 0);
            g.lineTo (this.size.width, 0);
        }
        else if (this.side == 2) {
            g.moveTo (this.size.width, 0);
            g.lineTo (this.size.width, this.size.height);
        }
        else if (this.side == 1) {
            g.moveTo (0, 0);
            g.lineTo (0, this.size.height);
        }
        else if (this.side == 3) {
            g.moveTo (0, this.size.height);
            g.lineTo (this.size.width, this.size.height);
        }

        g.strokePath( pen );*/
    };

    //create margins to dim buttons
    var topMargin = popup.add( 'button' );
    topMargin.onDraw = drawBorder;
    topMargin.side = 0;
    topMargin.minimumSize.height = DuScriptUI.defaultMargins;
    topMargin.alignment = [ 'fill', 'top' ];
    topMargin.maximumSize.height = topMargin.minimumSize.height = topMargin.preferredSize.height = 1;
    
    var mainRow = popup.add( 'group' );
    mainRow.alignment = alignment;
    mainRow.alignChildren = alignment;
    mainRow.margins = 0;
    mainRow.spacing = 0;

    var leftMargin = mainRow.add( 'button' );
    leftMargin.onDraw = drawBorder;
    leftMargin.side = 1;
    leftMargin.maximumSize.width = leftMargin.minimumSize.width = leftMargin.preferredSize.width = 1;
    leftMargin.alignment = [ 'left', 'fill' ];

    var mainColumn = mainRow.add( 'group' );
    mainColumn.orientation = 'column';
    mainColumn.spacing = 0;
    mainColumn.margins = 0;
    mainColumn.alignment = ['fill','fill'];

    var titleBar = DuScriptUI.titleBar(
        mainColumn,
        title
        );
    if (modal) DuScriptUI.setTextColor(titleBar.titleLabel, DuColor.Color.APP_HIGHLIGHT_COLOR)

    popup.content = mainColumn.add( 'group' );
    popup.content.margins = 0;
    popup.content.spacing = 0;
    popup.content.alignChildren = alignment;
    popup.content.orientation = "column";

    var rightMargin = mainRow.add( 'button' );
    rightMargin.onDraw = drawBorder;
    rightMargin.side = 2;
    rightMargin.maximumSize.width = rightMargin.minimumSize.width = rightMargin.preferredSize.width = 1;
    rightMargin.alignment = [ 'right', 'fill' ];

    var bottomMargin = popup.add( 'button' );
    bottomMargin.onDraw = drawBorder;
    bottomMargin.side = 3;
    bottomMargin.maximumSize.height = bottomMargin.minimumSize.height = bottomMargin.preferredSize.height = 1;
    bottomMargin.alignment = [ 'fill', 'bottom' ];

    popup.block = false;

    popup.build = function( contentGroup ) {};
    popup.built = false;

    popup.tiedAlwaysBlock = false;

    popup.tieTo = function (control, onShift, alwaysBlock)
    {
        onShift = def(onShift, false);
        alwaysBlock = def(alwaysBlock, false);

        popup.tiedAlwaysBlock = alwaysBlock;

        control.tiedPopups = def(control.tiedPopups, []);
        control.tiedOnShift  =def(control.tiedOnShift, []);
        control.tiedPopups.push(popup);
        control.tiedOnShift.push(onShift);
        
        if (control.tiedPopups.length == 1)
        {
            control.addEventListener( 'click', function(e) {
                if(e.view.parent != control) return;

                for (var i = 0; i < control.tiedPopups.length; i++)
                {
                    var ppup = control.tiedPopups[i];
                    if ( !e.shiftKey && control.tiedOnShift[i] ) return;

                    if (ppup.block)
                    {
                        ppup.block = false;
                        return;
                    }

                    if ( !ppup.built )
                    {
                        ppup.build( );
                        ppup.built = true;
                    }

                    var x = e.screenX - e.clientX;
                    var y = e.screenY - e.clientY;
                    //we need a layout and resize to get the window frame size
                    DuScriptUI.layout( ppup );
                    var location = [x,y];
                    location = DuScriptUI.moveInsideScreen( [x, y], ppup.frameSize );
                    ppup.location = location;
                    if (!ppup.pinned) DuScriptUI.eventFunctionsPaused = true;
                    if (!ppup.tiedAlwaysBlock) ppup.show();
                }
            }, true);
        }
    }

    popup.pin = function(p)
    {
        p = def (p, true);
        popup.pinned = p;
        titleBar.pinButton.setChecked(p);
    }

    var movingTitle = false;
    var movingPopup = false;
    var startMouseLocation = [0,0];
    var startPopupLocation = [0,0];

    function enterTitleMoveState(e)
    {
        movingTitle = true;
        startMouseLocation = [e.screenX, e.screenY];
        startPopupLocation = [popup.location[0], popup.location[1]];
    }

    function enterPopupMoveState(e)
    {
        movingPopup = true;
        startMouseLocation = [e.screenX, e.screenY];
        startPopupLocation = [popup.location[0], popup.location[1]];
    }

    function movePopup(e)
    {
        if (!movingPopup) return;
        if (movingTitle) return;
        var x = e.screenX - startMouseLocation[0];
        var y = e.screenY - startMouseLocation[1];
        popup.location = [ x, y ] + startPopupLocation;
    }

    function moveTitle(e)
    {
        if (!movingTitle) return;
        var x = e.screenX - startMouseLocation[0];
        var y = e.screenY - startMouseLocation[1];
        popup.location = [ x, y ] + startPopupLocation;
    }

    function endMoveState(e)
    {
        movingTitle = false;
        movingPopup = false;
    }

    function esc(e)
    {
        if ( e.keyName == "Escape") { hidePopup(); }
    }

    function hidePopup()
    {
        popup.hide();
        DuScriptUI.eventFunctionsPaused = false;
    }

    popup.cancel = popup.hidePopup = hidePopup;

    popup.onDeactivate = function () { if (!popup.pinned) hidePopup(); };
    titleBar.onClose = hidePopup;

    titleBar.onPin = function (pinned) { popup.pin(pinned); };

    popup.addEventListener( "mouseover", DuScriptUI.dimControls );
    popup.addEventListener( "keydown", esc );
    topMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    leftMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    rightMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    bottomMargin.addEventListener( "mouseover", DuScriptUI.dimControls );
    titleBar.addEventListener( "mouseover", DuScriptUI.dimControls );

    titleBar.addEventListener( "mousedown", enterPopupMoveState );
    titleBar.addEventListener( "mousemove", movePopup);
    titleBar.addEventListener( "mouseup", endMoveState );
    titleBar.addEventListener( "mouseout", endMoveState );

    titleBar.titleLabel.addEventListener( "mousedown", enterTitleMoveState );
    titleBar.titleLabel.addEventListener( "mousemove", moveTitle );
    titleBar.titleLabel.addEventListener( "mouseup", endMoveState );
    titleBar.titleLabel.addEventListener( "mouseout", endMoveState );

    if (modal) popup.pin();

    return popup;
}

/**
 * Resizes and shows the main panel of a script
 * @param {Panel|Window}		ui	- The UI created by Duik.ui.createUI
 * @param {boolean}		[enterRunTime=false]	- Set to true to automatically set DuESF to runtime state<br />
 * Set this to false if the ui shown is not the actual main panel of the script and it is shown before the main panel has been loaded.
 */
DuScriptUI.showUI = function( ui, enterRunTime )
{
    DuScriptUI.updateFundingInfo();

    enterRunTime = def( enterRunTime, true);

    DuDebug.log( "DuScriptUI.showUI" );

    DuDebug.log( "DuScriptUI.showUI: Defining layout & resize" );
    DuScriptUI.layout( ui, true );
    DuDebug.log( "DuScriptUI.showUI: Layout OK" );
    ui.onResizing = ui.onResize = function()
    {
        try
        {
            ui.layout.resize();
        }
        catch ( e )
        {}
    }
    DuDebug.log( "DuScriptUI.showUI: UI Ready" );

    // If it's a Window, it needs to be shown
    if ( ui instanceof Window )
    {
        DuDebug.log( "DuScriptUI.showUI: Showing window" );
        //ui.center();
        ui.show();
        DuDebug.log( "DuScriptUI.showUI: Window visible." );
    }
    DuDebug.log( "DuScriptUI.showUI: UI shown" );

    DuScriptUI.uiShown = true;
    
    if (enterRunTime) DuESF.enterRunTime();

    // Build tabs
    for (var i = 0, n = DuScriptUI.allTabs.length; i < n; i++)
    {
        var tab = DuScriptUI.allTabs[i];
        if ( !tab.activated ) continue;
        tab.duBuild();
        tab.visible = true;
        tab.tabActivated();
    }
}

/**
 * @class
 * @name DuScriptPanel
 * @extends DuPanel
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Panel or Window.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.scriptPanel} to create a Panel.<br />
 * @property {Group} settingsGroup - The ScriptUI group where to add the UI for the settings of the script.
 * @property {Group} mainGroup - The ScriptUI group where to add the main UI of the script.
 * @property {DuScriptPanel~onApplySettings} onApplySettings Called when the apply settings button is clicked.
 * @property {DuScriptPanel~onResetSettings} onResetSettings Called when the reset (default) settings button is clicked.
 * @category DuScriptUI
 */

/**
 * The function to execute when the apply settings button is clicked.
 * @callback DuScriptPanel~onApplySettings
 * @memberof DuScriptPanel
 */

/**
 * The function to execute when the reset settings button is clicked.
 * @callback DuScriptPanel~onResetSettings
 * @memberof DuScriptPanel
 */

/**
 * Adds some settings common to all scripts (the file, highlight color, languages...)
 * @method addCommonSettings
 * @memberof DuScriptPanel.prototype
 */

/**
 * Creates the main panel of a script
 * @param {Panel|null} container - The container ('this' in the root of the calling script), either a Panel (when launched from the 'Window' menu) or null (when launched from 'file/scripts/run...')
 * @param {bool} [addSettingsButton=true] - Whether to create a button to open the settings or not
 * @param {bool} [addHelpButton=false] - Whether to create a button to open the help panel or not
 * @param {File} [scriptFile] - The main script file, needed for the refresh button in debug mode
 * @return {DuScriptPanel} The panel created, either a ScriptUI Panel or a ScriptUI Window.
 * @example
 * var ui = DuScriptUI.mainPanel(this,"Test Script");
 * var refreshButton = ui.content.add('button',undefined,"Refresh");
 * refreshButton.onClick = function() { ui.refreshUI( new File($.fileName) ); }; //reloads the current script
 * DuScriptUI.showUI(ui);
 */
DuScriptUI.scriptPanel = function( container, addSettingsButton, addHelpButton, scriptFile )
{
    function testGroup( group )
    {
        group.add('statictext', undefined, "test");
        DuScriptUI.setBackgroundColor( group, DuColor.Color.BLACK );
    }

    addSettingsButton = def(addSettingsButton, true);
    addHelpButton = def(addHelpButton, false);

    var panel = DuScriptUI.mainPanel( container, undefined, ['fill','fill'] );
    panel.content.orientation = 'stack';
    panel.content.alignment = ['fill','fill'];

    var contentsMainGroup = DuScriptUI.group(panel.content, 'column');
    contentsMainGroup.alignment = ['fill', 'fill'];
    contentsMainGroup.margins = 0;

    var contentsMainStack = DuScriptUI.group(contentsMainGroup, 'column');
    contentsMainStack.orientation = 'stack';
    contentsMainStack.alignment = ['fill', 'fill'];

    panel.mainGroup = DuScriptUI.group(contentsMainStack, 'column');
    panel.mainGroup.alignment = ['fill', 'fill'];

    //a margin at the bottom (hidden by the bottom bar buttons)
    var mainGroupMarginBottom = DuScriptUI.group(contentsMainGroup, 'column');
    mainGroupMarginBottom.alignment= ['fill', 'bottom'];
    //mainGroupMarginBottom.minimumSize = [0, 16];

    // == SETTINGS PANEL
    var rootSettingsGroup = DuScriptUI.group(contentsMainStack, 'column');
    rootSettingsGroup.alignment = ['fill', 'fill'];
    rootSettingsGroup.visible = false;
    panel.settingsGroup = DuScriptUI.group(rootSettingsGroup, 'column');
    panel.settingsGroup.alignment = ['fill', 'top'];
    var settingsTitle = DuScriptUI.titleBar(
        panel.settingsGroup,
        tr( '{#} ' + DuScriptUI.String.SETTINGS,undefined, DuESF.scriptName),
        true,
        false
    );

    panel.hasCommonSettings = false;
    panel.addCommonSettings = function()
    {
        if (panel.hasCommonSettings) return;
        panel.hasCommonSettings = true;

        var common  = def(DuESF.scriptSettings.data.common, {});
        var debug = def( common.debug, false);

        // Add default settings
        // language
        // Prepare languages, count how many there are, etc
        DuTranslator.getAvailable();
        var languages = DuTranslator.getPrettyNames();
        var languageCount = languages.length;

        var languageGroup = DuScriptUI.group(panel.settingsGroup, 'row');

        if (languageCount > 1)
        {
            panel.settingsGroup.languageSelector = DuScriptUI.selector(
                languageGroup,
                DuScriptUI.String.LANGUAGE_TIP
            )

            for (var i = 0; i < languageCount; i++ )
            {
                panel.settingsGroup.languageSelector.addButton(
                    languages[i],
                    w16_language
                );
            }

            panel.settingsGroup.languageSelector.setCurrentIndex(0);
        }
        
        if (debug)
        {
            var languageExportLabel = DuScriptUI.String.EXPORT_TRANSLATION;
            if (panel.settingsGroup.languageSelector) languageExportLabel = '';

            panel.settingsGroup.exportTranslationButton = DuScriptUI.button(
                languageGroup,
                languageExportLabel,
                DuScriptUI.Icon.LANGUAGE_FILE,
                DuScriptUI.String.EXPORT_TRANSLATION_TIP
            );

            if (panel.settingsGroup.languageSelector)
                panel.settingsGroup.exportTranslationButton.alignment = ['right','fill'];

            panel.settingsGroup.exportTranslationButton.onClick = function() {
               
                //Ask for file
                var file = File.saveDialog ("Export translation File", "JSON: *.json");
                if (!file) return;

                DuTranslator.generateTranslationFile(file);
            }
        }

        // settings file
        panel.settingsGroup.fileButton = DuScriptUI.fileSelector (
            panel.settingsGroup,
            DuScriptUI.String.SETTINGS_FILE + '...',
            true,
            DuScriptUI.String.SETTINGS_FILE_TIP,
            w16_settings_file,
            'save',
            "JSON: *.json, All Files: *.*",
            'column'
        );
        // color
        panel.settingsGroup.colorSelector = DuScriptUI.selector(
            panel.settingsGroup,
            DuScriptUI.String.COLOR_HIGHLIGHT_TIP
        );
        panel.settingsGroup.colorSelector.addButton(
            DuScriptUI.String.AE_BLUE,
            w8_ae_blue,
            DuScriptUI.String.AE_BLUE_TIP
        );
        panel.settingsGroup.colorSelector.addButton(
            DuScriptUI.String.RX_PURPLE,
            w8_rx_purple,
            DuScriptUI.String.RX_PURPLE_TIP
        );
        panel.settingsGroup.colorSelector.addButton(
            DuScriptUI.String.RX_RED,
            w8_rx_red,
            DuScriptUI.String.RX_RED_TIP
        );
        panel.settingsGroup.colorSelector.addButton(
            DuScriptUI.String.AE_ORANGE,
            w8_ae_orange,
            DuScriptUI.String.AE_ORANGE_TIP
        );
        panel.settingsGroup.colorSelector.addButton(
            DuScriptUI.String.CUSTOM + '...',
            undefined,
            DuScriptUI.String.CUSTOM_COLOR_TIP
        );
        panel.settingsGroup.colorSelector.setCurrentIndex(0);
        // ui mode
        panel.settingsGroup.uiModeSelector = DuScriptUI.selector(
            panel.settingsGroup,
            DuScriptUI.String.UI_MODE_TIP
        )
        panel.settingsGroup.uiModeSelector.addButton(
            DuScriptUI.String.ROOKIE,
            w16_rookie,
            DuScriptUI.String.ROOKIE_UI_TIP
        );
        panel.settingsGroup.uiModeSelector.addButton(
            DuScriptUI.String.STANDARD,
            w16_standard,
            DuScriptUI.String.STANDARD_UI_TIP
        );
        panel.settingsGroup.uiModeSelector.addButton(
            DuScriptUI.String.EXPERT,
            w16_expert,
            DuScriptUI.String.EXPERT_UI_TIP
        );
        panel.settingsGroup.uiModeSelector.setCurrentIndex(0);
        // dev & debug
        panel.settingsGroup.debugButton = DuScriptUI.checkBox (
            panel.settingsGroup,
            DuScriptUI.String.NORMAL_MODE,
            w16_user,
            DuScriptUI.String.DEV_MODE_TIP,
            DuScriptUI.String.DEV_MODE,
            w16_bug
        )

        panel.settingsGroup.fileButton.onChange = function()
        {
            var file = panel.settingsGroup.fileButton.getFile();
            if (file == null) return;
            DuESF.scriptSettings.setFile(file);
            panel.settingsGroup.reset();
        }

        panel.settingsGroup.colorSelector.onChange = function()
        {
            var common  = def(DuESF.scriptSettings.data.common, {});
            var customColor = new DuColor( def( common.highlightColor, DuColor.Color.APP_HIGHLIGHT_COLOR ) );
            var colorIndex = panel.settingsGroup.colorSelector.index;
            if (colorIndex == panel.settingsGroup.colorSelector.items.length -1 )
            {
                var newColor = new DuColor( colorPicker( customColor.floatRGB() ) );
                // If white, the user has canceled
                if ( newColor.equals( DuColor.Color.WHITE ) )
                {
                    panel.settingsGroup.colorSelector.setCurrentIndex(0);
                    return;
                }

                // Store the color for the valid button
                panel.settingsGroup.colorSelector.customColor = newColor;
            }
        }

        // Load settings
        panel.settingsGroup.reset = function()
        {
            var common  = def(DuESF.scriptSettings.data.common, {});
            var highlightSelection = def( common.highlightSelection, 0);
            var currentLanguageName = def( common.currentLanguageName, 'Esperanto');
            var debug = def( common.debug, false);
            var uiMode = def( common.uiMode, 0);
            var customColor = new DuColor( def( common.highlightColor, DuColor.Color.APP_HIGHLIGHT_COLOR ) );
            
            // Settings File
            panel.settingsGroup.fileButton.setPath( DuESF.scriptSettings.file.absoluteURI );

            // Ui mode
            panel.settingsGroup.uiModeSelector.setCurrentIndex( uiMode );

            // Color
            panel.settingsGroup.colorSelector.setCurrentIndex( highlightSelection, true );
            // Set custom
            panel.settingsGroup.colorSelector.customColor = customColor;

            // Language
            if (panel.settingsGroup.languageSelector)
                for (var i = 0 , num = panel.settingsGroup.languageSelector.items.length; i < num; i++)
                {
                    if (panel.settingsGroup.languageSelector.items[i][0] == currentLanguageName)
                    {
                        panel.settingsGroup.languageSelector.setCurrentIndex(i);
                        break;
                    }
                }

            // Debug mode
            panel.settingsGroup.debugButton.setChecked( debug );

            panel.onResetSettings();
        }

        panel.settingsGroup.reset();
    }

    DuScriptUI.separator( rootSettingsGroup );

    panel.settingsGroup.updateButton = DuScriptUI.button(
        rootSettingsGroup,
        DuScriptUI.String.CHECK_UPDATE,
        DuScriptUI.Icon.DOWNLOAD,
        DuScriptUI.String.CHECK_UPDATE,
        false,
        'row',
        'center'
    )

    DuScriptUI.separator( rootSettingsGroup );

    var validGroup = DuScriptUI.group( rootSettingsGroup, 'row');

    panel.settingsGroup.resetButton = DuScriptUI.button(
        validGroup,
        DuScriptUI.String.DEFAULT,
        w12_reset,
        DuScriptUI.String.RESET_SETTINGS,
        false,
        'row',
        'center'
    );
    panel.settingsGroup.validButton = DuScriptUI.button(
        validGroup,
        DuScriptUI.String.APPLY,
        w12_check,
        DuScriptUI.String.APPLY_SETTINGS,
        false,
        'row',
        'center'
    );
    
    panel.onApplySettings = function() {};
    panel.onResetSettings = function() {};

    panel.settingsGroup.validButton.onClick = function()
    {
        if (!panel.hasCommonSettings)
        {
            panel.onApplySettings();
            return;
        }

        // Update and Save settings
        DuESF.scriptSettings.data.common = def( DuESF.scriptSettings.data.common, {} );

        // UI Mode
        DuESF.scriptSettings.data.common.uiMode = panel.settingsGroup.uiModeSelector.index;

        // Color
        var colorIndex = panel.settingsGroup.colorSelector.index;
        DuESF.scriptSettings.data.common.highlightSelection = colorIndex;
        // Custom
        if (colorIndex == panel.settingsGroup.colorSelector.items.length -1 )
        {
            // Save and set
            var color = panel.settingsGroup.colorSelector.customColor;
            DuESF.scriptSettings.data.common.highlightColor = color.floatRGBA();
            DuColor.Color.APP_HIGHLIGHT_COLOR = color;
        }
        else if (colorIndex == 0)
        {
            DuESF.scriptSettings.data.common.highlightColor = DuColor.Color.AFTER_EFFECTS_BLUE;
            DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.AFTER_EFFECTS_BLUE;
        }
        else if (colorIndex == 1)
        {
            DuESF.scriptSettings.data.common.highlightColor = DuColor.Color.RX_PURPLE;
            DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.RX_PURPLE;
        }
        else if (colorIndex == 2)
        {
            DuESF.scriptSettings.data.common.highlightColor = DuColor.Color.RAINBOX_RED;
            DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.RAINBOX_RED;
        }
        else if (colorIndex == 3)
        {
            DuESF.scriptSettings.data.common.highlightColor = DuColor.Color.AE_ORANGE;
            DuColor.Color.APP_HIGHLIGHT_COLOR = DuColor.Color.AE_ORANGE;
        }

        // Language
        if (panel.settingsGroup.languageSelector)
        {
            DuESF.scriptSettings.data.common.language = DuTranslator.getLanguageId(panel.settingsGroup.languageSelector.label.text);
            DuESF.scriptSettings.data.common.currentLanguageName = panel.settingsGroup.languageSelector.label.text;
        }
            
        // Dev Mode
        DuESF.scriptSettings.data.common.debug = panel.settingsGroup.debugButton.value;
		DuESF.debug = panel.settingsGroup.debugButton.value;

        DuESF.scriptSettings.save();

        panel.mainGroup.visible = true;
        rootSettingsGroup.visible = false;

        panel.onApplySettings();

        // Restart script
        var ok = DuScriptUI.refreshPanel( panel, scriptFile );
        if (!ok) alert(DuScriptUI.String.APPLY_SETTINGS_ALERT);
    }

    panel.settingsGroup.resetButton.onClick = function()
    {
        DuESF.settings.reset();
        DuESF.scriptSettings.reset();
        panel.settingsGroup.reset();
        panel.onResetSettings();
    }

    panel.settingsGroup.updateButton.onClick = function()
    {
        DuScriptUI.checkUpdate(undefined, undefined, true);
    }

    // == Bottom Line
    var bottomUberGroup = mainGroupMarginBottom;
    // TODO Test in Ae
    /*var bottomUberGroup = DuScriptUI.group(panel.content, 'column');
    bottomUberGroup.alignment = ['fill', 'bottom'];
    bottomUberGroup.margins = 0;
    bottomUberGroup.spacing = 0;*/

    // Draw a thin line like other panels.
    //var bottomLine = DuScriptUI.separator( bottomUberGroup );
    if ( DuESF.rxVersionURL != '' ) {
        DuScriptUI.fundingBar = bottomUberGroup.add( 'progressbar' );
        DuScriptUI.fundingBar.maximumSize = [32000, 2];
        DuScriptUI.fundingBar.alignment = ['fill', 'top'];
        DuScriptUI.fundingBar.helpTip = DuScriptUI.String.FUNDING_BAR_TIP;
        DuScriptUI.updateFundingInfo();
    }

    panel.bottomGroup = DuScriptUI.group(bottomUberGroup, 'row');
    panel.bottomGroup.margins = 0;

    if (DuESF.bugReportURL != '')
    {
        var bugButton = DuScriptUI.addBugButton( panel.bottomGroup );
        bugButton.alignment = ['left', 'fill'];
    }
    
    if (addSettingsButton)
    {
        var settingsButton = DuScriptUI.button(
            panel.bottomGroup,
            '',
            w12_settings,
            DuScriptUI.String.EDIT_SETTINGS
            );
        settingsButton.alignment = ['left', 'fill'];

        settingsButton.onClick = function()
        {
            if (!rootSettingsGroup.visible)
            {
                if(panel.hasCommonSettings) panel.settingsGroup.reset();
                panel.mainGroup.visible = false;
                rootSettingsGroup.visible = true;
            }
            else
            {
                panel.mainGroup.visible = true;
                rootSettingsGroup.visible = false;
            }
        }

        settingsTitle.onClose = function()
        {
            if( panel.hasCommonSettings ) panel.settingsGroup.reset();
            panel.mainGroup.visible = true;
            rootSettingsGroup.visible = false;
        }

    }

    if (addHelpButton)
    {
        var helpButton = DuScriptUI.addHelpButton( panel.bottomGroup, false );
        helpButton.alignment = ['left', 'fill'];
    }

    var donateButton = DuScriptUI.addDonateButton( panel.bottomGroup, true);
    donateButton.alignment = ['left', 'fill'];

    var versionButton = DuScriptUI.versionButton(
        panel.bottomGroup
        );
    versionButton.alignment = ['right', 'bottom'];
    
    //Refresh button
    if ( DuESF.debug && (scriptFile instanceof File) && scriptFile.exists )
    {
        var refreshButton = panel.bottomGroup.add( 'button', undefined, 'R' );
        refreshButton.alignment = [ 'right', 'bottom' ];
        refreshButton.maximumSize = [ 20, 20 ];
        refreshButton.onClick = function()
        {
            DuScriptUI.refreshPanel( panel, scriptFile );
        };
    }

    return panel;
}

DuScriptUI.refreshPanel = function( panel, scriptFile )
{
    return DuScriptUI.refreshWindow( panel, scriptFile );
}

DuScriptUI.refreshWindow = function ( win, scriptFile )
{
    // If Panel is a window, close, and run script again
    if( win instanceof Window && scriptFile.exists)
    {
        win.close();
        $.evalFile( scriptFile );
        return true;
    }
    return false;
}

/**
 * Creates a popup to ask for a simple string
 * @param {string} title The title of the popup
 * @param {string} defaultString The placeholder for the edit text
 * @returns {DuPopup} The popup, with an <code>onAccept( str )</code> callback.
 */
DuScriptUI.stringPrompt = function ( title, defaultString )
{
    defaultString = def(defaultString, '');

    var nameEditor = DuScriptUI.popUp( title );
    nameEditor.content.alignment = ['fill','top'];
    
    nameEditor.editText = DuScriptUI.editText(
        nameEditor.content,
        '',
        '',
        '',
        defaultString
    )
    nameEditor.editText.alignment = ['fill','top'];

    var nameButtons = DuScriptUI.group( nameEditor.content );
    nameButtons.alignment = ['fill','top'];

    var nameOKButton = DuScriptUI.button(
        nameButtons,
        DuScriptUI.String.OK,
        DuScriptUI.Icon.CHECK,
        title,
        false,
        'row',
        'center'
    )

    nameEditor.previousString = '';

    nameEditor.onAccept = function( str ){};

    nameEditor.accept = function() {
        nameEditor.onAccept( nameEditor.editText.text );
        nameEditor.hidePopup();
        return nameEditor.editText.text;
    }

    nameEditor.setText = function (text) {
        nameEditor.previousString = text;
        nameEditor.editText.setText(text);
    }

    nameEditor.edit = function() {
        nameEditor.editText.clicked();
    }

    nameOKButton.onClick = nameEditor.accept;
    nameEditor.addEventListener('enterkey', nameEditor.accept );

    return nameEditor;
}// ==================== |--------| ====================
// ==================== | button | ====================
// ==================== |--------| ====================

/**
 * @class
 * @name DuButton
 * @classdesc For use with {@link DuScriptUI}.<br />
 * An Image Button.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.button} to create an Image Button.<br />
 * The Image Button inherits the <code>Group</code> object from ScriptUI and has all of its properties and methods.
 * @property {string} helpLink - A URL to a help page, shown on shift click on the button.
 * @property {Image} image - The scriptui object representing the image.
 * @property {StaticText} label - The label
 * @property {DuPopup} optionsPopup - A popup for .
 * @property {Group} optionsPanel - The ScriptUI Group where to add the options (child of the popup).
 * @property {DuButton~onClick} onClick - The function to execute when the button is clicked
 * @property {DuButton~onAltClick} onAltClick - The function to execute when the button is Alt + clicked
 * @property {DuButton~onCtrlClick} onCtrlClick - The function to execute when the button is Ctrl + clicked
 * @property {DuButton~onCtrlAltClick} onCtrlAltClick - The function to execute when the button is Ctrl + Alt + clicked
 * @property {DuButton~onOptions} onOptions - The function to execute when the options are called (Shift+CLick or click on the options button)
 * @category DuScriptUI
 */

/**
 * The function to execute when the button is clicked.
 * @callback DuButton~onClick
 * @memberof DuButton
 */

/**
 * The function to execute when the button is Alt + clicked.
 * @callback DuButton~onAltClick
 * @memberof DuButton
 */

/**
 * The function to execute when the button is Ctrl + clicked.
 * @callback DuButton~onCtrlClick
 * @memberof DuButton
 */

/**
 * The function to execute when the button is Ctrl + Alt + clicked.
 * @callback DuButton~onCtrlAltClick
 * @memberof DuButton
 */

/**
 * The function to execute when the options are called (Shift+CLick or click on the options button).<br/>
 * Use the <code>showUI</code> parameter to build the options when the button is clicked without showing any UI.
 * @callback DuButton~onOptions
 * @param {Boolean} showUI This is set to false when the button is clicked: use this parameter to build the options without showing any UI when needed on all button clicks.
 * @memberof DuButton
 */

/**
 * Changes the background color of the button.
 * @method
 * @memberof DuButton
 * @name setBackgroundColor
 * @param {DuColor} color - the color.
 */

/**
 * Changes the text color of the button.
 * @method
 * @memberof DuButton
 * @name setTextColor
 * @param {DuColor} color - the color.
 */

/**
 * Changes the image of the button.
 * @method
 * @memberof DuButton
 * @name setImage
 * @param {File|DuBInary} image - the image. Changing the image does not work with PNG as strings, a File must be passed.
 */

/**
 * Changes the helptip of the button.
 * @method
 * @memberof DuButton
 * @name setHelpTip
 * @param {string} helptip - the helptip.
 */

/**
 * Changes the text of the button.
 * @method
 * @memberof DuButton
 * @name setText
 * @param {string} text - the text.
 */

/**
 * Creates a button with an optionnal icon. Must have at least an icon or a text, or both.
 * @param {Panel|Window|Group}		container	- The ScriptUI Object which will contain and display the button.
 * @param {string}					[text]		- The label of the button. Default: empty string
 * @param {string|DuBInary}			[image]		- The path to the icon (or a PNG as a string representation). Default: empty string
 * @param {string}					[helpTip]		- The helptip. Default: empty string
 * @param {Boolean}					[addOptionsPanel=false]	- Adds a panel for options and a button to access it.
 * @param {Boolean}					[orientation='row']	- The orientation of the button (icon, text, options button). Default will be changed to 'column' if there's no text.
 * @param {Boolean}					[alignment='left']	- The alignment of the button content ('center', 'right' or 'left' for 'row', 'top' 'bottom', 'center' for column).
 * @param {Boolean}					[localize=true]	- Set to false if the text must not be translated.
 * @param {Boolean}					[ignoreUIMode=false]	- Will show texte even if the ui mode is set to > 1 in the script settings
 * @param {Boolean}					[optionsWithoutButton=false]	- Don't add an "ok" button to the options popup
 * @param {string}					[optionsButtonText]	- Change the displayed text of the bottom button of the options
 * @param {Boolean}					[optionsWithoutPanel=false]	- Don't create the options popup panel (use <code>DuButton.onOptions</code> to add your own callback when the options are requested)
 * @return {DuButton}			The image button created.
 */
DuScriptUI.button = function(container, text, image, helpTip, addOptionsPanel, orientation, alignment, localize, ignoreUIMode, optionsWithoutButton, optionsButtonText, optionsWithoutPanel) {
    if (!isdef( container )) {
        throw 'DuScriptUI: DuScriptUI.button(container, text, image, helpTip, imageOver):\nMissing argument: container.';
    }

    if (jstype(container) != 'group' && jstype(container) != 'panel' && jstype(container) != 'window') {
        throw 'DuScriptUI: DuScriptUI.button(container, text, image, helpTip):\nTypeError.\n\ncontainer has to be a Group/Panel/Window.\n\ncontainer is ' + jstype(container) + ' with value ' + container.toString();
    }

    var options = {};
    text = def(text, '');

    if (jstype(text) != 'string') options = text;
    options.text = def(options.text, text);

    image = def(image, '');
    helpTip = def(helpTip, '');
    addOptionsPanel = def(addOptionsPanel, false);
    orientation = def(orientation, 'row');
    localize = def(localize, true);
    ignoreUIMode = def(ignoreUIMode, false);
    optionsWithoutButton = def(optionsWithoutButton, false);
    optionsWithoutPanel = def(optionsWithoutPanel, false);
    optionsButtonText = def(optionsButtonText, options.text);
    
    options.image = def(options.image, image);
    options.helpTip = def(options.helpTip, helpTip);
    options.options = def(options.options, addOptionsPanel);
    options.orientation = def(options.orientation, orientation);
    options.localize = def(options.localize, localize);
    options.ignoreUIMode = def(options.ignoreUIMode, ignoreUIMode);
    options.optionsWithoutButton = def(options.optionsWithoutButton, optionsWithoutButton);
    options.optionsButtonText = def(options.optionsButtonText, optionsButtonText);
    options.optionsWithoutPanel = def(options.optionsWithoutPanel, optionsWithoutPanel);
    options.small = def(options.small, false);
    
    var commonSettings = def(DuESF.scriptSettings.data.common, {});
    var uiMode = def(commonSettings.uiMode, 0);
    if (uiMode >= 2 && options.image != '' && !options.ignoreUIMode) options.text = '';

    if (!isdef( alignment )) {
        if (options.orientation == 'row' && options.text != '') alignment = 'left';
        else if (options.orientation == 'row') alignment = 'center';
        else alignment = 'top';
    }
    options.alignment = def(options.alignment, alignment);

    if (options.localize) {
        options.text = tr(options.text);
        options.helpTip = tr(options.helpTip);
    }

    if (options.options) {
        if (options.helpTip != '') options.helpTip += '\n\n';
        options.helpTip += DuScriptUI.String.MORE_OPTIONS_TIP;
    }  

    if (options.image == '' && options.text == '') options.text = 'button';

    var duButton = container.add('group');
    duButton.orientation = options.orientation;
    duButton.alignment = ['fill', 'top'];
    duButton.spacing = 0;
    duButton.bgColor = DuColor.Color.TRANSPARENT;
    if (DuESF.host == DuESF.HostApplication.PHOTOSHOP) duButton.bgColor = DuColor.Color.APP_BACKGROUND_COLOR;
    duButton.textColor = DuColor.Color.APP_TEXT_COLOR;

    duButton.onClick = function() {};
    duButton.onAltClick = function() {};
    duButton.onCtrlAltClick = function() {};
    duButton.onCtrlClick = function() {};
    duButton.onShiftClick = function() {};
    duButton.onOptions = function() {};

    // Options panel
    if (options.options) {

        if (!options.optionsWithoutPanel) {
            // Create panel
            var optionsPanel = DuScriptUI.popUp(options.text == '' ? 'Options' : options.text);
            duButton.optionsPopup = optionsPanel;
            duButton.optionsPanel = DuScriptUI.group(optionsPanel.content, 'column');

            if (!options.optionsWithoutButton) {
                DuScriptUI.separator(optionsPanel.content);

                duButton.optionsButton = DuScriptUI.button( optionsPanel.content, {
                    text: options.optionsButtonText,
                    image: w12_check,
                    helpTip: options.helpTip
                });

                duButton.optionsButton.onClick = function() {
                    duButton.clicked();
                };
                duButton.optionsButton.onAltClick = function() {
                    duButton.altClicked();
                };
                duButton.optionsButton.onCtrlClick = function() {
                    duButton.ctrlClicked();
                };
                duButton.optionsButton.onCtrlAltClick = function() {
                    duButton.ctrlAltClicked();
                };
            }

            optionsPanel.tieTo(duButton, true);
        }

        // Add button
        if (options.text != '' && options.orientation != 'column') {
            var optionsButton = DuScriptUI.button(
                duButton,
                '',
                w12_options,
                options.text + '\nOptions'
            )
            optionsButton.alignment = ['left', 'center'];

            if (!options.optionsWithoutPanel) optionsPanel.tieTo(optionsButton);

            optionsButton.onClick = function () { duButton.onOptions(true); };
        }
    }

    var mainGroup = DuScriptUI.group(duButton, options.orientation);
    mainGroup.alignment = ['fill', 'fill'];
    mainGroup.margins = 0;

    //Add fillers to be able to click anywhere on the button
    if (options.text != '' && options.orientation == 'row') {
        duButton.fillerL = mainGroup.add('statictext', undefined, " ");
        duButton.fillerL.alignment = ['left', 'fill'];
        if (options.alignment == 'left' && !options.options && !options.small) duButton.fillerL.size = [18, -1];
        else if (options.alignment == 'left') duButton.fillerL.size = [2, -1];
    }

    // Add options.image
    if (options.image != '') {
        duButton.imageGroup = mainGroup.add('group');
        duButton.imageGroup.margins = 0;
        duButton.imageGroup.spacing = 0;
        duButton.imageGroup.alignment = ['fill', 'fill'];
        var subgroup = duButton.imageGroup.add('group');
        subgroup.margins = 2;
        subgroup.spacing = 0;
        subgroup.alignment = ['fill', 'fill'];
        if (options.image instanceof DuBinary) options.image = options.image.binAsString;
        duButton.image = subgroup.add('image', undefined, options.image);
        if (options.orientation == 'row') duButton.imageGroup.alignment = [options.alignment, 'center'];
        else duButton.imageGroup.alignment = ['center', options.alignment];
        // Bigger buttons on photoshop
        if (DuESF.host == DuESF.HostApplication.PHOTOSHOP) duButton.imageGroup.margins = 3;
        duButton.image.helpTip = options.helpTip;
    }

    // Another filler
    if (options.text != '' && options.image != '' && options.orientation == 'row') {
        duButton.fillerM = mainGroup.add('statictext', undefined, " ");
        duButton.fillerM.alignment = ['left', 'fill'];
        if (options.small) duButton.fillerM.size = [2, -1];
        else duButton.fillerM.size = [8, -1];
    }

    // Add text
    if (options.text != '') {
        duButton.label = mainGroup.add('statictext', undefined, options.text);
        duButton.label.helpTip = options.helpTip;
        if (options.orientation == 'row' && !options.small) duButton.label.alignment = [options.alignment, 'center'];
        else if (options.orientation == 'row') duButton.label.alignment = [options.alignment, 'bottom'];
        else duButton.label.alignment = ['center', options.alignment];
    }

    // Another filler
    if (options.text != '' && options.orientation == 'row') {
        duButton.fillerR = mainGroup.add('statictext', undefined, " ");
        duButton.fillerR.alignment = ['fill', 'fill'];
        if (options.alignment == 'right') duButton.fillerR.size = [10, -1];
    }

    //events
    duButton.clicked = function() {
        if (options.options) {
            if (!options.optionsWithoutPanel && !duButton.optionsPopup.built) {
                duButton.optionsPopup.build();
                duButton.optionsPopup.built = true;
            }
            duButton.onOptions(false);
        }
        DuDebug.safeRun(duButton.onClick);
    }

    duButton.shiftClicked = function() {
        if (options.options) {
            if (!options.optionsWithoutPanel && !duButton.optionsPopup.built) {
                duButton.optionsPopup.build();
                duButton.optionsPopup.built = true;
            }
            duButton.onOptions(true);
        }
        DuDebug.safeRun(duButton.onShiftClick);
    }

    duButton.altClicked = function() {
        if (options.options) {
            if (!options.optionsWithoutPanel && !duButton.optionsPopup.built) {
                duButton.optionsPopup.build();
                duButton.optionsPopup.built = true;
            }
            duButton.onOptions(false);
        }
        DuDebug.safeRun(duButton.onAltClick);
    }

    duButton.ctrlAltClicked = function() {
        if (options.options) {
            if (!options.optionsWithoutPanel && !duButton.optionsPopup.built) {
                duButton.optionsPopup.build();
                duButton.optionsPopup.built = true;
            }
            duButton.onOptions(false);
        }
        DuDebug.safeRun(duButton.onCtrlAltClick);
    }

    duButton.ctrlClicked = function() {
        if (options.options) {
            if (!options.optionsWithoutPanel && !duButton.optionsPopup.built) {
                duButton.optionsPopup.build();
                duButton.optionsPopup.built = true;
            }
            duButton.onOptions(false);
        }
        DuDebug.safeRun(duButton.onCtrlClick);
    }

    duButton.highlight = function(e) {
        e.stopPropagation();
        DuScriptUI.dimControls();

        if (duButton.label && !options.small) {
            DuScriptUI.setTextColor(duButton.label, DuColor.Color.APP_HIGHLIGHT_COLOR);
        }
        else {
            DuScriptUI.setBackgroundColor(mainGroup, DuColor.Color.APP_HIGHLIGHT_COLOR.darker());
        }
        
        DuScriptUI.highlightedControls.push(duButton);
    }

    duButton.dim = function() {
        DuScriptUI.setBackgroundColor(mainGroup, duButton.bgColor);
        if (duButton.label) DuScriptUI.setTextColor(duButton.label, duButton.textColor);
    }

    duButton.setBackgroundColor = function(color) {
        duButton.bgColor = color;
        duButton.dim();
    }

    duButton.setTextColor = function(color) {
        duButton.textColor = color;
        duButton.dim();
    }

    duButton.setImage = function(image) {
        if (options.image == '') return;
        if (image instanceof DuBinary) image = image.toFile();
        duButton.image.image = image;
    }

    duButton.setHelpTip = function(helpTip) {
        if (options.image != '') duButton.image.helpTip = helpTip;
        if (options.text != '') duButton.label.helpTip = helpTip;
    }

    duButton.setText = function(text) {
        if (options.text != '') duButton.label.text = text;
    }

    //add events
    function clickEvent(e) {
        // On After Effects, event is triggered multiple times...
        if (e.view.parent != mainGroup && DuESF.host == DuESF.HostApplication.AFTER_EFFECTS) return;

        if (e.shiftKey) duButton.shiftClicked();
        else if (e.altKey && e.ctrlKey) duButton.ctrlAltClicked();
        else if (e.altKey) duButton.altClicked();
        else if (e.ctrlKey) duButton.ctrlClicked();
        else duButton.clicked();
    }

    mainGroup.addEventListener('click', clickEvent, true);

    mainGroup.addEventListener("mouseover", duButton.highlight);

    duButton.dim();

    return duButton;
}

/**
 * @class
 * @name DuSmallButton
 * @classdesc For use with {@link DuScriptUI}.<br />
 * An Small Button.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.smallbutton} to create a Small Button.<br />
 * The Small Button inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {string} helpLink - A URL to a help page, shown on shift click on the button.
 * @property {StaticText} label - The label
 * @property {any} value - A user value stored in the button, which is passed to the onClick method
 * @property {DuSmallButton~onClick} onClick - The function to execute when the button is clicked
 * @category DuScriptUI
 */

/**
 * The function to execute when the button is clicked.<br />
 * The implementation of this function can take one parameter which is the used defined value of the button.
 * @callback DuSmallButton~onClick
 * @memberof DuSmallButton
 * @param {any} value - The used defined value of the button
 */

/**
 * Creates a small button.
 * @param {Panel|Window|Group}			container	- The ScriptUI Object which will contain and display the button.
 * @param {string}					text		- The label of the button. Default: empty string
 * @param {string}					[helpTip]		- The helptip. Default: empty string
 * @param {any}					[value]		- A user value stored in the button, which is passed to the onClick method
 * @return {DuButton}			The image button created.
 */
DuScriptUI.smallbutton = function(container, text, helpTip, value) {
    if (!isdef( helpTip )) helpTip = '';

    text = tr(text);
    helpTip = tr(helpTip);

    var smallButton = container.add('group');
    smallButton.orientation = 'row';
    smallButton.margins = 0;
    smallButton.alignment = ['fill', 'top'];
    smallButton.alignChildren = ['fill', 'fill'];
    smallButton.spacing = 0;

    smallButton.onClick = function( v ) {};
    smallButton.onAltClick = smallButton.onClick;
    smallButton.onCtrlAltClick = smallButton.onClick;
    smallButton.onCtrlClick = smallButton.onClick;
    smallButton.label = smallButton.add('statictext', undefined, text);
    smallButton.label.helpTip = helpTip;
    smallButton.label.justify = 'center';

    smallButton.value = value;
    smallButton.helpLink = '';

    //events
    smallButton.clicked = function() {
        smallButton.onClick( smallButton.value );
    }

    smallButton.shiftClicked = function() {
        if (duButton.helpLink != '') {
            DuSystem.openURL(smallButton.helpLink);
        }
    }

    smallButton.altClicked = function() {
        smallButton.onAltClick( smallButton.value );
    }

    smallButton.ctrlAltClicked = function() {
        smallButton.onCtrlAltClick( smallButton.value );
    }

    smallButton.ctrlClicked = function() {
        smallButton.onCtrlClick( smallButton.value );
    }

    smallButton.highlight = function(e) {
        e.stopPropagation();
        DuScriptUI.dimControls();

        if (smallButton.label) DuScriptUI.setTextColor(smallButton.label, DuColor.Color.VERY_DARK_GREY);
        DuScriptUI.setBackgroundColor(smallButton, DuColor.Color.LIGHT_GREY);

        DuScriptUI.highlightedControls.push(smallButton);
    }

    smallButton.dim = function() {
        if (smallButton.label) DuScriptUI.setTextColor(smallButton.label, DuColor.Color.APP_TEXT_COLOR);
        DuScriptUI.setBackgroundColor(smallButton, DuColor.Color.TRANSPARENT);
    }

    //add events
    smallButton.addEventListener('click', function(e) {
        if (e.shiftKey) smallButton.shiftClicked();
        else if (e.altKey && e.ctrlKey) smallButton.ctrlAltClicked();
        else if (e.altKey) smallButton.altClicked();
        else if (e.ctrlKey) smallButton.ctrlClicked();
        else smallButton.clicked();
    }, true);


    smallButton.addEventListener("mouseover", smallButton.highlight);
    if (smallButton.label) smallButton.label.addEventListener("mouseover", smallButton.highlight);

    return smallButton;
}// ==================== |------| ====================
// ==================== | help | ====================
// ==================== |------| ====================

/**
 * Creates a button displaying the version of the script and redirecting to the about url.
 * @param {Panel|Window|Group} container - The ScriptUI Object which will contain and display the button.
 * @param {string|DuBinary} [image=DuESF.scriptIcon] - The path to the icon or a png binstring. Default: empty string
 * @return {DuButton} The version button created.
 */
DuScriptUI.versionButton = function( container, image )
{
    image = def(image, DuESF.scriptIcon);

    var button = DuScriptUI.button(
        container,
        'v' + DuESF.scriptVersion.fullVersion,
        image,
        DuESF.companyName + '\n' + DuESF.scriptName + ' v' + DuESF.scriptVersion.fullVersion,
        false,
        undefined,
        undefined,
        false
    )

    //button.bgColor = DuColor.Color.TRANSPARENT;
    button.dim();

    if (DuESF.aboutURL != '') button.onClick = function() {
        DuSystem.openURL(DuESF.aboutURL);
    };

    return button;
}

/**
 * Creates a button opening the bug report url.
 * @param {Panel|Window|Group} container - The ScriptUI Object which will contain and display the button.
 * @param {bool} [showLabel=false] - When true, the button includes a "Bug Report" label.
 * @return {DuButton} The bug button created.
 */
DuScriptUI.addBugButton = function( container, showLabel )
{
    showLabel = def(showLabel, false);

    var label = DuScriptUI.String.BUG_REPORT;
    var helpTip = DuScriptUI.String.BUG_REPORT_TIP;
    label = tr(label);
    helpTip = tr(helpTip);

    var button = DuScriptUI.button(
        container,
        showLabel ? label : "",
        w12_bugreport,
        helpTip
        );
    button.onClick = function ()
    {
        DuSystem.openURL( DuESF.bugReportURL );
    }
    button.onAltClick = function ()
    {
        DuSystem.openURL( 'http://bat-ultra-bunny.tumblr.com' );
    }
    return button;
}

/**
 * Creates a button opening the help panel.
 * @param {Panel|Window|Group} container - The ScriptUI Object which will contain and display the button.
 * @param {bool} [showLabel=false] - When true, the button includes a "Help" label.
 * @return {DuButton} The help button created.
 */
DuScriptUI.addHelpButton = function( container, showLabel )
{
    showLabel = def(showLabel, false);

    var label = DuScriptUI.String.HELP;
    var helpTip = DuScriptUI.String.HELP_TIP;
    label = tr(label);
    helpTip = tr(helpTip);

    var button = DuScriptUI.button(
        container,
        showLabel ? label : "",
        w12_help,
        helpTip
    );

    button.onClick = function ()
    {
        DuSystem.openURL( DuESF.docURL );
    }
    button.onAltClick = function ()
    {
        DuSystem.openURL( 'http://bat-ultra-bunny.tumblr.com' );
    }

    return button;
}

/**
 * Creates a button opening the link for like/follow/donation
 * @param {Panel|Window|Group} container - The ScriptUI Object which will contain and display the button.
 * @param {bool} [showLabel=false] - When true, the button includes a <code>"I ♥ " + DuESF.scriptName</code> label.
 * @return {DuButton} The like button created.
 */
DuScriptUI.addDonateButton = function ( container, showLabel )
{
    showLabel = def(showLabel, false);

    var defaultLabel = "I \u2665 " + DuESF.scriptName;

    var button = DuScriptUI.button(
        container,
        {
            text: showLabel ? defaultLabel : "",
            image: w12_heart,
            helpTip: defaultLabel,
            small: true
        }
    );

    DuScriptUI.fundingLabel = button.label;

    button.onClick = function ()
    {
        DuSystem.openURL( DuESF.donateURL );
    }
    button.onAltClick = function ()
    {
        DuSystem.openURL( 'http://patreon.com/duduf' );
    }

    DuScriptUI.updateFundingInfo();

    return button;
}

/**
 * Displays a prompt to select the language of the script.<br />
 * Won't do nothing if the script already has a language set in the settings.<br />
 * Use this method before launching the script. 
 * @param {function} callback - The function to execute when the user has chosen the language.<br />
 * This function should be the one which loads the script.
 * @param {Panel|Window} [ui]	- A container to display the UI. A modal Dialog is created if omitted
 */
DuScriptUI.askLanguage = function ( callback, ui )
{
    if (! (ui instanceof Panel || ui instanceof Window) )
    {
        ui = new Window('dialog', DuScriptUI.String.ASK_FILES_NETWORK_ACCESS_TITLE)
    }

    var commonSettings = def( DuESF.scriptSettings.data.common, {} );
    var currentLanguageName = def (commonSettings.currentLanguageName, '');

    DuTranslator.getAvailable();
    var languages = DuTranslator.getPrettyNames();
    var languageCount = languages.length;

    if (currentLanguageName != '' || languageCount <= 1)
    {
        callback()
        return;
    }

    var ui_languageGroup = DuScriptUI.group( ui, 'column' );

    ui_languageGroup.add('statictext', undefined, "EO: Selektu la lingvo kiu vi volas uzi per tio softvaro.", { multiline: true } );
    ui_languageGroup.add('statictext', undefined, "EN: Select the language you wish to use with this software.", { multiline: true } );

    var currentIndex = 0;
    var languageSelector = DuScriptUI.selector( ui_languageGroup, DuScriptUI.String.LANGUAGE_TIP );
    for (var i = 0; i < languageCount; i++ )
    {
        languageSelector.addButton(
            languages[i],
            w16_language
        );
        if (languages[i] == 'Esperanto') currentIndex = i;
    }

    languageSelector.setCurrentIndex( currentIndex );

    var okButton = DuScriptUI.button(
        ui_languageGroup,
        DuScriptUI.String.APPLY,
        w12_check,
        DuScriptUI.String.APPLY_SETTINGS,
        false,
        'row',
        'center'
    )

    okButton.onClick = function()
    {
        // Save settings
        DuESF.scriptSettings.data.common = def( DuESF.scriptSettings.data.common, {} );
        DuESF.scriptSettings.data.common.language = DuTranslator.getLanguageId(languageSelector.label.text);
        DuESF.scriptSettings.data.common.currentLanguageName = languageSelector.label.text;
        DuTranslator.setPrettyLanguage( languageSelector.label.text );

        DuESF.scriptSettings.save();

        // Delete
        ui.remove( ui_languageGroup );

        callback();
    }

    DuScriptUI.showUI( ui, false );
    DuScriptUI.uiShown = false;
}

/**
 * Checks if the script can be updated
 * @param {function} [callback] - The function to execute when the user has clicked on the "dismiss" button.
 * @param {Panel|Window} [ui]	- A container to display the UI. A modal Dialog is created if omitted
 * @param {Boolean} [showAlert] Whether to show an alert if the check failed or if the version is up-to-date.
 */
DuScriptUI.checkUpdate = function ( callback, ui, showAlert )
{
    var noCallback = false;
    if (!isdef( callback ))
    {
        callback = function(){};
        var noCallback = true;
    }
    showAlert = def(showAlert, false);
    if (DuESF.debug) showAlert = true;

    //Just once a day
    DuESF.scriptSettings.data.common  = def(DuESF.scriptSettings.data.common, {});
    var latestUpdateCheck = def( DuESF.scriptSettings.data.common.latestUpdateCheck, 0);
    var now = Date.now();
    // 24h
    if (now - latestUpdateCheck < 86400000 && !showAlert && !DuESF.debug) {
        // Just update funding info
        DuScriptUI.updateFundingInfo();
        return callback();
    }
    DuESF.scriptSettings.data.common.latestUpdateCheck = now;
    DuESF.scriptSettings.save();

    if ( DuESF.rxVersionURL == '' ) return callback();

    // Get the version & info from the server
    var update = DuVersion.checkUpdate();

    // Compare
    if (!update)
    {
        if (noCallback) return;
        return callback();
    }
    if (!update.success)
    {
        if (showAlert) alert("Sorry, something failed...\n\n" + update.message);
        if (noCallback) return;
        return callback();
    }

    // Update funding info
    if (update.monthlyFund && update.fundingGoal) {
        DuScriptUI.updateFundingInfo(update.monthlyFund, update.fundingGoal);
    }

    if (!update.update)
    {
        if (showAlert) alert("This version is up-to-date, congratulations!");
        if (noCallback) return;
        return callback();
    }

    // Show window if update
    var reuseUI = true;
    if (! (ui instanceof Panel || ui instanceof Window) )
    {
        reuseUI = false;
        ui = new Window('dialog', DuScriptUI.String.NEW_VERSION_TITLE,undefined,
        {
            resizeable: true
        } );
    }

    var ui_updateGroup = DuScriptUI.group( ui, 'column' );
    ui_updateGroup.alignment = ['fill', 'fill'];

    var titleGroup = DuScriptUI.group( ui_updateGroup );
    titleGroup.alignment = ['fill', 'top'];
    DuScriptUI.setBackgroundColor( titleGroup, DuColor.Color.DARK_GREY );

    DuScriptUI.staticText(
        titleGroup,
        DuString.args( "New {#}!", [ DuESF.scriptName ] ),
        DuColor.Color.APP_TEXT_COLOR.lighter(130)
        ).alignment = ['center','top'];

    var newVersionGroup = DuScriptUI.group( ui_updateGroup );
    newVersionGroup.alignment = ['fill', 'top'];
    newVersionGroup.margins = 2;

    DuScriptUI.staticText(
        newVersionGroup,
        "New version" + ": "
        );

    DuScriptUI.staticText(
        newVersionGroup,
        update.version,
        DuColor.Color.APP_TEXT_COLOR.lighter(115)
        );

    var descriptionGroup = DuScriptUI.group( ui_updateGroup );
    descriptionGroup.margins = 2;
    descriptionGroup.alignment = ['fill','fill'];
    DuScriptUI.setBackgroundColor( descriptionGroup, DuColor.Color.OBSIDIAN );

    var descriptionText = descriptionGroup.add("edittext", undefined, update.description, {multiline:true});
    descriptionText.alignment = ['fill','fill'];
    descriptionText.minimumSize = [-1,100];
    DuScriptUI.setBackgroundColor( descriptionText, DuColor.Color.OBSIDIAN );

    DuScriptUI.staticText(
        ui_updateGroup,
        "Current version: " + DuESF.scriptVersion.fullVersion,
        DuColor.Color.APP_TEXT_COLOR.darker(160)
        ).alignment = ['fill', 'bottom'];

    if (update.downloadURL)
    {
        var downloadButton = DuScriptUI.button(
            ui_updateGroup,
            "Download",
            DuScriptUI.Icon.DOWNLOAD,
            "Download the new version now."
        );
        downloadButton.alignment = ['fill','bottom'];

        downloadButton.onClick = function() {
            DuSystem.openURL( update.downloadURL );
        };
    }
    
    if (update.changelogURL)
    {
        var changelogButton = DuScriptUI.button(
            ui_updateGroup,
            "Changelog",
            DuScriptUI.Icon.LIST,
            "Read all the details about what's changed."
        );
        changelogButton.alignment = ['fill','bottom'];

        changelogButton.onClick = function() {
            DuSystem.openURL( update.changelogURL );
        };
    }

    if (update.donateURL)
    {
        var donateButton = DuScriptUI.button(
            ui_updateGroup,
            "I \u2665 " + DuESF.scriptName,
            DuScriptUI.Icon.HEART,
            "We need you!\nMake a donation to help us continue to release and update free software."
        );
        donateButton.alignment = ['fill','bottom'];

        donateButton.onClick = function()
        {
            DuSystem.openURL( update.donateURL );
        };
        donateButton.onAltClick = function ()
        {
            DuSystem.openURL( 'http://patreon.com/duduf' );
        }
    }

    var validButton = DuScriptUI.button(
        ui_updateGroup,
        noCallback ? "Close" : DuString.args("Update later"),
        noCallback ? DuScriptUI.Icon.CLOSE : DuScriptUI.Icon.NEXT,
        noCallback ? "Close" : DuString.args("Continue to {#}", [DuESF.scriptName])
    );
    validButton.onClick = function()
    {
        // Delete or hide ui
        if (reuseUI) ui.remove( ui_updateGroup );
        else ui.close();
        
        if (!noCallback) callback();

    }
    
    DuScriptUI.showUI( ui, false );
    DuScriptUI.uiShown = false;
}

DuScriptUI.updateFundingInfo = function (fund, goal) {

    DuESF.scriptSettings.data.funding = def(DuESF.scriptSettings.data.funding, {});
    DuESF.scriptSettings.data.funding.monthlyFund = def(DuESF.scriptSettings.data.funding.monthlyFund, 0);
    DuESF.scriptSettings.data.funding.fundingGoal = def(DuESF.scriptSettings.data.funding.fundingGoal, 4000);
    
    fund = def(fund, DuESF.scriptSettings.data.funding.monthlyFund);
    goal = def(goal, DuESF.scriptSettings.data.funding.fundingGoal);

    if (fund) {
        fund = parseFloat(fund);
        DuESF.scriptSettings.data.funding.monthlyFund = fund;        
    }
    if (goal) {
        goal = parseFloat(goal);
        DuESF.scriptSettings.data.funding.fundingGoal = goal;
    }

    DuESF.scriptSettings.save();

    if (!fund || !goal && DuScriptUI.fundingBar) {
        DuScriptUI.fundingBar.value = 0;
        DuScriptUI.fundingBar.helpTip = DuScriptUI.String.FUNDING_BAR_TIP;
        return;
    }

    var ratio = Math.round( fund / goal * 100);
    var helpTip = DuScriptUI.String.FUNDING_BAR_TIP + '\n\n' + 
            DuString.args( DuScriptUI.String.FUNDING_BAR_TIP_DETAILS, [DuESF.companyName, fund, ratio, goal] );

    if (DuScriptUI.fundingBar) {
        DuScriptUI.fundingBar.value = ratio;
        fund = Math.round( fund );
        DuScriptUI.fundingBar.helpTip = helpTip
    }
    if (DuScriptUI.fundingLabel) {
        DuScriptUI.fundingLabel.helpTip = helpTip;
        DuScriptUI.fundingLabel.text = ratio + '%';
    }
    
}// ==================== |-------| ====================
// ==================== | style | ====================
// ==================== |-------| ====================

/**
 * Resets the layout of the whole ui containing a scriptUI item.
 * @param {ScriptUI} item - The ScriptUI element which needs to be resized
 * @param {Boolean} [force] - Needs to be true if you need to layout before <code>DuESF.state</code> is <code>DuESF.State.RUNTIME</code>.<br />
 * That should be the case only for the main UI; Note that you should not need it anyway, {@link DuScriptUI.showUI} does that for you.
 */
DuScriptUI.layout = function( item, force )
{
    force = def( force, false );
    if (DuESF.state != DuESF.State.RUNTIME && !force) return;
    item.layout.layout( true );
    item.layout.resize();
}

/**
 * Changes the color of the text of a ScriptUI Object
 * @param {ScriptUI} text - The ScriptUI Object
 * @param {DuColor} color - The new color
 * @param {Boolean} [adjusted=false] - lightens the color if the brightness setting of Ae is not set on the darkest one
 */
DuScriptUI.setTextColor = function( text, color, adjusted )
{
    if ( !isdef( text ) ) throw "You must provide a ScriptUI Control to change the color of the text";
    adjusted = def( adjusted, false );

    var g = text.graphics;
    var c;
    if (adjusted) c = color.adjusted();
    else c = color;
    var textPen = g.newPen( g.PenType.SOLID_COLOR, c.floatRGBA(true), 1 );
    g.foregroundColor = textPen;
}

/**
 * Changes the color of the background of a ScriptUI Object
 * @param {ScriptUI} uiItem - The ScriptUI Object
 * @param {Array} color - The new color [R,V,B,A] Array
 * @param {Boolean} [adjusted=true] - lightens the color if the brightness setting of Ae is not set on the darkest one
 */
DuScriptUI.setBackgroundColor = function( uiItem, color, adjusted )
{
    if ( !isdef( uiItem ) ) throw "You must provide a ScriptUI Control to change the color of the background";
    adjusted = def( adjusted, true );
   
    var g = uiItem.graphics;
    var c;
    if (adjusted) c = color.adjusted();
    else c = color;
    var brush = g.newBrush( g.BrushType.SOLID_COLOR, c.floatRGBA(true) );
    g.backgroundColor = brush;
}// ==================== |--------| ====================
// ==================== | layout | ====================
// ==================== |--------| ====================


/**
 * Adds a group in a container, using  DuScriptUI default alignments, and DuScriptUI.defaultSpacing. Margins are set to 0.
 * @param {Panel|Window|Group} container Where to create the group
 * @param {string} [orientation] The orientation to use. One of "column", "row" or "stack". By default, "column" if added in a row, "row" if added in a column.
 * @return {Group}	The group created
 */
DuScriptUI.group = function( container, orientation )
{
    var group = container.add( "group" );
    group.spacing = 0;
    group.margins = 0;
    if ( orientation !== undefined ) group.orientation = orientation;
    if ( group.orientation === "row" )
    {
        group.alignChildren = DuScriptUI.defaultRowAlignment;
    }
    else if ( group.orientation === "column" )
    {
        group.alignChildren = DuScriptUI.defaultColumnAlignment;
    }
    else
    {
        group.alignChildren = DuScriptUI.defaultStackAlignment;
    }

    group.addEventListener( "mouseover", DuScriptUI.dimControls );

    return group;
}

/**
 * @class
 * @name DuSeparator
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A DuSeparator.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.separator} to create a DuSeparator.<br />
 * The DuSeparator inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {StaticText|CheckBox} label - the label
 * @property {boolean} checkable - Read-Only | true if a checkbox is displayed
 * @category DuScriptUI
 */

/**
 * Adds separator with an optionnal name in the group
 * @memberof DuScriptUI
 * @param {Panel|Window|Group} container - Where to create the separator
 * @param {string} [name] - The name displayed
 * @param {boolean} [checkable=false] - When true, adds a checkbox to the separator
 * @param {boolean} [drawLine=true] - Draws a line when there is no name. When false, the separator is an empty space
 * @param {boolean} [translatable=true] - If false, the name won't be translated
 * @return {DuSeparator} The separator
 */
DuScriptUI.separator = function( container, name, checkable, drawLine, translatable )
{
    name = def(name, '' );
    checkable = def( checkable, false );
    drawLine = def( drawLine, true );
    translatable = def(translatable, true);

    if(translatable) name = tr( name );

    var separator = DuScriptUI.group( container );
    separator.margins = 0;
    separator.checkable = checkable;

    separator.label = null;
    if ( name != '' || checkable )
    {
        if ( checkable ) separator.label = separator.add( 'checkbox', undefined, name );
        else separator.label = separator.add( 'statictext', undefined, name );
        separator.label.alignment = [ 'center', 'bottom' ];
        if ( drawLine ) DuScriptUI.setBackgroundColor( separator, DuColor.Color.DARK_GREY );
    }
    else if ( drawLine )
    {
        DuScriptUI.setBackgroundColor( separator, DuColor.Color.ABYSS_GREY );
        var size = 1;
        if (DuESF.host == DuESF.HostApplication.AFTER_EFFECTS) size = 2;
        if (container.orientation == 'row')
        {
            separator.alignment = ['left', 'fill'];
            separator.minimumSize = [size,-1];
        }
        else
        {
            separator.alignment = [ 'fill', 'top' ];
            separator.minimumSize = [-1,size];
        }
    }

    separator.addEventListener( "mouseover", DuScriptUI.dimControls );

    return separator;
}
// ==================== |----------| ====================
// ==================== | checkbox | ====================
// ==================== |----------| ====================


/**
 * @class
 * @name DuCheckBox
 * @classdesc For use with {@link DuScriptUI}.<br />
 * An Image Checkbox.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.checkBox} to create an Image Checkbox.<br />
 * The Image Checkbox inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {Image} image The scriptui object representing the image, if any
 * @property {StaticText} label The label, if any
 * @property {string} text The current text
 * @property {string} textChecked The text to display when the checkbox is checked
 * @property {string} defaultText The text to display when the checkbox is unchecked
 * @property {boolean} checked The checked state of the button
 * @property {DuColor} textColor The color of the text of the label
 * @property {DuCheckBox~onClick} onClick The function to execute when the button is clicked
 * @category DuScriptUI
 */

/**
 * The function to execute when the button is clicked.
 * @callback DuCheckBox~onClick
 * @memberof DuCheckBox
 */

/**
 * Sets the checked state of the button
 * @method
 * @memberof DuCheckBox
 * @name setChecked
 * @param {boolean} [checked=true] - The state
 */

/**
 * Creates a checkbox with an optionnal icon. Must have at least an icon or a text, or both.
 * @param {Panel|Window|Group} container The ScriptUI Object which will contain and display the button.
 * @param {string} text The label of the button. Default: empty string
 * @param {string|DuBinary} [image] The path to the icon. Default: empty string
 * @param {string} [helpTip=''] The helptip. Default: empty string
 * @param {string} [textChecked=text] The label of the button displayed when it is checked.
 * @param {string|DuBinary} [imageChecked] The image to show when it is checked
 * @param {string} [orientation='row'] The orientation
 * @return {DuCheckBox} The checkbox created.
 */
DuScriptUI.checkBox = function( container, text, image, helpTip, textChecked, imageChecked, orientation, isTab )
{
    var options = {};
    text = def(text, '');
    if (jstype(text) != 'string') options = text;
    options.text = def(options.text, text);
    
    isTab = def(isTab, false);
    options.isTab = def(options.isTab, isTab);

    orientation = def(orientation, 'row');
    options.orientation = def(options.orientation, orientation);
    
    textChecked = def(textChecked, options.text);
    options.textChecked = def(options.textChecked, textChecked);

    image = def(image, '');
    options.image = def(options.image, image);

    imageChecked = def(imageChecked, options.image);
    options.imageChecked = def(options.imageChecked, imageChecked);

    helpTip = def(helpTip, '');
    options.helpTip = def(options.helpTip, helpTip);

    if ( !container ) return null;

    if (options.isTab || options.orientation == 'column')
    {
        var commonSettings = def( DuESF.scriptSettings.data.common, {} );
        var uiMode = def(commonSettings.uiMode, 0);
        if (uiMode >= 2 && options.image != '') text = '';
    }

    //translate text and options.helpTip
    options.text = tr( options.text );
    options.helpTip = tr( options.helpTip );
    options.textChecked = tr( options.textChecked );

    //create ui
    var duCheckBox = container.add( 'group' );
    duCheckBox.orientation = 'column';

    if (options.isTab || options.orientation == 'column') duCheckBox.alignment = ['left', 'fill'];
    else duCheckBox.alignment = [ 'fill', 'top' ];

    if (options.isTab || options.text == '' || options.orientation == 'column' ) duCheckBox.hasIcon = false;
    else duCheckBox.hasIcon = true;

    if (options.image != '') duCheckBox.hasImage = true;
    else duCheckBox.hasImage = false;

    if (options.text != '') duCheckBox.hasLabel = true;
    else duCheckBox.hasLabel = false;   

    //if no options.image and no options.text, at least the icon
    if ( options.image == '' && options.text == '' ) duCheckBox.hasIcon = true;

    // attributes
    duCheckBox.onClick = function() {};
    duCheckBox.onAltClick = function() {};
    duCheckBox.checked = duCheckBox.value = false;
    duCheckBox.textChecked = options.textChecked;
    duCheckBox.defaultText = options.text;
    duCheckBox.text = options.text;
    duCheckBox.helpLink = '';
    duCheckBox.textColor = DuColor.Color.APP_TEXT_COLOR;

    duCheckBox.mainGroup = DuScriptUI.group(duCheckBox, 'column');
    duCheckBox.mainGroup.margins = 1;
    duCheckBox.mainGroup.alignment = ['fill', 'fill'];
    
    duCheckBox.buttonGroup = DuScriptUI.group(duCheckBox.mainGroup, options.orientation);
    duCheckBox.buttonGroup.alignment = ['fill', 'top'];

    //the checkbox icon & options.image group
    duCheckBox.imageGroup = duCheckBox.buttonGroup.add('group');
    duCheckBox.imageGroup.margins = 0;
    duCheckBox.imageGroup.spacing = 4;
    if ( options.text == '' || options.orientation == 'column' ) duCheckBox.imageGroup.alignment = [ 'center', 'center' ];
    else duCheckBox.imageGroup.alignment = [ 'left', 'center' ];

    if (duCheckBox.hasIcon)
    {
        var subgroup = duCheckBox.imageGroup.add('group');
        subgroup.orientation = 'stacked';
        subgroup.margins = 0;
        subgroup.spacing = 0;
        subgroup.size = [12,12];

        duCheckBox.checkboxIcon = subgroup.add( 'image', undefined, DuScriptUI.Icon.BOX_UNCHECKED.binAsString );
        duCheckBox.checkboxIcon.helpTip = options.helpTip;

        duCheckBox.checkboxIconChecked = subgroup.add( 'image', undefined, DuScriptUI.Icon.BOX_CHECKED.binAsString );
        duCheckBox.checkboxIconChecked.helpTip = options.helpTip;
        duCheckBox.checkboxIconChecked.visible = false;
    }

    //checkbox icon
    if ( duCheckBox.hasImage )
    {
        var subgroup = duCheckBox.imageGroup.add('group');
        subgroup.orientation = 'stacked';
        subgroup.margins = 2;
        subgroup.spacing = 0;
        subgroup.minimumSize = [20,20];

        if ( options.image instanceof DuBinary ) options.image = options.image.binAsString;
        if ( options.imageChecked instanceof DuBinary ) options.imageChecked = options.imageChecked.binAsString;

        if (options.imageChecked != '')
        {
            duCheckBox.imageChecked = subgroup.add( 'image', undefined, options.imageChecked );
            duCheckBox.imageChecked.helpTip = options.helpTip;
            duCheckBox.imageChecked.visible = false;
            duCheckBox.imageChecked.alignment = ['center', 'center'];
        }
        
        duCheckBox.image = subgroup.add( 'image', undefined, options.image);
        duCheckBox.image.helpTip = options.helpTip;
        duCheckBox.image.alignment = ['center', 'center'];
    }
 
    //Add fillers to be able to click anywhere on the button
    if ( duCheckBox.hasLabel && !options.isTab && options.orientation != 'column')
    {
        duCheckBox.fillerM = duCheckBox.buttonGroup.add( 'statictext', undefined, " " );
        duCheckBox.fillerM.alignment = [ 'left', 'fill' ];
        duCheckBox.fillerM.size = [ 7, -1];
    }

    // label
    if ( duCheckBox.hasLabel )
    {
        var labelGroup = duCheckBox.buttonGroup.add('group');
        labelGroup.orientation = 'stacked';
        labelGroup.margins = 0;
        if (options.orientation == 'column') labelGroup.alignment = [ 'center', 'top' ];
        else labelGroup.alignment = [ 'left', 'fill' ];

        duCheckBox.label = labelGroup.add( 'statictext', undefined, options.text );
        duCheckBox.label.helpTip = options.helpTip;
        if (options.orientation == 'column') duCheckBox.label.alignment = [ 'center', 'top' ];
        else duCheckBox.label.alignment = [ 'left', 'fill' ];
        DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_TEXT_COLOR );
        
        duCheckBox.labelChecked = labelGroup.add( 'statictext', undefined, options.textChecked );
        duCheckBox.labelChecked.helpTip = options.helpTip;
        duCheckBox.labelChecked.visible = false;
        if (options.orientation == 'column') duCheckBox.labelChecked.alignment = [ 'center', 'top' ];
        else duCheckBox.labelChecked.alignment = [ 'left', 'fill' ];
        DuScriptUI.setTextColor( duCheckBox.labelChecked, DuColor.Color.APP_HIGHLIGHT_COLOR );
    }

    //Add fillers to be able to click anywhere on the button
    if ( duCheckBox.hasLabel && !options.isTab && options.orientation != 'column' )
    {
        duCheckBox.fillerR = duCheckBox.buttonGroup.add( 'statictext', undefined, "" );
        duCheckBox.fillerR.alignment = [ 'fill', 'fill' ];
    }

    // outline
    if ( options.isTab )
    {
        duCheckBox.outLine = duCheckBox.mainGroup.add( 'group' );
        duCheckBox.outLine.margins = 0;
        duCheckBox.outLine.minimumSize.height = 2;
        duCheckBox.outLine.alignment = [ 'fill', 'bottom' ];
    }

    duCheckBox.setChecked = function( c )
    {
        c = def(c, true);
        duCheckBox.checked = duCheckBox.value = c;

        if ( c )
        {
            if (options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.APP_TEXT_COLOR );
            else 
            {
                //icon
                if ( duCheckBox.hasIcon )
                {
                    duCheckBox.checkboxIconChecked.visible = true;
                    duCheckBox.checkboxIcon.visible = false;
                }

                //image
                if ( duCheckBox.hasImage ) 
                {
                    duCheckBox.imageChecked.visible = true;
                    duCheckBox.image.visible = false;
                    if (!duCheckBox.hasIcon && !duCheckBox.hasLabel && options.imageChecked == '') DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );
                }

                //label
                if ( duCheckBox.hasLabel )
                {
                    duCheckBox.label.visible = false;
                    duCheckBox.labelChecked.visible = true;
                    duCheckBox.text = duCheckBox.textChecked;
                    DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_HIGHLIGHT_COLOR );
                }
            }
        }
        else 
        {
            if (options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.TRANSPARENT );
            else 
            {
                //icon
                if ( duCheckBox.hasIcon )
                {
                    duCheckBox.checkboxIconChecked.visible = false;
                    duCheckBox.checkboxIcon.visible = true;
                }

                //image
                if ( duCheckBox.hasImage ) 
                {
                    duCheckBox.imageChecked.visible = false;
                    duCheckBox.image.visible = true;
                    if (!duCheckBox.hasIcon && !duCheckBox.hasLabel) DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.TRANSPARENT );
                }

                //label
                if ( duCheckBox.hasLabel )
                {
                    duCheckBox.label.visible = true;
                    duCheckBox.labelChecked.visible = false;
                    duCheckBox.text = duCheckBox.defaultText;
                    DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_TEXT_COLOR );
                }
            }
        }
    }

    duCheckBox.clicked = function( e )
    {
        e.stopPropagation();

        if ( e.shiftKey )
        {
            if ( duCheckBox.helpLink != '' )
            {
                DuSystem.openURL( duCheckBox.helpLink );
            }
            return;
        }

        duCheckBox.setChecked( !duCheckBox.checked );
        DuDebug.safeRun(duCheckBox.onClick);
    }

    duCheckBox.altClicked = function()
    {
        DuDebug.safeRun(duCheckBox.onAltClick);
    }

    duCheckBox.highlight = function( e )
    {
        e.stopPropagation();
        DuScriptUI.dimControls();

        if ( duCheckBox.checked )
        {
            if (duCheckBox.hasLabel && !options.isTab) DuScriptUI.setTextColor( duCheckBox.labelChecked, DuColor.Color.APP_HIGHLIGHT_COLOR.lighter(150) );
            
            if (!duCheckBox.hasLabel && !options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.buttonGroup, DuColor.Color.APP_HIGHLIGHT_COLOR );
            // image
            if (!options.isTab && duCheckBox.hasImage && !duCheckBox.hasIcon && !duCheckBox.hasLabel && options.imageChecked == '') DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.APP_HIGHLIGHT_COLOR );

            //outline
            if ( options.isTab )
            {
                DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.APP_HIGHLIGHT_COLOR );
                if (duCheckBox.hasLabel) DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_HIGHLIGHT_COLOR );
            }
        }
        else 
        {
            if (duCheckBox.hasLabel && !options.isTab) DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_HIGHLIGHT_COLOR );

            if (!duCheckBox.hasLabel && !options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.buttonGroup, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );
            // image
            if (!options.isTab && duCheckBox.hasImage && !duCheckBox.hasIcon && !duCheckBox.hasLabel) DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );

            //outline
            if (options.isTab )
            {
                DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.APP_HIGHLIGHT_COLOR );
                if (duCheckBox.hasLabel) DuScriptUI.setTextColor( duCheckBox.label, DuColor.Color.APP_HIGHLIGHT_COLOR );
            }
        }
        

        DuScriptUI.highlightedControls.push( duCheckBox );
    }

    duCheckBox.dim = function( e )
    {
        if ( duCheckBox.checked )
        {
            if (duCheckBox.hasLabel && !options.isTab) DuScriptUI.setTextColor( duCheckBox.labelChecked, DuColor.Color.APP_HIGHLIGHT_COLOR );
            
            if (!duCheckBox.hasLabel && !options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.buttonGroup, DuColor.Color.TRANSPARENT );
            // image
            if (!options.isTab && duCheckBox.hasImage && !duCheckBox.hasIcon && !duCheckBox.hasLabel && options.imageChecked == '') DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );

            //outline
            if ( options.isTab )
            {
                DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.APP_TEXT_COLOR );
                if (duCheckBox.hasLabel) DuScriptUI.setTextColor( duCheckBox.label, duCheckBox.textColor );
            }
        }
        else 
        {
            if (duCheckBox.hasLabel && !options.isTab) DuScriptUI.setTextColor( duCheckBox.label, duCheckBox.textColor );
            
            if (!duCheckBox.hasLabel && !options.isTab) DuScriptUI.setBackgroundColor( duCheckBox.buttonGroup, DuColor.Color.TRANSPARENT );
            // image
            if (!options.isTab && duCheckBox.hasImage && !duCheckBox.hasIcon && !duCheckBox.hasLabel) DuScriptUI.setBackgroundColor( duCheckBox.imageGroup, DuColor.Color.TRANSPARENT );

            //outline
            if ( options.isTab )
            {
                DuScriptUI.setBackgroundColor( duCheckBox.outLine, DuColor.Color.TRANSPARENT );
                if (duCheckBox.hasLabel) DuScriptUI.setTextColor( duCheckBox.label, duCheckBox.textColor );
            }
        }
    }

    duCheckBox.addEventListener( "click", function(e)
    {
        if(e.view.parent != duCheckBox) return;
        
        if ( e.altKey ) duCheckBox.altClicked();
        else duCheckBox.clicked(e);
    }, true );


    duCheckBox.addEventListener( "mouseover", duCheckBox.highlight );
    duCheckBox.buttonGroup.addEventListener( "mouseover", duCheckBox.highlight );
    duCheckBox.mainGroup.addEventListener( "mouseover", duCheckBox.highlight );
    if(duCheckBox.label) duCheckBox.label.addEventListener( "mouseover", duCheckBox.highlight );
    if(duCheckBox.checkBox) duCheckBox.imageChecked.addEventListener( "mouseover", duCheckBox.highlight );
    if(duCheckBox.image) duCheckBox.image.addEventListener( "mouseover", duCheckBox.highlight );

    duCheckBox.dim();

    return duCheckBox;
}
// ==================== |--------| ====================
// ==================== | screen | ====================
// ==================== |--------| ====================


/**
 * Moves the coordinates so that the size completely fits inside an existing screen
 * @param {int[]} location The coordinates [top, left]
 * @param {Dimension} size The rectangle size, an object which has two properties: width and height
 * @return {int[]} the new location
 */ 
DuScriptUI.moveInsideScreen = function (location, size)
{
    var screen = DuScriptUI.getClosestScreen(location);

    var result = location;
    var left = location[0];
    var right = location[0] + size.width;
    var top = location[1];
    var bottom = location[1] + size.height;
    // if outside on the left
    if (screen.left > location[0]) result[0] += ( screen.left - left );
    if (screen.right < right) result[0] += ( screen.right - right );
    if (screen.top > top) result[1] += ( screen.top - top );
    if (screen.bottom < bottom) result[1] += ( screen.bottom - bottom );
    return result;
}

/**
 * Gets the corners of the screen the closest to (or containing) the location
 * @param {int[]} location The coordinates
 * @return {Object} The screen object with a top, left, right and bottom property. 
 */
DuScriptUI.getClosestScreen = function(location)
{
    var screen = null;
    var distance = 999999999;
    for (var i = 0, n = $.screens.length; i < n; i++)
    {
        var s = $.screens[i];

        // check if the location is inside the screen
        if (location[0] > s.left && location[0] < s.right && location[1] > s.top && location[1] < s.bottom)
        {
            return s;
        }

        //get the center
        var c = [ (s.left + s.right)/2, (s.top + s.bottom) / 2];
        //get the distance
        var d = DuMath.length(c, location);
        if (d < distance)
        {
            screen = s;
            distance = d;
        }
    }
    return screen;
}// ==================== |----------| ====================
// ==================== | selector | ====================
// ==================== |----------| ====================


/**
 * @class
 * @name DuSelector
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A drop down selector.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.selector} to create a Selector.<br />
 * The Selector inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {string} image - The path to the current image (or a PNG as a string representation)
 * @property {Image} icon - The Image currently displayed
 * @property {StaticText} label - The current text
 * @property {string[][]} items  - The buttons, each one is an array with [text, image, helptip]
 * @property {int} index  - The current index
 * @property {string} text  - The current text
 * @property {Selector~onChange} onChange  - The function to execute when the index changes.<br />
 * You can set your own function here, which must take no argument.<br />
 * The method is called after the index has changed.
 * @property {Selector~onRefresh} onRefresh  - The function to execute to refresh the content.<br />
 * You can set your own function here, which must take no argument.
 * @category DuScriptUI
 */

/**
 * The function to execute when the index changes.<br />
 * The method is called after the index has changed.
 * @callback Selector~onChange
 * @memberof DuSelector
 */

/**
 * The function to execute to refresh the content.
 * @callback Selector~onRefresh
 * @memberof DuSelector
 */

/**
 * Adds a new button to the selector
 * @method
 * @memberof DuSelector
 * @name addButton
 * @param {string} [text] - The text displayed by the button
 * @param {string} [image] - The icon, either a path to the file or a PNG represented as a string.
 * @param {string} [helpTip] - The help tip for the entry
 * @param {string} [imageOver] - The roll over icon, either a path to the file or a PNG represented as a string.
 * @param {boolean} [localize=true] - Set to false if the text must not be translated.
 */

/**
 * Removes all buttons from the selector. This is the same as {@link Selector.clear}.
 * @method
 * @memberof DuSelector
 * @name removeAll
 */

/**
 * Removes all buttons from the selector. This is the same as {@link Selector.removeAll}.
 * @method
 * @memberof DuSelector
 * @name clear
 */

/**
 * Changes the selection and the current index of the selector
 * @method
 * @memberof DuSelector
 * @name setCurrentIndex
 * @param {int} index - The new index
 */

/**
 * Changes the selection and the current index of the selector, using the text of the selection
 * @method
 * @memberof DuSelector
 * @name setCurrentText
 * @param {string} text - The text to select
 * @param {Boolean} [quiet=false] When true, the onChange() callback will not be triggered.
 */

/**
 * Creates a drop down selector, using image buttons
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the selector.
 * @param {string} [helpTip] - The help tip to show on the selector
 * @return {DuSelector} - The selector
 */
DuScriptUI.selector = function( container, helpTip, iconOnly )
{
    helpTip = def(helpTip, '');
    helpTip = tr(helpTip);
    iconOnly = def(iconOnly, false);

    //create main group
    var selector = container.add( 'group' );
    selector.orientation = 'row';
    selector.spacing = 0;
    selector.alignment = [ 'fill', 'top' ];
    selector.alignChildren = [ 'center', 'center' ];
    selector.freeze = false;

    selector.mainGroup = selector.add( 'group' );
    selector.mainGroup.orientation = 'row';
    if (!iconOnly) selector.mainGroup.margins = 1;
    selector.mainGroup.spacing = 4;
    selector.mainGroup.alignment = [ 'fill', 'fill' ];
    selector.mainGroup.alignChildren = [ 'center', 'center' ];
    selector.helpTip = helpTip;
    DuScriptUI.setBackgroundColor( selector.mainGroup, DuColor.Color.OBSIDIAN );

    //the menu button
    if (!iconOnly) {
        selector.menuButton = selector.mainGroup.add( 'image', undefined, DuScriptUI.Icon.MENU.binAsString );
        selector.menuButton.alignment = [ 'left', 'center' ];
        selector.menuButton.helpTip = helpTip;
    }
    
    //the image
    var iconGroup = selector.mainGroup.add('group');
    if (!iconOnly) {
        iconGroup.minimumSize = [20,20];
        iconGroup.margins = 2;
    }
    else {
        iconGroup.minimumSize = [16,16];
    }
    iconGroup.alignment = ['left', 'fill'];
    selector.icon = iconGroup.add( 'image', undefined, DuScriptUI.Icon.PLACEHOLDER );
    selector.icon.alignment = [ 'center', 'center' ];
    selector.icon.helpTip = helpTip;

    if (!iconOnly) {
        //add fillers to be able to click anywhere on the button
        selector.fillerM = selector.mainGroup.add( 'statictext', undefined, " " );
        selector.fillerM.alignment = [ 'left', 'fill' ];
        selector.fillerM.size = [ 0, -1];

        //the text
        selector.label = selector.mainGroup.add( 'statictext', undefined, '' );
        selector.label.helpTip = '';
        selector.label.alignment = [ 'fill', 'center' ];
        selector.label.helpTip = helpTip;

        //add fillers to be able to click anywhere on the button
        selector.fillerR = selector.mainGroup.add( 'statictext', undefined, " " );
        selector.fillerR.alignment = [ 'fill', 'fill' ];
    }
    

    //create popup
    selector.popup = new Window( 'palette', '', undefined,
    {
        borderless: true
    } );
    selector.popup.margins = 2;
    selector.popup.spacing = 0;
    selector.popup.closeButton = DuScriptUI.button( selector.popup, tr(DuScriptUI.String.CANCEL) );
    selector.popup.closeButton.onClick = selector.popup.onDeactivate = function()
    {
        selector.popup.hide();
        DuScriptUI.eventFunctionsPaused = false;
    };
    selector.popup.buttons = selector.popup.add( 'group' );
    selector.popup.buttons.orientation = 'column';
    selector.popup.buttons.margins = 0;
    selector.popup.buttons.spacing = 0;
    selector.popup.hide();

    //add default button
    selector.items = [];
    selector.index = -1;
    selector.currentData = null;

    selector.addButton = function( text, image, helpTip, localize, data )
    {
        selector.popup.hide();

        var options = {};
        text = def(text, '-');
        if (jstype(text) != 'string') options = text;
        options.text = def(options.text, text);
        
        image = def(image, '');
        options.image = def(options.image, image);

        helpTip = def(helpTip, '');
        options.helpTip = def(options.helpTip, helpTip);

        localize = def(localize, true);
        options.localize = def(options.localize, localize);

        data = def(data, null);
        options.data = def(options.data, data);

        if (options.localize)
        {
            options.text = tr( options.text );
            options.helpTip = tr( options.helpTip );
        }
        
        if (!iconOnly) {
            var size = text.length * 7;
            if ( selector.label.minimumSize.width < size ) selector.label.minimumSize.width = size;
        }

        var index = selector.items.length;
        selector.items.push( [ options.text, options.image, options.helpTip, options.data ] );
        //add to popup
        options.localize = false;
        options.ignoreUIMode = true;
        var button = DuScriptUI.button( selector.popup.buttons, options );
        button.bgColor = DuColor.Color.OBSIDIAN;
        button.dim();
        button.onClick = function()
        {
            selector.setCurrentIndex( index );
            selector.popup.hide();
        };
        selector.popup.layout.layout(true);
        selector.popup.update();
    }

    selector.removeAll = function()
    {
        selector.popup.hide();
        selector.items = [];
        selector.setCurrentIndex( 0 );
        for ( var i = selector.popup.buttons.children.length - 1; i >= 0; i-- )
        {
            selector.popup.buttons.remove( selector.popup.buttons.children[ i ] );
        }
        selector.popup.layout.layout(true);
        selector.popup.update();
    }
    selector.clear = selector.removeAll;

    selector.setCurrentIndex = function( index, quiet )
    {
        if ( index < 0 ) return;
        if ( index >= selector.items.length ) return;

        var item = selector.items[ index ];

        if ( !item ) return;

        var image = item[ 1 ];
        if ( image != '' )
        {
            if (image instanceof DuBinary) image = image.toFile();
            selector.icon.show();
            selector.icon.image = image;
        }
        else if (!iconOnly)
        {
            selector.icon.hide();
        }
        if (!iconOnly) selector.label.text = item[ 0 ];

        selector.index = index;

        selector.text = item[ 0 ];

        selector.currentData = item[3];

        if (!quiet && !selector.freeze) selector.onChange();
    }

    selector.setCurrentText = function( text )
    {
        for (var i = 0, n = selector.items.length; i < n; i++)
        {
            if (selector.items[i][0] == text)
            {
                selector.setCurrentIndex(i);
                break;
            }
        }
    }

    selector.clicked = function( e )
    {
        selector.onRefresh();
        var popup = false;

        if (!iconOnly) if ( e.target === selector.menuButton ) popup = true;
        if ( e.altKey ) popup = true;
        

        if ( popup )
        {
            var x = e.screenX - e.clientX;
            var y = e.screenY - e.clientY;
            selector.popup.location = [ x, y ];
            selector.popup.show();
            DuScriptUI.eventFunctionsPaused = true;
        }
        else
        {
            var index = selector.index;
            if ( e.ctrlKey ) index = -1;
            if ( index == selector.items.length - 1 ) index = 0;
            else index++;
            selector.setCurrentIndex( index );
            DuScriptUI.eventFunctionsPaused = false;
        }
    }

    //mouse over
    selector.highlight = function( e )
    {
        e.stopPropagation();
        DuScriptUI.dimControls();
        DuScriptUI.setBackgroundColor( selector, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );
        DuScriptUI.highlightedControls.push( selector );
    }

    selector.dim = function( e )
    {
        DuScriptUI.setBackgroundColor( selector, DuColor.Color.TRANSPARENT );
        //if (!iconOnly) DuScriptUI.setTextColor( selector.label, DuColor.Color.APP_TEXT_COLOR );
    }

    selector.mainGroup.addEventListener( "mouseover", selector.highlight );
    selector.mainGroup.addEventListener( "click", selector.clicked, true );

    selector.onChange = function() {};
    selector.onRefresh = function (){};

    selector.dim();

    return selector;
}

// ==================== |------| ====================
// ==================== | text | ====================
// ==================== |------| ====================


/**
 * @class
 * @name DuEditText
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Nice EditText.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.editText} to create a Nice EditText.<br />
 * The Nice EditText inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {string} text - Read-Only | The text displayed
 * @property {DuColor} textColor - The color of the text
 * @property {DuEditText~onActivate} onActivate - Function to execute when activated
 * @property {DuEditText~onDeactivate} onDeactivate - Function to execute when deactivated
 * @property {DuEditText~onChange} onChange - Function to execute when text changed
 * @property {DuEditText~onChange} onEnterPressed - Function to execute when enter key is pressed whil in edit mode
 * @category DuScriptUI
 */

/**
 * The function to execute when the text is changed.
 * @callback DuEditText~onChange
 * @memberof DuEditText
 */

/**
 * Function to execute when enter key is pressed whil in edit mode.
 * @callback DuEditText~onEnterPressed
 * @memberof DuEditText
 */


/**
 * The function to execute when the box is activated.
 * @callback DuEditText~onActivate
 * @memberof DuEditText
 */

/**
 * The function to execute when the box is deactivated.
 * @callback DuEditText~onDeactivate
 * @memberof DuEditText
 */

/**
 * Changes the text
 * @method
 * @memberof DuEditText
 * @name setText
 * @param {string} text - The new text
 */

 /**
 * Changes the prefix
 * @method
 * @memberof DuEditText
 * @name setPrefix
 * @param {string} prefix - The new prefix
 */

 /**
 * Changes the suffix
 * @method
 * @memberof DuEditText
 * @name setSuffix
 * @param {string} suffix - The new suffix
 */

/**
 * Changes the placeholder
 * @method
 * @memberof DuEditText
 * @name setPlaceholder
 * @param {string} placeholder - The placeholder text
 */

/**
 * Creates a nice edittext where the edit text is shown only on click.
 * @param {Window|Panel|Group}	container		- The ScriptUI Object which will contain and display the nice edit text.
 * @param {string} text - The initial text in the edit.
 * @param {string} [prefix=""] - A text prefix to display.
 * @param {string} [suffix=""] - A text suffix to display.
 * @param {string} [placeHolder=""] - A place holder default text.
 * @param {string} [helpTip=""] The helpTip of this control
 * @param {bool} [localize=true] Whether to translate the texts of this control
 * @return {DuEditText}	The custom Group containing the edit text.
 */
DuScriptUI.editText = function( container, text, prefix, suffix, placeHolder, helpTip, localize )
{
    var options = {};
    text = def(text, '');

    if (jstype(text) != 'string') options = text;

    prefix = def(prefix, '');
    suffix = def(suffix, '');
    placeHolder = def(placeHolder,'');
    helpTip = def(helpTip, '');
    localize = def(localize,true);

    options.text = def(options.text, text);
    options.suffix = def(options.suffix, suffix);
    options.prefix = def(options.prefix, prefix);
    options.placeHolder = def(options.placeHolder, placeHolder);
    options.helpTip = def(options.text, helpTip);
    options.localize = def(options.localize, localize);

    if ( options.localize )
    {
        options.text = tr( options.text );
        options.prefix = tr( options.prefix );
        options.suffix = tr( options.suffix );
        options.placeHolder = tr( options.placeHolder );
    }

    var niceEditText = container.add( 'group' );
    niceEditText.orientation = 'stack';
    niceEditText.margins = 0;
    niceEditText.alignChildren = [ 'fill', 'fill' ];
    niceEditText.placeHolder = options.placeHolder;
    var staticText = options.text;
    if ( options.text == "" && options.placeHolder != "" ) staticText = options.placeHolder;
    niceEditText.static = niceEditText.add( 'statictext', undefined, options.prefix + staticText + options.suffix );
    niceEditText.static.alignment = [ 'fill', 'center' ];
    niceEditText.static.helpTip = options.helpTip;
    if ( options.text == "" && options.placeHolder != "" ) DuScriptUI.setTextColor( niceEditText.static, DuColor.Color.APP_HIGHLIGHT_COLOR.darker(150) );
    else DuScriptUI.setTextColor( niceEditText.static, DuColor.Color.APP_HIGHLIGHT_COLOR );
    niceEditText.edit = niceEditText.add( 'edittext', undefined, options.text );
    niceEditText.edit.visible = false;
    niceEditText.edit.helpTip = options.helpTip;
    niceEditText.edit.alignment = ['fill', 'center'];
    niceEditText.prefix = options.prefix;
    niceEditText.suffix = options.suffix;
    niceEditText.textColor = DuColor.Color.APP_HIGHLIGHT_COLOR;
    niceEditText.freeze = false;

    niceEditText.text = options.text;
    niceEditText.tempText = '';
    niceEditText.previousText = options.text;
    niceEditText.editing = false;

    niceEditText.onActivate = function() {};
    niceEditText.onDeactivate = function() {};
    niceEditText.onChange = function() {};
    niceEditText.onChanging = function() {};
    niceEditText.onEnterPressed = function() {};

    niceEditText.clicked = function()
    {
        if ( niceEditText.editing ) return;
        else
        {
            niceEditText.static.visible = false;
            niceEditText.edit.visible = true;
            niceEditText.editing = true;
            niceEditText.edit.active = true;
        }
    }

    niceEditText.changed = function()
    {
        if ( niceEditText.text ==  niceEditText.edit.text ) 

        var freeze = niceEditText.freeze;
        niceEditText.freeze = true;

        niceEditText.editing = false;
        var staticText = '';
        if ( niceEditText.edit.text == '' && niceEditText.placeHolder != '' )
        {
            DuScriptUI.setTextColor( niceEditText.static, niceEditText.textColor.darker(200) );
            staticText = niceEditText.placeHolder;
        }
        else
        {
            if ( niceEditText.placeHolder != '' ) DuScriptUI.setTextColor( niceEditText.static, niceEditText.textColor );
            staticText = niceEditText.edit.text;
        }
        niceEditText.static.text = niceEditText.prefix + staticText + niceEditText.suffix;

        niceEditText.previousText = niceEditText.text;

        niceEditText.text = niceEditText.edit.text;
        niceEditText.edit.visible = false;
        niceEditText.static.visible = true;
        niceEditText.edit.active = false;

        niceEditText.freeze = freeze;
        if (!niceEditText.freeze) niceEditText.onChange();
    }

    niceEditText.changing = function()
    {
        var freeze = niceEditText.freeze;
        niceEditText.freeze = true;

        niceEditText.tempText = niceEditText.edit.text;

        niceEditText.freeze = freeze;
        if (!niceEditText.freeze) niceEditText.onChanging();
    }

    niceEditText.enterPressed = function()
    {
        if (!niceEditText.freeze) niceEditText.onEnterPressed();
    }

    niceEditText.setText = function( text )
    {
        var freeze = niceEditText.freeze;
        niceEditText.freeze = true;

        niceEditText.previousText = niceEditText.text;
        if (text == '')
        {
            niceEditText.edit.text = niceEditText.text = text;
            niceEditText.static.text = niceEditText.prefix + niceEditText.placeHolder + niceEditText.suffix;
        }
        else 
        {
            niceEditText.edit.text = niceEditText.text = text;
            niceEditText.static.text = niceEditText.prefix + text + niceEditText.suffix;
        }

        niceEditText.freeze = freeze;
    }

    niceEditText.setPrefix = function( prefix )
    {
        niceEditText.prefix = prefix;
        niceEditText.setText(niceEditText.text);
    }

    niceEditText.setSuffix = function( suffix )
    {
        niceEditText.suffix = suffix;
        niceEditText.setText(niceEditText.text);
    }

    niceEditText.setPlaceholder = function( ph )
    {
        var freeze = niceEditText.freeze;
        niceEditText.freeze = true;

        niceEditText.placeHolder = ph;
        var text = niceEditText.text;
        if (text == '')
        {
            niceEditText.edit.text = niceEditText.text = text;
            niceEditText.static.text = niceEditText.prefix + niceEditText.placeHolder + niceEditText.suffix;
        }
        else 
        {
            niceEditText.edit.text = niceEditText.text = text;
            niceEditText.static.text = niceEditText.prefix + text + niceEditText.suffix;
        }

        niceEditText.freeze = freeze;
    }

    niceEditText.edit.onActivate = function()
    {
        if (!niceEditText.freeze) niceEditText.onActivate();
    }
    niceEditText.edit.onDeactivate = function()
    {
        if (!niceEditText.freeze) niceEditText.changed();
        if (!niceEditText.freeze) niceEditText.onDeactivate();
    }
    niceEditText.edit.onChange = niceEditText.changed;
    niceEditText.edit.onChanging = niceEditText.changing;
    niceEditText.addEventListener( "mousedown", niceEditText.clicked, true );
    niceEditText.addEventListener( "mouseover", DuScriptUI.dimControls );
    niceEditText.edit.addEventListener('keydown', function(e){ if (e.keyName == 'Enter' && !niceEditText.freeze) niceEditText.enterPressed(); } );

    niceEditText.helpTip = options.helpTip;

    return niceEditText;
}

/**
 * Creates a statictext (with an optionnal color).
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the nice edit text.
 * @param {string} text - The initial text in the edit.
 * @param {DuColor} [color] - The color of the text. By default, uses a slightly darker text than the Host App text color
 * @param {bool} [localize=true] - Set this to false to never translate this text.
 * @param {bool} [multiLine=false] - Set this to true to add a multiline text. Auto detected by default if the text contains the newline character.
 * @return {StaticText} The ScriptUI StaticText created.
 */
DuScriptUI.staticText = function( container, text, color, localize, multiLine )
{
    var options = {};
    text = def(text, '');

    if (jstype(text) != 'string') options = text;

    options.text = def(options.text, text);

    multiLine = def(multiLine, options.text.indexOf("\n") >= 0 )
    localize = def(localize, true);
    color = def(color, DuColor.Color.APP_TEXT_COLOR.darker(130) );

    options.color = def(options.color, color);
    options.localize = def(options.localize, localize);
    options.multiLine = def(options.multiLine, multiLine);

    if ( options.localize ) options.text = tr( options.text );

    var t = container.add( 'statictext', undefined, options.text,
    {
        multiline: options.multiLine
    } );

    DuScriptUI.setTextColor( t, options.color );

    t.setText = function (txt) { t.text = txt; };

    return t;
}
// ==================== |--------------| ====================
// ==================== | fileSelector | ====================
// ==================== |--------------| ====================


/**
 * @class
 * @name DuFolderSelector
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A "Browse" button for folders only, with an optional text field for the path.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.folderSelector} to create a selector.<br />
 * The DuFolderSelector inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {string} path - The folder path, initialized with an empty string. Note that this may not point to an existing folder if the user entered an incorrect path in the text field.<br />
 * To be sure to get an existing folder, you can use the getFolder() method.
 * @property {DuEditText|null} editText - The text field, if any.
 * @property {DuButton} button - The "Browse" button.
 * @category DuScriptUI
 */

/**
 * Gets the selected folder.
 * @method
 * @memberof DuFolderSelector
 * @name getFolder
 * @return {Folder|null} The new Folder, if any. null if the Folder does not exist or the user has input an incorrect path.
 */

/**
 * Creates a folder selector with a field for the path and a browse button<br />
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the panel.
 * @param {string} [text="Browse..."] - The text to display on the button.
 * @param {boolean} [textField=true] - Whether to show the text field for the path.
 * @param {string} [helpTip=''] - The helptip for this control.
 * @param {string} [orientation='row'] - The orientation of the control (button+edittext).
 * @return {DuFolderSelector} The control.
 */
DuScriptUI.folderSelector = function ( container, text, textField, helpTip, orientation )
{
    text = def(text, "Browse...");
    textField = def(textField, true);
    helpTip = def(helpTip, '');
    orientation = def(orientation, 'row');

    if (DuESF.scriptSettings.data.common.uiMode >= 1) orientation = 'row';

    var folderSelector = container.add('group');
    folderSelector.orientation = orientation;
    folderSelector.margins = 0;
    folderSelector.spacing = 0;

    folderSelector.path = '';

    folderSelector.button = DuScriptUI.button(
        folderSelector,
        text,
        w12_folder,
        helpTip
        );
    if (orientation == 'row') folderSelector.button.alignment = ['left','fill'];

    folderSelector.editText = null;
    if (textField) {
        folderSelector.editText = DuScriptUI.editText(
            folderSelector,
            '',
            '',
            '',
            DuScriptUI.String.PATH + '...',
            helpTip
            );
        folderSelector.editText.alignment = ['fill','center'];

        folderSelector.editText.onChange = function () {
            folderSelector.path = folderSelector.editText.text;
        }
    }

    folderSelector.button.onClick = function () {
        var folder = Folder.selectDialog ("Select Folder");
        if (!folder) return;
        folderSelector.editText.setText(folder.fsName);
        folderSelector.path = folder.absoluteURI;
    }

    folderSelector.getFolder = function () {
        var folder = new Folder(folderSelector.path);
        if (folder.exists) return folder;
        else return null;
    }

    return folderSelector;
}


/**
 * @class
 * @name DuFileSelector
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A "Browse" button for files only, with an optional text field for the path.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.fileSelector} to create a selector.<br />
 * The DuFileSelector inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {string} path - The file path, initialized with an empty string. Note that this may not point to an existing folder if the user entered an incorrect path in the text field.<br />
 * To be sure to get an existing file, you can use the getFile() method.
 * @property {DuEditText|null} editText - The text field, if any.
 * @property {DuButton} button - The "Browse" button.
 * @property {DuFileSelector~onChange} onChange A function called when the file has changed.
 * @category DuScriptUI
 */

/**
 * Called when the file has changed.
 * @callback onChange
 * @memberof DuFileSelector
 */

/**
 * Gets the selected file.
 * @method
 * @memberof DuFileSelector
 * @name getFile
 * @return {File|null} The new File, if any. null if the File does not exist or the user has input an incorrect path.
 */

/**
 * Creates a file selector with a field for the path and a browse button.
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the panel.
 * @param {string} [text="Browse..."] - The text to display on the button.
 * @param {boolean} [textField=true] - Whether to show the text field for the path.
 * @param {string} [helpTip=''] - The helptip for this control.
 * @param {string|DuBinary} [image] - The image to use as an icon; a "file" icon by default.
 * @param {string} [mode='open'] - The open mode, either 'open' or 'save'.
 * @param {string} [orientation='row'] - The orientation of the control (button+edittext).
 * @return {DuFileSelector} The control.
 */
DuScriptUI.fileSelector = function ( container, text, textField, helpTip, image, mode, filters, orientation )
{
    text = def(text, "Browse...");
    textField = def(textField, true);
    helpTip = def(helpTip, '');
    mode = def(mode, 'open');
    image = def(image, w12_file);
    filters = def(filters, "All files: *.*");
    orientation = def(orientation, uiMode >= 1 ? 'row' : 'column');

    var commonSettings = def(DuESF.scriptSettings.data.common, {});
    var uiMode = def( commonSettings.uiMode, 0);

    var fileSelector = container.add('group');
    fileSelector.orientation = orientation;
    fileSelector.margins = 0;
    fileSelector.spacing = 0;

    fileSelector.path = '';

    fileSelector.button = DuScriptUI.button(
        fileSelector,
        text,
        image,
        helpTip
        );
    if (orientation == 'row') fileSelector.button.alignment = ['left','fill'];

    fileSelector.editText = null;
    if (textField) {
        fileSelector.editText = DuScriptUI.editText(
            fileSelector,
            '',
            '',
            '',
            DuScriptUI.String.PATH + '...',
            helpTip
            );
        fileSelector.editText.alignment = ['fill','center'];

        fileSelector.editText.onChange = function () {
            fileSelector.path = fileSelector.editText.text;
            fileSelector.onChange();
        }
    }

    fileSelector.onChange = function() {};

    fileSelector.button.onClick = function () {
        var file = new File(fileSelector.path);
        if (file.exists)
        {
            if (mode == 'open') file = file.openDlg("Select File", filters);
            else file = file.saveDlg ("Save File", filters);
        }
        else 
        {
            if (mode == 'open') file = File.openDialog("Select File",filters);
            else file = File.saveDialog ("Save File", filters);
        }
        
        if (!file) return;

        if (mode == 'open' && !file.exists)
        {
            if (fileSelector.editText) fileSelector.editText.setText("");
            fileSelector.path = file.absoluteURI;
        }
        else
        {
            if (fileSelector.editText) fileSelector.editText.setText(file.fsName);
            fileSelector.path = file.absoluteURI;
        }

        fileSelector.onChange();
    }

    fileSelector.getFile = function () {
        var file = new File(fileSelector.path);
        if (!file.exists && mode == 'open') return null;
        else return file;
    }

    fileSelector.setPath = function(path)
    {
        var file = new File(path);
        fileSelector.path = file.absoluteURI;
        if ((mode == 'open' && file.exists) || mode == 'save')
        {
            fileSelector.editText.setText( file.fsName ); 
        }
        else
        {
            fileSelector.editText.setText( "" );
        }
    }

    fileSelector.setPlaceholder = function(text)
    {
        fileSelector.editText.setPlaceholder(text);
    }



    return fileSelector;
}// ==================== |--------| ====================
// ==================== | slider | ====================
// ==================== |--------| ====================


/**
 * @class
 * @name DuSlider
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Nice Slider.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.slider} to create a Nice Slider.<br />
 * The Nice Slider inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {int} value - Read-Only | The current value
 * @property {DuSlider~onChanging} onChanging - Function to execute when changing
 * @property {DuSlider~onChange} onChange - Function to execute when changed
 * @category DuScriptUI
 */

/**
 * Function to execute when changing
 * @callback DuSlider~onChanging
 * @memberof DuSlider
 */

/**
 * Function to execute when changed
 * @callback DuSlider~onChange
 * @memberof DuSlider
 */

/**
 * Changes the value
 * @method
 * @memberof DuSlider
 * @name setValue
 * @param {int} value - The new value
 */
 
/**
 * Creates a slider.
 * @param {Window|Panel|Group}	container		- The ScriptUI Object which will contain and display the nice edit text.
 * @param {int}	[defaultValue=0]		- The initial value.
 * @param {int}	[min=0]		- The minimal value.
 * @param {int}	[max=100]		- The maximal value.
 * @param {string}	[orientation='column']		- Either 'row' or 'column'
 * @param {boolean}	[invertedAppearance]		- Revert the slider with max value on the left
 * @param {string}	[prefix]		- A text prefix to display.
 * @param {string}	[suffix]		- A text suffix to display.
 * @param {string}	[textAlignment='center'] - The alignment of the text.<br />
 * One of 'left', 'center', 'right' for column orientation,<br />
 * And 'top', 'center', 'bottom' for row orientation.
 * @param {int[]}	[valueButtons=[]] - A list of predefined values to add as buttons.
 * @return {DuSlider}	The custom Group containing the slider.
 * @todo implement helpTip
 */
DuScriptUI.slider = function( container, defaultValue, min, max, orientation, invertedAppearance, prefix, suffix, textAlignment, valueButtons )
{
    prefix = def(prefix, '');
    suffix = def(suffix, '');
    min = def( min, 0);
    max = def( max, 100);
    defaultValue = def(defaultValue, 0);
    textAlignment = def(textAlignment, 'center');
    valueButtons = def(valueButtons, []);
    orientation = def(orientation, 'column');

    if ( valueButtons.length > 0 && textAlignment == 'center' )
    {
        if ( orientation == 'column' ) textAlignment = 'right';
        else textAlignment = 'bottom';
    }

    prefix = tr( prefix );
    suffix = tr( suffix );

    var niceSlider = container.add( 'group' );
    niceSlider.orientation = orientation;
    niceSlider.spacing = 0;
    niceSlider.margins = 0;
    niceSlider.alignment = [ 'fill', 'top' ];
    niceSlider.alignChildren = [ 'fill', 'fill' ];

    niceSlider.value = defaultValue;
    niceSlider.invertedAppearance = invertedAppearance;

    var sliderValue = defaultValue;
    if ( niceSlider.invertedAppearance ) sliderValue = max - defaultValue + min;

    niceSlider.slider = niceSlider.add( 'slider', undefined, sliderValue, min, max );

    niceSlider.editGroup = DuScriptUI.group( niceSlider );
    niceSlider.editGroup.spacing = 0;
    niceSlider.editGroup.margins = 0;

    //a function to add buttons before or after the edittext, depending on the textAlignment
    niceSlider.buttons = [];

    function addButtons ()
    {
        //add
        for ( var i = 0, num = valueButtons.length; i < num; i++ )
        {
            niceSlider.buttons[i] = DuScriptUI.smallbutton(
                niceSlider.editGroup,
                valueButtons[ i ].toString(),
                "",
                valueButtons[ i ]
                );
            niceSlider.buttons[i].alignment = [ 'fill', 'fill' ];
            niceSlider.buttons[i].onClick = function( val )
            {
                niceSlider.setValue( val );
                niceSlider.onChange();
            }
        }
    }

    if ( textAlignment == 'right' || textAlignment == 'bottom' ) addButtons();

    niceSlider.edit = DuScriptUI.editText( niceSlider.editGroup, defaultValue.toString(), prefix + ': ', suffix + ' ', '', '', false );
    var numChars = max.toString().length;
    if ( min.toString().length > max.toString().length ) numChars = min.toString().length;
    niceSlider.edit.edit.characters = numChars + prefix.length + suffix.length - 1;
    if ( orientation == 'row' )
    {
        niceSlider.editGroup.alignment = [ 'right', 'fill'];
        niceSlider.edit.alignment = [ 'center', textAlignment ];
        niceSlider.edit.static.justify = 'center';
    }
    else
    {
        niceSlider.editGroup.alignment = [ 'fill', 'bottom'];
        niceSlider.edit.alignment = [ textAlignment, 'center' ];
        niceSlider.edit.static.justify = textAlignment;
    }

    if ( textAlignment == 'left' || textAlignment == 'top' ) addButtons();

    niceSlider.onChanging = function() {};
    niceSlider.onChange = function() {};

    niceSlider.setValue = function( val )
    {
        niceSlider.value = val;
        niceSlider.edit.setText( niceSlider.value );
        if ( niceSlider.invertedAppearance ) niceSlider.slider.value = niceSlider.slider.maxvalue - val + niceSlider.slider.minvalue;
        else niceSlider.slider.value = val;
    }

    //events
    niceSlider.slider.onChanging = function()
    {
        if ( niceSlider.invertedAppearance ) niceSlider.value = Math.round( niceSlider.slider.maxvalue - niceSlider.slider.value + niceSlider.slider.minvalue );
        else niceSlider.value = Math.round( niceSlider.slider.value );
        niceSlider.edit.setText( niceSlider.value );
        niceSlider.onChanging();
    }

    niceSlider.slider.onChange = function()
    {
        niceSlider.onChange();
    }

    niceSlider.edit.onChanging = function()
    {
        var val = parseInt( niceSlider.edit.text );
        if ( isNaN( val ) ) return;
        niceSlider.value = val;
        if ( niceSlider.invertedAppearance ) niceSlider.slider.value = niceSlider.slider.maxvalue - val + niceSlider.slider.minvalue;
        else niceSlider.slider.value = val;
        niceSlider.onChanging();
    }
    niceSlider.edit.onChange = function()
    {
        var val = parseInt( niceSlider.edit.text );
        if ( isNaN( val ) ) return;
        if ( val < niceSlider.slider.minvalue ) val = niceSlider.slider.minvalue;
        if ( val > niceSlider.slider.maxvalue ) val = niceSlider.slider.maxvalue;
        niceSlider.edit.setText( val );
        niceSlider.value = val;
        if ( niceSlider.invertedAppearance ) niceSlider.slider.value = niceSlider.slider.maxvalue - val + niceSlider.slider.minvalue;
        else niceSlider.slider.value = val;
        niceSlider.onChange();
    }

    niceSlider.addEventListener( "mouseover", DuScriptUI.dimControls );

    return niceSlider;
}
// ==================== |------| ====================
// ==================== | form | ====================
// ==================== |------| ====================


/**
 * @class
 * @name DuForm
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Form.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.form} to create a Form.<br />
 * The DuForm inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {Group} labels - The left vertical group
 * @property {Group} buttons - The right vertical group
 * @category DuScriptUI
 */

/**
 * Adds a field to the form
 * example: form.addField('Composition:','dropdownlist',['Composition1','Composition2'],'Select a composition')
 * @method
 * @memberof DuForm
 * @name addField
 * @param {string}			label		- The label text.
 * @param {string}			type		- The type of ScriptUI object to add (like 'button','edittext', etc.).
 * @param {object}			[value]		- The default value or content of the field added, depends on the type.
 * @param {string}			[helpTip]		- The helpTip of the form control.
 * @return {ScriptUI[]}		An array with at 0 the StaticText label, and at 1 the ScriptUI object of the type type, added to the form
 */

/**
 * Creates a layout to add forms to a UI, using ScriptUI groups.<br />
 * You can easily add controls/fields to this form using DuScriptUI.addField
 * @param {Window|Panel|Group}	container		- The ScriptUI Object which will contain and display the form.
 * @return {DuForm}		The custom Group containing the form.
 */
DuScriptUI.form = function( container )
{
    var mainGroup = container.add( 'group' );
    mainGroup.orientation = 'row';
    mainGroup.margins = 0;
    mainGroup.spacing = DuScriptUI.defaultSpacing;

    var labelsGroup = mainGroup.add( 'group' );
    labelsGroup.alignment = [ 'left', 'top' ];
    labelsGroup.orientation = 'column';
    labelsGroup.alignChildren = [ 'left', 'bottom' ];
    labelsGroup.spacing = DuScriptUI.defaultSpacing;

    var buttonsGroup = mainGroup.add( 'group' );
    buttonsGroup.alignment = [ 'fill', 'top' ];
    buttonsGroup.orientation = 'column';
    buttonsGroup.alignChildren = [ 'fill', 'fill' ];
    buttonsGroup.spacing = DuScriptUI.defaultSpacing;

    mainGroup.labels = labelsGroup;
    mainGroup.buttons = buttonsGroup;

    mainGroup.addEventListener( "mouseover", DuScriptUI.dimControls );

    mainGroup.addField = function( label, type, value, helpTip )
    {
        helpTip = def (helpTip, '');
        label = tr( label );
        helpTip = tr( helpTip );

        var control = null;
        var height = 20;
        if ( type == "DuButton" )
        {
            control = DuScriptUI.button( mainGroup.buttons, '', value[ 0 ], helpTip );
            height = control.image.preferredSize[ 1 ];
        }
        else
        {
            control = mainGroup.buttons.add( type, undefined, value );
            control.helpTip = helpTip;
            height = control.preferredSize[ 1 ];
        }

        var l = mainGroup.labels.add( 'statictext', undefined, label );
        l.helpTip = helpTip;

        l.minimumSize.height = l.maximumSize.height = height;
        return [ l, control ];
    }

    return mainGroup;
}
// ==================== |----------| ====================
// ==================== | tabPanel | ====================
// ==================== |----------| ====================

/**
 * @class
 * @name DuTabPanel
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A Panel with tabs.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.tabPanel} to create a picker.<br />
 * The DuTabPanel inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {DuButton[]} buttons - The buttons for the tabs. Not that an "index" property is added to the button, containing the DuTab index.
 * @property {DuTab[]} tabs - The tabs.
 * @property {int} index - The currently visible tab.
 * @property {Group} buttonsGroup - The ScriptUI Group containing the buttons
 * @property {Group} mainGroup - The ScriptUI Group containing the tabs
 * @property {string} scriptUIPanel - The file name ("script.jsx") of a scriptUI Panel. Alt+Click on this tab will open/close this panel.
 * @property {DuTabPanel~onChange} onChange - Called when the index changes.
 * @category DuScriptUI
 */

/**
 * Adds a new empty DuTab in the DuTabPanel.
 * @method
 * @memberof DuTabPanel
 * @name addTab
 * @param {string} [text=''] - The label of the button.
 * @param {string} [image=''] - The path to the icon.
 * @param {string} [helpTip=''] - The helptip.
 * @param {string} [imageOver=image] - The path to an icon displayed when the mouse is over the button.
 * @return {DuTab} The new DuTab.
 */

/**
 * Sets the current visible tab.
 * @method
 * @memberof DuTabPanel
 * @name setCurrentIndex
 * @param {int} [index=0] - The index of the tab to show.
 */

/**
 * Called when the index changes.
 * @callback DuTabPanel~onChange
 * @memberof DuTabPanel
 */

/**
 * @class
 * @name DuTab
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A DuTab inside a {@link DuTabPanel}.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuTabPanel.add} to create a new DuTab.
 * @property {int} index - The index of this tab.
 * @property {DuButton} button - The button associated with this tab.
 * @property {DuTab~tabActivated} onActivate - The function to execute when the tab is displayed.
 * @property {DuTab~tabDeActivated} onActivate - The function to execute when the tab is hidden.
 * @property {DuTab~build} build - You can use this callback to add a function which builds the UI of the tab, it will be called on first display.
 * @category DuScriptUI
 */

/**
 * The function to execute when the tab is about to be displayed.
 * @callback DuTab~tabActivated
 * @memberof DuTab
 */

/**
 * The function to execute when the tab is hidden.
 * @callback DuTab~tabDeActivated
 * @memberof DuTab
 */

/**
 * You can use this callback to add a function which builds the UI of the tab, it will be called on first display.<br />
 * This allows a faster startup of your script by delaying the creation of the tabs which are hidden at startup.<br />
 * You can add controls in the <code>this</code> object.
 * @callback DuTab~build
 * @memberof DuTab
 */

/**
 * Creates a panel with tabs
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the panel.
 * @param {string} tabOrientation - The orientation to use for tab buttons.
 * @return {DuTabPanel} The panel.
 */
DuScriptUI.tabPanel = function( container, tabOrientation )
{
    tabOrientation = def(tabOrientation, 'row');

    var panel = DuScriptUI.group( container, 'column' );

    panel.tabOrientation = tabOrientation;
    panel.alignment = [ 'fill', 'fill' ];
    panel.buttons = [];
    panel.tabs = [];
    panel.tabGroups = [];
    panel.showTitle = true;
    panel.onChange = function() {};

    //adds a group for the buttons
    panel.buttonsGroup = DuScriptUI.group( panel, 'row' );
    //adds a group for the tabs
    panel.mainGroup = DuScriptUI.group( panel, 'stack' );
    panel.mainGroup.alignment = [ 'fill', 'fill' ];

    panel.addTab = function( text, image, helpTip )
    {
        text = def( text, '');
        image = def (image, '');

        var commonSettings = def( DuESF.scriptSettings.data.common, {} );
        var uiMode = def(commonSettings.uiMode, 0);
        if (uiMode >= 2 && image != '') text = '';

        // If this button and the previous one have a label, add a spacer
        if (panel.buttons.length > 0)
        {
            var prevButton = panel.buttons[panel.buttons.length-1];
            if (prevButton.label) if (prevButton.label.text != '' && text != '')
            {
                var spacer = panel.buttonsGroup.add('group');
                spacer.spacing = 0;
                spacer.margins = 0;
                spacer.minimumSize = [5,-1];
            }
        }

        //adds the new button
        var button = DuScriptUI.checkBox( panel.buttonsGroup, text, image, helpTip, undefined, undefined, panel.tabOrientation, true );
        button.index = panel.tabs.length;       
        panel.buttons.push( button );

        //adds the new tab
        var tab = DuScriptUI.group( panel.mainGroup, 'column' );
        tab.alignment = [ 'fill', 'fill' ];
        tab.visible = false;
        tab.activated = false;

        //the onActivate callBack
        tab.tabActivated = function() {};
        tab.tabDeActivated = function() {};
        //the build callBack
        tab.build = function( theTab ) {};
        tab.duBuild = function() { 
            if ( tab.built ) return;
            DuDebug.log( "TabPanel - Building Tab: " + tab.name + ' ' + tab.index );
            tab.build( tab );
            //resize everything
            DuDebug.log( "TabPanel - Tab Built, Layout..." );
            DuScriptUI.layout( tab );

            DuDebug.log( "TabPanel - Tab ready." );
            tab.built = true;
        }
        tab.built = false;

        tab.scriptUIPanel = "";

        tab.button = button;

        //add to the list
        tab.index = panel.tabs.length;
        tab.name = text;
        panel.tabs.push( tab );

        DuScriptUI.allTabs.push( tab );

        button.onClick = function()
        {
            panel.setCurrentIndex( button.index );
        }

        return tab;
    }

    panel.setCurrentIndex = function( index )
    {
        index = def( index, panel.index );

        var numTabs = panel.tabs.length;

        if ( numTabs == 0 ) return;

        //hide all tabs
        for ( var i = 0; i < numTabs; i++ )
        {
            var tab = panel.tabs[ i ];
            tab.activated = i == index;
            // Build only AFTER main UI has been shown, this improves performance
            // DuScriptUI.showUI will build visible tabs
            if ( tab.activated && DuScriptUI.uiShown )
            {
                tab.duBuild();
                tab.visible = true;
                tab.tabActivated();
            }
            if ( !tab.activated )
            {
                tab.visible = false;
                tab.tabDeActivated();
            }

            panel.buttons[ i ].setChecked( tab.activated );
        }

        if ( index >= 0 && index < numTabs ) panel.index = index;
        else panel.index = -1;

        panel.onChange();
    }

    return panel;
}

/**
 * Builds all the tabs from all the tab panels
 */
DuScriptUI.buildAllTabs = function()
{
    for ( var i = 0, num = DuScriptUI.allTabs.length; i < num; i++ )
    {
        var tab = DuScriptUI.allTabs[ i ];
        if ( !tab.built )
        {
            tab.build( tab );
            //resize everything
            DuScriptUI.layout( tab );
            tab.built = true;
        }
    }
    //check if there's still unbuilt tabs which may have been added
    var redo = false;
    for ( var i = DuScriptUI.allTabs.length - 1; i >= 0; i-- )
    {
        var tab = DuScriptUI.allTabs[ i ];
        if ( !tab.built )
        {
            redo = true;
            break;
        }
    }
    if ( redo ) DuScriptUI.buildAllTabs();
}
// ==================== |---------------| ====================
// ==================== | colorSelector | ====================
// ==================== |---------------| ====================

/**
 * @class
 * @name DuColorSelector
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A color selector, with an edittext and a random button.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.colorSelector} to create a Selector.<br />
 * The Selector inherits the Group object from ScriptUI and has all of its properties and methods.
 * @category DuScriptUI
 */

/**
 * The current color
 * @type {DuColor}
 * @memberof DuColorSelector
 * @name color
 */

/**
 * Sets the current color
 * @method
 * @name setColor
 * @param {DuColor} color The new color
 * @memberof DuColorSelector
 */

/**
 * Method called when the has been changed
 * @type {DuColorSelector~onChange}
 * @name onChange
 * @memberof DuColorSelector
 */

/**
 * The function to execute when the color is changed.
 * @callback DuColorSelector~onChange
 * @memberof DuColorSelector
 */

/**
 * Creates a new color selector and adds it to the container
 * @param {Window|Panel|Group} container
 * @param {string} [helpTip] - The help tip to show on the selector
 * @returns {DuColorSelector}
 */
DuScriptUI.colorSelector = function ( container, helpTip )
{
    helpTip = def(helpTip, '');

    var colorSelector = container.add('group');
    colorSelector.orientation = 'row';
    colorSelector.margins = 0;
    colorSelector.spacing = 0;
    colorSelector.alignment = ['fill', 'top'];

    colorSelector.color = DuColor.Color.RX_PURPLE;

    var label = DuScriptUI.staticText( colorSelector, "Color:", DuColor.Color.RX_PURPLE );
    label.helpTip = helpTip;
    label.alignment = ['left','center'];

    var editText = DuScriptUI.editText( colorSelector, "A526C4", '#', '', '000000', helpTip );
    editText.alignment = ['fill', 'fill'];

    var randomButton = DuScriptUI.button( colorSelector, '', DuScriptUI.Icon.RANDOM, DuScriptUI.String.RANDOM_TIP );
    randomButton.alignment = ['right', 'center'];

    colorSelector.onChange = function() {};

    function labelClicked()
    {
        var color = new DuColor( colorPicker(editText.text) );
        editText.setText( color.hex() );
        colorChanged();
    }

    function randomClicked()
    {
        var color = DuColor.random();
        editText.setText( color.hex() );
        colorChanged();
    }

    function colorChanged()
    {
        var color = DuColor.fromHex( editText.text );
        colorSelector.color = color;
        DuScriptUI.setTextColor( label, color );
        colorSelector.onChange();
    }

    colorSelector.setColor = function( color )
    {
        editText.setText( color.hex() );
        colorChanged();
    }

    label.addEventListener("mousedown",labelClicked,false);
    randomButton.onClick = randomClicked;
    editText.onChange = colorChanged;

    return colorSelector;
}// ==================== |-------------| ====================
// ==================== | multiButton | ====================
// ==================== |-------------| ====================


/**
 * @class
 * @name DuMultiButton
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A multi button popup.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.multiButton} to create a DuMultiButton.<br />
 * The DuMultiButton inherits the Group object from ScriptUI and has all of its properties and methods.
 * @property {StaticText} label - The current text
 * @property {DuButton[]} buttons  - The buttons
 * @property {string} text  - The current text
 * @property {DuMultiButton~build} build - You can use this callback to add a function which builds the UI of the popup, it will be called on first display.
 * @category DuScriptUI
 */

/**
 * You can use this callback to add a function which builds the content of the popup, it will be called on first display.<br />
 * This allows a faster startup of your script by delaying the creation of the tabs which are hidden at startup.<br />
 * You can use <code>this.addButton</code> to add buttons in the popup.
 * @callback DuMultiButton~build
 * @memberof DuMultiButton
 */
/**
 * Creates a multi button popup
 * @param {Window|Panel|Group} container - The ScriptUI Object which will contain and display the multi button.
 * @param {string} [text] - The text.
 * @param {string|DuBInary} [image] - The path to the icon (or a PNG as a string representation). Default: empty string
 * @param {string} [helpTip] - The help tip to show on the multi button
 * @param {Boolean} [ignoreUIMode=false] - Will show texte even if the ui mode is set to > 1 in the script settings
 * @return {DuSelector} - The multiButton
 */
DuScriptUI.multiButton = function( container, text, image, helpTip, ignoreUIMode )
{
    text = def(text, '');
    if (text!= '') text = tr(text) + '...';
    helpTip = def(helpTip, '');
    helpTip = tr(helpTip);
    image = def(image, '');
    ignoreUIMode = def(ignoreUIMode, false);

    var commonSettings = def(DuESF.scriptSettings.data.common, {});
    var uiMode = def( commonSettings.uiMode, 0);
    if (uiMode >= 2 && image != '' && !ignoreUIMode) text = '';

    var multiButton = container.add( 'group' );
    multiButton.orientation = 'row';
    multiButton.spacing = 0;
    multiButton.alignment = [ 'fill', 'top' ];
    multiButton.alignChildren = [ 'center', 'center' ];

    multiButton.mainGroup = multiButton.add( 'group' );
    multiButton.mainGroup.orientation = 'row';
    if (text != '') {
        multiButton.mainGroup.margins = 1;
        multiButton.mainGroup.spacing = 4;
    }
    multiButton.mainGroup.alignment = [ 'fill', 'fill' ];
    multiButton.mainGroup.alignChildren = [ 'center', 'center' ];
    multiButton.helpTip = helpTip;

    //the menu button
    if ( text != '' )
    {
        multiButton.menuButton = multiButton.mainGroup.add( 'image', undefined, DuScriptUI.Icon.MORE.binAsString );
        multiButton.menuButton.alignment = [ 'left', 'center' ];
        multiButton.menuButton.helpTip = helpTip;
    }

    //the image
    if (image != '')
    {
        var iconGroup = multiButton.mainGroup.add('group');
        if ( text == '' ) {
            iconGroup.minimumSize = [16,16];
            iconGroup.alignment = ['center', 'fill'];
        }
        else {
            iconGroup.minimumSize = [20,20];
            iconGroup.margins = 2;
            iconGroup.alignment = ['left', 'fill'];
        }
        if (image instanceof DuBinary) image = image.binAsString;
        multiButton.icon = iconGroup.add( 'image', undefined, image );
        multiButton.icon.alignment = [ 'center', 'center' ];
        multiButton.icon.helpTip = helpTip;
    }

    if ( text != '')
    {
        //add fillers to be able to click anywhere on the button
        multiButton.fillerM = multiButton.mainGroup.add( 'statictext', undefined, " " );
        multiButton.fillerM.alignment = [ 'left', 'fill' ];
        multiButton.fillerM.size = [ 0, -1];

        //the text
        multiButton.label = multiButton.mainGroup.add( 'statictext', undefined, text );
        multiButton.label.helpTip = '';
        multiButton.label.alignment = [ 'fill', 'center' ];
        multiButton.label.helpTip = helpTip;

        //add fillers to be able to click anywhere on the button
        multiButton.fillerR = multiButton.mainGroup.add( 'statictext', undefined, " " );
        multiButton.fillerR.alignment = [ 'fill', 'fill' ];
    }

    //create popup
    multiButton.popup = new Window( 'palette', '', undefined,
    {
        borderless: true
    } );
    multiButton.popup.margins = 2;
    multiButton.popup.spacing = 0;
    multiButton.popup.closeButton = DuScriptUI.button( multiButton.popup, tr(DuScriptUI.String.CANCEL) );
    multiButton.popup.closeButton.onClick = multiButton.popup.onDeactivate = function()
    {
        multiButton.popup.hide();
        DuScriptUI.eventFunctionsPaused = false;
    };
    multiButton.popup.buttons = multiButton.popup.add( 'group' );
    multiButton.popup.buttons.orientation = 'column';
    multiButton.popup.buttons.margins = 0;
    multiButton.popup.buttons.spacing = 0;
    multiButton.popup.hide();

    multiButton.build = function() {};
    multiButton.built = false;
    
    //add default button
    multiButton.buttons = [];

    multiButton.addButton = function( text, image, helpTip, addOptionsPanel, localize, optionsWithoutButton, optionsButtonText )
    {
        multiButton.popup.hide();
        text = def(text, '-');
        image = def(image, '');
        helpTip = def(helpTip, '');
        localize = def(localize, true);

        if (localize)
        {
            text = tr( text );
            helpTip = tr( helpTip );
        }
        
        if (multiButton.label)
        {
            var size = text.length * 7;
            if ( multiButton.label.minimumSize.width < size ) multiButton.label.minimumSize.width = size;
        }
        
        //add to popup
        var button = DuScriptUI.button( multiButton.popup.buttons, text, image, helpTip, addOptionsPanel, undefined, undefined, false, true, optionsWithoutButton, optionsButtonText );
        multiButton.buttons.push( button );
        button.bgColor = DuColor.Color.OBSIDIAN;
        button.dim();
        
        multiButton.popup.layout.layout(true);
        multiButton.popup.update();

        return button;
    }

    multiButton.clicked = function( e )
    {
        if (!multiButton.built)
        {
            multiButton.build();
            multiButton.built = true;
        }

        var x = e.screenX - e.clientX;
        var y = e.screenY - e.clientY;
        multiButton.popup.location = [ x, y ];
        multiButton.popup.show();
        DuScriptUI.eventFunctionsPaused = true;
    }

    //mouse over
    multiButton.highlight = function( e )
    {
        e.stopPropagation();
        DuScriptUI.dimControls();
        if (multiButton.label)
        {
            DuScriptUI.setTextColor( multiButton.label, DuColor.Color.APP_HIGHLIGHT_COLOR );
        }
        else
        {
            DuScriptUI.setBackgroundColor( multiButton, DuColor.Color.APP_HIGHLIGHT_COLOR.darker() );
        }
        
        DuScriptUI.highlightedControls.push( multiButton );
    }

    multiButton.dim = function( e )
    {
        if (multiButton.label) DuScriptUI.setTextColor( multiButton.label, DuColor.Color.APP_TEXT_COLOR );
        DuScriptUI.setBackgroundColor( multiButton, DuColor.Color.TRANSPARENT );
    }

    multiButton.mainGroup.addEventListener( "mouseover", multiButton.highlight );
    multiButton.mainGroup.addEventListener( "click", multiButton.clicked, true );

    multiButton.dim();

    return multiButton;
}// ==================== |-------------| ====================
// ==================== | progressbar | ====================
// ==================== |-------------| ====================

/**
    * Constructs a progress bar popup
    * @class DuProgressBar
    * @classdesc A simple progress bar.<br />
    * This was inspired by {@link https://github.com/indiscripts/extendscript/blob/master/scriptui/ProgressBar.jsx the progress bar}
    * by {@link  https://www.indiscripts.com/ Marc Autret / IndiScripts}.
    * @param {string} title The title of the progress bar
 * @category DuScriptUI
 */
DuProgressBar = function( )
{
    this.window = new Window('palette', '', [0,0,360,86]);
    this.stage = this.window.add( 'statictext', { x:20, y:15, width:320, height:16 }, DuScriptUI.String.WORKING);
    
    var barGroup = this.window.add('group', { x:20, y:37, width:320, height:12 });
    barGroup.orientation = 'stacked';
    barGroup.margins = 0;
    this.bar = barGroup.add( 'progressbar', { x:0, y:0, width:320, height:12 }, 0, 0);
    this.image = barGroup.add( 'image', { x:0, y:0, width:320, height:12 }, DuScriptUI.Icon.PROGRESS.binAsString );
    
    this.label = this.window.add( 'statictext', { x:20, y:51, width:320, height:16 });

    this.message =  DuScriptUI.String.MAGIC + '%1';

    this.window.center();

    // A private method to update with the message and the value
    this.__ = function()
    {
        var ok = this.bar.maxvalue != 0;
        if (ok) this.label.text = DuString.replace(this.message, '%1', this.bar.value + ' / ' + this.bar.maxvalue);
        else this.label.text = DuScriptUI.String.MAGIC + '!';
        this.bar.visible = ok;
        this.image.visible = !ok;
        this.window.update();
    };
}

/**
 * Changes the text of the label
 * @param {string} message The text
 */
DuProgressBar.prototype.msg = function( message )
{
    if(isdef( message )) this.message = message;
    this.__();
}

/**
 * Changes the text of the current stage
 * @param {string} message The text
 */
DuProgressBar.prototype.stg = function( stage )
{
    this.stage.text = stage;
    this.msg();
}

/**
 * Shows the progress bar and updates the value and text
 * @param {string} [message=''] The text
 * @param {int} [maxValue=100] The maximum value
 */
DuProgressBar.prototype.show = function( message )
{
    this.window.show();
    this.msg(message);  
}

/**
 * Resets the progress bar to 0
 * @param {int} [maxValue=0] The new maximum value
 */
DuProgressBar.prototype.reset = function( maxValue )
{
    maxValue = def(maxValue, 0);
    this.bar.value = 0;
    this.bar.maxvalue = maxValue;
    this.stg( DuScriptUI.String.WORKING );
    this.msg( DuScriptUI.String.MAGIC + '%1' );
}

/**
 * Updates and increments the progress bar
 * @param {int} [value] The new value. if omitted, the bar is just incremented by 1
 * @param {string} [message] A new label
 */
DuProgressBar.prototype.hit = function( value, message )
{
    value = def(value, 1);
    this.bar.value += value;
    this.msg(message);
}

/**
 * Sets the maximum value
 * @param {int} maxValue The new maximum value
 * @param {Boolean} [onlyIfZero=true] Set to false to change the max value even if it was not 0 before
 */
DuProgressBar.prototype.setMax = function( maxValue, onlyIfZero )
{
    onlyIfZero = def(onlyIfZero, true);
    if (onlyIfZero && this.bar.maxvalue != 0) return;
    this.bar.maxvalue = maxValue;
    this.msg();
}

/**
 * Increments the maximum value
 * @param {int} [maxValue=1] The value to add to the maximum
 */
DuProgressBar.prototype.addMax = function( maxValue )
{
    maxValue = def(maxValue, 1);
    this.setMax(this.bar.maxvalue + maxValue, false);
}

/**
 * Hides the progress bar
 */
DuProgressBar.prototype.hide = function( )
{
    this.window.hide();
}

/**
 * Closes the progress bar
 */
DuProgressBar.prototype.close = function( )
{
    this.window.close();
}

/**
 * Show this progress bar before long operations with {@link DuProgressBar.show} and DuESF will update it.
 * @type {DuProgressBar}
 */
DuScriptUI.progressBar = new DuProgressBar();// ==================== |---------| ====================
// ==================== | toolbar | ====================
// ==================== |---------| ====================

/**
 * Creates a toolbar with a lighter background
 * @param {Panel|Window|Group} container The ScriptUI Object which will contain and display the toolbar.
 * @param {int} [numCols] The number of columns to use when adding the buttons.
 * @returns {Group} The toolbar, a ScriptUI Group
 */
DuScriptUI.toolBar = function( container, numCols )
{
    var commonSettings = def(DuESF.scriptSettings.data.common, {});
    var uiMode = def( commonSettings.uiMode, 0);

    if (!isdef( numCols ))
    {
        if (uiMode == 0) numCols = 3;
        else numCols = 6;
    }
    
    var toolsGroup = DuScriptUI.group( container, 'row' );
    toolsGroup.spacing = 3;
    toolsGroup.margins = 3;
    DuScriptUI.setBackgroundColor(toolsGroup , DuColor.Color.DARK_GREY );

    toolsGroup.columns = [];

    toolsGroup.spacing = 3;
    if (uiMode == 0) toolsGroup.alignChildren = ['fill', 'top'];
    else toolsGroup.alignChildren = ['center', 'top'];
    for (var i = 0; i < numCols; i++)
    {
        toolsGroup.columns.push( DuScriptUI.group(toolsGroup, 'column') );
    }

    toolsGroup.currentCol = 0;

    toolsGroup.addButton = function (text, icon, helpTip, addOptions, optionsWithoutPanel)
    {
        var options = {};
        text = def(text, '');

        if (jstype(text) != 'string') options = text;
        options.text = def(options.text, text);

        helpTip = def(helpTip, "");
        addOptions = def(addOptions, false);
        optionsWithoutPanel = def(optionsWithoutPanel, false);

        options.helpTip = def(options.helpTip, helpTip);
        options.options = def(options.options, addOptions);
        options.optionsWithoutPanel = def(options.optionsWithoutPanel, optionsWithoutPanel);
        options.image = def(options.image, icon);

        text = tr(options.text);
        helpTip = tr(options.helpTip);

        options.localize = false;
        options.orientation = uiMode == 0 ? 'column' : undefined;
        options.helpTip = uiMode == 0 ? helpTip : options.text + "\n\n" + helpTip;
        options.text =  uiMode == 0 ?  options.text : '';
        
        var button = DuScriptUI.button ( toolsGroup.columns[toolsGroup.currentCol], options);

        button.alignment = uiMode == 0 ? ['fill', 'top'] : ['center', 'top'];

        toolsGroup.currentCol = (toolsGroup.currentCol + 1) % numCols;


        return button;
    }

    return toolsGroup;
}
// ==================== |---------| ====================
// ==================== | library | ====================
// ==================== |---------| ====================

/**
 * @class
 * @name DuLibrary
 * @classdesc For use with {@link DuScriptUI}.<br />
 * A complete library interface.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.library} to create a Library.<br />
 * The Library inherits the <code>Group</code> object from ScriptUI and has all of its properties and methods.
 * @property {ListBox} list The Listbox with the current items for the library.
 * Items are extended with new properties, see {@link DuListItem} for more details.
 * @property {DuLibraryItem} library The associated library data. Use setLibrary to change it.
 * @property {DuLibrary~onRun} onRun The function used to run the selected item.
 * @property {DuLibrary~onAltRun} onAltRun The function used to run the selected item with alt click.
 * @property {DuLibrary~onCtrlRun} onCtrlRun The function used to run the selected item with ctrl click.
 * @property {DuLibrary~onCtrlAltRun} onCtrlAltRun The function used to run the selected item with ctrl alt click.
 * @property {DuLibrary~onEditData} onEditData The function to execute to edit data.
 * @property {DuLibrary~onFolderOpened} onFolderOpened The function to open a containing folder
 * @property {DuLibrary~onFolderEdited} onFolderEdited The function to edit the folder
 * @property {DuLibrary~onAddItem} onAddItem The function to execute when adding a new item.
 * @property {DuLibrary~onEditItem} onEditItem The function to execute when editing an item.
 * @property {DuLibrary~onRemoveItem} onRemoveItem The function to execute when removing an item.
 * @property {DuLibrary~onRefresh} onRefresh The function to execute to refresh the library.
 * @property {DuLibrary~setLibrary} setLibrary Sets a new library. May be called from onRefresh to replace the lib by a new one.
 * @property {DuLibrary~setLibrary} runItem Runs the selected item. Tied to the apply/run button by default.
 * @extends {Group}
 * @category DuScriptUI
 */

/**
 * The function to execute to refresh the library.
 * @callback DuLibrary~onRefresh
 * @param {DuLibraryItem} category The category to refresh.
 * @memberof DuLibrary
 */

/**
 * Sets a new library. May be called from onRefresh to replace the lib by a new one.
 * @callback DuLibrary~setLibrary
 * @param {DuLibraryItem} newLib The new library.
 * @memberof DuLibrary
 */

/**
 * The function used to run the selected item.
 * @callback DuLibrary~onRun
 * @param {DuListItem} item The item to run/apply.
 * @memberof DuLibrary
 */

/**
 * The function used to run the selected item.
 * @callback DuLibrary~onAltRun
 * @param {DuListItem} item The item to run/apply.
 * @memberof DuLibrary
 */

/**
 * The function used to run the selected item.
 * @callback DuLibrary~onCtrlRun
 * @param {DuListItem} item The item to run/apply.
 * @memberof DuLibrary
 */

/**
 * The function used to run the selected item.
 * @callback DuLibrary~onCtrlAltRun
 * @param {DuListItem} item The item to run/apply.
 * @memberof DuLibrary
 */

/**
 * The function used to edit an item data.
 * @callback DuLibrary~onEditData
 * @param {DuListItem} item The item to edit.
 * @memberof DuLibrary
 */

/**
 * The function to open a containing folder.
 * @callback DuLibrary~onFolderOpened
 * @param {DuListItem} item The item to edit.
 * @param {Object} category The current category.
 * @memberof DuLibrary
 */

/**
 * The function to edit the folder.
 * @callback DuLibrary~onFolderEdited
 * @param {DuListItem} item The item to edit.
 * @param {Object} category The current category.
 * @memberof DuLibrary
 */

/**
 * The function to execute when adding a new item.
 * @callback DuLibrary~onAddItem
 * @param {Object} category The current category.
 * @memberof DuLibrary
 */

/**
 * The function to execute when editing an item.
 * @callback DuLibrary~onAddItem
 * @param {DuListItem} item The item to edit.
 * @param {Object} category The current category.
 * @memberof DuLibrary
 */

/**
 * The function to execute when removing an item.
 * @callback DuLibrary~onRemoveItem
 * @param {DuListItem} item The item to remove.
 * @param {Object} category The current category.
 * @memberof DuLibrary
 */

/**
 * @class
 * @name DuListItem
 * @classdesc For use with {@link DuScriptUI}.<br />
 * An item in a custom listbox used with {@link DuLibrary}.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.library} to create a Library.<br />
 * The Library has a <code>list</code> property which is a ScriptUI <code>ListBox</code> which contains these DuListItem.<br />
 * DuListItem inherits the <code>Item</code> object from ScriptUI and has all of its properties and methods.
 * @property {*} data The data associated with the item, depends on the library object passed to the DuLibrary.
 * @property {string} libType The type of item, one of ['item', 'category', 'parent']
 * @property {bool} editableData Wether this item data can be edited by the user.
 * @property {bool} editableItem Whether this item can be edited by the user.
 * @category DuScriptUI
 */

/**
 * @class
 * @name DuLibraryItem
 * @classdesc For use with {@link DuLibrary}.<br />
 * An item in a library.
 * @hideconstructor
 * @property {*} data The data associated with the item.
 * @property {string} libType The type of item, one of ['item', 'category']
 * @property {bool} editableData Wether this item data can be edited by the user.
 * @property {bool} editableItem Whether this item can be edited by the user.
 * @property {string} icon Either the path to an image or a png representation as a string.
 * @category DuScriptUI
 */

/**
 * Adds a new {@link DuLibrary} to the container.
 * @param {Panel|Window|Group} container The ScriptUI Object which will contain and display the library.
 * @param {DuLibraryItem} library A library object. Key/value pairs, values being {@link DuLibraryItem} objects, keys being their display name.
 * @param {object} [options] Options and other values.
 */
DuScriptUI.library = function( container, library, options ) {
    options = def(options, {});
    options.runButton = def(options.runButton, true);
    options.editDataButton = def(options.editDataButton, false);
    options.folderButton = def(options.folderButton, true);
    options.canEditFolder = def(options.canEditFolder, false);
    options.editListButtons = def(options.editListButtons, true);
    options.refreshInterval = def(options.refreshInterval, -1);
    options.defaultItemIcon = def(options.defaultItemIcon, '');
    options.itemName = def(options.itemName, DuScriptUI.String.ITEM);
    options.runHelpTip = def(options.runHelpTip, DuScriptUI.String.RUN);
    options.folderHelpTip = def(options.folderHelpTip, DuScriptUI.String.OPEN_FOLDER);
    options.addItemHelpTip = def(options.addItemHelpTip, DuScriptUI.String.ADD_ITEM_OR_CAT);
    options.editItemHelpTip = def(options.editItemHelpTip, DuScriptUI.String.EDIT_ITEM_OR_CAT);
    options.removeItemHelpTip = def(options.removeItemHelpTip, DuScriptUI.String.REMOVE_ITEM_OR_CAT);
    options.editDataHelpTip = def(options.editDataHelpTip, '');
    options.sortButton = def(options.sortButton, true);
    options.refreshButton = def(options.refreshButton, false);

    // The main group
    var duLibrary = container.add('group');
    duLibrary.orientation = 'column';
    duLibrary.alignment = ['fill', 'fill'];
    duLibrary.margins = 0;
    duLibrary.spacing = 0;
    // And its lib
    duLibrary.library = library;

    var runIcon = '';
    if (options.runButton) runIcon = DuScriptUI.Icon.RUN;
    else runIcon = DuScriptUI.Icon.CHECK;

    // UTILS
    duLibrary.currentCategory = duLibrary.library;
    var currentCommand = [];
    duLibrary.sortMode = 'up';

    function setCategory( cat ) {
        duLibrary.onRefresh( cat );

        duLibrary.currentCategory = cat;

        // Update the sort button
        duLibrary.srtButton.freeze = true;
        if (duLibrary.sortMode == 'none') duLibrary.srtButton.setCurrentIndex(0);
        else if (duLibrary.sortMode == 'down') duLibrary.srtButton.setCurrentIndex(2);
        else duLibrary.srtButton.setCurrentIndex(1);
        duLibrary.srtButton.freeze = false;

        if (duLibrary.sortMode != 'none') cat = DuJSObj.sort(cat, false, function( a, b ) {
            var aType = cat[a].libType;
            var bType = cat[b].libType;
            var r = 1;
            if (duLibrary.sortMode == 'down') r = -1;
            // Categories go first no matter what
            if (aType == 'category' && bType == 'item') return -r;
            else if (aType == 'item' && bType == 'category') return r;
            // Alphabetical
            if (a < b) return -r;
            if (a > b) return r;            
            return 0;
        });

        libList.removeAll();

        if (duLibrary.currentCategory != duLibrary.library) {
            var item = libList.add('item', '..');
            item.image = DuScriptUI.Icon.PARENT.binAsString;
            item.libType = 'parent';
            item.data = '';
            item.editableItem = false;
            item.editableData = false;
        }

        for (i in cat) {
            if (!cat.hasOwnProperty(i)) continue;
            // ignore lib properties
            if (i == 'libType') continue;
            if (i == 'icon') continue;
            if (i == 'data') continue;
            if (i == 'editableData') continue;
            if (i == 'editableItem') continue;
            var val = cat[i];
            // ignore unknown types
            if (typeof val.libType === 'undefined') continue;
            if (val.libType == 'item') {
                val.icon = def(val.icon, options.defaultItemIcon);
                if (val.icon == '') val.icon = options.defaultItemIcon;
                val.data = def (val.data, '');
                val.editableData = def (val.editableData, false);
                val.editableItem = def (val.editableItem, false);

                var item = libList.add('item', i);
                item.libType = 'item';
                item.data = val.data;
                item.editableItem = val.editableItem;
                item.editableData = val.editableData;
                try {  item.image = val.icon; }
                catch(e) {}
            }
            else {
                val.icon = def(val.icon, DuScriptUI.Icon.FOLDER_CLOSED.binAsString);
                val.data = def (val.data, '');
                val.editableData = false;
                val.editableItem = def (val.editableItem, false);

                var item = libList.add('item', i);
                item.libType = 'category';
                item.data = val.data;
                item.editableItem = val.editableItem;
                item.editableData = val.editableData;
                try {  item.image = val.icon; }
                catch(e) {}
            }
        }

        libList.onChange();
    }

    function updateCategory() {
        var cat = duLibrary.library;
        duLibrary.onRefresh( cat );
        for (var i = 0; i < currentCommand.length; i++) {
            if (!cat[currentCommand[i]]) break;
            cat = cat[currentCommand[i]];
            if (cat) duLibrary.onRefresh( cat );
        }
        setCategory(cat);
    }

    function updateBreadCrumbs() {
        tipLabel.text = currentCommand.join(' > ');
    }

    function parseCmd() {
        // Check if we're starting a new block
        var currentCmd = cmdEdit.text;
        if ( DuString.endsWith(currentCmd, ' >')) return;
        if ( DuString.fullTrim(currentCmd) == '') {
            updateCategory();
            return;
        }
        var newBlock = DuString.endsWith(currentCmd, ' ');
        // Search
        if (!newBlock) {
            // Get last block
            var search = currentCmd.toLowerCase();
            // Reset list
            setCategory(duLibrary.currentCategory);
            // Filter
            for (var i = libList.items.length -1; i >= 0; i--) {
                var item = libList.items[i];
                if ( // unsuccessful search
                    item.text.toLowerCase().indexOf(search) < 0
                    )
                {
                    libList.remove(i);
                }
            }
        }
        // Select
        else if (libList.items.length > 0 && currentCmd.length > 0) {
            var item = libList.items[0];
            if (item.libType == 'parent') {
                currentCommand.pop();
                updateBreadCrumbs();
                updateCategory();
                cmdEdit.setText('');
            }
            else if (item.libType == 'category') {
                currentCommand.push(item.text);
                updateBreadCrumbs();
                updateCategory();
                cmdEdit.setText('');
            }
            /*else if (item.libType == 'item') {
                cmdEdit.setText(item.text + ' >');
                updateCategory();
            }*/
        }
    };

    function run() {
        parseCmd();
        cmdEdit.setText(cmdEdit.text + ' ');
        parseCmd();
        if (libList.items.length < 0) return;
        var item = libList.items[0];
        if (item.libType == 'item') {
            duLibrary.onRun(item);
            // Clears the edit
            cmdEdit.setText('');
            parseCmd();
        }
    }

    duLibrary.runItem = function ( modifier ) {
        var item = libList.selection;
        if (!item) return;
        modifier = def(modifier, '');

        if (item.libType == 'parent') {
            currentCommand.pop();
            updateBreadCrumbs();
            updateCategory();
            cmdEdit.setText('');
            return;
        }

        if (item.libType == 'category') {
            currentCommand.push(item.text);
            updateBreadCrumbs();
            updateCategory();
            cmdEdit.setText('');
            return;
        }
        if (modifier == 'alt') duLibrary.onAltRun(item);
        else if (modifier == 'ctrl') duLibrary.onCtrlRun(item);
        else if (modifier == 'ctrlAlt') duLibrary.onCtrlAltRun(item);
        else duLibrary.onRun(item);
        // Clears the edit
        cmdEdit.setText('');
        parseCmd();
    };

    duLibrary.clear = function () {
        var currentCmd = cmdEdit.text;
        // Empty
        if ( DuString.fullTrim(currentCmd) == '') {
            currentCommand = [];
            updateBreadCrumbs();
            updateCategory();
        }
        cmdEdit.setText('');
        parseCmd();
    };

    duLibrary.refresh = function () {
        duLibrary.onRefresh(duLibrary.currentCategory);
        setCategory(duLibrary.currentCategory);
        updateBreadCrumbs();
    };

    duLibrary.sort = function(mode) {
        duLibrary.sortMode = mode;
        duLibrary.onRefresh(duLibrary.currentCategory);
        setCategory(duLibrary.currentCategory);
        updateBreadCrumbs();
    };

    // CREATE UI

    var cmdGroup = DuScriptUI.group(duLibrary, 'row');
    cmdGroup.spacing = 3;
    cmdGroup.alignment = ['fill', 'top'];

    var clearButton = DuScriptUI.button(
        cmdGroup,
        '',
        DuScriptUI.Icon.CLOSE,
        DuScriptUI.String.CLEAR_LIB_TIP
    );
    clearButton.alignment = ['left', 'fill'];
    clearButton.onClick = duLibrary.clear;

    var cmdEdit = DuScriptUI.editText(
        cmdGroup,
        '',
        '',
        '',
        DuScriptUI.String.START_TYPING_CMD
    );
    cmdEdit.alignment = ['fill', 'fill'];
    cmdEdit.onChanging = cmdEdit.onChange = parseCmd;
    cmdEdit.onEnterPressed = run;

    var tipGroup = DuScriptUI.group( duLibrary, 'row');
    tipGroup.alignment = ['fill', 'top'];

    var tipLabel = DuScriptUI.staticText(
        tipGroup,
        ''
    );
    tipLabel.alignment = ['fill', 'fill'];

    var listGroup = DuScriptUI.group( duLibrary, 'row');
    listGroup.alignment = ['fill', 'fill'];

    var libList = listGroup.add('listbox');
    libList.alignment = ['fill', 'fill'];
    libList.onDoubleClick = duLibrary.runItem;
    libList.onChange = function() {
        var item = libList.selection;
        if (options.editDataButton) {
            if (!item) duLibrary.editDataButton.visible = false;
            else duLibrary.editDataButton.visible = item.editableData;
        }

        if (options.editListButtons) {
            if (!item) {
                duLibrary.editItemButton.visible = false;
                removeItemButton.visible = false;
            }
            else {
                duLibrary.editItemButton.visible = item.editableItem; 
                removeItemButton.visible = duLibrary.currentCategory.editableItem && item.editableItem;
            }
            addItemButton.visible = duLibrary.currentCategory.editableItem;
            
        }
    };

    var listButtonsGroup = DuScriptUI.group( listGroup, 'column');
    listButtonsGroup.alignment = ['right', 'fill'];

    duLibrary.runButton = DuScriptUI.button(
        listButtonsGroup,
        '',
        runIcon,
        options.runHelpTip
    );
    duLibrary.runButton.alignment = ['right','top'];
    duLibrary.runButton.onClick = duLibrary.runItem;
    duLibrary.runButton.onAltClick = function() { duLibrary.runItem('alt') };
    duLibrary.runButton.onCtrlClick = function() { duLibrary.runItem('ctrl') };
    duLibrary.runButton.onCtrlAltClick = function() { duLibrary.runItem('ctrlAlt') };

    if (options.editDataButton) {
        duLibrary.editDataButton = DuScriptUI.button(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.EDIT,
            options.editDataHelpTip
        );
        duLibrary.editDataButton.alignment = ['right','top'];
        duLibrary.editDataButton.onClick = function() { 
            var selection = libList.selection;
            if (!selection) return;
            if (!selection.editableData) return;
            duLibrary.onEditData( selection );
        };
        duLibrary.editDataButton.onAltClick = function() { 
            var selection = libList.selection;
            if (!selection) return;
            if (!selection.editableData) return;
            duLibrary.onAltEditData( selection );
        };
    }

    if (options.folderButton) {
        var fldrButton = DuScriptUI.button(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.FOLDER_CLOSED,
            options.folderHelpTip
        );
        fldrButton.alignment = ['right','top'];
        fldrButton.onClick = function() {
            var selection = libList.selection;
            duLibrary.onFolderOpened(selection, duLibrary.currentCategory);
        };
        if (options.canEditFolder) {
            fldrButton.onAltClick = function() {
                var selection = libList.selection;
                duLibrary.onFolderEdited(selection, duLibrary.currentCategory);
            };
        }
    }

    if (options.sortButton) {
        duLibrary.srtButton = DuScriptUI.selector( listButtonsGroup, '', true );
        duLibrary.srtButton.alignment = ['right','top'];
        duLibrary.srtButton.addButton(
            '',
            DuScriptUI.Icon.SORT
        );
        duLibrary.srtButton.addButton(
            '',
            DuScriptUI.Icon.SORT_UP
        );
        duLibrary.srtButton.addButton(
            '',
            DuScriptUI.Icon.SORT_DOWN
        );
        duLibrary.srtButton.setCurrentIndex(1);
        duLibrary.srtButton.onChange = function() {
            if (duLibrary.srtButton.index == 0) duLibrary.sort('none');
            else if (duLibrary.srtButton.index == 1) duLibrary.sort('up');
            else if (duLibrary.srtButton.index == 2) duLibrary.sort('down');
        }
    }

    if (options.refreshButton) {
        var rfrshButton = DuScriptUI.button(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.UPDATE,
            DuScriptUI.String.REFRESH_LIB
        );
        rfrshButton.alignment = ['right','top'];
        rfrshButton.onClick = duLibrary.refresh;
    }

    if (options.editListButtons) {
        var addItemButton = DuScriptUI.multiButton(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.ADD,
            options.addItemHelpTip
        );
        addItemButton.alignment = ['right','bottom'];
        duLibrary.addItemButton = addItemButton.addButton(
            options.itemName
        );
        duLibrary.addCategoryButton = addItemButton.addButton(
            DuScriptUI.String.CATEGORY
        );

        duLibrary.addItemButton.onClick = function() {
            duLibrary.onAddItem(duLibrary.currentCategory);
        };
        duLibrary.addCategoryButton.onClick = function() {
            duLibrary.onAddCategory(duLibrary.currentCategory);
        }

        duLibrary.editItemButton = DuScriptUI.button(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.EDIT,
            options.editItemHelpTip
        );
        duLibrary.editItemButton.alignment = ['right','bottom'];
        duLibrary.editItemButton.onClick = function() {
            var selection = libList.selection;
            if (!selection) return;
            if (!selection.editableItem) return;
            duLibrary.onEditItem(selection, duLibrary.currentCategory);
        };

        var removeItemButton = DuScriptUI.button(
            listButtonsGroup,
            '',
            DuScriptUI.Icon.REMOVE,
            options.removeItemHelpTip
        );
        removeItemButton.alignment = ['right','bottom'];
        removeItemButton.onClick = function() {
            var selection = libList.selection;
            if (!selection) return;
            if (selection.libType == 'parent') return;
            // Add confirm
            duLibrary.onRemoveItem(selection, duLibrary.currentCategory);
        };
    }

    duLibrary.onRun = function() {};
    duLibrary.onAltRun = function() {};
    duLibrary.onCtrlRun = function() {};
    duLibrary.onCtrlAltRun = function() {};
    duLibrary.onEditData = function() {};
    duLibrary.onAltEditData = function() {};
    duLibrary.onFolderOpened = function() {};
    duLibrary.onFolderEdited = function() {};
    duLibrary.onAddItem = function() {};
    duLibrary.onAddCategory = function() {};
    duLibrary.onEditItem = function() {};
    duLibrary.onRemoveItem = function() {};
    duLibrary.onRefresh = function() {};

    duLibrary.setLibrary = function (newLib) {
        duLibrary.library = newLib;
        updateCategory();
    }

    duLibrary.list = libList;

    // Init 
    setCategory(duLibrary.library);

    // Refresh
    if (options.refreshInterval > 0) DuScriptUI.addEvent(duLibrary.refresh, 10000);

    return duLibrary;
}// ==================== |--------------| ====================
// ==================== | settingField | ====================
// ==================== |--------------| ====================

/**
 * @class
 * @name DuSettingField
 * @classdesc For use with {@link DuScriptUI}.<br />
 * An Setting field, which can be enabled or disabled.<br />
 * This is not a real class, and cannot be instanciated.<br />
 * Use {@link DuScriptUI.settingField} to create setting field.<br />
 * The DuSettingField inherits the <code>Group</code> object from ScriptUI and has all of its properties and methods.
 * @property {DuSettingField~onClick} onClick - The function to execute when the checkbox is clicked
 * @category DuScriptUI
 */

/**
 * The function to execute when the checkbox is clicked.
 * @callback DuSettingField~onClick
 * @memberof DuSettingField
 */

/**
 * Creates a {@link DuSettingField} which can be enabled or disabled
 * @param {Panel|Window|Group}		container	- The ScriptUI Object which will contain and display the setting.
 * @param {string}					[text]		- The label of the setting
 * @param {int}					[minimumLabelWidth]		- The minmimum width of the label
 * @return {DuSettingField}			The setting created.
 */
DuScriptUI.settingField = function(container, text, minimumLabelWidth ) {
    minimumLabelWidth = def(minimumLabelWidth, -1);

    var settingGroup = DuScriptUI.group(container, 'row');
    settingGroup.margin = 0;
    settingGroup.spacing = 3;
    settingGroup.alignment = ['fill', 'top'];

    text = tr(text);

    var checkbox = DuScriptUI.checkBox( settingGroup, {
        text: text + ':',
        localize: false
    });
    checkbox.alignment = ['left', 'center'];
    checkbox.minimumSize = [minimumLabelWidth, -1];

    settingGroup = DuScriptUI.group(settingGroup, 'row');
    settingGroup.spacing = 0;
    settingGroup.margin = 0;
    settingGroup.alignment = ['fill', 'fill'];
    settingGroup.checked = settingGroup.enabled = false;

    settingGroup.onClick = function() {};

    settingGroup.setChecked = function (c) {
        checkbox.setChecked(c);
        settingGroup.enabled = c;
    };
    
    checkbox.onClick = function() {
        settingGroup.checked = checkbox.value;
        settingGroup.enabled = checkbox.value;
        settingGroup.onClick();
    };

    return settingGroup;
};
//low-level list of functions to be run when the user interacts with the UI
DuScriptUI.eventFunctions = [];

/**
 * Adds a function to be run periodically, which will be connected to several UI events, fired when the user interacts with the UI.
 * @param {function} func The function to connect to the UI
 * @param {int} [timeOut=3000] A timeOut in milliseconds which prevents the function to be run too often
 * @return {int} a unique identifier to be used to remove the function later, with {@link DuScriptUI.removeEvent}.
 */
DuScriptUI.addEvent = function (func, timeOut)
{
    timeOut = def(timeOut, 3000);
    func.id = new Date().getTime();
    func.timeOut = timeOut;
    func.lastFire = func.id;
    DuScriptUI.eventFunctions.push(func);
    return func.id;
}

/**
 * Removes a function previously added with {@link DuScriptUI.addEvent}.
 * @param {int} id The id of the function
 */
DuScriptUI.removeEvent = function (id)
{
    for (var i = 0, n = DuScriptUI.eventFunctions.length; i < n; i++)
    {
        var f = DuScriptUI.eventFunctions[i];
        if (f.id == id)
        {
            DuScriptUI.eventFunctions.splice(i,1);
            break;
        }
    }
}

/**
 * The default alignment of children of containers with "column" orientation
 * @type {String[]}
 * @default ["fill","top"]
 */
DuScriptUI.defaultColumnAlignment = [ "fill", "top" ];

/**
 * The default alignment of children of containers with "row" orientation
 * @type {String[]}
 * @default ["left","center"]
 */
DuScriptUI.defaultRowAlignment = [ "left", "center" ];

/**
 * The default alignment of children of containers with "stack" orientation
 * @type {String[]}
 * @default ["fill","top"]
 */
DuScriptUI.defaultStackAlignment = [ "fill", "fill" ];

/**
 * The default spacing of containers
 * @type {int}
 * @default 2
 */
DuScriptUI.defaultSpacing = 2;

/**
 * The default margins of containers
 * @type {int}
 * @default 2
 */
DuScriptUI.defaultMargins = 2;

/**
 * A bar used to show current funding status.
 * @type {ProgressBar}
 */
DuScriptUI.fundingBar = null;

/**
 * A label used to show current funding status.
 * @type {StaticText}
 */
DuScriptUI.fundingLabel = null;

//low-level undocumented list: keeps the currently highlighted controls
DuScriptUI.highlightedControls = [];

//low-level undocumented list: keeps all the tabs, used in the buildAllTabs method
DuScriptUI.allTabs = [];

//low-level undocumented flag: set to true when showUI has been called. Before this, there's no need to set layout for children, this will improve performance greatly.
DuScriptUI.uiShown = false;

//low-level undocumented flag: pause events firing (used with popups)
DuScriptUI.eventFunctionsPaused = false;

//low-level undocumented function: dims all currently highlighted controls
//Also runs all functions in DuScriptUI.eventFunctions
DuScriptUI.dimControls = function( )
{
    if (!DuScriptUI.eventFunctionsPaused)
    {
        var now = new Date().getTime();
        for (var i = 0, n = DuScriptUI.eventFunctions.length; i < n; i++)
        {
            var f = DuScriptUI.eventFunctions[i];
            if (now - f.lastFire < f.timeOut) continue;
            f();
            f.lastFire = now;
        }
    }

    if ( DuScriptUI.highlightedControls.length == 0 ) return;
    for ( var i = DuScriptUI.highlightedControls.length - 1; i >= 0; i-- )
    {
        try
        {
            DuScriptUI.highlightedControls[ i ].dim();
        }
        catch ( e )
        {};
        DuScriptUI.highlightedControls.pop();
    }
}

// ==================== |-----| ====================
// ==================== | oco | ====================
// ==================== |-----| ====================

/**
 * Methods to load and create OCO Documents and armatures
 * @namespace
 * @category DuOCO
 */
var DuOCO = {};

/**
 * Types of OCO armatures
 * @enum {string}
 */
DuOCO.Type = {
    /**
     * A meta-rig, used to automatically create a default armature to be used with an auto-rig.
     */
    META: 'meta',
    /**
     * An actual (rigged) character.
     */
    CHARACTER: 'character'
}

/**
 * Predefined limbs
 * @enum {string}
 */
DuOCO.Limb = {
    SPINE: 'spine',
    ARM: 'arm',
    LEG: 'leg',
    TAIL: 'tail',
    WING: 'wing',
    HAIR: 'hair',
    SNAKE_SPINE: 'snakeSpine',
    FISH_SPINE: 'fishSpine',
    FIN: 'fin',
    CUSTOM: 'custom'
}

/**
 * Some bone identifierss
 * @enum {string}
 */
DuOCO.Bone = {
    CUSTOM: 'custom',
    TIP: 'tip',
    CLAVICLE: 'clavicle',
    HUMERUS: 'humerus',
    RADIUS: 'radius',
    CARPUS: 'carpus',
    FINGER: 'finger',
    HEEL: 'heel',
    FEMUR: 'femur',
    TIBIA: 'tibia',
    TARSUS: 'tarsus',
    TOE: 'toe',
    HIPS: 'hips',
    SPINE: 'spine',
    TORSO: 'torso',
    NECK: 'neck',
    SKULL_TIP: 'skullTip',
    SKULL: 'skull',
    TAIL_ROOT: 'tail1',
    TAIL_MID: 'tail2',
    TAIL_END: 'tail3',
    FEATHER: 'feather',
    SNAKE_SPINE_ROOT: 'snakeSpine1',
    SNAKE_SPINE_MID: 'snakeSpine2',
    SNAKE_SPINE_END: 'snakeSpine3',
    FISH_SPINE_ROOT: 'fishSpine1',
    FISH_SPINE_MID: 'fishSpine2',
    FISH_SPINE_END: 'fishSpine3',
    HAIR_ROOT: 'snakeSpine1',
    HAIR_MID: 'snakeSpine2',
    HAIR_END: 'snakeSpine3',
    FIN: 'fin',
    FIN_FISHBONE: 'finBone'
}

/**
 * Types of limbs
 * @enum {string}
 */
DuOCO.LimbType = {
    HOMINOID: 'hominoid',
    PLANTIGRADE: 'plantigrade',
    DIGITIGRADE: 'digitigrade',
    UNGULATE: 'ungulate',
    ARTHROPOD: 'arthropod',
    CUSTOM: 'custom'
}

/**
 * Sides for the limbs Use these with {@link DuOCO.Location} to differenciate similar limbs,<br />
 * for example, a leg can be Front-Right, Front-Left, Back-Right, Back-Left, etc.
 * @enum {string}
 */
DuOCO.Side = {
    LEFT: DuScriptUI.String.LEFT_SHORT,
    RIGHT: DuScriptUI.String.RIGHT_SHORT,
    NONE: ''
}

/**
 * Locations for the limbs. Use these with {@link DuOCO.Side} to differenciate similar limbs,<br />
 * for example, a leg can be Front-Right, Front-Left, Back-Right, Back-Left, etc.
 * @enum {string}
 */
DuOCO.Location = {
    FRONT: DuScriptUI.String.FRONT_SHORT,
    BACK: DuScriptUI.String.BACK_LOCATION_SHORT,
    TAIL: DuScriptUI.String.TAIL_SHORT,
    MIDDLE: DuScriptUI.String.MIDDLE_SHORT,
    ABOVE: DuScriptUI.String.ABOVE_SHORT,
    UNDER: DuScriptUI.String.UNDER_SHORT,
    NONE: ''
}

DuOCO.View = {
    FRONT: 0,
    LEFT: 1,
    RIGHT: 2,
    BACK: 3,
    TOP: 4,
    BOTTOM: 5
}

/**
 * Gets the boundaries of an armature (a chain of bones)
 * @param {DuOCOBone[]} armature The chain of bones
 * @returns {float[]} [left, top, right, bottom]
 */
DuOCO.getBounds = function ( armature )
{
    var left = 9999;
    var right = -9999;
    var top = 9999;
    var bottom = -9999;

    for (var i = 0, n = armature.length; i < n; i++)
    {
        var b = armature[i];
        // Check current bone
        if (b.x < left) left = b.x;
        if (b.x > right) right = b.x;
        if (b.y < bottom) bottom = b.y;
        if (b.y > top) top = b.y;
        // Check children
        var childBounds = DuOCO.getBounds( b.children );
        if (childBounds[0] < left) left = childBounds[0];
        if (childBounds[1] < top) top = childBounds[1];
        if (childBounds[2] < right) right = childBounds[2];
        if (childBounds[3] < bottom) bottom = childBounds[3];
        // Check other limbs
        for ( var j = 0, nL = b.limbs.length; j < nL; j++ )
        {
            var limbBounds = b.limbs[i].bounds();
            if (limbBounds[0] < left) left = limbBounds[0];
            if (limbBounds[1] < top) top = limbBounds[1];
            if (limbBounds[2] < right) right = limbBounds[2];
            if (limbBounds[3] < bottom) bottom = limbBounds[3];
        }
    }

    return [left, top, right, bottom];
}

/**
 * Creates a new OCO Document.
 * @class
 * @classdesc An Open Cut-Out character or meta-rig document.
 * @param {string} name The name of the character or the meta rig
 * @category DuOCO
 */
function DuOCODoc(name)
{
    /**
     * The type of this OCO Doc
     * @name type
     * @memberof DuOCODoc
     * @type {string}
     */
    this.type = DuOCO.Type.META;
    /**
     * The name of this OCO Doc
     * @name name
     * @memberof DuOCODoc
     * @type {string}
     */
    this.name = name;
    /**
     * The height of the character. Should always be 1!
     * @name height
     * @memberof DuOCODoc
     * @type {float}
     */
    this.height = 185.0;
    /**
     * The width of the character.
     * @name width
     * @memberof DuOCODoc
     * @type {float}
     */
    this.width = 60.0,
    /**
     * The coordinates of the center of mass of the character. [X, Y].
     * @name centerOfMass
     * @memberof DuOCODoc
     * @type {float[]}
     */
    this.centerOfMass = [0.0, 107.0];
    /**
     * The limbs/ Armatures
     * @name limbs
     * @memberof DuOCOLimb
     * @type {DuOCOLimb[]}
     */
    this.limbs = [];
    this.resolution = [1920,1080];
    this.world = [960,980];
    this.pixelsPerCm = 4.22;
}

/**
 * Gets the boundaries of the doc
 * @returns {float[]} [left, top, right, bottom]
 */
DuOCODoc.prototype.bounds = function ()
{
    var left = 9999;
    var right = -9999;
    var top = 9999;
    var bottom = -9999;

    for (var i = 0, n = this.limbs.length; i < n; i++)
    {
        var limbBounds = this.limbs[i].bounds();
        if (limbBounds[0] < left) left = limbBounds[0];
        if (limbBounds[1] < top) top = limbBounds[1];
        if (limbBounds[2] < right) right = limbBounds[2];
        if (limbBounds[3] < bottom) bottom = limbBounds[3];
    }

    return [left, top, right, bottom];
}

/**
 * Updates the width and height of the character, according to the content.<br />
 * This method should be called each time a limb/bone is added/removed/edited and the bounds may change.
 */
DuOCODoc.prototype.updateSize = function()
{
    // Update doc width & height
    var bounds = this.bounds();
    // right - left
    this.width = this.bounds[2] - this.bounds[0];
    // top - bottom
    this.height = this.bounds[1] - this.bounds[3];
}

/**
 * Creates a new limb and adds it to the doc
 * @param {DuOCO.Limb} [limb=DuOCO.Limb.CUSTOM] A Predefined limb
 * @param {DuOCO.Side} [side=DuOCO.Side.NONE] - The side of the limb
 * @param {DuOCO.Location} [location=DuOCO.Location.NONE] - The location of the limb
 * @param {DuOCO.LimbType} [type=DuOCO.LimbType.CUSTOM] - The type of the limb
 * @return {DuOCOLimb} The new limb
 */
DuOCODoc.prototype.newLimb = function( limb, side, location, type )
{
    var l = new DuOCOLimb( limb, side, location, type );
    this.limbs.push(l);
    return l;
}

/**
 * Creates a new arm.
 * @param {DuOCO.LimbType} [type=DuOCO.LimbType.HOMINOID] The type of limb
 * @param {DuOCO.Side} [side=DuOCO.Side.LEFT] The side
 * @param {Boolean} [shoulder=false] Whether to create a shoulder
 * @param {Boolean} [arm=true]  Whether to create an arm / humerus
 * @param {Boolean} [forearm=true]  Whether to create a forearm
 * @param {Boolean} [hand=true]  Whether to create a hand
 * @param {Boolean} [claws=false]  Whether to add claws
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @param {DuOCO.Location} [location=DuOCO.Location.FRONT] The location of the limb
 * @param {DuOCO.View} [view] The view
 * @returns {DuOCOLimb} The arm
 */
DuOCODoc.prototype.newArm = function( type, side, shoulder, arm, forearm, hand, claws, position, location, view )
{
    side = def(side, DuOCO.Side.LEFT);
    type = def(type, DuOCO.LimbType.HOMINOID);
    location = def(location, DuOCO.Location.FRONT);

    shoulder = def( shoulder, false );
    arm = def( arm, true );
    forearm = def( forearm, true );
    hand = def( hand, true );
    claws = def( claws, false );

    // Unit
    var u = this.height;

    // type
    var hum = type == DuOCO.LimbType.HOMINOID;
    var hum = type == DuOCO.LimbType.PLANTIGRADE && !claws;
    var plan = type == DuOCO.LimbType.PLANTIGRADE && claws;
    var dig = type == DuOCO.LimbType.DIGITIGRADE;
    var ung = type == DuOCO.LimbType.UNGULATE;
    var artF = type == DuOCO.LimbType.ARTHROPOD && location != DuOCO.Location.MIDDLE && location != DuOCO.Location.BACK;
    var artM = type == DuOCO.LimbType.ARTHROPOD && location == DuOCO.Location.MIDDLE;
    var artB = type == DuOCO.LimbType.ARTHROPOD && location == DuOCO.Location.BACK;
    if ( !hum && !plan && !dig && !ung && !artF && !artM && !artB ) hum = true;

    // View
    if (!isdef( view ))
    {
        if (type == DuOCO.LimbType.PLANTIGRADE && !claws) view = DuOCO.View.FRONT;
        else view = DuOCO.View.RIGHT;
    }

    // count how many bones we need
    var num = 1;
    if ( shoulder ) num++;
    if ( arm ) num++;
    if ( forearm ) num++;
    if ( hand ) num++;
    if ( claws ) num++;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.ARM, side, location, type );
    var b = limb.newArmature( DuScriptUI.String.ARM, num );

    // side
    var s = 1;
    if ( side == DuOCO.Side.RIGHT && view == DuOCO.View.FRONT ) s = -1;
    else if ( side == DuOCO.Side.LEFT && view == DuOCO.View.BACK ) s = -1;
    else if ( view == DuOCO.View.LEFT ) s = -1;  

    // shoulder position
    var x, y;
    var ox = 0;
    var oy = 0;
    if (hum)
    {
        x = s * u * .02;
        y = u * .78;
    }
    else if (plan)
    {
        x = s * u * .40;
        y = u * .92;
    }
    else if (dig)
    {
        x = s * u * .45;
        y = u * .86;
    }
    else if (ung)
    {
        x = s * u * .33;
        y = u * .80;
    }
    else if (artF)
    {
        x = s * u * .33;
        y = u * .65;
    }
    else if (artM)
    {
        x = s * u * .09;
        y = u * .50;
    }
    else if (artB)
    {
        x = s * u * -.03;
        y = u * .48;
    }

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // for each part, set the location
    if ( shoulder )
    {
        b.name = DuScriptUI.String.SHOULDER;
        b.type = DuOCO.Bone.CLAVICLE;
        b.x = x + ox;
        b.y = y + oy;
        if (b.children.length > 0) b = b.children[0];
    }
    if ( arm )
    {
        b.name = DuScriptUI.String.ARM;
        b.type = DuOCO.Bone.HUMERUS;
        if (hum)
        {
            b.x = s * u * .12 + ox;
            b.y = u * .77 + oy;
        }
        else if (plan)
        {
            b.x = s * u * .48 + ox;
            b.y = u*.74 + oy;
        }
        else if (dig)
        {
            b.x = s * u * .45 + ox;
            b.y = u*.66 + oy;
        }
        else if (ung)
        {
            b.x = s * u * .35 + ox;
            b.y = u*.63 + oy;
        }
        else if (artF)
        {
            b.x = s * u * .24 + ox;
            b.y = u*.45 + oy;
        }
        else if (artM)
        {
            b.x = s * u * -.01 + ox;
            b.y = u*.44 + oy;
        }
        else if (artB)
        {
            b.x = s * u * -.17 + ox;
            b.y = u*.43 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    if ( forearm )
    {
        b.name = DuScriptUI.String.FOREARM;
        b.type = DuOCO.Bone.RADIUS;
        if (hum)
        {
            b.x = s * u * .15 + ox;
            b.y = u *.65 + oy;
        }
        else if (plan)
        {
            b.x = s * u * .36 + ox;
            b.y = u*.44 + oy;
        }
        else if (dig)
        {
            b.x = s * u * .21 + ox;
            b.y = u*.45 + oy;
        }
        else if (ung)
        {
            b.x = s * u * .24 + ox;
            b.y = u*.53 + oy;
        }
        else if (artF)
        {
            b.x = s * u * .55 + ox;
            b.y = u*.80 + oy;
        }
        else if (artM)
        {
            b.x = s * u * -.08 + ox;
            b.y = u*.82 + oy;
        }
        else if (artB)
        {
            b.x = s * u * -.44 + ox;
            b.y = u*.92 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    if ( hand )
    {
        b.name = DuScriptUI.String.HAND;
        b.type = DuOCO.Bone.CARPUS;
        if (hum)
        {
            b.x = s * u * .12 + ox;
            b.y = u * .51 + oy;
        }
        else if (plan)
        {
            b.x = s * u * .38 + ox;
            b.y = u*.05 + oy;
        }
        else if (dig)
        {
            b.x = s * u * .45 + ox;
            b.y = u*.14 + oy;
        }
        else if (ung)
        {
            b.x = s * u * .19 + ox;
            b.y = u*.31 + oy;
        }
        else if (artF)
        {
            b.x = s * u * .77 + ox;
            b.y = u*.28 + oy;
        }
        else if (artM)
        {
            b.x = s * u * -.17 + ox;
            b.y = u*.42 + oy;
        }
        else if (artB)
        {
            b.x = s * u * -.77 + ox;
            b.y = u*.47 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    if ( claws )
    {
        b.name = DuScriptUI.String.CLAWS;
        b.type = DuOCO.Bone.FINGER;
        if (plan)
        {
            b.x = s * u * .455 + ox;
            b.y = u*.035 + oy;
        }
        else if (dig)
        {
            b.x = s * u * .49 + ox;
            b.y = u*.03 + oy;
        }
        else if (ung)
        {
            b.x = s * u * .19 + ox;
            b.y = u*.14 + oy;
        }
        else if (artF)
        {
            b.x = s * u * .86 + ox;
            b.y = u*.07 + oy;
        }
        else if (artM)
        {
            b.x = s * u * -.25 + ox;
            b.y = u*.07 + oy;
        }
        else if (artB)
        {
            b.x = s * u * -.98 + ox;
            b.y = u*.07 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    // Tip
    b.name = DuScriptUI.String.ARM + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    if (hum)
    {
        b.x = s * u * .08 + ox;
        b.y = u * .42 + oy;
    }
    else if (plan)
    {
        b.x = s * u * .585 + ox;
        b.y = 0 + oy;
    }
    else if (dig)
    {
        b.x = s * u * .59 + ox;
        b.y = u*.03 + oy;
    }
    else if (ung)
    {
        b.x = s * u * .21 + ox;
        b.y = oy;
    }
    else if (artF)
    {
        b.x = s * u * .93 + ox;
        b.y = oy;
    }
    else if (artM)
    {
        b.x = s * u * -.31 + ox;
        b.y = oy;
    }
    else if (artB)
    {
        b.x = s * u * -1.06 + ox;
        b.y = oy;
    }

    //Heel
    if (plan)
    {
        var heelBone = new DuOCOBone( DuScriptUI.String.HEEL );
        heelBone.type = DuOCO.Bone.HEEL;
        heelBone.x = s * u * .38 + ox;
        heelBone.y = 0 + oy;
        b.children.push(heelBone);
    }

    return limb;
}

/**
 * Creates a new leg.
 * @param {DuOCO.LimbType} [type=DuOCO.LimbType.HOMINOID] The type of limb
 * @param {DuOCO.Side} [side=DuOCO.Side.LEFT] The side
 * @param {Boolean} [thigh=true]  Whether to create a thigh
 * @param {Boolean} [calf=true]  Whether to create a calf
 * @param {Boolean} [foot=true]  Whether to create a foot
 * @param {Boolean} [claws=false]  Whether to add claws
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @param {DuOCO.Location} [location=DuOCO.Location.BACK] The location of the limb
 * @param {DuOCO.View} [view] The view
 * @returns {DuOCOLimb} The leg
 */
DuOCODoc.prototype.newLeg = function( type, side, thigh, calf, foot, claws, position, location, view )
{
    side = def(side, DuOCO.Side.LEFT);
    type = def(type, DuOCO.LimbType.HOMINOID);
    location = def(location, DuOCO.Location.BACK);

    thigh = def( thigh, true );
    calf = def( calf, true );
    foot = def( foot, true );
    claws = def( claws, false );

    // Unit
    var u = this.height;

    // type
    var plan = type == DuOCO.LimbType.PLANTIGRADE;
    var dig = type == DuOCO.LimbType.DIGITIGRADE;
    var ung = type == DuOCO.LimbType.UNGULATE;
    var hum = type == DuOCO.LimbType.HOMINOID;

    // View
    if (!isdef( view ))
    {
        if (type == DuOCO.LimbType.PLANTIGRADE) view = DuOCO.View.FRONT;
        else view = DuOCO.View.RIGHT;
    }

    // count how many bones we need
    var num = 1;
    if ( thigh ) num++;
    if ( calf ) num++;
    if ( foot ) num++;
    if ( claws ) num++;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.LEG, side, location, type );
    var b = limb.newArmature( DuScriptUI.String.LEG, num );

    // side
    var s = 1;

    if ( side == DuOCO.Side.RIGHT && view == DuOCO.View.FRONT ) s = -1;
    else if ( side == DuOCO.Side.LEFT && view == DuOCO.View.BACK ) s = -1;
    else if ( view == DuOCO.View.LEFT ) s = -1;

    // thigh position
    var x, y;
    var ox = 0;
    var oy = 0;
    if (plan || hum)
    {
        x = s * u * .04;
        y = u * .53;
    }
    else if (dig)
    {
        x = s * u * -.45;
        y = u * .73;
    }
    else if (ung)
    {
        x = s * u * -.26;
        y = u * .69;
    }

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // for each part, set the location
    if ( thigh )
    {
        b.name = DuScriptUI.String.THIGH;
        b.type = DuOCO.Bone.FEMUR;
        b.x = x + ox;
        b.y = y + oy;
        if (b.children.length > 0) b = b.children[0];
    }
    if ( calf )
    {
        b.name = DuScriptUI.String.CALF;
        b.type = DuOCO.Bone.TIBIA;
        if (plan || hum)
        {
            b.x = s * u * .05 + ox;
            b.y = u*.28 + oy;
        }
        else if (dig)
        {
            b.x = s * u * -.16 + ox;
            b.y = u*.54 + oy;
        }
        else if (ung)
        {
            b.x = s * u * -.2 + ox;
            b.y = u*.52 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    if ( foot )
    {
        b.name = DuScriptUI.String.FOOT;
        b.type = DuOCO.Bone.TARSUS;
        if (plan || hum)
        {
            b.x = s * u * .036 + ox;
            b.y = u*.027 + oy;
        }
        else if (dig)
        {
            b.x = s * u * -.5 + ox;
            b.y = u*.24 + oy;
        }
        else if (ung)
        {
            b.x = s * u * -.38 + ox;
            b.y = u*.33 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    if ( claws )
    {
        b.name = DuScriptUI.String.CLAWS;
        if (hum) b.name = DuScriptUI.String.TOES;
        b.type = DuOCO.Bone.TOE;
        if (plan || hum)
        {
            b.x = s * u * .10 + ox;
            b.y = u*.0125 + oy;
        }
        else if (dig)
        {
            b.x = s * u * -.37 + ox;
            b.y = u*.03 + oy;
        }
        else if (ung)
        {
            b.name = DuScriptUI.String.HOOF;
            b.x = s * u * -.37 + ox;
            b.y = u*.08 + oy;
        }
        if (b.children.length > 0) b = b.children[0];
    }
    // Tip
    b.name = DuScriptUI.String.LEG + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    if (plan || hum)
    {
        b.x = s * u * .145 + ox;
        b.y = oy;
    }
    else if (dig)
    {
        b.x = s * u * -.25 + ox;
        b.y = oy;
    }
    else if (ung)
    {
        b.x = s * u * -.34 + ox;
        b.y = oy;
    }

    //Heel
    if ((plan || hum) && claws)
    {
        var heelBone = new DuOCOBone( DuScriptUI.String.HEEL );
        heelBone.type = DuOCO.Bone.HEEL;
        heelBone.x = s * u * .01 + ox;
        heelBone.y = oy;
        b.children.push(heelBone);
    }

    return limb;
}

/**
 * Creates a new spine.
 * @param {Boolean} [head=true]  Whether to create a head
 * @param {int} [neck=1] Number of neck bones
 * @param {int} [spine=2] Number of spine bones
 * @param {Boolean} [hips=true]  Whether to create hips
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @param {DuOCO.View} [view] The view
 * @returns {DuOCOLimb} The spine
 */
DuOCODoc.prototype.newSpine = function( head, neck, spine, hips, position )
{
    head = def( head, true );
    neck = def( neck, 1 );
    spine = def( spine, 2 );
    hips = def( hips, false );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = 1;
    if ( head ) num++;
    num += neck;
    num += spine;
    if ( hips ) num++;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.SPINE, DuOCO.Side.NONE, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.SPINE, num );

    // hips position
    var ox = 0;
    var oy = 0;
    var x = 0;
    var y = u * .53;

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // for each part, set the location
    if ( hips )
    {
        b.name = DuScriptUI.String.HIPS;
        b.type = DuOCO.Bone.HIPS;
        b.x = x + ox;
        b.y = y + oy;
        if (b.children.length > 0) b = b.children[0];
    }
    if (spine > 1)
    {
        var totalSpineLength = u*.27;
        var torsoLength = totalSpineLength*.5;
        var spineLength = (totalSpineLength - torsoLength) / (spine-1);
        var spineStart = u*.56;
        for (var i = 0; i < spine-1; i++)
        {
            b.name = DuScriptUI.String.SPINE;
            b.type = DuOCO.Bone.SPINE;
            b.y = spineStart + i*spineLength + oy;
            b.x = ox;
            if (b.children.length > 0) b = b.children[0];
        }
        // Torso
        b.name = DuScriptUI.String.TORSO;
        b.type = DuOCO.Bone.TORSO;
        b.y = spineStart + (spine-1)*spineLength + oy;
        b.x = ox;
        if (b.children.length > 0) b = b.children[0];
    }
    else if (spine == 1)
    {
        // Torso
        b.name = DuScriptUI.String.TORSO;
        b.type = DuOCO.Bone.TORSO;
        b.x = ox;
        b.y = u*.56 + oy;
        if (b.children.length > 0) b = b.children[0];
    }
    if (neck > 0)
    {
        var neckLength = u*.06 / neck;
        var neckStart = u*.83;
        for (var i = 0; i < neck; i++)
        {
            b.name = DuScriptUI.String.NECK;
            b.type = DuOCO.Bone.NECK;
            b.y = neckStart + i*neckLength + oy;
            b.x = ox;
            if (b.children.length > 0) b = b.children[0];
        }
    }  
    if ( head )
    {
        b.name = DuScriptUI.String.HEAD;
        b.type = DuOCO.Bone.SKULL;
        b.x = ox;
        b.y = u*.89 + oy;
        if (b.children.length > 0) b = b.children[0];
    }

    // Tip
    b.name = DuScriptUI.String.SPINE + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    b.x = ox;
    b.y = u + oy;

    return limb;
}

/**
 * Creates a new tail.
 * @param {int} [numBones=3] Number of tail bones
 * @returns {DuOCOLimb} The spine
 */
DuOCODoc.prototype.newTail = function( numBones )
{
    numBones = def( numBones, 3 );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = numBones+1;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.TAIL, DuOCO.Side.NONE, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.TAIL, num );

    // for each part, adjust name and type
    for (var i = 0, n = num-1; i < n; i++)
    {
        b.name = DuScriptUI.String.TAIL;
        if ( i <= (n-1) / 3) b.type = DuOCO.Bone.TAIL_ROOT;
        else if ( i <= (n-1)*2 / 3) b.type = DuOCO.Bone.TAIL_MID;
        else b.type = DuOCO.Bone.TAIL_END;
        
        if (b.children.length > 0) b = b.children[0];
    }

    b.name = DuScriptUI.String.TAIL + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;

    return limb;
}

/**
 * Creates a new hair strand.
 * @param {int} [numBones=3] Number of hair bones
 * @returns {DuOCOLimb} The hair
 */
DuOCODoc.prototype.newHairStrand = function( numBones )
{
    numBones = def( numBones, 3 );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = numBones+1;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.HAIR, DuOCO.Side.NONE, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.HAIR, num );

    var l = 100 / numBones;

    // for each part, adjust name and type
    for (var i = 0, n = num-1; i < n; i++)
    {
        b.name = DuScriptUI.String.HAIR;
        if ( i <= (n-1) / 3) b.type = DuOCO.Bone.HAIR_ROOT;
        else if ( i <= (n-1)*2 / 3) b.type = DuOCO.Bone.HAIR_MID;
        else b.type = DuOCO.Bone.HAIR_END;

        b.x = 0;
        b.y = 150 - i*l;
        
        if (b.children.length > 0) b = b.children[0];
    }

    b.name = DuScriptUI.String.HAIR + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    b.x = 0;
    b.y = 50;

    return limb;
}

/**
 * Creates a new wing.
 * @param {DuOCO.Side} [side=DuOCO.Side.LEFT] The side
 * @param {Boolean} [arm=true]  Whether to create an arm / humerus
 * @param {Boolean} [forearm=true]  Whether to create a forearm
 * @param {Boolean} [hand=true]  Whether to create a hand
 * @param {int} [feathers=5]  Number of feathers
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @param {DuOCO.View} [view=DuOCO.View.TOP] The view
 * @returns {DuOCOLimb} The wing
 */
DuOCODoc.prototype.newWing = function( side, arm, forearm, hand, feathers, position, view )
{
    side = def(side, DuOCO.Side.LEFT);
    view = def(view, DuOCO.View.TOP);

    arm = def( arm, true );
    forearm = def( forearm, true );
    hand = def( hand, true );
    feathers = def( feathers, 5 );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = 1;
    if (arm) num++;
    if (forearm) num++;
    if (hand) num++;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.WING, side, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.WING, num );

    // side
    var s = 1;
    if ( side == DuOCO.Side.RIGHT && (view == DuOCO.View.TOP || view == DuOCO.View.BACK) ) s = -1;
    else if ( side == DuOCO.Side.LEFT && (view == DuOCO.View.BOTTOM || view == DuOCO.View.FRONT) ) s = -1;
    else if ( view == DuOCO.View.LEFT ) s = -1;

    // arm position
    var x, y;
    if ( view == DuOCO.View.TOP || view == DuOCO.View.BOTTOM )
    {
        x = s * u * -.12;
        y = u * .64;
    }
    else return limb; // not supported yet
    var ox = 0;
    var oy = 0;

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // We need to keep the parents of the feathers
    var parent1, parent2;

    // for each part, set the location
    if ( arm )
    {
        b.name = DuScriptUI.String.ARM;
        b.type = DuOCO.Bone.HUMERUS;
        b.x = x + ox;
        b.y = y + oy;

        if (!forearm && !hand)
        {
            parent1 = b;
            parent2 = b;
        }

        if (b.children.length > 0) b = b.children[0];
    }
    if (forearm)
    {
        b.name = DuScriptUI.String.FOREARM;
        b.type = DuOCO.Bone.RADIUS;
        b.x = s * u * -.22 + ox;
        b.y = u * .53 + oy;

        parent1 = b;
        if (!hand) parent2 = b;

        if (b.children.length > 0) b = b.children[0];
    }
    if (hand)
    {
        b.name = DuScriptUI.String.HAND;
        b.type = DuOCO.Bone.CARPUS;
        b.x = s * u * -.37 + ox;
        b.y = u * .64 + oy;

        parent2 = b;
        if (!forearm) parent1 = b;

        if (b.children.length > 0) b = b.children[0];
    }

    // Tip
    b.name = DuScriptUI.String.WING + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    b.x = s * u * -.53 + ox;
    b.y = u * .66 + oy;

    // Add Feathers
    if (feathers == 0) return limb;

    function createFeather( xr, yr, xt, yt, p )
    {
        var boneName = DuString.generateUnique(DuScriptUI.String.FEATHER, names);
        b = new DuOCOBone( boneName );
        b.type = DuOCO.Bone.FEATHER;
        b.x = s * u * xr + ox;
        b.y = u * yr + oy;

        // tip
        var boneName = DuString.generateUnique(DuScriptUI.String.FEATHER + '_' + DuScriptUI.String.TIP_BONE, names);
        var bt = new DuOCOBone( boneName );
        bt.type = DuOCO.Bone.TIP;
        bt.x = s * u * xt + ox;
        bt.y = u * yt + oy;


        bt.attached = true;

        b.children.push(bt);
        p.children.push(b);
    }

    var names = [];
    // Single one, add in the middle
    if (feathers == 1)
    {
        createFeather( -.38, .63, -.56, .28, parent1 );
        return limb;
    }

    for (var i = 0, n = feathers; i < n; i++)
    {
        if ( i < n/2)
        {
            var x = DuMath.linear( i, 0, n/2, -.54, -.38);
            var y = DuMath.linear( i, 0, n/2, .66, .63);
            var xt = DuMath.linear( i, 0, n/2, -.96, -.56);
            var yt = DuMath.linear( i, 0, n/2, .62, .28);
            createFeather( x, y, xt, yt, parent2 );
        }
        else 
        {
            var x = DuMath.linear( i, n/2, n-1, -.38, -.22);
            var y = DuMath.linear( i, n/2, n-1, .63, .51);
            var xt = DuMath.linear( i, n/2, n-1, -.56, -.08);
            var yt = DuMath.linear( i, n/2, n-1, .28, .39);
            createFeather( x, y, xt, yt, parent1 );
        }
    }

    return limb;
}

/**
 * Creates a new snake spine.
 * @param {Boolean} [head=true]  Whether to create a head
 * @param {int} [spine=5] Number of spine bones
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @returns {DuOCOLimb} The snake spine
 */
DuOCODoc.prototype.newSnakeSpine = function( head, spine, position )
{
    head = def( head, true );
    spine = def( spine, 5 );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = spine+1;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.SNAKE_SPINE, DuOCO.Side.NONE, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.SPINE, num );

    // hips position
    var ox = 0;
    var oy = 0;
    var x = u *.75;
    var y = u * .5;

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // for each part, set the location
    var spineLength = u*1.5 / spine;
    for (var i = 0; i < spine; i++)
    {
        b.name = DuScriptUI.String.SPINE;
        if ( i <= (spine-1) / 3) b.type = DuOCO.Bone.SNAKE_SPINE_ROOT;
        else if ( i <= (spine-1)*2 / 3) b.type = DuOCO.Bone.SNAKE_SPINE_MID;
        else b.type = DuOCO.Bone.SNAKE_SPINE_END;
        b.y = y + oy;
        b.x = x - spineLength*i - ox;
        if (b.children.length > 0) b = b.children[0];
    }

    // Tip
    b.name = DuScriptUI.String.SPINE + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    b.x = -u *.75;
    b.y = y + oy;

    // Head
    if (head)
    {
        var b = new DuOCOBone( DuScriptUI.String.HEAD );
        b.type = DuOCO.Bone.SKULL;
        b.x = x;
        b.y = y;

        var s = limb.armature.pop();

        limb.armature.push(b);
        b.children.push(s);

        var bt = new DuOCOBone( DuScriptUI.String.HEAD + '_' + DuScriptUI.String.TIP_BONE );
        bt.type = DuOCO.Bone.SKULL_TIP;
        bt.x = x + u*.2;
        bt.y = y;
        bt.attached = true;

        b.children.push(bt);
    }

    return limb;
}

/**
 * Creates a new fish spine.
 * @param {Boolean} [head=true]  Whether to create a head
 * @param {int} [spine=3] Number of spine bones
 * @param {float[]} [position] The position of the first bone of the spine.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @returns {DuOCOLimb} The fish spine
 */
DuOCODoc.prototype.newFishSpine = function( head, spine, position )
{
    head = def( head, true );
    spine = def( spine, 3 );

    // Unit
    var u = this.height;

    // count how many bones we need
    var num = spine+1;

    if (num == 1) return null;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.FISH_SPINE, DuOCO.Side.NONE, DuOCO.Location.NONE );
    var b = limb.newArmature( DuScriptUI.String.SPINE, num );

    // hips position
    var ox = 0;
    var oy = 0;
    var x = u *.75;
    var y = u * .5;

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // for each part, set the location
    var spineLength = u / spine;
    for (var i = 0; i < spine; i++)
    {
        b.name = DuScriptUI.String.SPINE;
        if ( i <= (spine-1) / 3) b.type = DuOCO.Bone.FISH_SPINE_ROOT;
        else if ( i <= (spine-1)*2 / 3) b.type = DuOCO.Bone.FISH_SPINE_MID;
        else b.type = DuOCO.Bone.FISH_SPINE_END;
        b.y = y + oy;
        b.x = x - spineLength*i - ox;
        if (b.children.length > 0) b = b.children[0];
    }

    // Tip
    b.name = DuScriptUI.String.SPINE + '_' + DuScriptUI.String.TIP_BONE;
    b.type = DuOCO.Bone.TIP;
    b.x = -u *.25;
    b.y = y + oy;

    // Head
    if (head)
    {
        var b = new DuOCOBone( DuScriptUI.String.HEAD );
        b.type = DuOCO.Bone.SKULL;
        b.x = x;
        b.y = y;

        var s = limb.armature.pop();

        limb.armature.push(b);
        b.children.push(s);

        var bt = new DuOCOBone( DuScriptUI.String.HEAD + '_' + DuScriptUI.String.TIP_BONE );
        bt.type = DuOCO.Bone.SKULL_TIP;
        bt.x = x + u*.3;
        bt.y = y;
        bt.attached = true;

        b.children.push(bt);
    }

    return limb;
}

/**
 * Creates a new fin.
 * @param {int} [fishbones=5]  Number of feathers
 * @param {float[]} [position] The position of the first bone of the arm.<br />
 * If omitted, computed automatically according to the current character in the doc.
 * @param {DuOCO.View} [view=DuOCO.View.RIGHT] The view
 * @returns {DuOCOLimb} The fin
 */
DuOCODoc.prototype.newFin = function( side, fishbones, view )
{
    side = def(side, DuOCO.Side.LEFT);
    view = def(view, DuOCO.View.RIGHT);

    fishbones = def( fishbones, 5 );

    // Unit
    var u = this.height;

    // Create limb
    var limb = this.newLimb( DuOCO.Limb.FIN, side, DuOCO.Location.NONE );

    // side
    var s = 1;
    if ( side == DuOCO.Side.RIGHT && (view == DuOCO.View.TOP || view == DuOCO.View.BACK) ) s = -1;
    else if ( side == DuOCO.Side.LEFT && (view == DuOCO.View.BOTTOM || view == DuOCO.View.FRONT) ) s = -1;
    else if ( view == DuOCO.View.LEFT ) s = -1;

    // arm position
    var x = s * u * -.17;
    var y = u * .47;
    var ox = 0;
    var oy = 0;

    // offset
    if (isdef( position ) )
    {
        ox = position[0] - x;
        oy = position[1] - y;
    }

    // Create root
    var rootBone = new DuOCOBone( DuScriptUI.String.FIN );
    rootBone.type = DuOCO.Bone.FIN;
    rootBone.x = x + ox;
    rootBone.y = y + oy;
    limb.armature.push(rootBone);
    // Tip
    var bt = new DuOCOBone( DuScriptUI.String.FIN + '_' + DuScriptUI.String.TIP_BONE );
    bt.type = DuOCO.Bone.TIP;
    bt.x = s * u * -.24 + ox;
    bt.y = u * .62 + oy;
    bt.attached = true;
    rootBone.children.push(bt);

    // Add FishBones
    if (fishbones == 0) return limb;

    var names = [];

    function createFishbone( xr, yr, xt, yt )
    {
        var boneName = DuString.generateUnique(DuScriptUI.String.FISHBONE, names);
        b = new DuOCOBone( boneName );
        b.type = DuOCO.Bone.FIN_FISHBONE;
        b.x = s * u * xr + ox;
        b.y = u * yr + oy;

        // tip
        var boneName = DuString.generateUnique(DuScriptUI.String.FISHBONE + '_' + DuScriptUI.String.TIP_BONE, names);
        var bt = new DuOCOBone( boneName );
        bt.type = DuOCO.Bone.TIP;
        bt.x = s * u * xt + ox;
        bt.y = u * yt + oy;
        bt.attached = true;

        b.children.push(bt);
        rootBone.children.push(b);
    }

    // Single one, add in the middle
    if (fishbones == 1)
    {
        createFishbone( -.22, .43, -.77, .60 );
        return limb;
    }

    for (var i = 0, n = fishbones; i < n; i++)
    {
        var x = DuMath.linear( i, 0, n-1, -.24, -.15);
        var y = DuMath.linear( i, 0, n-1, .63, .41);
        var xt = DuMath.linear( i, 0, n-1, -.82, -.17);
        var yt = DuMath.linear( i, 0, n-1, .60, .29);
        createFishbone( x, y, xt, yt );
    }

    return limb;
}

/**
 * Converts a doc coordinate in centimeters to pixel coordinates
 * @param {float[]} point The coordinate to convert
 * @returns {int[]} The coordinates in pixels relative to the comp
 */
DuOCODoc.prototype.toPixels = function( point )
{
    // First, convert to pixels
    var x = point[0]*this.pixelsPerCm;
    // minus because in 2D apps, 0 is top
    var y = -point[1]*this.pixelsPerCm;
    // We're relative to the world, add its coordinates
    x += this.world[0];
    y += this.world[1];
    return [x, y];
}

/**
 * Converts a pixel coordinate in pixels to centimeters doc coordinates
 * @param {int[]} point The coordinate to convert
 * @returns {float[]} The coordinates in centimeters relative to the doc
 */
DuOCODoc.prototype.fromPixels = function( point )
{
    var x = point[0];
    var y = point[1];
    // We're relative to the world, remove its coordinates
    x -= this.world[0];
    y -= this.world[1];
    // Convert to cm
    x /= this.pixelsPerCm;
    // Y coordinate is at bottm in OCO, top in 2D docs
    y /= -this.pixelsPerCm;
    return [x, y];
}

/**
 * Creates a new OCO Limb.
 * @class
 * @classdesc A limb contained in an OCO Doc.
 * @param {DuOCO.Limb} [limb=DuOCO.Limb.CUSTOM] A Predefined limb
 * @param {DuOCO.Side} [side=DuOCO.Side.NONE] - The side of the limb
 * @param {DuOCO.Location} [location=DuOCO.Location.NONE] - The location of the limb
 * @param {DuOCO.LimbType} [type=DuOCO.LimbType.CUSTOM] - The type of the limb
 * @category DuOCO
 */
function DuOCOLimb(limb, side, location, type )
{
    /**
     * The predefined limb
     * @name limb
     * @memberof DuOCOLimb
     * @type {DuOCO.Limb}
     */
    this.limb = def(limb, DuOCO.Limb.CUSTOM);
    /**
     * The type of the limb
     * @name type
     * @memberof DuOCOLimb
     * @type {DuOCO.LimbType}
     */
    this.type = def(type, DuOCO.LimbType.CUSTOM);
    /**
     * The sided of the limb
     * @name side
     * @memberof DuOCOLimb
     * @type {DuOCO.Side}
     */
    this.side = def( side, DuOCO.Side.NONE);
    /**
     * The location of the limb
     * @name location
     * @memberof DuOCOLimb
     * @type { DuOCO.Location}
     */
    this.location = def( location, DuOCO.Location.NONE);
    /**
     * The bones of the limb
     * @name location
     * @memberof DuOCOLimb
     * @type {DuOCOBone[]}
     */
    this.armature = [];
}

/**
 * Gets the boundaries of the limb
 * @returns {float[]} [left, top, right, bottom]
 */
DuOCOLimb.prototype.bounds = function( )
{
    return DuOCO.getBounds( this.armature );
}

/**
 * Creates a new chain of bones and adds it to the limb.
 * @param {string} name The name of the bones (will increment if needed)
 * @param {int} [num=2] The number of bones in the chain
 * @param {float} [length=100.0] The length in centimeters
 * @return {DuOCOBone} The root bone.
 */
DuOCOLimb.prototype.newArmature = function( name, num, length )
{
    num = def(num, 2);
    length = def(length, 100.0);
    var boneLength = length / (num-1);

    var x = -length / 2;
    var b = null;
    var root = null;
    var names = [];

    for (var i = 0; i < num; i++)
    {
        var boneName = DuString.generateUnique(name, names);
        var bone = new DuOCOBone( boneName );
        names.push(boneName);
        bone.y = 100;
        bone.x = x;

        if (b != null)
        {
            b.children.push( bone );
            bone.attached = true;
        }
        else
        {
            this.armature.push( bone );
            root = bone;
        }

        x += boneLength;
        b = bone;
    }

    return root;
}

/**
 * Creates a new OCO Bone.
 * @class
 * @classdesc A bone contained in an OCO Limb.
 * @param {string} name The name
 * @category DuOCO
 */
function DuOCOBone(name)
{
    /**
     * The name of the bone
     * @name name
     * @memberof DuOCOBone
     * @type {string}
     */
    this.name = name;
    /**
     * The x coordinate of the bone
     * @name x
     * @memberof DuOCOBone
     * @type {float}
     */
    this.x = 0.0;
    /**
     * The y coordinate of the bone
     * @name y
     * @memberof DuOCOBone
     * @type {float}
     */
    this.y = 0.0;
    /**
     * true if this bone is attached to its parent.
     * @name attached
     * @memberof DuOCOBone
     * @type {Boolean}
     */
    this.attached = false;
    /**
     * The child bones.
     * @name children
     * @memberof DuOCOBone
     * @type {DuOCOBone[]}
     */
    this.children = [];
    /**
     * The child limbs.
     * @name limbs
     * @memberof DuOCOBone
     * @type {DuOCOLimb[]}
     */
    this.limbs = [];
    /**
     * The type of bone.
     * @name type
     * @memberof DuOCOBone
     * @type {DuOCO.Bone}
     */
    this.type = DuOCO.Bone.CUSTOM;
}

/**
 * Translates the bone by [x, y] pixels
 * @param {int} [x=0] The horizontal offset
 * @param {int} [y=0] The vertical offset
 * @param {bool} [translateChildren=true] If false, the children stay at their current location
 */
DuOCOBone.prototype.translate = function( x, y, translateChildren ) {
    translateChildren = def(translateChildren, true);
    x = def(x, 0);
    y = def(y, 0);

    this.x += x;
    this.y += y;

    if (translateChildren) {
        for (var i = 0, n = this.children.length; i < n; i++) {
            this.children[i].translate(x, y);
        }
    }
}

/**
 * Translates the bone to the new coordinates
 * @param {int} [x] The new X value. If omitted, moves the layer vertically
 * @param {int} [y] The new Y value. If omitted, moves the layer horizontally
 * @param {bool} [translateChildren=true] If false, the children stay at their current location
 */
DuOCOBone.prototype.translateTo = function( x, y, translateChildren ) {
    translateChildren = def(translateChildren, true);
    x = def(x, this.x);
    y = def(y, this.y);

    var offsetX = x - this.x;
    var offsetY = y - this.y;

    this.x = x;
    this.y = y;

    if (translateChildren) {
        for (var i = 0, n = this.children.length; i < n; i++) {
            this.children[i].translate(offsetX, offsetY);
        }
    }
}