1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-17 21:35:44 +03:00

Merge remote-tracking branch 'multiwii/master'

Conflicts:
	README.md
	_locales/en/messages.json
	changelog.html
	js/backup_restore.js
	js/data_storage.js
	js/msp.js
	js/protocols/stm32.js
	js/serial_backend.js
	main.css
	main.html
	main.js
	manifest.json
	tabs/auxiliary_configuration.css
	tabs/default.css
	tabs/firmware_flasher.js
	tabs/initial_setup.css
	tabs/initial_setup.html
	tabs/initial_setup.js
	tabs/modes.html
	tabs/modes.js
	tabs/motor_outputs.css
	tabs/motors.html
	tabs/receiver.css
	tabs/servos.js
This commit is contained in:
Dominic Clifton 2014-12-18 22:38:55 +00:00
commit a8cf910f51
108 changed files with 12813 additions and 4551 deletions

View file

@ -1,41 +1,101 @@
'use strict';
function configuration_backup() {
// request configuration data (one by one)
// code below is highly experimental, although it runs fine on latest firmware
// the data inside nested objects needs to be verified if deep copy works properly
function configuration_backup(callback) {
var activeProfile = null,
profilesN = 3;
function get_ident_data() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_status_data);
var profileSpecificData = [
MSP_codes.MSP_PID,
MSP_codes.MSP_RC_TUNING,
MSP_codes.MSP_ACC_TRIM,
MSP_codes.MSP_SERVO_CONF
];
var uniqueData = [
MSP_codes.MSP_BOX,
MSP_codes.MSP_MISC,
MSP_codes.MSP_RCMAP,
MSP_codes.MSP_CONFIG
];
var configuration = {
'generatedBy': chrome.runtime.getManifest().version,
'profiles': []
};
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
activeProfile = CONFIG.profile;
select_profile();
});
function select_profile() {
if (activeProfile > 0) {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [0], false, fetch_specific_data);
} else {
fetch_specific_data();
}
}
function get_status_data() {
MSP.send_message(MSP_codes.MSP_STATUS, false, false, get_pid_data);
function fetch_specific_data() {
var fetchingProfile = 0,
codeKey = 0;
function query() {
if (fetchingProfile < profilesN) {
MSP.send_message(profileSpecificData[codeKey], false, false, function () {
codeKey++;
if (codeKey < profileSpecificData.length) {
query();
} else {
configuration.profiles.push({
'PID': jQuery.extend(true, [], PIDs),
'RC': jQuery.extend(true, {}, RC_tuning),
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG)
});
codeKey = 0;
fetchingProfile++;
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [fetchingProfile], false, query);
}
});
} else {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [activeProfile], false, fetch_unique_data);
}
}
// start fetching
query();
}
function get_pid_data() {
MSP.send_message(MSP_codes.MSP_PID, false, false, get_rc_tuning_data);
function fetch_unique_data() {
var codeKey = 0;
function query() {
if (codeKey < uniqueData.length) {
MSP.send_message(uniqueData[codeKey], false, false, function () {
codeKey++;
query();
});
} else {
configuration.AUX = jQuery.extend(true, [], AUX_CONFIG_values);
configuration.MISC = jQuery.extend(true, {}, MISC);
configuration.RCMAP = jQuery.extend(true, [], RC_MAP);
configuration.BF_CONFIG = jQuery.extend(true, {}, BF_CONFIG);
save();
}
}
// start fetching
query();
}
function get_rc_tuning_data() {
MSP.send_message(MSP_codes.MSP_RC_TUNING, false, false, get_box_names_data);
}
function get_box_names_data() {
MSP.send_message(MSP_codes.MSP_BOXNAMES, false, false, get_box_data);
}
function get_box_data() {
MSP.send_message(MSP_codes.MSP_BOX, false, false, get_acc_trim_data);
}
function get_acc_trim_data() {
MSP.send_message(MSP_codes.MSP_ACC_TRIM, false, false, get_misc_data);
}
function get_misc_data() {
MSP.send_message(MSP_codes.MSP_MISC, false, false, backup);
}
function backup() {
function save() {
var chosenFileEntry = null;
var accepts = [{
@ -43,14 +103,18 @@ function configuration_backup() {
}];
// generate timestamp for the backup file
var d = new Date();
var now = d.getUTCFullYear() + '.' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getHours() + '.' + d.getMinutes();
var d = new Date(),
now = (d.getMonth() + 1) + '.' + d.getDate() + '.' + d.getFullYear() + '.' + d.getHours() + '.' + d.getMinutes();
// create or load the file
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'cleanflight_config_' + now, accepts: accepts}, function (fileEntry) {
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'baseflight_backup_' + now, accepts: accepts}, function (fileEntry) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
if (!fileEntry) {
console.log('No file selected, backup aborted.');
return;
}
@ -68,17 +132,6 @@ function configuration_backup() {
if (isWritable) {
chosenFileEntry = fileEntryWritable;
// create config object that will be used to store all downloaded data
var configuration = {
'firmware_version': CONFIG.version,
'configurator_version': chrome.runtime.getManifest().version,
'PID': PIDs,
//'AUX_val': AUX_CONFIG_values,
'RC': RC_tuning,
'AccelTrim': CONFIG.accelerometerTrims,
'MISC': MISC
};
// crunch the config object
var serialized_config_object = JSON.stringify(configuration);
var blob = new Blob([serialized_config_object], {type: 'text/plain'}); // first parameter for Blob needs to be an array
@ -99,6 +152,7 @@ function configuration_backup() {
}
console.log('Write SUCCESSFUL');
if (callback) callback();
};
writer.write(blob);
@ -113,12 +167,9 @@ function configuration_backup() {
});
});
}
// begin fetching latest data
get_ident_data();
}
function configuration_restore() {
function configuration_restore(callback) {
var chosenFileEntry = null;
var accepts = [{
@ -127,9 +178,13 @@ function configuration_restore() {
// load up the file
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function (fileEntry) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
return;
}
if (!fileEntry) {
console.log('No file selected, restore aborted.');
return;
}
@ -165,145 +220,165 @@ function configuration_restore() {
return;
}
// replacing "old configuration" with configuration from backup file
var configuration = deserialized_configuration_object;
// some configuration.VERSION code goes here? will see
PIDs = configuration.PID;
//AUX_CONFIG_values = configuration.AUX_val;
RC_tuning = configuration.RC;
CONFIG.accelerometerTrims = configuration.AccelTrim;
MISC = configuration.MISC;
// all of the arrays/objects are set, upload changes
configuration_upload();
configuration_upload(deserialized_configuration_object, callback);
}
};
reader.readAsText(file);
});
});
}
function configuration_upload() {
// this "cloned" function contains all the upload sequences for the respective array/objects
// that are currently scattered in separate tabs (ergo - pid_tuning.js/initial_setup.js/etc)
// for current purposes, this approach works, but its not really "valid" and this approach
// should be reworked in the future, so the same code won't be cloned over !!!
function configuration_upload(configuration, callback) {
function compareVersions(generated, required) {
var a = generated.split('.'),
b = required.split('.');
// PID section
var PID_buffer_out = new Array(),
PID_buffer_needle = 0;
for (var i = 0; i < a.length; ++i) {
a[i] = Number(a[i]);
}
for (var i = 0; i < b.length; ++i) {
b[i] = Number(b[i]);
}
if (a.length == 2) {
a[2] = 0;
}
for (var i = 0; i < PIDs.length; i++) {
switch (i) {
case 0:
case 1:
case 2:
case 3:
case 7:
case 8:
case 9:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 1000);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2]);
break;
case 4:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 100);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2]);
break;
case 5:
case 6:
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2] * 1000);
break;
if (a[0] > b[0]) return true;
if (a[0] < b[0]) return false;
if (a[1] > b[1]) return true;
if (a[1] < b[1]) return false;
if (a[2] > b[2]) return true;
if (a[2] < b[2]) return false;
return true;
}
PID_buffer_needle += 3;
}
function upload() {
var activeProfile = null,
profilesN = 3;
// Send over the PID changes
MSP.send_message(MSP_codes.MSP_SET_PID, PID_buffer_out, false, rc_tuning);
var profileSpecificData = [
MSP_codes.MSP_SET_PID,
MSP_codes.MSP_SET_RC_TUNING,
MSP_codes.MSP_SET_ACC_TRIM,
MSP_codes.MSP_SET_SERVO_CONF
];
function rc_tuning() {
// RC Tuning section
var RC_tuning_buffer_out = new Array();
RC_tuning_buffer_out[0] = parseInt(RC_tuning.RC_RATE * 100);
RC_tuning_buffer_out[1] = parseInt(RC_tuning.RC_EXPO * 100);
RC_tuning_buffer_out[2] = parseInt(RC_tuning.roll_pitch_rate * 100);
RC_tuning_buffer_out[3] = parseInt(RC_tuning.yaw_rate * 100);
RC_tuning_buffer_out[4] = parseInt(RC_tuning.dynamic_THR_PID * 100);
RC_tuning_buffer_out[5] = parseInt(RC_tuning.throttle_MID * 100);
RC_tuning_buffer_out[6] = parseInt(RC_tuning.throttle_EXPO * 100);
var uniqueData = [
MSP_codes.MSP_SET_BOX,
MSP_codes.MSP_SET_MISC,
MSP_codes.MSP_SET_RCMAP,
MSP_codes.MSP_SET_CONFIG
];
// Send over the RC_tuning changes
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, aux);
}
function aux() {
/*
// AUX section
var AUX_val_buffer_out = new Array(),
needle = 0;
for (var i = 0; i < AUX_CONFIG_values.length; i++) {
AUX_val_buffer_out[needle++] = lowByte(AUX_CONFIG_values[i]);
AUX_val_buffer_out[needle++] = highByte(AUX_CONFIG_values[i]);
}
// Send over the AUX changes
MSP.send_message(MSP_codes.MSP_SET_BOX, AUX_val_buffer_out, false, trim);
*/
}
// Trim section
function trim() {
var buffer_out = new Array();
buffer_out[0] = lowByte(CONFIG.accelerometerTrims[0]);
buffer_out[1] = highByte(CONFIG.accelerometerTrims[0]);
buffer_out[2] = lowByte(CONFIG.accelerometerTrims[1]);
buffer_out[3] = highByte(CONFIG.accelerometerTrims[1]);
// Send over the new trims
MSP.send_message(MSP_codes.MSP_SET_ACC_TRIM, buffer_out, false, misc);
}
function misc() {
// MISC
// we also have to fill the unsupported bytes
var buffer_out = new Array();
buffer_out[0] = 0; // powerfailmeter
buffer_out[1] = 0;
buffer_out[2] = lowByte(MISC.minthrottle);
buffer_out[3] = highByte(MISC.minthrottle);
buffer_out[4] = lowByte(MISC.maxthrottle);
buffer_out[5] = highByte(MISC.maxthrottle);
buffer_out[6] = lowByte(MISC.mincommand);
buffer_out[7] = highByte(MISC.mincommand);
buffer_out[8] = lowByte(MISC.failsafe_throttle);
buffer_out[9] = highByte(MISC.failsafe_throttle);
buffer_out[10] = 0;
buffer_out[11] = 0;
buffer_out[12] = 0;
buffer_out[13] = 0;
buffer_out[14] = 0;
buffer_out[15] = 0;
buffer_out[16] = lowByte(MISC.mag_declination);
buffer_out[17] = highByte(MISC.mag_declination);
buffer_out[18] = MISC.vbatscale;
buffer_out[19] = MISC.vbatmincellvoltage;
buffer_out[20] = MISC.vbatmaxcellvoltage;
buffer_out[21] = 0; // vbatlevel_crit (unused)
// Send ove the new MISC
MSP.send_message(MSP_codes.MSP_SET_MISC, buffer_out, false, function () {
// Save changes to EEPROM
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
GUI.log(chrome.i18n.getMessage('eeprom_saved_ok'));
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
activeProfile = CONFIG.profile;
select_profile();
});
});
function select_profile() {
if (activeProfile > 0) {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [0], false, upload_specific_data);
} else {
upload_specific_data();
}
}
function upload_specific_data() {
var savingProfile = 0,
codeKey = 0;
function load_objects(profile) {
PIDs = configuration.profiles[profile].PID;
RC_tuning = configuration.profiles[profile].RC;
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
}
function query() {
MSP.send_message(profileSpecificData[codeKey], MSP.crunch(profileSpecificData[codeKey]), false, function () {
codeKey++;
if (codeKey < profileSpecificData.length) {
query();
} else {
codeKey = 0;
savingProfile++;
if (savingProfile < profilesN) {
load_objects(savingProfile);
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [savingProfile], false, query);
});
} else {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
MSP.send_message(MSP_codes.MSP_SELECT_SETTING, [activeProfile], false, upload_unique_data);
});
}
}
});
}
// start uploading
load_objects(0);
query();
}
function upload_unique_data() {
var codeKey = 0;
function load_objects() {
AUX_CONFIG_values = configuration.AUX;
MISC = configuration.MISC;
RC_MAP = configuration.RCMAP;
BF_CONFIG = configuration.BF_CONFIG;
}
function query() {
if (codeKey < uniqueData.length) {
MSP.send_message(uniqueData[codeKey], MSP.crunch(uniqueData[codeKey]), false, function () {
codeKey++;
query();
});
} else {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
}
}
// start uploading
load_objects();
query();
}
function reboot() {
GUI.log(chrome.i18n.getMessage('eeprom_saved_ok'));
GUI.tab_switch_cleanup(function() {
MSP.send_message(MSP_codes.MSP_SET_REBOOT, false, false, reinitialize);
});
}
function reinitialize() {
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
GUI.log(chrome.i18n.getMessage('deviceReady'));
if (callback) callback();
});
}, 1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
}
}
// validate
if (typeof configuration.generatedBy !== 'undefined' && compareVersions(configuration.generatedBy, CONFIGURATOR.backupFileMinVersionAccepted)) {
upload();
} else {
GUI.log(chrome.i18n.getMessage('backupFileIncompatible'));
}
}
}

View file

