Commit d65a0b96 authored by 沈翠玲's avatar 沈翠玲

测试蓝牙打印

parent 7b79392b
<template>
<view class="commonBody">
<view class="prod-body">
<canvas canvas-id="canvas" id="canvas"
style="width: 664px; height: 564px"></canvas>
<view class="prod-body-left">
<!-- <view class="prod-body-left-btns">-->
<!-- <view class="workstation">-->
......@@ -935,6 +937,7 @@ import cameraAuthMixin from '@/components/AppScan/appScanMixins.js';
import { handleError } from 'vue';
import AppScan from '../../../components/AppScan/AppScan.vue';
import URow from '../../../uview-ui/components/u-row/u-row.vue';
import CTPL from "../../../uni_ctpl_sdk/ctpl.js";
export default {
name: 'ProdReport',
dicts: ['pro_pack_type', 'sap_yes_no'],
......@@ -1478,12 +1481,6 @@ export default {
// watch() {
// },
mounted() {
//监听工作中心切换事件
// uni.$on('switchWorkunit', (station) => {
// this.getTaskList();
// });
},
created() {
//获取屏幕高度
uni.getSystemInfo({
......@@ -1504,6 +1501,7 @@ export default {
if (this.vuex_workunit != null) {
this.getTaskList();
}
// if (this.vuex_task != null) {
// this.shiftTask(this.vuex_task.taskId);
// }
......@@ -1517,6 +1515,14 @@ export default {
return this.feedbackForm.quantityQualify + this.feedbackForm.quantityUnqualify;
}
},
async mounted () {
await CTPL.init();
CTPL.discovery( (res) => {
if (res.name === 'CT-428D') {
this.device = res
}
});
},
methods: {
cellStyle ({ row,column,rowIndex,columnIndex }) {
if(columnIndex === 1) {
......@@ -2477,49 +2483,120 @@ export default {
}
});
},
rePackageInfoPrint(item, row, i){
uni.showModal({
title: '系统提示',
content: '是否确认补打?',
success: (res) => {
if (res.confirm) {
if (!item.printTemplate) {
return this.$u.toast('请选择打印模版')
}
if (item.printTemplate && !this.vuex_printConnect) {
this.$u.toast('打印机连接失败');
return;
}
item.feedbackTime = this.parseTime(new Date())
this.$u.api
.rePackageInfoPrint({
workorderId: item.workorderId,
qrcode: row.qrcode,
})
.then((res) => {
if (res.code === 200) {
// this.proVisible = false;
// item.quantityUnqualify = 0;
// this.$u.toast('上报成功');
// this.getWorkorderDirectiveList(item, i)
if (item.printTemplate) {
let params = {};
res.data.forEach((datas) => {
params = {
reportName: 'mysql:' + item.printTemplate,
values: {
packagePrint: datas
}
};
this.printPdfSocket(params);
});
}
this.getTaskList();
}
connect(){
console.log('开始打印,连接的打印机Id是', this.device.deviceId)
const $this = this
CTPL.connect(
this.device,
function success(res1) {
uni.setBLEMTU({
deviceId: $this.device.deviceId,
mtu: 40,
success(res) {
// CTPL.setSpeed(4)
CTPL.setSize($this.pageObj.width, $this.pageObj.height)
CTPL.clearCache()
$this.getImageData()
// CTPL.drawLine(5,5,762,1)
// CTPL.drawText(9,8,0,1,1,'这是一段 Test文字');C
// CTPL.setPrintCopies(1, 1)
// CTPL.execute((res) => {
// console.log('res', res)
// })
// CTPL.drawLine(5,5,762,1)
// CTPL.drawText(9,8,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,28,762,1)
// CTPL.drawText(9,31,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,51,762,1)
// CTPL.drawText(9,54,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,74,762,1)
// CTPL.drawText(9,77,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,97,762,1)
// CTPL.drawText(9,100,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,120,762,1)
// CTPL.drawText(9,123,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,143,762,1)
// CTPL.drawText(9,145,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,165,762,1)
// CTPL.drawText(9,167,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,187,762,1)
// CTPL.drawText(9,190,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,210,762,1)
// CTPL.drawText(9,213,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,233,762,1)
// CTPL.drawText(9,236,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,256,762,1)
// CTPL.drawText(9,259,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,279,762,1)
// CTPL.drawText(9,282,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,302,762,1)
// CTPL.drawText(9,305,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,325,762,1)
// CTPL.drawText(9,328,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.drawLine(5,348,762,1)
// CTPL.drawText(9,351,0,1,1,'这是一段 Test文字,这是一段 Test文字,这是一段 Test文字');
// CTPL.setPrintCopies(1, 1)
// CTPL.execute((res) => {
// console.log('打印完成', res)
// })
},
});
},
function fail(e) {
console.log('报错',e)
}
}
)
uni.onBLEConnectionStateChange(function (res) {
console.log('打印机连接状态', res)
})
},
async rePackageInfoPrint(item, row, i){
this.connect()
// uni.showModal({
// title: '系统提示',
// content: '是否确认补打?',
// success: (res) => {
// if (res.confirm) {
// // if (!item.printTemplate) {
// // return this.$u.toast('请选择打印模版')
// // }
// // if (item.printTemplate && !this.vuex_printConnect) {
// // this.$u.toast('打印机连接失败');
// // return;
// // }
// this.printPdfSocket();
// item.feedbackTime = this.parseTime(new Date())
// this.$u.api
// .rePackageInfoPrint({
// workorderId: item.workorderId,
// qrcode: row.qrcode,
// })
// .then((res) => {
// if (res.code === 200) {
// // this.proVisible = false;
// // item.quantityUnqualify = 0;
// // this.$u.toast('上报成功');
// // this.getWorkorderDirectiveList(item, i)
// if (item.printTemplate) {
// let params = {};
// res.data.forEach((datas) => {
// params = {
// reportName: 'mysql:' + item.printTemplate,
// values: {
// packagePrint: datas
// }
// };
// this.printPdfSocket(params);
// });
// }
// this.getTaskList();
// }
// });
// }
// }
// })
},
handleSubmitPackageFeedback(item, row, i) {
......@@ -3284,4 +3361,8 @@ export default {
min-width: 100% !important;
}
}
#canvas {
position: absolute;
top: -9999px;
}
</style>
\ No newline at end of file
......@@ -3,6 +3,7 @@ import {
} from 'vuex'
import store from "@/store"
import io from '@hyoga/uni-socket.io';
import CTPL from "../uni_ctpl_sdk/ctpl.js";
// 尝试将用户在根目录中的store/index.js的vuex的state变量,全部加载到全局变量中
let $uStoreKey = [];
......@@ -25,13 +26,70 @@ module.exports = {
}
},
data() {
return {}
return {
pageObj: {
width: 100,
height: 80
},
device: null,
imagePath: '/static/1.png'
}
},
computed: {
// 将vuex的state中的所有变量,解构到全局混入的mixin中
...mapState($uStoreKey)
},
async mounted(){
},
methods: {
// 获取图片信息
getImageData() {
const $this = this
uni.getImageInfo({
src: this.imagePath,
success: (res) => {
// const scale = ($this.pageObj.width * 8) / res.width
const newWidth = $this.pageObj.width * 8
const newHeight = $this.pageObj.height * 8
const ctx = uni.createCanvasContext("canvas", $this)
ctx.drawImage(this.imagePath, 0, 0, newWidth, newHeight)
ctx.draw(false, () => {
uni.canvasGetImageData(
{
canvasId: "canvas",
x: 0,
y: 0,
width: newWidth,
height: newHeight,
success: function (response) {
console.log('转换成canvas的时间',response)
const imageRes = response
CTPL.drawBitMap(
0,
0,
imageRes.width,
imageRes.height,
0,
response.data
)
CTPL.setPrintCopies(1, 1)
CTPL.execute((res) => {
console.log('打印完成', res)
CTPL.disconnect()
})
},
fail: function (res) {
console.log('sda',res)
CTPL.disconnect()
},
},
$this
)
})
},
})
},
createSocket() {
if (getApp().globalData.printSocket && Object.keys(getApp().globalData.printSocket).length > 0) {
getApp().globalData.printSocket.close && getApp().globalData.printSocket.close()
......@@ -76,21 +134,49 @@ module.exports = {
this.$u.toast('请绑定打印机');
return;
}
if (this.vuex_printConnect) {
this.$u.api.getPrintDown(params).then((res) => {
if (res.code === 200) {
getApp().globalData.printSocket.emit('news', {
client: null,
printer: this.vuex_printerInfo.printerName,
type: 'url_pdf',
// pdf_path: 'http://192.168.3.91:8082/static/123.pdf',
pdf_path: res.fileUrl,
});
await CTPL.init();
await CTPL.discovery( (res) => {
if (res.name === 'CT-428D') {
this.device = res
console.log(this.device)
}
});
} else {
this.$u.toast('打印机连接失败');
const $this = this
setTimeout(()=>{
CTPL.connect(
$this.device,
function success(res1) {
console.log('扫描到的打印机',res1)
CTPL.setSize($this.pageObj.width, $this.pageObj.height)
CTPL.clearCache()
$this.getImageData((response)=>{
console.log('response', response)
const imageRes = response
// CTPL.drawBitMap(
// 0,
// 0,
// imageRes.width,
// imageRes.height,
// 0,
// response.data
// )
// CTPL.setPrintCopies(1, 1)
// CTPL.execute((res) => {
// console.log('res', res)
// })
})
},
function fail(e) {
console.log('报错',e)
}
)
uni.onBLEConnectionStateChange(function (res) {
console.log('sadsada', res)
})
}, 6000)
return
}
}
}
\ No newline at end of file
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.hardwareFeatures=exports.firmwareFeatures=exports.displayFeatures=void 0;var hardwareFeatures=exports.hardwareFeatures=[{infoId:0x01,infoLen:16,infoKey:"Model"},{infoId:0x02,infoLen:1,infoKey:"Dpi"},{infoId:0x03,infoLen:1,infoKey:"SupportCompress"},{infoId:0x04,infoLen:1,infoKey:"TwoColor"},{infoId:0x05,infoLen:1,infoKey:"DeviceCutter"},{infoId:0x06,infoLen:1,infoKey:"SupportCarbonDetection"},{infoId:0x07,infoLen:1,infoKey:"DevicePrintMaxWidthMM"},{infoId:0x08,infoLen:1,infoKey:"DevicePrintMaxHeightMM"},{infoId:0x09,infoLen:1,infoKey:"PrintAlignment"}];var firmwareFeatures=exports.firmwareFeatures=[{infoId:0x01,infoLen:4,infoKey:"State"},{infoId:0x02,infoLen:1,infoKey:"PaperType"},{infoId:0x03,infoLen:1,infoKey:"GapHeightMM"},{infoId:0x04,infoLen:1,infoKey:"FeedOffsetMM"},{infoId:0x05,infoLen:1,infoKey:"Density"},{infoId:0x06,infoLen:2,infoKey:"Speed"},{infoId:0x07,infoLen:1,infoKey:"Direction"},{infoId:0x08,infoLen:1,infoKey:"PrintOffsetYMM"},{infoId:0x09,infoLen:1,infoKey:"PrintOffsetXMM"},{infoId:0x0A,infoLen:1,infoKey:"CalibrationMM"},{infoId:0x0B,infoLen:1,infoKey:"AutoShutdownMinute"},{infoId:0x0C,infoLen:4,infoKey:"MemoryIdle"}];var displayFeatures=exports.displayFeatures=[{infoId:0x01,infoLen:1,infoKey:"PrintMode"},{infoId:0x02,infoLen:48,infoKey:"SerialNumber"},{infoId:0x03,infoLen:16,infoKey:"FirmwareVersion"},{infoId:0x04,infoLen:6,infoKey:"HardwareVersion"},{infoId:0x05,infoLen:1,infoKey:"Battery"}];
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
"use strict";function _instanceof(n,e){return null!=e&&"undefined"!=typeof Symbol&&e[Symbol.hasInstance]?!!e[Symbol.hasInstance](n):n instanceof e}Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _classCallCheck(a,n){if(!_instanceof(a,n))throw new TypeError("Cannot call a class as a function");}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t)}var encodeToGb2312=require("./encodeToGb2312.min.js");var ESCCommand=function(){function ESCCommand(){_classCallCheck(this,ESCCommand);this.escBuffer=[]}return _createClass(ESCCommand,[{key:"initPrinter",value:function initPrinter(){this.escBuffer=[];var a=[0x1B,0x40];this.escBuffer.push(new Uint8Array(a))}},{key:"setAlignment",value:function setAlignment(a){var b=[0x1B,0x61,a];this.escBuffer.push(new Uint8Array(b))}},{key:"setFontSize",value:function setFontSize(a,b){var c=[0x1D,0x21,a*16+b];this.escBuffer.push(new Uint8Array(c))}},{key:"drawTextContent",value:function drawTextContent(a){var b=this.stringToBuffer(a);this.escBuffer.push(b);this.escBuffer.push(new Uint8Array([0x0A]))}},{key:"setTextPosition",value:function setTextPosition(a){var b=[0x1D,0x48,a];this.escBuffer.push(new Uint8Array(b))}},{key:"setBarCodeSize",value:function setBarCodeSize(a,b){var c=[0x1D,0x77,a,0x1D,0x68,b];this.escBuffer.push(new Uint8Array(c))}},{key:"drawBarcode128WithValue",value:function drawBarcode128WithValue(a){var b=[0x1D,0x6B,73,a.length+2,0x7B,0x41];var c=this.stringToBuffer(a);this.escBuffer.push(new Uint8Array(b),new Uint8Array(c))}},{key:"setQRCodeWidth",value:function setQRCodeWidth(a){var b=[0x1D,0x28,0x6B,0x03,0x00,0x31,0x43,a];this.escBuffer.push(new Uint8Array(b))}},{key:"drawQRCode",value:function drawQRCode(a){var k=a.length+3;var b=k/256;var c=k%256;var d=[0x1D,0x28,0x6B,c,b,0x31,0x50,0x30];var e=this.stringToBuffer(a);var f=[0x1D,0x28,0x6B,0x03,0x00,0x31,0x51,0x30];this.escBuffer.push(new Uint8Array(d),new Uint8Array(e),new Uint8Array(f))}},{key:"drawLine",value:function drawLine(a,b){var c=[0x1D,0x28,0x52,a/256,a%256,b/256,b%256];this.escBuffer.push(new Uint8Array(c))}},{key:"drawBitMap",value:function drawBitMap(a,b,c){var d=this.escConvertBitMapImage(a,b,c);this.escBuffer.push(new Uint8Array(d))}},{key:"submitPrint",value:function submitPrint(){this.escBuffer.push(new Uint8Array([0x0A]))}},{key:"stringToBuffer",value:function stringToBuffer(a){var b=this.hexStringToByteArray(encodeToGb2312(a));return new Uint8Array(b)}},{key:"hexStringToByteArray",value:function hexStringToByteArray(a){var b=[];for(var i=0;i<a.length;i+=2){var c=parseInt(a.substr(i,2),16);b.push(c)}return b}},{key:"escConvertBitMapImage",value:function escConvertBitMapImage(a,b,c){var d=[];var w=b;var h=c;var e=parseInt((w+7)/8)*8;var f=h;var g=parseInt(e/8);var j=new Uint8Array(f*g);d.push(29);d.push(118);d.push(48);d.push(0);d.push(parseInt(g%256));d.push(parseInt(g/256));d.push(parseInt(f%256));d.push(parseInt(f/256));for(var y=0;y<h;y++){for(var x=0;x<w;x++){var k=a[(y*w+x)*4];if(k<128){j[parseInt(y*g+x/8)]|=0x80>>x%8}}}for(var i=0;i<j.length;i++){d.push(j[i])}return d}},{key:"getBuffer",value:function getBuffer(){var a=_toConsumableArray(this.escBuffer);return this.concatBuffers(a).buffer}},{key:"concatBuffers",value:function concatBuffers(a){var b=0;for(var i=0;i<a.length;i++){b+=a[i].byteLength}var c=new Uint8Array(b);var d=0;for(var e=0;e<a.length;e++){c.set(new Uint8Array(a[e]),d);d+=a[e].byteLength}return c}}])}();var _default=exports.default=new ESCCommand();
\ No newline at end of file
"use strict";function _instanceof(n,e){return null!=e&&"undefined"!=typeof Symbol&&e[Symbol.hasInstance]?!!e[Symbol.hasInstance](n):n instanceof e}Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _command=_interopRequireDefault(require("./command"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _classCallCheck(a,n){if(!_instanceof(a,n))throw new TypeError("Cannot call a class as a function");}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t)}var OTAUpdate=function(){function OTAUpdate(){_classCallCheck(this,OTAUpdate);this.otaBuffer=[];this.otaPacketIndex=0}return _createClass(OTAUpdate,[{key:"requestFirmwareUpdate",value:function requestFirmwareUpdate(){var a=[0x00,0x02,0x02,0x00,0x01,0x01];var b=_command.default.crc8(a);var c=new Uint8Array([0xDD].concat(a,[b,0xDD])).buffer;return c}},{key:"sliceData",value:function sliceData(a,b){var c=Math.min(a,b.length-this.otaPacketIndex);var d=b.slice(this.otaPacketIndex,this.otaPacketIndex+c);var e=Array.from(d);console.log("via: ",e[e.length-1]);this.otaPacketIndex+=c;var f=(d.length&0xFF00)>>8;var g=d.length&0x00FF;var h=[0x00,0x02,0x03,f,g];var i=new Uint8Array([].concat(h,_toConsumableArray(d)));var j=_command.default.crc8(i);var k=new Uint8Array([0xDD].concat(h,_toConsumableArray(d),[j,0xDD]));return k}},{key:"executeFirmwareUpdate",value:function executeFirmwareUpdate(a){var b=_command.default.crc8(a);var c=[0x00,0x02,0x04,0x00,0x01,b];var d=_command.default.crc8(c);var e=new Uint8Array([0xDD].concat(c,[d,0xDD])).buffer;return e}}])}();var _default=exports.default=new OTAUpdate();
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment