UNPKG

@eclicktech/mp-sdk

Version:

The Eclicktech Funsdata of MiniProgram SDK, suport echat, Alipay, TikTok

4,562 lines 149 kB
'use strict';

function _classCallCheck(a, n) {
  if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(e, r) {
  for (var t = 0; t < r.length; t++) {
    var o = r[t];
    o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
  }
}
function _createClass(e, r, t) {
  return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
    writable: !1
  }), e;
}
function _toPrimitive(t, r) {
  if ("object" != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r || "default");
    if ("object" != typeof i) return i;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, "string");
  return "symbol" == typeof i ? i : i + "";
}
function _typeof(o) {
  "@babel/helpers - typeof";

  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
    return typeof o;
  } : function (o) {
    return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  }, _typeof(o);
}

var Config = {
  LIB_VERSION: '3.3.1-beta.2',
  LIB_NAME: 'MP'
};

var _ = {};
var ArrayProto = Array.prototype,
  ObjProto = Object.prototype,
  slice = ArrayProto.slice,
  nativeToString = ObjProto.toString,
  nativeHasOwnProperty = Object.prototype.hasOwnProperty,
  nativeForEach = ArrayProto.forEach,
  nativeIsArray = Array.isArray,
  breaker = {};
var utmTypes = ["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"];
_.each = function (obj, iterator, context) {
  // eslint-disable-next-line
  if (obj === null || obj === undefined) {
    return false;
  }
  if (nativeForEach && obj.forEach === nativeForEach) {
    obj.forEach(iterator, context);
  } else if (obj.length === +obj.length) {
    for (var i = 0, l = obj.length; i < l; i++) {
      if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) {
        return false;
      }
    }
  } else {
    for (var key in obj) {
      if (nativeHasOwnProperty.call(obj, key)) {
        if (iterator.call(context, obj[key], key, obj) === breaker) {
          return false;
        }
      }
    }
  }
};
_.extend = function (obj) {
  _.each(slice.call(arguments, 1), function (source) {
    for (var prop in source) {
      if (source[prop] !== void 0) {
        obj[prop] = source[prop];
      }
    }
  });
  return obj;
};
_.extend2Layers = function (obj) {
  _.each(slice.call(arguments, 1), function (source) {
    for (var prop in source) {
      if (source[prop] !== void 0) {
        if (_.isObject(source[prop]) && _.isObject(obj[prop])) {
          _.extend(obj[prop], source[prop]);
        } else {
          obj[prop] = source[prop];
        }
      }
    }
  });
  return obj;
};
_.isArray = nativeIsArray || function (obj) {
  return nativeToString.call(obj) === "[object Array]";
};
_.isFunction = function (f) {
  try {
    return typeof f === "function";
  } catch (x) {
    return false;
  }
};

//alipay request type
_.isPromise = function (obj) {
  return nativeToString.call(obj) === "[object Promise]" && obj !== null && obj !== undefined;
};
_.isObject = function (obj) {
  return nativeToString.call(obj) === "[object Object]" && obj !== null && obj !== undefined;
};
_.isEmptyObject = function (obj) {
  if (_.isObject(obj)) {
    for (var key in obj) {
      if (nativeHasOwnProperty.call(obj, key)) {
        return false;
      }
    }
    return true;
  }
  return false;
};
_.isUndefined = function (obj) {
  return obj === void 0;
};
_.isString = function (obj) {
  return nativeToString.call(obj) === "[object String]";
};
_.isDate = function (obj) {
  return nativeToString.call(obj) === "[object Date]";
};
_.isBoolean = function (obj) {
  return nativeToString.call(obj) === "[object Boolean]";
};
_.isNumber = function (obj) {
  // eslint-disable-next-line no-useless-escape
  return nativeToString.call(obj) === "[object Number]" && /[\d\.]+/.test(String(obj));
};
_.isJSONString = function (str) {
  try {
    JSON.parse(str);
  } catch (e) {
    return false;
  }
  return true;
};
_.decodeURIComponent = function (val) {
  var result = "";
  try {
    result = decodeURIComponent(val);
  } catch (e) {
    result = val;
  }
  return result;
};
_.encodeURIComponent = function (val) {
  var result = "";
  try {
    result = encodeURIComponent(val);
  } catch (e) {
    result = val;
  }
  return result;
};
_.utf8Encode = function (string) {
  string = (string + "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
  var utftext = "";
  var start, end;
  var stringl = 0;
  var n;
  start = end = 0;
  stringl = string.length;
  for (n = 0; n < stringl; n++) {
    var c1 = string.charCodeAt(n);
    var enc = null;
    if (c1 < 128) {
      end++;
    } else if (c1 > 127 && c1 < 2048) {
      enc = String.fromCharCode(c1 >> 6 | 192, c1 & 63 | 128);
    } else {
      enc = String.fromCharCode(c1 >> 12 | 224, c1 >> 6 & 63 | 128, c1 & 63 | 128);
    }
    if (enc !== null) {
      if (end > start) {
        utftext += string.substring(start, end);
      }
      utftext += enc;
      start = end = n + 1;
    }
  }
  if (end > start) {
    utftext += string.substring(start, string.length);
  }
  return utftext;
};
_.base64Encode = function (data) {
  var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  var o1, o2, o3, h1, h2, h3, h4, bits;
  var i = 0,
    ac = 0,
    enc = "",
    tmpArr = [];
  if (!data) {
    return data;
  }
  data = _.utf8Encode(data);
  do {
    o1 = data.charCodeAt(i++);
    o2 = data.charCodeAt(i++);
    o3 = data.charCodeAt(i++);
    bits = o1 << 16 | o2 << 8 | o3;
    h1 = bits >> 18 & 0x3f;
    h2 = bits >> 12 & 0x3f;
    h3 = bits >> 6 & 0x3f;
    h4 = bits & 0x3f;
    tmpArr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  } while (i < data.length);
  enc = tmpArr.join("");
  switch (data.length % 3) {
    case 1:
      enc = enc.slice(0, -2) + "==";
      break;
    case 2:
      enc = enc.slice(0, -1) + "=";
      break;
  }
  return enc;
};
_.encodeDates = function (obj) {
  _.each(obj, function (v, k) {
    if (_.isDate(v)) {
      obj[k] = _.formatDate(v);
    } else if (_.isObject(v)) {
      obj[k] = _.encodeDates(v);
    } else if (_.isArray(v)) {
      for (var i = 0; i < v.length; i++) {
        if (_.isDate(v[i])) {
          obj[k][i] = _.formatDate(v[i]);
        }
      }
    }
  });
  return obj;
};
_.formatDate = function (d) {
  function pad(n) {
    return n < 10 ? "0" + n : n;
  }
  function secondPad(n) {
    if (n < 100 && n > 9) return "0" + n;else if (n < 10) return "00" + n;else return n;
  }
  return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()) + " " + pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + "." + secondPad(d.getMilliseconds());
};
_.formatTimeZone = function (d, i) {
  if (typeof i !== "number") return d;
  var len = d.getTime();
  var offset = d.getTimezoneOffset() * 60000;
  var utcTime = len + offset;
  return new Date(utcTime + 3600000 * i);
};
_.getTimeZone = function (d, i) {
  if (typeof i === "number") return i;
  return 0 - d.getTimezoneOffset() / 60.0;
};
_.searchObjDate = function (o, i) {
  try {
    if (_.isObject(o) || _.isArray(o)) {
      _.each(o, function (a, b) {
        if (_.isObject(a) || _.isArray(a)) {
          _.searchObjDate(o[b], i);
        } else {
          if (_.isDate(a)) {
            o[b] = _.formatDate(_.formatTimeZone(a, i));
          }
        }
      });
    }
  } catch (err) {
    logger.warn(err);
  }
};
_.UUID = function () {
  var visitTime = new Date().getTime();
  var uuid = "" + String(Math.random()).replace(".", "").slice(1, 11) + "-" + visitTime;
  return uuid;
};
_.UUIDv4 = function () {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      // eslint-disable-next-line eqeqeq
      v = c === "x" ? r : r & 0x3 | 0x8;
    return v.toString(16);
  });
};
_.setMpPlatform = function (mpPlatform) {
  _.mpPlatform = mpPlatform;
};
_.getMpPlatform = function () {
  return _.mpPlatform;
};
_.createExtraHeaders = function () {
  return {
    "Analytics-Integration-Type": Config.LIB_NAME,
    "Analytics-Integration-Version": Config.LIB_VERSION,
    "Analytics-Integration-Count": "1",
    "Analytics-Integration-Extra": _.getMpPlatform()
  };
};

// remove spaces in AppId
_.checkAppId = function (appId) {
  if (!appId) return undefined;
  appId = appId.replace(/\s+/g, "");
  return appId;
};