@ -1,10 +1,10 @@
'use strict';
var CONFIGURATOR = {
'releaseDate': 1415494669479, // 08.31.2014 - new Date().getTime()
'releaseDate': 1417875879820, // new Date().getTime() - 2014.12.06
'firmwareVersionAccepted': 2.3,
'backupFileMinVersionAccepted': '0.55', // chrome.runtime.getManifest().version is stored as string, so does this one
'connectionValid': false,
'mspPassThrough': false,
'cliActive': false,
'cliValid': false
};
@ -14,6 +14,7 @@ var CONFIG = {
flightControllerIdentifier: '',
flightControllerVersion: '',
version: 0,
buildInfo: '',
multiType: 0,
msp_version: 0,
capability: 0,
@ -22,17 +23,29 @@ var CONFIG = {
activeSensors: 0,
mode: 0,
profile: 0,
uid: [0, 0, 0],
accelerometerTrims: [0, 0]
};
var BF_CONFIG = {
mixerConfiguration: 0,
features: 0,
serialrx_type: 0,
board_align_roll: 0,
board_align_pitch: 0,
board_align_yaw: 0,
currentscale: 0,
currentoffset: 0
};
var PID_names = [];
var PIDs = new Array(10);
for (var i = 0; i < 10; i++) {
PIDs[i] = new Array(3);
}
var RC_MAP = [];
// defaults
// roll, pitch, yaw, throttle, aux 1, ... aux n
var RC = {
@ -47,11 +60,12 @@ var RC_tuning = {
yaw_rate: 0,
dynamic_THR_PID: 0,
throttle_MID: 0,
throttle_EXPO: 0,
throttle_EXPO: 0
};
var AUX_CONFIG = [];
var AUX_CONFIG_IDS = [];
var AUX_CONFIG_values = [];
var MODE_RANGES = [];
var ADJUSTMENT_RANGES = [];
@ -97,16 +111,20 @@ var ANALOG = {
};
var MISC = {
PowerTrigger1: 0, // intPowerTrigger1 (aka useless trash)
minthrottle: 0,
maxthrottle: 0,
mincommand: 0,
failsafe_throttle: 0,
plog0: 0, // plog useless shit
plog1: 0, // plog useless shit
mag_declination: 0, // not checked
vbatscale: 0,
vbatmincellvoltage: 0,
vbatmaxcellvoltage: 0,
empty: 0 // unknown
midrc: 0,
minthrottle: 0,
maxthrottle: 0,
mincommand: 0,
failsafe_throttle: 0,
gps_type: 0,
gps_baudrate: 0,
gps_ubx_sbas: 0,
multiwiicurrentoutput: 0,
rssi_aux_channel: 0,
placeholder2: 0,
mag_declination: 0, // not checked
vbatscale: 0,
vbatmincellvoltage: 0,
vbatmaxcellvoltage: 0,
placeholder3: 0
};

View file

@ -6,8 +6,8 @@ var GUI_control = function () {
this.auto_connect = false;
this.connecting_to = false;
this.connected_to = false;
this.connect_lock = false;
this.active_tab;
this.active_tab_ref = false;
this.tab_switch_in_progress = false;
this.operating_system;
this.optional_usb_permissions = false; // controlled by usb permissions code
@ -198,7 +198,7 @@ GUI_control.prototype.tab_switch_cleanup = function (callback) {
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
GUI.interval_kill_all(); // all intervals (mostly data pulling) needs to be removed on tab switch
this.active_tab_ref.cleanup(callback);
TABS[this.active_tab].cleanup(callback);
};
// initialize object into GUI variable

File diff suppressed because one or more lines are too long

View file

@ -1,78 +1,87 @@
(function() { var h,aa=aa||{},k=this,ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&
!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},m=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},n=function(a){return"string"==typeof a},p=function(a){return"function"==ca(a)},ea=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa=function(a,b,c){return a.call.apply(a.bind,arguments)},ga=function(a,b,c){if(!a)throw Error();
if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},q=function(a,b,c){q=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return q.apply(null,arguments)},ha=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);
return a.apply(this,b)}},r=Date.now||function(){return+new Date},s=function(a,b){var c=a.split("."),d=k;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d=d[e]?d[e]:d[e]={}:d[e]=b},t=function(a,b){function c(){}c.prototype=b.prototype;a.J=b.prototype;a.prototype=new c;a.vc=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};
Function.prototype.bind=Function.prototype.bind||function(a,b){if(1<arguments.length){var c=Array.prototype.slice.call(arguments,1);c.unshift(this,a);return q.apply(null,c)}return q(this,a)};var u=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,u);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};t(u,Error);u.prototype.name="CustomError";var ia=function(a,b){return a<b?-1:a>b?1:0};var ja=function(){};ja.prototype.Na=!1;ja.prototype.ra=function(){this.Na||(this.Na=!0,this.k())};ja.prototype.k=function(){if(this.ub)for(;this.ub.length;)this.ub.shift()()};var v=Array.prototype,ka=v.indexOf?function(a,b,c){return v.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(n(a))return n(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},la=v.forEach?function(a,b,c){v.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},ma=v.some?function(a,b,c){return v.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):
a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1},oa=function(a){var b;t:{b=na;for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break t}b=-1}return 0>b?null:n(a)?a.charAt(b):a[b]},pa=function(a,b){var c=ka(a,b),d;(d=0<=c)&&v.splice.call(a,c,1);return d},qa=function(a){return v.concat.apply(v,arguments)};var ra=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},sa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},ta=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},ua=function(a,b){var c;t:{for(c in a)if(b.call(void 0,a[c],c,a))break t;c=void 0}return c&&a[c]},va="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),wa=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<va.length;f++)c=
va[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};var w=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.P=!1;this.ab=!0};w.prototype.k=function(){};w.prototype.ra=function(){};w.prototype.preventDefault=function(){this.defaultPrevented=!0;this.ab=!1};var xa=function(a){xa[" "](a);return a};xa[" "]=ba;var x;t:{var ya=k.navigator;if(ya){var za=ya.userAgent;if(za){x=za;break t}}x=""}var y=function(a){return-1!=x.indexOf(a)};var Aa=y("Opera")||y("OPR"),z=y("Trident")||y("MSIE"),A=y("Gecko")&&-1==x.toLowerCase().indexOf("webkit")&&!(y("Trident")||y("MSIE")),B=-1!=x.toLowerCase().indexOf("webkit"),Ba=function(){var a=k.document;return a?a.documentMode:void 0},Ca=function(){var a="",b;if(Aa&&k.opera)return a=k.opera.version,p(a)?a():a;A?b=/rv\:([^\);]+)(\)|;)/:z?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:B&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(x))?a[1]:"");return z&&(b=Ba(),b>parseFloat(a))?String(b):a}(),Da={},C=function(a){var b;
if(!(b=Da[a])){b=0;for(var c=String(Ca).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f<e;f++){var g=c[f]||"",l=d[f]||"",J=RegExp("(\\d*)(\\D*)","g"),F=RegExp("(\\d*)(\\D*)","g");do{var R=J.exec(g)||["","",""],S=F.exec(l)||["","",""];if(0==R[0].length&&0==S[0].length)break;b=ia(0==R[1].length?0:parseInt(R[1],10),0==S[1].length?0:parseInt(S[1],10))||ia(0==R[2].length,0==S[2].length)||ia(R[2],S[2])}while(0==
b)}b=Da[a]=0<=b}return b},Ea=k.document,Fa=Ea&&z?Ba()||("CSS1Compat"==Ea.compatMode?parseInt(Ca,10):5):void 0;var Ga=!z||z&&9<=Fa,Ha=z&&!C("9"),Ia=!B||C("528"),Ja=A&&C("1.9b")||z&&C("8")||Aa&&C("9.5")||B&&C("528"),Ka=A&&!C("8")||z&&!C("9");var D=function(a,b){w.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.pb=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(A){var e;t:{try{xa(d.nodeName);e=!0;break t}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=B||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=B||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.state=a.state;this.pb=a;a.defaultPrevented&&this.preventDefault()}};t(D,w);D.prototype.preventDefault=function(){D.J.preventDefault.call(this);var a=this.pb;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,Ha)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};D.prototype.k=function(){};var La="closure_listenable_"+(1E6*Math.random()|0),Ma=function(a){return!(!a||!a[La])},Na=0;var Oa=function(a,b,c,d,e){this.L=a;this.proxy=null;this.src=b;this.type=c;this.ja=!!d;this.ma=e;this.key=++Na;this.removed=this.ka=!1},Pa=function(a){a.removed=!0;a.L=null;a.proxy=null;a.src=null;a.ma=null};var E=function(a){this.src=a;this.h={};this.U=0};E.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.h[f];a||(a=this.h[f]=[],this.U++);var g=Qa(a,b,d,e);-1<g?(b=a[g],c||(b.ka=!1)):(b=new Oa(b,this.src,f,!!d,e),b.ka=c,a.push(b));return b};E.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.h))return!1;var e=this.h[a];b=Qa(e,b,c,d);return-1<b?(Pa(e[b]),v.splice.call(e,b,1),0==e.length&&(delete this.h[a],this.U--),!0):!1};
var Ra=function(a,b){var c=b.type;if(!(c in a.h))return!1;var d=pa(a.h[c],b);d&&(Pa(b),0==a.h[c].length&&(delete a.h[c],a.U--));return d};E.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.h)if(!a||c==a){for(var d=this.h[c],e=0;e<d.length;e++)++b,Pa(d[e]);delete this.h[c];this.U--}return b};E.prototype.T=function(a,b,c,d){a=this.h[a.toString()];var e=-1;a&&(e=Qa(a,b,c,d));return-1<e?a[e]:null};
var Qa=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.L==b&&f.ja==!!c&&f.ma==d)return e}return-1};var Sa="closure_lm_"+(1E6*Math.random()|0),Ta={},Ua=0,Va=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)Va(a,b[f],c,d,e);return null}c=Wa(c);return Ma(a)?a.listen(b,c,d,e):Xa(a,b,c,!1,d,e)},Xa=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e,l=Ya(a);l||(a[Sa]=l=new E(a));c=l.add(b,c,d,e,f);if(c.proxy)return c;d=Za();c.proxy=d;d.src=a;d.L=c;a.addEventListener?a.addEventListener(b.toString(),d,g):a.attachEvent($a(b.toString()),d);Ua++;return c},Za=function(){var a=ab,
b=Ga?function(c){return a.call(b.src,b.L,c)}:function(c){c=a.call(b.src,b.L,c);if(!c)return c};return b},bb=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)bb(a,b[f],c,d,e);return null}c=Wa(c);return Ma(a)?a.Ta(b,c,d,e):Xa(a,b,c,!0,d,e)},cb=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)cb(a,b[f],c,d,e);else c=Wa(c),Ma(a)?a.Ma(b,c,d,e):a&&(a=Ya(a))&&(b=a.T(b,c,!!d,e))&&db(b)},db=function(a){if("number"==typeof a||!a||a.removed)return!1;var b=a.src;if(Ma(b))return Ra(b.w,a);var c=a.type,
d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.ja):b.detachEvent&&b.detachEvent($a(c),d);Ua--;(c=Ya(b))?(Ra(c,a),0==c.U&&(c.src=null,b[Sa]=null)):Pa(a);return!0},$a=function(a){return a in Ta?Ta[a]:Ta[a]="on"+a},fb=function(a,b,c,d){var e=1;if(a=Ya(a))if(b=a.h[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.ja==c&&!f.removed&&(e&=!1!==eb(f,d))}return Boolean(e)},eb=function(a,b){var c=a.L,d=a.ma||a.src;a.ka&&db(a);return c.call(d,b)},ab=function(a,b){if(a.removed)return!0;
if(!Ga){var c;if(!(c=b))t:{c=["window","event"];for(var d=k,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break t}c=d}e=c;c=new D(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){t:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break t}catch(g){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,l=e.length-1;!c.P&&0<=l;l--)c.currentTarget=e[l],d&=fb(e[l],f,!0,c);for(l=0;!c.P&&l<e.length;l++)c.currentTarget=e[l],d&=fb(e[l],f,
!1,c)}return d}return eb(a,new D(b,this))},Ya=function(a){a=a[Sa];return a instanceof E?a:null},gb="__closure_events_fn_"+(1E9*Math.random()>>>0),Wa=function(a){if(p(a))return a;a[gb]||(a[gb]=function(b){return a.handleEvent(b)});return a[gb]};var G=function(){this.w=new E(this);this.Wb=this;this.Ha=null};t(G,ja);G.prototype[La]=!0;h=G.prototype;h.addEventListener=function(a,b,c,d){Va(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){cb(this,a,b,c,d)};
h.dispatchEvent=function(a){var b,c=this.Ha;if(c){b=[];for(var d=1;c;c=c.Ha)b.push(c),++d}c=this.Wb;d=a.type||a;if(n(a))a=new w(a,c);else if(a instanceof w)a.target=a.target||c;else{var e=a;a=new w(d,c);wa(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.P&&0<=g;g--)f=a.currentTarget=b[g],e=hb(f,d,!0,a)&&e;a.P||(f=a.currentTarget=c,e=hb(f,d,!0,a)&&e,a.P||(e=hb(f,d,!1,a)&&e));if(b)for(g=0;!a.P&&g<b.length;g++)f=a.currentTarget=b[g],e=hb(f,d,!1,a)&&e;return e};
h.k=function(){G.J.k.call(this);this.w&&this.w.removeAll(void 0);this.Ha=null};h.listen=function(a,b,c,d){return this.w.add(String(a),b,!1,c,d)};h.Ta=function(a,b,c,d){return this.w.add(String(a),b,!0,c,d)};h.Ma=function(a,b,c,d){return this.w.remove(String(a),b,c,d)};var hb=function(a,b,c,d){b=a.w.h[String(b)];if(!b)return!0;b=b.concat();for(var e=!0,f=0;f<b.length;++f){var g=b[f];if(g&&!g.removed&&g.ja==c){var l=g.L,J=g.ma||g.src;g.ka&&Ra(a.w,g);e=!1!==l.call(J,d)&&e}}return e&&0!=d.ab};
G.prototype.T=function(a,b,c,d){return this.w.T(String(a),b,c,d)};var ib="StopIteration"in k?k.StopIteration:Error("StopIteration"),jb=function(){};jb.prototype.next=function(){throw ib;};jb.prototype.hc=function(){return this};var H=function(a,b){this.o={};this.b=[];this.fa=this.g=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else if(a){a instanceof H?(c=a.B(),d=a.p()):(c=ta(a),d=sa(a));for(var e=0;e<c.length;e++)this.set(c[e],d[e])}};H.prototype.p=function(){kb(this);for(var a=[],b=0;b<this.b.length;b++)a.push(this.o[this.b[b]]);return a};H.prototype.B=function(){kb(this);return this.b.concat()};
H.prototype.S=function(a){return I(this.o,a)};H.prototype.remove=function(a){return I(this.o,a)?(delete this.o[a],this.g--,this.fa++,this.b.length>2*this.g&&kb(this),!0):!1};var kb=function(a){if(a.g!=a.b.length){for(var b=0,c=0;b<a.b.length;){var d=a.b[b];I(a.o,d)&&(a.b[c++]=d);b++}a.b.length=c}if(a.g!=a.b.length){for(var e={},c=b=0;b<a.b.length;)d=a.b[b],I(e,d)||(a.b[c++]=d,e[d]=1),b++;a.b.length=c}};h=H.prototype;h.get=function(a,b){return I(this.o,a)?this.o[a]:b};
h.set=function(a,b){I(this.o,a)||(this.g++,this.b.push(a),this.fa++);this.o[a]=b};h.forEach=function(a,b){for(var c=this.B(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};h.clone=function(){return new H(this)};h.vb=function(){kb(this);for(var a={},b=0;b<this.b.length;b++){var c=this.b[b];a[c]=this.o[c]}return a};
h.hc=function(a){kb(this);var b=0,c=this.b,d=this.o,e=this.fa,f=this,g=new jb;g.next=function(){for(;;){if(e!=f.fa)throw Error("The map has changed since the iterator was created");if(b>=c.length)throw ib;var g=c[b++];return a?g:d[g]}};return g};var I=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var lb,mb,nb={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},ob={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},pb={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},qb={Wc:nb,wc:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},hd:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Cc:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,
defaultValue:void 0},od:ob,Ed:{id:"userId",name:"uid",valueType:"text",maxLength:void 0,defaultValue:void 0},ed:{id:"nonInteraction",name:"ni",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Mc:pb,xd:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},Nc:{id:"dimension",name:"cd[1-9][0-9]*",valueType:"text",maxLength:150,defaultValue:void 0},dd:{id:"metric",name:"cm[1-9][0-9]*",valueType:"integer",maxLength:void 0,defaultValue:void 0},yc:{id:"appId",name:"aid",valueType:"text",
maxLength:150,defaultValue:void 0},zc:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},Qc:{id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Pc:{id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Rc:{id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0},Sc:{id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},qd:{id:"socialNetwork",name:"sn",valueType:"text",
maxLength:50,defaultValue:void 0},pd:{id:"socialAction",name:"sa",valueType:"text",maxLength:50,defaultValue:void 0},rd:{id:"socialTarget",name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},Ad:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},zd:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},Bd:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},Cd:{id:"transactionShipping",
name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0},Dd:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,defaultValue:void 0},Kc:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},$c:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},ad:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},Yc:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},
Zc:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0},Xc:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,defaultValue:void 0},Ic:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},Gc:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},Hc:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},Fc:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},
Dc:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0},Ec:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,defaultValue:void 0},Vc:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},Lc:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},gd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Oc:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},
sd:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0},nd:{id:"serverResponseTime",name:"srt",valueType:"integer",maxLength:void 0,defaultValue:void 0},fd:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},jd:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},td:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},wd:{id:"timingVar",name:"utv",
valueType:"text",maxLength:500,defaultValue:void 0},vd:{id:"timingValue",name:"utt",valueType:"integer",maxLength:void 0,defaultValue:void 0},ud:{id:"timingLabel",name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},Tc:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},Uc:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}};var rb=function(a){k.setTimeout(function(){throw a;},0)},sb,tb=function(){var a=k.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&(a=function(){var a=document.createElement("iframe");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,a=q(function(a){if(a.origin==
d||a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a){var b=new a,c={},d=c;b.port1.onmessage=function(){c=c.next;var a=c.rb;c.rb=null;a()};return function(a){d.next={rb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("script")?function(a){var b=document.createElement("script");b.onreadystatechange=function(){b.onreadystatechange=
null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){k.setTimeout(a,0)}};var zb=function(a,b){ub||vb();wb||(ub(),wb=!0);xb.push(new yb(a,b))},ub,vb=function(){if(k.Promise&&k.Promise.resolve){var a=k.Promise.resolve();ub=function(){a.then(Ab)}}else ub=function(){var a=Ab;p(k.setImmediate)?k.setImmediate(a):(sb||(sb=tb()),sb(a))}},wb=!1,xb=[],Ab=function(){for(;xb.length;){var a=xb;xb=[];for(var b=0;b<a.length;b++){var c=a[b];try{c.ic.call(c.scope)}catch(d){rb(d)}}}wb=!1},yb=function(a,b){this.ic=a;this.scope=b};var Bb=function(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0},Cb=function(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};var L=function(a,b){this.l=0;this.t=void 0;this.m=this.n=null;this.oa=this.Ca=!1;try{var c=this;a.call(b,function(a){K(c,2,a)},function(a){K(c,3,a)})}catch(d){K(this,3,d)}};L.prototype.then=function(a,b,c){return Db(this,p(a)?a:null,p(b)?b:null,c)};Bb(L);L.prototype.cancel=function(a){0==this.l&&zb(function(){var b=new Eb(a);Fb(this,b)},this)};
var Fb=function(a,b){if(0==a.l)if(a.n){var c=a.n;if(c.m){for(var d=0,e=-1,f=0,g;g=c.m[f];f++)if(g=g.qa)if(d++,g==a&&(e=f),0<=e&&1<d)break;0<=e&&(0==c.l&&1==d?Fb(c,b):(d=c.m.splice(e,1)[0],Gb(c),d.Da(b)))}}else K(a,3,b)},Ib=function(a,b){a.m&&a.m.length||2!=a.l&&3!=a.l||Hb(a);a.m||(a.m=[]);a.m.push(b)},Db=function(a,b,c,d){var e={qa:null,$a:null,Da:null};e.qa=new L(function(a,g){e.$a=b?function(c){try{var e=b.call(d,c);a(e)}catch(F){g(F)}}:a;e.Da=c?function(b){try{var e=c.call(d,b);void 0===e&&b instanceof
Eb?g(b):a(e)}catch(F){g(F)}}:g});e.qa.n=a;Ib(a,e);return e.qa};L.prototype.kb=function(a){this.l=0;K(this,2,a)};L.prototype.lb=function(a){this.l=0;K(this,3,a)};
var K=function(a,b,c){if(0==a.l){if(a==c)b=3,c=new TypeError("Promise cannot resolve to itself");else{if(Cb(c)){a.l=1;c.then(a.kb,a.lb,a);return}if(ea(c))try{var d=c.then;if(p(d)){Jb(a,c,d);return}}catch(e){b=3,c=e}}a.t=c;a.l=b;Hb(a);3!=b||c instanceof Eb||Kb(a,c)}},Jb=function(a,b,c){a.l=1;var d=!1,e=function(b){d||(d=!0,a.kb(b))},f=function(b){d||(d=!0,a.lb(b))};try{c.call(b,e,f)}catch(g){f(g)}},Hb=function(a){a.Ca||(a.Ca=!0,zb(a.gc,a))};
L.prototype.gc=function(){for(;this.m&&this.m.length;){var a=this.m;this.m=[];for(var b=0;b<a.length;b++){var c=a[b],d=this.t;2==this.l?c.$a(d):(Gb(this),c.Da(d))}}this.Ca=!1};var Gb=function(a){for(;a&&a.oa;a=a.n)a.oa=!1},Kb=function(a,b){a.oa=!0;zb(function(){a.oa&&Lb.call(null,b)})},Lb=rb,Eb=function(a){u.call(this,a)};t(Eb,u);Eb.prototype.name="cancel";/*
(function() { var g,aa=aa||{},h=this,ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&
!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},m=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},n=function(a){return"string"==typeof a},ea=function(a){return"number"==typeof a},p=function(a){return"function"==ca(a)},q=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa=function(a,b,c){return a.call.apply(a.bind,
arguments)},ga=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},r=function(a,b,c){r=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return r.apply(null,arguments)},ha=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=
c.slice();b.push.apply(b,arguments);return a.apply(this,b)}},s=Date.now||function(){return+new Date},t=function(a,b){var c=a.split("."),d=h;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d=d[e]?d[e]:d[e]={}:d[e]=b},u=function(a,b){function c(){}c.prototype=b.prototype;a.L=b.prototype;a.prototype=new c;a.Pc=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};
Function.prototype.bind=Function.prototype.bind||function(a,b){if(1<arguments.length){var c=Array.prototype.slice.call(arguments,1);c.unshift(this,a);return r.apply(null,c)}return r(this,a)};var v=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,v);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};u(v,Error);v.prototype.name="CustomError";var ia=function(a,b){return a<b?-1:a>b?1:0};var w=Array.prototype,ja=w.indexOf?function(a,b,c){return w.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(n(a))return n(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},ka=w.forEach?function(a,b,c){w.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},la=w.some?function(a,b,c){return w.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):
a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1},ma=w.every?function(a,b,c){return w.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=n(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0},oa=function(a){var b;t:{b=na;for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break t}b=-1}return 0>b?null:n(a)?a.charAt(b):a[b]},pa=function(a,b){var c=ja(a,b),d;(d=0<=c)&&w.splice.call(a,c,1);return d},qa=function(a){return w.concat.apply(w,
arguments)},ra=function(a,b,c){return 2>=arguments.length?w.slice.call(a,b):w.slice.call(a,b,c)};var sa="StopIteration"in h?h.StopIteration:Error("StopIteration"),ta=function(){};ta.prototype.next=function(){throw sa;};ta.prototype.vc=function(){return this};var ua=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},va=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},wa=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},xa=function(a,b){var c;t:{for(c in a)if(b.call(void 0,a[c],c,a))break t;c=void 0}return c&&a[c]},ya="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),za=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<ya.length;f++)c=
ya[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};var x=function(a,b){this.p={};this.b=[];this.oa=this.h=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.ia(a)};x.prototype.t=function(){Aa(this);for(var a=[],b=0;b<this.b.length;b++)a.push(this.p[this.b[b]]);return a};x.prototype.F=function(){Aa(this);return this.b.concat()};x.prototype.Q=function(a){return y(this.p,a)};
x.prototype.remove=function(a){return y(this.p,a)?(delete this.p[a],this.h--,this.oa++,this.b.length>2*this.h&&Aa(this),!0):!1};var Aa=function(a){if(a.h!=a.b.length){for(var b=0,c=0;b<a.b.length;){var d=a.b[b];y(a.p,d)&&(a.b[c++]=d);b++}a.b.length=c}if(a.h!=a.b.length){for(var e={},c=b=0;b<a.b.length;)d=a.b[b],y(e,d)||(a.b[c++]=d,e[d]=1),b++;a.b.length=c}};g=x.prototype;g.get=function(a,b){return y(this.p,a)?this.p[a]:b};
g.set=function(a,b){y(this.p,a)||(this.h++,this.b.push(a),this.oa++);this.p[a]=b};g.ia=function(a){var b;a instanceof x?(b=a.F(),a=a.t()):(b=wa(a),a=va(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};g.forEach=function(a,b){for(var c=this.F(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};g.clone=function(){return new x(this)};g.Jb=function(){Aa(this);for(var a={},b=0;b<this.b.length;b++){var c=this.b[b];a[c]=this.p[c]}return a};
g.vc=function(a){Aa(this);var b=0,c=this.b,d=this.p,e=this.oa,f=this,k=new ta;k.next=function(){for(;;){if(e!=f.oa)throw Error("The map has changed since the iterator was created");if(b>=c.length)throw sa;var k=c[b++];return a?k:d[k]}};return k};var y=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Ba,Ca,Da={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},Ea={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},Fa={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},Ga={id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Ha={id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Ia={id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0},
Ja={id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ka={pd:Da,Qc:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Ad:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Wc:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,defaultValue:void 0},Gd:Ea,Wd:{id:"userId",name:"uid",valueType:"text",maxLength:void 0,defaultValue:void 0},xd:{id:"nonInteraction",name:"ni",valueType:"boolean",
maxLength:void 0,defaultValue:void 0},fd:Fa,Pd:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},Sc:{id:"appId",name:"aid",valueType:"text",maxLength:150,defaultValue:void 0},Tc:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},jd:Ga,hd:Ha,kd:Ia,ld:Ja,Id:{id:"socialNetwork",name:"sn",valueType:"text",maxLength:50,defaultValue:void 0},Hd:{id:"socialAction",name:"sa",valueType:"text",maxLength:50,defaultValue:void 0},Jd:{id:"socialTarget",
name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},Sd:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},Rd:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},Td:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},Ud:{id:"transactionShipping",name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0},Vd:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,
defaultValue:void 0},dd:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},td:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},ud:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},rd:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},sd:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0},qd:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,
defaultValue:void 0},bd:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},$c:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},ad:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},Zc:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},Xc:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0},Yc:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,
defaultValue:void 0},od:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},ed:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},zd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},gd:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},Kd:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0},Fd:{id:"serverResponseTime",name:"srt",valueType:"integer",
maxLength:void 0,defaultValue:void 0},yd:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Bd:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ld:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},Od:{id:"timingVar",name:"utv",valueType:"text",maxLength:500,defaultValue:void 0},Nd:{id:"timingValue",name:"utt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Md:{id:"timingLabel",
name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},md:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},nd:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}},La=function(a){if(1>a||200<a)throw Error("Expected dimension index range 1-200, but was : "+a);return{id:"dimension"+a,name:"cd"+a,valueType:"text",maxLength:150,defaultValue:void 0}},Ma=function(a){if(1>a||200<a)throw Error("Expected metric index range 1-200, but was : "+
a);return{id:"metric"+a,name:"cm"+a,valueType:"integer",maxLength:void 0,defaultValue:void 0}};var Na=function(a){if(1>a)return"0";if(3>a)return"1-2";a=Math.floor(Math.log(a-1)/Math.log(2));return Math.pow(2,a)+1+"-"+Math.pow(2,a+1)},Oa=function(a,b){for(var c=0,d=a.length-1,e=0;c<=d;){var f=Math.floor((c+d)/2),e=a[f];if(b<=e){d=0==f?0:a[f-1];if(b>d)return(d+1).toString()+"-"+e.toString();d=f-1}else if(b>e){if(f>=a.length-1)return(a[a.length-1]+1).toString()+"+";c=f+1}}return"<= 0"};var z=function(){this.ab=[]},Pa=function(){return new z};g=z.prototype;g.when=function(a){this.ab.push(a);return this};g.zb=function(a){var b=arguments;this.when(function(a){return 0<=ja(b,a.Gb())});return this};g.Oc=function(a,b){var c=ra(arguments,1);this.when(function(b){b=b.T().get(a);return 0<=ja(c,b)});return this};g.xb=function(a,b){if(q(this.e))throw Error("Filter has already been set.");this.e=q(b)?r(a,b):a;return this};
g.Ca=function(){if(0==this.ab.length)throw Error("Must specify at least one predicate using #when or a helper method.");if(!q(this.e))throw Error("Must specify a delegate filter using #applyFilter.");return r(function(a){ma(this.ab,function(b){return b(a)})&&this.e(a)},this)};var A=function(){this.Ab=!1;this.Bb="";this.qb=!1;this.za=null};A.prototype.wc=function(a){this.Ab=!0;this.Bb=a||" - ";return this};A.prototype.Nc=function(){this.qb=!0;return this};A.prototype.Ec=function(){return Qa(this,Na)};A.prototype.Fc=function(a){return Qa(this,ha(Oa,a))};
var Qa=function(a,b){if(null!=a.za)throw Error("LabelerBuilder: Only one labeling strategy may be used.");a.za=r(function(a){var d=a.T().get(Ja),e=a.T().get(Ia);ea(d)&&(d=b(d),null!=e&&this.Ab&&(d=e+this.Bb+d),a.T().set(Ia,d))},a);return a};A.prototype.Ca=function(){if(null==this.za)throw Error("LabelerBuilder: a labeling strategy must be specified prior to calling build().");return Pa().zb("event").xb(r(function(a){this.za(a);this.qb&&a.T().remove(Ja)},this)).Ca()};var Ra=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,N,J,U,V){if("%"==J)return"%";var Db=c.shift();if("undefined"==typeof Db)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Db;return B[J].apply(null,arguments)})},B={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1<b.indexOf("-",0)?a+Array(c-
a.length+1).join(" "):Array(c-a.length+1).join(" ")+a},f:function(a,b,c,d,e){d=a.toString();isNaN(e)||""==e||(d=a.toFixed(e));var f;f=0>a?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=a&&(d=f+d);if(isNaN(c)||d.length>=c)return d;d=isNaN(e)?Math.abs(a).toString():Math.abs(a).toFixed(e);a=c-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+Array(a+1).join(" "):f+Array(a+1).join(0<=b.indexOf("0",0)?"0":" ")+d},d:function(a,b,c,d,e,f,k,l){return B.f(parseInt(a,10),b,c,d,0,f,k,l)}};B.i=B.d;
B.u=B.d;var Sa=function(a){if("function"==typeof a.t)return a.t();if(n(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return va(a)},Ta=function(a,b){if("function"==typeof a.forEach)a.forEach(b,void 0);else if(da(a)||n(a))ka(a,b,void 0);else{var c;if("function"==typeof a.F)c=a.F();else if("function"!=typeof a.t)if(da(a)||n(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=wa(a);else c=void 0;for(var d=Sa(a),e=d.length,f=0;f<e;f++)b.call(void 0,d[f],c&&c[f],
a)}};var C=function(a){this.B=new x;for(var b=arguments,c=0;c<b.length;c+=2)this.set(b[c],b[c+1])};C.prototype.set=function(a,b){this.B.set(a.name,{key:a,value:b})};C.prototype.remove=function(a){this.B.remove(a.name)};C.prototype.get=function(a){a=this.B.get(a.name,null);return null===a?null:a.value};C.prototype.ia=function(a){this.B.ia(a.B)};var Ua=function(a,b){ka(a.B.t(),function(a){b(a.key,a.value)})};C.prototype.Jb=function(){var a={};Ua(this,function(b,c){a[b.id]=c});return a};
C.prototype.clone=function(){var a=new C;a.B=this.B.clone();return a};C.prototype.toString=function(){var a={};Ua(this,function(b,c){a[b.id]=c});return JSON.stringify(a)};var D=function(a){this.e=a};g=D.prototype;g.xc=function(a){var b=new D(r(this.P,this));b.I=Ga;b.N=a;return b};g.action=function(a){var b=new D(r(this.P,this));b.I=Ha;b.N=a;return b};g.label=function(a){var b=new D(r(this.P,this));b.I=Ia;b.N=a;return b};g.value=function(a){var b=new D(r(this.P,this));b.I=Ja;b.N=a;return b};g.yc=function(a,b){var c=new D(r(this.P,this));c.I=La(a);c.N=b;return c};g.Dc=function(a,b){var c=new D(r(this.P,this));c.I=Ma(a);c.N=b;return c};
g.send=function(a){var b=new C;this.P(b);return a.send("event",b)};g.P=function(a){null!=this.I&&null!=this.N&&!a.B.Q(this.I.name)&&a.set(this.I,this.N);q(this.e)&&this.e(a)};var Va=new D(ba);var E=function(){this.Y=this.Y;this.Da=this.Da};E.prototype.Y=!1;E.prototype.xa=function(){this.Y||(this.Y=!0,this.l())};E.prototype.l=function(){if(this.Da)for(;this.Da.length;)this.Da.shift()()};var F=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.U=!1;this.kb=!0};F.prototype.l=function(){};F.prototype.xa=function(){};F.prototype.preventDefault=function(){this.defaultPrevented=!0;this.kb=!1};var Wa=function(a){Wa[" "](a);return a};Wa[" "]=ba;var G;t:{var Xa=h.navigator;if(Xa){var Ya=Xa.userAgent;if(Ya){G=Ya;break t}}G=""}var H=function(a){return-1!=G.indexOf(a)};var Za=H("Opera")||H("OPR"),I=H("Trident")||H("MSIE"),K=H("Gecko")&&-1==G.toLowerCase().indexOf("webkit")&&!(H("Trident")||H("MSIE")),L=-1!=G.toLowerCase().indexOf("webkit"),$a=function(){var a=h.document;return a?a.documentMode:void 0},ab=function(){var a="",b;if(Za&&h.opera)return a=h.opera.version,p(a)?a():a;K?b=/rv\:([^\);]+)(\)|;)/:I?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:L&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(G))?a[1]:"");return I&&(b=$a(),b>parseFloat(a))?String(b):a}(),bb={},M=function(a){var b;
if(!(b=bb[a])){b=0;for(var c=String(ab).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f<e;f++){var k=c[f]||"",l=d[f]||"",N=RegExp("(\\d*)(\\D*)","g"),J=RegExp("(\\d*)(\\D*)","g");do{var U=N.exec(k)||["","",""],V=J.exec(l)||["","",""];if(0==U[0].length&&0==V[0].length)break;b=ia(0==U[1].length?0:parseInt(U[1],10),0==V[1].length?0:parseInt(V[1],10))||ia(0==U[2].length,0==V[2].length)||ia(U[2],V[2])}while(0==
b)}b=bb[a]=0<=b}return b},cb=h.document,db=cb&&I?$a()||("CSS1Compat"==cb.compatMode?parseInt(ab,10):5):void 0;var eb=!I||I&&9<=db,fb=I&&!M("9"),gb=!L||M("528"),hb=K&&M("1.9b")||I&&M("8")||Za&&M("9.5")||L&&M("528"),ib=K&&!M("8")||I&&!M("9");var O=function(a,b){F.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.Db=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(K){var e;t:{try{Wa(d.nodeName);e=!0;break t}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=L||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=L||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.state=a.state;this.Db=a;a.defaultPrevented&&this.preventDefault()}};u(O,F);O.prototype.preventDefault=function(){O.L.preventDefault.call(this);var a=this.Db;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,fb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};O.prototype.l=function(){};var jb="closure_listenable_"+(1E6*Math.random()|0),kb=function(a){return!(!a||!a[jb])},lb=0;var mb=function(a,b,c,d,e){this.O=a;this.proxy=null;this.src=b;this.type=c;this.pa=!!d;this.sa=e;this.key=++lb;this.removed=this.qa=!1},nb=function(a){a.removed=!0;a.O=null;a.proxy=null;a.src=null;a.sa=null};var P=function(a){this.src=a;this.j={};this.Z=0};P.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.j[f];a||(a=this.j[f]=[],this.Z++);var k=ob(a,b,d,e);-1<k?(b=a[k],c||(b.qa=!1)):(b=new mb(b,this.src,f,!!d,e),b.qa=c,a.push(b));return b};P.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.j))return!1;var e=this.j[a];b=ob(e,b,c,d);return-1<b?(nb(e[b]),w.splice.call(e,b,1),0==e.length&&(delete this.j[a],this.Z--),!0):!1};
var pb=function(a,b){var c=b.type;if(!(c in a.j))return!1;var d=pa(a.j[c],b);d&&(nb(b),0==a.j[c].length&&(delete a.j[c],a.Z--));return d};P.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.j)if(!a||c==a){for(var d=this.j[c],e=0;e<d.length;e++)++b,nb(d[e]);delete this.j[c];this.Z--}return b};P.prototype.X=function(a,b,c,d){a=this.j[a.toString()];var e=-1;a&&(e=ob(a,b,c,d));return-1<e?a[e]:null};
var ob=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.O==b&&f.pa==!!c&&f.sa==d)return e}return-1};var qb="closure_lm_"+(1E6*Math.random()|0),rb={},sb=0,tb=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)tb(a,b[f],c,d,e);return null}c=ub(c);return kb(a)?a.listen(b,c,d,e):vb(a,b,c,!1,d,e)},vb=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var k=!!e,l=wb(a);l||(a[qb]=l=new P(a));c=l.add(b,c,d,e,f);if(c.proxy)return c;d=xb();c.proxy=d;d.src=a;d.O=c;a.addEventListener?a.addEventListener(b.toString(),d,k):a.attachEvent(yb(b.toString()),d);sb++;return c},xb=function(){var a=zb,
b=eb?function(c){return a.call(b.src,b.O,c)}:function(c){c=a.call(b.src,b.O,c);if(!c)return c};return b},Ab=function(a,b,c,d,e){if(m(b)){for(var f=0;f<b.length;f++)Ab(a,b[f],c,d,e);return null}c=ub(c);return kb(a)?a.bb(b,c,d,e):vb(a,b,c,!0,d,e)},Bb=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)Bb(a,b[f],c,d,e);else c=ub(c),kb(a)?a.Va(b,c,d,e):a&&(a=wb(a))&&(b=a.X(b,c,!!d,e))&&Cb(b)},Cb=function(a){if(ea(a)||!a||a.removed)return!1;var b=a.src;if(kb(b))return pb(b.A,a);var c=a.type,d=a.proxy;
b.removeEventListener?b.removeEventListener(c,d,a.pa):b.detachEvent&&b.detachEvent(yb(c),d);sb--;(c=wb(b))?(pb(c,a),0==c.Z&&(c.src=null,b[qb]=null)):nb(a);return!0},yb=function(a){return a in rb?rb[a]:rb[a]="on"+a},Fb=function(a,b,c,d){var e=1;if(a=wb(a))if(b=a.j[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.pa==c&&!f.removed&&(e&=!1!==Eb(f,d))}return Boolean(e)},Eb=function(a,b){var c=a.O,d=a.sa||a.src;a.qa&&Cb(a);return c.call(d,b)},zb=function(a,b){if(a.removed)return!0;if(!eb){var c;
if(!(c=b))t:{c=["window","event"];for(var d=h,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break t}c=d}e=c;c=new O(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){t:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break t}catch(k){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,l=e.length-1;!c.U&&0<=l;l--)c.currentTarget=e[l],d&=Fb(e[l],f,!0,c);for(l=0;!c.U&&l<e.length;l++)c.currentTarget=e[l],d&=Fb(e[l],f,!1,c)}return d}return Eb(a,
new O(b,this))},wb=function(a){a=a[qb];return a instanceof P?a:null},Gb="__closure_events_fn_"+(1E9*Math.random()>>>0),ub=function(a){if(p(a))return a;a[Gb]||(a[Gb]=function(b){return a.handleEvent(b)});return a[Gb]};var Q=function(){E.call(this);this.A=new P(this);this.kc=this;this.Qa=null};u(Q,E);Q.prototype[jb]=!0;g=Q.prototype;g.addEventListener=function(a,b,c,d){tb(this,a,b,c,d)};g.removeEventListener=function(a,b,c,d){Bb(this,a,b,c,d)};
g.dispatchEvent=function(a){var b,c=this.Qa;if(c){b=[];for(var d=1;c;c=c.Qa)b.push(c),++d}c=this.kc;d=a.type||a;if(n(a))a=new F(a,c);else if(a instanceof F)a.target=a.target||c;else{var e=a;a=new F(d,c);za(a,e)}var e=!0,f;if(b)for(var k=b.length-1;!a.U&&0<=k;k--)f=a.currentTarget=b[k],e=Hb(f,d,!0,a)&&e;a.U||(f=a.currentTarget=c,e=Hb(f,d,!0,a)&&e,a.U||(e=Hb(f,d,!1,a)&&e));if(b)for(k=0;!a.U&&k<b.length;k++)f=a.currentTarget=b[k],e=Hb(f,d,!1,a)&&e;return e};
g.l=function(){Q.L.l.call(this);this.A&&this.A.removeAll(void 0);this.Qa=null};g.listen=function(a,b,c,d){return this.A.add(String(a),b,!1,c,d)};g.bb=function(a,b,c,d){return this.A.add(String(a),b,!0,c,d)};g.Va=function(a,b,c,d){return this.A.remove(String(a),b,c,d)};var Hb=function(a,b,c,d){b=a.A.j[String(b)];if(!b)return!0;b=b.concat();for(var e=!0,f=0;f<b.length;++f){var k=b[f];if(k&&!k.removed&&k.pa==c){var l=k.O,N=k.sa||k.src;k.qa&&pb(a.A,k);e=!1!==l.call(N,d)&&e}}return e&&0!=d.kb};
Q.prototype.X=function(a,b,c,d){return this.A.X(String(a),b,c,d)};var Ib=function(a){h.setTimeout(function(){throw a;},0)},Jb,Kb=function(){var a=h.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&(a=function(){var a=document.createElement("iframe");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,a=r(function(a){if(a.origin==
d||a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!H("Trident")&&!H("MSIE")){var b=new a,c={},d=c;b.port1.onmessage=function(){c=c.next;var a=c.Fb;c.Fb=null;a()};return function(a){d.next={Fb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("script")?function(a){var b=document.createElement("script");b.onreadystatechange=
function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){h.setTimeout(a,0)}};var Qb=function(a,b){Lb||Mb();Nb||(Lb(),Nb=!0);Ob.push(new Pb(a,b))},Lb,Mb=function(){if(h.Promise&&h.Promise.resolve){var a=h.Promise.resolve();Lb=function(){a.then(Rb)}}else Lb=function(){var a=Rb;!p(h.setImmediate)||h.Window&&h.Window.prototype.setImmediate==h.setImmediate?(Jb||(Jb=Kb()),Jb(a)):h.setImmediate(a)}},Nb=!1,Ob=[],Rb=function(){for(;Ob.length;){var a=Ob;Ob=[];for(var b=0;b<a.length;b++){var c=a[b];try{c.zc.call(c.scope)}catch(d){Ib(d)}}}Nb=!1},Pb=function(a,b){this.zc=a;this.scope=
b};var Sb=function(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0},Tb=function(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};var R=function(a,b){this.m=0;this.v=void 0;this.n=this.o=null;this.ua=this.La=!1;try{var c=this;a.call(b,function(a){Ub(c,2,a)},function(a){Ub(c,3,a)})}catch(d){Ub(this,3,d)}};R.prototype.then=function(a,b,c){return Vb(this,p(a)?a:null,p(b)?b:null,c)};Sb(R);R.prototype.cancel=function(a){0==this.m&&Qb(function(){var b=new Wb(a);Xb(this,b)},this)};
var Xb=function(a,b){if(0==a.m)if(a.o){var c=a.o;if(c.n){for(var d=0,e=-1,f=0,k;k=c.n[f];f++)if(k=k.wa)if(d++,k==a&&(e=f),0<=e&&1<d)break;0<=e&&(0==c.m&&1==d?Xb(c,b):(d=c.n.splice(e,1)[0],Yb(c),d.Ma(b)))}}else Ub(a,3,b)},$b=function(a,b){a.n&&a.n.length||2!=a.m&&3!=a.m||Zb(a);a.n||(a.n=[]);a.n.push(b)},Vb=function(a,b,c,d){var e={wa:null,jb:null,Ma:null};e.wa=new R(function(a,k){e.jb=b?function(c){try{var e=b.call(d,c);a(e)}catch(J){k(J)}}:a;e.Ma=c?function(b){try{var e=c.call(d,b);void 0===e&&b instanceof
Wb?k(b):a(e)}catch(J){k(J)}}:k});e.wa.o=a;$b(a,e);return e.wa};R.prototype.vb=function(a){this.m=0;Ub(this,2,a)};R.prototype.wb=function(a){this.m=0;Ub(this,3,a)};
var Ub=function(a,b,c){if(0==a.m){if(a==c)b=3,c=new TypeError("Promise cannot resolve to itself");else{if(Tb(c)){a.m=1;c.then(a.vb,a.wb,a);return}if(q(c))try{var d=c.then;if(p(d)){ac(a,c,d);return}}catch(e){b=3,c=e}}a.v=c;a.m=b;Zb(a);3!=b||c instanceof Wb||bc(a,c)}},ac=function(a,b,c){a.m=1;var d=!1,e=function(b){d||(d=!0,a.vb(b))},f=function(b){d||(d=!0,a.wb(b))};try{c.call(b,e,f)}catch(k){f(k)}},Zb=function(a){a.La||(a.La=!0,Qb(a.uc,a))};
R.prototype.uc=function(){for(;this.n&&this.n.length;){var a=this.n;this.n=[];for(var b=0;b<a.length;b++){var c=a[b],d=this.v;2==this.m?c.jb(d):(Yb(this),c.Ma(d))}}this.La=!1};var Yb=function(a){for(;a&&a.ua;a=a.o)a.ua=!1},bc=function(a,b){a.ua=!0;Qb(function(){a.ua&&cc.call(null,b)})},cc=Ib,Wb=function(a){v.call(this,a)};u(Wb,v);Wb.prototype.name="cancel";/*
Portions of this code are from MochiKit, received by
The Closure Authors under the MIT license. All other code is Copyright
2005-2009 The Closure Authors. All Rights Reserved.
*/
var M=function(a,b){this.da=[];this.Ya=a;this.Xa=b||null;this.R=this.C=!1;this.t=void 0;this.Ba=this.xb=this.Aa=!1;this.ea=0;this.n=null;this.za=0};M.prototype.cancel=function(a){if(this.C)this.t instanceof M&&this.t.cancel();else{if(this.n){var b=this.n;delete this.n;a?b.cancel(a):(b.za--,0>=b.za&&b.cancel())}this.Ya?this.Ya.call(this.Xa,this):this.Ba=!0;this.C||this.v(new Mb)}};M.prototype.Za=function(a,b){this.Aa=!1;Nb(this,a,b)};
var Nb=function(a,b,c){a.C=!0;a.t=c;a.R=!b;Ob(a)},Qb=function(a){if(a.C){if(!a.Ba)throw new Pb;a.Ba=!1}};M.prototype.F=function(a){Qb(this);Nb(this,!0,a)};M.prototype.v=function(a){Qb(this);Nb(this,!1,a)};M.prototype.H=function(a,b){return N(this,a,null,b)};var N=function(a,b,c,d){a.da.push([b,c,d]);a.C&&Ob(a);return a};M.prototype.then=function(a,b,c){var d,e,f=new L(function(a,b){d=a;e=b});N(this,d,function(a){a instanceof Mb?f.cancel():e(a)});return f.then(a,b,c)};Bb(M);
var Rb=function(a){var b=new M;N(a,b.F,b.v,b);return b},Tb=function(a){return ma(a.da,function(a){return p(a[1])})},Ob=function(a){if(a.ea&&a.C&&Tb(a)){var b=a.ea,c=Ub[b];c&&(k.clearTimeout(c.ga),delete Ub[b]);a.ea=0}a.n&&(a.n.za--,delete a.n);for(var b=a.t,d=c=!1;a.da.length&&!a.Aa;){var e=a.da.shift(),f=e[0],g=e[1],e=e[2];if(f=a.R?g:f)try{var l=f.call(e||a.Xa,b);void 0!==l&&(a.R=a.R&&(l==b||l instanceof Error),a.t=b=l);Cb(b)&&(d=!0,a.Aa=!0)}catch(J){b=J,a.R=!0,Tb(a)||(c=!0)}}a.t=b;d&&(l=q(a.Za,
a,!0),d=q(a.Za,a,!1),b instanceof M?(N(b,l,d),b.xb=!0):b.then(l,d));c&&(b=new Vb(b),Ub[b.ga]=b,a.ea=b.ga)},Wb=function(a){var b=new M;b.F(a);return b},Yb=function(){var a=Xb,b=new M;b.v(a);return b},Pb=function(){u.call(this)};t(Pb,u);Pb.prototype.message="Deferred has already fired";Pb.prototype.name="AlreadyCalledError";var Mb=function(){u.call(this)};t(Mb,u);Mb.prototype.message="Deferred was canceled";Mb.prototype.name="CanceledError";
var Vb=function(a){this.ga=k.setTimeout(q(this.bc,this),0);this.ba=a};Vb.prototype.bc=function(){delete Ub[this.ga];throw this.ba;};var Ub={};var Zb=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,J,F,R,S){if("%"==F)return"%";var Sb=c.shift();if("undefined"==typeof Sb)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Sb;return O[F].apply(null,arguments)})},O={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1<b.indexOf("-",0)?a+Array(c-
a.length+1).join(" "):Array(c-a.length+1).join(" ")+a},f:function(a,b,c,d,e){d=a.toString();isNaN(e)||""==e||(d=a.toFixed(e));var f;f=0>a?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=a&&(d=f+d);if(isNaN(c)||d.length>=c)return d;d=isNaN(e)?Math.abs(a).toString():Math.abs(a).toFixed(e);a=c-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+Array(a+1).join(" "):f+Array(a+1).join(0<=b.indexOf("0",0)?"0":" ")+d},d:function(a,b,c,d,e,f,g,l){return O.f(parseInt(a,10),b,c,d,0,f,g,l)}};O.i=O.d;
O.u=O.d;var $b=function(a){if("function"==typeof a.p)return a.p();if(n(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return sa(a)},ac=function(a,b){if("function"==typeof a.forEach)a.forEach(b,void 0);else if(da(a)||n(a))la(a,b,void 0);else{var c;if("function"==typeof a.B)c=a.B();else if("function"!=typeof a.p)if(da(a)||n(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=ta(a);else c=void 0;for(var d=$b(a),e=d.length,f=0;f<e;f++)b.call(void 0,d[f],c&&c[f],
a)}};var P=function(a){this.O=new H;for(var b=arguments,c=0;c<b.length;c+=2)this.set(b[c],b[c+1])};P.prototype.set=function(a,b){this.O.set(a.name,{key:a,value:b})};P.prototype.remove=function(a){this.O.remove(a.name)};P.prototype.get=function(a){a=this.O.get(a.name,null);return null===a?null:a.value};var bc=function(a,b){la(a.O.p(),function(a){b(a.key,a.value)})};P.prototype.vb=function(){var a={};bc(this,function(b,c){a[b.id]=c});return a};
P.prototype.clone=function(){var a=new P;a.O=this.O.clone();return a};P.prototype.toString=function(){var a={};bc(this,function(b,c){a[b.id]=c});return JSON.stringify(a)};var cc=function(a){this.Sa=[];this.A=a};cc.prototype.N=function(a){if(!p(a))throw Error("Invalid filter. Must be a function.");this.Sa.push(a)};cc.prototype.send=function(a,b){for(var c=new Q(a,b),d=0;d<this.Sa.length&&(this.Sa[d](c),!c.Ra);d++);return c.Ra?Wb():this.A.send(a,b)};var Q=function(a,b){this.dc=a;this.cc=b;this.Ra=!1};Q.prototype.lc=function(){return this.dc};Q.prototype.mc=function(){return this.cc};Q.prototype.cancel=function(){this.Ra=!0};var dc=function(a,b){this.width=a;this.height=b};dc.prototype.clone=function(){return new dc(this.width,this.height)};dc.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};!A&&!z||z&&z&&9<=Fa||A&&C("1.9.1");z&&C("9");var ec={id:"apiVersion",name:"v",valueType:"text",maxLength:void 0,defaultValue:void 0},fc={id:"appName",name:"an",valueType:"text",maxLength:100,defaultValue:void 0},gc={id:"appVersion",name:"av",valueType:"text",maxLength:100,defaultValue:void 0},hc={id:"clientId",name:"cid",valueType:"text",maxLength:void 0,defaultValue:void 0},ic={id:"language",name:"ul",valueType:"text",maxLength:20,defaultValue:void 0},jc={id:"libVersion",name:"_v",valueType:"text",maxLength:void 0,defaultValue:void 0},kc={id:"sampleRateOverride",
name:"usro",valueType:"integer",maxLength:void 0,defaultValue:void 0},lc={id:"screenColors",name:"sd",valueType:"text",maxLength:20,defaultValue:void 0},mc={id:"screenResolution",name:"sr",valueType:"text",maxLength:20,defaultValue:void 0},nc={id:"trackingId",name:"tid",valueType:"text",maxLength:void 0,defaultValue:void 0},oc={id:"viewportSize",name:"vp",valueType:"text",maxLength:20,defaultValue:void 0},pc={xc:ec,Ac:fc,Bc:gc,Jc:hc,bd:ic,cd:jc,kd:kc,ld:lc,md:mc,yd:nc,Fd:oc},rc=function(a){if(!n(a))return a;
var b=qc(a,qb);if(ea(b))return b;b=qc(a,pc);if(ea(b))return b;b=/^dimension(\d+)$/.exec(a);if(null!==b)return{id:a,name:"cd"+b[1],valueType:"text",maxLength:150,defaultValue:void 0};b=/^metric(\d+)$/.exec(a);if(null!==b)return{id:a,name:"cm"+b[1],valueType:"integer",maxLength:void 0,defaultValue:void 0};throw Error(a+" is not a valid parameter name.");},qc=function(a,b){var c=ua(b,function(b){return b.id==a&&"metric"!=a&&"dimension"!=a});return ea(c)?c:null};var T=function(a,b){this.Kb=b;this.q=b.Ja();this.nb=new P;this.Qa=!1};h=T.prototype;h.set=function(a,b){var c=rc(a);this.nb.set(c,b)};h.N=function(a){this.Kb.N(a)};h.send=function(a,b){var c=this.nb.clone();b&&ra(b,function(a,b){null!=a&&c.set(rc(b),a)},this);this.Qa&&(this.Qa=!1,c.set(ob,"start"));return this.q.send(a,c)};h.oc=function(a){var b={description:a};this.set(pb,a);return this.send("appview",b)};
h.pc=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})};h.rc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};h.qc=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};h.ob=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})};h.jc=function(){this.Qa=!0};h.uc=function(a,b,c,d){return new sc(this,a,b,c,d)};
var sc=function(a,b,c,d,e){this.mb=a;this.Ob=b;this.Rb=c;this.Pb=d;this.Q=e;this.Qb=r()};sc.prototype.send=function(){var a=this.mb.ob(this.Ob,this.Rb,r()-this.Qb,this.Pb,this.Q);this.mb=null;return a};var U=function(a,b,c,d,e){this.Vb=a;this.Sb=b;this.Tb=c;this.j=d;this.Ub=e};U.prototype.nc=function(a){var b=new T(0,this.Ub.create());b.set(jc,this.Vb);b.set(ec,1);b.set(fc,this.Sb);b.set(gc,this.Tb);b.set(nc,a);a=window.navigator.language;b.set(ic,a);a=screen.colorDepth+"-bit";b.set(lc,a);a=[screen.width,screen.height].join("x");b.set(mc,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new dc(a.clientWidth,a.clientHeight);a=[a.width,a.height].join("x");b.set(oc,a);return b};
U.prototype.kc=function(){return Rb(this.j.ca)};var tc=function(a){this.ec=a};tc.prototype.send=function(a,b){this.ec.push({Eb:a,Fb:b});return Wb()};var uc=function(a,b,c){this.j=a;this.la=[];this.K={enabled:new tc(this.la),disabled:c};this.q=this.K.enabled;N(Rb(this.j.ca),ha(this.Bb,b),this.Ab,this)};uc.prototype.Bb=function(a){this.K.enabled=a();vc(this);la(this.la,function(a){this.send(a.Eb,a.Fb)},this);this.la=null;wc(this.j,q(this.Gb,this))};uc.prototype.Ab=function(){this.q=this.K.enabled=this.K.disabled;this.la=null};uc.prototype.send=function(a,b){return this.q.send(a,b)};var vc=function(a){a.q=a.j.pa()?a.K.enabled:a.K.disabled};
uc.prototype.Gb=function(a){switch(a){case "analytics.tracking-permitted":vc(this)}};var xc=function(a,b,c,d,e,f){M.call(this,e,f);this.Ea=a;this.Fa=[];this.bb=!!b;this.zb=!!c;this.yb=!!d;for(b=this.cb=0;b<a.length;b++)N(a[b],q(this.hb,this,b,!0),q(this.hb,this,b,!1));0!=a.length||this.bb||this.F(this.Fa)};t(xc,M);xc.prototype.hb=function(a,b,c){this.cb++;this.Fa[a]=[b,c];this.C||(this.bb&&b?this.F([a,c]):this.zb&&!b?this.v(c):this.cb==this.Ea.length&&this.F(this.Fa));this.yb&&!b&&(c=null);return c};xc.prototype.v=function(a){xc.J.v.call(this,a);for(a=0;a<this.Ea.length;a++)this.Ea[a].cancel()};
var yc=function(a){return(new xc(a,!1,!0)).H(function(a){for(var c=[],d=0;d<a.length;d++)c[d]=a[d][1];return c})};var V=function(a){this.G=a;this.Q=100;this.eb=[];this.Ga=this.ha=null;this.ca=zc(this);this.ca.H(function(){Va(this.G,"a",q(this.Db,this))},this)},zc=function(a){return Ac(a).H(function(){return this},a)},Ac=function(a){return yc([Bc(a),Cc(a)])};V.prototype.Db=function(){var a=this.ha,b=this.pa();Ac(this).H(function(){if(a!=this.ha)throw Error("User ID changed unexpectedly!");b!=this.pa()&&Dc(this)},this)};var wc=function(a,b){a.eb.push(b)};
V.prototype.tc=function(a){this.G.set("analytics.tracking-permitted",a).H(function(){this.Ga=a},this)};V.prototype.pa=function(){var a;if(a=this.Ga)a=k._gaUserPrefs,a=!(a&&a.ioo&&a.ioo());return a};
var Bc=function(a){return a.G.get("analytics.tracking-permitted").H(function(a){this.Ga=void 0!==a?a:!0},a)},Cc=function(a){return a.G.get("analytics.user-id").H(function(a){if(!a){a="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split("");for(var c=0,d=a.length;c<d;c++)switch(a[c]){case "x":a[c]=Math.floor(16*Math.random()).toString(16);break;case "y":a[c]=(Math.floor(4*Math.random())+8).toString(16)}a=a.join("");this.G.set("analytics.user-id",a)}this.ha=a},a)};V.prototype.sc=function(a){this.Q=a};
var Dc=function(a){la(a.eb,function(a){a("analytics.tracking-permitted")})};var Ec=function(a){G.call(this);this.Oa=a;this.G=chrome.storage.local;chrome.storage.onChanged.addListener(q(this.$b,this))};t(Ec,G);Ec.prototype.$b=function(a){Fc(this,a)&&this.dispatchEvent("a")};var Fc=function(a,b){return ma(ta(b),function(a){return 0==a.lastIndexOf(this.Oa,0)},a)};Ec.prototype.get=function(a){var b=new M,c=this.Oa+"."+a;this.G.get(c,function(a){var e=chrome.runtime.lastError;e?b.v(e):b.F(a[c])});return b};
Ec.prototype.set=function(a,b){var c=new M,d={};d[this.Oa+"."+a]=b;this.G.set(d,function(){var a=chrome.runtime.lastError;a?c.v(a):c.F()});return c};var W=function(){};W.Ib=function(){return W.tb?W.tb:W.tb=new W};W.prototype.send=function(){return Wb()};var Gc=function(a,b){this.Pa=[];var c=q(function(){this.ta=new cc(b.Ja());la(this.Pa,function(a){this.ta.N(a)},this);this.Pa=null;return this.ta},this);this.q=new uc(a,c,W.Ib())};Gc.prototype.Ja=function(){return this.q};Gc.prototype.N=function(a){this.ta?this.ta.N(a):this.Pa.push(a)};var Hc=function(a,b){this.j=a;this.Zb=b};Hc.prototype.create=function(){return new Gc(this.j,this.Zb)};var Ic=function(a,b){G.call(this);this.sa=a||1;this.M=b||k;this.Ia=q(this.Yb,this);this.Ka=r()};t(Ic,G);h=Ic.prototype;h.enabled=!1;h.e=null;h.Yb=function(){if(this.enabled){var a=r()-this.Ka;0<a&&a<.8*this.sa?this.e=this.M.setTimeout(this.Ia,this.sa-a):(this.e&&(this.M.clearTimeout(this.e),this.e=null),this.dispatchEvent("tick"),this.enabled&&(this.e=this.M.setTimeout(this.Ia,this.sa),this.Ka=r()))}};h.start=function(){this.enabled=!0;this.e||(this.e=this.M.setTimeout(this.Ia,this.sa),this.Ka=r())};
h.stop=function(){this.enabled=!1;this.e&&(this.M.clearTimeout(this.e),this.e=null)};h.k=function(){Ic.J.k.call(this);this.stop();delete this.M};var Jc=function(a,b,c){if(p(a))c&&(a=q(a,c));else if(a&&"function"==typeof a.handleEvent)a=q(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<b?-1:k.setTimeout(a,b||0)};var X=function(a){this.La=a;this.b={}};t(X,ja);var Kc=[];X.prototype.listen=function(a,b,c,d){m(b)||(b&&(Kc[0]=b.toString()),b=Kc);for(var e=0;e<b.length;e++){var f=Va(a,b[e],c||this.handleEvent,d||!1,this.La||this);if(!f)break;this.b[f.key]=f}return this};X.prototype.Ta=function(a,b,c,d){return Lc(this,a,b,c,d)};var Lc=function(a,b,c,d,e,f){if(m(c))for(var g=0;g<c.length;g++)Lc(a,b,c[g],d,e,f);else{b=bb(b,c,d||a.handleEvent,e,f||a.La||a);if(!b)return a;a.b[b.key]=b}return a};
X.prototype.Ma=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)this.Ma(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.La||this,c=Wa(c),d=!!d,b=Ma(a)?a.T(b,c,d,e):a?(a=Ya(a))?a.T(b,c,d,e):null:null,b&&(db(b),delete this.b[b.key]);return this};X.prototype.removeAll=function(){ra(this.b,db);this.b={}};X.prototype.k=function(){X.J.k.call(this);this.removeAll()};X.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};var Y=function(){G.call(this);this.na=new X(this);Ia&&(Ja?this.na.listen(Ka?document.body:window,["online","offline"],this.ib):(this.jb=Ia?navigator.onLine:!0,this.e=new Ic(250),this.na.listen(this.e,"tick",this.Nb),this.e.start()))};t(Y,G);Y.prototype.Nb=function(){var a=Ia?navigator.onLine:!0;a!=this.jb&&(this.jb=a,this.ib())};Y.prototype.ib=function(){this.dispatchEvent((Ia?navigator.onLine:1)?"online":"offline")};
Y.prototype.k=function(){Y.J.k.call(this);this.na.ra();this.na=null;this.e&&(this.e.ra(),this.e=null)};var Mc=function(a,b){this.j=a;this.A=b};Mc.prototype.send=function(a,b){b.set(hc,this.j.ha);return this.A.send(a,b)};var Nc=function(a){this.A=a};Nc.prototype.send=function(a,b){Oc(b);Pc(b);return this.A.send(a,b)};var Oc=function(a){bc(a,function(b,c){void 0!==b.maxLength&&"text"==b.valueType&&0<b.maxLength&&c.length>b.maxLength&&a.set(b,c.substring(0,b.maxLength))})},Pc=function(a){bc(a,function(b,c){void 0!==b.defaultValue&&c==b.defaultValue&&a.remove(b)})};var Xb={status:"device-offline",ua:void 0},Qc={status:"rate-limited",ua:void 0},Rc={status:"sampled-out",ua:void 0},Sc={status:"sent",ua:void 0};var Tc=function(a,b){this.Mb=a;this.A=b};Tc.prototype.send=function(a,b){var c;c=this.Mb;var d=c.gb(),e=Math.floor((d-c.fb)*c.Hb);0<e&&(c.V=Math.min(c.V+e,c.Jb),c.fb=d);1>c.V?c=!1:(c.V-=1,c=!0);return c||"item"==a||"transaction"==a?this.A.send(a,b):Wb(Qc)};var Uc=function(){this.V=60;this.Jb=500;this.Hb=5E-4;this.gb=function(){return(new Date).getTime()};this.fb=this.gb()};var Vc=function(a,b){this.j=a;this.A=b};Vc.prototype.send=function(a,b){var c=b.get(hc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=this.j.Q:((d=b.get(kc))&&b.remove(kc),d||(d=this.j.Q));return c<655.36*d?this.A.send(a,b):Wb(Rc)};var Wc=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,Xc=B,Yc=function(a,b){if(Xc){Xc=!1;var c=k.location;if(c){var d=c.href;if(d&&(d=(d=Yc(3,d))&&decodeURIComponent(d))&&d!=c.hostname)throw Xc=!0,Error();}}return b.match(Wc)[a]||null};var Zc=function(){};Zc.prototype.qb=null;var ad=function(a){var b;(b=a.qb)||(b={},$c(a)&&(b[0]=!0,b[1]=!0),b=a.qb=b);return b};var bd,cd=function(){};t(cd,Zc);var dd=function(a){return(a=$c(a))?new ActiveXObject(a):new XMLHttpRequest},$c=function(a){if(!a.sb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.sb=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.sb};bd=new cd;var Z=function(a){G.call(this);this.headers=new H;this.aa=a||null;this.D=!1;this.Y=this.a=null;this.X=this.wa="";this.I=this.va=this.W=this.ya=!1;this.$=0;this.Z=null;this.Ua="";this.xa=this.wb=!1};t(Z,G);var ed=/^https?$/i,fd=["POST","PUT"],gd=[],hd=function(a,b,c){var d=new Z;gd.push(d);b&&d.listen("complete",b);d.Ta("ready",d.fc);d.send(a,"POST",c,void 0)};Z.prototype.fc=function(){this.ra();pa(gd,this)};
Z.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.wa+"; newUri="+a);b=b?b.toUpperCase():"GET";this.wa=a;this.X="";this.ya=!1;this.D=!0;this.a=this.aa?dd(this.aa):dd(bd);this.Y=this.aa?ad(this.aa):ad(bd);this.a.onreadystatechange=q(this.Va,this);try{this.va=!0,this.a.open(b,String(a),!0),this.va=!1}catch(e){this.ba(5,e);return}a=c||"";var f=this.headers.clone();d&&ac(d,function(a,b){f.set(b,a)});d=oa(f.B());c=k.FormData&&a instanceof
k.FormData;!(0<=ka(fd,b))||d||c||f.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");f.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.Ua&&(this.a.responseType=this.Ua);"withCredentials"in this.a&&(this.a.withCredentials=this.wb);try{id(this),0<this.$&&((this.xa=jd(this.a))?(this.a.timeout=this.$,this.a.ontimeout=q(this.Wa,this)):this.Z=Jc(this.Wa,this.$,this)),this.W=!0,this.a.send(a),this.W=!1}catch(g){this.ba(5,g)}};
var jd=function(a){return z&&C(9)&&"number"==typeof a.timeout&&void 0!==a.ontimeout},na=function(a){return"content-type"==a.toLowerCase()};Z.prototype.Wa=function(){"undefined"!=typeof aa&&this.a&&(this.X="Timed out after "+this.$+"ms, aborting",this.dispatchEvent("timeout"),this.abort(8))};Z.prototype.ba=function(a,b){this.D=!1;this.a&&(this.I=!0,this.a.abort(),this.I=!1);this.X=b;kd(this);ld(this)};var kd=function(a){a.ya||(a.ya=!0,a.dispatchEvent("complete"),a.dispatchEvent("error"))};
Z.prototype.abort=function(){this.a&&this.D&&(this.D=!1,this.I=!0,this.a.abort(),this.I=!1,this.dispatchEvent("complete"),this.dispatchEvent("abort"),ld(this))};Z.prototype.k=function(){this.a&&(this.D&&(this.D=!1,this.I=!0,this.a.abort(),this.I=!1),ld(this,!0));Z.J.k.call(this)};Z.prototype.Va=function(){this.Na||(this.va||this.W||this.I?md(this):this.Xb())};Z.prototype.Xb=function(){md(this)};
var md=function(a){if(a.D&&"undefined"!=typeof aa&&(!a.Y[1]||4!=nd(a)||2!=od(a)))if(a.W&&4==nd(a))Jc(a.Va,0,a);else if(a.dispatchEvent("readystatechange"),4==nd(a)){a.D=!1;try{var b=od(a),c,d;t:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:d=!0;break t;default:d=!1}if(!(c=d)){var e;if(e=0===b){var f=Yc(1,String(a.wa));if(!f&&self.location)var g=self.location.protocol,f=g.substr(0,g.length-1);e=!ed.test(f?f.toLowerCase():"")}c=e}if(c)a.dispatchEvent("complete"),a.dispatchEvent("success");
else{var l;try{l=2<nd(a)?a.a.statusText:""}catch(J){l=""}a.X=l+" ["+od(a)+"]";kd(a)}}finally{ld(a)}}},ld=function(a,b){if(a.a){id(a);var c=a.a,d=a.Y[0]?ba:null;a.a=null;a.Y=null;b||a.dispatchEvent("ready");try{c.onreadystatechange=d}catch(e){}}},id=function(a){a.a&&a.xa&&(a.a.ontimeout=null);"number"==typeof a.Z&&(k.clearTimeout(a.Z),a.Z=null)},nd=function(a){return a.a?a.a.readyState:0},od=function(a){try{return 2<nd(a)?a.a.status:-1}catch(b){return-1}};var pd=function(a,b,c){this.r=a||null;this.ac=!!c},qd=function(a){if(!a.c&&(a.c=new H,a.g=0,a.r))for(var b=a.r.split("&"),c=0;c<b.length;c++){var d=b[c].indexOf("="),e=null,f=null;0<=d?(e=b[c].substring(0,d),f=b[c].substring(d+1)):e=b[c];e=decodeURIComponent(e.replace(/\+/g," "));e=$(a,e);a.add(e,f?decodeURIComponent(f.replace(/\+/g," ")):"")}};h=pd.prototype;h.c=null;h.g=null;h.add=function(a,b){qd(this);this.r=null;a=$(this,a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.g++;return this};
h.remove=function(a){qd(this);a=$(this,a);return this.c.S(a)?(this.r=null,this.g-=this.c.get(a).length,this.c.remove(a)):!1};h.S=function(a){qd(this);a=$(this,a);return this.c.S(a)};h.B=function(){qd(this);for(var a=this.c.p(),b=this.c.B(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};h.p=function(a){qd(this);var b=[];if(n(a))this.S(a)&&(b=qa(b,this.c.get($(this,a))));else{a=this.c.p();for(var c=0;c<a.length;c++)b=qa(b,a[c])}return b};
h.set=function(a,b){qd(this);this.r=null;a=$(this,a);this.S(a)&&(this.g-=this.c.get(a).length);this.c.set(a,[b]);this.g++;return this};h.get=function(a,b){var c=a?this.p(a):[];return 0<c.length?String(c[0]):b};h.toString=function(){if(this.r)return this.r;if(!this.c)return"";for(var a=[],b=this.c.B(),c=0;c<b.length;c++)for(var d=b[c],e=encodeURIComponent(String(d)),d=this.p(d),f=0;f<d.length;f++){var g=e;""!==d[f]&&(g+="="+encodeURIComponent(String(d[f])));a.push(g)}return this.r=a.join("&")};
h.clone=function(){var a=new pd;a.r=this.r;this.c&&(a.c=this.c.clone(),a.g=this.g);return a};var $=function(a,b){var c=String(b);a.ac&&(c=c.toLowerCase());return c};var rd=function(a,b){this.Lb=a;this.ia=b};rd.prototype.send=function(a,b){if(Ia&&!navigator.onLine)return Yb();var c=new M,d=sd(a,b);d.length>this.ia?c.v({status:"payload-too-big",ua:Zb("Encoded hit length == %s, but should be <= %s.",d.length,this.ia)}):hd(this.Lb,function(){c.F(Sc)},d);return c};var sd=function(a,b){var c=new pd;c.add(nb.name,a);bc(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var td=function(a,b,c){this.j=a;this.Cb=b;this.ia=c};td.prototype.Ja=function(){if(!this.q){var a=this.j;if(!Rb(a.ca).C)throw Error("Cannot construct shared channel prior to settings being ready.");new Y;var b=new Nc(new rd(this.Cb,this.ia)),c=new Uc;this.q=new Mc(a,new Vc(a,new Tc(c,b)))}return this.q};var ud=new H,vd=function(){if(!lb){var a=new Ec("google-analytics");lb=new V(a)}return lb};s("goog.async.Deferred",M);s("goog.async.Deferred.prototype.addCallback",M.prototype.H);s("goog.events.EventTarget",G);s("goog.events.EventTarget.prototype.listen",G.prototype.listen);s("analytics.getService",function(a){var b=ud.get(a,null);if(null===b){var b=chrome.runtime.getManifest().version,c=vd();if(!mb){var d=vd();mb=new Hc(d,new td(d,"https://www.google-analytics.com/collect",8192))}b=new U("ca1.5.0",a,b,c,mb);ud.set(a,b)}return b});s("analytics.internal.GoogleAnalyticsService",U);
s("analytics.internal.GoogleAnalyticsService.prototype.getTracker",U.prototype.nc);s("analytics.internal.GoogleAnalyticsService.prototype.getConfig",U.prototype.kc);s("analytics.internal.ServiceSettings",V);s("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",V.prototype.tc);s("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",V.prototype.pa);s("analytics.internal.ServiceSettings.prototype.setSampleRate",V.prototype.sc);s("analytics.internal.ServiceTracker",T);
s("analytics.internal.ServiceTracker.prototype.send",T.prototype.send);s("analytics.internal.ServiceTracker.prototype.sendAppView",T.prototype.oc);s("analytics.internal.ServiceTracker.prototype.sendEvent",T.prototype.pc);s("analytics.internal.ServiceTracker.prototype.sendSocial",T.prototype.rc);s("analytics.internal.ServiceTracker.prototype.sendException",T.prototype.qc);s("analytics.internal.ServiceTracker.prototype.sendTiming",T.prototype.ob);
s("analytics.internal.ServiceTracker.prototype.startTiming",T.prototype.uc);s("analytics.internal.ServiceTracker.Timing",sc);s("analytics.internal.ServiceTracker.Timing.prototype.send",sc.prototype.send);s("analytics.internal.ServiceTracker.prototype.forceSessionStart",T.prototype.jc);s("analytics.internal.ServiceTracker.prototype.addFilter",T.prototype.N);s("analytics.internal.FilterChannel.Hit",Q);s("analytics.internal.FilterChannel.Hit.prototype.getHitType",Q.prototype.lc);
s("analytics.internal.FilterChannel.Hit.prototype.getParameters",Q.prototype.mc);s("analytics.internal.FilterChannel.Hit.prototype.cancel",Q.prototype.cancel);s("analytics.ParameterMap",P);s("analytics.ParameterMap.Entry",P.Entry);s("analytics.ParameterMap.prototype.set",P.prototype.set);s("analytics.ParameterMap.prototype.get",P.prototype.get);s("analytics.ParameterMap.prototype.remove",P.prototype.remove);s("analytics.ParameterMap.prototype.toObject",P.prototype.vb);
s("analytics.HitTypes.APPVIEW","appview");s("analytics.HitTypes.EVENT","event");s("analytics.HitTypes.SOCIAL","social");s("analytics.HitTypes.TRANSACTION","transaction");s("analytics.HitTypes.ITEM","item");s("analytics.HitTypes.TIMING","timing");s("analytics.HitTypes.EXCEPTION","exception");ra(qb,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();s("analytics.Parameters."+b,a)}); })()
var S=function(a,b){this.ja=[];this.hb=a;this.gb=b||null;this.W=this.C=!1;this.v=void 0;this.Ka=this.Lb=this.Ja=!1;this.ka=0;this.o=null;this.Ia=0};S.prototype.cancel=function(a){if(this.C)this.v instanceof S&&this.v.cancel();else{if(this.o){var b=this.o;delete this.o;a?b.cancel(a):(b.Ia--,0>=b.Ia&&b.cancel())}this.hb?this.hb.call(this.gb,this):this.Ka=!0;this.C||this.w(new dc)}};S.prototype.ib=function(a,b){this.Ja=!1;ec(this,a,b)};
var ec=function(a,b,c){a.C=!0;a.v=c;a.W=!b;fc(a)},hc=function(a){if(a.C){if(!a.Ka)throw new gc;a.Ka=!1}};S.prototype.G=function(a){hc(this);ec(this,!0,a)};S.prototype.w=function(a){hc(this);ec(this,!1,a)};S.prototype.J=function(a,b){return ic(this,a,null,b)};var ic=function(a,b,c,d){a.ja.push([b,c,d]);a.C&&fc(a);return a};S.prototype.then=function(a,b,c){var d,e,f=new R(function(a,b){d=a;e=b});ic(this,d,function(a){a instanceof dc?f.cancel():e(a)});return f.then(a,b,c)};Sb(S);
var jc=function(a){var b=new S;ic(a,b.G,b.w,b);return b},kc=function(a){return la(a.ja,function(a){return p(a[1])})},fc=function(a){if(a.ka&&a.C&&kc(a)){var b=a.ka,c=lc[b];c&&(h.clearTimeout(c.ma),delete lc[b]);a.ka=0}a.o&&(a.o.Ia--,delete a.o);for(var b=a.v,d=c=!1;a.ja.length&&!a.Ja;){var e=a.ja.shift(),f=e[0],k=e[1],e=e[2];if(f=a.W?k:f)try{var l=f.call(e||a.gb,b);void 0!==l&&(a.W=a.W&&(l==b||l instanceof Error),a.v=b=l);Tb(b)&&(d=!0,a.Ja=!0)}catch(N){b=N,a.W=!0,kc(a)||(c=!0)}}a.v=b;d&&(l=r(a.ib,
a,!0),d=r(a.ib,a,!1),b instanceof S?(ic(b,l,d),b.Lb=!0):b.then(l,d));c&&(b=new mc(b),lc[b.ma]=b,a.ka=b.ma)},nc=function(a){var b=new S;b.G(a);return b},pc=function(){var a=oc,b=new S;b.w(a);return b},gc=function(){v.call(this)};u(gc,v);gc.prototype.message="Deferred has already fired";gc.prototype.name="AlreadyCalledError";var dc=function(){v.call(this)};u(dc,v);dc.prototype.message="Deferred was canceled";dc.prototype.name="CanceledError";
var mc=function(a){this.ma=h.setTimeout(r(this.pc,this),0);this.ga=a};mc.prototype.pc=function(){delete lc[this.ma];throw this.ga;};var lc={};var qc=function(a){this.$a=[];this.e=a};qc.prototype.S=function(a){if(!p(a))throw Error("Invalid filter. Must be a function.");this.$a.push(a)};qc.prototype.send=function(a,b){for(var c=new T(a,b),d=0;d<this.$a.length&&(this.$a[d](c),!c.Za);d++);return c.Za?nc():this.e.send(a,b)};var T=function(a,b){this.rc=a;this.qc=b;this.Za=!1};T.prototype.Gb=function(){return this.rc};T.prototype.T=function(){return this.qc};T.prototype.cancel=function(){this.Za=!0};var rc=function(a,b){this.width=a;this.height=b};rc.prototype.clone=function(){return new rc(this.width,this.height)};rc.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};!K&&!I||I&&I&&9<=db||K&&M("1.9.1");I&&M("9");var sc={id:"apiVersion",name:"v",valueType:"text",maxLength:void 0,defaultValue:void 0},tc={id:"appName",name:"an",valueType:"text",maxLength:100,defaultValue:void 0},uc={id:"appVersion",name:"av",valueType:"text",maxLength:100,defaultValue:void 0},vc={id:"clientId",name:"cid",valueType:"text",maxLength:void 0,defaultValue:void 0},wc={id:"language",name:"ul",valueType:"text",maxLength:20,defaultValue:void 0},xc={id:"libVersion",name:"_v",valueType:"text",maxLength:void 0,defaultValue:void 0},yc={id:"sampleRateOverride",
name:"usro",valueType:"integer",maxLength:void 0,defaultValue:void 0},zc={id:"screenColors",name:"sd",valueType:"text",maxLength:20,defaultValue:void 0},Ac={id:"screenResolution",name:"sr",valueType:"text",maxLength:20,defaultValue:void 0},Bc={id:"trackingId",name:"tid",valueType:"text",maxLength:void 0,defaultValue:void 0},Cc={id:"viewportSize",name:"vp",valueType:"text",maxLength:20,defaultValue:void 0},Dc={Rc:sc,Uc:tc,Vc:uc,cd:vc,vd:wc,wd:xc,Cd:yc,Dd:zc,Ed:Ac,Qd:Bc,Xd:Cc},Fc=function(a){if(!n(a))return a;
var b=Ec(a,Ka);if(q(b))return b;b=Ec(a,Dc);if(q(b))return b;b=/^dimension(\d+)$/.exec(a);if(null!==b)return La(parseInt(b[1],10));b=/^metric(\d+)$/.exec(a);if(null!==b)return Ma(parseInt(b[1],10));throw Error(a+" is not a valid parameter name.");},Ec=function(a,b){var c=xa(b,function(b){return b.id==a&&"metric"!=a&&"dimension"!=a});return q(c)?c:null};var W=function(a,b){this.Zb=b;this.q=b.Sa();this.sb=new C;this.Ya=!1};g=W.prototype;g.set=function(a,b){var c=Fc(a);this.sb.set(c,b)};g.S=function(a){this.Zb.S(a)};g.send=function(a,b){if(a instanceof D)return a.send(this);var c=this.sb.clone();b instanceof C?c.ia(b):q(b)&&ua(b,function(a,b){null!=a&&c.set(Fc(b),a)},this);this.Ya&&(this.Ya=!1,c.set(Ea,"start"));return this.q.send(a,c)};g.Gc=function(a){var b={description:a};this.set(Fa,a);return this.send("appview",b)};
g.Hc=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})};g.Jc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};g.Ic=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};g.Cb=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})};g.Ac=function(){this.Ya=!0};g.Mc=function(a,b,c,d){return new Gc(this,a,b,c,d)};
var Gc=function(a,b,c,d,e){this.yb=a;this.bc=b;this.ec=c;this.cc=d;this.V=e;this.dc=s()};Gc.prototype.send=function(){var a=this.yb.Cb(this.bc,this.ec,s()-this.dc,this.cc,this.V);this.yb=null;return a};var Hc=function(a,b,c,d,e){this.ic=a;this.fc=b;this.gc=c;this.k=d;this.hc=e};
Hc.prototype.Cc=function(a){var b=new W(0,this.hc.create());b.set(xc,this.ic);b.set(sc,1);b.set(tc,this.fc);b.set(uc,this.gc);b.set(Bc,a);a=window.navigator.language;b.set(wc,a);a=screen.colorDepth+"-bit";b.set(zc,a);a=[screen.width,screen.height].join("x");b.set(Ac,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new rc(a.clientWidth,a.clientHeight);a=[a.width,a.height].join("x");b.set(Cc,a);return b};Hc.prototype.Bc=function(){return jc(this.k.ha)};var Ic=function(a){this.sc=a};Ic.prototype.send=function(a,b){this.sc.push({Ub:a,Vb:b});return nc()};var Jc=function(a,b,c){this.k=a;this.ra=[];this.M={enabled:new Ic(this.ra),disabled:c};this.q=this.M.enabled;ic(jc(this.k.ha),ha(this.Pb,b),this.Ob,this)};Jc.prototype.Pb=function(a){this.M.enabled=a();Kc(this);ka(this.ra,function(a){this.send(a.Ub,a.Vb)},this);this.ra=null;Lc(this.k,r(this.Xb,this))};Jc.prototype.Ob=function(){this.q=this.M.enabled=this.M.disabled;this.ra=null};Jc.prototype.send=function(a,b){return this.q.send(a,b)};var Kc=function(a){a.q=a.k.va()?a.M.enabled:a.M.disabled};
Jc.prototype.Xb=function(a){switch(a){case "analytics.tracking-permitted":Kc(this)}};var Mc=function(a,b,c,d,e,f){S.call(this,e,f);this.Na=a;this.Oa=[];this.lb=!!b;this.Nb=!!c;this.Mb=!!d;for(b=this.mb=0;b<a.length;b++)ic(a[b],r(this.rb,this,b,!0),r(this.rb,this,b,!1));0!=a.length||this.lb||this.G(this.Oa)};u(Mc,S);Mc.prototype.rb=function(a,b,c){this.mb++;this.Oa[a]=[b,c];this.C||(this.lb&&b?this.G([a,c]):this.Nb&&!b?this.w(c):this.mb==this.Na.length&&this.G(this.Oa));this.Mb&&!b&&(c=null);return c};Mc.prototype.w=function(a){Mc.L.w.call(this,a);for(a=0;a<this.Na.length;a++)this.Na[a].cancel()};
var Nc=function(a){return(new Mc(a,!1,!0)).J(function(a){for(var c=[],d=0;d<a.length;d++)c[d]=a[d][1];return c})};var X=function(a){this.H=a;this.V=100;this.nb=[];this.Pa=this.la=null;this.ha=Oc(this);this.ha.J(function(){tb(this.H,"a",r(this.Rb,this))},this)},Oc=function(a){return Pc(a).J(function(){return this},a)},Pc=function(a){return Nc([Qc(a),Rc(a)])};X.prototype.Rb=function(){var a=this.la,b=this.va();Pc(this).J(function(){if(a!=this.la)throw Error("User ID changed unexpectedly!");b!=this.va()&&Sc(this)},this)};var Lc=function(a,b){a.nb.push(b)};
X.prototype.Lc=function(a){this.H.set("analytics.tracking-permitted",a).J(function(){this.Pa=a},this)};X.prototype.va=function(){var a;if(a=this.Pa)a=h._gaUserPrefs,a=!(a&&a.ioo&&a.ioo());return a};
var Qc=function(a){return a.H.get("analytics.tracking-permitted").J(function(a){this.Pa=void 0!==a?a:!0},a)},Rc=function(a){return a.H.get("analytics.user-id").J(function(a){if(!a){a="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split("");for(var c=0,d=a.length;c<d;c++)switch(a[c]){case "x":a[c]=Math.floor(16*Math.random()).toString(16);break;case "y":a[c]=(Math.floor(4*Math.random())+8).toString(16)}a=a.join("");this.H.set("analytics.user-id",a)}this.la=a},a)};X.prototype.Kc=function(a){this.V=a};
var Sc=function(a){ka(a.nb,function(a){a("analytics.tracking-permitted")})};var Tc=function(a){Q.call(this);this.Wa=a;this.H=chrome.storage.local;chrome.storage.onChanged.addListener(r(this.nc,this))};u(Tc,Q);Tc.prototype.nc=function(a){Uc(this,a)&&this.dispatchEvent("a")};var Uc=function(a,b){return la(wa(b),function(a){return 0==a.lastIndexOf(this.Wa,0)},a)};Tc.prototype.get=function(a){var b=new S,c=this.Wa+"."+a;this.H.get(c,function(a){var e=chrome.runtime.lastError;e?b.w(e):b.G(a[c])});return b};
Tc.prototype.set=function(a,b){var c=new S,d={};d[this.Wa+"."+a]=b;this.H.set(d,function(){var a=chrome.runtime.lastError;a?c.w(a):c.G()});return c};var Y=function(){};Y.Yb=function(){return Y.Ib?Y.Ib:Y.Ib=new Y};Y.prototype.send=function(){return nc()};var Vc=function(a,b){this.Xa=[];var c=r(function(){this.Aa=new qc(b.Sa());ka(this.Xa,function(a){this.Aa.S(a)},this);this.Xa=null;return this.Aa},this);this.q=new Jc(a,c,Y.Yb())};Vc.prototype.Sa=function(){return this.q};Vc.prototype.S=function(a){this.Aa?this.Aa.S(a):this.Xa.push(a)};var Wc=function(a,b){this.k=a;this.mc=b};Wc.prototype.create=function(){return new Vc(this.k,this.mc)};var Xc=function(a,b){Q.call(this);this.ya=a||1;this.R=b||h;this.Ra=r(this.lc,this);this.Ta=s()};u(Xc,Q);g=Xc.prototype;g.enabled=!1;g.g=null;g.lc=function(){if(this.enabled){var a=s()-this.Ta;0<a&&a<.8*this.ya?this.g=this.R.setTimeout(this.Ra,this.ya-a):(this.g&&(this.R.clearTimeout(this.g),this.g=null),this.dispatchEvent("tick"),this.enabled&&(this.g=this.R.setTimeout(this.Ra,this.ya),this.Ta=s()))}};g.start=function(){this.enabled=!0;this.g||(this.g=this.R.setTimeout(this.Ra,this.ya),this.Ta=s())};
g.stop=function(){this.enabled=!1;this.g&&(this.R.clearTimeout(this.g),this.g=null)};g.l=function(){Xc.L.l.call(this);this.stop();delete this.R};var Yc=function(a,b,c){if(p(a))c&&(a=r(a,c));else if(a&&"function"==typeof a.handleEvent)a=r(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<b?-1:h.setTimeout(a,b||0)};var Z=function(a){E.call(this);this.Ua=a;this.b={}};u(Z,E);var Zc=[];Z.prototype.listen=function(a,b,c,d){m(b)||(b&&(Zc[0]=b.toString()),b=Zc);for(var e=0;e<b.length;e++){var f=tb(a,b[e],c||this.handleEvent,d||!1,this.Ua||this);if(!f)break;this.b[f.key]=f}return this};Z.prototype.bb=function(a,b,c,d){return $c(this,a,b,c,d)};var $c=function(a,b,c,d,e,f){if(m(c))for(var k=0;k<c.length;k++)$c(a,b,c[k],d,e,f);else{b=Ab(b,c,d||a.handleEvent,e,f||a.Ua||a);if(!b)return a;a.b[b.key]=b}return a};
Z.prototype.Va=function(a,b,c,d,e){if(m(b))for(var f=0;f<b.length;f++)this.Va(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.Ua||this,c=ub(c),d=!!d,b=kb(a)?a.X(b,c,d,e):a?(a=wb(a))?a.X(b,c,d,e):null:null,b&&(Cb(b),delete this.b[b.key]);return this};Z.prototype.removeAll=function(){ua(this.b,Cb);this.b={}};Z.prototype.l=function(){Z.L.l.call(this);this.removeAll()};Z.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};var ad=function(){Q.call(this);this.ta=new Z(this);gb&&(hb?this.ta.listen(ib?document.body:window,["online","offline"],this.tb):(this.ub=gb?navigator.onLine:!0,this.g=new Xc(250),this.ta.listen(this.g,"tick",this.ac),this.g.start()))};u(ad,Q);ad.prototype.ac=function(){var a=gb?navigator.onLine:!0;a!=this.ub&&(this.ub=a,this.tb())};ad.prototype.tb=function(){this.dispatchEvent((gb?navigator.onLine:1)?"online":"offline")};
ad.prototype.l=function(){ad.L.l.call(this);this.ta.xa();this.ta=null;this.g&&(this.g.xa(),this.g=null)};var bd=function(a,b){this.k=a;this.e=b};bd.prototype.send=function(a,b){b.set(vc,this.k.la);return this.e.send(a,b)};var cd=function(a){this.e=a};cd.prototype.send=function(a,b){dd(b);ed(b);return this.e.send(a,b)};var dd=function(a){Ua(a,function(b,c){void 0!==b.maxLength&&"text"==b.valueType&&0<b.maxLength&&c.length>b.maxLength&&a.set(b,c.substring(0,b.maxLength))})},ed=function(a){Ua(a,function(b,c){void 0!==b.defaultValue&&c==b.defaultValue&&a.remove(b)})};var oc={status:"device-offline",Ba:void 0},fd={status:"rate-limited",Ba:void 0},gd={status:"sampled-out",Ba:void 0},hd={status:"sent",Ba:void 0};var id=function(a,b){this.Wb=a;this.e=b};id.prototype.send=function(a,b){var c;c=this.Wb;var d=c.pb(),e=Math.floor((d-c.ob)*c.Sb);0<e&&(c.$=Math.min(c.$+e,c.Tb),c.ob=d);1>c.$?c=!1:(c.$-=1,c=!0);return c||"item"==a||"transaction"==a?this.e.send(a,b):nc(fd)};var jd=function(){this.$=60;this.Tb=500;this.Sb=5E-4;this.pb=function(){return(new Date).getTime()};this.ob=this.pb()};var kd=function(a,b){this.k=a;this.e=b};kd.prototype.send=function(a,b){var c=b.get(vc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=this.k.V:((d=b.get(yc))&&b.remove(yc),d||(d=this.k.V));return c<655.36*d?this.e.send(a,b):nc(gd)};var ld=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,md=L,nd=function(a,b){if(md){md=!1;var c=h.location;if(c){var d=c.href;if(d&&(d=(d=nd(3,d))?decodeURI(d):d)&&d!=c.hostname)throw md=!0,Error();}}return b.match(ld)[a]||null};var od=function(){};od.prototype.Eb=null;var qd=function(a){var b;(b=a.Eb)||(b={},pd(a)&&(b[0]=!0,b[1]=!0),b=a.Eb=b);return b};var rd,sd=function(){};u(sd,od);var td=function(a){return(a=pd(a))?new ActiveXObject(a):new XMLHttpRequest},pd=function(a){if(!a.Hb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.Hb=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.Hb};rd=new sd;var $=function(a){Q.call(this);this.headers=new x;this.fa=a||null;this.D=!1;this.ca=this.a=null;this.ba=this.Fa="";this.K=this.Ea=this.aa=this.Ha=!1;this.ea=0;this.da=null;this.cb="";this.Ga=this.Kb=!1};u($,Q);var ud=/^https?$/i,vd=["POST","PUT"],wd=[],xd=function(a,b,c){var d=new $;wd.push(d);b&&d.listen("complete",b);d.bb("ready",d.tc);d.send(a,"POST",c,void 0)};$.prototype.tc=function(){this.xa();pa(wd,this)};
$.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.Fa+"; newUri="+a);b=b?b.toUpperCase():"GET";this.Fa=a;this.ba="";this.Ha=!1;this.D=!0;this.a=this.fa?td(this.fa):td(rd);this.ca=this.fa?qd(this.fa):qd(rd);this.a.onreadystatechange=r(this.eb,this);try{this.Ea=!0,this.a.open(b,String(a),!0),this.Ea=!1}catch(e){this.ga(5,e);return}a=c||"";var f=this.headers.clone();d&&Ta(d,function(a,b){f.set(b,a)});d=oa(f.F());c=h.FormData&&a instanceof
h.FormData;!(0<=ja(vd,b))||d||c||f.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");f.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.cb&&(this.a.responseType=this.cb);"withCredentials"in this.a&&(this.a.withCredentials=this.Kb);try{yd(this),0<this.ea&&((this.Ga=zd(this.a))?(this.a.timeout=this.ea,this.a.ontimeout=r(this.fb,this)):this.da=Yc(this.fb,this.ea,this)),this.aa=!0,this.a.send(a),this.aa=!1}catch(k){this.ga(5,k)}};
var zd=function(a){return I&&M(9)&&ea(a.timeout)&&void 0!==a.ontimeout},na=function(a){return"content-type"==a.toLowerCase()};$.prototype.fb=function(){"undefined"!=typeof aa&&this.a&&(this.ba="Timed out after "+this.ea+"ms, aborting",this.dispatchEvent("timeout"),this.abort(8))};$.prototype.ga=function(a,b){this.D=!1;this.a&&(this.K=!0,this.a.abort(),this.K=!1);this.ba=b;Ad(this);Bd(this)};var Ad=function(a){a.Ha||(a.Ha=!0,a.dispatchEvent("complete"),a.dispatchEvent("error"))};
$.prototype.abort=function(){this.a&&this.D&&(this.D=!1,this.K=!0,this.a.abort(),this.K=!1,this.dispatchEvent("complete"),this.dispatchEvent("abort"),Bd(this))};$.prototype.l=function(){this.a&&(this.D&&(this.D=!1,this.K=!0,this.a.abort(),this.K=!1),Bd(this,!0));$.L.l.call(this)};$.prototype.eb=function(){this.Y||(this.Ea||this.aa||this.K?Cd(this):this.jc())};$.prototype.jc=function(){Cd(this)};
var Cd=function(a){if(a.D&&"undefined"!=typeof aa&&(!a.ca[1]||4!=Dd(a)||2!=Ed(a)))if(a.aa&&4==Dd(a))Yc(a.eb,0,a);else if(a.dispatchEvent("readystatechange"),4==Dd(a)){a.D=!1;try{var b=Ed(a),c,d;t:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:d=!0;break t;default:d=!1}if(!(c=d)){var e;if(e=0===b){var f=nd(1,String(a.Fa));if(!f&&self.location)var k=self.location.protocol,f=k.substr(0,k.length-1);e=!ud.test(f?f.toLowerCase():"")}c=e}if(c)a.dispatchEvent("complete"),a.dispatchEvent("success");
else{var l;try{l=2<Dd(a)?a.a.statusText:""}catch(N){l=""}a.ba=l+" ["+Ed(a)+"]";Ad(a)}}finally{Bd(a)}}},Bd=function(a,b){if(a.a){yd(a);var c=a.a,d=a.ca[0]?ba:null;a.a=null;a.ca=null;b||a.dispatchEvent("ready");try{c.onreadystatechange=d}catch(e){}}},yd=function(a){a.a&&a.Ga&&(a.a.ontimeout=null);ea(a.da)&&(h.clearTimeout(a.da),a.da=null)},Dd=function(a){return a.a?a.a.readyState:0},Ed=function(a){try{return 2<Dd(a)?a.a.status:-1}catch(b){return-1}};var Fd=function(a,b,c){this.r=a||null;this.oc=!!c},Hd=function(a){if(!a.c&&(a.c=new x,a.h=0,a.r))for(var b=a.r.split("&"),c=0;c<b.length;c++){var d=b[c].indexOf("="),e=null,f=null;0<=d?(e=b[c].substring(0,d),f=b[c].substring(d+1)):e=b[c];e=decodeURIComponent(e.replace(/\+/g," "));e=Gd(a,e);a.add(e,f?decodeURIComponent(f.replace(/\+/g," ")):"")}};g=Fd.prototype;g.c=null;g.h=null;g.add=function(a,b){Hd(this);this.r=null;a=Gd(this,a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.h++;return this};
g.remove=function(a){Hd(this);a=Gd(this,a);return this.c.Q(a)?(this.r=null,this.h-=this.c.get(a).length,this.c.remove(a)):!1};g.Q=function(a){Hd(this);a=Gd(this,a);return this.c.Q(a)};g.F=function(){Hd(this);for(var a=this.c.t(),b=this.c.F(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};g.t=function(a){Hd(this);var b=[];if(n(a))this.Q(a)&&(b=qa(b,this.c.get(Gd(this,a))));else{a=this.c.t();for(var c=0;c<a.length;c++)b=qa(b,a[c])}return b};
g.set=function(a,b){Hd(this);this.r=null;a=Gd(this,a);this.Q(a)&&(this.h-=this.c.get(a).length);this.c.set(a,[b]);this.h++;return this};g.get=function(a,b){var c=a?this.t(a):[];return 0<c.length?String(c[0]):b};g.toString=function(){if(this.r)return this.r;if(!this.c)return"";for(var a=[],b=this.c.F(),c=0;c<b.length;c++)for(var d=b[c],e=encodeURIComponent(String(d)),d=this.t(d),f=0;f<d.length;f++){var k=e;""!==d[f]&&(k+="="+encodeURIComponent(String(d[f])));a.push(k)}return this.r=a.join("&")};
g.clone=function(){var a=new Fd;a.r=this.r;this.c&&(a.c=this.c.clone(),a.h=this.h);return a};var Gd=function(a,b){var c=String(b);a.oc&&(c=c.toLowerCase());return c};var Id=function(a,b){this.$b=a;this.na=b};Id.prototype.send=function(a,b){if(gb&&!navigator.onLine)return pc();var c=new S,d=Jd(a,b);d.length>this.na?c.w({status:"payload-too-big",Ba:Ra("Encoded hit length == %s, but should be <= %s.",d.length,this.na)}):xd(this.$b,function(){c.G(hd)},d);return c};var Jd=function(a,b){var c=new Fd;c.add(Da.name,a);Ua(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var Kd=function(a,b,c){this.k=a;this.Qb=b;this.na=c};Kd.prototype.Sa=function(){if(!this.q){var a=this.k;if(!jc(a.ha).C)throw Error("Cannot construct shared channel prior to settings being ready.");new ad;var b=new cd(new Id(this.Qb,this.na)),c=new jd;this.q=new bd(a,new kd(a,new id(c,b)))}return this.q};var Ld=new x,Md=function(){if(!Ba){var a=new Tc("google-analytics");Ba=new X(a)}return Ba};t("goog.async.Deferred",S);t("goog.async.Deferred.prototype.addCallback",S.prototype.J);t("goog.events.EventTarget",Q);t("goog.events.EventTarget.prototype.listen",Q.prototype.listen);t("analytics.getService",function(a){var b=Ld.get(a,null);if(null===b){var b=chrome.runtime.getManifest().version,c=Md();if(!Ca){var d=Md();Ca=new Wc(d,new Kd(d,"https://www.google-analytics.com/collect",8192))}b=new Hc("ca1.5.2",a,b,c,Ca);Ld.set(a,b)}return b});t("analytics.internal.GoogleAnalyticsService",Hc);
t("analytics.internal.GoogleAnalyticsService.prototype.getTracker",Hc.prototype.Cc);t("analytics.internal.GoogleAnalyticsService.prototype.getConfig",Hc.prototype.Bc);t("analytics.internal.ServiceSettings",X);t("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",X.prototype.Lc);t("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",X.prototype.va);t("analytics.internal.ServiceSettings.prototype.setSampleRate",X.prototype.Kc);t("analytics.internal.ServiceTracker",W);
t("analytics.internal.ServiceTracker.prototype.send",W.prototype.send);t("analytics.internal.ServiceTracker.prototype.sendAppView",W.prototype.Gc);t("analytics.internal.ServiceTracker.prototype.sendEvent",W.prototype.Hc);t("analytics.internal.ServiceTracker.prototype.sendSocial",W.prototype.Jc);t("analytics.internal.ServiceTracker.prototype.sendException",W.prototype.Ic);t("analytics.internal.ServiceTracker.prototype.sendTiming",W.prototype.Cb);
t("analytics.internal.ServiceTracker.prototype.startTiming",W.prototype.Mc);t("analytics.internal.ServiceTracker.Timing",Gc);t("analytics.internal.ServiceTracker.Timing.prototype.send",Gc.prototype.send);t("analytics.internal.ServiceTracker.prototype.forceSessionStart",W.prototype.Ac);t("analytics.internal.ServiceTracker.prototype.addFilter",W.prototype.S);t("analytics.internal.FilterChannel.Hit",T);t("analytics.internal.FilterChannel.Hit.prototype.getHitType",T.prototype.Gb);
t("analytics.internal.FilterChannel.Hit.prototype.getParameters",T.prototype.T);t("analytics.internal.FilterChannel.Hit.prototype.cancel",T.prototype.cancel);t("analytics.ParameterMap",C);t("analytics.ParameterMap.Entry",C.Entry);t("analytics.ParameterMap.prototype.set",C.prototype.set);t("analytics.ParameterMap.prototype.get",C.prototype.get);t("analytics.ParameterMap.prototype.remove",C.prototype.remove);t("analytics.ParameterMap.prototype.toObject",C.prototype.Jb);
t("analytics.HitTypes.APPVIEW","appview");t("analytics.HitTypes.EVENT","event");t("analytics.HitTypes.SOCIAL","social");t("analytics.HitTypes.TRANSACTION","transaction");t("analytics.HitTypes.ITEM","item");t("analytics.HitTypes.TIMING","timing");t("analytics.HitTypes.EXCEPTION","exception");ua(Ka,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();t("analytics.Parameters."+b,a)});t("analytics.filters.EventLabelerBuilder",A);
t("analytics.filters.EventLabelerBuilder.prototype.appendToExistingLabel",A.prototype.wc);t("analytics.filters.EventLabelerBuilder.prototype.stripValue",A.prototype.Nc);t("analytics.filters.EventLabelerBuilder.prototype.powersOfTwo",A.prototype.Ec);t("analytics.filters.EventLabelerBuilder.prototype.rangeBounds",A.prototype.Fc);t("analytics.filters.EventLabelerBuilder.prototype.build",A.prototype.Ca);t("analytics.filters.FilterBuilder",z);t("analytics.filters.FilterBuilder.builder",Pa);
t("analytics.filters.FilterBuilder.prototype.when",z.prototype.when);t("analytics.filters.FilterBuilder.prototype.whenHitType",z.prototype.zb);t("analytics.filters.FilterBuilder.prototype.whenValue",z.prototype.Oc);t("analytics.filters.FilterBuilder.prototype.applyFilter",z.prototype.xb);t("analytics.filters.FilterBuilder.prototype.build",z.prototype.Ca);t("analytics.EventBuilder",D);t("analytics.EventBuilder.builder",function(){return Va});t("analytics.EventBuilder.prototype.category",D.prototype.xc);
t("analytics.EventBuilder.prototype.action",D.prototype.action);t("analytics.EventBuilder.prototype.label",D.prototype.label);t("analytics.EventBuilder.prototype.value",D.prototype.value);t("analytics.EventBuilder.prototype.dimension",D.prototype.yc);t("analytics.EventBuilder.prototype.metric",D.prototype.Dc);t("analytics.EventBuilder.prototype.send",D.prototype.send); })()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,934 @@
/**
* @author mrdoob / http://mrdoob.com/
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author julianwa / https://github.com/julianwa
*/
THREE.RenderableObject = function () {
this.id = 0;
this.object = null;
this.z = 0;
};
//
THREE.RenderableFace = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.v3 = new THREE.RenderableVertex();
this.normalModel = new THREE.Vector3();
this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
this.vertexNormalsLength = 0;
this.color = new THREE.Color();
this.material = null;
this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ];
this.z = 0;
};
//
THREE.RenderableVertex = function () {
this.position = new THREE.Vector3();
this.positionWorld = new THREE.Vector3();
this.positionScreen = new THREE.Vector4();
this.visible = true;
};
THREE.RenderableVertex.prototype.copy = function ( vertex ) {
this.positionWorld.copy( vertex.positionWorld );
this.positionScreen.copy( vertex.positionScreen );
};
//
THREE.RenderableLine = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.vertexColors = [ new THREE.Color(), new THREE.Color() ];
this.material = null;
this.z = 0;
};
//
THREE.RenderableSprite = function () {
this.id = 0;
this.object = null;
this.x = 0;
this.y = 0;
this.z = 0;
this.rotation = 0;
this.scale = new THREE.Vector2();
this.material = null;
};
//
THREE.Projector = function () {
var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
_face, _faceCount, _facePool = [], _facePoolLength = 0,
_line, _lineCount, _linePool = [], _linePoolLength = 0,
_sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0,
_renderData = { objects: [], lights: [], elements: [] },
_vA = new THREE.Vector3(),
_vB = new THREE.Vector3(),
_vC = new THREE.Vector3(),
_vector3 = new THREE.Vector3(),
_vector4 = new THREE.Vector4(),
_clipBox = new THREE.Box3( new THREE.Vector3( - 1, - 1, - 1 ), new THREE.Vector3( 1, 1, 1 ) ),
_boundingBox = new THREE.Box3(),
_points3 = new Array( 3 ),
_points4 = new Array( 4 ),
_viewMatrix = new THREE.Matrix4(),
_viewProjectionMatrix = new THREE.Matrix4(),
_modelMatrix,
_modelViewProjectionMatrix = new THREE.Matrix4(),
_normalMatrix = new THREE.Matrix3(),
_frustum = new THREE.Frustum(),
_clippedVertex1PositionScreen = new THREE.Vector4(),
_clippedVertex2PositionScreen = new THREE.Vector4();
//
this.projectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .projectVector() is now vector.project().' );
vector.project( camera );
};
this.unprojectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );
vector.unproject( camera );
};
this.pickingRay = function ( vector, camera ) {
console.error( 'THREE.Projector: .pickingRay() has been removed.' );
};
//
var RenderList = function () {
var normals = [];
var uvs = [];
var object = null;
var material = null;
var normalMatrix = new THREE.Matrix3();
var setObject = function ( value ) {
object = value;
material = object.material;
normalMatrix.getNormalMatrix( object.matrixWorld );
normals.length = 0;
uvs.length = 0;
};
var projectVertex = function ( vertex ) {
var position = vertex.position;
var positionWorld = vertex.positionWorld;
var positionScreen = vertex.positionScreen;
positionWorld.copy( position ).applyMatrix4( _modelMatrix );
positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix );
var invW = 1 / positionScreen.w;
positionScreen.x *= invW;
positionScreen.y *= invW;
positionScreen.z *= invW;
vertex.visible = positionScreen.x >= - 1 && positionScreen.x <= 1 &&
positionScreen.y >= - 1 && positionScreen.y <= 1 &&
positionScreen.z >= - 1 && positionScreen.z <= 1;
};
var pushVertex = function ( x, y, z ) {
_vertex = getNextVertexInPool();
_vertex.position.set( x, y, z );
projectVertex( _vertex );
};
var pushNormal = function ( x, y, z ) {
normals.push( x, y, z );
};
var pushUv = function ( x, y ) {
uvs.push( x, y );
};
var checkTriangleVisibility = function ( v1, v2, v3 ) {
if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true;
_points3[ 0 ] = v1.positionScreen;
_points3[ 1 ] = v2.positionScreen;
_points3[ 2 ] = v3.positionScreen;
return _clipBox.isIntersectionBox( _boundingBox.setFromPoints( _points3 ) );
};
var checkBackfaceCulling = function ( v1, v2, v3 ) {
return ( ( v3.positionScreen.x - v1.positionScreen.x ) *
( v2.positionScreen.y - v1.positionScreen.y ) -
( v3.positionScreen.y - v1.positionScreen.y ) *
( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
};
var pushLine = function ( a, b ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.copy( v1 );
_line.v2.copy( v2 );
_line.z = ( v1.positionScreen.z + v2.positionScreen.z ) / 2;
_line.material = object.material;
_renderData.elements.push( _line );
};
var pushTriangle = function ( a, b, c ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
var v3 = _vertexPool[ c ];
if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return;
if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) {
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
for ( var i = 0; i < 3; i ++ ) {
var offset = arguments[ i ] * 3;
var normal = _face.vertexNormalsModel[ i ];
normal.set( normals[ offset ], normals[ offset + 1 ], normals[ offset + 2 ] );
normal.applyMatrix3( normalMatrix ).normalize();
var offset2 = arguments[ i ] * 2;
var uv = _face.uvs[ i ];
uv.set( uvs[ offset2 ], uvs[ offset2 + 1 ] );
}
_face.vertexNormalsLength = 3;
_face.material = object.material;
_renderData.elements.push( _face );
}
};
return {
setObject: setObject,
projectVertex: projectVertex,
checkTriangleVisibility: checkTriangleVisibility,
checkBackfaceCulling: checkBackfaceCulling,
pushVertex: pushVertex,
pushNormal: pushNormal,
pushUv: pushUv,
pushLine: pushLine,
pushTriangle: pushTriangle
}
};
var renderList = new RenderList();
this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
_faceCount = 0;
_lineCount = 0;
_spriteCount = 0;
_renderData.elements.length = 0;
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
if ( camera.parent === undefined ) camera.updateMatrixWorld();
_viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );
_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
_frustum.setFromMatrix( _viewProjectionMatrix );
//
_objectCount = 0;
_renderData.objects.length = 0;
_renderData.lights.length = 0;
scene.traverseVisible( function ( object ) {
if ( object instanceof THREE.Light ) {
_renderData.lights.push( object );
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Sprite ) {
if ( object.material.visible === false ) return;
if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
_object = getNextObjectInPool();
_object.id = object.id;
_object.object = object;
if ( object.renderDepth !== null ) {
_object.z = object.renderDepth;
} else {
_vector3.setFromMatrixPosition( object.matrixWorld );
_vector3.applyProjection( _viewProjectionMatrix );
_object.z = _vector3.z;
}
_renderData.objects.push( _object );
}
}
} );
if ( sortObjects === true ) {
_renderData.objects.sort( painterSort );
}
//
for ( var o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
var object = _renderData.objects[ o ].object;
var geometry = object.geometry;
renderList.setObject( object );
_modelMatrix = object.matrixWorld;
_vertexCount = 0;
if ( object instanceof THREE.Mesh ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
var offsets = geometry.offsets;
if ( attributes.position === undefined ) continue;
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( attributes.normal !== undefined ) {
var normals = attributes.normal.array;
for ( var i = 0, l = normals.length; i < l; i += 3 ) {
renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] );
}
}
if ( attributes.uv !== undefined ) {
var uvs = attributes.uv.array;
for ( var i = 0, l = uvs.length; i < l; i += 2 ) {
renderList.pushUv( uvs[ i ], uvs[ i + 1 ] );
}
}
if ( attributes.index !== undefined ) {
var indices = attributes.index.array;
if ( offsets.length > 0 ) {
for ( var o = 0; o < offsets.length; o ++ ) {
var offset = offsets[ o ];
var index = offset.index;
for ( var i = offset.start, l = offset.start + offset.count; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ] + index, indices[ i + 1 ] + index, indices[ i + 2 ] + index );
}
}
} else {
for ( var i = 0, l = indices.length; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
}
}
} else {
for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
renderList.pushTriangle( i, i + 1, i + 2 );
}
}
} else if ( geometry instanceof THREE.Geometry ) {
var vertices = geometry.vertices;
var faces = geometry.faces;
var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
_normalMatrix.getNormalMatrix( _modelMatrix );
var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
var objectMaterials = isFaceMaterial === true ? object.material : null;
for ( var v = 0, vl = vertices.length; v < vl; v ++ ) {
var vertex = vertices[ v ];
renderList.pushVertex( vertex.x, vertex.y, vertex.z );
}
for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
var face = faces[ f ];
var material = isFaceMaterial === true
? objectMaterials.materials[ face.materialIndex ]
: object.material;
if ( material === undefined ) continue;
var side = material.side;
var v1 = _vertexPool[ face.a ];
var v2 = _vertexPool[ face.b ];
var v3 = _vertexPool[ face.c ];
if ( material.morphTargets === true ) {
var morphTargets = geometry.morphTargets;
var morphInfluences = object.morphTargetInfluences;
var v1p = v1.position;
var v2p = v2.position;
var v3p = v3.position;
_vA.set( 0, 0, 0 );
_vB.set( 0, 0, 0 );
_vC.set( 0, 0, 0 );
for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
var influence = morphInfluences[ t ];
if ( influence === 0 ) continue;
var targets = morphTargets[ t ].vertices;
_vA.x += ( targets[ face.a ].x - v1p.x ) * influence;
_vA.y += ( targets[ face.a ].y - v1p.y ) * influence;
_vA.z += ( targets[ face.a ].z - v1p.z ) * influence;
_vB.x += ( targets[ face.b ].x - v2p.x ) * influence;
_vB.y += ( targets[ face.b ].y - v2p.y ) * influence;
_vB.z += ( targets[ face.b ].z - v2p.z ) * influence;
_vC.x += ( targets[ face.c ].x - v3p.x ) * influence;
_vC.y += ( targets[ face.c ].y - v3p.y ) * influence;
_vC.z += ( targets[ face.c ].z - v3p.z ) * influence;
}
v1.position.add( _vA );
v2.position.add( _vB );
v3.position.add( _vC );
renderList.projectVertex( v1 );
renderList.projectVertex( v2 );
renderList.projectVertex( v3 );
}
if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue;
var visible = renderList.checkBackfaceCulling( v1, v2, v3 );
if ( side !== THREE.DoubleSide ) {
if ( side === THREE.FrontSide && visible === false ) continue;
if ( side === THREE.BackSide && visible === true ) continue;
}
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.normalModel.copy( face.normal );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
_face.normalModel.negate();
}
_face.normalModel.applyMatrix3( _normalMatrix ).normalize();
var faceVertexNormals = face.vertexNormals;
for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) {
var normalModel = _face.vertexNormalsModel[ n ];
normalModel.copy( faceVertexNormals[ n ] );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
normalModel.negate();
}
normalModel.applyMatrix3( _normalMatrix ).normalize();
}
_face.vertexNormalsLength = faceVertexNormals.length;
var vertexUvs = faceVertexUvs[ f ];
if ( vertexUvs !== undefined ) {
for ( var u = 0; u < 3; u ++ ) {
_face.uvs[ u ].copy( vertexUvs[ u ] );
}
}
_face.color = face.color;
_face.material = material;
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
_renderData.elements.push( _face );
}
}
} else if ( object instanceof THREE.Line ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
if ( attributes.position !== undefined ) {
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( attributes.index !== undefined ) {
var indices = attributes.index.array;
for ( var i = 0, l = indices.length; i < l; i += 2 ) {
renderList.pushLine( indices[ i ], indices[ i + 1 ] );
}
} else {
var step = object.mode === THREE.LinePieces ? 2 : 1;
for ( var i = 0, l = ( positions.length / 3 ) - 1; i < l; i += step ) {
renderList.pushLine( i, i + 1 );
}
}
}
} else if ( geometry instanceof THREE.Geometry ) {
_modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix );
var vertices = object.geometry.vertices;
if ( vertices.length === 0 ) continue;
v1 = getNextVertexInPool();
v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix );
// Handle LineStrip and LinePieces
var step = object.mode === THREE.LinePieces ? 2 : 1;
for ( var v = 1, vl = vertices.length; v < vl; v ++ ) {
v1 = getNextVertexInPool();
v1.positionScreen.copy( vertices[ v ] ).applyMatrix4( _modelViewProjectionMatrix );
if ( ( v + 1 ) % step > 0 ) continue;
v2 = _vertexPool[ _vertexCount - 2 ];
_clippedVertex1PositionScreen.copy( v1.positionScreen );
_clippedVertex2PositionScreen.copy( v2.positionScreen );
if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
// Perform the perspective divide
_clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
_clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
_line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
_line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
_line.material = object.material;
if ( object.material.vertexColors === THREE.VertexColors ) {
_line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] );
_line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] );
}
_renderData.elements.push( _line );
}
}
}
} else if ( object instanceof THREE.Sprite ) {
_vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 );
_vector4.applyMatrix4( _viewProjectionMatrix );
var invW = 1 / _vector4.w;
_vector4.z *= invW;
if ( _vector4.z >= - 1 && _vector4.z <= 1 ) {
_sprite = getNextSpriteInPool();
_sprite.id = object.id;
_sprite.x = _vector4.x * invW;
_sprite.y = _vector4.y * invW;
_sprite.z = _vector4.z;
_sprite.object = object;
_sprite.rotation = object.rotation;
_sprite.scale.x = object.scale.x * Math.abs( _sprite.x - ( _vector4.x + camera.projectionMatrix.elements[ 0 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 12 ] ) );
_sprite.scale.y = object.scale.y * Math.abs( _sprite.y - ( _vector4.y + camera.projectionMatrix.elements[ 5 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 13 ] ) );
_sprite.material = object.material;
_renderData.elements.push( _sprite );
}
}
}
if ( sortElements === true ) {
_renderData.elements.sort( painterSort );
}
return _renderData;
};
// Pools
function getNextObjectInPool() {
if ( _objectCount === _objectPoolLength ) {
var object = new THREE.RenderableObject();
_objectPool.push( object );
_objectPoolLength ++;
_objectCount ++;
return object;
}
return _objectPool[ _objectCount ++ ];
}
function getNextVertexInPool() {
if ( _vertexCount === _vertexPoolLength ) {
var vertex = new THREE.RenderableVertex();
_vertexPool.push( vertex );
_vertexPoolLength ++;
_vertexCount ++;
return vertex;
}
return _vertexPool[ _vertexCount ++ ];
}
function getNextFaceInPool() {
if ( _faceCount === _facePoolLength ) {
var face = new THREE.RenderableFace();
_facePool.push( face );
_facePoolLength ++;
_faceCount ++;
return face;
}
return _facePool[ _faceCount ++ ];
}
function getNextLineInPool() {
if ( _lineCount === _linePoolLength ) {
var line = new THREE.RenderableLine();
_linePool.push( line );
_linePoolLength ++;
_lineCount ++
return line;
}
return _linePool[ _lineCount ++ ];
}
function getNextSpriteInPool() {
if ( _spriteCount === _spritePoolLength ) {
var sprite = new THREE.RenderableSprite();
_spritePool.push( sprite );
_spritePoolLength ++;
_spriteCount ++
return sprite;
}
return _spritePool[ _spriteCount ++ ];
}
//
function painterSort( a, b ) {
if ( a.z !== b.z ) {
return b.z - a.z;
} else if ( a.id !== b.id ) {
return a.id - b.id;
} else {
return 0;
}
}
function clipLine( s1, s2 ) {
var alpha1 = 0, alpha2 = 1,
// Calculate the boundary coordinate of each vertex for the near and far clip planes,
// Z = -1 and Z = +1, respectively.
bc1near = s1.z + s1.w,
bc2near = s2.z + s2.w,
bc1far = - s1.z + s1.w,
bc2far = - s2.z + s2.w;
if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
// Both vertices lie entirely within all clip planes.
return true;
} else if ( ( bc1near < 0 && bc2near < 0 ) || ( bc1far < 0 && bc2far < 0 ) ) {
// Both vertices lie entirely outside one of the clip planes.
return false;
} else {
// The line segment spans at least one clip plane.
if ( bc1near < 0 ) {
// v1 lies outside the near plane, v2 inside
alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
} else if ( bc2near < 0 ) {
// v2 lies outside the near plane, v1 inside
alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
}
if ( bc1far < 0 ) {
// v1 lies outside the far plane, v2 inside
alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
} else if ( bc2far < 0 ) {
// v2 lies outside the far plane, v2 inside
alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
}
if ( alpha2 < alpha1 ) {
// The line segment spans two boundaries, but is outside both of them.
// (This can't happen when we're only clipping against just near/far but good
// to leave the check here for future usage if other clip planes are added.)
return false;
} else {
// Update the s1 and s2 vertices to match the clipped line segment.
s1.lerp( s2, alpha1 );
s2.lerp( s1, 1 - alpha2 );
return true;
}
}
}
};

