# 数组转树结构

const data = [
  { id: 1, name: '部门1', pid: 0 },
  { id: 2, name: '部门2', pid: 1 },
  { id: 3, name: '部门3', pid: 1 },
  { id: 4, name: '部门4', pid: 3 },
  { id: 5, name: '部门5', pid: 4 },
  { id: 6, name: '部门6', pid: 2 },
  { id: 7, name: '部门7', pid: 2 },
  { id: 8, name: '部门8', pid: 0 },
  { id: 9, name: '部门9', pid: 0 }
];

// 方法一:递归
const result = [];
function arrayToTree(data, pid, result) {
  for (const item of data) {
    if (item.pid === pid) {
      const newItem = { ...item, children: [] };
      result.push(newItem);
      arrayToTree(data, item.id, newItem.children);
    }
  }
}

function arrayToTree(arr, id) {
  const res = [];
  for (const item of arr) {
    if (item.pid === id) {
      // 找到当前id的子元素
      res.push({ ...item, children: arrayToTree(arr, item.id) });
    }
  }
  return res;
}

function arrayToTree(arr, id) {
  const node = arr.find((i) => i.id === id); // 找到当前元素
  node.children = [];
  for (const item of arr) {
    if (item.pid === id) {
      // 给当前元素添加子节点,每个子节点递归调用
      node.children.push(arrayToTree(arr, item.id));
    }
  }
  return node;
}

// 方法二:数组的 filter、map 组合
function arrayToTree(data, pid) {
  return data
    .filter((item) => item.pid === pid)
    .map((item) => ({ ...item, children: arrayToTree(data, item.id) }));
}

// 方法三:临时变量 map 来存储
function arrayToTree(data, rootId) {
  const result = [];
  const itemMap = new Map();

  for (let item of data) {
    itemMap.set(item.id, { ...item, children: [] });
  }
  for (let item of data) {
    const id = item.id;
    const pid = item.pid;
    const treeItem = itemMap.get(id);
    if (pid === rootId) {
      result.push(treeItem);
    } else {
      if (!itemMap.get(pid)) {
        itemMap.set(pid, { children: [] });
      }
      itemMap.get(pid).children.push(treeItem);
    }
  }
  return result;
}

# 树结构扁平化

function treeToFlatten(obj, array = []) {
  const { children, ...args } = obj;
  array.push(args);
  if (children && children.length) {
    for (const item of children) {
      treeToFlatten(item, array);
    }
  }
  return array;
}

// 循环处理
function treeToFlatten2(obj) {
  const stack = [];
  const res = [];
  stack.push(obj);
  while (stack.length) {
    const { children, ...args } = stack[0];
    res.push(args);
    stack.shift();
    if (children && children.length) {
      stack.push(...children);
    }
  }
  return res;
}

function flattenTree(items, childrenKey = 'children') {
  const flattenOptions: any[] = [];
  dfs(items);
  return flattenOptions;

  function dfs(nodes) {
    if (nodes == null) {
      return;
    }
    for (const node of nodes) {
      if (!node[childrenKey] || !node[childrenKey].length) {
        flattenOptions.push(node);
      } else {
        const { children, ...args } = node;
        flattenOptions.push(args);
        dfs(node[childrenKey]);
      }
    }
  }
}

# 查找路径

const data = [
  {
    name: 'a',
    children: [
      { name: 'b', children: [{ name: 'e' }] },
      { name: 'c', children: [{ name: 'f' }] },
      { name: 'd', children: [{ name: 'g' }] }
    ]
  },
  {
    name: 'a2',
    children: [
      { name: 'b2', children: [{ name: 'e2' }] },
      { name: 'c2', children: [{ name: 'f2' }] },
      { name: 'd2', children: [{ name: 'g2' }] }
    ]
  }
];
function findPath(data, name, path) {
  if (!path) path = [];
  for (let i = 0; i < data.length; i++) {
    let item = data[i];
    let temp = [...path];
    temp.push(item.name);
    if (item.name === name) return temp;
    if (item.children) {
      let res = fn(item.children, name, temp);
      if (res) return res;
    }
  }
}

# 找出任意 id 的所有祖先 id

/**
 * @description 找出任意id的所有祖先id
 */
const menu = [
  { id: 1, children: [] },
  {
    id: 2,
    children: [
      { id: 3, children: [{ id: 12, children: [{ id: 13, children: [] }] }] },
      { id: 4, children: [] }
    ]
  },
  {
    id: 8,
    children: [
      { id: 9, children: [] },
      { id: 10, children: [] }
    ]
  }
];

let nodes = [];
let AllParentId = [];
function getParentNodes(id, tree) {
  _getParentNodes([], id, tree);
  for (var i = 0; i < nodes.length; i++) {
    AllParentId.push(nodes[i].id);
  }
  return AllParentId.join(',');
}

function _getParentNodes(his, targetId, tree) {
  tree.some((list) => {
    const children = list.children || [];
    if (list.id === targetId) {
      nodes = his;
      return true;
    } else if (children.length > 0) {
      const history = [...his];
      history.push(list);
      return _getParentNodes(history, targetId, children);
    }
  });
}

let ids = getParentNodes(13, menu); // 2,3,12

# 生成图片验证码

function drawCode(ImageCode: string, elementId: string, imageId: string) {
  // let str = '';
  let canvas = document.getElementById(elementId) as HTMLCanvasElement; //获取HTML端画布
  let context = canvas.getContext('2d'); //获取画布2D上下文
  context!.fillStyle = 'cornflowerblue'; //画布填充色
  context!.fillRect(0, 0, canvas.width, canvas.height); //清空画布
  context!.fillStyle = 'white'; //设置字体颜色
  context!.font = '25px Arial'; //设置字体
  let rand: any[] = [];
  let x = [];
  let y = [];
  for (let i = 0; i < 4; i++) {
    rand.push(rand[i]);
    rand[i] = ImageCode.charAt(i);
    x[i] = i * 20 + 10;
    y[i] = Math.random() * 20 + 20;
    context!.fillText(rand[i], x[i], y[i]);
  }
  // str = rand.join('').toUpperCase();
  //画3条随机线
  for (let i = 0; i < 20; i++) {
    drawline(canvas, context);
  }

  // 画30个随机点
  for (let i = 0; i < 30; i++) {
    drawDot(canvas, context);
  }
  convertCanvasToImage(canvas, elementId, imageId);
}
// 随机线
function drawline(canvas: HTMLCanvasElement, context: any) {
  context.moveTo(
    Math.floor(Math.random() * canvas.width),
    Math.floor(Math.random() * canvas.height)
  ); //随机线的起点x坐标是画布x坐标0位置,y坐标是画布高度的随机数
  context.lineTo(
    Math.floor(Math.random() * canvas.width),
    Math.floor(Math.random() * canvas.height)
  ); //随机线的终点x坐标是画布宽度,y坐标是画布高度的随机数
  context.lineWidth = 0.5; //随机线宽
  context.strokeStyle = getBackground(0.1); //随机线描边属性
  context.stroke(); //描边,即起点描到终点
}
// 随机点(所谓画点其实就是画1px像素的线)
function drawDot(canvas: HTMLCanvasElement, context: any) {
  let px = Math.floor(Math.random() * canvas.width);
  let py = Math.floor(Math.random() * canvas.height);
  context.moveTo(px, py);
  context.lineTo(px + 1, py + 1);
  context.lineWidth = 0.2;
  context.strokeStyle = getBackground(0.1);
  context.stroke();
}
// 绘制图片
function convertCanvasToImage(canvas: HTMLCanvasElement, elementId: string, imageId: string) {
  document.getElementById(elementId)!.style.display = 'none';
  let image: HTMLImageElement = document.getElementById(imageId) as HTMLImageElement;
  image!.src = canvas.toDataURL('image/png');
  return image;
}
// 生成随机背景
function getBackground(Transparency: number) {
  let RColor = 255 * Math.random();
  let GColor = 255 * Math.random();
  let BColor = 255 * Math.random();
  return 'rgba(' + RColor + ', ' + GColor + ', ' + BColor + ', ' + Transparency + ')';
}

export default drawCode;

# 生成 UUID

/*
 * Generate a random uuid.
 *
 * USAGE: Math.uuid(length, radix)
 *   length - the desired number of characters
 *   radix  - the number of allowable values for each character.
 *
 * EXAMPLES:
 *   // No arguments  - returns RFC4122, version 4 ID
 *   >>> Math.uuid()
 *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
 *
 *   // One argument - returns ID of the specified length
 *   >>> Math.uuid(15)     // 15 character ID (default base=62)
 *   "VcydxgltxrVZSTV"
 *
 *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
 *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
 *   "01001010"
 *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
 *   "47473046"
 *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
 *   "098F4D35"
 */
(function () {
  // Private array of chars to use
  var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');

  Math.uuid = function (len, radix) {
    var chars = CHARS,
      uuid = [],
      i;
    radix = radix || chars.length;

    if (len) {
      // Compact form
      for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
    } else {
      // rfc4122, version 4 form
      var r;

      // rfc4122 requires these characters
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';

      // Fill in random data.  At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | (Math.random() * 16);
          uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
        }
      }
    }

    return uuid.join('');
  };

  // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
  // by minimizing calls to random()
  Math.uuidFast = function () {
    var chars = CHARS,
      uuid = new Array(36),
      rnd = 0,
      r;
    for (var i = 0; i < 36; i++) {
      if (i == 8 || i == 13 || i == 18 || i == 23) {
        uuid[i] = '-';
      } else if (i == 14) {
        uuid[i] = '4';
      } else {
        if (rnd <= 0x02) rnd = (0x2000000 + Math.random() * 0x1000000) | 0;
        r = rnd & 0xf;
        rnd = rnd >> 4;
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
      }
    }
    return uuid.join('');
  };

  // A more compact, but less performant, RFC4122v4 solution:
  Math.uuidCompact = function () {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = (Math.random() * 16) | 0,
        v = c == 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });
  };
})();