// remove spaces, pathname (file name), other parameters in URL
_.checkUrl = function (url) {
  if (!url) return undefined;
  url = url.replace(/\s+/g, "");
  url = _.url("basic", url);
  return url;
};
_.url = function () {
  function _t() {
    return new RegExp(/(.*?)\.?([^.]*?)\.(com|net|org|biz|ws|in|me|co\.uk|co|org\.uk|ltd\.uk|plc\.uk|me\.uk|edu|mil|br\.com|cn\.com|eu\.com|hu\.com|no\.com|qc\.com|sa\.com|se\.com|se\.net|us\.com|uy\.com|ac|co\.ac|gv\.ac|or\.ac|ac\.ac|af|am|as|at|ac\.at|co\.at|gv\.at|or\.at|asn\.au|com\.au|edu\.au|org\.au|net\.au|id\.au|be|ac\.be|adm\.br|adv\.br|am\.br|arq\.br|art\.br|bio\.br|cng\.br|cnt\.br|com\.br|ecn\.br|eng\.br|esp\.br|etc\.br|eti\.br|fm\.br|fot\.br|fst\.br|g12\.br|gov\.br|ind\.br|inf\.br|jor\.br|lel\.br|med\.br|mil\.br|net\.br|nom\.br|ntr\.br|odo\.br|org\.br|ppg\.br|pro\.br|psc\.br|psi\.br|rec\.br|slg\.br|tmp\.br|tur\.br|tv\.br|vet\.br|zlg\.br|br|ab\.ca|bc\.ca|mb\.ca|nb\.ca|nf\.ca|ns\.ca|nt\.ca|on\.ca|pe\.ca|qc\.ca|sk\.ca|yk\.ca|ca|cc|ac\.cn|net\.cn|com\.cn|edu\.cn|gov\.cn|org\.cn|bj\.cn|sh\.cn|tj\.cn|cq\.cn|he\.cn|nm\.cn|ln\.cn|jl\.cn|hl\.cn|js\.cn|zj\.cn|ah\.cn|gd\.cn|gx\.cn|hi\.cn|sc\.cn|gz\.cn|yn\.cn|xz\.cn|sn\.cn|gs\.cn|qh\.cn|nx\.cn|xj\.cn|tw\.cn|hk\.cn|mo\.cn|cn|cx|cz|de|dk|fo|com\.ec|tm\.fr|com\.fr|asso\.fr|presse\.fr|fr|gf|gs|co\.il|net\.il|ac\.il|k12\.il|gov\.il|muni\.il|ac\.in|co\.in|org\.in|ernet\.in|gov\.in|net\.in|res\.in|is|it|ac\.jp|co\.jp|go\.jp|or\.jp|ne\.jp|ac\.kr|co\.kr|go\.kr|ne\.kr|nm\.kr|or\.kr|li|lt|lu|asso\.mc|tm\.mc|com\.mm|org\.mm|net\.mm|edu\.mm|gov\.mm|ms|nl|no|nu|pl|ro|org\.ro|store\.ro|tm\.ro|firm\.ro|www\.ro|arts\.ro|rec\.ro|info\.ro|nom\.ro|nt\.ro|se|si|com\.sg|org\.sg|net\.sg|gov\.sg|sk|st|tf|ac\.th|co\.th|go\.th|mi\.th|net\.th|or\.th|tm|to|com\.tr|edu\.tr|gov\.tr|k12\.tr|net\.tr|org\.tr|com\.tw|org\.tw|net\.tw|ac\.uk|uk\.com|uk\.net|gb\.com|gb\.net|vg|sh|kz|ch|info|ua|gov|name|pro|ie|hk|com\.hk|org\.hk|net\.hk|edu\.hk|us|tk|cd|by|ad|lv|eu\.lv|bz|es|jp|cl|ag|mobi|eu|co\.nz|org\.nz|net\.nz|maori\.nz|iwi\.nz|io|la|md|sc|sg|vc|tw|travel|my|se|tv|pt|com\.pt|edu\.pt|asia|fi|com\.ve|net\.ve|fi|org\.ve|web\.ve|info\.ve|co\.ve|tel|im|gr|ru|net\.ru|org\.ru|hr|com\.hr|ly|xyz)$/);
  }
  function _d(s) {
    return _.decodeURIComponent(s.replace(/\+/g, " "));
  }
  function _i(arg, str) {
    var sptr = arg.charAt(0);
    var split = str.split(sptr);
    if (sptr === arg) {
      return split;
    }
    arg = parseInt(arg.substring(1), 10);
    return split[arg < 0 ? split.length + arg : arg - 1];
  }
  function _f(arg, str) {
    var sptr = arg.charAt(0);
    var split = str.split("&");
    var field = [];
    var params = {};
    var tmp = [];
    var arg2 = arg.substring(1);
    for (var i = 0, ii = split.length; i < ii; i++) {
      field = split[i].match(/(.*?)=(.*)/);
      // TODO: regex should be able to handle this.
      if (!field) {
        field = [split[i], split[i], ""];
      }
      if (field[1].replace(/\s/g, "") !== "") {
        field[2] = _d(field[2] || "");
        // If we have a match just return it right away.
        if (arg2 === field[1]) {
          return field[2];
        }
        // Check for array pattern.
        tmp = field[1].match(/(.*)\[([0-9]+)\]/);
        if (tmp) {
          params[tmp[1]] = params[tmp[1]] || [];
          params[tmp[1]][tmp[2]] = field[2];
        } else {
          params[field[1]] = field[2];
        }
      }
    }
    if (sptr === arg) {
      return params;
    }
    return params[arg2];
  }
  return function (arg, url) {
    var _l = {},
      tmp;
    if (arg === "tld?") {
      return _t();
    }
    url = url || window.location.toString();
    if (!arg) {
      return url;
    }
    arg = arg.toString();
    if (url.match(/^mailto:([^/].+)/)) {
      tmp = url.match(/^mailto:([^/].+)/);
      _l.protocol = "mailto";
      _l.email = tmp[1];
    } else {
      // Ignore Hashbangs.
      if (url.match(/(.*?)\/#!(.*)/)) {
        tmp = url.match(/(.*?)\/#!(.*)/);
        url = tmp[1] + tmp[2];
      }
      // Hash.
      if (url.match(/(.*?)#(.*)/)) {
        tmp = url.match(/(.*?)#(.*)/);
        _l.hash = tmp[2];
        url = tmp[1];
      }
      // Return hash parts.
      if (_l.hash && arg.match(/^#/)) {
        return _f(arg, _l.hash);
      }
      // Query
      if (url.match(/(.*?)\?(.*)/)) {
        tmp = url.match(/(.*?)\?(.*)/);
        _l.query = tmp[2];
        url = tmp[1];
      }
      // Return query parts.
      if (_l.query && arg.match(/^\?/)) {
        return _f(arg, _l.query);
      }
      // Protocol.
      if (url.match(/(.*?):?\/\/(.*)/)) {
        tmp = url.match(/(.*?):?\/\/(.*)/);
        _l.protocol = tmp[1].toLowerCase();
        url = tmp[2];
      }
      // Path.
      if (url.match(/(.*?)(\/.*)/)) {
        tmp = url.match(/(.*?)(\/.*)/);
        _l.path = tmp[2];
        url = tmp[1];
      }
      // Clean up path.
      _l.path = (_l.path || "").replace(/^([^/])/, "/$1").replace(/\/$/, "");
      // Return path parts.
      if (arg.match(/^[-0-9]+$/)) {
        arg = arg.replace(/^([^/])/, "/$1");
      }
      if (arg.match(/^\//)) {
        return _i(arg, _l.path.substring(1));
      }
      // File.
      tmp = _i("/-1", _l.path.substring(1));
      if (tmp && (tmp = tmp.match(/(.*?)\.(.*)/))) {
        _l.file = tmp[0];
        _l.filename = tmp[1];
        _l.fileext = tmp[2];
      }
      // Port.
      if (url.match(/(.*):([0-9]+)$/)) {
        tmp = url.match(/(.*):([0-9]+)$/);
        _l.port = tmp[2];
        url = tmp[1];
      }
      // Auth.
      if (url.match(/(.*?)@(.*)/)) {
        tmp = url.match(/(.*?)@(.*)/);
        _l.auth = tmp[1];
        url = tmp[2];
      }
      // User and pass.
      if (_l.auth) {
        tmp = _l.auth.match(/(.*):(.*)/);
        _l.user = tmp ? tmp[1] : _l.auth;
        _l.pass = tmp ? tmp[2] : undefined;
      }
      // Hostname.
      _l.hostname = url.toLowerCase();
      // Return hostname parts.
      if (arg.charAt(0) === ".") {
        return _i(arg, _l.hostname);
      }
      // Domain, tld and sub domain.
      if (_t()) {
        tmp = _l.hostname.match(_t());
        if (tmp) {
          _l.tld = tmp[3];
          _l.domain = tmp[2] ? tmp[2] + "." + tmp[3] : undefined;
          _l.sub = tmp[1] || undefined;
        }
      }
      // Set port and protocol defaults if not set.
      var portInfo = _l.port ? ":" + _l.port : "";
      _l.protocol = _l.protocol || window.location.protocol.replace(":", "");
      // console.log(_l);
      _l.port = _l.port || (_l.protocol === "https" ? "443" : "80");
      _l.protocol = _l.protocol || (_l.port === "443" ? "https" : "http");
      _l.basic = _l.protocol + "://" + _l.hostname + portInfo;
    }
    // Return arg.
    if (arg in _l) {
      return _l[arg];
    }
    // Return everything.
    if (arg === "{}") {
      return _l;
    }
    // Default to undefined for no match.
    return "";
  };
}();
_.createString = function (length) {
  var expect = length;
  var str = Math.random().toString(36).substr(2);
  while (str.length < expect) {
    str += Math.random().toString(36).substr(2);
  }
  str = str.substr(0, length);
  return str;
};
_.createAesKey = function () {
  return _.createString(16);
};
_.generateEncryptyData = function (text, secretKey) {
  if (typeof secretKey === "undefined") {
    return text;
  }
  var pkey = secretKey["publicKey"];
  var v = secretKey["version"];
  if (typeof pkey === "undefined" || typeof v === "undefined") {
    return text;
  }
  if (typeof CryptoJS === "undefined" || typeof JSEncrypt === "undefined") {
    return text;
  }
  var strKey = _.createAesKey();
  try {
    var key = CryptoJS.enc.Utf8.parse(strKey);
    var data = CryptoJS.enc.Utf8.parse(JSON.stringify(text));
    var padding = _.isUndefined(CryptoJS.pad.Pkcs7) ? CryptoJS.pad.PKCS7 : CryptoJS.pad.Pkcs7;
    var aesStr = CryptoJS.AES.encrypt(data, key, {
      mode: CryptoJS.mode.ECB,
      padding: padding
    }).toString();
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(pkey);
    var rsaStr = encrypt.encrypt(strKey);
    if (rsaStr === false) {
      logger.warn("Encryption failed, return the original data");
      return text;
    }
    return {
      pkv: v,
      ekey: rsaStr,
      payload: aesStr
    };
  } catch (e) {
    logger.warn("Encryption failed, return the original data: " + e);
  }
  return text;
};
_.getUtm = function () {
  var params = {};
  _.each(utmTypes, function (kwkey) {
    try {
      var kw = _.getQueryParam(location.href, kwkey);
      if (kw.length) {
        params[kwkey] = kw;
      }
    } catch (e) {
      logger.warn("get utm fail: " + e);
    }
  });
  return JSON.stringify(params);
};
/* eslint-disable */
_.getQueryParam = function (url, key) {
  key = key.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  url = _.decodeURIComponent(url);
  var regexS = "[\\?&]" + key + "=([^&#]*)",
    regex = new RegExp(regexS),
    results = regex.exec(url);
  if (results === null || results && typeof results[1] !== "string" && results[1].length) {
    return "";
  } else {
    return _.decodeURIComponent(results[1]);
  }
};
/* eslint-enable */

_.getUtmFromQuery = function (query) {
  var params = {};
  _.each(utmTypes, function (kwkey) {
    if (query[kwkey]) {
      params[kwkey] = query[kwkey];
    }
  });
  return JSON.stringify(params);
};
_.indexOf = function (arr, target) {
  var indexof = arr.indexOf;
  if (indexof) {
    return indexof.call(arr, target);
  } else {
    for (var i = 0; i < arr.length; i++) {
      if (target === arr[i]) {
        return i;
      }
    }
    return -1;
  }
};
/* eslint-disable */
_.checkCalibration = function (properties, time, enableCalibrationTime) {
  // if(!enableCalibrationTime){
  //     return properties;
  // }
  // if (properties && properties['#time_calibration']) {
  //     return;
  // }
  // var pro = {};
  // var timeCalibration = 6;
  // if (enableCalibrationTime) {
  //     if (_.isDate(time)) {
  //         timeCalibration = 5;
  //     } else {
  //         timeCalibration = 3;
  //     }
  // }
  // return _.extend(pro,properties,{'#time_calibration':timeCalibration});
  return properties;
};
/* eslint-enable */

_.isClickType = function (type) {
  var mpTaps = {
    tap: 1,
    longpress: 1,
    longtap: 1
  };
  return mpTaps[type];
};
_.getCurrentTimeStamp = function () {
  return Date.now();
};
_.getCurrentDate = function () {
  return new Date(Date.now());
};
var logger = _typeof(logger) === "object" ? logger : {};
logger.info = function () {
  if ((typeof console === "undefined" ? "undefined" : _typeof(console)) === "object" && console.log && logger.enabled) {
    try {
      arguments[0] = "[FunsData] Info: " + arguments[0];
      if (logger.listener) {
        logger.listener(arguments[0]);
      }
      return console.log.apply(console, arguments);
    } catch (e) {
      if (logger.listener) {
        logger.listener(arguments[0]);
      }
      console.log("[FunsData] Info: " + arguments[0]);
    }
  }
};
logger.warn = function () {
  if ((typeof console === "undefined" ? "undefined" : _typeof(console)) === "object" && console.log && logger.enabled) {
    try {
      arguments[0] = "[FunsData] Warning: " + arguments[0];
      return console.warn.apply(console, arguments);
    } catch (e) {
      console.warn("[FunsData] Warning: " + arguments[0]);
    }
  }
};

/** @const */
var KEY_NAME_MATCH_REGEX = /^[a-zA-Z][a-zA-Z0-9_]{0,49}$/;
var PropertyChecker = /*#__PURE__*/function () {
  function PropertyChecker() {
    _classCallCheck(this, PropertyChecker);
  }
  return _createClass(PropertyChecker, null, [{
    key: "stripProperties",
    value: function stripProperties(prop) {
      if (!_.isObject(prop)) {
        return prop;
      }
      _.each(prop, function (v, k) {
        if (!(_.isString(v) || _.isNumber(v) || _.isDate(v) || _.isBoolean(v) || _.isArray(v) || _.isObject(v))) {
          logger.warn('Your data -', k, v, '- format does not meet requirements and may not be stored correctly. Attribute values only support String, Number, Date, Boolean, Array, Object');
        }
      });
      return prop;
    }
  }, {
    key: "_checkPropertiesKey",
    value: function _checkPropertiesKey(obj) {
      var flag = true;
      _.each(obj, function (content, key) {
        if (!KEY_NAME_MATCH_REGEX.test(key)) {
          logger.warn('Invalid KEY: ' + key);
          flag = false;
        }
      });
      return flag;
    }
  }, {
    key: "event",
    value: function event(s) {
      if (!_.isString(s) || !KEY_NAME_MATCH_REGEX.test(s)) {
        logger.warn('Check the parameter format. The eventName must start with an English letter and contain no more than 50 characters including letters, digits, and underscores: ' + s);
        return false;
      } else {
        return true;
      }
    }
  }, {
    key: "propertyName",
    value: function propertyName(s) {
      if (!_.isString(s) || !KEY_NAME_MATCH_REGEX.test(s)) {
        logger.warn('Check the parameter format. PropertyName must start with a letter and contain letters, digits, and underscores (_). The value is a string of no more than 50 characters: ' + s);
        return false;
      } else {
        return true;
      }
    }
  }, {
    key: "properties",
    value: function properties(p) {
      this.stripProperties(p);
      if (p) {
        if (_.isObject(p)) {
          if (this._checkPropertiesKey(p)) {
            return true;
          } else {
            logger.warn('Check the parameter format. The properties key must start with a letter, contain digits, letters, and underscores (_), and contain a maximum of 50 characters');
            return false;
          }
        } else {
          logger.warn('properties can be none, but it must be an object');
          return false;
        }
      } else {
        return true;
      }
    }
  }, {
    key: "propertiesMust",
    value: function propertiesMust(p) {
      this.stripProperties(p);
      if (p === undefined || !_.isObject(p) || _.isEmptyObject(p)) {
        logger.warn('properties must be an object with a value');
        return false;
      } else {
        if (this._checkPropertiesKey(p)) {
          return true;
        } else {
          logger.warn('Check the parameter format. The properties key must start with a letter, contain digits, letters, and underscores (_), and contain a maximum of 50 characters');
          return false;
        }
      }
    }
  }, {
    key: "userId",
    value: function userId(id) {
      if (_.isString(id) && /^.{1,64}$/.test(id)) {
        return true;
      } else {
        logger.warn('The user ID must be a string of less than 64 characters and cannot be null');
        return false;
      }
    }
  }, {
    key: "userAddProperties",
    value: function userAddProperties(p) {
      if (!this.propertiesMust(p)) return false;
      for (var i in p) {
        if (!_.isNumber(p[i])) {
          logger.warn('The attributes of userAdd need to be Number');
          return false;
        }
      }
      return true;
    }
  }, {
    key: "userAppendProperties",
    value: function userAppendProperties(p) {
      if (!this.propertiesMust(p)) return false;
      for (var i in p) {
        if (!_.isArray(p[i])) {
          logger.warn('The attribute of userAppend must be Array');
          return false;
        }
      }
      return true;
    }
  }]);
}();

var PlatformProxy = /*#__PURE__*/function () {
  function PlatformProxy() {
    _classCallCheck(this, PlatformProxy);
    this.config = {
      persistenceName: "funsdata",
      persistenceNameOld: "funsdata_mg"
    };
  }
  return _createClass(PlatformProxy, [{
    key: "getConfig",
    value:
    /**
     * Get platform specific configuration: persistenceName required
     */
    function getConfig() {
      return this.config;
    }
  }, {
    key: "initSdkConfig",
    value: function initSdkConfig(_config) {}

    /**
     * Get local cache data
     * @param {string} name: cache key
     * @param {boolean} async: enable asynchronous getting cached
     * @param {function} callback: callback when getting data asynchronously, the parameter is an object
     * @return return cached data, it is an object
     */
  }, {
    key: "getStorage",
    value: function getStorage(name, async, callback) {
      // if (async) logger.warn('Analytics: invalid storage configuration');
      var data = localStorage.getItem(name);
      if (async) {
        if (_.isJSONString(data)) {
          callback(JSON.parse(data));
        } else {
          callback({});
        }
      } else {
        if (_.isJSONString(data)) {
          return JSON.parse(data);
        } else {
          return {};
        }
      }
    }

    /**
     * Set local cache data
     * @param {string} name: cache key
     * @param {string} value: JSON string value
     */
  }, {
    key: "setStorage",
    value: function setStorage(name, value) {
      localStorage.setItem(name, value);
    }

    /**
     * Delete data in local cache with key
     * @param {*} name: cache key
     */
  }, {
    key: "removeStorage",
    value: function removeStorage(name) {
      localStorage.removeItem(name);
    }
  }, {
    key: "_setSystemProxy",
    value: function _setSystemProxy(callback) {
      this._sysCallback = callback;
    }
    /**
     * Get system information asynchronously
     * @param {object} options: callback when getting completion
     * callback parameter:
     * brand: string, device brand
     * model: string, device model
     * screenWidth: number, screen width, unit px
     * screenHeight: number, screen height, unit px
     * system: string, operating system and version
     * platform: string, client platform
     */
  }, {
    key: "getSystemInfo",
    value: function getSystemInfo(options) {
      var res = {
        // eslint-disable-next-line
        mp_platform: "web",
        system: this._getOs(),
        screenWidth: window.screen.width,
        screenHeight: window.screen.height,
        systemLanguage: navigator.language
      };
      if (this._sysCallback) {
        res = _.extend(res, this._sysCallback(options));
      }
      options.success(res);
      options.complete();
    }
  }, {
    key: "_getOs",
    value: function _getOs() {
      var a = navigator.userAgent;
      if (/Windows/i.test(a)) {
        if (/Phone/.test(a) || /WPDesktop/.test(a)) {
          return "Windows Phone";
        }
        return "Windows";
      } else if (/(iPhone|iPad|iPod)/.test(a)) {
        return "iOS";
      } else if (/Android/.test(a)) {
        return "Android";
      } else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
        return "BlackBerry";
      } else if (/Mac/i.test(a)) {
        return "MacOS";
      } else if (/Linux/.test(a)) {
        return "Linux";
      } else if (/CrOS/.test(a)) {
        return "ChromeOS";
      } else {
        return "";
      }
    }

    /**
     * Get network type asynchronously
     * @param {object} options: callback when getting completion
     * res.networkType string: network type
     */
  }, {
    key: "getNetworkType",
    value: function getNetworkType(options) {
      options.complete();
    }

    /**
     * Listen for network state change
     * @param {function} callback: callback when network state changing
     */
  }, {
    key: "onNetworkStatusChange",
    value: function onNetworkStatusChange() {}

    /**
     * Make a network request
     * @param {object} options: parameters, including:
     *   url       string         server url
     *   data      string/object  request parameters
     *   method    string         HTTP method
     *   success   function       success callback
     *   fail      function       fail callback
     *   complete  function       complete callback
     */
  }, {
    key: "request",
    value: function request(options) {
      var res = {};
      var xhr = new XMLHttpRequest();
      xhr.open(options.method, options.url);
      if (options.header) {
        for (var key in options.header) {
          xhr.setRequestHeader(key, options.header[key]);
        }
      }
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          res["statusCode"] = 200;
          if (_.isJSONString(xhr.responseText)) {
            res["data"] = JSON.parse(xhr.responseText);
          }
          options.success(res);
        } else if (xhr.status !== 200) {
          res.errMsg = "network error";
          options.fail(res);
        }
      };
      xhr.ontimeout = function () {
        res.errMsg = "timeout";
        options.fail(res);
      };
      xhr.send(options.data);
      return xhr;
    }
  }, {
    key: "initAutoTrackInstance",
    value: function initAutoTrackInstance(instance, config) {
      this.instance = instance;
      this.autoTrack = config.autoTrack;
      var _that = this;
      _that.onPageShow();
      if (_that.autoTrack.appHide) {
        _that.instance.timeEvent("ta_page_hide");
      }
      if ("onvisibilitychange" in document) {
        document.onvisibilitychange = function () {
          if (document.hidden) {
            _that.onPageHide(true);
          } else {
            _that.onPageShow();
            if (_that.autoTrack.appHide) {
              _that.instance.timeEvent("ta_page_hide");
            }
          }
        };
      }
    }
  }, {
    key: "setGlobal",
    value: function setGlobal(instance, name) {
      window[name] = instance;
    }

    /**
     * Get system startup information, and register APP cut-off foreground callback
     * @TODO
     */
  }, {
    key: "getAppOptions",
    value: function getAppOptions() {}

    /**
     * Toast Debug information
     * @param {string} msg: information to display
     */
  }, {
    key: "showToast",
    value: function showToast() {}
  }, {
    key: "onPageShow",
    value: function onPageShow() {
      if (this.autoTrack.appShow) {
        var properties = {};
        _.extend(properties, this.autoTrack.properties);
        if (_.isFunction(this.autoTrack.callback)) {
          _.extend(properties, this.autoTrack.callback("appShow"));
        }
        this.instance._internalTrack("ta_page_show", properties);
      }
    }
  }, {
    key: "onPageHide",
    value: function onPageHide(tryBeacon) {
      if (this.autoTrack.appHide) {
        var properties = {};
        _.extend(properties, this.autoTrack.properties);
        if (_.isFunction(this.autoTrack.callback)) {
          _.extend(properties, this.autoTrack.callback("appHide"));
        }
        this.instance._internalTrack("ta_page_hide", properties, new Date(), null, tryBeacon);
      }
    }
  }, {
    key: "setGlobalData",
    value: function setGlobalData(_data) {}
  }], [{
    key: "createInstance",
    value: function createInstance() {
      return new PlatformProxy();
    }
  }]);
}();

// const DEFAULT_SHARE_DEPTH = 1;

var mpHooks = {
  data: 1,
  onLoad: 1,
  onShow: 1,
  onReady: 1,
  onPullDownRefresh: 1,
  onShareAppMessage: 1,
  onShareTimeline: 1,
  onReachBottom: 1,
  onPageScroll: 1,
  onResize: 1,
  onTabItemTap: 1,
  onHide: 1,
  onUnload: 1,
  onAddToFavorites: 1
};
var AutoTrackBridge = /*#__PURE__*/function () {
  function AutoTrackBridge(instance, config) {
    _classCallCheck(this, AutoTrackBridge);
    this.taInstance = instance;
    this.config = config.autoTrack || {};
    this.disablePresetList = config.disablePresetProperties || [];
    this.referrer = 'Directly open';
    if (this.config.isPlugin) {
      instance.App = function () {
        App.apply(this, arguments);
      };
      inension(instance.Page);
    } else {
      var originalApp = App;
      App = this._initAppExtention(originalApp);
      var originalPage = Page;
      Page = this._initPageExtension(originalPage);
    }
  }
  return _createClass(AutoTrackBridge, [{
    key: "_initPageExtension",
    value: function _initPageExtension(Page) {
      var _that = this;
      return function (page) {
        var onShow = page.onShow,
          onShareAppMessage = page.onShareAppMessage,
          onUnload = page.onUnload,
          onAddToFavorites = page.onAddToFavorites;
        page.onShow = function (options) {
          _that.onPageShow();
          if (typeof onShow === 'function') {
            onShow.call(this, options);
          }
        };
        if (typeof onShareAppMessage === 'function') {
          page.onShareAppMessage = function (object) {
            var ret = onShareAppMessage.call(this, object);
            return _that.onPageShare(ret);
          };
        }
        page.onUnload = function () {
          _that.onPageUnload();
          if (typeof onUnload === 'function') {
            onUnload.call(this);
          }
        };
        page.onAddToFavorites = function () {
          _that.onPageAddToFavorites();
          if (typeof onAddToFavorites === 'function') {
            onAddToFavorites.call(this);
          }
        };
        _that._handleClickProxy(page);
        return Page(page);
      };
    }
  }, {
    key: "_handleClickProxy",
    value: function _handleClickProxy(option) {
      if (this.config.mpClick) {
        var methods = [];
        for (var m in option) {
          if (typeof option[m] === 'function' && !mpHooks[m]) {
            methods.push(m);
          }
        }
        for (var i = 0; i < methods.length; i++) {
          this.clickMethodProxy(option, methods[i]);
        }
      }
    }
  }, {
    key: "clickMethodProxy",
    value: function clickMethodProxy(option, method) {
      var _that = this;
      var oldFunc = option[method];
      option[method] = function () {
        var res = oldFunc.call(this, arguments);
        var args = arguments[0];
        if (_.isObject(args)) {
          _that._trackClickEvent(args);
        }
        return res;
      };
    }
  }, {
    key: "_trackClickEvent",
    value: function _trackClickEvent(events) {
      var currentTarget = events.currentTarget || {};
      var target = events.target || {};
      if (target.id && currentTarget.id && target.id !== currentTarget.id) {
        return;
      }
      var prop = {};
      var type = events['type'];
      if (type && _.isClickType(type)) {
        var dataset = currentTarget.dataset || {};
        if (!this.disablePresetList.includes('#element_id')) {
          prop['#element_id'] = currentTarget.id;
        }
        if (!this.disablePresetList.includes('#element_type')) {
          prop['#element_type'] = dataset['type'];
        }
        if (!this.disablePresetList.includes('#element_content')) {
          prop['#element_content'] = dataset['content'];
        }
        if (!this.disablePresetList.includes('#element_name')) {
          prop['#element_name'] = dataset['name'];
        }
        if (!this.disablePresetList.includes('#url_path')) {
          prop['$url_path'] = this._getCurrentPath();
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('mpClick'));
        }
        this.taInstance._internalTrack('ta_mp_click', prop);
      }
    }
  }, {
    key: "_initAppExtention",
    value: function _initAppExtention(App) {
      var _that = this;
      return function (app) {
        var onLaunch = app.onLaunch,
          onShow = app.onShow,
          onHide = app.onHide;
        app.onLaunch = function (options) {
          _that.onAppLaunch(options, this);
          if (typeof onLaunch === 'function') {
            onLaunch.call(this, options);
          }
        };
        app.onShow = function (options) {
          _that.onAppShow(options);
          if (typeof onShow === 'function') {
            onShow.call(this, options);
          }
        };
        app.onHide = function () {
          _that.onAppHide();
          if (typeof onHide === 'function') {
            onHide.call(this);
          }
        };
        return App(app);
      };
    }
  }, {
    key: "onAppLaunch",
    value: function onAppLaunch(options, app) {
      this._setAutoTrackProperties(options);
      if (!_.isUndefined(app)) {
        app[this.taInstance.name] = this.taInstance;
      }
      if (this.config.appLaunch) {
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          if (options && options.path) {
            prop['#url_path'] = this._getPath(options.path);
          }
        }
        if (options) {
          if (!this.disablePresetList.includes('#utm')) {
            if (options.query) {
              prop['#utm'] = _.getUtmFromQuery(options.query);
            }
          }
          if (!this.disablePresetList.includes('#start_reason')) {
            prop['#start_reason'] = JSON.stringify(options);
          }
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('appLaunch'));
        }
        this.taInstance._internalTrack('ta_mp_launch', prop);
      }
    }
  }, {
    key: "onAppShow",
    value: function onAppShow(options) {
      if (this.config.appHide) {
        this.taInstance.timeEvent('ta_mp_hide');
      }
      this._setAutoTrackProperties(options);
      if (this.config.appShow) {
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          if (options && options.path) {
            prop['#url_path'] = this._getPath(options.path);
          }
        }
        if (options) {
          if (!this.disablePresetList.includes('#utm')) {
            if (options.query) {
              prop['#utm'] = _.getUtmFromQuery(options.query);
            }
          }
          if (!this.disablePresetList.includes('#start_reason')) {
            prop['#start_reason'] = JSON.stringify(options);
          }
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('appShow'));
        }
        this.taInstance._internalTrack('ta_mp_show', prop);
      }
    }
  }, {
    key: "onAppHide",
    value: function onAppHide() {
      if (this.config.appHide) {
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          prop['#url_path'] = this._getCurrentPath();
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('appHide'));
        }
        this.taInstance._internalTrack('ta_mp_hide', prop);
        this.taInstance.flush();
      }
    }
  }, {
    key: "_getCurrentPath",
    value: function _getCurrentPath() {
      var url = 'Not to get';
      try {
        // eslint-disable-next-line no-undef
        var pages = getCurrentPages();
        var currentPage = pages[pages.length - 1];
        url = currentPage.route; // Modify carefully, the ByteDance applet needs to replace this line of code. If you need to modify, please modify rollup.config.js synchronously
      } catch (e) {
        logger.info(e);
      }
      return url;
    }
  }, {
    key: "_setAutoTrackProperties",
    value: function _setAutoTrackProperties(options) {
      var props = {};
      if (!this.disablePresetList.includes('#scene')) {
        props['#scene'] = options.scene;
      }
      /*
      if (options && _.isObject(options.query) && options.query.tashare) {
          var shareInfo = _.decodeURIComponent(options.query.tashare);
          if (_.isJSONString(shareInfo)) {
              this.shareInfo = JSON.parse(shareInfo);
              props['#share_depth'] = _.isNumber(this.shareInfo.d) ? this.shareInfo.d : DEFAULT_SHARE_DEPTH;
          }
      }
      */

      this.taInstance._setAutoTrackProperties(props);
    }

    // _getShareDepth() {
    //     var shareInfo = this.shareInfo || {};
    //     if ((shareInfo.a && shareInfo.a === this.taInstance.getAccountId()) || (shareInfo.i && shareInfo.i === this.taInstance.getDistinctId())) {
    //         return shareInfo.d;
    //     } else if (shareInfo.d) {
    //         return shareInfo.d + 1;
    //     } else {
    //         return DEFAULT_SHARE_DEPTH;
    //     }
    // }
  }, {
    key: "_getPath",
    value: function _getPath(path) {
      return path = 'string' === typeof path ? path.replace(/^\//, '') : 'Abnormal values';
    }
  }, {
    key: "_generateShareInfo",
    value: function _generateShareInfo() {
      return JSON.stringify({
        distinctId: this.taInstance.getDistinctId()
      });
    }
  }, {
    key: "onPageShare",
    value: function onPageShare(result) {
      var ret = _.isObject(result) ? result : {};
      if (this.config.pageShare) {
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          prop['#url_path'] = this._getCurrentPath();
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('pageShare'));
        }
        this.taInstance._internalTrack('ta_mp_share', prop);
        if (_.isUndefined(ret.path) || ret.path === '') {
          ret.path = this._getCurrentPath();
        }
        if (_.isString(ret.path)) {
          if (-1 === ret.path.indexOf('?')) {
            ret.path = ret.path + '?';
          } else if ('&' !== ret.path.slice(-1)) {
            ret.path = ret.path + '&';
          }
          ret.path = ret.path + 'tdshare=' + encodeURIComponent(this._generateShareInfo());
        }
      }
      return ret;
    }
  }, {
    key: "onPageShow",
    value: function onPageShow() {
      if (this.config.pageLeave) {
        this.taInstance.timeEvent('ta_page_leave');
      }
      if (this.config.pageShow) {
        var path = this._getCurrentPath();
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          prop['#url_path'] = path || 'The system did not get a value';
        }
        if (!this.disablePresetList.includes('#referrer')) {
          prop['#referrer'] = this.referrer;
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('pageShow'));
        }
        this.referrer = path;
        this.taInstance._internalTrack('ta_mp_view', prop);
      }
    }
  }, {
    key: "onPageUnload",
    value: function onPageUnload() {
      if (this.config.pageLeave) {
        var path = this._getCurrentPath();
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          prop['#url_path'] = path || 'The system did not get a value';
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('pageLeave'));
        }
        this.taInstance._internalTrack('ta_page_leave', prop);
      }
    }
  }, {
    key: "onPageAddToFavorites",
    value: function onPageAddToFavorites() {
      if (this.config.mpFavorite) {
        var path = this._getCurrentPath();
        var prop = {};
        if (!this.disablePresetList.includes('#url_path')) {
          prop['#url_path'] = path || 'The system did not get a value';
        }
        _.extend(prop, this.config.properties);
        if (_.isFunction(this.config.callback)) {
          _.extend(prop, this.config.callback('mpFavorite'));
        }
        this.taInstance._internalTrack('ta_add_favorite', prop);
      }
    }
  }]);
}();

