diff --git a/.gitignore b/.gitignore
index c1402394..5bd81ab9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,13 @@
.DS_Store
node_modules
+miniprogram_npm
dist
lib
coverage
.cache
lerna-debug.log
.vscode
+.idea
!e2e/dist
e2e/dist/*_bundle.js
diff --git a/packages/paddlejs-examples/ocrXcx/README.md b/packages/paddlejs-examples/ocrXcx/README.md
new file mode 100644
index 00000000..32566852
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/README.md
@@ -0,0 +1,101 @@
+# OCR 微信小程序代码示例
+
+## 1.介绍
+本目录为文本识别小程序代码,通过使用 [Paddle.js](https://github.com/PaddlePaddle/Paddle.js) 以及 [Paddle.js微信小程序插件](https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx7138a7bb793608c3&token=956931339&lang=zh_CN) 完成在小程序上利用用户终端算力实现文本检测框选效果。
+
+## 2. 项目启动
+
+### 2.1 准备工作
+* [申请微信小程序账号](https://mp.weixin.qq.com/)
+* [微信小程序开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html)
+* 前端开发环境准备:node、npm
+* 小程序管理后台配置服务器域名,或打开开发者工具【不校验合法域名】
+
+详情参考:https://mp.weixin.qq.com/wxamp/devprofile/get_profile?token=1132303404&lang=zh_CN)
+
+### 2.2 启动步骤
+#### **1. clone Paddle.js**
+```sh
+git clone https://github.com/PaddlePaddle/Paddle.js.git
+```
+
+#### **2. 进入 ocrXcx 目录,安装依赖**
+```sh
+cd Paddle.js/packages/paddlejs-examples/ocrXcx && npm install
+```
+
+#### **3. 微信小程序导入代码**
+打开微信开发者工具 --> 导入 --> 选定目录,输入相关信息
+
+#### **4. 添加 Paddle.js微信小程序插件**
+小程序管理界面 --> 设置 --> 第三方设置 --> 插件管理 --> 添加插件 --> 搜索 `wx7138a7bb793608c3` 并添加
+[参考文档](https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/using.html)
+
+#### **5. 构建依赖**
+点击开发者工具中的菜单栏:工具 --> 构建 npm
+
+原因:node_modules 目录不会参与编译、上传和打包中,小程序想要使用 npm 包必须走一遍“构建 npm”的过程,构建完成会生成一个 miniprogram_npm 目录,里面会存放构建打包后的 npm 包,也就是小程序真正使用的 npm 包。*
+[参考文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)
+
+### 2.3 效果展示
+
+
+## 3. Paddle.js 框架推理
+```typescript
+// 引入 paddlejs 和 paddlejs-plugin,注册小程序环境变量和合适的 backend
+import * as paddlejs from '@paddlejs/paddlejs-core';
+import '@paddlejs/paddlejs-backend-webgl';
+const plugin = requirePlugin('paddlejs-plugin');
+plugin.register(paddlejs, wx);
+
+// 初始化推理引擎
+const runner = new paddlejs.Runner({modelPath, feedShape, mean, std});
+await runner.init();
+
+// 获取图像信息
+wx.canvasGetImageData({
+ canvasId: canvasId,
+ x: 0,
+ y: 0,
+ width: canvas.width,
+ height: canvas.height,
+ success(res) {
+ // 推理预测
+ runner.predict({
+ data: res.data,
+ width: canvas.width,
+ height: canvas.height,
+ }, function (data) {
+ // 获取推理结果
+ console.log(data)
+ });
+ }
+});
+```
+
+## 4. 常见问题
+### 4.1 出现报错 `Invalid context type [webgl2] for Canvas#getContext`
+
+可以不管,不影响正常代码运行和demo功能
+
+### 4.2 预览 看不到结果
+
+建议尝试真机调试
+
+### 4.3 微信开发者工具出现黑屏,然后出现超多报错
+
+重启微信开发者工具
+
+### 4.4 模拟和真机调试结果不一致;模拟检测不到文本等
+
+可以以真机为准;
+
+模拟检测不到文本等可以尝试随意改动下代码(增删换行等)再点击编译
+
+
+### 4.5 手机调试或运行时出现 长时间无反应等提示
+
+请继续等待,模型推理需要一定时间
+
+## 5. 更多
+* [详细文档](https://mp.weixin.qq.com/s/KBjXawSfBreUCsIYbUgF-w)
diff --git a/packages/paddlejs-examples/ocrXcx/app.js b/packages/paddlejs-examples/ocrXcx/app.js
new file mode 100644
index 00000000..4a0fdcb1
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/app.js
@@ -0,0 +1,12 @@
+/* global wx, App */
+import * as paddlejs from '@paddlejs/paddlejs-core';
+import '@paddlejs/paddlejs-backend-webgl';
+// eslint-disable-next-line no-undef
+const plugin = requirePlugin('paddlejs-plugin');
+plugin.register(paddlejs, wx);
+
+App({
+ globalData: {
+ Paddlejs: paddlejs.Runner
+ }
+});
diff --git a/packages/paddlejs-examples/ocrXcx/app.json b/packages/paddlejs-examples/ocrXcx/app.json
new file mode 100644
index 00000000..70fa27e7
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/app.json
@@ -0,0 +1,12 @@
+{
+ "pages": [
+ "pages/index/index"
+ ],
+ "plugins": {
+ "paddlejs-plugin": {
+ "version": "2.0.1",
+ "provider": "wx7138a7bb793608c3"
+ }
+ },
+ "sitemapLocation": "sitemap.json"
+}
\ No newline at end of file
diff --git a/packages/paddlejs-examples/ocrXcx/package-lock.json b/packages/paddlejs-examples/ocrXcx/package-lock.json
new file mode 100644
index 00000000..78f15f9a
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/package-lock.json
@@ -0,0 +1,72 @@
+{
+ "name": "paddlejs-demo",
+ "version": "0.0.1",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "paddlejs-demo",
+ "version": "0.0.1",
+ "license": "ISC",
+ "dependencies": {
+ "@paddlejs/paddlejs-backend-webgl": "^1.2.0",
+ "@paddlejs/paddlejs-core": "^2.1.18",
+ "d3-polygon": "2.0.0",
+ "js-clipper": "1.0.1",
+ "number-precision": "1.5.2"
+ }
+ },
+ "node_modules/@paddlejs/paddlejs-backend-webgl": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-backend-webgl/-/paddlejs-backend-webgl-1.2.9.tgz",
+ "integrity": "sha512-cVDa0/Wbw2EyfsYqdYUPhFeqKsET79keEUWjyhYQmQkJfWg8j1qdR6yp7g6nx9qAGrqFvwuj1s0EqkYA1dok6A=="
+ },
+ "node_modules/@paddlejs/paddlejs-core": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-core/-/paddlejs-core-2.2.0.tgz",
+ "integrity": "sha512-P3rPkF9fFHtq8uSte5gA7fJQwBNl9Ytsvj6aTcfQSsirnBO/HxMNu0gJyh7+lItvEtF92PR15eI0eOwJYfZDhQ=="
+ },
+ "node_modules/d3-polygon": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz",
+ "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ=="
+ },
+ "node_modules/js-clipper": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/js-clipper/-/js-clipper-1.0.1.tgz",
+ "integrity": "sha512-0XYAS0ZoCki5K0fWwj8j8ug4mgxHXReW3ayPbVqr4zXPJuIs2pyvemL1sALadsEiAywZwW5Ify1XfU4bNJvokg=="
+ },
+ "node_modules/number-precision": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/number-precision/-/number-precision-1.5.2.tgz",
+ "integrity": "sha512-q7C1ZW3FyjsJ+IpGB6ykX8OWWa5+6M+hEY0zXBlzq1Sq1IPY9GeI3CQ9b2i6CMIYoeSuFhop2Av/OhCxClXqag=="
+ }
+ },
+ "dependencies": {
+ "@paddlejs/paddlejs-backend-webgl": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-backend-webgl/-/paddlejs-backend-webgl-1.2.9.tgz",
+ "integrity": "sha512-cVDa0/Wbw2EyfsYqdYUPhFeqKsET79keEUWjyhYQmQkJfWg8j1qdR6yp7g6nx9qAGrqFvwuj1s0EqkYA1dok6A=="
+ },
+ "@paddlejs/paddlejs-core": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-core/-/paddlejs-core-2.2.0.tgz",
+ "integrity": "sha512-P3rPkF9fFHtq8uSte5gA7fJQwBNl9Ytsvj6aTcfQSsirnBO/HxMNu0gJyh7+lItvEtF92PR15eI0eOwJYfZDhQ=="
+ },
+ "d3-polygon": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz",
+ "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ=="
+ },
+ "js-clipper": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/js-clipper/-/js-clipper-1.0.1.tgz",
+ "integrity": "sha512-0XYAS0ZoCki5K0fWwj8j8ug4mgxHXReW3ayPbVqr4zXPJuIs2pyvemL1sALadsEiAywZwW5Ify1XfU4bNJvokg=="
+ },
+ "number-precision": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/number-precision/-/number-precision-1.5.2.tgz",
+ "integrity": "sha512-q7C1ZW3FyjsJ+IpGB6ykX8OWWa5+6M+hEY0zXBlzq1Sq1IPY9GeI3CQ9b2i6CMIYoeSuFhop2Av/OhCxClXqag=="
+ }
+ }
+}
diff --git a/packages/paddlejs-examples/ocrXcx/package.json b/packages/paddlejs-examples/ocrXcx/package.json
new file mode 100644
index 00000000..4e40298a
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "paddlejs-demo",
+ "version": "0.0.1",
+ "description": "",
+ "main": "app.js",
+ "dependencies": {
+ "@paddlejs/paddlejs-backend-webgl": "^1.2.0",
+ "@paddlejs/paddlejs-core": "^2.1.18",
+ "d3-polygon": "2.0.0",
+ "js-clipper": "1.0.1",
+ "number-precision": "1.5.2"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC"
+}
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/img/width.png b/packages/paddlejs-examples/ocrXcx/pages/index/img/width.png
new file mode 100644
index 00000000..02b8999d
Binary files /dev/null and b/packages/paddlejs-examples/ocrXcx/pages/index/img/width.png differ
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/index.js b/packages/paddlejs-examples/ocrXcx/pages/index/index.js
new file mode 100644
index 00000000..abfbccff
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/index.js
@@ -0,0 +1,526 @@
+/* global wx, Page */
+import * as paddlejs from '@paddlejs/paddlejs-core';
+import '@paddlejs/paddlejs-backend-webgl';
+import clipper from 'js-clipper';
+import { divide, enableBoundaryChecking, plus } from 'number-precision';
+
+import { recDecode } from 'recPostprocess.js';
+// eslint-disable-next-line no-undef
+const plugin = requirePlugin('paddlejs-plugin');
+const Polygon = require('d3-polygon');
+
+global.wasm_url = 'pages/index/wasm/opencv_js.wasm.br';
+const CV = require('./wasm/opencv.js');
+
+plugin.register(paddlejs, wx);
+
+let DETSHAPE = 960;
+let RECWIDTH = 320;
+const RECHEIGHT = 32;
+
+// 声明后续图像变换要用到的canvas;此时未绑定
+let canvas_det;
+let canvas_rec;
+let my_canvas;
+let my_canvas_ctx;
+
+
+const imgList = [
+ 'https://paddlejs.bj.bcebos.com/xcx/ocr.png'
+];
+
+// eslint-disable-next-line max-lines-per-function
+const outputBox = (res) => {
+ const thresh = 0.3;
+ const box_thresh = 0.5;
+ const max_candidates = 1000;
+ const min_size = 3;
+ const width = 960;
+ const height = 960;
+ const pred = res;
+ const segmentation = [];
+ pred.forEach(item => {
+ segmentation.push(item > thresh ? 255 : 0);
+ });
+
+ function get_mini_boxes(contour) {
+ // 生成最小外接矩形
+ const bounding_box = CV.minAreaRect(contour);
+ const points = [];
+ const mat = new CV.Mat();
+ // 获取矩形的四个顶点坐标
+ CV.boxPoints(bounding_box, mat);
+ for (let i = 0; i < mat.data32F.length; i += 2) {
+ const arr = [];
+ arr[0] = mat.data32F[i];
+ arr[1] = mat.data32F[i + 1];
+ points.push(arr);
+ }
+
+ function sortNumber(a, b) {
+ return a[0] - b[0];
+ }
+ points.sort(sortNumber);
+ let index_1 = 0;
+ let index_2 = 1;
+ let index_3 = 2;
+ let index_4 = 3;
+ if (points[1][1] > points[0][1]) {
+ index_1 = 0;
+ index_4 = 1;
+ }
+ else {
+ index_1 = 1;
+ index_4 = 0;
+ }
+
+ if (points[3][1] > points[2][1]) {
+ index_2 = 2;
+ index_3 = 3;
+ }
+ else {
+ index_2 = 3;
+ index_3 = 2;
+ }
+ const box = [
+ points[index_1],
+ points[index_2],
+ points[index_3],
+ points[index_4]
+ ];
+ const side = Math.min(bounding_box.size.height, bounding_box.size.width);
+ mat.delete();
+ return {
+ points: box,
+ side
+ };
+ }
+
+ function box_score_fast(bitmap, _box) {
+ const h = height;
+ const w = width;
+ const box = JSON.parse(JSON.stringify(_box));
+ const x = [];
+ const y = [];
+ box.forEach(item => {
+ x.push(item[0]);
+ y.push(item[1]);
+ });
+ // clip这个函数将将数组中的元素限制在a_min, a_max之间,大于a_max的就使得它等于 a_max,小于a_min,的就使得它等于a_min。
+ const xmin = clip(Math.floor(Math.min(...x)), 0, w - 1);
+ const xmax = clip(Math.ceil(Math.max(...x)), 0, w - 1);
+ const ymin = clip(Math.floor(Math.min(...y)), 0, h - 1);
+ const ymax = clip(Math.ceil(Math.max(...y)), 0, h - 1);
+ // eslint-disable-next-line new-cap
+ const mask = new CV.Mat.zeros(ymax - ymin + 1, xmax - xmin + 1, CV.CV_8UC1);
+ box.forEach(item => {
+ item[0] = Math.max(item[0] - xmin, 0);
+ item[1] = Math.max(item[1] - ymin, 0);
+ });
+ const npts = 4;
+ const point_data = new Uint8Array(box.flat());
+ const points = CV.matFromArray(npts, 1, CV.CV_32SC2, point_data);
+ const pts = new CV.MatVector();
+ pts.push_back(points);
+ const color = new CV.Scalar(255);
+ // 多个多边形填充
+ CV.fillPoly(mask, pts, color, 1);
+ const sliceArr = [];
+ for (let i = ymin; i < ymax + 1; i++) {
+ sliceArr.push(...bitmap.slice(960 * i + xmin, 960 * i + xmax + 1));
+ }
+ const mean = num_mean(sliceArr, mask.data);
+ mask.delete();
+ points.delete();
+ pts.delete();
+ return mean;
+ }
+
+ function clip(data, min, max) {
+ return data < min ? min : data > max ? max : data;
+ }
+
+ function unclip(box) {
+ const unclip_ratio = 1.6;
+ const area = Math.abs(Polygon.polygonArea(box));
+ const length = Polygon.polygonLength(box);
+ const distance = area * unclip_ratio / length;
+ const tmpArr = [];
+ box.forEach(item => {
+ const obj = {
+ X: 0,
+ Y: 0
+ };
+ obj.X = item[0];
+ obj.Y = item[1];
+ tmpArr.push(obj);
+ });
+ const offset = new clipper.ClipperOffset();
+ offset.AddPath(tmpArr, clipper.JoinType.jtRound, clipper.EndType.etClosedPolygon);
+ const expanded = [];
+ offset.Execute(expanded, distance);
+ let expandedArr = [];
+ expanded[0] && expanded[0].forEach(item => {
+ expandedArr.push([item.X, item.Y]);
+ });
+ expandedArr = [].concat(...expandedArr);
+ return expandedArr;
+ }
+
+ function num_mean(data, mask) {
+ let sum = 0;
+ let length = 0;
+ for (let i = 0; i < data.length; i++) {
+ if (mask[i]) {
+ sum = plus(sum, data[i]);
+ length++;
+ }
+ }
+ return divide(sum, length);
+ }
+
+ // eslint-disable-next-line new-cap
+ const src = new CV.matFromArray(960, 960, CV.CV_8UC1, segmentation);
+ const contours = new CV.MatVector();
+ const hierarchy = new CV.Mat();
+ // 获取轮廓
+ CV.findContours(src, contours, hierarchy, CV.RETR_LIST, CV.CHAIN_APPROX_SIMPLE);
+ const num_contours = Math.min(contours.size(), max_candidates);
+ const boxes = [];
+ const scores = [];
+ const arr = [];
+ for (let i = 0; i < num_contours; i++) {
+ const contour = contours.get(i);
+ let {
+ points,
+ side
+ } = get_mini_boxes(contour);
+ if (side < min_size) {
+ continue;
+ }
+ const score = box_score_fast(pred, points);
+ if (box_thresh > score) {
+ continue;
+ }
+ let box = unclip(points);
+ // eslint-disable-next-line new-cap
+ const boxMap = new CV.matFromArray(box.length / 2, 1, CV.CV_32SC2, box);
+ const resultObj = get_mini_boxes(boxMap);
+ box = resultObj.points;
+ side = resultObj.side;
+ if (side < min_size + 2) {
+ continue;
+ }
+ box.forEach(item => {
+ item[0] = clip(Math.round(item[0]), 0, 960);
+ item[1] = clip(Math.round(item[1]), 0, 960);
+ });
+ boxes.push(box);
+ scores.push(score);
+ arr.push(i);
+ boxMap.delete();
+ }
+ src.delete();
+ contours.delete();
+ hierarchy.delete();
+ return {
+ boxes,
+ scores
+ };
+};
+
+const sorted_boxes = (box) => {
+ function sortNumber(a, b) {
+ return a[0][1] - b[0][1];
+ }
+
+ const boxes = box.sort(sortNumber);
+ const num_boxes = boxes.length;
+ for (let i = 0; i < num_boxes - 1; i++) {
+ if (Math.abs(boxes[i + 1][0][1] - boxes[i][0][1]) < 10
+ && boxes[i + 1][0][0] < boxes[i][0][0]) {
+ const tmp = boxes[i];
+ boxes[i] = boxes[i + 1];
+ boxes[i + 1] = tmp;
+ }
+ }
+ return boxes;
+}
+
+function flatten(arr) {
+ return arr.toString().split(',').map(item => +item);
+}
+
+function int(num) {
+ return num > 0 ? Math.floor(num) : Math.ceil(num);
+}
+
+function clip(data, min, max) {
+ return data < min ? min : data > max ? max : data;
+}
+
+function get_rotate_crop_image(img, points) {
+ const img_crop_width = int(Math.max(
+ linalg_norm(points[0], points[1]),
+ linalg_norm(points[2], points[3])
+ ));
+ const img_crop_height = int(Math.max(
+ linalg_norm(points[0], points[3]),
+ linalg_norm(points[1], points[2])
+ ));
+ const pts_std = [
+ [0, 0],
+ [img_crop_width, 0],
+ [img_crop_width, img_crop_height],
+ [0, img_crop_height]
+ ];
+ const srcTri = CV.matFromArray(4, 1, CV.CV_32FC2, flatten(points));
+ const dstTri = CV.matFromArray(4, 1, CV.CV_32FC2, flatten(pts_std));
+ // 获取到目标矩阵
+ const M = CV.getPerspectiveTransform(srcTri, dstTri);
+ const src = CV.imread(img);
+ const dst = new CV.Mat();
+ const dsize = new CV.Size(img_crop_width, img_crop_height);
+ // 透视转换
+ CV.warpPerspective(src, dst, M, dsize, CV.INTER_CUBIC, CV.BORDER_REPLICATE, new CV.Scalar());
+
+ const dst_img_height = dst.rows;
+ const dst_img_width = dst.cols;
+ let dst_rot;
+ // 图像旋转
+ if (dst_img_height / dst_img_width >= 1.5) {
+ dst_rot = new CV.Mat();
+ const dsize_rot = new CV.Size(dst.rows, dst.cols);
+ const center = new CV.Point(dst.cols / 2, dst.cols / 2);
+ const M = CV.getRotationMatrix2D(center, 90, 1);
+ CV.warpAffine(dst, dst_rot, M, dsize_rot, CV.INTER_CUBIC, CV.BORDER_REPLICATE, new CV.Scalar());
+ }
+
+ const dst_resize = new CV.Mat();
+ const dsize_resize = new CV.Size(0, 0);
+ let scale;
+ if (dst_rot) {
+ scale = RECHEIGHT / dst_rot.rows;
+ CV.resize(dst_rot, dst_resize, dsize_resize, scale, scale, CV.INTER_AREA);
+ dst_rot.delete();
+ }
+ else {
+ scale = RECHEIGHT / dst_img_height;
+ CV.resize(dst, dst_resize, dsize_resize, scale, scale, CV.INTER_AREA);
+ }
+
+ canvas_det.width = dst_resize.cols;
+ canvas_det.height = dst_resize.rows;
+ canvas_det.getContext('2d').clearRect(0, 0, canvas_det.width, canvas_det.height);
+ CV.imshow(canvas_det, dst_resize);
+
+ src.delete();
+ dst.delete();
+ dst_resize.delete();
+ srcTri.delete();
+ dstTri.delete();
+}
+
+function linalg_norm(x, y) {
+ return Math.sqrt(Math.pow(x[0] - y[0], 2) + Math.pow(x[1] - y[1], 2));
+}
+
+function resize_norm_img_splice(
+ image,
+ origin_width,
+ origin_height,
+ index = 0
+) {
+ canvas_rec.width = RECWIDTH;
+ canvas_rec.height = RECHEIGHT;
+ const ctx = canvas_rec.getContext('2d');
+ ctx.fillStyle = '#fff';
+ ctx.clearRect(0, 0, canvas_rec.width, canvas_rec.height);
+ // ctx.drawImage(image, -index * RECWIDTH, 0, origin_width, origin_height);
+ ctx.putImageData(image, -index * RECWIDTH, 0);
+}
+
+// 声明检测和识别Runner;未初始化
+let detectRunner;
+let recRunner;
+
+Page({
+ data: {
+ imgList: imgList,
+ imgInfo: {},
+ result: '',
+ loaded: false
+ },
+
+ onLoad() {
+ enableBoundaryChecking(false);
+ // 绑定canvas;该操作是异步,因此最好加延迟保证后续使用时已完成绑定
+ wx.createSelectorQuery()
+ .select('#canvas_det')
+ .fields({ node: true, size: true })
+ .exec(async(res) => {
+ canvas_det = res[0].node;
+ });
+
+ wx.createSelectorQuery()
+ .select('#canvas_rec')
+ .fields({ node: true, size: true })
+ .exec(async(res) => {
+ canvas_rec = res[0].node;
+ });
+
+ wx.createSelectorQuery()
+ .select('#myCanvas')
+ .fields({ node: true, size: true })
+ .exec((res) => {
+ my_canvas = res[0].node;
+ my_canvas_ctx = my_canvas.getContext('2d');
+ });
+
+ const me = this;
+ // 初始化Runner
+ detectRunner = new paddlejs.Runner({
+ modelPath: 'https://paddlejs.bj.bcebos.com/models/fuse/ocr/ch_PP-OCRv2_det_fuse_activation',
+ mean: [0.485, 0.456, 0.406],
+ std: [0.229, 0.224, 0.225],
+ bgr: true,
+ webglFeedProcess: true
+ });
+ recRunner = new paddlejs.Runner({
+ modelPath: 'https://paddlejs.bj.bcebos.com/models/fuse/ocr/ch_PP-OCRv2_rec_fuse_activation/model.json',
+ fill: '#000',
+ mean: [0.5, 0.5, 0.5],
+ std: [0.5, 0.5, 0.5],
+ bgr: true,
+ webglFeedProcess: true
+ });
+ // 等待模型数据全部加载完成
+ Promise.all([detectRunner.init(), recRunner.init()]).then(_ => {
+ me.setData({
+ loaded: true
+ });
+ });
+
+ },
+
+ selectImage(event) {
+ const imgPath = this.data.imgList[event.target.dataset.index];
+ this.getImageInfo(imgPath);
+ },
+
+ getImageInfo(imgPath) {
+ const me = this;
+ wx.getImageInfo({
+ src: imgPath,
+ success: (imgInfo) => {
+ const {
+ path,
+ width,
+ height
+ } = imgInfo;
+ const canvasPath = imgPath.includes('http') ? path : imgPath;
+
+ let sw = 960;
+ let sh = 960;
+ let x = 0;
+ let y = 0;
+
+ if (height / width >= 1) {
+ sw = Math.round(sh * width / height);
+ x = Math.floor((960 - sw) / 2);
+ }
+ else {
+ sh = Math.round(sw * height / width);
+ y = Math.floor((960 - sh) / 2);
+ }
+ my_canvas.width = sw;
+ my_canvas.height = sh;
+
+ // 微信上canvas输入图片
+ const image = my_canvas.createImage();
+ image.src = canvasPath;
+ image.onload = () => {
+ my_canvas_ctx.clearRect(0, 0, my_canvas.width, my_canvas.height);
+ my_canvas_ctx.drawImage(image, x, y, sw, sh);
+ const imageData = my_canvas_ctx.getImageData(0, 0, sw, sh);
+ // 开始识别
+ me.recognize({
+ data: imageData.data,
+ width: 960,
+ height: 960
+ }, {canvasPath, sw, sh, x, y});
+ }
+ }
+ });
+ },
+
+ async recognize(res, img) {
+ const me = this;
+ // 文本框选坐标点
+ let points;
+ await detectRunner.predict(res, function (detectRes) {
+ points = outputBox(detectRes);
+ });
+
+ // 绘制文本框
+ me.drawCanvasPoints(img, points.boxes);
+
+ // 排序,使得最后结果输出尽量按照从上到下的顺序
+ const boxes = sorted_boxes(points.boxes);
+
+ const text_list = [];
+
+ for (let i = 0; i < boxes.length; i++) {
+ const tmp_box = JSON.parse(JSON.stringify(boxes[i]));
+ // 获取tmp_box对应图片到canvas_det
+ get_rotate_crop_image(res, tmp_box);
+ // 这里是计算要识别文字的图片片段是否大于识别模型要求的输入宽度;超过了的话会分成多次识别,再拼接结果
+ const width_num = Math.ceil(canvas_det.width / RECWIDTH);
+
+ let text_list_tmp = '';
+ for (let j = 0; j < width_num; j++) {
+ // 根据原图的宽度进行裁剪拼接,超出指定宽度会被截断;然后再次识别,最后拼接起来
+ resize_norm_img_splice(canvas_det.getContext('2d').getImageData(0, 0, canvas_det.width, canvas_det.height), canvas_det.width, canvas_det.height, j);
+
+ const imgData = canvas_rec.getContext('2d').getImageData(0, 0, canvas_rec.width, canvas_rec.height);
+
+ await recRunner.predict(imgData, function(output){
+ // 将输出向量转化为idx再传化为对应字符
+ const text = recDecode(output);
+ text_list_tmp = text_list_tmp.concat(text.text);
+ });
+ }
+ text_list.push(text_list_tmp);
+ }
+ me.setData({
+ result: JSON.stringify(boxes) + JSON.stringify(text_list)
+ });
+ },
+
+ drawCanvasPoints(img, points) {
+ // 设置线条
+ my_canvas_ctx.strokeStyle = 'blue';
+ my_canvas_ctx.lineWidth = 5;
+
+ // 先绘制图片
+ const image = my_canvas.createImage();
+ image.src = img.canvasPath;
+ image.onload = () => {
+ my_canvas_ctx.clearRect(0, 0, my_canvas_ctx.width, my_canvas_ctx.height);
+ my_canvas_ctx.drawImage(image, img.x, img.y, img.sw, img.sh);
+ // 绘制线框
+ points.length && points.forEach(point => {
+ my_canvas_ctx.beginPath();
+ // 设置路径起点坐标
+ my_canvas_ctx.moveTo(point[0][0], point[0][1]);
+ my_canvas_ctx.lineTo(point[1][0], point[1][1]);
+ my_canvas_ctx.lineTo(point[2][0], point[2][1]);
+ my_canvas_ctx.lineTo(point[3][0], point[3][1]);
+ my_canvas_ctx.lineTo(point[0][0], point[0][1]);
+ my_canvas_ctx.stroke();
+ my_canvas_ctx.closePath();
+ });
+ }
+
+ }
+});
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/index.json b/packages/paddlejs-examples/ocrXcx/pages/index/index.json
new file mode 100644
index 00000000..2c63c085
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/index.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/index.wxml b/packages/paddlejs-examples/ocrXcx/pages/index/index.wxml
new file mode 100644
index 00000000..58a6d6a1
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/index.wxml
@@ -0,0 +1,42 @@
+
+
+ 点击图片进行预测
+
+
+
+
+
+
+
+
+
+
+
+
+ 文本框选坐标:{{result}}
+
+
+
+
+ loading…
+
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/index.wxss b/packages/paddlejs-examples/ocrXcx/pages/index/index.wxss
new file mode 100644
index 00000000..17679eae
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/index.wxss
@@ -0,0 +1,56 @@
+text {
+ display: block;
+}
+
+.title {
+ margin-top: 10px;
+ font-size: 16px;
+ line-height: 32px;
+ font-weight: bold;
+}
+
+.imgWrapper {
+ margin: 10px 10px 0;
+ white-space: nowrap;
+}
+.img {
+ width: 960px;
+ height: 960px;
+ border: 1px solid #f1f1f1;
+}
+
+.result {
+ margin-top: 5px;
+}
+
+.selected {
+ border: 1px solid #999;
+}
+
+.select-btn {
+ margin-top: 20px;
+ width: 60%;
+}
+
+.mask {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, .7);
+}
+
+.loading {
+ color: #fff;
+ font-size: 20px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.img-view {
+ padding-bottom: 20px;
+ border-bottom: 1px solid #f1f1f1;
+}
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1 b/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1
new file mode 100644
index 00000000..b75af213
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1
@@ -0,0 +1,6623 @@
+'
+疗
+绚
+诚
+娇
+溜
+题
+贿
+者
+廖
+更
+纳
+加
+奉
+公
+一
+就
+汴
+计
+与
+路
+房
+原
+妇
+2
+0
+8
+-
+7
+其
+>
+:
+]
+,
+,
+骑
+刈
+全
+消
+昏
+傈
+安
+久
+钟
+嗅
+不
+影
+处
+驽
+蜿
+资
+关
+椤
+地
+瘸
+专
+问
+忖
+票
+嫉
+炎
+韵
+要
+月
+田
+节
+陂
+鄙
+捌
+备
+拳
+伺
+眼
+网
+盎
+大
+傍
+心
+东
+愉
+汇
+蹿
+科
+每
+业
+里
+航
+晏
+字
+平
+录
+先
+1
+3
+彤
+鲶
+产
+稍
+督
+腴
+有
+象
+岳
+注
+绍
+在
+泺
+文
+定
+核
+名
+水
+过
+理
+让
+偷
+率
+等
+这
+发
+”
+为
+含
+肥
+酉
+相
+鄱
+七
+编
+猥
+锛
+日
+镀
+蒂
+掰
+倒
+辆
+栾
+栗
+综
+涩
+州
+雌
+滑
+馀
+了
+机
+块
+司
+宰
+甙
+兴
+矽
+抚
+保
+用
+沧
+秩
+如
+收
+息
+滥
+页
+疑
+埠
+!
+!
+姥
+异
+橹
+钇
+向
+下
+跄
+的
+椴
+沫
+国
+绥
+獠
+报
+开
+民
+蜇
+何
+分
+凇
+长
+讥
+藏
+掏
+施
+羽
+中
+讲
+派
+嘟
+人
+提
+浼
+间
+世
+而
+古
+多
+倪
+唇
+饯
+控
+庚
+首
+赛
+蜓
+味
+断
+制
+觉
+技
+替
+艰
+溢
+潮
+夕
+钺
+外
+摘
+枋
+动
+双
+单
+啮
+户
+枇
+确
+锦
+曜
+杜
+或
+能
+效
+霜
+盒
+然
+侗
+电
+晁
+放
+步
+鹃
+新
+杖
+蜂
+吒
+濂
+瞬
+评
+总
+隍
+对
+独
+合
+也
+是
+府
+青
+天
+诲
+墙
+组
+滴
+级
+邀
+帘
+示
+已
+时
+骸
+仄
+泅
+和
+遨
+店
+雇
+疫
+持
+巍
+踮
+境
+只
+亨
+目
+鉴
+崤
+闲
+体
+泄
+杂
+作
+般
+轰
+化
+解
+迂
+诿
+蛭
+璀
+腾
+告
+版
+服
+省
+师
+小
+规
+程
+线
+海
+办
+引
+二
+桧
+牌
+砺
+洄
+裴
+修
+图
+痫
+胡
+许
+犊
+事
+郛
+基
+柴
+呼
+食
+研
+奶
+律
+蛋
+因
+葆
+察
+戏
+褒
+戒
+再
+李
+骁
+工
+貂
+油
+鹅
+章
+啄
+休
+场
+给
+睡
+纷
+豆
+器
+捎
+说
+敏
+学
+会
+浒
+设
+诊
+格
+廓
+查
+来
+霓
+室
+溆
+¢
+诡
+寥
+焕
+舜
+柒
+狐
+回
+戟
+砾
+厄
+实
+翩
+尿
+五
+入
+径
+惭
+喹
+股
+宇
+篝
+|
+;
+美
+期
+云
+九
+祺
+扮
+靠
+锝
+槌
+系
+企
+酰
+阊
+暂
+蚕
+忻
+豁
+本
+羹
+执
+条
+钦
+H
+獒
+限
+进
+季
+楦
+于
+芘
+玖
+铋
+茯
+未
+答
+粘
+括
+样
+精
+欠
+矢
+甥
+帷
+嵩
+扣
+令
+仔
+风
+皈
+行
+支
+部
+蓉
+刮
+站
+蜡
+救
+钊
+汗
+松
+嫌
+成
+可
+.
+鹤
+院
+从
+交
+政
+怕
+活
+调
+球
+局
+验
+髌
+第
+韫
+谗
+串
+到
+圆
+年
+米
+/
+*
+友
+忿
+检
+区
+看
+自
+敢
+刃
+个
+兹
+弄
+流
+留
+同
+没
+齿
+星
+聆
+轼
+湖
+什
+三
+建
+蛔
+儿
+椋
+汕
+震
+颧
+鲤
+跟
+力
+情
+璺
+铨
+陪
+务
+指
+族
+训
+滦
+鄣
+濮
+扒
+商
+箱
+十
+召
+慷
+辗
+所
+莞
+管
+护
+臭
+横
+硒
+嗓
+接
+侦
+六
+露
+党
+馋
+驾
+剖
+高
+侬
+妪
+幂
+猗
+绺
+骐
+央
+酐
+孝
+筝
+课
+徇
+缰
+门
+男
+西
+项
+句
+谙
+瞒
+秃
+篇
+教
+碲
+罚
+声
+呐
+景
+前
+富
+嘴
+鳌
+稀
+免
+朋
+啬
+睐
+去
+赈
+鱼
+住
+肩
+愕
+速
+旁
+波
+厅
+健
+茼
+厥
+鲟
+谅
+投
+攸
+炔
+数
+方
+击
+呋
+谈
+绩
+别
+愫
+僚
+躬
+鹧
+胪
+炳
+招
+喇
+膨
+泵
+蹦
+毛
+结
+5
+4
+谱
+识
+陕
+粽
+婚
+拟
+构
+且
+搜
+任
+潘
+比
+郢
+妨
+醪
+陀
+桔
+碘
+扎
+选
+哈
+骷
+楷
+亿
+明
+缆
+脯
+监
+睫
+逻
+婵
+共
+赴
+淝
+凡
+惦
+及
+达
+揖
+谩
+澹
+减
+焰
+蛹
+番
+祁
+柏
+员
+禄
+怡
+峤
+龙
+白
+叽
+生
+闯
+起
+细
+装
+谕
+竟
+聚
+钙
+上
+导
+渊
+按
+艾
+辘
+挡
+耒
+盹
+饪
+臀
+记
+邮
+蕙
+受
+各
+医
+搂
+普
+滇
+朗
+茸
+带
+翻
+酚
+(
+光
+堤
+墟
+蔷
+万
+幻
+〓
+瑙
+辈
+昧
+盏
+亘
+蛀
+吉
+铰
+请
+子
+假
+闻
+税
+井
+诩
+哨
+嫂
+好
+面
+琐
+校
+馊
+鬣
+缂
+营
+访
+炖
+占
+农
+缀
+否
+经
+钚
+棵
+趟
+张
+亟
+吏
+茶
+谨
+捻
+论
+迸
+堂
+玉
+信
+吧
+瞠
+乡
+姬
+寺
+咬
+溏
+苄
+皿
+意
+赉
+宝
+尔
+钰
+艺
+特
+唳
+踉
+都
+荣
+倚
+登
+荐
+丧
+奇
+涵
+批
+炭
+近
+符
+傩
+感
+道
+着
+菊
+虹
+仲
+众
+懈
+濯
+颞
+眺
+南
+释
+北
+缝
+标
+既
+茗
+整
+撼
+迤
+贲
+挎
+耱
+拒
+某
+妍
+卫
+哇
+英
+矶
+藩
+治
+他
+元
+领
+膜
+遮
+穗
+蛾
+飞
+荒
+棺
+劫
+么
+市
+火
+温
+拈
+棚
+洼
+转
+果
+奕
+卸
+迪
+伸
+泳
+斗
+邡
+侄
+涨
+屯
+萋
+胭
+氡
+崮
+枞
+惧
+冒
+彩
+斜
+手
+豚
+随
+旭
+淑
+妞
+形
+菌
+吲
+沱
+争
+驯
+歹
+挟
+兆
+柱
+传
+至
+包
+内
+响
+临
+红
+功
+弩
+衡
+寂
+禁
+老
+棍
+耆
+渍
+织
+害
+氵
+渑
+布
+载
+靥
+嗬
+虽
+苹
+咨
+娄
+库
+雉
+榜
+帜
+嘲
+套
+瑚
+亲
+簸
+欧
+边
+6
+腿
+旮
+抛
+吹
+瞳
+得
+镓
+梗
+厨
+继
+漾
+愣
+憨
+士
+策
+窑
+抑
+躯
+襟
+脏
+参
+贸
+言
+干
+绸
+鳄
+穷
+藜
+音
+折
+详
+)
+举
+悍
+甸
+癌
+黎
+谴
+死
+罩
+迁
+寒
+驷
+袖
+媒
+蒋
+掘
+模
+纠
+恣
+观
+祖
+蛆
+碍
+位
+稿
+主
+澧
+跌
+筏
+京
+锏
+帝
+贴
+证
+糠
+才
+黄
+鲸
+略
+炯
+饱
+四
+出
+园
+犀
+牧
+容
+汉
+杆
+浈
+汰
+瑷
+造
+虫
+瘩
+怪
+驴
+济
+应
+花
+沣
+谔
+夙
+旅
+价
+矿
+以
+考
+s
+u
+呦
+晒
+巡
+茅
+准
+肟
+瓴
+詹
+仟
+褂
+译
+桌
+混
+宁
+怦
+郑
+抿
+些
+余
+鄂
+饴
+攒
+珑
+群
+阖
+岔
+琨
+藓
+预
+环
+洮
+岌
+宀
+杲
+瀵
+最
+常
+囡
+周
+踊
+女
+鼓
+袭
+喉
+简
+范
+薯
+遐
+疏
+粱
+黜
+禧
+法
+箔
+斤
+遥
+汝
+奥
+直
+贞
+撑
+置
+绱
+集
+她
+馅
+逗
+钧
+橱
+魉
+[
+恙
+躁
+唤
+9
+旺
+膘
+待
+脾
+惫
+购
+吗
+依
+盲
+度
+瘿
+蠖
+俾
+之
+镗
+拇
+鲵
+厝
+簧
+续
+款
+展
+啃
+表
+剔
+品
+钻
+腭
+损
+清
+锶
+统
+涌
+寸
+滨
+贪
+链
+吠
+冈
+伎
+迥
+咏
+吁
+览
+防
+迅
+失
+汾
+阔
+逵
+绀
+蔑
+列
+川
+凭
+努
+熨
+揪
+利
+俱
+绉
+抢
+鸨
+我
+即
+责
+膦
+易
+毓
+鹊
+刹
+玷
+岿
+空
+嘞
+绊
+排
+术
+估
+锷
+违
+们
+苟
+铜
+播
+肘
+件
+烫
+审
+鲂
+广
+像
+铌
+惰
+铟
+巳
+胍
+鲍
+康
+憧
+色
+恢
+想
+拷
+尤
+疳
+知
+S
+Y
+F
+D
+A
+峄
+裕
+帮
+握
+搔
+氐
+氘
+难
+墒
+沮
+雨
+叁
+缥
+悴
+藐
+湫
+娟
+苑
+稠
+颛
+簇
+后
+阕
+闭
+蕤
+缚
+怎
+佞
+码
+嘤
+蔡
+痊
+舱
+螯
+帕
+赫
+昵
+升
+烬
+岫
+、
+疵
+蜻
+髁
+蕨
+隶
+烛
+械
+丑
+盂
+梁
+强
+鲛
+由
+拘
+揉
+劭
+龟
+撤
+钩
+呕
+孛
+费
+妻
+漂
+求
+阑
+崖
+秤
+甘
+通
+深
+补
+赃
+坎
+床
+啪
+承
+吼
+量
+暇
+钼
+烨
+阂
+擎
+脱
+逮
+称
+P
+神
+属
+矗
+华
+届
+狍
+葑
+汹
+育
+患
+窒
+蛰
+佼
+静
+槎
+运
+鳗
+庆
+逝
+曼
+疱
+克
+代
+官
+此
+麸
+耧
+蚌
+晟
+例
+础
+榛
+副
+测
+唰
+缢
+迹
+灬
+霁
+身
+岁
+赭
+扛
+又
+菡
+乜
+雾
+板
+读
+陷
+徉
+贯
+郁
+虑
+变
+钓
+菜
+圾
+现
+琢
+式
+乐
+维
+渔
+浜
+左
+吾
+脑
+钡
+警
+T
+啵
+拴
+偌
+漱
+湿
+硕
+止
+骼
+魄
+积
+燥
+联
+踢
+玛
+则
+窿
+见
+振
+畿
+送
+班
+钽
+您
+赵
+刨
+印
+讨
+踝
+籍
+谡
+舌
+崧
+汽
+蔽
+沪
+酥
+绒
+怖
+财
+帖
+肱
+私
+莎
+勋
+羔
+霸
+励
+哼
+帐
+将
+帅
+渠
+纪
+婴
+娩
+岭
+厘
+滕
+吻
+伤
+坝
+冠
+戊
+隆
+瘁
+介
+涧
+物
+黍
+并
+姗
+奢
+蹑
+掣
+垸
+锴
+命
+箍
+捉
+病
+辖
+琰
+眭
+迩
+艘
+绌
+繁
+寅
+若
+毋
+思
+诉
+类
+诈
+燮
+轲
+酮
+狂
+重
+反
+职
+筱
+县
+委
+磕
+绣
+奖
+晋
+濉
+志
+徽
+肠
+呈
+獐
+坻
+口
+片
+碰
+几
+村
+柿
+劳
+料
+获
+亩
+惕
+晕
+厌
+号
+罢
+池
+正
+鏖
+煨
+家
+棕
+复
+尝
+懋
+蜥
+锅
+岛
+扰
+队
+坠
+瘾
+钬
+@
+卧
+疣
+镇
+譬
+冰
+彷
+频
+黯
+据
+垄
+采
+八
+缪
+瘫
+型
+熹
+砰
+楠
+襁
+箐
+但
+嘶
+绳
+啤
+拍
+盥
+穆
+傲
+洗
+盯
+塘
+怔
+筛
+丿
+台
+恒
+喂
+葛
+永
+¥
+烟
+酒
+桦
+书
+砂
+蚝
+缉
+态
+瀚
+袄
+圳
+轻
+蛛
+超
+榧
+遛
+姒
+奘
+铮
+右
+荽
+望
+偻
+卡
+丶
+氰
+附
+做
+革
+索
+戚
+坨
+桷
+唁
+垅
+榻
+岐
+偎
+坛
+莨
+山
+殊
+微
+骇
+陈
+爨
+推
+嗝
+驹
+澡
+藁
+呤
+卤
+嘻
+糅
+逛
+侵
+郓
+酌
+德
+摇
+※
+鬃
+被
+慨
+殡
+羸
+昌
+泡
+戛
+鞋
+河
+宪
+沿
+玲
+鲨
+翅
+哽
+源
+铅
+语
+照
+邯
+址
+荃
+佬
+顺
+鸳
+町
+霭
+睾
+瓢
+夸
+椁
+晓
+酿
+痈
+咔
+侏
+券
+噎
+湍
+签
+嚷
+离
+午
+尚
+社
+锤
+背
+孟
+使
+浪
+缦
+潍
+鞅
+军
+姹
+驶
+笑
+鳟
+鲁
+》
+孽
+钜
+绿
+洱
+礴
+焯
+椰
+颖
+囔
+乌
+孔
+巴
+互
+性
+椽
+哞
+聘
+昨
+早
+暮
+胶
+炀
+隧
+低
+彗
+昝
+铁
+呓
+氽
+藉
+喔
+癖
+瑗
+姨
+权
+胱
+韦
+堑
+蜜
+酋
+楝
+砝
+毁
+靓
+歙
+锲
+究
+屋
+喳
+骨
+辨
+碑
+武
+鸠
+宫
+辜
+烊
+适
+坡
+殃
+培
+佩
+供
+走
+蜈
+迟
+翼
+况
+姣
+凛
+浔
+吃
+飘
+债
+犟
+金
+促
+苛
+崇
+坂
+莳
+畔
+绂
+兵
+蠕
+斋
+根
+砍
+亢
+欢
+恬
+崔
+剁
+餐
+榫
+快
+扶
+‖
+濒
+缠
+鳜
+当
+彭
+驭
+浦
+篮
+昀
+锆
+秸
+钳
+弋
+娣
+瞑
+夷
+龛
+苫
+拱
+致
+%
+嵊
+障
+隐
+弑
+初
+娓
+抉
+汩
+累
+蓖
+"
+唬
+助
+苓
+昙
+押
+毙
+破
+城
+郧
+逢
+嚏
+獭
+瞻
+溱
+婿
+赊
+跨
+恼
+璧
+萃
+姻
+貉
+灵
+炉
+密
+氛
+陶
+砸
+谬
+衔
+点
+琛
+沛
+枳
+层
+岱
+诺
+脍
+榈
+埂
+征
+冷
+裁
+打
+蹴
+素
+瘘
+逞
+蛐
+聊
+激
+腱
+萘
+踵
+飒
+蓟
+吆
+取
+咙
+簋
+涓
+矩
+曝
+挺
+揣
+座
+你
+史
+舵
+焱
+尘
+苏
+笈
+脚
+溉
+榨
+诵
+樊
+邓
+焊
+义
+庶
+儋
+蟋
+蒲
+赦
+呷
+杞
+诠
+豪
+还
+试
+颓
+茉
+太
+除
+紫
+逃
+痴
+草
+充
+鳕
+珉
+祗
+墨
+渭
+烩
+蘸
+慕
+璇
+镶
+穴
+嵘
+恶
+骂
+险
+绋
+幕
+碉
+肺
+戳
+刘
+潞
+秣
+纾
+潜
+銮
+洛
+须
+罘
+销
+瘪
+汞
+兮
+屉
+r
+林
+厕
+质
+探
+划
+狸
+殚
+善
+煊
+烹
+〒
+锈
+逯
+宸
+辍
+泱
+柚
+袍
+远
+蹋
+嶙
+绝
+峥
+娥
+缍
+雀
+徵
+认
+镱
+谷
+=
+贩
+勉
+撩
+鄯
+斐
+洋
+非
+祚
+泾
+诒
+饿
+撬
+威
+晷
+搭
+芍
+锥
+笺
+蓦
+候
+琊
+档
+礁
+沼
+卵
+荠
+忑
+朝
+凹
+瑞
+头
+仪
+弧
+孵
+畏
+铆
+突
+衲
+车
+浩
+气
+茂
+悖
+厢
+枕
+酝
+戴
+湾
+邹
+飚
+攘
+锂
+写
+宵
+翁
+岷
+无
+喜
+丈
+挑
+嗟
+绛
+殉
+议
+槽
+具
+醇
+淞
+笃
+郴
+阅
+饼
+底
+壕
+砚
+弈
+询
+缕
+庹
+翟
+零
+筷
+暨
+舟
+闺
+甯
+撞
+麂
+茌
+蔼
+很
+珲
+捕
+棠
+角
+阉
+媛
+娲
+诽
+剿
+尉
+爵
+睬
+韩
+诰
+匣
+危
+糍
+镯
+立
+浏
+阳
+少
+盆
+舔
+擘
+匪
+申
+尬
+铣
+旯
+抖
+赘
+瓯
+居
+ˇ
+哮
+游
+锭
+茏
+歌
+坏
+甚
+秒
+舞
+沙
+仗
+劲
+潺
+阿
+燧
+郭
+嗖
+霏
+忠
+材
+奂
+耐
+跺
+砀
+输
+岖
+媳
+氟
+极
+摆
+灿
+今
+扔
+腻
+枝
+奎
+药
+熄
+吨
+话
+q
+额
+慑
+嘌
+协
+喀
+壳
+埭
+视
+著
+於
+愧
+陲
+翌
+峁
+颅
+佛
+腹
+聋
+侯
+咎
+叟
+秀
+颇
+存
+较
+罪
+哄
+岗
+扫
+栏
+钾
+羌
+己
+璨
+枭
+霉
+煌
+涸
+衿
+键
+镝
+益
+岢
+奏
+连
+夯
+睿
+冥
+均
+糖
+狞
+蹊
+稻
+爸
+刿
+胥
+煜
+丽
+肿
+璃
+掸
+跚
+灾
+垂
+樾
+濑
+乎
+莲
+窄
+犹
+撮
+战
+馄
+软
+络
+显
+鸢
+胸
+宾
+妲
+恕
+埔
+蝌
+份
+遇
+巧
+瞟
+粒
+恰
+剥
+桡
+博
+讯
+凯
+堇
+阶
+滤
+卖
+斌
+骚
+彬
+兑
+磺
+樱
+舷
+两
+娱
+福
+仃
+差
+找
+桁
+÷
+净
+把
+阴
+污
+戬
+雷
+碓
+蕲
+楚
+罡
+焖
+抽
+妫
+咒
+仑
+闱
+尽
+邑
+菁
+爱
+贷
+沥
+鞑
+牡
+嗉
+崴
+骤
+塌
+嗦
+订
+拮
+滓
+捡
+锻
+次
+坪
+杩
+臃
+箬
+融
+珂
+鹗
+宗
+枚
+降
+鸬
+妯
+阄
+堰
+盐
+毅
+必
+杨
+崃
+俺
+甬
+状
+莘
+货
+耸
+菱
+腼
+铸
+唏
+痤
+孚
+澳
+懒
+溅
+翘
+疙
+杷
+淼
+缙
+骰
+喊
+悉
+砻
+坷
+艇
+赁
+界
+谤
+纣
+宴
+晃
+茹
+归
+饭
+梢
+铡
+街
+抄
+肼
+鬟
+苯
+颂
+撷
+戈
+炒
+咆
+茭
+瘙
+负
+仰
+客
+琉
+铢
+封
+卑
+珥
+椿
+镧
+窨
+鬲
+寿
+御
+袤
+铃
+萎
+砖
+餮
+脒
+裳
+肪
+孕
+嫣
+馗
+嵇
+恳
+氯
+江
+石
+褶
+冢
+祸
+阻
+狈
+羞
+银
+靳
+透
+咳
+叼
+敷
+芷
+啥
+它
+瓤
+兰
+痘
+懊
+逑
+肌
+往
+捺
+坊
+甩
+呻
+〃
+沦
+忘
+膻
+祟
+菅
+剧
+崆
+智
+坯
+臧
+霍
+墅
+攻
+眯
+倘
+拢
+骠
+铐
+庭
+岙
+瓠
+′
+缺
+泥
+迢
+捶
+?
+?
+郏
+喙
+掷
+沌
+纯
+秘
+种
+听
+绘
+固
+螨
+团
+香
+盗
+妒
+埚
+蓝
+拖
+旱
+荞
+铀
+血
+遏
+汲
+辰
+叩
+拽
+幅
+硬
+惶
+桀
+漠
+措
+泼
+唑
+齐
+肾
+念
+酱
+虚
+屁
+耶
+旗
+砦
+闵
+婉
+馆
+拭
+绅
+韧
+忏
+窝
+醋
+葺
+顾
+辞
+倜
+堆
+辋
+逆
+玟
+贱
+疾
+董
+惘
+倌
+锕
+淘
+嘀
+莽
+俭
+笏
+绑
+鲷
+杈
+择
+蟀
+粥
+嗯
+驰
+逾
+案
+谪
+褓
+胫
+哩
+昕
+颚
+鲢
+绠
+躺
+鹄
+崂
+儒
+俨
+丝
+尕
+泌
+啊
+萸
+彰
+幺
+吟
+骄
+苣
+弦
+脊
+瑰
+〈
+诛
+镁
+析
+闪
+剪
+侧
+哟
+框
+螃
+守
+嬗
+燕
+狭
+铈
+缮
+概
+迳
+痧
+鲲
+俯
+售
+笼
+痣
+扉
+挖
+满
+咋
+援
+邱
+扇
+歪
+便
+玑
+绦
+峡
+蛇
+叨
+〖
+泽
+胃
+斓
+喋
+怂
+坟
+猪
+该
+蚬
+炕
+弥
+赞
+棣
+晔
+娠
+挲
+狡
+创
+疖
+铕
+镭
+稷
+挫
+弭
+啾
+翔
+粉
+履
+苘
+哦
+楼
+秕
+铂
+土
+锣
+瘟
+挣
+栉
+习
+享
+桢
+袅
+磨
+桂
+谦
+延
+坚
+蔚
+噗
+署
+谟
+猬
+钎
+恐
+嬉
+雒
+倦
+衅
+亏
+璩
+睹
+刻
+殿
+王
+算
+雕
+麻
+丘
+柯
+骆
+丸
+塍
+谚
+添
+鲈
+垓
+桎
+蚯
+芥
+予
+飕
+镦
+谌
+窗
+醚
+菀
+亮
+搪
+莺
+蒿
+羁
+足
+J
+真
+轶
+悬
+衷
+靛
+翊
+掩
+哒
+炅
+掐
+冼
+妮
+l
+谐
+稚
+荆
+擒
+犯
+陵
+虏
+浓
+崽
+刍
+陌
+傻
+孜
+千
+靖
+演
+矜
+钕
+煽
+杰
+酗
+渗
+伞
+栋
+俗
+泫
+戍
+罕
+沾
+疽
+灏
+煦
+芬
+磴
+叱
+阱
+榉
+湃
+蜀
+叉
+醒
+彪
+租
+郡
+篷
+屎
+良
+垢
+隗
+弱
+陨
+峪
+砷
+掴
+颁
+胎
+雯
+绵
+贬
+沐
+撵
+隘
+篙
+暖
+曹
+陡
+栓
+填
+臼
+彦
+瓶
+琪
+潼
+哪
+鸡
+摩
+啦
+俟
+锋
+域
+耻
+蔫
+疯
+纹
+撇
+毒
+绶
+痛
+酯
+忍
+爪
+赳
+歆
+嘹
+辕
+烈
+册
+朴
+钱
+吮
+毯
+癜
+娃
+谀
+邵
+厮
+炽
+璞
+邃
+丐
+追
+词
+瓒
+忆
+轧
+芫
+谯
+喷
+弟
+半
+冕
+裙
+掖
+墉
+绮
+寝
+苔
+势
+顷
+褥
+切
+衮
+君
+佳
+嫒
+蚩
+霞
+佚
+洙
+逊
+镖
+暹
+唛
+&
+殒
+顶
+碗
+獗
+轭
+铺
+蛊
+废
+恹
+汨
+崩
+珍
+那
+杵
+曲
+纺
+夏
+薰
+傀
+闳
+淬
+姘
+舀
+拧
+卷
+楂
+恍
+讪
+厩
+寮
+篪
+赓
+乘
+灭
+盅
+鞣
+沟
+慎
+挂
+饺
+鼾
+杳
+树
+缨
+丛
+絮
+娌
+臻
+嗳
+篡
+侩
+述
+衰
+矛
+圈
+蚜
+匕
+筹
+匿
+濞
+晨
+叶
+骋
+郝
+挚
+蚴
+滞
+增
+侍
+描
+瓣
+吖
+嫦
+蟒
+匾
+圣
+赌
+毡
+癞
+恺
+百
+曳
+需
+篓
+肮
+庖
+帏
+卿
+驿
+遗
+蹬
+鬓
+骡
+歉
+芎
+胳
+屐
+禽
+烦
+晌
+寄
+媾
+狄
+翡
+苒
+船
+廉
+终
+痞
+殇
+々
+畦
+饶
+改
+拆
+悻
+萄
+£
+瓿
+乃
+訾
+桅
+匮
+溧
+拥
+纱
+铍
+骗
+蕃
+龋
+缬
+父
+佐
+疚
+栎
+醍
+掳
+蓄
+x
+惆
+颜
+鲆
+榆
+〔
+猎
+敌
+暴
+谥
+鲫
+贾
+罗
+玻
+缄
+扦
+芪
+癣
+落
+徒
+臾
+恿
+猩
+托
+邴
+肄
+牵
+春
+陛
+耀
+刊
+拓
+蓓
+邳
+堕
+寇
+枉
+淌
+啡
+湄
+兽
+酷
+萼
+碚
+濠
+萤
+夹
+旬
+戮
+梭
+琥
+椭
+昔
+勺
+蜊
+绐
+晚
+孺
+僵
+宣
+摄
+冽
+旨
+萌
+忙
+蚤
+眉
+噼
+蟑
+付
+契
+瓜
+悼
+颡
+壁
+曾
+窕
+颢
+澎
+仿
+俑
+浑
+嵌
+浣
+乍
+碌
+褪
+乱
+蔟
+隙
+玩
+剐
+葫
+箫
+纲
+围
+伐
+决
+伙
+漩
+瑟
+刑
+肓
+镳
+缓
+蹭
+氨
+皓
+典
+畲
+坍
+铑
+檐
+塑
+洞
+倬
+储
+胴
+淳
+戾
+吐
+灼
+惺
+妙
+毕
+珐
+缈
+虱
+盖
+羰
+鸿
+磅
+谓
+髅
+娴
+苴
+唷
+蚣
+霹
+抨
+贤
+唠
+犬
+誓
+逍
+庠
+逼
+麓
+籼
+釉
+呜
+碧
+秧
+氩
+摔
+霄
+穸
+纨
+辟
+妈
+映
+完
+牛
+缴
+嗷
+炊
+恩
+荔
+茆
+掉
+紊
+慌
+莓
+羟
+阙
+萁
+磐
+另
+蕹
+辱
+鳐
+湮
+吡
+吩
+唐
+睦
+垠
+舒
+圜
+冗
+瞿
+溺
+芾
+囱
+匠
+僳
+汐
+菩
+饬
+漓
+黑
+霰
+浸
+濡
+窥
+毂
+蒡
+兢
+驻
+鹉
+芮
+诙
+迫
+雳
+厂
+忐
+臆
+猴
+鸣
+蚪
+栈
+箕
+羡
+渐
+莆
+捍
+眈
+哓
+趴
+蹼
+埕
+嚣
+骛
+宏
+淄
+斑
+噜
+严
+瑛
+垃
+椎
+诱
+压
+庾
+绞
+焘
+廿
+抡
+迄
+棘
+夫
+纬
+锹
+眨
+瞌
+侠
+脐
+竞
+瀑
+孳
+骧
+遁
+姜
+颦
+荪
+滚
+萦
+伪
+逸
+粳
+爬
+锁
+矣
+役
+趣
+洒
+颔
+诏
+逐
+奸
+甭
+惠
+攀
+蹄
+泛
+尼
+拼
+阮
+鹰
+亚
+颈
+惑
+勒
+〉
+际
+肛
+爷
+刚
+钨
+丰
+养
+冶
+鲽
+辉
+蔻
+画
+覆
+皴
+妊
+麦
+返
+醉
+皂
+擀
+〗
+酶
+凑
+粹
+悟
+诀
+硖
+港
+卜
+z
+杀
+涕
+±
+舍
+铠
+抵
+弛
+段
+敝
+镐
+奠
+拂
+轴
+跛
+袱
+e
+t
+沉
+菇
+俎
+薪
+峦
+秭
+蟹
+历
+盟
+菠
+寡
+液
+肢
+喻
+染
+裱
+悱
+抱
+氙
+赤
+捅
+猛
+跑
+氮
+谣
+仁
+尺
+辊
+窍
+烙
+衍
+架
+擦
+倏
+璐
+瑁
+币
+楞
+胖
+夔
+趸
+邛
+惴
+饕
+虔
+蝎
+§
+哉
+贝
+宽
+辫
+炮
+扩
+饲
+籽
+魏
+菟
+锰
+伍
+猝
+末
+琳
+哚
+蛎
+邂
+呀
+姿
+鄞
+却
+歧
+仙
+恸
+椐
+森
+牒
+寤
+袒
+婆
+虢
+雅
+钉
+朵
+贼
+欲
+苞
+寰
+故
+龚
+坭
+嘘
+咫
+礼
+硷
+兀
+睢
+汶
+’
+铲
+烧
+绕
+诃
+浃
+钿
+哺
+柜
+讼
+颊
+璁
+腔
+洽
+咐
+脲
+簌
+筠
+镣
+玮
+鞠
+谁
+兼
+姆
+挥
+梯
+蝴
+谘
+漕
+刷
+躏
+宦
+弼
+b
+垌
+劈
+麟
+莉
+揭
+笙
+渎
+仕
+嗤
+仓
+配
+怏
+抬
+错
+泯
+镊
+孰
+猿
+邪
+仍
+秋
+鼬
+壹
+歇
+吵
+炼
+<
+尧
+射
+柬
+廷
+胧
+霾
+凳
+隋
+肚
+浮
+梦
+祥
+株
+堵
+退
+L
+鹫
+跎
+凶
+毽
+荟
+炫
+栩
+玳
+甜
+沂
+鹿
+顽
+伯
+爹
+赔
+蛴
+徐
+匡
+欣
+狰
+缸
+雹
+蟆
+疤
+默
+沤
+啜
+痂
+衣
+禅
+w
+i
+h
+辽
+葳
+黝
+钗
+停
+沽
+棒
+馨
+颌
+肉
+吴
+硫
+悯
+劾
+娈
+马
+啧
+吊
+悌
+镑
+峭
+帆
+瀣
+涉
+咸
+疸
+滋
+泣
+翦
+拙
+癸
+钥
+蜒
++
+尾
+庄
+凝
+泉
+婢
+渴
+谊
+乞
+陆
+锉
+糊
+鸦
+淮
+I
+B
+N
+晦
+弗
+乔
+庥
+葡
+尻
+席
+橡
+傣
+渣
+拿
+惩
+麋
+斛
+缃
+矮
+蛏
+岘
+鸽
+姐
+膏
+催
+奔
+镒
+喱
+蠡
+摧
+钯
+胤
+柠
+拐
+璋
+鸥
+卢
+荡
+倾
+^
+_
+珀
+逄
+萧
+塾
+掇
+贮
+笆
+聂
+圃
+冲
+嵬
+M
+滔
+笕
+值
+炙
+偶
+蜱
+搐
+梆
+汪
+蔬
+腑
+鸯
+蹇
+敞
+绯
+仨
+祯
+谆
+梧
+糗
+鑫
+啸
+豺
+囹
+猾
+巢
+柄
+瀛
+筑
+踌
+沭
+暗
+苁
+鱿
+蹉
+脂
+蘖
+牢
+热
+木
+吸
+溃
+宠
+序
+泞
+偿
+拜
+檩
+厚
+朐
+毗
+螳
+吞
+媚
+朽
+担
+蝗
+橘
+畴
+祈
+糟
+盱
+隼
+郜
+惜
+珠
+裨
+铵
+焙
+琚
+唯
+咚
+噪
+骊
+丫
+滢
+勤
+棉
+呸
+咣
+淀
+隔
+蕾
+窈
+饨
+挨
+煅
+短
+匙
+粕
+镜
+赣
+撕
+墩
+酬
+馁
+豌
+颐
+抗
+酣
+氓
+佑
+搁
+哭
+递
+耷
+涡
+桃
+贻
+碣
+截
+瘦
+昭
+镌
+蔓
+氚
+甲
+猕
+蕴
+蓬
+散
+拾
+纛
+狼
+猷
+铎
+埋
+旖
+矾
+讳
+囊
+糜
+迈
+粟
+蚂
+紧
+鲳
+瘢
+栽
+稼
+羊
+锄
+斟
+睁
+桥
+瓮
+蹙
+祉
+醺
+鼻
+昱
+剃
+跳
+篱
+跷
+蒜
+翎
+宅
+晖
+嗑
+壑
+峻
+癫
+屏
+狠
+陋
+袜
+途
+憎
+祀
+莹
+滟
+佶
+溥
+臣
+约
+盛
+峰
+磁
+慵
+婪
+拦
+莅
+朕
+鹦
+粲
+裤
+哎
+疡
+嫖
+琵
+窟
+堪
+谛
+嘉
+儡
+鳝
+斩
+郾
+驸
+酊
+妄
+胜
+贺
+徙
+傅
+噌
+钢
+栅
+庇
+恋
+匝
+巯
+邈
+尸
+锚
+粗
+佟
+蛟
+薹
+纵
+蚊
+郅
+绢
+锐
+苗
+俞
+篆
+淆
+膀
+鲜
+煎
+诶
+秽
+寻
+涮
+刺
+怀
+噶
+巨
+褰
+魅
+灶
+灌
+桉
+藕
+谜
+舸
+薄
+搀
+恽
+借
+牯
+痉
+渥
+愿
+亓
+耘
+杠
+柩
+锔
+蚶
+钣
+珈
+喘
+蹒
+幽
+赐
+稗
+晤
+莱
+泔
+扯
+肯
+菪
+裆
+腩
+豉
+疆
+骜
+腐
+倭
+珏
+唔
+粮
+亡
+润
+慰
+伽
+橄
+玄
+誉
+醐
+胆
+龊
+粼
+塬
+陇
+彼
+削
+嗣
+绾
+芽
+妗
+垭
+瘴
+爽
+薏
+寨
+龈
+泠
+弹
+赢
+漪
+猫
+嘧
+涂
+恤
+圭
+茧
+烽
+屑
+痕
+巾
+赖
+荸
+凰
+腮
+畈
+亵
+蹲
+偃
+苇
+澜
+艮
+换
+骺
+烘
+苕
+梓
+颉
+肇
+哗
+悄
+氤
+涠
+葬
+屠
+鹭
+植
+竺
+佯
+诣
+鲇
+瘀
+鲅
+邦
+移
+滁
+冯
+耕
+癔
+戌
+茬
+沁
+巩
+悠
+湘
+洪
+痹
+锟
+循
+谋
+腕
+鳃
+钠
+捞
+焉
+迎
+碱
+伫
+急
+榷
+奈
+邝
+卯
+辄
+皲
+卟
+醛
+畹
+忧
+稳
+雄
+昼
+缩
+阈
+睑
+扌
+耗
+曦
+涅
+捏
+瞧
+邕
+淖
+漉
+铝
+耦
+禹
+湛
+喽
+莼
+琅
+诸
+苎
+纂
+硅
+始
+嗨
+傥
+燃
+臂
+赅
+嘈
+呆
+贵
+屹
+壮
+肋
+亍
+蚀
+卅
+豹
+腆
+邬
+迭
+浊
+}
+童
+螂
+捐
+圩
+勐
+触
+寞
+汊
+壤
+荫
+膺
+渌
+芳
+懿
+遴
+螈
+泰
+蓼
+蛤
+茜
+舅
+枫
+朔
+膝
+眙
+避
+梅
+判
+鹜
+璜
+牍
+缅
+垫
+藻
+黔
+侥
+惚
+懂
+踩
+腰
+腈
+札
+丞
+唾
+慈
+顿
+摹
+荻
+琬
+~
+斧
+沈
+滂
+胁
+胀
+幄
+莜
+Z
+匀
+鄄
+掌
+绰
+茎
+焚
+赋
+萱
+谑
+汁
+铒
+瞎
+夺
+蜗
+野
+娆
+冀
+弯
+篁
+懵
+灞
+隽
+芡
+脘
+俐
+辩
+芯
+掺
+喏
+膈
+蝈
+觐
+悚
+踹
+蔗
+熠
+鼠
+呵
+抓
+橼
+峨
+畜
+缔
+禾
+崭
+弃
+熊
+摒
+凸
+拗
+穹
+蒙
+抒
+祛
+劝
+闫
+扳
+阵
+醌
+踪
+喵
+侣
+搬
+仅
+荧
+赎
+蝾
+琦
+买
+婧
+瞄
+寓
+皎
+冻
+赝
+箩
+莫
+瞰
+郊
+笫
+姝
+筒
+枪
+遣
+煸
+袋
+舆
+痱
+涛
+母
+〇
+启
+践
+耙
+绲
+盘
+遂
+昊
+搞
+槿
+诬
+纰
+泓
+惨
+檬
+亻
+越
+C
+o
+憩
+熵
+祷
+钒
+暧
+塔
+阗
+胰
+咄
+娶
+魔
+琶
+钞
+邻
+扬
+杉
+殴
+咽
+弓
+〆
+髻
+】
+吭
+揽
+霆
+拄
+殖
+脆
+彻
+岩
+芝
+勃
+辣
+剌
+钝
+嘎
+甄
+佘
+皖
+伦
+授
+徕
+憔
+挪
+皇
+庞
+稔
+芜
+踏
+溴
+兖
+卒
+擢
+饥
+鳞
+煲
+‰
+账
+颗
+叻
+斯
+捧
+鳍
+琮
+讹
+蛙
+纽
+谭
+酸
+兔
+莒
+睇
+伟
+觑
+羲
+嗜
+宜
+褐
+旎
+辛
+卦
+诘
+筋
+鎏
+溪
+挛
+熔
+阜
+晰
+鳅
+丢
+奚
+灸
+呱
+献
+陉
+黛
+鸪
+甾
+萨
+疮
+拯
+洲
+疹
+辑
+叙
+恻
+谒
+允
+柔
+烂
+氏
+逅
+漆
+拎
+惋
+扈
+湟
+纭
+啕
+掬
+擞
+哥
+忽
+涤
+鸵
+靡
+郗
+瓷
+扁
+廊
+怨
+雏
+钮
+敦
+E
+懦
+憋
+汀
+拚
+啉
+腌
+岸
+f
+痼
+瞅
+尊
+咀
+眩
+飙
+忌
+仝
+迦
+熬
+毫
+胯
+篑
+茄
+腺
+凄
+舛
+碴
+锵
+诧
+羯
+後
+漏
+汤
+宓
+仞
+蚁
+壶
+谰
+皑
+铄
+棰
+罔
+辅
+晶
+苦
+牟
+闽
+\
+烃
+饮
+聿
+丙
+蛳
+朱
+煤
+涔
+鳖
+犁
+罐
+荼
+砒
+淦
+妤
+黏
+戎
+孑
+婕
+瑾
+戢
+钵
+枣
+捋
+砥
+衩
+狙
+桠
+稣
+阎
+肃
+梏
+诫
+孪
+昶
+婊
+衫
+嗔
+侃
+塞
+蜃
+樵
+峒
+貌
+屿
+欺
+缫
+阐
+栖
+诟
+珞
+荭
+吝
+萍
+嗽
+恂
+啻
+蜴
+磬
+峋
+俸
+豫
+谎
+徊
+镍
+韬
+魇
+晴
+U
+囟
+猜
+蛮
+坐
+囿
+伴
+亭
+肝
+佗
+蝠
+妃
+胞
+滩
+榴
+氖
+垩
+苋
+砣
+扪
+馏
+姓
+轩
+厉
+夥
+侈
+禀
+垒
+岑
+赏
+钛
+辐
+痔
+披
+纸
+碳
+“
+坞
+蠓
+挤
+荥
+沅
+悔
+铧
+帼
+蒌
+蝇
+a
+p
+y
+n
+g
+哀
+浆
+瑶
+凿
+桶
+馈
+皮
+奴
+苜
+佤
+伶
+晗
+铱
+炬
+优
+弊
+氢
+恃
+甫
+攥
+端
+锌
+灰
+稹
+炝
+曙
+邋
+亥
+眶
+碾
+拉
+萝
+绔
+捷
+浍
+腋
+姑
+菖
+凌
+涞
+麽
+锢
+桨
+潢
+绎
+镰
+殆
+锑
+渝
+铬
+困
+绽
+觎
+匈
+糙
+暑
+裹
+鸟
+盔
+肽
+迷
+綦
+『
+亳
+佝
+俘
+钴
+觇
+骥
+仆
+疝
+跪
+婶
+郯
+瀹
+唉
+脖
+踞
+针
+晾
+忒
+扼
+瞩
+叛
+椒
+疟
+嗡
+邗
+肆
+跆
+玫
+忡
+捣
+咧
+唆
+艄
+蘑
+潦
+笛
+阚
+沸
+泻
+掊
+菽
+贫
+斥
+髂
+孢
+镂
+赂
+麝
+鸾
+屡
+衬
+苷
+恪
+叠
+希
+粤
+爻
+喝
+茫
+惬
+郸
+绻
+庸
+撅
+碟
+宄
+妹
+膛
+叮
+饵
+崛
+嗲
+椅
+冤
+搅
+咕
+敛
+尹
+垦
+闷
+蝉
+霎
+勰
+败
+蓑
+泸
+肤
+鹌
+幌
+焦
+浠
+鞍
+刁
+舰
+乙
+竿
+裔
+。
+茵
+函
+伊
+兄
+丨
+娜
+匍
+謇
+莪
+宥
+似
+蝽
+翳
+酪
+翠
+粑
+薇
+祢
+骏
+赠
+叫
+Q
+噤
+噻
+竖
+芗
+莠
+潭
+俊
+羿
+耜
+O
+郫
+趁
+嗪
+囚
+蹶
+芒
+洁
+笋
+鹑
+敲
+硝
+啶
+堡
+渲
+揩
+』
+携
+宿
+遒
+颍
+扭
+棱
+割
+萜
+蔸
+葵
+琴
+捂
+饰
+衙
+耿
+掠
+募
+岂
+窖
+涟
+蔺
+瘤
+柞
+瞪
+怜
+匹
+距
+楔
+炜
+哆
+秦
+缎
+幼
+茁
+绪
+痨
+恨
+楸
+娅
+瓦
+桩
+雪
+嬴
+伏
+榔
+妥
+铿
+拌
+眠
+雍
+缇
+‘
+卓
+搓
+哌
+觞
+噩
+屈
+哧
+髓
+咦
+巅
+娑
+侑
+淫
+膳
+祝
+勾
+姊
+莴
+胄
+疃
+薛
+蜷
+胛
+巷
+芙
+芋
+熙
+闰
+勿
+窃
+狱
+剩
+钏
+幢
+陟
+铛
+慧
+靴
+耍
+k
+浙
+浇
+飨
+惟
+绗
+祜
+澈
+啼
+咪
+磷
+摞
+诅
+郦
+抹
+跃
+壬
+吕
+肖
+琏
+颤
+尴
+剡
+抠
+凋
+赚
+泊
+津
+宕
+殷
+倔
+氲
+漫
+邺
+涎
+怠
+$
+垮
+荬
+遵
+俏
+叹
+噢
+饽
+蜘
+孙
+筵
+疼
+鞭
+羧
+牦
+箭
+潴
+c
+眸
+祭
+髯
+啖
+坳
+愁
+芩
+驮
+倡
+巽
+穰
+沃
+胚
+怒
+凤
+槛
+剂
+趵
+嫁
+v
+邢
+灯
+鄢
+桐
+睽
+檗
+锯
+槟
+婷
+嵋
+圻
+诗
+蕈
+颠
+遭
+痢
+芸
+怯
+馥
+竭
+锗
+徜
+恭
+遍
+籁
+剑
+嘱
+苡
+龄
+僧
+桑
+潸
+弘
+澶
+楹
+悲
+讫
+愤
+腥
+悸
+谍
+椹
+呢
+桓
+葭
+攫
+阀
+翰
+躲
+敖
+柑
+郎
+笨
+橇
+呃
+魁
+燎
+脓
+葩
+磋
+垛
+玺
+狮
+沓
+砜
+蕊
+锺
+罹
+蕉
+翱
+虐
+闾
+巫
+旦
+茱
+嬷
+枯
+鹏
+贡
+芹
+汛
+矫
+绁
+拣
+禺
+佃
+讣
+舫
+惯
+乳
+趋
+疲
+挽
+岚
+虾
+衾
+蠹
+蹂
+飓
+氦
+铖
+孩
+稞
+瑜
+壅
+掀
+勘
+妓
+畅
+髋
+W
+庐
+牲
+蓿
+榕
+练
+垣
+唱
+邸
+菲
+昆
+婺
+穿
+绡
+麒
+蚱
+掂
+愚
+泷
+涪
+漳
+妩
+娉
+榄
+讷
+觅
+旧
+藤
+煮
+呛
+柳
+腓
+叭
+庵
+烷
+阡
+罂
+蜕
+擂
+猖
+咿
+媲
+脉
+【
+沏
+貅
+黠
+熏
+哲
+烁
+坦
+酵
+兜
+×
+潇
+撒
+剽
+珩
+圹
+乾
+摸
+樟
+帽
+嗒
+襄
+魂
+轿
+憬
+锡
+〕
+喃
+皆
+咖
+隅
+脸
+残
+泮
+袂
+鹂
+珊
+囤
+捆
+咤
+误
+徨
+闹
+淙
+芊
+淋
+怆
+囗
+拨
+梳
+渤
+R
+G
+绨
+蚓
+婀
+幡
+狩
+麾
+谢
+唢
+裸
+旌
+伉
+纶
+裂
+驳
+砼
+咛
+澄
+樨
+蹈
+宙
+澍
+倍
+貔
+操
+勇
+蟠
+摈
+砧
+虬
+够
+缁
+悦
+藿
+撸
+艹
+摁
+淹
+豇
+虎
+榭
+ˉ
+吱
+d
+°
+喧
+荀
+踱
+侮
+奋
+偕
+饷
+犍
+惮
+坑
+璎
+徘
+宛
+妆
+袈
+倩
+窦
+昂
+荏
+乖
+K
+怅
+撰
+鳙
+牙
+袁
+酞
+X
+痿
+琼
+闸
+雁
+趾
+荚
+虻
+涝
+《
+杏
+韭
+偈
+烤
+绫
+鞘
+卉
+症
+遢
+蓥
+诋
+杭
+荨
+匆
+竣
+簪
+辙
+敕
+虞
+丹
+缭
+咩
+黟
+m
+淤
+瑕
+咂
+铉
+硼
+茨
+嶂
+痒
+畸
+敬
+涿
+粪
+窘
+熟
+叔
+嫔
+盾
+忱
+裘
+憾
+梵
+赡
+珙
+咯
+娘
+庙
+溯
+胺
+葱
+痪
+摊
+荷
+卞
+乒
+髦
+寐
+铭
+坩
+胗
+枷
+爆
+溟
+嚼
+羚
+砬
+轨
+惊
+挠
+罄
+竽
+菏
+氧
+浅
+楣
+盼
+枢
+炸
+阆
+杯
+谏
+噬
+淇
+渺
+俪
+秆
+墓
+泪
+跻
+砌
+痰
+垡
+渡
+耽
+釜
+讶
+鳎
+煞
+呗
+韶
+舶
+绷
+鹳
+缜
+旷
+铊
+皱
+龌
+檀
+霖
+奄
+槐
+艳
+蝶
+旋
+哝
+赶
+骞
+蚧
+腊
+盈
+丁
+`
+蜚
+矸
+蝙
+睨
+嚓
+僻
+鬼
+醴
+夜
+彝
+磊
+笔
+拔
+栀
+糕
+厦
+邰
+纫
+逭
+纤
+眦
+膊
+馍
+躇
+烯
+蘼
+冬
+诤
+暄
+骶
+哑
+瘠
+」
+臊
+丕
+愈
+咱
+螺
+擅
+跋
+搏
+硪
+谄
+笠
+淡
+嘿
+骅
+谧
+鼎
+皋
+姚
+歼
+蠢
+驼
+耳
+胬
+挝
+涯
+狗
+蒽
+孓
+犷
+凉
+芦
+箴
+铤
+孤
+嘛
+坤
+V
+茴
+朦
+挞
+尖
+橙
+诞
+搴
+碇
+洵
+浚
+帚
+蜍
+漯
+柘
+嚎
+讽
+芭
+荤
+咻
+祠
+秉
+跖
+埃
+吓
+糯
+眷
+馒
+惹
+娼
+鲑
+嫩
+讴
+轮
+瞥
+靶
+褚
+乏
+缤
+宋
+帧
+删
+驱
+碎
+扑
+俩
+俄
+偏
+涣
+竹
+噱
+皙
+佰
+渚
+唧
+斡
+#
+镉
+刀
+崎
+筐
+佣
+夭
+贰
+肴
+峙
+哔
+艿
+匐
+牺
+镛
+缘
+仡
+嫡
+劣
+枸
+堀
+梨
+簿
+鸭
+蒸
+亦
+稽
+浴
+{
+衢
+束
+槲
+j
+阁
+揍
+疥
+棋
+潋
+聪
+窜
+乓
+睛
+插
+冉
+阪
+苍
+搽
+「
+蟾
+螟
+幸
+仇
+樽
+撂
+慢
+跤
+幔
+俚
+淅
+覃
+觊
+溶
+妖
+帛
+侨
+曰
+妾
+泗
+·
+:
+瀘
+風
+Ë
+(
+)
+∶
+紅
+紗
+瑭
+雲
+頭
+鶏
+財
+許
+•
+¥
+樂
+焗
+麗
+—
+;
+滙
+東
+榮
+繪
+興
+…
+門
+業
+π
+楊
+國
+顧
+é
+盤
+寳
+Λ
+龍
+鳳
+島
+誌
+緣
+結
+銭
+萬
+勝
+祎
+璟
+優
+歡
+臨
+時
+購
+=
+★
+藍
+昇
+鐵
+觀
+勅
+農
+聲
+畫
+兿
+術
+發
+劉
+記
+專
+耑
+園
+書
+壴
+種
+Ο
+●
+褀
+號
+銀
+匯
+敟
+锘
+葉
+橪
+廣
+進
+蒄
+鑽
+阝
+祙
+貢
+鍋
+豊
+夬
+喆
+團
+閣
+開
+燁
+賓
+館
+酡
+沔
+順
++
+硚
+劵
+饸
+陽
+車
+湓
+復
+萊
+氣
+軒
+華
+堃
+迮
+纟
+戶
+馬
+學
+裡
+電
+嶽
+獨
+マ
+シ
+サ
+ジ
+燘
+袪
+環
+❤
+臺
+灣
+専
+賣
+孖
+聖
+攝
+線
+▪
+α
+傢
+俬
+夢
+達
+莊
+喬
+貝
+薩
+劍
+羅
+壓
+棛
+饦
+尃
+璈
+囍
+醫
+G
+I
+A
+#
+N
+鷄
+髙
+嬰
+啓
+約
+隹
+潔
+賴
+藝
+~
+寶
+籣
+麺
+
+嶺
+√
+義
+網
+峩
+長
+∧
+魚
+機
+構
+②
+鳯
+偉
+L
+B
+㙟
+畵
+鴿
+'
+詩
+溝
+嚞
+屌
+藔
+佧
+玥
+蘭
+織
+1
+3
+9
+0
+7
+點
+砭
+鴨
+鋪
+銘
+廳
+弍
+‧
+創
+湯
+坶
+℃
+卩
+骝
+&
+烜
+荘
+當
+潤
+扞
+係
+懷
+碶
+钅
+蚨
+讠
+☆
+叢
+爲
+埗
+涫
+塗
+→
+楽
+現
+鯨
+愛
+瑪
+鈺
+忄
+悶
+藥
+飾
+樓
+視
+孬
+ㆍ
+燚
+苪
+師
+①
+丼
+锽
+│
+韓
+標
+è
+兒
+閏
+匋
+張
+漢
+Ü
+髪
+會
+閑
+檔
+習
+裝
+の
+峯
+菘
+輝
+И
+雞
+釣
+億
+浐
+K
+O
+R
+8
+H
+E
+P
+T
+W
+D
+S
+C
+M
+F
+姌
+饹
+»
+晞
+廰
+ä
+嵯
+鷹
+負
+飲
+絲
+冚
+楗
+澤
+綫
+區
+❋
+←
+質
+靑
+揚
+③
+滬
+統
+産
+協
+﹑
+乸
+畐
+經
+運
+際
+洺
+岽
+為
+粵
+諾
+崋
+豐
+碁
+ɔ
+V
+2
+6
+齋
+誠
+訂
+´
+勑
+雙
+陳
+無
+í
+泩
+媄
+夌
+刂
+i
+c
+t
+o
+r
+a
+嘢
+耄
+燴
+暃
+壽
+媽
+靈
+抻
+體
+唻
+É
+冮
+甹
+鎮
+錦
+ʌ
+蜛
+蠄
+尓
+駕
+戀
+飬
+逹
+倫
+貴
+極
+Я
+Й
+寬
+磚
+嶪
+郎
+職
+|
+間
+n
+d
+剎
+伈
+課
+飛
+橋
+瘊
+№
+譜
+骓
+圗
+滘
+縣
+粿
+咅
+養
+濤
+彳
+®
+%
+Ⅱ
+啰
+㴪
+見
+矞
+薬
+糁
+邨
+鲮
+顔
+罱
+З
+選
+話
+贏
+氪
+俵
+競
+瑩
+繡
+枱
+β
+綉
+á
+獅
+爾
+™
+麵
+戋
+淩
+徳
+個
+劇
+場
+務
+簡
+寵
+h
+實
+膠
+轱
+圖
+築
+嘣
+樹
+㸃
+營
+耵
+孫
+饃
+鄺
+飯
+麯
+遠
+輸
+坫
+孃
+乚
+閃
+鏢
+㎡
+題
+廠
+關
+↑
+爺
+將
+軍
+連
+篦
+覌
+參
+箸
+-
+窠
+棽
+寕
+夀
+爰
+歐
+呙
+閥
+頡
+熱
+雎
+垟
+裟
+凬
+勁
+帑
+馕
+夆
+疌
+枼
+馮
+貨
+蒤
+樸
+彧
+旸
+靜
+龢
+暢
+㐱
+鳥
+珺
+鏡
+灡
+爭
+堷
+廚
+Ó
+騰
+診
+┅
+蘇
+褔
+凱
+頂
+豕
+亞
+帥
+嘬
+⊥
+仺
+桖
+複
+饣
+絡
+穂
+顏
+棟
+納
+▏
+濟
+親
+設
+計
+攵
+埌
+烺
+ò
+頤
+燦
+蓮
+撻
+節
+講
+濱
+濃
+娽
+洳
+朿
+燈
+鈴
+護
+膚
+铔
+過
+補
+Z
+U
+5
+4
+坋
+闿
+䖝
+餘
+缐
+铞
+貿
+铪
+桼
+趙
+鍊
+[
+㐂
+垚
+菓
+揸
+捲
+鐘
+滏
+𣇉
+爍
+輪
+燜
+鴻
+鮮
+動
+鹞
+鷗
+丄
+慶
+鉌
+翥
+飮
+腸
+⇋
+漁
+覺
+來
+熘
+昴
+翏
+鲱
+圧
+鄉
+萭
+頔
+爐
+嫚
+г
+貭
+類
+聯
+幛
+輕
+訓
+鑒
+夋
+锨
+芃
+珣
+䝉
+扙
+嵐
+銷
+處
+ㄱ
+語
+誘
+苝
+歸
+儀
+燒
+楿
+內
+粢
+葒
+奧
+麥
+礻
+滿
+蠔
+穵
+瞭
+態
+鱬
+榞
+硂
+鄭
+黃
+煙
+祐
+奓
+逺
+*
+瑄
+獲
+聞
+薦
+讀
+這
+樣
+決
+問
+啟
+們
+執
+説
+轉
+單
+隨
+唘
+帶
+倉
+庫
+還
+贈
+尙
+皺
+■
+餅
+產
+○
+∈
+報
+狀
+楓
+賠
+琯
+嗮
+禮
+`
+傳
+>
+≤
+嗞
+Φ
+≥
+換
+咭
+∣
+↓
+曬
+ε
+応
+寫
+″
+終
+様
+純
+費
+療
+聨
+凍
+壐
+郵
+ü
+黒
+∫
+製
+塊
+調
+軽
+確
+撃
+級
+馴
+Ⅲ
+涇
+繹
+數
+碼
+證
+狒
+処
+劑
+<
+晧
+賀
+衆
+]
+櫥
+兩
+陰
+絶
+對
+鯉
+憶
+◎
+p
+e
+Y
+蕒
+煖
+頓
+測
+試
+鼽
+僑
+碩
+妝
+帯
+≈
+鐡
+舖
+權
+喫
+倆
+ˋ
+該
+悅
+ā
+俫
+.
+f
+s
+b
+m
+k
+g
+u
+j
+貼
+淨
+濕
+針
+適
+備
+l
+/
+給
+謢
+強
+觸
+衛
+與
+⊙
+$
+緯
+變
+⑴
+⑵
+⑶
+㎏
+殺
+∩
+幚
+─
+價
+▲
+離
+ú
+ó
+飄
+烏
+関
+閟
+﹝
+﹞
+邏
+輯
+鍵
+驗
+訣
+導
+歷
+屆
+層
+▼
+儱
+錄
+熳
+ē
+艦
+吋
+錶
+辧
+飼
+顯
+④
+禦
+販
+気
+対
+枰
+閩
+紀
+幹
+瞓
+貊
+淚
+△
+眞
+墊
+Ω
+獻
+褲
+縫
+緑
+亜
+鉅
+餠
+{
+}
+◆
+蘆
+薈
+█
+◇
+溫
+彈
+晳
+粧
+犸
+穩
+訊
+崬
+凖
+熥
+П
+舊
+條
+紋
+圍
+Ⅳ
+筆
+尷
+難
+雜
+錯
+綁
+識
+頰
+鎖
+艶
+□
+殁
+殼
+⑧
+├
+▕
+鵬
+ǐ
+ō
+ǒ
+糝
+綱
+▎
+μ
+盜
+饅
+醬
+籤
+蓋
+釀
+鹽
+據
+à
+ɡ
+辦
+◥
+彐
+┌
+婦
+獸
+鲩
+伱
+ī
+蒟
+蒻
+齊
+袆
+腦
+寧
+凈
+妳
+煥
+詢
+偽
+謹
+啫
+鯽
+騷
+鱸
+損
+傷
+鎻
+髮
+買
+冏
+儥
+両
+﹢
+∞
+載
+喰
+z
+羙
+悵
+燙
+曉
+員
+組
+徹
+艷
+痠
+鋼
+鼙
+縮
+細
+嚒
+爯
+≠
+維
+"
+鱻
+壇
+厍
+帰
+浥
+犇
+薡
+軎
+²
+應
+醜
+刪
+緻
+鶴
+賜
+噁
+軌
+尨
+镔
+鷺
+槗
+彌
+葚
+濛
+請
+溇
+緹
+賢
+訪
+獴
+瑅
+資
+縤
+陣
+蕟
+栢
+韻
+祼
+恁
+伢
+謝
+劃
+涑
+總
+衖
+踺
+砋
+凉
+籃
+駿
+苼
+瘋
+昽
+紡
+驊
+腎
+﹗
+響
+杋
+剛
+嚴
+禪
+歓
+槍
+傘
+檸
+檫
+炣
+勢
+鏜
+鎢
+銑
+尐
+減
+奪
+惡
+θ
+僮
+婭
+臘
+ū
+ì
+殻
+鉄
+∑
+蛲
+焼
+緖
+續
+紹
+懮
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1.js b/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1.js
new file mode 100644
index 00000000..17052aca
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/ppocr_keys_v1.js
@@ -0,0 +1 @@
+export const character = ["'",'疗','绚','诚','娇','溜','题','贿','者','廖','更','纳','加','奉','公','一','就','汴','计','与','路','房','原','妇','2','0','8','-','7','其','>',':',']',',',',','骑','刈','全','消','昏','傈','安','久','钟','嗅','不','影','处','驽','蜿','资','关','椤','地','瘸','专','问','忖','票','嫉','炎','韵','要','月','田','节','陂','鄙','捌','备','拳','伺','眼','网','盎','大','傍','心','东','愉','汇','蹿','科','每','业','里','航','晏','字','平','录','先','1','3','彤','鲶','产','稍','督','腴','有','象','岳','注','绍','在','泺','文','定','核','名','水','过','理','让','偷','率','等','这','发','”','为','含','肥','酉','相','鄱','七','编','猥','锛','日','镀','蒂','掰','倒','辆','栾','栗','综','涩','州','雌','滑','馀','了','机','块','司','宰','甙','兴','矽','抚','保','用','沧','秩','如','收','息','滥','页','疑','埠','!','!','姥','异','橹','钇','向','下','跄','的','椴','沫','国','绥','獠','报','开','民','蜇','何','分','凇','长','讥','藏','掏','施','羽','中','讲','派','嘟','人','提','浼','间','世','而','古','多','倪','唇','饯','控','庚','首','赛','蜓','味','断','制','觉','技','替','艰','溢','潮','夕','钺','外','摘','枋','动','双','单','啮','户','枇','确','锦','曜','杜','或','能','效','霜','盒','然','侗','电','晁','放','步','鹃','新','杖','蜂','吒','濂','瞬','评','总','隍','对','独','合','也','是','府','青','天','诲','墙','组','滴','级','邀','帘','示','已','时','骸','仄','泅','和','遨','店','雇','疫','持','巍','踮','境','只','亨','目','鉴','崤','闲','体','泄','杂','作','般','轰','化','解','迂','诿','蛭','璀','腾','告','版','服','省','师','小','规','程','线','海','办','引','二','桧','牌','砺','洄','裴','修','图','痫','胡','许','犊','事','郛','基','柴','呼','食','研','奶','律','蛋','因','葆','察','戏','褒','戒','再','李','骁','工','貂','油','鹅','章','啄','休','场','给','睡','纷','豆','器','捎','说','敏','学','会','浒','设','诊','格','廓','查','来','霓','室','溆','¢','诡','寥','焕','舜','柒','狐','回','戟','砾','厄','实','翩','尿','五','入','径','惭','喹','股','宇','篝','|',';','美','期','云','九','祺','扮','靠','锝','槌','系','企','酰','阊','暂','蚕','忻','豁','本','羹','执','条','钦','H','獒','限','进','季','楦','于','芘','玖','铋','茯','未','答','粘','括','样','精','欠','矢','甥','帷','嵩','扣','令','仔','风','皈','行','支','部','蓉','刮','站','蜡','救','钊','汗','松','嫌','成','可','.','鹤','院','从','交','政','怕','活','调','球','局','验','髌','第','韫','谗','串','到','圆','年','米','/','*','友','忿','检','区','看','自','敢','刃','个','兹','弄','流','留','同','没','齿','星','聆','轼','湖','什','三','建','蛔','儿','椋','汕','震','颧','鲤','跟','力','情','璺','铨','陪','务','指','族','训','滦','鄣','濮','扒','商','箱','十','召','慷','辗','所','莞','管','护','臭','横','硒','嗓','接','侦','六','露','党','馋','驾','剖','高','侬','妪','幂','猗','绺','骐','央','酐','孝','筝','课','徇','缰','门','男','西','项','句','谙','瞒','秃','篇','教','碲','罚','声','呐','景','前','富','嘴','鳌','稀','免','朋','啬','睐','去','赈','鱼','住','肩','愕','速','旁','波','厅','健','茼','厥','鲟','谅','投','攸','炔','数','方','击','呋','谈','绩','别','愫','僚','躬','鹧','胪','炳','招','喇','膨','泵','蹦','毛','结','5','4','谱','识','陕','粽','婚','拟','构','且','搜','任','潘','比','郢','妨','醪','陀','桔','碘','扎','选','哈','骷','楷','亿','明','缆','脯','监','睫','逻','婵','共','赴','淝','凡','惦','及','达','揖','谩','澹','减','焰','蛹','番','祁','柏','员','禄','怡','峤','龙','白','叽','生','闯','起','细','装','谕','竟','聚','钙','上','导','渊','按','艾','辘','挡','耒','盹','饪','臀','记','邮','蕙','受','各','医','搂','普','滇','朗','茸','带','翻','酚','(','光','堤','墟','蔷','万','幻','〓','瑙','辈','昧','盏','亘','蛀','吉','铰','请','子','假','闻','税','井','诩','哨','嫂','好','面','琐','校','馊','鬣','缂','营','访','炖','占','农','缀','否','经','钚','棵','趟','张','亟','吏','茶','谨','捻','论','迸','堂','玉','信','吧','瞠','乡','姬','寺','咬','溏','苄','皿','意','赉','宝','尔','钰','艺','特','唳','踉','都','荣','倚','登','荐','丧','奇','涵','批','炭','近','符','傩','感','道','着','菊','虹','仲','众','懈','濯','颞','眺','南','释','北','缝','标','既','茗','整','撼','迤','贲','挎','耱','拒','某','妍','卫','哇','英','矶','藩','治','他','元','领','膜','遮','穗','蛾','飞','荒','棺','劫','么','市','火','温','拈','棚','洼','转','果','奕','卸','迪','伸','泳','斗','邡','侄','涨','屯','萋','胭','氡','崮','枞','惧','冒','彩','斜','手','豚','随','旭','淑','妞','形','菌','吲','沱','争','驯','歹','挟','兆','柱','传','至','包','内','响','临','红','功','弩','衡','寂','禁','老','棍','耆','渍','织','害','氵','渑','布','载','靥','嗬','虽','苹','咨','娄','库','雉','榜','帜','嘲','套','瑚','亲','簸','欧','边','6','腿','旮','抛','吹','瞳','得','镓','梗','厨','继','漾','愣','憨','士','策','窑','抑','躯','襟','脏','参','贸','言','干','绸','鳄','穷','藜','音','折','详',')','举','悍','甸','癌','黎','谴','死','罩','迁','寒','驷','袖','媒','蒋','掘','模','纠','恣','观','祖','蛆','碍','位','稿','主','澧','跌','筏','京','锏','帝','贴','证','糠','才','黄','鲸','略','炯','饱','四','出','园','犀','牧','容','汉','杆','浈','汰','瑷','造','虫','瘩','怪','驴','济','应','花','沣','谔','夙','旅','价','矿','以','考','s','u','呦','晒','巡','茅','准','肟','瓴','詹','仟','褂','译','桌','混','宁','怦','郑','抿','些','余','鄂','饴','攒','珑','群','阖','岔','琨','藓','预','环','洮','岌','宀','杲','瀵','最','常','囡','周','踊','女','鼓','袭','喉','简','范','薯','遐','疏','粱','黜','禧','法','箔','斤','遥','汝','奥','直','贞','撑','置','绱','集','她','馅','逗','钧','橱','魉','[','恙','躁','唤','9','旺','膘','待','脾','惫','购','吗','依','盲','度','瘿','蠖','俾','之','镗','拇','鲵','厝','簧','续','款','展','啃','表','剔','品','钻','腭','损','清','锶','统','涌','寸','滨','贪','链','吠','冈','伎','迥','咏','吁','览','防','迅','失','汾','阔','逵','绀','蔑','列','川','凭','努','熨','揪','利','俱','绉','抢','鸨','我','即','责','膦','易','毓','鹊','刹','玷','岿','空','嘞','绊','排','术','估','锷','违','们','苟','铜','播','肘','件','烫','审','鲂','广','像','铌','惰','铟','巳','胍','鲍','康','憧','色','恢','想','拷','尤','疳','知','S','Y','F','D','A','峄','裕','帮','握','搔','氐','氘','难','墒','沮','雨','叁','缥','悴','藐','湫','娟','苑','稠','颛','簇','后','阕','闭','蕤','缚','怎','佞','码','嘤','蔡','痊','舱','螯','帕','赫','昵','升','烬','岫','、','疵','蜻','髁','蕨','隶','烛','械','丑','盂','梁','强','鲛','由','拘','揉','劭','龟','撤','钩','呕','孛','费','妻','漂','求','阑','崖','秤','甘','通','深','补','赃','坎','床','啪','承','吼','量','暇','钼','烨','阂','擎','脱','逮','称','P','神','属','矗','华','届','狍','葑','汹','育','患','窒','蛰','佼','静','槎','运','鳗','庆','逝','曼','疱','克','代','官','此','麸','耧','蚌','晟','例','础','榛','副','测','唰','缢','迹','灬','霁','身','岁','赭','扛','又','菡','乜','雾','板','读','陷','徉','贯','郁','虑','变','钓','菜','圾','现','琢','式','乐','维','渔','浜','左','吾','脑','钡','警','T','啵','拴','偌','漱','湿','硕','止','骼','魄','积','燥','联','踢','玛','则','窿','见','振','畿','送','班','钽','您','赵','刨','印','讨','踝','籍','谡','舌','崧','汽','蔽','沪','酥','绒','怖','财','帖','肱','私','莎','勋','羔','霸','励','哼','帐','将','帅','渠','纪','婴','娩','岭','厘','滕','吻','伤','坝','冠','戊','隆','瘁','介','涧','物','黍','并','姗','奢','蹑','掣','垸','锴','命','箍','捉','病','辖','琰','眭','迩','艘','绌','繁','寅','若','毋','思','诉','类','诈','燮','轲','酮','狂','重','反','职','筱','县','委','磕','绣','奖','晋','濉','志','徽','肠','呈','獐','坻','口','片','碰','几','村','柿','劳','料','获','亩','惕','晕','厌','号','罢','池','正','鏖','煨','家','棕','复','尝','懋','蜥','锅','岛','扰','队','坠','瘾','钬','@','卧','疣','镇','譬','冰','彷','频','黯','据','垄','采','八','缪','瘫','型','熹','砰','楠','襁','箐','但','嘶','绳','啤','拍','盥','穆','傲','洗','盯','塘','怔','筛','丿','台','恒','喂','葛','永','¥','烟','酒','桦','书','砂','蚝','缉','态','瀚','袄','圳','轻','蛛','超','榧','遛','姒','奘','铮','右','荽','望','偻','卡','丶','氰','附','做','革','索','戚','坨','桷','唁','垅','榻','岐','偎','坛','莨','山','殊','微','骇','陈','爨','推','嗝','驹','澡','藁','呤','卤','嘻','糅','逛','侵','郓','酌','德','摇','※','鬃','被','慨','殡','羸','昌','泡','戛','鞋','河','宪','沿','玲','鲨','翅','哽','源','铅','语','照','邯','址','荃','佬','顺','鸳','町','霭','睾','瓢','夸','椁','晓','酿','痈','咔','侏','券','噎','湍','签','嚷','离','午','尚','社','锤','背','孟','使','浪','缦','潍','鞅','军','姹','驶','笑','鳟','鲁','》','孽','钜','绿','洱','礴','焯','椰','颖','囔','乌','孔','巴','互','性','椽','哞','聘','昨','早','暮','胶','炀','隧','低','彗','昝','铁','呓','氽','藉','喔','癖','瑗','姨','权','胱','韦','堑','蜜','酋','楝','砝','毁','靓','歙','锲','究','屋','喳','骨','辨','碑','武','鸠','宫','辜','烊','适','坡','殃','培','佩','供','走','蜈','迟','翼','况','姣','凛','浔','吃','飘','债','犟','金','促','苛','崇','坂','莳','畔','绂','兵','蠕','斋','根','砍','亢','欢','恬','崔','剁','餐','榫','快','扶','‖','濒','缠','鳜','当','彭','驭','浦','篮','昀','锆','秸','钳','弋','娣','瞑','夷','龛','苫','拱','致','%','嵊','障','隐','弑','初','娓','抉','汩','累','蓖','"','唬','助','苓','昙','押','毙','破','城','郧','逢','嚏','獭','瞻','溱','婿','赊','跨','恼','璧','萃','姻','貉','灵','炉','密','氛','陶','砸','谬','衔','点','琛','沛','枳','层','岱','诺','脍','榈','埂','征','冷','裁','打','蹴','素','瘘','逞','蛐','聊','激','腱','萘','踵','飒','蓟','吆','取','咙','簋','涓','矩','曝','挺','揣','座','你','史','舵','焱','尘','苏','笈','脚','溉','榨','诵','樊','邓','焊','义','庶','儋','蟋','蒲','赦','呷','杞','诠','豪','还','试','颓','茉','太','除','紫','逃','痴','草','充','鳕','珉','祗','墨','渭','烩','蘸','慕','璇','镶','穴','嵘','恶','骂','险','绋','幕','碉','肺','戳','刘','潞','秣','纾','潜','銮','洛','须','罘','销','瘪','汞','兮','屉','r','林','厕','质','探','划','狸','殚','善','煊','烹','〒','锈','逯','宸','辍','泱','柚','袍','远','蹋','嶙','绝','峥','娥','缍','雀','徵','认','镱','谷','=','贩','勉','撩','鄯','斐','洋','非','祚','泾','诒','饿','撬','威','晷','搭','芍','锥','笺','蓦','候','琊','档','礁','沼','卵','荠','忑','朝','凹','瑞','头','仪','弧','孵','畏','铆','突','衲','车','浩','气','茂','悖','厢','枕','酝','戴','湾','邹','飚','攘','锂','写','宵','翁','岷','无','喜','丈','挑','嗟','绛','殉','议','槽','具','醇','淞','笃','郴','阅','饼','底','壕','砚','弈','询','缕','庹','翟','零','筷','暨','舟','闺','甯','撞','麂','茌','蔼','很','珲','捕','棠','角','阉','媛','娲','诽','剿','尉','爵','睬','韩','诰','匣','危','糍','镯','立','浏','阳','少','盆','舔','擘','匪','申','尬','铣','旯','抖','赘','瓯','居','ˇ','哮','游','锭','茏','歌','坏','甚','秒','舞','沙','仗','劲','潺','阿','燧','郭','嗖','霏','忠','材','奂','耐','跺','砀','输','岖','媳','氟','极','摆','灿','今','扔','腻','枝','奎','药','熄','吨','话','q','额','慑','嘌','协','喀','壳','埭','视','著','於','愧','陲','翌','峁','颅','佛','腹','聋','侯','咎','叟','秀','颇','存','较','罪','哄','岗','扫','栏','钾','羌','己','璨','枭','霉','煌','涸','衿','键','镝','益','岢','奏','连','夯','睿','冥','均','糖','狞','蹊','稻','爸','刿','胥','煜','丽','肿','璃','掸','跚','灾','垂','樾','濑','乎','莲','窄','犹','撮','战','馄','软','络','显','鸢','胸','宾','妲','恕','埔','蝌','份','遇','巧','瞟','粒','恰','剥','桡','博','讯','凯','堇','阶','滤','卖','斌','骚','彬','兑','磺','樱','舷','两','娱','福','仃','差','找','桁','÷','净','把','阴','污','戬','雷','碓','蕲','楚','罡','焖','抽','妫','咒','仑','闱','尽','邑','菁','爱','贷','沥','鞑','牡','嗉','崴','骤','塌','嗦','订','拮','滓','捡','锻','次','坪','杩','臃','箬','融','珂','鹗','宗','枚','降','鸬','妯','阄','堰','盐','毅','必','杨','崃','俺','甬','状','莘','货','耸','菱','腼','铸','唏','痤','孚','澳','懒','溅','翘','疙','杷','淼','缙','骰','喊','悉','砻','坷','艇','赁','界','谤','纣','宴','晃','茹','归','饭','梢','铡','街','抄','肼','鬟','苯','颂','撷','戈','炒','咆','茭','瘙','负','仰','客','琉','铢','封','卑','珥','椿','镧','窨','鬲','寿','御','袤','铃','萎','砖','餮','脒','裳','肪','孕','嫣','馗','嵇','恳','氯','江','石','褶','冢','祸','阻','狈','羞','银','靳','透','咳','叼','敷','芷','啥','它','瓤','兰','痘','懊','逑','肌','往','捺','坊','甩','呻','〃','沦','忘','膻','祟','菅','剧','崆','智','坯','臧','霍','墅','攻','眯','倘','拢','骠','铐','庭','岙','瓠','′','缺','泥','迢','捶','?','?','郏','喙','掷','沌','纯','秘','种','听','绘','固','螨','团','香','盗','妒','埚','蓝','拖','旱','荞','铀','血','遏','汲','辰','叩','拽','幅','硬','惶','桀','漠','措','泼','唑','齐','肾','念','酱','虚','屁','耶','旗','砦','闵','婉','馆','拭','绅','韧','忏','窝','醋','葺','顾','辞','倜','堆','辋','逆','玟','贱','疾','董','惘','倌','锕','淘','嘀','莽','俭','笏','绑','鲷','杈','择','蟀','粥','嗯','驰','逾','案','谪','褓','胫','哩','昕','颚','鲢','绠','躺','鹄','崂','儒','俨','丝','尕','泌','啊','萸','彰','幺','吟','骄','苣','弦','脊','瑰','〈','诛','镁','析','闪','剪','侧','哟','框','螃','守','嬗','燕','狭','铈','缮','概','迳','痧','鲲','俯','售','笼','痣','扉','挖','满','咋','援','邱','扇','歪','便','玑','绦','峡','蛇','叨','〖','泽','胃','斓','喋','怂','坟','猪','该','蚬','炕','弥','赞','棣','晔','娠','挲','狡','创','疖','铕','镭','稷','挫','弭','啾','翔','粉','履','苘','哦','楼','秕','铂','土','锣','瘟','挣','栉','习','享','桢','袅','磨','桂','谦','延','坚','蔚','噗','署','谟','猬','钎','恐','嬉','雒','倦','衅','亏','璩','睹','刻','殿','王','算','雕','麻','丘','柯','骆','丸','塍','谚','添','鲈','垓','桎','蚯','芥','予','飕','镦','谌','窗','醚','菀','亮','搪','莺','蒿','羁','足','J','真','轶','悬','衷','靛','翊','掩','哒','炅','掐','冼','妮','l','谐','稚','荆','擒','犯','陵','虏','浓','崽','刍','陌','傻','孜','千','靖','演','矜','钕','煽','杰','酗','渗','伞','栋','俗','泫','戍','罕','沾','疽','灏','煦','芬','磴','叱','阱','榉','湃','蜀','叉','醒','彪','租','郡','篷','屎','良','垢','隗','弱','陨','峪','砷','掴','颁','胎','雯','绵','贬','沐','撵','隘','篙','暖','曹','陡','栓','填','臼','彦','瓶','琪','潼','哪','鸡','摩','啦','俟','锋','域','耻','蔫','疯','纹','撇','毒','绶','痛','酯','忍','爪','赳','歆','嘹','辕','烈','册','朴','钱','吮','毯','癜','娃','谀','邵','厮','炽','璞','邃','丐','追','词','瓒','忆','轧','芫','谯','喷','弟','半','冕','裙','掖','墉','绮','寝','苔','势','顷','褥','切','衮','君','佳','嫒','蚩','霞','佚','洙','逊','镖','暹','唛','&','殒','顶','碗','獗','轭','铺','蛊','废','恹','汨','崩','珍','那','杵','曲','纺','夏','薰','傀','闳','淬','姘','舀','拧','卷','楂','恍','讪','厩','寮','篪','赓','乘','灭','盅','鞣','沟','慎','挂','饺','鼾','杳','树','缨','丛','絮','娌','臻','嗳','篡','侩','述','衰','矛','圈','蚜','匕','筹','匿','濞','晨','叶','骋','郝','挚','蚴','滞','增','侍','描','瓣','吖','嫦','蟒','匾','圣','赌','毡','癞','恺','百','曳','需','篓','肮','庖','帏','卿','驿','遗','蹬','鬓','骡','歉','芎','胳','屐','禽','烦','晌','寄','媾','狄','翡','苒','船','廉','终','痞','殇','々','畦','饶','改','拆','悻','萄','£','瓿','乃','訾','桅','匮','溧','拥','纱','铍','骗','蕃','龋','缬','父','佐','疚','栎','醍','掳','蓄','x','惆','颜','鲆','榆','〔','猎','敌','暴','谥','鲫','贾','罗','玻','缄','扦','芪','癣','落','徒','臾','恿','猩','托','邴','肄','牵','春','陛','耀','刊','拓','蓓','邳','堕','寇','枉','淌','啡','湄','兽','酷','萼','碚','濠','萤','夹','旬','戮','梭','琥','椭','昔','勺','蜊','绐','晚','孺','僵','宣','摄','冽','旨','萌','忙','蚤','眉','噼','蟑','付','契','瓜','悼','颡','壁','曾','窕','颢','澎','仿','俑','浑','嵌','浣','乍','碌','褪','乱','蔟','隙','玩','剐','葫','箫','纲','围','伐','决','伙','漩','瑟','刑','肓','镳','缓','蹭','氨','皓','典','畲','坍','铑','檐','塑','洞','倬','储','胴','淳','戾','吐','灼','惺','妙','毕','珐','缈','虱','盖','羰','鸿','磅','谓','髅','娴','苴','唷','蚣','霹','抨','贤','唠','犬','誓','逍','庠','逼','麓','籼','釉','呜','碧','秧','氩','摔','霄','穸','纨','辟','妈','映','完','牛','缴','嗷','炊','恩','荔','茆','掉','紊','慌','莓','羟','阙','萁','磐','另','蕹','辱','鳐','湮','吡','吩','唐','睦','垠','舒','圜','冗','瞿','溺','芾','囱','匠','僳','汐','菩','饬','漓','黑','霰','浸','濡','窥','毂','蒡','兢','驻','鹉','芮','诙','迫','雳','厂','忐','臆','猴','鸣','蚪','栈','箕','羡','渐','莆','捍','眈','哓','趴','蹼','埕','嚣','骛','宏','淄','斑','噜','严','瑛','垃','椎','诱','压','庾','绞','焘','廿','抡','迄','棘','夫','纬','锹','眨','瞌','侠','脐','竞','瀑','孳','骧','遁','姜','颦','荪','滚','萦','伪','逸','粳','爬','锁','矣','役','趣','洒','颔','诏','逐','奸','甭','惠','攀','蹄','泛','尼','拼','阮','鹰','亚','颈','惑','勒','〉','际','肛','爷','刚','钨','丰','养','冶','鲽','辉','蔻','画','覆','皴','妊','麦','返','醉','皂','擀','〗','酶','凑','粹','悟','诀','硖','港','卜','z','杀','涕','±','舍','铠','抵','弛','段','敝','镐','奠','拂','轴','跛','袱','e','t','沉','菇','俎','薪','峦','秭','蟹','历','盟','菠','寡','液','肢','喻','染','裱','悱','抱','氙','赤','捅','猛','跑','氮','谣','仁','尺','辊','窍','烙','衍','架','擦','倏','璐','瑁','币','楞','胖','夔','趸','邛','惴','饕','虔','蝎','§','哉','贝','宽','辫','炮','扩','饲','籽','魏','菟','锰','伍','猝','末','琳','哚','蛎','邂','呀','姿','鄞','却','歧','仙','恸','椐','森','牒','寤','袒','婆','虢','雅','钉','朵','贼','欲','苞','寰','故','龚','坭','嘘','咫','礼','硷','兀','睢','汶','’','铲','烧','绕','诃','浃','钿','哺','柜','讼','颊','璁','腔','洽','咐','脲','簌','筠','镣','玮','鞠','谁','兼','姆','挥','梯','蝴','谘','漕','刷','躏','宦','弼','b','垌','劈','麟','莉','揭','笙','渎','仕','嗤','仓','配','怏','抬','错','泯','镊','孰','猿','邪','仍','秋','鼬','壹','歇','吵','炼','<','尧','射','柬','廷','胧','霾','凳','隋','肚','浮','梦','祥','株','堵','退','L','鹫','跎','凶','毽','荟','炫','栩','玳','甜','沂','鹿','顽','伯','爹','赔','蛴','徐','匡','欣','狰','缸','雹','蟆','疤','默','沤','啜','痂','衣','禅','w','i','h','辽','葳','黝','钗','停','沽','棒','馨','颌','肉','吴','硫','悯','劾','娈','马','啧','吊','悌','镑','峭','帆','瀣','涉','咸','疸','滋','泣','翦','拙','癸','钥','蜒','+','尾','庄','凝','泉','婢','渴','谊','乞','陆','锉','糊','鸦','淮','I','B','N','晦','弗','乔','庥','葡','尻','席','橡','傣','渣','拿','惩','麋','斛','缃','矮','蛏','岘','鸽','姐','膏','催','奔','镒','喱','蠡','摧','钯','胤','柠','拐','璋','鸥','卢','荡','倾','^','_','珀','逄','萧','塾','掇','贮','笆','聂','圃','冲','嵬','M','滔','笕','值','炙','偶','蜱','搐','梆','汪','蔬','腑','鸯','蹇','敞','绯','仨','祯','谆','梧','糗','鑫','啸','豺','囹','猾','巢','柄','瀛','筑','踌','沭','暗','苁','鱿','蹉','脂','蘖','牢','热','木','吸','溃','宠','序','泞','偿','拜','檩','厚','朐','毗','螳','吞','媚','朽','担','蝗','橘','畴','祈','糟','盱','隼','郜','惜','珠','裨','铵','焙','琚','唯','咚','噪','骊','丫','滢','勤','棉','呸','咣','淀','隔','蕾','窈','饨','挨','煅','短','匙','粕','镜','赣','撕','墩','酬','馁','豌','颐','抗','酣','氓','佑','搁','哭','递','耷','涡','桃','贻','碣','截','瘦','昭','镌','蔓','氚','甲','猕','蕴','蓬','散','拾','纛','狼','猷','铎','埋','旖','矾','讳','囊','糜','迈','粟','蚂','紧','鲳','瘢','栽','稼','羊','锄','斟','睁','桥','瓮','蹙','祉','醺','鼻','昱','剃','跳','篱','跷','蒜','翎','宅','晖','嗑','壑','峻','癫','屏','狠','陋','袜','途','憎','祀','莹','滟','佶','溥','臣','约','盛','峰','磁','慵','婪','拦','莅','朕','鹦','粲','裤','哎','疡','嫖','琵','窟','堪','谛','嘉','儡','鳝','斩','郾','驸','酊','妄','胜','贺','徙','傅','噌','钢','栅','庇','恋','匝','巯','邈','尸','锚','粗','佟','蛟','薹','纵','蚊','郅','绢','锐','苗','俞','篆','淆','膀','鲜','煎','诶','秽','寻','涮','刺','怀','噶','巨','褰','魅','灶','灌','桉','藕','谜','舸','薄','搀','恽','借','牯','痉','渥','愿','亓','耘','杠','柩','锔','蚶','钣','珈','喘','蹒','幽','赐','稗','晤','莱','泔','扯','肯','菪','裆','腩','豉','疆','骜','腐','倭','珏','唔','粮','亡','润','慰','伽','橄','玄','誉','醐','胆','龊','粼','塬','陇','彼','削','嗣','绾','芽','妗','垭','瘴','爽','薏','寨','龈','泠','弹','赢','漪','猫','嘧','涂','恤','圭','茧','烽','屑','痕','巾','赖','荸','凰','腮','畈','亵','蹲','偃','苇','澜','艮','换','骺','烘','苕','梓','颉','肇','哗','悄','氤','涠','葬','屠','鹭','植','竺','佯','诣','鲇','瘀','鲅','邦','移','滁','冯','耕','癔','戌','茬','沁','巩','悠','湘','洪','痹','锟','循','谋','腕','鳃','钠','捞','焉','迎','碱','伫','急','榷','奈','邝','卯','辄','皲','卟','醛','畹','忧','稳','雄','昼','缩','阈','睑','扌','耗','曦','涅','捏','瞧','邕','淖','漉','铝','耦','禹','湛','喽','莼','琅','诸','苎','纂','硅','始','嗨','傥','燃','臂','赅','嘈','呆','贵','屹','壮','肋','亍','蚀','卅','豹','腆','邬','迭','浊','}','童','螂','捐','圩','勐','触','寞','汊','壤','荫','膺','渌','芳','懿','遴','螈','泰','蓼','蛤','茜','舅','枫','朔','膝','眙','避','梅','判','鹜','璜','牍','缅','垫','藻','黔','侥','惚','懂','踩','腰','腈','札','丞','唾','慈','顿','摹','荻','琬','~','斧','沈','滂','胁','胀','幄','莜','Z','匀','鄄','掌','绰','茎','焚','赋','萱','谑','汁','铒','瞎','夺','蜗','野','娆','冀','弯','篁','懵','灞','隽','芡','脘','俐','辩','芯','掺','喏','膈','蝈','觐','悚','踹','蔗','熠','鼠','呵','抓','橼','峨','畜','缔','禾','崭','弃','熊','摒','凸','拗','穹','蒙','抒','祛','劝','闫','扳','阵','醌','踪','喵','侣','搬','仅','荧','赎','蝾','琦','买','婧','瞄','寓','皎','冻','赝','箩','莫','瞰','郊','笫','姝','筒','枪','遣','煸','袋','舆','痱','涛','母','〇','启','践','耙','绲','盘','遂','昊','搞','槿','诬','纰','泓','惨','檬','亻','越','C','o','憩','熵','祷','钒','暧','塔','阗','胰','咄','娶','魔','琶','钞','邻','扬','杉','殴','咽','弓','〆','髻','】','吭','揽','霆','拄','殖','脆','彻','岩','芝','勃','辣','剌','钝','嘎','甄','佘','皖','伦','授','徕','憔','挪','皇','庞','稔','芜','踏','溴','兖','卒','擢','饥','鳞','煲','‰','账','颗','叻','斯','捧','鳍','琮','讹','蛙','纽','谭','酸','兔','莒','睇','伟','觑','羲','嗜','宜','褐','旎','辛','卦','诘','筋','鎏','溪','挛','熔','阜','晰','鳅','丢','奚','灸','呱','献','陉','黛','鸪','甾','萨','疮','拯','洲','疹','辑','叙','恻','谒','允','柔','烂','氏','逅','漆','拎','惋','扈','湟','纭','啕','掬','擞','哥','忽','涤','鸵','靡','郗','瓷','扁','廊','怨','雏','钮','敦','E','懦','憋','汀','拚','啉','腌','岸','f','痼','瞅','尊','咀','眩','飙','忌','仝','迦','熬','毫','胯','篑','茄','腺','凄','舛','碴','锵','诧','羯','後','漏','汤','宓','仞','蚁','壶','谰','皑','铄','棰','罔','辅','晶','苦','牟','闽','\\','烃','饮','聿','丙','蛳','朱','煤','涔','鳖','犁','罐','荼','砒','淦','妤','黏','戎','孑','婕','瑾','戢','钵','枣','捋','砥','衩','狙','桠','稣','阎','肃','梏','诫','孪','昶','婊','衫','嗔','侃','塞','蜃','樵','峒','貌','屿','欺','缫','阐','栖','诟','珞','荭','吝','萍','嗽','恂','啻','蜴','磬','峋','俸','豫','谎','徊','镍','韬','魇','晴','U','囟','猜','蛮','坐','囿','伴','亭','肝','佗','蝠','妃','胞','滩','榴','氖','垩','苋','砣','扪','馏','姓','轩','厉','夥','侈','禀','垒','岑','赏','钛','辐','痔','披','纸','碳','“','坞','蠓','挤','荥','沅','悔','铧','帼','蒌','蝇','a','p','y','n','g','哀','浆','瑶','凿','桶','馈','皮','奴','苜','佤','伶','晗','铱','炬','优','弊','氢','恃','甫','攥','端','锌','灰','稹','炝','曙','邋','亥','眶','碾','拉','萝','绔','捷','浍','腋','姑','菖','凌','涞','麽','锢','桨','潢','绎','镰','殆','锑','渝','铬','困','绽','觎','匈','糙','暑','裹','鸟','盔','肽','迷','綦','『','亳','佝','俘','钴','觇','骥','仆','疝','跪','婶','郯','瀹','唉','脖','踞','针','晾','忒','扼','瞩','叛','椒','疟','嗡','邗','肆','跆','玫','忡','捣','咧','唆','艄','蘑','潦','笛','阚','沸','泻','掊','菽','贫','斥','髂','孢','镂','赂','麝','鸾','屡','衬','苷','恪','叠','希','粤','爻','喝','茫','惬','郸','绻','庸','撅','碟','宄','妹','膛','叮','饵','崛','嗲','椅','冤','搅','咕','敛','尹','垦','闷','蝉','霎','勰','败','蓑','泸','肤','鹌','幌','焦','浠','鞍','刁','舰','乙','竿','裔','。','茵','函','伊','兄','丨','娜','匍','謇','莪','宥','似','蝽','翳','酪','翠','粑','薇','祢','骏','赠','叫','Q','噤','噻','竖','芗','莠','潭','俊','羿','耜','O','郫','趁','嗪','囚','蹶','芒','洁','笋','鹑','敲','硝','啶','堡','渲','揩','』','携','宿','遒','颍','扭','棱','割','萜','蔸','葵','琴','捂','饰','衙','耿','掠','募','岂','窖','涟','蔺','瘤','柞','瞪','怜','匹','距','楔','炜','哆','秦','缎','幼','茁','绪','痨','恨','楸','娅','瓦','桩','雪','嬴','伏','榔','妥','铿','拌','眠','雍','缇','‘','卓','搓','哌','觞','噩','屈','哧','髓','咦','巅','娑','侑','淫','膳','祝','勾','姊','莴','胄','疃','薛','蜷','胛','巷','芙','芋','熙','闰','勿','窃','狱','剩','钏','幢','陟','铛','慧','靴','耍','k','浙','浇','飨','惟','绗','祜','澈','啼','咪','磷','摞','诅','郦','抹','跃','壬','吕','肖','琏','颤','尴','剡','抠','凋','赚','泊','津','宕','殷','倔','氲','漫','邺','涎','怠','$','垮','荬','遵','俏','叹','噢','饽','蜘','孙','筵','疼','鞭','羧','牦','箭','潴','c','眸','祭','髯','啖','坳','愁','芩','驮','倡','巽','穰','沃','胚','怒','凤','槛','剂','趵','嫁','v','邢','灯','鄢','桐','睽','檗','锯','槟','婷','嵋','圻','诗','蕈','颠','遭','痢','芸','怯','馥','竭','锗','徜','恭','遍','籁','剑','嘱','苡','龄','僧','桑','潸','弘','澶','楹','悲','讫','愤','腥','悸','谍','椹','呢','桓','葭','攫','阀','翰','躲','敖','柑','郎','笨','橇','呃','魁','燎','脓','葩','磋','垛','玺','狮','沓','砜','蕊','锺','罹','蕉','翱','虐','闾','巫','旦','茱','嬷','枯','鹏','贡','芹','汛','矫','绁','拣','禺','佃','讣','舫','惯','乳','趋','疲','挽','岚','虾','衾','蠹','蹂','飓','氦','铖','孩','稞','瑜','壅','掀','勘','妓','畅','髋','W','庐','牲','蓿','榕','练','垣','唱','邸','菲','昆','婺','穿','绡','麒','蚱','掂','愚','泷','涪','漳','妩','娉','榄','讷','觅','旧','藤','煮','呛','柳','腓','叭','庵','烷','阡','罂','蜕','擂','猖','咿','媲','脉','【','沏','貅','黠','熏','哲','烁','坦','酵','兜','×','潇','撒','剽','珩','圹','乾','摸','樟','帽','嗒','襄','魂','轿','憬','锡','〕','喃','皆','咖','隅','脸','残','泮','袂','鹂','珊','囤','捆','咤','误','徨','闹','淙','芊','淋','怆','囗','拨','梳','渤','R','G','绨','蚓','婀','幡','狩','麾','谢','唢','裸','旌','伉','纶','裂','驳','砼','咛','澄','樨','蹈','宙','澍','倍','貔','操','勇','蟠','摈','砧','虬','够','缁','悦','藿','撸','艹','摁','淹','豇','虎','榭','ˉ','吱','d','°','喧','荀','踱','侮','奋','偕','饷','犍','惮','坑','璎','徘','宛','妆','袈','倩','窦','昂','荏','乖','K','怅','撰','鳙','牙','袁','酞','X','痿','琼','闸','雁','趾','荚','虻','涝','《','杏','韭','偈','烤','绫','鞘','卉','症','遢','蓥','诋','杭','荨','匆','竣','簪','辙','敕','虞','丹','缭','咩','黟','m','淤','瑕','咂','铉','硼','茨','嶂','痒','畸','敬','涿','粪','窘','熟','叔','嫔','盾','忱','裘','憾','梵','赡','珙','咯','娘','庙','溯','胺','葱','痪','摊','荷','卞','乒','髦','寐','铭','坩','胗','枷','爆','溟','嚼','羚','砬','轨','惊','挠','罄','竽','菏','氧','浅','楣','盼','枢','炸','阆','杯','谏','噬','淇','渺','俪','秆','墓','泪','跻','砌','痰','垡','渡','耽','釜','讶','鳎','煞','呗','韶','舶','绷','鹳','缜','旷','铊','皱','龌','檀','霖','奄','槐','艳','蝶','旋','哝','赶','骞','蚧','腊','盈','丁','`','蜚','矸','蝙','睨','嚓','僻','鬼','醴','夜','彝','磊','笔','拔','栀','糕','厦','邰','纫','逭','纤','眦','膊','馍','躇','烯','蘼','冬','诤','暄','骶','哑','瘠','」','臊','丕','愈','咱','螺','擅','跋','搏','硪','谄','笠','淡','嘿','骅','谧','鼎','皋','姚','歼','蠢','驼','耳','胬','挝','涯','狗','蒽','孓','犷','凉','芦','箴','铤','孤','嘛','坤','V','茴','朦','挞','尖','橙','诞','搴','碇','洵','浚','帚','蜍','漯','柘','嚎','讽','芭','荤','咻','祠','秉','跖','埃','吓','糯','眷','馒','惹','娼','鲑','嫩','讴','轮','瞥','靶','褚','乏','缤','宋','帧','删','驱','碎','扑','俩','俄','偏','涣','竹','噱','皙','佰','渚','唧','斡','#','镉','刀','崎','筐','佣','夭','贰','肴','峙','哔','艿','匐','牺','镛','缘','仡','嫡','劣','枸','堀','梨','簿','鸭','蒸','亦','稽','浴','{','衢','束','槲','j','阁','揍','疥','棋','潋','聪','窜','乓','睛','插','冉','阪','苍','搽','「','蟾','螟','幸','仇','樽','撂','慢','跤','幔','俚','淅','覃','觊','溶','妖','帛','侨','曰','妾','泗','·',':','瀘','風','Ë','(',')','∶','紅','紗','瑭','雲','頭','鶏','財','許','•','¥','樂','焗','麗','—',';','滙','東','榮','繪','興','…','門','業','π','楊','國','顧','é','盤','寳','Λ','龍','鳳','島','誌','緣','結','銭','萬','勝','祎','璟','優','歡','臨','時','購','=','★','藍','昇','鐵','觀','勅','農','聲','畫','兿','術','發','劉','記','專','耑','園','書','壴','種','Ο','●','褀','號','銀','匯','敟','锘','葉','橪','廣','進','蒄','鑽','阝','祙','貢','鍋','豊','夬','喆','團','閣','開','燁','賓','館','酡','沔','順','+','硚','劵','饸','陽','車','湓','復','萊','氣','軒','華','堃','迮','纟','戶','馬','學','裡','電','嶽','獨','マ','シ','サ','ジ','燘','袪','環','❤','臺','灣','専','賣','孖','聖','攝','線','▪','α','傢','俬','夢','達','莊','喬','貝','薩','劍','羅','壓','棛','饦','尃','璈','囍','醫','G','I','A','#','N','鷄','髙','嬰','啓','約','隹','潔','賴','藝','~','寶','籣','麺',' ','嶺','√','義','網','峩','長','∧','魚','機','構','②','鳯','偉','L','B','㙟','畵','鴿',''','詩','溝','嚞','屌','藔','佧','玥','蘭','織','1','3','9','0','7','點','砭','鴨','鋪','銘','廳','弍','‧','創','湯','坶','℃','卩','骝','&','烜','荘','當','潤','扞','係','懷','碶','钅','蚨','讠','☆','叢','爲','埗','涫','塗','→','楽','現','鯨','愛','瑪','鈺','忄','悶','藥','飾','樓','視','孬','ㆍ','燚','苪','師','①','丼','锽','│','韓','標','è','兒','閏','匋','張','漢','Ü','髪','會','閑','檔','習','裝','の','峯','菘','輝','И','雞','釣','億','浐','K','O','R','8','H','E','P','T','W','D','S','C','M','F','姌','饹','»','晞','廰','ä','嵯','鷹','負','飲','絲','冚','楗','澤','綫','區','❋','←','質','靑','揚','③','滬','統','産','協','﹑','乸','畐','經','運','際','洺','岽','為','粵','諾','崋','豐','碁','ɔ','V','2','6','齋','誠','訂','´','勑','雙','陳','無','í','泩','媄','夌','刂','i','c','t','o','r','a','嘢','耄','燴','暃','壽','媽','靈','抻','體','唻','É','冮','甹','鎮','錦','ʌ','蜛','蠄','尓','駕','戀','飬','逹','倫','貴','極','Я','Й','寬','磚','嶪','郎','職','|','間','n','d','剎','伈','課','飛','橋','瘊','№','譜','骓','圗','滘','縣','粿','咅','養','濤','彳','®','%','Ⅱ','啰','㴪','見','矞','薬','糁','邨','鲮','顔','罱','З','選','話','贏','氪','俵','競','瑩','繡','枱','β','綉','á','獅','爾','™','麵','戋','淩','徳','個','劇','場','務','簡','寵','h','實','膠','轱','圖','築','嘣','樹','㸃','營','耵','孫','饃','鄺','飯','麯','遠','輸','坫','孃','乚','閃','鏢','㎡','題','廠','關','↑','爺','將','軍','連','篦','覌','參','箸','-','窠','棽','寕','夀','爰','歐','呙','閥','頡','熱','雎','垟','裟','凬','勁','帑','馕','夆','疌','枼','馮','貨','蒤','樸','彧','旸','靜','龢','暢','㐱','鳥','珺','鏡','灡','爭','堷','廚','Ó','騰','診','┅','蘇','褔','凱','頂','豕','亞','帥','嘬','⊥','仺','桖','複','饣','絡','穂','顏','棟','納','▏','濟','親','設','計','攵','埌','烺','ò','頤','燦','蓮','撻','節','講','濱','濃','娽','洳','朿','燈','鈴','護','膚','铔','過','補','Z','U','5','4','坋','闿','䖝','餘','缐','铞','貿','铪','桼','趙','鍊','[','㐂','垚','菓','揸','捲','鐘','滏','𣇉','爍','輪','燜','鴻','鮮','動','鹞','鷗','丄','慶','鉌','翥','飮','腸','⇋','漁','覺','來','熘','昴','翏','鲱','圧','鄉','萭','頔','爐','嫚','г','貭','類','聯','幛','輕','訓','鑒','夋','锨','芃','珣','䝉','扙','嵐','銷','處','ㄱ','語','誘','苝','歸','儀','燒','楿','內','粢','葒','奧','麥','礻','滿','蠔','穵','瞭','態','鱬','榞','硂','鄭','黃','煙','祐','奓','逺','*','瑄','獲','聞','薦','讀','這','樣','決','問','啟','們','執','説','轉','單','隨','唘','帶','倉','庫','還','贈','尙','皺','■','餅','產','○','∈','報','狀','楓','賠','琯','嗮','禮','`','傳','>','≤','嗞','Φ','≥','換','咭','∣','↓','曬','ε','応','寫','″','終','様','純','費','療','聨','凍','壐','郵','ü','黒','∫','製','塊','調','軽','確','撃','級','馴','Ⅲ','涇','繹','數','碼','證','狒','処','劑','<','晧','賀','衆',']','櫥','兩','陰','絶','對','鯉','憶','◎','p','e','Y','蕒','煖','頓','測','試','鼽','僑','碩','妝','帯','≈','鐡','舖','權','喫','倆','ˋ','該','悅','ā','俫','.','f','s','b','m','k','g','u','j','貼','淨','濕','針','適','備','l','/','給','謢','強','觸','衛','與','⊙','$','緯','變','⑴','⑵','⑶','㎏','殺','∩','幚','─','價','▲','離','ú','ó','飄','烏','関','閟','﹝','﹞','邏','輯','鍵','驗','訣','導','歷','屆','層','▼','儱','錄','熳','ē','艦','吋','錶','辧','飼','顯','④','禦','販','気','対','枰','閩','紀','幹','瞓','貊','淚','△','眞','墊','Ω','獻','褲','縫','緑','亜','鉅','餠','{','}','◆','蘆','薈','█','◇','溫','彈','晳','粧','犸','穩','訊','崬','凖','熥','П','舊','條','紋','圍','Ⅳ','筆','尷','難','雜','錯','綁','識','頰','鎖','艶','□','殁','殼','⑧','├','▕','鵬','ǐ','ō','ǒ','糝','綱','▎','μ','盜','饅','醬','籤','蓋','釀','鹽','據','à','ɡ','辦','◥','彐','┌','婦','獸','鲩','伱','ī','蒟','蒻','齊','袆','腦','寧','凈','妳','煥','詢','偽','謹','啫','鯽','騷','鱸','損','傷','鎻','髮','買','冏','儥','両','﹢','∞','載','喰','z','羙','悵','燙','曉','員','組','徹','艷','痠','鋼','鼙','縮','細','嚒','爯','≠','維','"','鱻','壇','厍','帰','浥','犇','薡','軎','²','應','醜','刪','緻','鶴','賜','噁','軌','尨','镔','鷺','槗','彌','葚','濛','請','溇','緹','賢','訪','獴','瑅','資','縤','陣','蕟','栢','韻','祼','恁','伢','謝','劃','涑','總','衖','踺','砋','凉','籃','駿','苼','瘋','昽','紡','驊','腎','﹗','響','杋','剛','嚴','禪','歓','槍','傘','檸','檫','炣','勢','鏜','鎢','銑','尐','減','奪','惡','θ','僮','婭','臘','ū','ì','殻','鉄','∑','蛲','焼','緖','續','紹','懮']
\ No newline at end of file
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/recPostprocess.js b/packages/paddlejs-examples/ocrXcx/pages/index/recPostprocess.js
new file mode 100644
index 00000000..05e52525
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/recPostprocess.js
@@ -0,0 +1,63 @@
+import { character } from 'ppocr_keys_v1.js';
+
+const ocr_character = character;
+let preds_idx = [];
+let preds_prob = [];
+
+function init(preds) {
+ preds_idx = [];
+ preds_prob = [];
+ // preds: [1, ?, 6625]
+ const pred_len = 6625;
+ for (let i = 0; i < preds.length; i += pred_len) {
+ const tmpArr = preds.slice(i, i + pred_len - 1);
+ const tmpMax = Math.max(...tmpArr);
+ const tmpIdx = tmpArr.indexOf(tmpMax);
+ preds_prob.push(tmpMax);
+ preds_idx.push(tmpIdx);
+ }
+}
+
+function get_ignored_tokens() {
+ return [0];
+}
+
+function decode(text_index, text_prob, is_remove_duplicate = false) {
+ const ignored_tokens = get_ignored_tokens();
+ const char_list = [];
+ const conf_list = [];
+ for (let idx = 0; idx < text_index.length; idx++) {
+ if (text_index[idx] in ignored_tokens) {
+ continue;
+ }
+ if (is_remove_duplicate) {
+ if (idx > 0 && text_index[idx - 1] === text_index[idx]) {
+ continue;
+ }
+ }
+ char_list.push(ocr_character[text_index[idx] - 1]);
+ if (text_prob) {
+ conf_list.push(text_prob[idx]);
+ }
+ else {
+ conf_list.push(1);
+ }
+ }
+ let text = '';
+ let mean = 0;
+
+ if (char_list.length) {
+ text = char_list.join('');
+ let sum = 0;
+ conf_list.forEach(item => {
+ sum += item;
+ });
+ mean = sum / conf_list.length;
+ }
+ return { text, mean };
+}
+
+export function recDecode(preds) {
+ init(preds);
+ return decode(preds_idx, preds_prob, true);
+}
\ No newline at end of file
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv.js b/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv.js
new file mode 100644
index 00000000..d939a10c
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv.js
@@ -0,0 +1,7109 @@
+/* eslint-disable */
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(function () {
+ return (root.cv = factory());
+ });
+ } else if (typeof module === 'object' && module.exports) {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like environments that support module.exports,
+ // like Node.
+ module.exports = factory();
+ } else {
+ // Browser globals
+ root.cv = factory();
+ }
+}(this, function () {
+ var IsWechat = true;
+ var cv = (function () {
+ var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
+ if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
+ return (
+ function (cv) {
+ cv = cv || {};
+ // IsWechat
+ var wasmBinaryFile = global.wasm_url;
+
+ var Module = typeof cv !== "undefined" ? cv : {};
+ console.log('Module', Module)
+ var moduleOverrides = {};
+ var key;
+ for (key in Module) {
+ if (Module.hasOwnProperty(key)) {
+ moduleOverrides[key] = Module[key]
+ }
+ }
+ var arguments_ = [];
+ var thisProgram = "./this.program";
+ var quit_ = function (status, toThrow) {
+ throw toThrow
+ };
+ var ENVIRONMENT_IS_WEB = false;
+ var ENVIRONMENT_IS_WORKER = false;
+ var ENVIRONMENT_IS_NODE = false;
+ var ENVIRONMENT_IS_SHELL = false;
+ ENVIRONMENT_IS_WEB = typeof window === "object";
+ ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
+ ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string";
+ ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+ var scriptDirectory = "";
+
+ function locateFile(path) {
+ if (Module["locateFile"]) {
+ return Module["locateFile"](path, scriptDirectory)
+ }
+ return scriptDirectory + path
+ }
+
+ var read_, readAsync, readBinary, setWindowTitle;
+ var nodeFS;
+ var nodePath;
+ if (ENVIRONMENT_IS_NODE) {
+ if (ENVIRONMENT_IS_WORKER) {
+ scriptDirectory = require("path").dirname(scriptDirectory) + "/"
+ } else {
+ scriptDirectory = __dirname + "/"
+ }
+ read_ = function shell_read(filename, binary) {
+ if (!nodeFS) nodeFS = require("fs");
+ if (!nodePath) nodePath = require("path");
+ filename = nodePath["normalize"](filename);
+ return nodeFS["readFileSync"](filename, binary ? null : "utf8")
+ };
+ readBinary = function readBinary(filename) {
+ var ret = read_(filename, true);
+ if (!ret.buffer) {
+ ret = new Uint8Array(ret)
+ }
+ assert(ret.buffer);
+ return ret
+ };
+ if (process["argv"].length > 1) {
+ thisProgram = process["argv"][1].replace(/\\/g, "/")
+ }
+ arguments_ = process["argv"].slice(2);
+ process["on"]("uncaughtException", function (ex) {
+ if (!(ex instanceof ExitStatus)) {
+ throw ex
+ }
+ });
+ process["on"]("unhandledRejection", abort);
+ quit_ = function (status) {
+ process["exit"](status)
+ };
+ Module["inspect"] = function () {
+ return "[Emscripten Module object]"
+ }
+ } else if (!IsWechat && ENVIRONMENT_IS_SHELL) {
+ if (typeof read != "undefined") {
+ read_ = function shell_read(f) {
+ return read(f)
+ }
+ }
+ readBinary = function readBinary(f) {
+ var data;
+ if (typeof readbuffer === "function") {
+ return new Uint8Array(readbuffer(f))
+ }
+ data = read(f, "binary");
+ assert(typeof data === "object");
+ return data
+ };
+ if (typeof scriptArgs != "undefined") {
+ arguments_ = scriptArgs
+ } else if (typeof arguments != "undefined") {
+ arguments_ = arguments
+ }
+ if (typeof quit === "function") {
+ quit_ = function (status) {
+ quit(status)
+ }
+ }
+ if (typeof print !== "undefined") {
+ if (typeof console === "undefined") console = {};
+ console.log = print;
+ console.warn = console.error = typeof printErr !== "undefined" ? printErr : print
+ }
+ } else if (IsWechat || ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+ if (ENVIRONMENT_IS_WORKER) {
+ scriptDirectory = self.location.href
+ } else if (!IsWechat && document.currentScript) {
+ scriptDirectory = document.currentScript.src
+ }
+ if (_scriptDir) {
+ scriptDirectory = _scriptDir
+ }
+ if (scriptDirectory.indexOf("blob:") !== 0) {
+ scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1)
+ } else {
+ scriptDirectory = ""
+ }
+ {
+ read_ = function shell_read(url) {
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", url, false);
+ xhr.send(null);
+ return xhr.responseText
+ };
+ if (ENVIRONMENT_IS_WORKER) {
+ readBinary = function readBinary(url) {
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", url, false);
+ xhr.responseType = "arraybuffer";
+ xhr.send(null);
+ return new Uint8Array(xhr.response)
+ }
+ }
+ readAsync = function readAsync(url, onload, onerror) {
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", url, true);
+ xhr.responseType = "arraybuffer";
+ xhr.onload = function xhr_onload() {
+ if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
+ onload(xhr.response);
+ return
+ }
+ onerror()
+ };
+ xhr.onerror = onerror;
+ xhr.send(null)
+ }
+ }
+ setWindowTitle = function (title) {
+ document.title = title
+ }
+ } else {
+ }
+ var out = Module["print"] || console.log.bind(console);
+ var err = Module["printErr"] || console.warn.bind(console);
+ for (key in moduleOverrides) {
+ if (moduleOverrides.hasOwnProperty(key)) {
+ Module[key] = moduleOverrides[key]
+ }
+ }
+ moduleOverrides = null;
+ if (Module["arguments"]) arguments_ = Module["arguments"];
+ if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
+ if (Module["quit"]) quit_ = Module["quit"];
+ var STACK_ALIGN = 16;
+
+ function dynamicAlloc(size) {
+ var ret = HEAP32[DYNAMICTOP_PTR >> 2];
+ var end = ret + size + 15 & -16;
+ HEAP32[DYNAMICTOP_PTR >> 2] = end;
+ return ret
+ }
+
+ function alignMemory(size, factor) {
+ if (!factor) factor = STACK_ALIGN;
+ return Math.ceil(size / factor) * factor
+ }
+
+ function getNativeTypeSize(type) {
+ switch (type) {
+ case"i1":
+ case"i8":
+ return 1;
+ case"i16":
+ return 2;
+ case"i32":
+ return 4;
+ case"i64":
+ return 8;
+ case"float":
+ return 4;
+ case"double":
+ return 8;
+ default: {
+ if (type[type.length - 1] === "*") {
+ return 4
+ } else if (type[0] === "i") {
+ var bits = Number(type.substr(1));
+ assert(bits % 8 === 0, "getNativeTypeSize invalid bits " + bits + ", type " + type);
+ return bits / 8
+ } else {
+ return 0
+ }
+ }
+ }
+ }
+
+ function warnOnce(text) {
+ if (!warnOnce.shown) warnOnce.shown = {};
+ if (!warnOnce.shown[text]) {
+ warnOnce.shown[text] = 1;
+ err(text)
+ }
+ }
+
+ function convertJsFunctionToWasm(func, sig) {
+ // if (typeof WebAssembly.Function === "function") {
+ // var typeNames = {"i": "i32", "j": "i64", "f": "f32", "d": "f64"};
+ // var type = {parameters: [], results: sig[0] == "v" ? [] : [typeNames[sig[0]]]};
+ // for (var i = 1; i < sig.length; ++i) {
+ // type.parameters.push(typeNames[sig[i]])
+ // }
+ // return new WebAssembly.Function(type, func)
+ // }
+ var typeSection = [1, 0, 1, 96];
+ var sigRet = sig.slice(0, 1);
+ var sigParam = sig.slice(1);
+ var typeCodes = {"i": 127, "j": 126, "f": 125, "d": 124};
+ typeSection.push(sigParam.length);
+ for (var i = 0; i < sigParam.length; ++i) {
+ typeSection.push(typeCodes[sigParam[i]])
+ }
+ if (sigRet == "v") {
+ typeSection.push(0)
+ } else {
+ typeSection = typeSection.concat([1, typeCodes[sigRet]])
+ }
+ typeSection[1] = typeSection.length - 2;
+ var bytes = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0].concat(typeSection, [2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0]));
+ var module = new WXWebAssembly.Module(bytes);
+ var instance = new WXWebAssembly.Instance(module, {"e": {"f": func}});
+ var wrappedFunc = instance.exports["f"];
+ return wrappedFunc
+ }
+
+ var freeTableIndexes = [];
+ var functionsInTableMap;
+
+ function addFunctionWasm(func, sig) {
+ var table = wasmTable;
+ if (!functionsInTableMap) {
+ functionsInTableMap = new WeakMap;
+ for (var i = 0; i < table.length; i++) {
+ var item = table.get(i);
+ if (item) {
+ functionsInTableMap.set(item, i)
+ }
+ }
+ }
+ if (functionsInTableMap.has(func)) {
+ return functionsInTableMap.get(func)
+ }
+ var ret;
+ if (freeTableIndexes.length) {
+ ret = freeTableIndexes.pop()
+ } else {
+ ret = table.length;
+ try {
+ table.grow(1)
+ } catch (err) {
+ if (!(err instanceof RangeError)) {
+ throw err
+ }
+ throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."
+ }
+ }
+ try {
+ table.set(ret, func)
+ } catch (err) {
+ if (!(err instanceof TypeError)) {
+ throw err
+ }
+ var wrapped = convertJsFunctionToWasm(func, sig);
+ table.set(ret, wrapped)
+ }
+ functionsInTableMap.set(func, ret);
+ return ret
+ }
+
+ function removeFunctionWasm(index) {
+ functionsInTableMap.delete(wasmTable.get(index));
+ freeTableIndexes.push(index)
+ }
+
+ var funcWrappers = {};
+
+ function dynCall(sig, ptr, args) {
+ if (args && args.length) {
+ return Module["dynCall_" + sig].apply(null, [ptr].concat(args))
+ } else {
+ return Module["dynCall_" + sig].call(null, ptr)
+ }
+ }
+
+ var tempRet0 = 0;
+ var setTempRet0 = function (value) {
+ tempRet0 = value
+ };
+ var wasmBinary;
+ if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
+ var noExitRuntime;
+ if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
+ if (typeof WXWebAssembly !== "object") {
+ abort("no native wasm support detected")
+ }
+
+ function setValue(ptr, value, type, noSafe) {
+ type = type || "i8";
+ if (type.charAt(type.length - 1) === "*") type = "i32";
+ switch (type) {
+ case"i1":
+ HEAP8[ptr >> 0] = value;
+ break;
+ case"i8":
+ HEAP8[ptr >> 0] = value;
+ break;
+ case"i16":
+ HEAP16[ptr >> 1] = value;
+ break;
+ case"i32":
+ HEAP32[ptr >> 2] = value;
+ break;
+ case"i64":
+ tempI64 = [value >>> 0, (tempDouble = value, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];
+ break;
+ case"float":
+ HEAPF32[ptr >> 2] = value;
+ break;
+ case"double":
+ HEAPF64[ptr >> 3] = value;
+ break;
+ default:
+ abort("invalid type for setValue: " + type)
+ }
+ }
+
+ var wasmMemory;
+ var wasmTable = new WXWebAssembly.Table({"initial": 1538, "maximum": 1538 + 0, "element": "anyfunc"});
+ var ABORT = false;
+ var EXITSTATUS = 0;
+
+ function assert(condition, text) {
+ if (!condition) {
+ abort("Assertion failed: " + text)
+ }
+ }
+
+ function getCFunc(ident) {
+ var func = Module["_" + ident];
+ assert(func, "Cannot call unknown function " + ident + ", make sure it is exported");
+ return func
+ }
+
+ function ccall(ident, returnType, argTypes, args, opts) {
+ var toC = {
+ "string": function (str) {
+ var ret = 0;
+ if (str !== null && str !== undefined && str !== 0) {
+ var len = (str.length << 2) + 1;
+ ret = stackAlloc(len);
+ stringToUTF8(str, ret, len)
+ }
+ return ret
+ }, "array": function (arr) {
+ var ret = stackAlloc(arr.length);
+ writeArrayToMemory(arr, ret);
+ return ret
+ }
+ };
+
+ function convertReturnValue(ret) {
+ if (returnType === "string") return UTF8ToString(ret);
+ if (returnType === "boolean") return Boolean(ret);
+ return ret
+ }
+
+ var func = getCFunc(ident);
+ var cArgs = [];
+ var stack = 0;
+ if (args) {
+ for (var i = 0; i < args.length; i++) {
+ var converter = toC[argTypes[i]];
+ if (converter) {
+ if (stack === 0) stack = stackSave();
+ cArgs[i] = converter(args[i])
+ } else {
+ cArgs[i] = args[i]
+ }
+ }
+ }
+ var ret = func.apply(null, cArgs);
+ ret = convertReturnValue(ret);
+ if (stack !== 0) stackRestore(stack);
+ return ret
+ }
+
+ var ALLOC_NONE = 3;
+
+ function getMemory(size) {
+ if (!runtimeInitialized) return dynamicAlloc(size);
+ return _malloc(size)
+ }
+
+ var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined;
+
+ function UTF8ArrayToString(heap, idx, maxBytesToRead) {
+ var endIdx = idx + maxBytesToRead;
+ var endPtr = idx;
+ while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
+ if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
+ return UTF8Decoder.decode(heap.subarray(idx, endPtr))
+ } else {
+ var str = "";
+ while (idx < endPtr) {
+ var u0 = heap[idx++];
+ if (!(u0 & 128)) {
+ str += String.fromCharCode(u0);
+ continue
+ }
+ var u1 = heap[idx++] & 63;
+ if ((u0 & 224) == 192) {
+ str += String.fromCharCode((u0 & 31) << 6 | u1);
+ continue
+ }
+ var u2 = heap[idx++] & 63;
+ if ((u0 & 240) == 224) {
+ u0 = (u0 & 15) << 12 | u1 << 6 | u2
+ } else {
+ u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63
+ }
+ if (u0 < 65536) {
+ str += String.fromCharCode(u0)
+ } else {
+ var ch = u0 - 65536;
+ str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023)
+ }
+ }
+ }
+ return str
+ }
+
+ function UTF8ToString(ptr, maxBytesToRead) {
+ return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""
+ }
+
+ function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
+ if (!(maxBytesToWrite > 0)) return 0;
+ var startIdx = outIdx;
+ var endIdx = outIdx + maxBytesToWrite - 1;
+ for (var i = 0; i < str.length; ++i) {
+ var u = str.charCodeAt(i);
+ if (u >= 55296 && u <= 57343) {
+ var u1 = str.charCodeAt(++i);
+ u = 65536 + ((u & 1023) << 10) | u1 & 1023
+ }
+ if (u <= 127) {
+ if (outIdx >= endIdx) break;
+ heap[outIdx++] = u
+ } else if (u <= 2047) {
+ if (outIdx + 1 >= endIdx) break;
+ heap[outIdx++] = 192 | u >> 6;
+ heap[outIdx++] = 128 | u & 63
+ } else if (u <= 65535) {
+ if (outIdx + 2 >= endIdx) break;
+ heap[outIdx++] = 224 | u >> 12;
+ heap[outIdx++] = 128 | u >> 6 & 63;
+ heap[outIdx++] = 128 | u & 63
+ } else {
+ if (outIdx + 3 >= endIdx) break;
+ heap[outIdx++] = 240 | u >> 18;
+ heap[outIdx++] = 128 | u >> 12 & 63;
+ heap[outIdx++] = 128 | u >> 6 & 63;
+ heap[outIdx++] = 128 | u & 63
+ }
+ }
+ heap[outIdx] = 0;
+ return outIdx - startIdx
+ }
+
+ function stringToUTF8(str, outPtr, maxBytesToWrite) {
+ return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite)
+ }
+
+ function lengthBytesUTF8(str) {
+ var len = 0;
+ for (var i = 0; i < str.length; ++i) {
+ var u = str.charCodeAt(i);
+ if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
+ if (u <= 127) ++len; else if (u <= 2047) len += 2; else if (u <= 65535) len += 3; else len += 4
+ }
+ return len
+ }
+
+ var UTF16Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : undefined;
+
+ function UTF16ToString(ptr, maxBytesToRead) {
+ var endPtr = ptr;
+ var idx = endPtr >> 1;
+ var maxIdx = idx + maxBytesToRead / 2;
+ while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
+ endPtr = idx << 1;
+ if (endPtr - ptr > 32 && UTF16Decoder) {
+ return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr))
+ } else {
+ var i = 0;
+ var str = "";
+ while (1) {
+ var codeUnit = HEAP16[ptr + i * 2 >> 1];
+ if (codeUnit == 0 || i == maxBytesToRead / 2) return str;
+ ++i;
+ str += String.fromCharCode(codeUnit)
+ }
+ }
+ }
+
+ function stringToUTF16(str, outPtr, maxBytesToWrite) {
+ if (maxBytesToWrite === undefined) {
+ maxBytesToWrite = 2147483647
+ }
+ if (maxBytesToWrite < 2) return 0;
+ maxBytesToWrite -= 2;
+ var startPtr = outPtr;
+ var numCharsToWrite = maxBytesToWrite < str.length * 2 ? maxBytesToWrite / 2 : str.length;
+ for (var i = 0; i < numCharsToWrite; ++i) {
+ var codeUnit = str.charCodeAt(i);
+ HEAP16[outPtr >> 1] = codeUnit;
+ outPtr += 2
+ }
+ HEAP16[outPtr >> 1] = 0;
+ return outPtr - startPtr
+ }
+
+ function lengthBytesUTF16(str) {
+ return str.length * 2
+ }
+
+ function UTF32ToString(ptr, maxBytesToRead) {
+ var i = 0;
+ var str = "";
+ while (!(i >= maxBytesToRead / 4)) {
+ var utf32 = HEAP32[ptr + i * 4 >> 2];
+ if (utf32 == 0) break;
+ ++i;
+ if (utf32 >= 65536) {
+ var ch = utf32 - 65536;
+ str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023)
+ } else {
+ str += String.fromCharCode(utf32)
+ }
+ }
+ return str
+ }
+
+ function stringToUTF32(str, outPtr, maxBytesToWrite) {
+ if (maxBytesToWrite === undefined) {
+ maxBytesToWrite = 2147483647
+ }
+ if (maxBytesToWrite < 4) return 0;
+ var startPtr = outPtr;
+ var endPtr = startPtr + maxBytesToWrite - 4;
+ for (var i = 0; i < str.length; ++i) {
+ var codeUnit = str.charCodeAt(i);
+ if (codeUnit >= 55296 && codeUnit <= 57343) {
+ var trailSurrogate = str.charCodeAt(++i);
+ codeUnit = 65536 + ((codeUnit & 1023) << 10) | trailSurrogate & 1023
+ }
+ HEAP32[outPtr >> 2] = codeUnit;
+ outPtr += 4;
+ if (outPtr + 4 > endPtr) break
+ }
+ HEAP32[outPtr >> 2] = 0;
+ return outPtr - startPtr
+ }
+
+ function lengthBytesUTF32(str) {
+ var len = 0;
+ for (var i = 0; i < str.length; ++i) {
+ var codeUnit = str.charCodeAt(i);
+ if (codeUnit >= 55296 && codeUnit <= 57343) ++i;
+ len += 4
+ }
+ return len
+ }
+
+ function writeArrayToMemory(array, buffer) {
+ HEAP8.set(array, buffer)
+ }
+
+ function writeAsciiToMemory(str, buffer, dontAddNull) {
+ for (var i = 0; i < str.length; ++i) {
+ HEAP8[buffer++ >> 0] = str.charCodeAt(i)
+ }
+ if (!dontAddNull) HEAP8[buffer >> 0] = 0
+ }
+
+ var WASM_PAGE_SIZE = 65536;
+
+ function alignUp(x, multiple) {
+ if (x % multiple > 0) {
+ x += multiple - x % multiple
+ }
+ return x
+ }
+
+ var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+ function updateGlobalBufferAndViews(buf) {
+ buffer = buf;
+ Module["HEAP8"] = HEAP8 = new Int8Array(buf);
+ Module["HEAP16"] = HEAP16 = new Int16Array(buf);
+ Module["HEAP32"] = HEAP32 = new Int32Array(buf);
+ Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
+ Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf);
+ Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf);
+ Module["HEAPF32"] = HEAPF32 = new Float32Array(buf);
+ Module["HEAPF64"] = HEAPF64 = new Float64Array(buf)
+ }
+
+ var STACK_BASE = 5885696, DYNAMIC_BASE = 5885696, DYNAMICTOP_PTR = 642656;
+ var INITIAL_INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 134217728;
+ if (Module["wasmMemory"]) {
+ wasmMemory = Module["wasmMemory"]
+ } else {
+ wasmMemory = new WXWebAssembly.Memory({
+ "initial": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE,
+ "maximum": 2147483648 / WASM_PAGE_SIZE
+ })
+ }
+ if (wasmMemory) {
+ buffer = wasmMemory.buffer
+ }
+ INITIAL_INITIAL_MEMORY = buffer.byteLength;
+ updateGlobalBufferAndViews(buffer);
+ HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE;
+
+ function callRuntimeCallbacks(callbacks) {
+ while (callbacks.length > 0) {
+ var callback = callbacks.shift();
+ if (typeof callback == "function") {
+ callback(Module);
+ continue
+ }
+ var func = callback.func;
+ if (typeof func === "number") {
+ if (callback.arg === undefined) {
+ Module["dynCall_v"](func)
+ } else {
+ Module["dynCall_vi"](func, callback.arg)
+ }
+ } else {
+ func(callback.arg === undefined ? null : callback.arg)
+ }
+ }
+ }
+
+ var __ATPRERUN__ = [];
+ var __ATINIT__ = [];
+ var __ATMAIN__ = [];
+ var __ATPOSTRUN__ = [];
+ var runtimeInitialized = false;
+ var runtimeExited = false;
+
+ function preRun() {
+ if (Module["preRun"]) {
+ if (typeof Module["preRun"] == "function") Module["preRun"] = [Module["preRun"]];
+ while (Module["preRun"].length) {
+ addOnPreRun(Module["preRun"].shift())
+ }
+ }
+ callRuntimeCallbacks(__ATPRERUN__)
+ }
+
+ function initRuntime() {
+ runtimeInitialized = true;
+ if (!Module["noFSInit"] && !FS.init.initialized) FS.init();
+ TTY.init();
+ callRuntimeCallbacks(__ATINIT__)
+ }
+
+ function preMain() {
+ FS.ignorePermissions = false;
+ callRuntimeCallbacks(__ATMAIN__)
+ }
+
+ function exitRuntime() {
+ runtimeExited = true
+ }
+
+ function postRun() {
+ if (Module["postRun"]) {
+ if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]];
+ while (Module["postRun"].length) {
+ addOnPostRun(Module["postRun"].shift())
+ }
+ }
+ callRuntimeCallbacks(__ATPOSTRUN__)
+ }
+
+ function addOnPreRun(cb) {
+ __ATPRERUN__.unshift(cb)
+ }
+
+ function addOnPostRun(cb) {
+ __ATPOSTRUN__.unshift(cb)
+ }
+
+ var Math_abs = Math.abs;
+ var Math_ceil = Math.ceil;
+ var Math_floor = Math.floor;
+ var Math_min = Math.min;
+ var runDependencies = 0;
+ var runDependencyWatcher = null;
+ var dependenciesFulfilled = null;
+
+ function getUniqueRunDependency(id) {
+ return id
+ }
+
+ function addRunDependency(id) {
+ runDependencies++;
+ if (Module["monitorRunDependencies"]) {
+ Module["monitorRunDependencies"](runDependencies)
+ }
+ }
+
+ function removeRunDependency(id) {
+ runDependencies--;
+ if (Module["monitorRunDependencies"]) {
+ Module["monitorRunDependencies"](runDependencies)
+ }
+ if (runDependencies == 0) {
+ if (runDependencyWatcher !== null) {
+ clearInterval(runDependencyWatcher);
+ runDependencyWatcher = null
+ }
+ if (dependenciesFulfilled) {
+ var callback = dependenciesFulfilled;
+ dependenciesFulfilled = null;
+ callback()
+ }
+ }
+ }
+
+ Module["preloadedImages"] = {};
+ Module["preloadedAudios"] = {};
+
+ function abort(what) {
+ if (Module["onAbort"]) {
+ Module["onAbort"](what)
+ }
+ what += "";
+ err(what);
+ ABORT = true;
+ EXITSTATUS = 1;
+ what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info.";
+ throw what
+ }
+
+ function hasPrefix(str, prefix) {
+ return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0
+ }
+
+ var dataURIPrefix = "data:application/octet-stream;base64,";
+
+ function isDataURI(filename) {
+ return hasPrefix(filename, dataURIPrefix)
+ }
+
+ var fileURIPrefix = "file://";
+
+ function isFileURI(filename) {
+ return hasPrefix(filename, fileURIPrefix)
+ }
+
+ // var wasmBinaryFile = "opencv_js.wasm";
+ if (!isDataURI(wasmBinaryFile)) {
+ wasmBinaryFile = locateFile(wasmBinaryFile)
+ }
+
+ function getBinary() {
+ try {
+ if (wasmBinary) {
+ return new Uint8Array(wasmBinary)
+ }
+ if (readBinary) {
+ return readBinary(wasmBinaryFile)
+ } else {
+ throw"both async and sync fetching of the wasm failed"
+ }
+ } catch (err) {
+ abort(err)
+ }
+ }
+
+ function getBinaryPromise() {
+ if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function" && !isFileURI(wasmBinaryFile)) {
+ return fetch(wasmBinaryFile, {credentials: "same-origin"}).then(function (response) {
+ if (!response["ok"]) {
+ throw"failed to load wasm binary file at '" + wasmBinaryFile + "'"
+ }
+ return response["arrayBuffer"]()
+ }).catch(function () {
+ return getBinary()
+ })
+ }
+ return new Promise(function (resolve, reject) {
+ resolve(getBinary())
+ })
+ }
+
+ function createWasm() {
+ var info = {"env": asmLibraryArg, "wasi_snapshot_preview1": asmLibraryArg};
+
+ function receiveInstance(instance, module) {
+ var exports = instance.exports;
+ Module["asm"] = exports;
+ removeRunDependency("wasm-instantiate")
+ }
+
+ addRunDependency("wasm-instantiate");
+
+ function receiveInstantiatedSource(output) {
+ receiveInstance(output["instance"])
+ }
+
+ function instantiateArrayBuffer(receiver) {
+ return getBinaryPromise().then(function (binary) {
+ return WXWebAssembly.instantiate(binary, info)
+ }).then(receiver, function (reason) {
+ err("failed to asynchronously prepare wasm: " + reason);
+ abort(reason)
+ })
+ }
+
+ function instantiateAsync() {
+ if (IsWechat) {
+ var result = WXWebAssembly.instantiate(wasmBinaryFile, info);
+
+ return result.then(receiveInstantiatedSource, function (reason) {
+ err("wasm streaming compile failed: " + reason);
+ err("falling back to ArrayBuffer instantiation");
+ return instantiateArrayBuffer(receiveInstantiatedSource)
+ });
+
+ } else {
+ if (!wasmBinary && typeof WebAssembly.instantiateStreaming === "function" && !isDataURI(wasmBinaryFile) && !isFileURI(wasmBinaryFile) && typeof fetch === "function") {
+ fetch(wasmBinaryFile, {credentials: "same-origin"}).then(function (response) {
+ var result = WebAssembly.instantiateStreaming(response, info);
+ return result.then(receiveInstantiatedSource, function (reason) {
+ err("wasm streaming compile failed: " + reason);
+ err("falling back to ArrayBuffer instantiation");
+ return instantiateArrayBuffer(receiveInstantiatedSource)
+ })
+ })
+ } else {
+ return instantiateArrayBuffer(receiveInstantiatedSource)
+ }
+ }
+ }
+
+ if (Module["instantiateWasm"]) {
+ try {
+ var exports = Module["instantiateWasm"](info, receiveInstance);
+ return exports
+ } catch (e) {
+ err("Module.instantiateWasm callback failed with error: " + e);
+ return false
+ }
+ }
+ instantiateAsync();
+ return {}
+ }
+
+ var tempDouble;
+ var tempI64;
+ __ATINIT__.push({
+ func: function () {
+ ___wasm_call_ctors()
+ }
+ });
+
+ function _emscripten_set_main_loop_timing(mode, value) {
+ Browser.mainLoop.timingMode = mode;
+ Browser.mainLoop.timingValue = value;
+ if (!Browser.mainLoop.func) {
+ return 1
+ }
+ if (mode == 0) {
+ Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() {
+ var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now()) | 0;
+ setTimeout(Browser.mainLoop.runner, timeUntilNextTick)
+ };
+ Browser.mainLoop.method = "timeout"
+ } else if (mode == 1) {
+ Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() {
+ Browser.requestAnimationFrame(Browser.mainLoop.runner)
+ };
+ Browser.mainLoop.method = "rAF"
+ } else if (mode == 2) {
+ if (typeof setImmediate === "undefined") {
+ var setImmediates = [];
+ var emscriptenMainLoopMessageId = "setimmediate";
+ var Browser_setImmediate_messageHandler = function (event) {
+ if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
+ event.stopPropagation();
+ setImmediates.shift()()
+ }
+ };
+ addEventListener("message", Browser_setImmediate_messageHandler, true);
+ setImmediate = function Browser_emulated_setImmediate(func) {
+ setImmediates.push(func);
+ if (ENVIRONMENT_IS_WORKER) {
+ if (Module["setImmediates"] === undefined) Module["setImmediates"] = [];
+ Module["setImmediates"].push(func);
+ postMessage({target: emscriptenMainLoopMessageId})
+ } else postMessage(emscriptenMainLoopMessageId, "*")
+ }
+ }
+ Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() {
+ setImmediate(Browser.mainLoop.runner)
+ };
+ Browser.mainLoop.method = "immediate"
+ }
+ return 0
+ }
+
+ var _emscripten_get_now;
+ if (ENVIRONMENT_IS_NODE) {
+ _emscripten_get_now = function () {
+ var t = process["hrtime"]();
+ return t[0] * 1e3 + t[1] / 1e6
+ }
+ } else if (typeof dateNow !== "undefined") {
+ _emscripten_get_now = dateNow
+ } else _emscripten_get_now = function () {
+ return performance.now()
+ };
+
+ function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop, arg, noSetTiming) {
+ noExitRuntime = true;
+ assert(!Browser.mainLoop.func, "emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");
+ Browser.mainLoop.func = func;
+ Browser.mainLoop.arg = arg;
+ var browserIterationFunc;
+ if (typeof arg !== "undefined") {
+ browserIterationFunc = function () {
+ Module["dynCall_vi"](func, arg)
+ }
+ } else {
+ browserIterationFunc = function () {
+ Module["dynCall_v"](func)
+ }
+ }
+ var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop;
+ Browser.mainLoop.runner = function Browser_mainLoop_runner() {
+ if (ABORT) return;
+ if (Browser.mainLoop.queue.length > 0) {
+ var start = Date.now();
+ var blocker = Browser.mainLoop.queue.shift();
+ blocker.func(blocker.arg);
+ if (Browser.mainLoop.remainingBlockers) {
+ var remaining = Browser.mainLoop.remainingBlockers;
+ var next = remaining % 1 == 0 ? remaining - 1 : Math.floor(remaining);
+ if (blocker.counted) {
+ Browser.mainLoop.remainingBlockers = next
+ } else {
+ next = next + .5;
+ Browser.mainLoop.remainingBlockers = (8 * remaining + next) / 9
+ }
+ }
+ console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + " ms");
+ Browser.mainLoop.updateStatus();
+ if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
+ setTimeout(Browser.mainLoop.runner, 0);
+ return
+ }
+ if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
+ Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0;
+ if (Browser.mainLoop.timingMode == 1 && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) {
+ Browser.mainLoop.scheduler();
+ return
+ } else if (Browser.mainLoop.timingMode == 0) {
+ Browser.mainLoop.tickStartTime = _emscripten_get_now()
+ }
+ Browser.mainLoop.runIter(browserIterationFunc);
+ if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
+ if (typeof SDL === "object" && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData();
+ Browser.mainLoop.scheduler()
+ };
+ if (!noSetTiming) {
+ if (fps && fps > 0) _emscripten_set_main_loop_timing(0, 1e3 / fps); else _emscripten_set_main_loop_timing(1, 1);
+ Browser.mainLoop.scheduler()
+ }
+ if (simulateInfiniteLoop) {
+ throw"unwind"
+ }
+ }
+
+ var Browser = {
+ mainLoop: {
+ scheduler: null,
+ method: "",
+ currentlyRunningMainloop: 0,
+ func: null,
+ arg: 0,
+ timingMode: 0,
+ timingValue: 0,
+ currentFrameNumber: 0,
+ queue: [],
+ pause: function () {
+ Browser.mainLoop.scheduler = null;
+ Browser.mainLoop.currentlyRunningMainloop++
+ },
+ resume: function () {
+ Browser.mainLoop.currentlyRunningMainloop++;
+ var timingMode = Browser.mainLoop.timingMode;
+ var timingValue = Browser.mainLoop.timingValue;
+ var func = Browser.mainLoop.func;
+ Browser.mainLoop.func = null;
+ _emscripten_set_main_loop(func, 0, false, Browser.mainLoop.arg, true);
+ _emscripten_set_main_loop_timing(timingMode, timingValue);
+ Browser.mainLoop.scheduler()
+ },
+ updateStatus: function () {
+ if (Module["setStatus"]) {
+ var message = Module["statusMessage"] || "Please wait...";
+ var remaining = Browser.mainLoop.remainingBlockers;
+ var expected = Browser.mainLoop.expectedBlockers;
+ if (remaining) {
+ if (remaining < expected) {
+ Module["setStatus"](message + " (" + (expected - remaining) + "/" + expected + ")")
+ } else {
+ Module["setStatus"](message)
+ }
+ } else {
+ Module["setStatus"]("")
+ }
+ }
+ },
+ runIter: function (func) {
+ if (ABORT) return;
+ if (Module["preMainLoop"]) {
+ var preRet = Module["preMainLoop"]();
+ if (preRet === false) {
+ return
+ }
+ }
+ try {
+ func()
+ } catch (e) {
+ if (e instanceof ExitStatus) {
+ return
+ } else {
+ if (e && typeof e === "object" && e.stack) err("exception thrown: " + [e, e.stack]);
+ throw e
+ }
+ }
+ if (Module["postMainLoop"]) Module["postMainLoop"]()
+ }
+ },
+ isFullscreen: false,
+ pointerLock: false,
+ moduleContextCreatedCallbacks: [],
+ workers: [],
+ init: function () {
+ if (!Module["preloadPlugins"]) Module["preloadPlugins"] = [];
+ if (Browser.initted) return;
+ Browser.initted = true;
+ try {
+ new Blob;
+ Browser.hasBlobConstructor = true
+ } catch (e) {
+ Browser.hasBlobConstructor = false;
+ console.log("warning: no blob constructor, cannot create blobs with mimetypes")
+ }
+ Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : !Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null;
+ Browser.URLObject = typeof window != "undefined" ? window.URL ? window.URL : window.webkitURL : undefined;
+ if (!Module.noImageDecoding && typeof Browser.URLObject === "undefined") {
+ console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+ Module.noImageDecoding = true
+ }
+ var imagePlugin = {};
+ imagePlugin["canHandle"] = function imagePlugin_canHandle(name) {
+ return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name)
+ };
+ imagePlugin["handle"] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+ var b = null;
+ if (Browser.hasBlobConstructor) {
+ try {
+ b = new Blob([byteArray], {type: Browser.getMimetype(name)});
+ if (b.size !== byteArray.length) {
+ b = new Blob([new Uint8Array(byteArray).buffer], {type: Browser.getMimetype(name)})
+ }
+ } catch (e) {
+ warnOnce("Blob constructor present but fails: " + e + "; falling back to blob builder")
+ }
+ }
+ if (!b) {
+ var bb = new Browser.BlobBuilder;
+ bb.append(new Uint8Array(byteArray).buffer);
+ b = bb.getBlob()
+ }
+ var url = Browser.URLObject.createObjectURL(b);
+ var img = new Image;
+ img.onload = function img_onload() {
+ assert(img.complete, "Image " + name + " could not be decoded");
+ var canvas = document.createElement("canvas");
+ canvas.width = img.width;
+ canvas.height = img.height;
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+ Module["preloadedImages"][name] = canvas;
+ Browser.URLObject.revokeObjectURL(url);
+ if (onload) onload(byteArray)
+ };
+ img.onerror = function img_onerror(event) {
+ console.log("Image " + url + " could not be decoded");
+ if (onerror) onerror()
+ };
+ img.src = url
+ };
+ Module["preloadPlugins"].push(imagePlugin);
+ var audioPlugin = {};
+ audioPlugin["canHandle"] = function audioPlugin_canHandle(name) {
+ return !Module.noAudioDecoding && name.substr(-4) in {".ogg": 1, ".wav": 1, ".mp3": 1}
+ };
+ audioPlugin["handle"] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+ var done = false;
+
+ function finish(audio) {
+ if (done) return;
+ done = true;
+ Module["preloadedAudios"][name] = audio;
+ if (onload) onload(byteArray)
+ }
+
+ function fail() {
+ if (done) return;
+ done = true;
+ Module["preloadedAudios"][name] = new Audio;
+ if (onerror) onerror()
+ }
+
+ if (Browser.hasBlobConstructor) {
+ try {
+ var b = new Blob([byteArray], {type: Browser.getMimetype(name)})
+ } catch (e) {
+ return fail()
+ }
+ var url = Browser.URLObject.createObjectURL(b);
+ var audio = new Audio;
+ audio.addEventListener("canplaythrough", function () {
+ finish(audio)
+ }, false);
+ audio.onerror = function audio_onerror(event) {
+ if (done) return;
+ console.log("warning: browser could not fully decode audio " + name + ", trying slower base64 approach");
+
+ function encode64(data) {
+ var BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var PAD = "=";
+ var ret = "";
+ var leftchar = 0;
+ var leftbits = 0;
+ for (var i = 0; i < data.length; i++) {
+ leftchar = leftchar << 8 | data[i];
+ leftbits += 8;
+ while (leftbits >= 6) {
+ var curr = leftchar >> leftbits - 6 & 63;
+ leftbits -= 6;
+ ret += BASE[curr]
+ }
+ }
+ if (leftbits == 2) {
+ ret += BASE[(leftchar & 3) << 4];
+ ret += PAD + PAD
+ } else if (leftbits == 4) {
+ ret += BASE[(leftchar & 15) << 2];
+ ret += PAD
+ }
+ return ret
+ }
+
+ audio.src = "data:audio/x-" + name.substr(-3) + ";base64," + encode64(byteArray);
+ finish(audio)
+ };
+ audio.src = url;
+ Browser.safeSetTimeout(function () {
+ finish(audio)
+ }, 1e4)
+ } else {
+ return fail()
+ }
+ };
+ Module["preloadPlugins"].push(audioPlugin);
+
+ function pointerLockChange() {
+ Browser.pointerLock = document["pointerLockElement"] === Module["canvas"] || document["mozPointerLockElement"] === Module["canvas"] || document["webkitPointerLockElement"] === Module["canvas"] || document["msPointerLockElement"] === Module["canvas"]
+ }
+
+ var canvas = Module["canvas"];
+ if (canvas) {
+ canvas.requestPointerLock = canvas["requestPointerLock"] || canvas["mozRequestPointerLock"] || canvas["webkitRequestPointerLock"] || canvas["msRequestPointerLock"] || function () {
+ };
+ canvas.exitPointerLock = document["exitPointerLock"] || document["mozExitPointerLock"] || document["webkitExitPointerLock"] || document["msExitPointerLock"] || function () {
+ };
+ canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+ document.addEventListener("pointerlockchange", pointerLockChange, false);
+ document.addEventListener("mozpointerlockchange", pointerLockChange, false);
+ document.addEventListener("webkitpointerlockchange", pointerLockChange, false);
+ document.addEventListener("mspointerlockchange", pointerLockChange, false);
+ if (Module["elementPointerLock"]) {
+ canvas.addEventListener("click", function (ev) {
+ if (!Browser.pointerLock && Module["canvas"].requestPointerLock) {
+ Module["canvas"].requestPointerLock();
+ ev.preventDefault()
+ }
+ }, false)
+ }
+ }
+ },
+ createContext: function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+ if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx;
+ var ctx;
+ var contextHandle;
+ if (useWebGL) {
+ var contextAttributes = {antialias: false, alpha: false, majorVersion: 1};
+ if (webGLContextAttributes) {
+ for (var attribute in webGLContextAttributes) {
+ contextAttributes[attribute] = webGLContextAttributes[attribute]
+ }
+ }
+ if (typeof GL !== "undefined") {
+ contextHandle = GL.createContext(canvas, contextAttributes);
+ if (contextHandle) {
+ ctx = GL.getContext(contextHandle).GLctx
+ }
+ }
+ } else {
+ ctx = canvas.getContext("2d")
+ }
+ if (!ctx) return null;
+ if (setInModule) {
+ if (!useWebGL) assert(typeof GLctx === "undefined", "cannot set in module if GLctx is used, but we are a non-GL context that would replace it");
+ Module.ctx = ctx;
+ if (useWebGL) GL.makeContextCurrent(contextHandle);
+ Module.useWebGL = useWebGL;
+ Browser.moduleContextCreatedCallbacks.forEach(function (callback) {
+ callback()
+ });
+ Browser.init()
+ }
+ return ctx
+ },
+ destroyContext: function (canvas, useWebGL, setInModule) {
+ },
+ fullscreenHandlersInstalled: false,
+ lockPointer: undefined,
+ resizeCanvas: undefined,
+ requestFullscreen: function (lockPointer, resizeCanvas) {
+ Browser.lockPointer = lockPointer;
+ Browser.resizeCanvas = resizeCanvas;
+ if (typeof Browser.lockPointer === "undefined") Browser.lockPointer = true;
+ if (typeof Browser.resizeCanvas === "undefined") Browser.resizeCanvas = false;
+ var canvas = Module["canvas"];
+
+ function fullscreenChange() {
+ Browser.isFullscreen = false;
+ var canvasContainer = canvas.parentNode;
+ if ((document["fullscreenElement"] || document["mozFullScreenElement"] || document["msFullscreenElement"] || document["webkitFullscreenElement"] || document["webkitCurrentFullScreenElement"]) === canvasContainer) {
+ canvas.exitFullscreen = Browser.exitFullscreen;
+ if (Browser.lockPointer) canvas.requestPointerLock();
+ Browser.isFullscreen = true;
+ if (Browser.resizeCanvas) {
+ Browser.setFullscreenCanvasSize()
+ } else {
+ Browser.updateCanvasDimensions(canvas)
+ }
+ } else {
+ canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+ canvasContainer.parentNode.removeChild(canvasContainer);
+ if (Browser.resizeCanvas) {
+ Browser.setWindowedCanvasSize()
+ } else {
+ Browser.updateCanvasDimensions(canvas)
+ }
+ }
+ if (Module["onFullScreen"]) Module["onFullScreen"](Browser.isFullscreen);
+ if (Module["onFullscreen"]) Module["onFullscreen"](Browser.isFullscreen)
+ }
+
+ if (!Browser.fullscreenHandlersInstalled) {
+ Browser.fullscreenHandlersInstalled = true;
+ document.addEventListener("fullscreenchange", fullscreenChange, false);
+ document.addEventListener("mozfullscreenchange", fullscreenChange, false);
+ document.addEventListener("webkitfullscreenchange", fullscreenChange, false);
+ document.addEventListener("MSFullscreenChange", fullscreenChange, false)
+ }
+ var canvasContainer = document.createElement("div");
+ canvas.parentNode.insertBefore(canvasContainer, canvas);
+ canvasContainer.appendChild(canvas);
+ canvasContainer.requestFullscreen = canvasContainer["requestFullscreen"] || canvasContainer["mozRequestFullScreen"] || canvasContainer["msRequestFullscreen"] || (canvasContainer["webkitRequestFullscreen"] ? function () {
+ canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"])
+ } : null) || (canvasContainer["webkitRequestFullScreen"] ? function () {
+ canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])
+ } : null);
+ canvasContainer.requestFullscreen()
+ },
+ exitFullscreen: function () {
+ if (!Browser.isFullscreen) {
+ return false
+ }
+ var CFS = document["exitFullscreen"] || document["cancelFullScreen"] || document["mozCancelFullScreen"] || document["msExitFullscreen"] || document["webkitCancelFullScreen"] || function () {
+ };
+ CFS.apply(document, []);
+ return true
+ },
+ nextRAF: 0,
+ fakeRequestAnimationFrame: function (func) {
+ var now = Date.now();
+ if (Browser.nextRAF === 0) {
+ Browser.nextRAF = now + 1e3 / 60
+ } else {
+ while (now + 2 >= Browser.nextRAF) {
+ Browser.nextRAF += 1e3 / 60
+ }
+ }
+ var delay = Math.max(Browser.nextRAF - now, 0);
+ setTimeout(func, delay)
+ },
+ requestAnimationFrame: function (func) {
+ if (typeof requestAnimationFrame === "function") {
+ requestAnimationFrame(func);
+ return
+ }
+ var RAF = Browser.fakeRequestAnimationFrame;
+ RAF(func)
+ },
+ safeCallback: function (func) {
+ return function () {
+ if (!ABORT) return func.apply(null, arguments)
+ }
+ },
+ allowAsyncCallbacks: true,
+ queuedAsyncCallbacks: [],
+ pauseAsyncCallbacks: function () {
+ Browser.allowAsyncCallbacks = false
+ },
+ resumeAsyncCallbacks: function () {
+ Browser.allowAsyncCallbacks = true;
+ if (Browser.queuedAsyncCallbacks.length > 0) {
+ var callbacks = Browser.queuedAsyncCallbacks;
+ Browser.queuedAsyncCallbacks = [];
+ callbacks.forEach(function (func) {
+ func()
+ })
+ }
+ },
+ safeRequestAnimationFrame: function (func) {
+ return Browser.requestAnimationFrame(function () {
+ if (ABORT) return;
+ if (Browser.allowAsyncCallbacks) {
+ func()
+ } else {
+ Browser.queuedAsyncCallbacks.push(func)
+ }
+ })
+ },
+ safeSetTimeout: function (func, timeout) {
+ noExitRuntime = true;
+ return setTimeout(function () {
+ if (ABORT) return;
+ if (Browser.allowAsyncCallbacks) {
+ func()
+ } else {
+ Browser.queuedAsyncCallbacks.push(func)
+ }
+ }, timeout)
+ },
+ safeSetInterval: function (func, timeout) {
+ noExitRuntime = true;
+ return setInterval(function () {
+ if (ABORT) return;
+ if (Browser.allowAsyncCallbacks) {
+ func()
+ }
+ }, timeout)
+ },
+ getMimetype: function (name) {
+ return {
+ "jpg": "image/jpeg",
+ "jpeg": "image/jpeg",
+ "png": "image/png",
+ "bmp": "image/bmp",
+ "ogg": "audio/ogg",
+ "wav": "audio/wav",
+ "mp3": "audio/mpeg"
+ }[name.substr(name.lastIndexOf(".") + 1)]
+ },
+ getUserMedia: function (func) {
+ if (!window.getUserMedia) {
+ window.getUserMedia = navigator["getUserMedia"] || navigator["mozGetUserMedia"]
+ }
+ window.getUserMedia(func)
+ },
+ getMovementX: function (event) {
+ return event["movementX"] || event["mozMovementX"] || event["webkitMovementX"] || 0
+ },
+ getMovementY: function (event) {
+ return event["movementY"] || event["mozMovementY"] || event["webkitMovementY"] || 0
+ },
+ getMouseWheelDelta: function (event) {
+ var delta = 0;
+ switch (event.type) {
+ case"DOMMouseScroll":
+ delta = event.detail / 3;
+ break;
+ case"mousewheel":
+ delta = event.wheelDelta / 120;
+ break;
+ case"wheel":
+ delta = event.deltaY;
+ switch (event.deltaMode) {
+ case 0:
+ delta /= 100;
+ break;
+ case 1:
+ delta /= 3;
+ break;
+ case 2:
+ delta *= 80;
+ break;
+ default:
+ throw"unrecognized mouse wheel delta mode: " + event.deltaMode
+ }
+ break;
+ default:
+ throw"unrecognized mouse wheel event: " + event.type
+ }
+ return delta
+ },
+ mouseX: 0,
+ mouseY: 0,
+ mouseMovementX: 0,
+ mouseMovementY: 0,
+ touches: {},
+ lastTouches: {},
+ calculateMouseEvent: function (event) {
+ if (Browser.pointerLock) {
+ if (event.type != "mousemove" && "mozMovementX" in event) {
+ Browser.mouseMovementX = Browser.mouseMovementY = 0
+ } else {
+ Browser.mouseMovementX = Browser.getMovementX(event);
+ Browser.mouseMovementY = Browser.getMovementY(event)
+ }
+ if (typeof SDL != "undefined") {
+ Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+ Browser.mouseY = SDL.mouseY + Browser.mouseMovementY
+ } else {
+ Browser.mouseX += Browser.mouseMovementX;
+ Browser.mouseY += Browser.mouseMovementY
+ }
+ } else {
+ var rect = Module["canvas"].getBoundingClientRect();
+ var cw = Module["canvas"].width;
+ var ch = Module["canvas"].height;
+ var scrollX = typeof window.scrollX !== "undefined" ? window.scrollX : window.pageXOffset;
+ var scrollY = typeof window.scrollY !== "undefined" ? window.scrollY : window.pageYOffset;
+ if (event.type === "touchstart" || event.type === "touchend" || event.type === "touchmove") {
+ var touch = event.touch;
+ if (touch === undefined) {
+ return
+ }
+ var adjustedX = touch.pageX - (scrollX + rect.left);
+ var adjustedY = touch.pageY - (scrollY + rect.top);
+ adjustedX = adjustedX * (cw / rect.width);
+ adjustedY = adjustedY * (ch / rect.height);
+ var coords = {x: adjustedX, y: adjustedY};
+ if (event.type === "touchstart") {
+ Browser.lastTouches[touch.identifier] = coords;
+ Browser.touches[touch.identifier] = coords
+ } else if (event.type === "touchend" || event.type === "touchmove") {
+ var last = Browser.touches[touch.identifier];
+ if (!last) last = coords;
+ Browser.lastTouches[touch.identifier] = last;
+ Browser.touches[touch.identifier] = coords
+ }
+ return
+ }
+ var x = event.pageX - (scrollX + rect.left);
+ var y = event.pageY - (scrollY + rect.top);
+ x = x * (cw / rect.width);
+ y = y * (ch / rect.height);
+ Browser.mouseMovementX = x - Browser.mouseX;
+ Browser.mouseMovementY = y - Browser.mouseY;
+ Browser.mouseX = x;
+ Browser.mouseY = y
+ }
+ },
+ asyncLoad: function (url, onload, onerror, noRunDep) {
+ var dep = !noRunDep ? getUniqueRunDependency("al " + url) : "";
+ readAsync(url, function (arrayBuffer) {
+ assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+ onload(new Uint8Array(arrayBuffer));
+ if (dep) removeRunDependency(dep)
+ }, function (event) {
+ if (onerror) {
+ onerror()
+ } else {
+ throw'Loading data file "' + url + '" failed.'
+ }
+ });
+ if (dep) addRunDependency(dep)
+ },
+ resizeListeners: [],
+ updateResizeListeners: function () {
+ var canvas = Module["canvas"];
+ Browser.resizeListeners.forEach(function (listener) {
+ listener(canvas.width, canvas.height)
+ })
+ },
+ setCanvasSize: function (width, height, noUpdates) {
+ var canvas = Module["canvas"];
+ Browser.updateCanvasDimensions(canvas, width, height);
+ if (!noUpdates) Browser.updateResizeListeners()
+ },
+ windowedWidth: 0,
+ windowedHeight: 0,
+ setFullscreenCanvasSize: function () {
+ if (typeof SDL != "undefined") {
+ var flags = HEAPU32[SDL.screen >> 2];
+ flags = flags | 8388608;
+ HEAP32[SDL.screen >> 2] = flags
+ }
+ Browser.updateCanvasDimensions(Module["canvas"]);
+ Browser.updateResizeListeners()
+ },
+ setWindowedCanvasSize: function () {
+ if (typeof SDL != "undefined") {
+ var flags = HEAPU32[SDL.screen >> 2];
+ flags = flags & ~8388608;
+ HEAP32[SDL.screen >> 2] = flags
+ }
+ Browser.updateCanvasDimensions(Module["canvas"]);
+ Browser.updateResizeListeners()
+ },
+ updateCanvasDimensions: function (canvas, wNative, hNative) {
+ if (wNative && hNative) {
+ canvas.widthNative = wNative;
+ canvas.heightNative = hNative
+ } else {
+ wNative = canvas.widthNative;
+ hNative = canvas.heightNative
+ }
+ var w = wNative;
+ var h = hNative;
+ if (Module["forcedAspectRatio"] && Module["forcedAspectRatio"] > 0) {
+ if (w / h < Module["forcedAspectRatio"]) {
+ w = Math.round(h * Module["forcedAspectRatio"])
+ } else {
+ h = Math.round(w / Module["forcedAspectRatio"])
+ }
+ }
+ if ((document["fullscreenElement"] || document["mozFullScreenElement"] || document["msFullscreenElement"] || document["webkitFullscreenElement"] || document["webkitCurrentFullScreenElement"]) === canvas.parentNode && typeof screen != "undefined") {
+ var factor = Math.min(screen.width / w, screen.height / h);
+ w = Math.round(w * factor);
+ h = Math.round(h * factor)
+ }
+ if (Browser.resizeCanvas) {
+ if (canvas.width != w) canvas.width = w;
+ if (canvas.height != h) canvas.height = h;
+ if (typeof canvas.style != "undefined") {
+ canvas.style.removeProperty("width");
+ canvas.style.removeProperty("height")
+ }
+ } else {
+ if (canvas.width != wNative) canvas.width = wNative;
+ if (canvas.height != hNative) canvas.height = hNative;
+ if (typeof canvas.style != "undefined") {
+ if (w != wNative || h != hNative) {
+ canvas.style.setProperty("width", w + "px", "important");
+ canvas.style.setProperty("height", h + "px", "important")
+ } else {
+ canvas.style.removeProperty("width");
+ canvas.style.removeProperty("height")
+ }
+ }
+ }
+ },
+ wgetRequests: {},
+ nextWgetRequestHandle: 0,
+ getNextWgetRequestHandle: function () {
+ var handle = Browser.nextWgetRequestHandle;
+ Browser.nextWgetRequestHandle++;
+ return handle
+ }
+ };
+
+ function demangle(func) {
+ demangle.recursionGuard = (demangle.recursionGuard | 0) + 1;
+ if (demangle.recursionGuard > 1) return func;
+ var __cxa_demangle_func = Module["___cxa_demangle"] || Module["__cxa_demangle"];
+ assert(__cxa_demangle_func);
+ var stackTop = stackSave();
+ try {
+ var s = func;
+ if (s.startsWith("__Z")) s = s.substr(1);
+ var len = lengthBytesUTF8(s) + 1;
+ var buf = stackAlloc(len);
+ stringToUTF8(s, buf, len);
+ var status = stackAlloc(4);
+ var ret = __cxa_demangle_func(buf, 0, 0, status);
+ if (HEAP32[status >> 2] === 0 && ret) {
+ return UTF8ToString(ret)
+ }
+ } catch (e) {
+ } finally {
+ _free(ret);
+ stackRestore(stackTop);
+ if (demangle.recursionGuard < 2) --demangle.recursionGuard
+ }
+ return func
+ }
+
+ function demangleAll(text) {
+ var regex = /\b_Z[\w\d_]+/g;
+ return text.replace(regex, function (x) {
+ var y = demangle(x);
+ return x === y ? x : y + " [" + x + "]"
+ })
+ }
+
+ function jsStackTrace() {
+ var err = new Error;
+ if (!err.stack) {
+ try {
+ throw new Error
+ } catch (e) {
+ err = e
+ }
+ if (!err.stack) {
+ return "(no stack trace available)"
+ }
+ }
+ return err.stack.toString()
+ }
+
+ function stackTrace() {
+ var js = jsStackTrace();
+ if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"]();
+ return demangleAll(js)
+ }
+
+ function ___cxa_allocate_exception(size) {
+ return _malloc(size)
+ }
+
+ function _atexit(func, arg) {
+ }
+
+ function ___cxa_atexit(a0, a1) {
+ return _atexit(a0, a1)
+ }
+
+ var ___exception_infos = {};
+ var ___exception_last = 0;
+
+ function __ZSt18uncaught_exceptionv() {
+ return __ZSt18uncaught_exceptionv.uncaught_exceptions > 0
+ }
+
+ function ___cxa_throw(ptr, type, destructor) {
+ ___exception_infos[ptr] = {
+ ptr: ptr,
+ adjusted: [ptr],
+ type: type,
+ destructor: destructor,
+ refcount: 0,
+ caught: false,
+ rethrown: false
+ };
+ ___exception_last = ptr;
+ if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
+ __ZSt18uncaught_exceptionv.uncaught_exceptions = 1
+ } else {
+ __ZSt18uncaught_exceptionv.uncaught_exceptions++
+ }
+ throw ptr
+ }
+
+ function setErrNo(value) {
+ HEAP32[___errno_location() >> 2] = value;
+ return value
+ }
+
+ function ___map_file(pathname, size) {
+ setErrNo(63);
+ return -1
+ }
+
+ var PATH = {
+ splitPath: function (filename) {
+ var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+ return splitPathRe.exec(filename).slice(1)
+ }, normalizeArray: function (parts, allowAboveRoot) {
+ var up = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i];
+ if (last === ".") {
+ parts.splice(i, 1)
+ } else if (last === "..") {
+ parts.splice(i, 1);
+ up++
+ } else if (up) {
+ parts.splice(i, 1);
+ up--
+ }
+ }
+ if (allowAboveRoot) {
+ for (; up; up--) {
+ parts.unshift("..")
+ }
+ }
+ return parts
+ }, normalize: function (path) {
+ var isAbsolute = path.charAt(0) === "/", trailingSlash = path.substr(-1) === "/";
+ path = PATH.normalizeArray(path.split("/").filter(function (p) {
+ return !!p
+ }), !isAbsolute).join("/");
+ if (!path && !isAbsolute) {
+ path = "."
+ }
+ if (path && trailingSlash) {
+ path += "/"
+ }
+ return (isAbsolute ? "/" : "") + path
+ }, dirname: function (path) {
+ var result = PATH.splitPath(path), root = result[0], dir = result[1];
+ if (!root && !dir) {
+ return "."
+ }
+ if (dir) {
+ dir = dir.substr(0, dir.length - 1)
+ }
+ return root + dir
+ }, basename: function (path) {
+ if (path === "/") return "/";
+ var lastSlash = path.lastIndexOf("/");
+ if (lastSlash === -1) return path;
+ return path.substr(lastSlash + 1)
+ }, extname: function (path) {
+ return PATH.splitPath(path)[3]
+ }, join: function () {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return PATH.normalize(paths.join("/"))
+ }, join2: function (l, r) {
+ return PATH.normalize(l + "/" + r)
+ }
+ };
+ var PATH_FS = {
+ resolve: function () {
+ var resolvedPath = "", resolvedAbsolute = false;
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+ var path = i >= 0 ? arguments[i] : FS.cwd();
+ if (typeof path !== "string") {
+ throw new TypeError("Arguments to path.resolve must be strings")
+ } else if (!path) {
+ return ""
+ }
+ resolvedPath = path + "/" + resolvedPath;
+ resolvedAbsolute = path.charAt(0) === "/"
+ }
+ resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(function (p) {
+ return !!p
+ }), !resolvedAbsolute).join("/");
+ return (resolvedAbsolute ? "/" : "") + resolvedPath || "."
+ }, relative: function (from, to) {
+ from = PATH_FS.resolve(from).substr(1);
+ to = PATH_FS.resolve(to).substr(1);
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== "") break
+ }
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== "") break
+ }
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1)
+ }
+
+ var fromParts = trim(from.split("/"));
+ var toParts = trim(to.split("/"));
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break
+ }
+ }
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push("..")
+ }
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+ return outputParts.join("/")
+ }
+ };
+ var TTY = {
+ ttys: [], init: function () {
+ }, shutdown: function () {
+ }, register: function (dev, ops) {
+ TTY.ttys[dev] = {input: [], output: [], ops: ops};
+ FS.registerDevice(dev, TTY.stream_ops)
+ }, stream_ops: {
+ open: function (stream) {
+ var tty = TTY.ttys[stream.node.rdev];
+ if (!tty) {
+ throw new FS.ErrnoError(43)
+ }
+ stream.tty = tty;
+ stream.seekable = false
+ }, close: function (stream) {
+ stream.tty.ops.flush(stream.tty)
+ }, flush: function (stream) {
+ stream.tty.ops.flush(stream.tty)
+ }, read: function (stream, buffer, offset, length, pos) {
+ if (!stream.tty || !stream.tty.ops.get_char) {
+ throw new FS.ErrnoError(60)
+ }
+ var bytesRead = 0;
+ for (var i = 0; i < length; i++) {
+ var result;
+ try {
+ result = stream.tty.ops.get_char(stream.tty)
+ } catch (e) {
+ throw new FS.ErrnoError(29)
+ }
+ if (result === undefined && bytesRead === 0) {
+ throw new FS.ErrnoError(6)
+ }
+ if (result === null || result === undefined) break;
+ bytesRead++;
+ buffer[offset + i] = result
+ }
+ if (bytesRead) {
+ stream.node.timestamp = Date.now()
+ }
+ return bytesRead
+ }, write: function (stream, buffer, offset, length, pos) {
+ if (!stream.tty || !stream.tty.ops.put_char) {
+ throw new FS.ErrnoError(60)
+ }
+ try {
+ for (var i = 0; i < length; i++) {
+ stream.tty.ops.put_char(stream.tty, buffer[offset + i])
+ }
+ } catch (e) {
+ throw new FS.ErrnoError(29)
+ }
+ if (length) {
+ stream.node.timestamp = Date.now()
+ }
+ return i
+ }
+ }, default_tty_ops: {
+ get_char: function (tty) {
+ if (!tty.input.length) {
+ var result = null;
+ if (ENVIRONMENT_IS_NODE) {
+ var BUFSIZE = 256;
+ var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE);
+ var bytesRead = 0;
+ try {
+ bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null)
+ } catch (e) {
+ if (e.toString().indexOf("EOF") != -1) bytesRead = 0; else throw e
+ }
+ if (bytesRead > 0) {
+ result = buf.slice(0, bytesRead).toString("utf-8")
+ } else {
+ result = null
+ }
+ } else if (typeof window != "undefined" && typeof window.prompt == "function") {
+ result = window.prompt("Input: ");
+ if (result !== null) {
+ result += "\n"
+ }
+ } else if (typeof readline == "function") {
+ result = readline();
+ if (result !== null) {
+ result += "\n"
+ }
+ }
+ if (!result) {
+ return null
+ }
+ tty.input = intArrayFromString(result, true)
+ }
+ return tty.input.shift()
+ }, put_char: function (tty, val) {
+ if (val === null || val === 10) {
+ out(UTF8ArrayToString(tty.output, 0));
+ tty.output = []
+ } else {
+ if (val != 0) tty.output.push(val)
+ }
+ }, flush: function (tty) {
+ if (tty.output && tty.output.length > 0) {
+ out(UTF8ArrayToString(tty.output, 0));
+ tty.output = []
+ }
+ }
+ }, default_tty1_ops: {
+ put_char: function (tty, val) {
+ if (val === null || val === 10) {
+ err(UTF8ArrayToString(tty.output, 0));
+ tty.output = []
+ } else {
+ if (val != 0) tty.output.push(val)
+ }
+ }, flush: function (tty) {
+ if (tty.output && tty.output.length > 0) {
+ err(UTF8ArrayToString(tty.output, 0));
+ tty.output = []
+ }
+ }
+ }
+ };
+ var MEMFS = {
+ ops_table: null, mount: function (mount) {
+ return MEMFS.createNode(null, "/", 16384 | 511, 0)
+ }, createNode: function (parent, name, mode, dev) {
+ if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+ throw new FS.ErrnoError(63)
+ }
+ if (!MEMFS.ops_table) {
+ MEMFS.ops_table = {
+ dir: {
+ node: {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr,
+ lookup: MEMFS.node_ops.lookup,
+ mknod: MEMFS.node_ops.mknod,
+ rename: MEMFS.node_ops.rename,
+ unlink: MEMFS.node_ops.unlink,
+ rmdir: MEMFS.node_ops.rmdir,
+ readdir: MEMFS.node_ops.readdir,
+ symlink: MEMFS.node_ops.symlink
+ }, stream: {llseek: MEMFS.stream_ops.llseek}
+ },
+ file: {
+ node: {getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr},
+ stream: {
+ llseek: MEMFS.stream_ops.llseek,
+ read: MEMFS.stream_ops.read,
+ write: MEMFS.stream_ops.write,
+ allocate: MEMFS.stream_ops.allocate,
+ mmap: MEMFS.stream_ops.mmap,
+ msync: MEMFS.stream_ops.msync
+ }
+ },
+ link: {
+ node: {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr,
+ readlink: MEMFS.node_ops.readlink
+ }, stream: {}
+ },
+ chrdev: {
+ node: {getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr},
+ stream: FS.chrdev_stream_ops
+ }
+ }
+ }
+ var node = FS.createNode(parent, name, mode, dev);
+ if (FS.isDir(node.mode)) {
+ node.node_ops = MEMFS.ops_table.dir.node;
+ node.stream_ops = MEMFS.ops_table.dir.stream;
+ node.contents = {}
+ } else if (FS.isFile(node.mode)) {
+ node.node_ops = MEMFS.ops_table.file.node;
+ node.stream_ops = MEMFS.ops_table.file.stream;
+ node.usedBytes = 0;
+ node.contents = null
+ } else if (FS.isLink(node.mode)) {
+ node.node_ops = MEMFS.ops_table.link.node;
+ node.stream_ops = MEMFS.ops_table.link.stream
+ } else if (FS.isChrdev(node.mode)) {
+ node.node_ops = MEMFS.ops_table.chrdev.node;
+ node.stream_ops = MEMFS.ops_table.chrdev.stream
+ }
+ node.timestamp = Date.now();
+ if (parent) {
+ parent.contents[name] = node
+ }
+ return node
+ }, getFileDataAsRegularArray: function (node) {
+ if (node.contents && node.contents.subarray) {
+ var arr = [];
+ for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);
+ return arr
+ }
+ return node.contents
+ }, getFileDataAsTypedArray: function (node) {
+ if (!node.contents) return new Uint8Array(0);
+ if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes);
+ return new Uint8Array(node.contents)
+ }, expandFileStorage: function (node, newCapacity) {
+ var prevCapacity = node.contents ? node.contents.length : 0;
+ if (prevCapacity >= newCapacity) return;
+ var CAPACITY_DOUBLING_MAX = 1024 * 1024;
+ newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0);
+ if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
+ var oldContents = node.contents;
+ node.contents = new Uint8Array(newCapacity);
+ if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
+ return
+ }, resizeFileStorage: function (node, newSize) {
+ if (node.usedBytes == newSize) return;
+ if (newSize == 0) {
+ node.contents = null;
+ node.usedBytes = 0;
+ return
+ }
+ if (!node.contents || node.contents.subarray) {
+ var oldContents = node.contents;
+ node.contents = new Uint8Array(newSize);
+ if (oldContents) {
+ node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes)))
+ }
+ node.usedBytes = newSize;
+ return
+ }
+ if (!node.contents) node.contents = [];
+ if (node.contents.length > newSize) node.contents.length = newSize; else while (node.contents.length < newSize) node.contents.push(0);
+ node.usedBytes = newSize
+ }, node_ops: {
+ getattr: function (node) {
+ var attr = {};
+ attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+ attr.ino = node.id;
+ attr.mode = node.mode;
+ attr.nlink = 1;
+ attr.uid = 0;
+ attr.gid = 0;
+ attr.rdev = node.rdev;
+ if (FS.isDir(node.mode)) {
+ attr.size = 4096
+ } else if (FS.isFile(node.mode)) {
+ attr.size = node.usedBytes
+ } else if (FS.isLink(node.mode)) {
+ attr.size = node.link.length
+ } else {
+ attr.size = 0
+ }
+ attr.atime = new Date(node.timestamp);
+ attr.mtime = new Date(node.timestamp);
+ attr.ctime = new Date(node.timestamp);
+ attr.blksize = 4096;
+ attr.blocks = Math.ceil(attr.size / attr.blksize);
+ return attr
+ }, setattr: function (node, attr) {
+ if (attr.mode !== undefined) {
+ node.mode = attr.mode
+ }
+ if (attr.timestamp !== undefined) {
+ node.timestamp = attr.timestamp
+ }
+ if (attr.size !== undefined) {
+ MEMFS.resizeFileStorage(node, attr.size)
+ }
+ }, lookup: function (parent, name) {
+ throw FS.genericErrors[44]
+ }, mknod: function (parent, name, mode, dev) {
+ return MEMFS.createNode(parent, name, mode, dev)
+ }, rename: function (old_node, new_dir, new_name) {
+ if (FS.isDir(old_node.mode)) {
+ var new_node;
+ try {
+ new_node = FS.lookupNode(new_dir, new_name)
+ } catch (e) {
+ }
+ if (new_node) {
+ for (var i in new_node.contents) {
+ throw new FS.ErrnoError(55)
+ }
+ }
+ }
+ delete old_node.parent.contents[old_node.name];
+ old_node.name = new_name;
+ new_dir.contents[new_name] = old_node;
+ old_node.parent = new_dir
+ }, unlink: function (parent, name) {
+ delete parent.contents[name]
+ }, rmdir: function (parent, name) {
+ var node = FS.lookupNode(parent, name);
+ for (var i in node.contents) {
+ throw new FS.ErrnoError(55)
+ }
+ delete parent.contents[name]
+ }, readdir: function (node) {
+ var entries = [".", ".."];
+ for (var key in node.contents) {
+ if (!node.contents.hasOwnProperty(key)) {
+ continue
+ }
+ entries.push(key)
+ }
+ return entries
+ }, symlink: function (parent, newname, oldpath) {
+ var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
+ node.link = oldpath;
+ return node
+ }, readlink: function (node) {
+ if (!FS.isLink(node.mode)) {
+ throw new FS.ErrnoError(28)
+ }
+ return node.link
+ }
+ }, stream_ops: {
+ read: function (stream, buffer, offset, length, position) {
+ var contents = stream.node.contents;
+ if (position >= stream.node.usedBytes) return 0;
+ var size = Math.min(stream.node.usedBytes - position, length);
+ if (size > 8 && contents.subarray) {
+ buffer.set(contents.subarray(position, position + size), offset)
+ } else {
+ for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i]
+ }
+ return size
+ }, write: function (stream, buffer, offset, length, position, canOwn) {
+ if (buffer.buffer === HEAP8.buffer) {
+ canOwn = false
+ }
+ if (!length) return 0;
+ var node = stream.node;
+ node.timestamp = Date.now();
+ if (buffer.subarray && (!node.contents || node.contents.subarray)) {
+ if (canOwn) {
+ node.contents = buffer.subarray(offset, offset + length);
+ node.usedBytes = length;
+ return length
+ } else if (node.usedBytes === 0 && position === 0) {
+ node.contents = buffer.slice(offset, offset + length);
+ node.usedBytes = length;
+ return length
+ } else if (position + length <= node.usedBytes) {
+ node.contents.set(buffer.subarray(offset, offset + length), position);
+ return length
+ }
+ }
+ MEMFS.expandFileStorage(node, position + length);
+ if (node.contents.subarray && buffer.subarray) {
+ node.contents.set(buffer.subarray(offset, offset + length), position)
+ } else {
+ for (var i = 0; i < length; i++) {
+ node.contents[position + i] = buffer[offset + i]
+ }
+ }
+ node.usedBytes = Math.max(node.usedBytes, position + length);
+ return length
+ }, llseek: function (stream, offset, whence) {
+ var position = offset;
+ if (whence === 1) {
+ position += stream.position
+ } else if (whence === 2) {
+ if (FS.isFile(stream.node.mode)) {
+ position += stream.node.usedBytes
+ }
+ }
+ if (position < 0) {
+ throw new FS.ErrnoError(28)
+ }
+ return position
+ }, allocate: function (stream, offset, length) {
+ MEMFS.expandFileStorage(stream.node, offset + length);
+ stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length)
+ }, mmap: function (stream, address, length, position, prot, flags) {
+ assert(address === 0);
+ if (!FS.isFile(stream.node.mode)) {
+ throw new FS.ErrnoError(43)
+ }
+ var ptr;
+ var allocated;
+ var contents = stream.node.contents;
+ if (!(flags & 2) && contents.buffer === buffer) {
+ allocated = false;
+ ptr = contents.byteOffset
+ } else {
+ if (position > 0 || position + length < contents.length) {
+ if (contents.subarray) {
+ contents = contents.subarray(position, position + length)
+ } else {
+ contents = Array.prototype.slice.call(contents, position, position + length)
+ }
+ }
+ allocated = true;
+ ptr = FS.mmapAlloc(length);
+ if (!ptr) {
+ throw new FS.ErrnoError(48)
+ }
+ HEAP8.set(contents, ptr)
+ }
+ return {ptr: ptr, allocated: allocated}
+ }, msync: function (stream, buffer, offset, length, mmapFlags) {
+ if (!FS.isFile(stream.node.mode)) {
+ throw new FS.ErrnoError(43)
+ }
+ if (mmapFlags & 2) {
+ return 0
+ }
+ var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
+ return 0
+ }
+ }
+ };
+ var FS = {
+ root: null,
+ mounts: [],
+ devices: {},
+ streams: [],
+ nextInode: 1,
+ nameTable: null,
+ currentPath: "/",
+ initialized: false,
+ ignorePermissions: true,
+ trackingDelegate: {},
+ tracking: {openFlags: {READ: 1, WRITE: 2}},
+ ErrnoError: null,
+ genericErrors: {},
+ filesystems: null,
+ syncFSRequests: 0,
+ handleFSError: function (e) {
+ if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace();
+ return setErrNo(e.errno)
+ },
+ lookupPath: function (path, opts) {
+ path = PATH_FS.resolve(FS.cwd(), path);
+ opts = opts || {};
+ if (!path) return {path: "", node: null};
+ var defaults = {follow_mount: true, recurse_count: 0};
+ for (var key in defaults) {
+ if (opts[key] === undefined) {
+ opts[key] = defaults[key]
+ }
+ }
+ if (opts.recurse_count > 8) {
+ throw new FS.ErrnoError(32)
+ }
+ var parts = PATH.normalizeArray(path.split("/").filter(function (p) {
+ return !!p
+ }), false);
+ var current = FS.root;
+ var current_path = "/";
+ for (var i = 0; i < parts.length; i++) {
+ var islast = i === parts.length - 1;
+ if (islast && opts.parent) {
+ break
+ }
+ current = FS.lookupNode(current, parts[i]);
+ current_path = PATH.join2(current_path, parts[i]);
+ if (FS.isMountpoint(current)) {
+ if (!islast || islast && opts.follow_mount) {
+ current = current.mounted.root
+ }
+ }
+ if (!islast || opts.follow) {
+ var count = 0;
+ while (FS.isLink(current.mode)) {
+ var link = FS.readlink(current_path);
+ current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
+ var lookup = FS.lookupPath(current_path, {recurse_count: opts.recurse_count});
+ current = lookup.node;
+ if (count++ > 40) {
+ throw new FS.ErrnoError(32)
+ }
+ }
+ }
+ }
+ return {path: current_path, node: current}
+ },
+ getPath: function (node) {
+ var path;
+ while (true) {
+ if (FS.isRoot(node)) {
+ var mount = node.mount.mountpoint;
+ if (!path) return mount;
+ return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path
+ }
+ path = path ? node.name + "/" + path : node.name;
+ node = node.parent
+ }
+ },
+ hashName: function (parentid, name) {
+ var hash = 0;
+ for (var i = 0; i < name.length; i++) {
+ hash = (hash << 5) - hash + name.charCodeAt(i) | 0
+ }
+ return (parentid + hash >>> 0) % FS.nameTable.length
+ },
+ hashAddNode: function (node) {
+ var hash = FS.hashName(node.parent.id, node.name);
+ node.name_next = FS.nameTable[hash];
+ FS.nameTable[hash] = node
+ },
+ hashRemoveNode: function (node) {
+ var hash = FS.hashName(node.parent.id, node.name);
+ if (FS.nameTable[hash] === node) {
+ FS.nameTable[hash] = node.name_next
+ } else {
+ var current = FS.nameTable[hash];
+ while (current) {
+ if (current.name_next === node) {
+ current.name_next = node.name_next;
+ break
+ }
+ current = current.name_next
+ }
+ }
+ },
+ lookupNode: function (parent, name) {
+ var errCode = FS.mayLookup(parent);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode, parent)
+ }
+ var hash = FS.hashName(parent.id, name);
+ for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+ var nodeName = node.name;
+ if (node.parent.id === parent.id && nodeName === name) {
+ return node
+ }
+ }
+ return FS.lookup(parent, name)
+ },
+ createNode: function (parent, name, mode, rdev) {
+ var node = new FS.FSNode(parent, name, mode, rdev);
+ FS.hashAddNode(node);
+ return node
+ },
+ destroyNode: function (node) {
+ FS.hashRemoveNode(node)
+ },
+ isRoot: function (node) {
+ return node === node.parent
+ },
+ isMountpoint: function (node) {
+ return !!node.mounted
+ },
+ isFile: function (mode) {
+ return (mode & 61440) === 32768
+ },
+ isDir: function (mode) {
+ return (mode & 61440) === 16384
+ },
+ isLink: function (mode) {
+ return (mode & 61440) === 40960
+ },
+ isChrdev: function (mode) {
+ return (mode & 61440) === 8192
+ },
+ isBlkdev: function (mode) {
+ return (mode & 61440) === 24576
+ },
+ isFIFO: function (mode) {
+ return (mode & 61440) === 4096
+ },
+ isSocket: function (mode) {
+ return (mode & 49152) === 49152
+ },
+ flagModes: {
+ "r": 0,
+ "rs": 1052672,
+ "r+": 2,
+ "w": 577,
+ "wx": 705,
+ "xw": 705,
+ "w+": 578,
+ "wx+": 706,
+ "xw+": 706,
+ "a": 1089,
+ "ax": 1217,
+ "xa": 1217,
+ "a+": 1090,
+ "ax+": 1218,
+ "xa+": 1218
+ },
+ modeStringToFlags: function (str) {
+ var flags = FS.flagModes[str];
+ if (typeof flags === "undefined") {
+ throw new Error("Unknown file open mode: " + str)
+ }
+ return flags
+ },
+ flagsToPermissionString: function (flag) {
+ var perms = ["r", "w", "rw"][flag & 3];
+ if (flag & 512) {
+ perms += "w"
+ }
+ return perms
+ },
+ nodePermissions: function (node, perms) {
+ if (FS.ignorePermissions) {
+ return 0
+ }
+ if (perms.indexOf("r") !== -1 && !(node.mode & 292)) {
+ return 2
+ } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) {
+ return 2
+ } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) {
+ return 2
+ }
+ return 0
+ },
+ mayLookup: function (dir) {
+ var errCode = FS.nodePermissions(dir, "x");
+ if (errCode) return errCode;
+ if (!dir.node_ops.lookup) return 2;
+ return 0
+ },
+ mayCreate: function (dir, name) {
+ try {
+ var node = FS.lookupNode(dir, name);
+ return 20
+ } catch (e) {
+ }
+ return FS.nodePermissions(dir, "wx")
+ },
+ mayDelete: function (dir, name, isdir) {
+ var node;
+ try {
+ node = FS.lookupNode(dir, name)
+ } catch (e) {
+ return e.errno
+ }
+ var errCode = FS.nodePermissions(dir, "wx");
+ if (errCode) {
+ return errCode
+ }
+ if (isdir) {
+ if (!FS.isDir(node.mode)) {
+ return 54
+ }
+ if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+ return 10
+ }
+ } else {
+ if (FS.isDir(node.mode)) {
+ return 31
+ }
+ }
+ return 0
+ },
+ mayOpen: function (node, flags) {
+ if (!node) {
+ return 44
+ }
+ if (FS.isLink(node.mode)) {
+ return 32
+ } else if (FS.isDir(node.mode)) {
+ if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) {
+ return 31
+ }
+ }
+ return FS.nodePermissions(node, FS.flagsToPermissionString(flags))
+ },
+ MAX_OPEN_FDS: 4096,
+ nextfd: function (fd_start, fd_end) {
+ fd_start = fd_start || 0;
+ fd_end = fd_end || FS.MAX_OPEN_FDS;
+ for (var fd = fd_start; fd <= fd_end; fd++) {
+ if (!FS.streams[fd]) {
+ return fd
+ }
+ }
+ throw new FS.ErrnoError(33)
+ },
+ getStream: function (fd) {
+ return FS.streams[fd]
+ },
+ createStream: function (stream, fd_start, fd_end) {
+ if (!FS.FSStream) {
+ FS.FSStream = function () {
+ };
+ FS.FSStream.prototype = {
+ object: {
+ get: function () {
+ return this.node
+ }, set: function (val) {
+ this.node = val
+ }
+ }, isRead: {
+ get: function () {
+ return (this.flags & 2097155) !== 1
+ }
+ }, isWrite: {
+ get: function () {
+ return (this.flags & 2097155) !== 0
+ }
+ }, isAppend: {
+ get: function () {
+ return this.flags & 1024
+ }
+ }
+ }
+ }
+ var newStream = new FS.FSStream;
+ for (var p in stream) {
+ newStream[p] = stream[p]
+ }
+ stream = newStream;
+ var fd = FS.nextfd(fd_start, fd_end);
+ stream.fd = fd;
+ FS.streams[fd] = stream;
+ return stream
+ },
+ closeStream: function (fd) {
+ FS.streams[fd] = null
+ },
+ chrdev_stream_ops: {
+ open: function (stream) {
+ var device = FS.getDevice(stream.node.rdev);
+ stream.stream_ops = device.stream_ops;
+ if (stream.stream_ops.open) {
+ stream.stream_ops.open(stream)
+ }
+ }, llseek: function () {
+ throw new FS.ErrnoError(70)
+ }
+ },
+ major: function (dev) {
+ return dev >> 8
+ },
+ minor: function (dev) {
+ return dev & 255
+ },
+ makedev: function (ma, mi) {
+ return ma << 8 | mi
+ },
+ registerDevice: function (dev, ops) {
+ FS.devices[dev] = {stream_ops: ops}
+ },
+ getDevice: function (dev) {
+ return FS.devices[dev]
+ },
+ getMounts: function (mount) {
+ var mounts = [];
+ var check = [mount];
+ while (check.length) {
+ var m = check.pop();
+ mounts.push(m);
+ check.push.apply(check, m.mounts)
+ }
+ return mounts
+ },
+ syncfs: function (populate, callback) {
+ if (typeof populate === "function") {
+ callback = populate;
+ populate = false
+ }
+ FS.syncFSRequests++;
+ if (FS.syncFSRequests > 1) {
+ err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work")
+ }
+ var mounts = FS.getMounts(FS.root.mount);
+ var completed = 0;
+
+ function doCallback(errCode) {
+ FS.syncFSRequests--;
+ return callback(errCode)
+ }
+
+ function done(errCode) {
+ if (errCode) {
+ if (!done.errored) {
+ done.errored = true;
+ return doCallback(errCode)
+ }
+ return
+ }
+ if (++completed >= mounts.length) {
+ doCallback(null)
+ }
+ }
+
+ mounts.forEach(function (mount) {
+ if (!mount.type.syncfs) {
+ return done(null)
+ }
+ mount.type.syncfs(mount, populate, done)
+ })
+ },
+ mount: function (type, opts, mountpoint) {
+ var root = mountpoint === "/";
+ var pseudo = !mountpoint;
+ var node;
+ if (root && FS.root) {
+ throw new FS.ErrnoError(10)
+ } else if (!root && !pseudo) {
+ var lookup = FS.lookupPath(mountpoint, {follow_mount: false});
+ mountpoint = lookup.path;
+ node = lookup.node;
+ if (FS.isMountpoint(node)) {
+ throw new FS.ErrnoError(10)
+ }
+ if (!FS.isDir(node.mode)) {
+ throw new FS.ErrnoError(54)
+ }
+ }
+ var mount = {type: type, opts: opts, mountpoint: mountpoint, mounts: []};
+ var mountRoot = type.mount(mount);
+ mountRoot.mount = mount;
+ mount.root = mountRoot;
+ if (root) {
+ FS.root = mountRoot
+ } else if (node) {
+ node.mounted = mount;
+ if (node.mount) {
+ node.mount.mounts.push(mount)
+ }
+ }
+ return mountRoot
+ },
+ unmount: function (mountpoint) {
+ var lookup = FS.lookupPath(mountpoint, {follow_mount: false});
+ if (!FS.isMountpoint(lookup.node)) {
+ throw new FS.ErrnoError(28)
+ }
+ var node = lookup.node;
+ var mount = node.mounted;
+ var mounts = FS.getMounts(mount);
+ Object.keys(FS.nameTable).forEach(function (hash) {
+ var current = FS.nameTable[hash];
+ while (current) {
+ var next = current.name_next;
+ if (mounts.indexOf(current.mount) !== -1) {
+ FS.destroyNode(current)
+ }
+ current = next
+ }
+ });
+ node.mounted = null;
+ var idx = node.mount.mounts.indexOf(mount);
+ node.mount.mounts.splice(idx, 1)
+ },
+ lookup: function (parent, name) {
+ return parent.node_ops.lookup(parent, name)
+ },
+ mknod: function (path, mode, dev) {
+ var lookup = FS.lookupPath(path, {parent: true});
+ var parent = lookup.node;
+ var name = PATH.basename(path);
+ if (!name || name === "." || name === "..") {
+ throw new FS.ErrnoError(28)
+ }
+ var errCode = FS.mayCreate(parent, name);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ if (!parent.node_ops.mknod) {
+ throw new FS.ErrnoError(63)
+ }
+ return parent.node_ops.mknod(parent, name, mode, dev)
+ },
+ create: function (path, mode) {
+ mode = mode !== undefined ? mode : 438;
+ mode &= 4095;
+ mode |= 32768;
+ return FS.mknod(path, mode, 0)
+ },
+ mkdir: function (path, mode) {
+ mode = mode !== undefined ? mode : 511;
+ mode &= 511 | 512;
+ mode |= 16384;
+ return FS.mknod(path, mode, 0)
+ },
+ mkdirTree: function (path, mode) {
+ var dirs = path.split("/");
+ var d = "";
+ for (var i = 0; i < dirs.length; ++i) {
+ if (!dirs[i]) continue;
+ d += "/" + dirs[i];
+ try {
+ FS.mkdir(d, mode)
+ } catch (e) {
+ if (e.errno != 20) throw e
+ }
+ }
+ },
+ mkdev: function (path, mode, dev) {
+ if (typeof dev === "undefined") {
+ dev = mode;
+ mode = 438
+ }
+ mode |= 8192;
+ return FS.mknod(path, mode, dev)
+ },
+ symlink: function (oldpath, newpath) {
+ if (!PATH_FS.resolve(oldpath)) {
+ throw new FS.ErrnoError(44)
+ }
+ var lookup = FS.lookupPath(newpath, {parent: true});
+ var parent = lookup.node;
+ if (!parent) {
+ throw new FS.ErrnoError(44)
+ }
+ var newname = PATH.basename(newpath);
+ var errCode = FS.mayCreate(parent, newname);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ if (!parent.node_ops.symlink) {
+ throw new FS.ErrnoError(63)
+ }
+ return parent.node_ops.symlink(parent, newname, oldpath)
+ },
+ rename: function (old_path, new_path) {
+ var old_dirname = PATH.dirname(old_path);
+ var new_dirname = PATH.dirname(new_path);
+ var old_name = PATH.basename(old_path);
+ var new_name = PATH.basename(new_path);
+ var lookup, old_dir, new_dir;
+ try {
+ lookup = FS.lookupPath(old_path, {parent: true});
+ old_dir = lookup.node;
+ lookup = FS.lookupPath(new_path, {parent: true});
+ new_dir = lookup.node
+ } catch (e) {
+ throw new FS.ErrnoError(10)
+ }
+ if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
+ if (old_dir.mount !== new_dir.mount) {
+ throw new FS.ErrnoError(75)
+ }
+ var old_node = FS.lookupNode(old_dir, old_name);
+ var relative = PATH_FS.relative(old_path, new_dirname);
+ if (relative.charAt(0) !== ".") {
+ throw new FS.ErrnoError(28)
+ }
+ relative = PATH_FS.relative(new_path, old_dirname);
+ if (relative.charAt(0) !== ".") {
+ throw new FS.ErrnoError(55)
+ }
+ var new_node;
+ try {
+ new_node = FS.lookupNode(new_dir, new_name)
+ } catch (e) {
+ }
+ if (old_node === new_node) {
+ return
+ }
+ var isdir = FS.isDir(old_node.mode);
+ var errCode = FS.mayDelete(old_dir, old_name, isdir);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ if (!old_dir.node_ops.rename) {
+ throw new FS.ErrnoError(63)
+ }
+ if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) {
+ throw new FS.ErrnoError(10)
+ }
+ if (new_dir !== old_dir) {
+ errCode = FS.nodePermissions(old_dir, "w");
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ }
+ try {
+ if (FS.trackingDelegate["willMovePath"]) {
+ FS.trackingDelegate["willMovePath"](old_path, new_path)
+ }
+ } catch (e) {
+ err("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message)
+ }
+ FS.hashRemoveNode(old_node);
+ try {
+ old_dir.node_ops.rename(old_node, new_dir, new_name)
+ } catch (e) {
+ throw e
+ } finally {
+ FS.hashAddNode(old_node)
+ }
+ try {
+ if (FS.trackingDelegate["onMovePath"]) FS.trackingDelegate["onMovePath"](old_path, new_path)
+ } catch (e) {
+ err("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message)
+ }
+ },
+ rmdir: function (path) {
+ var lookup = FS.lookupPath(path, {parent: true});
+ var parent = lookup.node;
+ var name = PATH.basename(path);
+ var node = FS.lookupNode(parent, name);
+ var errCode = FS.mayDelete(parent, name, true);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ if (!parent.node_ops.rmdir) {
+ throw new FS.ErrnoError(63)
+ }
+ if (FS.isMountpoint(node)) {
+ throw new FS.ErrnoError(10)
+ }
+ try {
+ if (FS.trackingDelegate["willDeletePath"]) {
+ FS.trackingDelegate["willDeletePath"](path)
+ }
+ } catch (e) {
+ err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message)
+ }
+ parent.node_ops.rmdir(parent, name);
+ FS.destroyNode(node);
+ try {
+ if (FS.trackingDelegate["onDeletePath"]) FS.trackingDelegate["onDeletePath"](path)
+ } catch (e) {
+ err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message)
+ }
+ },
+ readdir: function (path) {
+ var lookup = FS.lookupPath(path, {follow: true});
+ var node = lookup.node;
+ if (!node.node_ops.readdir) {
+ throw new FS.ErrnoError(54)
+ }
+ return node.node_ops.readdir(node)
+ },
+ unlink: function (path) {
+ var lookup = FS.lookupPath(path, {parent: true});
+ var parent = lookup.node;
+ var name = PATH.basename(path);
+ var node = FS.lookupNode(parent, name);
+ var errCode = FS.mayDelete(parent, name, false);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ if (!parent.node_ops.unlink) {
+ throw new FS.ErrnoError(63)
+ }
+ if (FS.isMountpoint(node)) {
+ throw new FS.ErrnoError(10)
+ }
+ try {
+ if (FS.trackingDelegate["willDeletePath"]) {
+ FS.trackingDelegate["willDeletePath"](path)
+ }
+ } catch (e) {
+ err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message)
+ }
+ parent.node_ops.unlink(parent, name);
+ FS.destroyNode(node);
+ try {
+ if (FS.trackingDelegate["onDeletePath"]) FS.trackingDelegate["onDeletePath"](path)
+ } catch (e) {
+ err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message)
+ }
+ },
+ readlink: function (path) {
+ var lookup = FS.lookupPath(path);
+ var link = lookup.node;
+ if (!link) {
+ throw new FS.ErrnoError(44)
+ }
+ if (!link.node_ops.readlink) {
+ throw new FS.ErrnoError(28)
+ }
+ return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link))
+ },
+ stat: function (path, dontFollow) {
+ var lookup = FS.lookupPath(path, {follow: !dontFollow});
+ var node = lookup.node;
+ if (!node) {
+ throw new FS.ErrnoError(44)
+ }
+ if (!node.node_ops.getattr) {
+ throw new FS.ErrnoError(63)
+ }
+ return node.node_ops.getattr(node)
+ },
+ lstat: function (path) {
+ return FS.stat(path, true)
+ },
+ chmod: function (path, mode, dontFollow) {
+ var node;
+ if (typeof path === "string") {
+ var lookup = FS.lookupPath(path, {follow: !dontFollow});
+ node = lookup.node
+ } else {
+ node = path
+ }
+ if (!node.node_ops.setattr) {
+ throw new FS.ErrnoError(63)
+ }
+ node.node_ops.setattr(node, {mode: mode & 4095 | node.mode & ~4095, timestamp: Date.now()})
+ },
+ lchmod: function (path, mode) {
+ FS.chmod(path, mode, true)
+ },
+ fchmod: function (fd, mode) {
+ var stream = FS.getStream(fd);
+ if (!stream) {
+ throw new FS.ErrnoError(8)
+ }
+ FS.chmod(stream.node, mode)
+ },
+ chown: function (path, uid, gid, dontFollow) {
+ var node;
+ if (typeof path === "string") {
+ var lookup = FS.lookupPath(path, {follow: !dontFollow});
+ node = lookup.node
+ } else {
+ node = path
+ }
+ if (!node.node_ops.setattr) {
+ throw new FS.ErrnoError(63)
+ }
+ node.node_ops.setattr(node, {timestamp: Date.now()})
+ },
+ lchown: function (path, uid, gid) {
+ FS.chown(path, uid, gid, true)
+ },
+ fchown: function (fd, uid, gid) {
+ var stream = FS.getStream(fd);
+ if (!stream) {
+ throw new FS.ErrnoError(8)
+ }
+ FS.chown(stream.node, uid, gid)
+ },
+ truncate: function (path, len) {
+ if (len < 0) {
+ throw new FS.ErrnoError(28)
+ }
+ var node;
+ if (typeof path === "string") {
+ var lookup = FS.lookupPath(path, {follow: true});
+ node = lookup.node
+ } else {
+ node = path
+ }
+ if (!node.node_ops.setattr) {
+ throw new FS.ErrnoError(63)
+ }
+ if (FS.isDir(node.mode)) {
+ throw new FS.ErrnoError(31)
+ }
+ if (!FS.isFile(node.mode)) {
+ throw new FS.ErrnoError(28)
+ }
+ var errCode = FS.nodePermissions(node, "w");
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ node.node_ops.setattr(node, {size: len, timestamp: Date.now()})
+ },
+ ftruncate: function (fd, len) {
+ var stream = FS.getStream(fd);
+ if (!stream) {
+ throw new FS.ErrnoError(8)
+ }
+ if ((stream.flags & 2097155) === 0) {
+ throw new FS.ErrnoError(28)
+ }
+ FS.truncate(stream.node, len)
+ },
+ utime: function (path, atime, mtime) {
+ var lookup = FS.lookupPath(path, {follow: true});
+ var node = lookup.node;
+ node.node_ops.setattr(node, {timestamp: Math.max(atime, mtime)})
+ },
+ open: function (path, flags, mode, fd_start, fd_end) {
+ if (path === "") {
+ throw new FS.ErrnoError(44)
+ }
+ flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags;
+ mode = typeof mode === "undefined" ? 438 : mode;
+ if (flags & 64) {
+ mode = mode & 4095 | 32768
+ } else {
+ mode = 0
+ }
+ var node;
+ if (typeof path === "object") {
+ node = path
+ } else {
+ path = PATH.normalize(path);
+ try {
+ var lookup = FS.lookupPath(path, {follow: !(flags & 131072)});
+ node = lookup.node
+ } catch (e) {
+ }
+ }
+ var created = false;
+ if (flags & 64) {
+ if (node) {
+ if (flags & 128) {
+ throw new FS.ErrnoError(20)
+ }
+ } else {
+ node = FS.mknod(path, mode, 0);
+ created = true
+ }
+ }
+ if (!node) {
+ throw new FS.ErrnoError(44)
+ }
+ if (FS.isChrdev(node.mode)) {
+ flags &= ~512
+ }
+ if (flags & 65536 && !FS.isDir(node.mode)) {
+ throw new FS.ErrnoError(54)
+ }
+ if (!created) {
+ var errCode = FS.mayOpen(node, flags);
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ }
+ if (flags & 512) {
+ FS.truncate(node, 0)
+ }
+ flags &= ~(128 | 512 | 131072);
+ var stream = FS.createStream({
+ node: node,
+ path: FS.getPath(node),
+ flags: flags,
+ seekable: true,
+ position: 0,
+ stream_ops: node.stream_ops,
+ ungotten: [],
+ error: false
+ }, fd_start, fd_end);
+ if (stream.stream_ops.open) {
+ stream.stream_ops.open(stream)
+ }
+ if (Module["logReadFiles"] && !(flags & 1)) {
+ if (!FS.readFiles) FS.readFiles = {};
+ if (!(path in FS.readFiles)) {
+ FS.readFiles[path] = 1;
+ err("FS.trackingDelegate error on read file: " + path)
+ }
+ }
+ try {
+ if (FS.trackingDelegate["onOpenFile"]) {
+ var trackingFlags = 0;
+ if ((flags & 2097155) !== 1) {
+ trackingFlags |= FS.tracking.openFlags.READ
+ }
+ if ((flags & 2097155) !== 0) {
+ trackingFlags |= FS.tracking.openFlags.WRITE
+ }
+ FS.trackingDelegate["onOpenFile"](path, trackingFlags)
+ }
+ } catch (e) {
+ err("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message)
+ }
+ return stream
+ },
+ close: function (stream) {
+ if (FS.isClosed(stream)) {
+ throw new FS.ErrnoError(8)
+ }
+ if (stream.getdents) stream.getdents = null;
+ try {
+ if (stream.stream_ops.close) {
+ stream.stream_ops.close(stream)
+ }
+ } catch (e) {
+ throw e
+ } finally {
+ FS.closeStream(stream.fd)
+ }
+ stream.fd = null
+ },
+ isClosed: function (stream) {
+ return stream.fd === null
+ },
+ llseek: function (stream, offset, whence) {
+ if (FS.isClosed(stream)) {
+ throw new FS.ErrnoError(8)
+ }
+ if (!stream.seekable || !stream.stream_ops.llseek) {
+ throw new FS.ErrnoError(70)
+ }
+ if (whence != 0 && whence != 1 && whence != 2) {
+ throw new FS.ErrnoError(28)
+ }
+ stream.position = stream.stream_ops.llseek(stream, offset, whence);
+ stream.ungotten = [];
+ return stream.position
+ },
+ read: function (stream, buffer, offset, length, position) {
+ if (length < 0 || position < 0) {
+ throw new FS.ErrnoError(28)
+ }
+ if (FS.isClosed(stream)) {
+ throw new FS.ErrnoError(8)
+ }
+ if ((stream.flags & 2097155) === 1) {
+ throw new FS.ErrnoError(8)
+ }
+ if (FS.isDir(stream.node.mode)) {
+ throw new FS.ErrnoError(31)
+ }
+ if (!stream.stream_ops.read) {
+ throw new FS.ErrnoError(28)
+ }
+ var seeking = typeof position !== "undefined";
+ if (!seeking) {
+ position = stream.position
+ } else if (!stream.seekable) {
+ throw new FS.ErrnoError(70)
+ }
+ var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+ if (!seeking) stream.position += bytesRead;
+ return bytesRead
+ },
+ write: function (stream, buffer, offset, length, position, canOwn) {
+ if (length < 0 || position < 0) {
+ throw new FS.ErrnoError(28)
+ }
+ if (FS.isClosed(stream)) {
+ throw new FS.ErrnoError(8)
+ }
+ if ((stream.flags & 2097155) === 0) {
+ throw new FS.ErrnoError(8)
+ }
+ if (FS.isDir(stream.node.mode)) {
+ throw new FS.ErrnoError(31)
+ }
+ if (!stream.stream_ops.write) {
+ throw new FS.ErrnoError(28)
+ }
+ if (stream.seekable && stream.flags & 1024) {
+ FS.llseek(stream, 0, 2)
+ }
+ var seeking = typeof position !== "undefined";
+ if (!seeking) {
+ position = stream.position
+ } else if (!stream.seekable) {
+ throw new FS.ErrnoError(70)
+ }
+ var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+ if (!seeking) stream.position += bytesWritten;
+ try {
+ if (stream.path && FS.trackingDelegate["onWriteToFile"]) FS.trackingDelegate["onWriteToFile"](stream.path)
+ } catch (e) {
+ err("FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message)
+ }
+ return bytesWritten
+ },
+ allocate: function (stream, offset, length) {
+ if (FS.isClosed(stream)) {
+ throw new FS.ErrnoError(8)
+ }
+ if (offset < 0 || length <= 0) {
+ throw new FS.ErrnoError(28)
+ }
+ if ((stream.flags & 2097155) === 0) {
+ throw new FS.ErrnoError(8)
+ }
+ if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
+ throw new FS.ErrnoError(43)
+ }
+ if (!stream.stream_ops.allocate) {
+ throw new FS.ErrnoError(138)
+ }
+ stream.stream_ops.allocate(stream, offset, length)
+ },
+ mmap: function (stream, address, length, position, prot, flags) {
+ if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) {
+ throw new FS.ErrnoError(2)
+ }
+ if ((stream.flags & 2097155) === 1) {
+ throw new FS.ErrnoError(2)
+ }
+ if (!stream.stream_ops.mmap) {
+ throw new FS.ErrnoError(43)
+ }
+ return stream.stream_ops.mmap(stream, address, length, position, prot, flags)
+ },
+ msync: function (stream, buffer, offset, length, mmapFlags) {
+ if (!stream || !stream.stream_ops.msync) {
+ return 0
+ }
+ return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags)
+ },
+ munmap: function (stream) {
+ return 0
+ },
+ ioctl: function (stream, cmd, arg) {
+ if (!stream.stream_ops.ioctl) {
+ throw new FS.ErrnoError(59)
+ }
+ return stream.stream_ops.ioctl(stream, cmd, arg)
+ },
+ readFile: function (path, opts) {
+ opts = opts || {};
+ opts.flags = opts.flags || "r";
+ opts.encoding = opts.encoding || "binary";
+ if (opts.encoding !== "utf8" && opts.encoding !== "binary") {
+ throw new Error('Invalid encoding type "' + opts.encoding + '"')
+ }
+ var ret;
+ var stream = FS.open(path, opts.flags);
+ var stat = FS.stat(path);
+ var length = stat.size;
+ var buf = new Uint8Array(length);
+ FS.read(stream, buf, 0, length, 0);
+ if (opts.encoding === "utf8") {
+ ret = UTF8ArrayToString(buf, 0)
+ } else if (opts.encoding === "binary") {
+ ret = buf
+ }
+ FS.close(stream);
+ return ret
+ },
+ writeFile: function (path, data, opts) {
+ opts = opts || {};
+ opts.flags = opts.flags || "w";
+ var stream = FS.open(path, opts.flags, opts.mode);
+ if (typeof data === "string") {
+ var buf = new Uint8Array(lengthBytesUTF8(data) + 1);
+ var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
+ FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn)
+ } else if (ArrayBuffer.isView(data)) {
+ FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn)
+ } else {
+ throw new Error("Unsupported data type")
+ }
+ FS.close(stream)
+ },
+ cwd: function () {
+ return FS.currentPath
+ },
+ chdir: function (path) {
+ var lookup = FS.lookupPath(path, {follow: true});
+ if (lookup.node === null) {
+ throw new FS.ErrnoError(44)
+ }
+ if (!FS.isDir(lookup.node.mode)) {
+ throw new FS.ErrnoError(54)
+ }
+ var errCode = FS.nodePermissions(lookup.node, "x");
+ if (errCode) {
+ throw new FS.ErrnoError(errCode)
+ }
+ FS.currentPath = lookup.path
+ },
+ createDefaultDirectories: function () {
+ FS.mkdir("/tmp");
+ FS.mkdir("/home");
+ FS.mkdir("/home/web_user")
+ },
+ createDefaultDevices: function () {
+ FS.mkdir("/dev");
+ FS.registerDevice(FS.makedev(1, 3), {
+ read: function () {
+ return 0
+ }, write: function (stream, buffer, offset, length, pos) {
+ return length
+ }
+ });
+ FS.mkdev("/dev/null", FS.makedev(1, 3));
+ TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+ TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+ FS.mkdev("/dev/tty", FS.makedev(5, 0));
+ FS.mkdev("/dev/tty1", FS.makedev(6, 0));
+ var random_device;
+ if (typeof crypto === "object" && typeof crypto["getRandomValues"] === "function") {
+ var randomBuffer = new Uint8Array(1);
+ random_device = function () {
+ crypto.getRandomValues(randomBuffer);
+ return randomBuffer[0]
+ }
+ } else if (ENVIRONMENT_IS_NODE) {
+ try {
+ var crypto_module = require("crypto");
+ random_device = function () {
+ return crypto_module["randomBytes"](1)[0]
+ }
+ } catch (e) {
+ }
+ } else {
+ }
+ if (!random_device) {
+ random_device = function () {
+ abort("random_device")
+ }
+ }
+ FS.createDevice("/dev", "random", random_device);
+ FS.createDevice("/dev", "urandom", random_device);
+ FS.mkdir("/dev/shm");
+ FS.mkdir("/dev/shm/tmp")
+ },
+ createSpecialDirectories: function () {
+ FS.mkdir("/proc");
+ FS.mkdir("/proc/self");
+ FS.mkdir("/proc/self/fd");
+ FS.mount({
+ mount: function () {
+ var node = FS.createNode("/proc/self", "fd", 16384 | 511, 73);
+ node.node_ops = {
+ lookup: function (parent, name) {
+ var fd = +name;
+ var stream = FS.getStream(fd);
+ if (!stream) throw new FS.ErrnoError(8);
+ var ret = {
+ parent: null,
+ mount: {mountpoint: "fake"},
+ node_ops: {
+ readlink: function () {
+ return stream.path
+ }
+ }
+ };
+ ret.parent = ret;
+ return ret
+ }
+ };
+ return node
+ }
+ }, {}, "/proc/self/fd")
+ },
+ createStandardStreams: function () {
+ if (Module["stdin"]) {
+ FS.createDevice("/dev", "stdin", Module["stdin"])
+ } else {
+ FS.symlink("/dev/tty", "/dev/stdin")
+ }
+ if (Module["stdout"]) {
+ FS.createDevice("/dev", "stdout", null, Module["stdout"])
+ } else {
+ FS.symlink("/dev/tty", "/dev/stdout")
+ }
+ if (Module["stderr"]) {
+ FS.createDevice("/dev", "stderr", null, Module["stderr"])
+ } else {
+ FS.symlink("/dev/tty1", "/dev/stderr")
+ }
+ var stdin = FS.open("/dev/stdin", "r");
+ var stdout = FS.open("/dev/stdout", "w");
+ var stderr = FS.open("/dev/stderr", "w")
+ },
+ ensureErrnoError: function () {
+ if (FS.ErrnoError) return;
+ FS.ErrnoError = function ErrnoError(errno, node) {
+ this.node = node;
+ this.setErrno = function (errno) {
+ this.errno = errno
+ };
+ this.setErrno(errno);
+ this.message = "FS error"
+ };
+ FS.ErrnoError.prototype = new Error;
+ FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+ [44].forEach(function (code) {
+ FS.genericErrors[code] = new FS.ErrnoError(code);
+ FS.genericErrors[code].stack = ""
+ })
+ },
+ staticInit: function () {
+ FS.ensureErrnoError();
+ FS.nameTable = new Array(4096);
+ FS.mount(MEMFS, {}, "/");
+ FS.createDefaultDirectories();
+ FS.createDefaultDevices();
+ FS.createSpecialDirectories();
+ FS.filesystems = {"MEMFS": MEMFS}
+ },
+ init: function (input, output, error) {
+ FS.init.initialized = true;
+ FS.ensureErrnoError();
+ Module["stdin"] = input || Module["stdin"];
+ Module["stdout"] = output || Module["stdout"];
+ Module["stderr"] = error || Module["stderr"];
+ FS.createStandardStreams()
+ },
+ quit: function () {
+ FS.init.initialized = false;
+ var fflush = Module["_fflush"];
+ if (fflush) fflush(0);
+ for (var i = 0; i < FS.streams.length; i++) {
+ var stream = FS.streams[i];
+ if (!stream) {
+ continue
+ }
+ FS.close(stream)
+ }
+ },
+ getMode: function (canRead, canWrite) {
+ var mode = 0;
+ if (canRead) mode |= 292 | 73;
+ if (canWrite) mode |= 146;
+ return mode
+ },
+ joinPath: function (parts, forceRelative) {
+ var path = PATH.join.apply(null, parts);
+ if (forceRelative && path[0] == "/") path = path.substr(1);
+ return path
+ },
+ absolutePath: function (relative, base) {
+ return PATH_FS.resolve(base, relative)
+ },
+ standardizePath: function (path) {
+ return PATH.normalize(path)
+ },
+ findObject: function (path, dontResolveLastLink) {
+ var ret = FS.analyzePath(path, dontResolveLastLink);
+ if (ret.exists) {
+ return ret.object
+ } else {
+ setErrNo(ret.error);
+ return null
+ }
+ },
+ analyzePath: function (path, dontResolveLastLink) {
+ try {
+ var lookup = FS.lookupPath(path, {follow: !dontResolveLastLink});
+ path = lookup.path
+ } catch (e) {
+ }
+ var ret = {
+ isRoot: false,
+ exists: false,
+ error: 0,
+ name: null,
+ path: null,
+ object: null,
+ parentExists: false,
+ parentPath: null,
+ parentObject: null
+ };
+ try {
+ var lookup = FS.lookupPath(path, {parent: true});
+ ret.parentExists = true;
+ ret.parentPath = lookup.path;
+ ret.parentObject = lookup.node;
+ ret.name = PATH.basename(path);
+ lookup = FS.lookupPath(path, {follow: !dontResolveLastLink});
+ ret.exists = true;
+ ret.path = lookup.path;
+ ret.object = lookup.node;
+ ret.name = lookup.node.name;
+ ret.isRoot = lookup.path === "/"
+ } catch (e) {
+ ret.error = e.errno
+ }
+ return ret
+ },
+ createFolder: function (parent, name, canRead, canWrite) {
+ var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name);
+ var mode = FS.getMode(canRead, canWrite);
+ return FS.mkdir(path, mode)
+ },
+ createPath: function (parent, path, canRead, canWrite) {
+ parent = typeof parent === "string" ? parent : FS.getPath(parent);
+ var parts = path.split("/").reverse();
+ while (parts.length) {
+ var part = parts.pop();
+ if (!part) continue;
+ var current = PATH.join2(parent, part);
+ try {
+ FS.mkdir(current)
+ } catch (e) {
+ }
+ parent = current
+ }
+ return current
+ },
+ createFile: function (parent, name, properties, canRead, canWrite) {
+ var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name);
+ var mode = FS.getMode(canRead, canWrite);
+ return FS.create(path, mode)
+ },
+ createDataFile: function (parent, name, data, canRead, canWrite, canOwn) {
+ var path = name ? PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name) : parent;
+ var mode = FS.getMode(canRead, canWrite);
+ var node = FS.create(path, mode);
+ if (data) {
+ if (typeof data === "string") {
+ var arr = new Array(data.length);
+ for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+ data = arr
+ }
+ FS.chmod(node, mode | 146);
+ var stream = FS.open(node, "w");
+ FS.write(stream, data, 0, data.length, 0, canOwn);
+ FS.close(stream);
+ FS.chmod(node, mode)
+ }
+ return node
+ },
+ createDevice: function (parent, name, input, output) {
+ var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name);
+ var mode = FS.getMode(!!input, !!output);
+ if (!FS.createDevice.major) FS.createDevice.major = 64;
+ var dev = FS.makedev(FS.createDevice.major++, 0);
+ FS.registerDevice(dev, {
+ open: function (stream) {
+ stream.seekable = false
+ }, close: function (stream) {
+ if (output && output.buffer && output.buffer.length) {
+ output(10)
+ }
+ }, read: function (stream, buffer, offset, length, pos) {
+ var bytesRead = 0;
+ for (var i = 0; i < length; i++) {
+ var result;
+ try {
+ result = input()
+ } catch (e) {
+ throw new FS.ErrnoError(29)
+ }
+ if (result === undefined && bytesRead === 0) {
+ throw new FS.ErrnoError(6)
+ }
+ if (result === null || result === undefined) break;
+ bytesRead++;
+ buffer[offset + i] = result
+ }
+ if (bytesRead) {
+ stream.node.timestamp = Date.now()
+ }
+ return bytesRead
+ }, write: function (stream, buffer, offset, length, pos) {
+ for (var i = 0; i < length; i++) {
+ try {
+ output(buffer[offset + i])
+ } catch (e) {
+ throw new FS.ErrnoError(29)
+ }
+ }
+ if (length) {
+ stream.node.timestamp = Date.now()
+ }
+ return i
+ }
+ });
+ return FS.mkdev(path, mode, dev)
+ },
+ createLink: function (parent, name, target, canRead, canWrite) {
+ var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name);
+ return FS.symlink(target, path)
+ },
+ forceLoadFile: function (obj) {
+ if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+ var success = true;
+ if (typeof XMLHttpRequest !== "undefined") {
+ throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")
+ } else if (read_) {
+ try {
+ obj.contents = intArrayFromString(read_(obj.url), true);
+ obj.usedBytes = obj.contents.length
+ } catch (e) {
+ success = false
+ }
+ } else {
+ throw new Error("Cannot load without read() or XMLHttpRequest.")
+ }
+ if (!success) setErrNo(29);
+ return success
+ },
+ createLazyFile: function (parent, name, url, canRead, canWrite) {
+ function LazyUint8Array() {
+ this.lengthKnown = false;
+ this.chunks = []
+ }
+
+ LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+ if (idx > this.length - 1 || idx < 0) {
+ return undefined
+ }
+ var chunkOffset = idx % this.chunkSize;
+ var chunkNum = idx / this.chunkSize | 0;
+ return this.getter(chunkNum)[chunkOffset]
+ };
+ LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+ this.getter = getter
+ };
+ LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+ var xhr = new XMLHttpRequest;
+ xhr.open("HEAD", url, false);
+ xhr.send(null);
+ if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+ var datalength = Number(xhr.getResponseHeader("Content-length"));
+ var header;
+ var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+ var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
+ var chunkSize = 1024 * 1024;
+ if (!hasByteServing) chunkSize = datalength;
+ var doXHR = function (from, to) {
+ if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+ if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!");
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", url, false);
+ if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+ if (typeof Uint8Array != "undefined") xhr.responseType = "arraybuffer";
+ if (xhr.overrideMimeType) {
+ xhr.overrideMimeType("text/plain; charset=x-user-defined")
+ }
+ xhr.send(null);
+ if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+ if (xhr.response !== undefined) {
+ return new Uint8Array(xhr.response || [])
+ } else {
+ return intArrayFromString(xhr.responseText || "", true)
+ }
+ };
+ var lazyArray = this;
+ lazyArray.setDataGetter(function (chunkNum) {
+ var start = chunkNum * chunkSize;
+ var end = (chunkNum + 1) * chunkSize - 1;
+ end = Math.min(end, datalength - 1);
+ if (typeof lazyArray.chunks[chunkNum] === "undefined") {
+ lazyArray.chunks[chunkNum] = doXHR(start, end)
+ }
+ if (typeof lazyArray.chunks[chunkNum] === "undefined") throw new Error("doXHR failed!");
+ return lazyArray.chunks[chunkNum]
+ });
+ if (usesGzip || !datalength) {
+ chunkSize = datalength = 1;
+ datalength = this.getter(0).length;
+ chunkSize = datalength;
+ out("LazyFiles on gzip forces download of the whole file when length is accessed")
+ }
+ this._length = datalength;
+ this._chunkSize = chunkSize;
+ this.lengthKnown = true
+ };
+ if (typeof XMLHttpRequest !== "undefined") {
+ if (!ENVIRONMENT_IS_WORKER) throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";
+ var lazyArray = new LazyUint8Array;
+ Object.defineProperties(lazyArray, {
+ length: {
+ get: function () {
+ if (!this.lengthKnown) {
+ this.cacheLength()
+ }
+ return this._length
+ }
+ }, chunkSize: {
+ get: function () {
+ if (!this.lengthKnown) {
+ this.cacheLength()
+ }
+ return this._chunkSize
+ }
+ }
+ });
+ var properties = {isDevice: false, contents: lazyArray}
+ } else {
+ var properties = {isDevice: false, url: url}
+ }
+ var node = FS.createFile(parent, name, properties, canRead, canWrite);
+ if (properties.contents) {
+ node.contents = properties.contents
+ } else if (properties.url) {
+ node.contents = null;
+ node.url = properties.url
+ }
+ Object.defineProperties(node, {
+ usedBytes: {
+ get: function () {
+ return this.contents.length
+ }
+ }
+ });
+ var stream_ops = {};
+ var keys = Object.keys(node.stream_ops);
+ keys.forEach(function (key) {
+ var fn = node.stream_ops[key];
+ stream_ops[key] = function forceLoadLazyFile() {
+ if (!FS.forceLoadFile(node)) {
+ throw new FS.ErrnoError(29)
+ }
+ return fn.apply(null, arguments)
+ }
+ });
+ stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+ if (!FS.forceLoadFile(node)) {
+ throw new FS.ErrnoError(29)
+ }
+ var contents = stream.node.contents;
+ if (position >= contents.length) return 0;
+ var size = Math.min(contents.length - position, length);
+ if (contents.slice) {
+ for (var i = 0; i < size; i++) {
+ buffer[offset + i] = contents[position + i]
+ }
+ } else {
+ for (var i = 0; i < size; i++) {
+ buffer[offset + i] = contents.get(position + i)
+ }
+ }
+ return size
+ };
+ node.stream_ops = stream_ops;
+ return node
+ },
+ createPreloadedFile: function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) {
+ Browser.init();
+ var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
+ var dep = getUniqueRunDependency("cp " + fullname);
+
+ function processData(byteArray) {
+ function finish(byteArray) {
+ if (preFinish) preFinish();
+ if (!dontCreateFile) {
+ FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn)
+ }
+ if (onload) onload();
+ removeRunDependency(dep)
+ }
+
+ var handled = false;
+ Module["preloadPlugins"].forEach(function (plugin) {
+ if (handled) return;
+ if (plugin["canHandle"](fullname)) {
+ plugin["handle"](byteArray, fullname, finish, function () {
+ if (onerror) onerror();
+ removeRunDependency(dep)
+ });
+ handled = true
+ }
+ });
+ if (!handled) finish(byteArray)
+ }
+
+ addRunDependency(dep);
+ if (typeof url == "string") {
+ Browser.asyncLoad(url, function (byteArray) {
+ processData(byteArray)
+ }, onerror)
+ } else {
+ processData(url)
+ }
+ },
+ indexedDB: function () {
+ return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
+ },
+ DB_NAME: function () {
+ return "EM_FS_" + window.location.pathname
+ },
+ DB_VERSION: 20,
+ DB_STORE_NAME: "FILE_DATA",
+ saveFilesToDB: function (paths, onload, onerror) {
+ onload = onload || function () {
+ };
+ onerror = onerror || function () {
+ };
+ var indexedDB = FS.indexedDB();
+ try {
+ var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION)
+ } catch (e) {
+ return onerror(e)
+ }
+ openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+ out("creating db");
+ var db = openRequest.result;
+ db.createObjectStore(FS.DB_STORE_NAME)
+ };
+ openRequest.onsuccess = function openRequest_onsuccess() {
+ var db = openRequest.result;
+ var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite");
+ var files = transaction.objectStore(FS.DB_STORE_NAME);
+ var ok = 0, fail = 0, total = paths.length;
+
+ function finish() {
+ if (fail == 0) onload(); else onerror()
+ }
+
+ paths.forEach(function (path) {
+ var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+ putRequest.onsuccess = function putRequest_onsuccess() {
+ ok++;
+ if (ok + fail == total) finish()
+ };
+ putRequest.onerror = function putRequest_onerror() {
+ fail++;
+ if (ok + fail == total) finish()
+ }
+ });
+ transaction.onerror = onerror
+ };
+ openRequest.onerror = onerror
+ },
+ loadFilesFromDB: function (paths, onload, onerror) {
+ onload = onload || function () {
+ };
+ onerror = onerror || function () {
+ };
+ var indexedDB = FS.indexedDB();
+ try {
+ var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION)
+ } catch (e) {
+ return onerror(e)
+ }
+ openRequest.onupgradeneeded = onerror;
+ openRequest.onsuccess = function openRequest_onsuccess() {
+ var db = openRequest.result;
+ try {
+ var transaction = db.transaction([FS.DB_STORE_NAME], "readonly")
+ } catch (e) {
+ onerror(e);
+ return
+ }
+ var files = transaction.objectStore(FS.DB_STORE_NAME);
+ var ok = 0, fail = 0, total = paths.length;
+
+ function finish() {
+ if (fail == 0) onload(); else onerror()
+ }
+
+ paths.forEach(function (path) {
+ var getRequest = files.get(path);
+ getRequest.onsuccess = function getRequest_onsuccess() {
+ if (FS.analyzePath(path).exists) {
+ FS.unlink(path)
+ }
+ FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+ ok++;
+ if (ok + fail == total) finish()
+ };
+ getRequest.onerror = function getRequest_onerror() {
+ fail++;
+ if (ok + fail == total) finish()
+ }
+ });
+ transaction.onerror = onerror
+ };
+ openRequest.onerror = onerror
+ },
+ mmapAlloc: function (size) {
+ var alignedSize = alignMemory(size, 16384);
+ var ptr = _malloc(alignedSize);
+ while (size < alignedSize) HEAP8[ptr + size++] = 0;
+ return ptr
+ }
+ };
+ var SYSCALLS = {
+ mappings: {}, DEFAULT_POLLMASK: 5, umask: 511, calculateAt: function (dirfd, path) {
+ if (path[0] !== "/") {
+ var dir;
+ if (dirfd === -100) {
+ dir = FS.cwd()
+ } else {
+ var dirstream = FS.getStream(dirfd);
+ if (!dirstream) throw new FS.ErrnoError(8);
+ dir = dirstream.path
+ }
+ path = PATH.join2(dir, path)
+ }
+ return path
+ }, doStat: function (func, path, buf) {
+ try {
+ var stat = func(path)
+ } catch (e) {
+ if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
+ return -54
+ }
+ throw e
+ }
+ HEAP32[buf >> 2] = stat.dev;
+ HEAP32[buf + 4 >> 2] = 0;
+ HEAP32[buf + 8 >> 2] = stat.ino;
+ HEAP32[buf + 12 >> 2] = stat.mode;
+ HEAP32[buf + 16 >> 2] = stat.nlink;
+ HEAP32[buf + 20 >> 2] = stat.uid;
+ HEAP32[buf + 24 >> 2] = stat.gid;
+ HEAP32[buf + 28 >> 2] = stat.rdev;
+ HEAP32[buf + 32 >> 2] = 0;
+ tempI64 = [stat.size >>> 0, (tempDouble = stat.size, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1];
+ HEAP32[buf + 48 >> 2] = 4096;
+ HEAP32[buf + 52 >> 2] = stat.blocks;
+ HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0;
+ HEAP32[buf + 60 >> 2] = 0;
+ HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0;
+ HEAP32[buf + 68 >> 2] = 0;
+ HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0;
+ HEAP32[buf + 76 >> 2] = 0;
+ tempI64 = [stat.ino >>> 0, (tempDouble = stat.ino, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1];
+ return 0
+ }, doMsync: function (addr, stream, len, flags, offset) {
+ var buffer = HEAPU8.slice(addr, addr + len);
+ FS.msync(stream, buffer, offset, len, flags)
+ }, doMkdir: function (path, mode) {
+ path = PATH.normalize(path);
+ if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1);
+ FS.mkdir(path, mode, 0);
+ return 0
+ }, doMknod: function (path, mode, dev) {
+ switch (mode & 61440) {
+ case 32768:
+ case 8192:
+ case 24576:
+ case 4096:
+ case 49152:
+ break;
+ default:
+ return -28
+ }
+ FS.mknod(path, mode, dev);
+ return 0
+ }, doReadlink: function (path, buf, bufsize) {
+ if (bufsize <= 0) return -28;
+ var ret = FS.readlink(path);
+ var len = Math.min(bufsize, lengthBytesUTF8(ret));
+ var endChar = HEAP8[buf + len];
+ stringToUTF8(ret, buf, bufsize + 1);
+ HEAP8[buf + len] = endChar;
+ return len
+ }, doAccess: function (path, amode) {
+ if (amode & ~7) {
+ return -28
+ }
+ var node;
+ var lookup = FS.lookupPath(path, {follow: true});
+ node = lookup.node;
+ if (!node) {
+ return -44
+ }
+ var perms = "";
+ if (amode & 4) perms += "r";
+ if (amode & 2) perms += "w";
+ if (amode & 1) perms += "x";
+ if (perms && FS.nodePermissions(node, perms)) {
+ return -2
+ }
+ return 0
+ }, doDup: function (path, flags, suggestFD) {
+ var suggest = FS.getStream(suggestFD);
+ if (suggest) FS.close(suggest);
+ return FS.open(path, flags, 0, suggestFD, suggestFD).fd
+ }, doReadv: function (stream, iov, iovcnt, offset) {
+ var ret = 0;
+ for (var i = 0; i < iovcnt; i++) {
+ var ptr = HEAP32[iov + i * 8 >> 2];
+ var len = HEAP32[iov + (i * 8 + 4) >> 2];
+ var curr = FS.read(stream, HEAP8, ptr, len, offset);
+ if (curr < 0) return -1;
+ ret += curr;
+ if (curr < len) break
+ }
+ return ret
+ }, doWritev: function (stream, iov, iovcnt, offset) {
+ var ret = 0;
+ for (var i = 0; i < iovcnt; i++) {
+ var ptr = HEAP32[iov + i * 8 >> 2];
+ var len = HEAP32[iov + (i * 8 + 4) >> 2];
+ var curr = FS.write(stream, HEAP8, ptr, len, offset);
+ if (curr < 0) return -1;
+ ret += curr
+ }
+ return ret
+ }, varargs: undefined, get: function () {
+ SYSCALLS.varargs += 4;
+ var ret = HEAP32[SYSCALLS.varargs - 4 >> 2];
+ return ret
+ }, getStr: function (ptr) {
+ var ret = UTF8ToString(ptr);
+ return ret
+ }, getStreamFromFD: function (fd) {
+ var stream = FS.getStream(fd);
+ if (!stream) throw new FS.ErrnoError(8);
+ return stream
+ }, get64: function (low, high) {
+ return low
+ }
+ };
+
+ function syscallMunmap(addr, len) {
+ if ((addr | 0) === -1 || len === 0) {
+ return -28
+ }
+ var info = SYSCALLS.mappings[addr];
+ if (!info) return 0;
+ if (len === info.len) {
+ var stream = FS.getStream(info.fd);
+ if (info.prot & 2) {
+ SYSCALLS.doMsync(addr, stream, len, info.flags, info.offset)
+ }
+ FS.munmap(stream);
+ SYSCALLS.mappings[addr] = null;
+ if (info.allocated) {
+ _free(info.malloc)
+ }
+ }
+ return 0
+ }
+
+ function ___sys_munmap(addr, len) {
+ try {
+ return syscallMunmap(addr, len)
+ } catch (e) {
+ if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
+ return -e.errno
+ }
+ }
+
+ var tupleRegistrations = {};
+
+ function runDestructors(destructors) {
+ while (destructors.length) {
+ var ptr = destructors.pop();
+ var del = destructors.pop();
+ del(ptr)
+ }
+ }
+
+ function simpleReadValueFromPointer(pointer) {
+ return this["fromWireType"](HEAPU32[pointer >> 2])
+ }
+
+ var awaitingDependencies = {};
+ var registeredTypes = {};
+ var typeDependencies = {};
+ var char_0 = 48;
+ var char_9 = 57;
+
+ function makeLegalFunctionName(name) {
+ if (undefined === name) {
+ return "_unknown"
+ }
+ name = name.replace(/[^a-zA-Z0-9_]/g, "$");
+ var f = name.charCodeAt(0);
+ if (f >= char_0 && f <= char_9) {
+ return "_" + name
+ } else {
+ return name
+ }
+ }
+
+ function createNamedFunction(name, body) {
+ name = makeLegalFunctionName(name);
+ if (IsWechat) {
+ var f1 = function (body) {
+ return function () {
+ "use strict";
+ return body.apply(this, arguments);
+ }
+ }
+ return f1(body)
+ } else {
+ return new Function("body", "return function " + name + "() {\n" + ' "use strict";' + " return body.apply(this, arguments);\n" + "};\n")(body)
+ }
+ }
+
+ function extendError(baseErrorType, errorName) {
+ var errorClass = createNamedFunction(errorName, function (message) {
+ this.name = errorName;
+ this.message = message;
+ var stack = new Error(message).stack;
+ if (stack !== undefined) {
+ this.stack = this.toString() + "\n" + stack.replace(/^Error(:[^\n]*)?\n/, "")
+ }
+ });
+ errorClass.prototype = Object.create(baseErrorType.prototype);
+ errorClass.prototype.constructor = errorClass;
+ errorClass.prototype.toString = function () {
+ if (this.message === undefined) {
+ return this.name
+ } else {
+ return this.name + ": " + this.message
+ }
+ };
+ return errorClass
+ }
+
+ var InternalError = undefined;
+
+ function throwInternalError(message) {
+ throw new InternalError(message)
+ }
+
+ function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) {
+ myTypes.forEach(function (type) {
+ typeDependencies[type] = dependentTypes
+ });
+
+ function onComplete(typeConverters) {
+ var myTypeConverters = getTypeConverters(typeConverters);
+ if (myTypeConverters.length !== myTypes.length) {
+ throwInternalError("Mismatched type converter count")
+ }
+ for (var i = 0; i < myTypes.length; ++i) {
+ registerType(myTypes[i], myTypeConverters[i])
+ }
+ }
+
+ var typeConverters = new Array(dependentTypes.length);
+ var unregisteredTypes = [];
+ var registered = 0;
+ dependentTypes.forEach(function (dt, i) {
+ if (registeredTypes.hasOwnProperty(dt)) {
+ typeConverters[i] = registeredTypes[dt]
+ } else {
+ unregisteredTypes.push(dt);
+ if (!awaitingDependencies.hasOwnProperty(dt)) {
+ awaitingDependencies[dt] = []
+ }
+ awaitingDependencies[dt].push(function () {
+ typeConverters[i] = registeredTypes[dt];
+ ++registered;
+ if (registered === unregisteredTypes.length) {
+ onComplete(typeConverters)
+ }
+ })
+ }
+ });
+ if (0 === unregisteredTypes.length) {
+ onComplete(typeConverters)
+ }
+ }
+
+ function __embind_finalize_value_array(rawTupleType) {
+ var reg = tupleRegistrations[rawTupleType];
+ delete tupleRegistrations[rawTupleType];
+ var elements = reg.elements;
+ var elementsLength = elements.length;
+ var elementTypes = elements.map(function (elt) {
+ return elt.getterReturnType
+ }).concat(elements.map(function (elt) {
+ return elt.setterArgumentType
+ }));
+ var rawConstructor = reg.rawConstructor;
+ var rawDestructor = reg.rawDestructor;
+ whenDependentTypesAreResolved([rawTupleType], elementTypes, function (elementTypes) {
+ elements.forEach(function (elt, i) {
+ var getterReturnType = elementTypes[i];
+ var getter = elt.getter;
+ var getterContext = elt.getterContext;
+ var setterArgumentType = elementTypes[i + elementsLength];
+ var setter = elt.setter;
+ var setterContext = elt.setterContext;
+ elt.read = function (ptr) {
+ return getterReturnType["fromWireType"](getter(getterContext, ptr))
+ };
+ elt.write = function (ptr, o) {
+ var destructors = [];
+ setter(setterContext, ptr, setterArgumentType["toWireType"](destructors, o));
+ runDestructors(destructors)
+ }
+ });
+ return [{
+ name: reg.name,
+ "fromWireType": function (ptr) {
+ var rv = new Array(elementsLength);
+ for (var i = 0; i < elementsLength; ++i) {
+ rv[i] = elements[i].read(ptr)
+ }
+ rawDestructor(ptr);
+ return rv
+ },
+ "toWireType": function (destructors, o) {
+ if (elementsLength !== o.length) {
+ throw new TypeError("Incorrect number of tuple elements for " + reg.name + ": expected=" + elementsLength + ", actual=" + o.length)
+ }
+ var ptr = rawConstructor();
+ for (var i = 0; i < elementsLength; ++i) {
+ elements[i].write(ptr, o[i])
+ }
+ if (destructors !== null) {
+ destructors.push(rawDestructor, ptr)
+ }
+ return ptr
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": simpleReadValueFromPointer,
+ destructorFunction: rawDestructor
+ }]
+ })
+ }
+
+ var structRegistrations = {};
+
+ function __embind_finalize_value_object(structType) {
+ var reg = structRegistrations[structType];
+ delete structRegistrations[structType];
+ var rawConstructor = reg.rawConstructor;
+ var rawDestructor = reg.rawDestructor;
+ var fieldRecords = reg.fields;
+ var fieldTypes = fieldRecords.map(function (field) {
+ return field.getterReturnType
+ }).concat(fieldRecords.map(function (field) {
+ return field.setterArgumentType
+ }));
+ whenDependentTypesAreResolved([structType], fieldTypes, function (fieldTypes) {
+ var fields = {};
+ fieldRecords.forEach(function (field, i) {
+ var fieldName = field.fieldName;
+ var getterReturnType = fieldTypes[i];
+ var getter = field.getter;
+ var getterContext = field.getterContext;
+ var setterArgumentType = fieldTypes[i + fieldRecords.length];
+ var setter = field.setter;
+ var setterContext = field.setterContext;
+ fields[fieldName] = {
+ read: function (ptr) {
+ return getterReturnType["fromWireType"](getter(getterContext, ptr))
+ }, write: function (ptr, o) {
+ var destructors = [];
+ setter(setterContext, ptr, setterArgumentType["toWireType"](destructors, o));
+ runDestructors(destructors)
+ }
+ }
+ });
+ return [{
+ name: reg.name,
+ "fromWireType": function (ptr) {
+ var rv = {};
+ for (var i in fields) {
+ rv[i] = fields[i].read(ptr)
+ }
+ rawDestructor(ptr);
+ return rv
+ },
+ "toWireType": function (destructors, o) {
+ for (var fieldName in fields) {
+ if (!(fieldName in o)) {
+ throw new TypeError('Missing field: "' + fieldName + '"')
+ }
+ }
+ var ptr = rawConstructor();
+ for (fieldName in fields) {
+ fields[fieldName].write(ptr, o[fieldName])
+ }
+ if (destructors !== null) {
+ destructors.push(rawDestructor, ptr)
+ }
+ return ptr
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": simpleReadValueFromPointer,
+ destructorFunction: rawDestructor
+ }]
+ })
+ }
+
+ function getShiftFromSize(size) {
+ switch (size) {
+ case 1:
+ return 0;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 8:
+ return 3;
+ default:
+ throw new TypeError("Unknown type size: " + size)
+ }
+ }
+
+ function embind_init_charCodes() {
+ var codes = new Array(256);
+ for (var i = 0; i < 256; ++i) {
+ codes[i] = String.fromCharCode(i)
+ }
+ embind_charCodes = codes
+ }
+
+ var embind_charCodes = undefined;
+
+ function readLatin1String(ptr) {
+ var ret = "";
+ var c = ptr;
+ while (HEAPU8[c]) {
+ ret += embind_charCodes[HEAPU8[c++]]
+ }
+ return ret
+ }
+
+ var BindingError = undefined;
+
+ function throwBindingError(message) {
+ throw new BindingError(message)
+ }
+
+ function registerType(rawType, registeredInstance, options) {
+ options = options || {};
+ if (!("argPackAdvance" in registeredInstance)) {
+ throw new TypeError("registerType registeredInstance requires argPackAdvance")
+ }
+ var name = registeredInstance.name;
+ if (!rawType) {
+ throwBindingError('type "' + name + '" must have a positive integer typeid pointer')
+ }
+ if (registeredTypes.hasOwnProperty(rawType)) {
+ if (options.ignoreDuplicateRegistrations) {
+ return
+ } else {
+ throwBindingError("Cannot register type '" + name + "' twice")
+ }
+ }
+ registeredTypes[rawType] = registeredInstance;
+ delete typeDependencies[rawType];
+ if (awaitingDependencies.hasOwnProperty(rawType)) {
+ var callbacks = awaitingDependencies[rawType];
+ delete awaitingDependencies[rawType];
+ callbacks.forEach(function (cb) {
+ cb()
+ })
+ }
+ }
+
+ function __embind_register_bool(rawType, name, size, trueValue, falseValue) {
+ var shift = getShiftFromSize(size);
+ name = readLatin1String(name);
+ registerType(rawType, {
+ name: name, "fromWireType": function (wt) {
+ return !!wt
+ }, "toWireType": function (destructors, o) {
+ return o ? trueValue : falseValue
+ }, "argPackAdvance": 8, "readValueFromPointer": function (pointer) {
+ var heap;
+ if (size === 1) {
+ heap = HEAP8
+ } else if (size === 2) {
+ heap = HEAP16
+ } else if (size === 4) {
+ heap = HEAP32
+ } else {
+ throw new TypeError("Unknown boolean type size: " + name)
+ }
+ return this["fromWireType"](heap[pointer >> shift])
+ }, destructorFunction: null
+ })
+ }
+
+ function ClassHandle_isAliasOf(other) {
+ if (!(this instanceof ClassHandle)) {
+ return false
+ }
+ if (!(other instanceof ClassHandle)) {
+ return false
+ }
+ var leftClass = this.$$.ptrType.registeredClass;
+ var left = this.$$.ptr;
+ var rightClass = other.$$.ptrType.registeredClass;
+ var right = other.$$.ptr;
+ while (leftClass.baseClass) {
+ left = leftClass.upcast(left);
+ leftClass = leftClass.baseClass
+ }
+ while (rightClass.baseClass) {
+ right = rightClass.upcast(right);
+ rightClass = rightClass.baseClass
+ }
+ return leftClass === rightClass && left === right
+ }
+
+ function shallowCopyInternalPointer(o) {
+ return {
+ count: o.count,
+ deleteScheduled: o.deleteScheduled,
+ preservePointerOnDelete: o.preservePointerOnDelete,
+ ptr: o.ptr,
+ ptrType: o.ptrType,
+ smartPtr: o.smartPtr,
+ smartPtrType: o.smartPtrType
+ }
+ }
+
+ function throwInstanceAlreadyDeleted(obj) {
+ function getInstanceTypeName(handle) {
+ return handle.$$.ptrType.registeredClass.name
+ }
+
+ throwBindingError(getInstanceTypeName(obj) + " instance already deleted")
+ }
+
+ var finalizationGroup = false;
+
+ function detachFinalizer(handle) {
+ }
+
+ function runDestructor($$) {
+ if ($$.smartPtr) {
+ $$.smartPtrType.rawDestructor($$.smartPtr)
+ } else {
+ $$.ptrType.registeredClass.rawDestructor($$.ptr)
+ }
+ }
+
+ function releaseClassHandle($$) {
+ $$.count.value -= 1;
+ var toDelete = 0 === $$.count.value;
+ if (toDelete) {
+ runDestructor($$)
+ }
+ }
+
+ function attachFinalizer(handle) {
+ if ("undefined" === typeof FinalizationGroup) {
+ attachFinalizer = function (handle) {
+ return handle
+ };
+ return handle
+ }
+ finalizationGroup = new FinalizationGroup(function (iter) {
+ for (var result = iter.next(); !result.done; result = iter.next()) {
+ var $$ = result.value;
+ if (!$$.ptr) {
+ console.warn("object already deleted: " + $$.ptr)
+ } else {
+ releaseClassHandle($$)
+ }
+ }
+ });
+ attachFinalizer = function (handle) {
+ finalizationGroup.register(handle, handle.$$, handle.$$);
+ return handle
+ };
+ detachFinalizer = function (handle) {
+ finalizationGroup.unregister(handle.$$)
+ };
+ return attachFinalizer(handle)
+ }
+
+ function ClassHandle_clone() {
+ if (!this.$$.ptr) {
+ throwInstanceAlreadyDeleted(this)
+ }
+ if (this.$$.preservePointerOnDelete) {
+ this.$$.count.value += 1;
+ return this
+ } else {
+ var clone = attachFinalizer(Object.create(Object.getPrototypeOf(this), {$$: {value: shallowCopyInternalPointer(this.$$)}}));
+ clone.$$.count.value += 1;
+ clone.$$.deleteScheduled = false;
+ return clone
+ }
+ }
+
+ function ClassHandle_delete() {
+ if (!this.$$.ptr) {
+ throwInstanceAlreadyDeleted(this)
+ }
+ if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {
+ throwBindingError("Object already scheduled for deletion")
+ }
+ detachFinalizer(this);
+ releaseClassHandle(this.$$);
+ if (!this.$$.preservePointerOnDelete) {
+ this.$$.smartPtr = undefined;
+ this.$$.ptr = undefined
+ }
+ }
+
+ function ClassHandle_isDeleted() {
+ return !this.$$.ptr
+ }
+
+ var delayFunction = undefined;
+ var deletionQueue = [];
+
+ function flushPendingDeletes() {
+ while (deletionQueue.length) {
+ var obj = deletionQueue.pop();
+ obj.$$.deleteScheduled = false;
+ obj["delete"]()
+ }
+ }
+
+ function ClassHandle_deleteLater() {
+ if (!this.$$.ptr) {
+ throwInstanceAlreadyDeleted(this)
+ }
+ if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {
+ throwBindingError("Object already scheduled for deletion")
+ }
+ deletionQueue.push(this);
+ if (deletionQueue.length === 1 && delayFunction) {
+ delayFunction(flushPendingDeletes)
+ }
+ this.$$.deleteScheduled = true;
+ return this
+ }
+
+ function init_ClassHandle() {
+ ClassHandle.prototype["isAliasOf"] = ClassHandle_isAliasOf;
+ ClassHandle.prototype["clone"] = ClassHandle_clone;
+ ClassHandle.prototype["delete"] = ClassHandle_delete;
+ ClassHandle.prototype["isDeleted"] = ClassHandle_isDeleted;
+ ClassHandle.prototype["deleteLater"] = ClassHandle_deleteLater
+ }
+
+ function ClassHandle() {
+ }
+
+ var registeredPointers = {};
+
+ function ensureOverloadTable(proto, methodName, humanName) {
+ if (undefined === proto[methodName].overloadTable) {
+ var prevFunc = proto[methodName];
+ proto[methodName] = function () {
+ if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) {
+ throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!")
+ }
+ return proto[methodName].overloadTable[arguments.length].apply(this, arguments)
+ };
+ proto[methodName].overloadTable = [];
+ proto[methodName].overloadTable[prevFunc.argCount] = prevFunc
+ }
+ }
+
+ function exposePublicSymbol(name, value, numArguments) {
+ if (Module.hasOwnProperty(name)) {
+ if (undefined === numArguments || undefined !== Module[name].overloadTable && undefined !== Module[name].overloadTable[numArguments]) {
+ throwBindingError("Cannot register public name '" + name + "' twice")
+ }
+ ensureOverloadTable(Module, name, name);
+ if (Module.hasOwnProperty(numArguments)) {
+ throwBindingError("Cannot register multiple overloads of a function with the same number of arguments (" + numArguments + ")!")
+ }
+ Module[name].overloadTable[numArguments] = value
+ } else {
+ Module[name] = value;
+ if (undefined !== numArguments) {
+ Module[name].numArguments = numArguments
+ }
+ }
+ }
+
+ function RegisteredClass(name, constructor, instancePrototype, rawDestructor, baseClass, getActualType, upcast, downcast) {
+ this.name = name;
+ this.constructor = constructor;
+ this.instancePrototype = instancePrototype;
+ this.rawDestructor = rawDestructor;
+ this.baseClass = baseClass;
+ this.getActualType = getActualType;
+ this.upcast = upcast;
+ this.downcast = downcast;
+ this.pureVirtualFunctions = []
+ }
+
+ function upcastPointer(ptr, ptrClass, desiredClass) {
+ while (ptrClass !== desiredClass) {
+ if (!ptrClass.upcast) {
+ throwBindingError("Expected null or instance of " + desiredClass.name + ", got an instance of " + ptrClass.name)
+ }
+ ptr = ptrClass.upcast(ptr);
+ ptrClass = ptrClass.baseClass
+ }
+ return ptr
+ }
+
+ function constNoSmartPtrRawPointerToWireType(destructors, handle) {
+ if (handle === null) {
+ if (this.isReference) {
+ throwBindingError("null is not a valid " + this.name)
+ }
+ return 0
+ }
+ if (!handle.$$) {
+ throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name)
+ }
+ if (!handle.$$.ptr) {
+ throwBindingError("Cannot pass deleted object as a pointer of type " + this.name)
+ }
+ var handleClass = handle.$$.ptrType.registeredClass;
+ var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
+ return ptr
+ }
+
+ function genericPointerToWireType(destructors, handle) {
+ var ptr;
+ if (handle === null) {
+ if (this.isReference) {
+ throwBindingError("null is not a valid " + this.name)
+ }
+ if (this.isSmartPointer) {
+ ptr = this.rawConstructor();
+ if (destructors !== null) {
+ destructors.push(this.rawDestructor, ptr)
+ }
+ return ptr
+ } else {
+ return 0
+ }
+ }
+ if (!handle.$$) {
+ throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name)
+ }
+ if (!handle.$$.ptr) {
+ throwBindingError("Cannot pass deleted object as a pointer of type " + this.name)
+ }
+ if (!this.isConst && handle.$$.ptrType.isConst) {
+ throwBindingError("Cannot convert argument of type " + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + " to parameter type " + this.name)
+ }
+ var handleClass = handle.$$.ptrType.registeredClass;
+ ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
+ if (this.isSmartPointer) {
+ if (undefined === handle.$$.smartPtr) {
+ throwBindingError("Passing raw pointer to smart pointer is illegal")
+ }
+ switch (this.sharingPolicy) {
+ case 0:
+ if (handle.$$.smartPtrType === this) {
+ ptr = handle.$$.smartPtr
+ } else {
+ throwBindingError("Cannot convert argument of type " + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + " to parameter type " + this.name)
+ }
+ break;
+ case 1:
+ ptr = handle.$$.smartPtr;
+ break;
+ case 2:
+ if (handle.$$.smartPtrType === this) {
+ ptr = handle.$$.smartPtr
+ } else {
+ var clonedHandle = handle["clone"]();
+ ptr = this.rawShare(ptr, __emval_register(function () {
+ clonedHandle["delete"]()
+ }));
+ if (destructors !== null) {
+ destructors.push(this.rawDestructor, ptr)
+ }
+ }
+ break;
+ default:
+ throwBindingError("Unsupporting sharing policy")
+ }
+ }
+ return ptr
+ }
+
+ function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) {
+ if (handle === null) {
+ if (this.isReference) {
+ throwBindingError("null is not a valid " + this.name)
+ }
+ return 0
+ }
+ if (!handle.$$) {
+ throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name)
+ }
+ if (!handle.$$.ptr) {
+ throwBindingError("Cannot pass deleted object as a pointer of type " + this.name)
+ }
+ if (handle.$$.ptrType.isConst) {
+ throwBindingError("Cannot convert argument of type " + handle.$$.ptrType.name + " to parameter type " + this.name)
+ }
+ var handleClass = handle.$$.ptrType.registeredClass;
+ var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
+ return ptr
+ }
+
+ function RegisteredPointer_getPointee(ptr) {
+ if (this.rawGetPointee) {
+ ptr = this.rawGetPointee(ptr)
+ }
+ return ptr
+ }
+
+ function RegisteredPointer_destructor(ptr) {
+ if (this.rawDestructor) {
+ this.rawDestructor(ptr)
+ }
+ }
+
+ function RegisteredPointer_deleteObject(handle) {
+ if (handle !== null) {
+ handle["delete"]()
+ }
+ }
+
+ function downcastPointer(ptr, ptrClass, desiredClass) {
+ if (ptrClass === desiredClass) {
+ return ptr
+ }
+ if (undefined === desiredClass.baseClass) {
+ return null
+ }
+ var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass);
+ if (rv === null) {
+ return null
+ }
+ return desiredClass.downcast(rv)
+ }
+
+ function getInheritedInstanceCount() {
+ return Object.keys(registeredInstances).length
+ }
+
+ function getLiveInheritedInstances() {
+ var rv = [];
+ for (var k in registeredInstances) {
+ if (registeredInstances.hasOwnProperty(k)) {
+ rv.push(registeredInstances[k])
+ }
+ }
+ return rv
+ }
+
+ function setDelayFunction(fn) {
+ delayFunction = fn;
+ if (deletionQueue.length && delayFunction) {
+ delayFunction(flushPendingDeletes)
+ }
+ }
+
+ function init_embind() {
+ Module["getInheritedInstanceCount"] = getInheritedInstanceCount;
+ Module["getLiveInheritedInstances"] = getLiveInheritedInstances;
+ Module["flushPendingDeletes"] = flushPendingDeletes;
+ Module["setDelayFunction"] = setDelayFunction
+ }
+
+ var registeredInstances = {};
+
+ function getBasestPointer(class_, ptr) {
+ if (ptr === undefined) {
+ throwBindingError("ptr should not be undefined")
+ }
+ while (class_.baseClass) {
+ ptr = class_.upcast(ptr);
+ class_ = class_.baseClass
+ }
+ return ptr
+ }
+
+ function getInheritedInstance(class_, ptr) {
+ ptr = getBasestPointer(class_, ptr);
+ return registeredInstances[ptr]
+ }
+
+ function makeClassHandle(prototype, record) {
+ if (!record.ptrType || !record.ptr) {
+ throwInternalError("makeClassHandle requires ptr and ptrType")
+ }
+ var hasSmartPtrType = !!record.smartPtrType;
+ var hasSmartPtr = !!record.smartPtr;
+ if (hasSmartPtrType !== hasSmartPtr) {
+ throwInternalError("Both smartPtrType and smartPtr must be specified")
+ }
+ record.count = {value: 1};
+ return attachFinalizer(Object.create(prototype, {$$: {value: record}}))
+ }
+
+ function RegisteredPointer_fromWireType(ptr) {
+ var rawPointer = this.getPointee(ptr);
+ if (!rawPointer) {
+ this.destructor(ptr);
+ return null
+ }
+ var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer);
+ if (undefined !== registeredInstance) {
+ if (0 === registeredInstance.$$.count.value) {
+ registeredInstance.$$.ptr = rawPointer;
+ registeredInstance.$$.smartPtr = ptr;
+ return registeredInstance["clone"]()
+ } else {
+ var rv = registeredInstance["clone"]();
+ this.destructor(ptr);
+ return rv
+ }
+ }
+
+ function makeDefaultHandle() {
+ if (this.isSmartPointer) {
+ return makeClassHandle(this.registeredClass.instancePrototype, {
+ ptrType: this.pointeeType,
+ ptr: rawPointer,
+ smartPtrType: this,
+ smartPtr: ptr
+ })
+ } else {
+ return makeClassHandle(this.registeredClass.instancePrototype, {ptrType: this, ptr: ptr})
+ }
+ }
+
+ var actualType = this.registeredClass.getActualType(rawPointer);
+ var registeredPointerRecord = registeredPointers[actualType];
+ if (!registeredPointerRecord) {
+ return makeDefaultHandle.call(this)
+ }
+ var toType;
+ if (this.isConst) {
+ toType = registeredPointerRecord.constPointerType
+ } else {
+ toType = registeredPointerRecord.pointerType
+ }
+ var dp = downcastPointer(rawPointer, this.registeredClass, toType.registeredClass);
+ if (dp === null) {
+ return makeDefaultHandle.call(this)
+ }
+ if (this.isSmartPointer) {
+ return makeClassHandle(toType.registeredClass.instancePrototype, {
+ ptrType: toType,
+ ptr: dp,
+ smartPtrType: this,
+ smartPtr: ptr
+ })
+ } else {
+ return makeClassHandle(toType.registeredClass.instancePrototype, {ptrType: toType, ptr: dp})
+ }
+ }
+
+ function init_RegisteredPointer() {
+ RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee;
+ RegisteredPointer.prototype.destructor = RegisteredPointer_destructor;
+ RegisteredPointer.prototype["argPackAdvance"] = 8;
+ RegisteredPointer.prototype["readValueFromPointer"] = simpleReadValueFromPointer;
+ RegisteredPointer.prototype["deleteObject"] = RegisteredPointer_deleteObject;
+ RegisteredPointer.prototype["fromWireType"] = RegisteredPointer_fromWireType
+ }
+
+ function RegisteredPointer(name, registeredClass, isReference, isConst, isSmartPointer, pointeeType, sharingPolicy, rawGetPointee, rawConstructor, rawShare, rawDestructor) {
+ this.name = name;
+ this.registeredClass = registeredClass;
+ this.isReference = isReference;
+ this.isConst = isConst;
+ this.isSmartPointer = isSmartPointer;
+ this.pointeeType = pointeeType;
+ this.sharingPolicy = sharingPolicy;
+ this.rawGetPointee = rawGetPointee;
+ this.rawConstructor = rawConstructor;
+ this.rawShare = rawShare;
+ this.rawDestructor = rawDestructor;
+ if (!isSmartPointer && registeredClass.baseClass === undefined) {
+ if (isConst) {
+ this["toWireType"] = constNoSmartPtrRawPointerToWireType;
+ this.destructorFunction = null
+ } else {
+ this["toWireType"] = nonConstNoSmartPtrRawPointerToWireType;
+ this.destructorFunction = null
+ }
+ } else {
+ this["toWireType"] = genericPointerToWireType
+ }
+ }
+
+ function replacePublicSymbol(name, value, numArguments) {
+ if (!Module.hasOwnProperty(name)) {
+ throwInternalError("Replacing nonexistant public symbol")
+ }
+ if (undefined !== Module[name].overloadTable && undefined !== numArguments) {
+ Module[name].overloadTable[numArguments] = value
+ } else {
+ Module[name] = value;
+ Module[name].argCount = numArguments
+ }
+ }
+
+ function embind__requireFunction(signature, rawFunction) {
+ signature = readLatin1String(signature);
+
+ function makeDynCaller(dynCall) {
+ if (IsWechat) {
+ var f1 = function (dynCall, rawFunction) {
+ return function () {
+ return dynCall(rawFunction, ...arguments);
+ }
+ }
+ return f1(dynCall, rawFunction)
+
+ } else {
+ var args = [];
+ for (var i = 1; i < signature.length; ++i) {
+ args.push("a" + i)
+ }
+ var name = "dynCall_" + signature + "_" + rawFunction;
+ var body = "return function " + name + "(" + args.join(", ") + ") {\n";
+ body += " return dynCall(rawFunction" + (args.length ? ", " : "") + args.join(", ") + ");\n";
+ body += "};\n";
+
+ return new Function("dynCall", "rawFunction", body)(dynCall, rawFunction)
+ }
+ }
+
+ var dc = Module["dynCall_" + signature];
+ var fp = makeDynCaller(dc);
+ if (typeof fp !== "function") {
+ throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction)
+ }
+ return fp
+ }
+
+ var UnboundTypeError = undefined;
+
+ function getTypeName(type) {
+ var ptr = ___getTypeName(type);
+ var rv = readLatin1String(ptr);
+ _free(ptr);
+ return rv
+ }
+
+ function throwUnboundTypeError(message, types) {
+ var unboundTypes = [];
+ var seen = {};
+
+ function visit(type) {
+ if (seen[type]) {
+ return
+ }
+ if (registeredTypes[type]) {
+ return
+ }
+ if (typeDependencies[type]) {
+ typeDependencies[type].forEach(visit);
+ return
+ }
+ unboundTypes.push(type);
+ seen[type] = true
+ }
+
+ types.forEach(visit);
+ throw new UnboundTypeError(message + ": " + unboundTypes.map(getTypeName).join([", "]))
+ }
+
+ function __embind_register_class(rawType, rawPointerType, rawConstPointerType, baseClassRawType, getActualTypeSignature, getActualType, upcastSignature, upcast, downcastSignature, downcast, name, destructorSignature, rawDestructor) {
+ name = readLatin1String(name);
+ getActualType = embind__requireFunction(getActualTypeSignature, getActualType);
+ if (upcast) {
+ upcast = embind__requireFunction(upcastSignature, upcast)
+ }
+ if (downcast) {
+ downcast = embind__requireFunction(downcastSignature, downcast)
+ }
+ rawDestructor = embind__requireFunction(destructorSignature, rawDestructor);
+ var legalFunctionName = makeLegalFunctionName(name);
+ exposePublicSymbol(legalFunctionName, function () {
+ throwUnboundTypeError("Cannot construct " + name + " due to unbound types", [baseClassRawType])
+ });
+ whenDependentTypesAreResolved([rawType, rawPointerType, rawConstPointerType], baseClassRawType ? [baseClassRawType] : [], function (base) {
+ base = base[0];
+ var baseClass;
+ var basePrototype;
+ if (baseClassRawType) {
+ baseClass = base.registeredClass;
+ basePrototype = baseClass.instancePrototype
+ } else {
+ basePrototype = ClassHandle.prototype
+ }
+ var constructor = createNamedFunction(legalFunctionName, function () {
+ if (Object.getPrototypeOf(this) !== instancePrototype) {
+ throw new BindingError("Use 'new' to construct " + name)
+ }
+ if (undefined === registeredClass.constructor_body) {
+ throw new BindingError(name + " has no accessible constructor")
+ }
+ var body = registeredClass.constructor_body[arguments.length];
+ if (undefined === body) {
+ throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!")
+ }
+ return body.apply(this, arguments)
+ });
+ var instancePrototype = Object.create(basePrototype, {constructor: {value: constructor}});
+ constructor.prototype = instancePrototype;
+ var registeredClass = new RegisteredClass(name, constructor, instancePrototype, rawDestructor, baseClass, getActualType, upcast, downcast);
+ var referenceConverter = new RegisteredPointer(name, registeredClass, true, false, false);
+ var pointerConverter = new RegisteredPointer(name + "*", registeredClass, false, false, false);
+ var constPointerConverter = new RegisteredPointer(name + " const*", registeredClass, false, true, false);
+ registeredPointers[rawType] = {
+ pointerType: pointerConverter,
+ constPointerType: constPointerConverter
+ };
+ replacePublicSymbol(legalFunctionName, constructor);
+ return [referenceConverter, pointerConverter, constPointerConverter]
+ })
+ }
+
+ function new_(constructor, argumentList) {
+ if (!(constructor instanceof Function)) {
+ throw new TypeError("new_ called with constructor type " + typeof constructor + " which is not a function")
+ }
+ var dummy = createNamedFunction(constructor.name || "unknownFunctionName", function () {
+ });
+ dummy.prototype = constructor.prototype;
+ var obj = new dummy;
+ var r = constructor.apply(obj, argumentList);
+ return r instanceof Object ? r : obj
+ }
+
+ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) {
+ var argCount = argTypes.length;
+ if (argCount < 2) {
+ throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")
+ }
+ var isClassMethodFunc = argTypes[1] !== null && classType !== null;
+ var needsDestructorStack = false;
+ for (var i = 1; i < argTypes.length; ++i) {
+ if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) {
+ needsDestructorStack = true;
+ break
+ }
+ }
+ var returns = argTypes[0].name !== "void";
+ if (IsWechat) {
+ var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]];
+ for (var i = 0; i < argCount - 2; ++i) {
+ args2.push(argTypes[i + 2])
+ }
+ if (isClassMethodFunc) {
+ for (var i = 1; i < argCount; ++i) {
+ if (argTypes[i].destructorFunction !== null) {
+ args2.push(argTypes[i].destructorFunction)
+ }else{
+ args2.push(null)
+ }
+ }
+ } else {
+ for (var i = 2; i < argCount; ++i) {
+ if (argTypes[i].destructorFunction !== null) {
+ args2.push(argTypes[i].destructorFunction)
+ }else{
+ args2.push(null)
+ }
+ }
+ }
+
+ function f1(throwBindingError, invoker, fn, runDestructors, retType, classParam) {
+ // argType0,argType1,argType2
+ const argsTypeOrigin = Array.prototype.slice.call(arguments, 6, 6 + argCount - 2)
+ // arg0Wired_dtor
+ const argsWired_dtorOrigin = Array.prototype.slice.call(arguments, 6 + argCount - 2)
+
+ return function () {
+ // arg0, arg1, arg2
+ if (arguments.length !== argCount - 2) {
+ throwBindingError('function ' + humanName + ' called with ' + arguments.length + ' arguments, expected 0 args!');
+ }
+ var thisWired;
+ if (isClassMethodFunc) {
+ if (needsDestructorStack) {
+ var destructors = [];
+ thisWired = classParam.toWireType(destructors, this);
+ } else {
+ thisWired = classParam.toWireType(null, this);
+ }
+ }
+
+ // arg0Wired,arg1Wired,arg2Wired
+ var argsWired = [];
+ for (var i = 0; i < arguments.length; i++) {
+ argsWired.push(argsTypeOrigin[i].toWireType(null, arguments[i]))
+ }
+
+ var rv;
+ if (isClassMethodFunc) {
+ rv = invoker(fn, thisWired, ...argsWired);
+ } else {
+ rv = invoker(fn, ...argsWired);
+ }
+
+ if (needsDestructorStack) {
+ runDestructors(destructors);
+ } else {
+ if (isClassMethodFunc) {
+ for (var i = 1; i < argTypes.length; ++i) {
+ if (argTypes[i].destructorFunction !== null) {
+ argsWired_dtorOrigin[i - 1](thisWired);
+ }
+ }
+ } else {
+ for (var i = 2; i < argTypes.length; ++i) {
+ if (argTypes[i].destructorFunction !== null) {
+ argsWired_dtorOrigin[i - 2](argsWired[i - 2]);
+ }
+ }
+ }
+ }
+ if (returns) {
+ var ret = retType.fromWireType(rv);
+ return ret;
+ }
+ }
+ }
+ return f1.apply(null, args2)
+ } else {
+ var argsList = "";
+ var argsListWired = "";
+ for (var i = 0; i < argCount - 2; ++i) {
+ argsList += (i !== 0 ? ", " : "") + "arg" + i;
+ argsListWired += (i !== 0 ? ", " : "") + "arg" + i + "Wired"
+ }
+
+ var invokerFnBody = "return function " + makeLegalFunctionName(humanName) + "(" + argsList + ") {\n" + "if (arguments.length !== " + (argCount - 2) + ") {\n" + "throwBindingError('function " + humanName + " called with ' + arguments.length + ' arguments, expected " + (argCount - 2) + " args!');\n" + "}\n";
+ if (needsDestructorStack) {
+ invokerFnBody += "var destructors = [];\n"
+ }
+ var dtorStack = needsDestructorStack ? "destructors" : "null";
+ var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"];
+ var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]];
+ if (isClassMethodFunc) {
+ invokerFnBody += "var thisWired = classParam.toWireType(" + dtorStack + ", this);\n"
+ }
+ for (var i = 0; i < argCount - 2; ++i) {
+ invokerFnBody += "var arg" + i + "Wired = argType" + i + ".toWireType(" + dtorStack + ", arg" + i + "); // " + argTypes[i + 2].name + "\n";
+ args1.push("argType" + i);
+ args2.push(argTypes[i + 2])
+ }
+ if (isClassMethodFunc) {
+ argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired
+ }
+ invokerFnBody += (returns ? "var rv = " : "") + "invoker(fn" + (argsListWired.length > 0 ? ", " : "") + argsListWired + ");\n";
+ if (needsDestructorStack) {
+ invokerFnBody += "runDestructors(destructors);\n"
+ } else {
+ for (var i = isClassMethodFunc ? 1 : 2; i < argTypes.length; ++i) {
+ var paramName = i === 1 ? "thisWired" : "arg" + (i - 2) + "Wired";
+ if (argTypes[i].destructorFunction !== null) {
+ invokerFnBody += paramName + "_dtor(" + paramName + "); // " + argTypes[i].name + "\n";
+ args1.push(paramName + "_dtor");
+ args2.push(argTypes[i].destructorFunction)
+ }
+ }
+ }
+ if (returns) {
+ invokerFnBody += "var ret = retType.fromWireType(rv);\n" + "return ret;\n"
+ } else { }
+ invokerFnBody += "}\n";
+ args1.push(invokerFnBody);
+ var invokerFunction = new_(Function, args1).apply(null, args2);
+ return invokerFunction
+ }
+ }
+
+ function heap32VectorToArray(count, firstElement) {
+ var array = [];
+ for (var i = 0; i < count; i++) {
+ array.push(HEAP32[(firstElement >> 2) + i])
+ }
+ return array
+ }
+
+ function __embind_register_class_class_function(rawClassType, methodName, argCount, rawArgTypesAddr, invokerSignature, rawInvoker, fn) {
+ var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
+ methodName = readLatin1String(methodName);
+ rawInvoker = embind__requireFunction(invokerSignature, rawInvoker);
+ whenDependentTypesAreResolved([], [rawClassType], function (classType) {
+ classType = classType[0];
+ var humanName = classType.name + "." + methodName;
+
+ function unboundTypesHandler() {
+ throwUnboundTypeError("Cannot call " + humanName + " due to unbound types", rawArgTypes)
+ }
+
+ var proto = classType.registeredClass.constructor;
+ if (undefined === proto[methodName]) {
+ unboundTypesHandler.argCount = argCount - 1;
+ proto[methodName] = unboundTypesHandler
+ } else {
+ ensureOverloadTable(proto, methodName, humanName);
+ proto[methodName].overloadTable[argCount - 1] = unboundTypesHandler
+ }
+ whenDependentTypesAreResolved([], rawArgTypes, function (argTypes) {
+ var invokerArgsArray = [argTypes[0], null].concat(argTypes.slice(1));
+ var func = craftInvokerFunction(humanName, invokerArgsArray, null, rawInvoker, fn);
+ if (undefined === proto[methodName].overloadTable) {
+ func.argCount = argCount - 1;
+ proto[methodName] = func
+ } else {
+ proto[methodName].overloadTable[argCount - 1] = func
+ }
+ return []
+ });
+ return []
+ })
+ }
+
+ function __embind_register_class_constructor(rawClassType, argCount, rawArgTypesAddr, invokerSignature, invoker, rawConstructor) {
+ assert(argCount > 0);
+ var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
+ invoker = embind__requireFunction(invokerSignature, invoker);
+ var args = [rawConstructor];
+ var destructors = [];
+ whenDependentTypesAreResolved([], [rawClassType], function (classType) {
+ classType = classType[0];
+ var humanName = "constructor " + classType.name;
+ if (undefined === classType.registeredClass.constructor_body) {
+ classType.registeredClass.constructor_body = []
+ }
+ if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) {
+ throw new BindingError("Cannot register multiple constructors with identical number of parameters (" + (argCount - 1) + ") for class '" + classType.name + "'! Overload resolution is currently only performed using the parameter count, not actual type info!")
+ }
+ classType.registeredClass.constructor_body[argCount - 1] = function unboundTypeHandler() {
+ throwUnboundTypeError("Cannot construct " + classType.name + " due to unbound types", rawArgTypes)
+ };
+ whenDependentTypesAreResolved([], rawArgTypes, function (argTypes) {
+ classType.registeredClass.constructor_body[argCount - 1] = function constructor_body() {
+ if (arguments.length !== argCount - 1) {
+ throwBindingError(humanName + " called with " + arguments.length + " arguments, expected " + (argCount - 1))
+ }
+ destructors.length = 0;
+ args.length = argCount;
+ for (var i = 1; i < argCount; ++i) {
+ args[i] = argTypes[i]["toWireType"](destructors, arguments[i - 1])
+ }
+ var ptr = invoker.apply(null, args);
+ runDestructors(destructors);
+ return argTypes[0]["fromWireType"](ptr)
+ };
+ return []
+ });
+ return []
+ })
+ }
+
+ function __embind_register_class_function(rawClassType, methodName, argCount, rawArgTypesAddr, invokerSignature, rawInvoker, context, isPureVirtual) {
+ var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
+ methodName = readLatin1String(methodName);
+ rawInvoker = embind__requireFunction(invokerSignature, rawInvoker);
+ whenDependentTypesAreResolved([], [rawClassType], function (classType) {
+ classType = classType[0];
+ var humanName = classType.name + "." + methodName;
+ if (isPureVirtual) {
+ classType.registeredClass.pureVirtualFunctions.push(methodName)
+ }
+
+ function unboundTypesHandler() {
+ throwUnboundTypeError("Cannot call " + humanName + " due to unbound types", rawArgTypes)
+ }
+
+ var proto = classType.registeredClass.instancePrototype;
+ var method = proto[methodName];
+ if (undefined === method || undefined === method.overloadTable && method.className !== classType.name && method.argCount === argCount - 2) {
+ unboundTypesHandler.argCount = argCount - 2;
+ unboundTypesHandler.className = classType.name;
+ proto[methodName] = unboundTypesHandler
+ } else {
+ ensureOverloadTable(proto, methodName, humanName);
+ proto[methodName].overloadTable[argCount - 2] = unboundTypesHandler
+ }
+ whenDependentTypesAreResolved([], rawArgTypes, function (argTypes) {
+ var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context);
+ if (undefined === proto[methodName].overloadTable) {
+ memberFunction.argCount = argCount - 2;
+ proto[methodName] = memberFunction
+ } else {
+ proto[methodName].overloadTable[argCount - 2] = memberFunction
+ }
+ return []
+ });
+ return []
+ })
+ }
+
+ function validateThis(this_, classType, humanName) {
+ if (!(this_ instanceof Object)) {
+ throwBindingError(humanName + ' with invalid "this": ' + this_)
+ }
+ if (!(this_ instanceof classType.registeredClass.constructor)) {
+ throwBindingError(humanName + ' incompatible with "this" of type ' + this_.constructor.name)
+ }
+ if (!this_.$$.ptr) {
+ throwBindingError("cannot call emscripten binding method " + humanName + " on deleted object")
+ }
+ return upcastPointer(this_.$$.ptr, this_.$$.ptrType.registeredClass, classType.registeredClass)
+ }
+
+ function __embind_register_class_property(classType, fieldName, getterReturnType, getterSignature, getter, getterContext, setterArgumentType, setterSignature, setter, setterContext) {
+ fieldName = readLatin1String(fieldName);
+ getter = embind__requireFunction(getterSignature, getter);
+ whenDependentTypesAreResolved([], [classType], function (classType) {
+ classType = classType[0];
+ var humanName = classType.name + "." + fieldName;
+ var desc = {
+ get: function () {
+ throwUnboundTypeError("Cannot access " + humanName + " due to unbound types", [getterReturnType, setterArgumentType])
+ }, enumerable: true, configurable: true
+ };
+ if (setter) {
+ desc.set = function () {
+ throwUnboundTypeError("Cannot access " + humanName + " due to unbound types", [getterReturnType, setterArgumentType])
+ }
+ } else {
+ desc.set = function (v) {
+ throwBindingError(humanName + " is a read-only property")
+ }
+ }
+ Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, desc);
+ whenDependentTypesAreResolved([], setter ? [getterReturnType, setterArgumentType] : [getterReturnType], function (types) {
+ var getterReturnType = types[0];
+ var desc = {
+ get: function () {
+ var ptr = validateThis(this, classType, humanName + " getter");
+ return getterReturnType["fromWireType"](getter(getterContext, ptr))
+ }, enumerable: true
+ };
+ if (setter) {
+ setter = embind__requireFunction(setterSignature, setter);
+ var setterArgumentType = types[1];
+ desc.set = function (v) {
+ var ptr = validateThis(this, classType, humanName + " setter");
+ var destructors = [];
+ setter(setterContext, ptr, setterArgumentType["toWireType"](destructors, v));
+ runDestructors(destructors)
+ }
+ }
+ Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, desc);
+ return []
+ });
+ return []
+ })
+ }
+
+ function __embind_register_constant(name, type, value) {
+ name = readLatin1String(name);
+ whenDependentTypesAreResolved([], [type], function (type) {
+ type = type[0];
+ Module[name] = type["fromWireType"](value);
+ return []
+ })
+ }
+
+ var emval_free_list = [];
+ var emval_handle_array = [{}, {value: undefined}, {value: null}, {value: true}, {value: false}];
+
+ function __emval_decref(handle) {
+ if (handle > 4 && 0 === --emval_handle_array[handle].refcount) {
+ emval_handle_array[handle] = undefined;
+ emval_free_list.push(handle)
+ }
+ }
+
+ function count_emval_handles() {
+ var count = 0;
+ for (var i = 5; i < emval_handle_array.length; ++i) {
+ if (emval_handle_array[i] !== undefined) {
+ ++count
+ }
+ }
+ return count
+ }
+
+ function get_first_emval() {
+ for (var i = 5; i < emval_handle_array.length; ++i) {
+ if (emval_handle_array[i] !== undefined) {
+ return emval_handle_array[i]
+ }
+ }
+ return null
+ }
+
+ function init_emval() {
+ Module["count_emval_handles"] = count_emval_handles;
+ Module["get_first_emval"] = get_first_emval
+ }
+
+ function __emval_register(value) {
+ switch (value) {
+ case undefined: {
+ return 1
+ }
+ case null: {
+ return 2
+ }
+ case true: {
+ return 3
+ }
+ case false: {
+ return 4
+ }
+ default: {
+ var handle = emval_free_list.length ? emval_free_list.pop() : emval_handle_array.length;
+ emval_handle_array[handle] = {refcount: 1, value: value};
+ return handle
+ }
+ }
+ }
+
+ function __embind_register_emval(rawType, name) {
+ name = readLatin1String(name);
+ registerType(rawType, {
+ name: name,
+ "fromWireType": function (handle) {
+ var rv = emval_handle_array[handle].value;
+ __emval_decref(handle);
+ return rv
+ },
+ "toWireType": function (destructors, value) {
+ return __emval_register(value)
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": simpleReadValueFromPointer,
+ destructorFunction: null
+ })
+ }
+
+ function _embind_repr(v) {
+ if (v === null) {
+ return "null"
+ }
+ var t = typeof v;
+ if (t === "object" || t === "array" || t === "function") {
+ return v.toString()
+ } else {
+ return "" + v
+ }
+ }
+
+ function floatReadValueFromPointer(name, shift) {
+ switch (shift) {
+ case 2:
+ return function (pointer) {
+ return this["fromWireType"](HEAPF32[pointer >> 2])
+ };
+ case 3:
+ return function (pointer) {
+ return this["fromWireType"](HEAPF64[pointer >> 3])
+ };
+ default:
+ throw new TypeError("Unknown float type: " + name)
+ }
+ }
+
+ function __embind_register_float(rawType, name, size) {
+ var shift = getShiftFromSize(size);
+ name = readLatin1String(name);
+ registerType(rawType, {
+ name: name,
+ "fromWireType": function (value) {
+ return value
+ },
+ "toWireType": function (destructors, value) {
+ if (typeof value !== "number" && typeof value !== "boolean") {
+ throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name)
+ }
+ return value
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": floatReadValueFromPointer(name, shift),
+ destructorFunction: null
+ })
+ }
+
+ function __embind_register_function(name, argCount, rawArgTypesAddr, signature, rawInvoker, fn) {
+ var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
+ name = readLatin1String(name);
+ rawInvoker = embind__requireFunction(signature, rawInvoker);
+ exposePublicSymbol(name, function () {
+ throwUnboundTypeError("Cannot call " + name + " due to unbound types", argTypes)
+ }, argCount - 1);
+ whenDependentTypesAreResolved([], argTypes, function (argTypes) {
+ var invokerArgsArray = [argTypes[0], null].concat(argTypes.slice(1));
+ replacePublicSymbol(name, craftInvokerFunction(name, invokerArgsArray, null, rawInvoker, fn), argCount - 1);
+ return []
+ })
+ }
+
+ function integerReadValueFromPointer(name, shift, signed) {
+ switch (shift) {
+ case 0:
+ return signed ? function readS8FromPointer(pointer) {
+ return HEAP8[pointer]
+ } : function readU8FromPointer(pointer) {
+ return HEAPU8[pointer]
+ };
+ case 1:
+ return signed ? function readS16FromPointer(pointer) {
+ return HEAP16[pointer >> 1]
+ } : function readU16FromPointer(pointer) {
+ return HEAPU16[pointer >> 1]
+ };
+ case 2:
+ return signed ? function readS32FromPointer(pointer) {
+ return HEAP32[pointer >> 2]
+ } : function readU32FromPointer(pointer) {
+ return HEAPU32[pointer >> 2]
+ };
+ default:
+ throw new TypeError("Unknown integer type: " + name)
+ }
+ }
+
+ function __embind_register_integer(primitiveType, name, size, minRange, maxRange) {
+ name = readLatin1String(name);
+ if (maxRange === -1) {
+ maxRange = 4294967295
+ }
+ var shift = getShiftFromSize(size);
+ var fromWireType = function (value) {
+ return value
+ };
+ if (minRange === 0) {
+ var bitshift = 32 - 8 * size;
+ fromWireType = function (value) {
+ return value << bitshift >>> bitshift
+ }
+ }
+ var isUnsignedType = name.indexOf("unsigned") != -1;
+ registerType(primitiveType, {
+ name: name,
+ "fromWireType": fromWireType,
+ "toWireType": function (destructors, value) {
+ if (typeof value !== "number" && typeof value !== "boolean") {
+ throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name)
+ }
+ if (value < minRange || value > maxRange) {
+ throw new TypeError('Passing a number "' + _embind_repr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ", " + maxRange + "]!")
+ }
+ return isUnsignedType ? value >>> 0 : value | 0
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": integerReadValueFromPointer(name, shift, minRange !== 0),
+ destructorFunction: null
+ })
+ }
+
+ function __embind_register_memory_view(rawType, dataTypeIndex, name) {
+ var typeMapping = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array];
+ var TA = typeMapping[dataTypeIndex];
+
+ function decodeMemoryView(handle) {
+ handle = handle >> 2;
+ var heap = HEAPU32;
+ var size = heap[handle];
+ var data = heap[handle + 1];
+ return new TA(buffer, data, size)
+ }
+
+ name = readLatin1String(name);
+ registerType(rawType, {
+ name: name,
+ "fromWireType": decodeMemoryView,
+ "argPackAdvance": 8,
+ "readValueFromPointer": decodeMemoryView
+ }, {ignoreDuplicateRegistrations: true})
+ }
+
+ function __embind_register_std_string(rawType, name) {
+ name = readLatin1String(name);
+ var stdStringIsUTF8 = name === "std::string";
+ registerType(rawType, {
+ name: name,
+ "fromWireType": function (value) {
+ var length = HEAPU32[value >> 2];
+ var str;
+ if (stdStringIsUTF8) {
+ var decodeStartPtr = value + 4;
+ for (var i = 0; i <= length; ++i) {
+ var currentBytePtr = value + 4 + i;
+ if (i == length || HEAPU8[currentBytePtr] == 0) {
+ var maxRead = currentBytePtr - decodeStartPtr;
+ var stringSegment = UTF8ToString(decodeStartPtr, maxRead);
+ if (str === undefined) {
+ str = stringSegment
+ } else {
+ str += String.fromCharCode(0);
+ str += stringSegment
+ }
+ decodeStartPtr = currentBytePtr + 1
+ }
+ }
+ } else {
+ var a = new Array(length);
+ for (var i = 0; i < length; ++i) {
+ a[i] = String.fromCharCode(HEAPU8[value + 4 + i])
+ }
+ str = a.join("")
+ }
+ _free(value);
+ return str
+ },
+ "toWireType": function (destructors, value) {
+ if (value instanceof ArrayBuffer) {
+ value = new Uint8Array(value)
+ }
+ var getLength;
+ var valueIsOfTypeString = typeof value === "string";
+ if (!(valueIsOfTypeString || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array)) {
+ throwBindingError("Cannot pass non-string to std::string")
+ }
+ if (stdStringIsUTF8 && valueIsOfTypeString) {
+ getLength = function () {
+ return lengthBytesUTF8(value)
+ }
+ } else {
+ getLength = function () {
+ return value.length
+ }
+ }
+ var length = getLength();
+ var ptr = _malloc(4 + length + 1);
+ HEAPU32[ptr >> 2] = length;
+ if (stdStringIsUTF8 && valueIsOfTypeString) {
+ stringToUTF8(value, ptr + 4, length + 1)
+ } else {
+ if (valueIsOfTypeString) {
+ for (var i = 0; i < length; ++i) {
+ var charCode = value.charCodeAt(i);
+ if (charCode > 255) {
+ _free(ptr);
+ throwBindingError("String has UTF-16 code units that do not fit in 8 bits")
+ }
+ HEAPU8[ptr + 4 + i] = charCode
+ }
+ } else {
+ for (var i = 0; i < length; ++i) {
+ HEAPU8[ptr + 4 + i] = value[i]
+ }
+ }
+ }
+ if (destructors !== null) {
+ destructors.push(_free, ptr)
+ }
+ return ptr
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": simpleReadValueFromPointer,
+ destructorFunction: function (ptr) {
+ _free(ptr)
+ }
+ })
+ }
+
+ function __embind_register_std_wstring(rawType, charSize, name) {
+ name = readLatin1String(name);
+ var decodeString, encodeString, getHeap, lengthBytesUTF, shift;
+ if (charSize === 2) {
+ decodeString = UTF16ToString;
+ encodeString = stringToUTF16;
+ lengthBytesUTF = lengthBytesUTF16;
+ getHeap = function () {
+ return HEAPU16
+ };
+ shift = 1
+ } else if (charSize === 4) {
+ decodeString = UTF32ToString;
+ encodeString = stringToUTF32;
+ lengthBytesUTF = lengthBytesUTF32;
+ getHeap = function () {
+ return HEAPU32
+ };
+ shift = 2
+ }
+ registerType(rawType, {
+ name: name,
+ "fromWireType": function (value) {
+ var length = HEAPU32[value >> 2];
+ var HEAP = getHeap();
+ var str;
+ var decodeStartPtr = value + 4;
+ for (var i = 0; i <= length; ++i) {
+ var currentBytePtr = value + 4 + i * charSize;
+ if (i == length || HEAP[currentBytePtr >> shift] == 0) {
+ var maxReadBytes = currentBytePtr - decodeStartPtr;
+ var stringSegment = decodeString(decodeStartPtr, maxReadBytes);
+ if (str === undefined) {
+ str = stringSegment
+ } else {
+ str += String.fromCharCode(0);
+ str += stringSegment
+ }
+ decodeStartPtr = currentBytePtr + charSize
+ }
+ }
+ _free(value);
+ return str
+ },
+ "toWireType": function (destructors, value) {
+ if (!(typeof value === "string")) {
+ throwBindingError("Cannot pass non-string to C++ string type " + name)
+ }
+ var length = lengthBytesUTF(value);
+ var ptr = _malloc(4 + length + charSize);
+ HEAPU32[ptr >> 2] = length >> shift;
+ encodeString(value, ptr + 4, length + charSize);
+ if (destructors !== null) {
+ destructors.push(_free, ptr)
+ }
+ return ptr
+ },
+ "argPackAdvance": 8,
+ "readValueFromPointer": simpleReadValueFromPointer,
+ destructorFunction: function (ptr) {
+ _free(ptr)
+ }
+ })
+ }
+
+ function __embind_register_value_array(rawType, name, constructorSignature, rawConstructor, destructorSignature, rawDestructor) {
+ tupleRegistrations[rawType] = {
+ name: readLatin1String(name),
+ rawConstructor: embind__requireFunction(constructorSignature, rawConstructor),
+ rawDestructor: embind__requireFunction(destructorSignature, rawDestructor),
+ elements: []
+ }
+ }
+
+ function __embind_register_value_array_element(rawTupleType, getterReturnType, getterSignature, getter, getterContext, setterArgumentType, setterSignature, setter, setterContext) {
+ tupleRegistrations[rawTupleType].elements.push({
+ getterReturnType: getterReturnType,
+ getter: embind__requireFunction(getterSignature, getter),
+ getterContext: getterContext,
+ setterArgumentType: setterArgumentType,
+ setter: embind__requireFunction(setterSignature, setter),
+ setterContext: setterContext
+ })
+ }
+
+ function __embind_register_value_object(rawType, name, constructorSignature, rawConstructor, destructorSignature, rawDestructor) {
+ structRegistrations[rawType] = {
+ name: readLatin1String(name),
+ rawConstructor: embind__requireFunction(constructorSignature, rawConstructor),
+ rawDestructor: embind__requireFunction(destructorSignature, rawDestructor),
+ fields: []
+ }
+ }
+
+ function __embind_register_value_object_field(structType, fieldName, getterReturnType, getterSignature, getter, getterContext, setterArgumentType, setterSignature, setter, setterContext) {
+ structRegistrations[structType].fields.push({
+ fieldName: readLatin1String(fieldName),
+ getterReturnType: getterReturnType,
+ getter: embind__requireFunction(getterSignature, getter),
+ getterContext: getterContext,
+ setterArgumentType: setterArgumentType,
+ setter: embind__requireFunction(setterSignature, setter),
+ setterContext: setterContext
+ })
+ }
+
+ function __embind_register_void(rawType, name) {
+ name = readLatin1String(name);
+ registerType(rawType, {
+ isVoid: true, name: name, "argPackAdvance": 0, "fromWireType": function () {
+ return undefined
+ }, "toWireType": function (destructors, o) {
+ return undefined
+ }
+ })
+ }
+
+ var emval_symbols = {};
+
+ function getStringOrSymbol(address) {
+ var symbol = emval_symbols[address];
+ if (symbol === undefined) {
+ return readLatin1String(address)
+ } else {
+ return symbol
+ }
+ }
+
+ var emval_methodCallers = [];
+
+ function requireHandle(handle) {
+ if (!handle) {
+ throwBindingError("Cannot use deleted val. handle = " + handle)
+ }
+ return emval_handle_array[handle].value
+ }
+
+ function __emval_call_void_method(caller, handle, methodName, args) {
+ caller = emval_methodCallers[caller];
+ handle = requireHandle(handle);
+ methodName = getStringOrSymbol(methodName);
+ caller(handle, methodName, null, args)
+ }
+
+ function __emval_addMethodCaller(caller) {
+ var id = emval_methodCallers.length;
+ emval_methodCallers.push(caller);
+ return id
+ }
+
+ function requireRegisteredType(rawType, humanName) {
+ var impl = registeredTypes[rawType];
+ if (undefined === impl) {
+ throwBindingError(humanName + " has unknown type " + getTypeName(rawType))
+ }
+ return impl
+ }
+
+ function __emval_lookupTypes(argCount, argTypes) {
+ var a = new Array(argCount);
+ for (var i = 0; i < argCount; ++i) {
+ a[i] = requireRegisteredType(HEAP32[(argTypes >> 2) + i], "parameter " + i)
+ }
+ return a
+ }
+
+ function __emval_get_method_caller(argCount, argTypes) {
+ var types = __emval_lookupTypes(argCount, argTypes);
+ var retType = types[0];
+ var signatureName = retType.name + "_$" + types.slice(1).map(function (t) {
+ return t.name
+ }).join("_") + "$";
+ var params = ["retType"];
+ var args = [retType];
+ var argsList = "";
+ for (var i = 0; i < argCount - 1; ++i) {
+ argsList += (i !== 0 ? ", " : "") + "arg" + i;
+ params.push("argType" + i);
+ args.push(types[1 + i])
+ }
+ var functionName = makeLegalFunctionName("methodCaller_" + signatureName);
+ var functionBody = "return function " + functionName + "(handle, name, destructors, args) {\n";
+ var offset = 0;
+ for (var i = 0; i < argCount - 1; ++i) {
+ functionBody += " var arg" + i + " = argType" + i + ".readValueFromPointer(args" + (offset ? "+" + offset : "") + ");\n";
+ offset += types[i + 1]["argPackAdvance"]
+ }
+ functionBody += " var rv = handle[name](" + argsList + ");\n";
+ for (var i = 0; i < argCount - 1; ++i) {
+ if (types[i + 1]["deleteObject"]) {
+ functionBody += " argType" + i + ".deleteObject(arg" + i + ");\n"
+ }
+ }
+ if (!retType.isVoid) {
+ functionBody += " return retType.toWireType(destructors, rv);\n"
+ }
+ functionBody += "};\n";
+ params.push(functionBody);
+ var invokerFunction = new_(Function, params).apply(null, args);
+ return __emval_addMethodCaller(invokerFunction)
+ }
+
+ function __emval_incref(handle) {
+ if (handle > 4) {
+ emval_handle_array[handle].refcount += 1
+ }
+ }
+
+ function __emval_new_array() {
+ return __emval_register([])
+ }
+
+ function __emval_take_value(type, argv) {
+ type = requireRegisteredType(type, "_emval_take_value");
+ var v = type["readValueFromPointer"](argv);
+ return __emval_register(v)
+ }
+
+ function _abort() {
+ abort()
+ }
+
+ function _emscripten_get_sbrk_ptr() {
+ return 642656
+ }
+
+ function _emscripten_memcpy_big(dest, src, num) {
+ HEAPU8.copyWithin(dest, src, src + num)
+ }
+
+ function _emscripten_get_heap_size() {
+ return HEAPU8.length
+ }
+
+ function emscripten_realloc_buffer(size) {
+ try {
+ wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16);
+ updateGlobalBufferAndViews(wasmMemory.buffer);
+ return 1
+ } catch (e) {
+ }
+ }
+
+ function _emscripten_resize_heap(requestedSize) {
+ requestedSize = requestedSize >>> 0;
+ var oldSize = _emscripten_get_heap_size();
+ var PAGE_MULTIPLE = 65536;
+ var maxHeapSize = 2147483648;
+ if (requestedSize > maxHeapSize) {
+ return false
+ }
+ var minHeapSize = 16777216;
+ for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
+ var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
+ overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
+ var newSize = Math.min(maxHeapSize, alignUp(Math.max(minHeapSize, requestedSize, overGrownHeapSize), PAGE_MULTIPLE));
+ var replacement = emscripten_realloc_buffer(newSize);
+ if (replacement) {
+ return true
+ }
+ }
+ return false
+ }
+
+ var ENV = {};
+
+ function __getExecutableName() {
+ return thisProgram || "./this.program"
+ }
+
+ function getEnvStrings() {
+ if (!getEnvStrings.strings) {
+ var lang = (typeof navigator === "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8";
+ var env = {
+ "USER": "web_user",
+ "LOGNAME": "web_user",
+ "PATH": "/",
+ "PWD": "/",
+ "HOME": "/home/web_user",
+ "LANG": lang,
+ "_": __getExecutableName()
+ };
+ for (var x in ENV) {
+ env[x] = ENV[x]
+ }
+ var strings = [];
+ for (var x in env) {
+ strings.push(x + "=" + env[x])
+ }
+ getEnvStrings.strings = strings
+ }
+ return getEnvStrings.strings
+ }
+
+ function _environ_get(__environ, environ_buf) {
+ var bufSize = 0;
+ getEnvStrings().forEach(function (string, i) {
+ var ptr = environ_buf + bufSize;
+ HEAP32[__environ + i * 4 >> 2] = ptr;
+ writeAsciiToMemory(string, ptr);
+ bufSize += string.length + 1
+ });
+ return 0
+ }
+
+ function _environ_sizes_get(penviron_count, penviron_buf_size) {
+ var strings = getEnvStrings();
+ HEAP32[penviron_count >> 2] = strings.length;
+ var bufSize = 0;
+ strings.forEach(function (string) {
+ bufSize += string.length + 1
+ });
+ HEAP32[penviron_buf_size >> 2] = bufSize;
+ return 0
+ }
+
+ function _fd_close(fd) {
+ try {
+ var stream = SYSCALLS.getStreamFromFD(fd);
+ FS.close(stream);
+ return 0
+ } catch (e) {
+ if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
+ return e.errno
+ }
+ }
+
+ function _fd_read(fd, iov, iovcnt, pnum) {
+ try {
+ var stream = SYSCALLS.getStreamFromFD(fd);
+ var num = SYSCALLS.doReadv(stream, iov, iovcnt);
+ HEAP32[pnum >> 2] = num;
+ return 0
+ } catch (e) {
+ if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
+ return e.errno
+ }
+ }
+
+ function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
+ try {
+ var stream = SYSCALLS.getStreamFromFD(fd);
+ var HIGH_OFFSET = 4294967296;
+ var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);
+ var DOUBLE_LIMIT = 9007199254740992;
+ if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {
+ return -61
+ }
+ FS.llseek(stream, offset, whence);
+ tempI64 = [stream.position >>> 0, (tempDouble = stream.position, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1];
+ if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null;
+ return 0
+ } catch (e) {
+ if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
+ return e.errno
+ }
+ }
+
+ function _fd_write(fd, iov, iovcnt, pnum) {
+ try {
+ var stream = SYSCALLS.getStreamFromFD(fd);
+ var num = SYSCALLS.doWritev(stream, iov, iovcnt);
+ HEAP32[pnum >> 2] = num;
+ return 0
+ } catch (e) {
+ if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
+ return e.errno
+ }
+ }
+
+ function _pthread_mutexattr_destroy() {
+ }
+
+ function _pthread_mutexattr_init() {
+ }
+
+ function _pthread_mutexattr_settype() {
+ }
+
+ function _setTempRet0($i) {
+ setTempRet0($i | 0)
+ }
+
+ function __isLeapYear(year) {
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
+ }
+
+ function __arraySum(array, index) {
+ var sum = 0;
+ for (var i = 0; i <= index; sum += array[i++]) {
+ }
+ return sum
+ }
+
+ var __MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ var __MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+ function __addDays(date, days) {
+ var newDate = new Date(date.getTime());
+ while (days > 0) {
+ var leap = __isLeapYear(newDate.getFullYear());
+ var currentMonth = newDate.getMonth();
+ var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth];
+ if (days > daysInCurrentMonth - newDate.getDate()) {
+ days -= daysInCurrentMonth - newDate.getDate() + 1;
+ newDate.setDate(1);
+ if (currentMonth < 11) {
+ newDate.setMonth(currentMonth + 1)
+ } else {
+ newDate.setMonth(0);
+ newDate.setFullYear(newDate.getFullYear() + 1)
+ }
+ } else {
+ newDate.setDate(newDate.getDate() + days);
+ return newDate
+ }
+ }
+ return newDate
+ }
+
+ function _strftime(s, maxsize, format, tm) {
+ var tm_zone = HEAP32[tm + 40 >> 2];
+ var date = {
+ tm_sec: HEAP32[tm >> 2],
+ tm_min: HEAP32[tm + 4 >> 2],
+ tm_hour: HEAP32[tm + 8 >> 2],
+ tm_mday: HEAP32[tm + 12 >> 2],
+ tm_mon: HEAP32[tm + 16 >> 2],
+ tm_year: HEAP32[tm + 20 >> 2],
+ tm_wday: HEAP32[tm + 24 >> 2],
+ tm_yday: HEAP32[tm + 28 >> 2],
+ tm_isdst: HEAP32[tm + 32 >> 2],
+ tm_gmtoff: HEAP32[tm + 36 >> 2],
+ tm_zone: tm_zone ? UTF8ToString(tm_zone) : ""
+ };
+ var pattern = UTF8ToString(format);
+ var EXPANSION_RULES_1 = {
+ "%c": "%a %b %d %H:%M:%S %Y",
+ "%D": "%m/%d/%y",
+ "%F": "%Y-%m-%d",
+ "%h": "%b",
+ "%r": "%I:%M:%S %p",
+ "%R": "%H:%M",
+ "%T": "%H:%M:%S",
+ "%x": "%m/%d/%y",
+ "%X": "%H:%M:%S",
+ "%Ec": "%c",
+ "%EC": "%C",
+ "%Ex": "%m/%d/%y",
+ "%EX": "%H:%M:%S",
+ "%Ey": "%y",
+ "%EY": "%Y",
+ "%Od": "%d",
+ "%Oe": "%e",
+ "%OH": "%H",
+ "%OI": "%I",
+ "%Om": "%m",
+ "%OM": "%M",
+ "%OS": "%S",
+ "%Ou": "%u",
+ "%OU": "%U",
+ "%OV": "%V",
+ "%Ow": "%w",
+ "%OW": "%W",
+ "%Oy": "%y"
+ };
+ for (var rule in EXPANSION_RULES_1) {
+ pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule])
+ }
+ var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+ var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+
+ function leadingSomething(value, digits, character) {
+ var str = typeof value === "number" ? value.toString() : value || "";
+ while (str.length < digits) {
+ str = character[0] + str
+ }
+ return str
+ }
+
+ function leadingNulls(value, digits) {
+ return leadingSomething(value, digits, "0")
+ }
+
+ function compareByDay(date1, date2) {
+ function sgn(value) {
+ return value < 0 ? -1 : value > 0 ? 1 : 0
+ }
+
+ var compare;
+ if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) {
+ if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) {
+ compare = sgn(date1.getDate() - date2.getDate())
+ }
+ }
+ return compare
+ }
+
+ function getFirstWeekStartDate(janFourth) {
+ switch (janFourth.getDay()) {
+ case 0:
+ return new Date(janFourth.getFullYear() - 1, 11, 29);
+ case 1:
+ return janFourth;
+ case 2:
+ return new Date(janFourth.getFullYear(), 0, 3);
+ case 3:
+ return new Date(janFourth.getFullYear(), 0, 2);
+ case 4:
+ return new Date(janFourth.getFullYear(), 0, 1);
+ case 5:
+ return new Date(janFourth.getFullYear() - 1, 11, 31);
+ case 6:
+ return new Date(janFourth.getFullYear() - 1, 11, 30)
+ }
+ }
+
+ function getWeekBasedYear(date) {
+ var thisDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday);
+ var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
+ var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4);
+ var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
+ var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
+ if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
+ if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
+ return thisDate.getFullYear() + 1
+ } else {
+ return thisDate.getFullYear()
+ }
+ } else {
+ return thisDate.getFullYear() - 1
+ }
+ }
+
+ var EXPANSION_RULES_2 = {
+ "%a": function (date) {
+ return WEEKDAYS[date.tm_wday].substring(0, 3)
+ }, "%A": function (date) {
+ return WEEKDAYS[date.tm_wday]
+ }, "%b": function (date) {
+ return MONTHS[date.tm_mon].substring(0, 3)
+ }, "%B": function (date) {
+ return MONTHS[date.tm_mon]
+ }, "%C": function (date) {
+ var year = date.tm_year + 1900;
+ return leadingNulls(year / 100 | 0, 2)
+ }, "%d": function (date) {
+ return leadingNulls(date.tm_mday, 2)
+ }, "%e": function (date) {
+ return leadingSomething(date.tm_mday, 2, " ")
+ }, "%g": function (date) {
+ return getWeekBasedYear(date).toString().substring(2)
+ }, "%G": function (date) {
+ return getWeekBasedYear(date)
+ }, "%H": function (date) {
+ return leadingNulls(date.tm_hour, 2)
+ }, "%I": function (date) {
+ var twelveHour = date.tm_hour;
+ if (twelveHour == 0) twelveHour = 12; else if (twelveHour > 12) twelveHour -= 12;
+ return leadingNulls(twelveHour, 2)
+ }, "%j": function (date) {
+ return leadingNulls(date.tm_mday + __arraySum(__isLeapYear(date.tm_year + 1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon - 1), 3)
+ }, "%m": function (date) {
+ return leadingNulls(date.tm_mon + 1, 2)
+ }, "%M": function (date) {
+ return leadingNulls(date.tm_min, 2)
+ }, "%n": function () {
+ return "\n"
+ }, "%p": function (date) {
+ if (date.tm_hour >= 0 && date.tm_hour < 12) {
+ return "AM"
+ } else {
+ return "PM"
+ }
+ }, "%S": function (date) {
+ return leadingNulls(date.tm_sec, 2)
+ }, "%t": function () {
+ return "\t"
+ }, "%u": function (date) {
+ return date.tm_wday || 7
+ }, "%U": function (date) {
+ var janFirst = new Date(date.tm_year + 1900, 0, 1);
+ var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7 - janFirst.getDay());
+ var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday);
+ if (compareByDay(firstSunday, endDate) < 0) {
+ var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31;
+ var firstSundayUntilEndJanuary = 31 - firstSunday.getDate();
+ var days = firstSundayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate();
+ return leadingNulls(Math.ceil(days / 7), 2)
+ }
+ return compareByDay(firstSunday, janFirst) === 0 ? "01" : "00"
+ }, "%V": function (date) {
+ var janFourthThisYear = new Date(date.tm_year + 1900, 0, 4);
+ var janFourthNextYear = new Date(date.tm_year + 1901, 0, 4);
+ var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
+ var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
+ var endDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday);
+ if (compareByDay(endDate, firstWeekStartThisYear) < 0) {
+ return "53"
+ }
+ if (compareByDay(firstWeekStartNextYear, endDate) <= 0) {
+ return "01"
+ }
+ var daysDifference;
+ if (firstWeekStartThisYear.getFullYear() < date.tm_year + 1900) {
+ daysDifference = date.tm_yday + 32 - firstWeekStartThisYear.getDate()
+ } else {
+ daysDifference = date.tm_yday + 1 - firstWeekStartThisYear.getDate()
+ }
+ return leadingNulls(Math.ceil(daysDifference / 7), 2)
+ }, "%w": function (date) {
+ return date.tm_wday
+ }, "%W": function (date) {
+ var janFirst = new Date(date.tm_year, 0, 1);
+ var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7 - janFirst.getDay() + 1);
+ var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday);
+ if (compareByDay(firstMonday, endDate) < 0) {
+ var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31;
+ var firstMondayUntilEndJanuary = 31 - firstMonday.getDate();
+ var days = firstMondayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate();
+ return leadingNulls(Math.ceil(days / 7), 2)
+ }
+ return compareByDay(firstMonday, janFirst) === 0 ? "01" : "00"
+ }, "%y": function (date) {
+ return (date.tm_year + 1900).toString().substring(2)
+ }, "%Y": function (date) {
+ return date.tm_year + 1900
+ }, "%z": function (date) {
+ var off = date.tm_gmtoff;
+ var ahead = off >= 0;
+ off = Math.abs(off) / 60;
+ off = off / 60 * 100 + off % 60;
+ return (ahead ? "+" : "-") + String("0000" + off).slice(-4)
+ }, "%Z": function (date) {
+ return date.tm_zone
+ }, "%%": function () {
+ return "%"
+ }
+ };
+ for (var rule in EXPANSION_RULES_2) {
+ if (pattern.indexOf(rule) >= 0) {
+ pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date))
+ }
+ }
+ var bytes = intArrayFromString(pattern, false);
+ if (bytes.length > maxsize) {
+ return 0
+ }
+ writeArrayToMemory(bytes, s);
+ return bytes.length - 1
+ }
+
+ function _strftime_l(s, maxsize, format, tm) {
+ return _strftime(s, maxsize, format, tm)
+ }
+
+ Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) {
+ Browser.requestFullscreen(lockPointer, resizeCanvas)
+ };
+ Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) {
+ Browser.requestAnimationFrame(func)
+ };
+ Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) {
+ Browser.setCanvasSize(width, height, noUpdates)
+ };
+ Module["pauseMainLoop"] = function Module_pauseMainLoop() {
+ Browser.mainLoop.pause()
+ };
+ Module["resumeMainLoop"] = function Module_resumeMainLoop() {
+ Browser.mainLoop.resume()
+ };
+ Module["getUserMedia"] = function Module_getUserMedia() {
+ Browser.getUserMedia()
+ };
+ Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) {
+ return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes)
+ };
+ var FSNode = function (parent, name, mode, rdev) {
+ if (!parent) {
+ parent = this
+ }
+ this.parent = parent;
+ this.mount = parent.mount;
+ this.mounted = null;
+ this.id = FS.nextInode++;
+ this.name = name;
+ this.mode = mode;
+ this.node_ops = {};
+ this.stream_ops = {};
+ this.rdev = rdev
+ };
+ var readMode = 292 | 73;
+ var writeMode = 146;
+ Object.defineProperties(FSNode.prototype, {
+ read: {
+ get: function () {
+ return (this.mode & readMode) === readMode
+ }, set: function (val) {
+ val ? this.mode |= readMode : this.mode &= ~readMode
+ }
+ }, write: {
+ get: function () {
+ return (this.mode & writeMode) === writeMode
+ }, set: function (val) {
+ val ? this.mode |= writeMode : this.mode &= ~writeMode
+ }
+ }, isFolder: {
+ get: function () {
+ return FS.isDir(this.mode)
+ }
+ }, isDevice: {
+ get: function () {
+ return FS.isChrdev(this.mode)
+ }
+ }
+ });
+ FS.FSNode = FSNode;
+ FS.staticInit();
+ Module["FS_createFolder"] = FS.createFolder;
+ Module["FS_createPath"] = FS.createPath;
+ Module["FS_createDataFile"] = FS.createDataFile;
+ Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
+ Module["FS_createLazyFile"] = FS.createLazyFile;
+ Module["FS_createLink"] = FS.createLink;
+ Module["FS_createDevice"] = FS.createDevice;
+ Module["FS_unlink"] = FS.unlink;
+ InternalError = Module["InternalError"] = extendError(Error, "InternalError");
+ embind_init_charCodes();
+ BindingError = Module["BindingError"] = extendError(Error, "BindingError");
+ init_ClassHandle();
+ init_RegisteredPointer();
+ init_embind();
+ UnboundTypeError = Module["UnboundTypeError"] = extendError(Error, "UnboundTypeError");
+ init_emval();
+ var ASSERTIONS = false;
+
+ function intArrayFromString(stringy, dontAddNull, length) {
+ var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
+ var u8array = new Array(len);
+ var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
+ if (dontAddNull) u8array.length = numBytesWritten;
+ return u8array
+ }
+
+ var asmLibraryArg = {
+ "__cxa_allocate_exception": ___cxa_allocate_exception,
+ "__cxa_atexit": ___cxa_atexit,
+ "__cxa_throw": ___cxa_throw,
+ "__map_file": ___map_file,
+ "__sys_munmap": ___sys_munmap,
+ "_embind_finalize_value_array": __embind_finalize_value_array,
+ "_embind_finalize_value_object": __embind_finalize_value_object,
+ "_embind_register_bool": __embind_register_bool,
+ "_embind_register_class": __embind_register_class,
+ "_embind_register_class_class_function": __embind_register_class_class_function,
+ "_embind_register_class_constructor": __embind_register_class_constructor,
+ "_embind_register_class_function": __embind_register_class_function,
+ "_embind_register_class_property": __embind_register_class_property,
+ "_embind_register_constant": __embind_register_constant,
+ "_embind_register_emval": __embind_register_emval,
+ "_embind_register_float": __embind_register_float,
+ "_embind_register_function": __embind_register_function,
+ "_embind_register_integer": __embind_register_integer,
+ "_embind_register_memory_view": __embind_register_memory_view,
+ "_embind_register_std_string": __embind_register_std_string,
+ "_embind_register_std_wstring": __embind_register_std_wstring,
+ "_embind_register_value_array": __embind_register_value_array,
+ "_embind_register_value_array_element": __embind_register_value_array_element,
+ "_embind_register_value_object": __embind_register_value_object,
+ "_embind_register_value_object_field": __embind_register_value_object_field,
+ "_embind_register_void": __embind_register_void,
+ "_emval_call_void_method": __emval_call_void_method,
+ "_emval_decref": __emval_decref,
+ "_emval_get_method_caller": __emval_get_method_caller,
+ "_emval_incref": __emval_incref,
+ "_emval_new_array": __emval_new_array,
+ "_emval_take_value": __emval_take_value,
+ "abort": _abort,
+ "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr,
+ "emscripten_memcpy_big": _emscripten_memcpy_big,
+ "emscripten_resize_heap": _emscripten_resize_heap,
+ "environ_get": _environ_get,
+ "environ_sizes_get": _environ_sizes_get,
+ "fd_close": _fd_close,
+ "fd_read": _fd_read,
+ "fd_seek": _fd_seek,
+ "fd_write": _fd_write,
+ "memory": wasmMemory,
+ "pthread_mutexattr_destroy": _pthread_mutexattr_destroy,
+ "pthread_mutexattr_init": _pthread_mutexattr_init,
+ "pthread_mutexattr_settype": _pthread_mutexattr_settype,
+ "setTempRet0": _setTempRet0,
+ "strftime_l": _strftime_l,
+ "table": wasmTable
+ };
+ var asm = createWasm();
+ var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function () {
+ return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["__wasm_call_ctors"]).apply(null, arguments)
+ };
+ var _malloc = Module["_malloc"] = function () {
+ return (_malloc = Module["_malloc"] = Module["asm"]["malloc"]).apply(null, arguments)
+ };
+ var _free = Module["_free"] = function () {
+ return (_free = Module["_free"] = Module["asm"]["free"]).apply(null, arguments)
+ };
+ var ___errno_location = Module["___errno_location"] = function () {
+ return (___errno_location = Module["___errno_location"] = Module["asm"]["__errno_location"]).apply(null, arguments)
+ };
+ var ___getTypeName = Module["___getTypeName"] = function () {
+ return (___getTypeName = Module["___getTypeName"] = Module["asm"]["__getTypeName"]).apply(null, arguments)
+ };
+ var ___embind_register_native_and_builtin_types = Module["___embind_register_native_and_builtin_types"] = function () {
+ return (___embind_register_native_and_builtin_types = Module["___embind_register_native_and_builtin_types"] = Module["asm"]["__embind_register_native_and_builtin_types"]).apply(null, arguments)
+ };
+ var _setThrew = Module["_setThrew"] = function () {
+ return (_setThrew = Module["_setThrew"] = Module["asm"]["setThrew"]).apply(null, arguments)
+ };
+ var stackSave = Module["stackSave"] = function () {
+ return (stackSave = Module["stackSave"] = Module["asm"]["stackSave"]).apply(null, arguments)
+ };
+ var stackRestore = Module["stackRestore"] = function () {
+ return (stackRestore = Module["stackRestore"] = Module["asm"]["stackRestore"]).apply(null, arguments)
+ };
+ var stackAlloc = Module["stackAlloc"] = function () {
+ return (stackAlloc = Module["stackAlloc"] = Module["asm"]["stackAlloc"]).apply(null, arguments)
+ };
+ var ___cxa_demangle = Module["___cxa_demangle"] = function () {
+ return (___cxa_demangle = Module["___cxa_demangle"] = Module["asm"]["__cxa_demangle"]).apply(null, arguments)
+ };
+ var _emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = function () {
+ return (_emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = Module["asm"]["emscripten_main_thread_process_queued_calls"]).apply(null, arguments)
+ };
+ var __growWasmMemory = Module["__growWasmMemory"] = function () {
+ return (__growWasmMemory = Module["__growWasmMemory"] = Module["asm"]["__growWasmMemory"]).apply(null, arguments)
+ };
+ var dynCall_ii = Module["dynCall_ii"] = function () {
+ return (dynCall_ii = Module["dynCall_ii"] = Module["asm"]["dynCall_ii"]).apply(null, arguments)
+ };
+ var dynCall_vi = Module["dynCall_vi"] = function () {
+ return (dynCall_vi = Module["dynCall_vi"] = Module["asm"]["dynCall_vi"]).apply(null, arguments)
+ };
+ var dynCall_i = Module["dynCall_i"] = function () {
+ return (dynCall_i = Module["dynCall_i"] = Module["asm"]["dynCall_i"]).apply(null, arguments)
+ };
+ var dynCall_iii = Module["dynCall_iii"] = function () {
+ return (dynCall_iii = Module["dynCall_iii"] = Module["asm"]["dynCall_iii"]).apply(null, arguments)
+ };
+ var dynCall_iiii = Module["dynCall_iiii"] = function () {
+ return (dynCall_iiii = Module["dynCall_iiii"] = Module["asm"]["dynCall_iiii"]).apply(null, arguments)
+ };
+ var dynCall_iiiii = Module["dynCall_iiiii"] = function () {
+ return (dynCall_iiiii = Module["dynCall_iiiii"] = Module["asm"]["dynCall_iiiii"]).apply(null, arguments)
+ };
+ var dynCall_iiiiii = Module["dynCall_iiiiii"] = function () {
+ return (dynCall_iiiiii = Module["dynCall_iiiiii"] = Module["asm"]["dynCall_iiiiii"]).apply(null, arguments)
+ };
+ var dynCall_iiiiiii = Module["dynCall_iiiiiii"] = function () {
+ return (dynCall_iiiiiii = Module["dynCall_iiiiiii"] = Module["asm"]["dynCall_iiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viii = Module["dynCall_viii"] = function () {
+ return (dynCall_viii = Module["dynCall_viii"] = Module["asm"]["dynCall_viii"]).apply(null, arguments)
+ };
+ var dynCall_viiii = Module["dynCall_viiii"] = function () {
+ return (dynCall_viiii = Module["dynCall_viiii"] = Module["asm"]["dynCall_viiii"]).apply(null, arguments)
+ };
+ var dynCall_vii = Module["dynCall_vii"] = function () {
+ return (dynCall_vii = Module["dynCall_vii"] = Module["asm"]["dynCall_vii"]).apply(null, arguments)
+ };
+ var dynCall_viiidd = Module["dynCall_viiidd"] = function () {
+ return (dynCall_viiidd = Module["dynCall_viiidd"] = Module["asm"]["dynCall_viiidd"]).apply(null, arguments)
+ };
+ var dynCall_viiiidd = Module["dynCall_viiiidd"] = function () {
+ return (dynCall_viiiidd = Module["dynCall_viiiidd"] = Module["asm"]["dynCall_viiiidd"]).apply(null, arguments)
+ };
+ var dynCall_viiid = Module["dynCall_viiid"] = function () {
+ return (dynCall_viiid = Module["dynCall_viiid"] = Module["asm"]["dynCall_viiid"]).apply(null, arguments)
+ };
+ var dynCall_viiiid = Module["dynCall_viiiid"] = function () {
+ return (dynCall_viiiid = Module["dynCall_viiiid"] = Module["asm"]["dynCall_viiiid"]).apply(null, arguments)
+ };
+ var dynCall_viiiii = Module["dynCall_viiiii"] = function () {
+ return (dynCall_viiiii = Module["dynCall_viiiii"] = Module["asm"]["dynCall_viiiii"]).apply(null, arguments)
+ };
+ var dynCall_dii = Module["dynCall_dii"] = function () {
+ return (dynCall_dii = Module["dynCall_dii"] = Module["asm"]["dynCall_dii"]).apply(null, arguments)
+ };
+ var dynCall_diii = Module["dynCall_diii"] = function () {
+ return (dynCall_diii = Module["dynCall_diii"] = Module["asm"]["dynCall_diii"]).apply(null, arguments)
+ };
+ var dynCall_iiiid = Module["dynCall_iiiid"] = function () {
+ return (dynCall_iiiid = Module["dynCall_iiiid"] = Module["asm"]["dynCall_iiiid"]).apply(null, arguments)
+ };
+ var dynCall_fiii = Module["dynCall_fiii"] = function () {
+ return (dynCall_fiii = Module["dynCall_fiii"] = Module["asm"]["dynCall_fiii"]).apply(null, arguments)
+ };
+ var dynCall_fiiii = Module["dynCall_fiiii"] = function () {
+ return (dynCall_fiiii = Module["dynCall_fiiii"] = Module["asm"]["dynCall_fiiii"]).apply(null, arguments)
+ };
+ var dynCall_fiiiii = Module["dynCall_fiiiii"] = function () {
+ return (dynCall_fiiiii = Module["dynCall_fiiiii"] = Module["asm"]["dynCall_fiiiii"]).apply(null, arguments)
+ };
+ var dynCall_diiiii = Module["dynCall_diiiii"] = function () {
+ return (dynCall_diiiii = Module["dynCall_diiiii"] = Module["asm"]["dynCall_diiiii"]).apply(null, arguments)
+ };
+ var dynCall_diiii = Module["dynCall_diiii"] = function () {
+ return (dynCall_diiii = Module["dynCall_diiii"] = Module["asm"]["dynCall_diiii"]).apply(null, arguments)
+ };
+ var dynCall_viid = Module["dynCall_viid"] = function () {
+ return (dynCall_viid = Module["dynCall_viid"] = Module["asm"]["dynCall_viid"]).apply(null, arguments)
+ };
+ var dynCall_fii = Module["dynCall_fii"] = function () {
+ return (dynCall_fii = Module["dynCall_fii"] = Module["asm"]["dynCall_fii"]).apply(null, arguments)
+ };
+ var dynCall_viif = Module["dynCall_viif"] = function () {
+ return (dynCall_viif = Module["dynCall_viif"] = Module["asm"]["dynCall_viif"]).apply(null, arguments)
+ };
+ var dynCall_viiif = Module["dynCall_viiif"] = function () {
+ return (dynCall_viiif = Module["dynCall_viiif"] = Module["asm"]["dynCall_viiif"]).apply(null, arguments)
+ };
+ var dynCall_iiiif = Module["dynCall_iiiif"] = function () {
+ return (dynCall_iiiif = Module["dynCall_iiiif"] = Module["asm"]["dynCall_iiiif"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiii = Module["dynCall_viiiiiii"] = function () {
+ return (dynCall_viiiiiii = Module["dynCall_viiiiiii"] = Module["asm"]["dynCall_viiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viiiiii = Module["dynCall_viiiiii"] = function () {
+ return (dynCall_viiiiii = Module["dynCall_viiiiii"] = Module["asm"]["dynCall_viiiiii"]).apply(null, arguments)
+ };
+ var dynCall_iiidd = Module["dynCall_iiidd"] = function () {
+ return (dynCall_iiidd = Module["dynCall_iiidd"] = Module["asm"]["dynCall_iiidd"]).apply(null, arguments)
+ };
+ var dynCall_viidd = Module["dynCall_viidd"] = function () {
+ return (dynCall_viidd = Module["dynCall_viidd"] = Module["asm"]["dynCall_viidd"]).apply(null, arguments)
+ };
+ var dynCall_viiiiddi = Module["dynCall_viiiiddi"] = function () {
+ return (dynCall_viiiiddi = Module["dynCall_viiiiddi"] = Module["asm"]["dynCall_viiiiddi"]).apply(null, arguments)
+ };
+ var dynCall_viiiddi = Module["dynCall_viiiddi"] = function () {
+ return (dynCall_viiiddi = Module["dynCall_viiiddi"] = Module["asm"]["dynCall_viiiddi"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiii = Module["dynCall_viiiiiiii"] = function () {
+ return (dynCall_viiiiiiii = Module["dynCall_viiiiiiii"] = Module["asm"]["dynCall_viiiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiiii = Module["dynCall_viiiiiiiii"] = function () {
+ return (dynCall_viiiiiiiii = Module["dynCall_viiiiiiiii"] = Module["asm"]["dynCall_viiiiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiiddi = Module["dynCall_viiiiiiiddi"] = function () {
+ return (dynCall_viiiiiiiddi = Module["dynCall_viiiiiiiddi"] = Module["asm"]["dynCall_viiiiiiiddi"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiiiiiddi = Module["dynCall_viiiiiiiiiiddi"] = function () {
+ return (dynCall_viiiiiiiiiiddi = Module["dynCall_viiiiiiiiiiddi"] = Module["asm"]["dynCall_viiiiiiiiiiddi"]).apply(null, arguments)
+ };
+ var dynCall_iiiiiiiii = Module["dynCall_iiiiiiiii"] = function () {
+ return (dynCall_iiiiiiiii = Module["dynCall_iiiiiiiii"] = Module["asm"]["dynCall_iiiiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiiiii = Module["dynCall_viiiiiiiiii"] = function () {
+ return (dynCall_viiiiiiiiii = Module["dynCall_viiiiiiiiii"] = Module["asm"]["dynCall_viiiiiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_viidi = Module["dynCall_viidi"] = function () {
+ return (dynCall_viidi = Module["dynCall_viidi"] = Module["asm"]["dynCall_viidi"]).apply(null, arguments)
+ };
+ var dynCall_vidii = Module["dynCall_vidii"] = function () {
+ return (dynCall_vidii = Module["dynCall_vidii"] = Module["asm"]["dynCall_vidii"]).apply(null, arguments)
+ };
+ var dynCall_viijii = Module["dynCall_viijii"] = function () {
+ return (dynCall_viijii = Module["dynCall_viijii"] = Module["asm"]["dynCall_viijii"]).apply(null, arguments)
+ };
+ var dynCall_v = Module["dynCall_v"] = function () {
+ return (dynCall_v = Module["dynCall_v"] = Module["asm"]["dynCall_v"]).apply(null, arguments)
+ };
+ var dynCall_viiiiiiiiidd = Module["dynCall_viiiiiiiiidd"] = function () {
+ return (dynCall_viiiiiiiiidd = Module["dynCall_viiiiiiiiidd"] = Module["asm"]["dynCall_viiiiiiiiidd"]).apply(null, arguments)
+ };
+ var dynCall_jiji = Module["dynCall_jiji"] = function () {
+ return (dynCall_jiji = Module["dynCall_jiji"] = Module["asm"]["dynCall_jiji"]).apply(null, arguments)
+ };
+ var dynCall_iidiiii = Module["dynCall_iidiiii"] = function () {
+ return (dynCall_iidiiii = Module["dynCall_iidiiii"] = Module["asm"]["dynCall_iidiiii"]).apply(null, arguments)
+ };
+ var dynCall_iiiiij = Module["dynCall_iiiiij"] = function () {
+ return (dynCall_iiiiij = Module["dynCall_iiiiij"] = Module["asm"]["dynCall_iiiiij"]).apply(null, arguments)
+ };
+ var dynCall_iiiiid = Module["dynCall_iiiiid"] = function () {
+ return (dynCall_iiiiid = Module["dynCall_iiiiid"] = Module["asm"]["dynCall_iiiiid"]).apply(null, arguments)
+ };
+ var dynCall_iiiiijj = Module["dynCall_iiiiijj"] = function () {
+ return (dynCall_iiiiijj = Module["dynCall_iiiiijj"] = Module["asm"]["dynCall_iiiiijj"]).apply(null, arguments)
+ };
+ var dynCall_iiiiiiii = Module["dynCall_iiiiiiii"] = function () {
+ return (dynCall_iiiiiiii = Module["dynCall_iiiiiiii"] = Module["asm"]["dynCall_iiiiiiii"]).apply(null, arguments)
+ };
+ var dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = function () {
+ return (dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = Module["asm"]["dynCall_iiiiiijj"]).apply(null, arguments)
+ };
+ Module["getMemory"] = getMemory;
+ Module["addRunDependency"] = addRunDependency;
+ Module["removeRunDependency"] = removeRunDependency;
+ Module["FS_createFolder"] = FS.createFolder;
+ Module["FS_createPath"] = FS.createPath;
+ Module["FS_createDataFile"] = FS.createDataFile;
+ Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
+ Module["FS_createLazyFile"] = FS.createLazyFile;
+ Module["FS_createLink"] = FS.createLink;
+ Module["FS_createDevice"] = FS.createDevice;
+ Module["FS_unlink"] = FS.unlink;
+ var calledRun;
+
+ function ExitStatus(status) {
+ this.name = "ExitStatus";
+ this.message = "Program terminated with exit(" + status + ")";
+ this.status = status
+ }
+
+ dependenciesFulfilled = function runCaller() {
+ if (!calledRun) run();
+ if (!calledRun) dependenciesFulfilled = runCaller
+ };
+
+ function run(args) {
+ args = args || arguments_;
+ if (runDependencies > 0) {
+ return
+ }
+ preRun();
+ if (runDependencies > 0) return;
+
+ function doRun() {
+ if (calledRun) return;
+ calledRun = true;
+ Module["calledRun"] = true;
+ if (ABORT) return;
+ initRuntime();
+ preMain();
+ // readyPromiseResolve(Module);
+ if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
+ postRun()
+ }
+
+ if (Module["setStatus"]) {
+ Module["setStatus"]("Running...");
+ setTimeout(function () {
+ setTimeout(function () {
+ Module["setStatus"]("")
+ }, 1);
+ doRun()
+ }, 1)
+ } else {
+ doRun()
+ }
+ }
+
+ Module["run"] = run;
+ if (Module["preInit"]) {
+ if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]];
+ while (Module["preInit"].length > 0) {
+ Module["preInit"].pop()()
+ }
+ }
+ noExitRuntime = true;
+ run();
+ if (!IsWechat) {
+ // 在微信里不执行,请见另一个Module["imread"]
+ Module["imread"] = function (imageSource) {
+ var img = null;
+ if (typeof imageSource === "string") {
+ img = document.getElementById(imageSource)
+ } else {
+ img = imageSource
+ }
+ var canvas = null;
+ var ctx = null;
+ if (img instanceof HTMLImageElement) {
+ canvas = document.createElement("canvas");
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0, img.width, img.height)
+ } else if (img instanceof HTMLCanvasElement) {
+ canvas = img;
+ ctx = canvas.getContext("2d")
+ } else {
+ throw new Error("Please input the valid canvas or img id.");
+ return
+ }
+ var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ return cv.matFromImageData(imgData)
+
+ };
+ // 在微信里不执行,请见另一个Module["imshow"]
+ Module["imshow"] = function (canvasSource, mat) {
+ var canvas = null;
+ if (typeof canvasSource === "string") {
+ canvas = document.getElementById(canvasSource)
+ } else {
+ canvas = canvasSource
+ }
+ if (!(canvas instanceof HTMLCanvasElement)) {
+ throw new Error("Please input the valid canvas element or id.");
+ return
+ }
+ if (!(mat instanceof cv.Mat)) {
+ throw new Error("Please input the valid cv.Mat instance.");
+ return
+ }
+ var img = new cv.Mat;
+ var depth = mat.type() % 8;
+ var scale = depth <= cv.CV_8S ? 1 : depth <= cv.CV_32S ? 1 / 256 : 255;
+ var shift = depth === cv.CV_8S || depth === cv.CV_16S ? 128 : 0;
+ mat.convertTo(img, cv.CV_8U, scale, shift);
+ switch (img.type()) {
+ case cv.CV_8UC1:
+ cv.cvtColor(img, img, cv.COLOR_GRAY2RGBA);
+ break;
+ case cv.CV_8UC3:
+ cv.cvtColor(img, img, cv.COLOR_RGB2RGBA);
+ break;
+ case cv.CV_8UC4:
+ break;
+ default:
+ throw new Error("Bad number of channels (Source image must have 1, 3 or 4 channels)");
+ return
+ }
+ var imgData = new ImageData(new Uint8ClampedArray(img.data), img.cols, img.rows);
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ canvas.width = imgData.width;
+ canvas.height = imgData.height;
+ ctx.putImageData(imgData, 0, 0);
+ img.delete()
+
+ };
+ } else {
+ Module["imread"] = function (imgData) {
+ return cv.matFromImageData(imgData)
+ };
+
+ Module["imshow"] = function (canvas, mat) {
+ if (!(mat instanceof cv.Mat)) {
+ throw new Error("Please input the valid cv.Mat instance.");
+ return
+ }
+ var img = new cv.Mat;
+ var depth = mat.type() % 8;
+ var scale = depth <= cv.CV_8S ? 1 : depth <= cv.CV_32S ? 1 / 256 : 255;
+ var shift = depth === cv.CV_8S || depth === cv.CV_16S ? 128 : 0;
+
+ mat.convertTo(img, cv.CV_8U, scale, shift);
+
+ switch (img.type()) {
+ case cv.CV_8UC1:
+ cv.cvtColor(img, img, cv.COLOR_GRAY2RGBA);
+ break;
+ case cv.CV_8UC3:
+ cv.cvtColor(img, img, cv.COLOR_RGB2RGBA);
+ break;
+ case cv.CV_8UC4:
+ break;
+ default:
+ throw new Error("Bad number of channels (Source image must have 1, 3 or 4 channels)");
+ return
+ }
+
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ // 创建ImageData对象
+ var imgData = ctx.createImageData(img.cols, img.rows);
+ // imgData.data是只读对象,但是imgData.data.set()方法可修改imgData.data。
+ imgData.data.set(new Uint8ClampedArray(img.data))
+ // 画布canvas的宽度和高度,不能比图像imgData小。
+ canvas.width = imgData.width;
+ canvas.height = imgData.height;
+ // 需要传递ImageData类型,但小程序无法通过new ImageData()创建该类型。
+ ctx.putImageData(imgData, 0, 0);
+ img.delete()
+ };
+ }
+ Module["VideoCapture"] = function (videoSource) {
+ var video = null;
+ if (typeof videoSource === "string") {
+ video = document.getElementById(videoSource)
+ } else {
+ video = videoSource
+ }
+ if (!(video instanceof HTMLVideoElement)) {
+ throw new Error("Please input the valid video element or id.");
+ return
+ }
+ var canvas = document.createElement("canvas");
+ canvas.width = video.width;
+ canvas.height = video.height;
+ var ctx = canvas.getContext("2d");
+ this.video = video;
+ this.read = function (frame) {
+ if (!(frame instanceof cv.Mat)) {
+ throw new Error("Please input the valid cv.Mat instance.");
+ return
+ }
+ if (frame.type() !== cv.CV_8UC4) {
+ throw new Error("Bad type of input mat: the type should be cv.CV_8UC4.");
+ return
+ }
+ if (frame.cols !== video.width || frame.rows !== video.height) {
+ throw new Error("Bad size of input mat: the size should be same as the video.");
+ return
+ }
+ ctx.drawImage(video, 0, 0, video.width, video.height);
+ frame.data.set(ctx.getImageData(0, 0, video.width, video.height).data)
+ }
+ };
+
+ function Range(start, end) {
+ this.start = typeof start === "undefined" ? 0 : start;
+ this.end = typeof end === "undefined" ? 0 : end
+ }
+
+ Module["Range"] = Range;
+
+ function Point(x, y) {
+ this.x = typeof x === "undefined" ? 0 : x;
+ this.y = typeof y === "undefined" ? 0 : y
+ }
+
+ Module["Point"] = Point;
+
+ function Size(width, height) {
+ this.width = typeof width === "undefined" ? 0 : width;
+ this.height = typeof height === "undefined" ? 0 : height
+ }
+
+ Module["Size"] = Size;
+
+ function Rect() {
+ switch (arguments.length) {
+ case 0: {
+ this.x = 0;
+ this.y = 0;
+ this.width = 0;
+ this.height = 0;
+ break
+ }
+ case 1: {
+ var rect = arguments[0];
+ this.x = rect.x;
+ this.y = rect.y;
+ this.width = rect.width;
+ this.height = rect.height;
+ break
+ }
+ case 2: {
+ var point = arguments[0];
+ var size = arguments[1];
+ this.x = point.x;
+ this.y = point.y;
+ this.width = size.width;
+ this.height = size.height;
+ break
+ }
+ case 4: {
+ this.x = arguments[0];
+ this.y = arguments[1];
+ this.width = arguments[2];
+ this.height = arguments[3];
+ break
+ }
+ default: {
+ throw new Error("Invalid arguments")
+ }
+ }
+ }
+
+ Module["Rect"] = Rect;
+
+ function RotatedRect() {
+ switch (arguments.length) {
+ case 0: {
+ this.center = {x: 0, y: 0};
+ this.size = {width: 0, height: 0};
+ this.angle = 0;
+ break
+ }
+ case 3: {
+ this.center = arguments[0];
+ this.size = arguments[1];
+ this.angle = arguments[2];
+ break
+ }
+ default: {
+ throw new Error("Invalid arguments")
+ }
+ }
+ }
+
+ RotatedRect.points = function (obj) {
+ return Module.rotatedRectPoints(obj)
+ };
+ RotatedRect.boundingRect = function (obj) {
+ return Module.rotatedRectBoundingRect(obj)
+ };
+ RotatedRect.boundingRect2f = function (obj) {
+ return Module.rotatedRectBoundingRect2f(obj)
+ };
+ Module["RotatedRect"] = RotatedRect;
+
+ function Scalar(v0, v1, v2, v3) {
+ this.push(typeof v0 === "undefined" ? 0 : v0);
+ this.push(typeof v1 === "undefined" ? 0 : v1);
+ this.push(typeof v2 === "undefined" ? 0 : v2);
+ this.push(typeof v3 === "undefined" ? 0 : v3)
+ }
+
+ Scalar.prototype = new Array;
+ Scalar.all = function (v) {
+ return new Scalar(v, v, v, v)
+ };
+ Module["Scalar"] = Scalar;
+
+ function MinMaxLoc() {
+ switch (arguments.length) {
+ case 0: {
+ this.minVal = 0;
+ this.maxVal = 0;
+ this.minLoc = new Point;
+ this.maxLoc = new Point;
+ break
+ }
+ case 4: {
+ this.minVal = arguments[0];
+ this.maxVal = arguments[1];
+ this.minLoc = arguments[2];
+ this.maxLoc = arguments[3];
+ break
+ }
+ default: {
+ throw new Error("Invalid arguments")
+ }
+ }
+ }
+
+ Module["MinMaxLoc"] = MinMaxLoc;
+
+ function Circle() {
+ switch (arguments.length) {
+ case 0: {
+ this.center = new Point;
+ this.radius = 0;
+ break
+ }
+ case 2: {
+ this.center = arguments[0];
+ this.radius = arguments[1];
+ break
+ }
+ default: {
+ throw new Error("Invalid arguments")
+ }
+ }
+ }
+
+ Module["Circle"] = Circle;
+
+ function TermCriteria() {
+ switch (arguments.length) {
+ case 0: {
+ this.type = 0;
+ this.maxCount = 0;
+ this.epsilon = 0;
+ break
+ }
+ case 3: {
+ this.type = arguments[0];
+ this.maxCount = arguments[1];
+ this.epsilon = arguments[2];
+ break
+ }
+ default: {
+ throw new Error("Invalid arguments")
+ }
+ }
+ }
+
+ Module["TermCriteria"] = TermCriteria;
+ Module["matFromArray"] = function (rows, cols, type, array) {
+ var mat = new cv.Mat(rows, cols, type);
+ switch (type) {
+ case cv.CV_8U:
+ case cv.CV_8UC1:
+ case cv.CV_8UC2:
+ case cv.CV_8UC3:
+ case cv.CV_8UC4: {
+ mat.data.set(array);
+ break
+ }
+ case cv.CV_8S:
+ case cv.CV_8SC1:
+ case cv.CV_8SC2:
+ case cv.CV_8SC3:
+ case cv.CV_8SC4: {
+ mat.data8S.set(array);
+ break
+ }
+ case cv.CV_16U:
+ case cv.CV_16UC1:
+ case cv.CV_16UC2:
+ case cv.CV_16UC3:
+ case cv.CV_16UC4: {
+ mat.data16U.set(array);
+ break
+ }
+ case cv.CV_16S:
+ case cv.CV_16SC1:
+ case cv.CV_16SC2:
+ case cv.CV_16SC3:
+ case cv.CV_16SC4: {
+ mat.data16S.set(array);
+ break
+ }
+ case cv.CV_32S:
+ case cv.CV_32SC1:
+ case cv.CV_32SC2:
+ case cv.CV_32SC3:
+ case cv.CV_32SC4: {
+ mat.data32S.set(array);
+ break
+ }
+ case cv.CV_32F:
+ case cv.CV_32FC1:
+ case cv.CV_32FC2:
+ case cv.CV_32FC3:
+ case cv.CV_32FC4: {
+ mat.data32F.set(array);
+ break
+ }
+ case cv.CV_64F:
+ case cv.CV_64FC1:
+ case cv.CV_64FC2:
+ case cv.CV_64FC3:
+ case cv.CV_64FC4: {
+ mat.data64F.set(array);
+ break
+ }
+ default: {
+ throw new Error("Type is unsupported")
+ }
+ }
+ return mat
+ };
+ Module["matFromImageData"] = function (imageData) {
+ var mat = new cv.Mat(imageData.height, imageData.width, cv.CV_8UC4);
+ mat.data.set(imageData.data);
+ return mat
+ };
+
+
+ return cv;
+ }
+ );
+ })();
+ return cv(global);
+}));
diff --git a/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv_js.wasm.br b/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv_js.wasm.br
new file mode 100644
index 00000000..a499e4ba
Binary files /dev/null and b/packages/paddlejs-examples/ocrXcx/pages/index/wasm/opencv_js.wasm.br differ
diff --git a/packages/paddlejs-examples/ocrXcx/project.config.json b/packages/paddlejs-examples/ocrXcx/project.config.json
new file mode 100644
index 00000000..e86f0a2f
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/project.config.json
@@ -0,0 +1,58 @@
+{
+ "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "packOptions": {
+ "ignore": [],
+ "include": []
+ },
+ "setting": {
+ "urlCheck": false,
+ "es6": true,
+ "enhance": true,
+ "postcss": true,
+ "preloadBackgroundData": false,
+ "minified": true,
+ "newFeature": false,
+ "coverView": true,
+ "nodeModules": true,
+ "autoAudits": false,
+ "showShadowRootInWxmlPanel": true,
+ "scopeDataCheck": false,
+ "uglifyFileName": false,
+ "checkInvalidKey": true,
+ "checkSiteMap": true,
+ "uploadWithSourceMap": true,
+ "compileHotReLoad": false,
+ "lazyloadPlaceholderEnable": false,
+ "useMultiFrameRuntime": true,
+ "useApiHook": true,
+ "useApiHostProcess": true,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ },
+ "enableEngineNative": false,
+ "useIsolateContext": true,
+ "userConfirmedBundleSwitch": false,
+ "packNpmManually": false,
+ "packNpmRelationList": [],
+ "minifyWXSS": true,
+ "disableUseStrict": false,
+ "minifyWXML": true,
+ "showES6CompileOption": false,
+ "useCompilerPlugins": false,
+ "useStaticServer": true,
+ "ignoreUploadUnusedFiles": false
+ },
+ "compileType": "miniprogram",
+ "libVersion": "2.22.1",
+ "appid": "wx78461a9c81d1234c",
+ "projectname": "mobilenet",
+ "simulatorType": "wechat",
+ "simulatorPluginLibVersion": {},
+ "condition": {},
+ "editorSetting": {
+ "tabIndent": "insertSpaces",
+ "tabSize": 2
+ }
+}
\ No newline at end of file
diff --git a/packages/paddlejs-examples/ocrXcx/project.private.config.json b/packages/paddlejs-examples/ocrXcx/project.private.config.json
new file mode 100644
index 00000000..f8998ee5
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/project.private.config.json
@@ -0,0 +1,8 @@
+{
+ "projectname": "ocrXcx",
+ "setting": {
+ "compileHotReLoad": true
+ },
+ "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "libVersion": "2.23.4"
+}
\ No newline at end of file
diff --git a/packages/paddlejs-examples/ocrXcx/sitemap.json b/packages/paddlejs-examples/ocrXcx/sitemap.json
new file mode 100644
index 00000000..ca02add2
--- /dev/null
+++ b/packages/paddlejs-examples/ocrXcx/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file