// 方式二
function getUuid(size = 8, toUpperCase = true) {
  let random;
  let str = '';

  for (let i = 0; i < size; i += 1) {
    random = (Math.random() * 16) | 0;
    if (i === 8 || i === 12 || i === 16 || i === 20) {
      str += '-';
    }
    str += (i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString(16);
  }

  return toUpperCase ? str.toLocaleUpperCase() : str;
}

// 方式三
function generateUUID() {
  const blobURL = URL.createObjectURL(new Blob());
  // 输出:http://localhost:8100/4dd4ec39-6959-4126-83d5-f4a6d80136a7

  // substring 不能传入负数从后面截取,所以用文本长度减去不要的长度 -> blobURL.length - 27
  // 或直接找到最后一个“/”截取
  const uuid = blobURL.substring(blobURL.lastIndexOf('/') + 1);
  // 输出:4dd4ec39-6959-4126-83d5-f4a6d80136a7

  URL.revokeObjectURL(blobURL); //释放这个url

  // 注意:substr 虽然可以用负数 blobURL.substr(-36),但是后续可能会被移除,所以不建议使用
  return uuid;
}

// 方式四
function generateRandomId() {
  return 'xxxxxxxxxxxxxxxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

// 方式五
function seededRandom(max, min, seed) {
  max = max || 1;
  min = min || 0;
  seed = (seed * 9301 + 49297) % 233280;
  const rnd = seed / 233280.0;
  return min + rnd * (max - min);
}
export function makeId() {
  const seed = new Date().getTime();
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let text = '';
  for (let i = 0; i < 10; i++) {
    text += possible.charAt(Math.floor(seededRandom(0, possible.length, seed)));
  }
  return text;
}
/**
 * 回退方案:如果 crypto.randomUUID() 不可用,使用其他方法生成 UUID
 * @returns {string} 生成的 UUID
 */
function generateUUID() {
  // 创建一个16字节(128位)的数组
  const buffer = new Uint8Array(16);

  // 使用 crypto API 填充随机值
  crypto.getRandomValues(buffer);

  // 设置版本号 (4) 和变体 (10)
  buffer[6] = (buffer[6] & 0x0f) | 0x40; // 版本4
  buffer[8] = (buffer[8] & 0x3f) | 0x80; // 变体10

  // 将字节数组转换为十六进制字符串
  let hex = '';
  for (let i = 0; i < 16; i++) {
    hex += buffer[i].toString(16).padStart(2, '0');
  }

  // 格式化为 UUID 格式: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  return [
    hex.substring(0, 8),
    hex.substring(8, 12),
    hex.substring(12, 16),
    hex.substring(16, 20),
    hex.substring(20, 32)
  ].join('-');
}

# 生成随机数

/**
 * 使用 Web Crypto API 生成指定范围内的随机数
 * @param {number} min - 范围的最小值(包含)
 * @param {number} max - 范围的最大值(包含)
 * @param {number} [decimalPlaces=0] - 保留的小数位数,默认为0(整数)
 * @returns {number} 指定范围内的随机数
 */
function generateSecureRandomNumber(min, max, decimalPlaces = 0) {
  // 如果最小值大于最大值,则交换两者
  if (min > max) {
    [min, max] = [max, min]; // ES6 解构赋值交换变量
  }

  // 计算范围
  const range = max - min;

  // 创建缓冲区来存储随机值
  // 确保至少为1字节,且处理range为0的情况
  let bufferSize;
  if (range <= 0 || !isFinite(range)) {
    bufferSize = 1; // 默认使用1字节
  } else {
    bufferSize = Math.ceil(Math.log2(range) / 8) || 1;
  }

  const buffer = new Uint8Array(bufferSize);

  // 生成随机值
  crypto.getRandomValues(buffer);

  let result;

  if (decimalPlaces === 0) {
    // 生成整数
    // 将缓冲区转换为一个整数
    let randomValue = 0;
    for (let i = 0; i < buffer.length; i++) {
      randomValue = (randomValue << 8) + buffer[i];
    }

    // 处理范围可能为0的情况
    if (range === 0) {
      result = min;
    } else {
      // 将随机值映射到指定范围内
      result = min + ((randomValue % Math.floor(range)) + 1);
    }
  } else {
    // 生成浮点数
    // 将缓冲区转换为一个0到1之间的浮点数
    let randomValue = 0;
    for (let i = 0; i < buffer.length; i++) {
      randomValue = (randomValue * 256 + buffer[i]) / 256;
    }

    // 处理范围可能为0的情况
    if (range === 0) {
      result = min;
    } else {
      // 将随机值映射到指定范围内
      result = min + randomValue * range;
    }

    // 根据指定的小数位数对结果进行四舍五入
    const factor = Math.pow(10, decimalPlaces);
    result = Math.round(result * factor) / factor;

    // 确保返回的数字总是具有指定的小数位数
    // 使用toFixed确保小数位数,然后转换回数字
    result = parseFloat(result.toFixed(decimalPlaces));
  }

  return result;
}

// 使用示例
console.log('整数随机数:');
console.log(generateSecureRandomNumber(1, 100)); // 1-100之间的整数

console.log('\n保留2位小数的随机数:');
console.log(generateSecureRandomNumber(1, 100, 2)); // 1-100之间,保留2位小数

console.log('\n测试最小值大于最大值的情况:');
console.log(generateSecureRandomNumber(100, 1, 2)); // 自动交换,1-100之间,保留2位小数

console.log('\n负数范围的随机数:');
console.log(generateSecureRandomNumber(-10, 10, 3)); // -10到10之间,保留3位小数

// 测试边界情况
console.log('\n测试边界情况:');
console.log(generateSecureRandomNumber(0, 0.01, 2)); // 0到0.01之间,保留2位小数
console.log(generateSecureRandomNumber(5, 5, 2)); // 确切值5,保留2位小数
console.log(generateSecureRandomNumber(5, 5)); // 确切值5,整数

# 金额格式化

function validateValue(value) {
  const NUM_PATTERN = /^(0|[+-]?((0|([1-9]\d*))\.\d+)?)$/;
  if (value === null || value === undefined || value === 'null' || value === 'undefined') {
    return '';
  }

  return NUM_PATTERN.test(value) ? value : '';
}

/**
 * 判断值是否有效
 * @param {number | string} 值
 * @param {string} [separator] 分隔符号,可选,默认英文逗号(,)
 */

// 方式一:正则 1
function formatCurrency(value, separator = ',') {
  const currency = validateValue(value);
  if (!currency) return value;

  return String(currency).replace(/\B(?=(\d{3})+(?!\d))/g, separator);
}

// 正则 2
function formatCurrency(value) {
  const currency = validateValue(value);
  if (!currency) return value;

  const num = parseFloat(val, 10);
  // toFixed 可用于保留几位小数
  return num
    .toFixed(2)
    .toString()
    .replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, '$1,');
}

// 正则 3
function formatCurrency(value) {
  const currency = validateValue(value);
  if (!currency) return value;

  return currency.toString().replace(/\d+/, function (n) {
    // 先提取整数部分
    return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
      // 对整数部分添加分隔符
      return $1 + ',';
    });
  });
}

// 方式二:内置 API(toLocaleString)
const number = 10000;
const options = {
  style: 'currency',
  currency: 'CNY'
};
const formatNumber = number.toLocaleString('zh-CN', options);
// ¥10,000.00
// 注释掉 style -> 10,000

/**
 * @description 格式化金额
 * @param number:要格式化的数字
 * @param decimals:保留几位小数 默认0位
 * @param decPoint:小数点符号 默认.
 * @param thousandsSep:千分位符号 默认为,
 */
function formatMoney(number, decimals = 2, decPoint = '.', thousandsSep = ',') {
  number = (number + '').replace(/[^0-9+-Ee.]/g, '');
  const n = !isFinite(+number) ? 0 : +number;
  const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals);
  const sep = typeof thousandsSep === 'undefined' ? ',' : thousandsSep;
  const dec = typeof decPoint === 'undefined' ? '.' : decPoint;
  let s = '';
  const toFixedFix = function (n, prec) {
    const k = Math.pow(10, prec);
    return '' + Math.ceil(n * k) / k;
  };
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  const re = /(-?\d+)(\d{3})/;
  while (re.test(s[0])) {
    s[0] = s[0].replace(re, '$1' + sep + '$2');
  }
  if ((s[1] || '').length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1).join('0');
  }
  return s.join(dec);
}

# 获取 URL 中参数

/**
 * @name 获取URL参数
 * @param {String} [url] 可选,默认 location.search
 * @returns {Object} <key, value>参数对象
 * @description 注意:IOS SyntaxError: Invalid regular expression: invalid group specifier name 在 iOS 上会不支持常用零宽断言?<=、?<!、?!、?= 因此上面的函数不适用 iOS,下面的方法可以
 */
function getUrlQueryParams(url = location.search) {
  const params: {} = {};
  const keys = url.match(/([^?&]+)(?==)/g);
  const values = url.match(/(?<==)([^&]*)/g);
  for (const index in keys) {
    params[keys[index]] = values[index];
  }
  return params;
}

/**
 * @name 获取URL参数
 * @param {String} [url] 可选,默认 location.search
 * @returns {Object} <key, value>参数对象
 */
function getUrlQueryParams(url = location.search) {
  const params = {};
  const reg = /([^&?]*)=([^&]*)/g;
  const res = url.match(reg);
  for (const key in res) {
    const query = res[key].split('=');
    params[query[0]] = query[1];
  }
  return params;
}

/**
 * @name 获取单个URL参数
 * @param {String} key 获取键名称
 * @param {String} [url] 可选,默认 location.search
 * @returns {String} 值
 */
function getUrlSingleParam(key, url = location.search) {
  if (!key || typeof key !== 'string') return null;
  const reg = new RegExp('(\\?|&)' + key + '=([^&]*)(&|$)');
  const r = url.match(reg);
  if (r != null) {
    return decodeURIComponent(r[2]);
  }
  return null;
}

/**
 * @name 获取单个URL参数
 * @param {String} name 获取键名称
 * @param {String} [url] 可选,默认 location.href
 * @returns {String} 值
 */
const getUrlKey = function (name, url = location.href) {
  return (
    decodeURIComponent(
      (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(url) || [, ''])[1].replace(
        /\+/g,
        '%20'
      )
    ) || null
  );
};

# 校验 XML 正确性

/*
 * 验证xml格式的正确性
 * 在IE和非IE浏览器解析xml是不同的,因此需要两种方法去解析,在IE中有ActiveXObject("Microsoft.XMLDOM")对象可以用来解析,* 在非IE中可以使用DOMParser对象去解析。
 */
function validateXML(xmlContent) {
  // errorCode 0是xml正确,1是xml错误,2是无法验证
  var xmlDoc,
    errorMessage,
    errorCode = 0;
  // code for IE
  if (window.ActiveXObject) {
    xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc.async = 'false';
    xmlDoc.loadXML(xmlContent);

    if (xmlDoc.parseError.errorCode != 0) {
      errorMessage = '错误code: ' + xmlDoc.parseError.errorCode + '\n';
      errorMessage = errorMessage + '错误原因: ' + xmlDoc.parseError.reason;
      errorMessage = errorMessage + '错误位置: ' + xmlDoc.parseError.line;
      errorCode = 1;
    } else {
      errorMessage = '格式正确';
    }
  }
  // code for Mozilla, Firefox, Opera, chrome, safari,etc.
  else if (document.implementation.createDocument) {
    var parser = new DOMParser();
    xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
    var error = xmlDoc.getElementsByTagName('parsererror');
    if (error.length > 0) {
      if (xmlDoc.documentElement.nodeName == 'parsererror') {
        errorCode = 1;
        errorMessage = xmlDoc.documentElement.childNodes[0].nodeValue;
      } else {
        errorCode = 1;
        errorMessage = xmlDoc.getElementsByTagName('parsererror')[0].innerHTML;
      }
    } else {
      errorMessage = '格式正确';
    }
  } else {
    errorCode = 2;
    errorMessage = '浏览器不支持验证,无法验证xml正确性';
  }
  return {
    msg: errorMessage,
    error_code: errorCode
  };
}

# 并发请求

/**
 * @name 并发请求
 * @param {any} tasks 任务 可更加具体业务调整,传入url数组/请求方式数组
 * @param {number} maxNum 最大请求数
 */
export default function requestLimit(tasks: any[], maxNum: number = 3) {
  return new Promise((resolve, reject) => {
    if (tasks.length === 0) {
      resolve([]);
      return;
    }
    const results: any = [];
    let index = 0; // 请求下标
    let count = 0; // 当前请求完成的数量
    async function request() {
      if (index === tasks.length) return;
      const currIndex = index;
      const task = tasks[index];
      index++;
      try {
        const { data } = await task.fn(task.params);
        // 结果加入到 results 中
        results[currIndex] = data;
      } catch (error) {
        // 失败也将当前结果加入到 results 中
        results[currIndex] = error;
      } finally {
        count++;
        if (count === tasks.length) {
          resolve(results);
        }
        request();
      }
    }

    const times = Math.min(maxNum, tasks.length);
    for (let i = 0; i < times; i++) {
      request();
    }
  });
}

# Blob 转 JSON

// Blod 转 JSON
export function blobToObject(data) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsText(data, 'utf-8');
    reader.onload = function () {
      try {
        resolve(JSON.parse(reader.result as string));
      } catch (error) {
        resolve({
          code: 200,
          message: '获取文件信息成功'
        });
      }
    };
  });
}

# 将 base64 转换为文件对象

export function dataURLtoFile(dataurl, filename, type = 'file') {
  const arr = dataurl.split(',');
  const mimeArr = arr[0].match(/:(.*?);/);
  const mime = (mimeArr && mimeArr[1]) || '';
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  if (type === 'file') {
    //转换成file对象
    return new File([u8arr], filename, { type: mime });
  } else {
    //转换成成blob对象
    return new Blob([u8arr], { type: mime });
  }
}

# 浏览器缩放比例监听

<script>
export default {
  mounted() {
    window.addEventListener('resize', () => {
      this.getWindowRatio();
    });
  },
  methods: {
    getWindowRatio() {
      let ratio = 0;
      let screen = window.screen;
      let ua = navigator.userAgent.toLowerCase();

      if (window.devicePixelRatio !== undefined) {
        ratio = window.devicePixelRatio;
      } else if (~ua.indexOf('msie')) {
        if (screen.deviceXDPI && screen.logicalXDPI) {
          ratio = screen.deviceXDPI / screen.logicalXDPI;
        }
      } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
        ratio = window.outerWidth / window.innerWidth;
      }
      if (ratio) {
        ratio = Math.round(ratio * 100);
      }
      switch (ratio) {
        case 100:
          this.text = 'text-class';
          break;
        case 110:
          this.text = 'text-class2';
          break;
        case 125:
          this.text = 'text-class3';
          break;
        case 150:
          this.text = 'text-class4';
          break;
      }
      this.ratio = ratio;
    }
  }
};
</script>

# 返回汉字拼音首字母

const strChineseFirstPY =
  'YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSCYYYNJQYXXGJHHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPCBZJJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZZXNBGNNXBXLZSZSBSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZXYALMELDCCXGZYRJXSDLTYZCQKCNNJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXPJBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQTGLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCSKDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMBDTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCSHZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZASYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNCLLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXHLGTGXBQJDZPYJSJYJCTMRNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJFFFFJCZFMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXKLQSCGJCLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZMLJLLJKYWXMKJLHSKJGBMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJGBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLLSDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJXXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYLJSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXPXJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYLYMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWGYJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPPBFYHZHTJYFDZWKGKZBLDNTSXHQEEGZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBMLSFBHHGYGYYGGBHSCYAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZYGPZSZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMCHKDSCRSWJPWXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCKZXSHMLQXXTTHXWZFKHCCZDYTCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHPYYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTXJCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGGTGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZWGPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWFZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDGCYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGAFFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTLFYQKASDNTCYHBLWDZHBBYDWJRYGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSLCMBJCSZZKYDCZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZSYMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZBYJTZBXHFDXKDASWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZEMMQBSQEHXFZMBMFLZZSRXYMJGSXWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNYNPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMCPJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYXYWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXYYRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZYJZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMTCJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYSXQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDHZGZDWYBSSCSKXSYHYTXXGCQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJYZWZXZDDXJSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWXLYDHLYQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAWHZMLJTWYGXLYQZLJEEYYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZSZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQYTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZQJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYWYWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSBDSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZGMDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQCFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMTYBBCLBJASKYTSSQYYMSZXFJEWLXLLSZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBSDZZTFDMXHCNJZYMQWSRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZXJTCZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHXNWXXKHKFHTSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHHCJYXGLHZXCSNHEKDTGZXQYPKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKTLXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWSZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSLFYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCPMMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQQPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQJSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZKKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQHHHEYTMHLFSBDJSYYSHFYSTCZQLPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBBZPNPPTYZZYBQNYDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJLJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNNWZXQXCDSLQGDSDPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAXYWQCJTLLCKJJTJHGDXDXYQYZZBYWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZKSSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQGYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJXLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJYEMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLLHYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGDXJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXMSZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYSPYMPQZMLPPLFFXJJNZZYLSJEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZSXYFYMNCWDABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYSPMJKHWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCTZQXKYQFPYYRPFFLKQUNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJSWLJMYMMZYHFBJDGYXCCPSHXNZCSBSJYJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLHPFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZBLCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZDQQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYGBDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPHZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZSKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPBYKXRYLYBHKJKSFXTZJMMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRTQZSSTKXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZMMNYTPZSXQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNYXHSZXCGJZYQPYLFHDJSBPCCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZLYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZCQQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXYGYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDESJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLBDJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMHQNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJMQPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXSRGJCWTJTZZQMGWJJTJHTQJBBHWZPXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMBZZLYGHGFMSHPZFZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQPWQLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYHDHRJZSFGXTSYCZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYKQSYSLZDQJMPXYYSSRHZJNYWTQDFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQQQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYSYXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYFJHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYPJYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJSXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWTYYDCHQLXKPZWBGQYBKFCMZWPZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYLMSTDJCYHBZLLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLTYXHQLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJCFPQRYQXCYYYQYGRPYWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXNSQYXMQYWRGYQLXBBZLJSYLPSYTJZYHYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXLYYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCRYLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDPBCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCDJJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZGMYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYSLBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYMCCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXXTXXNBHRMLYJSLTXMRHNLXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYXLSZQYXBEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXDRMJWRHXCJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZDJGTKHSSTCYJLPSWZLXZXRWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZBLZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNTYJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSDCHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLYCYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYMDJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGWHKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLLMQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZMDPJHGCLGMJJPGAEHHBWCQXAXHHHZCHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZQYXXDXXPFDMMSSYMPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPPMHNLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPMLKJXMHLMLQMXCTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNPPLPLPEPSZALLTYLKCKQZKGENQLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYDWQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDFXQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXLDDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZLLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQHZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHTXSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTCTSSYLLGZRZBBQZZKLPKLCZYSSUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYSJYCZTLQZYBBYBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJQJPDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRFKZTJDHCZKLBSDZCFJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXPZXHYZYCLWDXJJHXMFDZPFZHQHQMQGKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDLXBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZLSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHLXZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFLCJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZKJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFSZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZXZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJHZYJFJXRZSDLLLTQSQQZQWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXYWGSYJYZNBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJHZCXZBTYNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJKRDHHGXJLJJTGXJXXSTJTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFXGFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRLFSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLYZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFXPYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXDYLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQYCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDUTJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJFZYNAKRGYWYQPQXXFKJTSZZXSWZDDFBBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJKYHCPSTMCSQTZJYXTPCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJPXGLBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZZGJZZXTZJXYCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCYSCCLDXYCDDQLYJJWMQLLCSGLJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZMYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBGMYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCYXZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJYHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBXGLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJDQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQDSPDJZZGKGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXXNCWCXYPMAELYKKJMZZZBRXYYQJFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCXTLWDQZPCYCYKPPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXMBDZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLYXWJHSNLXYYXHBHAWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXXLYLLJDZBTYMHPFSTTQQWLHOKYBLZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHLJKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZKBXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHGZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFYWLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZWFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGCULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJLLQZYJSWXMZZMMYLMXCLMXCZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLLLPYPSYJYSXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZYPFDWFGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYDTZJYQGGKQTTFZXBDKTYYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJDSZBLPRZTSWSBXBCLLXXLZDJZSJPYLYXXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGYGMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCYZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZYXXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZLJJXLSBHPYXXPSXSHHEZTXFPTLQYZZXHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWDXZSXZDZXLEYJJZQBHZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJHOJYNXELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYDMPXMDSXYBSQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPGNYDMSXHMMMMAMYNBYJTMPXYYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXMJSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZBYZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQSQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQQJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZKZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMTJQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLCTZSXKJZQZPZLBZRBTJDCXFCZDBCCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYCZGJWYXDXFRSKSTQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZFYBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCPZBLLCYBBBBUBBCBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSSTPHNDJXXBYXQTZQDDTJTDYYTGWSCSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZAZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYYLLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJXGNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYMRBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMSLPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZXJCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXTQCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLFNDXQKCZFYWHGQMRDSXYCYTXNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZCZPTQFZMYFLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZTLMLWZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZJYJGMCTXLTGXSZLMLHBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQMSTPXLSKLZYNWRTSQLSZBPSPSGZWYHTLKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCLXXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQJZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKNXJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGYZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQGBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZLPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZNCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPCQDHLXZLYCBLCXZZJADJLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQKTWPXXHCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBBFJLLCXDLMJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPSSYYFNEJDXYZHLXLLLZQZSJNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYADTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDDWRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZPKJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSHCKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQHYWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHHJTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQBSHYLLPJJJTHYJKYPPTHYYKTYEZYENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFSYZYZBJTBCTSBSDHRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZNSDJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQPQJPZYPZJZNJPZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQCZLPTXCDYYZXSQZSLXLZMYCPCQBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJQQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZTDKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBRFERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDDNXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXCYZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSDDTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZSQYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZHLYQQJBEYFXXXWHSRXWQHWPSLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELGLXYDJYTLFBHBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYFLZBYFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJTJTPWJYBJJBXJJTJTEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHYYXWSHCTXRLJHQXHCCYYYJLTKTTYTMXGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYLBLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZGLHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJLJXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQQMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQDCYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTTSSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHWWKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWPYMLGKDLDLGKQQBGYCHJXY';
//此处收录了375个多音字,
const oMultiDiff = {
  19969: 'DZ',
  19975: 'WM',
  19988: 'QJ',
  20048: 'YL',
  20056: 'SC',
  20060: 'NM',
  20094: 'QG',
  20127: 'QJ',
  20167: 'QC',
  20193: 'YG',
  20250: 'KH',
  20256: 'ZC',
  20282: 'SC',
  20285: 'QJG',
  20291: 'TD',
  20314: 'YD',
  20340: 'NE',
  20375: 'TD',
  20389: 'YJ',
  20391: 'CZ',
  20415: 'PB',
  20446: 'YS',
  20447: 'SQ',
  20854: 'QJ',
  20857: 'ZC',
  20911: 'PF',
  20504: 'TC',
  20608: 'KG',
  20985: 'AW',
  21032: 'PB',
  21048: 'XQ',
  21049: 'SC',
  21089: 'YS',
  21119: 'JC',
  21242: 'SB',
  21273: 'SC',
  21305: 'YP',
  21306: 'QO',
  21330: 'ZC',
  21333: 'SDC',
  21345: 'QK',
  21378: 'CA',
  21397: 'SC',
  21414: 'XS',
  21442: 'SC',
  21477: 'JG',
  21480: 'TD',
  21484: 'ZS',
  21494: 'YX',
  21505: 'YX',
  21512: 'HG',
  21523: 'XH',
  21537: 'PB',
  21542: 'PF',
  21549: 'KH',
  21571: 'E',
  21574: 'DA',
  21588: 'TD',
  21589: 'O',
  21618: 'ZC',
  21621: 'KHA',
  21632: 'ZJ',
  21654: 'KG',
  21679: 'LKG',
  21683: 'KH',
  21710: 'A',
  21719: 'YH',
  21734: 'WOE',
  21769: 'A',
  21780: 'WN',
  21804: 'XH',
  21834: 'A',
  21899: 'ZD',
  21903: 'RN',
  21908: 'WO',
  21939: 'ZC',
  21956: 'SA',
  21964: 'YA',
  21970: 'TD',
  22003: 'A',
  22031: 'JG',
  22040: 'XS',
  22060: 'ZC',
  22066: 'ZC',
  22079: 'MH',
  22129: 'XJ',
  22179: 'XA',
  22237: 'NJ',
  22244: 'TD',
  22280: 'JQ',
  22300: 'YH',
  22313: 'XW',
  22331: 'YQ',
  22343: 'YJ',
  22351: 'PH',
  22395: 'DC',
  22412: 'TD',
  22484: 'PB',
  22500: 'PB',
  22534: 'ZD',
  22549: 'DH',
  22561: 'PB',
  22612: 'TD',
  22771: 'KQ',
  22831: 'HB',
  22841: 'JG',
  22855: 'QJ',
  22865: 'XQ',
  23013: 'ML',
  23081: 'WM',
  23487: 'SX',
  23558: 'QJ',
  23561: 'YW',
  23586: 'YW',
  23614: 'YW',
  23615: 'SN',
  23631: 'PB',
  23646: 'ZS',
  23663: 'ZT',
  23673: 'YG',
  23762: 'TD',
  23769: 'ZS',
  23780: 'QJ',
  23884: 'QK',
  24055: 'XH',
  24113: 'DC',
  24162: 'ZC',
  24191: 'GA',
  24273: 'QJ',
  24324: 'NL',
  24377: 'TD',
  24378: 'QJ',
  24439: 'PF',
  24554: 'ZS',
  24683: 'TD',
  24694: 'WE',
  24733: 'LK',
  24925: 'TN',
  25094: 'ZG',
  25100: 'XQ',
  25103: 'XH',
  25153: 'PB',
  25170: 'PB',
  25179: 'KG',
  25203: 'PB',
  25240: 'ZS',
  25282: 'FB',
  25303: 'NA',
  25324: 'KG',
  25341: 'ZY',
  25373: 'WZ',
  25375: 'XJ',
  25384: 'A',
  25457: 'A',
  25528: 'SD',
  25530: 'SC',
  25552: 'TD',
  25774: 'ZC',
  25874: 'ZC',
  26044: 'YW',
  26080: 'WM',
  26292: 'PB',
  26333: 'PB',
  26355: 'ZY',
  26366: 'CZ',
  26397: 'ZC',
  26399: 'QJ',
  26415: 'ZS',
  26451: 'SB',
  26526: 'ZC',
  26552: 'JG',
  26561: 'TD',
  26588: 'JG',
  26597: 'CZ',
  26629: 'ZS',
  26638: 'YL',
  26646: 'XQ',
  26653: 'KG',
  26657: 'XJ',
  26727: 'HG',
  26894: 'ZC',
  26937: 'ZS',
  26946: 'ZC',
  26999: 'KJ',
  27099: 'KJ',
  27449: 'YQ',
  27481: 'XS',
  27542: 'ZS',
  27663: 'ZS',
  27748: 'TS',
  27784: 'SC',
  27788: 'ZD',
  27795: 'TD',
  27812: 'O',
  27850: 'PB',
  27852: 'MB',
  27895: 'SL',
  27898: 'PL',
  27973: 'QJ',
  27981: 'KH',
  27986: 'HX',
  27994: 'XJ',
  28044: 'YC',
  28065: 'WG',
  28177: 'SM',
  28267: 'QJ',
  28291: 'KH',
  28337: 'ZQ',
  28463: 'TL',
  28548: 'DC',
  28601: 'TD',
  28689: 'PB',
  28805: 'JG',
  28820: 'QG',
  28846: 'PB',
  28952: 'TD',
  28975: 'ZC',
  29100: 'A',
  29325: 'QJ',
  29575: 'SL',
  29602: 'FB',
  30010: 'TD',
  30044: 'CX',
  30058: 'PF',
  30091: 'YSP',
  30111: 'YN',
  30229: 'XJ',
  30427: 'SC',
  30465: 'SX',
  30631: 'YQ',
  30655: 'QJ',
  30684: 'QJG',
  30707: 'SD',
  30729: 'XH',
  30796: 'LG',
  30917: 'PB',
  31074: 'NM',
  31085: 'JZ',
  31109: 'SC',
  31181: 'ZC',
  31192: 'MLB',
  31293: 'JQ',
  31400: 'YX',
  31584: 'YJ',
  31896: 'ZN',
  31909: 'ZY',
  31995: 'XJ',
  32321: 'PF',
  32327: 'ZY',
  32418: 'HG',
  32420: 'XQ',
  32421: 'HG',
  32438: 'LG',
  32473: 'GJ',
  32488: 'TD',
  32521: 'QJ',
  32527: 'PB',
  32562: 'ZSQ',
  32564: 'JZ',
  32735: 'ZD',
  32793: 'PB',
  33071: 'PF',
  33098: 'XL',
  33100: 'YA',
  33152: 'PB',
  33261: 'CX',
  33324: 'BP',
  33333: 'TD',
  33406: 'YA',
  33426: 'WM',
  33432: 'PB',
  33445: 'JG',
  33486: 'ZN',
  33493: 'TS',
  33507: 'QJ',
  33540: 'QJ',
  33544: 'ZC',
  33564: 'XQ',
  33617: 'YT',
  33632: 'QJ',
  33636: 'XH',
  33637: 'YX',
  33694: 'WG',
  33705: 'PF',
  33728: 'YW',
  33882: 'SR',
  34067: 'WM',
  34074: 'YW',
  34121: 'QJ',
  34255: 'ZC',
  34259: 'XL',
  34425: 'JH',
  34430: 'XH',
  34485: 'KH',
  34503: 'YS',
  34532: 'HG',
  34552: 'XS',
  34558: 'YE',
  34593: 'ZL',
  34660: 'YQ',
  34892: 'XH',
  34928: 'SC',
  34999: 'QJ',
  35048: 'PB',
  35059: 'SC',
  35098: 'ZC',
  35203: 'TQ',
  35265: 'JX',
  35299: 'JX',
  35782: 'SZ',
  35828: 'YS',
  35830: 'E',
  35843: 'TD',
  35895: 'YG',
  35977: 'MH',
  36158: 'JG',
  36228: 'QJ',
  36426: 'XQ',
  36466: 'DC',
  36710: 'JC',
  36711: 'ZYG',
  36767: 'PB',
  36866: 'SK',
  36951: 'YW',
  37034: 'YX',
  37063: 'XH',
  37218: 'ZC',
  37325: 'ZC',
  38063: 'PB',
  38079: 'TD',
  38085: 'QY',
  38107: 'DC',
  38116: 'TD',
  38123: 'YD',
  38224: 'HG',
  38241: 'XTC',
  38271: 'ZC',
  38415: 'YE',
  38426: 'KH',
  38461: 'YD',
  38463: 'AE',
  38466: 'PB',
  38477: 'XJ',
  38518: 'YT',
  38551: 'WK',
  38585: 'ZC',
  38704: 'XS',
  38739: 'LJ',
  38761: 'GJ',
  38808: 'SQ',
  39048: 'JG',
  39049: 'XJ',
  39052: 'HG',
  39076: 'CZ',
  39271: 'XT',
  39534: 'TD',
  39552: 'TD',
  39584: 'PB',
  39647: 'SB',
  39730: 'LG',
  39748: 'TPB',
  40109: 'ZQ',
  40479: 'ND',
  40516: 'HG',
  40536: 'HG',
  40583: 'QJ',
  40765: 'YQ',
  40784: 'QJ',
  40840: 'YK',
  40863: 'QJG'
};
// 获取五笔简码
const wubiLib = [
  'A鞴鞲鞣鞫鞯鞔鞒鞑鞅靼銎跫綦翳蛩颟鹳鹋鸫鸢慝觐觋贳瓯戡檠迓甙忒弋撖摁廾蘼蘖蘩蘅蘧藿藜藁藓薰薷薹薅薜薮蕹薏薇薨薤蕻蕲蕃瞢蕺蕞蕤蕨蕈蕙蓼蓿蔻蕖蔺蔟蔹蓰蔸甍蔌蓣蓥蒗蒴蒹蒡蓠蒺蒿蓊蓓蒽蓦蓐蓍蓁葭萱蒎蒌葶葩葆萼葸蒉葺蒈蒇葳葙葚葑葜菡菰萦菀菅菪菹菸萃萏菟菔萆萑萸萜菖菽菝萋萘堇菘菥萁菁莼莺莨莞莘荻莸荽莩莶荼莅莜莓莪莠莴莳荸莰荮荭荪荬荩茛荨荥荦茳茺茭荠茗荀荟荃荇荏茯荞莛茱茴茼莒茈荜荛荑茜苕苠茕茔茆茚茑苓苻茌苘苒苴苜茇茏苤苷茉苡芤苎苄芟芪芡芴芩苁苌苋芮芷芘苣苊苈芰芾芸芫芙芗芑芎芄芨芊芏艿艽艹鄞郾邛劐蒯赜匾匮匦叵匚廿茁著芝蒸斟蔗蘸藻葬匝蕴苑芋荧营萤莹英荫茵艺颐医药尧燕雅牙芽鸦薛靴蓄芯薪邪鞋萧巷项匣熙昔芜巫卧蔚萎苇藤萄苔蓑蒜苏斯薯蔬世式甚芍苫莎散萨若蕊茹荣蓉茸戎惹鹊颧区擎芹勤莲荔莉蕾勒劳蓝莱葵匡苦恐苛勘菌巨菊鞠敬警茎荆靳芥藉戒节蕉匠蒋荐茧荚蓟基惑或获荤茄切翘鞘巧蔷其七欺期蒲菩葡莆萍苹匹蓬藕殴鸥欧孽蔫匿慕募幕暮墓某莫蘑摹蔑藐苗蒙萌茂茅莽茫芒蔓落萝芦菱黄荒划花葫菏荷邯菇苟共贡汞巩恭功攻工葛革戈甘芬匪菲芳范藩贰董东蒂荡葱茨臣茶茬草藏苍蔡菜菠鞭蔽蓖苯薄苞靶芭鞍艾蔼',
  'B粜蚩颞聩聒聍聆聃耵骘孢孓孑屮隳凵勐鄹隰隗隍隈陴陲陬陧陟陔陉陂阼阽阪阱阡阢阝卺亟丞阻子孜坠职阵障陨院隅隐阴也耶阳逊限陷险隙卫陀陶孙祟隧随隋陕阮孺娶取了辽聊联孔聚阶降际聘陪聂陌孟陆陋陇隆陵函孩孤耿隔附防耳堕队陡耽聪除出耻承陈陛隘阿',
  'C鍪蟊蝥颡矜皴鹬鹜甬瞀怼炱毵骧骥骣骢骠骟骝骛骖骓骒骐骊骈骅骁骀驿驺驸驷驵婺逡迨迳巯畚弁厶邰刭驻骤蚤允驭豫预予又勇恿以矣验驯熊戏驼驮通台双驶圣骚桑叁柔劝驱垒骏驹颈劲骄艰鸡骑骗能难牟矛马骆骡驴欢骇观对叠邓怠驰骋叉参驳巴',
  'D鬣鬟鬓鬏鬈髹髭髻髫髯髦髡髟魇蹙趸翡舂蜚蜃虿耱耨耩耧耦耥耢耠耜耖耔耒鹩鹕鹌鸸鸪瓠礴礞礤礓磴礅磲磉磙磔碥碹碲碣碡碜碇碚碓碛硪硌硇硐硗硖硭硎砩砣砬砥砼砟砻砺砹砝砜砭斫砑砘砗砉砀矸矶恧恝焘斐飙欹腴挈臧戛彗尴尬尥尢匏耷奁夼劢酆劂剞刳赝靥厮厥厣厝厍仄嘏左奏鬃砖砧丈在砸耘愿原郁右友有尤硬页雁砚厌艳奄研压戌雄硝厢咸夏厦袭矽硒戊威万碗厅套碳态太泰碎肆硕爽耍戍寿石盛砷奢砂三辱确犬秦历砾励厉厘磊奎盔矿夸克磕砍厩韭兢礁硷碱慧灰磺牵砌契奇戚破砒碰硼砰裴耪碾奈耐面迈码碌垄聋龙硫磷胡厚耗夯硅顾故古辜龚耕感奉丰奋非矾而厄夺碟碉碘大达磋存磁蠢唇春础厨成辰厂碴厕布泵奔辈悲碑磅帮邦百耙碍',
  'E雎貔貘貅貊貂豸豕繇鹞燹膦臁膻臊朦臌膪膣滕膑膈媵塍腧腭腽腼腩腠腱腚腙腓腌腈脲脘脬脞脶豚脒朕胼胲脎脍胭胴胱胫胝朐胗胍胙胂胛胪胩胨胧肷肭肫肱肽朊肼肜肟刖虢爰戤孚尕邈彡豳奚垡郛鼐助逐肘肿脂肢胀脏孕月用臃盈臆胰腋舀遥腰悬须胸腥胁腺县膝腕妥脱腿腆腾膛胎舜甩受胜膳腮乳脸肋腊胯爵脚胶及肌且腔脐脾鹏朋膨胚胖脓腻脑乃膜觅貌脉貉股胳肛肝腹腑脯服肤肺肥肪肚胆脆肠彩采膊脖豹胞膀肮胺爱',
  'F鼋霾霰霭霪霎霏霈霁霆雯雳雩謦赭赧趱趑趔趄赳麴翥裘箐罄螫颢颉顸耋鹁盍瞽磬悫恚熹觳毂彀耄觏觌赍贲耆甏戟辇韬韫嫠遘逵逑懿鼙馨墀墚墉墁塬塥堠塄堙堞堀埭埽堍堋埝埤埸埯埴垸埒埙埚埘埕垠垴垧埏垲垌垤垭坳坶坭坨坻坼垆坫垅坩坂圻坜圯圮圹圳圪圬圩酃邗卦啬孛亓兀亍走专煮志址直支震真者赵增载哉栽运云越远袁垣元域雨壹堰严盐雪需墟幸协孝霄献现霞喜雾坞无斡未违韦顽土填替趟塘坦坛坍塔塌索寺霜士示十声赦墒丧韧壤却去趣趋求雷老垃坤亏款块垮坑壳坷考坎堪刊均救境井进劫截教嘉吉圾击魂卉墙乾起埔坡坪霹坯彭培霓南霉卖埋露零霖坏壶赫郝壕翰韩过圭规鼓垢埂赶干赴夫封坟坊二垛墩堆堵都动颠地堤戴寸矗翅赤城趁朝超场才裁埠勃博雹霸坝埃',
  'G餮餍鳌鏊靓豉豇麸纛翮蠹螯虺聱鹉鹂忑欤敕赉戬戋軎殪殡殛殚殍殓殒殄殇殂殁獒橐瓒璩璨璞璋璇璁璀璎璜瑾瑭瑷瑙瑕瑗瑜瑁琚琛琬琮琰琨琥琦瑛琪琏珲珞珧珩琊顼珙珥珈珉珀玳玷珑珂珏玟玢玮玑玎骜遨逦逋忝墼垩鄢郦郅郏邳邴剌芈噩孬鬲亘丕卅丐琢赘珠致至殖政正整臻珍盏责枣遭再玉与盂于迂夷一瑶殃焉亚殉邢形型刑下五武吾王玩豌歪瓦屯吞天琐速素死束殊事蚀珊瑟瑞融球琼青琴裂列两璃丽理琅赖来开玖静晋柬歼颊夹棘霍惠妻平琵琶弄囊末灭玫麦玛琉玲琳烈还环画互瑚瑰更副甫敷否珐恶顿毒逗豆靛到殆带歹刺曹残蚕不玻丙表碧逼甭班斑熬敖',
  'H虍瞿龌龊龉龈龇龆龅龃龀訾觜鹾粲虔颦颥鸬瞵瞰瞠瞟瞑瞌睽瞍睿睥睢睨睚睃睇睑睐眸眵眦眭眙眈眇盹眍眄盱砦忐氍觑觇赀攴遽壑矍卣乩丨紫桌卓瞩止睁贞战占瞻眨虞眼眩虚些瞎凸瞳眺瞬睡叔上龋眶肯卡具旧睛睫瞧歧颇频皮盼虐睦目瞄眠眯瞒虑虏卤颅卢龄虎睹督鼎盯点瞪此雌瞅齿柴餐睬步卜彪',
  'I鲨鲎鎏鋈裟淼泶沓懑氅挲尜娑逍灞灏瀵瀹瀛瀣瀚濯濠濞濮濡濂澶澹澧濉濑潺潼潲潸澌澍澉漩漉漪潴潋漶漯滹漕漤潇潆潢溟滂溏滏溴滗溷溻溽溧溥滢漭滠溘溱滟湄渥渲湔湓溆湟溲湫湎湮渫涮渌涫渖淙淝淦渑淠涿渎淞淅淇渚浣浼浠浜涔涓浞涠涞浯涑洳浔浒浏洚洵洮浍洫洎洙洄洇浈浃洌洧洹泾泯泓沱泮泫泺泖泠沲泗泱泸泷沭泔泐沩沆汶汴汩汨沌沔沐沅沣汊汜汔氵喾凼黉鼗渍滓淄滋注洲治滞汁浙兆沼涨掌漳湛沾渣泽澡源渊浴誉渔渝淤游油涌泳淫溢沂液耀漾洋演淹涯汛学汹兴泻泄肖小淆消削湘涎洗汐溪污沃涡温渭潍汪湾洼湍涂汀添涕淘逃滔涛烫淌棠堂汤潭滩汰溯水漱淑湿省渗沈深涉少裳尚赏汕沙涩洒润汝溶染雀渠泅清沁潦粱梁涟沥漓泪涝浪滥澜溃渴浚觉沮举酒浸津洁浇江涧溅渐尖济脊汲激活混浑汇辉浅潜洽泣汽沏柒漆瀑浦婆泼漂澎沛泡潘派湃沤浓泞涅溺泥淖漠沫渺泌没漫满洛沦滦滤潞漏流溜淋劣涣淮滑沪湖洪鸿涸河浩汉汗涵海光灌沽沟港溉涪浮汾沸泛法洱渡洞淀滇涤滴党当淡淬淳滁池澄沉尘澈潮敞常尝测沧泊渤波滨濒澳',
  'J蠼蠛蠊蟾蠓蠖蟮蟠蟪蟛蟀蟑蟓蟋螳螵螬蟥螃螗螭螅螈蟆蟒螨螓蝙蝤蝼蝣蝓螋蝮蝌蝰蝠蝻蝾蝽蜢螂蜿蜷蜩蜱蜴蝈蜾蜮蜥蜞蜻蜣蜉蜍蜊蜈蛸蛑蛘蛟蛴蛞蜓蛐蛳蛭蛲蛱蚴蛏蛉蚯蚱蚺蚰蛎蚵蛄蚶蚓蚪蚣蚧蚝蚬蚋蚍蚨虻虼虮虬煦曩曦曜曛暾暝暧暌暄晷晗晡晖晏晁晔晟昵昱昴曷炅昀昕昃杲昙昊旰旯戥韪暹遢夥勖刂禺昨最蛀蛛蜘照昭早晕曰遇愚蛹映影蝇易蚁曳野蜒蚜星蝎歇晓显贤暇虾晰晤蜗蚊旺晚蛙蜕题剔帅墅竖曙暑是时师肾申蛇晌晒蠕日蛆晴晾量里览蜡昆颗景晶紧鉴坚监晦蛔晃蝗曝暖螟明冕盟昧冒曼蚂螺临蝴虹旱果滚归蛊蛤蜂遏蛾蝶电旦虫匙晨畅昌蝉暴蚌昂暗',
  'K饕鼍黾躞躜躐躔躏躅蹴蹯蹼蹶蹰蹊蹒蹑蹂蹁蹉踱踽踵踹蹀踺踯踣踮踬踟踝踔跽踉跤跻跹跣跸跷跬跆跛跏跎跞跚跗跖跄趺趼趿趵颚鹭鹗戢璐囔嚯嚓嚅噼噻噫噱噤嚆噔噌噜噙噢噍嘬噗嘹噘嘭嘧嘀嗾嘣嘤嘁嘌嘈嘞嗤嗵嗨嗍嗌嗳嗲嗥嗯嗄嗝嗦嗔嗬嗫嗑嘟嗉嗷嗪喙喔喽嗟喑嗖啾喟喁喈喹喱喃嗒喋啜唰唳啷啶啵啖唷唼啐唿啕啁啭啉喵喏啧唪唧唑唏唣唢哳唔哽唠哧唛哞哏哝咤咪咩哜哚哙哌咿咻哕咣呲哔哓咦咧哒咴哂咭哐咝呦呶咄咛咚呤呱呷咔咂吲吣呙呗吡呃呖呔呓呒呋吆吖吒叻叨叩叽叱卟郢嘴足踪啄嘱咒忠盅中只趾吱咋喳噪躁咱郧跃员喻吁咏踊哟吟邑遗叶噎咬唁咽哑呀勋喧嘘嗅兄啸嚣哮响吓吸嘻吴呜嗡吻喂味唯哇唾吐听跳嚏啼蹄踢叹踏蹋唆虽嗽嗣嘶顺吮噬嗜史呻哨啥嗓嚷哩啦喇旷跨哭口吭啃咳咯咖喀鹃踞距咀叫嚼践呛遣器品啤喷呸跑咆趴啪呕哦啮呢呐哪鸣吗嘛骂吕路咙另唤患哗唬呼吼喉哄哼嘿喝呵号嚎喊哈贵跪剐咕跟嘎噶咐吩吠啡鄂跺哆蹲吨叮跌吊叼蹬蹈呆蹿吹串喘川躇踌吃逞呈吵嘲唱蹭踩哺别鄙蹦跋吧叭唉哎啊',
  'L黯黪黥黩黢黟黠黝黜錾袈罾羁罹罱罴罨詈罟罡罘疃畹畛畈畋畎畀町辚辘辏辎辍辋辄辂辁轾轼轺轹轷轸轶轵轳轲轱轭轫椠嬲迦圜圉圊圄囿囹囫囵囡囝囗勰哿罪浊转轴置辙罩辗斩轧暂圆园辕因鸭轩辖胃畏围团图田四思蜀署输软圈囚轻辆连力累困界较轿驾架甲加辑畸回堑黔畦圃毗畔男默墨皿逻罗轮略轰黑贺国辊轨固辅辐罚恩囤畴车边办罢',
  'M髑髌髋髂髅髀髁骼骺骶鹘骷骰骱罂颛鹦殳飚飕飓飑胄觊赙赕赇赈赆赅贻贶遄迥巅嶷嶝嶙嶂嵴嵩嵊嵫嵝嵯嵛嵬崽崴崾嵘崆崞崤崮崦崧崃崂峥峋峤峒峄岷峁岣岫岬岽岢岵岜岚岑岘岈岖岐岍屺岌幡幞幛幔幄帷帼帻帱帔帙帏兕夙罔冂剀刿赚贮周峙帜帧账帐崭赠贼则赃峪屿邮由婴屹鸯央岩崖峡巍网彤同帖贴炭岁髓赎赊赡删山肉冉曲岿凯峻巾见贱几贿幌凰峭嵌岂崎赔帕内帽赂岭骸骨购岗刚冈赋幅凤风峰贩凡帆峨剁朵赌雕典迪丹崔赐幢崇册财贬崩贝败凹盎岸',
  'N鐾羿襞胥疋鹨鹛愍熨擘甓檗璧嬖羼屦屣孱屙屐咫尻遐戕爿懵懔憷憧憔憬慵慊愫愎愀惴愣愕愦愠悴惚惆惘惝悱悻惬悛悌悒悃悝悭悚悖恽恪恂恺恻恹恸怡怿怊怫怩怍怏怛怦怵怙忸忭忪怆怅忾忤忡怄忮怃忏忖忉忄嵋崛奘巽乜昼怔展憎悦羽愉忧翌翼异忆乙已迅恤性惺心忻屑懈习犀惜悟屋慰尉尾惟惋臀屠恬屉惕巳司刷属书疏收恃屎虱尸慎慑屈情怜懒愧快慷慨剧惧局居惊尽届忌悸己悔恢恍惶怯悄恰屏譬屁劈怕懦尿尼恼悯民眉忙慢买屡履戮慌怀恒恨悍憾憨惯怪敢改愤飞发惰恫懂刁殿惦翟悼导蛋惮翠戳丑尺迟忱层惨惭怖避臂壁辟必懊',
  'O糨糗糅糈糍糌糇糁粽粼粞粝粑敉籼黼黻黹灬爝燧燔燠熠熵熳熘煺煸煊煅煨煜煳焱焯焖焓焐烊烨炫炷烀炻炝炖炜炀遴燮郯邺剡籽灼烛粘炸燥灶凿糟业焰炎烟烯熄烷烃糖烁数烧煽熔燃炔料燎粮炼粒类烙烂烤炕糠炬炯粳精烬火烩煌粕炮糯米迷煤炉娄焕糊烘焊糕烽粪粉烦断灯粹粗锤炊炽炒糙灿炳焙爆',
  'P衤窳窭皲襻襦襁褶褫褴褊褛褓褙褡裰裾裨裼褚裱裥裣裎裢裉袼袷裆袢袂衿衽衲衩窨窬窠窦窕窈窆窀穹穸鸩禳禧禚禊禅祺祧祯祠祗祢祚祓祜祛祉祆祀礻邃逭辶謇蹇寰褰寮寤搴骞甯宸宥宓宕宄宀廴郓冥冢冖剜祖宗字祝宙窒之寨窄宅宰灾冤裕寓宇寅宜揖窑宴穴宣袖写宵祥宪窝宛完袜褪突袒它宿宋守视室实审神社衫赛塞褥冗容裙穷寝寥帘礼牢窥宽裤窟寇空客军究窘襟窖家寂寄祸豁窃窍祁祈袍农宁寞幂密蜜寐裸禄窿宦宏鹤褐罕寒害冠官褂寡宫割富袱福额定祷窜窗穿初宠衬察补宾被宝袄案安',
  'Q鳢鳟鳝鳜鳙鳗鳕鳔鳓鳐鳏鳎鳍鳋鳊鳇鳆鳅鳄鲽鲼鲻鲺鲷鲶鲵鲴鲳鲲鲱鲰鲮鲭鲫鲩鲧鲦鲥鲣鲢鲡鲠鲟鲛鲚鲕鲔鲒鲑鲐鲋稣鲈鲇鲆鲅鲂鱿鑫觯觫觥觚觞觖斛袅鹱鸱鸲锺镳镲镱镯镬镫镪镩镨镧镦镥镤镢镡镝镟镞镛镙镘镗镖镔镓镒镏镎镌镉镆镅镄锵镂锿锾锼锸锷锶锴锲锱锬锩锫锪锢锟锞锝锛锘锖锕锔锓锒锏锎锍锊锉锇锆锂锃铿铽铼铹铷铵铴铳铯铮铫铩铪铨铧铥铤铢铠铟铞铛铘铙铗铖铕铒铑铐铎铍铌铋铊铉铈铄钿钽钼钺钹钸钷钶钴钲钰钯钬钭钪钫钤钣钜钛钚钕钗钔钐钏钍钌钊钋钇钆钅盥眢欷肴橥桀枭玺邂遛逖迩馕馔馓馑馐馍馊馇馄馀饽饷饴饬饫饪饩饨饧饣夤飧舛獾獯獬獠獗獍獐猱猸猬猥猹猢猕猝猞猊猡猓猗狻狺猃狳猁狷狴狲狩狯狨狒狍狎狁狃犸犷犴犰犭弑鬯劬奂刍郗郇郄邸邬凫匐訇匍勹刎刈氐爻丌钻邹锥铸猪皱钟炙争狰镇针锗詹铡匀钥怨猿鸳狱鱼犹铀迎印饮银逸铱旬锈匈凶猩锌蟹销象镶馅鲜锨狭铣夕希锡勿乌钨危外鸵兔铜铁锑獭锁饲氏饰狮勺煞刹杀色鳃锐饶然卿镣链镰吏鲤狸镭乐狼馈狂钧句锯狙灸久镜鲸锦金解饺角狡铰饯键钾急饥昏钦锹欠钳钱铅钎铺刨钮狞镍镊鸟馁钠名铭勉免猛锰镁贸卯铆锚猫馒锣卵铝鲁留馏铃猎猾狐忽猴狠锅龟逛馆够狗勾钩铬镐钢钙负孵锋饭犯钒饵尔儿饿多钝锻镀独兜锭钉钓甸狄岛错匆触雏锄钞猖铲馋猜铂钵狈钡鲍饱包镑',
  'R魑魍魈魉魃魅踅絷罅缶蜇颀鹎鸷瓞皤皓皎皈敫氲氪氤氩氡氚氙氘氕搿掰贽遑逅攮攥攉擢擤擗擐擀撺撙撸撷摺摭撄摞搡搦搌搠搛搋摅掾揆摒揎揞揄揿揠揸揲掼掮捩掊掬捭掴掎捺捱揶掭捃捋挹拶挢拮拗拚拊抻抟扪扌郫邾卮揍拙捉撞撰拽爪抓拄朱质制掷挚指执拯挣振蛰哲折找招摘扎择皂攒岳援拥殷抑掖摇邀氧扬掩押欣卸携挟掀舞捂握挝皖挽挖拓托拖推投捅挺挑提掏搪探摊抬挞所损擞搜撕拴摔抒授手势逝誓拭拾失摄捎擅扫搔撒揉扔热扰攘缺泉邱丘氰氢擒撂撩擂捞揽拦拉扩括捆魁挎扣抠控拷抗扛看揩掘抉攫撅捐据拒拘揪近斤捷接揭搅捡拣技挤挥皇撬抢扦掐气扑迫魄乒拼撇披批捧抨抛乓排拍爬挪扭牛拧捏捻撵年拈拟挠氖拇抹摸抿描抡掠氯掳搂拢拎换护后捍撼氦鬼罐拐挂瓜拱搁搞皋缸抚氟拂扶氛返反扼掇遁盾抖迭掉垫掂抵的捣挡氮掸担打搭挫措搓撮摧捶揣搐抽斥持撑掣撤扯抄掺搀拆搽插操擦捕帛搏拨播兵摈膘卑报抱拌扮扳搬拜摆白把拔扒捌翱按氨皑挨',
  'S醺醴醵醯醮醭醪醣醢醑醍醐醅醌酹酴酲酾酽酯酩酰酡酢酤酏酎酐酊覃皙懋檫檩檐檑橼橘樨樽橹檎樵橛樾橄槲樘樗槭樯槿榍槠榕槟槁榱槔榭榫榻榧榛楹楣楦榉槎榈榇槌椴楸榀楫榄楝楂楠椹楱椐棣楗椁椋棰椤棹椟棼楮棂桫梓桷桴梏梵栩桉桧桁桦桕栝梃桤桄桢桎桡桠栳栲柽柁栎柢枸柃栀柝枳柚枵柙栌枰柩栊柘栉柰杼杷枋枞枨杵枧枘杳杪枇枥杩杈杞杓杌鄄剽柞醉棕酌椎桩柱株植枝枕甄杖樟栈榨栅札酝榆酉樱椅椰要样杨酗朽杏醒械楔校橡想相檄西析梧桅枉椭桶酮桐梯桃檀酞梭酸粟酥松栓树述术梳枢柿梢杉森榷醛权栗李楞棱酪榔栏婪框酷枯可棵柯楷禁杰桔酵椒槛检贾枷极机桥橇枪棋栖朴票瓢飘棚配攀柠酿木模棉醚梦檬酶梅枚麓楼柳榴林桓槐横核杭酣棍柜桂棺构梗根格歌哥杠柑杆概覆枫焚酚樊杜栋顶丁档村醋醇椿椽楚橱酬橙郴查槽材柄彬标本杯棒榜梆板柏',
  'T齄鼾鼽黧鳘雒艨艟艚艏艋艉艄舾舴舳舻舸舫舨舯舭舣舢舡衄臬籀籁簸簦簪簟簋簖簏篼篾簌篪篦篥篚篝篌篁篑箴箫箢箜箪箅箨箝箬箸箧箦筱筲筢筻筮筠筝筌筵筅筚筘笞笾笳笤笥笠笱笮笙笪笸筇笏笫笊笕笄笃笈竽竺舐螽鹄鸹穰馥黏穑稷稹稔稞稂稃嵇稆秫秣秭秕雉矬矧眚憩愆歃牖牒牍攵氆氇毽毳毪犒犏犍犋犄牿牾牯牦牝昝榘逶逄迤迮迕夂衢徼徵徭徨徜徙徕後徉徇徂彷彳岙鄱郜籴汆劓睾毓胤囟夭乇丿纂租自篆筑竹舟重种稚秩智知征毡乍怎造赞粤御禹釉役移秧衍延衙循熏血选徐秀行衅笑向箱香舷衔先系悉息稀牺务物午我稳魏委微往颓徒秃透筒艇廷条舔甜特躺毯笋穗算艘私税黍释适矢剩升牲甥生身射舌稍扇筛入壬躯秋利篱黎犁梨篮筐筷科靠矩咎径筋街秸矫舰箭简笺稼季籍箕积稽秽徽簧乔签迁千迄乞片篇篷磐盘徘牌穆牧牡敏秒秘每么毛箩乱律篓笼徊乎衡很和禾航管乖刮箍躬各告稿篙秆竿复符逢繁翻番乏筏鹅舵躲短犊冬丢第笛敌等得德稻待答篡簇囱辞垂船处臭筹愁稠秤惩程乘称彻长策舱簿舶箔秉币彼笔鼻笨惫备版般稗笆奥矮',
  'U鲞蹩翦粢羲羰羯羧羟羝竦翊癯癫癖癜癔癞癍瘳瘾癃瘵瘿瘰瘭癀瘠瘢瘼瘛瘙瘕瘘瘥瘊瘗瘌瘅瘀瘐痿痼痱瘃痧痫痤痦痨痣痍痖痂痃疰疱痄疸疴疳疣疬疝疠疖疔疒鹣鹚鹈鹇蠲戆恣恙飒歆旮甑瓿猷槊桊孳妾遒丬阚阙阗阖阕阒阏阍阌阋阊阈阆阄阃闾闼闶闵闳闱闫闩啻鄯鄣邶凇冼冽冱冫衮兖夔冁馘遵尊总姿资咨兹着准状壮妆装痔郑症疹瘴彰章站闸曾韵阅痈音益毅意疫冶养痒羊疡彦沿阎颜阉丫癣羞新辛效翔羡闲问闻瘟头痛童剃誊疼痰瘫遂塑送朔兽瘦首韶商善闪闰瘸券拳痊酋亲疗凉立痢冷兰阑辣阔况竣决卷眷疽疚净竞竟靖痉疥竭郊交酱奖桨浆将将姜减剪兼煎间冀疾羌歉前凄普剖瓶瞥痞疲旁叛判疟凝逆闹闽闷门美六瘤凌羚凛豢痪痕阂闺关羹阁疙羔赣盖冯疯阀兑端痘斗冻凋奠递弟帝盗道郸单瘩瘁凑次瓷慈疵闯疮冲痴阐产差部并病冰瘪憋鳖辫辩辨弊敝闭痹迸背北半瓣疤癌',
  'V鼷鼹鼯鼬鼢暨艮舄舁臾鸠聿肀邕甾巛驽孥孀嬷嬗嬉嫜嫘嫦嫖嫱嫣媸嫔嫒媲嫫媾婷媛媪胬婵婢娼婕婊婧婀娓娣娴娲娉娌姹姘姣姝娆娅姗妯妲姒妤妞妫姊妗妣妪妩妍妃妁弩彐邋逯帑叟劭馗帚召杂娱尹姻姨姚妖巡寻婿絮旭姓嫌媳婉丸娃退迢她肃恕鼠始婶娠邵嫂如妊刃忍群隶姥恳垦郡君娟舅臼九姐剿娇建奸嫁妓既嫉即姬婚毁女怒努奴娘妮嫩奶娜那姆妙娩媚妹媒妈录灵好姑妇妨娥妒嫡刀逮巢剥',
  'W黛雠隽隼隹翕翎衾颔颌鹪鹆鸺畲龛恁爨煲歙毹牮觎瓴戗璺岱坌郐兮龠俎佥佘氽仝儋儇僮僦僬僭儆僖傺傩傧傥偻偬偎偈偕偃偾倨倥倌倜俾倭倮倏倬俳偌倩俸俟俑俜俣俚俅俪俨俦侔侬佼侪佻佾侏侃侉侑佴佶伽伲佗佟佝佚攸佧佞伫伉伧伥仵佤伢仳伛仞仫仡仨仂仉仃亻劁坐作做佐仔追住众仲侄值侦仗债欲愈逾俞余舆佑悠优佣亿倚仪伊依爷仰佯叙修休信斜像仙侠侮伍瓮翁位伪伟途偷停体倘贪他僳俗颂怂耸似伺舒售侍仕使食什伸舍伤傻僧伞儒仍任人仁全倾禽侵僚敛俩俐例傈儡佬傀侩俊倔倦俱仅今介借侥焦僵剑健件俭价假佳祭伎集货伙会俏侨仟企仆凭贫偏僻盆佩偶您念你倪拿命们仑伦侣令领伶赁鳞邻化华候侯盒合何含刽癸谷估公供个鸽父阜付傅斧釜俯俘伏佛忿份分仿伐俄段侗爹佃低凳登倒但袋贷代傣催促丛从创传储仇侈倡偿豺岔侧仓伯饼便倍堡保傍伴颁佰爸八傲俺',
  'X飨糸蠡颍鸶鸨犟畿幺缵缳缲缱缰缯缭缬缫缪缧缦缥缤缣缢缡缟缛缜缙缗缒缑缏缌缋缈缇缃缂缁绾绻绺绶缍绲绱绯绮绫绨绡绠绛绗绔绐绌绋绉绂绁绀纾纰纭纩纨纥纣纡纟鬻弼艴弭弪彘彖辔匕组纵综缀粥终纸旨织张绽约缘幼幽颖缨引绎肄彝疑绚续绪绣乡线弦纤细毋纹纬维统绦缩绥丝绳绅绍缮纱弱绒纫绕顷练缆绝绢纠经结皆绞缴疆缄纪继级缉绩绘强纽纳母缅绵弥络纶绿缕幻缓弧红弘贯弓给纲缚弗缝纷费纺缎缔弹绰纯绸弛缠编毖毙毕比绷绑绊',
  'Y麟麝鏖麒麋麈麇麂縻麾麽饔銮綮翩颏颃鹫鹧鹑鸾憝扉扈扃戽戾旖旒旎旌旃旄旆於斓齑膂肓昶栾娈膺廪廨廛廑廒赓庳庾庵庹庠庥庖庋庑庀奕弈壅塾劾邡邙邝谶谵谳谲谯谮谫谪谧谥谡谠谟谝谘谛谙谖谕谔谒谑谏谌谇谄谂谀诿诼诹诶诳诰诮诩诨诤诠诟诜诙诘诖诔诓诒诎诏诋诃诂讷讵讴讪讧讦讠羸蠃嬴禀裒脔亵袤亳亠丶座诅族卒谆庄主诛诸诌州衷证诊这遮肇斋诈育语诱永雍庸赢应鹰译谊议诣义裔亦衣夜谣谚言讶讯训询玄旋畜序许谢谐享详襄席误诬紊文谓为妄忘望亡弯庭亭讨唐谈谭诉诵讼说谁衰庶熟孰试市识诗施设认让瓤庆请廖谅亮良恋廉离朗郎廊谰廓库课刻亢康诀就京谨诫讲肩记计剂讥迹诲讳谎敲谴谦讫弃启旗齐谱评烹庞诺亩谋魔摩磨谬庙谜糜靡氓盲谩蛮麻论孪挛峦率旅鹿庐刘吝话户亨毫豪亥裹郭诡广雇庚膏高该讣腐府讽废诽放访房方讹敦度读订谍调店底诞词床充诚颤谗诧斌遍卞变扁庇褒谤哀'
  //"~","!","@","#","$","%","^","&","*","(",")","-","+","_","=","[","}",
];
/**
 * @param {String} str 中文字符串
 * @returns {String} result 拼音首字母串数组
 */