// import AutoTrackBridgeMG from './AutoTrack.mg';
var PlatformProxy$1 = /*#__PURE__*/function () {
  function PlatformProxy$1(api, platformConfig, internalConfig) {
    _classCallCheck(this, PlatformProxy$1);
    this.api = api;
    this.config = platformConfig;
    this._config = internalConfig;
  }
  return _createClass(PlatformProxy$1, [{
    key: "getConfig",
    value:
    /**
     * Get platform specific configuration: persistenceName required
     */
    function getConfig() {
      return this.config;
    }
  }, {
    key: "initSdkConfig",
    value: function initSdkConfig(_config) {
      // Empty implementation for mini-program platforms
    }

    /**
     * Get local cache data
     * @param {string} name: cache key
     * @param {boolean} async: enable asynchronous getting cached
     * @param {function} callback: callback when getting data asynchronously, the parameter is an object
     * @return return cached data, it is an object
     */
  }, {
    key: "getStorage",
    value: function getStorage(name, async, callback) {
      if (async) {
        this.api.getStorage({
          key: name,
          success: function success(res) {
            var data = _.isJSONString(res.data) ? JSON.parse(res.data) : {};
            callback(data);
          },
          fail: function fail() {
            logger.warn("getStorage faild");
            callback({});
          }
        });
      } else {
        try {
          if (this._config.platform === "dd_mp" || this._config.platform === "ali_mp" || this._config.platform === "ali_mg") {
            var res = this.api.getStorageSync({
              key: name
            });
            if (_.isJSONString(res.data)) {
              return JSON.parse(res.data);
            } else {
              return {};
            }
          }
          var data = this.api.getStorageSync(name);
          if (_.isJSONString(data)) {
            return JSON.parse(data);
          } else {
            return {};
          }
        } catch (e) {
          return {};
        }
      }
    }

    /**
     * Set local cache data
     * @param {string} name: cache key
     * @param {string} value: JSON string value
     */
  }, {
    key: "setStorage",
    value: function setStorage(name, value) {
      try {
        if (this._config.platform === "ali_mp" || this._config.platform === "dd_mp" || this._config.platform === "ali_mg") {
          this.api.setStorageSync({
            key: name,
            data: value
          });
        } else {
          this.api.setStorageSync(name, value);
        }
      } catch (e) {
        // eslint-disable-next-line no-empty
      }
    }

    /**
     * Delete data in local cache with key
     * @param {*} name: cache key
     */
  }, {
    key: "removeStorage",
    value: function removeStorage(name) {
      try {
        if (_.isFunction(this.api.removeStorage)) {
          this.api.removeStorage({
            key: name
          });
        } else if (_.isFunction(this.api.deleteStorage)) {
          this.api.deleteStorage({
            key: name
          });
        }
      } catch (e) {
        // eslint-disable-next-line no-empty
      }
    }
  }, {
    key: "_getPlatform",
    value: function _getPlatform() {
      return "";
    }

    /**
     * Get system information asynchronously
     * @param {object} options: callback when getting completion
     * callback parameter:
     * brand: string, device brand
     * model: string, device model
     * screenWidth: number, screen width, unit px
     * screenHeight: number, screen height, unit px
     * system: string, operating system and version
     * platform: string, client platform
     */
  }, {
    key: "getSystemInfo",
    value: function getSystemInfo(options) {
      var platform = this._config.mpPlatform;
      var self = this;
      this.api.getSystemInfo({
        success: function success(res) {
          if (_.isFunction(platform)) {
            res["mp_platform"] = platform(res);
          } else {
            res["mp_platform"] = platform;
          }
          if (self._config.platform === "ali_mp" || self._config.platform === "ali_mg") {
            res["system"] = res["platform"] + " " + res["system"];
          }
          if (self._config.platform === "wechat_mp" || self._config.platform === "wechat_mg") {
            var accountInfo = self.api.getAccountInfoSync();
            res["appVersion"] = accountInfo.miniProgram.version;
          } else if (self._config.platform === "tt_mg" || self._config.platform === "tt_mg") {
            res["appVersion"] = self.api.getEnvInfoSync().microapp.mpVersion;
          }
          options.success(res);
          if (platform === "wechat") {
            //Sometimes the WeChat platform complete will not call back,
            //you need to call options.complete in the success callback to complete the acquisition of system information
            options.complete();
          }
        },
        complete: function complete() {
          options.complete();
        }
      });
    }

    /**
     * Get network type asynchronously
     * @param {object} options: callback when getting completion
     * res.networkType string: network type
     */
  }, {
    key: "getNetworkType",
    value: function getNetworkType(options) {
      if (!_.isFunction(this.api.getNetworkType)) {
        options.success({});
        options.complete();
      } else {
        this.api.getNetworkType({
          success: function success(res) {
            options.success(res);
          },
          complete: function complete() {
            options.complete();
          }
        });
      }
    }

    /**
     * Listen for network state change
     * @param {function} callback: callback when network state changing
     */
  }, {
    key: "onNetworkStatusChange",
    value: function onNetworkStatusChange(callback) {
      if (!_.isFunction(this.api.onNetworkStatusChange)) {
        callback({});
      } else {
        this.api.onNetworkStatusChange(callback);
      }
    }

    /**
     * Make a network request
     * @param {object} options: parameters, including:
     *   url       string         server url
     *   data      string/object  request parameters
     *   method    string         HTTP method
     *   success   function       success callback
     *   fail      function       fail callback
     *   complete  function       complete callback
     */
  }, {
    key: "request",
    value: function request(options) {
      if (this._config.platform === "ali_mp" || this._config.platform === "dd_mp" || this._config.platform === "ali_mg") {
        var config = _.extend({}, options);
        config.headers = options.header;
        config.header = undefined;
        config.success = function (res) {
          res.statusCode = res.status;
          options.success(res);
        };
        config.fail = function (res) {
          res.errMsg = res.errorMessage;
          options.fail(res);
        };
        if (this._config.platform === "dd_mp") {
          return this.api.httpRequest(config);
        } else {
          return this.api.request(config);
        }
      } else {
        return this.api.request(options);
      }
    }

    /**
     * Initialize the lifecycle monitoring instance
     * @param {FunsDataAPI} instance: SDK instance, listen lifecycle of application
     * @param {object} config: auto-tracking events config
     */
  }, {
    key: "initAutoTrackInstance",
    value: function initAutoTrackInstance(instance, config) {
      if (_.isObject(config.autoTrack)) {
        config.autoTrack["isPlugin"] = config.is_plugin;
      }
      if (this._config.mp) {
        return new AutoTrackBridge(instance, config, this.api);
      }
    }
  }, {
    key: "setGlobal",
    value: function setGlobal(instance, name) {
      if (this._config.mp) {
        logger.warn("Analytics: we do not set global name for Analytics instance when you do not enable auto track.");
      } else {
        if (this._config.platform !== "ali_mg") {
          GameGlobal[name] = instance;
        }
      }
    }

    /**
     * Get system startup information, and register APP cut-off foreground callback
     * @param {function} callback
     */
  }, {
    key: "getAppOptions",
    value: function getAppOptions(callback) {
      var options = {};
      try {
        options = this.api.getLaunchOptionsSync();
      } catch (e) {
        logger.warn("Cannot get launch options.");
      }
      if (_.isFunction(callback)) {
        try {
          if (this._config.mp) {
            this.api.onAppShow(callback);
          } else {
            this.api.onShow(callback);
          }
        } catch (e) {
          logger.warn("Cannot register onShow callback.");
        }
      }
      return options;
    }

    /**
     * Toast Debug information
     * @param {string} msg: information to display
     */
  }, {
    key: "showToast",
    value: function showToast(msg) {
      if (_.isFunction(this.api.showToast)) {
        var content = {
          title: msg
        };
        if (this._config.platform === "dd_mp" || this._config.platform === "ali_mp") {
          content.content = msg;
        }
        this.api.showToast(content);
      }
    }
  }, {
    key: "setGlobalData",
    value: function setGlobalData(data) {
      if (this._config.platform === "wechat_mg") {
        if (GameGlobal) {
          GameGlobal.tdanalytics2024 = data;
        }
      } else if (this._config.platform === "ali_mp") {
        global.tdanalytics2024 = data;
      } else if (this._config.platform === "tt_mp" || this._config.platform === "kuaishou_mp") {
        this.api.tdanalytics2024 = data;
      } else {
        globalThis.tdanalytics2024 = data;
      }
    }
  }], [{
    key: "createInstance",
    value: function createInstance() {
      // rollup will replace the following strings with the corresponding platforms when packaging
      return this._createInstance("wechat_mp");
    }
  }, {
    key: "_createInstance",
    value: function _createInstance(option) {
      switch (option) {
        // for historical reason, we use different persistence names for different platforms.
        case "wechat_mp":
          return new PlatformProxy$1(wx, {
            persistenceName: "funsdata",
            persistenceNameOld: "funsdata_wechat",
            plat: "wx"
          }, {
            mpPlatform: "wechat",
            mp: true,
            platform: option
          });
        case "tt_mp":
          return new PlatformProxy$1(tt, {
            persistenceName: "funsdata",
            persistenceNameOld: "funsdata_tt"
          }, {
            mpPlatform: function mpPlatform(res) {
              return res["appName"];
            },
            mp: true,
            platform: option
          });
        case "ali_mp":
          return new PlatformProxy$1(my, {
            persistenceName: "funsdata",
            persistenceNameOld: "funsdata_ali"
          }, {
            mpPlatform: function mpPlatform(res) {
              return res["app"];
            },
            mp: true,
            platform: option
          });

        // case 'qtt_mg':
        //     return new PlatformProxy(qttGame.systemInfo, {persistenceName: 'thinkingdata', persistenceNameOld: 'thinkingdata_qtt'}, {mpPlatform: 'qutoutiao', platform: option });
        // case 'linksure_mg':
        //     return new PlatformProxy(wuji, {persistenceName: 'thinkingdata', persistenceNameOld: 'thinkingdata_linksure'}, {mpPlatform: 'linksure', platform: option });

        case "WEB":
          return new PlatformProxy.createInstance();
      }
    }
  }]);
}();

