路泰科技体检小程序UI设计新版本
:qx
qx
2025-08-06 e3afb7ab25d2709d4e2fe8859bb23ef56b5a1360
:qx
6个文件已修改
35个文件已添加
6460 ■■■■■ 已修改文件
config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/index.html 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/erweima.vue 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/index.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pagesA/Examiner/Examiner.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/LICENSE.md 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/README.md 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/changelog.md 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/common/cache.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/common/queue.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/common/types/cache.d.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/common/types/queue.d.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue 1131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue 1131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js 666 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js 1191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/Sansnn-uQRCode/package.json 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config.js
@@ -3,7 +3,7 @@
    // baseUrl: 'https://ltpeis.xaltjdkj.cn:5011/ltkj-admin',
    // baseUrl: 'https://ltpeis.xaltjdkj.cn:5021',
    // baseUrl: 'http://ltpeis.xaltjdkj.cn:5801',
    baseUrl: 'http://192.168.1.244:5011',
    baseUrl: 'http://192.168.1.113:5011',
    
  // 应用信息
  appInfo: {
package.json
@@ -1,7 +1,11 @@
{
  "dependencies": {
    "@uqrcode/js": "^4.0.7",
    "crypto-js": "^4.2.0",
    "jsencrypt": "^3.3.2",
    "qrcode": "^1.5.4",
    "qrcode.vue": "^3.6.0",
    "uqrcodejs": "^4.0.7",
    "uview-ui": "^2.0.38"
  },
  "devDependencies": {
pages.json
@@ -29,6 +29,11 @@
                "navigationBarTitleText": "我的"
            }
        }, {
            "path": "pages/mine/erweima",
            "style": {
                "navigationBarTitleText": "我的"
            }
        },{
            "path": "pages/cart/cart",
            "style": {
                "navigationBarTitleText": "预约健康"
pages/index.html
@@ -1,20 +1,20 @@
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <script>
      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
        CSS.supports('top: constant(a)'))
      document.write(
        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
    </script>
    <title></title>
    <!--preload-links-->
    <!--app-context-->
  </head>
  <body>
    <div id="app"><!--app-html--></div>
    <script type="module" src="/main.js"></script>
  </body>
</html>
    <head>
        <meta charset="UTF-8" />
        <script>
            var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
                CSS.supports('top: constant(a)'))
            document.write(
                '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
                (coverSupport ? ', viewport-fit=cover' : '') + '" />')
        </script>
        <title></title>
        <!--preload-links-->
        <!--app-context-->
    </head>
    <body>
        <div id="app"><!--app-html--></div>
        <script type="module" src="/main.js"></script>
    </body>
</html>
pages/mine/erweima.vue
New file
@@ -0,0 +1,356 @@
<template>
    <view class="container">
        <!-- 输入区域 -->
        <view class="input-group">
            <text class="label">
                <uni-icons type="compose" size="16" color="#2c3e50" />
                输入文本或URL:
            </text>
            <textarea v-model="inputText" placeholder="在此输入文本、网址或其他信息..." />
        </view>
        <!-- 示例按钮 -->
        <view class="examples">
            <view v-for="(example, index) in examples" :key="index" class="example-btn" @tap="setExample(example.text)">
                {{ example.label }}
            </view>
        </view>
        <!-- 生成按钮 -->
        <button class="generate-btn" @tap="generateQRCode">
            <uni-icons type="bolt" size="20" color="#fff" />
            <text>{{generating ? "生成中...." :"生成二维码" }}</text>
        </button>
        <!-- 二维码显示区域 -->
        <view class="qrcode-container">
            <canvas v-if="qrCodeGenerated" ref="qrcodeCanvas" canvas-id="qrcodeCanvas" class="qrcode-canvas"
                @longpress="handleLongPress" width="200" height="200" />
            <view v-else class="placeholder">
                <uni-icons type="qrcode" size="48" color="#95a5a6" />
                <text>二维码将在此处显示</text>
            </view>
        </view>
    </view>
</template>
<script>
    import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
    export default {
        data() {
            return {
                inputText: 'https://www.example.com',
                qrCodeGenerated: false,
                isMiniprogram: false,
                qrCodeDataUrl: null,
                platformName: 'H5',
                platformIcon: 'circle',
                error: null,
                generating: false,
                saveButtonText: '保存二维码',
                examples: [{
                        label: '示例网址',
                        text: 'https://www.example.com'
                    },
                    {
                        label: '示例文本',
                        text: 'Hello, World!'
                    },
                    {
                        label: '联系方式',
                        text: '微信:example_user'
                    },
                    {
                        label: 'WiFi连接',
                        text: 'WIFI:T:WPA;S:MyNetwork;P:password123;;'
                    }
                ]
            };
        },
        mounted() {
            // this.detectPlatform();
        },
        methods: {
            // detectPlatform() {
            //     // 判断是否在小程序环境中
            //     // #ifdef MP-WEIXIN
            //     this.isMiniprogram = true;
            //     this.platformName = '微信小程序';
            //     this.platformIcon = 'weixin';
            //     this.saveButtonText = '保存到相册';
            //     // #endif
            //     // #ifdef APP-PLUS
            //     this.isMiniprogram = true;
            //     this.platformName = 'App';
            //     this.platformIcon = 'mobile';
            //     this.saveButtonText = '保存到相册';
            //     // #endif
            // },
            setExample(text) {
                this.inputText = text;
                this.generateQRCode();
            },
            // 生成二维码 - 使用 canvas-id 替代 ref
            async generateQRCode() {
                const text = this.inputText.trim();
                if (!text) {
                    this.error = '请输入要生成二维码的内容!';
                    return;
                }
                this.generating = true;
                this.error = null;
                this.qrCodeGenerated = true;
                try {
                    const qr = new UQRCode();
                    qr.data = text;
                    qr.size = 200;
                    qr.make();
                    const ctx = uni.createCanvasContext('qrcodeCanvas',
                    this); // 组件内调用需传this,vue3 中 this 为 getCurrentInstance()?.proxy
                    qr.canvasContext = ctx;
                    qr.drawCanvas();
                    this.generating = false;
                } catch (e) {
                    console.error('二维码生成异常:', e);
                    alert('生成二维码时出错!');
                    this.qrCodeGenerated = false;
                }
            },
            // 保存二维码
            saveQRCode() {
                if (!this.qrCodeGenerated) {
                    alert('请先生成二维码');
                    return;
                }
                const canvas = this.$refs.qrcodeCanvas;
                if (!canvas) return;
                // 在不同平台使用不同的保存方式
                if (this.isMiniprogram) {
                    // 小程序环境保存
                    this.saveInMiniprogram(canvas);
                } else {
                    // H5环境保存
                    this.saveInH5(canvas);
                }
            },
            // 在H5环境中保存二维码
            saveInH5(canvas) {
                const dataURL = canvas.toDataURL('image/png');
                const link = document.createElement('a');
                link.href = dataURL;
                link.download = `qrcode-${new Date().getTime()}.png`;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                alert('二维码已保存');
            },
            // 在小程序环境中保存二维码
            saveInMiniprogram(canvas) {
                // 模拟Uniapp保存图片到相册
                if (typeof uni !== 'undefined') {
                    uni.canvasToTempFilePath({
                        canvas: canvas,
                        success: (res) => {
                            uni.saveImageToPhotosAlbum({
                                filePath: res.tempFilePath,
                                success: () => {
                                    uni.showToast({
                                        title: '保存成功',
                                        icon: 'success'
                                    });
                                },
                                fail: () => {
                                    uni.showToast({
                                        title: '保存失败',
                                        icon: 'none'
                                    });
                                }
                            });
                        },
                        fail: (err) => {
                            console.error('保存失败:', err);
                            uni.showToast({
                                title: '保存失败',
                                icon: 'none'
                            });
                        }
                    });
                }
                // 微信原生小程序保存
                else if (typeof wx !== 'undefined') {
                    wx.canvasToTempFilePath({
                        canvas: canvas,
                        success: (res) => {
                            wx.saveImageToPhotosAlbum({
                                filePath: res.tempFilePath,
                                success: () => {
                                    wx.showToast({
                                        title: '保存成功',
                                        icon: 'success'
                                    });
                                },
                                fail: () => {
                                    wx.showToast({
                                        title: '保存失败',
                                        icon: 'none'
                                    });
                                }
                            });
                        },
                        fail: (err) => {
                            console.error('保存失败:', err);
                            wx.showToast({
                                title: '保存失败',
                                icon: 'none'
                            });
                        }
                    });
                }
            },
            // 小程序长按事件
            handleLongPress() {
                if (this.isMiniprogram) {
                    this.saveQRCode();
                }
            }
        }
    };
</script>
<style lang="scss">
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
    }
    textarea {
        width: 100%;
        height: 120px;
        padding: 15px;
        border: 2px solid #ddd;
        border-radius: 12px;
        font-size: 1rem;
        resize: none;
        transition: all 0.3s ease;
    }
    textarea:focus {
        border-color: #3498db;
        outline: none;
        box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
    }
    .generate-btn {
        width: 100%;
        padding: 15px;
        background: linear-gradient(to right, #3498db, #2c3e50);
        color: white;
        border: none;
        border-radius: 12px;
        font-size: 1.2rem;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.3s ease;
        margin-bottom: 25px;
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 10px;
    }
    .generate-btn:hover {
        background: linear-gradient(to right, #2980b9, #1a252f);
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }
    .qrcode-container {
        text-align: center;
        margin-bottom: 25px;
        padding: 20px;
        border-radius: 15px;
        background: #f8f9fa;
        box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
        min-height: 260px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .qrcode-canvas {
        width: 200px;
        height: 200px;
        margin: 0 auto;
        padding: 10px;
        background: white;
        border-radius: 10px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }
    .placeholder {
        color: #95a5a6;
        font-size: 1.1rem;
    }
    .examples {
        display: flex;
        gap: 15px;
        flex-wrap: wrap;
        margin-top: 15px;
        justify-content: center;
    }
    .example-btn {
        padding: 8px 15px;
        background: #e0e7ff;
        color: #4f46e5;
        border-radius: 20px;
        font-size: 0.9rem;
        cursor: pointer;
        transition: all 0.2s;
    }
    .example-btn:hover {
        background: #c7d2fe;
    }
    @media (max-width: 500px) {
        #app {
            padding: 20px;
        }
        .header h1 {
            font-size: 1.8rem;
        }
        .header p {
            font-size: 1rem;
        }
        .qrcode-canvas {
            width: 180px;
            height: 180px;
        }
    }
</style>
pages/mine/index.vue
@@ -136,6 +136,16 @@
                            <uni-icons type="right" size="16" color="#999" />
                        </view>
                    </view>
                    <view class="tool-item" @click="handleerweima">
                        <view class="tool-item__left">
                            <!-- <uni-icons type="help" size="20" color="#666" /> -->
                            <image class="rt-image" src="/static/images/index/wt.png" mode="scaleToFill"></image>
                            <text class="tool-text">二维码测试</text>
                        </view>
                        <view class="tool-item__right">
                            <uni-icons type="right" size="16" color="#999" />
                        </view>
                    </view>
                    <view class="tool-item">
                        <view class="tool-item__left" @click="handleLogout">
@@ -531,6 +541,11 @@
                }
            },
            handleerweima(){
                uni.navigateTo({
                    url: `/pages/mine/erweima`
                })
            },
            personnel(canshu) {
                if (this.token) {
                    // this.$tab.navigateTo('/pagesA/Examiner/Examiner')
pagesA/Examiner/Examiner.vue
@@ -288,7 +288,6 @@
                this.index1 = e.detail.value;
            },
            saveInspect() {
                console.log(1111)
                let inspect = this.form;
                if (inspect.cusName == '') {
                    this.$modal.msgError("请输入姓名")
uni_modules/Sansnn-uQRCode/LICENSE.md
New file
@@ -0,0 +1,201 @@
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
   1. Definitions.
      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.
      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.
      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.
      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.
      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.
      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.
      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).
      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.
      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."
      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.
   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.
   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.
   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:
      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and
      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and
      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and
      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.
      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.
   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.
   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.
   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.
   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.
   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.
   END OF TERMS AND CONDITIONS
   APPENDIX: How to apply the Apache License to your work.
      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.
   Copyright [yyyy] [name of copyright owner]
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
uni_modules/Sansnn-uQRCode/README.md
New file
@@ -0,0 +1,392 @@
# 介绍
`uQRCode`是一款基于`Javascript`环境开发的二维码生成插件,适用所有`Javascript`运行环境的前端应用和`Node.js`应用。
`uQRCode`可扩展性高,它支持自定义渲染二维码,可通过`uQRCode API`得到二维码绘制关键信息后,使用`canvas`、`svg`或`js`操作`dom`的方式绘制二维码图案。还可自定义二维码样式,如随机颜色、圆点、方块、块与块之间的间距等。
欢迎加入群聊【uQRCode交流群】:[695070434](https://jq.qq.com/?_wv=1027&k=JRjzDqiw)。
# 设计器
uQRCode发布了配套的可视化设计器,可根据自己喜好在设计器中设计二维码样式,一键生成配置代码复制到项目中,详情请在微信小程序搜索“柚子二维码”,或扫描下方小程序码体验。
![uQRCode设计器](https://uqrcode.cn/mp_weixin_code.jpg)
## 设计器模板示例
![uQRCode设计器](https://uqrcode.cn/yz_1.png)
![uQRCode设计器](https://uqrcode.cn/yz_2.png)
![uQRCode设计器](https://uqrcode.cn/yz_3.png)
![uQRCode设计器](https://uqrcode.cn/yz_4.png)
![uQRCode设计器](https://uqrcode.cn/yz_5.png)
![uQRCode设计器](https://uqrcode.cn/yz_6.png)
![uQRCode设计器](https://uqrcode.cn/yz_7.png)
![uQRCode设计器](https://uqrcode.cn/yz_8.png)
![uQRCode设计器](https://uqrcode.cn/yz_9.png)
# 快速上手
> 在`uni-app`中,我们更推荐使用组件方式来生成二维码,组件方式大大提高了页面的可读性以及避开了一些平台容易出问题的地方,当组件无法满足需求的时候,再考虑切换成原生方式。
官方文档:[https://uqrcode.cn/doc](https://uqrcode.cn/doc)。
github地址:[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode)。
npm地址:[https://www.npmjs.com/package/uqrcodejs](https://www.npmjs.com/package/uqrcodejs)。
uni-app插件市场地址:[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)。
## 原生方式
原生方式仅需要获取`uqrcode.js`文件便可使用。详细配置请移步到:文档 > [原生](https://uqrcode.cn/doc/document/native.html)。
### 安装
1. 通过`npm`安装,成功后即可使用`import`或`require`进行引用。
``` bash
# npm安装
npm install uqrcodejs
# 或者
npm install @uqrcode/js
```
2. 通过项目开源地址获取`uqrcode.js`,下载`uqrcode.js`后,将其复制到您项目指定目录,在页面中引入`uqrcode.js`文件即可开始使用。
### 引入
- 通过`import`引入。
``` javascript
// npm安装
import UQRCode from 'uqrcodejs'; // npm install uqrcodejs
// 或者
import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
```
- `Node.js`通过`require`引入。
``` javascript
// npm安装
const UQRCode = require('uqrcodejs'); // npm install uqrcodejs
// 或者
const UQRCode = require('@uqrcode/js'); // npm install @uqrcode/js
```
- 原生浏览器环境,在js脚本加载时添加到`window`。
``` html
<script type="text/javascript" src="uqrcode.js"></script>
<script>
    var UQRCode = window.UQRCode;
</script>
```
### 简单用法
`uQRCode`基于`Canvas API`封装了一套方法,建议开发者使用`canvas`生成,一键调用,非常方便。以下是示例:
- HTML示例
  - DOM部分
  ``` html
  <canvas id="qrcode" width="200" height="200"></canvas>
  ```
  - JS部分
  ``` javascript
  // 获取uQRCode实例
  var qr = new UQRCode();
  // 设置二维码内容
  qr.data = "https://uqrcode.cn/doc";
  // 设置二维码大小,必须与canvas设置的宽高一致
  qr.size = 200;
  // 调用制作二维码方法
  qr.make();
  // 获取canvas元素
  var canvas = document.getElementById("qrcode");
  // 获取canvas上下文
  var canvasContext = canvas.getContext("2d");
  // 设置uQRCode实例的canvas上下文
  qr.canvasContext = canvasContext;
  // 调用绘制方法将二维码图案绘制到canvas上
  qr.drawCanvas();
  ```
- uni-app示例
  - Template部分
  ``` html
  <canvas id="qrcode" canvas-id="qrcode" style="width: 200px;height: 200px;"></canvas>
  ```
  - JS部分
  ``` javascript
  onReady() {
    // 获取uQRCode实例
    var qr = new UQRCode();
    // 设置二维码内容
    qr.data = "https://uqrcode.cn/doc";
    // 设置二维码大小,必须与canvas设置的宽高一致
    qr.size = 200;
    // 调用制作二维码方法
    qr.make();
    // 获取canvas上下文
    var canvasContext = uni.createCanvasContext('qrcode', this); // 如果是组件,this必须传入
    // 设置uQRCode实例的canvas上下文
    qr.canvasContext = canvasContext;
    // 调用绘制方法将二维码图案绘制到canvas上
    qr.drawCanvas();
  }
  ```
- 微信小程序,推荐使用Canvas 2D,关于Canvas 2D的使用请参考微信开放文档。
### 高级用法
考虑到部分平台可能不支持`canvas`,所以`uQRCode`并没有强制要求和`canvas`一起使用,您还可以选择其他方式来生成二维码,例如使用`js`操作`dom`进行绘制或是使用`svg`绘制等。以下是示例:
- uni-app v-for+view
```html
<template>
  <view>
    <view class="qrcode">
      <view v-for="(row, rowI) in modules" :key="rowI" style="display: flex;flex-direction: row;">
        <view v-for="(col, colI) in row" :key="colI">
          <view v-if="col.isBlack" style="width: 10px;height: 10px;background-color: black;">
            <!-- 黑色码点 -->
          </view>
          <view v-else style="width: 10px;height: 10px;background-color: white;">
            <!-- 白色码点 -->
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
  import UQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js';
  export default {
    data() {
      return {
        modules: []
      }
    },
    onLoad() {
      const qr = new UQRCode();
      qr.data = 'uQRCode';
      qr.make();
      this.modules = qr.modules;
    },
    methods: {
    }
  }
</script>
```
- js操作dom
``` html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>uQRCode二维码生成</title>
</head>
<body>
    <div id="qrcode" style="position: relative;"></div>
    <script type="text/javascript" src="uqrcode.js"></script>
    <script>
    // 引入uQRCode
    var UQRCode = window.UQRCode;
    // 获取uQRCode实例
    var qr = new UQRCode();
    // 设置二维码内容
    qr.data = "https://uqrcode.cn/doc";
    // 设置二维码大小,必须与canvas设置的宽高一致
    qr.size = 200;
    // 设置二维码前景图,可以是路径
    qr.foregroundImageSrc =
        'data:image/png;base64,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';
    // 调用制作二维码方法
    qr.make();
    var drawModules = qr.getDrawModules();
    // 遍历drawModules创建dom元素
    var qrHtml = '';
    for (var i = 0; i < drawModules.length; i++) {
        var drawModule = drawModules[i];
        switch (drawModule.type) {
        case 'tile':
            /* 绘制小块 */
            qrHtml += `<div style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;background: ${drawModule.color};"></div>`;
            break;
        case 'image':
            /* 绘制图像 */
            qrHtml += `<img style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;" src="${drawModule.imageSrc}" />`;
            break;
        }
    }
    document.getElementById('qrcode').innerHTML = qrHtml;
    </script>
</body>
</html>
```
- svg
``` html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>uQRCode二维码生成</title>
</head>
<body>
    <svg id="qrcode" width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>
    <script type="text/javascript" src="uqrcode.js"></script>
    <script>
    // 引入uQRCode
    var UQRCode = window.UQRCode;
    // 获取uQRCode实例
    var qr = new UQRCode();
    // 设置二维码内容
    qr.data = "https://uqrcode.cn/doc";
    // 设置二维码大小,必须与canvas设置的宽高一致
    qr.size = 200;
    // 设置二维码前景图,可以是路径
    qr.foregroundImageSrc =
        'data:image/png;base64,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';
    // 调用制作二维码方法
    qr.make();
    var drawModules = qr.getDrawModules();
    // 遍历drawModules创建svg元素
    var qrHtml = '';
    for (var i = 0; i < drawModules.length; i++) {
        var drawModule = drawModules[i];
        switch (drawModule.type) {
        case 'tile':
            /* 绘制小块 */
            qrHtml += `<rect x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" style="fill: ${drawModule.color};" />`;
            break;
        case 'image':
            /* 绘制图像 */
            qrHtml += `<image href="${drawModule.imageSrc}" x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" />`;
            break;
        }
    }
    document.getElementById('qrcode').innerHTML = qrHtml;
    </script>
</body>
</html>
```
> 更多用法大家自行探索咯,期待分享哟~
### 导出临时文件路径
原生方式基于`Canvas`的,请自行参阅各平台`Canvas`的导出方式。以下是部分示例:
- uni-app
```javascript
// 通过uni.createCanvasContext方式创建绘制上下文的,对应导出API为uni.canvasToTempFilePath
// 调用完ctx.draw()方法后不能第一时间导出,否则会异常,需要有一定的延时
setTimeout(() => {
    uni.canvasToTempFilePath(
        {
            canvasId: this.canvasId,
            fileType: this.fileType,
            width: this.canvasWidth,
            height: this.canvasHeight,
            success: res => {
                console.log(res);
            },
            fail: err => {
                console.log(err);
            }
        },
        // this // 组件内使用必传当前实例
    );
}, 300);
```
- Canvas2D
```javascript
// 得到base64
console.log(canvas.toDataURL());
// 得到buffer
console.log(canvas.toBuffer());
```
### 保存二维码到本地相册
必须在导出临时文件路径成功后再执行保存。uni-app通用保存方式(H5除外):
```javascript
uni.saveImageToPhotosAlbum({
    filePath: tempFilePath,
    success: res => {
        console.log(res);
    },
    fail: err => {
        console.log(err);
    }
});
```
H5可以通过设置`<a>`标签`href`属性的方式进行保存:
```javascript
const aEle = document.createElement('a');
aEle.download = 'uQRCode'; // 设置下载的文件名,默认是'下载'
aEle.href = tempFilePath;
document.body.appendChild(aEle);
aEle.click();
aEle.remove(); // 下载之后把创建的元素删除
```
经过测试,PC端浏览器可以下载,部分安卓自带或第三方浏览器可以下载,安卓微信浏览器不适用,移动端iOS所有浏览器均不适用,差异较大,还是推荐各位导出文件给图片组件显示,然后提示用户通过长按图片进行保存这种方式。
## uni-app组件方式
### 安装
通过uni-app插件市场地址安装:[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)。详细配置请移步到:文档 > [uni-app组件](https://uqrcode.cn/doc/document/uni-app.html)。
### 引入
uni-app默认为easycom模式,可直接键入`<uqrcode>`标签。
### 简单用法
安装`uqrcode`组件后,在`template`中键入`<uqrcode/>`。设置`ref`属性可使用组件内部方法,`canvas-id`属性为组件内部的canvas组件标识,`value`属性为二维码生成对应内容,`options`为配置选项,可配置二维码样式,绘制Logo等,详见:[options](https://uqrcode.cn/doc/document/uni-app.html#options) 。
``` html
<uqrcode ref="uqrcode" canvas-id="qrcode" value="https://uqrcode.cn/doc" :options="{ margin: 10 }"></uqrcode>
```
### 导出临时文件路径
为了保证方法调用成功,请在 [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 事件返回`success=true`后调用。
```javascript
// uqrcode为组件的ref名称
this.$refs.uqrcode.toTempFilePath({
  success: res => {
    console.log(res);
  }
});
```
### 保存二维码到本地相册
为了保证方法调用成功,请在 [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 事件返回`success=true`后调用。
```javascript
// uqrcode为组件的ref名称
this.$refs.uqrcode.save({
  success: () => {
    uni.showToast({
      icon: 'success',
      title: '保存成功'
    });
  }
});
```
## 更多使用说明请前往官方文档查看:[https://uqrcode.cn/doc](https://uqrcode.cn/doc)。
uni_modules/Sansnn-uQRCode/changelog.md
New file
@@ -0,0 +1,12 @@
## 4.0.6(2022-12-12)
修复`getDrawModules`,第一次获取结果正常,后续获取`tile`模块不存在的问题;
修复安卓type:normal因Canvas API使用了小数或为0的参数导致生成异常的问题(注:安卓非2d Canvas部分API参数不支持携带小数,部分API参数必须大于0)。
## 4.0.1(2022-11-28)
优化组件loading属性的表现;
新增组件type选项normal,以便于在某些条件编译初始为type=2d时还可以选择使用非2d组件类型;
修复组件条件编译在其他编辑器语法提示报错;
修复原生对es5的支持。
## 4.0.0(2022-11-21)
v4版本源代码全面开放,开源地址:[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode);
升级说明:v4为大版本更新,虽然已尽可能兼容上一代版本,但不可避免的还是存在一些细节差异,若更新后出现问题,请参考对照[v3 文档](https://uqrcode.cn/doc/v3),[v4 文档](https://uqrcode.cn/doc)进行修改。
uni_modules/Sansnn-uQRCode/common/cache.js
New file
@@ -0,0 +1 @@
export const cacheImageList = [];
uni_modules/Sansnn-uQRCode/common/queue.js
New file
@@ -0,0 +1,41 @@
function Queue() {
  let waitingQueue = this.waitingQueue = [];
  let isRunning = this.isRunning = false; // 记录是否有未完成的任务
  function execute(task, resolve, reject) {
    task()
      .then((data) => {
        resolve(data);
      })
      .catch((e) => {
        reject(e);
      })
      .finally(() => {
        // 等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态
        if (waitingQueue.length) {
          const next = waitingQueue.shift();
          execute(next.task, next.resolve, next.reject);
        } else {
          isRunning = false;
        }
      });
  }
  this.exec = function(task) {
    return new Promise((resolve, reject) => {
      if (isRunning) {
        waitingQueue.push({
          task,
          resolve,
          reject
        });
      } else {
        isRunning = true;
        execute(task, resolve, reject);
      }
    });
  }
}
/* 队列实例,某些平台一起使用多个组件时需要通过队列逐一绘制,否则部分绘制方法异常,nvue端的iOS gcanvas尤其明显,在不通过队列绘制时会出现图片丢失的情况 */
export const queueDraw = new Queue();
export const queueLoadImage = new Queue();
uni_modules/Sansnn-uQRCode/common/types/cache.d.ts
New file
@@ -0,0 +1,3 @@
declare module '*/common/cache' {
  export const cacheImageList: Array;
}
uni_modules/Sansnn-uQRCode/common/types/queue.d.ts
New file
@@ -0,0 +1,4 @@
declare module '*/common/queue' {
  export const queueDraw: any;
  export const queueLoadImage: any;
}
uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue
New file
@@ -0,0 +1,1131 @@
<template>
  <view class="uqrcode" :class="{ 'uqrcode-hide': hide }" :style="{ width: `${templateOptions.width}px`, height: `${templateOptions.height}px` }">
    <view class="uqrcode-canvas-wrapper">
      <!-- 画布 -->
      <!-- #ifndef APP-NVUE -->
      <canvas class="uqrcode-canvas" :id="canvasId" :canvas-id="canvasId" :type="canvasType" :style="{
          width: `${templateOptions.canvasWidth}px`,
          height: `${templateOptions.canvasHeight}px`,
          transform: templateOptions.canvasTransform
        }" v-if="templateOptions.canvasDisplay" @click="onClick"></canvas>
      <!-- #endif -->
      <!-- nvue用gcanvas -->
      <!-- #ifdef APP-NVUE -->
      <gcanvas class="uqrcode-canvas" ref="gcanvas" :style="{
          width: `${templateOptions.canvasWidth}px`,
          height: `${templateOptions.canvasHeight}px`
        }" v-if="templateOptions.canvasDisplay" @click="onClick"></gcanvas>
      <!-- #endif -->
    </view>
    <!-- 加载效果 -->
    <view class="uqrcode-makeing" v-if="loading === undefined ? makeing : loading">
      <slot name="loading">
        <image class="uqrcode-makeing-image" :style="{ width: `${templateOptions.size / 4}px`, height: `${templateOptions.size / 4}px` }"
          src="data:image/gif;base64,R0lGODlhAAEAAfIEAOHh4SSsWuDg4N3d3f///wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODhGMzM4RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyODhGMzM5RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4OEYzMzZEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4OEYzMzdEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQ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">
        </image>
      </slot>
    </view>
    <!-- 错误处理 -->
    <view class="uqrcode-error" v-if="isError" @click="onClick">
      <slot name="error" :error="error">
        <text class="uqrcode-error-message">{{ error.errMsg }}</text>
      </slot>
    </view>
    <!-- H5保存提示 -->
    <!-- #ifdef H5 -->
    <view class="uqrcode-h5-save" v-if="isH5Save">
      <slot name="h5save" :tempFilePath="tempFilePath">
        <image class="uqrcode-h5-save-image" :src="tempFilePath"></image>
        <text class="uqrcode-h5-save-text">{{ h5SaveIsDownload ? '若保存失败,' : '' }}请长按二维码进行保存</text>
      </slot>
      <view class="uqrcode-h5-save-close" @click.stop="isH5Save = false">
        <view class="uqrcode-h5-save-close-before"></view>
        <view class="uqrcode-h5-save-close-after"></view>
      </view>
    </view>
    <!-- #endif -->
  </view>
</template>
<script>
  // #ifdef VUE3
  import {
    toRaw
  } from 'vue';
  // #endif
  /* 引入uQRCode核心js */
  import UQRCode from '../../js_sdk/uqrcode/uqrcode';
  /* 引入nvue所需模块 */
  // #ifdef APP-NVUE
  import {
    enable,
    WeexBridge
  } from '../../js_sdk/gcanvas';
  const modal = weex.requireModule('modal');
  // #endif
  /* 引入队列 */
  import {
    queueDraw,
    queueLoadImage
  } from '../../common/queue';
  /* 引入缓存图片 */
  import {
    cacheImageList
  } from '../../common/cache';
  let instance = null;
  export default {
    name: 'uqrcode',
    props: {
      /**
       * canvas组件id
       */
      canvasId: {
        type: String,
        required: true // canvasId在微信小程序初始值不能为空,created中赋值也不行,必须给一个值,否则挂载组件后无法绘制。不考虑用随机id,uuid
      },
      /**
       * 二维码内容
       */
      value: {
        type: [String, Number]
      },
      /**
       * 选项
       */
      options: {
        type: Object,
        default: () => {
          return {};
        }
      },
      /**
       * 二维码大小
       */
      size: {
        type: [String, Number],
        default: 200
      },
      /**
       * 二维码尺寸单位
       */
      sizeUnit: {
        type: String,
        default: 'px'
      },
      /**
       * 导出的文件类型
       */
      fileType: {
        type: String,
        default: 'png'
      },
      /**
       * 是否初始化组件后就开始生成
       */
      start: {
        type: Boolean,
        default: true
      },
      /**
       * 是否数据发生改变自动重绘
       */
      auto: {
        type: Boolean,
        default: true
      },
      /**
       * 隐藏组件
       */
      hide: {
        type: Boolean,
        default: false
      },
      /**
       * canvas 类型,微信小程序默认使用2d,非2d微信官方已放弃维护,问题比较多
       * 注意:微信小程序type2d手机上正常,PC上微信内打开小程序toDataURL报错,看后期微信官方团队会不会做兼容,不兼容的话只能在自行判断在PC使用非2d,或者直接提示用户请在手机上操作,微信团队的海报中心小程序就是这么做的
       */
      type: {
        type: String,
        default: () => {
          // #ifdef MP-WEIXIN
          return '2d';
          // #endif
          // #ifndef MP-WEIXIN
          return 'normal';
          // #endif
        }
      },
      /**
       * 队列绘制,主要针对NVue端
       */
      queue: {
        type: Boolean,
        default: false
      },
      /**
       * 是否队列加载图片,可减少canvas发起的网络资源请求,节省服务器资源
       */
      isQueueLoadImage: {
        type: Boolean,
        default: false
      },
      /**
       * loading态
       */
      loading: {
        type: Boolean,
        default: undefined
      },
      /**
       * H5保存即自动下载(在支持的环境下),默认false为仅弹层提示用户需要长按图片保存,不会自动下载
       */
      h5SaveIsDownload: {
        type: Boolean,
        default: false
      },
      /**
       * H5下载名称
       */
      h5DownloadName: {
        type: String,
        default: 'uQRCode'
      }
    },
    data() {
      return {
        canvas: undefined,
        canvasType: undefined,
        canvasContext: undefined,
        makeDelegate: undefined,
        drawDelegate: undefined,
        toTempFilePathDelegate: undefined,
        makeExecuted: false,
        makeing: false,
        drawing: false,
        isError: false,
        error: undefined,
        isH5Save: false,
        tempFilePath: '',
        templateOptions: {
          size: 0,
          width: 0, // 组件宽度
          height: 0,
          canvasWidth: 0, // canvas宽度
          canvasHeight: 0,
          canvasTransform: '',
          canvasDisplay: false
        },
        uqrcodeOptions: {
          data: ''
        },
        plugins: [],
        makeingPattern: [
          [
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, true, true, true, false, true, true, true],
            [true, true, true, true, true, true, false, true, true, true],
            [true, true, true, true, true, true, false, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true]
          ]
        ]
      };
    },
    watch: {
      type: {
        handler(val) {
          const types = ['2d'];
          if (types.includes(val)) {
            this.canvasType = val;
          } else {
            this.canvasType = undefined;
          }
        },
        immediate: true
      },
      value: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        }
      },
      size: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        }
      },
      options: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        },
        deep: true
      },
      makeing: {
        handler(val) {
          if (!val) {
            if (typeof this.toTempFilePathDelegate === 'function') {
              this.toTempFilePathDelegate();
            }
          }
        }
      }
    },
    mounted() {
      this.templateOptions.size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
      this.templateOptions.width = this.templateOptions.size;
      this.templateOptions.height = this.templateOptions.size;
      this.templateOptions.canvasWidth = this.templateOptions.size;
      this.templateOptions.canvasHeight = this.templateOptions.size;
      if (this.canvasType == '2d') {
        // #ifndef MP-WEIXIN
        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
        this.templateOptions.canvasHeight})`;
        // #endif
      } else {
        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
        this.templateOptions.canvasHeight})`;
      }
      if (this.start) {
        this.make();
      }
    },
    methods: {
      /**
       * 获取模板选项
       */
      getTemplateOptions() {
        var size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
        return deepReplace(this.templateOptions, {
          size,
          width: size,
          height: size
        });
      },
      /**
       * 获取插件选项
       */
      getUqrcodeOptions() {
        return deepReplace(this.options, {
          data: String(this.value),
          size: Number(this.templateOptions.size)
        });
      },
      /**
       * 重置画布
       */
      resetCanvas(callback) {
        this.templateOptions.canvasDisplay = false;
        this.$nextTick(() => {
          this.templateOptions.canvasDisplay = true;
          this.$nextTick(() => {
            callback && callback();
          });
        });
      },
      /**
       * 绘制二维码
       */
      async draw(callback = {}, isDrawDelegate = false) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        if (this.drawing) {
          if (!isDrawDelegate) {
            this.drawDelegate = () => {
              this.draw(callback, true);
            };
            return;
          }
        } else {
          this.drawing = true;
        }
        if (!this.canvasId) {
          console.error('[uQRCode]: canvasId must be set!');
          this.isError = true;
          this.drawing = false;
          callback.fail({
            errMsg: '[uQRCode]: canvasId must be set!'
          });
          callback.complete({
            errMsg: '[uQRCode]: canvasId must be set!'
          });
          return;
        }
        if (!this.value) {
          console.error('[uQRCode]: value must be set!');
          this.isError = true;
          this.drawing = false;
          callback.fail({
            errMsg: '[uQRCode]: value must be set!'
          });
          callback.complete({
            errMsg: '[uQRCode]: value must be set!'
          });
          return;
        }
        /* 组件数据 */
        this.templateOptions = this.getTemplateOptions();
        /* uQRCode选项 */
        this.uqrcodeOptions = this.getUqrcodeOptions();
        /* 纠错等级兼容字母写法 */
        if (typeof this.uqrcodeOptions.errorCorrectLevel === 'string') {
          this.uqrcodeOptions.errorCorrectLevel = UQRCode.errorCorrectLevel[this.uqrcodeOptions.errorCorrectLevel];
        }
        /* nvue不支持动态修改gcanvas尺寸,除nvue外,默认使用useDynamicSize */
        // #ifndef APP-NVUE
        if (typeof this.options.useDynamicSize === 'undefined') {
          this.uqrcodeOptions.useDynamicSize = true;
        }
        // #endif
        // #ifdef APP-NVUE
        if (typeof this.options.useDynamicSize === 'undefined') {
          this.uqrcodeOptions.useDynamicSize = false;
        }
        // if (typeof this.options.drawReserve === 'undefined') {
        //   this.uqrcodeOptions.drawReserve = true;
        // }
        // #endif
        /* 获取uQRCode实例 */
        const qr = instance = new UQRCode();
        /* 注册扩展 */
        this.plugins.forEach(p => qr.register(p.plugin));
        /* 设置uQRCode选项 */
        qr.setOptions(this.uqrcodeOptions);
        /* 调用制作二维码方法 */
        qr.make();
        /* 获取canvas上下文 */
        let canvasContext = null;
        // #ifndef APP-NVUE
        if (this.canvasType === '2d') {
          // #ifdef MP-WEIXIN
          /* 微信小程序获取canvas2d上下文方式 */
          const canvas = (this.canvas = await new Promise(resolve => {
            uni
              .createSelectorQuery()
              .in(this) // 在组件内使用需要
              .select(`#${this.canvasId}`)
              .fields({
                node: true,
                size: true
              })
              .exec(res => {
                resolve(res[0].node);
              });
          }));
          canvasContext = this.canvasContext = canvas.getContext('2d');
          /* 2d的组件设置宽高与实际canvas绘制宽高不是一个,打个比方,组件size=200,canvas.width设置为100,那么绘制出来就是100=200,组件size=400,canvas.width设置为800,绘制大小还是800=400,所以无需理会下方返回的dynamicSize是多少,按dpr重新赋值给canvas即可 */
          this.templateOptions.canvasWidth = qr.size;
          this.templateOptions.canvasHeight = qr.size;
          this.templateOptions.canvasTransform = '';
          /* 使用dynamicSize+scale,可以解决小块间出现白线问题,dpr可以解决模糊问题 */
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = qr.dynamicSize * dpr;
          canvas.height = qr.dynamicSize * dpr;
          canvasContext.scale(dpr, dpr);
          /* 微信小程序获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            /* 小程序下获取网络图片信息需先配置download域名白名单才能生效 */
            return new Promise((resolve, reject) => {
              const img = canvas.createImage();
              img.src = src;
              img.onload = () => {
                resolve(img);
              };
              img.onerror = err => {
                reject(err);
              };
            });
          });
          // #endif
          // #ifndef MP-WEIXIN
          /* 非微信小程序不支持2d,切换回uniapp获取canvas上下文方式 */
          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
          /* 使用dynamicSize,可以解决小块间出现白线问题,再通过scale缩放至size,使其达到所设尺寸 */
          this.templateOptions.canvasWidth = qr.dynamicSize;
          this.templateOptions.canvasHeight = qr.dynamicSize;
          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
          this.templateOptions.canvasHeight})`;
          /* uniapp获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            return new Promise((resolve, reject) => {
              if (src.startsWith('http')) {
                uni.getImageInfo({
                  src,
                  success: res => {
                    resolve(res.path);
                  },
                  fail: err => {
                    reject(err);
                  }
                });
              } else {
                if (src.startsWith('.')) {
                  console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
                  throw new Error('[uQRCode]: local image path only supports absolute path!');
                } else {
                  resolve(src);
                }
              }
            });
          });
          // #endif
        } else {
          /* uniapp获取canvas上下文方式 */
          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
          /* 使用dynamicSize,可以解决小块间出现白线问题,再通过scale缩放至size,使其达到所设尺寸 */
          this.templateOptions.canvasWidth = qr.dynamicSize;
          this.templateOptions.canvasHeight = qr.dynamicSize;
          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
          this.templateOptions.canvasHeight})`;
          /* uniapp获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            return new Promise((resolve, reject) => {
              /* getImageInfo在微信小程序的bug:本地路径返回路径会把开头的/或../移除,导致路径错误,解决方法:限制只能使用绝对路径 */
              if (src.startsWith('http')) {
                uni.getImageInfo({
                  src,
                  success: res => {
                    resolve(res.path);
                  },
                  fail: err => {
                    reject(err);
                  }
                });
              } else {
                if (src.startsWith('.')) {
                  console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
                  throw new Error('[uQRCode]: local image path only supports absolute path!');
                } else {
                  resolve(src);
                }
              }
            });
          });
        }
        // #endif
        // #ifdef APP-NVUE
        /* NVue获取canvas上下文方式 */
        const gcanvas = this.$refs['gcanvas'];
        const canvas = enable(gcanvas, {
          bridge: WeexBridge
        });
        canvasContext = this.canvasContext = canvas.getContext('2d');
        /* NVue获取图像方式 */
        qr.loadImage = this.getLoadImage(function(src) {
          return new Promise((resolve, reject) => {
            /* getImageInfo在nvue的bug:获取同一个路径的图片信息,同一时间第一次获取成功,后续失败,猜测是写入本地时产生文件写入冲突,所以没有返回,特别是对于网络资源 --- 已实现队列绘制,已解决此问题 */
            if (src.startsWith('.')) {
              console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
              throw new Error('[uQRCode]: local image path only supports absolute path!');
            } else {
              uni.getImageInfo({
                src,
                success: res => {
                  resolve(res.path);
                },
                fail: err => {
                  reject(err);
                }
              });
            }
          });
        });
        // #endif
        /* 设置uQRCode实例的canvas上下文 */
        qr.canvasContext = canvasContext;
        /* 延时等待页面重新绘制完毕 */
        setTimeout(() => {
          /* 从插件获取具体要调用哪一个扩展函数 */
          var plugin = this.plugins.find(p => p.name == qr.style);
          var drawCanvasName = plugin ? plugin.drawCanvas : 'drawCanvas';
          /* 虽然qr[drawCanvasName]是直接返回Promise的,但由于js内部this指向问题,故不能直接exec(qr[drawCanvasName])此方式执行,需要改成exec(() => qr[drawCanvasName]())才能正确获取this */
          var drawCanvas;
          if (this.queue) {
            drawCanvas = () => queueDraw.exec(() => qr[drawCanvasName]());
            // drawCanvas = () => queueDraw.exec(() => new Promise((resolve, reject) => {
            //   setTimeout(() => {
            //     qr[drawCanvasName]().then(resolve).catch(reject);
            //   }, 1000);
            // }));
          } else {
            drawCanvas = () => qr[drawCanvasName]();
          }
          /* 调用绘制方法将二维码图案绘制到canvas上 */
          drawCanvas()
            .then(() => {
              if (this.drawDelegate) {
                /* 高频重绘纠正 */
                let delegate = this.drawDelegate;
                this.drawDelegate = undefined;
                delegate();
              } else {
                this.drawing = false;
                callback.success();
              }
            })
            .catch(err => {
              console.log(err);
              if (this.drawDelegate) {
                /* 高频重绘纠正 */
                let delegate = this.drawDelegate;
                this.drawDelegate = undefined;
                delegate();
              } else {
                this.drawing = false;
                this.isError = true;
                callback.fail(err);
              }
            })
            .finally(() => {
              callback.complete();
            });
        }, 300);
      },
      /**
       * 生成二维码
       */
      make(callback = {}) {
        this.makeExecuted = true;
        this.makeing = true;
        this.isError = false;
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        this.resetCanvas(() => {
          clearTimeout(this.makeDelegate);
          this.makeDelegate = setTimeout(() => {
            this.draw({
              success: () => {
                setTimeout(() => {
                  callback.success();
                  this.complete(true);
                }, 300);
              },
              fail: err => {
                callback.fail(err);
                this.error = err;
                this.complete(false, err.errMsg);
              },
              complete: () => {
                callback.complete();
                this.makeing = false;
              }
            });
          }, 300);
        });
      },
      /**
       * 重新生成
       */
      remake(callback) {
        this.$emit('change');
        this.make(callback);
      },
      /**
       * 生成完成
       */
      complete(success = true, errMsg = '') {
        if (success) {
          this.$emit('complete', {
            success
          });
        } else {
          this.$emit('complete', {
            success,
            errMsg
          });
        }
      },
      /**
       * 导出临时路径
       */
      toTempFilePath(callback = {}) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        if (!this.makeExecuted) {
          console.error('[uQRCode]: make() 方法从未调用!请先成功调用 make() 后再进行操作。');
          var err = {
            errMsg: '[uQRCode]: make() method has never been executed! please execute make() successfully before operating.'
          };
          callback.fail(err);
          callback.complete(err);
          return;
        }
        if (this.isError) {
          callback.fail(this.error);
          callback.complete(this.error);
          return;
        }
        if (this.makeing) {
          /* 如果还在生成状态,那当前操作将托管到委托,监听生成完成后再通过委托复调当前方法 */
          this.toTempFilePathDelegate = () => {
            this.toTempFilePath(callback);
          };
          return;
        } else {
          this.toTempFilePathDelegate = null;
        }
        // #ifndef APP-NVUE
        if (this.canvasType === '2d') {
          // #ifdef MP-WEIXIN
          try {
            let dataURL = null;
            // #ifdef VUE3
            dataURL = toRaw(this.canvas)
              .toDataURL();
            // #endif
            // #ifndef VUE3
            dataURL = this.canvas.toDataURL();
            // #endif
            callback.success({
              tempFilePath: dataURL
            });
            callback.complete({
              tempFilePath: dataURL
            });
          } catch (e) {
            callback.fail(e);
            callback.complete(e);
          }
          // #endif
        } else {
          uni.canvasToTempFilePath({
              canvasId: this.canvasId,
              fileType: this.fileType,
              width: Number(this.templateOptions.canvasWidth),
              height: Number(this.templateOptions.canvasHeight),
              destWidth: Number(this.templateOptions.size),
              destHeight: Number(this.templateOptions.size),
              success: res => {
                callback.success(res);
              },
              fail: err => {
                callback.fail(err);
              },
              complete: () => {
                callback.complete();
              }
            },
            this
          );
        }
        // #endif
        // #ifdef APP-NVUE
        const dpr = uni.getSystemInfoSync().pixelRatio;
        this.canvasContext.toTempFilePath(
          0,
          0,
          this.templateOptions.canvasWidth * dpr,
          this.templateOptions.canvasHeight * dpr,
          this.templateOptions.size * dpr,
          this.templateOptions.size * dpr,
          '',
          1,
          res => {
            callback.success(res);
            callback.complete(res);
          }
        );
        // #endif
      },
      /**
       * 保存
       */
      save(callback = {}) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        this.toTempFilePath({
          success: res => {
            // #ifndef H5
            if (this.canvasType === '2d') {
              // #ifdef MP-WEIXIN
              /* 需要将 data:image/png;base64, 这段去除 writeFile 才能正常打开文件,否则是损坏文件,无法打开 */
              const reg = new RegExp('^data:image/png;base64,', 'g');
              const dataURL = res.tempFilePath.replace(reg, '');
              const fs = wx.getFileSystemManager();
              const tempFilePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}${
                Math.random()
                  .toString()
                  .split('.')[1]
              }.png`;
              fs.writeFile({
                filePath: tempFilePath, // 要写入的文件路径 (本地路径)
                data: dataURL, // base64图片
                encoding: 'base64',
                success: res1 => {
                  uni.saveImageToPhotosAlbum({
                    filePath: tempFilePath,
                    success: res2 => {
                      callback.success(res2);
                    },
                    fail: err2 => {
                      callback.fail(err2);
                    },
                    complete: () => {
                      callback.complete();
                    }
                  });
                },
                fail: err => {
                  callback.fail(err);
                },
                complete: () => {
                  callback.complete();
                }
              });
              // #endif
            } else {
              uni.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: res1 => {
                  callback.success(res1);
                },
                fail: err1 => {
                  callback.fail(err1);
                },
                complete: () => {
                  callback.complete();
                }
              });
            }
            // #endif
            // #ifdef H5
            /* 可以在电脑浏览器下载,移动端iOS不行,安卓微信浏览器不行,安卓外部浏览器可以 */
            this.isH5Save = true;
            this.tempFilePath = res.tempFilePath;
            if (this.h5SaveIsDownload) {
              const aEle = document.createElement('a');
              aEle.download = this.h5DownloadName; // 设置下载的文件名,默认是'下载'
              aEle.href = res.tempFilePath;
              document.body.appendChild(aEle);
              aEle.click();
              aEle.remove(); // 下载之后把创建的元素删除
            }
            callback.success({
              errMsg: 'ok'
            });
            callback.complete({
              errMsg: 'ok'
            });
            // #endif
          },
          fail: err => {
            callback.fail(err);
            callback.complete(err);
          }
        });
      },
      /**
       * 注册click事件
       */
      onClick(e) {
        this.$emit('click', e);
      },
      /**
       * 获取实例
       */
      getInstance() {
        return instance;
      },
      /**
       * 注册扩展,组件仅支持注册type为style的drawCanvas扩展
       * @param {Object} plugin
       */
      registerStyle(plugin) {
        if (plugin.Type != 'style') {
          console.warn('[uQRCode]: registerStyle 仅支持注册 style 类型的扩展!');
          return {
            errMsg: 'registerStyle 仅支持注册 style 类型的扩展!'
          };
        }
        if (typeof plugin === 'function') {
          this.plugins.push({
            plugin,
            name: plugin.Name,
            drawCanvas: plugin.DrawCanvas
          });
        }
      },
      getLoadImage(loadImage) {
        var that = this;
        if (typeof loadImage == 'function') {
          return function(src) {
            /* 判断是否是队列加载图片的 */
            if (that.isQueueLoadImage) {
              /* 解决iOS APP||NVUE同时绘制多个二维码导致图片丢失需使用队列 */
              return queueLoadImage.exec(() => {
                return new Promise((resolve, reject) => {
                  setTimeout(() => {
                    const cache = cacheImageList.find(x => x.src == src);
                    if (cache) {
                      resolve(cache.img);
                    } else {
                      loadImage(src)
                        .then(img => {
                          cacheImageList.push({
                            src,
                            img
                          });
                          resolve(img);
                        })
                        .catch(err => {
                          reject(err);
                        });
                    }
                  }, 10);
                });
              });
            } else {
              return loadImage(src);
            }
          };
        } else {
          return function(src) {
            return Promise.resolve(src);
          };
        }
      }
    }
  };
  /**
   * 对象属性深度替换
   * @param {Object} o 原始对象/默认对象/被替换的对象
   * @param {Object} r 从这个对象里取值替换到o对象里
   * @return {Object} 替换后的新对象
   */
  function deepReplace(o = {}, r = {}, c = false) {
    let obj;
    if (c) {
      // 从源替换
      obj = o;
    } else {
      // 不替换源,copy一份备份来替换
      obj = {
        ...o
      };
    }
    for (let k in r) {
      var vr = r[k];
      if (vr != undefined) {
        if (vr.constructor == Object) {
          obj[k] = this.deepReplace(obj[k], vr);
        } else if (vr.constructor == String && !vr) {
          obj[k] = obj[k];
        } else {
          obj[k] = vr;
        }
      }
    }
    return obj;
  }
</script>
<style scoped>
  .uqrcode {
    position: relative;
  }
  .uqrcode-hide {
    position: fixed;
    left: 7500rpx;
  }
  .uqrcode-canvas {
    transform-origin: top left;
  }
  .uqrcode-makeing {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 10;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    justify-content: center;
    align-items: center;
  }
  .uqrcode-makeing-image {
    /* #ifndef APP-NVUE */
    display: block;
    max-width: 120px;
    max-height: 120px;
    /* #endif */
  }
  .uqrcode-error {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    justify-content: center;
    align-items: center;
  }
  .uqrcode-error-message {
    font-size: 12px;
    color: #939291;
  }
  /* #ifdef H5 */
  .uqrcode-h5-save {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;
    background-color: rgba(0, 0, 0, 0.68);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  .uqrcode-h5-save-image {
    width: 512rpx;
    height: 512rpx;
    padding: 32rpx;
  }
  .uqrcode-h5-save-text {
    margin-top: 20rpx;
    font-size: 32rpx;
    font-weight: 700;
    color: #ffffff;
  }
  .uqrcode-h5-save-close {
    position: relative;
    margin-top: 72rpx;
    width: 60rpx;
    height: 60rpx;
    border: 2rpx solid #ffffff;
    border-radius: 60rpx;
    padding: 10rpx;
  }
  .uqrcode-h5-save-close-before {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(45deg);
    width: 40rpx;
    height: 4rpx;
    background: #ffffff;
  }
  .uqrcode-h5-save-close-after {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-45deg);
    width: 40rpx;
    height: 4rpx;
    background: #ffffff;
  }
  /* #endif */
</style>
uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue
New file
@@ -0,0 +1,1131 @@
<template>
  <view class="uqrcode" :class="{ 'uqrcode-hide': hide }" :style="{ width: `${templateOptions.width}px`, height: `${templateOptions.height}px` }">
    <view class="uqrcode-canvas-wrapper">
      <!-- 画布 -->
      <!-- #ifndef APP-NVUE -->
      <canvas class="uqrcode-canvas" :id="canvasId" :canvas-id="canvasId" :type="canvasType" :style="{
          width: `${templateOptions.canvasWidth}px`,
          height: `${templateOptions.canvasHeight}px`,
          transform: templateOptions.canvasTransform
        }" v-if="templateOptions.canvasDisplay" @click="onClick"></canvas>
      <!-- #endif -->
      <!-- nvue用gcanvas -->
      <!-- #ifdef APP-NVUE -->
      <gcanvas class="uqrcode-canvas" ref="gcanvas" :style="{
          width: `${templateOptions.canvasWidth}px`,
          height: `${templateOptions.canvasHeight}px`
        }" v-if="templateOptions.canvasDisplay" @click="onClick"></gcanvas>
      <!-- #endif -->
    </view>
    <!-- 加载效果 -->
    <view class="uqrcode-makeing" v-if="loading === undefined ? makeing : loading">
      <slot name="loading">
        <image class="uqrcode-makeing-image" :style="{ width: `${templateOptions.size / 4}px`, height: `${templateOptions.size / 4}px` }"
          src="data:image/gif;base64,R0lGODlhAAEAAfIEAOHh4SSsWuDg4N3d3f///wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODhGMzM4RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyODhGMzM5RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4OEYzMzZEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4OEYzMzdEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQ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">
        </image>
      </slot>
    </view>
    <!-- 错误处理 -->
    <view class="uqrcode-error" v-if="isError" @click="onClick">
      <slot name="error" :error="error">
        <text class="uqrcode-error-message">{{ error.errMsg }}</text>
      </slot>
    </view>
    <!-- H5保存提示 -->
    <!-- #ifdef H5 -->
    <view class="uqrcode-h5-save" v-if="isH5Save">
      <slot name="h5save" :tempFilePath="tempFilePath">
        <image class="uqrcode-h5-save-image" :src="tempFilePath"></image>
        <text class="uqrcode-h5-save-text">{{ h5SaveIsDownload ? '若保存失败,' : '' }}请长按二维码进行保存</text>
      </slot>
      <view class="uqrcode-h5-save-close" @click.stop="isH5Save = false">
        <view class="uqrcode-h5-save-close-before"></view>
        <view class="uqrcode-h5-save-close-after"></view>
      </view>
    </view>
    <!-- #endif -->
  </view>
</template>
<script>
  // #ifdef VUE3
  import {
    toRaw
  } from 'vue';
  // #endif
  /* 引入uQRCode核心js */
  import UQRCode from '../../js_sdk/uqrcode/uqrcode';
  /* 引入nvue所需模块 */
  // #ifdef APP-NVUE
  import {
    enable,
    WeexBridge
  } from '../../js_sdk/gcanvas';
  const modal = weex.requireModule('modal');
  // #endif
  /* 引入队列 */
  import {
    queueDraw,
    queueLoadImage
  } from '../../common/queue';
  /* 引入缓存图片 */
  import {
    cacheImageList
  } from '../../common/cache';
  let instance = null;
  export default {
    name: 'uqrcode',
    props: {
      /**
       * canvas组件id
       */
      canvasId: {
        type: String,
        required: true // canvasId在微信小程序初始值不能为空,created中赋值也不行,必须给一个值,否则挂载组件后无法绘制。不考虑用随机id,uuid
      },
      /**
       * 二维码内容
       */
      value: {
        type: [String, Number]
      },
      /**
       * 选项
       */
      options: {
        type: Object,
        default: () => {
          return {};
        }
      },
      /**
       * 二维码大小
       */
      size: {
        type: [String, Number],
        default: 200
      },
      /**
       * 二维码尺寸单位
       */
      sizeUnit: {
        type: String,
        default: 'px'
      },
      /**
       * 导出的文件类型
       */
      fileType: {
        type: String,
        default: 'png'
      },
      /**
       * 是否初始化组件后就开始生成
       */
      start: {
        type: Boolean,
        default: true
      },
      /**
       * 是否数据发生改变自动重绘
       */
      auto: {
        type: Boolean,
        default: true
      },
      /**
       * 隐藏组件
       */
      hide: {
        type: Boolean,
        default: false
      },
      /**
       * canvas 类型,微信小程序默认使用2d,非2d微信官方已放弃维护,问题比较多
       * 注意:微信小程序type2d手机上正常,PC上微信内打开小程序toDataURL报错,看后期微信官方团队会不会做兼容,不兼容的话只能在自行判断在PC使用非2d,或者直接提示用户请在手机上操作,微信团队的海报中心小程序就是这么做的
       */
      type: {
        type: String,
        default: () => {
          // #ifdef MP-WEIXIN
          return '2d';
          // #endif
          // #ifndef MP-WEIXIN
          return 'normal';
          // #endif
        }
      },
      /**
       * 队列绘制,主要针对NVue端
       */
      queue: {
        type: Boolean,
        default: false
      },
      /**
       * 是否队列加载图片,可减少canvas发起的网络资源请求,节省服务器资源
       */
      isQueueLoadImage: {
        type: Boolean,
        default: false
      },
      /**
       * loading态
       */
      loading: {
        type: Boolean,
        default: undefined
      },
      /**
       * H5保存即自动下载(在支持的环境下),默认false为仅弹层提示用户需要长按图片保存,不会自动下载
       */
      h5SaveIsDownload: {
        type: Boolean,
        default: false
      },
      /**
       * H5下载名称
       */
      h5DownloadName: {
        type: String,
        default: 'uQRCode'
      }
    },
    data() {
      return {
        canvas: undefined,
        canvasType: undefined,
        canvasContext: undefined,
        makeDelegate: undefined,
        drawDelegate: undefined,
        toTempFilePathDelegate: undefined,
        makeExecuted: false,
        makeing: false,
        drawing: false,
        isError: false,
        error: undefined,
        isH5Save: false,
        tempFilePath: '',
        templateOptions: {
          size: 0,
          width: 0, // 组件宽度
          height: 0,
          canvasWidth: 0, // canvas宽度
          canvasHeight: 0,
          canvasTransform: '',
          canvasDisplay: false
        },
        uqrcodeOptions: {
          data: ''
        },
        plugins: [],
        makeingPattern: [
          [
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, true, true, true, false, true, true, true],
            [true, true, true, true, true, true, false, true, true, true],
            [true, true, true, true, true, true, false, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, true, true, true, true, false, false, false],
            [true, true, true, false, false, false, false, true, true, true],
            [true, true, true, false, false, false, false, true, true, true]
          ],
          [
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, false, false, false, false, false, false, false],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true],
            [true, true, true, true, true, true, true, true, true, true]
          ]
        ]
      };
    },
    watch: {
      type: {
        handler(val) {
          const types = ['2d'];
          if (types.includes(val)) {
            this.canvasType = val;
          } else {
            this.canvasType = undefined;
          }
        },
        immediate: true
      },
      value: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        }
      },
      size: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        }
      },
      options: {
        handler() {
          if (this.auto) {
            this.remake();
          }
        },
        deep: true
      },
      makeing: {
        handler(val) {
          if (!val) {
            if (typeof this.toTempFilePathDelegate === 'function') {
              this.toTempFilePathDelegate();
            }
          }
        }
      }
    },
    mounted() {
      this.templateOptions.size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
      this.templateOptions.width = this.templateOptions.size;
      this.templateOptions.height = this.templateOptions.size;
      this.templateOptions.canvasWidth = this.templateOptions.size;
      this.templateOptions.canvasHeight = this.templateOptions.size;
      if (this.canvasType == '2d') {
        // #ifndef MP-WEIXIN
        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
        this.templateOptions.canvasHeight})`;
        // #endif
      } else {
        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
        this.templateOptions.canvasHeight})`;
      }
      if (this.start) {
        this.make();
      }
    },
    methods: {
      /**
       * 获取模板选项
       */
      getTemplateOptions() {
        var size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
        return deepReplace(this.templateOptions, {
          size,
          width: size,
          height: size
        });
      },
      /**
       * 获取插件选项
       */
      getUqrcodeOptions() {
        return deepReplace(this.options, {
          data: String(this.value),
          size: Number(this.templateOptions.size)
        });
      },
      /**
       * 重置画布
       */
      resetCanvas(callback) {
        this.templateOptions.canvasDisplay = false;
        this.$nextTick(() => {
          this.templateOptions.canvasDisplay = true;
          this.$nextTick(() => {
            callback && callback();
          });
        });
      },
      /**
       * 绘制二维码
       */
      async draw(callback = {}, isDrawDelegate = false) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        if (this.drawing) {
          if (!isDrawDelegate) {
            this.drawDelegate = () => {
              this.draw(callback, true);
            };
            return;
          }
        } else {
          this.drawing = true;
        }
        if (!this.canvasId) {
          console.error('[uQRCode]: canvasId must be set!');
          this.isError = true;
          this.drawing = false;
          callback.fail({
            errMsg: '[uQRCode]: canvasId must be set!'
          });
          callback.complete({
            errMsg: '[uQRCode]: canvasId must be set!'
          });
          return;
        }
        if (!this.value) {
          console.error('[uQRCode]: value must be set!');
          this.isError = true;
          this.drawing = false;
          callback.fail({
            errMsg: '[uQRCode]: value must be set!'
          });
          callback.complete({
            errMsg: '[uQRCode]: value must be set!'
          });
          return;
        }
        /* 组件数据 */
        this.templateOptions = this.getTemplateOptions();
        /* uQRCode选项 */
        this.uqrcodeOptions = this.getUqrcodeOptions();
        /* 纠错等级兼容字母写法 */
        if (typeof this.uqrcodeOptions.errorCorrectLevel === 'string') {
          this.uqrcodeOptions.errorCorrectLevel = UQRCode.errorCorrectLevel[this.uqrcodeOptions.errorCorrectLevel];
        }
        /* nvue不支持动态修改gcanvas尺寸,除nvue外,默认使用useDynamicSize */
        // #ifndef APP-NVUE
        if (typeof this.options.useDynamicSize === 'undefined') {
          this.uqrcodeOptions.useDynamicSize = true;
        }
        // #endif
        // #ifdef APP-NVUE
        if (typeof this.options.useDynamicSize === 'undefined') {
          this.uqrcodeOptions.useDynamicSize = false;
        }
        // if (typeof this.options.drawReserve === 'undefined') {
        //   this.uqrcodeOptions.drawReserve = true;
        // }
        // #endif
        /* 获取uQRCode实例 */
        const qr = instance = new UQRCode();
        /* 注册扩展 */
        this.plugins.forEach(p => qr.register(p.plugin));
        /* 设置uQRCode选项 */
        qr.setOptions(this.uqrcodeOptions);
        /* 调用制作二维码方法 */
        qr.make();
        /* 获取canvas上下文 */
        let canvasContext = null;
        // #ifndef APP-NVUE
        if (this.canvasType === '2d') {
          // #ifdef MP-WEIXIN
          /* 微信小程序获取canvas2d上下文方式 */
          const canvas = (this.canvas = await new Promise(resolve => {
            uni
              .createSelectorQuery()
              .in(this) // 在组件内使用需要
              .select(`#${this.canvasId}`)
              .fields({
                node: true,
                size: true
              })
              .exec(res => {
                resolve(res[0].node);
              });
          }));
          canvasContext = this.canvasContext = canvas.getContext('2d');
          /* 2d的组件设置宽高与实际canvas绘制宽高不是一个,打个比方,组件size=200,canvas.width设置为100,那么绘制出来就是100=200,组件size=400,canvas.width设置为800,绘制大小还是800=400,所以无需理会下方返回的dynamicSize是多少,按dpr重新赋值给canvas即可 */
          this.templateOptions.canvasWidth = qr.size;
          this.templateOptions.canvasHeight = qr.size;
          this.templateOptions.canvasTransform = '';
          /* 使用dynamicSize+scale,可以解决小块间出现白线问题,dpr可以解决模糊问题 */
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = qr.dynamicSize * dpr;
          canvas.height = qr.dynamicSize * dpr;
          canvasContext.scale(dpr, dpr);
          /* 微信小程序获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            /* 小程序下获取网络图片信息需先配置download域名白名单才能生效 */
            return new Promise((resolve, reject) => {
              const img = canvas.createImage();
              img.src = src;
              img.onload = () => {
                resolve(img);
              };
              img.onerror = err => {
                reject(err);
              };
            });
          });
          // #endif
          // #ifndef MP-WEIXIN
          /* 非微信小程序不支持2d,切换回uniapp获取canvas上下文方式 */
          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
          /* 使用dynamicSize,可以解决小块间出现白线问题,再通过scale缩放至size,使其达到所设尺寸 */
          this.templateOptions.canvasWidth = qr.dynamicSize;
          this.templateOptions.canvasHeight = qr.dynamicSize;
          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
          this.templateOptions.canvasHeight})`;
          /* uniapp获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            return new Promise((resolve, reject) => {
              if (src.startsWith('http')) {
                uni.getImageInfo({
                  src,
                  success: res => {
                    resolve(res.path);
                  },
                  fail: err => {
                    reject(err);
                  }
                });
              } else {
                if (src.startsWith('.')) {
                  console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
                  throw new Error('[uQRCode]: local image path only supports absolute path!');
                } else {
                  resolve(src);
                }
              }
            });
          });
          // #endif
        } else {
          /* uniapp获取canvas上下文方式 */
          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
          /* 使用dynamicSize,可以解决小块间出现白线问题,再通过scale缩放至size,使其达到所设尺寸 */
          this.templateOptions.canvasWidth = qr.dynamicSize;
          this.templateOptions.canvasHeight = qr.dynamicSize;
          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
          this.templateOptions.canvasHeight})`;
          /* uniapp获取图像方式 */
          qr.loadImage = this.getLoadImage(function(src) {
            return new Promise((resolve, reject) => {
              /* getImageInfo在微信小程序的bug:本地路径返回路径会把开头的/或../移除,导致路径错误,解决方法:限制只能使用绝对路径 */
              if (src.startsWith('http')) {
                uni.getImageInfo({
                  src,
                  success: res => {
                    resolve(res.path);
                  },
                  fail: err => {
                    reject(err);
                  }
                });
              } else {
                if (src.startsWith('.')) {
                  console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
                  throw new Error('[uQRCode]: local image path only supports absolute path!');
                } else {
                  resolve(src);
                }
              }
            });
          });
        }
        // #endif
        // #ifdef APP-NVUE
        /* NVue获取canvas上下文方式 */
        const gcanvas = this.$refs['gcanvas'];
        const canvas = enable(gcanvas, {
          bridge: WeexBridge
        });
        canvasContext = this.canvasContext = canvas.getContext('2d');
        /* NVue获取图像方式 */
        qr.loadImage = this.getLoadImage(function(src) {
          return new Promise((resolve, reject) => {
            /* getImageInfo在nvue的bug:获取同一个路径的图片信息,同一时间第一次获取成功,后续失败,猜测是写入本地时产生文件写入冲突,所以没有返回,特别是对于网络资源 --- 已实现队列绘制,已解决此问题 */
            if (src.startsWith('.')) {
              console.error('[uQRCode]: 本地图片路径仅支持绝对路径!');
              throw new Error('[uQRCode]: local image path only supports absolute path!');
            } else {
              uni.getImageInfo({
                src,
                success: res => {
                  resolve(res.path);
                },
                fail: err => {
                  reject(err);
                }
              });
            }
          });
        });
        // #endif
        /* 设置uQRCode实例的canvas上下文 */
        qr.canvasContext = canvasContext;
        /* 延时等待页面重新绘制完毕 */
        setTimeout(() => {
          /* 从插件获取具体要调用哪一个扩展函数 */
          var plugin = this.plugins.find(p => p.name == qr.style);
          var drawCanvasName = plugin ? plugin.drawCanvas : 'drawCanvas';
          /* 虽然qr[drawCanvasName]是直接返回Promise的,但由于js内部this指向问题,故不能直接exec(qr[drawCanvasName])此方式执行,需要改成exec(() => qr[drawCanvasName]())才能正确获取this */
          var drawCanvas;
          if (this.queue) {
            drawCanvas = () => queueDraw.exec(() => qr[drawCanvasName]());
            // drawCanvas = () => queueDraw.exec(() => new Promise((resolve, reject) => {
            //   setTimeout(() => {
            //     qr[drawCanvasName]().then(resolve).catch(reject);
            //   }, 1000);
            // }));
          } else {
            drawCanvas = () => qr[drawCanvasName]();
          }
          /* 调用绘制方法将二维码图案绘制到canvas上 */
          drawCanvas()
            .then(() => {
              if (this.drawDelegate) {
                /* 高频重绘纠正 */
                let delegate = this.drawDelegate;
                this.drawDelegate = undefined;
                delegate();
              } else {
                this.drawing = false;
                callback.success();
              }
            })
            .catch(err => {
              console.log(err);
              if (this.drawDelegate) {
                /* 高频重绘纠正 */
                let delegate = this.drawDelegate;
                this.drawDelegate = undefined;
                delegate();
              } else {
                this.drawing = false;
                this.isError = true;
                callback.fail(err);
              }
            })
            .finally(() => {
              callback.complete();
            });
        }, 300);
      },
      /**
       * 生成二维码
       */
      make(callback = {}) {
        this.makeExecuted = true;
        this.makeing = true;
        this.isError = false;
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        this.resetCanvas(() => {
          clearTimeout(this.makeDelegate);
          this.makeDelegate = setTimeout(() => {
            this.draw({
              success: () => {
                setTimeout(() => {
                  callback.success();
                  this.complete(true);
                }, 300);
              },
              fail: err => {
                callback.fail(err);
                this.error = err;
                this.complete(false, err.errMsg);
              },
              complete: () => {
                callback.complete();
                this.makeing = false;
              }
            });
          }, 300);
        });
      },
      /**
       * 重新生成
       */
      remake(callback) {
        this.$emit('change');
        this.make(callback);
      },
      /**
       * 生成完成
       */
      complete(success = true, errMsg = '') {
        if (success) {
          this.$emit('complete', {
            success
          });
        } else {
          this.$emit('complete', {
            success,
            errMsg
          });
        }
      },
      /**
       * 导出临时路径
       */
      toTempFilePath(callback = {}) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        if (!this.makeExecuted) {
          console.error('[uQRCode]: make() 方法从未调用!请先成功调用 make() 后再进行操作。');
          var err = {
            errMsg: '[uQRCode]: make() method has never been executed! please execute make() successfully before operating.'
          };
          callback.fail(err);
          callback.complete(err);
          return;
        }
        if (this.isError) {
          callback.fail(this.error);
          callback.complete(this.error);
          return;
        }
        if (this.makeing) {
          /* 如果还在生成状态,那当前操作将托管到委托,监听生成完成后再通过委托复调当前方法 */
          this.toTempFilePathDelegate = () => {
            this.toTempFilePath(callback);
          };
          return;
        } else {
          this.toTempFilePathDelegate = null;
        }
        // #ifndef APP-NVUE
        if (this.canvasType === '2d') {
          // #ifdef MP-WEIXIN
          try {
            let dataURL = null;
            // #ifdef VUE3
            dataURL = toRaw(this.canvas)
              .toDataURL();
            // #endif
            // #ifndef VUE3
            dataURL = this.canvas.toDataURL();
            // #endif
            callback.success({
              tempFilePath: dataURL
            });
            callback.complete({
              tempFilePath: dataURL
            });
          } catch (e) {
            callback.fail(e);
            callback.complete(e);
          }
          // #endif
        } else {
          uni.canvasToTempFilePath({
              canvasId: this.canvasId,
              fileType: this.fileType,
              width: Number(this.templateOptions.canvasWidth),
              height: Number(this.templateOptions.canvasHeight),
              destWidth: Number(this.templateOptions.size),
              destHeight: Number(this.templateOptions.size),
              success: res => {
                callback.success(res);
              },
              fail: err => {
                callback.fail(err);
              },
              complete: () => {
                callback.complete();
              }
            },
            this
          );
        }
        // #endif
        // #ifdef APP-NVUE
        const dpr = uni.getSystemInfoSync().pixelRatio;
        this.canvasContext.toTempFilePath(
          0,
          0,
          this.templateOptions.canvasWidth * dpr,
          this.templateOptions.canvasHeight * dpr,
          this.templateOptions.size * dpr,
          this.templateOptions.size * dpr,
          '',
          1,
          res => {
            callback.success(res);
            callback.complete(res);
          }
        );
        // #endif
      },
      /**
       * 保存
       */
      save(callback = {}) {
        if (typeof callback.success != 'function') {
          callback.success = () => {};
        }
        if (typeof callback.fail != 'function') {
          callback.fail = () => {};
        }
        if (typeof callback.complete != 'function') {
          callback.complete = () => {};
        }
        this.toTempFilePath({
          success: res => {
            // #ifndef H5
            if (this.canvasType === '2d') {
              // #ifdef MP-WEIXIN
              /* 需要将 data:image/png;base64, 这段去除 writeFile 才能正常打开文件,否则是损坏文件,无法打开 */
              const reg = new RegExp('^data:image/png;base64,', 'g');
              const dataURL = res.tempFilePath.replace(reg, '');
              const fs = wx.getFileSystemManager();
              const tempFilePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}${
                Math.random()
                  .toString()
                  .split('.')[1]
              }.png`;
              fs.writeFile({
                filePath: tempFilePath, // 要写入的文件路径 (本地路径)
                data: dataURL, // base64图片
                encoding: 'base64',
                success: res1 => {
                  uni.saveImageToPhotosAlbum({
                    filePath: tempFilePath,
                    success: res2 => {
                      callback.success(res2);
                    },
                    fail: err2 => {
                      callback.fail(err2);
                    },
                    complete: () => {
                      callback.complete();
                    }
                  });
                },
                fail: err => {
                  callback.fail(err);
                },
                complete: () => {
                  callback.complete();
                }
              });
              // #endif
            } else {
              uni.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: res1 => {
                  callback.success(res1);
                },
                fail: err1 => {
                  callback.fail(err1);
                },
                complete: () => {
                  callback.complete();
                }
              });
            }
            // #endif
            // #ifdef H5
            /* 可以在电脑浏览器下载,移动端iOS不行,安卓微信浏览器不行,安卓外部浏览器可以 */
            this.isH5Save = true;
            this.tempFilePath = res.tempFilePath;
            if (this.h5SaveIsDownload) {
              const aEle = document.createElement('a');
              aEle.download = this.h5DownloadName; // 设置下载的文件名,默认是'下载'
              aEle.href = res.tempFilePath;
              document.body.appendChild(aEle);
              aEle.click();
              aEle.remove(); // 下载之后把创建的元素删除
            }
            callback.success({
              errMsg: 'ok'
            });
            callback.complete({
              errMsg: 'ok'
            });
            // #endif
          },
          fail: err => {
            callback.fail(err);
            callback.complete(err);
          }
        });
      },
      /**
       * 注册click事件
       */
      onClick(e) {
        this.$emit('click', e);
      },
      /**
       * 获取实例
       */
      getInstance() {
        return instance;
      },
      /**
       * 注册扩展,组件仅支持注册type为style的drawCanvas扩展
       * @param {Object} plugin
       */
      registerStyle(plugin) {
        if (plugin.Type != 'style') {
          console.warn('[uQRCode]: registerStyle 仅支持注册 style 类型的扩展!');
          return {
            errMsg: 'registerStyle 仅支持注册 style 类型的扩展!'
          };
        }
        if (typeof plugin === 'function') {
          this.plugins.push({
            plugin,
            name: plugin.Name,
            drawCanvas: plugin.DrawCanvas
          });
        }
      },
      getLoadImage(loadImage) {
        var that = this;
        if (typeof loadImage == 'function') {
          return function(src) {
            /* 判断是否是队列加载图片的 */
            if (that.isQueueLoadImage) {
              /* 解决iOS APP||NVUE同时绘制多个二维码导致图片丢失需使用队列 */
              return queueLoadImage.exec(() => {
                return new Promise((resolve, reject) => {
                  setTimeout(() => {
                    const cache = cacheImageList.find(x => x.src == src);
                    if (cache) {
                      resolve(cache.img);
                    } else {
                      loadImage(src)
                        .then(img => {
                          cacheImageList.push({
                            src,
                            img
                          });
                          resolve(img);
                        })
                        .catch(err => {
                          reject(err);
                        });
                    }
                  }, 10);
                });
              });
            } else {
              return loadImage(src);
            }
          };
        } else {
          return function(src) {
            return Promise.resolve(src);
          };
        }
      }
    }
  };
  /**
   * 对象属性深度替换
   * @param {Object} o 原始对象/默认对象/被替换的对象
   * @param {Object} r 从这个对象里取值替换到o对象里
   * @return {Object} 替换后的新对象
   */
  function deepReplace(o = {}, r = {}, c = false) {
    let obj;
    if (c) {
      // 从源替换
      obj = o;
    } else {
      // 不替换源,copy一份备份来替换
      obj = {
        ...o
      };
    }
    for (let k in r) {
      var vr = r[k];
      if (vr != undefined) {
        if (vr.constructor == Object) {
          obj[k] = this.deepReplace(obj[k], vr);
        } else if (vr.constructor == String && !vr) {
          obj[k] = obj[k];
        } else {
          obj[k] = vr;
        }
      }
    }
    return obj;
  }
</script>
<style scoped>
  .uqrcode {
    position: relative;
  }
  .uqrcode-hide {
    position: fixed;
    left: 7500rpx;
  }
  .uqrcode-canvas {
    transform-origin: top left;
  }
  .uqrcode-makeing {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 10;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    justify-content: center;
    align-items: center;
  }
  .uqrcode-makeing-image {
    /* #ifndef APP-NVUE */
    display: block;
    max-width: 120px;
    max-height: 120px;
    /* #endif */
  }
  .uqrcode-error {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    justify-content: center;
    align-items: center;
  }
  .uqrcode-error-message {
    font-size: 12px;
    color: #939291;
  }
  /* #ifdef H5 */
  .uqrcode-h5-save {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;
    background-color: rgba(0, 0, 0, 0.68);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  .uqrcode-h5-save-image {
    width: 512rpx;
    height: 512rpx;
    padding: 32rpx;
  }
  .uqrcode-h5-save-text {
    margin-top: 20rpx;
    font-size: 32rpx;
    font-weight: 700;
    color: #ffffff;
  }
  .uqrcode-h5-save-close {
    position: relative;
    margin-top: 72rpx;
    width: 60rpx;
    height: 60rpx;
    border: 2rpx solid #ffffff;
    border-radius: 60rpx;
    padding: 10rpx;
  }
  .uqrcode-h5-save-close-before {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(45deg);
    width: 40rpx;
    height: 4rpx;
    background: #ffffff;
  }
  .uqrcode-h5-save-close-after {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-45deg);
    width: 40rpx;
    height: 4rpx;
    background: #ffffff;
  }
  /* #endif */
</style>
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js
New file
@@ -0,0 +1,241 @@
const isWeex = typeof WXEnvironment !== 'undefined';
const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
const isWeexAndroid = isWeex && !isWeexIOS;
import GLmethod from '../context-webgl/GLmethod';
const GCanvasModule =
    (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
        (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
let isDebugging = false;
let isComboDisabled = false;
const logCommand = (function () {
    const methodQuery = [];
    Object.keys(GLmethod).forEach(key => {
        methodQuery[GLmethod[key]] = key;
    })
    const queryMethod = (id) => {
        return methodQuery[parseInt(id)] || 'NotFoundMethod';
    }
    const logCommand = (id, cmds) => {
        const mId = cmds.split(',')[0];
        const mName = queryMethod(mId);
        console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
    }
    return logCommand;
})();
function joinArray(arr, sep) {
    let res = '';
    for (let i = 0; i < arr.length; i++) {
        if (i !== 0) {
            res += sep;
        }
        res += arr[i];
    }
    return res;
}
const commandsCache = {}
const GBridge = {
    callEnable: (ref, configArray) => {
        commandsCache[ref] = [];
        return GCanvasModule.enable({
            componentId: ref,
            config: configArray
        });
    },
    callEnableDebug: () => {
        isDebugging = true;
    },
    callEnableDisableCombo: () => {
        isComboDisabled = true;
    },
    callSetContextType: function (componentId, context_type) {
        GCanvasModule.setContextType(context_type, componentId);
    },
    callReset: function(id){
        GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
    },
    render: isWeexIOS ? function (componentId) {
        return GCanvasModule.extendCallNative({
            contextId: componentId,
            type: 0x60000001
        });
    } : function (componentId) {
        return callGCanvasLinkNative(componentId, 0x60000001, 'render');
    },
    render2d: isWeexIOS ? function (componentId, commands, callback) {
        if (isDebugging) {
            console.log('>>> >>> render2d ===');
            console.log('>>> commands: ' + commands);
        }
        GCanvasModule.render([commands, callback?true:false], componentId, callback);
    } : function (componentId, commands,callback) {
        if (isDebugging) {
            console.log('>>> >>> render2d ===');
            console.log('>>> commands: ' + commands);
        }
        callGCanvasLinkNative(componentId, 0x20000001, commands);
        if(callback){
        callback();
        }
    },
    callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
        throw 'should not be here anymore ' + cmdArgs;
    } : function (componentId, cmdArgs) {
        throw 'should not be here anymore ' + cmdArgs;
    },
    flushNative: isWeexIOS ? function (componentId) {
        const cmdArgs = joinArray(commandsCache[componentId], ';');
        commandsCache[componentId] = [];
        if (isDebugging) {
            console.log('>>> >>> flush native ===');
            console.log('>>> commands: ' + cmdArgs);
        }
        const result = GCanvasModule.extendCallNative({
            "contextId": componentId,
            "type": 0x60000000,
            "args": cmdArgs
        });
        const res = result && result.result;
        if (isDebugging) {
            console.log('>>> result: ' + res);
        }
        return res;
    } : function (componentId) {
        const cmdArgs = joinArray(commandsCache[componentId], ';');
        commandsCache[componentId] = [];
        if (isDebugging) {
            console.log('>>> >>> flush native ===');
            console.log('>>> commands: ' + cmdArgs);
        }
        const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
        if (isDebugging) {
            console.log('>>> result: ' + result);
        }
        return result;
    },
    callNative: function (componentId, cmdArgs, cache) {
        if (isDebugging) {
            logCommand(componentId, cmdArgs);
        }
        commandsCache[componentId].push(cmdArgs);
        if (!cache || isComboDisabled) {
            return GBridge.flushNative(componentId);
        } else {
            return undefined;
        }
    },
    texImage2D(componentId, ...args) {
        if (isWeexIOS) {
            if (args.length === 6) {
                const [target, level, internalformat, format, type, image] = args;
                GBridge.callNative(
                    componentId,
                    GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
                )
            } else if (args.length === 9) {
                const [target, level, internalformat, width, height, border, format, type, image] = args;
                GBridge.callNative(
                    componentId,
                    GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
                    + format + ',' + type + ',' + (image ? image.src : 0)
                )
            }
        } else if (isWeexAndroid) {
            if (args.length === 6) {
                const [target, level, internalformat, format, type, image] = args;
                GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
            } else if (args.length === 9) {
                const [target, level, internalformat, width, height, border, format, type, image] = args;
                GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
            }
        }
    },
    texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
        if (isWeexIOS) {
            if (arguments.length === 8) {
                GBridge.callNative(
                    componentId,
                    GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
                )
            }
        } else if (isWeexAndroid) {
            GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
        }
    },
    bindImageTexture(componentId, src, imageId) {
        GCanvasModule.bindImageTexture([src, imageId], componentId);
    },
    perloadImage([url, id], callback) {
        GCanvasModule.preLoadImage([url, id], function (image) {
            image.url = url;
            image.id = id;
            callback(image);
        });
    },
    measureText(text, fontStyle, componentId) {
        return GCanvasModule.measureText([text, fontStyle], componentId);
    },
    getImageData (componentId, x, y, w, h, callback) {
        GCanvasModule.getImageData([x, y,w,h],componentId,callback);
    },
    putImageData (componentId, data, x, y, w, h, callback) {
        GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
    },
    toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){
        GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
    }
}
export default GBridge;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js
New file
@@ -0,0 +1,18 @@
class FillStyleLinearGradient {
    constructor(x0, y0, x1, y1) {
        this._start_pos = { _x: x0, _y: y0 };
        this._end_pos = { _x: x1, _y: y1 };
        this._stop_count = 0;
        this._stops = [0, 0, 0, 0, 0];
    }
    addColorStop = function (pos, color) {
        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
            this._stops[this._stop_count] = { _pos: pos, _color: color };
            this._stop_count++;
        }
    }
}
export default FillStyleLinearGradient;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js
New file
@@ -0,0 +1,8 @@
class FillStylePattern {
    constructor(img, pattern) {
        this._style = pattern;
        this._img = img;
    }
}
export default FillStylePattern;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js
New file
@@ -0,0 +1,17 @@
class FillStyleRadialGradient {
    constructor(x0, y0, r0, x1, y1, r1) {
        this._start_pos = { _x: x0, _y: y0, _r: r0 };
        this._end_pos = { _x: x1, _y: y1, _r: r1 };
        this._stop_count = 0;
        this._stops = [0, 0, 0, 0, 0];
    }
    addColorStop(pos, color) {
        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
            this._stops[this._stop_count] = { _pos: pos, _color: color };
            this._stop_count++;
        }
    }
}
export default FillStyleRadialGradient;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js
New file
@@ -0,0 +1,666 @@
import FillStylePattern from './FillStylePattern';
import FillStyleLinearGradient from './FillStyleLinearGradient';
import FillStyleRadialGradient from './FillStyleRadialGradient';
import GImage from '../env/image.js';
import {
    ArrayBufferToBase64,
    Base64ToUint8ClampedArray
} from '../env/tool.js';
export default class CanvasRenderingContext2D {
    _drawCommands = '';
    _globalAlpha = 1.0;
    _fillStyle = 'rgb(0,0,0)';
    _strokeStyle = 'rgb(0,0,0)';
    _lineWidth = 1;
    _lineCap = 'butt';
    _lineJoin = 'miter';
    _miterLimit = 10;
    _globalCompositeOperation = 'source-over';
    _textAlign = 'start';
    _textBaseline = 'alphabetic';
    _font = '10px sans-serif';
    _savedGlobalAlpha = [];
    timer = null;
    componentId = null;
    _notCommitDrawImageCache = [];
    _needRedrawImageCache = [];
    _redrawCommands = '';
    _autoSaveContext = true;
    // _imageMap = new GHashMap();
    // _textureMap = new GHashMap();
    constructor() {
        this.className = 'CanvasRenderingContext2D';
        //this.save()
    }
    setFillStyle(value) {
        this.fillStyle = value;
    }
    set fillStyle(value) {
        this._fillStyle = value;
        if (typeof(value) == 'string') {
            this._drawCommands = this._drawCommands.concat("F" + value + ";");
        } else if (value instanceof FillStylePattern) {
            const image = value._img;
            if (!image.complete) {
                image.onload = () => {
                    var index = this._needRedrawImageCache.indexOf(image);
                    if (index > -1) {
                        this._needRedrawImageCache.splice(index, 1);
                        CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
                        this._redrawflush(true);
                    }
                }
                this._notCommitDrawImageCache.push(image);
            } else {
                CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
            }
            //CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
            this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
        } else if (value instanceof FillStyleLinearGradient) {
            var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
                value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
                value._stop_count;
            for (var i = 0; i < value._stop_count; ++i) {
                command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
            }
            this._drawCommands = this._drawCommands.concat(command + ";");
        } else if (value instanceof FillStyleRadialGradient) {
            var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
                .toFixed(2) + "," +
                value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
                value._stop_count;
            for (var i = 0; i < value._stop_count; ++i) {
                command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
            }
            this._drawCommands = this._drawCommands.concat(command + ";");
        }
    }
    get fillStyle() {
        return this._fillStyle;
    }
    get globalAlpha() {
        return this._globalAlpha;
    }
    setGlobalAlpha(value) {
        this.globalAlpha = value;
    }
    set globalAlpha(value) {
        this._globalAlpha = value;
        this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
    }
    get strokeStyle() {
        return this._strokeStyle;
    }
    setStrokeStyle(value) {
        this.strokeStyle = value;
    }
    set strokeStyle(value) {
        this._strokeStyle = value;
        if (typeof(value) == 'string') {
            this._drawCommands = this._drawCommands.concat("S" + value + ";");
        } else if (value instanceof FillStylePattern) {
            CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
            this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
        } else if (value instanceof FillStyleLinearGradient) {
            var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
                value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
                value._stop_count;
            for (var i = 0; i < value._stop_count; ++i) {
                command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
            }
            this._drawCommands = this._drawCommands.concat(command + ";");
        } else if (value instanceof FillStyleRadialGradient) {
            var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
                .toFixed(2) + "," +
                value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
                value._stop_count;
            for (var i = 0; i < value._stop_count; ++i) {
                command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
            }
            this._drawCommands = this._drawCommands.concat(command + ";");
        }
    }
    get lineWidth() {
        return this._lineWidth;
    }
    setLineWidth(value) {
        this.lineWidth = value;
    }
    set lineWidth(value) {
        this._lineWidth = value;
        this._drawCommands = this._drawCommands.concat("W" + value + ";");
    }
    get lineCap() {
        return this._lineCap;
    }
    setLineCap(value) {
        this.lineCap = value;
    }
    set lineCap(value) {
        this._lineCap = value;
        this._drawCommands = this._drawCommands.concat("C" + value + ";");
    }
    get lineJoin() {
        return this._lineJoin;
    }
    setLineJoin(value) {
        this.lineJoin = value
    }
    set lineJoin(value) {
        this._lineJoin = value;
        this._drawCommands = this._drawCommands.concat("J" + value + ";");
    }
    get miterLimit() {
        return this._miterLimit;
    }
    setMiterLimit(value) {
        this.miterLimit = value
    }
    set miterLimit(value) {
        this._miterLimit = value;
        this._drawCommands = this._drawCommands.concat("M" + value + ";");
    }
    get globalCompositeOperation() {
        return this._globalCompositeOperation;
    }
    set globalCompositeOperation(value) {
        this._globalCompositeOperation = value;
        let mode = 0;
        switch (value) {
            case "source-over":
                mode = 0;
                break;
            case "source-atop":
                mode = 5;
                break;
            case "source-in":
                mode = 0;
                break;
            case "source-out":
                mode = 2;
                break;
            case "destination-over":
                mode = 4;
                break;
            case "destination-atop":
                mode = 4;
                break;
            case "destination-in":
                mode = 4;
                break;
            case "destination-out":
                mode = 3;
                break;
            case "lighter":
                mode = 1;
                break;
            case "copy":
                mode = 2;
                break;
            case "xor":
                mode = 6;
                break;
            default:
                mode = 0;
        }
        this._drawCommands = this._drawCommands.concat("B" + mode + ";");
    }
    get textAlign() {
        return this._textAlign;
    }
    setTextAlign(value) {
        this.textAlign = value
    }
    set textAlign(value) {
        this._textAlign = value;
        let Align = 0;
        switch (value) {
            case "start":
                Align = 0;
                break;
            case "end":
                Align = 1;
                break;
            case "left":
                Align = 2;
                break;
            case "center":
                Align = 3;
                break;
            case "right":
                Align = 4;
                break;
            default:
                Align = 0;
        }
        this._drawCommands = this._drawCommands.concat("A" + Align + ";");
    }
    get textBaseline() {
        return this._textBaseline;
    }
    setTextBaseline(value) {
        this.textBaseline = value
    }
    set textBaseline(value) {
        this._textBaseline = value;
        let baseline = 0;
        switch (value) {
            case "alphabetic":
                baseline = 0;
                break;
            case "middle":
                baseline = 1;
                break;
            case "top":
                baseline = 2;
                break;
            case "hanging":
                baseline = 3;
                break;
            case "bottom":
                baseline = 4;
                break;
            case "ideographic":
                baseline = 5;
                break;
            default:
                baseline = 0;
                break;
        }
        this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
    }
    get font() {
        return this._font;
    }
    setFontSize(size) {
        var str = this._font;
        var strs = str.trim().split(/\s+/);
        for (var i = 0; i < strs.length; i++) {
            var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
                "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
                "normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
                "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
            ];
            if (-1 == values.indexOf(strs[i].trim())) {
                if (typeof size === 'string') {
                    strs[i] = size;
                } else if (typeof size === 'number') {
                    strs[i] = String(size) + 'px';
                }
                break;
            }
        }
        this.font = strs.join(" ");
    }
    set font(value) {
        this._font = value;
        this._drawCommands = this._drawCommands.concat("j" + value + ";");
    }
    setTransform(a, b, c, d, tx, ty) {
        this._drawCommands = this._drawCommands.concat("t" +
            (a === 1 ? "1" : a.toFixed(2)) + "," +
            (b === 0 ? "0" : b.toFixed(2)) + "," +
            (c === 0 ? "0" : c.toFixed(2)) + "," +
            (d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
    }
    transform(a, b, c, d, tx, ty) {
        this._drawCommands = this._drawCommands.concat("f" +
            (a === 1 ? "1" : a.toFixed(2)) + "," +
            (b === 0 ? "0" : b.toFixed(2)) + "," +
            (c === 0 ? "0" : c.toFixed(2)) + "," +
            (d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
    }
    resetTransform() {
        this._drawCommands = this._drawCommands.concat("m;");
    }
    scale(a, d) {
        this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
            d.toFixed(2) + ";");
    }
    rotate(angle) {
        this._drawCommands = this._drawCommands
            .concat("r" + angle.toFixed(6) + ";");
    }
    translate(tx, ty) {
        this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
    }
    save() {
        this._savedGlobalAlpha.push(this._globalAlpha);
        this._drawCommands = this._drawCommands.concat("v;");
    }
    restore() {
        this._drawCommands = this._drawCommands.concat("e;");
        this._globalAlpha = this._savedGlobalAlpha.pop();
    }
    createPattern(img, pattern) {
        if (typeof img === 'string') {
            var imgObj = new GImage();
            imgObj.src = img;
            img = imgObj;
        }
        return new FillStylePattern(img, pattern);
    }
    createLinearGradient(x0, y0, x1, y1) {
        return new FillStyleLinearGradient(x0, y0, x1, y1);
    }
    createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
        return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
    };
    createCircularGradient = function(x0, y0, r0) {
        return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
    };
    strokeRect(x, y, w, h) {
        this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
    }
    clearRect(x, y, w, h) {
        this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
            "," + h + ";");
    }
    clip() {
        this._drawCommands = this._drawCommands.concat("p;");
    }
    resetClip() {
        this._drawCommands = this._drawCommands.concat("q;");
    }
    closePath() {
        this._drawCommands = this._drawCommands.concat("o;");
    }
    moveTo(x, y) {
        this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
    }
    lineTo(x, y) {
        this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
    }
    quadraticCurveTo = function(cpx, cpy, x, y) {
        this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
    }
    bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
        this._drawCommands = this._drawCommands.concat(
            "z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
            x.toFixed(2) + "," + y.toFixed(2) + ";");
    }
    arcTo(x1, y1, x2, y2, radius) {
        this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
    }
    beginPath() {
        this._drawCommands = this._drawCommands.concat("b;");
    }
    fillRect(x, y, w, h) {
        this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
            "," + h + ";");
    }
    rect(x, y, w, h) {
        this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
    }
    fill() {
        this._drawCommands = this._drawCommands.concat("L;");
    }
    stroke(path) {
        this._drawCommands = this._drawCommands.concat("x;");
    }
    arc(x, y, radius, startAngle, endAngle, anticlockwise) {
        let ianticlockwise = 0;
        if (anticlockwise) {
            ianticlockwise = 1;
        }
        this._drawCommands = this._drawCommands.concat(
            "y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
            radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
            ";"
        );
    }
    fillText(text, x, y) {
        let tmptext = text.replace(/!/g, "!!");
        tmptext = tmptext.replace(/,/g, "!,");
        tmptext = tmptext.replace(/;/g, "!;");
        this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
    }
    strokeText = function(text, x, y) {
        let tmptext = text.replace(/!/g, "!!");
        tmptext = tmptext.replace(/,/g, "!,");
        tmptext = tmptext.replace(/;/g, "!;");
        this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
    }
    measureText(text) {
        return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
    }
    isPointInPath = function(x, y) {
        throw new Error('GCanvas not supported yet');
    }
    drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
        if (typeof image === 'string') {
            var imgObj = new GImage();
            imgObj.src = image;
            image = imgObj;
        }
        if (image instanceof GImage) {
            if (!image.complete) {
                imgObj.onload = () => {
                    var index = this._needRedrawImageCache.indexOf(image);
                    if (index > -1) {
                        this._needRedrawImageCache.splice(index, 1);
                        CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
                        this._redrawflush(true);
                    }
                }
                this._notCommitDrawImageCache.push(image);
            } else {
                CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
            }
            var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
            var args = [];
            for (var arg in srcArgs) {
                if (typeof(srcArgs[arg]) != 'undefined') {
                    args.push(srcArgs[arg]);
                }
            }
            this.__drawImage.apply(this, args);
            //this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
        }
    }
    __drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
        const numArgs = arguments.length;
        function drawImageCommands() {
            if (numArgs === 3) {
                const x = parseFloat(sx) || 0.0;
                const y = parseFloat(sy) || 0.0;
                return ("d" + image._id + ",0,0," +
                    image.width + "," + image.height + "," +
                    x + "," + y + "," + image.width + "," + image.height + ";");
            } else if (numArgs === 5) {
                const x = parseFloat(sx) || 0.0;
                const y = parseFloat(sy) || 0.0;
                const width = parseInt(sw) || image.width;
                const height = parseInt(sh) || image.height;
                return ("d" + image._id + ",0,0," +
                    image.width + "," + image.height + "," +
                    x + "," + y + "," + width + "," + height + ";");
            } else if (numArgs === 9) {
                sx = parseFloat(sx) || 0.0;
                sy = parseFloat(sy) || 0.0;
                sw = parseInt(sw) || image.width;
                sh = parseInt(sh) || image.height;
                dx = parseFloat(dx) || 0.0;
                dy = parseFloat(dy) || 0.0;
                dw = parseInt(dw) || image.width;
                dh = parseInt(dh) || image.height;
                return ("d" + image._id + "," +
                    sx + "," + sy + "," + sw + "," + sh + "," +
                    dx + "," + dy + "," + dw + "," + dh + ";");
            }
        }
        this._drawCommands += drawImageCommands();
    }
    _flush(reserve, callback) {
        const commands = this._drawCommands;
        this._drawCommands = '';
        CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
        this._needRender = false;
    }
    _redrawflush(reserve, callback) {
        const commands = this._redrawCommands;
        CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
        if (this._needRedrawImageCache.length == 0) {
            this._redrawCommands = '';
        }
    }
    draw(reserve, callback) {
        if (!reserve) {
            this._globalAlpha = this._savedGlobalAlpha.pop();
            this._savedGlobalAlpha.push(this._globalAlpha);
            this._redrawCommands = this._drawCommands;
            this._needRedrawImageCache = this._notCommitDrawImageCache;
            if (this._autoSaveContext) {
                this._drawCommands = ("v;" + this._drawCommands);
                this._autoSaveContext = false;
            } else {
                this._drawCommands = ("e;X;v;" + this._drawCommands);
            }
        } else {
            this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
            this._redrawCommands += this._drawCommands;
            if (this._autoSaveContext) {
                this._drawCommands = ("v;" + this._drawCommands);
                this._autoSaveContext = false;
            }
        }
        this._notCommitDrawImageCache = [];
        if (this._flush) {
            this._flush(reserve, callback);
        }
    }
    getImageData(x, y, w, h, callback) {
        CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
            res.data = Base64ToUint8ClampedArray(res.data);
            if (typeof(callback) == 'function') {
                callback(res);
            }
        });
    }
    putImageData(data, x, y, w, h, callback) {
        if (data instanceof Uint8ClampedArray) {
            data = ArrayBufferToBase64(data);
            CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
                if (typeof(callback) == 'function') {
                    callback(res);
                }
            });
        }
    }
    toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
        CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
            fileType, quality,
            function(res) {
                if (typeof(callback) == 'function') {
                    callback(res);
                }
            });
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js
New file
@@ -0,0 +1,11 @@
export default class WebGLActiveInfo {
    className = 'WebGLActiveInfo';
    constructor({
        type, name, size
    }) {
        this.type = type;
        this.name = name;
        this.size = size;
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js
New file
@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLBuffer';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLBuffer {
    className = name;
    constructor(id) {
        this.id = id;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js
New file
@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLFrameBuffer';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLFramebuffer {
    className = name;
    constructor(id) {
        this.id = id;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js
New file
@@ -0,0 +1,298 @@
export default {
    "DEPTH_BUFFER_BIT": 256,
    "STENCIL_BUFFER_BIT": 1024,
    "COLOR_BUFFER_BIT": 16384,
    "POINTS": 0,
    "LINES": 1,
    "LINE_LOOP": 2,
    "LINE_STRIP": 3,
    "TRIANGLES": 4,
    "TRIANGLE_STRIP": 5,
    "TRIANGLE_FAN": 6,
    "ZERO": 0,
    "ONE": 1,
    "SRC_COLOR": 768,
    "ONE_MINUS_SRC_COLOR": 769,
    "SRC_ALPHA": 770,
    "ONE_MINUS_SRC_ALPHA": 771,
    "DST_ALPHA": 772,
    "ONE_MINUS_DST_ALPHA": 773,
    "DST_COLOR": 774,
    "ONE_MINUS_DST_COLOR": 775,
    "SRC_ALPHA_SATURATE": 776,
    "FUNC_ADD": 32774,
    "BLEND_EQUATION": 32777,
    "BLEND_EQUATION_RGB": 32777,
    "BLEND_EQUATION_ALPHA": 34877,
    "FUNC_SUBTRACT": 32778,
    "FUNC_REVERSE_SUBTRACT": 32779,
    "BLEND_DST_RGB": 32968,
    "BLEND_SRC_RGB": 32969,
    "BLEND_DST_ALPHA": 32970,
    "BLEND_SRC_ALPHA": 32971,
    "CONSTANT_COLOR": 32769,
    "ONE_MINUS_CONSTANT_COLOR": 32770,
    "CONSTANT_ALPHA": 32771,
    "ONE_MINUS_CONSTANT_ALPHA": 32772,
    "BLEND_COLOR": 32773,
    "ARRAY_BUFFER": 34962,
    "ELEMENT_ARRAY_BUFFER": 34963,
    "ARRAY_BUFFER_BINDING": 34964,
    "ELEMENT_ARRAY_BUFFER_BINDING": 34965,
    "STREAM_DRAW": 35040,
    "STATIC_DRAW": 35044,
    "DYNAMIC_DRAW": 35048,
    "BUFFER_SIZE": 34660,
    "BUFFER_USAGE": 34661,
    "CURRENT_VERTEX_ATTRIB": 34342,
    "FRONT": 1028,
    "BACK": 1029,
    "FRONT_AND_BACK": 1032,
    "TEXTURE_2D": 3553,
    "CULL_FACE": 2884,
    "BLEND": 3042,
    "DITHER": 3024,
    "STENCIL_TEST": 2960,
    "DEPTH_TEST": 2929,
    "SCISSOR_TEST": 3089,
    "POLYGON_OFFSET_FILL": 32823,
    "SAMPLE_ALPHA_TO_COVERAGE": 32926,
    "SAMPLE_COVERAGE": 32928,
    "NO_ERROR": 0,
    "INVALID_ENUM": 1280,
    "INVALID_VALUE": 1281,
    "INVALID_OPERATION": 1282,
    "OUT_OF_MEMORY": 1285,
    "CW": 2304,
    "CCW": 2305,
    "LINE_WIDTH": 2849,
    "ALIASED_POINT_SIZE_RANGE": 33901,
    "ALIASED_LINE_WIDTH_RANGE": 33902,
    "CULL_FACE_MODE": 2885,
    "FRONT_FACE": 2886,
    "DEPTH_RANGE": 2928,
    "DEPTH_WRITEMASK": 2930,
    "DEPTH_CLEAR_VALUE": 2931,
    "DEPTH_FUNC": 2932,
    "STENCIL_CLEAR_VALUE": 2961,
    "STENCIL_FUNC": 2962,
    "STENCIL_FAIL": 2964,
    "STENCIL_PASS_DEPTH_FAIL": 2965,
    "STENCIL_PASS_DEPTH_PASS": 2966,
    "STENCIL_REF": 2967,
    "STENCIL_VALUE_MASK": 2963,
    "STENCIL_WRITEMASK": 2968,
    "STENCIL_BACK_FUNC": 34816,
    "STENCIL_BACK_FAIL": 34817,
    "STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
    "STENCIL_BACK_PASS_DEPTH_PASS": 34819,
    "STENCIL_BACK_REF": 36003,
    "STENCIL_BACK_VALUE_MASK": 36004,
    "STENCIL_BACK_WRITEMASK": 36005,
    "VIEWPORT": 2978,
    "SCISSOR_BOX": 3088,
    "COLOR_CLEAR_VALUE": 3106,
    "COLOR_WRITEMASK": 3107,
    "UNPACK_ALIGNMENT": 3317,
    "PACK_ALIGNMENT": 3333,
    "MAX_TEXTURE_SIZE": 3379,
    "MAX_VIEWPORT_DIMS": 3386,
    "SUBPIXEL_BITS": 3408,
    "RED_BITS": 3410,
    "GREEN_BITS": 3411,
    "BLUE_BITS": 3412,
    "ALPHA_BITS": 3413,
    "DEPTH_BITS": 3414,
    "STENCIL_BITS": 3415,
    "POLYGON_OFFSET_UNITS": 10752,
    "POLYGON_OFFSET_FACTOR": 32824,
    "TEXTURE_BINDING_2D": 32873,
    "SAMPLE_BUFFERS": 32936,
    "SAMPLES": 32937,
    "SAMPLE_COVERAGE_VALUE": 32938,
    "SAMPLE_COVERAGE_INVERT": 32939,
    "COMPRESSED_TEXTURE_FORMATS": 34467,
    "DONT_CARE": 4352,
    "FASTEST": 4353,
    "NICEST": 4354,
    "GENERATE_MIPMAP_HINT": 33170,
    "BYTE": 5120,
    "UNSIGNED_BYTE": 5121,
    "SHORT": 5122,
    "UNSIGNED_SHORT": 5123,
    "INT": 5124,
    "UNSIGNED_INT": 5125,
    "FLOAT": 5126,
    "DEPTH_COMPONENT": 6402,
    "ALPHA": 6406,
    "RGB": 6407,
    "RGBA": 6408,
    "LUMINANCE": 6409,
    "LUMINANCE_ALPHA": 6410,
    "UNSIGNED_SHORT_4_4_4_4": 32819,
    "UNSIGNED_SHORT_5_5_5_1": 32820,
    "UNSIGNED_SHORT_5_6_5": 33635,
    "FRAGMENT_SHADER": 35632,
    "VERTEX_SHADER": 35633,
    "MAX_VERTEX_ATTRIBS": 34921,
    "MAX_VERTEX_UNIFORM_VECTORS": 36347,
    "MAX_VARYING_VECTORS": 36348,
    "MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
    "MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
    "MAX_TEXTURE_IMAGE_UNITS": 34930,
    "MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
    "SHADER_TYPE": 35663,
    "DELETE_STATUS": 35712,
    "LINK_STATUS": 35714,
    "VALIDATE_STATUS": 35715,
    "ATTACHED_SHADERS": 35717,
    "ACTIVE_UNIFORMS": 35718,
    "ACTIVE_ATTRIBUTES": 35721,
    "SHADING_LANGUAGE_VERSION": 35724,
    "CURRENT_PROGRAM": 35725,
    "NEVER": 512,
    "LESS": 513,
    "EQUAL": 514,
    "LEQUAL": 515,
    "GREATER": 516,
    "NOTEQUAL": 517,
    "GEQUAL": 518,
    "ALWAYS": 519,
    "KEEP": 7680,
    "REPLACE": 7681,
    "INCR": 7682,
    "DECR": 7683,
    "INVERT": 5386,
    "INCR_WRAP": 34055,
    "DECR_WRAP": 34056,
    "VENDOR": 7936,
    "RENDERER": 7937,
    "VERSION": 7938,
    "NEAREST": 9728,
    "LINEAR": 9729,
    "NEAREST_MIPMAP_NEAREST": 9984,
    "LINEAR_MIPMAP_NEAREST": 9985,
    "NEAREST_MIPMAP_LINEAR": 9986,
    "LINEAR_MIPMAP_LINEAR": 9987,
    "TEXTURE_MAG_FILTER": 10240,
    "TEXTURE_MIN_FILTER": 10241,
    "TEXTURE_WRAP_S": 10242,
    "TEXTURE_WRAP_T": 10243,
    "TEXTURE": 5890,
    "TEXTURE_CUBE_MAP": 34067,
    "TEXTURE_BINDING_CUBE_MAP": 34068,
    "TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
    "TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
    "TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
    "TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
    "TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
    "TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
    "MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
    "TEXTURE0": 33984,
    "TEXTURE1": 33985,
    "TEXTURE2": 33986,
    "TEXTURE3": 33987,
    "TEXTURE4": 33988,
    "TEXTURE5": 33989,
    "TEXTURE6": 33990,
    "TEXTURE7": 33991,
    "TEXTURE8": 33992,
    "TEXTURE9": 33993,
    "TEXTURE10": 33994,
    "TEXTURE11": 33995,
    "TEXTURE12": 33996,
    "TEXTURE13": 33997,
    "TEXTURE14": 33998,
    "TEXTURE15": 33999,
    "TEXTURE16": 34000,
    "TEXTURE17": 34001,
    "TEXTURE18": 34002,
    "TEXTURE19": 34003,
    "TEXTURE20": 34004,
    "TEXTURE21": 34005,
    "TEXTURE22": 34006,
    "TEXTURE23": 34007,
    "TEXTURE24": 34008,
    "TEXTURE25": 34009,
    "TEXTURE26": 34010,
    "TEXTURE27": 34011,
    "TEXTURE28": 34012,
    "TEXTURE29": 34013,
    "TEXTURE30": 34014,
    "TEXTURE31": 34015,
    "ACTIVE_TEXTURE": 34016,
    "REPEAT": 10497,
    "CLAMP_TO_EDGE": 33071,
    "MIRRORED_REPEAT": 33648,
    "FLOAT_VEC2": 35664,
    "FLOAT_VEC3": 35665,
    "FLOAT_VEC4": 35666,
    "INT_VEC2": 35667,
    "INT_VEC3": 35668,
    "INT_VEC4": 35669,
    "BOOL": 35670,
    "BOOL_VEC2": 35671,
    "BOOL_VEC3": 35672,
    "BOOL_VEC4": 35673,
    "FLOAT_MAT2": 35674,
    "FLOAT_MAT3": 35675,
    "FLOAT_MAT4": 35676,
    "SAMPLER_2D": 35678,
    "SAMPLER_CUBE": 35680,
    "VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
    "VERTEX_ATTRIB_ARRAY_SIZE": 34339,
    "VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
    "VERTEX_ATTRIB_ARRAY_TYPE": 34341,
    "VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
    "VERTEX_ATTRIB_ARRAY_POINTER": 34373,
    "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
    "IMPLEMENTATION_COLOR_READ_TYPE": 35738,
    "IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
    "COMPILE_STATUS": 35713,
    "LOW_FLOAT": 36336,
    "MEDIUM_FLOAT": 36337,
    "HIGH_FLOAT": 36338,
    "LOW_INT": 36339,
    "MEDIUM_INT": 36340,
    "HIGH_INT": 36341,
    "FRAMEBUFFER": 36160,
    "RENDERBUFFER": 36161,
    "RGBA4": 32854,
    "RGB5_A1": 32855,
    "RGB565": 36194,
    "DEPTH_COMPONENT16": 33189,
    "STENCIL_INDEX8": 36168,
    "DEPTH_STENCIL": 34041,
    "RENDERBUFFER_WIDTH": 36162,
    "RENDERBUFFER_HEIGHT": 36163,
    "RENDERBUFFER_INTERNAL_FORMAT": 36164,
    "RENDERBUFFER_RED_SIZE": 36176,
    "RENDERBUFFER_GREEN_SIZE": 36177,
    "RENDERBUFFER_BLUE_SIZE": 36178,
    "RENDERBUFFER_ALPHA_SIZE": 36179,
    "RENDERBUFFER_DEPTH_SIZE": 36180,
    "RENDERBUFFER_STENCIL_SIZE": 36181,
    "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
    "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
    "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
    "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
    "COLOR_ATTACHMENT0": 36064,
    "DEPTH_ATTACHMENT": 36096,
    "STENCIL_ATTACHMENT": 36128,
    "DEPTH_STENCIL_ATTACHMENT": 33306,
    "NONE": 0,
    "FRAMEBUFFER_COMPLETE": 36053,
    "FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
    "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
    "FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
    "FRAMEBUFFER_UNSUPPORTED": 36061,
    "FRAMEBUFFER_BINDING": 36006,
    "RENDERBUFFER_BINDING": 36007,
    "MAX_RENDERBUFFER_SIZE": 34024,
    "INVALID_FRAMEBUFFER_OPERATION": 1286,
    "UNPACK_FLIP_Y_WEBGL": 37440,
    "UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
    "CONTEXT_LOST_WEBGL": 37442,
    "UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
    "BROWSER_DEFAULT_WEBGL": 37444
};
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js
New file
@@ -0,0 +1,142 @@
let i = 1;
const GLmethod = {};
GLmethod.activeTexture = i++;         //1
GLmethod.attachShader = i++;
GLmethod.bindAttribLocation = i++;
GLmethod.bindBuffer = i++;
GLmethod.bindFramebuffer = i++;
GLmethod.bindRenderbuffer = i++;
GLmethod.bindTexture = i++;
GLmethod.blendColor = i++;
GLmethod.blendEquation = i++;
GLmethod.blendEquationSeparate = i++; //10
GLmethod.blendFunc = i++;
GLmethod.blendFuncSeparate = i++;
GLmethod.bufferData = i++;
GLmethod.bufferSubData = i++;
GLmethod.checkFramebufferStatus = i++;
GLmethod.clear = i++;
GLmethod.clearColor = i++;
GLmethod.clearDepth = i++;
GLmethod.clearStencil = i++;
GLmethod.colorMask = i++;              //20
GLmethod.compileShader = i++;
GLmethod.compressedTexImage2D = i++;
GLmethod.compressedTexSubImage2D = i++;
GLmethod.copyTexImage2D = i++;
GLmethod.copyTexSubImage2D = i++;
GLmethod.createBuffer = i++;
GLmethod.createFramebuffer = i++;
GLmethod.createProgram = i++;
GLmethod.createRenderbuffer = i++;
GLmethod.createShader = i++;           //30
GLmethod.createTexture = i++;
GLmethod.cullFace = i++;
GLmethod.deleteBuffer = i++;
GLmethod.deleteFramebuffer = i++;
GLmethod.deleteProgram = i++;
GLmethod.deleteRenderbuffer = i++;
GLmethod.deleteShader = i++;
GLmethod.deleteTexture = i++;
GLmethod.depthFunc = i++;
GLmethod.depthMask = i++;              //40
GLmethod.depthRange = i++;
GLmethod.detachShader = i++;
GLmethod.disable = i++;
GLmethod.disableVertexAttribArray = i++;
GLmethod.drawArrays = i++;
GLmethod.drawArraysInstancedANGLE = i++;
GLmethod.drawElements = i++;
GLmethod.drawElementsInstancedANGLE = i++;
GLmethod.enable = i++;
GLmethod.enableVertexAttribArray = i++;    //50
GLmethod.flush = i++;
GLmethod.framebufferRenderbuffer = i++;
GLmethod.framebufferTexture2D = i++;
GLmethod.frontFace = i++;
GLmethod.generateMipmap = i++;
GLmethod.getActiveAttrib = i++;
GLmethod.getActiveUniform = i++;
GLmethod.getAttachedShaders = i++;
GLmethod.getAttribLocation = i++;
GLmethod.getBufferParameter = i++;         //60
GLmethod.getContextAttributes = i++;
GLmethod.getError = i++;
GLmethod.getExtension = i++;
GLmethod.getFramebufferAttachmentParameter = i++;
GLmethod.getParameter = i++;
GLmethod.getProgramInfoLog = i++;
GLmethod.getProgramParameter = i++;
GLmethod.getRenderbufferParameter = i++;
GLmethod.getShaderInfoLog = i++;
GLmethod.getShaderParameter = i++;         //70
GLmethod.getShaderPrecisionFormat = i++;
GLmethod.getShaderSource = i++;
GLmethod.getSupportedExtensions = i++;
GLmethod.getTexParameter = i++;
GLmethod.getUniform = i++;
GLmethod.getUniformLocation = i++;
GLmethod.getVertexAttrib = i++;
GLmethod.getVertexAttribOffset = i++;
GLmethod.isBuffer = i++;
GLmethod.isContextLost = i++;              //80
GLmethod.isEnabled = i++;
GLmethod.isFramebuffer = i++;
GLmethod.isProgram = i++;
GLmethod.isRenderbuffer = i++;
GLmethod.isShader = i++;
GLmethod.isTexture = i++;
GLmethod.lineWidth = i++;
GLmethod.linkProgram = i++;
GLmethod.pixelStorei = i++;
GLmethod.polygonOffset = i++;              //90
GLmethod.readPixels = i++;
GLmethod.renderbufferStorage = i++;
GLmethod.sampleCoverage = i++;
GLmethod.scissor = i++;
GLmethod.shaderSource = i++;
GLmethod.stencilFunc = i++;
GLmethod.stencilFuncSeparate = i++;
GLmethod.stencilMask = i++;
GLmethod.stencilMaskSeparate = i++;
GLmethod.stencilOp = i++;                  //100
GLmethod.stencilOpSeparate = i++;
GLmethod.texImage2D = i++;
GLmethod.texParameterf = i++;
GLmethod.texParameteri = i++;
GLmethod.texSubImage2D = i++;
GLmethod.uniform1f = i++;
GLmethod.uniform1fv = i++;
GLmethod.uniform1i = i++;
GLmethod.uniform1iv = i++;
GLmethod.uniform2f = i++;                  //110
GLmethod.uniform2fv = i++;
GLmethod.uniform2i = i++;
GLmethod.uniform2iv = i++;
GLmethod.uniform3f = i++;
GLmethod.uniform3fv = i++;
GLmethod.uniform3i = i++;
GLmethod.uniform3iv = i++;
GLmethod.uniform4f = i++;
GLmethod.uniform4fv = i++;
GLmethod.uniform4i = i++;                  //120
GLmethod.uniform4iv = i++;
GLmethod.uniformMatrix2fv = i++;
GLmethod.uniformMatrix3fv = i++;
GLmethod.uniformMatrix4fv = i++;
GLmethod.useProgram = i++;
GLmethod.validateProgram = i++;
GLmethod.vertexAttrib1f = i++; //new
GLmethod.vertexAttrib2f = i++; //new
GLmethod.vertexAttrib3f = i++; //new
GLmethod.vertexAttrib4f = i++; //new       //130
GLmethod.vertexAttrib1fv = i++; //new
GLmethod.vertexAttrib2fv = i++; //new
GLmethod.vertexAttrib3fv = i++; //new
GLmethod.vertexAttrib4fv = i++; //new
GLmethod.vertexAttribPointer = i++;
GLmethod.viewport = i++;
export default GLmethod;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js
New file
@@ -0,0 +1,23 @@
const GLtype = {};
[
    "GLbitfield",
    "GLboolean",
    "GLbyte",
    "GLclampf",
    "GLenum",
    "GLfloat",
    "GLint",
    "GLintptr",
    "GLsizei",
    "GLsizeiptr",
    "GLshort",
    "GLubyte",
    "GLuint",
    "GLushort"
].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1));
export default GLtype;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js
New file
@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLProgram';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLProgram {
    className = name;
    constructor(id) {
        this.id = id;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js
New file
@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLRenderBuffer';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLRenderbuffer {
    className = name;
    constructor(id) {
        this.id = id;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js
New file
@@ -0,0 +1,1191 @@
import GLenum from './GLenum';
import ActiveInfo from './ActiveInfo';
import Buffer from './Buffer';
import Framebuffer from './Framebuffer';
import Renderbuffer from './Renderbuffer';
import Texture from './Texture';
import Program from './Program';
import Shader from './Shader';
import ShaderPrecisionFormat from './ShaderPrecisionFormat';
import UniformLocation from './UniformLocation';
import GLmethod from './GLmethod';
const processArray = (array, checkArrayType = false) => {
    function joinArray(arr, sep) {
        let res = '';
        for (let i = 0; i < arr.length; i++) {
            if (i !== 0) {
                res += sep;
            }
            res += arr[i];
        }
        return res;
    }
    let type = 'Float32Array';
    if (checkArrayType) {
        if (array instanceof Uint8Array) {
            type = 'Uint8Array'
        } else if (array instanceof Uint16Array) {
            type = 'Uint16Array';
        } else if (array instanceof Uint32Array) {
            type = 'Uint32Array';
        } else if (array instanceof Float32Array) {
            type = 'Float32Array';
        } else {
            throw new Error('Check array type failed. Array type is ' + typeof array);
        }
    }
    const ArrayTypes = {
        Uint8Array: 1,
        Uint16Array: 2,
        Uint32Array: 4,
        Float32Array: 14
    };
    return ArrayTypes[type] + ',' + btoa(joinArray(array, ','))
}
export default class WebGLRenderingContext {
    // static GBridge = null;
    className = 'WebGLRenderingContext';
    constructor(canvas, type, attrs) {
        this._canvas = canvas;
        this._type = type;
        this._version = 'WebGL 1.0';
        this._attrs = attrs;
        this._map = new Map();
        Object.keys(GLenum)
            .forEach(name => Object.defineProperty(this, name, {
                value: GLenum[name]
            }));
    }
    get canvas() {
        return this._canvas;
    }
    activeTexture = function (textureUnit) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.activeTexture + ',' + textureUnit,
            true
        );
    }
    attachShader = function (progarm, shader) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.attachShader + ',' + progarm.id + ',' + shader.id,
            true
        );
    }
    bindAttribLocation = function (program, index, name) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bindAttribLocation + ',' + program.id + ',' + index + ',' + name,
            true
        )
    }
    bindBuffer = function (target, buffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bindBuffer + ',' + target + ',' + (buffer ? buffer.id : 0),
            true
        );
    }
    bindFramebuffer = function (target, framebuffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bindFramebuffer + ',' + target + ',' + (framebuffer ? framebuffer.id : 0),
            true
        )
    }
    bindRenderbuffer = function (target, renderBuffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bindRenderbuffer + ',' + target + ',' + (renderBuffer ? renderBuffer.id : 0),
            true
        )
    }
    bindTexture = function (target, texture) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bindTexture + ',' + target + ',' + (texture ? texture.id : 0),
            true
        )
    }
    blendColor = function (r, g, b, a) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.blendColor + ',' + target + ',' + r + ',' + g + ',' + b + ',' + a,
            true
        )
    }
    blendEquation = function (mode) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.blendEquation + ',' + mode,
            true
        )
    }
    blendEquationSeparate = function (modeRGB, modeAlpha) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.blendEquationSeparate + ',' + modeRGB + ',' + modeAlpha,
            true
        )
    }
    blendFunc = function (sfactor, dfactor) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.blendFunc + ',' + sfactor + ',' + dfactor,
            true
        );
    }
    blendFuncSeparate = function (srcRGB, dstRGB, srcAlpha, dstAlpha) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.blendFuncSeparate + ',' + srcRGB + ',' + dstRGB + ',' + srcAlpha + ',' + dstAlpha,
            true
        );
    }
    bufferData = function (target, data, usage) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bufferData + ',' + target + ',' + processArray(data, true) + ',' + usage,
            true
        )
    }
    bufferSubData = function (target, offset, data) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.bufferSubData + ',' + target + ',' + offset + ',' + processArray(data, true),
            true
        )
    }
    checkFramebufferStatus = function (target) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.checkFramebufferStatus + ',' + target
        );
        return Number(result);
    }
    clear = function (mask) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.clear + ',' + mask
        );
        this._canvas._needRender = true;
    }
    clearColor = function (r, g, b, a) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.clearColor + ',' + r + ',' + g + ',' + b,
            true
        )
    }
    clearDepth = function (depth) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.clearDepth + ',' + depth,
            true
        )
    }
    clearStencil = function (s) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.clearStencil + ',' + s
        );
    }
    colorMask = function (r, g, b, a) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.colorMask + ',' + r + ',' + g + ',' + b + ',' + a
        )
    }
    compileShader = function (shader) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.compileShader + ',' + shader.id,
            true
        )
    }
    compressedTexImage2D = function (target, level, internalformat, width, height, border, pixels) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.compressedTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' +
            width + ',' + height + ',' + border + ',' + processArray(pixels),
            true
        )
    }
    compressedTexSubImage2D = function (target, level, xoffset, yoffset, width, height, format, pixels) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.compressedTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' +
            width + ',' + height + ',' + format + ',' + processArray(pixels),
            true
        )
    }
    copyTexImage2D = function (target, level, internalformat, x, y, width, height, border) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.copyTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + x + ',' + y + ',' +
            width + ',' + height + ',' + border,
            true
        );
    }
    copyTexSubImage2D = function (target, level, xoffset, yoffset, x, y, width, height) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.copyTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + x + ',' + y + ',' +
            width + ',' + height
        );
    }
    createBuffer = function () {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createBuffer + ''
        );
        const buffer = new Buffer(result);
        this._map.set(buffer.uuid(), buffer);
        return buffer;
    }
    createFramebuffer = function () {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createFramebuffer + ''
        );
        const framebuffer = new Framebuffer(result);
        this._map.set(framebuffer.uuid(), framebuffer);
        return framebuffer;
    }
    createProgram = function () {
        const id = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createProgram + ''
        );
        const program = new Program(id);
        this._map.set(program.uuid(), program);
        return program;
    }
    createRenderbuffer = function () {
        const id = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createRenderbuffer + ''
        )
        const renderBuffer = new Renderbuffer(id);
        this._map.set(renderBuffer.uuid(), renderBuffer);
        return renderBuffer;
    }
    createShader = function (type) {
        const id = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createShader + ',' + type
        )
        const shader = new Shader(id, type);
        this._map.set(shader.uuid(), shader);
        return shader;
    }
    createTexture = function () {
        const id = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.createTexture + ''
        );
        const texture = new Texture(id);
        this._map.set(texture.uuid(), texture);
        return texture;
    }
    cullFace = function (mode) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.cullFace + ',' + mode,
            true
        )
    }
    deleteBuffer = function (buffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteBuffer + ',' + buffer.id,
            true
        )
    }
    deleteFramebuffer = function (framebuffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteFramebuffer + ',' + framebuffer.id,
            true
        )
    }
    deleteProgram = function (program) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteProgram + ',' + program.id,
            true
        )
    }
    deleteRenderbuffer = function (renderbuffer) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteRenderbuffer + ',' + renderbuffer.id,
            true
        )
    }
    deleteShader = function (shader) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteShader + ',' + shader.id,
            true
        )
    }
    deleteTexture = function (texture) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.deleteTexture + ',' + texture.id,
            true
        )
    }
    depthFunc = function (func) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.depthFunc + ',' + func
        )
    }
    depthMask = function (flag) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.depthMask + ',' + Number(flag),
            true
        )
    }
    depthRange = function (zNear, zFar) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.depthRange + ',' + zNear + ',' + zFar,
            true
        )
    }
    detachShader = function (program, shader) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.detachShader + ',' + program.id + ',' + shader.id,
            true
        )
    }
    disable = function (cap) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.disable + ',' + cap,
            true
        )
    }
    disableVertexAttribArray = function (index) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.disableVertexAttribArray + ',' + index,
            true
        );
    }
    drawArrays = function (mode, first, count) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.drawArrays + ',' + mode + ',' + first + ',' + count
        )
        this._canvas._needRender = true;
    }
    drawElements = function (mode, count, type, offset) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.drawElements + ',' + mode + ',' + count + ',' + type + ',' + offset + ';'
        );
        this._canvas._needRender = true;
    }
    enable = function (cap) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.enable + ',' + cap,
            true
        );
    }
    enableVertexAttribArray = function (index) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.enableVertexAttribArray + ',' + index,
            true
        )
    }
    flush = function () {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.flush + ''
        )
    }
    framebufferRenderbuffer = function (target, attachment, textarget, texture, level) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.framebufferRenderbuffer + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
            true
        )
    }
    framebufferTexture2D = function (target, attachment, textarget, texture, level) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.framebufferTexture2D + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
            true
        )
    }
    frontFace = function (mode) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.frontFace + ',' + mode,
            true
        )
    }
    generateMipmap = function (target) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.generateMipmap + ',' + target,
            true
        )
    }
    getActiveAttrib = function (progarm, index) {
        const resultString = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getActiveAttrib + ',' + progarm.id + ',' + index
        )
        const [type, size, name] = resultString.split(',');
        return new ActiveInfo({
            type: Number(type),
            size: Number(size),
            name
        });
    }
    getActiveUniform = function (progarm, index) {
        const resultString = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getActiveUniform + ',' + progarm.id + ',' + index
        );
        const [type, size, name] = resultString.split(',');
        return new ActiveInfo({
            type: Number(type),
            size: Number(size),
            name
        })
    }
    getAttachedShaders = function (progarm) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getAttachedShaders + ',' + progarm.id
        );
        const [type, ...ids] = result;
        return ids.map(id => this._map.get(Shader.uuid(id)));
    }
    getAttribLocation = function (progarm, name) {
        return WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getAttribLocation + ',' + progarm.id + ',' + name
        )
    }
    getBufferParameter = function (target, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getBufferParameter + ',' + target + ',' + pname
        );
        const [type, res] = getBufferParameter;
        return res;
    }
    getError = function () {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getError + ''
        )
        return result;
    }
    getExtension = function (name) {
        return null;
    }
    getFramebufferAttachmentParameter = function (target, attachment, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getFramebufferAttachmentParameter + ',' + target + ',' + attachment + ',' + pname
        )
        switch (pname) {
            case GLenum.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                return this._map.get(Renderbuffer.uuid(result)) || this._map.get(Texture.uuid(result)) || null;
            default:
                return result;
        }
    }
    getParameter = function (pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getParameter + ',' + pname
        )
        switch (pname) {
            case GLenum.VERSION:
                return this._version;
            case GLenum.ARRAY_BUFFER_BINDING: // buffer
            case GLenum.ELEMENT_ARRAY_BUFFER_BINDING: // buffer
                return this._map.get(Buffer.uuid(result)) || null;
            case GLenum.CURRENT_PROGRAM: // program
                return this._map.get(Program.uuid(result)) || null;
            case GLenum.FRAMEBUFFER_BINDING: // framebuffer
                return this._map.get(Framebuffer.uuid(result)) || null;
            case GLenum.RENDERBUFFER_BINDING: // renderbuffer
                return this._map.get(Renderbuffer.uuid(result)) || null;
            case GLenum.TEXTURE_BINDING_2D: // texture
            case GLenum.TEXTURE_BINDING_CUBE_MAP: // texture
                return this._map.get(Texture.uuid(result)) || null;
            case GLenum.ALIASED_LINE_WIDTH_RANGE: // Float32Array
            case GLenum.ALIASED_POINT_SIZE_RANGE: // Float32Array
            case GLenum.BLEND_COLOR: // Float32Array
            case GLenum.COLOR_CLEAR_VALUE: // Float32Array
            case GLenum.DEPTH_RANGE: // Float32Array
            case GLenum.MAX_VIEWPORT_DIMS: // Int32Array
            case GLenum.SCISSOR_BOX: // Int32Array
            case GLenum.VIEWPORT: // Int32Array
            case GLenum.COMPRESSED_TEXTURE_FORMATS: // Uint32Array
            default:
                const [type, ...res] = result.split(',');
                if (res.length === 1) {
                    return Number(res[0]);
                } else {
                    return res.map(Number);
                }
        }
    }
    getProgramInfoLog = function (progarm) {
        return WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getProgramInfoLog + ',' + progarm.id
        )
    }
    getProgramParameter = function (program, pname) {
        const res = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getProgramParameter + ',' + program.id + ',' + pname
        );
        const [type, result] = res.split(',').map(i => parseInt(i));
        if (type === 1) {
            return Boolean(result);
        } else if (type === 2) {
            return result;
        } else {
            throw new Error('Unrecongized program paramater ' + res + ', type: ' + typeof res);
        }
    }
    getRenderbufferParameter = function (target, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getRenderbufferParameter + ',' + target + ',' + pname
        )
        return result;
    }
    getShaderInfoLog = function (shader) {
        return WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getShaderInfoLog + ',' + shader.id
        );
    }
    getShaderParameter = function (shader, pname) {
        return WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getShaderParameter + ',' + shader.id + ',' + pname
        )
    }
    getShaderPrecisionFormat = function (shaderType, precisionType) {
        const [rangeMin, rangeMax, precision] = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getShaderPrecisionFormat + ',' + shaderType + ',' + precisionType
        );
        const shaderPrecisionFormat = new ShaderPrecisionFormat({
            rangeMin: Number(rangeMin),
            rangeMax: Number(rangeMax),
            precision: Number(precision)
        });
        return shaderPrecisionFormat;
    }
    getShaderSource = function (shader) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getShaderSource + ',' + shader.id
        );
        return result;
    }
    getSupportedExtensions = function () {
        return Object.keys({});
    }
    getTexParameter = function (target, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getTexParameter + ',' + target + ',' + pname
        )
        return result;
    }
    getUniformLocation = function (program, name) {
        const id = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getUniformLocation + ',' + program.id + ',' + name
        );
        if (id === -1) {
            return null;
        } else {
            return new UniformLocation(Number(id));
        }
    }
    getVertexAttrib = function (index, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getVertexAttrib + ',' + index + ',' + pname
        );
        switch (pname) {
            case GLenum.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
                return this._map.get(Buffer.uuid(result)) || null;
            case GLenum.CURRENT_VERTEX_ATTRIB: // Float32Array
            default:
                return result;
        }
    }
    getVertexAttribOffset = function (index, pname) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.getVertexAttribOffset + ',' + index + ',' + pname
        )
        return Number(result);
    }
    isBuffer = function (buffer) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isBuffer + ',' + buffer.id
        )
        return Boolean(result);
    }
    isContextLost = function () {
        return false;
    }
    isEnabled = function (cap) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isEnabled + ',' + cap
        )
        return Boolean(result);
    }
    isFramebuffer = function (framebuffer) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isFramebuffer + ',' + framebuffer.id
        )
        return Boolean(result);
    }
    isProgram = function (program) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isProgram + ',' + program.id
        )
        return Boolean(result);
    }
    isRenderbuffer = function (renderBuffer) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isRenderbuffer + ',' + renderbuffer.id
        )
        return Boolean(result);
    }
    isShader = function (shader) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isShader + ',' + shader.id
        )
        return Boolean(result);
    }
    isTexture = function (texture) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.isTexture + ',' + texture.id
        );
        return Boolean(result);
    }
    lineWidth = function (width) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.lineWidth + ',' + width,
            true
        )
    }
    linkProgram = function (program) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.linkProgram + ',' + program.id,
            true
        );
    }
    pixelStorei = function (pname, param) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.pixelStorei + ',' + pname + ',' + Number(param)
        )
    }
    polygonOffset = function (factor, units) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.polygonOffset + ',' + factor + ',' + units
        )
    }
    readPixels = function (x, y, width, height, format, type, pixels) {
        const result = WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.readPixels + ',' + x + ',' + y + ',' + width + ',' + height + ',' + format + ',' + type
        )
        return result;
    }
    renderbufferStorage = function (target, internalFormat, width, height) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.renderbufferStorage + ',' + target + ',' + internalFormat + ',' + width + ',' + height,
            true
        )
    }
    sampleCoverage = function (value, invert) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.sampleCoverage + ',' + value + ',' + Number(invert),
            true
        )
    }
    scissor = function (x, y, width, height) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.scissor + ',' + x + ',' + y + ',' + width + ',' + height,
            true
        )
    }
    shaderSource = function (shader, source) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.shaderSource + ',' + shader.id + ',' + source
        )
    }
    stencilFunc = function (func, ref, mask) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilFunc + ',' + func + ',' + ref + ',' + mask,
            true
        )
    }
    stencilFuncSeparate = function (face, func, ref, mask) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilFuncSeparate + ',' + face + ',' + func + ',' + ref + ',' + mask,
            true
        )
    }
    stencilMask = function (mask) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilMask + ',' + mask,
            true
        )
    }
    stencilMaskSeparate = function (face, mask) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilMaskSeparate + ',' + face + ',' + mask,
            true
        )
    }
    stencilOp = function (fail, zfail, zpass) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilOp + ',' + fail + ',' + zfail + ',' + zpass
        )
    }
    stencilOpSeparate = function (face, fail, zfail, zpass) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.stencilOp + ',' + face + ',' + fail + ',' + zfail + ',' + zpass,
            true
        )
    }
    texImage2D = function (...args) {
        WebGLRenderingContext.GBridge.texImage2D(this._canvas.id, ...args);
    }
    texParameterf = function (target, pname, param) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.texParameterf + ',' + target + ',' + pname + ',' + param,
            true
        )
    }
    texParameteri = function (target, pname, param) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.texParameteri + ',' + target + ',' + pname + ',' + param
        )
    }
    texSubImage2D = function (...args) {
        WebGLRenderingContext.GBridge.texSubImage2D(this._canvas.id, ...args);
    }
    uniform1f = function (location, v0) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform1f + ',' + location.id + ',' + v0
        )
    }
    uniform1fv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform1fv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform1i = function (location, v0) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform1i + ',' + location.id + ',' + v0,
            // true
        )
    }
    uniform1iv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform1iv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform2f = function (location, v0, v1) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform2f + ',' + location.id + ',' + v0 + ',' + v1,
            true
        )
    }
    uniform2fv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform2fv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform2i = function (location, v0, v1) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform2i + ',' + location.id + ',' + v0 + ',' + v1,
            true
        )
    }
    uniform2iv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform2iv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform3f = function (location, v0, v1, v2) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform3f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
            true
        )
    }
    uniform3fv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform3fv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform3i = function (location, v0, v1, v2) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform3i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
            true
        )
    }
    uniform3iv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform3iv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform4f = function (location, v0, v1, v2, v3) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform4f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
            true
        )
    }
    uniform4fv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform4fv + ',' + location.id + ',' + processArray(value),
            true
        )
    }
    uniform4i = function (location, v0, v1, v2, v3) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform4i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
            true
        )
    }
    uniform4iv = function (location, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniform4iv + ',' + location.id + ',' + processArray(value, true),
            true
        )
    }
    uniformMatrix2fv = function (location, transpose, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniformMatrix2fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
            true
        )
    }
    uniformMatrix3fv = function (location, transpose, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniformMatrix3fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
            true
        )
    }
    uniformMatrix4fv = function (location, transpose, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.uniformMatrix4fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
            true
        );
    }
    useProgram = function (progarm) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.useProgram + ',' + progarm.id + '',
            true
        )
    }
    validateProgram = function (program) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.validateProgram + ',' + program.id,
            true
        )
    }
    vertexAttrib1f = function (index, v0) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib1f + ',' + index + ',' + v0,
            true
        )
    }
    vertexAttrib2f = function (index, v0, v1) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib2f + ',' + index + ',' + v0 + ',' + v1,
            true
        )
    }
    vertexAttrib3f = function (index, v0, v1, v2) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib3f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2,
            true
        )
    }
    vertexAttrib4f = function (index, v0, v1, v2, v3) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib4f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
            true
        )
    }
    vertexAttrib1fv = function (index, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib1fv + ',' + index + ',' + processArray(value),
            true
        )
    }
    vertexAttrib2fv = function (index, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib2fv + ',' + index + ',' + processArray(value),
            true
        )
    }
    vertexAttrib3fv = function (index, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib3fv + ',' + index + ',' + processArray(value),
            true
        )
    }
    vertexAttrib4fv = function (index, value) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttrib4fv + ',' + index + ',' + processArray(value),
            true
        )
    }
    vertexAttribPointer = function (index, size, type, normalized, stride, offset) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.vertexAttribPointer + ',' + index + ',' + size + ',' + type + ',' + Number(normalized) + ',' + stride + ',' + offset,
            true
        )
    }
    viewport = function (x, y, width, height) {
        WebGLRenderingContext.GBridge.callNative(
            this._canvas.id,
            GLmethod.viewport + ',' + x + ',' + y + ',' + width + ',' + height,
            true
        )
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js
New file
@@ -0,0 +1,22 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLShader';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLShader {
    className = name;
    constructor(id, type) {
        this.id = id;
        this.type = type;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js
New file
@@ -0,0 +1,11 @@
export default class WebGLShaderPrecisionFormat {
    className = 'WebGLShaderPrecisionFormat';
    constructor({
        rangeMin, rangeMax, precision
    }) {
        this.rangeMin = rangeMin;
        this.rangeMax = rangeMax;
        this.precision = precision;
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js
New file
@@ -0,0 +1,22 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLTexture';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLTexture {
    className = name;
    constructor(id, type) {
        this.id = id;
        this.type = type;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js
New file
@@ -0,0 +1,22 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLUniformLocation';
function uuid(id) {
    return getTransferedObjectUUID(name, id);
}
export default class WebGLUniformLocation {
    className = name;
    constructor(id, type) {
        this.id = id;
        this.type = type;
    }
    static uuid = uuid;
    uuid() {
        return uuid(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js
New file
@@ -0,0 +1,3 @@
export function getTransferedObjectUUID(name, id) {
    return `${name.toLowerCase()}-${id}`;
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js
New file
@@ -0,0 +1,74 @@
import GContext2D from '../context-2d/RenderingContext';
import GContextWebGL from '../context-webgl/RenderingContext';
export default class GCanvas {
    // static GBridge = null;
    id = null;
    _needRender = true;
    constructor(id, { disableAutoSwap }) {
        this.id = id;
        this._disableAutoSwap = disableAutoSwap;
        if (disableAutoSwap) {
            this._swapBuffers = () => {
                GCanvas.GBridge.render(this.id);
            }
        }
    }
    getContext(type) {
        let context = null;
        if (type.match(/webgl/i)) {
            context = new GContextWebGL(this);
            context.componentId = this.id;
            if (!this._disableAutoSwap) {
                const render = () => {
                    if (this._needRender) {
                        GCanvas.GBridge.render(this.id);
                        this._needRender = false;
                    }
                }
                setInterval(render, 16);
            }
            GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
        } else if (type.match(/2d/i)) {
            context = new GContext2D(this);
            context.componentId = this.id;
//             const render = ( callback ) => {
//
//                 const commands = context._drawCommands;
//                 context._drawCommands = '';
//
//                 GCanvas.GBridge.render2d(this.id, commands, callback);
//                 this._needRender = false;
//             }
//             //draw方法触发
//             context._flush = render;
//             //setInterval(render, 16);
            GCanvas.GBridge.callSetContextType(this.id, 0);
        } else {
            throw new Error('not supported context ' + type);
        }
        return context;
    }
    reset() {
        GCanvas.GBridge.callReset(this.id);
    }
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js
New file
@@ -0,0 +1,96 @@
let incId = 1;
const noop = function () { };
class GImage {
    static GBridge = null;
    constructor() {
        this._id = incId++;
        this._width = 0;
        this._height = 0;
        this._src = undefined;
        this._onload = noop;
        this._onerror = noop;
        this.complete = false;
    }
    get width() {
        return this._width;
    }
    set width(v) {
        this._width = v;
    }
    get height() {
        return this._height;
    }
    set height(v) {
        this._height = v;
    }
    get src() {
        return this._src;
    }
    set src(v) {
        if (v.startsWith('//')) {
            v = 'http:' + v;
        }
        this._src = v;
        GImage.GBridge.perloadImage([this._src, this._id], (data) => {
            if (typeof data === 'string') {
                data = JSON.parse(data);
            }
            if (data.error) {
                var evt = { type: 'error', target: this };
                this.onerror(evt);
            } else {
                this.complete = true;
                this.width = typeof data.width === 'number' ? data.width : 0;
                this.height = typeof data.height === 'number' ? data.height : 0;
                var evt = { type: 'load', target: this };
                this.onload(evt);
            }
        });
    }
    addEventListener(name, listener) {
        if (name === 'load') {
            this.onload = listener;
        } else if (name === 'error') {
            this.onerror = listener;
        }
    }
    removeEventListener(name, listener) {
        if (name === 'load') {
            this.onload = noop;
        } else if (name === 'error') {
            this.onerror = noop;
        }
    }
    get onload() {
        return this._onload;
    }
    set onload(v) {
        this._onload = v;
    }
    get onerror() {
        return this._onerror;
    }
    set onerror(v) {
        this._onerror = v;
    }
}
export default GImage;
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js
New file
@@ -0,0 +1,24 @@
export function ArrayBufferToBase64 (buffer) {
    var binary = '';
    var bytes = new Uint8ClampedArray(buffer);
    for (var len = bytes.byteLength, i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return btoa(binary);
}
export function Base64ToUint8ClampedArray(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');
    const rawData = atob(base64);
    const outputArray = new Uint8ClampedArray(rawData.length);
    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js
New file
@@ -0,0 +1,39 @@
import GCanvas from './env/canvas';
import GImage from './env/image';
import GWebGLRenderingContext from './context-webgl/RenderingContext';
import GContext2D from './context-2d/RenderingContext';
import GBridgeWeex from './bridge/bridge-weex';
export let Image = GImage;
export let WeexBridge = GBridgeWeex;
export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
    const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
    GBridge.callEnable(el.ref, [
        0,      // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
        -1,     // hybridLayerType:  0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE
        false,  // supportScroll
        false,  // newCanvasMode
        1,      // compatible
        'white',// clearColor
        false   // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
    ]);
    if (debug === true) {
        GBridge.callEnableDebug();
    }
    if (disableComboCommands) {
        GBridge.callEnableDisableCombo();
    }
    var canvas = new GCanvas(el.ref, { disableAutoSwap });
    canvas.width = el.style.width;
    canvas.height = el.style.height;
    return canvas;
};
uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js
New file
@@ -0,0 +1,34 @@
//---------------------------------------------------------------------
// uQRCode二维码生成插件 v4.0.6
//
// uQRCode是一款基于Javascript环境开发的二维码生成插件,适用所有Javascript运行环境的前端应用和Node.js。
//
// Copyright (c) Sansnn uQRCode All rights reserved.
//
// Licensed under the Apache License, Version 2.0.
//   http://www.apache.org/licenses/LICENSE-2.0
//
// github地址:
//   https://github.com/Sansnn/uQRCode
//
// npm地址:
//   https://www.npmjs.com/package/uqrcodejs
//
// uni-app插件市场地址:
//   https://ext.dcloud.net.cn/plugin?id=1287
//
// 复制使用请保留本段注释,感谢支持开源!
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// 当前文件格式为 es,将 bundle 保留为 ES 模块文件,适用于其他打包工具以及支持 <script type=module> 标签的浏览器(别名: esm,module)
// 如需在其他环境使用,请获取环境对应的格式文件
// 格式说明:
// amd - 异步模块定义,适用于 RequireJS 等模块加载器
// cjs - CommonJS,适用于 Node 环境和其他打包工具(别名:commonjs)
// es - 将 bundle 保留为 ES 模块文件,适用于其他打包工具以及支持 <script type=module> 标签的浏览器(别名: esm,module)
// umd - 通用模块定义,生成的包同时支持 amd、cjs 和 iife 三种格式
//---------------------------------------------------------------------
function o(o){this.mode=r.MODE_8BIT_BYTE,this.data=o;}function e(o,e){this.typeNumber=o,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array;}o.prototype={getLength:function(o){return this.data.length},write:function(o){for(var e=0;e<this.data.length;e++)o.put(this.data.charCodeAt(e),8);}},e.prototype={addData:function(e){var r=new o(e);this.dataList.push(r),this.dataCache=null;},isDark:function(o,e){if(o<0||this.moduleCount<=o||e<0||this.moduleCount<=e)throw new Error(o+","+e);return this.modules[o][e]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var o=1;for(o=1;o<40;o++){for(var e=v.getRSBlocks(o,this.errorCorrectLevel),r=new p,t=0,i=0;i<e.length;i++)t+=e[i].dataCount;for(i=0;i<this.dataList.length;i++){var n=this.dataList[i];r.put(n.mode,4),r.put(n.getLength(),h.getLengthInBits(n.mode,o)),n.write(r);}if(r.getLengthInBits()<=8*t)break}this.typeNumber=o;}this.makeImpl(!1,this.getBestMaskPattern());},makeImpl:function(o,r){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var t=0;t<this.moduleCount;t++){this.modules[t]=new Array(this.moduleCount);for(var i=0;i<this.moduleCount;i++)this.modules[t][i]=null;}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(o,r),this.typeNumber>=7&&this.setupTypeNumber(o),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,r);},setupPositionProbePattern:function(o,e){for(var r=-1;r<=7;r++)if(!(o+r<=-1||this.moduleCount<=o+r))for(var t=-1;t<=7;t++)e+t<=-1||this.moduleCount<=e+t||(this.modules[o+r][e+t]=0<=r&&r<=6&&(0==t||6==t)||0<=t&&t<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=t&&t<=4);},getBestMaskPattern:function(){for(var o=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var t=h.getLostPoint(this);(0==r||o>t)&&(o=t,e=r);}return e},createMovieClip:function(o,e,r){var t=o.createEmptyMovieClip(e,r);this.make();for(var i=0;i<this.modules.length;i++)for(var n=1*i,a=0;a<this.modules[i].length;a++){var d=1*a;this.modules[i][a]&&(t.beginFill(0,100),t.moveTo(d,n),t.lineTo(d+1,n),t.lineTo(d+1,n+1),t.lineTo(d,n+1),t.endFill());}return t},setupTimingPattern:function(){for(var o=8;o<this.moduleCount-8;o++)null==this.modules[o][6]&&(this.modules[o][6]=o%2==0);for(var e=8;e<this.moduleCount-8;e++)null==this.modules[6][e]&&(this.modules[6][e]=e%2==0);},setupPositionAdjustPattern:function(){for(var o=h.getPatternPosition(this.typeNumber),e=0;e<o.length;e++)for(var r=0;r<o.length;r++){var t=o[e],i=o[r];if(null==this.modules[t][i])for(var n=-2;n<=2;n++)for(var a=-2;a<=2;a++)this.modules[t+n][i+a]=-2==n||2==n||-2==a||2==a||0==n&&0==a;}},setupTypeNumber:function(o){for(var e=h.getBCHTypeNumber(this.typeNumber),r=0;r<18;r++){var t=!o&&1==(e>>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=t;}for(r=0;r<18;r++){t=!o&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=t;}},setupTypeInfo:function(o,e){for(var r=this.errorCorrectLevel<<3|e,t=h.getBCHTypeInfo(r),i=0;i<15;i++){var n=!o&&1==(t>>i&1);i<6?this.modules[i][8]=n:i<8?this.modules[i+1][8]=n:this.modules[this.moduleCount-15+i][8]=n;}for(i=0;i<15;i++){n=!o&&1==(t>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=n:i<9?this.modules[8][15-i-1+1]=n:this.modules[8][15-i-1]=n;}this.modules[this.moduleCount-8][8]=!o;},mapData:function(o,e){for(var r=-1,t=this.moduleCount-1,i=7,n=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var d=0;d<2;d++)if(null==this.modules[t][a-d]){var u=!1;n<o.length&&(u=1==(o[n]>>>i&1)),h.getMask(e,t,a-d)&&(u=!u),this.modules[t][a-d]=u,-1==--i&&(n++,i=7);}if((t+=r)<0||this.moduleCount<=t){t-=r,r=-r;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(o,r,t){for(var i=v.getRSBlocks(o,r),n=new p,a=0;a<t.length;a++){var d=t[a];n.put(d.mode,4),n.put(d.getLength(),h.getLengthInBits(d.mode,o)),d.write(n);}var u=0;for(a=0;a<i.length;a++)u+=i[a].dataCount;if(n.getLengthInBits()>8*u)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*u+")");for(n.getLengthInBits()+4<=8*u&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*u||(n.put(e.PAD0,8),n.getLengthInBits()>=8*u));)n.put(e.PAD1,8);return e.createBytes(n,i)},e.createBytes=function(o,e){for(var r=0,t=0,i=0,n=new Array(e.length),a=new Array(e.length),d=0;d<e.length;d++){var u=e[d].dataCount,s=e[d].totalCount-u;t=Math.max(t,u),i=Math.max(i,s),n[d]=new Array(u);for(var g=0;g<n[d].length;g++)n[d][g]=255&o.buffer[g+r];r+=u;var l=h.getErrorCorrectPolynomial(s),c=new f(n[d],l.getLength()-1).mod(l);a[d]=new Array(l.getLength()-1);for(g=0;g<a[d].length;g++){var m=g+c.getLength()-a[d].length;a[d][g]=m>=0?c.get(m):0;}}var v=0;for(g=0;g<e.length;g++)v+=e[g].totalCount;var p=new Array(v),C=0;for(g=0;g<t;g++)for(d=0;d<e.length;d++)g<n[d].length&&(p[C++]=n[d][g]);for(g=0;g<i;g++)for(d=0;d<e.length;d++)g<a[d].length&&(p[C++]=a[d][g]);return p};for(var r={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},t={L:1,M:0,Q:3,H:2},i=0,n=1,a=2,d=3,u=4,s=5,g=6,l=7,h={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(o){for(var e=o<<10;h.getBCHDigit(e)-h.getBCHDigit(h.G15)>=0;)e^=h.G15<<h.getBCHDigit(e)-h.getBCHDigit(h.G15);return (o<<10|e)^h.G15_MASK},getBCHTypeNumber:function(o){for(var e=o<<12;h.getBCHDigit(e)-h.getBCHDigit(h.G18)>=0;)e^=h.G18<<h.getBCHDigit(e)-h.getBCHDigit(h.G18);return o<<12|e},getBCHDigit:function(o){for(var e=0;0!=o;)e++,o>>>=1;return e},getPatternPosition:function(o){return h.PATTERN_POSITION_TABLE[o-1]},getMask:function(o,e,r){switch(o){case i:return (e+r)%2==0;case n:return e%2==0;case a:return r%3==0;case d:return (e+r)%3==0;case u:return (Math.floor(e/2)+Math.floor(r/3))%2==0;case s:return e*r%2+e*r%3==0;case g:return (e*r%2+e*r%3)%2==0;case l:return (e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+o)}},getErrorCorrectPolynomial:function(o){for(var e=new f([1],0),r=0;r<o;r++)e=e.multiply(new f([1,c.gexp(r)],0));return e},getLengthInBits:function(o,e){if(1<=e&&e<10)switch(o){case r.MODE_NUMBER:return 10;case r.MODE_ALPHA_NUM:return 9;case r.MODE_8BIT_BYTE:case r.MODE_KANJI:return 8;default:throw new Error("mode:"+o)}else if(e<27)switch(o){case r.MODE_NUMBER:return 12;case r.MODE_ALPHA_NUM:return 11;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 10;default:throw new Error("mode:"+o)}else {if(!(e<41))throw new Error("type:"+e);switch(o){case r.MODE_NUMBER:return 14;case r.MODE_ALPHA_NUM:return 13;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 12;default:throw new Error("mode:"+o)}}},getLostPoint:function(o){for(var e=o.getModuleCount(),r=0,t=0;t<e;t++)for(var i=0;i<e;i++){for(var n=0,a=o.isDark(t,i),d=-1;d<=1;d++)if(!(t+d<0||e<=t+d))for(var u=-1;u<=1;u++)i+u<0||e<=i+u||0==d&&0==u||a==o.isDark(t+d,i+u)&&n++;n>5&&(r+=3+n-5);}for(t=0;t<e-1;t++)for(i=0;i<e-1;i++){var s=0;o.isDark(t,i)&&s++,o.isDark(t+1,i)&&s++,o.isDark(t,i+1)&&s++,o.isDark(t+1,i+1)&&s++,0!=s&&4!=s||(r+=3);}for(t=0;t<e;t++)for(i=0;i<e-6;i++)o.isDark(t,i)&&!o.isDark(t,i+1)&&o.isDark(t,i+2)&&o.isDark(t,i+3)&&o.isDark(t,i+4)&&!o.isDark(t,i+5)&&o.isDark(t,i+6)&&(r+=40);for(i=0;i<e;i++)for(t=0;t<e-6;t++)o.isDark(t,i)&&!o.isDark(t+1,i)&&o.isDark(t+2,i)&&o.isDark(t+3,i)&&o.isDark(t+4,i)&&!o.isDark(t+5,i)&&o.isDark(t+6,i)&&(r+=40);var g=0;for(i=0;i<e;i++)for(t=0;t<e;t++)o.isDark(t,i)&&g++;return r+=10*(Math.abs(100*g/e/e-50)/5)}},c={glog:function(o){if(o<1)throw new Error("glog("+o+")");return c.LOG_TABLE[o]},gexp:function(o){for(;o<0;)o+=255;for(;o>=256;)o-=255;return c.EXP_TABLE[o]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},m=0;m<8;m++)c.EXP_TABLE[m]=1<<m;for(m=8;m<256;m++)c.EXP_TABLE[m]=c.EXP_TABLE[m-4]^c.EXP_TABLE[m-5]^c.EXP_TABLE[m-6]^c.EXP_TABLE[m-8];for(m=0;m<255;m++)c.LOG_TABLE[c.EXP_TABLE[m]]=m;function f(o,e){if(null==o.length)throw new Error(o.length+"/"+e);for(var r=0;r<o.length&&0==o[r];)r++;this.num=new Array(o.length-r+e);for(var t=0;t<o.length-r;t++)this.num[t]=o[t+r];}function v(o,e){this.totalCount=o,this.dataCount=e;}function p(){this.buffer=new Array,this.length=0;}function C(o){return o.setFillStyle=o.setFillStyle||function(e){o.fillStyle=e;},o.setFontSize=o.setFontSize||function(e){o.font=`${e}px`;},o.setTextAlign=o.setTextAlign||function(e){o.textAlign=e;},o.setTextBaseline=o.setTextBaseline||function(e){o.textBaseline=e;},o.setGlobalAlpha=o.setGlobalAlpha||function(e){o.globalAlpha=e;},o.setStrokeStyle=o.setStrokeStyle||function(e){o.strokeStyle=e;},o.setShadow=o.setShadow||function(e,r,t,i){o.shadowOffsetX=e,o.shadowOffsetY=r,o.shadowBlur=t,o.shadowColor=i;},o.draw=o.draw||function(o,e){e&&e();},o.clearRect=o.clearRect||function(e,r,t,i){o.draw(!1);},o}function b(o,e){var r=this.data="",t=this.size=200;this.useDynamicSize=!1,this.dynamicSize=t;var i=this.typeNumber=-1;this.errorCorrectLevel=b.errorCorrectLevel.H;var n=this.margin=0;this.areaColor="#FFFFFF",this.backgroundColor="rgba(255,255,255,0)",this.backgroundImageSrc=void 0;var a=this.backgroundImageWidth=void 0,d=this.backgroundImageHeight=void 0,u=this.backgroundImageX=void 0,s=this.backgroundImageY=void 0;this.backgroundImageAlpha=1,this.backgroundImageBorderRadius=0;var g=this.backgroundPadding=0;this.foregroundColor="#000000",this.foregroundImageSrc=void 0;var l=this.foregroundImageWidth=void 0,h=this.foregroundImageHeight=void 0,c=this.foregroundImageX=void 0,m=this.foregroundImageY=void 0,f=this.foregroundImagePadding=0;this.foregroundImageBackgroundColor="#FFFFFF";var v=this.foregroundImageBorderRadius=0,p=this.foregroundImageShadowOffsetX=0,k=this.foregroundImageShadowOffsetY=0,y=this.foregroundImageShadowBlur=0;this.foregroundImageShadowColor="#808080";var w=this.foregroundPadding=0,I=this.positionProbeBackgroundColor=void 0,B=this.positionProbeForegroundColor=void 0,S=this.separatorColor=void 0,P=this.positionAdjustBackgroundColor=void 0,L=this.positionAdjustForegroundColor=void 0,D=this.timingBackgroundColor=void 0,A=this.timingForegroundColor=void 0,E=this.typeNumberBackgroundColor=void 0,T=this.typeNumberForegroundColor=void 0,N=this.darkBlockColor=void 0;this.base=void 0,this.modules=[],this.moduleCount=0,this.drawModules=[];var M=this.canvasContext=void 0;this.loadImage,this.drawReserve=!1,this.isMaked=!1,Object.defineProperties(this,{data:{get(){if(""===r||void 0===r)throw console.error("[uQRCode]: data must be set!"),new b.Error("data must be set!");return r},set(o){r=String(o);}},size:{get:()=>t,set(o){t=Number(o);}},typeNumber:{get:()=>i,set(o){i=Number(o);}},margin:{get:()=>n,set(o){n=Number(o);}},backgroundImageWidth:{get(){return void 0===a?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*a:a},set(o){a=Number(o);}},backgroundImageHeight:{get(){return void 0===d?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*d:d},set(o){d=Number(o);}},backgroundImageX:{get(){return void 0===u?0:this.useDynamicSize?this.dynamicSize/this.size*u:u},set(o){u=Number(o);}},backgroundImageY:{get(){return void 0===s?0:this.useDynamicSize?this.dynamicSize/this.size*s:s},set(o){s=Number(o);}},backgroundPadding:{get:()=>g,set(o){g=o>1?1:o<0?0:o;}},foregroundImageWidth:{get(){return void 0===l?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*l:l},set(o){l=Number(o);}},foregroundImageHeight:{get(){return void 0===h?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*h:h},set(o){h=Number(o);}},foregroundImageX:{get(){return void 0===c?this.dynamicSize/2-this.foregroundImageWidth/2:this.useDynamicSize?this.dynamicSize/this.size*c:c},set(o){c=Number(o);}},foregroundImageY:{get(){return void 0===m?this.dynamicSize/2-this.foregroundImageHeight/2:this.useDynamicSize?this.dynamicSize/this.size*m:m},set(o){m=Number(o);}},foregroundImagePadding:{get(){return this.useDynamicSize?this.dynamicSize/this.size*f:f},set(o){f=Number(o);}},foregroundImageBorderRadius:{get(){return this.useDynamicSize?this.dynamicSize/this.size*v:v},set(o){v=Number(o);}},foregroundImageShadowOffsetX:{get(){return this.useDynamicSize?this.dynamicSize/this.size*p:p},set(o){p=Number(o);}},foregroundImageShadowOffsetY:{get(){return this.useDynamicSize?this.dynamicSize/this.size*k:k},set(o){k=Number(o);}},foregroundImageShadowBlur:{get(){return this.useDynamicSize?this.dynamicSize/this.size*y:y},set(o){y=Number(o);}},foregroundPadding:{get:()=>w,set(o){w=o>1?1:o<0?0:o;}},positionProbeBackgroundColor:{get(){return I||this.backgroundColor},set(o){I=o;}},positionProbeForegroundColor:{get(){return B||this.foregroundColor},set(o){B=o;}},separatorColor:{get(){return S||this.backgroundColor},set(o){S=o;}},positionAdjustBackgroundColor:{get(){return P||this.backgroundColor},set(o){P=o;}},positionAdjustForegroundColor:{get(){return L||this.foregroundColor},set(o){L=o;}},timingBackgroundColor:{get(){return D||this.backgroundColor},set(o){D=o;}},timingForegroundColor:{get(){return A||this.foregroundColor},set(o){A=o;}},typeNumberBackgroundColor:{get(){return E||this.backgroundColor},set(o){E=o;}},typeNumberForegroundColor:{get(){return T||this.foregroundColor},set(o){T=o;}},darkBlockColor:{get(){return N||this.foregroundColor},set(o){N=o;}},canvasContext:{get(){if(void 0===M)throw console.error("[uQRCode]: use drawCanvas, you need to set the canvasContext!"),new b.Error("use drawCanvas, you need to set the canvasContext!");return M},set(o){M=C(o);}}}),b.plugins.forEach((o=>o(b,this,!1))),o&&this.setOptions(o),e&&(this.canvasContext=C(e));}f.prototype={get:function(o){return this.num[o]},getLength:function(){return this.num.length},multiply:function(o){for(var e=new Array(this.getLength()+o.getLength()-1),r=0;r<this.getLength();r++)for(var t=0;t<o.getLength();t++)e[r+t]^=c.gexp(c.glog(this.get(r))+c.glog(o.get(t)));return new f(e,0)},mod:function(o){if(this.getLength()-o.getLength()<0)return this;for(var e=c.glog(this.get(0))-c.glog(o.get(0)),r=new Array(this.getLength()),t=0;t<this.getLength();t++)r[t]=this.get(t);for(t=0;t<o.getLength();t++)r[t]^=c.gexp(c.glog(o.get(t))+e);return new f(r,0).mod(o)}},v.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],v.getRSBlocks=function(o,e){var r=v.getRsBlockTable(o,e);if(null==r)throw new Error("bad rs block @ typeNumber:"+o+"/errorCorrectLevel:"+e);for(var t=r.length/3,i=new Array,n=0;n<t;n++)for(var a=r[3*n+0],d=r[3*n+1],u=r[3*n+2],s=0;s<a;s++)i.push(new v(d,u));return i},v.getRsBlockTable=function(o,e){switch(e){case t.L:return v.RS_BLOCK_TABLE[4*(o-1)+0];case t.M:return v.RS_BLOCK_TABLE[4*(o-1)+1];case t.Q:return v.RS_BLOCK_TABLE[4*(o-1)+2];case t.H:return v.RS_BLOCK_TABLE[4*(o-1)+3];default:return}},p.prototype={get:function(o){var e=Math.floor(o/8);return 1==(this.buffer[e]>>>7-o%8&1)},put:function(o,e){for(var r=0;r<e;r++)this.putBit(1==(o>>>e-r-1&1));},getLengthInBits:function(){return this.length},putBit:function(o){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),o&&(this.buffer[e]|=128>>>this.length%8),this.length++;}},e.errorCorrectLevel=t,b.errorCorrectLevel=e.errorCorrectLevel,b.Error=function(o){this.errMsg="[uQRCode]: "+o;},b.plugins=[],b.use=function(o){"function"==typeof o&&b.plugins.push(o);},b.prototype.loadImage=function(o){return Promise.resolve(o)},b.prototype.setOptions=function(o){var e,r,t,i,n,a,d,u,s,g,l,h,c,m,f,v,p,C,b,k,y,w,I,B,S,P,L,D,A,E,T,N,M,z,R,_,O,F,x,H,X,Y,j,W,G,K,Q,U,$,J,q,V,Z,oo,eo,ro;o&&(Object.keys(o).forEach((e=>{this[e]=o[e];})),function(o={},e={},r=!1){let t;t=r?o:{...o};for(let o in e){var i=e[o];null!=i&&(i.constructor==Object?t[o]=this.deepReplace(t[o],i):i.constructor!=String||i?t[o]=i:t[o]=t[o]);}}(this,{data:o.data||o.text,size:o.size,useDynamicSize:o.useDynamicSize,typeNumber:o.typeNumber,errorCorrectLevel:o.errorCorrectLevel,margin:o.margin,areaColor:o.areaColor,backgroundColor:o.backgroundColor||(null===(e=o.background)||void 0===e?void 0:e.color),backgroundImageSrc:o.backgroundImageSrc||(null===(r=o.background)||void 0===r||null===(t=r.image)||void 0===t?void 0:t.src),backgroundImageWidth:o.backgroundImageWidth||(null===(i=o.background)||void 0===i||null===(n=i.image)||void 0===n?void 0:n.width),backgroundImageHeight:o.backgroundImageHeight||(null===(a=o.background)||void 0===a||null===(d=a.image)||void 0===d?void 0:d.height),backgroundImageX:o.backgroundImageX||(null===(u=o.background)||void 0===u||null===(s=u.image)||void 0===s?void 0:s.x),backgroundImageY:o.backgroundImageY||(null===(g=o.background)||void 0===g||null===(l=g.image)||void 0===l?void 0:l.y),backgroundImageAlpha:o.backgroundImageAlpha||(null===(h=o.background)||void 0===h||null===(c=h.image)||void 0===c?void 0:c.alpha),backgroundImageBorderRadius:o.backgroundImageBorderRadius||(null===(m=o.background)||void 0===m||null===(f=m.image)||void 0===f?void 0:f.borderRadius),backgroundPadding:o.backgroundPadding,foregroundColor:o.foregroundColor||(null===(v=o.foreground)||void 0===v?void 0:v.color),foregroundImageSrc:o.foregroundImageSrc||(null===(p=o.foreground)||void 0===p||null===(C=p.image)||void 0===C?void 0:C.src),foregroundImageWidth:o.foregroundImageWidth||(null===(b=o.foreground)||void 0===b||null===(k=b.image)||void 0===k?void 0:k.width),foregroundImageHeight:o.foregroundImageHeight||(null===(y=o.foreground)||void 0===y||null===(w=y.image)||void 0===w?void 0:w.height),foregroundImageX:o.foregroundImageX||(null===(I=o.foreground)||void 0===I||null===(B=I.image)||void 0===B?void 0:B.x),foregroundImageY:o.foregroundImageY||(null===(S=o.foreground)||void 0===S||null===(P=S.image)||void 0===P?void 0:P.y),foregroundImagePadding:o.foregroundImagePadding||(null===(L=o.foreground)||void 0===L||null===(D=L.image)||void 0===D?void 0:D.padding),foregroundImageBackgroundColor:o.foregroundImageBackgroundColor||(null===(A=o.foreground)||void 0===A||null===(E=A.image)||void 0===E?void 0:E.backgroundColor),foregroundImageBorderRadius:o.foregroundImageBorderRadius||(null===(T=o.foreground)||void 0===T||null===(N=T.image)||void 0===N?void 0:N.borderRadius),foregroundImageShadowOffsetX:o.foregroundImageShadowOffsetX||(null===(M=o.foreground)||void 0===M||null===(z=M.image)||void 0===z?void 0:z.shadowOffsetX),foregroundImageShadowOffsetY:o.foregroundImageShadowOffsetY||(null===(R=o.foreground)||void 0===R||null===(_=R.image)||void 0===_?void 0:_.shadowOffsetY),foregroundImageShadowBlur:o.foregroundImageShadowBlur||(null===(O=o.foreground)||void 0===O||null===(F=O.image)||void 0===F?void 0:F.shadowBlur),foregroundImageShadowColor:o.foregroundImageShadowColor||(null===(x=o.foreground)||void 0===x||null===(H=x.image)||void 0===H?void 0:H.shadowColor),foregroundPadding:o.foregroundPadding,positionProbeBackgroundColor:o.positionProbeBackgroundColor||(null===(X=o.positionProbe)||void 0===X?void 0:X.backgroundColor)||(null===(Y=o.positionDetection)||void 0===Y?void 0:Y.backgroundColor),positionProbeForegroundColor:o.positionProbeForegroundColor||(null===(j=o.positionProbe)||void 0===j?void 0:j.foregroundColor)||(null===(W=o.positionDetection)||void 0===W?void 0:W.foregroundColor),separatorColor:o.separatorColor||(null===(G=o.separator)||void 0===G?void 0:G.color),positionAdjustBackgroundColor:o.positionAdjustBackgroundColor||(null===(K=o.positionAdjust)||void 0===K?void 0:K.backgroundColor)||(null===(Q=o.alignment)||void 0===Q?void 0:Q.backgroundColor),positionAdjustForegroundColor:o.positionAdjustForegroundColor||(null===(U=o.positionAdjust)||void 0===U?void 0:U.foregroundColor)||(null===($=o.alignment)||void 0===$?void 0:$.foregroundColor),timingBackgroundColor:o.timingBackgroundColor||(null===(J=o.timing)||void 0===J?void 0:J.backgroundColor),timingForegroundColor:o.timingForegroundColor||(null===(q=o.timing)||void 0===q?void 0:q.foregroundColor),typeNumberBackgroundColor:o.typeNumberBackgroundColor||(null===(V=o.typeNumber)||void 0===V?void 0:V.backgroundColor)||(null===(Z=o.versionInformation)||void 0===Z?void 0:Z.backgroundColor),typeNumberForegroundColor:o.typeNumberForegroundColor||(null===(oo=o.typeNumber)||void 0===oo?void 0:oo.foregroundColor)||(null===(eo=o.versionInformation)||void 0===eo?void 0:eo.foregroundColor),darkBlockColor:o.darkBlockColor||(null===(ro=o.darkBlock)||void 0===ro?void 0:ro.color)},!0));},b.prototype.make=function(){let{foregroundColor:o,backgroundColor:r,typeNumber:t,errorCorrectLevel:i,data:n,size:a,margin:d,useDynamicSize:u}=this;if(o===r)throw console.error("[uQRCode]: foregroundColor and backgroundColor cannot be the same!"),new b.Error("foregroundColor and backgroundColor cannot be the same!");var s=new e(t,i);s.addData(function(o){o=o.toString();for(var e,r="",t=0;t<o.length;t++)(e=o.charCodeAt(t))>=1&&e<=127?r+=o.charAt(t):e>2047?(r+=String.fromCharCode(224|e>>12&15),r+=String.fromCharCode(128|e>>6&63),r+=String.fromCharCode(128|e>>0&63)):(r+=String.fromCharCode(192|e>>6&31),r+=String.fromCharCode(128|e>>0&63));return r}(n)),s.make(),this.base=s,this.typeNumber=s.typeNumber,this.modules=s.modules,this.moduleCount=s.moduleCount,this.dynamicSize=u?Math.ceil((a-2*d)/s.moduleCount)*s.moduleCount+2*d:a,function(o){let{dynamicSize:e,margin:r,backgroundColor:t,backgroundPadding:i,foregroundColor:n,foregroundPadding:a,modules:d,moduleCount:u}=o,s=(e-2*r)/u,g=s,l=0;i>0&&(l=g*i/2,g-=2*l);let h=s,c=0;a>0&&(c=h*a/2,h-=2*c);for(var m=0;m<u;m++)for(var f=0;f<u;f++){var v=f*s+r,p=m*s+r;if(d[m][f]){var C=c,b=v+c,k=p+c,y=h,w=h;d[m][f]={type:["foreground"],color:n,isBlack:!0,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}else C=l,b=v+l,k=p+l,y=g,w=g,d[m][f]={type:["background"],color:t,isBlack:!1,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}}(this),function(o){let{modules:e,moduleCount:r,positionProbeBackgroundColor:t,positionProbeForegroundColor:i}=o,n=r-7;[[0,0,1],[1,0,1],[2,0,1],[3,0,1],[4,0,1],[5,0,1],[6,0,1],[0,1,1],[1,1,0],[2,1,0],[3,1,0],[4,1,0],[5,1,0],[6,1,1],[0,2,1],[1,2,0],[2,2,1],[3,2,1],[4,2,1],[5,2,0],[6,2,1],[0,3,1],[1,3,0],[2,3,1],[3,3,1],[4,3,1],[5,3,0],[6,3,1],[0,4,1],[1,4,0],[2,4,1],[3,4,1],[4,4,1],[5,4,0],[6,4,1],[0,5,1],[1,5,0],[2,5,0],[3,5,0],[4,5,0],[5,5,0],[6,5,1],[0,6,1],[1,6,1],[2,6,1],[3,6,1],[4,6,1],[5,6,1],[6,6,1]].forEach((o=>{var r=e[o[0]][o[1]],a=e[o[0]+n][o[1]],d=e[o[0]][o[1]+n];d.type.push("positionProbe"),a.type.push("positionProbe"),r.type.push("positionProbe"),r.color=1==o[2]?i:t,a.color=1==o[2]?i:t,d.color=1==o[2]?i:t;}));}(this),function(o){let{modules:e,moduleCount:r,separatorColor:t}=o;[[7,0],[7,1],[7,2],[7,3],[7,4],[7,5],[7,6],[7,7],[0,7],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7]].forEach((o=>{var i=e[o[0]][o[1]],n=e[r-o[0]-1][o[1]],a=e[o[0]][r-o[1]-1];a.type.push("separator"),n.type.push("separator"),i.type.push("separator"),i.color=t,n.color=t,a.color=t;}));}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,foregroundColor:i,backgroundColor:n,positionAdjustForegroundColor:a,positionAdjustBackgroundColor:d,timingForegroundColor:u,timingBackgroundColor:s}=o;const g=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]][e-1];if(g){const o=[[-2,-2,1],[-1,-2,1],[0,-2,1],[1,-2,1],[2,-2,1],[-2,-1,1],[-1,-1,0],[0,-1,0],[1,-1,0],[2,-1,1],[-2,0,1],[-1,0,0],[0,0,1],[1,0,0],[2,0,1],[-2,1,1],[-1,1,0],[0,1,0],[1,1,0],[2,1,1],[-2,2,1],[-1,2,1],[0,2,1],[1,2,1],[2,2,1]],e=g.length;for(let l=0;l<e;l++)for(let h=0;h<e;h++){let{x:e,y:c}={x:g[l],y:g[h]};e<9&&c<9||e>t-9-1&&c<9||c>t-9-1&&e<9||o.forEach((o=>{var t=r[e+o[0]][c+o[1]];t.type.push("positionAdjust"),t.type.includes("timing")?1==o[2]?t.color=a==i?u:a:t.color=a==i&&d==n?s:d:t.color=1==o[2]?a:d;}));}}}(this),function(o){let{modules:e,moduleCount:r,timingForegroundColor:t,timingBackgroundColor:i}=o,n=r-16;for(let o=0;o<n;o++){var a=e[6][8+o],d=e[8+o][6];a.type.push("timing"),d.type.push("timing"),a.color=1&o^1?t:i,d.color=1&o^1?t:i;}}(this),function(o){let{modules:e,moduleCount:r,darkBlockColor:t}=o;var i=e[r-7-1][8];i.type.push("darkBlock"),i.color=t;}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,typeNumberBackgroundColor:i,typeNumberForegroundColor:n}=o;if(e<7)return r;const a=[0,0,0,0,0,0,0,"000111110010010100","001000010110111100","001001101010011001","001010010011010011","001011101111110110","001100011101100010","001101100001000111","001110011000001101","001111100100101000","010000101101111000","010001010001011101","010010101000010111","010011010100110010","010100100110100110","010101011010000011","010110100011001001","010111011111101100","011000111011000100","011001000111100001","011010111110101011","011011000010001110","011100110000011010","011101001100111111","011110110101110101","011111001001010000","100000100111010101","100001011011110000","100010100010111010","100011011110011111","100100101100001011","100101010000101110","100110101001100100","100111010101000001","101000110001101001"];let d=a[e]+a[e],u=[t-11,t-10,t-9];[[5,u[2]],[5,u[1]],[5,u[0]],[4,u[2]],[4,u[1]],[4,u[0]],[3,u[2]],[3,u[1]],[3,u[0]],[2,u[2]],[2,u[1]],[2,u[0]],[1,u[2]],[1,u[1]],[1,u[0]],[0,u[2]],[0,u[1]],[0,u[0]],[u[2],5],[u[1],5],[u[0],5],[u[2],4],[u[1],4],[u[0],4],[u[2],3],[u[1],3],[u[0],3],[u[2],2],[u[1],2],[u[0],2],[u[2],1],[u[1],1],[u[0],1],[u[2],0],[u[1],0],[u[0],0]].forEach(((o,e)=>{var t=r[o[0]][o[1]];t.type.push("typeNumber"),t.color="1"==d[e]?n:i;}));}(this),this.isMaked=!0,this.drawModules=[];},b.prototype.getDrawModules=function(){if(this.drawModules&&this.drawModules.length>0)return this.drawModules;let o=this.drawModules=[],{modules:e,moduleCount:r,dynamicSize:t,areaColor:i,backgroundImageSrc:n,backgroundImageX:a,backgroundImageY:d,backgroundImageWidth:u,backgroundImageHeight:s,backgroundImageAlpha:g,backgroundImageBorderRadius:l,foregroundImageSrc:h,foregroundImageX:c,foregroundImageY:m,foregroundImageWidth:f,foregroundImageHeight:v,foregroundImagePadding:p,foregroundImageBackgroundColor:C,foregroundImageBorderRadius:b,foregroundImageShadowOffsetX:k,foregroundImageShadowOffsetY:y,foregroundImageShadowBlur:w,foregroundImageShadowColor:I}=this;i&&o.push({name:"area",type:"area",color:i,x:0,y:0,width:t,height:t}),n&&o.push({name:"backgroundImage",type:"image",imageSrc:n,mappingName:"backgroundImageSrc",x:a,y:d,width:u,height:s,alpha:g,borderRadius:l});for(var B=0;B<r;B++)for(var S=0;S<r;S++){var P=e[B][S];P.isDrawn||(P.type.includes("foreground")?o.push({name:"foreground",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}):o.push({name:"background",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}),P.isDrawn=!0);}return h&&o.push({name:"foregroundImage",type:"image",imageSrc:h,mappingName:"foregroundImageSrc",x:c,y:m,width:f,height:v,padding:p,backgroundColor:C,borderRadius:b,shadowOffsetX:k,shadowOffsetY:y,shadowBlur:w,shadowColor:I}),o},b.prototype.isBlack=function(o,e){var r=this.moduleCount;return !(0>o||0>e||o>=r||e>=r)&&this.modules[o][e].isBlack},b.prototype.drawCanvas=function(){let{isMaked:o,canvasContext:e,useDynamicSize:r,dynamicSize:t,foregroundColor:i,foregroundPadding:n,backgroundColor:a,backgroundPadding:d,drawReserve:u,margin:s}=this;if(!o)return console.error("[uQRCode]: please execute the make method first!"),Promise.reject(new b.Error("please execute the make method first!"));let g=this.getDrawModules(),l=async(o,r)=>{try{e.clearRect(0,0,t,t),e.draw(!1);for(var i=0;i<g.length;i++){var n=g[i];switch(e.save(),n.type){case"area":e.setFillStyle(n.color),e.fillRect(n.x,n.y,n.width,n.height);break;case"tile":var a=n.x,d=n.y,s=n.width,l=n.height;e.setFillStyle(n.color),e.fillRect(a,d,s,l);break;case"image":if("backgroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2),e.setGlobalAlpha(n.alpha),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{var h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}else if("foregroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);var c,m=Math.round(n.padding);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2);var f=a-m,v=d-m,p=s+2*m,C=l+2*m,k=Math.round(p/s*c);p<2*k&&(k=p/2),C<2*k&&(k=C/2),e.save(),e.setShadow(n.shadowOffsetX,n.shadowOffsetY,n.shadowBlur,n.shadowColor),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(n.backgroundColor),e.fill()):(e.setFillStyle(n.backgroundColor),e.fillRect(f,v,p,C)),e.restore(),e.save(),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fill()):(e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fillRect(f,v,p,C)),e.restore(),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}}u&&e.draw(!0),e.restore();}e.draw(!0),setTimeout(o,150);}catch(o){if(!(o instanceof b.Error))throw o;r(o);}};return new Promise(((o,e)=>{l(o,e);}))},b.prototype.draw=function(){return this.drawCanvas()},b.prototype.register=function(o){o&&o(b,this,!0);};export{b as default};
uni_modules/Sansnn-uQRCode/package.json
New file
@@ -0,0 +1,79 @@
{
  "id": "Sansnn-uQRCode",
  "displayName": "uQRCode 全端二维码生成插件 支持nvue 支持nodejs服务端",
  "version": "4.0.6",
  "description": "uQRCode是一款基于Javascript环境开发的二维码生成插件,适用所有Javascript运行环境的前端应用和Node.js。",
  "keywords": [
    "二维码",
    "uQRCode",
    "qrcode",
    "qr"
],
  "repository": "https://github.com/Sansnn/uQRCode",
"engines": {
  },
"dcloudext": {
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": ""
    },
    "declaration": {
      "ads": "无",
      "data": "无",
      "permissions": "无"
    },
    "npmurl": "https://www.npmjs.com/package/uqrcodejs",
    "type": "sdk-js"
  },
  "uni_modules": {
    "dependencies": [],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "App": {
          "app-vue": "y",
          "app-nvue": "y"
        },
        "H5-mobile": {
          "Safari": "y",
          "Android Browser": "y",
          "微信浏览器(Android)": "y",
          "QQ浏览器(Android)": "y"
        },
        "H5-pc": {
          "Chrome": "y",
          "IE": "y",
          "Edge": "y",
          "Firefox": "y",
          "Safari": "y"
        },
        "小程序": {
          "微信": "y",
          "阿里": "y",
          "百度": "y",
          "字节跳动": "y",
          "QQ": "y"
        },
        "快应用": {
          "华为": "y",
          "联盟": "y"
        },
        "Vue": {
          "vue2": "y",
          "vue3": "y"
        }
      }
    }
  }
}