diff --git a/src/components/yan-qr/qrcode.js b/src/components/yan-qr/qrcode.js
new file mode 100644
index 0000000..95505dd
--- /dev/null
+++ b/src/components/yan-qr/qrcode.js
@@ -0,0 +1,1404 @@
+let uQRCode = {};
+(function() {
+ function QR8bitByte(data) {
+ this.mode = QRMode.MODE_8BIT_BYTE;
+ this.data = data;
+ }
+ QR8bitByte.prototype = {
+
+ getLength: function(buffer) {
+ return this.data.length;
+ },
+
+ write: function(buffer) {
+ for (var i = 0; i < this.data.length; i++) {
+ // not JIS …
+ buffer.put(this.data.charCodeAt(i), 8);
+ }
+ }
+ };
+ function QRCode(typeNumber, errorCorrectLevel) {
+ this.typeNumber = typeNumber;
+ this.errorCorrectLevel = errorCorrectLevel;
+ this.modules = null;
+ this.moduleCount = 0;
+ this.dataCache = null;
+ this.dataList = new Array();
+ }
+
+ QRCode.prototype = {
+
+ addData: function(data) {
+ var newData = new QR8bitByte(data);
+ this.dataList.push(newData);
+ this.dataCache = null;
+ },
+
+ isDark: function(row, col) {
+ if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
+ throw new Error(row + "," + col);
+ }
+ return this.modules[row][col];
+ },
+
+ getModuleCount: function() {
+ return this.moduleCount;
+ },
+
+ make: function() {
+ if (this.typeNumber < 1) {
+ var typeNumber = 1;
+ for (typeNumber = 1; typeNumber < 40; typeNumber++) {
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
+
+ var buffer = new QRBitBuffer();
+ var totalDataCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalDataCount += rsBlocks[i].dataCount;
+ }
+
+ for (var i = 0; i < this.dataList.length; i++) {
+ var data = this.dataList[i];
+ buffer.put(data.mode, 4);
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+ data.write(buffer);
+ }
+ if (buffer.getLengthInBits() <= totalDataCount * 8)
+ break;
+ }
+ this.typeNumber = typeNumber;
+ }
+ this.makeImpl(false, this.getBestMaskPattern());
+ },
+
+ makeImpl: function(test, maskPattern) {
+
+ this.moduleCount = this.typeNumber * 4 + 17;
+ this.modules = new Array(this.moduleCount);
+
+ for (var row = 0; row < this.moduleCount; row++) {
+
+ this.modules[row] = new Array(this.moduleCount);
+
+ for (var col = 0; col < this.moduleCount; col++) {
+ this.modules[row][col] = null; //(col + row) % 3;
+ }
+ }
+
+ this.setupPositionProbePattern(0, 0);
+ this.setupPositionProbePattern(this.moduleCount - 7, 0);
+ this.setupPositionProbePattern(0, this.moduleCount - 7);
+ this.setupPositionAdjustPattern();
+ this.setupTimingPattern();
+ this.setupTypeInfo(test, maskPattern);
+
+ if (this.typeNumber >= 7) {
+ this.setupTypeNumber(test);
+ }
+
+ if (this.dataCache == null) {
+ this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
+ }
+
+ this.mapData(this.dataCache, maskPattern);
+ },
+
+ setupPositionProbePattern: function(row, col) {
+
+ for (var r = -1; r <= 7; r++) {
+
+ if (row + r <= -1 || this.moduleCount <= row + r) continue;
+
+ for (var c = -1; c <= 7; c++) {
+
+ if (col + c <= -1 || this.moduleCount <= col + c) continue;
+
+ if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
+ (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
+ (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
+ this.modules[row + r][col + c] = true;
+ } else {
+ this.modules[row + r][col + c] = false;
+ }
+ }
+ }
+ },
+
+ getBestMaskPattern: function() {
+
+ var minLostPoint = 0;
+ var pattern = 0;
+
+ for (var i = 0; i < 8; i++) {
+
+ this.makeImpl(true, i);
+
+ var lostPoint = QRUtil.getLostPoint(this);
+
+ if (i == 0 || minLostPoint > lostPoint) {
+ minLostPoint = lostPoint;
+ pattern = i;
+ }
+ }
+
+ return pattern;
+ },
+
+ createMovieClip: function(target_mc, instance_name, depth) {
+
+ var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
+ var cs = 1;
+
+ this.make();
+
+ for (var row = 0; row < this.modules.length; row++) {
+
+ var y = row * cs;
+
+ for (var col = 0; col < this.modules[row].length; col++) {
+
+ var x = col * cs;
+ var dark = this.modules[row][col];
+
+ if (dark) {
+ qr_mc.beginFill(0, 100);
+ qr_mc.moveTo(x, y);
+ qr_mc.lineTo(x + cs, y);
+ qr_mc.lineTo(x + cs, y + cs);
+ qr_mc.lineTo(x, y + cs);
+ qr_mc.endFill();
+ }
+ }
+ }
+
+ return qr_mc;
+ },
+
+ setupTimingPattern: function() {
+
+ for (var r = 8; r < this.moduleCount - 8; r++) {
+ if (this.modules[r][6] != null) {
+ continue;
+ }
+ this.modules[r][6] = (r % 2 == 0);
+ }
+
+ for (var c = 8; c < this.moduleCount - 8; c++) {
+ if (this.modules[6][c] != null) {
+ continue;
+ }
+ this.modules[6][c] = (c % 2 == 0);
+ }
+ },
+
+ setupPositionAdjustPattern: function() {
+
+ var pos = QRUtil.getPatternPosition(this.typeNumber);
+
+ for (var i = 0; i < pos.length; i++) {
+
+ for (var j = 0; j < pos.length; j++) {
+
+ var row = pos[i];
+ var col = pos[j];
+
+ if (this.modules[row][col] != null) {
+ continue;
+ }
+
+ for (var r = -2; r <= 2; r++) {
+
+ for (var c = -2; c <= 2; c++) {
+
+ if (r == -2 || r == 2 || c == -2 || c == 2 ||
+ (r == 0 && c == 0)) {
+ this.modules[row + r][col + c] = true;
+ } else {
+ this.modules[row + r][col + c] = false;
+ }
+ }
+ }
+ }
+ }
+ },
+
+ setupTypeNumber: function(test) {
+
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+
+ for (var i = 0; i < 18; i++) {
+ var mod = (!test && ((bits >> i) & 1) == 1);
+ this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
+ }
+
+ for (var i = 0; i < 18; i++) {
+ var mod = (!test && ((bits >> i) & 1) == 1);
+ this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+ }
+ },
+
+ setupTypeInfo: function(test, maskPattern) {
+
+ var data = (this.errorCorrectLevel << 3) | maskPattern;
+ var bits = QRUtil.getBCHTypeInfo(data);
+
+ // vertical
+ for (var i = 0; i < 15; i++) {
+
+ var mod = (!test && ((bits >> i) & 1) == 1);
+
+ if (i < 6) {
+ this.modules[i][8] = mod;
+ } else if (i < 8) {
+ this.modules[i + 1][8] = mod;
+ } else {
+ this.modules[this.moduleCount - 15 + i][8] = mod;
+ }
+ }
+
+ // horizontal
+ for (var i = 0; i < 15; i++) {
+
+ var mod = (!test && ((bits >> i) & 1) == 1);
+
+ if (i < 8) {
+ this.modules[8][this.moduleCount - i - 1] = mod;
+ } else if (i < 9) {
+ this.modules[8][15 - i - 1 + 1] = mod;
+ } else {
+ this.modules[8][15 - i - 1] = mod;
+ }
+ }
+
+ // fixed module
+ this.modules[this.moduleCount - 8][8] = (!test);
+
+ },
+
+ mapData: function(data, maskPattern) {
+
+ var inc = -1;
+ var row = this.moduleCount - 1;
+ var bitIndex = 7;
+ var byteIndex = 0;
+
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+
+ if (col == 6) col--;
+
+ while (true) {
+
+ for (var c = 0; c < 2; c++) {
+
+ if (this.modules[row][col - c] == null) {
+
+ var dark = false;
+
+ if (byteIndex < data.length) {
+ dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
+ }
+
+ var mask = QRUtil.getMask(maskPattern, row, col - c);
+
+ if (mask) {
+ dark = !dark;
+ }
+
+ this.modules[row][col - c] = dark;
+ bitIndex--;
+
+ if (bitIndex == -1) {
+ byteIndex++;
+ bitIndex = 7;
+ }
+ }
+ }
+
+ row += inc;
+
+ if (row < 0 || this.moduleCount <= row) {
+ row -= inc;
+ inc = -inc;
+ break;
+ }
+ }
+ }
+
+ }
+
+ };
+
+ QRCode.PAD0 = 0xEC;
+ QRCode.PAD1 = 0x11;
+
+ QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
+
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
+
+ var buffer = new QRBitBuffer();
+
+ for (var i = 0; i < dataList.length; i++) {
+ var data = dataList[i];
+ buffer.put(data.mode, 4);
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+ data.write(buffer);
+ }
+
+ // calc num max data.
+ var totalDataCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalDataCount += rsBlocks[i].dataCount;
+ }
+
+ if (buffer.getLengthInBits() > totalDataCount * 8) {
+ throw new Error("code length overflow. (" +
+ buffer.getLengthInBits() +
+ ">" +
+ totalDataCount * 8 +
+ ")");
+ }
+
+ // end code
+ if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
+ buffer.put(0, 4);
+ }
+
+ // padding
+ while (buffer.getLengthInBits() % 8 != 0) {
+ buffer.putBit(false);
+ }
+
+ // padding
+ while (true) {
+
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
+ break;
+ }
+ buffer.put(QRCode.PAD0, 8);
+
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
+ break;
+ }
+ buffer.put(QRCode.PAD1, 8);
+ }
+
+ return QRCode.createBytes(buffer, rsBlocks);
+ }
+
+ QRCode.createBytes = function(buffer, rsBlocks) {
+
+ var offset = 0;
+
+ var maxDcCount = 0;
+ var maxEcCount = 0;
+
+ var dcdata = new Array(rsBlocks.length);
+ var ecdata = new Array(rsBlocks.length);
+
+ for (var r = 0; r < rsBlocks.length; r++) {
+
+ var dcCount = rsBlocks[r].dataCount;
+ var ecCount = rsBlocks[r].totalCount - dcCount;
+
+ maxDcCount = Math.max(maxDcCount, dcCount);
+ maxEcCount = Math.max(maxEcCount, ecCount);
+
+ dcdata[r] = new Array(dcCount);
+
+ for (var i = 0; i < dcdata[r].length; i++) {
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+ }
+ offset += dcCount;
+
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+
+ var modPoly = rawPoly.mod(rsPoly);
+ ecdata[r] = new Array(rsPoly.getLength() - 1);
+ for (var i = 0; i < ecdata[r].length; i++) {
+ var modIndex = i + modPoly.getLength() - ecdata[r].length;
+ ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
+ }
+
+ }
+
+ var totalCodeCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalCodeCount += rsBlocks[i].totalCount;
+ }
+
+ var data = new Array(totalCodeCount);
+ var index = 0;
+
+ for (var i = 0; i < maxDcCount; i++) {
+ for (var r = 0; r < rsBlocks.length; r++) {
+ if (i < dcdata[r].length) {
+ data[index++] = dcdata[r][i];
+ }
+ }
+ }
+
+ for (var i = 0; i < maxEcCount; i++) {
+ for (var r = 0; r < rsBlocks.length; r++) {
+ if (i < ecdata[r].length) {
+ data[index++] = ecdata[r][i];
+ }
+ }
+ }
+
+ return data;
+
+ }
+
+ //———————————————————————
+ // QRMode
+ //———————————————————————
+
+ var QRMode = {
+ MODE_NUMBER: 1 << 0,
+ MODE_ALPHA_NUM: 1 << 1,
+ MODE_8BIT_BYTE: 1 << 2,
+ MODE_KANJI: 1 << 3
+ };
+
+ //———————————————————————
+ // QRErrorCorrectLevel
+ //———————————————————————
+
+ var QRErrorCorrectLevel = {
+ L: 1,
+ M: 0,
+ Q: 3,
+ H: 2
+ };
+
+ //———————————————————————
+ // QRMaskPattern
+ //———————————————————————
+
+ var QRMaskPattern = {
+ PATTERN000: 0,
+ PATTERN001: 1,
+ PATTERN010: 2,
+ PATTERN011: 3,
+ PATTERN100: 4,
+ PATTERN101: 5,
+ PATTERN110: 6,
+ PATTERN111: 7
+ };
+
+ //———————————————————————
+ // QRUtil
+ //———————————————————————
+
+ var QRUtil = {
+
+ 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: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+ G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+
+ getBCHTypeInfo: function(data) {
+ var d = data << 10;
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+ d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
+ }
+ return ((data << 10) | d) ^ QRUtil.G15_MASK;
+ },
+
+ getBCHTypeNumber: function(data) {
+ var d = data << 12;
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+ d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
+ }
+ return (data << 12) | d;
+ },
+
+ getBCHDigit: function(data) {
+
+ var digit = 0;
+
+ while (data != 0) {
+ digit++;
+ data >>>= 1;
+ }
+
+ return digit;
+ },
+
+ getPatternPosition: function(typeNumber) {
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
+ },
+
+ getMask: function(maskPattern, i, j) {
+
+ switch (maskPattern) {
+
+ case QRMaskPattern.PATTERN000:
+ return (i + j) % 2 == 0;
+ case QRMaskPattern.PATTERN001:
+ return i % 2 == 0;
+ case QRMaskPattern.PATTERN010:
+ return j % 3 == 0;
+ case QRMaskPattern.PATTERN011:
+ return (i + j) % 3 == 0;
+ case QRMaskPattern.PATTERN100:
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
+ case QRMaskPattern.PATTERN101:
+ return (i * j) % 2 + (i * j) % 3 == 0;
+ case QRMaskPattern.PATTERN110:
+ return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
+ case QRMaskPattern.PATTERN111:
+ return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
+
+ default:
+ throw new Error("bad maskPattern:" + maskPattern);
+ }
+ },
+
+ getErrorCorrectPolynomial: function(errorCorrectLength) {
+
+ var a = new QRPolynomial([1], 0);
+
+ for (var i = 0; i < errorCorrectLength; i++) {
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+ }
+
+ return a;
+ },
+
+ getLengthInBits: function(mode, type) {
+
+ if (1 <= type && type < 10) {
+
+ // 1 - 9
+
+ switch (mode) {
+ case QRMode.MODE_NUMBER:
+ return 10;
+ case QRMode.MODE_ALPHA_NUM:
+ return 9;
+ case QRMode.MODE_8BIT_BYTE:
+ return 8;
+ case QRMode.MODE_KANJI:
+ return 8;
+ default:
+ throw new Error("mode:" + mode);
+ }
+
+ } else if (type < 27) {
+
+ // 10 - 26
+
+ switch (mode) {
+ case QRMode.MODE_NUMBER:
+ return 12;
+ case QRMode.MODE_ALPHA_NUM:
+ return 11;
+ case QRMode.MODE_8BIT_BYTE:
+ return 16;
+ case QRMode.MODE_KANJI:
+ return 10;
+ default:
+ throw new Error("mode:" + mode);
+ }
+
+ } else if (type < 41) {
+
+ // 27 - 40
+
+ switch (mode) {
+ case QRMode.MODE_NUMBER:
+ return 14;
+ case QRMode.MODE_ALPHA_NUM:
+ return 13;
+ case QRMode.MODE_8BIT_BYTE:
+ return 16;
+ case QRMode.MODE_KANJI:
+ return 12;
+ default:
+ throw new Error("mode:" + mode);
+ }
+
+ } else {
+ throw new Error("type:" + type);
+ }
+ },
+
+ getLostPoint: function(qrCode) {
+
+ var moduleCount = qrCode.getModuleCount();
+
+ var lostPoint = 0;
+
+ // LEVEL1
+
+ for (var row = 0; row < moduleCount; row++) {
+
+ for (var col = 0; col < moduleCount; col++) {
+
+ var sameCount = 0;
+ var dark = qrCode.isDark(row, col);
+
+ for (var r = -1; r <= 1; r++) {
+
+ if (row + r < 0 || moduleCount <= row + r) {
+ continue;
+ }
+
+ for (var c = -1; c <= 1; c++) {
+
+ if (col + c < 0 || moduleCount <= col + c) {
+ continue;
+ }
+
+ if (r == 0 && c == 0) {
+ continue;
+ }
+
+ if (dark == qrCode.isDark(row + r, col + c)) {
+ sameCount++;
+ }
+ }
+ }
+
+ if (sameCount > 5) {
+ lostPoint += (3 + sameCount - 5);
+ }
+ }
+ }
+
+ // LEVEL2
+
+ for (var row = 0; row < moduleCount - 1; row++) {
+ for (var col = 0; col < moduleCount - 1; col++) {
+ var count = 0;
+ if (qrCode.isDark(row, col)) count++;
+ if (qrCode.isDark(row + 1, col)) count++;
+ if (qrCode.isDark(row, col + 1)) count++;
+ if (qrCode.isDark(row + 1, col + 1)) count++;
+ if (count == 0 || count == 4) {
+ lostPoint += 3;
+ }
+ }
+ }
+
+ // LEVEL3
+
+ for (var row = 0; row < moduleCount; row++) {
+ for (var col = 0; col < moduleCount - 6; col++) {
+ if (qrCode.isDark(row, col) &&
+ !qrCode.isDark(row, col + 1) &&
+ qrCode.isDark(row, col + 2) &&
+ qrCode.isDark(row, col + 3) &&
+ qrCode.isDark(row, col + 4) &&
+ !qrCode.isDark(row, col + 5) &&
+ qrCode.isDark(row, col + 6)) {
+ lostPoint += 40;
+ }
+ }
+ }
+
+ for (var col = 0; col < moduleCount; col++) {
+ for (var row = 0; row < moduleCount - 6; row++) {
+ if (qrCode.isDark(row, col) &&
+ !qrCode.isDark(row + 1, col) &&
+ qrCode.isDark(row + 2, col) &&
+ qrCode.isDark(row + 3, col) &&
+ qrCode.isDark(row + 4, col) &&
+ !qrCode.isDark(row + 5, col) &&
+ qrCode.isDark(row + 6, col)) {
+ lostPoint += 40;
+ }
+ }
+ }
+
+ // LEVEL4
+
+ var darkCount = 0;
+
+ for (var col = 0; col < moduleCount; col++) {
+ for (var row = 0; row < moduleCount; row++) {
+ if (qrCode.isDark(row, col)) {
+ darkCount++;
+ }
+ }
+ }
+
+ var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
+ lostPoint += ratio * 10;
+
+ return lostPoint;
+ }
+
+ };
+
+ //———————————————————————
+ // QRMath
+ //———————————————————————
+
+ var QRMath = {
+
+ glog: function(n) {
+
+ if (n < 1) {
+ throw new Error("glog(" + n + ")");
+ }
+
+ return QRMath.LOG_TABLE[n];
+ },
+
+ gexp: function(n) {
+
+ while (n < 0) {
+ n += 255;
+ }
+
+ while (n >= 256) {
+ n -= 255;
+ }
+
+ return QRMath.EXP_TABLE[n];
+ },
+
+ EXP_TABLE: new Array(256),
+
+ LOG_TABLE: new Array(256)
+
+ };
+
+ for (var i = 0; i < 8; i++) {
+ QRMath.EXP_TABLE[i] = 1 << i;
+ }
+ for (var i = 8; i < 256; i++) {
+ QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
+ QRMath.EXP_TABLE[i - 5] ^
+ QRMath.EXP_TABLE[i - 6] ^
+ QRMath.EXP_TABLE[i - 8];
+ }
+ for (var i = 0; i < 255; i++) {
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+ }
+
+ //———————————————————————
+ // QRPolynomial
+ //———————————————————————
+
+ function QRPolynomial(num, shift) {
+
+ if (num.length == undefined) {
+ throw new Error(num.length + "/" + shift);
+ }
+
+ var offset = 0;
+
+ while (offset < num.length && num[offset] == 0) {
+ offset++;
+ }
+
+ this.num = new Array(num.length - offset + shift);
+ for (var i = 0; i < num.length - offset; i++) {
+ this.num[i] = num[i + offset];
+ }
+ }
+
+ QRPolynomial.prototype = {
+
+ get: function(index) {
+ return this.num[index];
+ },
+
+ getLength: function() {
+ return this.num.length;
+ },
+
+ multiply: function(e) {
+
+ var num = new Array(this.getLength() + e.getLength() - 1);
+
+ for (var i = 0; i < this.getLength(); i++) {
+ for (var j = 0; j < e.getLength(); j++) {
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+ }
+ }
+
+ return new QRPolynomial(num, 0);
+ },
+
+ mod: function(e) {
+
+ if (this.getLength() - e.getLength() < 0) {
+ return this;
+ }
+
+ var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
+
+ var num = new Array(this.getLength());
+
+ for (var i = 0; i < this.getLength(); i++) {
+ num[i] = this.get(i);
+ }
+
+ for (var i = 0; i < e.getLength(); i++) {
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+ }
+
+ // recursive call
+ return new QRPolynomial(num, 0).mod(e);
+ }
+ };
+
+ //———————————————————————
+ // QRRSBlock
+ //———————————————————————
+
+ function QRRSBlock(totalCount, dataCount) {
+ this.totalCount = totalCount;
+ this.dataCount = dataCount;
+ }
+
+ QRRSBlock.RS_BLOCK_TABLE = [
+
+ // L
+ // M
+ // Q
+ // H
+
+ // 1
+ [1, 26, 19],
+ [1, 26, 16],
+ [1, 26, 13],
+ [1, 26, 9],
+
+ // 2
+ [1, 44, 34],
+ [1, 44, 28],
+ [1, 44, 22],
+ [1, 44, 16],
+
+ // 3
+ [1, 70, 55],
+ [1, 70, 44],
+ [2, 35, 17],
+ [2, 35, 13],
+
+ // 4
+ [1, 100, 80],
+ [2, 50, 32],
+ [2, 50, 24],
+ [4, 25, 9],
+
+ // 5
+ [1, 134, 108],
+ [2, 67, 43],
+ [2, 33, 15, 2, 34, 16],
+ [2, 33, 11, 2, 34, 12],
+
+ // 6
+ [2, 86, 68],
+ [4, 43, 27],
+ [4, 43, 19],
+ [4, 43, 15],
+
+ // 7
+ [2, 98, 78],
+ [4, 49, 31],
+ [2, 32, 14, 4, 33, 15],
+ [4, 39, 13, 1, 40, 14],
+
+ // 8
+ [2, 121, 97],
+ [2, 60, 38, 2, 61, 39],
+ [4, 40, 18, 2, 41, 19],
+ [4, 40, 14, 2, 41, 15],
+
+ // 9
+ [2, 146, 116],
+ [3, 58, 36, 2, 59, 37],
+ [4, 36, 16, 4, 37, 17],
+ [4, 36, 12, 4, 37, 13],
+
+ // 10
+ [2, 86, 68, 2, 87, 69],
+ [4, 69, 43, 1, 70, 44],
+ [6, 43, 19, 2, 44, 20],
+ [6, 43, 15, 2, 44, 16],
+
+ // 11
+ [4, 101, 81],
+ [1, 80, 50, 4, 81, 51],
+ [4, 50, 22, 4, 51, 23],
+ [3, 36, 12, 8, 37, 13],
+
+ // 12
+ [2, 116, 92, 2, 117, 93],
+ [6, 58, 36, 2, 59, 37],
+ [4, 46, 20, 6, 47, 21],
+ [7, 42, 14, 4, 43, 15],
+
+ // 13
+ [4, 133, 107],
+ [8, 59, 37, 1, 60, 38],
+ [8, 44, 20, 4, 45, 21],
+ [12, 33, 11, 4, 34, 12],
+
+ // 14
+ [3, 145, 115, 1, 146, 116],
+ [4, 64, 40, 5, 65, 41],
+ [11, 36, 16, 5, 37, 17],
+ [11, 36, 12, 5, 37, 13],
+
+ // 15
+ [5, 109, 87, 1, 110, 88],
+ [5, 65, 41, 5, 66, 42],
+ [5, 54, 24, 7, 55, 25],
+ [11, 36, 12],
+
+ // 16
+ [5, 122, 98, 1, 123, 99],
+ [7, 73, 45, 3, 74, 46],
+ [15, 43, 19, 2, 44, 20],
+ [3, 45, 15, 13, 46, 16],
+
+ // 17
+ [1, 135, 107, 5, 136, 108],
+ [10, 74, 46, 1, 75, 47],
+ [1, 50, 22, 15, 51, 23],
+ [2, 42, 14, 17, 43, 15],
+
+ // 18
+ [5, 150, 120, 1, 151, 121],
+ [9, 69, 43, 4, 70, 44],
+ [17, 50, 22, 1, 51, 23],
+ [2, 42, 14, 19, 43, 15],
+
+ // 19
+ [3, 141, 113, 4, 142, 114],
+ [3, 70, 44, 11, 71, 45],
+ [17, 47, 21, 4, 48, 22],
+ [9, 39, 13, 16, 40, 14],
+
+ // 20
+ [3, 135, 107, 5, 136, 108],
+ [3, 67, 41, 13, 68, 42],
+ [15, 54, 24, 5, 55, 25],
+ [15, 43, 15, 10, 44, 16],
+
+ // 21
+ [4, 144, 116, 4, 145, 117],
+ [17, 68, 42],
+ [17, 50, 22, 6, 51, 23],
+ [19, 46, 16, 6, 47, 17],
+
+ // 22
+ [2, 139, 111, 7, 140, 112],
+ [17, 74, 46],
+ [7, 54, 24, 16, 55, 25],
+ [34, 37, 13],
+
+ // 23
+ [4, 151, 121, 5, 152, 122],
+ [4, 75, 47, 14, 76, 48],
+ [11, 54, 24, 14, 55, 25],
+ [16, 45, 15, 14, 46, 16],
+
+ // 24
+ [6, 147, 117, 4, 148, 118],
+ [6, 73, 45, 14, 74, 46],
+ [11, 54, 24, 16, 55, 25],
+ [30, 46, 16, 2, 47, 17],
+
+ // 25
+ [8, 132, 106, 4, 133, 107],
+ [8, 75, 47, 13, 76, 48],
+ [7, 54, 24, 22, 55, 25],
+ [22, 45, 15, 13, 46, 16],
+
+ // 26
+ [10, 142, 114, 2, 143, 115],
+ [19, 74, 46, 4, 75, 47],
+ [28, 50, 22, 6, 51, 23],
+ [33, 46, 16, 4, 47, 17],
+
+ // 27
+ [8, 152, 122, 4, 153, 123],
+ [22, 73, 45, 3, 74, 46],
+ [8, 53, 23, 26, 54, 24],
+ [12, 45, 15, 28, 46, 16],
+
+ // 28
+ [3, 147, 117, 10, 148, 118],
+ [3, 73, 45, 23, 74, 46],
+ [4, 54, 24, 31, 55, 25],
+ [11, 45, 15, 31, 46, 16],
+
+ // 29
+ [7, 146, 116, 7, 147, 117],
+ [21, 73, 45, 7, 74, 46],
+ [1, 53, 23, 37, 54, 24],
+ [19, 45, 15, 26, 46, 16],
+
+ // 30
+ [5, 145, 115, 10, 146, 116],
+ [19, 75, 47, 10, 76, 48],
+ [15, 54, 24, 25, 55, 25],
+ [23, 45, 15, 25, 46, 16],
+
+ // 31
+ [13, 145, 115, 3, 146, 116],
+ [2, 74, 46, 29, 75, 47],
+ [42, 54, 24, 1, 55, 25],
+ [23, 45, 15, 28, 46, 16],
+
+ // 32
+ [17, 145, 115],
+ [10, 74, 46, 23, 75, 47],
+ [10, 54, 24, 35, 55, 25],
+ [19, 45, 15, 35, 46, 16],
+
+ // 33
+ [17, 145, 115, 1, 146, 116],
+ [14, 74, 46, 21, 75, 47],
+ [29, 54, 24, 19, 55, 25],
+ [11, 45, 15, 46, 46, 16],
+
+ // 34
+ [13, 145, 115, 6, 146, 116],
+ [14, 74, 46, 23, 75, 47],
+ [44, 54, 24, 7, 55, 25],
+ [59, 46, 16, 1, 47, 17],
+
+ // 35
+ [12, 151, 121, 7, 152, 122],
+ [12, 75, 47, 26, 76, 48],
+ [39, 54, 24, 14, 55, 25],
+ [22, 45, 15, 41, 46, 16],
+
+ // 36
+ [6, 151, 121, 14, 152, 122],
+ [6, 75, 47, 34, 76, 48],
+ [46, 54, 24, 10, 55, 25],
+ [2, 45, 15, 64, 46, 16],
+
+ // 37
+ [17, 152, 122, 4, 153, 123],
+ [29, 74, 46, 14, 75, 47],
+ [49, 54, 24, 10, 55, 25],
+ [24, 45, 15, 46, 46, 16],
+
+ // 38
+ [4, 152, 122, 18, 153, 123],
+ [13, 74, 46, 32, 75, 47],
+ [48, 54, 24, 14, 55, 25],
+ [42, 45, 15, 32, 46, 16],
+
+ // 39
+ [20, 147, 117, 4, 148, 118],
+ [40, 75, 47, 7, 76, 48],
+ [43, 54, 24, 22, 55, 25],
+ [10, 45, 15, 67, 46, 16],
+
+ // 40
+ [19, 148, 118, 6, 149, 119],
+ [18, 75, 47, 31, 76, 48],
+ [34, 54, 24, 34, 55, 25],
+ [20, 45, 15, 61, 46, 16]
+ ];
+
+ QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
+
+ var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
+
+ if (rsBlock == undefined) {
+ throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
+ }
+
+ var length = rsBlock.length / 3;
+
+ var list = new Array();
+
+ for (var i = 0; i < length; i++) {
+
+ var count = rsBlock[i * 3 + 0];
+ var totalCount = rsBlock[i * 3 + 1];
+ var dataCount = rsBlock[i * 3 + 2];
+
+ for (var j = 0; j < count; j++) {
+ list.push(new QRRSBlock(totalCount, dataCount));
+ }
+ }
+
+ return list;
+ }
+
+ QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
+
+ switch (errorCorrectLevel) {
+ case QRErrorCorrectLevel.L:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
+ case QRErrorCorrectLevel.M:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
+ case QRErrorCorrectLevel.Q:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
+ case QRErrorCorrectLevel.H:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
+ default:
+ return undefined;
+ }
+ }
+
+ //———————————————————————
+ // QRBitBuffer
+ //———————————————————————
+
+ function QRBitBuffer() {
+ this.buffer = new Array();
+ this.length = 0;
+ }
+
+ QRBitBuffer.prototype = {
+
+ get: function(index) {
+ var bufIndex = Math.floor(index / 8);
+ return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
+ },
+
+ put: function(num, length) {
+ for (var i = 0; i < length; i++) {
+ this.putBit(((num >>> (length - i - 1)) & 1) == 1);
+ }
+ },
+
+ getLengthInBits: function() {
+ return this.length;
+ },
+
+ putBit: function(bit) {
+
+ var bufIndex = Math.floor(this.length / 8);
+ if (this.buffer.length <= bufIndex) {
+ this.buffer.push(0);
+ }
+
+ if (bit) {
+ this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
+ }
+
+ this.length++;
+ }
+ };
+
+ //———————————————————————
+ // Support Chinese
+ //———————————————————————
+ function utf16To8(text) {
+ var result = '';
+ var c;
+ for (var i = 0; i < text.length; i++) {
+ c = text.charCodeAt(i);
+ if (c >= 0x0001 && c <= 0x007F) {
+ result += text.charAt(i);
+ } else if (c > 0x07FF) {
+ result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
+ result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
+ result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+ } else {
+ result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
+ result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+ }
+ }
+ return result;
+ }
+
+ uQRCode = {
+
+ errorCorrectLevel: QRErrorCorrectLevel,
+
+ defaults: {
+ size: 354,
+ margin: 0,
+ backgroundColor: '#ffffff',
+ foregroundColor: '#000000',
+ fileType: 'png', // 'jpg', 'png'
+ errorCorrectLevel: QRErrorCorrectLevel.H,
+ typeNumber: -1
+ },
+
+ make: function(options) {
+ return new Promise((reslove, reject) => {
+ var defaultOptions = {
+ canvasId: options.canvasId,
+ componentInstance: options.componentInstance,
+ text: options.text,
+ size: this.defaults.size,
+ margin: this.defaults.margin,
+ backgroundColor: this.defaults.backgroundColor,
+ foregroundColor: this.defaults.foregroundColor,
+ fileType: this.defaults.fileType,
+ errorCorrectLevel: this.defaults.errorCorrectLevel,
+ typeNumber: this.defaults.typeNumber
+ };
+ if (options) {
+ for (var i in options) {
+ defaultOptions[i] = options[i];
+ }
+ }
+ options = defaultOptions;
+ if (!options.canvasId) {
+ console.error('uQRCode: Please set canvasId!');
+ return;
+ }
+
+ function createCanvas() {
+ var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
+ qrcode.addData(utf16To8(options.text));
+ qrcode.make();
+
+ var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
+ ctx.setFillStyle(options.backgroundColor);
+ ctx.fillRect(0, 0, options.size, options.size);
+
+ var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
+ var tileH = tileW;
+
+ for (var row = 0; row < qrcode.getModuleCount(); row++) {
+ for (var col = 0; col < qrcode.getModuleCount(); col++) {
+ var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
+ ctx.setFillStyle(style);
+ var x = Math.round(col * tileW) + options.margin;
+ var y = Math.round(row * tileH) + options.margin;
+ var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
+ var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
+ ctx.fillRect(x, y, w, h);
+ }
+ }
+
+ setTimeout(function() {
+ ctx.draw(false, (function() {
+ setTimeout(function() {
+ uni.canvasToTempFilePath({
+ canvasId: options.canvasId,
+ fileType: options.fileType,
+ width: options.size,
+ height: options.size,
+ destWidth: options.size,
+ destHeight: options.size,
+ success: function(res) {
+ let resData; // 将统一为base64格式
+ let tempFilePath = res.tempFilePath; // H5为base64,其他为相对路径
+
+ // #ifdef H5
+ resData = tempFilePath;
+ options.success && options.success(resData);
+ reslove(resData);
+ // #endif
+
+ // #ifdef APP-PLUS
+ const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
+ let fileReader = new plus.io.FileReader();
+ fileReader.readAsDataURL(path);
+ fileReader.onloadend = res => {
+ resData = res.target.result;
+ options.success && options.success(resData);
+ reslove(resData);
+ };
+ // #endif
+
+ // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+ uni.getFileSystemManager().readFile({
+ filePath: tempFilePath,
+ encoding: 'base64',
+ success: res => {
+ resData = 'data:image/png;base64,' + res.data;
+ options.success && options.success(resData);
+ reslove(resData);
+ }
+ })
+ // #endif
+
+ // #ifndef H5 || APP-PLUS || MP-WEIXIN || MP-QQ || MP-TOUTIAO
+ if (plus) {
+ const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
+ let fileReader = new plus.io.FileReader();
+ fileReader.readAsDataURL(path);
+ fileReader.onloadend = res => {
+ resData = res.target.result;
+ options.success && options.success(resData);
+ reslove(resData);
+ };
+ } else {
+ uni.request({
+ url: tempFilePath,
+ method: 'GET',
+ responseType: 'arraybuffer',
+ success: res => {
+ resData = `data:image/png;base64,${uni.arrayBufferToBase64(res.data)}`; // 把arraybuffer转成base64
+ options.success && options.success(resData);
+ reslove(resData);
+ }
+ })
+ }
+ // #endif
+ },
+ fail: function(error) {
+ options.fail && options.fail(error);
+ reject(error);
+ },
+ complete: function(res) {
+ options.complete && options.complete(res);
+ }
+ }, options.componentInstance);
+ }, options.text.length + 100);
+ })());
+ }, 150);
+ }
+
+ createCanvas();
+ });
+ }
+ }
+
+})()
+export default uQRCode
\ No newline at end of file
diff --git a/src/components/yan-qr/yan-qr.md b/src/components/yan-qr/yan-qr.md
new file mode 100644
index 0000000..b54b174
--- /dev/null
+++ b/src/components/yan-qr/yan-qr.md
@@ -0,0 +1,95 @@
+## 使用方式
+``` javascript
+
+```
+
+## 属性说明
+|属性名 |类型 | 默认值 |说明 |
+|-- |-- |-----------|-- |
+|canvasId |String | 'qrcode' |canvas-id |
+|text |String | 'hello' |二维码内容 |
+|size |Number | 340 |单位是px |
+|margin |Number | 0 |边距 |
+|level |String | 'L' |二维码解析度L/M/Q/H |
+|fColor |String | '#000000' |二维码颜色 |
+|bColor |String | '#ffffff' |二维码背景颜色 |
+|fileType |String | 'png' |二维码图片类型 |
+
+## 示例代码
+``` javascript
+
+
+
+
+ 需要转换的文本:
+
+
+
+ 二维码
+
+
+
+ 二维码图片地址
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/src/components/yan-qr/yan-qr.vue b/src/components/yan-qr/yan-qr.vue
new file mode 100644
index 0000000..39025a8
--- /dev/null
+++ b/src/components/yan-qr/yan-qr.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/package.json b/src/package.json
new file mode 100644
index 0000000..3341673
--- /dev/null
+++ b/src/package.json
@@ -0,0 +1,18 @@
+{
+ "id": "yan-qr",
+ "name": "动态生成二维码",
+ "displayName": "动态生成二维码",
+ "version": "1.0.0",
+ "description": "动态生成二维码",
+ "keywords": [
+ "二维码",
+ "生成二维码",
+ "动态二维码"
+ ],
+ "dcloudext": {
+ "category": [
+ "前端组件",
+ "通用组件"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages.json b/src/pages.json
index 4aacc65..94ec62b 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -173,6 +173,30 @@
"navigationBarTitleText": "切换车型",
"enablePullDownRefresh": false
}
+ },
+ {
+ "path" : "pages/index/activity",
+ "style" :
+ {
+ "navigationBarTitleText" : "活动",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/me/myGift",
+ "style" :
+ {
+ "navigationBarTitleText" : "我的奖品",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/me/qrCode",
+ "style" :
+ {
+ "navigationBarTitleText" : "核销二维码",
+ "enablePullDownRefresh" : false
+ }
}
],
diff --git a/src/pages/index/activity.vue b/src/pages/index/activity.vue
new file mode 100644
index 0000000..f31dae9
--- /dev/null
+++ b/src/pages/index/activity.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/index/components/ggl/index.vue b/src/pages/index/components/ggl/index.vue
new file mode 100644
index 0000000..3847459
--- /dev/null
+++ b/src/pages/index/components/ggl/index.vue
@@ -0,0 +1,147 @@
+
+
+
+ 您今日还剩1次刮奖机会,共有999人参加活动
+
+
+
+
+ 点我刮奖
+
+
+
+
+
+ 中奖名单
+
+
+ 188****8888
+ 一等奖
+
+
+
+
+
+ 活动说明
+
+ 1. 中奖率100%
+ 2. 报名后可获得一次抽奖机会
+ 3. 中奖用户请于"我的-我的奖品"中查看并核销
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/index/components/ggl/scraping.vue b/src/pages/index/components/ggl/scraping.vue
new file mode 100644
index 0000000..652324d
--- /dev/null
+++ b/src/pages/index/components/ggl/scraping.vue
@@ -0,0 +1,266 @@
+
+
+
+
+ {{ showText }}
+
+
+
+
+
+
+
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 9984b63..83f128d 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -11,6 +11,9 @@
+
+
+
@@ -49,6 +52,7 @@
categoryList: [],
rightList: storage.get(`rightList_subject${this.subject}`) || [],
wrongList: storage.get(`wrongList_subject${this.subject}`) || [],
+ activityList: ['https://cdn.uviewui.com/uview/swiper/swiper1.png']
};
},
onShow() {
@@ -115,6 +119,12 @@
}, 100)
}
},
+ // 去活动
+ handleToActivity(index) {
+ uni.navigateTo({
+ url: '/pages/index/activity'
+ })
+ }
}
}
diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue
index c4f0b23..b8e4d21 100644
--- a/src/pages/me/index.vue
+++ b/src/pages/me/index.vue
@@ -75,6 +75,11 @@
+
+
+
+
+
@@ -224,6 +229,11 @@ export default {
handleLogout() {
useUserStore().logout()
},
+ handleGift() {
+ uni.navigateTo({
+ url: '/pages/me/myGift'
+ })
+ }
}
}
diff --git a/src/pages/me/myGift.vue b/src/pages/me/myGift.vue
new file mode 100644
index 0000000..4b13133
--- /dev/null
+++ b/src/pages/me/myGift.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+ 一等奖
+
+
+
+ 活动名称:幸运刮刮乐开心赢大奖
+ 参与时间:2024-01-01 08:00
+ 有效期至:2024-03-01 08:00
+
+
+
+ 核销
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/me/qrCode.vue b/src/pages/me/qrCode.vue
new file mode 100644
index 0000000..ce5d803
--- /dev/null
+++ b/src/pages/me/qrCode.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/static/image/index/tip.png b/src/static/image/index/tip.png
new file mode 100644
index 0000000..18bb5ff
Binary files /dev/null and b/src/static/image/index/tip.png differ
diff --git a/src/static/image/mine/giftitem.png b/src/static/image/mine/giftitem.png
new file mode 100644
index 0000000..c037a01
Binary files /dev/null and b/src/static/image/mine/giftitem.png differ
diff --git a/src/static/image/mine/writeoff.png b/src/static/image/mine/writeoff.png
new file mode 100644
index 0000000..2ed0c53
Binary files /dev/null and b/src/static/image/mine/writeoff.png differ
diff --git a/src/uni_modules/lime-qrcode/changelog.md b/src/uni_modules/lime-qrcode/changelog.md
new file mode 100644
index 0000000..f4879bb
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/changelog.md
@@ -0,0 +1,25 @@
+## 0.1.2(2023-12-14)
+- fix: uvue 引入 API 自定义包出错
+## 0.1.1(2023-12-11)
+- chore: uvue的二维码API独立,需要单独下载
+## 0.1.0(2023-12-07)
+- fix: 修复因utssdk目录导致无法运行
+## 0.0.9(2023-12-06)
+- feat: 支持uvue
+## 0.0.8(2023-12-06)
+- feat: 支持uvue
+## 0.0.7(2023-12-06)
+- feat: 支持uvue
+## 0.0.6(2023-12-06)
+- feat: 支持uvue
+## 0.0.5(2023-07-30)
+- fix: 修复再次生成前没有清空,导致图形叠加
+## 0.0.4(2023-07-27)
+- fix: 修复相同尺寸无法再次生成
+## 0.0.3(2023-06-09)
+- feat: 支持通过`@vue/composition-api`在`vue2`上使用
+- chore: 更新文档
+## 0.0.2(2023-06-08)
+- chore: 更新文档
+## 0.0.1(2023-06-08)
+- 首次
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue b/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue
new file mode 100644
index 0000000..2bd97dd
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue b/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue
new file mode 100644
index 0000000..f228583
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue
@@ -0,0 +1,223 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/props.ts b/src/uni_modules/lime-qrcode/components/l-qrcode/props.ts
new file mode 100644
index 0000000..fb4d101
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/props.ts
@@ -0,0 +1,36 @@
+// @ts-nocheck
+// import type { PropType } from './vue'
+export default {
+ value: String,
+ icon: String,
+ size: {
+ type: [Number, String],
+ default: 160
+ },
+ iconSize: {
+ type: [Number, String],
+ default: 40
+ },
+ marginSize: Number,
+ color: {
+ type: String,
+ default: '#000'
+ },
+ bgColor: {
+ type: String,
+ default: 'transparent'
+ },
+ bordered: {
+ type: Boolean,
+ default: true
+ },
+ errorLevel: {
+ type: String as PropType<'L'|'M'|'Q'|'H'>,
+ default: 'M' // 'L' | 'M' | 'Q' | 'H'
+ },
+ useCanvasToTempFilePath: Boolean
+ // status: {
+ // type: String as PropType<'active'|'expired'|'loading'>,
+ // default: 'active' // active | expired | loading
+ // }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js b/src/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js
new file mode 100644
index 0000000..b04047b
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js
@@ -0,0 +1,6 @@
+function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;t.length>n;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function n(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function r(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);t>n;n++)r[n]=e[n];return r}function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,o=function(){};return{s:o,n:function(){return e.length>r?{done:!1,value:e[r++]}:{done:!0}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){u=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(u)throw a}}}}
+/**
+ * @license QR Code generator library (TypeScript)
+ * Copyright (c) Project Nayuki.
+ * SPDX-License-Identifier: MIT
+ */var a;!function(t){var r=function(){function r(t,n,i,o){if(e(this,r),this.version=void 0,this.errorCorrectionLevel=void 0,this.size=void 0,this.mask=void 0,this.modules=[],this.isFunction=[],this.version=t,this.errorCorrectionLevel=n,r.MIN_VERSION>t||t>r.MAX_VERSION)throw new RangeError("Version value out of range");if(-1>o||o>7)throw new RangeError("Mask value out of range");this.size=4*t+17;for(var a=[],u=0;this.size>u;u++)a.push(!1);for(var l=0;this.size>l;l++)this.modules.push(a.slice()),this.isFunction.push(a.slice());this.drawFunctionPatterns();var h=this.addEccAndInterleave(i);if(this.drawCodewords(h),-1==o)for(var c=1e9,f=0;8>f;f++){this.applyMask(f),this.drawFormatBits(f);var v=this.getPenaltyScore();c>v&&(o=f,c=v),this.applyMask(f)}s(o>=0&&7>=o),this.mask=o,this.applyMask(o),this.drawFormatBits(o),this.isFunction=[]}return n(r,[{key:"getModule",value:function(e,t){return e>=0&&this.size>e&&t>=0&&this.size>t&&this.modules[t][e]}},{key:"getModules",value:function(){return this.modules}},{key:"drawFunctionPatterns",value:function(){for(var e=0;this.size>e;e++)this.setFunctionModule(6,e,e%2==0),this.setFunctionModule(e,6,e%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);for(var t=this.getAlignmentPatternPositions(),n=t.length,r=0;n>r;r++)for(var i=0;n>i;i++)0==r&&0==i||0==r&&i==n-1||r==n-1&&0==i||this.drawAlignmentPattern(t[r],t[i]);this.drawFormatBits(0),this.drawVersion()}},{key:"drawFormatBits",value:function(e){for(var t=this.errorCorrectionLevel.formatBits<<3|e,n=t,r=0;10>r;r++)n=n<<1^1335*(n>>>9);var i=21522^(t<<10|n);s(i>>>15==0);for(var o=0;5>=o;o++)this.setFunctionModule(8,o,a(i,o));this.setFunctionModule(8,7,a(i,6)),this.setFunctionModule(8,8,a(i,7)),this.setFunctionModule(7,8,a(i,8));for(var u=9;15>u;u++)this.setFunctionModule(14-u,8,a(i,u));for(var l=0;8>l;l++)this.setFunctionModule(this.size-1-l,8,a(i,l));for(var h=8;15>h;h++)this.setFunctionModule(8,this.size-15+h,a(i,h));this.setFunctionModule(8,this.size-8,!0)}},{key:"drawVersion",value:function(){if(this.version>=7){for(var e=this.version,t=0;12>t;t++)e=e<<1^7973*(e>>>11);var n=this.version<<12|e;s(n>>>18==0);for(var r=0;18>r;r++){var i=a(n,r),o=this.size-11+r%3,u=Math.floor(r/3);this.setFunctionModule(o,u,i),this.setFunctionModule(u,o,i)}}}},{key:"drawFinderPattern",value:function(e,t){for(var n=-4;4>=n;n++)for(var r=-4;4>=r;r++){var i=Math.max(Math.abs(r),Math.abs(n)),o=e+r,a=t+n;o>=0&&this.size>o&&a>=0&&this.size>a&&this.setFunctionModule(o,a,2!=i&&4!=i)}}},{key:"drawAlignmentPattern",value:function(e,t){for(var n=-2;2>=n;n++)for(var r=-2;2>=r;r++)this.setFunctionModule(e+r,t+n,1!=Math.max(Math.abs(r),Math.abs(n)))}},{key:"setFunctionModule",value:function(e,t,n){this.modules[t][e]=n,this.isFunction[t][e]=!0}},{key:"addEccAndInterleave",value:function(e){var t=this.version,n=this.errorCorrectionLevel;if(e.length!=r.getNumDataCodewords(t,n))throw new RangeError("Invalid argument");for(var i=r.NUM_ERROR_CORRECTION_BLOCKS[n.ordinal][t],o=r.ECC_CODEWORDS_PER_BLOCK[n.ordinal][t],a=Math.floor(r.getNumRawDataModules(t)/8),u=i-a%i,l=Math.floor(a/i),h=[],c=r.reedSolomonComputeDivisor(o),f=0,v=0;i>f;f++){var d=e.slice(v,v+l-o+(u>f?0:1));v+=d.length;var m=r.reedSolomonComputeRemainder(d,c);u>f&&d.push(0),h.push(d.concat(m))}for(var g=[],y=function(e){h.forEach((function(t,n){e==l-o&&u>n||g.push(t[e])}))},E=0;h[0].length>E;E++)y(E);return s(g.length==a),g}},{key:"drawCodewords",value:function(e){if(e.length!=Math.floor(r.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");for(var t=0,n=this.size-1;n>=1;n-=2){6==n&&(n=5);for(var i=0;this.size>i;i++)for(var o=0;2>o;o++){var u=n-o,l=0==(n+1&2)?this.size-1-i:i;!this.isFunction[l][u]&&8*e.length>t&&(this.modules[l][u]=a(e[t>>>3],7-(7&t)),t++)}}s(t==8*e.length)}},{key:"applyMask",value:function(e){if(0>e||e>7)throw new RangeError("Mask value out of range");for(var t=0;this.size>t;t++)for(var n=0;this.size>n;n++){var r=void 0;switch(e){case 0:r=(n+t)%2==0;break;case 1:r=t%2==0;break;case 2:r=n%3==0;break;case 3:r=(n+t)%3==0;break;case 4:r=(Math.floor(n/3)+Math.floor(t/2))%2==0;break;case 5:r=n*t%2+n*t%3==0;break;case 6:r=(n*t%2+n*t%3)%2==0;break;case 7:r=((n+t)%2+n*t%3)%2==0;break;default:throw Error("Unreachable")}!this.isFunction[t][n]&&r&&(this.modules[t][n]=!this.modules[t][n])}}},{key:"getPenaltyScore",value:function(){for(var e=0,t=0;this.size>t;t++){for(var n=!1,i=0,a=[0,0,0,0,0,0,0],u=0;this.size>u;u++)this.modules[t][u]==n?5==++i?e+=r.PENALTY_N1:i>5&&e++:(this.finderPenaltyAddHistory(i,a),n||(e+=this.finderPenaltyCountPatterns(a)*r.PENALTY_N3),n=this.modules[t][u],i=1);e+=this.finderPenaltyTerminateAndCount(n,i,a)*r.PENALTY_N3}for(var l=0;this.size>l;l++){for(var h=!1,c=0,f=[0,0,0,0,0,0,0],v=0;this.size>v;v++)this.modules[v][l]==h?5==++c?e+=r.PENALTY_N1:c>5&&e++:(this.finderPenaltyAddHistory(c,f),h||(e+=this.finderPenaltyCountPatterns(f)*r.PENALTY_N3),h=this.modules[v][l],c=1);e+=this.finderPenaltyTerminateAndCount(h,c,f)*r.PENALTY_N3}for(var d=0;this.size-1>d;d++)for(var m=0;this.size-1>m;m++){var g=this.modules[d][m];g==this.modules[d][m+1]&&g==this.modules[d+1][m]&&g==this.modules[d+1][m+1]&&(e+=r.PENALTY_N2)}var y,E=0,w=o(this.modules);try{for(w.s();!(y=w.n()).done;){E=y.value.reduce((function(e,t){return e+(t?1:0)}),E)}}catch(e){w.e(e)}finally{w.f()}var M=this.size*this.size,C=Math.ceil(Math.abs(20*E-10*M)/M)-1;return s(C>=0&&9>=C),s((e+=C*r.PENALTY_N4)>=0&&2568888>=e),e}},{key:"getAlignmentPatternPositions",value:function(){if(1==this.version)return[];for(var e=Math.floor(this.version/7)+2,t=32==this.version?26:2*Math.ceil((4*this.version+4)/(2*e-2)),n=[6],r=this.size-7;e>n.length;r-=t)n.splice(1,0,r);return n}},{key:"finderPenaltyCountPatterns",value:function(e){var t=e[1];s(3*this.size>=t);var n=t>0&&e[2]==t&&e[3]==3*t&&e[4]==t&&e[5]==t;return(!n||4*t>e[0]||t>e[6]?0:1)+(!n||4*t>e[6]||t>e[0]?0:1)}},{key:"finderPenaltyTerminateAndCount",value:function(e,t,n){return e&&(this.finderPenaltyAddHistory(t,n),t=0),this.finderPenaltyAddHistory(t+=this.size,n),this.finderPenaltyCountPatterns(n)}},{key:"finderPenaltyAddHistory",value:function(e,t){0==t[0]&&(e+=this.size),t.pop(),t.unshift(e)}}],[{key:"encodeText",value:function(e,n){var i=t.QrSegment.makeSegments(e);return r.encodeSegments(i,n)}},{key:"encodeBinary",value:function(e,n){var i=t.QrSegment.makeBytes(e);return r.encodeSegments([i],n)}},{key:"encodeSegments",value:function(e,t){var n,a,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,h=arguments.length>3&&void 0!==arguments[3]?arguments[3]:40,c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1,f=5>=arguments.length||void 0===arguments[5]||arguments[5];if(r.MIN_VERSION>l||l>h||h>r.MAX_VERSION||-1>c||c>7)throw new RangeError("Invalid value");for(n=l;;n++){var v=8*r.getNumDataCodewords(n,t),d=u.getTotalBits(e,n);if(v>=d){a=d;break}if(n>=h)throw new RangeError("Data too long")}for(var m=0,g=[r.Ecc.MEDIUM,r.Ecc.QUARTILE,r.Ecc.HIGH];g.length>m;m++){var y=g[m];f&&a<=8*r.getNumDataCodewords(n,y)&&(t=y)}var E,w=[],M=o(e);try{for(M.s();!(E=M.n()).done;){var C=E.value;i(C.mode.modeBits,4,w),i(C.numChars,C.mode.numCharCountBits(n),w);var R,A=o(C.getData());try{for(A.s();!(R=A.n()).done;){var p=R.value;w.push(p)}}catch(e){A.e(e)}finally{A.f()}}}catch(e){M.e(e)}finally{M.f()}s(w.length==a);var P=8*r.getNumDataCodewords(n,t);s(P>=w.length),i(0,Math.min(4,P-w.length),w),i(0,(8-w.length%8)%8,w),s(w.length%8==0);for(var N=236;P>w.length;N^=253)i(N,8,w);for(var k=[];w.length>8*k.length;)k.push(0);return w.forEach((function(e,t){return k[t>>>3]|=e<<7-(7&t)})),new r(n,t,k,c)}},{key:"getNumRawDataModules",value:function(e){if(r.MIN_VERSION>e||e>r.MAX_VERSION)throw new RangeError("Version number out of range");var t=(16*e+128)*e+64;if(e>=2){var n=Math.floor(e/7)+2;t-=(25*n-10)*n-55,7>e||(t-=36)}return s(t>=208&&29648>=t),t}},{key:"getNumDataCodewords",value:function(e,t){return Math.floor(r.getNumRawDataModules(e)/8)-r.ECC_CODEWORDS_PER_BLOCK[t.ordinal][e]*r.NUM_ERROR_CORRECTION_BLOCKS[t.ordinal][e]}},{key:"reedSolomonComputeDivisor",value:function(e){if(1>e||e>255)throw new RangeError("Degree out of range");for(var t=[],n=0;e-1>n;n++)t.push(0);t.push(1);for(var i=1,o=0;e>o;o++){for(var a=0;t.length>a;a++)t[a]=r.reedSolomonMultiply(t[a],i),t.length>a+1&&(t[a]^=t[a+1]);i=r.reedSolomonMultiply(i,2)}return t}},{key:"reedSolomonComputeRemainder",value:function(e,t){var n,i=t.map((function(e){return 0})),a=o(e);try{var s=function(){var e=n.value^i.shift();i.push(0),t.forEach((function(t,n){return i[n]^=r.reedSolomonMultiply(t,e)}))};for(a.s();!(n=a.n()).done;)s()}catch(e){a.e(e)}finally{a.f()}return i}},{key:"reedSolomonMultiply",value:function(e,t){if(e>>>8!=0||t>>>8!=0)throw new RangeError("Byte out of range");for(var n=0,r=7;r>=0;r--)n=n<<1^285*(n>>>7),n^=(t>>>r&1)*e;return s(n>>>8==0),n}}]),r}();function i(e,t,n){if(0>t||t>31||e>>>t!=0)throw new RangeError("Value out of range");for(var r=t-1;r>=0;r--)n.push(e>>>r&1)}function a(e,t){return 0!=(e>>>t&1)}function s(e){if(!e)throw Error("Assertion error")}r.MIN_VERSION=1,r.MAX_VERSION=40,r.PENALTY_N1=3,r.PENALTY_N2=3,r.PENALTY_N3=40,r.PENALTY_N4=10,r.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],r.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],t.QrCode=r;var u=function(){function t(n,r,i){if(e(this,t),this.mode=void 0,this.numChars=void 0,this.bitData=void 0,this.mode=n,this.numChars=r,this.bitData=i,0>r)throw new RangeError("Invalid argument");this.bitData=i.slice()}return n(t,[{key:"getData",value:function(){return this.bitData.slice()}}],[{key:"makeBytes",value:function(e){var n,r=[],a=o(e);try{for(a.s();!(n=a.n()).done;){i(n.value,8,r)}}catch(e){a.e(e)}finally{a.f()}return new t(t.Mode.BYTE,e.length,r)}},{key:"makeNumeric",value:function(e){if(!t.isNumeric(e))throw new RangeError("String contains non-numeric characters");for(var n=[],r=0;e.length>r;){var o=Math.min(e.length-r,3);i(parseInt(e.substring(r,r+o),10),3*o+1,n),r+=o}return new t(t.Mode.NUMERIC,e.length,n)}},{key:"makeAlphanumeric",value:function(e){if(!t.isAlphanumeric(e))throw new RangeError("String contains unencodable characters in alphanumeric mode");var n,r=[];for(n=0;e.length>=n+2;n+=2){var o=45*t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n));i(o+=t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n+1)),11,r)}return e.length>n&&i(t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n)),6,r),new t(t.Mode.ALPHANUMERIC,e.length,r)}},{key:"makeSegments",value:function(e){return""==e?[]:t.isNumeric(e)?[t.makeNumeric(e)]:t.isAlphanumeric(e)?[t.makeAlphanumeric(e)]:[t.makeBytes(t.toUtf8ByteArray(e))]}},{key:"makeEci",value:function(e){var n=[];if(0>e)throw new RangeError("ECI assignment value out of range");if(128>e)i(e,8,n);else if(16384>e)i(2,2,n),i(e,14,n);else{if(e>=1e6)throw new RangeError("ECI assignment value out of range");i(6,3,n),i(e,21,n)}return new t(t.Mode.ECI,0,n)}},{key:"isNumeric",value:function(e){return t.NUMERIC_REGEX.test(e)}},{key:"isAlphanumeric",value:function(e){return t.ALPHANUMERIC_REGEX.test(e)}},{key:"getTotalBits",value:function(e,t){var n,r=0,i=o(e);try{for(i.s();!(n=i.n()).done;){var a=n.value,s=a.mode.numCharCountBits(t);if(a.numChars>=1<n;n++)"%"!=e.charAt(n)?t.push(e.charCodeAt(n)):(t.push(parseInt(e.substring(n+1,n+3),16)),n+=2);return t}}]),t}();u.NUMERIC_REGEX=/^[0-9]*$/,u.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,u.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",t.QrSegment=u}(a||(a={})),function(t){!function(t){var r=n((function t(n,r){e(this,t),this.ordinal=void 0,this.formatBits=void 0,this.ordinal=n,this.formatBits=r}));r.LOW=new r(0,1),r.MEDIUM=new r(1,0),r.QUARTILE=new r(2,3),r.HIGH=new r(3,2),t.Ecc=r}(t.QrCode||(t.QrCode={}))}(a||(a={})),function(t){!function(t){var r=function(){function t(n,r){e(this,t),this.modeBits=void 0,this.numBitsCharCount=void 0,this.modeBits=n,this.numBitsCharCount=r}return n(t,[{key:"numCharCountBits",value:function(e){return this.numBitsCharCount[Math.floor((e+7)/17)]}}]),t}();r.NUMERIC=new r(1,[10,12,14]),r.ALPHANUMERIC=new r(2,[9,11,13]),r.BYTE=new r(4,[8,16,16]),r.KANJI=new r(8,[8,10,12]),r.ECI=new r(7,[0,0,0]),t.Mode=r}(t.QrSegment||(t.QrSegment={}))}(a||(a={}));var s=a,u=["value","size","level","bgColor","fgColor","includeMargin","marginSize","imageSettings"],l={L:s.QrCode.Ecc.LOW,M:s.QrCode.Ecc.MEDIUM,Q:s.QrCode.Ecc.QUARTILE,H:s.QrCode.Ecc.HIGH};function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=[];return e.forEach((function(e,r){var i=null;e.forEach((function(o,a){if(!o&&null!==i)return n.push("M".concat(i+t," ").concat(r+t,"h").concat(a-i,"v1H").concat(i+t,"z")),void(i=null);if(a!==e.length-1)o&&null===i&&(i=a);else{if(!o)return;n.push(null===i?"M".concat(a+t,",").concat(r+t," h1v1H").concat(a+t,"z"):"M".concat(i+t,",").concat(r+t," h").concat(a+1-i,"v1H").concat(i+t,"z"))}}))})),n.join("")}function c(e,t){return e.slice().map((function(e,n){return t.y>n||n>=t.y+t.h?e:e.map((function(e,n){return(t.x>n||n>=t.x+t.w)&&e}))}))}var f=function(){function t(n,r){var i=this;for(var o in e(this,t),this.canvas=void 0,this.pixelRatio="undefined"!=typeof window?window.devicePixelRatio:1,this.path2D=!0,this.SUPPORTS_PATH2D=void 0,this.createImage=function(){return new Image},this.createPath2D=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,t="createPath2D";return i.canvas&&t in i.canvas?i.canvas[t](e):new Path2D(e)},this.canvas=n,r)o in this&&(this[o]=r[o]);this.SUPPORTS_PATH2D=function(){try{i.createPath2D()}catch(e){return!1}return!0}()}return n(t,[{key:"render",value:function(e,t){var n=this,i=e.value,o=e.size,a=void 0===o?128:o,f=e.level,v=void 0===f?"L":f,d=e.bgColor,m=void 0===d?"#FFFFFF":d,g=e.fgColor,y=void 0===g?"#000000":g,E=e.includeMargin,w=void 0!==E&&E,M=e.marginSize,C=e.imageSettings,R=(r(e,u),null==C?void 0:C.src),A=this.canvas,p=A.getContext("2d");if(p&&i){var P=s.QrCode.encodeText(i,l[v]).getModules(),N=function(e,t){return null!=t?Math.floor(t):e?4:0}(w,M),k=P.length+2*N,S=function(e,t,n,r){if(null==r)return null;var i=e.length+2*n,o=Math.floor(.1*t),a=i/t,s=(r.width||o)*a,u=(r.height||o)*a,l=null==r.x?e.length/2-s/2:r.x*a,h=null==r.y?e.length/2-u/2:r.y*a,c=null;if(r.excavate){var f=Math.floor(l),v=Math.floor(h);c={x:f,y:v,w:Math.ceil(s+l-f),h:Math.ceil(u+h-v)}}return{x:l,y:h,h:u,w:s,excavation:c}}(P,a,N,C),I=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=null!=S&&null!==e&&e.complete&&0!==e.naturalHeight&&0!==e.naturalWidth;r&&null!=S.excavation&&(P=c(P,S.excavation)),t&&t(P);var i=n.pixelRatio;p.clearRect(0,0,A.width,A.height),p.setTransform(1,0,0,1,0,0),A.height=A.width=a*i;var o=a/k*i;if(p.scale(o,o),p.fillStyle=m,p.fillRect(0,0,k,k),p.fillStyle=y,n.SUPPORTS_PATH2D&&n.path2D){var s=n.createPath2D(h(P,N));p.fill(s)}else P.forEach((function(e,t){e.forEach((function(e,n){e&&p.fillRect(n+N,t+N,1,1)}))}));var u=(null==e?void 0:e.path)||e;r&&p.drawImage(u,S.x+N,S.y+N,S.w,S.h),"draw"in p&&p.draw()};if(R){var b=this.createImage(A);b.onload=function(){I(b)},b.onerror=function(e){I(),console.warn(e)},b.src=R}else I()}}}]),t}();export{f as QRCodeCanvas};
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/type.ts b/src/uni_modules/lime-qrcode/components/l-qrcode/type.ts
new file mode 100644
index 0000000..d6c5bc8
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/type.ts
@@ -0,0 +1,25 @@
+export type ImageSettings = {
+ width: number
+ height: number
+ x?: number
+ y?: number
+ excavate: boolean
+}
+export type QRCodePropsTypes = {
+ value?: string
+ size?: number
+ fgColor?: string
+ level?: string
+ marginSize: number
+ includeMargin: boolean
+ imageSettings?: ImageSettings
+}
+
+export type QRCodeCallback = (cells : boolean[][]) => void
+
+export type Excavation = {
+ x: number
+ y: number
+ h: number
+ w: number
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts b/src/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts
new file mode 100644
index 0000000..02bed09
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts
@@ -0,0 +1,78 @@
+
+// @ts-nocheck
+import type { ComponentInternalInstance } from './vue'
+import { getRect } from '@/uni_modules/lime-shared/getRect'
+import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
+export const isCanvas2d = canIUseCanvas2d()
+
+export async function getCanvas(canvasId: string, options: {context: ComponentInternalInstance}) {
+ let { context } = options
+ // #ifdef MP || VUE2
+ if (context.proxy) context = context.proxy
+ // #endif
+ return getRect('#' + canvasId, {context, type: isCanvas2d ? 'fields': 'boundingClientRect'}).then(res => {
+ if(res.node){
+ return res.node
+ } else {
+ const ctx = uni.createCanvasContext(canvasId, context)
+ return {
+ getContext(type: string) {
+ if(type == '2d') {
+ return ctx
+ }
+ },
+ width: res.width,
+ height: res.height,
+ }
+ // #ifdef H5
+ // canvas.value = context.proxy.$el.querySelector('#'+ canvasId)
+ // #endif
+ }
+ })
+}
+
+// #ifndef H5 || APP-NVUE
+class Image {
+ currentSrc: string | null = null
+ naturalHeight: number = 0
+ naturalWidth: number = 0
+ width: number = 0
+ height: number = 0
+ tagName: string = 'IMG'
+ path: any = ''
+ crossOrigin: any = ''
+ referrerPolicy: any = ''
+ onload: () => void
+ onerror: () => void
+ constructor() {}
+ set src(src) {
+ this.currentSrc = src
+ uni.getImageInfo({
+ src,
+ success: (res) => {
+ this.path = res.path
+ this.naturalWidth = this.width = res.width
+ this.naturalHeight = this.height = res.height
+ this.onload()
+ },
+ fail: () => {
+ this.onerror()
+ }
+ })
+ }
+ get src() {
+ return this.currentSrc
+ }
+}
+// #endif
+
+export function createImage(canvas: WechatMiniprogram.Canvas) {
+ if(canvas && canvas.createImage) {
+ return canvas.createImage()
+ } else if(typeof window != 'undefined' && window.Image) {
+ return new window.Image()
+ }
+ // #ifndef H5 || APP-NVUE
+ return new Image()
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/l-qrcode/utils.uts b/src/uni_modules/lime-qrcode/components/l-qrcode/utils.uts
new file mode 100644
index 0000000..a88a930
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/l-qrcode/utils.uts
@@ -0,0 +1,35 @@
+export function addUnit(value: any|null):string{
+ if(value == null){
+ return ''
+ }
+ value = `${value}`
+ return /^(-)?\d+(\\.\d+)?$/.test(value) ? `${value}px` : value
+}
+
+export function unitConvert(value: any|null): number{
+ if(typeof value == 'number'){
+ return value as number
+ }
+ if(typeof value == 'string'){
+ value = `${value}`
+ if(/^(-)?\d+(\\.\d+)?$/.test(value)){
+ return parseFloat(value);
+ }
+
+ const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
+ const results = reg.exec(value);
+ if (results == null) {
+ return 0;
+ }
+ const unit = results[3];
+ const v = parseFloat(value);
+ if (unit == 'rpx') {
+ const { windowWidth } = uni.getWindowInfo()
+ return windowWidth / 750 * v;
+ }
+ if (unit == 'px') {
+ return v;
+ }
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue b/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue
new file mode 100644
index 0000000..745ac82
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue
@@ -0,0 +1,134 @@
+
+
+ QRCode
+ QRCode
+
+
+ 基础
+
+
+
+
+
+
+ icon
+
+
+
+
+
+
+
+
+
+
+
+ 颜色
+
+
+
+
+
+
+
+
+
+ 纠错比例
+
+
+
+
+
+
+
+ 动态
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue b/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue
new file mode 100644
index 0000000..5319ae4
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/uni_modules/lime-qrcode/hybrid/html/index.html b/src/uni_modules/lime-qrcode/hybrid/html/index.html
new file mode 100644
index 0000000..bf4def9
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/hybrid/html/index.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+ lime-qrcode
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js b/src/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js
new file mode 100644
index 0000000..a0c79ce
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js
@@ -0,0 +1,6 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).lime={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;t.length>n;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function i(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);t>n;n++)r[n]=e[n];return r}function a(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return e.length>r?{done:!1,value:e[r++]}:{done:!0}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){u=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(u)throw a}}}}
+/**
+ * @license QR Code generator library (TypeScript)
+ * Copyright (c) Project Nayuki.
+ * SPDX-License-Identifier: MIT
+ */var s;!function(e){var n=function(){function n(e,r,i,o){if(t(this,n),this.version=void 0,this.errorCorrectionLevel=void 0,this.size=void 0,this.mask=void 0,this.modules=[],this.isFunction=[],this.version=e,this.errorCorrectionLevel=r,n.MIN_VERSION>e||e>n.MAX_VERSION)throw new RangeError("Version value out of range");if(-1>o||o>7)throw new RangeError("Mask value out of range");this.size=4*e+17;for(var a=[],u=0;this.size>u;u++)a.push(!1);for(var l=0;this.size>l;l++)this.modules.push(a.slice()),this.isFunction.push(a.slice());this.drawFunctionPatterns();var h=this.addEccAndInterleave(i);if(this.drawCodewords(h),-1==o)for(var c=1e9,f=0;8>f;f++){this.applyMask(f),this.drawFormatBits(f);var d=this.getPenaltyScore();c>d&&(o=f,c=d),this.applyMask(f)}s(o>=0&&7>=o),this.mask=o,this.applyMask(o),this.drawFormatBits(o),this.isFunction=[]}return r(n,[{key:"getModule",value:function(e,t){return e>=0&&this.size>e&&t>=0&&this.size>t&&this.modules[t][e]}},{key:"getModules",value:function(){return this.modules}},{key:"drawFunctionPatterns",value:function(){for(var e=0;this.size>e;e++)this.setFunctionModule(6,e,e%2==0),this.setFunctionModule(e,6,e%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);for(var t=this.getAlignmentPatternPositions(),n=t.length,r=0;n>r;r++)for(var i=0;n>i;i++)0==r&&0==i||0==r&&i==n-1||r==n-1&&0==i||this.drawAlignmentPattern(t[r],t[i]);this.drawFormatBits(0),this.drawVersion()}},{key:"drawFormatBits",value:function(e){for(var t=this.errorCorrectionLevel.formatBits<<3|e,n=t,r=0;10>r;r++)n=n<<1^1335*(n>>>9);var i=21522^(t<<10|n);s(i>>>15==0);for(var a=0;5>=a;a++)this.setFunctionModule(8,a,o(i,a));this.setFunctionModule(8,7,o(i,6)),this.setFunctionModule(8,8,o(i,7)),this.setFunctionModule(7,8,o(i,8));for(var u=9;15>u;u++)this.setFunctionModule(14-u,8,o(i,u));for(var l=0;8>l;l++)this.setFunctionModule(this.size-1-l,8,o(i,l));for(var h=8;15>h;h++)this.setFunctionModule(8,this.size-15+h,o(i,h));this.setFunctionModule(8,this.size-8,!0)}},{key:"drawVersion",value:function(){if(this.version>=7){for(var e=this.version,t=0;12>t;t++)e=e<<1^7973*(e>>>11);var n=this.version<<12|e;s(n>>>18==0);for(var r=0;18>r;r++){var i=o(n,r),a=this.size-11+r%3,u=Math.floor(r/3);this.setFunctionModule(a,u,i),this.setFunctionModule(u,a,i)}}}},{key:"drawFinderPattern",value:function(e,t){for(var n=-4;4>=n;n++)for(var r=-4;4>=r;r++){var i=Math.max(Math.abs(r),Math.abs(n)),o=e+r,a=t+n;o>=0&&this.size>o&&a>=0&&this.size>a&&this.setFunctionModule(o,a,2!=i&&4!=i)}}},{key:"drawAlignmentPattern",value:function(e,t){for(var n=-2;2>=n;n++)for(var r=-2;2>=r;r++)this.setFunctionModule(e+r,t+n,1!=Math.max(Math.abs(r),Math.abs(n)))}},{key:"setFunctionModule",value:function(e,t,n){this.modules[t][e]=n,this.isFunction[t][e]=!0}},{key:"addEccAndInterleave",value:function(e){var t=this.version,r=this.errorCorrectionLevel;if(e.length!=n.getNumDataCodewords(t,r))throw new RangeError("Invalid argument");for(var i=n.NUM_ERROR_CORRECTION_BLOCKS[r.ordinal][t],o=n.ECC_CODEWORDS_PER_BLOCK[r.ordinal][t],a=Math.floor(n.getNumRawDataModules(t)/8),u=i-a%i,l=Math.floor(a/i),h=[],c=n.reedSolomonComputeDivisor(o),f=0,d=0;i>f;f++){var v=e.slice(d,d+l-o+(u>f?0:1));d+=v.length;var m=n.reedSolomonComputeRemainder(v,c);u>f&&v.push(0),h.push(v.concat(m))}for(var g=[],y=function(e){h.forEach((function(t,n){e==l-o&&u>n||g.push(t[e])}))},E=0;h[0].length>E;E++)y(E);return s(g.length==a),g}},{key:"drawCodewords",value:function(e){if(e.length!=Math.floor(n.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");for(var t=0,r=this.size-1;r>=1;r-=2){6==r&&(r=5);for(var i=0;this.size>i;i++)for(var a=0;2>a;a++){var u=r-a,l=0==(r+1&2)?this.size-1-i:i;!this.isFunction[l][u]&&8*e.length>t&&(this.modules[l][u]=o(e[t>>>3],7-(7&t)),t++)}}s(t==8*e.length)}},{key:"applyMask",value:function(e){if(0>e||e>7)throw new RangeError("Mask value out of range");for(var t=0;this.size>t;t++)for(var n=0;this.size>n;n++){var r=void 0;switch(e){case 0:r=(n+t)%2==0;break;case 1:r=t%2==0;break;case 2:r=n%3==0;break;case 3:r=(n+t)%3==0;break;case 4:r=(Math.floor(n/3)+Math.floor(t/2))%2==0;break;case 5:r=n*t%2+n*t%3==0;break;case 6:r=(n*t%2+n*t%3)%2==0;break;case 7:r=((n+t)%2+n*t%3)%2==0;break;default:throw Error("Unreachable")}!this.isFunction[t][n]&&r&&(this.modules[t][n]=!this.modules[t][n])}}},{key:"getPenaltyScore",value:function(){for(var e=0,t=0;this.size>t;t++){for(var r=!1,i=0,o=[0,0,0,0,0,0,0],u=0;this.size>u;u++)this.modules[t][u]==r?5==++i?e+=n.PENALTY_N1:i>5&&e++:(this.finderPenaltyAddHistory(i,o),r||(e+=this.finderPenaltyCountPatterns(o)*n.PENALTY_N3),r=this.modules[t][u],i=1);e+=this.finderPenaltyTerminateAndCount(r,i,o)*n.PENALTY_N3}for(var l=0;this.size>l;l++){for(var h=!1,c=0,f=[0,0,0,0,0,0,0],d=0;this.size>d;d++)this.modules[d][l]==h?5==++c?e+=n.PENALTY_N1:c>5&&e++:(this.finderPenaltyAddHistory(c,f),h||(e+=this.finderPenaltyCountPatterns(f)*n.PENALTY_N3),h=this.modules[d][l],c=1);e+=this.finderPenaltyTerminateAndCount(h,c,f)*n.PENALTY_N3}for(var v=0;this.size-1>v;v++)for(var m=0;this.size-1>m;m++){var g=this.modules[v][m];g==this.modules[v][m+1]&&g==this.modules[v+1][m]&&g==this.modules[v+1][m+1]&&(e+=n.PENALTY_N2)}var y,E=0,w=a(this.modules);try{for(w.s();!(y=w.n()).done;){E=y.value.reduce((function(e,t){return e+(t?1:0)}),E)}}catch(e){w.e(e)}finally{w.f()}var M=this.size*this.size,C=Math.ceil(Math.abs(20*E-10*M)/M)-1;return s(C>=0&&9>=C),s((e+=C*n.PENALTY_N4)>=0&&2568888>=e),e}},{key:"getAlignmentPatternPositions",value:function(){if(1==this.version)return[];for(var e=Math.floor(this.version/7)+2,t=32==this.version?26:2*Math.ceil((4*this.version+4)/(2*e-2)),n=[6],r=this.size-7;e>n.length;r-=t)n.splice(1,0,r);return n}},{key:"finderPenaltyCountPatterns",value:function(e){var t=e[1];s(3*this.size>=t);var n=t>0&&e[2]==t&&e[3]==3*t&&e[4]==t&&e[5]==t;return(!n||4*t>e[0]||t>e[6]?0:1)+(!n||4*t>e[6]||t>e[0]?0:1)}},{key:"finderPenaltyTerminateAndCount",value:function(e,t,n){return e&&(this.finderPenaltyAddHistory(t,n),t=0),this.finderPenaltyAddHistory(t+=this.size,n),this.finderPenaltyCountPatterns(n)}},{key:"finderPenaltyAddHistory",value:function(e,t){0==t[0]&&(e+=this.size),t.pop(),t.unshift(e)}}],[{key:"encodeText",value:function(t,r){var i=e.QrSegment.makeSegments(t);return n.encodeSegments(i,r)}},{key:"encodeBinary",value:function(t,r){var i=e.QrSegment.makeBytes(t);return n.encodeSegments([i],r)}},{key:"encodeSegments",value:function(e,t){var r,o,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,h=arguments.length>3&&void 0!==arguments[3]?arguments[3]:40,c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1,f=5>=arguments.length||void 0===arguments[5]||arguments[5];if(n.MIN_VERSION>l||l>h||h>n.MAX_VERSION||-1>c||c>7)throw new RangeError("Invalid value");for(r=l;;r++){var d=8*n.getNumDataCodewords(r,t),v=u.getTotalBits(e,r);if(d>=v){o=v;break}if(r>=h)throw new RangeError("Data too long")}for(var m=0,g=[n.Ecc.MEDIUM,n.Ecc.QUARTILE,n.Ecc.HIGH];g.length>m;m++){var y=g[m];f&&o<=8*n.getNumDataCodewords(r,y)&&(t=y)}var E,w=[],M=a(e);try{for(M.s();!(E=M.n()).done;){var C=E.value;i(C.mode.modeBits,4,w),i(C.numChars,C.mode.numCharCountBits(r),w);var R,p=a(C.getData());try{for(p.s();!(R=p.n()).done;){var A=R.value;w.push(A)}}catch(e){p.e(e)}finally{p.f()}}}catch(e){M.e(e)}finally{M.f()}s(w.length==o);var P=8*n.getNumDataCodewords(r,t);s(P>=w.length),i(0,Math.min(4,P-w.length),w),i(0,(8-w.length%8)%8,w),s(w.length%8==0);for(var N=236;P>w.length;N^=253)i(N,8,w);for(var k=[];w.length>8*k.length;)k.push(0);return w.forEach((function(e,t){return k[t>>>3]|=e<<7-(7&t)})),new n(r,t,k,c)}},{key:"getNumRawDataModules",value:function(e){if(n.MIN_VERSION>e||e>n.MAX_VERSION)throw new RangeError("Version number out of range");var t=(16*e+128)*e+64;if(e>=2){var r=Math.floor(e/7)+2;t-=(25*r-10)*r-55,7>e||(t-=36)}return s(t>=208&&29648>=t),t}},{key:"getNumDataCodewords",value:function(e,t){return Math.floor(n.getNumRawDataModules(e)/8)-n.ECC_CODEWORDS_PER_BLOCK[t.ordinal][e]*n.NUM_ERROR_CORRECTION_BLOCKS[t.ordinal][e]}},{key:"reedSolomonComputeDivisor",value:function(e){if(1>e||e>255)throw new RangeError("Degree out of range");for(var t=[],r=0;e-1>r;r++)t.push(0);t.push(1);for(var i=1,o=0;e>o;o++){for(var a=0;t.length>a;a++)t[a]=n.reedSolomonMultiply(t[a],i),t.length>a+1&&(t[a]^=t[a+1]);i=n.reedSolomonMultiply(i,2)}return t}},{key:"reedSolomonComputeRemainder",value:function(e,t){var r,i=t.map((function(e){return 0})),o=a(e);try{var s=function(){var e=r.value^i.shift();i.push(0),t.forEach((function(t,r){return i[r]^=n.reedSolomonMultiply(t,e)}))};for(o.s();!(r=o.n()).done;)s()}catch(e){o.e(e)}finally{o.f()}return i}},{key:"reedSolomonMultiply",value:function(e,t){if(e>>>8!=0||t>>>8!=0)throw new RangeError("Byte out of range");for(var n=0,r=7;r>=0;r--)n=n<<1^285*(n>>>7),n^=(t>>>r&1)*e;return s(n>>>8==0),n}}]),n}();function i(e,t,n){if(0>t||t>31||e>>>t!=0)throw new RangeError("Value out of range");for(var r=t-1;r>=0;r--)n.push(e>>>r&1)}function o(e,t){return 0!=(e>>>t&1)}function s(e){if(!e)throw Error("Assertion error")}n.MIN_VERSION=1,n.MAX_VERSION=40,n.PENALTY_N1=3,n.PENALTY_N2=3,n.PENALTY_N3=40,n.PENALTY_N4=10,n.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],n.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],e.QrCode=n;var u=function(){function e(n,r,i){if(t(this,e),this.mode=void 0,this.numChars=void 0,this.bitData=void 0,this.mode=n,this.numChars=r,this.bitData=i,0>r)throw new RangeError("Invalid argument");this.bitData=i.slice()}return r(e,[{key:"getData",value:function(){return this.bitData.slice()}}],[{key:"makeBytes",value:function(t){var n,r=[],o=a(t);try{for(o.s();!(n=o.n()).done;){i(n.value,8,r)}}catch(e){o.e(e)}finally{o.f()}return new e(e.Mode.BYTE,t.length,r)}},{key:"makeNumeric",value:function(t){if(!e.isNumeric(t))throw new RangeError("String contains non-numeric characters");for(var n=[],r=0;t.length>r;){var o=Math.min(t.length-r,3);i(parseInt(t.substring(r,r+o),10),3*o+1,n),r+=o}return new e(e.Mode.NUMERIC,t.length,n)}},{key:"makeAlphanumeric",value:function(t){if(!e.isAlphanumeric(t))throw new RangeError("String contains unencodable characters in alphanumeric mode");var n,r=[];for(n=0;t.length>=n+2;n+=2){var o=45*e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n));i(o+=e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n+1)),11,r)}return t.length>n&&i(e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n)),6,r),new e(e.Mode.ALPHANUMERIC,t.length,r)}},{key:"makeSegments",value:function(t){return""==t?[]:e.isNumeric(t)?[e.makeNumeric(t)]:e.isAlphanumeric(t)?[e.makeAlphanumeric(t)]:[e.makeBytes(e.toUtf8ByteArray(t))]}},{key:"makeEci",value:function(t){var n=[];if(0>t)throw new RangeError("ECI assignment value out of range");if(128>t)i(t,8,n);else if(16384>t)i(2,2,n),i(t,14,n);else{if(t>=1e6)throw new RangeError("ECI assignment value out of range");i(6,3,n),i(t,21,n)}return new e(e.Mode.ECI,0,n)}},{key:"isNumeric",value:function(t){return e.NUMERIC_REGEX.test(t)}},{key:"isAlphanumeric",value:function(t){return e.ALPHANUMERIC_REGEX.test(t)}},{key:"getTotalBits",value:function(e,t){var n,r=0,i=a(e);try{for(i.s();!(n=i.n()).done;){var o=n.value,s=o.mode.numCharCountBits(t);if(o.numChars>=1<n;n++)"%"!=e.charAt(n)?t.push(e.charCodeAt(n)):(t.push(parseInt(e.substring(n+1,n+3),16)),n+=2);return t}}]),e}();u.NUMERIC_REGEX=/^[0-9]*$/,u.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,u.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",e.QrSegment=u}(s||(s={})),function(e){!function(e){var n=r((function e(n,r){t(this,e),this.ordinal=void 0,this.formatBits=void 0,this.ordinal=n,this.formatBits=r}));n.LOW=new n(0,1),n.MEDIUM=new n(1,0),n.QUARTILE=new n(2,3),n.HIGH=new n(3,2),e.Ecc=n}(e.QrCode||(e.QrCode={}))}(s||(s={})),function(e){!function(e){var n=function(){function e(n,r){t(this,e),this.modeBits=void 0,this.numBitsCharCount=void 0,this.modeBits=n,this.numBitsCharCount=r}return r(e,[{key:"numCharCountBits",value:function(e){return this.numBitsCharCount[Math.floor((e+7)/17)]}}]),e}();n.NUMERIC=new n(1,[10,12,14]),n.ALPHANUMERIC=new n(2,[9,11,13]),n.BYTE=new n(4,[8,16,16]),n.KANJI=new n(8,[8,10,12]),n.ECI=new n(7,[0,0,0]),e.Mode=n}(e.QrSegment||(e.QrSegment={}))}(s||(s={}));var u=s,l=["value","size","level","bgColor","fgColor","includeMargin","marginSize","imageSettings"],h={L:u.QrCode.Ecc.LOW,M:u.QrCode.Ecc.MEDIUM,Q:u.QrCode.Ecc.QUARTILE,H:u.QrCode.Ecc.HIGH};function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=[];return e.forEach((function(e,r){var i=null;e.forEach((function(o,a){if(!o&&null!==i)return n.push("M".concat(i+t," ").concat(r+t,"h").concat(a-i,"v1H").concat(i+t,"z")),void(i=null);if(a!==e.length-1)o&&null===i&&(i=a);else{if(!o)return;n.push(null===i?"M".concat(a+t,",").concat(r+t," h1v1H").concat(a+t,"z"):"M".concat(i+t,",").concat(r+t," h").concat(a+1-i,"v1H").concat(i+t,"z"))}}))})),n.join("")}function f(e,t){return e.slice().map((function(e,n){return t.y>n||n>=t.y+t.h?e:e.map((function(e,n){return(t.x>n||n>=t.x+t.w)&&e}))}))}var d=function(){function e(n,r){var i=this;for(var o in t(this,e),this.canvas=void 0,this.pixelRatio="undefined"!=typeof window?window.devicePixelRatio:1,this.path2D=!0,this.SUPPORTS_PATH2D=void 0,this.createImage=function(){return new Image},this.createPath2D=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,t="createPath2D";return i.canvas&&t in i.canvas?i.canvas[t](e):new Path2D(e)},this.canvas=n,r)o in this&&(this[o]=r[o]);this.SUPPORTS_PATH2D=function(){try{i.createPath2D()}catch(e){return!1}return!0}()}return r(e,[{key:"render",value:function(e,t){var n=this,r=e.value,o=e.size,a=void 0===o?128:o,s=e.level,d=void 0===s?"L":s,v=e.bgColor,m=void 0===v?"#FFFFFF":v,g=e.fgColor,y=void 0===g?"#000000":g,E=e.includeMargin,w=void 0!==E&&E,M=e.marginSize,C=e.imageSettings,R=(i(e,l),null==C?void 0:C.src),p=this.canvas,A=p.getContext("2d");if(A&&r){var P=u.QrCode.encodeText(r,h[d]).getModules(),N=function(e,t){return null!=t?Math.floor(t):e?4:0}(w,M),k=P.length+2*N,S=function(e,t,n,r){if(null==r)return null;var i=e.length+2*n,o=Math.floor(.1*t),a=i/t,s=(r.width||o)*a,u=(r.height||o)*a,l=null==r.x?e.length/2-s/2:r.x*a,h=null==r.y?e.length/2-u/2:r.y*a,c=null;if(r.excavate){var f=Math.floor(l),d=Math.floor(h);c={x:f,y:d,w:Math.ceil(s+l-f),h:Math.ceil(u+h-d)}}return{x:l,y:h,h:u,w:s,excavation:c}}(P,a,N,C),I=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=null!=S&&null!==e&&e.complete&&0!==e.naturalHeight&&0!==e.naturalWidth;r&&null!=S.excavation&&(P=f(P,S.excavation)),t&&t(P);var i=n.pixelRatio;A.clearRect(0,0,p.width,p.height),A.setTransform(1,0,0,1,0,0),p.height=p.width=a*i;var o=a/k*i;if(A.scale(o,o),A.fillStyle=m,A.fillRect(0,0,k,k),A.fillStyle=y,n.SUPPORTS_PATH2D&&n.path2D){var s=n.createPath2D(c(P,N));A.fill(s)}else P.forEach((function(e,t){e.forEach((function(e,n){e&&A.fillRect(n+N,t+N,1,1)}))}));var u=(null==e?void 0:e.path)||e;r&&A.drawImage(u,S.x+N,S.y+N,S.w,S.h),"draw"in A&&A.draw()};if(R){var b=this.createImage(p);b.onload=function(){I(b)},b.onerror=function(e){I(),console.warn(e)},b.src=R}else I()}}}]),e}();e.QRCodeCanvas=d,Object.defineProperty(e,"__esModule",{value:!0})}));
diff --git a/src/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js b/src/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js
new file mode 100644
index 0000000..d6524fa
--- /dev/null
+++ b/src/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js
@@ -0,0 +1 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=n()}(this,(function(){"use strict";try{var e={};Object.defineProperty(e,"passive",{get:function(){!0}}),window.addEventListener("test-passive",null,e)}catch(e){}var n=Object.prototype.hasOwnProperty;function i(e,i){return n.call(e,i)}var t=[];function o(){return window.__dcloud_weex_postMessage||window.__dcloud_weex_}var r=function(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(o()){if("postMessage"===e){var r={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(r):window.__dcloud_weex_.postMessage(JSON.stringify(r))}var a={type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(a):window.__dcloud_weex_.postMessageToService(JSON.stringify(a))}if(!window.plus)return window.parent.postMessage({type:"WEB_INVOKE_APPSERVICE",data:i,pageId:""},"*");if(0===t.length){var d=plus.webview.currentWebview();if(!d)throw new Error("plus.webview.currentWebview() is undefined");var s=d.parent(),w="";w=s?s.id:d.id,t.push(w)}if(plus.webview.getWebviewById("__uniapp__service"))plus.webview.postMessageToUniNView({type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}},"__uniapp__service");else{var u=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE",'",').concat(u,",").concat(JSON.stringify(t),");"))}},a={navigateTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;r("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("redirectTo",{url:encodeURI(n)})},getEnv:function(e){o()?e({nvue:!0}):window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};r("postMessage",e.data||{})}},d=/uni-app/i.test(navigator.userAgent),s=/Html5Plus/i.test(navigator.userAgent),w=/complete|loaded|interactive/;var u=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var g=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var c=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var v=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var m=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);var f=window.ks&&window.ks.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var l=window.tt&&window.tt.miniProgram&&/Lark|Feishu/i.test(navigator.userAgent);var _=window.jd&&window.jd.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);for(var E,b=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},h=[function(e){if(d||s)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&w.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),a},function(e){if(m)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(c)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(u){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(v)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(f)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.ks.miniProgram},function(e){if(l)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(_)return window.JDJSBridgeReady&&window.JDJSBridgeReady.invoke?setTimeout(e,0):document.addEventListener("JDJSBridgeReady",e),window.jd.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),a}],y=0;y
+```
+
+
+#### ICON
+- 带 Icon 的二维码
+
+```html
+
+```
+
+#### 颜色
+- 通过设置 `color` 自定义二维码颜色,通过设置 `bgColor` 自定义背景颜色。
+
+```html
+
+
+```
+
+#### 纠错比例
+- 通过设置 `errorLevel` 调整不同的容错等级。
+
+```html
+
+```
+
+#### 生成图片
+- 1、通过调用插件的`canvasToTempFilePath`方法生成图片。
+
+```html
+
+
+
+```
+```js
+// vue3
+const qrcodeRef = ref(null)
+const onClick = () => {
+ if(!qrcodeRef.value) return
+ qrcodeRef.value.canvasToTempFilePath({
+ success(res) {
+ image.value = res.tempFilePath
+ console.log('success:::', res)
+ },
+ fail(err) {
+ console.log('err:::', err)
+ }
+ })
+}
+
+// vue2
+const el = this.$refs['qrcodeRef']
+el.canvasToTempFilePath({
+ success:(res)=>{
+ this.image = res.tempFilePath
+ },
+ fail(err) {
+ console.log('err:::', err)
+ }
+})
+
+// uvue
+const el:LQrcodeComponentPublicInstance = this.$refs['qrcodeRef'] as LQrcodeComponentPublicInstance
+el.canvasToTempFilePath({
+ success:(res: TakeSnapshotSuccess)=>{
+ this.image = res.tempFilePath
+ },
+ fail(err: TakeSnapshotFail) {
+ console.log('err:::', err)
+ }
+})
+```
+
+- 2、通过设置`useCanvasToTempFilePath`在`success`事件里接收图片地址
+
+```html
+
+
+```
+```js
+const image = ref(null)
+const success = (img) => {
+ image.value = img
+}
+```
+
+### 关于vue2的使用方式
+- 插件使用了`composition-api`, 如果你希望在vue2中使用请按官方的教程[vue-composition-api](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)配置
+- 关键代码是: 在main.js中 在vue2部分加上这一段即可,官方是把它单独成了一个文件.
+
+```js
+// main.js vue2
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+```
+另外插件也用到了TS,vue2可能会遇过官方的TS版本过低的问题,找到HX目录下的`compile-typescript`目录
+```cmd
+// \HBuilderX\plugins\compile-typescript
+yarn add typescript -D
+- or -
+npm install typescript -D
+```
+
+### 查看示例
+- 导入后直接使用这个标签查看演示效果
+
+```html
+// 代码位于 uni_modules/lime-qrcode/compoents/lime-qrcode
+
+```
+
+### 插件标签
+- 默认 l-qrcode 为 component
+- 默认 lime-qrcode 为 demo
+
+
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --------------------------| ------------------------------------------------------------ | ---------------- | ------------ |
+| value | 扫描后的文本 | string | `-` |
+| icon | 二维码中图片的地址 | string | `-` |
+| size | 二维码大小 | number,string | `160` |
+| iconSize | 二维码中图片的大小 | number,string | `40` |
+| color | 二维码颜色 | string | `-` |
+| bgColor | 二维码背景颜色 | string | `-` |
+| errorLevel | 二维码纠错等级 | `'L' | 'M' | 'Q' | 'H' ` | `M` |
+| marginSize | 边距码大小,默认为0码点 | number | `0` |
+
+### 常见问题
+- icon 是网络地址时,H5和Nvue需要解决跨域问题,小程序需要配置download
+
+## 打赏
+
+如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/addUnit/index.ts b/src/uni_modules/lime-shared/addUnit/index.ts
new file mode 100644
index 0000000..2468a3a
--- /dev/null
+++ b/src/uni_modules/lime-shared/addUnit/index.ts
@@ -0,0 +1,25 @@
+// @ts-nocheck
+import {isNumeric} from '../isNumeric'
+import {isDef} from '../isDef'
+/**
+ * 给一个值添加单位(像素 px)
+ * @param value 要添加单位的值,可以是字符串或数字
+ * @returns 添加了单位的值,如果值为 undefined 则返回 undefined
+ */
+export function addUnit(value?: string | number): string | undefined {
+ if (!isDef(value)) {
+ return undefined;
+ }
+
+ value = String(value); // 将值转换为字符串
+
+ // 如果值是数字,则在后面添加单位 "px",否则保持原始值
+ return isNumeric(value) ? `${value}px` : value;
+}
+
+
+// console.log(addUnit(100)); // 输出: "100px"
+// console.log(addUnit("200")); // 输出: "200px"
+// console.log(addUnit("300px")); // 输出: "300px"(已经包含单位)
+// console.log(addUnit()); // 输出: undefined(值为 undefined)
+// console.log(addUnit(null)); // 输出: undefined(值为 null)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/arrayBufferToFile/index.ts b/src/uni_modules/lime-shared/arrayBufferToFile/index.ts
new file mode 100644
index 0000000..9760b20
--- /dev/null
+++ b/src/uni_modules/lime-shared/arrayBufferToFile/index.ts
@@ -0,0 +1,63 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * buffer转路径
+ * @param {Object} buffer
+ */
+// @ts-nocheck
+export function arrayBufferToFile(buffer: ArrayBuffer | Blob, name?: string, format?:string):Promise<(File|string)> {
+ return new Promise((resolve, reject) => {
+ // #ifdef MP
+ const fs = uni.getFileSystemManager()
+ //自定义文件名
+ if (!name && !format) {
+ reject(new Error('ERROR_NAME_PARSE'))
+ }
+ const fileName = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+ let pre = platform()
+ const filePath = `${pre.env.USER_DATA_PATH}/${fileName}`
+ fs.writeFile({
+ filePath,
+ data: buffer,
+ success() {
+ resolve(filePath)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ // #endif
+
+ // #ifdef H5
+ const file = new File([buffer], name, {
+ type: format,
+ });
+ resolve(file)
+ // #endif
+
+ // #ifdef APP-PLUS
+ const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ const base64 = uni.arrayBufferToBase64(buffer)
+ bitmap.loadBase64Data(base64, () => {
+ if (!name && !format) {
+ reject(new Error('ERROR_NAME_PARSE'))
+ }
+ const fileNmae = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+ const filePath = `_doc/uniapp_temp/${fileNmae}`
+ bitmap.save(filePath, {},
+ () => {
+ bitmap.clear()
+ resolve(filePath)
+ },
+ (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts b/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
new file mode 100644
index 0000000..f83b640
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+// 未完成
+export function base64ToArrayBuffer(base64 : string) {
+ const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
+ if (!format) {
+ new Error('ERROR_BASE64SRC_PARSE')
+ }
+ if(uni.base64ToArrayBuffer) {
+ return uni.base64ToArrayBuffer(bodyData)
+ } else {
+
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/base64ToPath/index.ts b/src/uni_modules/lime-shared/base64ToPath/index.ts
new file mode 100644
index 0000000..1f14d0a
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToPath/index.ts
@@ -0,0 +1,76 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64: string, filename?: string):Promise {
+ const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
+ console.log('format', format)
+ return new Promise((resolve, reject) => {
+ // #ifdef MP
+ const fs = uni.getFileSystemManager()
+ //自定义文件名
+ if (!filename && !format) {
+ reject(new Error('ERROR_BASE64SRC_PARSE'))
+ }
+ // const time = new Date().getTime();
+ const name = filename || `${new Date().getTime()}.${format}`;
+ let pre = platform()
+ const filePath = `${pre.env.USER_DATA_PATH}/${name}`
+ fs.writeFile({
+ filePath,
+ data: base64.split(',')[1],
+ encoding: 'base64',
+ success() {
+ resolve(filePath)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ // #endif
+
+ // #ifdef H5
+ // mime类型
+ let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
+ //base64 解码
+ let byteString = atob(base64.split(',')[1]);
+ //创建缓冲数组
+ let arrayBuffer = new ArrayBuffer(byteString.length);
+ //创建视图
+ let intArray = new Uint8Array(arrayBuffer);
+ for (let i = 0; i < byteString.length; i++) {
+ intArray[i] = byteString.charCodeAt(i);
+ }
+ resolve(URL.createObjectURL(new Blob([intArray], {
+ type: mimeString
+ })))
+ // #endif
+
+ // #ifdef APP-PLUS
+ const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ bitmap.loadBase64Data(base64, () => {
+ if (!filename && !format) {
+ reject(new Error('ERROR_BASE64SRC_PARSE'))
+ }
+ // const time = new Date().getTime();
+ const name = filename || `${new Date().getTime()}.${format}`;
+ const filePath = `_doc/uniapp_temp/${name}`
+ bitmap.save(filePath, {},
+ () => {
+ bitmap.clear()
+ resolve(filePath)
+ },
+ (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/camelCase/index.ts b/src/uni_modules/lime-shared/camelCase/index.ts
new file mode 100644
index 0000000..78a81c8
--- /dev/null
+++ b/src/uni_modules/lime-shared/camelCase/index.ts
@@ -0,0 +1,21 @@
+/**
+ * 将字符串转换为 camelCase 或 PascalCase 风格的命名约定
+ * @param str 要转换的字符串
+ * @param isPascalCase 指示是否转换为 PascalCase 的布尔值,默认为 false
+ * @returns 转换后的字符串
+ */
+export function camelCase(str: string, isPascalCase: boolean = false): string {
+ // 将字符串分割成单词数组
+ let words: string[] = str.split(/[\s_-]+/);
+
+ // 将数组中的每个单词首字母大写(除了第一个单词)
+ let camelCased: string[] = words.map((word, index) => {
+ if (index === 0 && !isPascalCase) {
+ return word.toLowerCase(); // 第一个单词全小写
+ }
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ });
+
+ // 将数组中的单词拼接成一个字符串
+ return camelCased.join('');
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts b/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
new file mode 100644
index 0000000..22e4416
--- /dev/null
+++ b/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
@@ -0,0 +1,58 @@
+// @ts-nocheck
+// #ifdef MP-ALIPAY
+interface My {
+ SDKVersion: string
+}
+declare var my: My
+// #endif
+
+function compareVersion(v1:string, v2:string) {
+ let a1 = v1.split('.');
+ let a2 = v2.split('.');
+ const len = Math.max(a1.length, a2.length);
+
+ while (a1.length < len) {
+ a1.push('0');
+ }
+ while (a2.length < len) {
+ a2.push('0');
+ }
+
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(a1[i], 10);
+ const num2 = parseInt(a2[i], 10);
+
+ if (num1 > num2) {
+ return 1;
+ }
+ if (num1 < num2) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+function gte(version: string) {
+ let {SDKVersion} = uni.getSystemInfoSync();
+ // #ifdef MP-ALIPAY
+ SDKVersion = my.SDKVersion
+ // #endif
+ return compareVersion(SDKVersion, version) >= 0;
+}
+
+/** 环境是否支持canvas 2d */
+export function canIUseCanvas2d() {
+ // #ifdef MP-WEIXIN
+ return gte('2.9.0');
+ // #endif
+ // #ifdef MP-ALIPAY
+ return gte('2.7.0');
+ // #endif
+ // #ifdef MP-TOUTIAO
+ return gte('1.78.0');
+ // #endif
+ // #ifndef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO
+ return false
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/changelog.md b/src/uni_modules/lime-shared/changelog.md
new file mode 100644
index 0000000..62c3f5b
--- /dev/null
+++ b/src/uni_modules/lime-shared/changelog.md
@@ -0,0 +1,30 @@
+## 0.1.4(2023-09-05)
+- feat: 增加 Hooks `useIntersectionObserver`
+- feat: 增加 `floatAdd`
+- feat: 因为本人插件兼容 vue2 需要使用 `composition-api`,故增加vue文件代码插件的条件编译
+## 0.1.3(2023-08-13)
+- feat: 增加 `camelCase`
+## 0.1.2(2023-07-17)
+- feat: 增加 `getClassStr`
+## 0.1.1(2023-07-06)
+- feat: 增加 `isNumeric`, 区别于 `isNumber`
+## 0.1.0(2023-06-30)
+- fix: `clamp`忘记导出了
+## 0.0.9(2023-06-27)
+- feat: 增加`arrayBufferToFile`
+## 0.0.8(2023-06-19)
+- feat: 增加`createAnimation`、`clamp`
+## 0.0.7(2023-06-08)
+- chore: 更新注释
+## 0.0.6(2023-06-08)
+- chore: 增加`createImage`为`lime-watermark`和`lime-qrcode`提供依赖
+## 0.0.5(2023-06-03)
+- chore: 更新注释
+## 0.0.4(2023-05-22)
+- feat: 增加`range`,`exif`,`selectComponent`
+## 0.0.3(2023-05-08)
+- feat: 增加`fillZero`,`debounce`,`throttle`,`random`
+## 0.0.2(2023-05-05)
+- chore: 更新文档
+## 0.0.1(2023-05-05)
+- 无
diff --git a/src/uni_modules/lime-shared/clamp/index.ts b/src/uni_modules/lime-shared/clamp/index.ts
new file mode 100644
index 0000000..b62565c
--- /dev/null
+++ b/src/uni_modules/lime-shared/clamp/index.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+/**
+ * 将一个值限制在指定的范围内
+ * @param min 最小值
+ * @param max 最大值
+ * @param val 要限制的值
+ * @returns 限制后的值
+ */
+export function clamp(min: number, max: number, val: number): number {
+ return Math.max(min, Math.min(max, val));
+}
+
+
+// console.log(clamp(0, 10, 5)); // 输出: 5(在范围内,不做更改)
+// console.log(clamp(0, 10, -5)); // 输出: 0(小于最小值,被限制为最小值)
+// console.log(clamp(0, 10, 15)); // 输出: 10(大于最大值,被限制为最大值)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/cloneDeep/index.ts b/src/uni_modules/lime-shared/cloneDeep/index.ts
new file mode 100644
index 0000000..ded334d
--- /dev/null
+++ b/src/uni_modules/lime-shared/cloneDeep/index.ts
@@ -0,0 +1,103 @@
+// @ts-nocheck
+/**
+ * 深度克隆一个对象或数组
+ * @param obj 要克隆的对象或数组
+ * @returns 克隆后的对象或数组
+ */
+export function cloneDeep(obj: any): T {
+ // 如果传入的对象为空,返回空
+ if (obj === null) {
+ return null as unknown as T;
+ }
+
+ // 如果传入的对象是 Set 类型,则将其转换为数组,并通过新的 Set 构造函数创建一个新的 Set 对象
+ if (obj instanceof Set) {
+ return new Set([...obj]) as unknown as T;
+ }
+
+ // 如果传入的对象是 Map 类型,则将其转换为数组,并通过新的 Map 构造函数创建一个新的 Map 对象
+ if (obj instanceof Map) {
+ return new Map([...obj]) as unknown as T;
+ }
+
+ // 如果传入的对象是 WeakMap 类型,则直接用传入的 WeakMap 对象进行赋值
+ if (obj instanceof WeakMap) {
+ let weakMap = new WeakMap();
+ weakMap = obj;
+ return weakMap as unknown as T;
+ }
+
+ // 如果传入的对象是 WeakSet 类型,则直接用传入的 WeakSet 对象进行赋值
+ if (obj instanceof WeakSet) {
+ let weakSet = new WeakSet();
+ weakSet = obj;
+ return weakSet as unknown as T;
+ }
+
+ // 如果传入的对象是 RegExp 类型,则通过新的 RegExp 构造函数创建一个新的 RegExp 对象
+ if (obj instanceof RegExp) {
+ return new RegExp(obj) as unknown as T;
+ }
+
+ // 如果传入的对象是 undefined 类型,则返回 undefined
+ if (typeof obj === 'undefined') {
+ return undefined as unknown as T;
+ }
+
+ // 如果传入的对象是数组,则递归调用 cloneDeep 函数对数组中的每个元素进行克隆
+ if (Array.isArray(obj)) {
+ return obj.map(cloneDeep) as unknown as T;
+ }
+
+ // 如果传入的对象是 Date 类型,则通过新的 Date 构造函数创建一个新的 Date 对象
+ if (obj instanceof Date) {
+ return new Date(obj.getTime()) as unknown as T;
+ }
+
+ // 如果传入的对象是普通对象,则使用递归调用 cloneDeep 函数对对象的每个属性进行克隆
+ if (typeof obj === 'object') {
+ const newObj: any = {};
+ for (const [key, value] of Object.entries(obj)) {
+ newObj[key] = cloneDeep(value);
+ }
+ const symbolKeys = Object.getOwnPropertySymbols(obj);
+ for (const key of symbolKeys) {
+ newObj[key] = cloneDeep(obj[key]);
+ }
+ return newObj;
+ }
+
+ // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
+ return obj;
+}
+
+// 示例使用
+
+// // 克隆一个对象
+// const obj = { name: 'John', age: 30 };
+// const clonedObj = cloneDeep(obj);
+
+// console.log(clonedObj); // 输出: { name: 'John', age: 30 }
+// console.log(clonedObj === obj); // 输出: false (副本与原对象是独立的)
+
+// // 克隆一个数组
+// const arr = [1, 2, 3];
+// const clonedArr = cloneDeep(arr);
+
+// console.log(clonedArr); // 输出: [1, 2, 3]
+// console.log(clonedArr === arr); // 输出: false (副本与原数组是独立的)
+
+// // 克隆一个包含嵌套对象的对象
+// const person = {
+// name: 'Alice',
+// age: 25,
+// address: {
+// city: 'New York',
+// country: 'USA',
+// },
+// };
+// const clonedPerson = cloneDeep(person);
+
+// console.log(clonedPerson); // 输出: { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }
+// console.log(clonedPerson === person); // 输出: false (副本与原对象是独立的)
+// console.log(clonedPerson.address === person.address); // 输出: false (嵌套对象的副本也是独立的)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/closest/index.ts b/src/uni_modules/lime-shared/closest/index.ts
new file mode 100644
index 0000000..95804cd
--- /dev/null
+++ b/src/uni_modules/lime-shared/closest/index.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+
+/**
+ * 在给定数组中找到最接近目标数字的元素。
+ * @param arr 要搜索的数字数组。
+ * @param target 目标数字。
+ * @returns 最接近目标数字的数组元素。
+ */
+export function closest(arr: number[], target: number) {
+ return arr.reduce((pre, cur) =>
+ Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
+ );
+}
+
+// 示例
+// // 定义一个数字数组
+// const numbers = [1, 3, 5, 7, 9];
+
+// // 在数组中找到最接近目标数字 6 的元素
+// const closestNumber = closest(numbers, 6);
+
+// console.log(closestNumber); // 输出结果: 5
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createAnimation/index.ts b/src/uni_modules/lime-shared/createAnimation/index.ts
new file mode 100644
index 0000000..5b6e2da
--- /dev/null
+++ b/src/uni_modules/lime-shared/createAnimation/index.ts
@@ -0,0 +1,149 @@
+// @ts-nocheck
+// nvue 需要在节点上设置ref或在export里传入
+// const animation = createAnimation({
+// ref: this.$refs['xxx'],
+// duration: 0,
+// timingFunction: 'linear'
+// })
+// animation.opacity(1).translate(x, y).step({duration})
+// animation.export(ref)
+
+// 抹平nvue 与 uni.createAnimation的使用差距
+// 但是nvue动画太慢~~~无语
+
+
+
+
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+
+type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
+ | 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
+
+interface Styles {
+ [key : string] : any
+}
+
+interface StepConfig {
+ duration?: number
+ timingFunction?: string
+ delay?: number
+ needLayout?: boolean
+ transformOrigin?: string
+}
+interface StepAnimate {
+ styles?: Styles
+ config?: StepConfig
+}
+interface StepAnimates {
+ [key: number]: StepAnimate
+}
+interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
+ ref?: string
+}
+
+type Callback = (time: number) => void
+const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+ 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+ 'translateZ'
+]
+const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
+const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
+
+class LimeAnimation {
+ ref : any
+ context : any
+ options : UniApp.CreateAnimationOptions
+ // stack : any[] = []
+ next : number = 0
+ currentStepAnimates : StepAnimates = {}
+ duration : number = 0
+ constructor(options : CreateAnimationOptions) {
+ const {ref} = options
+ this.ref = ref
+ this.options = options
+ }
+ addAnimate(type : AnimationTypes, args: (string | number)[]) {
+ let aniObj = this.currentStepAnimates[this.next]
+ let stepAnimate:StepAnimate = {}
+ if (!aniObj) {
+ stepAnimate = {styles: {}, config: {}}
+ } else {
+ stepAnimate = aniObj
+ }
+
+ if (animateTypes1.includes(type)) {
+ if (!stepAnimate.styles.transform) {
+ stepAnimate.styles.transform = ''
+ }
+ let unit = ''
+ if (type === 'rotate') {
+ unit = 'deg'
+ }
+ stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
+ } else {
+ stepAnimate.styles[type] = `${args.join(',')}`
+ }
+ this.currentStepAnimates[this.next] = stepAnimate
+ }
+ animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
+ const el = ref || this.ref
+ if (!el) return
+ return new Promise((resolve) => {
+ const time = +new Date()
+ nvueAnimation.transition(el, {
+ styles,
+ ...config
+ }, () => {
+ resolve(+new Date() - time)
+ })
+ })
+ }
+ nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
+ let obj = animates[step]
+ if (obj) {
+ let { styles, config } = obj
+ // this.duration += config.duration
+ this.animateRun(styles, config, ref).then((time: number) => {
+ step += 1
+ this.duration += time
+ this.nextAnimate(animates, step, ref, cb)
+ })
+ } else {
+ this.currentStepAnimates = {}
+ cb && cb(this.duration)
+ }
+ }
+ step(config:StepConfig = {}) {
+ this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+ this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+ this.next++
+ return this
+ }
+ export(ref: any, cb?: Callback) {
+ ref = ref || this.ref
+ if(!ref) return
+ this.duration = 0
+ this.next = 0
+ this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
+ return null
+ }
+}
+
+
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+ LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
+ this.addAnimate(type, args)
+ return this
+ }
+})
+// #endif
+export function createAnimation(options : CreateAnimationOptions) {
+ // #ifndef APP-NVUE
+ // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
+ return uni.createAnimation({ ...options })
+ // #endif
+ // #ifdef APP-NVUE
+ return new LimeAnimation(options)
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createImage/index.ts b/src/uni_modules/lime-shared/createImage/index.ts
new file mode 100644
index 0000000..674b6f5
--- /dev/null
+++ b/src/uni_modules/lime-shared/createImage/index.ts
@@ -0,0 +1,61 @@
+// @ts-nocheck
+import {isBrowser} from '../isBrowser'
+class Image {
+ currentSrc: string | null = null
+ naturalHeight: number = 0
+ naturalWidth: number = 0
+ width: number = 0
+ height: number = 0
+ tagName: string = 'IMG'
+ path: string = ''
+ crossOrigin: string = ''
+ referrerPolicy: string = ''
+ onload: () => void = () => {}
+ onerror: () => void = () => {}
+ complete: boolean = false
+ constructor() {}
+ set src(src: string) {
+ console.log('src', src)
+ if(!src) {
+ return this.onerror()
+ }
+ src = src.replace(/^@\//,'/')
+ this.currentSrc = src
+ uni.getImageInfo({
+ src,
+ success: (res) => {
+ const localReg = /^\.|^\/(?=[^\/])/;
+ // #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
+ res.path = localReg.test(src) ? `/${res.path}` : res.path;
+ // #endif
+ this.complete = true
+ this.path = res.path
+ this.naturalWidth = this.width = res.width
+ this.naturalHeight = this.height = res.height
+ this.onload()
+ },
+ fail: () => {
+ this.onerror()
+ }
+ })
+ }
+ get src() {
+ return this.currentSrc
+ }
+}
+interface UniImage extends WechatMiniprogram.Image {
+ complete?: boolean
+ naturalHeight?: number
+ naturalWidth?: number
+}
+/** 创建用于 canvas 的 img */
+export function createImage(canvas?: any): HTMLImageElement | UniImage {
+ if(canvas && canvas.createImage) {
+ return (canvas as WechatMiniprogram.Canvas).createImage()
+ } else if(this.tagName == 'canvas' && !('toBlob' in this) || canvas && !('toBlob' in canvas)){
+ return new Image()
+ } else if(isBrowser) {
+ return new window.Image()
+ }
+ return new Image()
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/debounce/index.ts b/src/uni_modules/lime-shared/debounce/index.ts
new file mode 100644
index 0000000..5875145
--- /dev/null
+++ b/src/uni_modules/lime-shared/debounce/index.ts
@@ -0,0 +1,38 @@
+// @ts-nocheck
+type Timeout = ReturnType | null;
+/**
+ * 防抖函数,通过延迟一定时间来限制函数的执行频率。
+ * @param fn 要防抖的函数。
+ * @param wait 触发防抖的等待时间,单位为毫秒。
+ * @returns 防抖函数。
+ */
+export function debounce(fn: (...args: any[]) => void, wait = 300) {
+ let timer: Timeout = null; // 用于存储 setTimeout 的标识符的变量
+
+ return function (this: any, ...args: any[]) {
+ if (timer) clearTimeout(timer); // 如果上一个 setTimeout 存在,则清除它
+
+ // 设置一个新的 setTimeout,在指定的等待时间后调用防抖函数
+ timer = setTimeout(() => {
+ fn.apply(this, args); // 使用提供的参数调用原始函数
+ }, wait);
+ };
+};
+
+
+
+// 示例
+// 定义一个函数
+// function saveData(data: string) {
+// // 模拟保存数据的操作
+// console.log(`Saving data: ${data}`);
+// }
+
+// // 创建一个防抖函数,延迟 500 毫秒后调用 saveData 函数
+// const debouncedSaveData = debounce(saveData, 500);
+
+// // 连续调用防抖函数
+// debouncedSaveData('Data 1'); // 不会立即调用 saveData 函数
+// debouncedSaveData('Data 2'); // 不会立即调用 saveData 函数
+
+// 在 500 毫秒后,只会调用一次 saveData 函数,输出结果为 "Saving data: Data 2"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/exif/index.ts b/src/uni_modules/lime-shared/exif/index.ts
new file mode 100644
index 0000000..b67e233
--- /dev/null
+++ b/src/uni_modules/lime-shared/exif/index.ts
@@ -0,0 +1,1056 @@
+// @ts-nocheck
+import { base64ToArrayBuffer } from '../base64ToArrayBuffer';
+import { pathToBase64 } from '../pathToBase64';
+import { isBase64 } from '../isBase64';
+import { isString } from '../isString';
+
+interface File {
+ exifdata : any
+ iptcdata : any
+ xmpdata : any
+ src : string
+}
+class EXIF {
+ isXmpEnabled = false
+ debug = false
+ Tags = {
+ // version tags
+ 0x9000: "ExifVersion", // EXIF version
+ 0xA000: "FlashpixVersion", // Flashpix format version
+
+ // colorspace tags
+ 0xA001: "ColorSpace", // Color space information tag
+
+ // image configuration
+ 0xA002: "PixelXDimension", // Valid width of meaningful image
+ 0xA003: "PixelYDimension", // Valid height of meaningful image
+ 0x9101: "ComponentsConfiguration", // Information about channels
+ 0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel
+
+ // user information
+ 0x927C: "MakerNote", // Any desired information written by the manufacturer
+ 0x9286: "UserComment", // Comments by user
+
+ // related file
+ 0xA004: "RelatedSoundFile", // Name of related sound file
+
+ // date and time
+ 0x9003: "DateTimeOriginal", // Date and time when the original image was generated
+ 0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally
+ 0x9290: "SubsecTime", // Fractions of seconds for DateTime
+ 0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
+ 0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
+
+ // picture-taking conditions
+ 0x829A: "ExposureTime", // Exposure time (in seconds)
+ 0x829D: "FNumber", // F number
+ 0x8822: "ExposureProgram", // Exposure program
+ 0x8824: "SpectralSensitivity", // Spectral sensitivity
+ 0x8827: "ISOSpeedRatings", // ISO speed rating
+ 0x8828: "OECF", // Optoelectric conversion factor
+ 0x9201: "ShutterSpeedValue", // Shutter speed
+ 0x9202: "ApertureValue", // Lens aperture
+ 0x9203: "BrightnessValue", // Value of brightness
+ 0x9204: "ExposureBias", // Exposure bias
+ 0x9205: "MaxApertureValue", // Smallest F number of lens
+ 0x9206: "SubjectDistance", // Distance to subject in meters
+ 0x9207: "MeteringMode", // Metering mode
+ 0x9208: "LightSource", // Kind of light source
+ 0x9209: "Flash", // Flash status
+ 0x9214: "SubjectArea", // Location and area of main subject
+ 0x920A: "FocalLength", // Focal length of the lens in mm
+ 0xA20B: "FlashEnergy", // Strobe energy in BCPS
+ 0xA20C: "SpatialFrequencyResponse", //
+ 0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
+ 0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
+ 0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
+ 0xA214: "SubjectLocation", // Location of subject in image
+ 0xA215: "ExposureIndex", // Exposure index selected on camera
+ 0xA217: "SensingMethod", // Image sensor type
+ 0xA300: "FileSource", // Image source (3 == DSC)
+ 0xA301: "SceneType", // Scene type (1 == directly photographed)
+ 0xA302: "CFAPattern", // Color filter array geometric pattern
+ 0xA401: "CustomRendered", // Special processing
+ 0xA402: "ExposureMode", // Exposure mode
+ 0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual
+ 0xA404: "DigitalZoomRation", // Digital zoom ratio
+ 0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
+ 0xA406: "SceneCaptureType", // Type of scene
+ 0xA407: "GainControl", // Degree of overall image gain adjustment
+ 0xA408: "Contrast", // Direction of contrast processing applied by camera
+ 0xA409: "Saturation", // Direction of saturation processing applied by camera
+ 0xA40A: "Sharpness", // Direction of sharpness processing applied by camera
+ 0xA40B: "DeviceSettingDescription", //
+ 0xA40C: "SubjectDistanceRange", // Distance to subject
+
+ // other tags
+ 0xA005: "InteroperabilityIFDPointer",
+ 0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image
+ }
+ TiffTags = {
+ 0x0100: "ImageWidth",
+ 0x0101: "ImageHeight",
+ 0x8769: "ExifIFDPointer",
+ 0x8825: "GPSInfoIFDPointer",
+ 0xA005: "InteroperabilityIFDPointer",
+ 0x0102: "BitsPerSample",
+ 0x0103: "Compression",
+ 0x0106: "PhotometricInterpretation",
+ 0x0112: "Orientation",
+ 0x0115: "SamplesPerPixel",
+ 0x011C: "PlanarConfiguration",
+ 0x0212: "YCbCrSubSampling",
+ 0x0213: "YCbCrPositioning",
+ 0x011A: "XResolution",
+ 0x011B: "YResolution",
+ 0x0128: "ResolutionUnit",
+ 0x0111: "StripOffsets",
+ 0x0116: "RowsPerStrip",
+ 0x0117: "StripByteCounts",
+ 0x0201: "JPEGInterchangeFormat",
+ 0x0202: "JPEGInterchangeFormatLength",
+ 0x012D: "TransferFunction",
+ 0x013E: "WhitePoint",
+ 0x013F: "PrimaryChromaticities",
+ 0x0211: "YCbCrCoefficients",
+ 0x0214: "ReferenceBlackWhite",
+ 0x0132: "DateTime",
+ 0x010E: "ImageDescription",
+ 0x010F: "Make",
+ 0x0110: "Model",
+ 0x0131: "Software",
+ 0x013B: "Artist",
+ 0x8298: "Copyright"
+ }
+ GPSTags = {
+ 0x0000: "GPSVersionID",
+ 0x0001: "GPSLatitudeRef",
+ 0x0002: "GPSLatitude",
+ 0x0003: "GPSLongitudeRef",
+ 0x0004: "GPSLongitude",
+ 0x0005: "GPSAltitudeRef",
+ 0x0006: "GPSAltitude",
+ 0x0007: "GPSTimeStamp",
+ 0x0008: "GPSSatellites",
+ 0x0009: "GPSStatus",
+ 0x000A: "GPSMeasureMode",
+ 0x000B: "GPSDOP",
+ 0x000C: "GPSSpeedRef",
+ 0x000D: "GPSSpeed",
+ 0x000E: "GPSTrackRef",
+ 0x000F: "GPSTrack",
+ 0x0010: "GPSImgDirectionRef",
+ 0x0011: "GPSImgDirection",
+ 0x0012: "GPSMapDatum",
+ 0x0013: "GPSDestLatitudeRef",
+ 0x0014: "GPSDestLatitude",
+ 0x0015: "GPSDestLongitudeRef",
+ 0x0016: "GPSDestLongitude",
+ 0x0017: "GPSDestBearingRef",
+ 0x0018: "GPSDestBearing",
+ 0x0019: "GPSDestDistanceRef",
+ 0x001A: "GPSDestDistance",
+ 0x001B: "GPSProcessingMethod",
+ 0x001C: "GPSAreaInformation",
+ 0x001D: "GPSDateStamp",
+ 0x001E: "GPSDifferential"
+ }
+ // EXIF 2.3 Spec
+ IFD1Tags = {
+ 0x0100: "ImageWidth",
+ 0x0101: "ImageHeight",
+ 0x0102: "BitsPerSample",
+ 0x0103: "Compression",
+ 0x0106: "PhotometricInterpretation",
+ 0x0111: "StripOffsets",
+ 0x0112: "Orientation",
+ 0x0115: "SamplesPerPixel",
+ 0x0116: "RowsPerStrip",
+ 0x0117: "StripByteCounts",
+ 0x011A: "XResolution",
+ 0x011B: "YResolution",
+ 0x011C: "PlanarConfiguration",
+ 0x0128: "ResolutionUnit",
+ 0x0201: "JpegIFOffset", // When image format is JPEG, this value show offset to JPEG data stored.(aka "ThumbnailOffset" or "JPEGInterchangeFormat")
+ 0x0202: "JpegIFByteCount", // When image format is JPEG, this value shows data size of JPEG image (aka "ThumbnailLength" or "JPEGInterchangeFormatLength")
+ 0x0211: "YCbCrCoefficients",
+ 0x0212: "YCbCrSubSampling",
+ 0x0213: "YCbCrPositioning",
+ 0x0214: "ReferenceBlackWhite"
+ }
+ StringValues = {
+ ExposureProgram: {
+ 0: "Not defined",
+ 1: "Manual",
+ 2: "Normal program",
+ 3: "Aperture priority",
+ 4: "Shutter priority",
+ 5: "Creative program",
+ 6: "Action program",
+ 7: "Portrait mode",
+ 8: "Landscape mode"
+ },
+ MeteringMode: {
+ 0: "Unknown",
+ 1: "Average",
+ 2: "CenterWeightedAverage",
+ 3: "Spot",
+ 4: "MultiSpot",
+ 5: "Pattern",
+ 6: "Partial",
+ 255: "Other"
+ },
+ LightSource: {
+ 0: "Unknown",
+ 1: "Daylight",
+ 2: "Fluorescent",
+ 3: "Tungsten (incandescent light)",
+ 4: "Flash",
+ 9: "Fine weather",
+ 10: "Cloudy weather",
+ 11: "Shade",
+ 12: "Daylight fluorescent (D 5700 - 7100K)",
+ 13: "Day white fluorescent (N 4600 - 5400K)",
+ 14: "Cool white fluorescent (W 3900 - 4500K)",
+ 15: "White fluorescent (WW 3200 - 3700K)",
+ 17: "Standard light A",
+ 18: "Standard light B",
+ 19: "Standard light C",
+ 20: "D55",
+ 21: "D65",
+ 22: "D75",
+ 23: "D50",
+ 24: "ISO studio tungsten",
+ 255: "Other"
+ },
+ Flash: {
+ 0x0000: "Flash did not fire",
+ 0x0001: "Flash fired",
+ 0x0005: "Strobe return light not detected",
+ 0x0007: "Strobe return light detected",
+ 0x0009: "Flash fired, compulsory flash mode",
+ 0x000D: "Flash fired, compulsory flash mode, return light not detected",
+ 0x000F: "Flash fired, compulsory flash mode, return light detected",
+ 0x0010: "Flash did not fire, compulsory flash mode",
+ 0x0018: "Flash did not fire, auto mode",
+ 0x0019: "Flash fired, auto mode",
+ 0x001D: "Flash fired, auto mode, return light not detected",
+ 0x001F: "Flash fired, auto mode, return light detected",
+ 0x0020: "No flash function",
+ 0x0041: "Flash fired, red-eye reduction mode",
+ 0x0045: "Flash fired, red-eye reduction mode, return light not detected",
+ 0x0047: "Flash fired, red-eye reduction mode, return light detected",
+ 0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode",
+ 0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
+ 0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
+ 0x0059: "Flash fired, auto mode, red-eye reduction mode",
+ 0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode",
+ 0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode"
+ },
+ SensingMethod: {
+ 1: "Not defined",
+ 2: "One-chip color area sensor",
+ 3: "Two-chip color area sensor",
+ 4: "Three-chip color area sensor",
+ 5: "Color sequential area sensor",
+ 7: "Trilinear sensor",
+ 8: "Color sequential linear sensor"
+ },
+ SceneCaptureType: {
+ 0: "Standard",
+ 1: "Landscape",
+ 2: "Portrait",
+ 3: "Night scene"
+ },
+ SceneType: {
+ 1: "Directly photographed"
+ },
+ CustomRendered: {
+ 0: "Normal process",
+ 1: "Custom process"
+ },
+ WhiteBalance: {
+ 0: "Auto white balance",
+ 1: "Manual white balance"
+ },
+ GainControl: {
+ 0: "None",
+ 1: "Low gain up",
+ 2: "High gain up",
+ 3: "Low gain down",
+ 4: "High gain down"
+ },
+ Contrast: {
+ 0: "Normal",
+ 1: "Soft",
+ 2: "Hard"
+ },
+ Saturation: {
+ 0: "Normal",
+ 1: "Low saturation",
+ 2: "High saturation"
+ },
+ Sharpness: {
+ 0: "Normal",
+ 1: "Soft",
+ 2: "Hard"
+ },
+ SubjectDistanceRange: {
+ 0: "Unknown",
+ 1: "Macro",
+ 2: "Close view",
+ 3: "Distant view"
+ },
+ FileSource: {
+ 3: "DSC"
+ },
+
+ Components: {
+ 0: "",
+ 1: "Y",
+ 2: "Cb",
+ 3: "Cr",
+ 4: "R",
+ 5: "G",
+ 6: "B"
+ }
+ }
+ enableXmp() {
+ this.isXmpEnabled = true
+ }
+ disableXmp() {
+ this.isXmpEnabled = false;
+ }
+ /**
+ * 获取图片数据
+ * @param img 图片地址
+ * @param callback 回调 返回图片数据
+ * */
+ getData(img : any, callback : Function) {
+ // if (((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement)) && !img.complete)
+ // return false;
+ let file : File = {
+ src: '',
+ exifdata: null,
+ iptcdata: null,
+ xmpdata: null,
+ }
+ if (isBase64(img)) {
+ file.src = img
+ } else if (img.path) {
+ file.src = img.path
+ } else if (isString(img)) {
+ file.src = img
+ } else {
+ return false;
+ }
+
+
+ if (!imageHasData(file)) {
+ getImageData(file, callback);
+ } else {
+ if (callback) {
+ callback.call(file);
+ }
+ }
+ return true;
+ }
+ /**
+ * 获取图片tag
+ * @param img 图片数据
+ * @param tag tag 类型
+ * */
+ getTag(img : File, tag : string) {
+ if (!imageHasData(img)) return;
+ return img.exifdata[tag];
+ }
+ getIptcTag(img : File, tag : string) {
+ if (!imageHasData(img)) return;
+ return img.iptcdata[tag];
+ }
+ getAllTags(img : File) {
+ if (!imageHasData(img)) return {};
+ let a,
+ data = img.exifdata,
+ tags = {};
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ tags[a] = data[a];
+ }
+ }
+ return tags;
+ }
+ getAllIptcTags(img : File) {
+ if (!imageHasData(img)) return {};
+ let a,
+ data = img.iptcdata,
+ tags = {};
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ tags[a] = data[a];
+ }
+ }
+ return tags;
+ }
+ pretty(img : File) {
+ if (!imageHasData(img)) return "";
+ let a,
+ data = img.exifdata,
+ strPretty = "";
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ if (typeof data[a] == "object") {
+ if (data[a] instanceof Number) {
+ strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a]
+ .denominator + "]\r\n";
+ } else {
+ strPretty += a + " : [" + data[a].length + " values]\r\n";
+ }
+ } else {
+ strPretty += a + " : " + data[a] + "\r\n";
+ }
+ }
+ }
+ return strPretty;
+ }
+ readFromBinaryFile(file: ArrayBuffer) {
+ return findEXIFinJPEG(file);
+ }
+}
+
+export const exif = new EXIF()
+// export function getData(img, callback) {
+// const exif = new EXIF()
+// exif.getData(img, callback)
+// }
+
+// export default {getData}
+const ExifTags = exif.Tags
+const TiffTags = exif.TiffTags
+const IFD1Tags = exif.IFD1Tags
+const GPSTags = exif.GPSTags
+const StringValues = exif.StringValues
+
+
+function imageHasData(img : File) : boolean {
+ return !!(img.exifdata);
+}
+
+function objectURLToBlob(url : string, callback : Function) {
+ try {
+ const http = new XMLHttpRequest();
+ http.open("GET", url, true);
+ http.responseType = "blob";
+ http.onload = function (e) {
+ if (this.status == 200 || this.status === 0) {
+ callback(this.response);
+ }
+ };
+ http.send();
+ } catch (e) {
+ console.warn(e)
+ }
+}
+
+
+function getImageData(img : File, callback : Function) {
+ function handleBinaryFile(binFile: ArrayBuffer) {
+ const data = findEXIFinJPEG(binFile);
+ img.exifdata = data ?? {};
+ const iptcdata = findIPTCinJPEG(binFile);
+ img.iptcdata = iptcdata ?? {};
+ if (exif.isXmpEnabled) {
+ const xmpdata = findXMPinJPEG(binFile);
+ img.xmpdata = xmpdata ?? {};
+ }
+ if (callback) {
+ callback.call(img);
+ }
+ }
+
+ if (img.src) {
+ if (/^data\:/i.test(img.src)) { // Data URI
+ // var arrayBuffer = base64ToArrayBuffer(img.src);
+ handleBinaryFile(base64ToArrayBuffer(img.src));
+
+ } else if (/^blob\:/i.test(img.src) && typeof FileReader !== 'undefined') { // Object URL
+ var fileReader = new FileReader();
+ fileReader.onload = function (e) {
+ handleBinaryFile(e.target.result);
+ };
+ objectURLToBlob(img.src, function (blob : Blob) {
+ fileReader.readAsArrayBuffer(blob);
+ });
+ } else if (typeof XMLHttpRequest !== 'undefined') {
+ var http = new XMLHttpRequest();
+ http.onload = function () {
+ if (this.status == 200 || this.status === 0) {
+ handleBinaryFile(http.response);
+ } else {
+ throw "Could not load image";
+ }
+ http = null;
+ };
+ http.open("GET", img.src, true);
+ http.responseType = "arraybuffer";
+ http.send(null);
+ } else {
+ pathToBase64(img.src).then(res => {
+ handleBinaryFile(base64ToArrayBuffer(res));
+ })
+ }
+ } else if (typeof FileReader !== 'undefined' && self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
+ var fileReader = new FileReader();
+ fileReader.onload = function (e : any) {
+ if (exif.debug) console.log("Got file of length " + e.target.result.byteLength);
+ handleBinaryFile(e.target.result);
+ };
+
+ fileReader.readAsArrayBuffer(img);
+ }
+}
+
+function findEXIFinJPEG(file: ArrayBuffer) {
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength,
+ marker;
+
+ while (offset < length) {
+ if (dataView.getUint8(offset) != 0xFF) {
+ if (exif.debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(
+ offset));
+ return false; // not a valid marker, something is wrong
+ }
+
+ marker = dataView.getUint8(offset + 1);
+ if (exif.debug) console.log(marker);
+
+ // we could implement handling for other markers here,
+ // but we're only looking for 0xFFE1 for EXIF data
+
+ if (marker == 225) {
+ if (exif.debug) console.log("Found 0xFFE1 marker");
+
+ return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
+
+ // offset += 2 + file.getShortAt(offset+2, true);
+
+ } else {
+ offset += 2 + dataView.getUint16(offset + 2);
+ }
+
+ }
+
+}
+
+function findIPTCinJPEG(file: ArrayBuffer) {
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength;
+
+
+ const isFieldSegmentStart = function (dataView, offset: number) {
+ return (
+ dataView.getUint8(offset) === 0x38 &&
+ dataView.getUint8(offset + 1) === 0x42 &&
+ dataView.getUint8(offset + 2) === 0x49 &&
+ dataView.getUint8(offset + 3) === 0x4D &&
+ dataView.getUint8(offset + 4) === 0x04 &&
+ dataView.getUint8(offset + 5) === 0x04
+ );
+ };
+
+ while (offset < length) {
+
+ if (isFieldSegmentStart(dataView, offset)) {
+
+ // Get the length of the name header (which is padded to an even number of bytes)
+ var nameHeaderLength = dataView.getUint8(offset + 7);
+ if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1;
+ // Check for pre photoshop 6 format
+ if (nameHeaderLength === 0) {
+ // Always 4
+ nameHeaderLength = 4;
+ }
+
+ var startOffset = offset + 8 + nameHeaderLength;
+ var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);
+
+ return readIPTCData(file, startOffset, sectionLength);
+
+ break;
+
+ }
+
+
+ // Not the marker, continue searching
+ offset++;
+
+ }
+
+}
+
+const IptcFieldMap = {
+ 0x78: 'caption',
+ 0x6E: 'credit',
+ 0x19: 'keywords',
+ 0x37: 'dateCreated',
+ 0x50: 'byline',
+ 0x55: 'bylineTitle',
+ 0x7A: 'captionWriter',
+ 0x69: 'headline',
+ 0x74: 'copyright',
+ 0x0F: 'category'
+};
+
+function readIPTCData(file: ArrayBuffer, startOffset: number, sectionLength: number) {
+ const dataView = new DataView(file);
+ let data = {};
+ let fieldValue, fieldName, dataSize, segmentType, segmentSize;
+ let segmentStartPos = startOffset;
+ while (segmentStartPos < startOffset + sectionLength) {
+ if (dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos + 1) === 0x02) {
+ segmentType = dataView.getUint8(segmentStartPos + 2);
+ if (segmentType in IptcFieldMap) {
+ dataSize = dataView.getInt16(segmentStartPos + 3);
+ segmentSize = dataSize + 5;
+ fieldName = IptcFieldMap[segmentType];
+ fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize);
+ // Check if we already stored a value with this name
+ if (data.hasOwnProperty(fieldName)) {
+ // Value already stored with this name, create multivalue field
+ if (data[fieldName] instanceof Array) {
+ data[fieldName].push(fieldValue);
+ } else {
+ data[fieldName] = [data[fieldName], fieldValue];
+ }
+ } else {
+ data[fieldName] = fieldValue;
+ }
+ }
+
+ }
+ segmentStartPos++;
+ }
+ return data;
+}
+
+function readTags(file: DataView, tiffStart: number, dirStart: number, strings: any[], bigEnd: number) {
+ let entries = file.getUint16(dirStart, !bigEnd),
+ tags = {},
+ entryOffset, tag;
+
+ for (let i = 0; i < entries; i++) {
+ entryOffset = dirStart + i * 12 + 2;
+ tag = strings[file.getUint16(entryOffset, !bigEnd)];
+ if (!tag && exif.debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd));
+ tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
+ }
+ return tags;
+}
+
+function readTagValue(file: DataView, entryOffset: number, tiffStart: number, dirStart: number, bigEnd: number) {
+ let type = file.getUint16(entryOffset + 2, !bigEnd),
+ numValues = file.getUint32(entryOffset + 4, !bigEnd),
+ valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart,
+ offset,
+ vals, val, n,
+ numerator, denominator;
+
+ switch (type) {
+ case 1: // byte, 8-bit unsigned int
+ case 7: // undefined, 8-bit byte, value depending on field
+ if (numValues == 1) {
+ return file.getUint8(entryOffset + 8, !bigEnd);
+ } else {
+ offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint8(offset + n);
+ }
+ return vals;
+ }
+
+ case 2: // ascii, 8-bit byte
+ offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+ return getStringFromDB(file, offset, numValues - 1);
+
+ case 3: // short, 16 bit int
+ if (numValues == 1) {
+ return file.getUint16(entryOffset + 8, !bigEnd);
+ } else {
+ offset = numValues > 2 ? valueOffset : (entryOffset + 8);
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint16(offset + 2 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 4: // long, 32 bit int
+ if (numValues == 1) {
+ return file.getUint32(entryOffset + 8, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 5: // rational = two long values, first is numerator, second is denominator
+ if (numValues == 1) {
+ numerator = file.getUint32(valueOffset, !bigEnd);
+ denominator = file.getUint32(valueOffset + 4, !bigEnd);
+ val = new Number(numerator / denominator);
+ val.numerator = numerator;
+ val.denominator = denominator;
+ return val;
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ numerator = file.getUint32(valueOffset + 8 * n, !bigEnd);
+ denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd);
+ vals[n] = new Number(numerator / denominator);
+ vals[n].numerator = numerator;
+ vals[n].denominator = denominator;
+ }
+ return vals;
+ }
+
+ case 9: // slong, 32 bit signed int
+ if (numValues == 1) {
+ return file.getInt32(entryOffset + 8, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 10: // signed rational, two slongs, first is numerator, second is denominator
+ if (numValues == 1) {
+ return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 *
+ n, !bigEnd);
+ }
+ return vals;
+ }
+ }
+}
+/**
+ * Given an IFD (Image File Directory) start offset
+ * returns an offset to next IFD or 0 if it's the last IFD.
+ */
+function getNextIFDOffset(dataView: DataView, dirStart: number, bigEnd: number) {
+ //the first 2bytes means the number of directory entries contains in this IFD
+ var entries = dataView.getUint16(dirStart, !bigEnd);
+
+ // After last directory entry, there is a 4bytes of data,
+ // it means an offset to next IFD.
+ // If its value is '0x00000000', it means this is the last IFD and there is no linked IFD.
+
+ return dataView.getUint32(dirStart + 2 + entries * 12, !bigEnd); // each entry is 12 bytes long
+}
+
+function readThumbnailImage(dataView: DataView, tiffStart: number, firstIFDOffset: number, bigEnd: number) {
+ // get the IFD1 offset
+ const IFD1OffsetPointer = getNextIFDOffset(dataView, tiffStart + firstIFDOffset, bigEnd);
+
+ if (!IFD1OffsetPointer) {
+ // console.log('******** IFD1Offset is empty, image thumb not found ********');
+ return {};
+ } else if (IFD1OffsetPointer > dataView.byteLength) { // this should not happen
+ // console.log('******** IFD1Offset is outside the bounds of the DataView ********');
+ return {};
+ }
+ // console.log('******* thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer);
+
+ let thumbTags : any = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd)
+
+ // EXIF 2.3 specification for JPEG format thumbnail
+
+ // If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG.
+ // Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail
+ // by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag.
+ // Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that
+ // JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later.
+
+ if (thumbTags['Compression'] && typeof Blob !== 'undefined') {
+ // console.log('Thumbnail image found!');
+
+ switch (thumbTags['Compression']) {
+ case 6:
+ // console.log('Thumbnail image format is JPEG');
+ if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) {
+ // extract the thumbnail
+ var tOffset = tiffStart + thumbTags.JpegIFOffset;
+ var tLength = thumbTags.JpegIFByteCount;
+ thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], {
+ type: 'image/jpeg'
+ });
+ }
+ break;
+
+ case 1:
+ console.log("Thumbnail image format is TIFF, which is not implemented.");
+ break;
+ default:
+ console.log("Unknown thumbnail image format '%s'", thumbTags['Compression']);
+ }
+ } else if (thumbTags['PhotometricInterpretation'] == 2) {
+ console.log("Thumbnail image format is RGB, which is not implemented.");
+ }
+ return thumbTags;
+}
+
+function getStringFromDB(buffer: DataView, start: number, length: number) {
+ let outstr = "";
+ for (let n = start; n < start + length; n++) {
+ outstr += String.fromCharCode(buffer.getUint8(n));
+ }
+ return outstr;
+}
+
+function readEXIFData(file: DataView, start: number) {
+ if (getStringFromDB(file, start, 4) != "Exif") {
+ if (exif.debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));
+ return false;
+ }
+
+ let bigEnd,
+ tags, tag,
+ exifData, gpsData,
+ tiffOffset = start + 6;
+
+ // test for TIFF validity and endianness
+ if (file.getUint16(tiffOffset) == 0x4949) {
+ bigEnd = false;
+ } else if (file.getUint16(tiffOffset) == 0x4D4D) {
+ bigEnd = true;
+ } else {
+ if (exif.debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
+ return false;
+ }
+
+ if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) {
+ if (exif.debug) console.log("Not valid TIFF data! (no 0x002A)");
+ return false;
+ }
+
+ const firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);
+
+ if (firstIFDOffset < 0x00000008) {
+ if (exif.debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4,
+ !bigEnd));
+ return false;
+ }
+
+ tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);
+
+ if (tags.ExifIFDPointer) {
+ exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);
+ for (tag in exifData) {
+ switch (tag) {
+ case "LightSource":
+ case "Flash":
+ case "MeteringMode":
+ case "ExposureProgram":
+ case "SensingMethod":
+ case "SceneCaptureType":
+ case "SceneType":
+ case "CustomRendered":
+ case "WhiteBalance":
+ case "GainControl":
+ case "Contrast":
+ case "Saturation":
+ case "Sharpness":
+ case "SubjectDistanceRange":
+ case "FileSource":
+ exifData[tag] = StringValues[tag][exifData[tag]];
+ break;
+
+ case "ExifVersion":
+ case "FlashpixVersion":
+ exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2],
+ exifData[tag][3]);
+ break;
+
+ case "ComponentsConfiguration":
+ exifData[tag] =
+ StringValues.Components[exifData[tag][0]] +
+ StringValues.Components[exifData[tag][1]] +
+ StringValues.Components[exifData[tag][2]] +
+ StringValues.Components[exifData[tag][3]];
+ break;
+ }
+ tags[tag] = exifData[tag];
+ }
+ }
+
+ if (tags.GPSInfoIFDPointer) {
+ gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
+ for (tag in gpsData) {
+ switch (tag) {
+ case "GPSVersionID":
+ gpsData[tag] = gpsData[tag][0] +
+ "." + gpsData[tag][1] +
+ "." + gpsData[tag][2] +
+ "." + gpsData[tag][3];
+ break;
+ }
+ tags[tag] = gpsData[tag];
+ }
+ }
+
+ // extract thumbnail
+ tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd);
+
+ return tags;
+}
+
+function findXMPinJPEG(file: ArrayBuffer) {
+
+ if (!('DOMParser' in self)) {
+ // console.warn('XML parsing not supported without DOMParser');
+ return;
+ }
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength,
+ dom = new DOMParser();
+
+ while (offset < (length - 4)) {
+ if (getStringFromDB(dataView, offset, 4) == "http") {
+ const startOffset = offset - 1;
+ const sectionLength = dataView.getUint16(offset - 2) - 1;
+ let xmpString = getStringFromDB(dataView, startOffset, sectionLength)
+ const xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8;
+ xmpString = xmpString.substring(xmpString.indexOf(' 0) {
+ json['@attributes'] = {};
+ for (var j = 0; j < xml.attributes.length; j++) {
+ var attribute = xml.attributes.item(j);
+ json['@attributes'][attribute.nodeName] = attribute.nodeValue;
+ }
+ }
+ } else if (xml.nodeType == 3) { // text node
+ return xml.nodeValue;
+ }
+
+ // deal with children
+ if (xml.hasChildNodes()) {
+ for (var i = 0; i < xml.childNodes.length; i++) {
+ var child = xml.childNodes.item(i);
+ var nodeName = child.nodeName;
+ if (json[nodeName] == null) {
+ json[nodeName] = xml2json(child);
+ } else {
+ if (json[nodeName].push == null) {
+ var old = json[nodeName];
+ json[nodeName] = [];
+ json[nodeName].push(old);
+ }
+ json[nodeName].push(xml2json(child));
+ }
+ }
+ }
+
+ return json;
+}
+
+function xml2Object(xml: any) {
+ try {
+ var obj = {};
+ if (xml.children.length > 0) {
+ for (var i = 0; i < xml.children.length; i++) {
+ var item = xml.children.item(i);
+ var attributes = item.attributes;
+ for (var idx in attributes) {
+ var itemAtt = attributes[idx];
+ var dataKey = itemAtt.nodeName;
+ var dataValue = itemAtt.nodeValue;
+
+ if (dataKey !== undefined) {
+ obj[dataKey] = dataValue;
+ }
+ }
+ var nodeName = item.nodeName;
+
+ if (typeof (obj[nodeName]) == "undefined") {
+ obj[nodeName] = xml2json(item);
+ } else {
+ if (typeof (obj[nodeName].push) == "undefined") {
+ var old = obj[nodeName];
+
+ obj[nodeName] = [];
+ obj[nodeName].push(old);
+ }
+ obj[nodeName].push(xml2json(item));
+ }
+ }
+ } else {
+ obj = xml.textContent;
+ }
+ return obj;
+ } catch (e) {
+ console.log(e.message);
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/fillZero/index.ts b/src/uni_modules/lime-shared/fillZero/index.ts
new file mode 100644
index 0000000..9952c45
--- /dev/null
+++ b/src/uni_modules/lime-shared/fillZero/index.ts
@@ -0,0 +1,11 @@
+// @ts-nocheck
+/**
+ * 在数字前填充零,返回字符串形式的结果
+ * @param number 要填充零的数字
+ * @param length 填充零后的字符串长度,默认为2
+ * @returns 填充零后的字符串
+ */
+export function fillZero(number: number, length: number = 2): string {
+ // 将数字转换为字符串,然后使用 padStart 方法填充零到指定长度
+ return `${number}`.padStart(length, '0');
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/floatAdd/index.ts b/src/uni_modules/lime-shared/floatAdd/index.ts
new file mode 100644
index 0000000..aba4774
--- /dev/null
+++ b/src/uni_modules/lime-shared/floatAdd/index.ts
@@ -0,0 +1,36 @@
+import {isNumber} from '../isNumber'
+/**
+ * 返回两个浮点数相加的结果
+ * @param num1 第一个浮点数
+ * @param num2 第二个浮点数
+ * @returns 两个浮点数的相加结果
+ */
+export function floatAdd(num1: number, num2: number): number {
+ // 检查 num1 和 num2 是否为数字类型
+ if (!(isNumber(num1) || isNumber(num2))) {
+ console.warn('Please pass in the number type');
+ return NaN;
+ }
+
+ let r1: number, r2: number, m: number;
+
+ try {
+ // 获取 num1 小数点后的位数
+ r1 = num1.toString().split('.')[1].length;
+ } catch (error) {
+ r1 = 0;
+ }
+
+ try {
+ // 获取 num2 小数点后的位数
+ r2 = num2.toString().split('.')[1].length;
+ } catch (error) {
+ r2 = 0;
+ }
+
+ // 计算需要扩大的倍数
+ m = Math.pow(10, Math.max(r1, r2));
+
+ // 返回相加结果
+ return (num1 * m + num2 * m) / m;
+}
diff --git a/src/uni_modules/lime-shared/getClassStr/index.ts b/src/uni_modules/lime-shared/getClassStr/index.ts
new file mode 100644
index 0000000..c3c62ac
--- /dev/null
+++ b/src/uni_modules/lime-shared/getClassStr/index.ts
@@ -0,0 +1,27 @@
+// @ts-nocheck
+/**
+ * 获取对象的类名字符串
+ * @param obj - 需要处理的对象
+ * @returns 由对象属性作为类名组成的字符串
+ */
+export function getClassStr(obj: T): string {
+ let classNames: string[] = [];
+
+ // 遍历对象的属性
+ for (let key in obj) {
+ // 检查属性确实属于对象自身且其值为true
+ if ((obj as any).hasOwnProperty(key) && obj[key]) {
+ // 将属性名添加到类名数组中
+ classNames.push(key);
+ }
+ }
+
+ // 将类名数组用空格连接成字符串并返回
+ return classNames.join(' ');
+}
+
+
+// 示例
+// const obj = { foo: true, bar: false, baz: true };
+// const classNameStr = getClassStr(obj);
+// console.log(classNameStr); // 输出: "foo baz"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getCurrentPage/index.ts b/src/uni_modules/lime-shared/getCurrentPage/index.ts
new file mode 100644
index 0000000..79ecac8
--- /dev/null
+++ b/src/uni_modules/lime-shared/getCurrentPage/index.ts
@@ -0,0 +1,6 @@
+// @ts-nocheck
+/** 获取当前页 */
+export const getCurrentPage = () => {
+ const pages = getCurrentPages();
+ return pages[pages.length - 1] //as T & WechatMiniprogram.Page.TrivialInstance;
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getLocalFilePath/index.ts b/src/uni_modules/lime-shared/getLocalFilePath/index.ts
new file mode 100644
index 0000000..8d6a68c
--- /dev/null
+++ b/src/uni_modules/lime-shared/getLocalFilePath/index.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+export const getLocalFilePath = (path: string) => {
+ if(typeof plus == 'undefined') return path
+ if(/^(_www|_doc|_documents|_downloads|file:\/\/|\/storage\/emulated\/0\/)/.test(path)) return path
+ if (/^\//.test(path)) {
+ const localFilePath = plus.io.convertAbsoluteFileSystem(path)
+ if (localFilePath !== path) {
+ return localFilePath
+ } else {
+ path = path.slice(1)
+ }
+ }
+ return '_www/' + path
+}
diff --git a/src/uni_modules/lime-shared/getRect/index.ts b/src/uni_modules/lime-shared/getRect/index.ts
new file mode 100644
index 0000000..9763ee2
--- /dev/null
+++ b/src/uni_modules/lime-shared/getRect/index.ts
@@ -0,0 +1,86 @@
+// @ts-nocheck
+
+// #ifdef APP-NVUE
+// 当编译环境是 APP-NVUE 时,引入 uni.requireNativePlugin('dom'),具体插件用途未知
+const dom = uni.requireNativePlugin('dom')
+// #endif
+
+interface RectOptions {
+ /**
+ * 上下文
+ */
+ context ?: any // ComponentInternalInstance 类型,用于指定上下文
+
+ /**
+ * 是否需要获取所有节点,nvue 环境下不支持
+ */
+ needAll ?: boolean,
+
+ /**
+ * 节点引用对象,类型为 UniNamespace.NodesRef
+ */
+ nodes ?: UniNamespace.NodesRef
+
+ /**
+ * 节点引用对象的键,类型为 UniNamespace.NodesRef 中的某个键
+ */
+ type ?: keyof UniNamespace.NodesRef
+}
+
+/**
+ * 获取节点信息
+ * @param selector 选择器字符串
+ * @param options RectOptions 对象,用于配置选项
+ * @returns 包含节点信息的 Promise 对象
+ */
+export function getRect(selector : string, options : RectOptions = {}) {
+ // #ifndef APP-NVUE
+ const typeDefault = 'boundingClientRect'
+ let { context, needAll, type = typeDefault } = options
+ // #endif
+
+ // #ifdef MP || VUE2
+ if (context.proxy) context = context.proxy
+ // #endif
+
+ return new Promise((resolve, reject) => {
+ // #ifndef APP-NVUE
+ const dom = uni.createSelectorQuery().in(context)[needAll ? 'selectAll' : 'select'](selector);
+ const result = (rect: UniNamespace.NodeInfo) => {
+ if (rect) {
+ resolve(rect)
+ } else {
+ reject('no rect')
+ }
+ }
+ if (type == typeDefault) {
+ dom[type](result).exec()
+ } else {
+ dom[type]({
+ node: true,
+ size: true,
+ rect: true
+ }, result).exec()
+ }
+ // #endif
+ // #ifdef APP-NVUE
+ let { context } = options
+ if (/#|\./.test(selector) && context.refs) {
+ selector = selector.replace(/#|\./, '')
+ if (context.refs[selector]) {
+ selector = context.refs[selector]
+ if(Array.isArray(selector)) {
+ selector = selector[0]
+ }
+ }
+ }
+ dom.getComponentRect(selector, (res) => {
+ if (res.size) {
+ resolve(res.size)
+ } else {
+ reject('no rect')
+ }
+ })
+ // #endif
+ });
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getStyleStr/index.ts b/src/uni_modules/lime-shared/getStyleStr/index.ts
new file mode 100644
index 0000000..33decd5
--- /dev/null
+++ b/src/uni_modules/lime-shared/getStyleStr/index.ts
@@ -0,0 +1,30 @@
+// @ts-nocheck
+interface CSSProperties {
+ [key: string]: string | number
+}
+/**
+ * 将字符串转换为带有连字符分隔的小写形式
+ * @param key - 要转换的字符串
+ * @returns 转换后的字符串
+ */
+export function toLowercaseSeparator(key: string) {
+ return key.replace(/([A-Z])/g, '-$1').toLowerCase();
+}
+
+/**
+ * 获取样式对象对应的样式字符串
+ * @param style - CSS样式对象
+ * @returns 由非空有效样式属性键值对组成的字符串
+ */
+export function getStyleStr(style: CSSProperties): string {
+ return Object.keys(style)
+ .filter(key => style[key] !== undefined && style[key] !== null && style[key] !== '')
+ .map((key: string) => `${toLowercaseSeparator(key)}: ${style[key]};`)
+ .join(' ');
+}
+
+// 示例
+// const style = { color: 'red', fontSize: '16px', backgroundColor: '', border: null };
+// const styleStr = getStyleStr(style);
+// console.log(styleStr);
+// 输出: "color: red; font-size: 16px;"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/hasOwn/index.ts b/src/uni_modules/lime-shared/hasOwn/index.ts
new file mode 100644
index 0000000..7317879
--- /dev/null
+++ b/src/uni_modules/lime-shared/hasOwn/index.ts
@@ -0,0 +1,30 @@
+// @ts-nocheck
+const hasOwnProperty = Object.prototype.hasOwnProperty
+/**
+ * 检查对象或数组是否具有指定的属性或键
+ * @param obj 要检查的对象或数组
+ * @param key 指定的属性或键
+ * @returns 如果对象或数组具有指定的属性或键,则返回true;否则返回false
+ */
+export function hasOwn(obj: Object | Array, key: string): boolean {
+ return hasOwnProperty.call(obj, key);
+}
+
+// 示例
+// const obj = { name: 'John', age: 30 };
+
+// if (hasOwn(obj, 'name')) {
+// console.log("对象具有 'name' 属性");
+// } else {
+// console.log("对象不具有 'name' 属性");
+// }
+// // 输出: 对象具有 'name' 属性
+
+// const arr = [1, 2, 3];
+
+// if (hasOwn(arr, 'length')) {
+// console.log("数组具有 'length' 属性");
+// } else {
+// console.log("数组不具有 'length' 属性");
+// }
+// 输出: 数组具有 'length' 属性
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/index.ts b/src/uni_modules/lime-shared/index.ts
new file mode 100644
index 0000000..8ffb34d
--- /dev/null
+++ b/src/uni_modules/lime-shared/index.ts
@@ -0,0 +1,43 @@
+// @ts-nocheck
+// validator
+export * from './isString'
+export * from './isNumber'
+export * from './isNumeric'
+export * from './isDef'
+export * from './isFunction'
+export * from './isObject'
+export * from './isPromise'
+export * from './isBase64'
+
+export * from './hasOwn'
+
+// 单位转换
+export * from './addUnit'
+export * from './unitConvert'
+export * from './toNumber'
+
+export * from './random'
+export * from './range'
+export * from './fillZero'
+
+// image
+export * from './base64ToPath'
+export * from './pathToBase64'
+export * from './exif'
+
+// canvas
+export * from './canIUseCanvas2d'
+
+// page
+export * from './getCurrentPage'
+
+// dom
+export * from './getRect'
+export * from './selectComponent'
+export * from './createAnimation'
+
+// delay
+export * from './sleep'
+export * from './debounce'
+export * from './throttle'
+
diff --git a/src/uni_modules/lime-shared/isBase64/index.ts b/src/uni_modules/lime-shared/isBase64/index.ts
new file mode 100644
index 0000000..44d0f6d
--- /dev/null
+++ b/src/uni_modules/lime-shared/isBase64/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+/**
+ * 判断给定的路径是否为Base64编码的图像路径
+ * @param path 图像路径
+ * @returns 如果路径是Base64编码,则返回true;否则返回false
+ */
+export const isBase64 = (path: string): boolean => {
+ return /^data:image\/(\w+);base64/.test(path);
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isBrowser/index.ts b/src/uni_modules/lime-shared/isBrowser/index.ts
new file mode 100644
index 0000000..241c7f7
--- /dev/null
+++ b/src/uni_modules/lime-shared/isBrowser/index.ts
@@ -0,0 +1,2 @@
+// @ts-nocheck
+export const isBrowser = typeof window !== 'undefined';
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isDef/index.ts b/src/uni_modules/lime-shared/isDef/index.ts
new file mode 100644
index 0000000..029407e
--- /dev/null
+++ b/src/uni_modules/lime-shared/isDef/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否已定义(不为 undefined)且不为 null
+ * @param value 要检查的值
+ * @returns 如果值已定义且不为 null,则返回 true;否则返回 false
+ */
+export function isDef(value: unknown): boolean {
+ return value !== undefined && value !== null;
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isFunction/index.ts b/src/uni_modules/lime-shared/isFunction/index.ts
new file mode 100644
index 0000000..981442d
--- /dev/null
+++ b/src/uni_modules/lime-shared/isFunction/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为函数类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是函数类型,则返回 true;否则返回 false
+ */
+export const isFunction = (val: unknown): val is Function =>
+ typeof val === 'function';
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isNumber/index.ts b/src/uni_modules/lime-shared/isNumber/index.ts
new file mode 100644
index 0000000..2feff2f
--- /dev/null
+++ b/src/uni_modules/lime-shared/isNumber/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为数字类型
+ * @param value 要检查的值,可以是 number 类型或 string 类型的数字
+ * @returns 如果值是数字类型且不是 NaN,则返回 true;否则返回 false
+ */
+export function isNumber(value: number | string): boolean {
+ return typeof value === 'number' && !isNaN(value);
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isNumeric/index.ts b/src/uni_modules/lime-shared/isNumeric/index.ts
new file mode 100644
index 0000000..5ee60ba
--- /dev/null
+++ b/src/uni_modules/lime-shared/isNumeric/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为数字类型或表示数字的字符串
+ * @param value 要检查的值,可以是 string 类型或 number 类型
+ * @returns 如果值是数字类型或表示数字的字符串,则返回 true;否则返回 false
+ */
+export function isNumeric(value: string | number): boolean {
+ return /^(-)?\d+(\.\d+)?$/.test(value);
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isObject/index.ts b/src/uni_modules/lime-shared/isObject/index.ts
new file mode 100644
index 0000000..17234c9
--- /dev/null
+++ b/src/uni_modules/lime-shared/isObject/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为对象类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是对象类型,则返回 true;否则返回 false
+ */
+export const isObject = (val : unknown) : val is Record =>
+ val !== null && typeof val === 'object';
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isPromise/index.ts b/src/uni_modules/lime-shared/isPromise/index.ts
new file mode 100644
index 0000000..63847cd
--- /dev/null
+++ b/src/uni_modules/lime-shared/isPromise/index.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+import {isFunction} from '../isFunction'
+import {isObject} from '../isObject'
+/**
+ * 检查一个值是否为 Promise 类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是 Promise 类型,则返回 true;否则返回 false
+ */
+export const isPromise = (val: unknown): val is Promise => {
+ // 使用 isObject 函数判断值是否为对象类型
+ // 使用 isFunction 函数判断值是否具有 then 方法和 catch 方法
+ return isObject(val) && isFunction(val.then) && isFunction(val.catch);
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/isString/index.ts b/src/uni_modules/lime-shared/isString/index.ts
new file mode 100644
index 0000000..a130eb2
--- /dev/null
+++ b/src/uni_modules/lime-shared/isString/index.ts
@@ -0,0 +1,7 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为字符串类型
+ * @param str 要检查的值
+ * @returns 如果值的类型是字符串类型,则返回 true;否则返回 false
+ */
+export const isString = (str: unknown): str is string => typeof str === 'string';
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/kebabCase/index.ts b/src/uni_modules/lime-shared/kebabCase/index.ts
new file mode 100644
index 0000000..fa0e4b2
--- /dev/null
+++ b/src/uni_modules/lime-shared/kebabCase/index.ts
@@ -0,0 +1,17 @@
+// export function toLowercaseSeparator(key: string) {
+// return key.replace(/([A-Z])/g, '-$1').toLowerCase();
+// }
+
+/**
+ * 将字符串转换为指定连接符的命名约定
+ * @param str 要转换的字符串
+ * @param separator 指定的连接符,默认为 "-"
+ * @returns 转换后的字符串
+ */
+export function kebabCase(str: string, separator: string = "-"): string {
+ return str
+ .replace(/[A-Z]/g, match => `${separator}${match.toLowerCase()}`) // 将大写字母替换为连接符加小写字母
+ .replace(/[\s_-]+/g, separator) // 将空格、下划线和短横线替换为指定连接符
+ .replace(new RegExp(`^${separator}|${separator}$`, "g"), "") // 删除开头和结尾的连接符
+ .toLowerCase(); // 将结果转换为全小写
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/package.json b/src/uni_modules/lime-shared/package.json
new file mode 100644
index 0000000..2e000c9
--- /dev/null
+++ b/src/uni_modules/lime-shared/package.json
@@ -0,0 +1,83 @@
+{
+ "id": "lime-shared",
+ "displayName": "lime-shared",
+ "version": "0.1.4",
+ "description": "本人插件的几个公共函数,获取当前页,图片的base64转临时路径,图片的exif信息等",
+ "keywords": [
+ "lime-shared",
+ "exif",
+ "selectComponent"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "type": "sdk-js",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "u",
+ "Edge": "u",
+ "Firefox": "u",
+ "Safari": "u"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "y",
+ "快手": "y",
+ "飞书": "y",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/pathToBase64/index.ts b/src/uni_modules/lime-shared/pathToBase64/index.ts
new file mode 100644
index 0000000..8167f88
--- /dev/null
+++ b/src/uni_modules/lime-shared/pathToBase64/index.ts
@@ -0,0 +1,121 @@
+// @ts-nocheck
+
+// #ifdef APP-PLUS
+import { getLocalFilePath } from '../getLocalFilePath'
+// #endif
+function isImage(extension : string) {
+ const imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "svg"];
+ return imageExtensions.includes(extension.toLowerCase());
+}
+// #ifdef H5
+function getSVGFromURL(url: string) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.responseType = 'text';
+
+ xhr.onload = function () {
+ if (xhr.status === 200) {
+ const svg = xhr.responseText;
+ resolve(svg);
+ } else {
+ reject(new Error(xhr.statusText));
+ }
+ };
+
+ xhr.onerror = function () {
+ reject(new Error('Network error'));
+ };
+
+ xhr.send();
+ });
+}
+// #endif
+/**
+ * 路径转base64
+ * @param {Object} string
+ */
+export function pathToBase64(path : string) : Promise {
+ if (/^data:/.test(path)) return path
+ let extension = path.substring(path.lastIndexOf('.') + 1);
+ const isImageFile = isImage(extension)
+ let prefix = ''
+ if (isImageFile) {
+ prefix = 'image/';
+ if(extension == 'svg') {
+ extension += '+xml'
+ }
+ } else if (extension === 'pdf') {
+ prefix = 'application/pdf';
+ } else if (extension === 'txt') {
+ prefix = 'text/plain';
+ } else {
+ // 添加更多文件类型的判断
+ // 如果不是图片、PDF、文本等类型,可以设定默认的前缀或采取其他处理
+ prefix = 'application/octet-stream';
+ }
+ return new Promise((resolve, reject) => {
+ // #ifdef H5
+ if (isImageFile) {
+ if(extension == 'svg') {
+ getSVGFromURL(path).then(svg => {
+ const base64 = btoa(svg);
+ resolve(`data:image/svg+xml;base64,${base64}`);
+ })
+ } else {
+ let image = new Image();
+ image.setAttribute("crossOrigin", 'Anonymous');
+ image.onload = function () {
+ let canvas = document.createElement('canvas');
+ canvas.width = this.naturalWidth;
+ canvas.height = this.naturalHeight;
+ canvas.getContext('2d').drawImage(image, 0, 0);
+ let result = canvas.toDataURL(`${prefix}${extension}`)
+ resolve(result);
+ canvas.height = canvas.width = 0
+ }
+ image.src = path + '?v=' + Math.random()
+ image.onerror = (error) => {
+ reject(error);
+ };
+ }
+
+ } else {
+ reject('not image');
+ }
+
+ // #endif
+
+ // #ifdef MP
+ if (uni.canIUse('getFileSystemManager')) {
+ uni.getFileSystemManager().readFile({
+ filePath: path,
+ encoding: 'base64',
+ success: (res) => {
+ resolve(`data:${prefix}${extension};base64,${res.data}`)
+ },
+ fail: (error) => {
+ console.error({ error, path })
+ reject(error)
+ }
+ })
+ }
+ // #endif
+
+ // #ifdef APP-PLUS
+ plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
+ entry.file((file : any) => {
+ const fileReader = new plus.io.FileReader()
+ fileReader.onload = (data) => {
+ resolve(data.target.result)
+ }
+ fileReader.onerror = (error) => {
+ console.error({ error, path })
+ reject(error)
+ }
+ fileReader.readAsDataURL(file)
+ }, reject)
+ }, reject)
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/piexif/index.ts b/src/uni_modules/lime-shared/piexif/index.ts
new file mode 100644
index 0000000..6a52b10
--- /dev/null
+++ b/src/uni_modules/lime-shared/piexif/index.ts
@@ -0,0 +1,2320 @@
+// @ts-nocheck
+// 源于piexifjs
+import { cloneDeep } from '../cloneDeep'
+import { isString } from '../isString'
+const TAGS = {
+ 'Image': {
+ 11: {
+ 'name': 'ProcessingSoftware',
+ 'type': 'Ascii'
+ },
+ 254: {
+ 'name': 'NewSubfileType',
+ 'type': 'Long'
+ },
+ 255: {
+ 'name': 'SubfileType',
+ 'type': 'Short'
+ },
+ 256: {
+ 'name': 'ImageWidth',
+ 'type': 'Long'
+ },
+ 257: {
+ 'name': 'ImageLength',
+ 'type': 'Long'
+ },
+ 258: {
+ 'name': 'BitsPerSample',
+ 'type': 'Short'
+ },
+ 259: {
+ 'name': 'Compression',
+ 'type': 'Short'
+ },
+ 262: {
+ 'name': 'PhotometricInterpretation',
+ 'type': 'Short'
+ },
+ 263: {
+ 'name': 'Threshholding',
+ 'type': 'Short'
+ },
+ 264: {
+ 'name': 'CellWidth',
+ 'type': 'Short'
+ },
+ 265: {
+ 'name': 'CellLength',
+ 'type': 'Short'
+ },
+ 266: {
+ 'name': 'FillOrder',
+ 'type': 'Short'
+ },
+ 269: {
+ 'name': 'DocumentName',
+ 'type': 'Ascii'
+ },
+ 270: {
+ 'name': 'ImageDescription',
+ 'type': 'Ascii'
+ },
+ 271: {
+ 'name': 'Make',
+ 'type': 'Ascii'
+ },
+ 272: {
+ 'name': 'Model',
+ 'type': 'Ascii'
+ },
+ 273: {
+ 'name': 'StripOffsets',
+ 'type': 'Long'
+ },
+ 274: {
+ 'name': 'Orientation',
+ 'type': 'Short'
+ },
+ 277: {
+ 'name': 'SamplesPerPixel',
+ 'type': 'Short'
+ },
+ 278: {
+ 'name': 'RowsPerStrip',
+ 'type': 'Long'
+ },
+ 279: {
+ 'name': 'StripByteCounts',
+ 'type': 'Long'
+ },
+ 282: {
+ 'name': 'XResolution',
+ 'type': 'Rational'
+ },
+ 283: {
+ 'name': 'YResolution',
+ 'type': 'Rational'
+ },
+ 284: {
+ 'name': 'PlanarConfiguration',
+ 'type': 'Short'
+ },
+ 290: {
+ 'name': 'GrayResponseUnit',
+ 'type': 'Short'
+ },
+ 291: {
+ 'name': 'GrayResponseCurve',
+ 'type': 'Short'
+ },
+ 292: {
+ 'name': 'T4Options',
+ 'type': 'Long'
+ },
+ 293: {
+ 'name': 'T6Options',
+ 'type': 'Long'
+ },
+ 296: {
+ 'name': 'ResolutionUnit',
+ 'type': 'Short'
+ },
+ 301: {
+ 'name': 'TransferFunction',
+ 'type': 'Short'
+ },
+ 305: {
+ 'name': 'Software',
+ 'type': 'Ascii'
+ },
+ 306: {
+ 'name': 'DateTime',
+ 'type': 'Ascii'
+ },
+ 315: {
+ 'name': 'Artist',
+ 'type': 'Ascii'
+ },
+ 316: {
+ 'name': 'HostComputer',
+ 'type': 'Ascii'
+ },
+ 317: {
+ 'name': 'Predictor',
+ 'type': 'Short'
+ },
+ 318: {
+ 'name': 'WhitePoint',
+ 'type': 'Rational'
+ },
+ 319: {
+ 'name': 'PrimaryChromaticities',
+ 'type': 'Rational'
+ },
+ 320: {
+ 'name': 'ColorMap',
+ 'type': 'Short'
+ },
+ 321: {
+ 'name': 'HalftoneHints',
+ 'type': 'Short'
+ },
+ 322: {
+ 'name': 'TileWidth',
+ 'type': 'Short'
+ },
+ 323: {
+ 'name': 'TileLength',
+ 'type': 'Short'
+ },
+ 324: {
+ 'name': 'TileOffsets',
+ 'type': 'Short'
+ },
+ 325: {
+ 'name': 'TileByteCounts',
+ 'type': 'Short'
+ },
+ 330: {
+ 'name': 'SubIFDs',
+ 'type': 'Long'
+ },
+ 332: {
+ 'name': 'InkSet',
+ 'type': 'Short'
+ },
+ 333: {
+ 'name': 'InkNames',
+ 'type': 'Ascii'
+ },
+ 334: {
+ 'name': 'NumberOfInks',
+ 'type': 'Short'
+ },
+ 336: {
+ 'name': 'DotRange',
+ 'type': 'Byte'
+ },
+ 337: {
+ 'name': 'TargetPrinter',
+ 'type': 'Ascii'
+ },
+ 338: {
+ 'name': 'ExtraSamples',
+ 'type': 'Short'
+ },
+ 339: {
+ 'name': 'SampleFormat',
+ 'type': 'Short'
+ },
+ 340: {
+ 'name': 'SMinSampleValue',
+ 'type': 'Short'
+ },
+ 341: {
+ 'name': 'SMaxSampleValue',
+ 'type': 'Short'
+ },
+ 342: {
+ 'name': 'TransferRange',
+ 'type': 'Short'
+ },
+ 343: {
+ 'name': 'ClipPath',
+ 'type': 'Byte'
+ },
+ 344: {
+ 'name': 'XClipPathUnits',
+ 'type': 'Long'
+ },
+ 345: {
+ 'name': 'YClipPathUnits',
+ 'type': 'Long'
+ },
+ 346: {
+ 'name': 'Indexed',
+ 'type': 'Short'
+ },
+ 347: {
+ 'name': 'JPEGTables',
+ 'type': 'Undefined'
+ },
+ 351: {
+ 'name': 'OPIProxy',
+ 'type': 'Short'
+ },
+ 512: {
+ 'name': 'JPEGProc',
+ 'type': 'Long'
+ },
+ 513: {
+ 'name': 'JPEGInterchangeFormat',
+ 'type': 'Long'
+ },
+ 514: {
+ 'name': 'JPEGInterchangeFormatLength',
+ 'type': 'Long'
+ },
+ 515: {
+ 'name': 'JPEGRestartInterval',
+ 'type': 'Short'
+ },
+ 517: {
+ 'name': 'JPEGLosslessPredictors',
+ 'type': 'Short'
+ },
+ 518: {
+ 'name': 'JPEGPointTransforms',
+ 'type': 'Short'
+ },
+ 519: {
+ 'name': 'JPEGQTables',
+ 'type': 'Long'
+ },
+ 520: {
+ 'name': 'JPEGDCTables',
+ 'type': 'Long'
+ },
+ 521: {
+ 'name': 'JPEGACTables',
+ 'type': 'Long'
+ },
+ 529: {
+ 'name': 'YCbCrCoefficients',
+ 'type': 'Rational'
+ },
+ 530: {
+ 'name': 'YCbCrSubSampling',
+ 'type': 'Short'
+ },
+ 531: {
+ 'name': 'YCbCrPositioning',
+ 'type': 'Short'
+ },
+ 532: {
+ 'name': 'ReferenceBlackWhite',
+ 'type': 'Rational'
+ },
+ 700: {
+ 'name': 'XMLPacket',
+ 'type': 'Byte'
+ },
+ 18246: {
+ 'name': 'Rating',
+ 'type': 'Short'
+ },
+ 18249: {
+ 'name': 'RatingPercent',
+ 'type': 'Short'
+ },
+ 32781: {
+ 'name': 'ImageID',
+ 'type': 'Ascii'
+ },
+ 33421: {
+ 'name': 'CFARepeatPatternDim',
+ 'type': 'Short'
+ },
+ 33422: {
+ 'name': 'CFAPattern',
+ 'type': 'Byte'
+ },
+ 33423: {
+ 'name': 'BatteryLevel',
+ 'type': 'Rational'
+ },
+ 33432: {
+ 'name': 'Copyright',
+ 'type': 'Ascii'
+ },
+ 33434: {
+ 'name': 'ExposureTime',
+ 'type': 'Rational'
+ },
+ 34377: {
+ 'name': 'ImageResources',
+ 'type': 'Byte'
+ },
+ 34665: {
+ 'name': 'ExifTag',
+ 'type': 'Long'
+ },
+ 34675: {
+ 'name': 'InterColorProfile',
+ 'type': 'Undefined'
+ },
+ 34853: {
+ 'name': 'GPSTag',
+ 'type': 'Long'
+ },
+ 34857: {
+ 'name': 'Interlace',
+ 'type': 'Short'
+ },
+ 34858: {
+ 'name': 'TimeZoneOffset',
+ 'type': 'Long'
+ },
+ 34859: {
+ 'name': 'SelfTimerMode',
+ 'type': 'Short'
+ },
+ 37387: {
+ 'name': 'FlashEnergy',
+ 'type': 'Rational'
+ },
+ 37388: {
+ 'name': 'SpatialFrequencyResponse',
+ 'type': 'Undefined'
+ },
+ 37389: {
+ 'name': 'Noise',
+ 'type': 'Undefined'
+ },
+ 37390: {
+ 'name': 'FocalPlaneXResolution',
+ 'type': 'Rational'
+ },
+ 37391: {
+ 'name': 'FocalPlaneYResolution',
+ 'type': 'Rational'
+ },
+ 37392: {
+ 'name': 'FocalPlaneResolutionUnit',
+ 'type': 'Short'
+ },
+ 37393: {
+ 'name': 'ImageNumber',
+ 'type': 'Long'
+ },
+ 37394: {
+ 'name': 'SecurityClassification',
+ 'type': 'Ascii'
+ },
+ 37395: {
+ 'name': 'ImageHistory',
+ 'type': 'Ascii'
+ },
+ 37397: {
+ 'name': 'ExposureIndex',
+ 'type': 'Rational'
+ },
+ 37398: {
+ 'name': 'TIFFEPStandardID',
+ 'type': 'Byte'
+ },
+ 37399: {
+ 'name': 'SensingMethod',
+ 'type': 'Short'
+ },
+ 40091: {
+ 'name': 'XPTitle',
+ 'type': 'Byte'
+ },
+ 40092: {
+ 'name': 'XPComment',
+ 'type': 'Byte'
+ },
+ 40093: {
+ 'name': 'XPAuthor',
+ 'type': 'Byte'
+ },
+ 40094: {
+ 'name': 'XPKeywords',
+ 'type': 'Byte'
+ },
+ 40095: {
+ 'name': 'XPSubject',
+ 'type': 'Byte'
+ },
+ 50341: {
+ 'name': 'PrintImageMatching',
+ 'type': 'Undefined'
+ },
+ 50706: {
+ 'name': 'DNGVersion',
+ 'type': 'Byte'
+ },
+ 50707: {
+ 'name': 'DNGBackwardVersion',
+ 'type': 'Byte'
+ },
+ 50708: {
+ 'name': 'UniqueCameraModel',
+ 'type': 'Ascii'
+ },
+ 50709: {
+ 'name': 'LocalizedCameraModel',
+ 'type': 'Byte'
+ },
+ 50710: {
+ 'name': 'CFAPlaneColor',
+ 'type': 'Byte'
+ },
+ 50711: {
+ 'name': 'CFALayout',
+ 'type': 'Short'
+ },
+ 50712: {
+ 'name': 'LinearizationTable',
+ 'type': 'Short'
+ },
+ 50713: {
+ 'name': 'BlackLevelRepeatDim',
+ 'type': 'Short'
+ },
+ 50714: {
+ 'name': 'BlackLevel',
+ 'type': 'Rational'
+ },
+ 50715: {
+ 'name': 'BlackLevelDeltaH',
+ 'type': 'SRational'
+ },
+ 50716: {
+ 'name': 'BlackLevelDeltaV',
+ 'type': 'SRational'
+ },
+ 50717: {
+ 'name': 'WhiteLevel',
+ 'type': 'Short'
+ },
+ 50718: {
+ 'name': 'DefaultScale',
+ 'type': 'Rational'
+ },
+ 50719: {
+ 'name': 'DefaultCropOrigin',
+ 'type': 'Short'
+ },
+ 50720: {
+ 'name': 'DefaultCropSize',
+ 'type': 'Short'
+ },
+ 50721: {
+ 'name': 'ColorMatrix1',
+ 'type': 'SRational'
+ },
+ 50722: {
+ 'name': 'ColorMatrix2',
+ 'type': 'SRational'
+ },
+ 50723: {
+ 'name': 'CameraCalibration1',
+ 'type': 'SRational'
+ },
+ 50724: {
+ 'name': 'CameraCalibration2',
+ 'type': 'SRational'
+ },
+ 50725: {
+ 'name': 'ReductionMatrix1',
+ 'type': 'SRational'
+ },
+ 50726: {
+ 'name': 'ReductionMatrix2',
+ 'type': 'SRational'
+ },
+ 50727: {
+ 'name': 'AnalogBalance',
+ 'type': 'Rational'
+ },
+ 50728: {
+ 'name': 'AsShotNeutral',
+ 'type': 'Short'
+ },
+ 50729: {
+ 'name': 'AsShotWhiteXY',
+ 'type': 'Rational'
+ },
+ 50730: {
+ 'name': 'BaselineExposure',
+ 'type': 'SRational'
+ },
+ 50731: {
+ 'name': 'BaselineNoise',
+ 'type': 'Rational'
+ },
+ 50732: {
+ 'name': 'BaselineSharpness',
+ 'type': 'Rational'
+ },
+ 50733: {
+ 'name': 'BayerGreenSplit',
+ 'type': 'Long'
+ },
+ 50734: {
+ 'name': 'LinearResponseLimit',
+ 'type': 'Rational'
+ },
+ 50735: {
+ 'name': 'CameraSerialNumber',
+ 'type': 'Ascii'
+ },
+ 50736: {
+ 'name': 'LensInfo',
+ 'type': 'Rational'
+ },
+ 50737: {
+ 'name': 'ChromaBlurRadius',
+ 'type': 'Rational'
+ },
+ 50738: {
+ 'name': 'AntiAliasStrength',
+ 'type': 'Rational'
+ },
+ 50739: {
+ 'name': 'ShadowScale',
+ 'type': 'SRational'
+ },
+ 50740: {
+ 'name': 'DNGPrivateData',
+ 'type': 'Byte'
+ },
+ 50741: {
+ 'name': 'MakerNoteSafety',
+ 'type': 'Short'
+ },
+ 50778: {
+ 'name': 'CalibrationIlluminant1',
+ 'type': 'Short'
+ },
+ 50779: {
+ 'name': 'CalibrationIlluminant2',
+ 'type': 'Short'
+ },
+ 50780: {
+ 'name': 'BestQualityScale',
+ 'type': 'Rational'
+ },
+ 50781: {
+ 'name': 'RawDataUniqueID',
+ 'type': 'Byte'
+ },
+ 50827: {
+ 'name': 'OriginalRawFileName',
+ 'type': 'Byte'
+ },
+ 50828: {
+ 'name': 'OriginalRawFileData',
+ 'type': 'Undefined'
+ },
+ 50829: {
+ 'name': 'ActiveArea',
+ 'type': 'Short'
+ },
+ 50830: {
+ 'name': 'MaskedAreas',
+ 'type': 'Short'
+ },
+ 50831: {
+ 'name': 'AsShotICCProfile',
+ 'type': 'Undefined'
+ },
+ 50832: {
+ 'name': 'AsShotPreProfileMatrix',
+ 'type': 'SRational'
+ },
+ 50833: {
+ 'name': 'CurrentICCProfile',
+ 'type': 'Undefined'
+ },
+ 50834: {
+ 'name': 'CurrentPreProfileMatrix',
+ 'type': 'SRational'
+ },
+ 50879: {
+ 'name': 'ColorimetricReference',
+ 'type': 'Short'
+ },
+ 50931: {
+ 'name': 'CameraCalibrationSignature',
+ 'type': 'Byte'
+ },
+ 50932: {
+ 'name': 'ProfileCalibrationSignature',
+ 'type': 'Byte'
+ },
+ 50934: {
+ 'name': 'AsShotProfileName',
+ 'type': 'Byte'
+ },
+ 50935: {
+ 'name': 'NoiseReductionApplied',
+ 'type': 'Rational'
+ },
+ 50936: {
+ 'name': 'ProfileName',
+ 'type': 'Byte'
+ },
+ 50937: {
+ 'name': 'ProfileHueSatMapDims',
+ 'type': 'Long'
+ },
+ 50938: {
+ 'name': 'ProfileHueSatMapData1',
+ 'type': 'Float'
+ },
+ 50939: {
+ 'name': 'ProfileHueSatMapData2',
+ 'type': 'Float'
+ },
+ 50940: {
+ 'name': 'ProfileToneCurve',
+ 'type': 'Float'
+ },
+ 50941: {
+ 'name': 'ProfileEmbedPolicy',
+ 'type': 'Long'
+ },
+ 50942: {
+ 'name': 'ProfileCopyright',
+ 'type': 'Byte'
+ },
+ 50964: {
+ 'name': 'ForwardMatrix1',
+ 'type': 'SRational'
+ },
+ 50965: {
+ 'name': 'ForwardMatrix2',
+ 'type': 'SRational'
+ },
+ 50966: {
+ 'name': 'PreviewApplicationName',
+ 'type': 'Byte'
+ },
+ 50967: {
+ 'name': 'PreviewApplicationVersion',
+ 'type': 'Byte'
+ },
+ 50968: {
+ 'name': 'PreviewSettingsName',
+ 'type': 'Byte'
+ },
+ 50969: {
+ 'name': 'PreviewSettingsDigest',
+ 'type': 'Byte'
+ },
+ 50970: {
+ 'name': 'PreviewColorSpace',
+ 'type': 'Long'
+ },
+ 50971: {
+ 'name': 'PreviewDateTime',
+ 'type': 'Ascii'
+ },
+ 50972: {
+ 'name': 'RawImageDigest',
+ 'type': 'Undefined'
+ },
+ 50973: {
+ 'name': 'OriginalRawFileDigest',
+ 'type': 'Undefined'
+ },
+ 50974: {
+ 'name': 'SubTileBlockSize',
+ 'type': 'Long'
+ },
+ 50975: {
+ 'name': 'RowInterleaveFactor',
+ 'type': 'Long'
+ },
+ 50981: {
+ 'name': 'ProfileLookTableDims',
+ 'type': 'Long'
+ },
+ 50982: {
+ 'name': 'ProfileLookTableData',
+ 'type': 'Float'
+ },
+ 51008: {
+ 'name': 'OpcodeList1',
+ 'type': 'Undefined'
+ },
+ 51009: {
+ 'name': 'OpcodeList2',
+ 'type': 'Undefined'
+ },
+ 51022: {
+ 'name': 'OpcodeList3',
+ 'type': 'Undefined'
+ }
+ },
+ 'Exif': {
+ 33434: {
+ 'name': 'ExposureTime',
+ 'type': 'Rational'
+ },
+ 33437: {
+ 'name': 'FNumber',
+ 'type': 'Rational'
+ },
+ 34850: {
+ 'name': 'ExposureProgram',
+ 'type': 'Short'
+ },
+ 34852: {
+ 'name': 'SpectralSensitivity',
+ 'type': 'Ascii'
+ },
+ 34855: {
+ 'name': 'ISOSpeedRatings',
+ 'type': 'Short'
+ },
+ 34856: {
+ 'name': 'OECF',
+ 'type': 'Undefined'
+ },
+ 34864: {
+ 'name': 'SensitivityType',
+ 'type': 'Short'
+ },
+ 34865: {
+ 'name': 'StandardOutputSensitivity',
+ 'type': 'Long'
+ },
+ 34866: {
+ 'name': 'RecommendedExposureIndex',
+ 'type': 'Long'
+ },
+ 34867: {
+ 'name': 'ISOSpeed',
+ 'type': 'Long'
+ },
+ 34868: {
+ 'name': 'ISOSpeedLatitudeyyy',
+ 'type': 'Long'
+ },
+ 34869: {
+ 'name': 'ISOSpeedLatitudezzz',
+ 'type': 'Long'
+ },
+ 36864: {
+ 'name': 'ExifVersion',
+ 'type': 'Undefined'
+ },
+ 36867: {
+ 'name': 'DateTimeOriginal',
+ 'type': 'Ascii'
+ },
+ 36868: {
+ 'name': 'DateTimeDigitized',
+ 'type': 'Ascii'
+ },
+ 37121: {
+ 'name': 'ComponentsConfiguration',
+ 'type': 'Undefined'
+ },
+ 37122: {
+ 'name': 'CompressedBitsPerPixel',
+ 'type': 'Rational'
+ },
+ 37377: {
+ 'name': 'ShutterSpeedValue',
+ 'type': 'SRational'
+ },
+ 37378: {
+ 'name': 'ApertureValue',
+ 'type': 'Rational'
+ },
+ 37379: {
+ 'name': 'BrightnessValue',
+ 'type': 'SRational'
+ },
+ 37380: {
+ 'name': 'ExposureBiasValue',
+ 'type': 'SRational'
+ },
+ 37381: {
+ 'name': 'MaxApertureValue',
+ 'type': 'Rational'
+ },
+ 37382: {
+ 'name': 'SubjectDistance',
+ 'type': 'Rational'
+ },
+ 37383: {
+ 'name': 'MeteringMode',
+ 'type': 'Short'
+ },
+ 37384: {
+ 'name': 'LightSource',
+ 'type': 'Short'
+ },
+ 37385: {
+ 'name': 'Flash',
+ 'type': 'Short'
+ },
+ 37386: {
+ 'name': 'FocalLength',
+ 'type': 'Rational'
+ },
+ 37396: {
+ 'name': 'SubjectArea',
+ 'type': 'Short'
+ },
+ 37500: {
+ 'name': 'MakerNote',
+ 'type': 'Undefined'
+ },
+ 37510: {
+ 'name': 'UserComment',
+ 'type': 'Ascii'
+ },
+ 37520: {
+ 'name': 'SubSecTime',
+ 'type': 'Ascii'
+ },
+ 37521: {
+ 'name': 'SubSecTimeOriginal',
+ 'type': 'Ascii'
+ },
+ 37522: {
+ 'name': 'SubSecTimeDigitized',
+ 'type': 'Ascii'
+ },
+ 40960: {
+ 'name': 'FlashpixVersion',
+ 'type': 'Undefined'
+ },
+ 40961: {
+ 'name': 'ColorSpace',
+ 'type': 'Short'
+ },
+ 40962: {
+ 'name': 'PixelXDimension',
+ 'type': 'Long'
+ },
+ 40963: {
+ 'name': 'PixelYDimension',
+ 'type': 'Long'
+ },
+ 40964: {
+ 'name': 'RelatedSoundFile',
+ 'type': 'Ascii'
+ },
+ 40965: {
+ 'name': 'InteroperabilityTag',
+ 'type': 'Long'
+ },
+ 41483: {
+ 'name': 'FlashEnergy',
+ 'type': 'Rational'
+ },
+ 41484: {
+ 'name': 'SpatialFrequencyResponse',
+ 'type': 'Undefined'
+ },
+ 41486: {
+ 'name': 'FocalPlaneXResolution',
+ 'type': 'Rational'
+ },
+ 41487: {
+ 'name': 'FocalPlaneYResolution',
+ 'type': 'Rational'
+ },
+ 41488: {
+ 'name': 'FocalPlaneResolutionUnit',
+ 'type': 'Short'
+ },
+ 41492: {
+ 'name': 'SubjectLocation',
+ 'type': 'Short'
+ },
+ 41493: {
+ 'name': 'ExposureIndex',
+ 'type': 'Rational'
+ },
+ 41495: {
+ 'name': 'SensingMethod',
+ 'type': 'Short'
+ },
+ 41728: {
+ 'name': 'FileSource',
+ 'type': 'Undefined'
+ },
+ 41729: {
+ 'name': 'SceneType',
+ 'type': 'Undefined'
+ },
+ 41730: {
+ 'name': 'CFAPattern',
+ 'type': 'Undefined'
+ },
+ 41985: {
+ 'name': 'CustomRendered',
+ 'type': 'Short'
+ },
+ 41986: {
+ 'name': 'ExposureMode',
+ 'type': 'Short'
+ },
+ 41987: {
+ 'name': 'WhiteBalance',
+ 'type': 'Short'
+ },
+ 41988: {
+ 'name': 'DigitalZoomRatio',
+ 'type': 'Rational'
+ },
+ 41989: {
+ 'name': 'FocalLengthIn35mmFilm',
+ 'type': 'Short'
+ },
+ 41990: {
+ 'name': 'SceneCaptureType',
+ 'type': 'Short'
+ },
+ 41991: {
+ 'name': 'GainControl',
+ 'type': 'Short'
+ },
+ 41992: {
+ 'name': 'Contrast',
+ 'type': 'Short'
+ },
+ 41993: {
+ 'name': 'Saturation',
+ 'type': 'Short'
+ },
+ 41994: {
+ 'name': 'Sharpness',
+ 'type': 'Short'
+ },
+ 41995: {
+ 'name': 'DeviceSettingDescription',
+ 'type': 'Undefined'
+ },
+ 41996: {
+ 'name': 'SubjectDistanceRange',
+ 'type': 'Short'
+ },
+ 42016: {
+ 'name': 'ImageUniqueID',
+ 'type': 'Ascii'
+ },
+ 42032: {
+ 'name': 'CameraOwnerName',
+ 'type': 'Ascii'
+ },
+ 42033: {
+ 'name': 'BodySerialNumber',
+ 'type': 'Ascii'
+ },
+ 42034: {
+ 'name': 'LensSpecification',
+ 'type': 'Rational'
+ },
+ 42035: {
+ 'name': 'LensMake',
+ 'type': 'Ascii'
+ },
+ 42036: {
+ 'name': 'LensModel',
+ 'type': 'Ascii'
+ },
+ 42037: {
+ 'name': 'LensSerialNumber',
+ 'type': 'Ascii'
+ },
+ 42240: {
+ 'name': 'Gamma',
+ 'type': 'Rational'
+ }
+ },
+ 'GPS': {
+ 0: {
+ 'name': 'GPSVersionID',
+ 'type': 'Byte'
+ },
+ 1: {
+ 'name': 'GPSLatitudeRef',
+ 'type': 'Ascii'
+ },
+ 2: {
+ 'name': 'GPSLatitude',
+ 'type': 'Rational'
+ },
+ 3: {
+ 'name': 'GPSLongitudeRef',
+ 'type': 'Ascii'
+ },
+ 4: {
+ 'name': 'GPSLongitude',
+ 'type': 'Rational'
+ },
+ 5: {
+ 'name': 'GPSAltitudeRef',
+ 'type': 'Byte'
+ },
+ 6: {
+ 'name': 'GPSAltitude',
+ 'type': 'Rational'
+ },
+ 7: {
+ 'name': 'GPSTimeStamp',
+ 'type': 'Rational'
+ },
+ 8: {
+ 'name': 'GPSSatellites',
+ 'type': 'Ascii'
+ },
+ 9: {
+ 'name': 'GPSStatus',
+ 'type': 'Ascii'
+ },
+ 10: {
+ 'name': 'GPSMeasureMode',
+ 'type': 'Ascii'
+ },
+ 11: {
+ 'name': 'GPSDOP',
+ 'type': 'Rational'
+ },
+ 12: {
+ 'name': 'GPSSpeedRef',
+ 'type': 'Ascii'
+ },
+ 13: {
+ 'name': 'GPSSpeed',
+ 'type': 'Rational'
+ },
+ 14: {
+ 'name': 'GPSTrackRef',
+ 'type': 'Ascii'
+ },
+ 15: {
+ 'name': 'GPSTrack',
+ 'type': 'Rational'
+ },
+ 16: {
+ 'name': 'GPSImgDirectionRef',
+ 'type': 'Ascii'
+ },
+ 17: {
+ 'name': 'GPSImgDirection',
+ 'type': 'Rational'
+ },
+ 18: {
+ 'name': 'GPSMapDatum',
+ 'type': 'Ascii'
+ },
+ 19: {
+ 'name': 'GPSDestLatitudeRef',
+ 'type': 'Ascii'
+ },
+ 20: {
+ 'name': 'GPSDestLatitude',
+ 'type': 'Rational'
+ },
+ 21: {
+ 'name': 'GPSDestLongitudeRef',
+ 'type': 'Ascii'
+ },
+ 22: {
+ 'name': 'GPSDestLongitude',
+ 'type': 'Rational'
+ },
+ 23: {
+ 'name': 'GPSDestBearingRef',
+ 'type': 'Ascii'
+ },
+ 24: {
+ 'name': 'GPSDestBearing',
+ 'type': 'Rational'
+ },
+ 25: {
+ 'name': 'GPSDestDistanceRef',
+ 'type': 'Ascii'
+ },
+ 26: {
+ 'name': 'GPSDestDistance',
+ 'type': 'Rational'
+ },
+ 27: {
+ 'name': 'GPSProcessingMethod',
+ 'type': 'Undefined'
+ },
+ 28: {
+ 'name': 'GPSAreaInformation',
+ 'type': 'Undefined'
+ },
+ 29: {
+ 'name': 'GPSDateStamp',
+ 'type': 'Ascii'
+ },
+ 30: {
+ 'name': 'GPSDifferential',
+ 'type': 'Short'
+ },
+ 31: {
+ 'name': 'GPSHPositioningError',
+ 'type': 'Rational'
+ }
+ },
+ 'Interop': {
+ 1: {
+ 'name': 'InteroperabilityIndex',
+ 'type': 'Ascii'
+ }
+ },
+};
+const TYPES = {
+ "Byte": 1,
+ "Ascii": 2,
+ "Short": 3,
+ "Long": 4,
+ "Rational": 5,
+ "Undefined": 7,
+ "SLong": 9,
+ "SRational": 10
+};
+TAGS["0th"] = TAGS["Image"];
+TAGS["1st"] = TAGS["Image"];
+class Piexif {
+ version = "1.0.4"
+ TAGS = TAGS
+ ImageIFD = {
+ ProcessingSoftware: 11,
+ NewSubfileType: 254,
+ SubfileType: 255,
+ ImageWidth: 256,
+ ImageLength: 257,
+ BitsPerSample: 258,
+ Compression: 259,
+ PhotometricInterpretation: 262,
+ Threshholding: 263,
+ CellWidth: 264,
+ CellLength: 265,
+ FillOrder: 266,
+ DocumentName: 269,
+ ImageDescription: 270,
+ Make: 271,
+ Model: 272,
+ StripOffsets: 273,
+ Orientation: 274,
+ SamplesPerPixel: 277,
+ RowsPerStrip: 278,
+ StripByteCounts: 279,
+ XResolution: 282,
+ YResolution: 283,
+ PlanarConfiguration: 284,
+ GrayResponseUnit: 290,
+ GrayResponseCurve: 291,
+ T4Options: 292,
+ T6Options: 293,
+ ResolutionUnit: 296,
+ TransferFunction: 301,
+ Software: 305,
+ DateTime: 306,
+ Artist: 315,
+ HostComputer: 316,
+ Predictor: 317,
+ WhitePoint: 318,
+ PrimaryChromaticities: 319,
+ ColorMap: 320,
+ HalftoneHints: 321,
+ TileWidth: 322,
+ TileLength: 323,
+ TileOffsets: 324,
+ TileByteCounts: 325,
+ SubIFDs: 330,
+ InkSet: 332,
+ InkNames: 333,
+ NumberOfInks: 334,
+ DotRange: 336,
+ TargetPrinter: 337,
+ ExtraSamples: 338,
+ SampleFormat: 339,
+ SMinSampleValue: 340,
+ SMaxSampleValue: 341,
+ TransferRange: 342,
+ ClipPath: 343,
+ XClipPathUnits: 344,
+ YClipPathUnits: 345,
+ Indexed: 346,
+ JPEGTables: 347,
+ OPIProxy: 351,
+ JPEGProc: 512,
+ JPEGInterchangeFormat: 513,
+ JPEGInterchangeFormatLength: 514,
+ JPEGRestartInterval: 515,
+ JPEGLosslessPredictors: 517,
+ JPEGPointTransforms: 518,
+ JPEGQTables: 519,
+ JPEGDCTables: 520,
+ JPEGACTables: 521,
+ YCbCrCoefficients: 529,
+ YCbCrSubSampling: 530,
+ YCbCrPositioning: 531,
+ ReferenceBlackWhite: 532,
+ XMLPacket: 700,
+ Rating: 18246,
+ RatingPercent: 18249,
+ ImageID: 32781,
+ CFARepeatPatternDim: 33421,
+ CFAPattern: 33422,
+ BatteryLevel: 33423,
+ Copyright: 33432,
+ ExposureTime: 33434,
+ ImageResources: 34377,
+ ExifTag: 34665,
+ InterColorProfile: 34675,
+ GPSTag: 34853,
+ Interlace: 34857,
+ TimeZoneOffset: 34858,
+ SelfTimerMode: 34859,
+ FlashEnergy: 37387,
+ SpatialFrequencyResponse: 37388,
+ Noise: 37389,
+ FocalPlaneXResolution: 37390,
+ FocalPlaneYResolution: 37391,
+ FocalPlaneResolutionUnit: 37392,
+ ImageNumber: 37393,
+ SecurityClassification: 37394,
+ ImageHistory: 37395,
+ ExposureIndex: 37397,
+ TIFFEPStandardID: 37398,
+ SensingMethod: 37399,
+ XPTitle: 40091,
+ XPComment: 40092,
+ XPAuthor: 40093,
+ XPKeywords: 40094,
+ XPSubject: 40095,
+ PrintImageMatching: 50341,
+ DNGVersion: 50706,
+ DNGBackwardVersion: 50707,
+ UniqueCameraModel: 50708,
+ LocalizedCameraModel: 50709,
+ CFAPlaneColor: 50710,
+ CFALayout: 50711,
+ LinearizationTable: 50712,
+ BlackLevelRepeatDim: 50713,
+ BlackLevel: 50714,
+ BlackLevelDeltaH: 50715,
+ BlackLevelDeltaV: 50716,
+ WhiteLevel: 50717,
+ DefaultScale: 50718,
+ DefaultCropOrigin: 50719,
+ DefaultCropSize: 50720,
+ ColorMatrix1: 50721,
+ ColorMatrix2: 50722,
+ CameraCalibration1: 50723,
+ CameraCalibration2: 50724,
+ ReductionMatrix1: 50725,
+ ReductionMatrix2: 50726,
+ AnalogBalance: 50727,
+ AsShotNeutral: 50728,
+ AsShotWhiteXY: 50729,
+ BaselineExposure: 50730,
+ BaselineNoise: 50731,
+ BaselineSharpness: 50732,
+ BayerGreenSplit: 50733,
+ LinearResponseLimit: 50734,
+ CameraSerialNumber: 50735,
+ LensInfo: 50736,
+ ChromaBlurRadius: 50737,
+ AntiAliasStrength: 50738,
+ ShadowScale: 50739,
+ DNGPrivateData: 50740,
+ MakerNoteSafety: 50741,
+ CalibrationIlluminant1: 50778,
+ CalibrationIlluminant2: 50779,
+ BestQualityScale: 50780,
+ RawDataUniqueID: 50781,
+ OriginalRawFileName: 50827,
+ OriginalRawFileData: 50828,
+ ActiveArea: 50829,
+ MaskedAreas: 50830,
+ AsShotICCProfile: 50831,
+ AsShotPreProfileMatrix: 50832,
+ CurrentICCProfile: 50833,
+ CurrentPreProfileMatrix: 50834,
+ ColorimetricReference: 50879,
+ CameraCalibrationSignature: 50931,
+ ProfileCalibrationSignature: 50932,
+ AsShotProfileName: 50934,
+ NoiseReductionApplied: 50935,
+ ProfileName: 50936,
+ ProfileHueSatMapDims: 50937,
+ ProfileHueSatMapData1: 50938,
+ ProfileHueSatMapData2: 50939,
+ ProfileToneCurve: 50940,
+ ProfileEmbedPolicy: 50941,
+ ProfileCopyright: 50942,
+ ForwardMatrix1: 50964,
+ ForwardMatrix2: 50965,
+ PreviewApplicationName: 50966,
+ PreviewApplicationVersion: 50967,
+ PreviewSettingsName: 50968,
+ PreviewSettingsDigest: 50969,
+ PreviewColorSpace: 50970,
+ PreviewDateTime: 50971,
+ RawImageDigest: 50972,
+ OriginalRawFileDigest: 50973,
+ SubTileBlockSize: 50974,
+ RowInterleaveFactor: 50975,
+ ProfileLookTableDims: 50981,
+ ProfileLookTableData: 50982,
+ OpcodeList1: 51008,
+ OpcodeList2: 51009,
+ OpcodeList3: 51022,
+ NoiseProfile: 51041,
+ }
+ ExifIFD = {
+ ExposureTime: 33434,
+ FNumber: 33437,
+ ExposureProgram: 34850,
+ SpectralSensitivity: 34852,
+ ISOSpeedRatings: 34855,
+ OECF: 34856,
+ SensitivityType: 34864,
+ StandardOutputSensitivity: 34865,
+ RecommendedExposureIndex: 34866,
+ ISOSpeed: 34867,
+ ISOSpeedLatitudeyyy: 34868,
+ ISOSpeedLatitudezzz: 34869,
+ ExifVersion: 36864,
+ DateTimeOriginal: 36867,
+ DateTimeDigitized: 36868,
+ ComponentsConfiguration: 37121,
+ CompressedBitsPerPixel: 37122,
+ ShutterSpeedValue: 37377,
+ ApertureValue: 37378,
+ BrightnessValue: 37379,
+ ExposureBiasValue: 37380,
+ MaxApertureValue: 37381,
+ SubjectDistance: 37382,
+ MeteringMode: 37383,
+ LightSource: 37384,
+ Flash: 37385,
+ FocalLength: 37386,
+ SubjectArea: 37396,
+ MakerNote: 37500,
+ UserComment: 37510,
+ SubSecTime: 37520,
+ SubSecTimeOriginal: 37521,
+ SubSecTimeDigitized: 37522,
+ FlashpixVersion: 40960,
+ ColorSpace: 40961,
+ PixelXDimension: 40962,
+ PixelYDimension: 40963,
+ RelatedSoundFile: 40964,
+ InteroperabilityTag: 40965,
+ FlashEnergy: 41483,
+ SpatialFrequencyResponse: 41484,
+ FocalPlaneXResolution: 41486,
+ FocalPlaneYResolution: 41487,
+ FocalPlaneResolutionUnit: 41488,
+ SubjectLocation: 41492,
+ ExposureIndex: 41493,
+ SensingMethod: 41495,
+ FileSource: 41728,
+ SceneType: 41729,
+ CFAPattern: 41730,
+ CustomRendered: 41985,
+ ExposureMode: 41986,
+ WhiteBalance: 41987,
+ DigitalZoomRatio: 41988,
+ FocalLengthIn35mmFilm: 41989,
+ SceneCaptureType: 41990,
+ GainControl: 41991,
+ Contrast: 41992,
+ Saturation: 41993,
+ Sharpness: 41994,
+ DeviceSettingDescription: 41995,
+ SubjectDistanceRange: 41996,
+ ImageUniqueID: 42016,
+ CameraOwnerName: 42032,
+ BodySerialNumber: 42033,
+ LensSpecification: 42034,
+ LensMake: 42035,
+ LensModel: 42036,
+ LensSerialNumber: 42037,
+ Gamma: 42240,
+ }
+ GPSIFD = {
+ GPSVersionID: 0,
+ GPSLatitudeRef: 1,
+ GPSLatitude: 2,
+ GPSLongitudeRef: 3,
+ GPSLongitude: 4,
+ GPSAltitudeRef: 5,
+ GPSAltitude: 6,
+ GPSTimeStamp: 7,
+ GPSSatellites: 8,
+ GPSStatus: 9,
+ GPSMeasureMode: 10,
+ GPSDOP: 11,
+ GPSSpeedRef: 12,
+ GPSSpeed: 13,
+ GPSTrackRef: 14,
+ GPSTrack: 15,
+ GPSImgDirectionRef: 16,
+ GPSImgDirection: 17,
+ GPSMapDatum: 18,
+ GPSDestLatitudeRef: 19,
+ GPSDestLatitude: 20,
+ GPSDestLongitudeRef: 21,
+ GPSDestLongitude: 22,
+ GPSDestBearingRef: 23,
+ GPSDestBearing: 24,
+ GPSDestDistanceRef: 25,
+ GPSDestDistance: 26,
+ GPSProcessingMethod: 27,
+ GPSAreaInformation: 28,
+ GPSDateStamp: 29,
+ GPSDifferential: 30,
+ GPSHPositioningError: 31,
+ }
+ InteropIFD = {
+ InteroperabilityIndex: 1,
+ }
+ GPSHelper = {
+ degToDmsRational(degFloat : number) {
+ const degAbs = Math.abs(degFloat);
+ const minFloat = degAbs % 1 * 60;
+ const secFloat = minFloat % 1 * 60;
+ const deg = Math.floor(degAbs);
+ const min = Math.floor(minFloat);
+ const sec = Math.round(secFloat * 100);
+
+ return [
+ [deg, 1],
+ [min, 1],
+ [sec, 100]
+ ];
+ },
+ dmsRationalToDeg(dmsArray : number[][], ref : string) {
+ const sign = (ref === 'S' || ref === 'W') ? -1.0 : 1.0;
+ const deg = dmsArray[0][0] / dmsArray[0][1] +
+ dmsArray[1][0] / dmsArray[1][1] / 60.0 +
+ dmsArray[2][0] / dmsArray[2][1] / 3600.0;
+
+ return deg * sign;
+ },
+ }
+ remove(jpeg) {
+ let b64 = false;
+ if (jpeg.slice(0, 2) == "\xff\xd8") { } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg
+ .slice(0, 22) == "data:image/jpg;base64,") {
+ jpeg = atob(jpeg.split(",")[1]);
+ b64 = true;
+ } else {
+ throw new Error("Given data is not jpeg.");
+ }
+
+ const segments = splitIntoSegments(jpeg);
+ const newSegments = segments.filter(function (seg) {
+ return !(seg.slice(0, 2) == "\xff\xe1" &&
+ seg.slice(4, 10) == "Exif\x00\x00");
+ });
+
+ let new_data = newSegments.join("");
+ if (b64) {
+ new_data = "data:image/jpeg;base64," + btoa(new_data);
+ }
+
+ return new_data;
+ }
+ insert(exif, jpeg) {
+ let b64 = false;
+ if (exif.slice(0, 6) != "\x45\x78\x69\x66\x00\x00") {
+ throw new Error("Given data is not exif.");
+ }
+ if (jpeg.slice(0, 2) == "\xff\xd8") { } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg
+ .slice(0, 22) == "data:image/jpg;base64,") {
+ jpeg = atob(jpeg.split(",")[1]);
+ b64 = true;
+ } else {
+ throw new Error("Given data is not jpeg.");
+ }
+
+ const exifStr = "\xff\xe1" + pack(">H", [exif.length + 2]) + exif;
+ const segments = splitIntoSegments(jpeg);
+ let new_data = mergeSegments(segments, exifStr);
+ if (b64) {
+ new_data = "data:image/jpeg;base64," + btoa(new_data);
+ }
+
+ return new_data;
+ }
+ load(data) {
+ let input_data;
+ if (isString(data)) {
+ if (data.slice(0, 2) == "\xff\xd8") {
+ input_data = data;
+ } else if (data.slice(0, 23) == "data:image/jpeg;base64," || data.slice(0, 22) == "data:image/jpg;base64,") {
+ input_data = atob(data.split(",")[1]);
+ } else if (data.slice(0, 4) == "Exif") {
+ input_data = data.slice(6);
+ } else {
+ throw new Error("'load' gots invalid file data.");
+ }
+ } else {
+ throw new Error("'load' gots invalid type argument.");
+ }
+
+ let exifDict = {};
+ let exif_dict = {
+ "0th": {},
+ "Exif": {},
+ "GPS": {},
+ "Interop": {},
+ "1st": {},
+ "thumbnail": null
+ };
+ const exifReader = new ExifReader(input_data);
+ if (exifReader.tiftag === null) {
+ return exif_dict;
+ }
+
+ if (exifReader.tiftag.slice(0, 2) == "\x49\x49") {
+ exifReader.endian_mark = "<";
+ } else {
+ exifReader.endian_mark = ">";
+ }
+
+ let pointer = unpack(exifReader.endian_mark + "L",
+ exifReader.tiftag.slice(4, 8))[0];
+ exif_dict["0th"] = exifReader.get_ifd(pointer, "0th");
+
+ const first_ifd_pointer = exif_dict["0th"]["first_ifd_pointer"];
+ delete exif_dict["0th"]["first_ifd_pointer"];
+
+ if (34665 in exif_dict["0th"]) {
+ pointer = exif_dict["0th"][34665];
+ exif_dict["Exif"] = exifReader.get_ifd(pointer, "Exif");
+ }
+ if (34853 in exif_dict["0th"]) {
+ pointer = exif_dict["0th"][34853];
+ exif_dict["GPS"] = exifReader.get_ifd(pointer, "GPS");
+ }
+ if (40965 in exif_dict["Exif"]) {
+ pointer = exif_dict["Exif"][40965];
+ exif_dict["Interop"] = exifReader.get_ifd(pointer, "Interop");
+ }
+ if (first_ifd_pointer != "\x00\x00\x00\x00") {
+ pointer = unpack(exifReader.endian_mark + "L",
+ first_ifd_pointer)[0];
+ exif_dict["1st"] = exifReader.get_ifd(pointer, "1st");
+ if ((513 in exif_dict["1st"]) && (514 in exif_dict["1st"])) {
+ var end = exif_dict["1st"][513] + exif_dict["1st"][514];
+ var thumb = exifReader.tiftag.slice(exif_dict["1st"][513], end);
+ exif_dict["thumbnail"] = thumb;
+ }
+ }
+
+ return exif_dict;
+ }
+ dump(exif_dict_original) {
+ const TIFF_HEADER_LENGTH = 8;
+
+ const exif_dict : any = cloneDeep(exif_dict_original);
+ const header = "Exif\x00\x00\x4d\x4d\x00\x2a\x00\x00\x00\x08";
+ let exif_is = 0//false;
+ let gps_is = 0 //false;
+ let interop_is = 0//false;
+ let first_is = false;
+
+ let zeroth_ifd,
+ exif_ifd,
+ interop_ifd,
+ gps_ifd,
+ first_ifd;
+
+ if ("0th" in exif_dict) {
+ zeroth_ifd = exif_dict["0th"];
+ } else {
+ zeroth_ifd = {};
+ }
+
+ if ((("Exif" in exif_dict) && (Object.keys(exif_dict["Exif"]).length)) ||
+ (("Interop" in exif_dict) && (Object.keys(exif_dict["Interop"]).length))) {
+ zeroth_ifd[34665] = 1;
+ exif_is = 1//true;
+ exif_ifd = exif_dict["Exif"];
+ if (("Interop" in exif_dict) && Object.keys(exif_dict["Interop"]).length) {
+ exif_ifd[40965] = 1;
+ interop_is = 1//true;
+ interop_ifd = exif_dict["Interop"];
+ } else if (Object.keys(exif_ifd).indexOf(this.ExifIFD.InteroperabilityTag.toString()) > -1) {
+ delete exif_ifd[40965];
+ }
+ } else if (Object.keys(zeroth_ifd).indexOf(this.ImageIFD.ExifTag.toString()) > -1) {
+ delete zeroth_ifd[34665];
+ }
+
+ if (("GPS" in exif_dict) && (Object.keys(exif_dict["GPS"]).length)) {
+ zeroth_ifd[this.ImageIFD.GPSTag] = 1;
+ gps_is = 1 //true;
+ gps_ifd = exif_dict["GPS"];
+ } else if (Object.keys(zeroth_ifd).indexOf(this.ImageIFD.GPSTag.toString()) > -1) {
+ delete zeroth_ifd[this.ImageIFD.GPSTag];
+ }
+
+ if (("1st" in exif_dict) &&
+ ("thumbnail" in exif_dict) &&
+ (exif_dict["thumbnail"] != null)) {
+ first_is = true;
+ exif_dict["1st"][513] = 1;
+ exif_dict["1st"][514] = 1;
+ first_ifd = exif_dict["1st"];
+ }
+
+ const zeroth_set = _dict_to_bytes(zeroth_ifd, "0th", 0);
+ const zeroth_length = (zeroth_set[0].length + exif_is * 12 + gps_is * 12 + 4 +
+ zeroth_set[1].length);
+
+ let exif_set,
+ exif_bytes = "",
+ exif_length = 0,
+ gps_set,
+ gps_bytes = "",
+ gps_length = 0,
+ interop_set,
+ interop_bytes = "",
+ interop_length = 0,
+ first_set,
+ first_bytes = "",
+ thumbnail;
+ if (exif_is) {
+ exif_set = _dict_to_bytes(exif_ifd, "Exif", zeroth_length);
+ exif_length = exif_set[0].length + interop_is * 12 + exif_set[1].length;
+ }
+ if (gps_is) {
+ gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length);
+ gps_bytes = gps_set.join("");
+ gps_length = gps_bytes.length;
+ }
+ if (interop_is) {
+ const offset = zeroth_length + exif_length + gps_length;
+ interop_set = _dict_to_bytes(interop_ifd, "Interop", offset);
+ interop_bytes = interop_set.join("");
+ interop_length = interop_bytes.length;
+ }
+ if (first_is) {
+ const offset = zeroth_length + exif_length + gps_length + interop_length;
+ first_set = _dict_to_bytes(first_ifd, "1st", offset);
+ thumbnail = _get_thumbnail(exif_dict["thumbnail"]);
+ if (thumbnail.length > 64000) {
+ throw new Error("Given thumbnail is too large. max 64kB");
+ }
+ }
+
+ let exif_pointer = "",
+ gps_pointer = "",
+ interop_pointer = "",
+ first_ifd_pointer = "\x00\x00\x00\x00";
+ if (exif_is) {
+ const pointer_value = TIFF_HEADER_LENGTH + zeroth_length;
+ const pointer_str = pack(">L", [pointer_value]);
+ const key = 34665;
+ const key_str = pack(">H", [key]);
+ const type_str = pack(">H", [TYPES["Long"]]);
+ const length_str = pack(">L", [1]);
+ exif_pointer = key_str + type_str + length_str + pointer_str;
+ }
+ if (gps_is) {
+ const pointer_value = TIFF_HEADER_LENGTH + zeroth_length + exif_length;
+ const pointer_str = pack(">L", [pointer_value]);
+ const key = 34853;
+ const key_str = pack(">H", [key]);
+ const type_str = pack(">H", [TYPES["Long"]]);
+ const length_str = pack(">L", [1]);
+ gps_pointer = key_str + type_str + length_str + pointer_str;
+ }
+ if (interop_is) {
+ const pointer_value = (TIFF_HEADER_LENGTH +
+ zeroth_length + exif_length + gps_length);
+ const pointer_str = pack(">L", [pointer_value]);
+ const key = 40965;
+ const key_str = pack(">H", [key]);
+ const type_str = pack(">H", [TYPES["Long"]]);
+ const length_str = pack(">L", [1]);
+ interop_pointer = key_str + type_str + length_str + pointer_str;
+ }
+ if (first_is) {
+ const pointer_value = (TIFF_HEADER_LENGTH + zeroth_length +
+ exif_length + gps_length + interop_length);
+ first_ifd_pointer = pack(">L", [pointer_value]);
+ const thumbnail_pointer = (pointer_value + first_set[0].length + 24 +
+ 4 + first_set[1].length);
+ const thumbnail_p_bytes = ("\x02\x01\x00\x04\x00\x00\x00\x01" +
+ pack(">L", [thumbnail_pointer]));
+ const thumbnail_length_bytes = ("\x02\x02\x00\x04\x00\x00\x00\x01" +
+ pack(">L", [thumbnail.length]));
+ first_bytes = (first_set[0] + thumbnail_p_bytes +
+ thumbnail_length_bytes + "\x00\x00\x00\x00" +
+ first_set[1] + thumbnail);
+ }
+
+ const zeroth_bytes = (zeroth_set[0] + exif_pointer + gps_pointer +
+ first_ifd_pointer + zeroth_set[1]);
+ if (exif_is) {
+ exif_bytes = exif_set[0] + interop_pointer + exif_set[1];
+ }
+
+ return (header + zeroth_bytes + exif_bytes + gps_bytes +
+ interop_bytes + first_bytes);
+ }
+}
+
+
+
+function _get_thumbnail(jpeg) {
+ let segments = splitIntoSegments(jpeg);
+ while (("\xff\xe0" <= segments[1].slice(0, 2)) && (segments[1].slice(0, 2) <= "\xff\xef")) {
+ segments = [segments[0]].concat(segments.slice(2));
+ }
+ return segments.join("");
+}
+function _pack_byte(array) {
+ return pack(">" + nStr("B", array.length), array);
+}
+
+function _pack_short(array) {
+ return pack(">" + nStr("H", array.length), array);
+}
+
+function _pack_long(array) {
+ return pack(">" + nStr("L", array.length), array);
+}
+
+function _value_to_bytes(raw_value, value_type, offset) {
+ let four_bytes_over = "";
+ let value_str = "";
+ let length,
+ new_value,
+ num,
+ den;
+
+ if (value_type == "Byte") {
+ length = raw_value.length;
+ if (length <= 4) {
+ value_str = (_pack_byte(raw_value) +
+ nStr("\x00", 4 - length));
+ } else {
+ value_str = pack(">L", [offset]);
+ four_bytes_over = _pack_byte(raw_value);
+ }
+ } else if (value_type == "Short") {
+ length = raw_value.length;
+ if (length <= 2) {
+ value_str = (_pack_short(raw_value) +
+ nStr("\x00\x00", 2 - length));
+ } else {
+ value_str = pack(">L", [offset]);
+ four_bytes_over = _pack_short(raw_value);
+ }
+ } else if (value_type == "Long") {
+ length = raw_value.length;
+ if (length <= 1) {
+ value_str = _pack_long(raw_value);
+ } else {
+ value_str = pack(">L", [offset]);
+ four_bytes_over = _pack_long(raw_value);
+ }
+ } else if (value_type == "Ascii") {
+ new_value = raw_value + "\x00";
+ length = new_value.length;
+ if (length > 4) {
+ value_str = pack(">L", [offset]);
+ four_bytes_over = new_value;
+ } else {
+ value_str = new_value + nStr("\x00", 4 - length);
+ }
+ } else if (value_type == "Rational") {
+ if (typeof (raw_value[0]) == "number") {
+ length = 1;
+ num = raw_value[0];
+ den = raw_value[1];
+ new_value = pack(">L", [num]) + pack(">L", [den]);
+ } else {
+ length = raw_value.length;
+ new_value = "";
+ for (var n = 0; n < length; n++) {
+ num = raw_value[n][0];
+ den = raw_value[n][1];
+ new_value += (pack(">L", [num]) +
+ pack(">L", [den]));
+ }
+ }
+ value_str = pack(">L", [offset]);
+ four_bytes_over = new_value;
+ } else if (value_type == "SRational") {
+ if (typeof (raw_value[0]) == "number") {
+ length = 1;
+ num = raw_value[0];
+ den = raw_value[1];
+ new_value = pack(">l", [num]) + pack(">l", [den]);
+ } else {
+ length = raw_value.length;
+ new_value = "";
+ for (var n = 0; n < length; n++) {
+ num = raw_value[n][0];
+ den = raw_value[n][1];
+ new_value += (pack(">l", [num]) +
+ pack(">l", [den]));
+ }
+ }
+ value_str = pack(">L", [offset]);
+ four_bytes_over = new_value;
+ } else if (value_type == "Undefined") {
+ length = raw_value.length;
+ if (length > 4) {
+ value_str = pack(">L", [offset]);
+ four_bytes_over = raw_value;
+ } else {
+ value_str = raw_value + nStr("\x00", 4 - length);
+ }
+ }
+
+ var length_str = pack(">L", [length]);
+
+ return [length_str, value_str, four_bytes_over];
+}
+
+function _dict_to_bytes(ifd_dict, ifd, ifd_offset) {
+ const TIFF_HEADER_LENGTH = 8;
+ const tag_count = Object.keys(ifd_dict).length;
+ const entry_header = pack(">H", [tag_count]);
+ let entries_length;
+ if (["0th", "1st"].indexOf(ifd) > -1) {
+ entries_length = 2 + tag_count * 12 + 4;
+ } else {
+ entries_length = 2 + tag_count * 12;
+ }
+ let entries = "";
+ let values = "";
+ let key;
+
+ for (key in ifd_dict) {
+ if (typeof (key) == "string") {
+ key = parseInt(key);
+ }
+ if ((ifd == "0th") && ([34665, 34853].indexOf(key) > -1)) {
+ continue;
+ } else if ((ifd == "Exif") && (key == 40965)) {
+ continue;
+ } else if ((ifd == "1st") && ([513, 514].indexOf(key) > -1)) {
+ continue;
+ }
+
+ var raw_value = ifd_dict[key];
+ var key_str = pack(">H", [key]);
+ var value_type = TAGS[ifd][key]["type"];
+ var type_str = pack(">H", [TYPES[value_type]]);
+
+ if (typeof (raw_value) == "number") {
+ raw_value = [raw_value];
+ }
+ var offset = TIFF_HEADER_LENGTH + entries_length + ifd_offset + values.length;
+ var b = _value_to_bytes(raw_value, value_type, offset);
+ var length_str = b[0];
+ var value_str = b[1];
+ var four_bytes_over = b[2];
+
+ entries += key_str + type_str + length_str + value_str;
+ values += four_bytes_over;
+ }
+
+ return [entry_header + entries, values];
+}
+
+
+
+class ExifReader {
+ tiftag = null
+ endian_mark = ''
+ constructor(data) {
+ let segments,
+ app1;
+ if (data.slice(0, 2) == "\xff\xd8") { // JPEG
+ segments = splitIntoSegments(data);
+ app1 = getExifSeg(segments);
+ if (app1) {
+ this.tiftag = app1.slice(10);
+ }
+ } else if (["\x49\x49", "\x4d\x4d"].indexOf(data.slice(0, 2)) > -1) { // TIFF
+ this.tiftag = data;
+ } else if (data.slice(0, 4) == "Exif") { // Exif
+ this.tiftag = data.slice(6);
+ } else {
+ throw new Error("Given file is neither JPEG nor TIFF.");
+ }
+ }
+ get_ifd(pointer, ifd_name) {
+ let ifd_dict = {};
+ let tag_count = unpack(this.endian_mark + "H",
+ this.tiftag.slice(pointer, pointer + 2))[0];
+ const offset = pointer + 2;
+ let t;
+ if (["0th", "1st"].indexOf(ifd_name) > -1) {
+ t = "Image";
+ } else {
+ t = ifd_name;
+ }
+
+ for (let x = 0; x < tag_count; x++) {
+ pointer = offset + 12 * x;
+ const tag = unpack(this.endian_mark + "H",
+ this.tiftag.slice(pointer, pointer + 2))[0];
+ const value_type = unpack(this.endian_mark + "H",
+ this.tiftag.slice(pointer + 2, pointer + 4))[0];
+ const value_num = unpack(this.endian_mark + "L",
+ this.tiftag.slice(pointer + 4, pointer + 8))[0];
+ const value = this.tiftag.slice(pointer + 8, pointer + 12);
+
+ const v_set = [value_type, value_num, value];
+ if (tag in TAGS[t]) {
+ ifd_dict[tag] = this.convert_value(v_set);
+ }
+ }
+
+ if (ifd_name == "0th") {
+ pointer = offset + 12 * tag_count;
+ ifd_dict["first_ifd_pointer"] = this.tiftag.slice(pointer, pointer + 4);
+ }
+
+ return ifd_dict;
+ }
+
+ convert_value(val) {
+ let data = null;
+ const t = val[0];
+ const length = val[1];
+ const value = val[2];
+ let pointer;
+
+ if (t == 1) { // BYTE
+ if (length > 4) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = unpack(this.endian_mark + nStr("B", length),
+ this.tiftag.slice(pointer, pointer + length));
+ } else {
+ data = unpack(this.endian_mark + nStr("B", length), value.slice(0, length));
+ }
+ } else if (t == 2) { // ASCII
+ if (length > 4) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = this.tiftag.slice(pointer, pointer + length - 1);
+ } else {
+ data = value.slice(0, length - 1);
+ }
+ } else if (t == 3) { // SHORT
+ if (length > 2) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = unpack(this.endian_mark + nStr("H", length),
+ this.tiftag.slice(pointer, pointer + length * 2));
+ } else {
+ data = unpack(this.endian_mark + nStr("H", length),
+ value.slice(0, length * 2));
+ }
+ } else if (t == 4) { // LONG
+ if (length > 1) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = unpack(this.endian_mark + nStr("L", length),
+ this.tiftag.slice(pointer, pointer + length * 4));
+ } else {
+ data = unpack(this.endian_mark + nStr("L", length),
+ value);
+ }
+ } else if (t == 5) { // RATIONAL
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ if (length > 1) {
+ data = [];
+ for (let x = 0; x < length; x++) {
+ data.push([unpack(this.endian_mark + "L",
+ this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
+ unpack(this.endian_mark + "L",
+ this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
+ ]);
+ }
+ } else {
+ data = [unpack(this.endian_mark + "L",
+ this.tiftag.slice(pointer, pointer + 4))[0],
+ unpack(this.endian_mark + "L",
+ this.tiftag.slice(pointer + 4, pointer + 8))[0]
+ ];
+ }
+ } else if (t == 7) { // UNDEFINED BYTES
+ if (length > 4) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = this.tiftag.slice(pointer, pointer + length);
+ } else {
+ data = value.slice(0, length);
+ }
+ } else if (t == 9) { // SLONG
+ if (length > 1) {
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ data = unpack(this.endian_mark + nStr("l", length),
+ this.tiftag.slice(pointer, pointer + length * 4));
+ } else {
+ data = unpack(this.endian_mark + nStr("l", length),
+ value);
+ }
+ } else if (t == 10) { // SRATIONAL
+ pointer = unpack(this.endian_mark + "L", value)[0];
+ if (length > 1) {
+ data = [];
+ for (let x = 0; x < length; x++) {
+ data.push([unpack(this.endian_mark + "l",
+ this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
+ unpack(this.endian_mark + "l",
+ this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
+ ]);
+ }
+ } else {
+ data = [unpack(this.endian_mark + "l",
+ this.tiftag.slice(pointer, pointer + 4))[0],
+ unpack(this.endian_mark + "l",
+ this.tiftag.slice(pointer + 4, pointer + 8))[0]
+ ];
+ }
+ } else {
+ throw new Error("Exif might be wrong. Got incorrect value " +
+ "type to decode. type:" + t);
+ }
+
+ if ((data instanceof Array) && (data.length == 1)) {
+ return data[0];
+ } else {
+ return data;
+ }
+ }
+
+}
+
+
+function pack(mark, array) {
+ if (!(array instanceof Array)) {
+ throw new Error("'pack' error. Got invalid type argument.");
+ }
+ if ((mark.length - 1) != array.length) {
+ throw new Error("'pack' error. " + (mark.length - 1) + " marks, " + array.length + " elements.");
+ }
+
+ let littleEndian;
+ if (mark[0] == "<") {
+ littleEndian = true;
+ } else if (mark[0] == ">") {
+ littleEndian = false;
+ } else {
+ throw new Error("");
+ }
+ let packed = "";
+ let p = 1;
+ let val = null;
+ let c = null;
+ let valStr = null;
+
+ while (c = mark[p]) {
+ if (c.toLowerCase() == "b") {
+ val = array[p - 1];
+ if ((c == "b") && (val < 0)) {
+ val += 0x100;
+ }
+ if ((val > 0xff) || (val < 0)) {
+ throw new Error("'pack' error.");
+ } else {
+ valStr = String.fromCharCode(val);
+ }
+ } else if (c == "H") {
+ val = array[p - 1];
+ if ((val > 0xffff) || (val < 0)) {
+ throw new Error("'pack' error.");
+ } else {
+ valStr = String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
+ String.fromCharCode(val % 0x100);
+ if (littleEndian) {
+ valStr = valStr.split("").reverse().join("");
+ }
+ }
+ } else if (c.toLowerCase() == "l") {
+ val = array[p - 1];
+ if ((c == "l") && (val < 0)) {
+ val += 0x100000000;
+ }
+ if ((val > 0xffffffff) || (val < 0)) {
+ throw new Error("'pack' error.");
+ } else {
+ valStr = String.fromCharCode(Math.floor(val / 0x1000000)) +
+ String.fromCharCode(Math.floor((val % 0x1000000) / 0x10000)) +
+ String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
+ String.fromCharCode(val % 0x100);
+ if (littleEndian) {
+ valStr = valStr.split("").reverse().join("");
+ }
+ }
+ } else {
+ throw new Error("'pack' error.");
+ }
+
+ packed += valStr;
+ p += 1;
+ }
+
+ return packed;
+}
+
+
+function unpack(mark, str) {
+ if (typeof (str) != "string") {
+ throw new Error("'unpack' error. Got invalid type argument.");
+ }
+ let l = 0;
+ for (let markPointer = 1; markPointer < mark.length; markPointer++) {
+ if (mark[markPointer].toLowerCase() == "b") {
+ l += 1;
+ } else if (mark[markPointer].toLowerCase() == "h") {
+ l += 2;
+ } else if (mark[markPointer].toLowerCase() == "l") {
+ l += 4;
+ } else {
+ throw new Error("'unpack' error. Got invalid mark.");
+ }
+ }
+
+ if (l != str.length) {
+ throw new Error("'unpack' error. Mismatch between symbol and string length. " + l + ":" + str.length);
+ }
+
+ let littleEndian;
+ if (mark[0] == "<") {
+ littleEndian = true;
+ } else if (mark[0] == ">") {
+ littleEndian = false;
+ } else {
+ throw new Error("'unpack' error.");
+ }
+ let unpacked = [];
+ let strPointer = 0;
+ let p = 1;
+ let val = null;
+ let c = null;
+ let length = null;
+ let sliced = "";
+
+ while (c = mark[p]) {
+ if (c.toLowerCase() == "b") {
+ length = 1;
+ sliced = str.slice(strPointer, strPointer + length);
+ val = sliced.charCodeAt(0);
+ if ((c == "b") && (val >= 0x80)) {
+ val -= 0x100;
+ }
+ } else if (c == "H") {
+ length = 2;
+ sliced = str.slice(strPointer, strPointer + length);
+ if (littleEndian) {
+ sliced = sliced.split("").reverse().join("");
+ }
+ val = sliced.charCodeAt(0) * 0x100 +
+ sliced.charCodeAt(1);
+ } else if (c.toLowerCase() == "l") {
+ length = 4;
+ sliced = str.slice(strPointer, strPointer + length);
+ if (littleEndian) {
+ sliced = sliced.split("").reverse().join("");
+ }
+ val = sliced.charCodeAt(0) * 0x1000000 +
+ sliced.charCodeAt(1) * 0x10000 +
+ sliced.charCodeAt(2) * 0x100 +
+ sliced.charCodeAt(3);
+ if ((c == "l") && (val >= 0x80000000)) {
+ val -= 0x100000000;
+ }
+ } else {
+ throw new Error("'unpack' error. " + c);
+ }
+
+ unpacked.push(val);
+ strPointer += length;
+ p += 1;
+ }
+
+ return unpacked;
+}
+
+
+function nStr(ch, num) {
+ let str = "";
+ for (let i = 0; i < num; i++) {
+ str += ch;
+ }
+ return str;
+}
+
+
+function splitIntoSegments(data) {
+ if (data.slice(0, 2) != "\xff\xd8") {
+ throw new Error("Given data isn't JPEG.");
+ }
+
+ let head = 2;
+ const segments = ["\xff\xd8"];
+ while (true) {
+ if (data.slice(head, head + 2) == "\xff\xda") {
+ segments.push(data.slice(head));
+ break;
+ } else {
+ var length = unpack(">H", data.slice(head + 2, head + 4))[0];
+ var endPoint = head + length + 2;
+ segments.push(data.slice(head, endPoint));
+ head = endPoint;
+ }
+
+ if (head >= data.length) {
+ throw new Error("Wrong JPEG data.");
+ }
+ }
+ return segments;
+}
+
+
+function getExifSeg(segments) {
+ let seg;
+ for (let i = 0; i < segments.length; i++) {
+ seg = segments[i];
+ if (seg.slice(0, 2) == "\xff\xe1" &&
+ seg.slice(4, 10) == "Exif\x00\x00") {
+ return seg;
+ }
+ }
+ return null;
+}
+
+
+function mergeSegments(segments, exif) {
+ let hasExifSegment = false;
+ let additionalAPP1ExifSegments = [];
+
+ segments.forEach(function (segment, i) {
+ // Replace first occurence of APP1:Exif segment
+ if (segment.slice(0, 2) == "\xff\xe1" &&
+ segment.slice(4, 10) == "Exif\x00\x00"
+ ) {
+ if (!hasExifSegment) {
+ segments[i] = exif;
+ hasExifSegment = true;
+ } else {
+ additionalAPP1ExifSegments.unshift(i);
+ }
+ }
+ });
+
+ // Remove additional occurences of APP1:Exif segment
+ additionalAPP1ExifSegments.forEach(function (segmentIndex) {
+ segments.splice(segmentIndex, 1);
+ });
+
+ if (!hasExifSegment && exif) {
+ segments = [segments[0], exif].concat(segments.slice(1));
+ }
+
+ return segments.join("");
+}
+
+
diff --git a/src/uni_modules/lime-shared/platform/index.ts b/src/uni_modules/lime-shared/platform/index.ts
new file mode 100644
index 0000000..af07091
--- /dev/null
+++ b/src/uni_modules/lime-shared/platform/index.ts
@@ -0,0 +1,27 @@
+// @ts-nocheck
+declare var tt: Uni
+declare var swan: Uni
+declare var my: Uni
+declare var dd: Uni
+declare var ks: Uni
+declare var jd: Uni
+declare var qa: Uni
+declare var qq: Uni
+declare var qh: Uni
+declare var qq: Uni
+
+export function platform(): Uni | WechatMiniprogram.Wx {
+ const UNDEFINED = 'undefined'
+ if(typeof wx !== UNDEFINED) return wx // 微信
+ if(typeof tt !== UNDEFINED) return tt // 字节 飞书
+ if(typeof swan !== UNDEFINED) return swan // 百度
+ if(typeof my !== UNDEFINED) return my // 支付宝
+ if(typeof dd !== UNDEFINED) return dd // 钉钉
+ if(typeof ks !== UNDEFINED) return ks // 快手
+ if(typeof jd !== UNDEFINED) return jd // 京东
+ if(typeof qa !== UNDEFINED) return qa // 快应用
+ if(typeof qq !== UNDEFINED) return qq // qq
+ if(typeof qh !== UNDEFINED) return qh // 360
+ if(typeof uni !== UNDEFINED) return uni
+ return null
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/raf/index.ts b/src/uni_modules/lime-shared/raf/index.ts
new file mode 100644
index 0000000..ec7650d
--- /dev/null
+++ b/src/uni_modules/lime-shared/raf/index.ts
@@ -0,0 +1,30 @@
+// @ts-nocheck
+import {isBrowser} from '../isBrowser'
+
+// 是否支持被动事件监听
+export const supportsPassive = true;
+
+// 请求动画帧
+export function raf(fn: FrameRequestCallback): number {
+ // 如果是在浏览器环境下,使用 requestAnimationFrame 方法
+ if (isBrowser) {
+ return requestAnimationFrame(fn); // 请求动画帧
+ } else { // 在非浏览器环境下,使用 setTimeout 模拟
+ return setTimeout(fn, 1000 / 30); // 使用 setTimeout 模拟动画帧,每秒钟执行 30 次
+ }
+}
+
+// 取消动画帧
+export function cancelRaf(id: number) {
+ // 如果是在浏览器环境下,使用 cancelAnimationFrame 方法
+ if (isBrowser) {
+ cancelAnimationFrame(id); // 取消动画帧
+ } else { // 在非浏览器环境下,使用 clearTimeout 模拟
+ clearTimeout(id); // 使用 clearTimeout 模拟取消动画帧
+ }
+}
+
+// 双倍动画帧
+export function doubleRaf(fn: FrameRequestCallback): void {
+ raf(() => raf(fn)); // 在下一帧回调中再次请求动画帧,实现双倍动画帧效果
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/random/index.ts b/src/uni_modules/lime-shared/random/index.ts
new file mode 100644
index 0000000..dbf2681
--- /dev/null
+++ b/src/uni_modules/lime-shared/random/index.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+/**
+ * 生成一个指定范围内的随机数
+ * @param min 随机数的最小值
+ * @param max 随机数的最大值
+ * @param fixed 随机数的小数位数,默认为 0
+ * @returns 生成的随机数
+ */
+export function random(min: number, max: number, fixed: number = 0) {
+ // 将 min 和 max 转换为数字类型
+ min = +min || 0;
+ max = +max || 0;
+ // 计算随机数范围内的一个随机数
+ const num = Math.random() * (max - min) + min;
+ // 如果 fixed 参数为 0,则返回四舍五入的整数随机数;否则保留固定小数位数
+ return fixed == 0 ? Math.round(num) : Number(num.toFixed(fixed));
+}
+
+// 示例
+// console.log(random(0, 10)); // 输出:在 0 和 10 之间的一个整数随机数
+// console.log(random(0, 1, 2)); // 输出:在 0 和 1 之间的一个保留两位小数的随机数
+// console.log(random(1, 100, 3)); // 输出:在 1 和 100 之间的一个保留三位小数的随机数
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/range/index.ts b/src/uni_modules/lime-shared/range/index.ts
new file mode 100644
index 0000000..80acfbf
--- /dev/null
+++ b/src/uni_modules/lime-shared/range/index.ts
@@ -0,0 +1,31 @@
+// @ts-nocheck
+/**
+ * 生成一个数字范围的数组
+ * @param start 范围的起始值
+ * @param end 范围的结束值
+ * @param step 步长,默认为 1
+ * @param fromRight 是否从右侧开始生成,默认为 false
+ * @returns 生成的数字范围数组
+ */
+export function range(start: number, end: number, step: number = 1, fromRight: boolean = false): number[] {
+ let index = -1;
+ // 计算范围的长度
+ let length = Math.max(Math.ceil((end - start) / (step || 1)), 0);
+ // 创建一个长度为 length 的数组
+ const result = new Array(length);
+
+ // 使用循环生成数字范围数组
+ while (length--) {
+ // 根据 fromRight 参数决定从左侧还是右侧开始填充数组
+ result[fromRight ? length : ++index] = start;
+ start += step;
+ }
+
+ return result;
+}
+
+
+// 示例
+// console.log(range(0, 5)); // 输出: [0, 1, 2, 3, 4]
+// console.log(range(1, 10, 2, true)); // 输出: [9, 7, 5, 3, 1]
+// console.log(range(5, 0, -1)); // 输出: [5, 4, 3, 2, 1]
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/readme.md b/src/uni_modules/lime-shared/readme.md
new file mode 100644
index 0000000..09ec7e9
--- /dev/null
+++ b/src/uni_modules/lime-shared/readme.md
@@ -0,0 +1,251 @@
+# lime-shared 工具库
+- 本人插件的几个公共函数
+
+## 引入
+```js
+// 按需引入
+// 这种只会引入相关的方法
+import {getRect} from '@/uni_modules/lime-shared/getRect'
+
+// 全量引入
+// 这种引入方式,会全量打包
+import {getRect} from '@/uni_modules/lime-shared'
+```
+
+## Utils
+
+#### getRect
+- 返回节点尺寸信息
+
+```js
+// 组件内需要传入上下文
+// 如果是nvue 则需要在节点上加与id或class同名的ref
+getRect('#id',{context: this}).then(res => {})
+```
+
+#### addUnit
+- 将未带单位的数值添加px,如果有单位则返回原值
+
+```js
+addUnit(10)
+// 10px
+```
+
+#### unitConvert
+- 将带有rpx|px的字符转成number,若本身是number则直接返回
+
+```js
+unitConvert('10rpx')
+// 5 设备不同 返回的值也不同
+unitConvert('10px')
+// 10
+unitConvert(10)
+// 10
+```
+
+#### canIUseCanvas2d
+- 环境是否支持使用 canvas 2d
+
+```js
+canIUseCanvas2d()
+// 若支持返回 true 否则 false
+```
+
+
+#### getCurrentPage
+- 获取当前页
+
+```js
+const page = getCurrentPage()
+```
+
+
+#### base64ToPath
+- 把base64的图片转成临时路径
+
+```js
+base64ToPath(`xxxxx`).then(res => {})
+```
+
+#### pathToBase64
+- 把图片的临时路径转成base64
+
+```js
+pathToBase64(`xxxxx/xxx.png`).then(res => {})
+```
+
+#### sleep
+- 睡眠,让 async 内部程序等待一定时间后再执行
+
+```js
+async next () => {
+ await sleep(300)
+ console.log('limeui');
+}
+```
+
+#### isBase64
+- 判断字符串是否为base64
+
+```js
+isBase64('xxxxx')
+```
+
+#### throttle
+- 节流
+
+```js
+throttle((nama) => {console.log(nama)}, 200)('limeui');
+```
+
+#### debounce
+- 防抖
+
+```js
+debounce((nama) => {console.log(nama)}, 200)('limeui');
+```
+
+#### random
+- 返回指定范围的随机数
+
+```js
+random(1, 5);
+```
+
+#### range
+- 生成区间数组
+
+```js
+range(0, 5)
+// [0,1,2,3,4,5]
+```
+
+#### clamp
+- 夹在min和max之间的数值,如小于min,返回min, 如大于max,返回max,否侧原值返回
+
+```js
+clamp(0, 10, -1)
+// 0
+clamp(0, 10, 11)
+// 10
+clamp(0, 10, 9)
+// 9
+```
+
+#### floatAdd
+- 返回两个浮点数相加的结果
+
+```js
+floatAdd(0.1, 0.2) // 0.3
+```
+
+
+#### fillZero
+- 补零,如果传入的是`个位数`则在前面补0
+
+```js
+fillZero(9);
+// 09
+```
+
+#### exif
+- 获取图片exif
+- 支持临时路径、base64
+
+```js
+uni.chooseImage({
+ count: 1, //最多可以选择的图片张数
+ sizeType: "original",
+ success: (res) => {
+ exif.getData(res.tempFiles[0], function() {
+ let tagj = exif.getTag(this, "GPSLongitude");
+ let Orientation = exif.getTag(this, 'Orientation');
+ console.log(tagj, Orientation)
+ })
+ }
+})
+```
+
+#### selectComponent
+- 获取页面或当前实例的指定组件,会在页面或实例向所有的节点查找(包括子组件或子子组件)
+- 仅vue3,vue2没有测试过
+
+```js
+// 当前页面
+const page = getCurrentPage()
+selectComponent('.custom', {context: page}).then(res => {
+})
+```
+
+
+#### createAnimation
+- 创建动画,与uni.createAnimation使用方法一致,只为了抹平nvue
+
+```html
+
+```
+```js
+const ball = ref(null)
+const animation = createAnimation({
+ transformOrigin: "50% 50%",
+ duration: 1000,
+ timingFunction: "ease",
+ delay: 0
+})
+
+animation.scale(2,2).rotate(45).step()
+// nvue 无导出数据,这样写只为了平台一致,
+// nvue 需要把 ref 传入,其它平台不需要
+const animationData = animation.export(ball.value)
+```
+
+
+## composition-api
+- 因本人插件需要兼容vue2/vue3,故增加一个vue文件,代替条件编译
+- vue2需要在main.js加上这一段
+```js
+// vue2
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+```
+
+```js
+//使用
+import {computed, onMounted, watch, reactive} from '@/uni_modules/lime-shared/vue'
+```
+
+
+## Hooks
+#### useIntersectionObserver
+- 使用 Intersection Observer 观察元素可见性的钩子函数
+
+```html
+
+
Hello world
+
+```
+
+```js
+// options 接口可传的参数,若在插件里context为必传
+interface UseIntersectionObserverOptions {
+ root ?: string; // 观察器的根元素选择器字符串
+ rootMargin ?: {
+ top ?: number; // 根元素顶部边距
+ bottom ?: number; // 根元素底部边距
+ left ?: number; // 根元素左侧边距
+ right ?: number; // 根元素右侧边距
+ }; // 根元素的边距
+ thresholds ?: any[]; // 交叉比例数组,用于指定何时触发回调函数
+ context ?: any; // 上下文对象,用于指定观察器的上下文
+ initialRatio ?: number; // 初始的交叉比例
+ observeAll ?: boolean; // 是否同时观察所有交叉对象
+}
+const options: UseIntersectionObserverOptions = {
+ rootMargin: {top: 44},
+ context: this
+}
+const {stop} = useIntersectionObserver('.target', (result) => {
+
+}, options)
+```
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/selectComponent/index.ts b/src/uni_modules/lime-shared/selectComponent/index.ts
new file mode 100644
index 0000000..39db2fe
--- /dev/null
+++ b/src/uni_modules/lime-shared/selectComponent/index.ts
@@ -0,0 +1,152 @@
+// @ts-nocheck
+interface SelectOptions {
+ context?: any
+ needAll?: boolean
+ node?: boolean
+}
+// #ifdef MP
+function selectMPComponent(key: string, name: string, context: any, needAll: boolean) {
+ const {proxy, $vm} = context
+ context = $vm || proxy
+ if(!['ref','component'].includes(key)) {
+ const queue = [context]
+ let result = null
+ const selector = (key == 'id' ? '#': '.') + name;
+ while(queue.length > 0) {
+ const child = queue.shift();
+ const flag = child?.selectComponent(selector)
+ if(flag) {
+ if(!needAll) {return result = flag.$vm}
+ return result = child.selectAllComponents(selector).map(item => item.$vm)
+ } else {
+ child.$children && (queue.push(...child.$children));
+ }
+ }
+ return result
+ } else {
+ const {$templateRefs} = context.$
+ const nameMap = {}
+ for (var i = 0; i < $templateRefs.length; i++) {
+ const item = $templateRefs[i]
+ nameMap[item.i] = item.r
+ }
+ let result = []
+ if(context.$children.length) {
+ const queue = [...context.$children]
+ while(queue.length > 0) {
+ const child = queue.shift();
+ if(key == 'component' && (child.type?.name === name || child.$?.type?.name === name)) {
+ result.push(child)
+ } else if(child.$refs && child.$refs[name]) {
+ result = child.$refs[name]
+ } else if(nameMap[child.id] === name){
+ result.push(child)
+ } else {
+ child.$children && (queue.push(...child.$children));
+ }
+ if(result.length && !needAll) {
+ return;
+ }
+ }
+ }
+ return needAll ? result : result[0]
+ }
+}
+// #endif
+// #ifdef H5
+function selectH5Component(key: string, name: string, context: any, needAll: boolean) {
+ const {_, component } = context
+ const child = {component: _ || component || context, children: null , subTree: null, props: null}
+ let result = []
+ let queue = [child]
+ while(queue.length > 0 ) {
+ const child = queue.shift()
+ const {component, children , props, subTree} = child
+ if(key === 'component' && component?.type?.name == name) {
+ result.push(component)
+ } else if(key === 'ref' && component && (props?.ref == name || component[key][name])) {
+ if(props?.ref == name) {
+ //exposed
+ result.push(component)
+ } else if(component[key][name]) {
+ result.push(component[key][name])
+ }
+ } else if(key !== 'ref' && component?.exposed && new RegExp(`\\b${name}\\b`).test(component.attrs[key])) {
+ // exposed
+ result.push(component)
+ } else if(children && Array.isArray(children)) {
+ queue.push(...children)
+ } else if(!component && subTree) {
+ queue.push(subTree)
+ } else if(component?.subTree) {
+ queue.push(component.subTree)
+ }
+ if(result.length && !needAll) {
+ break
+ }
+ }
+ return needAll ? result : result[0]
+}
+// #endif
+// #ifdef APP
+function selectAPPComponent(key: string, name: string, context: any, needAll: boolean, node: boolean) {
+ let result = []
+ // const {_, component} = context
+ // const child = {component: _ || component || context, children: null, props: null, subTree: null}
+ const queue = [context]
+ while(queue.length > 0) {
+ const child = queue.shift()
+ const {component, children, props, subTree} = child
+ const isComp = component && props && component.exposed && !node
+ if(key == 'component' && child.type && child.type.name === name) {
+ result.push(component)
+ } else if(props?.[key] === name && node) {
+ result.push(child)
+ } else if(key === 'ref' && isComp && (props.ref === name || props.ref_key === name)) {
+ // exposed
+ result.push(component)
+ } else if(key !== 'ref' && isComp && new RegExp(`\\b${name}\\b`).test(props[key])) {
+ // exposed
+ result.push(component)
+ }
+ // else if(component && component.subTree && Array.isArray(component.subTree.children)){
+ // queue.push(...component.subTree.children)
+ // }
+ else if(subTree) {
+ queue.push(subTree)
+ } else if(component && component.subTree){
+ queue.push(component.subTree)
+ }
+ else if(children && Array.isArray(children)) {
+ queue.push(...children)
+ }
+ if(result.length && !needAll) {
+ break;
+ }
+ }
+ return needAll ? result : result[0]
+}
+// #endif
+export function selectComponent(selector: string, options: SelectOptions = {}) {
+ // . class
+ // # id
+ // $ ref
+ // @ component name
+ const reg = /^(\.|#|@|\$)([a-zA-Z_0-9\-]+)$/;
+ if(!reg.test(selector)) return null
+ let { context, needAll, node} = options
+ const [,prefix, name] = selector.match(reg)
+ const symbolMappings = {'.': 'class', '#': 'id', '$':'ref', '@':'component'}
+
+ const key = symbolMappings [prefix] //prefix === '.' ? 'class' : prefix === '#' ? 'id' : 'ref';
+ console.log('key', key)
+ // #ifdef MP
+ return selectMPComponent(key, name, context, needAll)
+ // #endif
+ // #ifdef H5
+ return selectH5Component(key, name, context, needAll)
+ // #endif
+ // #ifdef APP
+ return selectAPPComponent(key, name, context, needAll, node)
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/sleep/index.ts b/src/uni_modules/lime-shared/sleep/index.ts
new file mode 100644
index 0000000..3ae6926
--- /dev/null
+++ b/src/uni_modules/lime-shared/sleep/index.ts
@@ -0,0 +1,30 @@
+// @ts-nocheck
+/**
+ * 延迟指定时间后解析的 Promise
+ * @param delay 延迟的时间(以毫秒为单位),默认为 300 毫秒
+ * @returns 一个 Promise,在延迟结束后解析
+ */
+export const sleep = (delay: number = 300) =>
+ new Promise(resolve => setTimeout(resolve, delay));
+
+
+// 示例
+// async function example() {
+// console.log("Start");
+
+// // 延迟 1 秒后执行
+// await sleep(1000);
+// console.log("1 second later");
+
+// // 延迟 500 毫秒后执行
+// await sleep(500);
+// console.log("500 milliseconds later");
+
+// // 延迟 2 秒后执行
+// await sleep(2000);
+// console.log("2 seconds later");
+
+// console.log("End");
+// }
+
+// example();
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/throttle/index.ts b/src/uni_modules/lime-shared/throttle/index.ts
new file mode 100644
index 0000000..740f788
--- /dev/null
+++ b/src/uni_modules/lime-shared/throttle/index.ts
@@ -0,0 +1,41 @@
+// @ts-nocheck
+/**
+ * 节流函数,用于限制函数的调用频率
+ * @param fn 要进行节流的函数
+ * @param delay 两次调用之间的最小间隔时间
+ * @returns 节流后的函数
+ */
+export function throttle(fn: (...args: any[]) => void, delay: number) {
+ let flag = true; // 标记是否可以执行函数
+
+ return (...args: any[]) => {
+ if (flag) {
+ flag = false; // 设置为不可执行状态
+ fn(...args); // 执行传入的函数
+
+ setTimeout(() => {
+ flag = true; // 经过指定时间后,设置为可执行状态
+ }, delay);
+ }
+ };
+}
+
+
+// // 示例
+// // 定义一个被节流的函数
+// function handleScroll() {
+// console.log("Scroll event handled!");
+// }
+
+// // 使用节流函数对 handleScroll 进行节流,间隔时间为 500 毫秒
+// const throttledScroll = throttle(handleScroll, 500);
+
+// // 模拟多次调用 handleScroll
+// throttledScroll(); // 输出 "Scroll event handled!"
+// throttledScroll(); // 不会输出
+// throttledScroll(); // 不会输出
+
+// // 经过 500 毫秒后,再次调用 handleScroll
+// setTimeout(() => {
+// throttledScroll(); // 输出 "Scroll event handled!"
+// }, 500);
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/toArray/index.ts b/src/uni_modules/lime-shared/toArray/index.ts
new file mode 100644
index 0000000..b59b0af
--- /dev/null
+++ b/src/uni_modules/lime-shared/toArray/index.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+/**
+ * 将一个或多个元素转换为数组
+ * @param item 要转换为数组的元素
+ * @returns 转换后的数组
+ */
+export const toArray = (item: T | T[]): T[] => Array.isArray(item) ? item : [item];
+
+// 示例
+// console.log(toArray(5)); // 输出: [5]
+// console.log(toArray("hello")); // 输出: ["hello"]
+// console.log(toArray([1, 2, 3])); // 输出: [1, 2, 3]
+// console.log(toArray(["apple", "banana"])); // 输出: ["apple", "banana"]
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/toNumber/index.ts b/src/uni_modules/lime-shared/toNumber/index.ts
new file mode 100644
index 0000000..a0745bb
--- /dev/null
+++ b/src/uni_modules/lime-shared/toNumber/index.ts
@@ -0,0 +1,15 @@
+// @ts-nocheck
+/**
+ * 将字符串转换为数字
+ * @param val 要转换的字符串
+ * @returns 转换后的数字或原始字符串
+ */
+export function toNumber(val: string): number | string {
+ const n = parseFloat(val); // 使用 parseFloat 函数将字符串转换为浮点数
+ return isNaN(n) ? val : n; // 使用 isNaN 函数判断是否为非数字,返回转换后的数字或原始字符串
+}
+
+// 示例
+// console.log(toNumber("123")); // 输出: 123
+// console.log(toNumber("3.14")); // 输出: 3.14
+// console.log(toNumber("hello")); // 输出: "hello"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/unitConvert/index.ts b/src/uni_modules/lime-shared/unitConvert/index.ts
new file mode 100644
index 0000000..7cedccf
--- /dev/null
+++ b/src/uni_modules/lime-shared/unitConvert/index.ts
@@ -0,0 +1,39 @@
+// @ts-nocheck
+import {isString} from '../isString'
+import {isNumeric} from '../isNumeric'
+
+/**
+ * 单位转换函数,将字符串数字或带有单位的字符串转换为数字
+ * @param value 要转换的值,可以是字符串数字或带有单位的字符串
+ * @returns 转换后的数字,如果无法转换则返回0
+ */
+export function unitConvert(value: string | number): number {
+ // 如果是字符串数字
+ if (isNumeric(value)) {
+ return Number(value);
+ }
+ // 如果有单位
+ if (isString(value)) {
+ const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
+ const results = reg.exec(value);
+ if (!value || !results) {
+ return 0;
+ }
+ const unit = results[3];
+ value = parseFloat(value);
+ if (unit === 'rpx') {
+ return uni.upx2px(value);
+ }
+ if (unit === 'px') {
+ return value * 1;
+ }
+ // 如果是其他单位,可以继续添加对应的转换逻辑
+ }
+ return 0;
+}
+
+// 示例
+// console.log(unitConvert("123")); // 输出: 123 (字符串数字转换为数字)
+// console.log(unitConvert("3.14em")); // 输出: 0 (无法识别的单位)
+// console.log(unitConvert("20rpx")); // 输出: 根据具体情况而定 (根据单位进行转换)
+// console.log(unitConvert(10)); // 输出: 10 (数字不需要转换)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/useIntersectionObserver/index.ts b/src/uni_modules/lime-shared/useIntersectionObserver/index.ts
new file mode 100644
index 0000000..b5862fe
--- /dev/null
+++ b/src/uni_modules/lime-shared/useIntersectionObserver/index.ts
@@ -0,0 +1,81 @@
+import { watch, unref, Ref } from "../vue"
+// #ifdef APP-NVUE
+// const dom = weex.requireModule('dom')
+// const dom = uni.requireNativePlugin('dom')
+// #endif
+
+interface UseIntersectionObserverOptions {
+ root ?: string; // 观察器的根元素选择器字符串
+ rootMargin ?: {
+ top ?: number; // 根元素顶部边距
+ bottom ?: number; // 根元素底部边距
+ left ?: number; // 根元素左侧边距
+ right ?: number; // 根元素右侧边距
+ }; // 根元素的边距
+ thresholds ?: any[]; // 交叉比例数组,用于指定何时触发回调函数
+ context ?: any; // 上下文对象,用于指定观察器的上下文
+ initialRatio ?: number; // 初始的交叉比例
+ observeAll ?: boolean; // 是否同时观察所有交叉对象
+}
+
+/**
+ * 使用 Intersection Observer 观察元素可见性的自定义钩子函数
+ * @param {Ref | string} target - 目标元素,可以是一个字符串或 ref 对象
+ * @param {(result: UniNamespace.ObserveResult) => void} callback - 回调函数,当目标元素的可见性发生变化时调用
+ * @param {UseIntersectionObserverOptions} options - 可选的配置参数
+ * @returns {Object} - 包含 stop 方法的对象,用于停止观察
+ */
+export function useIntersectionObserver(
+ target : Ref | string,
+ callback : (result : UniNamespace.ObserveResult) => void,
+ options : UseIntersectionObserverOptions = {}) {
+ const {
+ root, // 观察器的根元素选择器
+ rootMargin = { top: 0, bottom: 0 }, // 根元素的边距,默认为顶部和底部都为0
+ thresholds = [0], // 交叉比例数组,默认为[0]
+ initialRatio = 0, // 初始交叉比例,默认为0
+ observeAll = false, // 是否同时观察所有交叉对象,默认为false
+ context // 上下文对象,用于指定观察器的上下文
+ } = options
+ const noop = () => { }; // 空函数,用于初始化 cleanup
+ let cleanup = noop; // 清理函数,用于停止 Intersection Observer 的观察
+
+ const stopWatch = watch(() => ({ el: unref(target), root: unref(root) }), ({ el, root }) => {
+ if (!el) {
+ return
+ }
+ // #ifndef APP-NVUE
+ // 创建 Intersection Observer 实例
+ const observer = uni.createIntersectionObserver(context, { thresholds, initialRatio, observeAll })
+ if (root) {
+ // 相对于根元素设置边界
+ observer.relativeTo(root, rootMargin)
+ } else {
+ // 相对于视口设置边界
+ observer.relativeToViewport(rootMargin)
+ }
+ // 观察目标元素的可见性变化
+ observer.observe(el, callback)
+ cleanup = () => {
+ // 停止观察
+ observer.disconnect()
+ // 将 cleanup 函数重置为空函数
+ cleanup = noop
+ }
+ // #endif
+ // #ifdef APP-NVUE
+ // dom.getComponentRect(el, (res) => {
+ // console.log('res', res)
+ // })
+ // #endif
+ }, { immediate: true, flush: 'post' })
+
+ const stop = () => {
+ // 调用 cleanup 函数停止观察
+ cleanup && cleanup()
+ // 停止 watch
+ stopWatch && stopWatch()
+ }
+
+ return { stop }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/vue/index.ts b/src/uni_modules/lime-shared/vue/index.ts
new file mode 100644
index 0000000..91a4a7f
--- /dev/null
+++ b/src/uni_modules/lime-shared/vue/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+
+// #ifdef VUE3
+export * from 'vue';
+// #endif
+// #ifndef VUE3
+export * from '@vue/composition-api';
+// #endif