var PlatformAPI = /*#__PURE__*/function () {
  function PlatformAPI() {
    _classCallCheck(this, PlatformAPI);
  }
  return _createClass(PlatformAPI, null, [{
    key: "_getCurrentPlatform",
    value: function _getCurrentPlatform() {
      return this.currentPlatform || (this.currentPlatform = PlatformProxy$1.createInstance());
    }

    /**
     * Get platform specific configuration: persistenceName required
     */
  }, {
    key: "getConfig",
    value: function getConfig() {
      return this._getCurrentPlatform().getConfig();
    }
  }, {
    key: "initConfig",
    value: function initConfig(config) {
      this._getCurrentPlatform().initSdkConfig(config);
    }
  }, {
    key: "isWxPlat",
    value: function isWxPlat() {
      return this.getConfig().plat === 'wx';
    }

    /**
     * Get local cache data
     * @param {string} name: cache key
     * @param {boolean} async: enable asynchronous getting cached
     * @param {function} callback: callback when getting data asynchronously, the parameter is an object
     * @return return cached data, it is an object
     */
  }, {
    key: "getStorage",
    value: function getStorage(name, async, callback) {
      return this._getCurrentPlatform().getStorage(name, async, callback);
    }

    /**
     * Set local cache data
     * @param {string} name: cache key
     * @param {string} value: JSON string value
     */
  }, {
    key: "setStorage",
    value: function setStorage(name, value) {
      return this._getCurrentPlatform().setStorage(name, value);
    }

    /**
     * Delete data in local cache with key
     * @param {*} name: cache key
     */
  }, {
    key: "removeStorage",
    value: function removeStorage(name) {
      return this._getCurrentPlatform().removeStorage(name);
    }

    /**
     * Get system information asynchronously
     * @param {object} options: callback when getting completion
     * callback parameter:
        * brand: string, device brand
        * model: string, device model
        * screenWidth: number, screen width, unit px
        * screenHeight: number, screen height, unit px
        * system: string, operating system and version
        * platform: string, client platform
     */
  }, {
    key: "getSystemInfo",
    value: function getSystemInfo(options) {
      return this._getCurrentPlatform().getSystemInfo(options);
    }

    /**
     * Get network type asynchronously
     * @param {object} options: callback when getting completion
     * res.networkType string: network type
     */
  }, {
    key: "getNetworkType",
    value: function getNetworkType(options) {
      return this._getCurrentPlatform().getNetworkType(options);
    }

    /**
     * Listen for network state change
     * @param {function} callback: callback when network state changing
     */
  }, {
    key: "onNetworkStatusChange",
    value: function onNetworkStatusChange(callback) {
      this._getCurrentPlatform().onNetworkStatusChange(callback);
    }

    /**
     * Make a network request
     * @param {object} options: parameters, including:
     *   url       string         server url
     *   data      string/object  request parameters
     *   method    string         HTTP method
     *   success   function       success callback
     *   fail      function       fail callback
     *   complete  function       complete callback
     */
  }, {
    key: "request",
    value: function request(options) {
      return this._getCurrentPlatform().request(options);
    }

    /**
     * Initialize the lifecycle monitoring instance
     * @param {FunsDataAPI} instance: SDK instance, listen lifecycle of application
     * @param {object} config: auto-tracking events config
     */
  }, {
    key: "initAutoTrackInstance",
    value: function initAutoTrackInstance(instance, config) {
      return this._getCurrentPlatform().initAutoTrackInstance(instance, config);
    }

    /**
     * Set instance to global
     * @param {object} instance
     * @param {string} name
     */
  }, {
    key: "setGlobal",
    value: function setGlobal(instance, name) {
      if (instance && name) {
        this._getCurrentPlatform().setGlobal(instance, name);
      }
    }

    /**
     * Get system startup information, and register APP cut-off foreground callback
     * @param {function} callback
     */
  }, {
    key: "getAppOptions",
    value: function getAppOptions(callback) {
      return this._getCurrentPlatform().getAppOptions(callback);
    }

    /**
     * Toast Debug information
     * @param {string} msg: information to display
     */
  }, {
    key: "showDebugToast",
    value: function showDebugToast(msg) {
      this._getCurrentPlatform().showToast(msg);
    }
  }, {
    key: "setGlobalData",
    value: function setGlobalData(data) {
      this._getCurrentPlatform().setGlobalData(data);
    }
  }]);
}();

var HttpTask = /*#__PURE__*/function () {
  function HttpTask(data, serverUrl, tryCount, timeout, callback) {
    _classCallCheck(this, HttpTask);
    this.data = data;
    this.serverUrl = serverUrl;
    this.callback = callback;
    this.tryCount = _.isNumber(tryCount) ? tryCount : 1;
    this.timeout = _.isNumber(timeout) ? timeout : 3000;
    this.taClassName = 'HttpTask';
  }
  return _createClass(HttpTask, [{
    key: "run",
    value: function run() {
      var that = this;
      var headers = _.createExtraHeaders();
      headers['content-type'] = 'application/json';
      // eslint-disable-next-line no-undef
      this.runTime = _.getCurrentTimeStamp();
      PlatformAPI.request({
        url: this.serverUrl,
        method: 'POST',
        data: this.data,
        header: headers,
        success: function success(res) {
          that.onSuccess(res);
        },
        fail: function fail(res) {
          that.onFailed(res);
        }
      });
    }
  }, {
    key: "onSuccess",
    value: function onSuccess(res) {
      if (this.sendTimeout()) {
        return;
      }
      if (_.isObject(res) && res.statusCode === 200) {
        var msg;
        if (_.isUndefined(res.data) || _.isUndefined(res.data['code'])) {
          res['data'] = {
            'code': 0
          };
        }
        switch (res.data.code) {
          case 0:
            msg = 'success';
            break;
          case -1:
            msg = 'invalid data';
            break;
          case -2:
            msg = 'invalid APP ID';
            break;
          default:
            msg = 'Unknown return code';
        }
        this.callback({
          code: res.data.code,
          msg: msg
        });
      } else {
        this.callback({
          code: -3,
          msg: _.isObject(res) ? res.statusCode : 'Unknown error'
        });
      }
    }
  }, {
    key: "onFailed",
    value: function onFailed(res) {
      if (this.sendTimeout()) {
        return;
      }
      if (--this.tryCount > 0) {
        this.run();
      } else {
        this.callback({
          code: -3,
          msg: _.isObject(res) ? res.errMsg : 'Unknown error'
        });
      }
    }
  }, {
    key: "sendTimeout",
    value: function sendTimeout() {
      var curTime = _.getCurrentTimeStamp();
      if (curTime - this.runTime > this.timeout) {
        return true;
      }
      return false;
    }
  }]);
}();
var HttpTaskDebug = /*#__PURE__*/function () {
  function HttpTaskDebug(data, serverDebugUrl, tryCount, timeout, dryrun, deviceId, callback) {
    _classCallCheck(this, HttpTaskDebug);
    this.data = data;
    this.serverDebugUrl = serverDebugUrl;
    this.callback = callback;
    this.tryCount = _.isNumber(tryCount) ? tryCount : 1;
    this.timeout = _.isNumber(timeout) ? timeout : 3000;
    this.dryrun = dryrun;
    this.deviceId = deviceId;
    this.taClassName = 'HttpTaskDebug';
  }
  return _createClass(HttpTaskDebug, [{
    key: "run",
    value: function run() {
      var _this = this;
      var debugData = 'appid=' + this.data['#app_id'] + '&source=client&dryRun=' + this.dryrun + '&deviceId=' + this.deviceId + '&data=' + encodeURIComponent(JSON.stringify(this.data['data'][0]));
      var headers = _.createExtraHeaders();
      headers['content-type'] = 'application/x-www-form-urlencoded';
      // eslint-disable-next-line no-undef
      var request = PlatformAPI.request({
        url: this.serverDebugUrl,
        method: 'POST',
        data: debugData,
        header: headers,
        success: function success(res) {
          _this.onSuccess(res);
          clearTimeout(timer);
        },
        fail: function fail(res) {
          _this.onFailed(res);
          clearTimeout(timer);
        }
      });
      var timer = setTimeout(function () {
        if ((_.isObject(request) || _.isPromise(request)) && _.isFunction(request.abort)) {
          request.abort();
        }
      }, this.timeout);
    }
  }, {
    key: "onSuccess",
    value: function onSuccess(res) {
      if (_.isObject(res) && res.statusCode === 200) {
        var msg;
        if (_.isUndefined(res.data) || _.isUndefined(res.data['errorLevel'])) {
          res['data'] = {
            'errorLevel': 0
          };
        }
        if (res.data['errorLevel'] === 0) {
          msg = 'Verify data success.';
        } else if (res.data['errorLevel'] === 1) {
          var errorProperties = res.data['errorProperties'];
          var errorStr = '';
          for (var i = 0; i < errorProperties.length; i++) {
            var errorReasons = errorProperties[i]['errorReason'];
            var propertyName = errorProperties[i]['propertyName'];
            errorStr = errorStr + ' propertyName:' + propertyName + ' errorReasons:' + errorReasons + '\n';
          }
          msg = 'Debug data error. errorLevel:' + res.data['errorLevel'] + ' reason:' + errorStr;
        } else if (res.data['errorLevel'] === 2 || res.data['errorLevel'] === -1) {
          msg = 'Debug data error. errorLevel:' + res.data['errorLevel'] + ' reason:' + res.data['errorReasons'];
        }
        logger.info(msg);
        this.callback({
          code: res.data['errorLevel'],
          msg: msg
        });
      } else {
        this.callback({
          code: -3,
          msg: _.isObject(res) ? res.statusCode : 'Unknown error'
        });
      }
    }
  }, {
    key: "onFailed",
    value: function onFailed(res) {
      if (--this.tryCount > 0) {
        this.run();
      } else {
        this.callback({
          code: -3,
          msg: _.isObject(res) ? res.errMsg : 'Unknown error'
        });
      }
    }
  }]);
}();
var SenderQueue = /*#__PURE__*/function () {
  function SenderQueue() {
    _classCallCheck(this, SenderQueue);
    this.items = [];
    this.isRunning = false;
    this.showDebug = false;
  }
  return _createClass(SenderQueue, [{
    key: "enqueue",
    value: function enqueue(data, serverUrl, config) {
      var _this2 = this;
      var _enqueue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
      var element;
      var that = this;
      if (config.debugMode === 'debug') {
        element = new HttpTaskDebug(data, serverUrl, config.maxRetries, config.sendTimeout, 0, config.deviceId, function (res) {
          that.isRunning = false;
          delete _this2.runTime;
          if (_.isFunction(config.callback)) {
            config.callback(res);
          }
          that._runNext();
          if (that.showDebug === false) {
            if (res.code === 0 || res.code === 1 || res.code === 2) {
              that.showDebug = true;
              // eslint-disable-next-line no-undef
              if (_.isFunction(PlatformAPI.showDebugToast)) {
                // eslint-disable-next-line no-undef
                PlatformAPI.showDebugToast('The current mode is Debug');
              }
            }
          }
        });
      } else if (config.debugMode === 'debugOnly') {
        element = new HttpTaskDebug(data, serverUrl, config.maxRetries, config.sendTimeout, 1, config.deviceId, function (res) {
          that.isRunning = false;
          delete _this2.runTime;
          if (_.isFunction(config.callback)) {
            config.callback(res);
          }
          that._runNext();
          if (that.showDebug === false) {
            if (res.code === 0 || res.code === 1 || res.code === 2) {
              that.showDebug = true;
              // eslint-disable-next-line no-undef
              if (_.isFunction(PlatformAPI.showDebugToast)) {
                // eslint-disable-next-line no-undef
                PlatformAPI.showDebugToast('The current mode is debugOnly');
              }
            }
          }
        });
      } else {
        element = new HttpTask(JSON.stringify(data), serverUrl, config.maxRetries, config.sendTimeout, function (res) {
          that.isRunning = false;
          delete _this2.runTime;
          if (_.isFunction(config.callback)) {
            config.callback(res);
          }
          that._runNext();
        });
      }
      if (_enqueue === true) {
        this.items.push(element);
        this._runNext();
      } else {
        element.run();
      }
    }
  }, {
    key: "_dequeue",
    value: function _dequeue() {
      return this.items.shift();
    }
  }, {
    key: "_runNext",
    value: function _runNext() {
      if (this.items.length > 0 && !this.isRunning) {
        this.isRunning = true;
        this.runTime = _.getCurrentDate();
        if (this.items[0].taClassName !== 'HttpTask') {
          this._dequeue().run();
        } else {
          var items = this.items.splice(0, this.items.length);
          var httpTask0 = items[0];
          var data = JSON.parse(httpTask0.data);
          var appId = data['#app_id'];
          var callbackList = [];
          callbackList.push(httpTask0.callback);
          for (var i = 1; i < items.length; i++) {
            var task = items[i];
            var taskData = JSON.parse(task.data);
            if (taskData['#app_id'] === appId && httpTask0.serverUrl === task.serverUrl) {
              data['data'] = data['data'].concat(taskData['data']);
              callbackList.push(task.callback);
            } else {
              // If serverUrl and appId is different, it needs to be put back into the queue and sent next time
              this.items.push(task);
            }
          }
          var flushTime = _.getCurrentTimeStamp();
          data['#flush_time'] = flushTime;
          var element;
          element = new HttpTask(JSON.stringify(data), httpTask0.serverUrl, httpTask0.tryCount, httpTask0.timeout, function (res) {
            for (var cb in callbackList) {
              if (Object.hasOwnProperty.call(callbackList, cb)) {
                var _element = callbackList[cb];
                _element(res);
              }
            }
          });
          element.run();
        }
      }
    }
  }, {
    key: "runTimeout",
    value: function runTimeout(sendTimeout) {
      if (_.isDate(this.runTime)) {
        var nowDate = _.getCurrentDate();
        if (nowDate.getTime() - this.runTime.getTime() > sendTimeout) {
          return true;
        }
      }
      return false;
    }
  }, {
    key: "resetTimeout",
    value: function resetTimeout() {
      this.isRunning = false;
      delete this.runTime;
    }
  }]);
}();
var senderQueue = new SenderQueue();