814
js/libraries/three/three.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1130
js/msp.js

File diff suppressed because it is too large Load diff

View file

@ -111,7 +111,7 @@ PortHandler.check = function () {
if (GUI.active_tab != 'firmware_flasher') {
GUI.timeout_add('auto-connect_timeout', function () {
$('div#port-picker a.connect').click();
}, 50); // small timeout so we won't get any nasty connect errors due to system initializing the bus
}, 100); // timeout so bus have time to initialize after being detected by the system
}
}

View file

@ -13,11 +13,11 @@ var PortUsage = {
},
update: function() {
if (serial.bitrate) {
var port_usage_down = parseInt(((serial.bytes_received - this.previous_received) * 10 / serial.bitrate) * 100);
var port_usage_up = parseInt(((serial.bytes_sent - this.previous_sent) * 10 / serial.bitrate) * 100);
var port_usage_down = parseInt(((serial.bytesReceived - this.previous_received) * 10 / serial.bitrate) * 100);
var port_usage_up = parseInt(((serial.bytesSent - this.previous_sent) * 10 / serial.bitrate) * 100);
this.previous_received = serial.bytes_received;
this.previous_sent = serial.bytes_sent;
this.previous_received = serial.bytesReceived;
this.previous_sent = serial.bytesSent;
// update UI
$('span.port_usage_down').text(chrome.i18n.getMessage('statusbar_usage_download', [port_usage_down]));

View file

@ -8,7 +8,9 @@
'use strict';
var STM32_protocol = function () {
this.baud;
this.options = {};
this.callback; // ref
this.hex; // ref
this.verify_hex;
@ -47,15 +49,18 @@ var STM32_protocol = function () {
};
// no input parameters
STM32_protocol.prototype.connect = function (port, baud, hex, options) {
STM32_protocol.prototype.connect = function (port, baud, hex, options, callback) {
var self = this;
self.hex = hex;
self.baud = baud;
self.callback = callback;
// we will crunch the options here since doing it inside initialization routine would be too late / redundant
// we will crunch the options here since doing it inside initialization routine would be too late
self.options = {
no_reboot: false,
reboot_baud: false,
erase_chip: false
erase_chip: false,
flash_slowly: false
};
if (options.no_reboot) {
@ -68,8 +73,13 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) {
self.options.erase_chip = true;
}
if (options.flash_slowly) {
self.options.flash_slowly = true;
self.baud = 115200;
}
if (self.options.no_reboot) {
serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
// we are connected, disabling connect button in the UI
GUI.connect_lock = true;
@ -95,10 +105,11 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options) {
serial.send(bufferOut, function () {
serial.disconnect(function (result) {
if (result) {
serial.connect(port, {bitrate: baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
self.initialize();
} else {
GUI.connect_lock = false;
GUI.log('<span style="color: red">Failed</span> to open serial port');
}
});
@ -122,7 +133,7 @@ STM32_protocol.prototype.initialize = function () {
self.receive_buffer = [];
self.verify_hex = [];
self.upload_time_start = microtime();
self.upload_time_start = new Date().getTime();
self.upload_process_alive = false;
// reset progress bar to initial state
@ -130,6 +141,9 @@ STM32_protocol.prototype.initialize = function () {
self.progress_bar_e.val(0);
self.progress_bar_e.removeClass('valid invalid');
// lock some UI elements TODO needs rework
$('select[name="release"]').prop('disabled', true);
serial.onReceive.addListener(function (info) {
self.read(info);
});
@ -139,7 +153,10 @@ STM32_protocol.prototype.initialize = function () {
self.upload_process_alive = false;
} else {
console.log('STM32 - timed out, programming failed ...');
GUI.log('STM32 - timed out, programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('STM32 - timed out, programming: FAILED');
self.progress_bar_e.addClass('invalid');
googleAnalytics.sendEvent('Flashing', 'Programming', 'timeout');
// protocol got stuck, clear timer and disconnect
@ -218,8 +235,9 @@ STM32_protocol.prototype.send = function (Array, bytes_to_read, callback) {
// result = true/false
STM32_protocol.prototype.verify_response = function (val, data) {
if (val != data[0]) {
console.log('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
GUI.log('STM32 Communication <span style="color: red">failed</span>, wrong response, expected: ' + val + ' received: ' + data[0]);
console.error('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
$('span.progressLabel').text('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
self.progress_bar_e.addClass('invalid');
// disconnect
this.upload_procedure(99);
@ -327,7 +345,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
switch (step) {
case 1:
// initialize serial interface on the MCU side, auto baud rate settings
GUI.log('Contacting bootloader ...');
$('span.progressLabel').text('Contacting bootloader ...');
var send_counter = 0;
GUI.interval_add('stm32_initialize_mcu', function () { // 200 ms interval (just in case mcu was already initialized), we need to break the 2 bytes command requirement
@ -339,8 +357,10 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// proceed to next step
self.upload_procedure(2);
} else {
$('span.progressLabel').text('Communication with bootloader failed');
self.progress_bar_e.addClass('invalid');
GUI.interval_remove('stm32_initialize_mcu');
GUI.log('Communication with bootloader <span style="color: red">failed</span>');
// disconnect
self.upload_procedure(99);
@ -350,7 +370,10 @@ STM32_protocol.prototype.upload_procedure = function (step) {
if (send_counter++ > 3) {
// stop retrying, its too late to get any response from MCU
console.log('STM32 - no response from bootloader, disconnecting');
GUI.log('No reponse from the bootloader, programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('No response from the bootloader, programming: FAILED');
self.progress_bar_e.addClass('invalid');
GUI.interval_remove('stm32_initialize_mcu');
GUI.interval_remove('STM32_timeout');
@ -393,7 +416,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
break;
case 4:
// erase memory
GUI.log('Erasing ...');
$('span.progressLabel').text('Erasing ...');
if (self.options.erase_chip) {
console.log('Executing global chip erase');
@ -415,16 +438,18 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send([self.command.erase, 0xBC], 1, function (reply) { // 0x43 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
// the bootloader receives one byte that contains N, the number of pages to be erased 1
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000;
var erase_pages_n = Math.ceil(max_address / self.page_size);
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
erase_pages_n = Math.ceil(max_address / self.page_size),
buff = [],
checksum = erase_pages_n - 1;
var buff = [];
buff.push(erase_pages_n - 1);
var checksum = buff[0];
for (var i = 0; i < erase_pages_n; i++) {
buff.push(i);
checksum ^= i;
}
buff.push(checksum);
self.send(buff, 1, function (reply) {
@ -441,14 +466,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
case 5:
// upload
console.log('Writing data ...');
GUI.log('Flashing ...');
$('span.progressLabel').text('Flashing ...');
var blocks = self.hex.data.length - 1;
var flashing_block = 0;
var address = self.hex.data[flashing_block].address;
var bytes_flashed = 0;
var bytes_flashed_total = 0; // used for progress bar
var blocks = self.hex.data.length - 1,
flashing_block = 0,
address = self.hex.data[flashing_block].address,
bytes_flashed = 0,
bytes_flashed_total = 0; // used for progress bar
var write = function () {
if (bytes_flashed < self.hex.data[flashing_block].bytes) {
@ -481,13 +505,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send(array_out, 1, function (reply) {
if (self.verify_response(self.status.ACK, reply)) {
// update progress bar
self.progress_bar_e.val(bytes_flashed_total / (self.hex.bytes_total * 2) * 100);
// flash another page
write();
}
});
// update progress bar
self.progress_bar_e.val(Math.round(bytes_flashed_total / (self.hex.bytes_total * 2) * 100));
}
});
}
@ -517,14 +541,13 @@ STM32_protocol.prototype.upload_procedure = function (step) {
case 6:
// verify
console.log('Verifying data ...');
GUI.log('Verifying ...');
$('span.progressLabel').text('Verifying ...');
var blocks = self.hex.data.length - 1;
var reading_block = 0;
var address = self.hex.data[reading_block].address;
var bytes_verified = 0;
var bytes_verified_total = 0; // used for progress bar
var blocks = self.hex.data.length - 1,
reading_block = 0,
address = self.hex.data[reading_block].address,
bytes_verified = 0,
bytes_verified_total = 0; // used for progress bar
// initialize arrays
for (var i = 0; i <= blocks; i++) {
@ -557,14 +580,14 @@ STM32_protocol.prototype.upload_procedure = function (step) {
bytes_verified += bytes_to_read;
bytes_verified_total += bytes_to_read;
// update progress bar
self.progress_bar_e.val((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100);
// verify another page
reading();
});
}
});
// update progress bar
self.progress_bar_e.val(Math.round((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100));
}
});
}
@ -590,7 +613,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
if (verify) {
console.log('Programming: SUCCESSFUL');
GUI.log('Programming: <strong style="color: green">SUCCESSFUL</strong>');
$('span.progressLabel').text('Programming: SUCCESSFUL');
googleAnalytics.sendEvent('Flashing', 'Programming', 'success');
// update progress bar
@ -600,7 +623,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.upload_procedure(7);
} else {
console.log('Programming: FAILED');
GUI.log('Programming: <strong style="color: red">FAILED</strong>');
$('span.progressLabel').text('Programming: FAILED');
googleAnalytics.sendEvent('Flashing', 'Programming', 'fail');
// update progress bar
@ -623,9 +646,9 @@ STM32_protocol.prototype.upload_procedure = function (step) {
self.send([self.command.go, 0xDE], 1, function (reply) { // 0x21 ^ 0xFF
if (self.verify_response(self.status.ACK, reply)) {
var gt_address = 0x8000000;
var address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address];
var address_checksum = address[0] ^ address[1] ^ address[2] ^ address[3];
var gt_address = 0x8000000,
address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address],
address_checksum = address[0] ^ address[1] ^ address[2] ^ address[3];
self.send([address[0], address[1], address[2], address[3], address_checksum], 1, function (reply) {
if (self.verify_response(self.status.ACK, reply)) {
@ -640,18 +663,22 @@ STM32_protocol.prototype.upload_procedure = function (step) {
// disconnect
GUI.interval_remove('STM32_timeout'); // stop STM32 timeout timer (everything is finished now)
console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
// close connection
serial.disconnect(function (result) {
if (result) { // All went as expected
} else { // Something went wrong
}
PortUsage.reset();
// unlocking connect button
GUI.connect_lock = false;
// unlock some UI elements TODO needs rework
$('select[name="release"]').prop('disabled', false);
// handle timing
var timeSpent = new Date().getTime() - self.upload_time_start;
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');
if (self.callback) self.callback();
});
break;
}

View file

@ -13,6 +13,7 @@
'use strict';
var STM32DFU_protocol = function () {
this.callback; // ref
this.hex; // ref
this.verify_hex;
@ -62,12 +63,13 @@ var STM32DFU_protocol = function () {
};
};
STM32DFU_protocol.prototype.connect = function (device, hex) {
STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
var self = this;
self.hex = hex;
self.callback = callback;
// reset and set some variables before we start
self.upload_time_start = microtime();
self.upload_time_start = new Date().getTime();
self.verify_hex = [];
// reset progress bar to initial state
@ -466,9 +468,13 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
break;
case 99:
// cleanup
console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
self.releaseInterface(0);
var timeSpent = new Date().getTime() - self.upload_time_start;
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');
if (self.callback) self.callback();
break;
}
};

143
js/review.js Normal file
View file

@ -0,0 +1,143 @@
'use strict';
$(document).ready(function () {
function Dialog(identifier, content, handler) {
var self = this;
this.block = $('<div />').css({
'position': 'fixed',
'top': 0,
'left': 0,
'width': '100%',
'height': '100%',
'background-color': 'rgba(0, 0, 0, 0.25)',
'z-index': 1000
});
$('body').append(this.block);
this.element = $('<div />').prop('id', 'dialog').addClass(identifier).load(content, function () {
// position the dialog
self.element.css({
'top': window.innerHeight / 3,
'left': (window.innerWidth - self.element.width()) / 2
});
// display content
self.element.fadeIn(100);
if (handler) handler(self);
});
$('body').append(this.element);
// handle window resize
var resizeHandler = function () {
self.element.css({
'top': window.innerHeight / 3,
'left': (window.innerWidth - self.element.width()) / 2
});
};
$(window).on('resize', resizeHandler);
// handle confirm/dismiss keys
var keyDownHandler = function (e) {
if (e.which == 13) {
// Enter
self.element.find('.yes').click();
} else if (e.which == 27) {
// ESC
self.element.find('.no').click();
}
};
$(document).on('keydown', keyDownHandler);
// cleanup routine
this.cleanup = function () {
$(window).off('resize', resizeHandler);
$(document).off('keydown', keyDownHandler);
self.element.empty().remove();
self.block.remove();
};
return this;
}
chrome.storage.sync.get('appReview', function (result) {
if (typeof result.appReview !== 'undefined') {
var data = result.appReview;
if (data.launched < 10) {
data.launched += 1;
chrome.storage.sync.set({'appReview': data});
return;
}
if ((data.firstStart + 604800000) < new Date().getTime()) {
if ((data.refused == 0 || (data.refused + 604800000) < new Date().getTime()) && !data.reviewed) { // needs verifying
var dialog = new Dialog('review', './tabs/review.html', function () {
localize();
$('.initial', dialog.element).show();
var stage = 0;
$(dialog.element).on('click', '.yes, .no', function () {
if (!stage) {
$('p', dialog.element).hide();
if ($(this).hasClass('yes')) {
$('.storeReview', dialog.element).show();
stage = 1;
googleAnalytics.sendEvent('Review', 'Likes App', true);
} else {
$('.bugTicket', dialog.element).show();
stage = 2
googleAnalytics.sendEvent('Review', 'Likes App', false);
}
return false;
}
if (stage == 1) {
if ($(this).hasClass('yes')) {
window.open('https://chrome.google.com/webstore/detail/baseflight-configurator/mppkgnedeapfejgfimkdoninnofofigk/reviews');
data.reviewed = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Submits Review', true);
} else {
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Refused', true);
}
}
if (stage == 2) {
if ($(this).hasClass('yes')) {
window.open('https://chrome.google.com/webstore/detail/baseflight-configurator/mppkgnedeapfejgfimkdoninnofofigk/support');
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Submits Bug Ticket', true);
} else {
data.refused = new Date().getTime();
googleAnalytics.sendEvent('Review', 'Refused', true);
}
}
chrome.storage.sync.set({'appReview': data});
dialog.cleanup();
});
});
}
}
} else {
// object not in storage, initial setup
chrome.storage.sync.set({'appReview': {
'firstStart': new Date().getTime(),
'launched': 1,
'reviewed': 0,
'refused': 0
}});
}
});
});

View file

@ -1,26 +1,36 @@
'use strict';
var serial = {
connectionId: -1,
bitrate: 0,
bytes_received: 0,
bytes_sent: 0,
connectionId: false,
openRequested: false,
openCanceled: false,
bitrate: 0,
bytesReceived: 0,
bytesSent: 0,
failed: 0,
transmitting: false,
output_buffer: [],
outputBuffer: [],
connect: function(path, options, callback) {
connect: function (path, options, callback) {
var self = this;
self.openRequested = true;
chrome.serial.connect(path, options, function(connectionInfo) {
if (connectionInfo) {
chrome.serial.connect(path, options, function (connectionInfo) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
if (connectionInfo && !self.openCanceled) {
self.connectionId = connectionInfo.connectionId;
self.bitrate = connectionInfo.bitrate;
self.bytes_received = 0;
self.bytes_sent = 0;
self.bytesReceived = 0;
self.bytesSent = 0;
self.failed = 0;
self.openRequested = false;
self.onReceive.addListener(function log_bytes_received(info) {
self.bytes_received += info.data.byteLength;
self.onReceive.addListener(function log_bytesReceived(info) {
self.bytesReceived += info.data.byteLength;
});
self.onReceiveError.addListener(function watch_for_on_receive_errors(info) {
@ -29,26 +39,34 @@ var serial = {
switch (info.error) {
case 'system_error': // we might be able to recover from this one
var crunch_status = function (info) {
if (!info.paused) {
console.log('SERIAL: Connection recovered from last onReceiveError');
googleAnalytics.sendException('Serial: onReceiveError - recovered', false);
} else {
console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting');
GUI.log('Unrecoverable <span style="color: red">failure</span> of serial connection, disconnecting...');
googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false);
if (!self.failed++) {
chrome.serial.setPaused(self.connectionId, false, function () {
self.getInfo(function (info) {
if (info) {
if (!info.paused) {
console.log('SERIAL: Connection recovered from last onReceiveError');
googleAnalytics.sendException('Serial: onReceiveError - recovered', false);
if (GUI.connected_to || GUI.connecting_to) {
$('a.connect').click();
} else {
self.disconnect();
}
}
self.failed = 0;
} else {
console.log('SERIAL: Connection did not recover from last onReceiveError, disconnecting');
GUI.log('Unrecoverable <span style="color: red">failure</span> of serial connection, disconnecting...');
googleAnalytics.sendException('Serial: onReceiveError - unrecoverable', false);
if (GUI.connected_to || GUI.connecting_to) {
$('a.connect').click();
} else {
self.disconnect();
}
}
} else {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
}
});
});
}
chrome.serial.setPaused(self.connectionId, false, function () {
self.getInfo(crunch_status);
});
break;
case 'timeout':
// TODO
@ -65,105 +83,144 @@ var serial = {
console.log('SERIAL: Connection opened with ID: ' + connectionInfo.connectionId + ', Baud: ' + connectionInfo.bitrate);
if (callback) callback(connectionInfo);
} else if (connectionInfo && self.openCanceled) {
// connection opened, but this connect sequence was canceled
// we will disconnect without triggering any callbacks
self.connectionId = connectionInfo.connectionId;
console.log('SERIAL: Connection opened with ID: ' + connectionInfo.connectionId + ', but request was canceled, disconnecting');
// some bluetooth dongles/dongle drivers really doesn't like to be closed instantly, adding a small delay
setTimeout(function initialization() {
self.openRequested = false;
self.openCanceled = false;
self.disconnect(function resetUI() {
if (callback) callback(false);
});
}, 150);
} else if (self.openCanceled) {
// connection didn't open and sequence was canceled, so we will do nothing
console.log('SERIAL: Connection didn\'t open and request was canceled');
self.openRequested = false;
self.openCanceled = false;
if (callback) callback(false);
} else {
self.openRequested = false;
console.log('SERIAL: Failed to open serial port');
googleAnalytics.sendException('Serial: FailedToOpen', false);
if (callback) callback(false);
}
});
},
disconnect: function(callback) {
disconnect: function (callback) {
var self = this;
self.empty_output_buffer();
if (self.connectionId) {
self.emptyOutputBuffer();
// remove listeners
for (var i = (self.onReceive.listeners.length - 1); i >= 0; i--) {
self.onReceive.removeListener(self.onReceive.listeners[i]);
}
for (var i = (self.onReceiveError.listeners.length - 1); i >= 0; i--) {
self.onReceiveError.removeListener(self.onReceiveError.listeners[i]);
}
chrome.serial.disconnect(this.connectionId, function(result) {
if (result) {
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed');
} else {
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed');
googleAnalytics.sendException('Serial: FailedToClose', false);
// remove listeners
for (var i = (self.onReceive.listeners.length - 1); i >= 0; i--) {
self.onReceive.removeListener(self.onReceive.listeners[i]);
}
console.log('SERIAL: Statistics - Sent: ' + self.bytes_sent + ' bytes, Received: ' + self.bytes_received + ' bytes');
for (var i = (self.onReceiveError.listeners.length - 1); i >= 0; i--) {
self.onReceiveError.removeListener(self.onReceiveError.listeners[i]);
}
self.connectionId = -1;
self.bitrate = 0;
chrome.serial.disconnect(this.connectionId, function (result) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
if (callback) callback(result);
});
if (result) {
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
} else {
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
googleAnalytics.sendException('Serial: FailedToClose', false);
}
self.connectionId = false;
self.bitrate = 0;
if (callback) callback(result);
});
} else {
// connection wasn't opened, so we won't try to close anything
// instead we will rise canceled flag which will prevent connect from continueing further after being canceled
self.openCanceled = true;
}
},
getDevices: function(callback) {
chrome.serial.getDevices(function(devices_array) {
getDevices: function (callback) {
chrome.serial.getDevices(function (devices_array) {
var devices = [];
devices_array.forEach(function(device) {
devices_array.forEach(function (device) {
devices.push(device.path);
});
callback(devices);
});
},
getInfo: function(callback) {
getInfo: function (callback) {
chrome.serial.getInfo(this.connectionId, callback);
},
getControlSignals: function(callback) {
getControlSignals: function (callback) {
chrome.serial.getControlSignals(this.connectionId, callback);
},
setControlSignals: function(signals, callback) {
setControlSignals: function (signals, callback) {
chrome.serial.setControlSignals(this.connectionId, signals, callback);
},
send: function(data, callback) {
send: function (data, callback) {
var self = this;
self.output_buffer.push({'data': data, 'callback': callback});
this.outputBuffer.push({'data': data, 'callback': callback});
if (!self.transmitting) {
self.transmitting = true;
function send() {
// store inside separate variables in case array gets destroyed
var data = self.outputBuffer[0].data,
callback = self.outputBuffer[0].callback;
var sending = function () {
// store inside separate variables in case array gets destroyed
var data = self.output_buffer[0].data;
var callback = self.output_buffer[0].callback;
chrome.serial.send(self.connectionId, data, function (sendInfo) {
// track sent bytes for statistics
self.bytesSent += sendInfo.bytesSent;
chrome.serial.send(self.connectionId, data, function(sendInfo) {
callback(sendInfo);
self.output_buffer.shift();
// fire callback
if (callback) callback(sendInfo);
self.bytes_sent += sendInfo.bytesSent;
// remove data for current transmission form the buffer
self.outputBuffer.shift();
if (self.output_buffer.length) {
// keep the buffer withing reasonable limits
while (self.output_buffer.length > 500) {
self.output_buffer.pop();
// if there is any data in the queue fire send immediately, otherwise stop trasmitting
if (self.outputBuffer.length) {
// keep the buffer withing reasonable limits
if (self.outputBuffer.length > 100) {
var counter = 0;
while (self.outputBuffer.length > 100) {
self.outputBuffer.pop();
counter++;
}
sending();
} else {
self.transmitting = false;
console.log('SERIAL: Send buffer overflowing, dropped: ' + counter + ' entries');
}
});
};
sending();
send();
} else {
self.transmitting = false;
}
});
}
if (!this.transmitting) {
this.transmitting = true;
send();
}
},
onReceive: {
listeners: [],
addListener: function(function_reference) {
var listener = chrome.serial.onReceive.addListener(function_reference);
addListener: function (function_reference) {
chrome.serial.onReceive.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function(function_reference) {
removeListener: function (function_reference) {
for (var i = (this.listeners.length - 1); i >= 0; i--) {
if (this.listeners[i] == function_reference) {
chrome.serial.onReceive.removeListener(function_reference);
@ -177,12 +234,11 @@ var serial = {
onReceiveError: {
listeners: [],
addListener: function(function_reference) {
var listener = chrome.serial.onReceiveError.addListener(function_reference);
addListener: function (function_reference) {
chrome.serial.onReceiveError.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function(function_reference) {
removeListener: function (function_reference) {
for (var i = (this.listeners.length - 1); i >= 0; i--) {
if (this.listeners[i] == function_reference) {
chrome.serial.onReceiveError.removeListener(function_reference);
@ -193,8 +249,8 @@ var serial = {
}
}
},
empty_output_buffer: function() {
this.output_buffer = [];
emptyOutputBuffer: function () {
this.outputBuffer = [];
this.transmitting = false;
}
};

View file

@ -3,10 +3,9 @@
$(document).ready(function () {
$('div#port-picker a.connect').click(function () {
if (GUI.connect_lock != true) { // GUI control overrides the user control
var clicks = $(this).data('clicks');
var selected_port = String($('div#port-picker #port').val());
var selected_baud = parseInt($('div#port-picker #baud').val());
var clicks = $(this).data('clicks'),
selected_port = String($('div#port-picker #port').val()),
selected_baud = parseInt($('div#port-picker #baud').val());
if (selected_port != '0' && selected_port != 'DFU') {
if (!clicks) {
@ -27,31 +26,33 @@ $(document).ready(function () {
serial.disconnect(onClosed);
GUI.connected_to = false;
CONFIGURATOR.connectionValid = false;
MSP.disconnect_cleanup();
PortUsage.reset();
// Reset various UI elements
$('span.i2c-error').text(0);
$('span.cycle-time').text(0);
MSP.disconnect_cleanup();
PortUsage.reset();
CONFIGURATOR.connectionValid = false;
CONFIGURATOR.mspPassThrough = false;
// unlock port select & baud
$('div#port-picker #port').prop('disabled', false);
if (!GUI.auto_connect) $('div#port-picker #baud').prop('disabled', false);
// reset connect / disconnect button
$(this).text(chrome.i18n.getMessage('connect'));
$(this).removeClass('active');
sensor_status(0); // reset active sensor indicators
$('#tabs > ul li').removeClass('active'); // de-select any selected tabs
// reset active sensor indicators
sensor_status(0);
// de-select any selected tabs
$('#tabs > ul li').removeClass('active');
// detach listeners and remove element data
$('#content').empty();
// load default html
TABS.default.initialize();
TABS.landing.initialize();
}
$(this).data("clicks", !clicks);
@ -125,44 +126,43 @@ function onOpen(openInfo) {
serial.onReceive.addListener(read_serial);
if (!CONFIGURATOR.mspPassThrough) {
// disconnect after 10 seconds with error if we don't get IDENT data
GUI.timeout_add('connecting', function () {
if (!CONFIGURATOR.connectionValid) {
GUI.log(chrome.i18n.getMessage('noConfigurationReceived'));
// disconnect after 10 seconds with error if we don't get IDENT data
GUI.timeout_add('connecting', function () {
if (!CONFIGURATOR.connectionValid) {
GUI.log(chrome.i18n.getMessage('noConfigurationReceived'));
$('div#port-picker a.connect').click(); // disconnect
}
}, 10000);
$('div#port-picker a.connect').click(); // disconnect
}
}, 10000);
MSP.send_message(MSP_codes.MSP_API_VERSION, false, false, function () {
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
});
// request configuration data
MSP.send_message(MSP_codes.MSP_UID, false, false, function () {
GUI.log(chrome.i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)]));
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
GUI.timeout_remove('connecting'); // kill connecting timer
MSP.send_message(MSP_codes.MSP_API_VERSION, false, false, function () {
GUI.log(chrome.i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
});
GUI.log(chrome.i18n.getMessage('firmwareVersion', [CONFIG.version]));
// request configuration data
MSP.send_message(MSP_codes.MSP_UID, false, false, function () {
GUI.timeout_remove('connecting'); // kill connecting timer
if (CONFIG.version >= CONFIGURATOR.firmwareVersionAccepted) {
GUI.log(chrome.i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)]));
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
if (CONFIG.version >= CONFIGURATOR.firmwareVersionAccepted) {
MSP.send_message(MSP_codes.MSP_BUILDINFO, false, false, function () {
googleAnalytics.sendEvent('Firmware', 'Using', CONFIG.buildInfo);
GUI.log('Running firmware released on: <strong>' + CONFIG.buildInfo + '</strong>');
// continue as usually
CONFIGURATOR.connectionValid = true;
$('div#port-picker a.connect').text(chrome.i18n.getMessage('disconnect')).addClass('active');
$('#tabs li a:first').click();
} else {
GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.firmwareVersionAccepted]));
$('div#port-picker a.connect').click(); // disconnect
}
});
});
} else {
GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.firmwareVersionAccepted]));
$('div#port-picker a.connect').click(); // disconnect
}
});
} else {
$('div#port-picker a.connect').text(chrome.i18n.getMessage('disconnect')).addClass('active');
GUI.log('Connection opened in <strong>pass-through</strong> mode');
}
});
} else {
console.log('Failed to open serial port');
GUI.log(chrome.i18n.getMessage('serialPortOpenFail'));
@ -187,12 +187,10 @@ function onClosed(result) {
}
function read_serial(info) {
if (!CONFIGURATOR.cliActive && !CONFIGURATOR.mspPassThrough) {
if (!CONFIGURATOR.cliActive) {
MSP.read(info);
} else if (CONFIGURATOR.cliActive) {
TABS.cli.read(info);
} else if (CONFIGURATOR.mspPassThrough) {
MSP.read(info);
}
}
@ -251,6 +249,10 @@ function lowByte(num) {
return 0x00FF & num;
}
function specificByte(num, pos) {
return 0x000000FF & (num >> (8 * pos));
}
function bit_check(num, bit) {
return ((num >> bit) % 2 != 0);
}