export function makePy(str) {
  if (typeof str != 'string') throw new Error(-1, '函数makePy需要字符串类型参数!');
  var arrResult = new Array(); //保存中间结果的数组
  for (var i = 0, len = str.length; i < len; i++) {
    // 获得unicode码
    const ch = str.charAt(i);
    // 检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理
    arrResult.push(checkCh(ch));
  }
  // 处理arrResult,返回所有可能的拼音首字母串数组
  return mkRslt(arrResult);
}
function checkCh(ch) {
  const uni = ch.charCodeAt(0);
  //如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数
  if (uni > 40869 || uni < 19968) return ch; //dealWithOthers(ch);
  //检查是否是多音字,是按多音字处理,不是就直接在strChineseFirstPY字符串中找对应的首字母
  return strChineseFirstPY.charAt(uni - 19968);
}
function mkRslt(arr) {
  var arrRslt = [''];
  for (var i = 0, len = arr.length; i < len; i++) {
    var str = arr[i];
    var strlen = str.length;
    if (strlen == 1) {
      for (var k = 0; k < arrRslt.length; k++) {
        arrRslt[k] += str;
      }
    } else {
      var tmpArr = arrRslt.slice(0);
      arrRslt = [];
      for (k = 0; k < strlen; k++) {
        //复制一个相同的arrRslt
        var tmp = tmpArr.slice(0);
        //把当前字符str[k]添加到每个元素末尾
        for (var j = 0; j < tmp.length; j++) {
          tmp[j] += str.charAt(k);
        }
        //把复制并修改后的数组连接到arrRslt上
        arrRslt = arrRslt.concat(tmp);
      }
    }
  }
  // 去除前后空格
  // arrRslt = arrRslt.toString().replace(/(^\s*)|(\s*$)/g,"");
  // 去除所有空格
  arrRslt = arrRslt.toString().replace(/\s+/g, '');
  return arrRslt;
}
//两端去空格函数
//String.prototype.trimAll = function(){return this.replace(/\s+/g,"");}
//String.prototype.trim = function(){return this.replace(/(^\s*)|(\s*$)/g,""); }

// 拼音转五笔简码
export function makeWb(str) {
  if (typeof str != 'string') throw new Error(-1, '函数makePy需要字符串类型参数!');
  var arrResult = new Array(); //保存中间结果的数组
  // 处理数字和字母:对数字和字母直接返回
  for (var i = 0, len = str.length; i < len; i++) {
    // 获得unicode码
    var ch = str.charAt(i);
    // 检查字库
    arrResult.push(getWubiCode(ch));
  }
  return mkRslt(arrResult);
}
function getWubiCode(ch) {
  // 遍历简码数组
  for (var i = 0, len = wubiLib.length; i < len; i++) {
    var str = wubiLib[i];
    for (var k = 0; k < str.length; k++) {
      if (ch == str[k]) {
        // 返回第一个字母
        return str[0];
      }
    }
  }
}

# base64 转 blob

const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, { type: contentType });
  return blob;
};

# 字符串去除 html 标签

function removeHtmlTag(str = '') {
  let content = str.replace(/<\/?[^>]*>/g, ''); //去除标签
  content = content.replace(/[|]*\n/, ''); //去除行尾空格
  content = content.replace(/&nbsp;/gi, ''); //去除&nbsp;
  return content;
}

// 保留img标签
function removeHtmlTagRetainImg(str = '') {
  let content = str.replace(/<\/?((?!img).)*?\/?>/g, ''); //去除标签
  return content;
}