var DEFAULT_CONFIG = {
  name: "funsdata",
  // global name
  // eslint-disable-next-line camelcase
  is_plugin: false,
  // if is it plugin. Basic library < 2.6.4 does not allow modification of App and Page
  maxRetries: 3,
  // number of retries for data reporting requests. v1.3.0+
  sendTimeout: 3000,
  // request timeout, Ms
  enablePersistence: true,
  // enable local storage
  asyncPersistence: false,
  // enable asynchronous storage
  enableLog: true,
  // enable printing logs
  strict: false,
  // disable strict data format checking, allow possible problem data to be reported
  debugMode: "none",
  // Debug mode (none/debug/debugOnly)
  enableCalibrationTime: false,
  enableBatch: false,
  disablePresetProperties: [],
  cloudEnv: "online",
  reportingToTencentSdk: 3
};

/**
 * Get system information asynchronously and initialize preset properties
 *
 * #lib: SDK type,
 * #lib_version: SDK version
 * #network_type: current network type
 * #manufacture: device manufactory
 * #device_model: device mode, e.g iPhone 8
 * #screen_width: device screen width
 * #screen_height: device screen height
 * #os: device os name
 * #os_version: device os version
 * #mp_platform: current platform name
 */
var systemInformation = {
  properties: {},
  disableList: [],
  initDisableList: function initDisableList(list) {
    this.disableList = list;
    if (!this.disableList.includes("#lib")) {
      this.properties["#lib"] = Config.LIB_NAME;
    }
    if (!this.disableList.includes("#lib_version")) {
      this.properties["#lib_version"] = Config.LIB_VERSION;
    }
  },
  initDeviceId: function initDeviceId(deviceId) {
    if (_.isString(deviceId)) {
      if (!this.disableList.includes("#device_id")) {
        this.properties["#device_id"] = deviceId;
      }
    }
  },
  getSystemInfo: function getSystemInfo(callback) {
    var that = this;
    PlatformAPI.onNetworkStatusChange(function (res) {
      if (!that.disableList.includes("#network_type")) {
        that.properties["#network_type"] = res.networkType;
      }
    });
    PlatformAPI.getNetworkType({
      success: function success(res) {
        if (!that.disableList.includes("#network_type")) {
          that.properties["#network_type"] = res.networkType;
        }
      },
      complete: function complete() {
        PlatformAPI.getSystemInfo({
          success: function success(res) {
            var osInfo = res["system"] ? res["system"].replace(/\s+/g, " ").split(" ") : [];
            var data = {};
            if (!that.disableList.includes("#manufacturer")) {
              data["#manufacturer"] = res["brand"];
            }
            if (!that.disableList.includes("#device_model")) {
              data["#device_model"] = res["model"];
            }
            if (!that.disableList.includes("#screen_width")) {
              data["#screen_width"] = Number(res["screenWidth"]);
            }
            if (!that.disableList.includes("#screen_height")) {
              data["#screen_height"] = Number(res["screenHeight"]);
            }
            if (!that.disableList.includes("#os")) {
              data["#os"] = osInfo[0];
            }
            if (!that.disableList.includes("#os_version")) {
              data["#os_version"] = osInfo[1];
            }
            if (!that.disableList.includes("#mp_platform")) {
              data["#mp_platform"] = res["mp_platform"];
            }
            if (!that.disableList.includes("#system_language")) {
              data["#system_language"] = res["systemLanguage"];
            }
            if (!that.disableList.includes("#app_version")) {
              data["#app_version"] = res["appVersion"];
            }
            _.extend(that.properties, data);
            _.setMpPlatform(res["mp_platform"]);
          },
          complete: function complete() {
            callback();
          }
        });
      }
    });
  }
};

/**
 * Data cache management class
 *
 * Keys :
 * 1. device_id: #device_id
 * 2. distinct_id: #distinct_id
 * 3. account_id: #account_id
 * 4. props: super properties
 * 5. event_timers: #duration
 *
 */
var FunsDataPersistence = /*#__PURE__*/function () {
  function FunsDataPersistence(config, callback) {
    var _this = this;
    _classCallCheck(this, FunsDataPersistence);
    this.enabled = config.enablePersistence;
    if (this.enabled) {
      if (config.isChildInstance) {
        this.name = config.persistenceName + "_" + config.name;
        this.nameOld = config.persistenceNameOld + "_" + config.name;
      } else {
        this.name = config.persistenceName;
        this.nameOld = config.persistenceNameOld;
      }
      if (config.asyncPersistence) {
        this._state = {};
        PlatformAPI.getStorage(this.name, true, function (data) {
          if (_.isEmptyObject(data)) {
            PlatformAPI.getStorage(_this.nameOld, true, function (dataOld) {
              _this._state = _.extend2Layers({}, dataOld, _this._state);
              _this._init(config, callback);
              _this._save();
            });
          } else {
            _this._state = _.extend2Layers({}, data, _this._state);
            _this._init(config, callback);
            _this._save();
          }
        });
      } else {
        this._state = PlatformAPI.getStorage(this.name) || {};
        if (_.isEmptyObject(this._state)) {
          this._state = PlatformAPI.getStorage(this.nameOld) || {};
        }
        this._init(config, callback);
      }
    } else {
      this._state = {};
      this._init(config, callback);
    }
  }
  return _createClass(FunsDataPersistence, [{
    key: "_init",
    value: function _init(config, callback) {
      if (!this.getDistinctId()) {
        this.setDistinctId(_.UUID());
      }
      if (!config.isChildInstance) {
        if (!this.getDeviceId()) {
          this._setDeviceId(_.UUID());
        }
        systemInformation.initDeviceId(this.getDeviceId());
      }

      // Mark sdk initialization is complete, you can write to the local cache
      this.initComplete = true;
      if (typeof callback === "function") {
        callback();
      }
      this._save();
    }
  }, {
    key: "_save",
    value: function _save() {
      if (this.enabled && this.initComplete) {
        PlatformAPI.setStorage(this.name, JSON.stringify(this._state));
      }
    }
  }, {
    key: "_set",
    value: function _set(name, value) {
      var _this2 = this;
      var obj;
      if (typeof name === "string") {
        obj = {};
        obj[name] = value;
      } else if (_typeof(name) === "object") {
        obj = name;
      }
      _.each(obj, function (value, key) {
        _this2._state[key] = value;
      });
      this._save();
    }
  }, {
    key: "_get",
    value: function _get(name) {
      return this._state[name];
    }
  }, {
    key: "setEventTimer",
    value: function setEventTimer(eventName, timestamp) {
      var timers = this._state.event_timers || {};
      timers[eventName] = timestamp;
      this._set("event_timers", timers);
    }
  }, {
    key: "removeEventTimer",
    value: function removeEventTimer(eventName) {
      var timers = this._state.event_timers || {};
      var timestamp = timers[eventName];
      if (!_.isUndefined(timestamp)) {
        delete this._state.event_timers[eventName];
        this._save();
      }
      return timestamp;
    }
  }, {
    key: "getDeviceId",
    value: function getDeviceId() {
      return this._state.device_id;
    }
  }, {
    key: "_setDeviceId",
    value: function _setDeviceId(deviceId) {
      if (this.getDeviceId()) {
        logger.warn("cannot modify the device id.");
        return;
      }
      this._set("device_id", deviceId);
    }
  }, {
    key: "getDistinctId",
    value: function getDistinctId() {
      return this._state.distinct_id;
    }
  }, {
    key: "setDistinctId",
    value: function setDistinctId(distinctId) {
      this._set("distinct_id", distinctId);
    }
  }, {
    key: "getAccountId",
    value: function getAccountId() {
      return this._state.account_id;
    }
  }, {
    key: "setAccountId",
    value: function setAccountId(accoundId) {
      this._set("account_id", accoundId);
    }
  }, {
    key: "getSuperProperties",
    value: function getSuperProperties() {
      return this._state.props || {};
    }
  }, {
    key: "setSuperProperties",
    value: function setSuperProperties(superProperties, replace) {
      var props = replace ? superProperties : _.extend(this.getSuperProperties(), superProperties);
      this._set("props", props);
    }
  }]);
}();
var dataStoragePrefix = "ta_mpsdk_";
var tabStoragePrefix = "tab_tampsdk_";
var BatchConsumer = /*#__PURE__*/function () {
  function BatchConsumer(config, value) {
    _classCallCheck(this, BatchConsumer);
    this.config = config;
    this.analytics = value;
    this.timer = null;
    this.batchConfig = _.extend({
      size: 6,
      //event batch size
      interval: 6000,
      //interval to send data in milliseconds
      maxLimit: 500 // event cache maximum limit
    }, this.config.batchConfig);
    if (this.batchConfig.size < 1) {
      this.batchConfig.size = 1;
    }
    if (this.batchConfig.size > 30) {
      this.batchConfig.size = 30;
    }
    this.storageKey = dataStoragePrefix + this.config.appId;
    this.maxLimit = this.batchConfig["maxLimit"];
    this.batchList = [];
    //Synchronize data not sent last time
    var storageList = PlatformAPI.getStorage(this.storageKey);
    if (_.isArray(storageList)) {
      this.batchList = storageList;
    }
    //Migrate old version historical data
    var tabKey = tabStoragePrefix + this.config.appId;
    var tabs = PlatformAPI.getStorage(tabKey);
    if (_.isArray(tabs)) {
      for (var i = 0; i < tabs.length; i++) {
        var oldItem = PlatformAPI.getStorage(tabs[i]);
        this.batchList.push(oldItem);
        PlatformAPI.removeStorage(tabs[i]);
      }
      PlatformAPI.removeStorage(tabKey);
    }
    this.dataHasChange = false;
    this.dataSendTimeStamp = 0;
  }
  return _createClass(BatchConsumer, [{
    key: "batchInterval",
    value: function batchInterval() {
      this.loopWrite();
      this.loopSend();
    }
  }, {
    key: "loopWrite",
    value: function loopWrite() {
      var self = this;
      setTimeout(function () {
        self.batchWrite();
        self.loopWrite();
      }, 500);
    }
  }, {
    key: "batchWrite",
    value: function batchWrite() {
      if (this.dataHasChange) {
        this.dataHasChange = false;
        PlatformAPI.setStorage(this.storageKey, JSON.stringify(this.batchList));
      }
    }
  }, {
    key: "loopSend",
    value: function loopSend() {
      var self = this;
      self.timer = setTimeout(function () {
        self.batchSend();
        clearTimeout(self.timer);
        self.loopSend();
      }, this.batchConfig.interval);
    }
  }, {
    key: "add",
    value: function add(data) {
      if (this.batchList.length > this.maxLimit) {
        this.batchList.shift();
      }
      this.batchList.push(data);
      this.dataHasChange = true;
      if (this.batchList.length > this.batchConfig.size) {
        this.batchSend();
      }
    }
  }, {
    key: "flush",
    value: function flush() {
      clearTimeout(this.timer);
      this.batchSend();
      this.loopSend();
    }
  }, {
    key: "batchSend",
    value: function batchSend() {
      var nowDate = _.getCurrentTimeStamp();
      if (this.dataSendTimeStamp !== 0 && nowDate - this.dataSendTimeStamp < this.config.sendTimeout + 500) {
        return;
      }
      this.dataSendTimeStamp = _.getCurrentTimeStamp();
      var sendData;
      if (this.batchList.length > 30) {
        sendData = this.batchList.slice(0, 30);
      } else {
        sendData = this.batchList;
      }
      var len = sendData.length;
      if (len > 0) {
        var postData = {};
        postData["data"] = sendData;
        postData["#app_id"] = this.config["appId"];
        postData["#flush_time"] = _.getCurrentTimeStamp();
        var self = this;
        senderQueue.enqueue(postData, this.analytics.serverUrl, {
          maxRetries: 1,
          sendTimeout: this.config.sendTimeout,
          callback: function callback(res) {
            if (res.code === 0) {
              logger.info("Flush success: " + JSON.stringify(postData, null, 4));
              self.batchRemove(len);
            }
          },
          debugMode: this.config.debugMode,
          deviceId: this.analytics.getDeviceId()
        }, false);
      }
    }
  }, {
    key: "batchRemove",
    value: function batchRemove(len) {
      this.dataSendTimeStamp = 0;
      this.batchList.splice(0, len);
      this.dataHasChange = true;
      this.batchWrite();
    }
  }]);
}();
var FunsDataAnalyticsAPI = /*#__PURE__*/function () {
  function FunsDataAnalyticsAPI(config) {
    _classCallCheck(this, FunsDataAnalyticsAPI);
    if (!config) return;
    if (PlatformAPI.isWxPlat() && (config.reportingToTencentSdk === 1 || config.reportingToTencentSdk === 2)) {
      var WXSDK = config.tgaInitParams.tgaSDK;
      if (config.tgaInitParams && WXSDK) {
        if (config.debugMode === "debug" || config.debugMode === "debugOnly") {
          WXSDK.setDebug(true);
        }
        this.wxSdk = new WXSDK({
          user_action_set_id: config.tgaInitParams.user_action_set_id,
          secret_key: config.tgaInitParams.secret_key,
          appid: config.tgaInitParams.appid
        });
        if (config.tgaInitParams.openId) {
          this.wxSdk.setOpenId(config.tgaInitParams.openId);
        } else {
          if (config.tgaInitParams.unionId) {
            this.wxSdk.setUnionId(config.tgaInitParams.unionId);
          }
        }
      }
    }
    this.isTADisable = config.reportingToTencentSdk === 1;
    config.appId = config.appId ? _.checkAppId(config.appId) : _.checkAppId(config.appid);
    config.serverUrl = config.serverUrl || config.server_url;
    if (!config.appId || !config.serverUrl) {
      throw new Error("appId or serverUrl can not be empty");
    }
    var defaultConfig = _.extend({}, DEFAULT_CONFIG, PlatformAPI.getConfig());
    if (_.isObject(config)) {
      this.config = _.extend(defaultConfig, config);
    } else {
      this.config = defaultConfig;
    }
    this._init(this.config);
  }

  // internal init function. it should not be used by users.
  return _createClass(FunsDataAnalyticsAPI, [{
    key: "_init",
    value: function _init(config) {
      var _this3 = this;
      this.name = config.name;
      this.appId = config.appId || config.appid;
      var serverUrl = config.serverUrl || config.server_url;
      this.serverUrl = serverUrl;
      this.serverDebugUrl = serverUrl + "/data_debug";
      this.configUrl = serverUrl + "/config";
      this.autoTrackProperties = {};
      PlatformAPI.initConfig(config);
      // cache commands.
      this._queue = [];
      this.observers = [];

      // this.updateConfig(this.configUrl, this.appId);
      if (config.isChildInstance) {
        this._state = {};
      } else {
        logger.enabled = config.enableLog;
        this.instances = [];
        this._state = {
          getSystemInfo: false,
          initComplete: false
        };
        // systemInformation.getSystemInfo(() => {
        //     this._updateState({
        //         getSystemInfo: true,
        //     });
        // });

        PlatformAPI.setGlobal(this, this.name);
      }
      systemInformation.initDisableList(this.config.disablePresetProperties);
      this.store = new FunsDataPersistence(config, function () {
        if (_this3.config.asyncPersistence && _.isFunction(_this3.config.persistenceComplete)) {
          _this3.config.persistenceComplete(_this3);
        }
        _this3._updateState();
      });
      this.enabled = _.isBoolean(this.store._get("ta_enabled")) ? this.store._get("ta_enabled") : true;
      this.isOptOut = _.isBoolean(this.store._get("ta_isOptOut")) ? this.store._get("ta_isOptOut") : false;
      if (!config.isChildInstance && config.autoTrack) {
        this.autoTrack = PlatformAPI.initAutoTrackInstance(this, config);
      }

      //Enable batch reporting of data
      if (this.config.enableBatch !== undefined && this.config.enableBatch !== false) {
        this.batchConsumer = new BatchConsumer(this.config, this);
        this.batchConsumer.batchInterval();
      }
    }
  }, {
    key: "initSystemInfo",
    value: function initSystemInfo() {
      var _this4 = this;
      if (!this.config.isChildInstance) {
        systemInformation.getSystemInfo(function () {
          _this4._updateState({
            getSystemInfo: true
          });
        });
      }
    }
  }, {
    key: "updateConfig",
    value: function updateConfig(configUrl, appId) {
      var _this5 = this;
      var headers = _.createExtraHeaders();
      headers["content-type"] = "application/json";
      var request = PlatformAPI.request({
        url: configUrl + "?appid=" + appId,
        method: "GET",
        header: headers,
        success: function success(res) {
          if (!_.isUndefined(res) && !_.isUndefined(res.data)) {
            logger.info("Get remote config success" + "(" + appId + ") :" + JSON.stringify(res.data));
            if (!_.isUndefined(res.data["data"])) {
              _this5.config.syncBatchSize = res.data["data"]["sync_batch_size"];
              _this5.config.syncInterval = res.data["data"]["sync_interval"];
              _this5.config.disableEventList = res.data["data"]["disable_event_list"];
              if (!_.isUndefined(res.data["data"]["secret_key"])) {
                var secretKey = res.data["data"]["secret_key"];
                _this5.config.secretKey = {
                  publicKey: secretKey["key"],
                  version: secretKey["version"]
                };
              }
            }
          }
        },
        fail: function fail(res) {
          logger.info("Get remote config fail" + "(" + appId + ") :" + res.errMsg);
        }
      });
      setTimeout(function () {
        if ((_.isObject(request) || _.isPromise(request)) && _.isFunction(request.abort)) {
          request.abort();
        }
      }, 3000);
    }

    /**
     * Create a new instance (sub-instance).
     * All properties that can be set are independent of the main instance.
     *
     * @param {string} name: sub-instance name
     * @param {object} config: optional, config of sub-instance
     */
  }, {
    key: "initInstance",
    value: function initInstance(name, config) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this.config.isChildInstance) {
        logger.warn("initInstance() cannot be called on child instance");
        return undefined;
      }
      if (_.isString(name) && name !== this.name && _.isUndefined(this[name])) {
        var instance = new FunsDataAnalyticsAPI(_.extend({}, this.config, {
          enablePersistence: false,
          isChildInstance: true,
          name: name
        }, config));
        this[name] = instance;
        this.instances.push(name);
        this[name]._state = this._state;
        return instance;
      } else {
        logger.warn("initInstance() failed due to the name is invalid: " + name);
        return undefined;
      }
    }

    /**
     * Get sub-instance with name
     *
     * @param {string} name: sub-instance name
     */
  }, {
    key: "lightInstance",
    value: function lightInstance(name) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      return this[name];
    }

    /**
     * Internal function, used to set some preset properties related to the life cycle
     *
     * Common attributes are:
     * - #scene Scene value, available in onLaunch callback. It can also be actively obtained according to the platform interface
     * - #url_path page path
     *
     * When sending event data, the priority is:
     * Event Properties > Dynamic Public Properties > Common Event Properties > Automatic Collection Properties > Other Preset Properties
     *
     * @param {object} props, event properties
     */
  }, {
    key: "_setAutoTrackProperties",
    value: function _setAutoTrackProperties(props) {
      _.extend(this.autoTrackProperties, props);
    }

    /**
     * After calling init(), the data starts to be reported
     *
     * Before calling this function, all reporting requests will be cached. When the user completes the necessary settings, call this function to trigger reporting.
     */
  }, {
    key: "init",
    value: function init() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      this.initSystemInfo();
      if (this._state.initComplete) return false;
      this._updateState({
        initComplete: true
      });
      logger.info("Analytics SDK initialize success, AppId = " + this.config.appId + ", ServerUrl = " + this.config.serverUrl + ", Mode = " + this.config.model + ", DeviceId = " + this.getDeviceId() + ", Lib = " + Config.LIB_NAME + ", LibVersion = " + Config.LIB_VERSION);
    }

    /**
     * Internal function, to judge whether the initialization is completed, and the data can be actually sent
     *
     * Each instance has three asynchronous states
     * - getSystemInfo Whether has obtained system information, the sub-instance defaults to true.
     * - initComplete Whether the init() function is called, true means that the user has completed the necessary initialization settings. Child instances this state defaults to true.
     * - store.initComplete Whether the cache information has been read
     */
  }, {
    key: "_isReady",
    value: function _isReady() {
      return this._state.getSystemInfo && this._state.initComplete && this.store.initComplete;
    }
  }, {
    key: "_updateState",
    value: function _updateState(state) {
      var _this6 = this;
      if (_.isObject(state)) {
        _.extend(this._state, state);
      }
      this._onStateChange();
      _.each(this.instances, function (name) {
        _this6[name]._onStateChange();
      });
    }

    // Only after the system information initialization is completed and the user actively calls init(), will the data be actually sent.
  }, {
    key: "_onStateChange",
    value: function _onStateChange() {
      var _this7 = this;
      if (this._isReady() && this._queue && this._queue.length > 0) {
        _.each(this._queue, function (item) {
          _this7[item[0]].apply(_this7, slice.call(item[1]));
        });
        this._queue = [];
      }
    }
  }, {
    key: "_hasDisabled",
    value: function _hasDisabled() {
      var hasDisabled = !this.enabled || this.isOptOut;
      if (hasDisabled) {
        logger.info("SDK is Pause or Stop!");
      }
      return hasDisabled;
    }

    // send request. Due to the limitations of some platforms on the number of network connections, we use senderQueue to send data.
  }, {
    key: "_sendRequest",
    value: function _sendRequest(eventData, time, tryBeacon) {
      if (this._hasDisabled()) {
        return;
      }
      if (!_.isUndefined(this.config.disableEventList)) {
        if (this.config.disableEventList.includes(eventData.eventName)) {
          logger.info("Disabled Event : " + eventData.eventName);
          return;
        }
      }
      time = _.isDate(time) ? time : _.getCurrentDate();
      var data = {
        data: [{
          "#type": eventData.type,
          "#time": _.formatDate(_.formatTimeZone(time, this.config.zoneOffset)),
          "#distinct_id": this.store.getDistinctId(),
          "#timestamp": new Date().getTime()
        }]
      };
      if (this.store.getAccountId()) {
        data.data[0]["#account_id"] = this.store.getAccountId();
      }
      if (eventData.type === "track" || eventData.type === "track_update" || eventData.type === "track_overwrite") {
        data.data[0]["#event_name"] = eventData.eventName;
        if (eventData.type === "track_update" || eventData.type === "track_overwrite") {
          data.data[0]["#event_id"] = eventData.extraId;
        } else if (eventData.firstCheckId) {
          data.data[0]["#first_check_id"] = eventData.firstCheckId;
        }
        data.data[0]["properties"] = _.extend({
          "#zone_offset": _.getTimeZone(time, this.config.zoneOffset)
        }, systemInformation.properties, this.autoTrackProperties, this.store.getSuperProperties(), this.dynamicProperties ? this.dynamicProperties() : {});
        var startTimestamp = this.store.removeEventTimer(eventData.eventName);
        if (!_.isUndefined(startTimestamp)) {
          var durationMillisecond = _.getCurrentTimeStamp() - startTimestamp;
          var duration = parseFloat((durationMillisecond / 1000).toFixed(3));
          if (duration > 86400) {
            duration = 86400;
          } else if (duration < 0) {
            duration = 0;
          }
          data.data[0]["properties"]["#duration"] = duration;
        }
      } else {
        data.data[0]["properties"] = {};
      }
      if (_.isObject(eventData.properties) && !_.isEmptyObject(eventData.properties)) {
        _.extend(data.data[0].properties, eventData.properties);
      }
      _.searchObjDate(data.data[0], this.config.zoneOffset);
      if (this.config.maxRetries > 1) {
        data.data[0]["#uuid"] = _.UUIDv4();
      }
      data["#app_id"] = this.appId;

      // 添加 automaticData 字段,将 data.data[0] 和 data.data[0].properties 的所有字段拍平到 automaticData 中
      var automaticData = _.extend({}, data.data[0]);
      // 移除 properties 字段,将其内容直接合并到 automaticData 中
      if (automaticData.properties) {
        _.extend(automaticData, automaticData.properties);
        delete automaticData.properties;
      }
      data["automaticData"] = automaticData;
      this.notifyAllObserver("onDataEnqueue", {
        appId: this.appId,
        event: data.data[0]
      });
      logger.info("Enqueue data, " + JSON.stringify(data, null, 4));
      if (eventData.debugMode === "debug" || eventData.debugMode === "debugOnly") {
        if (senderQueue.runTimeout(this.config.sendTimeout)) {
          senderQueue.resetTimeout();
        }
        senderQueue.enqueue(data, this.serverDebugUrl, {
          maxRetries: this.config.maxRetries,
          sendTimeout: this.config.sendTimeout,
          callback: eventData.onComplete,
          debugMode: eventData.debugMode,
          deviceId: this.getDeviceId()
        });
        return;
      }
      var serverUrl = this.config.debugMode === "debug" || this.config.debugMode === "debugOnly" ? this.serverDebugUrl : this.serverUrl;
      if (_.isBoolean(this.config.enableEncrypt) && this.config.enableEncrypt === true) {
        data.data[0] = _.generateEncryptyData(data.data[0], this.config.secretKey);
      }
      if (this.batchConsumer && this.config.debugMode === "none" && !tryBeacon) {
        this.batchConsumer.add(data.data[0]);
        if (_.isFunction(eventData.onComplete)) {
          eventData.onComplete({
            code: 0,
            msg: "success"
          });
        }
        return;
      }
      if (tryBeacon) {
        var formData = new FormData();
        if (this.config.debugMode === "debug" || this.config.debugMode === "debugOnly") {
          formData.append("source", "client");
          formData.append("appid", this.appId);
          formData.append("dryRun", this.config.debugMode === "debugOnly" ? 1 : 0);
          formData.append("deviceId", this.getDeviceId());
          formData.append("data", JSON.stringify(data.data[0]));
          navigator.sendBeacon(serverUrl, formData);
        } else {
          var flushTime = _.getCurrentTimeStamp();
          data["#flush_time"] = flushTime;
          navigator.sendBeacon(serverUrl, JSON.stringify(data));
        }
        if (_.isFunction(eventData.onComplete)) {
          eventData.onComplete({
            statusCode: 200
          });
        }
      } else {
        if (senderQueue.runTimeout(this.config.sendTimeout)) {
          senderQueue.resetTimeout();
        }
        senderQueue.enqueue(data, serverUrl, {
          maxRetries: this.config.maxRetries,
          sendTimeout: this.config.sendTimeout,
          callback: eventData.onComplete,
          debugMode: this.config.debugMode,
          deviceId: this.getDeviceId()
        });
      }
    }

    // Is it a parameter object
  }, {
    key: "_isObjectParams",
    value: function _isObjectParams(obj) {
      return _.isObject(obj) && _.isFunction(obj.onComplete);
    }

    /**
     * Track a narmal Event.
     * @param {string} eventName: event name, required
     * @param {object} properties: event properties, optional
     * @param {date} time: event time, optional
     * @param {function} onComplete: callback, optional
     */
  }, {
    key: "track",
    value: function track(eventName, properties, time, onComplete) {
      if (PlatformAPI.isWxPlat()) {
        if (this.wxSdk) {
          if (!properties) {
            properties = {};
          }
          this.wxSdk.track(eventName, properties);
        }
        if (this.isTADisable) {
          return;
        }
      }
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(eventName)) {
        var options = eventName;
        eventName = options.eventName;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.event(eventName) && PropertyChecker.properties(properties) || !this.config.strict) {
        this._internalTrack(eventName, properties, time, onComplete, false, true);
      } else if (_.isFunction(onComplete)) {
        onComplete({
          code: -1,
          msg: "invalid parameters"
        });
      }
    }
  }, {
    key: "trackInternal",
    value: function trackInternal(options) {
      if (this._hasDisabled()) {
        return;
      }
      this._internalTrack(options.eventName, options.properties, options.time, options.onComplete, false, true, options.debugMode);
    }

    /**
     * Track a updatable Event
     * @param {object} options: event infomations
     *
     * options.eventName: event name, required
     * options.eventId: event ID, to mark the event, required
     * options.time: event time, optional
     * options.properties: event properties, optional
     * options.onComplete: callback, optional
     */
  }, {
    key: "trackUpdate",
    value: function trackUpdate(options) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (options && options.eventId && (PropertyChecker.event(options.eventName) && PropertyChecker.properties(options.properties) || !this.config.strict)) {
        if (this._isReady()) {
          var property = _.checkCalibration(options.properties, options.time, this.config.enableCalibrationTime);
          var time = _.isDate(options.time) ? options.time : _.getCurrentDate();
          this._sendRequest({
            type: "track_update",
            eventName: options.eventName,
            properties: property,
            onComplete: options.onComplete,
            extraId: options.eventId
          }, time);
        } else {
          //options.time = time;
          this._queue.push(["trackUpdate", [options]]);
        }
      } else {
        logger.warn("Invalide parameter for trackUpdate: you should pass an object contains eventId to trackUpdate()");
        if (_.isFunction(options.onComplete)) {
          options.onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Track a overwritable Event
     * @param {object} options event infomations
     *
     * options.eventName: event name, required
     * options.eventId: event ID, to mark the event, required
     * options.time: event time, optional
     * options.properties: event properties, optional
     * options.onComplete: callback, optional
     */
  }, {
    key: "trackOverwrite",
    value: function trackOverwrite(options) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (options && options.eventId && (PropertyChecker.event(options.eventName) && PropertyChecker.properties(options.properties) || !this.config.strict)) {
        if (this._isReady()) {
          var property = _.checkCalibration(options.properties, options.time, this.config.enableCalibrationTime);
          var time = _.isDate(options.time) ? options.time : _.getCurrentDate();
          this._sendRequest({
            type: "track_overwrite",
            eventName: options.eventName,
            properties: property,
            onComplete: options.onComplete,
            extraId: options.eventId
          }, time);
        } else {
          //options.time = time;
          this._queue.push(["trackOverwrite", [options]]);
        }
      } else {
        logger.warn("Invalide parameter for trackOverwrite: you should pass an object contains eventId to trackOverwrite()");
        if (_.isFunction(options.onComplete)) {
          options.onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Track a first Event
     * @param {object} options event infomations
     *
     * options.eventName: event name, required
     * options.firstCheckId: event ID, to mark the event, default is #device_id, required
     * options.time: event time, optional
     * options.properties: event properties, optional
     * options.onComplete: callback, optional
     */
  }, {
    key: "trackFirstEvent",
    value: function trackFirstEvent(options) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (options && options.eventName && (PropertyChecker.event(options.eventName) && PropertyChecker.properties(options.properties) || !this.config.strict)) {
        if (this._isReady()) {
          var property = _.checkCalibration(options.properties, options.time, this.config.enableCalibrationTime);
          var time = _.isDate(options.time) ? options.time : _.getCurrentDate();
          this._sendRequest({
            type: "track",
            eventName: options.eventName,
            properties: property,
            onComplete: options.onComplete,
            firstCheckId: options.firstCheckId ? options.firstCheckId : this.getDeviceId()
          }, time);
        } else {
          //options.time = time;
          this._queue.push(["trackFirstEvent", [options]]);
        }
      } else {
        logger.warn("Invalide parameter for trackFirstEvent: you should pass an object contains eventName to trackFirstEvent()");
        if (_.isFunction(options.onComplete)) {
          options.onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    // internal function. Do not call this function directly.
  }, {
    key: "_internalTrack",
    value: function _internalTrack(eventName, properties, time, onComplete, tryBeacon, isFromTrack, debugMode) {
      if (!isFromTrack) {
        if (this.wxSdk) {
          if (!properties) {
            properties = {};
          }
          properties["trackBy"] = "FunsData";
          this.wxSdk.track(eventName, properties);
        }
        if (this.isTADisable) {
          return;
        }
      }
      if (this._hasDisabled()) {
        return;
      }
      var property = _.checkCalibration(properties, time, this.config.enableCalibrationTime);
      time = _.isDate(time) ? time : _.getCurrentDate();
      if (this._isReady()) {
        this._sendRequest({
          type: "track",
          eventName: eventName,
          debugMode: debugMode,
          properties: property,
          onComplete: onComplete
        }, time, tryBeacon);
      } else {
        this._queue.push(["_internalTrack", [eventName, properties, time, onComplete, tryBeacon, true]]);
      }
    }

    /**
     * Sets the user property, replacing the original value with the new value if the property already exists.
     * @param {*} properties event properties, optional
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userSet",
    value: function userSet(properties, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.propertiesMust(properties) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          this._sendRequest({
            type: "user_set",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userSet", [properties, time, onComplete]]);
        }
      } else {
        logger.warn("calling userSet failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }
    /**
     * Sets a single user attribute, ignoring the new attribute value if the attribute already exists.
     * @param {*} properties event properties, optional
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userSetOnce",
    value: function userSetOnce(properties, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.propertiesMust(properties) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          this._sendRequest({
            type: "user_setOnce",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userSetOnce", [properties, time, onComplete]]);
        }
      } else {
        logger.warn("calling userSetOnce failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Reset user properties.
     * @param {*} property event property, optional
     * @param {*} time  event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userUnset",
    value: function userUnset(property, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        property = options.property;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.propertyName(property) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          var properties = {};
          properties[property] = 0;
          this._sendRequest({
            type: "user_unset",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userUnset", [property, onComplete, time]]);
        }
      } else {
        logger.warn("calling userUnset failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Delete the user attributes,This operation is not reversible and should be performed with caution.
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userDel",
    value: function userDel(time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(time)) {
        var options = time;
        time = options.time;
        onComplete = options.onComplete;
      }
      time = _.isDate(time) ? time : _.getCurrentDate();
      if (this._isReady()) {
        this._sendRequest({
          type: "user_del",
          onComplete: onComplete
        }, time);
      } else {
        this._queue.push(["userDel", [time, onComplete]]);
      }
    }

    /**
     * Adds the numeric type user attributes.
     * @param {*} properties event properties, optional
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userAdd",
    value: function userAdd(properties, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.userAddProperties(properties) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          this._sendRequest({
            type: "user_add",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userAdd", [properties, time, onComplete]]);
        }
      } else {
        logger.warn("calling userAdd failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Append a user attribute of the List type.
     * @param {*} properties event properties, optional
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userAppend",
    value: function userAppend(properties, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.userAppendProperties(properties) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          this._sendRequest({
            type: "user_append",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userAppend", [properties, time, onComplete]]);
        }
      } else {
        logger.warn("calling userAppend failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * The element appended to the library needs to be done to remove the processing,and then import.
     * @param {*} properties event properties, optional
     * @param {*} time event time, optional
     * @param {*} onComplete callback, optional
     * @returns
     */
  }, {
    key: "userUniqAppend",
    value: function userUniqAppend(properties, time, onComplete) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (this._isObjectParams(properties)) {
        var options = properties;
        properties = options.properties;
        time = options.time;
        onComplete = options.onComplete;
      }
      if (PropertyChecker.userAppendProperties(properties) || !this.config.strict) {
        time = _.isDate(time) ? time : _.getCurrentDate();
        if (this._isReady()) {
          this._sendRequest({
            type: "user_uniq_append",
            properties: properties,
            onComplete: onComplete
          }, time);
        } else {
          this._queue.push(["userUniqAppend", [properties, time, onComplete]]);
        }
      } else {
        logger.warn("calling userAppend failed due to invalid arguments");
        if (_.isFunction(onComplete)) {
          onComplete({
            code: -1,
            msg: "invalid parameters"
          });
        }
      }
    }

    /**
     * Empty the cache queue. When this api is called, the data in the current cache queue will attempt to be reported.
     * If the report succeeds, local cache data will be deleted.
     */
  }, {
    key: "flush",
    value: function flush() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this.batchConsumer && this.config.debugMode === "none") {
        this.batchConsumer.flush();
      }
    }
  }, {
    key: "authorizeOpenID",
    value: function authorizeOpenID(id) {
      this.identify(id);
    }

    /**
     * Set the distinct ID to replace the default UUID distinct ID.
     * @param {*} distinctId distinct ID
     * @returns
     */
  }, {
    key: "identify",
    value: function identify(distinctId) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (distinctId === undefined || distinctId.trim() === "") return;
      if (typeof distinctId === "number") {
        distinctId = String(distinctId);
      } else if (typeof distinctId !== "string") {
        return false;
      }
      this.store.setDistinctId(distinctId);
      logger.info("Setting distinct ID, DistinctId = " + distinctId);
      this.notifyAllObserver("onAccountChanged", {
        accountId: this.getAccountId(),
        distinctId: distinctId
      });
    }

    /**
     * Get a visitor ID: The #distinct_id value in the reported data.
     * @returns distinct ID
     */
  }, {
    key: "getDistinctId",
    value: function getDistinctId() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return "";
      return this.store.getDistinctId();
    }

    /**
     * Set the account ID. Each setting overrides the previous value. Login events will not be uploaded.
     * @param {*} accoundId
     * @returns
     */
  }, {
    key: "login",
    value: function login(accoundId) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (accoundId === undefined || accoundId.trim() === "") return;
      if (typeof accoundId === "number") {
        accoundId = String(accoundId);
      } else if (typeof accoundId !== "string") {
        return false;
      }
      this.store.setAccountId(accoundId);
      logger.info("Login SDK, AccountId = " + accoundId);
      this.notifyAllObserver("onAccountChanged", {
        accountId: accoundId,
        distinctId: this.getDistinctId()
      });
    }
  }, {
    key: "getAccountId",
    value: function getAccountId() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return "";
      return this.store.getAccountId();
    }

    /**
     * Clearing the account ID will not upload user logout events.
     * @returns
     */
  }, {
    key: "logout",
    value: function logout() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      this.store.setAccountId(null);
      logger.info("Logout SDK");
      this.notifyAllObserver("onAccountChanged", {
        accountId: "",
        distinctId: this.getDistinctId()
      });
    }
  }, {
    key: "notifyAllObserver",
    value: function notifyAllObserver(type, obj) {
      for (var i = 0; i < this.observers.length; i++) {
        this.observers[i](type, obj);
      }
    }

    /**
     * Set the public event attribute, which will be included in every event uploaded after that. The public event properties are saved without setting them each time.
     * @param {*} obj public event attribute
     * @returns
     */
  }, {
    key: "setSuperProperties",
    value: function setSuperProperties(obj) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (PropertyChecker.propertiesMust(obj) || !this.config.strict) {
        this.store.setSuperProperties(obj);
      } else {
        logger.warn("setSuperProperties parameter must be a valid property value");
      }
    }

    /**
     * Clear all public event attributes.
     * @returns
     */
  }, {
    key: "clearSuperProperties",
    value: function clearSuperProperties() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      this.store.setSuperProperties({}, true);
    }

    /**
     * Clears a public event attribute.
     * @param {*} propertyName Public event attribute key to clear
     * @returns
     */
  }, {
    key: "unsetSuperProperty",
    value: function unsetSuperProperty(propertyName) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      if (this._hasDisabled()) {
        return;
      }
      if (_.isString(propertyName)) {
        var superProperties = this.getSuperProperties();
        delete superProperties[propertyName];
        this.store.setSuperProperties(superProperties, true);
      }
    }

    /**
     * Gets the public event properties that have been set.
     * @returns Public event properties that have been set
     */
  }, {
    key: "getSuperProperties",
    value: function getSuperProperties() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return {};
      return this.store.getSuperProperties();
    }
    /**
     * Gets prefabricated properties for all events.
     * @returns
     */
  }, {
    key: "getPresetProperties",
    value: function getPresetProperties() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return {};
      var properties = systemInformation.properties;
      var presetProperties = {};
      if (!this.config.disablePresetProperties.includes("#os")) {
        var os = properties["#os"];
        presetProperties.os = _.isUndefined(os) ? "" : os;
      }
      if (!this.config.disablePresetProperties.includes("#screen_width")) {
        var screenWidth = properties["#screen_width"];
        presetProperties.screenWidth = _.isUndefined(screenWidth) ? 0 : screenWidth;
      }
      if (!this.config.disablePresetProperties.includes("#screen_height")) {
        var screenHeight = properties["#screen_height"];
        presetProperties.screenHeight = _.isUndefined(screenHeight) ? 0 : screenHeight;
      }
      if (!this.config.disablePresetProperties.includes("#network_type")) {
        var networkType = properties["#network_type"];
        presetProperties.networkType = _.isUndefined(networkType) ? "" : networkType;
      }
      if (!this.config.disablePresetProperties.includes("#device_model")) {
        var deviceModel = properties["#device_model"];
        presetProperties.deviceModel = _.isUndefined(deviceModel) ? "" : deviceModel;
      }
      if (!this.config.disablePresetProperties.includes("#os_version")) {
        var osVersion = properties["#os_version"];
        presetProperties.osVersion = _.isUndefined(osVersion) ? "" : osVersion;
      }
      if (!this.config.disablePresetProperties.includes("#device_id")) {
        presetProperties.deviceId = this.getDeviceId();
      }
      var zoneOffset = _.getTimeZone(_.getCurrentDate(), this.config.zoneOffset);
      presetProperties.zoneOffset = zoneOffset;
      if (!this.config.disablePresetProperties.includes("#manufacturer")) {
        var manufacturer = properties["#manufacturer"];
        presetProperties.manufacturer = _.isUndefined(manufacturer) ? "" : manufacturer;
      }
      presetProperties.toEventPresetProperties = function () {
        var pro = {};
        if (presetProperties.deviceModel) {
          pro["#device_model"] = presetProperties.deviceModel;
        }
        if (presetProperties.deviceId) {
          pro["#device_id"] = presetProperties.deviceId;
        }
        if (presetProperties.screenWidth) {
          pro["#screen_width"] = presetProperties.screenWidth;
        }
        if (presetProperties.screenHeight) {
          pro["#screen_height"] = presetProperties.screenHeight;
        }
        if (presetProperties.os) {
          pro["#os"] = presetProperties.os;
        }
        if (presetProperties.osVersion) {
          pro["#os_version"] = presetProperties.osVersion;
        }
        if (presetProperties.networkType) {
          pro["#network_type"] = presetProperties.networkType;
        }
        pro["#zone_offset"] = zoneOffset;
        if (presetProperties.manufacturer) {
          pro["#manufacturer"] = presetProperties.manufacturer;
        }
        return pro;
      };
      return presetProperties;
    }

    /**
     * Set dynamic public properties. Each event uploaded after that will contain a public event attribute.
     * @param {*} dynamicProperties Dynamic public attribute interface
     * @returns
     */
  }, {
    key: "setDynamicSuperProperties",
    value: function setDynamicSuperProperties(dynamicProperties) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return {};
      if (this._hasDisabled()) {
        return;
      }
      if (typeof dynamicProperties === "function") {
        if (PropertyChecker.properties(dynamicProperties()) || !this.config.strict) {
          this.dynamicProperties = dynamicProperties;
        } else {
          logger.warn("A dynamic public property must return a valid property value");
        }
      } else {
        logger.warn("setDynamicSuperProperties parameter must be a function type");
      }
    }
  }, {
    key: "registerAnalyticsObserver",
    value: function registerAnalyticsObserver(analyticsObserver) {
      if (this._hasDisabled()) {
        return;
      }
      if (typeof analyticsObserver === "function") {
        this.observers.push(analyticsObserver);
      } else {
        logger.warn("registerAnalyticsObserver parameter must be a function type");
      }
    }

    /**
     * Record the event duration, call this method to start the timing, stop the timing when the target event is uploaded, and add the attribute #duration to the event properties, in seconds.
     * @param {*} eventName target event name
     * @param {*} time
     * @returns
     */
  }, {
    key: "timeEvent",
    value: function timeEvent(eventName, time) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return {};
      if (this._hasDisabled()) {
        return;
      }
      time = _.isDate(time) ? time : _.getCurrentDate();
      if (this._isReady()) {
        if (PropertyChecker.event(eventName) || !this.config.strict) {
          this.store.setEventTimer(eventName, time.getTime());
        } else {
          logger.warn("calling timeEvent failed due to invalid eventName: " + eventName);
        }
      } else {
        this._queue.push(["timeEvent", [eventName, time]]);
      }
    }
  }, {
    key: "getDeviceId",
    value: function getDeviceId() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return "";
      return systemInformation.properties["#device_id"];
    }

    /**
     * Pause/Resume reporting event data
     * @param {bool} enabled:true is Resume, false is Pause
     * @deprecated This method is deprecated, use setTrackStatus() instand.
     */
  }, {
    key: "enableTracking",
    value: function enableTracking(enabled) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      this.enabled = enabled;
      this.store._set("ta_enabled", enabled);
    }

    /**
     * Stop reporting event data, and cache data will be cleared
     * @deprecated This method is deprecated, use setTrackStatus() instand.
     */
  }, {
    key: "optOutTracking",
    value: function optOutTracking() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      this.store.setSuperProperties({}, true);
      this.store.setDistinctId(_.UUID());
      this.store.setAccountId(null);
      this._queue.splice(0, this._queue.length);
      this.isOptOut = true;
      this.store._set("ta_isOptOut", true);
    }

    /**
     * Stop reporting event data, and cache data will be cleared, and flush a user_del
     * @deprecated This method is deprecated, use setTrackStatus() instand.
     */
  }, {
    key: "optOutTrackingAndDeleteUser",
    value: function optOutTrackingAndDeleteUser() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      var time = _.getCurrentDate();
      this._sendRequest({
        type: "user_del"
      }, time);
      this.optOutTracking();
    }

    /**
     * Allow reporting event data
     * @deprecated This method is deprecated, use setTrackStatus() instand.
     */
  }, {
    key: "optInTracking",
    value: function optInTracking() {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      this.isOptOut = false;
      this.store._set("ta_isOptOut", false);
    }

    /**
     * Set status for events reporting
     * PAUSE, pause events reporting
     * STOP, stop events reporting, and cache data will be cleared
     * SAVE_ONLY, event data stores in the cache, but not be reported (native support, js equal to NORMAL)
     * NORMAL, resume event reporting
     * @param {string} status, events reporting status
     */
  }, {
    key: "setTrackStatus",
    value: function setTrackStatus(status) {
      if (PlatformAPI.isWxPlat() && this.isTADisable) return;
      switch (status) {
        case "PAUSE":
          this.eventSaveOnly = false;
          this.optInTracking();
          this.enableTracking(false);
          break;
        case "STOP":
          this.eventSaveOnly = false;
          // this.enableTracking(false);
          this.optOutTracking(true);
          break;
        case "SAVE_ONLY":
          // this.eventSaveOnly = true;
          // this.enableTracking(false);
          // this.optInTracking();
          break;
        case "NORMAL":
        default:
          this.eventSaveOnly = false;
          this.optInTracking();
          this.enableTracking(true);
          break;
      }
      logger.info("Change Status to " + status);
    }
  }]);
}();

