diff --git a/cim-client-vue/Auto.vue b/cim-client-vue/Auto.vue new file mode 100644 index 0000000..4853f4e --- /dev/null +++ b/cim-client-vue/Auto.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/cim-client-vue/websocket/cim.web.sdk.js b/cim-client-vue/websocket/cim.web.sdk.js new file mode 100644 index 0000000..af89afe --- /dev/null +++ b/cim-client-vue/websocket/cim.web.sdk.js @@ -0,0 +1,183 @@ +/* eslint-disable */ +import './message.js' +import './replybody.js' +import './sentbody.js' + +/*CIM服务器IP*/ +const CIM_HOST = "192.168.1.12"; +/* + * 服务端 websocket端口 + */ +const CIM_PORT = 34567; +const CIM_URI = "ws://" + CIM_HOST + ":" + CIM_PORT; + +const APP_VERSION = "1.0.0"; +const APP_CHANNEL = "browser"; +const APP_PACKAGE = "com.farsunset.cim"; + +/* + *特殊的消息类型,代表被服务端强制下线 + */ +const ACTION_999 = "999"; +const DATA_HEADER_LENGTH = 1; + +const MESSAGE = 2; +const REPLY_BODY = 4; + +let socket; +let manualStop = false; +const CIMPushManager = {}; +const onConnect = CIMPushManager.connect = function () { + manualStop = false; + window.localStorage.account = ''; + socket = new WebSocket(CIM_URI); + socket.cookieEnabled = false; + socket.binaryType = 'arraybuffer'; + socket.onopen = CIMPushManager.innerOnConnectFinished; + socket.onmessage = CIMPushManager.innerOnMessageReceived; + socket.onclose = CIMPushManager.innerOnConnectionClosed; +}; + +const onbindAccount = CIMPushManager.bindAccount = function (account) { + window.localStorage.account = account; + + let deviceId = window.localStorage.deviceIddeviceId; + if (deviceId == '' || deviceId == undefined) { + deviceId = generateUUID(); + window.localStorage.deviceId = deviceId; + } + + let browser = getBrowser(); + console.log(proto) + let body = new proto.com.farsunset.cim.sdk.web.model.SentBody(); + body.setKey("client_bind"); + body.setTimestamp(new Date().getTime()); + body.getDataMap().set("account", account); + body.getDataMap().set("channel", APP_CHANNEL); + body.getDataMap().set("appVersion", APP_VERSION); + body.getDataMap().set("osVersion", browser.version); + body.getDataMap().set("packageName", APP_PACKAGE); + body.getDataMap().set("deviceId", deviceId); + body.getDataMap().set("device", browser.name); + CIMPushManager.sendRequest(body); +}; + +CIMPushManager.stop = function () { + manualStop = true; + socket.close(); +}; + +CIMPushManager.resume = function () { + manualStop = false; + CIMPushManager.connect(); +}; + +CIMPushManager.innerOnConnectFinished = function () { + let account = window.localStorage.account; + if (account === '' || account === undefined) { + window.onConnectFinished(); + } else { + CIMPushManager.bindAccount(account); + } +}; + +CIMPushManager.innerOnMessageReceived = function (e) { + let data = new Uint8Array(e.data); + let type = data[0]; + let body = data.subarray(DATA_HEADER_LENGTH, data.length); + + if (type == MESSAGE) { + let message = proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinary(body); + onInterceptMessageReceived(message.toObject(false)); + return; + } + + if (type == REPLY_BODY) { + let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body); + /** + * 将proto对象转换成json对象,去除无用信息 + */ + let reply = {}; + reply.code = message.getCode(); + reply.key = message.getKey(); + reply.message = message.getMessage(); + reply.timestamp = message.getTimestamp(); + reply.data = {}; + + /** + * 注意,遍历map这里的参数 value在前key在后 + */ + message.getDataMap().forEach(function (v, k) { + reply.data[k] = v; + }); + + window.onReplyReceived(reply); + } +}; + +CIMPushManager.innerOnConnectionClosed = function (e) { + if (!manualStop) { + let time = Math.floor(Math.random() * (30 - 15 + 1) + 15); + setTimeout(function () { + CIMPushManager.connect(); + }, time); + } +}; + +CIMPushManager.sendRequest = function (body) { + let data = body.serializeBinary(); + let protobuf = new Uint8Array(data.length); + protobuf.set(data, 0); + socket.send(protobuf); +}; + +function onInterceptMessageReceived(message) { + /* + *被强制下线之后,不再继续连接服务端 + */ + if (message.action == ACTION_999) { + manualStop = true; + } + /* + *收到消息后,将消息发送给页面 + */ + if (onMessageReceived instanceof Function) { + window.onMessageReceived(message); + } +} + +function getBrowser() { + let explorer = window.navigator.userAgent.toLowerCase(); + if (explorer.indexOf("msie") >= 0) { + let ver = explorer.match(/msie ([\d.]+)/)[1]; + return {name: "IE", version: ver}; + } else if (explorer.indexOf("firefox") >= 0) { + let ver = explorer.match(/firefox\/([\d.]+)/)[1]; + return {name: "Firefox", version: ver}; + } else if (explorer.indexOf("chrome") >= 0) { + let ver = explorer.match(/chrome\/([\d.]+)/)[1]; + return {name: "Chrome", version: ver}; + } else if (explorer.indexOf("opera") >= 0) { + let ver = explorer.match(/opera.([\d.]+)/)[1]; + return {name: "Opera", version: ver}; + } else if (explorer.indexOf("Safari") >= 0) { + let ver = explorer.match(/version\/([\d.]+)/)[1]; + return {name: "Safari", version: ver}; + } + return {name: "Other", version: "1.0.0"}; +} + +function generateUUID() { + let d = new Date().getTime(); + let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + let r = (d + Math.random() * 16) % 16 | 0; + d = Math.floor(d / 16); + return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); + return uuid.replace(/-/g, ''); +} + +export { + onConnect, + onbindAccount +} \ No newline at end of file diff --git a/cim-client-vue/websocket/message.js b/cim-client-vue/websocket/message.js new file mode 100644 index 0000000..e59c610 --- /dev/null +++ b/cim-client-vue/websocket/message.js @@ -0,0 +1,2775 @@ +/* eslint-disable */ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.toObject = function(opt_includeInstance) { + return proto.com.farsunset.cim.sdk.web.model.Message.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.com.farsunset.cim.sdk.web.model.Message} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.com.farsunset.cim.sdk.web.model.Message.toObject = function(includeInstance, msg) { + var obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, 0), + action: jspb.Message.getFieldWithDefault(msg, 2, ""), + content: jspb.Message.getFieldWithDefault(msg, 3, ""), + sender: jspb.Message.getFieldWithDefault(msg, 4, ""), + receiver: jspb.Message.getFieldWithDefault(msg, 5, ""), + extra: jspb.Message.getFieldWithDefault(msg, 6, ""), + title: jspb.Message.getFieldWithDefault(msg, 7, ""), + format: jspb.Message.getFieldWithDefault(msg, 8, ""), + timestamp: jspb.Message.getFieldWithDefault(msg, 9, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.com.farsunset.cim.sdk.web.model.Message} + */ +proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.com.farsunset.cim.sdk.web.model.Message; + return proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.com.farsunset.cim.sdk.web.model.Message} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.com.farsunset.cim.sdk.web.model.Message} + */ +proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setAction(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setContent(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setSender(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setReceiver(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setExtra(value); + break; + case 7: + var value = /** @type {string} */ (reader.readString()); + msg.setTitle(value); + break; + case 8: + var value = /** @type {string} */ (reader.readString()); + msg.setFormat(value); + break; + case 9: + var value = /** @type {number} */ (reader.readInt64()); + msg.setTimestamp(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.com.farsunset.cim.sdk.web.model.Message.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.com.farsunset.cim.sdk.web.model.Message} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.com.farsunset.cim.sdk.web.model.Message.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } + f = message.getAction(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getContent(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getSender(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getReceiver(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getExtra(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } + f = message.getTitle(); + if (f.length > 0) { + writer.writeString( + 7, + f + ); + } + f = message.getFormat(); + if (f.length > 0) { + writer.writeString( + 8, + f + ); + } + f = message.getTimestamp(); + if (f !== 0) { + writer.writeInt64( + 9, + f + ); + } +}; + + +/** + * optional int64 id = 1; + * @return {number} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getId = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setId = function(value) { + jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional string action = 2; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getAction = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setAction = function(value) { + jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string content = 3; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getContent = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setContent = function(value) { + jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional string sender = 4; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getSender = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setSender = function(value) { + jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string receiver = 5; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getReceiver = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setReceiver = function(value) { + jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional string extra = 6; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getExtra = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setExtra = function(value) { + jspb.Message.setProto3StringField(this, 6, value); +}; + + +/** + * optional string title = 7; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getTitle = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setTitle = function(value) { + jspb.Message.setProto3StringField(this, 7, value); +}; + + +/** + * optional string format = 8; + * @return {string} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getFormat = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, "")); +}; + + +/** @param {string} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setFormat = function(value) { + jspb.Message.setProto3StringField(this, 8, value); +}; + + +/** + * optional int64 timestamp = 9; + * @return {number} + */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.getTimestamp = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0)); +}; + + +/** @param {number} value */ +proto.com.farsunset.cim.sdk.web.model.Message.prototype.setTimestamp = function(value) { + jspb.Message.setProto3IntField(this, 9, value); +}; + + +goog.object.extend(exports, proto.com.farsunset.cim.sdk.web.model); + +},{"google-protobuf":3}],2:[function(require,module,exports){ +var myProto = require('./Message_pb'); + + module.exports = { + DataProto: myProto + } +},{"./Message_pb":1}],3:[function(require,module,exports){ +(function (global,Buffer){ +var $jscomp={scope:{},getGlobal:function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global?global:a}};$jscomp.global=$jscomp.getGlobal(this);$jscomp.initSymbol=function(){$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol);$jscomp.initSymbol=function(){}};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(a){return"jscomp_symbol_"+a+$jscomp.symbolCounter_++}; +$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();$jscomp.global.Symbol.iterator||($jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));$jscomp.initSymbolIterator=function(){}};$jscomp.makeIterator=function(a){$jscomp.initSymbolIterator();$jscomp.initSymbol();$jscomp.initSymbolIterator();var b=a[Symbol.iterator];if(b)return b.call(a);var c=0;return{next:function(){return cb;)--c in this?this[--a]=this[c]:delete this[a];return this};$jscomp.array.copyWithin$install=function(){$jscomp.array.installHelper_("copyWithin",$jscomp.array.copyWithin)}; +$jscomp.array.fill=function(a,b,c){var d=this.length||0;0>b&&(b=Math.max(0,d+b));if(null==c||c>d)c=d;c=Number(c);0>c&&(c=Math.max(0,d+c));for(b=Number(b||0);b>>0;if(0===a)return 32;var b=0;0===(a&4294901760)&&(a<<=16,b+=16);0===(a&4278190080)&&(a<<=8,b+=8);0===(a&4026531840)&&(a<<=4,b+=4);0===(a&3221225472)&&(a<<=2,b+=2);0===(a&2147483648)&&b++;return b};$jscomp.math.imul=function(a,b){a=Number(a);b=Number(b);var c=a&65535,d=b&65535;return c*d+((a>>>16&65535)*d+c*(b>>>16&65535)<<16>>>0)|0};$jscomp.math.sign=function(a){a=Number(a);return 0===a||isNaN(a)?a:0a&&-.25a&&-.25a?-b:b};$jscomp.math.acosh=function(a){a=Number(a);return Math.log(a+Math.sqrt(a*a-1))};$jscomp.math.asinh=function(a){a=Number(a);if(0===a)return a;var b=Math.log(Math.abs(a)+Math.sqrt(a*a+1));return 0>a?-b:b}; +$jscomp.math.atanh=function(a){a=Number(a);return($jscomp.math.log1p(a)-$jscomp.math.log1p(-a))/2};$jscomp.math.hypot=function(a,b,c){a=Number(a);b=Number(b);var d,e,f,g=Math.max(Math.abs(a),Math.abs(b));for(d=2;dg){a/=g;b/=g;f=a*a+b*b;for(d=2;da?-b:b};$jscomp.math.cbrt=function(a){if(0===a)return a;a=Number(a);var b=Math.pow(Math.abs(a),1/3);return 0>a?-b:b};$jscomp.number=$jscomp.number||{};$jscomp.number.isFinite=function(a){return"number"!==typeof a?!1:!isNaN(a)&&Infinity!==a&&-Infinity!==a};$jscomp.number.isInteger=function(a){return $jscomp.number.isFinite(a)?a===Math.floor(a):!1}; +$jscomp.number.isNaN=function(a){return"number"===typeof a&&isNaN(a)};$jscomp.number.isSafeInteger=function(a){return $jscomp.number.isInteger(a)&&Math.abs(a)<=$jscomp.number.MAX_SAFE_INTEGER};$jscomp.number.EPSILON=function(){return Math.pow(2,-52)}();$jscomp.number.MAX_SAFE_INTEGER=function(){return 9007199254740991}();$jscomp.number.MIN_SAFE_INTEGER=function(){return-9007199254740991}();$jscomp.object=$jscomp.object||{}; +$jscomp.object.assign=function(a,b){for(var c=1;cd||1114111=d?b+=String.fromCharCode(d):(d-=65536,b+=String.fromCharCode(d>>>10&1023|55296),b+=String.fromCharCode(d&1023|56320))}return b}; +$jscomp.string.repeat=function(a){var b=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279>>=1)b+=b;return c};$jscomp.string.repeat$install=function(){String.prototype.repeat||(String.prototype.repeat=$jscomp.string.repeat)}; +$jscomp.string.codePointAt=function(a){var b=$jscomp.checkStringArgs(this,null,"codePointAt"),c=b.length;a=Number(a)||0;if(0<=a&&ad||56319a||57343=e}; +$jscomp.string.startsWith$install=function(){String.prototype.startsWith||(String.prototype.startsWith=$jscomp.string.startsWith)};$jscomp.string.endsWith=function(a,b){var c=$jscomp.checkStringArgs(this,a,"endsWith");a+="";void 0===b&&(b=c.length);for(var d=Math.max(0,Math.min(b|0,c.length)),e=a.length;0=e};$jscomp.string.endsWith$install=function(){String.prototype.endsWith||(String.prototype.endsWith=$jscomp.string.endsWith)}; +var COMPILED=!0,goog=goog||{};goog.global=this;goog.isDef=function(a){return void 0!==a};goog.exportPath_=function(a,b,c){a=a.split(".");c=c||goog.global;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)!a.length&&goog.isDef(b)?c[d]=b:c=c[d]?c[d]:c[d]={}}; +goog.define=function(a,b){var c=b;COMPILED||(goog.global.CLOSURE_UNCOMPILED_DEFINES&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES,a)?c=goog.global.CLOSURE_UNCOMPILED_DEFINES[a]:goog.global.CLOSURE_DEFINES&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,a)&&(c=goog.global.CLOSURE_DEFINES[a]));goog.exportPath_(a,c)};goog.DEBUG=!0;goog.LOCALE="en";goog.TRUSTED_SITE=!0;goog.STRICT_MODE_COMPATIBLE=!1;goog.DISALLOW_TEST_ONLY_CODE=COMPILED&&!goog.DEBUG; +goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING=!1;goog.provide=function(a){if(!COMPILED&&goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');goog.constructNamespace_(a)};goog.constructNamespace_=function(a,b){if(!COMPILED){delete goog.implicitNamespaces_[a];for(var c=a;(c=c.substring(0,c.lastIndexOf(".")))&&!goog.getObjectByName(c);)goog.implicitNamespaces_[c]=!0}goog.exportPath_(a,b)};goog.VALID_MODULE_RE_=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module=function(a){if(!goog.isString(a)||!a||-1==a.search(goog.VALID_MODULE_RE_))throw Error("Invalid module identifier");if(!goog.isInModuleLoader_())throw Error("Module "+a+" has been loaded incorrectly.");if(goog.moduleLoaderState_.moduleName)throw Error("goog.module may only be called once per module.");goog.moduleLoaderState_.moduleName=a;if(!COMPILED){if(goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');delete goog.implicitNamespaces_[a]}};goog.module.get=function(a){return goog.module.getInternal_(a)}; +goog.module.getInternal_=function(a){if(!COMPILED)return goog.isProvided_(a)?a in goog.loadedModules_?goog.loadedModules_[a]:goog.getObjectByName(a):null};goog.moduleLoaderState_=null;goog.isInModuleLoader_=function(){return null!=goog.moduleLoaderState_}; +goog.module.declareLegacyNamespace=function(){if(!COMPILED&&!goog.isInModuleLoader_())throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module");if(!COMPILED&&!goog.moduleLoaderState_.moduleName)throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace.");goog.moduleLoaderState_.declareLegacyNamespace=!0}; +goog.setTestOnly=function(a){if(goog.DISALLOW_TEST_ONLY_CODE)throw a=a||"",Error("Importing test-only code into non-debug environment"+(a?": "+a:"."));};goog.forwardDeclare=function(a){};COMPILED||(goog.isProvided_=function(a){return a in goog.loadedModules_||!goog.implicitNamespaces_[a]&&goog.isDefAndNotNull(goog.getObjectByName(a))},goog.implicitNamespaces_={"goog.module":!0}); +goog.getObjectByName=function(a,b){for(var c=a.split("."),d=b||goog.global,e;e=c.shift();)if(goog.isDefAndNotNull(d[e]))d=d[e];else return null;return d};goog.globalize=function(a,b){var c=b||goog.global,d;for(d in a)c[d]=a[d]};goog.addDependency=function(a,b,c,d){if(goog.DEPENDENCIES_ENABLED){var e;a=a.replace(/\\/g,"/");for(var f=goog.dependencies_,g=0;e=b[g];g++)f.nameToPath[e]=a,f.pathIsModule[a]=!!d;for(d=0;b=c[d];d++)a in f.requires||(f.requires[a]={}),f.requires[a][b]=!0}}; +goog.ENABLE_DEBUG_LOADER=!0;goog.logToConsole_=function(a){goog.global.console&&goog.global.console.error(a)};goog.require=function(a){if(!COMPILED){goog.ENABLE_DEBUG_LOADER&&goog.IS_OLD_IE_&&goog.maybeProcessDeferredDep_(a);if(goog.isProvided_(a))return goog.isInModuleLoader_()?goog.module.getInternal_(a):null;if(goog.ENABLE_DEBUG_LOADER){var b=goog.getPathFromDeps_(a);if(b)return goog.writeScripts_(b),null}a="goog.require could not find: "+a;goog.logToConsole_(a);throw Error(a);}}; +goog.basePath="";goog.nullFunction=function(){};goog.abstractMethod=function(){throw Error("unimplemented abstract method");};goog.addSingletonGetter=function(a){a.getInstance=function(){if(a.instance_)return a.instance_;goog.DEBUG&&(goog.instantiatedSingletons_[goog.instantiatedSingletons_.length]=a);return a.instance_=new a}};goog.instantiatedSingletons_=[];goog.LOAD_MODULE_USING_EVAL=!0;goog.SEAL_MODULE_EXPORTS=goog.DEBUG;goog.loadedModules_={};goog.DEPENDENCIES_ENABLED=!COMPILED&&goog.ENABLE_DEBUG_LOADER; +goog.DEPENDENCIES_ENABLED&&(goog.dependencies_={pathIsModule:{},nameToPath:{},requires:{},visited:{},written:{},deferred:{}},goog.inHtmlDocument_=function(){var a=goog.global.document;return null!=a&&"write"in a},goog.findBasePath_=function(){if(goog.isDef(goog.global.CLOSURE_BASE_PATH))goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_())for(var a=goog.global.document.getElementsByTagName("SCRIPT"),b=a.length-1;0<=b;--b){var c=a[b].src,d=c.lastIndexOf("?"),d=-1==d?c.length: +d;if("base.js"==c.substr(d-7,7)){goog.basePath=c.substr(0,d-7);break}}},goog.importScript_=function(a,b){(goog.global.CLOSURE_IMPORT_SCRIPT||goog.writeScriptTag_)(a,b)&&(goog.dependencies_.written[a]=!0)},goog.IS_OLD_IE_=!(goog.global.atob||!goog.global.document||!goog.global.document.all),goog.importModule_=function(a){goog.importScript_("",'goog.retrieveAndExecModule_("'+a+'");')&&(goog.dependencies_.written[a]=!0)},goog.queuedModules_=[],goog.wrapModule_=function(a,b){return goog.LOAD_MODULE_USING_EVAL&& +goog.isDef(goog.global.JSON)?"goog.loadModule("+goog.global.JSON.stringify(b+"\n//# sourceURL="+a+"\n")+");":'goog.loadModule(function(exports) {"use strict";'+b+"\n;return exports});\n//# sourceURL="+a+"\n"},goog.loadQueuedModules_=function(){var a=goog.queuedModules_.length;if(0\x3c/script>')},goog.appendScriptSrcNode_=function(a){var b=goog.global.document, +c=b.createElement("script");c.type="text/javascript";c.src=a;c.defer=!1;c.async=!1;b.head.appendChild(c)},goog.writeScriptTag_=function(a,b){if(goog.inHtmlDocument_()){var c=goog.global.document;if(!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING&&"complete"==c.readyState){if(/\bdeps.js$/.test(a))return!1;throw Error('Cannot write "'+a+'" after document load');}var d=goog.IS_OLD_IE_;void 0===b?d?(d=" onreadystatechange='goog.onScriptLoad_(this, "+ ++goog.lastNonModuleScriptIndex_+")' ",c.write('