/**
 * Analytics,  Analytics SDK for Mini Game & App.
 * @example
 * //引入SDK
 * var Analytics = require('./analytics.wx.min.js');
 * //初始化SDK
 * var config = {
 *   appId: 'your-app-id', // 项目的 App ID
 *   serverUrl: 'https://your.serverurl.com' // 数据上报地址
 * };
 * Analytics.init(config);
 * //用户登录
 * Analytics.login('thinker');
 * //设置事件公共属性
 * var superProperties = {
 *     channel : 'td', //字符串
 *     age : 1,//数字
 *     isSuccess : true,//布尔
 *     birthday :  new Date(),//日期
 *     array : [ 'value' ],//数组
 *     row : { key : 'value' },//对象
 *     array_rows : [ { key : 'value' } ]//对象组
 * };
 * Analytics.setSuperProperties(superProperties);
 * //上报事件
 * var eventProperties = {
 *     product_name: '钻石'
 * };
 * Analytics.track({
 *     eventName: 'product_buy', // 事件名称
 *     properties: eventProperties //事件属性
 * });
 * //上报用户属性
 * var userProperties = {
 *     username: 'tiki'
 * };
 * Analytics.userSet({
 *     properties: userProperties
 * });
 */
var Analytics = /*#__PURE__*/function () {
  function Analytics() {
    _classCallCheck(this, Analytics);
  }
  return _createClass(Analytics, null, [{
    key: "_shareInstance",
    value:
    // constructor(){

    // }

    function _shareInstance(appId) {
      if (this._instanceMaps[appId] !== undefined) {
        return this._instanceMaps[appId];
      } else if (this._defaultInstance !== undefined) {
        return this._defaultInstance;
      } else {
        return undefined;
      }
    }
    //初始化
    /**
     * Create a new instance.
     * All properties that can be set are independent of the main instance.
     *
     * @param {Object} config
     * @param {String} config.appId Project App ID
     * @param {String} config.serverUrl Project Server Url
     * @param {Object} config.autoTrack Auto-tracking Events
     * @param {Boolean} config.autoTrack.appShow Auto Track App Show Events
     * @param {Boolean} config.autoTrack.appHide Auto Track App Hide Events
     * @param {Boolean} config.enableLog Enable Log Printing
     */
  }, {
    key: "init",
    value: function init(config) {
      try {
        if (this._instanceMaps && this._instanceMaps[config.appId]) return;
        var td = new FunsDataAnalyticsAPI(config);
        if (td !== undefined) {
          td.init();
          if (this._defaultInstance === undefined) {
            this._defaultInstance = td;
            this._instanceMaps = {};
          }
          this._instanceMaps[config.appId] = td;
        }
      } catch (e) {
        console.log("Analytics SDK initialize fail with reason = " + e);
      }
    }

    //轻实例
    /**
     * Get sub-instance with name
     *
     * @param {String} appId Project App ID
     * @returns {String} Sub-instance token
     */
  }, {
    key: "lightInstance",
    value: function lightInstance(appId) {
      return this._shareInstance(appId).lightInstance();
    }

    //事件
    //普通事件
    /**
     * Track a narmal Event.
     * @param {Object} options
     * @param {String} options.eventName Event name, required
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "track",
    value: function track() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).track(options.eventName, options.properties, options.time, options.onComplete);
    }
  }, {
    key: "trackInternal",
    value: function trackInternal() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).trackInternal(options);
    }

    /**
     * Track a first Event
     * @param {Object} options event infomations
     *
     * @param {String} options.eventName Event name, required
     * @param {String} options.firstCheckId Event ID, to mark the event, default is #device_id, required
     * @param {Date} options.time Event time, optional
     * @param {Object} options.properties Event properties, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID, optional
     */
  }, {
    key: "trackFirst",
    value: function trackFirst() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).trackFirstEvent(options);
    }

    /**
     * Track a updatable Event
     * @param {Object} options event infomations
     *
     * @param {String} options.eventName Event name, required
     * @param {String} options.eventId Event ID, to mark the event, required
     * @param {Date} options.time Event time, optional
     * @param {Object} options.properties Event properties, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID, optional
     */
  }, {
    key: "trackUpdate",
    value: function trackUpdate() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).trackUpdate(options);
    }

    /**
     * Track a overwritable Event
     * @param {Object} options event infomations
     *
     * @param {String} options.eventName Event name, required
     * @param {String} options.eventId Event ID, to mark the event, required
     * @param {Date} options.time Event time, optional
     * @param {Object} options.properties Event properties, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID, optional
     */
  }, {
    key: "trackOverwrite",
    value: function trackOverwrite() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).trackOverwrite(options);
    }

    /**
     * Record the event duration, call this method to start the timing, stop the timing when the target event is uploaded, and add the attribute #duration to the event properties, in seconds.
     * @param {Object} options
     * @param {String} options.eventName Event name
     * @param {Date} options.time Event time
     * @param {String} appId Project App ID
     */
  }, {
    key: "timeEvent",
    value: function timeEvent() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).timeEvent(options.eventName, options.time);
    }

    /**
     *
     */
    // static enableAutoTrack(eventType, properties, appid) {

    // }

    /**
     * Sets the user property, replacing the original value with the new value if the property already exists.
     * @param {Object} options
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userSet",
    value: function userSet() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userSet(options.properties, options.time, options.onComplete);
    }

    /**
     * Sets a single user attribute, ignoring the new attribute value if the attribute already exists.
     * @param {Object} options
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userSetOnce",
    value: function userSetOnce() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userSetOnce(options.properties, options.time, options.onComplete);
    }

    /**
     * Reset user properties.
     * @param {Object} options
     * @param {String} options.property Event property, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userUnset",
    value: function userUnset() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userUnset(options.property, options.time, options.onComplete);
    }

    /**
     * Adds the numeric type user attributes.
     * @param {Object} options
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userAdd",
    value: function userAdd() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userAdd(options.properties, options.time, options.onComplete);
    }

    /**
     * Append a user attribute of the List type.
     * @param {Object} options
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userAppend",
    value: function userAppend() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userAppend(options.properties, options.time, options.onComplete);
    }

    /**
     * The element appended to the library needs to be done to remove the processing,and then import.
     * @param {Object} options
     * @param {Object} options.properties Event properties, optional
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userUniqAppend",
    value: function userUniqAppend() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userUniqAppend(options.properties, options.time, options.onComplete);
    }

    /**
     * Delete the user attributes,This operation is not reversible and should be performed with caution.
     * @param {Object} options
     * @param {Date} options.time Event time, optional
     * @param {Function} options.onComplete Callback, optional
     * @param {String} appId Project App ID
     */
  }, {
    key: "userDelete",
    value: function userDelete() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).userDel(options.time, options.onComplete);
    }

    /**
     * Set the public event attribute, which will be included in every event uploaded after that. The public event properties are saved without setting them each time.
     * @param {Object} properties Public event attribute
     * @param {String} appId Project App ID
     */
  }, {
    key: "setSuperProperties",
    value: function setSuperProperties(properties) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).setSuperProperties(properties);
    }

    /**
     * Clears a public event attribute.
     * @param {String} property Public event attribute key to clear
     * @param {String} appId Project App ID
     */
  }, {
    key: "unsetSuperProperty",
    value: function unsetSuperProperty(property) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).unsetSuperProperty(property);
    }

    /**
     * Clear all public event attributes.
     * @param {String} appId Project App ID
     */
  }, {
    key: "clearSuperProperties",
    value: function clearSuperProperties(appId) {
      this._shareInstance(appId).clearSuperProperties();
    }

    /**
     * Gets the public event properties that have been set.
     * @param {String} appId Project App ID
     * @returns {Object} Public event properties that have been set
     */
  }, {
    key: "getSuperProperties",
    value: function getSuperProperties(appId) {
      return this._shareInstance(appId).getSuperProperties();
    }

    /**
     * Set dynamic public properties. Each event uploaded after that will contain a public event attribute.
     * @param {Function} dynamicProperties Dynamic public attribute interface
     * @param {String} appId Project App ID
     */
  }, {
    key: "setDynamicSuperProperties",
    value: function setDynamicSuperProperties(dynamicProperties) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).setDynamicSuperProperties(dynamicProperties);
    }
  }, {
    key: "registerAnalyticsObserver",
    value: function registerAnalyticsObserver(analyticsObserver) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).registerAnalyticsObserver(analyticsObserver);
    }

    /**
     * Gets prefabricated properties for all events.
     * @param {String} appId Project App ID
     * @returns {Object} preset properties
     */
  }, {
    key: "getPresetProperties",
    value: function getPresetProperties(appId) {
      return this._shareInstance(appId).getPresetProperties();
    }

    /**
     * Set the account ID. Each setting overrides the previous value. Login events will not be uploaded.
     * @param {String} accountId Login user account ID
     * @param {String} appId Project App ID
     */
  }, {
    key: "login",
    value: function login(accountId) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).login(accountId);
    }

    /**
     * Clearing the account ID will not upload user logout events.
     * @param {String} appId Project App ID
     */
  }, {
    key: "logout",
    value: function logout(appId) {
      this._shareInstance(appId).logout();
    }

    /**
     * Set the distinct ID to replace the default UUID distinct ID.
     * @param {String} distinctId Distinct ID
     * @param {String} appId Project App ID
     */
  }, {
    key: "setDistinctId",
    value: function setDistinctId(distinctId) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).identify(distinctId);
    }

    /**
     * Get a visitor ID The #distinct_id value in the reported data.
     * @param {String} appId Project App ID
     * @returns {String} distinct ID
     */
  }, {
    key: "getDistinctId",
    value: function getDistinctId(appId) {
      return this._shareInstance(appId).getDistinctId();
    }

    /**
     * Get a account ID The #account_id value in the reported data.
     * @param {String} appId Project App ID
     * @returns {String} accoount ID
     */
  }, {
    key: "getAccountId",
    value: function getAccountId(appId) {
      return this._shareInstance(appId).getAccountId();
    }

    /**
     * Get sdk version
     * @returns {String} sdk version
     */
  }, {
    key: "getSDKVersion",
    value: function getSDKVersion() {
      return Config.LIB_VERSION;
    }

    /**
     * Get device ID
     * @param {String} appId Project App ID
     * @returns {String} Current Device ID
     */
  }, {
    key: "getDeviceId",
    value: function getDeviceId(appId) {
      return this._shareInstance(appId).getDeviceId();
    }

    /**
     * Empty the cache queue. When this api is called, the data in the current cache queue will attempt to be reported.
     * If the report succeeds, local cache data will be deleted.
     * @param {String} appId Project App ID
     */
  }, {
    key: "flush",
    value: function flush(appId) {
      this._shareInstance(appId).flush();
    }

    /**
     * Set status for events reporting
     * PAUSE, pause events reporting
     * STOP, stop events reporting, and cache data will be cleared
     * SAVE_ONLY, event data stores in the cache, but not be reported (native support, js equal to NORMAL)
     * NORMAL, resume event reporting
     * @param {String} status Events reporting status
     * @param {String} appId Project App ID
     */
  }, {
    key: "setTrackStatus",
    value: function setTrackStatus(status) {
      var appId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
      this._shareInstance(appId).setTrackStatus(status);
    }
  }, {
    key: "setLogPrintListener",
    value: function setLogPrintListener(listener) {
      logger.listener = listener;
    }

    /**
     * Get old api FunsDataAPI
     * @returns {Function} FunsDataAPI, old api
     */
  }, {
    key: "FunsDataAPI",
    value: function FunsDataAPI() {
      return FunsDataAnalyticsAPI;
    }
  }]);
}();
PlatformAPI.setGlobalData(Analytics);

module.exports = Analytics;