1 |
- {"version":3,"sources":["webpack:///js/comment.js","webpack:///./mobile/src/router/comment.js","webpack:///./mobile/src/js/upload.js","webpack:///./mobile/src/js/useragent.js","webpack:///./mobile/src/js/comment.js"],"names":["webpackJsonp","1","module","exports","__webpack_require__","13","_typeof","Symbol","iterator","obj","constructor","prototype","$","window","document","undefined","regist","mName","brickjs","Upload","selector","cfgs","this","url","params","useCanvas","size","limit","width","quality","error","errorMsg","overnum","invalidLarge","invalidSmall","invalidType","forbidden","autoUpload","uploadBtn","tpl","tplContainer","autoHide","onSelect","files","onUploading","onProgress","loaded","total","onSuccess","response","file","onFailure","msg","onDelete","onComplete","onError","extend","_init","BinaryFile","strData","iDataOffset","iDataLength","data","dataOffset","dataLength","getRawData","length","getByteAt","iOffset","charCodeAt","getBytesAt","iLength","aBytes","i","IEBinary_getLength","IEBinary_getByteAt","VBArray","IEBinary_getBytesAt","toArray","getLength","getSByteAt","iByte","getShortAt","bBigEndian","iShort","getSShortAt","iUShort","getLongAt","iByte1","iByte2","iByte3","iByte4","iLong","getSLongAt","iULong","getStringAt","aStr","j","String","fromCharCode","join","getCharAt","toBase64","btoa","fromBase64","strBase64","atob","BinaryAjax","createRequest","oHTTP","ActiveXObject","XMLHttpRequest","getHead","strURL","fncCallback","fncError","onload","status","onreadystatechange","readyState","open","send","sendRequest","aRange","bAcceptRanges","iFileSize","iDataLen","binaryResponse","responseText","fileSize","getResponseHeader","oRes","responseBody","overrideMimeType","setRequestHeader","iStart","iEnd","parseInt","strAcceptRanges","Plugin","options","methods","defaults","_defaults","_name","pluginName","init","newsize","w","h","W","H","C","c","r","height","cropped","dataURLtoBlob","mimeString","split","byteString","ab","ArrayBuffer","ia","Uint8Array","bb","BlobBuilder","WebKitBlobBuilder","MozBlobBuilder","append","getBlob","Blob","type","detectSubsampling","img","iw","canvas","createElement","ctx","getContext","drawImage","getImageData","rotate","orientation","angle","o","90","180","270","2","3","4","5","6","7","8","transformCoordinate","translate","scale","Math","PI","detectVerticalSquash","ih","sy","ey","py","ratio","callback","d","target","arguments","a","al","deep","Boolean","prop","crop","$this","reader","FileReader","onloadend","e","dataURL","result","binary","exif","EXIF","readFromBinaryFile","Image","save","tmpCanvas","tmpCtx","vertSquashRatio","sh","sx","sw","clearRect","dx","floor","dw","ceil","dy","dh","restore","newcanvas","x","y","toDataURL","src","readAsDataURL","imageHasData","exifdata","http","findEXIFinJPEG","call","marker","offset","debug","console","log","readEXIFData","readTags","tiffStart","dirStart","strings","bigEnd","entryOffset","tag","entries","tags","readTagValue","vals","val","n","numerator","denominator","numValues","valueOffset","Number","start","exifData","gpsData","tiffOffset","TiffTags","ExifIFDPointer","ExifTags","StringValues","Components","GPSInfoIFDPointer","GPSTags","getData","complete","getTag","getAllTags","hasOwnProperty","pretty","strPretty","36864","40960","40961","40962","40963","37121","37122","37500","37510","40964","36867","36868","37520","37521","37522","33434","33437","34850","34852","34855","34856","37377","37378","37379","37380","37381","37382","37383","37384","37385","37396","37386","41483","41484","41486","41487","41488","41492","41493","41495","41728","41729","41730","41985","41986","41987","41988","41989","41990","41991","41992","41993","41994","41995","41996","40965","42016","256","257","34665","34853","258","259","262","274","277","284","530","531","282","283","296","273","278","279","513","514","301","318","319","529","532","306","271","272","305","315","33432","0","9","10","11","12","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","ExposureProgram","MeteringMode","255","LightSource","Flash","31","32","65","69","71","73","77","79","89","93","95","SensingMethod","SceneCaptureType","SceneType","CustomRendered","WhiteBalance","GainControl","Contrast","Saturation","Sharpness","SubjectDistanceRange","FileSource","Tags","self","container","input","find","disabled","filesFilter","failFiles","count","compress","_bind","tempFiles","change","_showError","html","hide","push","tempFilesLen","each","index1","index2","pop","_filter","_createTpl","_upload","click","failure","css","filesArr","index","maxSize","parseFloat","fileName","name","indexOf","aborted","items","previews","revoker","UserAgent","isiOS","toFixed","fileIndex","canvasResize","preview","_templ","show","_bindTpl","_dealObjectURL","setTimeout","clearTimeout","on","_delete","attr","currentFiles","_watchTpl","b","item","animate","replace","RegExp","create","URL","createObjectURL","revokeObjectURL","webkitURL","disable","xhr","upload","addEventListener","_checkPogress","eval","fileAborted","message","_resizeIos","_resize","formData","FormData","p","ratio1","ratio2","encodeURIComponent","title","uploadtype","isAndroid","chrome","pow","fileDelete","_hidePreview","itemLen","fadeOut","remove","fileFailure","enable","alert","Zepto","jQuery","isDesktop","isWindows","isLinux","isMac","isTablet","isiPad","isAndroidTablet","isMobile","isiPhone","isWindowsPhone","isWeChat","isWeibo","ie","firefox","safari","opera","uc","mqq","baidu","androidBrowser","browser","engine","osVersion","_versions","_browsers","weibo","wechat","_platforms","windows","windowsPhone","mac","linux","iPad","iPod","iPhone","android","_osVersion","iOS","_engine","trident","gecko","applewebkit","presto","ua","navigator","userAgent","toLowerCase","_getPlatform","_getBrowser","_getBroserVersion","test","_testMobile","_getOSVersion","_getEngine","_toFixedVersion","ver","floatLength","$2","$1","contains","str","getUserAgent","parent"],"mappings":"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","file":"js/comment.js?v=f4729b47","sourcesContent":["webpackJsonp([1],{\n\n/***/ 1:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(18);\n\n__webpack_require__(8);\n\n/***/ }),\n\n/***/ 13:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n;(function ($, window, document, undefined) {\n function regist(mName, module) {\n if (typeof window.brickjs === \"undefined\") {\n window.brickjs = {};\n }\n brickjs[mName] = module;\n }\n ;\n /*\n * Binary Ajax 0.1.10\n * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/\n * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]\n */\n\n var BinaryFile = function BinaryFile(strData, iDataOffset, iDataLength) {\n var data = strData;\n var dataOffset = iDataOffset || 0;\n var dataLength = 0;\n\n this.getRawData = function () {\n return data;\n };\n\n if (typeof strData == \"string\") {\n dataLength = iDataLength || data.length;\n\n this.getByteAt = function (iOffset) {\n return data.charCodeAt(iOffset + dataOffset) & 0xFF;\n };\n\n this.getBytesAt = function (iOffset, iLength) {\n var aBytes = [];\n\n for (var i = 0; i < iLength; i++) {\n aBytes[i] = data.charCodeAt(iOffset + i + dataOffset) & 0xFF;\n }\n ;\n\n return aBytes;\n };\n } else if (typeof strData == \"unknown\") {\n dataLength = iDataLength || IEBinary_getLength(data);\n\n this.getByteAt = function (iOffset) {\n return IEBinary_getByteAt(data, iOffset + dataOffset);\n };\n\n this.getBytesAt = function (iOffset, iLength) {\n return new VBArray(IEBinary_getBytesAt(data, iOffset + dataOffset, iLength)).toArray();\n };\n }\n\n this.getLength = function () {\n return dataLength;\n };\n\n this.getSByteAt = function (iOffset) {\n var iByte = this.getByteAt(iOffset);\n if (iByte > 127) return iByte - 256;else return iByte;\n };\n\n this.getShortAt = function (iOffset, bBigEndian) {\n var iShort = bBigEndian ? (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1) : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset);\n if (iShort < 0) iShort += 65536;\n return iShort;\n };\n this.getSShortAt = function (iOffset, bBigEndian) {\n var iUShort = this.getShortAt(iOffset, bBigEndian);\n if (iUShort > 32767) return iUShort - 65536;else return iUShort;\n };\n this.getLongAt = function (iOffset, bBigEndian) {\n var iByte1 = this.getByteAt(iOffset),\n iByte2 = this.getByteAt(iOffset + 1),\n iByte3 = this.getByteAt(iOffset + 2),\n iByte4 = this.getByteAt(iOffset + 3);\n\n var iLong = bBigEndian ? (((iByte1 << 8) + iByte2 << 8) + iByte3 << 8) + iByte4 : (((iByte4 << 8) + iByte3 << 8) + iByte2 << 8) + iByte1;\n if (iLong < 0) iLong += 4294967296;\n return iLong;\n };\n this.getSLongAt = function (iOffset, bBigEndian) {\n var iULong = this.getLongAt(iOffset, bBigEndian);\n if (iULong > 2147483647) return iULong - 4294967296;else return iULong;\n };\n\n this.getStringAt = function (iOffset, iLength) {\n var aStr = [];\n\n var aBytes = this.getBytesAt(iOffset, iLength);\n for (var j = 0; j < iLength; j++) {\n aStr[j] = String.fromCharCode(aBytes[j]);\n }\n return aStr.join(\"\");\n };\n\n this.getCharAt = function (iOffset) {\n return String.fromCharCode(this.getByteAt(iOffset));\n };\n this.toBase64 = function () {\n return window.btoa(data);\n };\n this.fromBase64 = function (strBase64) {\n data = window.atob(strBase64);\n };\n };\n\n var BinaryAjax = function () {\n\n function createRequest() {\n var oHTTP = null;\n if (window.ActiveXObject) {\n oHTTP = new ActiveXObject(\"Microsoft.XMLHTTP\");\n } else if (window.XMLHttpRequest) {\n oHTTP = new XMLHttpRequest();\n }\n return oHTTP;\n }\n\n function getHead(strURL, fncCallback, fncError) {\n var oHTTP = createRequest();\n if (oHTTP) {\n if (fncCallback) {\n if (typeof oHTTP.onload != \"undefined\") {\n oHTTP.onload = function () {\n if (oHTTP.status == \"200\") {\n fncCallback(this);\n } else {\n if (fncError) fncError();\n }\n oHTTP = null;\n };\n } else {\n oHTTP.onreadystatechange = function () {\n if (oHTTP.readyState == 4) {\n if (oHTTP.status == \"200\") {\n fncCallback(this);\n } else {\n if (fncError) fncError();\n }\n oHTTP = null;\n }\n };\n }\n }\n oHTTP.open(\"HEAD\", strURL, true);\n oHTTP.send(null);\n } else {\n if (fncError) fncError();\n }\n }\n\n function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) {\n var oHTTP = createRequest();\n if (oHTTP) {\n\n var iDataOffset = 0;\n if (aRange && !bAcceptRanges) {\n iDataOffset = aRange[0];\n }\n var iDataLen = 0;\n if (aRange) {\n iDataLen = aRange[1] - aRange[0] + 1;\n }\n\n if (fncCallback) {\n if (typeof oHTTP.onload != \"undefined\") {\n oHTTP.onload = function () {\n if (oHTTP.status == \"200\" || oHTTP.status == \"206\" || oHTTP.status == \"0\") {\n oHTTP.binaryResponse = new BinaryFile(oHTTP.responseText, iDataOffset, iDataLen);\n oHTTP.fileSize = iFileSize || oHTTP.getResponseHeader(\"Content-Length\");\n fncCallback(oHTTP);\n } else {\n if (fncError) fncError();\n }\n oHTTP = null;\n };\n } else {\n oHTTP.onreadystatechange = function () {\n if (oHTTP.readyState == 4) {\n if (oHTTP.status == \"200\" || oHTTP.status == \"206\" || oHTTP.status == \"0\") {\n // IE6 craps if we try to extend the XHR object\n var oRes = {\n status: oHTTP.status,\n // IE needs responseBody, Chrome/Safari needs responseText\n binaryResponse: new BinaryFile(typeof oHTTP.responseBody == \"unknown\" ? oHTTP.responseBody : oHTTP.responseText, iDataOffset, iDataLen),\n fileSize: iFileSize || oHTTP.getResponseHeader(\"Content-Length\")\n };\n fncCallback(oRes);\n } else {\n if (fncError) fncError();\n }\n oHTTP = null;\n }\n };\n }\n }\n oHTTP.open(\"GET\", strURL, true);\n\n if (oHTTP.overrideMimeType) oHTTP.overrideMimeType('text/plain; charset=x-user-defined');\n\n if (aRange && bAcceptRanges) {\n oHTTP.setRequestHeader(\"Range\", \"bytes=\" + aRange[0] + \"-\" + aRange[1]);\n }\n\n oHTTP.setRequestHeader(\"If-Modified-Since\", \"Sat, 1 Jan 1970 00:00:00 GMT\");\n\n oHTTP.send(null);\n } else {\n if (fncError) fncError();\n }\n }\n\n return function (strURL, fncCallback, fncError, aRange) {\n\n if (aRange) {\n getHead(strURL, function (oHTTP) {\n var iLength = parseInt(oHTTP.getResponseHeader(\"Content-Length\"), 10);\n var strAcceptRanges = oHTTP.getResponseHeader(\"Accept-Ranges\");\n\n var iStart, iEnd;\n iStart = aRange[0];\n if (aRange[0] < 0) iStart += iLength;\n iEnd = iStart + aRange[1] - 1;\n\n sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], strAcceptRanges == \"bytes\", iLength);\n });\n } else {\n sendRequest(strURL, fncCallback, fncError);\n }\n };\n }();; /*\n * \n * canvasResize\n * \n * Version: 1.2.0 \n * Date (d/m/y): 02/10/12\n * Update (d/m/y): 14/05/13\n * Original author: @gokercebeci \n * Licensed under the MIT license\n * - This plugin working with binaryajax.js and exif.js \n * (It's under the MPL License http://www.nihilogic.dk/licenses/mpl-license.txt)\n * Demo: http://canvasResize.gokercebeci.com/\n * \n * - I fixed iOS6 Safari's image file rendering issue for large size image (over mega-pixel)\n * using few functions from https://github.com/stomita/ios-imagefile-megapixel\n * (detectSubsampling, )\n * And fixed orientation issue by using https://github.com/jseidelin/exif-js\n * Thanks, Shinichi Tomita and Jacob Seidelin\n */\n\n (function ($) {\n var pluginName = 'canvasResize',\n methods = {\n newsize: function newsize(w, h, W, H, C) {\n var c = C ? 'h' : '';\n if (W && w > W || H && h > H) {\n var r = w / h;\n if ((r >= 1 || H === 0) && W && !C) {\n w = W;\n h = W / r >> 0;\n } else if (C && r <= W / H) {\n w = W;\n h = W / r >> 0;\n c = 'w';\n } else {\n w = H * r >> 0;\n h = H;\n }\n }\n return {\n 'width': w,\n 'height': h,\n 'cropped': c\n };\n },\n dataURLtoBlob: function dataURLtoBlob(data) {\n var mimeString = data.split(',')[0].split(':')[1].split(';')[0];\n var byteString = atob(data.split(',')[1]);\n var ab = new ArrayBuffer(byteString.length);\n var ia = new Uint8Array(ab);\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n var bb = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;\n if (bb) {\n // console.log('BlobBuilder'); \n bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)();\n bb.append(ab);\n return bb.getBlob(mimeString);\n } else {\n // console.log('Blob'); \n bb = new Blob([ab], {\n 'type': mimeString\n });\n return bb;\n }\n },\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n detectSubsampling: function detectSubsampling(img) {\n var iw = img.width,\n ih = img.height;\n if (iw * ih > 1048576) {\n // subsampling may happen over megapixel image\n var canvas = document.createElement('canvas');\n canvas.width = canvas.height = 1;\n var ctx = canvas.getContext('2d');\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n },\n /**\n * Update the orientation according to the specified rotation angle\n */\n rotate: function rotate(orientation, angle) {\n var o = {\n // nothing\n 1: { 90: 6, 180: 3, 270: 8 },\n // horizontal flip\n 2: { 90: 7, 180: 4, 270: 5 },\n // 180 rotate left\n 3: { 90: 8, 180: 1, 270: 6 },\n // vertical flip\n 4: { 90: 5, 180: 2, 270: 7 },\n // vertical flip + 90 rotate right\n 5: { 90: 2, 180: 7, 270: 4 },\n // 90 rotate right\n 6: { 90: 3, 180: 8, 270: 1 },\n // horizontal flip + 90 rotate right\n 7: { 90: 4, 180: 5, 270: 2 },\n // 90 rotate left\n 8: { 90: 1, 180: 6, 270: 3 }\n };\n return o[orientation][angle] ? o[orientation][angle] : orientation;\n },\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n transformCoordinate: function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext('2d');\n switch (orientation) {\n case 1:\n // nothing\n break;\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n },\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n detectVerticalSquash: function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = ih;\n var ctx = canvas.getContext('2d');\n ctx.drawImage(img, 0, 0);\n var data = ctx.getImageData(0, 0, 1, ih).data;\n // search image edge pixel position in case it is squashed vertically.\n var sy = 0;\n var ey = ih;\n var py = ih;\n while (py > sy) {\n var alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = ey + sy >> 1;\n }\n var ratio = py / ih;\n return ratio === 0 ? 1 : ratio;\n },\n callback: function callback(d) {\n return d;\n },\n extend: function extend() {\n var target = arguments[0] || {},\n a = 1,\n al = arguments.length,\n deep = false;\n if (target.constructor === Boolean) {\n deep = target;\n target = arguments[1] || {};\n }\n if (al === 1) {\n target = this;\n a = 0;\n }\n var prop;\n for (; a < al; a++) {\n if ((prop = arguments[a]) !== null) for (var i in prop) {\n if (target === prop[i]) continue;\n if (deep && _typeof(prop[i]) === 'object' && target[i]) methods.extend(target[i], prop[i]);else if (prop[i] !== undefined) target[i] = prop[i];\n }\n }return target;\n }\n },\n defaults = {\n width: 300,\n height: 0,\n crop: false,\n quality: 80,\n rotate: 0,\n 'callback': methods.callback\n };\n function Plugin(file, options) {\n this.file = file;\n // EXTEND\n this.options = methods.extend({}, defaults, options);\n this._defaults = defaults;\n this._name = pluginName;\n this.init();\n }\n Plugin.prototype = {\n init: function init() {\n //this.options.init(this);\n var $this = this;\n var file = this.file;\n\n var reader = new FileReader();\n reader.onloadend = function (e) {\n\n var dataURL = e.target.result;\n var byteString = atob(dataURL.split(',')[1]);\n var binary = new BinaryFile(byteString, 0, byteString.length);\n var exif = EXIF.readFromBinaryFile(binary);\n\n var img = new Image();\n img.onload = function (e) {\n\n var orientation = exif['Orientation'] || 1;\n orientation = methods.rotate(orientation, $this.options.rotate);\n\n // CW or CCW ? replace width and height\n var size = orientation >= 5 && orientation <= 8 ? methods.newsize(img.height, img.width, $this.options.width, $this.options.height, $this.options.crop) : methods.newsize(img.width, img.height, $this.options.width, $this.options.height, $this.options.crop);\n\n var iw = img.width,\n ih = img.height;\n var width = size.width,\n height = size.height;\n\n var canvas = document.createElement(\"canvas\");\n var ctx = canvas.getContext(\"2d\");\n ctx.save();\n methods.transformCoordinate(canvas, width, height, orientation);\n\n // over image size\n if (methods.detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n var d = 1024; // size of tiling canvas\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = tmpCanvas.height = d;\n var tmpCtx = tmpCanvas.getContext('2d');\n var vertSquashRatio = methods.detectVerticalSquash(img, iw, ih);\n var sy = 0;\n while (sy < ih) {\n var sh = sy + d > ih ? ih - sy : d;\n var sx = 0;\n while (sx < iw) {\n var sw = sx + d > iw ? iw - sx : d;\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n var dx = Math.floor(sx * width / iw);\n var dw = Math.ceil(sw * width / iw);\n var dy = Math.floor(sy * height / ih / vertSquashRatio);\n var dh = Math.ceil(sh * height / ih / vertSquashRatio);\n ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh);\n sx += d;\n }\n sy += d;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n\n // if rotated width and height data replacing issue \n var newcanvas = document.createElement('canvas');\n newcanvas.width = size.cropped === 'h' ? height : width;\n newcanvas.height = size.cropped === 'w' ? width : height;\n var x = size.cropped === 'h' ? (height - width) * .5 : 0;\n var y = size.cropped === 'w' ? (width - height) * .5 : 0;\n var newctx = newcanvas.getContext('2d');\n newctx.drawImage(canvas, x, y, width, height);\n\n // console.log(file, file.type);\n if (file.type === \"image/png\") {\n var data = newcanvas.toDataURL(file.type);\n } else {\n var data = newcanvas.toDataURL(\"image/jpeg\", $this.options.quality * .01);\n }\n\n // CALLBACK\n $this.options.callback(data, newcanvas.width, newcanvas.height);\n\n // });\n };\n img.src = dataURL;\n // =====================================================\n };\n reader.readAsDataURL(file);\n //reader.readAsBinaryString(file);\n }\n };\n $[pluginName] = function (file, options) {\n if (typeof file === 'string') return methods[file](options);else new Plugin(file, options);\n };\n })(window);; /*\n * Javascript EXIF Reader 0.1.6\n * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/\n * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]\n */\n\n var EXIF = function () {\n\n var debug = false;\n\n var ExifTags = {\n\n // version tags\n 0x9000: \"ExifVersion\", // EXIF version\n 0xA000: \"FlashpixVersion\", // Flashpix format version\n\n // colorspace tags\n 0xA001: \"ColorSpace\", // Color space information tag\n\n // image configuration\n 0xA002: \"PixelXDimension\", // Valid width of meaningful image\n 0xA003: \"PixelYDimension\", // Valid height of meaningful image\n 0x9101: \"ComponentsConfiguration\", // Information about channels\n 0x9102: \"CompressedBitsPerPixel\", // Compressed bits per pixel\n\n // user information\n 0x927C: \"MakerNote\", // Any desired information written by the manufacturer\n 0x9286: \"UserComment\", // Comments by user\n\n // related file\n 0xA004: \"RelatedSoundFile\", // Name of related sound file\n\n // date and time\n 0x9003: \"DateTimeOriginal\", // Date and time when the original image was generated\n 0x9004: \"DateTimeDigitized\", // Date and time when the image was stored digitally\n 0x9290: \"SubsecTime\", // Fractions of seconds for DateTime\n 0x9291: \"SubsecTimeOriginal\", // Fractions of seconds for DateTimeOriginal\n 0x9292: \"SubsecTimeDigitized\", // Fractions of seconds for DateTimeDigitized\n\n // picture-taking conditions\n 0x829A: \"ExposureTime\", // Exposure time (in seconds)\n 0x829D: \"FNumber\", // F number\n 0x8822: \"ExposureProgram\", // Exposure program\n 0x8824: \"SpectralSensitivity\", // Spectral sensitivity\n 0x8827: \"ISOSpeedRatings\", // ISO speed rating\n 0x8828: \"OECF\", // Optoelectric conversion factor\n 0x9201: \"ShutterSpeedValue\", // Shutter speed\n 0x9202: \"ApertureValue\", // Lens aperture\n 0x9203: \"BrightnessValue\", // Value of brightness\n 0x9204: \"ExposureBias\", // Exposure bias\n 0x9205: \"MaxApertureValue\", // Smallest F number of lens\n 0x9206: \"SubjectDistance\", // Distance to subject in meters\n 0x9207: \"MeteringMode\", // Metering mode\n 0x9208: \"LightSource\", // Kind of light source\n 0x9209: \"Flash\", // Flash status\n 0x9214: \"SubjectArea\", // Location and area of main subject\n 0x920A: \"FocalLength\", // Focal length of the lens in mm\n 0xA20B: \"FlashEnergy\", // Strobe energy in BCPS\n 0xA20C: \"SpatialFrequencyResponse\", // \n 0xA20E: \"FocalPlaneXResolution\", // Number of pixels in width direction per FocalPlaneResolutionUnit\n 0xA20F: \"FocalPlaneYResolution\", // Number of pixels in height direction per FocalPlaneResolutionUnit\n 0xA210: \"FocalPlaneResolutionUnit\", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution\n 0xA214: \"SubjectLocation\", // Location of subject in image\n 0xA215: \"ExposureIndex\", // Exposure index selected on camera\n 0xA217: \"SensingMethod\", // Image sensor type\n 0xA300: \"FileSource\", // Image source (3 == DSC)\n 0xA301: \"SceneType\", // Scene type (1 == directly photographed)\n 0xA302: \"CFAPattern\", // Color filter array geometric pattern\n 0xA401: \"CustomRendered\", // Special processing\n 0xA402: \"ExposureMode\", // Exposure mode\n 0xA403: \"WhiteBalance\", // 1 = auto white balance, 2 = manual\n 0xA404: \"DigitalZoomRation\", // Digital zoom ratio\n 0xA405: \"FocalLengthIn35mmFilm\", // Equivalent foacl length assuming 35mm film camera (in mm)\n 0xA406: \"SceneCaptureType\", // Type of scene\n 0xA407: \"GainControl\", // Degree of overall image gain adjustment\n 0xA408: \"Contrast\", // Direction of contrast processing applied by camera\n 0xA409: \"Saturation\", // Direction of saturation processing applied by camera\n 0xA40A: \"Sharpness\", // Direction of sharpness processing applied by camera\n 0xA40B: \"DeviceSettingDescription\", // \n 0xA40C: \"SubjectDistanceRange\", // Distance to subject\n\n // other tags\n 0xA005: \"InteroperabilityIFDPointer\",\n 0xA420: \"ImageUniqueID\" // Identifier assigned uniquely to each image\n };\n\n var TiffTags = {\n 0x0100: \"ImageWidth\",\n 0x0101: \"ImageHeight\",\n 0x8769: \"ExifIFDPointer\",\n 0x8825: \"GPSInfoIFDPointer\",\n 0xA005: \"InteroperabilityIFDPointer\",\n 0x0102: \"BitsPerSample\",\n 0x0103: \"Compression\",\n 0x0106: \"PhotometricInterpretation\",\n 0x0112: \"Orientation\",\n 0x0115: \"SamplesPerPixel\",\n 0x011C: \"PlanarConfiguration\",\n 0x0212: \"YCbCrSubSampling\",\n 0x0213: \"YCbCrPositioning\",\n 0x011A: \"XResolution\",\n 0x011B: \"YResolution\",\n 0x0128: \"ResolutionUnit\",\n 0x0111: \"StripOffsets\",\n 0x0116: \"RowsPerStrip\",\n 0x0117: \"StripByteCounts\",\n 0x0201: \"JPEGInterchangeFormat\",\n 0x0202: \"JPEGInterchangeFormatLength\",\n 0x012D: \"TransferFunction\",\n 0x013E: \"WhitePoint\",\n 0x013F: \"PrimaryChromaticities\",\n 0x0211: \"YCbCrCoefficients\",\n 0x0214: \"ReferenceBlackWhite\",\n 0x0132: \"DateTime\",\n 0x010E: \"ImageDescription\",\n 0x010F: \"Make\",\n 0x0110: \"Model\",\n 0x0131: \"Software\",\n 0x013B: \"Artist\",\n 0x8298: \"Copyright\"\n };\n\n var GPSTags = {\n 0x0000: \"GPSVersionID\",\n 0x0001: \"GPSLatitudeRef\",\n 0x0002: \"GPSLatitude\",\n 0x0003: \"GPSLongitudeRef\",\n 0x0004: \"GPSLongitude\",\n 0x0005: \"GPSAltitudeRef\",\n 0x0006: \"GPSAltitude\",\n 0x0007: \"GPSTimeStamp\",\n 0x0008: \"GPSSatellites\",\n 0x0009: \"GPSStatus\",\n 0x000A: \"GPSMeasureMode\",\n 0x000B: \"GPSDOP\",\n 0x000C: \"GPSSpeedRef\",\n 0x000D: \"GPSSpeed\",\n 0x000E: \"GPSTrackRef\",\n 0x000F: \"GPSTrack\",\n 0x0010: \"GPSImgDirectionRef\",\n 0x0011: \"GPSImgDirection\",\n 0x0012: \"GPSMapDatum\",\n 0x0013: \"GPSDestLatitudeRef\",\n 0x0014: \"GPSDestLatitude\",\n 0x0015: \"GPSDestLongitudeRef\",\n 0x0016: \"GPSDestLongitude\",\n 0x0017: \"GPSDestBearingRef\",\n 0x0018: \"GPSDestBearing\",\n 0x0019: \"GPSDestDistanceRef\",\n 0x001A: \"GPSDestDistance\",\n 0x001B: \"GPSProcessingMethod\",\n 0x001C: \"GPSAreaInformation\",\n 0x001D: \"GPSDateStamp\",\n 0x001E: \"GPSDifferential\"\n };\n\n var StringValues = {\n ExposureProgram: {\n 0: \"Not defined\",\n 1: \"Manual\",\n 2: \"Normal program\",\n 3: \"Aperture priority\",\n 4: \"Shutter priority\",\n 5: \"Creative program\",\n 6: \"Action program\",\n 7: \"Portrait mode\",\n 8: \"Landscape mode\"\n },\n MeteringMode: {\n 0: \"Unknown\",\n 1: \"Average\",\n 2: \"CenterWeightedAverage\",\n 3: \"Spot\",\n 4: \"MultiSpot\",\n 5: \"Pattern\",\n 6: \"Partial\",\n 255: \"Other\"\n },\n LightSource: {\n 0: \"Unknown\",\n 1: \"Daylight\",\n 2: \"Fluorescent\",\n 3: \"Tungsten (incandescent light)\",\n 4: \"Flash\",\n 9: \"Fine weather\",\n 10: \"Cloudy weather\",\n 11: \"Shade\",\n 12: \"Daylight fluorescent (D 5700 - 7100K)\",\n 13: \"Day white fluorescent (N 4600 - 5400K)\",\n 14: \"Cool white fluorescent (W 3900 - 4500K)\",\n 15: \"White fluorescent (WW 3200 - 3700K)\",\n 17: \"Standard light A\",\n 18: \"Standard light B\",\n 19: \"Standard light C\",\n 20: \"D55\",\n 21: \"D65\",\n 22: \"D75\",\n 23: \"D50\",\n 24: \"ISO studio tungsten\",\n 255: \"Other\"\n },\n Flash: {\n 0x0000: \"Flash did not fire\",\n 0x0001: \"Flash fired\",\n 0x0005: \"Strobe return light not detected\",\n 0x0007: \"Strobe return light detected\",\n 0x0009: \"Flash fired, compulsory flash mode\",\n 0x000D: \"Flash fired, compulsory flash mode, return light not detected\",\n 0x000F: \"Flash fired, compulsory flash mode, return light detected\",\n 0x0010: \"Flash did not fire, compulsory flash mode\",\n 0x0018: \"Flash did not fire, auto mode\",\n 0x0019: \"Flash fired, auto mode\",\n 0x001D: \"Flash fired, auto mode, return light not detected\",\n 0x001F: \"Flash fired, auto mode, return light detected\",\n 0x0020: \"No flash function\",\n 0x0041: \"Flash fired, red-eye reduction mode\",\n 0x0045: \"Flash fired, red-eye reduction mode, return light not detected\",\n 0x0047: \"Flash fired, red-eye reduction mode, return light detected\",\n 0x0049: \"Flash fired, compulsory flash mode, red-eye reduction mode\",\n 0x004D: \"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected\",\n 0x004F: \"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected\",\n 0x0059: \"Flash fired, auto mode, red-eye reduction mode\",\n 0x005D: \"Flash fired, auto mode, return light not detected, red-eye reduction mode\",\n 0x005F: \"Flash fired, auto mode, return light detected, red-eye reduction mode\"\n },\n SensingMethod: {\n 1: \"Not defined\",\n 2: \"One-chip color area sensor\",\n 3: \"Two-chip color area sensor\",\n 4: \"Three-chip color area sensor\",\n 5: \"Color sequential area sensor\",\n 7: \"Trilinear sensor\",\n 8: \"Color sequential linear sensor\"\n },\n SceneCaptureType: {\n 0: \"Standard\",\n 1: \"Landscape\",\n 2: \"Portrait\",\n 3: \"Night scene\"\n },\n SceneType: {\n 1: \"Directly photographed\"\n },\n CustomRendered: {\n 0: \"Normal process\",\n 1: \"Custom process\"\n },\n WhiteBalance: {\n 0: \"Auto white balance\",\n 1: \"Manual white balance\"\n },\n GainControl: {\n 0: \"None\",\n 1: \"Low gain up\",\n 2: \"High gain up\",\n 3: \"Low gain down\",\n 4: \"High gain down\"\n },\n Contrast: {\n 0: \"Normal\",\n 1: \"Soft\",\n 2: \"Hard\"\n },\n Saturation: {\n 0: \"Normal\",\n 1: \"Low saturation\",\n 2: \"High saturation\"\n },\n Sharpness: {\n 0: \"Normal\",\n 1: \"Soft\",\n 2: \"Hard\"\n },\n SubjectDistanceRange: {\n 0: \"Unknown\",\n 1: \"Macro\",\n 2: \"Close view\",\n 3: \"Distant view\"\n },\n FileSource: {\n 3: \"DSC\"\n },\n Components: {\n 0: \"\",\n 1: \"Y\",\n 2: \"Cb\",\n 3: \"Cr\",\n 4: \"R\",\n 5: \"G\",\n 6: \"B\"\n }\n };\n\n function addEvent(element, event, handler) {\n if (element.addEventListener) {\n element.addEventListener(event, handler, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + event, handler);\n }\n }\n\n function imageHasData(img) {\n return !!img.exifdata;\n }\n\n function getImageData(img, callback) {\n BinaryAjax(img.src, function (http) {\n var data = findEXIFinJPEG(http.binaryResponse);\n img.exifdata = data || {};\n if (callback) {\n callback.call(img);\n }\n });\n }\n\n function findEXIFinJPEG(file) {\n if (file.getByteAt(0) != 0xFF || file.getByteAt(1) != 0xD8) {\n return false; // not a valid jpeg\n }\n\n var offset = 2,\n length = file.getLength(),\n marker;\n\n while (offset < length) {\n if (file.getByteAt(offset) != 0xFF) {\n if (debug) console.log(\"Not a valid marker at offset \" + offset + \", found: \" + file.getByteAt(offset));\n return false; // not a valid marker, something is wrong\n }\n\n marker = file.getByteAt(offset + 1);\n\n // we could implement handling for other markers here, \n // but we're only looking for 0xFFE1 for EXIF data\n\n if (marker == 22400) {\n if (debug) console.log(\"Found 0xFFE1 marker\");\n\n return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2);\n\n // offset += 2 + file.getShortAt(offset+2, true);\n } else if (marker == 225) {\n // 0xE1 = Application-specific 1 (for EXIF)\n if (debug) console.log(\"Found 0xFFE1 marker\");\n\n return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2);\n } else {\n offset += 2 + file.getShortAt(offset + 2, true);\n }\n }\n }\n\n function readTags(file, tiffStart, dirStart, strings, bigEnd) {\n var entries = file.getShortAt(dirStart, bigEnd),\n tags = {},\n entryOffset,\n tag,\n i;\n\n for (i = 0; i < entries; i++) {\n entryOffset = dirStart + i * 12 + 2;\n tag = strings[file.getShortAt(entryOffset, bigEnd)];\n if (!tag && debug) console.log(\"Unknown tag: \" + file.getShortAt(entryOffset, bigEnd));\n tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);\n }\n return tags;\n }\n\n function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) {\n var type = file.getShortAt(entryOffset + 2, bigEnd),\n numValues = file.getLongAt(entryOffset + 4, bigEnd),\n valueOffset = file.getLongAt(entryOffset + 8, bigEnd) + tiffStart,\n offset,\n vals,\n val,\n n,\n numerator,\n denominator;\n\n switch (type) {\n case 1: // byte, 8-bit unsigned int\n case 7:\n // undefined, 8-bit byte, value depending on field\n if (numValues == 1) {\n return file.getByteAt(entryOffset + 8, bigEnd);\n } else {\n offset = numValues > 4 ? valueOffset : entryOffset + 8;\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getByteAt(offset + n);\n }\n return vals;\n }\n\n case 2:\n // ascii, 8-bit byte\n offset = numValues > 4 ? valueOffset : entryOffset + 8;\n return file.getStringAt(offset, numValues - 1);\n\n case 3:\n // short, 16 bit int\n if (numValues == 1) {\n return file.getShortAt(entryOffset + 8, bigEnd);\n } else {\n offset = numValues > 2 ? valueOffset : entryOffset + 8;\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getShortAt(offset + 2 * n, bigEnd);\n }\n return vals;\n }\n\n case 4:\n // long, 32 bit int\n if (numValues == 1) {\n return file.getLongAt(entryOffset + 8, bigEnd);\n } else {\n vals = [];\n for (var n = 0; n < numValues; n++) {\n vals[n] = file.getLongAt(valueOffset + 4 * n, bigEnd);\n }\n return vals;\n }\n\n case 5:\n // rational = two long values, first is numerator, second is denominator\n if (numValues == 1) {\n numerator = file.getLongAt(valueOffset, bigEnd);\n denominator = file.getLongAt(valueOffset + 4, bigEnd);\n val = new Number(numerator / denominator);\n val.numerator = numerator;\n val.denominator = denominator;\n return val;\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n numerator = file.getLongAt(valueOffset + 8 * n, bigEnd);\n denominator = file.getLongAt(valueOffset + 4 + 8 * n, bigEnd);\n vals[n] = new Number(numerator / denominator);\n vals[n].numerator = numerator;\n vals[n].denominator = denominator;\n }\n return vals;\n }\n\n case 9:\n // slong, 32 bit signed int\n if (numValues == 1) {\n return file.getSLongAt(entryOffset + 8, bigEnd);\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getSLongAt(valueOffset + 4 * n, bigEnd);\n }\n return vals;\n }\n\n case 10:\n // signed rational, two slongs, first is numerator, second is denominator\n if (numValues == 1) {\n return file.getSLongAt(valueOffset, bigEnd) / file.getSLongAt(valueOffset + 4, bigEnd);\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getSLongAt(valueOffset + 8 * n, bigEnd) / file.getSLongAt(valueOffset + 4 + 8 * n, bigEnd);\n }\n return vals;\n }\n }\n }\n\n function readEXIFData(file, start) {\n if (file.getStringAt(start, 4) != \"Exif\") {\n if (debug) console.log(\"Not valid EXIF data! \" + file.getStringAt(start, 4));\n return false;\n }\n\n var bigEnd,\n tags,\n tag,\n exifData,\n gpsData,\n tiffOffset = start + 6;\n\n // test for TIFF validity and endianness\n if (file.getShortAt(tiffOffset) == 0x4949) {\n bigEnd = false;\n } else if (file.getShortAt(tiffOffset) == 0x4D4D) {\n bigEnd = true;\n } else {\n if (debug) console.log(\"Not valid TIFF data! (no 0x4949 or 0x4D4D)\");\n return false;\n }\n\n if (file.getShortAt(tiffOffset + 2, bigEnd) != 0x002A) {\n if (debug) console.log(\"Not valid TIFF data! (no 0x002A)\");\n return false;\n }\n\n if (file.getLongAt(tiffOffset + 4, bigEnd) != 0x00000008) {\n if (debug) console.log(\"Not valid TIFF data! (First offset not 8)\", file.getShortAt(tiffOffset + 4, bigEnd));\n return false;\n }\n\n tags = readTags(file, tiffOffset, tiffOffset + 8, TiffTags, bigEnd);\n\n if (tags.ExifIFDPointer) {\n exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);\n for (tag in exifData) {\n switch (tag) {\n case \"LightSource\":\n case \"Flash\":\n case \"MeteringMode\":\n case \"ExposureProgram\":\n case \"SensingMethod\":\n case \"SceneCaptureType\":\n case \"SceneType\":\n case \"CustomRendered\":\n case \"WhiteBalance\":\n case \"GainControl\":\n case \"Contrast\":\n case \"Saturation\":\n case \"Sharpness\":\n case \"SubjectDistanceRange\":\n case \"FileSource\":\n exifData[tag] = StringValues[tag][exifData[tag]];\n break;\n\n case \"ExifVersion\":\n case \"FlashpixVersion\":\n exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);\n break;\n\n case \"ComponentsConfiguration\":\n exifData[tag] = StringValues.Components[exifData[tag][0]] + StringValues.Components[exifData[tag][1]] + StringValues.Components[exifData[tag][2]] + StringValues.Components[exifData[tag][3]];\n break;\n }\n tags[tag] = exifData[tag];\n }\n }\n\n if (tags.GPSInfoIFDPointer) {\n gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);\n for (tag in gpsData) {\n switch (tag) {\n case \"GPSVersionID\":\n gpsData[tag] = gpsData[tag][0] + \".\" + gpsData[tag][1] + \".\" + gpsData[tag][2] + \".\" + gpsData[tag][3];\n break;\n }\n tags[tag] = gpsData[tag];\n }\n }\n\n return tags;\n }\n\n function getData(img, callback) {\n if (!img.complete) return false;\n if (!imageHasData(img)) {\n getImageData(img, callback);\n } else {\n if (callback) {\n callback.call(img);\n }\n }\n return true;\n }\n\n function getTag(img, tag) {\n if (!imageHasData(img)) return;\n return img.exifdata[tag];\n }\n\n function getAllTags(img) {\n if (!imageHasData(img)) return {};\n var a,\n data = img.exifdata,\n tags = {};\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n tags[a] = data[a];\n }\n }\n return tags;\n }\n\n function pretty(img) {\n if (!imageHasData(img)) return \"\";\n var a,\n data = img.exifdata,\n strPretty = \"\";\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n if (_typeof(data[a]) == \"object\") {\n if (data[a] instanceof Number) {\n strPretty += a + \" : \" + data[a] + \" [\" + data[a].numerator + \"/\" + data[a].denominator + \"]\\r\\n\";\n } else {\n strPretty += a + \" : [\" + data[a].length + \" values]\\r\\n\";\n }\n } else {\n strPretty += a + \" : \" + data[a] + \"\\r\\n\";\n }\n }\n }\n return strPretty;\n }\n\n function readFromBinaryFile(file) {\n return findEXIFinJPEG(file);\n }\n\n return {\n readFromBinaryFile: readFromBinaryFile,\n pretty: pretty,\n getTag: getTag,\n getAllTags: getAllTags,\n getData: getData,\n Tags: ExifTags,\n TiffTags: TiffTags,\n GPSTags: GPSTags,\n StringValues: StringValues\n };\n }();; /** \n * @file html5图片上传\n * @author yuanmin.pu@condenast.com.cn\n * @version 0.1.0\n * @requires http://js.selfimg.com.cn/jquery/jquery-1.7.1.min.js[http://js.selfimg.com.cn/gallery/zepto/1.1.4/zepto.min.js]\n * @requires http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n * @example <a href=\"../upload/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/upload/0.1.0/upload.min.js\n */\n\n /** \n * @class\n * @author yuanmin.pu@condenast.com.cn\n * @description html5图片上传\n * @version 0.1.0\n * @requires http://js.selfimg.com.cn/jquery/jquery-1.7.1.min.js[http://js.selfimg.com.cn/gallery/zepto/1.1.4/zepto.min.js]\n * @requires http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n * @example <a href=\"../upload/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/upload/0.1.0/upload.min.js\n * @param {Object} selector 绑定的对象\n * @param {Object} cfgs 配置项\n * @param {String} [cfgs.url=http://imgsys.self.com.cn/interface] 接口地址\n * @param {Object} cfgs.params 地址参数\n * @param {Boolean} [cfgs.useCanvas=true] 是否使用canvas压缩,默认使用(ios下始终为true)\n * @param {(String|Number)} [cfgs.size=0] 大小限制,使用canvas则为压缩后的大小,默认不限制,单位M\n * @param {Number} [cfgs.limit=0] 数量限制,默认不限制\n * @param {Number} [cfgs.width=640] 宽度限制\n * @param {Number} [cfgs.quality=100] 图片质量0-100\n * @param {String} [cfgs.error] 文件检查错误输出\n * @param {Object} [cfgs.errorMsg] 文件检查错误信息\n * @param {Boolean} [cfgs.autoUpload=false] 是否自动上传\n * @param {Boolean} [cfgs.uploadBtn] 开始上传按钮,手动上传时配置\n * @param {(Object|String)} [cfgs.tpl=null] 上传列表模板:null不使用,空字符串使用默认,非空字符串使用自定义\n * @param {Object} [cfgs.tplContainer] 上传列表容器\n * @param {Boolean} [cfgs.autoHide=true] 多文件上传时自动隐藏上传成功的列表\n * @param {Function} [cfgs.onSelect] 文件选择后\n * @param {Function} [cfgs.onUploading] 整体文件上传中\n * @param {Function} [cfgs.onProgress] 文件上传进度\n * @param {Function} [cfgs.onSuccess] 文件上传成功时\n * @param {Function} [cfgs.onFailure] 文件上传失败时\n * @param {Function} [cfgs.onDelete] 文件删除后\n * @param {Function} [cfgs.onComplete] 文件全部上传完毕时\n * @param {Function} [cfgs.onError] 文件检查错误处理 function(msg) {}\n */\n function Upload(selector, cfgs) {\n this.cfgs = {\n url: 'http://imgsys.self.com.cn/interfaces',\n params: {},\n useCanvas: true,\n size: 0,\n limit: 0,\n width: 640,\n quality: 100,\n error: '',\n errorMsg: {\n overnum: '超出上传数量限制',\n invalidLarge: '太大了',\n invalidSmall: '太小了',\n invalidType: '是不支持的图片类型',\n forbidden: '图片上传中或者图片上传被禁用'\n },\n autoUpload: false,\n uploadBtn: '',\n tpl: '',\n tplContainer: '',\n autoHide: true,\n onSelect: function onSelect(files) {},\n onUploading: function onUploading() {},\n onProgress: function onProgress(loaded, total) {},\n onSuccess: function onSuccess(response, file) {},\n onFailure: function onFailure(msg, file) {},\n onDelete: function onDelete(file) {},\n onComplete: function onComplete(msg, files) {},\n onError: null\n };\n\n $.extend(true, this.cfgs, cfgs);\n this._init(selector);\n }\n\n Upload.prototype = {\n _init: function _init(selector) {\n var self = this;\n\n /** 包含容器 */\n self.container = $(selector);\n /** 上传控件 */\n self.input = self.container.find('[type=\"file\"]');\n /** 上传列表容器 */\n self.tplContainer = self.container.find(self.cfgs.tplContainer);\n /** 文件检查错误输出对象 */\n self.error = self.container.find(self.cfgs.error);\n /** 开始上传按钮 */\n self.uploadBtn = self.container.find(self.cfgs.uploadBtn);\n self.tpl = self.cfgs.tpl || '';\n self.disabled = true;\n self.files = [];\n self.filesFilter = [];\n self.failFiles = [];\n self.count = 0; // 总文件数\n self.compress = 0; // 压缩次数\n self._bind();\n },\n _bind: function _bind() {\n var self = this,\n tempFiles = [];\n\n self.input.change(function (e) {\n if (!self.disabled) {\n self._showError(self.error, self.cfgs.errorMsg.forbidden);\n return;\n }\n\n if (self.error.length) {\n self.error.html('').hide();\n }\n\n self.failFiles = [];\n tempFiles = [];\n tempFiles.push(e.target.files);\n var tempFilesLen = tempFiles[0].length;\n\n $.each(tempFiles, function (index1, files) {\n $.each(files, function (index2, file) {\n self.files.push(file);\n });\n });\n\n if (self.cfgs.limit > 0 && self.files.length > self.cfgs.limit) {\n for (var i = 0; i < tempFilesLen; i++) {\n self.files.pop();\n }\n self._showError(self.error, self.cfgs.errorMsg.overnum + self.cfgs.limit);\n } else {\n self.filesFilter = self._filter(self.files);\n self.count = self.filesFilter.length;\n self.cfgs.onSelect(self.filesFilter);\n\n if (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.filesFilter.length) {\n self._createTpl(self.filesFilter);\n }\n\n if (self.cfgs.autoUpload) {\n self._upload();\n }\n }\n });\n\n if (self.uploadBtn.length) {\n self.uploadBtn.click(function () {\n if (!self.disabled) {\n self._showError(self.error, self.cfgs.errorMsg.forbidden);\n return;\n }\n\n if (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.filesFilter.length) {\n var failure = self.tplContainer.find('[node-status=\"failure\"]');\n\n failure.find('[node-type=\"result\"]').hide();\n failure.find('[node-type=\"progress\"]').css('width', 0);\n failure.find('[node-type=\"reupload\"]').hide();\n }\n\n self.count = self.filesFilter.length;\n self.failFiles = [];\n self._upload();\n });\n }\n },\n _filter: function _filter(files) {\n var self = this,\n filesArr = [],\n msg = [];\n\n $.each(files, function (index, file) {\n var maxSize = parseFloat(self.cfgs.size),\n fileName = file.name ? file.name : '';\n\n if (file.type) {\n if (file.type.indexOf('image') === 0) {\n if (!self.cfgs.useCanvas && maxSize > 0 && file.size >= maxSize * 1048576) {\n msg.push(fileName + self.cfgs.errorMsg.invalidLarge);\n } else {\n file.index = index;\n file.aborted = false;\n filesArr.push(file);\n }\n } else {\n msg.push(fileName + self.cfgs.errorMsg.invalidType);\n }\n } else {\n if (!self.cfgs.useCanvas && maxSize > 0 && file.size >= maxSize * 1048576) {\n msg.push(fileName + self.cfgs.errorMsg.invalidLarge);\n } else {\n file.index = index;\n file.aborted = false;\n filesArr.push(file);\n }\n }\n });\n\n if (msg.length) {\n self._showError(self.error, msg.join('\\n'));\n }\n\n return filesArr;\n },\n _createTpl: function _createTpl(files) {\n var self = this,\n tpl = '',\n items = '',\n previews = [],\n revoker = null;\n\n if (self.cfgs.tpl) {\n tpl = self.cfgs.tpl;\n } else {\n tpl = '<li node-id=$fileIndex>\\\n \t\t<p node-type=\"preview\" style=\"background-image:url($preview);\"></p>\\\n \t\t<p node-type=\"result\"></p>\\\n \t<p node-type=\"name\">$name</p>\\\n \t<p node-type=\"size\">$size</p>\\\n \t<p node-type=\"progress\"></p>\\\n \t<p node-type=\"reupload\" node-data=$fileIndex>^</p>\\\n \t<p node-type=\"close\" node-data=$fileIndex>x</p>\\\n \t</li>';\n }\n\n if (brickjs.UserAgent.isiOS) {\n $.each(files, function (index, file) {\n var size = file.size / 1024,\n obj = {\n name: file.name,\n size: size >= 1024 ? (size / 1024).toFixed(1) + 'M' : size.toFixed(1) + 'KB',\n fileIndex: file.index\n };\n\n canvasResize(file, {\n width: self.cfgs.width,\n height: 0,\n crop: false,\n quality: self.cfgs.quality,\n callback: function callback(data, width, height) {\n obj.preview = data;\n items += self._templ(tpl, obj);\n\n if (index === files.length - 1) {\n self.tplContainer.html(items).show();\n self._bindTpl();\n }\n }\n });\n });\n\n return;\n }\n\n $.each(files, function (index, file) {\n var size = file.size / 1024,\n obj = {\n name: file.name,\n size: size >= 1024 ? (size / 1024).toFixed(1) + 'M' : size.toFixed(1) + 'KB',\n fileIndex: file.index\n };\n\n obj.preview = self._dealObjectURL(file, true);\n items += self._templ(tpl, obj);\n previews.push(obj.preview);\n });\n\n revoker = setTimeout(function () {\n $.each(previews, function (index, val) {\n self._dealObjectURL(val);\n });\n\n clearTimeout(revoker);\n }, 5000);\n self.tplContainer.html(items).show();\n self._bindTpl();\n },\n _bindTpl: function _bindTpl() {\n var self = this;\n\n self.tplContainer.on('click', '[node-type=\"close\"]', function () {\n self._delete($(this).attr('node-data'));\n });\n\n self.tplContainer.on('click', '[node-type=\"reupload\"]', function () {\n var fileIndex = $(this).hide().attr('node-data'),\n currentFiles = [],\n failure = '';\n\n $.each(self.filesFilter, function (index, file) {\n if (file.index == fileIndex) {\n failure = self.tplContainer.find('[node-id=\"' + fileIndex + '\"]');\n failure.find('[node-type=\"result\"]').hide();\n failure.find('[node-type=\"progress\"]').css('width', 0);\n currentFiles.push(file);\n self._upload(currentFiles);\n return false;\n };\n });\n });\n },\n _watchTpl: function _watchTpl(status, index, a, b) {\n var self = this,\n item = '';\n\n if (typeof self.cfgs.tpl !== 'string' || !self.tplContainer.length) {\n return;\n }\n\n item = self.container.find('[node-id=\"' + index + '\"]');\n\n switch (status) {\n case 'progress':\n item.find('[node-type=\"progress\"]').animate({ width: a / b * 100 + '%' });\n break;\n case 'success':\n item.attr('node-status', 'success').find('[node-type=\"result\"]').html('上传成功').show();\n item.find('[node-type=\"progress\"]').css('width', '100%');\n break;\n case 'failure':\n item.attr('node-status', 'failure').find('[node-type=\"result\"]').html(a ? a : '上传失败').show();\n item.find('[node-type=\"reupload\"]').show();\n break;\n }\n },\n _templ: function _templ(c, a) {\n for (var b in a) {\n if (a.hasOwnProperty(b)) {\n c = c.replace(new RegExp('\\\\$' + b, 'ig'), a[b]);\n }\n }\n\n return c;\n },\n _dealObjectURL: function _dealObjectURL(file, create) {\n if (window.URL) {\n if (create) {\n return window.URL.createObjectURL(file);\n } else {\n window.URL.revokeObjectURL(file);\n }\n } else if (window.webkitURL) {\n if (create) {\n return window.webkitURL.createObjectURL(file);\n } else {\n window.webkitURL.revokeObjectURL(file);\n }\n }\n },\n _upload: function _upload(target) {\n var self = this,\n filesFilter = self.filesFilter;\n\n if (target) {\n filesFilter = target;\n }\n\n if (filesFilter.length === 0) {\n return;\n }\n\n self.cfgs.onUploading();\n self.disable();\n\n $.each(filesFilter, function (index, file) {\n var xhr = new XMLHttpRequest(),\n fileIndex = file.index,\n fileName = file.name ? file.name : '';\n\n xhr.upload.addEventListener('progress', function (e) {\n self._watchTpl('progress', fileIndex, e.loaded, e.total);\n self.cfgs.onProgress(e.loaded, e.total, file);\n }, false);\n\n xhr.addEventListener('error', function (e) {\n self._checkPogress(target, file);\n self._watchTpl('failure', fileIndex);\n self.cfgs.onFailure('上传失败', file);\n if (self.cfgs.autoUpload) {\n self._delete(file, target);\n }\n }, false);\n\n xhr.addEventListener('load', function (e) {\n var response = eval('(' + xhr.responseText + ')'),\n fileAborted = file.aborted;\n\n if (!fileAborted) {\n if (response && response.status == 1) {\n self._watchTpl('success', fileIndex);\n self.cfgs.onSuccess(response, file);\n self._delete(file, target);\n } else {\n self._checkPogress(target, file);\n self._watchTpl('failure', fileIndex, response ? response.message : '上传失败');\n self.cfgs.onFailure(response ? response.message : '上传失败', file);\n }\n }\n }, false);\n\n if (!self.cfgs.useCanvas && !brickjs.UserAgent.isiOS) {\n var formData = new FormData();\n\n formData.append('Filedata', file);\n\n for (var p in self.cfgs.params) {\n if (self.cfgs.params.hasOwnProperty(p)) {\n formData.append(p, self.cfgs.params[p]);\n }\n }\n\n xhr.open('POST', self.cfgs.url, true);\n xhr.send(formData);\n } else if (brickjs.UserAgent.isiOS) {\n self._resizeIos(file, 1, 1, xhr);\n } else {\n self._resize(file, 1, 1, xhr);\n }\n });\n },\n _resize: function _resize(file, ratio1, ratio2, xhr) {\n var self = this,\n canvas = document.createElement('canvas'),\n ctx = canvas.getContext('2d'),\n reader = new FileReader(),\n img = new Image(),\n ratio = 1,\n data = null,\n maxSize = parseFloat(self.cfgs.size) || 1000,\n dataLength = 0;\n\n reader.onload = function (e) {\n img.onload = function () {\n ratio = this.width > self.cfgs.width ? self.cfgs.width / this.width : 1;\n canvas.width = this.width * ratio * ratio1;\n canvas.height = this.height * ratio * ratio1;\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n\n if (file.type === 'image/png') {\n data = canvas.toDataURL(file.type);\n } else {\n data = canvas.toDataURL('image/jpeg', self.cfgs.quality / 100 * ratio2);\n }\n\n if (data.length < maxSize * 1024 * 1024) {\n xhr.open('POST', self.cfgs.url, true);\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n xhr.send('Filedata=' + encodeURIComponent(data) + '&title=' + self.cfgs.params.title + '&uploadtype=' + self.cfgs.params.uploadtype);\n } else {\n self.compress++;\n\n if (file.type === 'image/png' || brickjs.UserAgent.isAndroid && !brickjs.UserAgent.chrome) {\n self._resize(file, Math.pow(.8, self.compress), 1, xhr);\n } else {\n self._resize(file, 1, Math.pow(.8, self.compress), xhr);\n }\n }\n };\n\n img.src = e.target.result;\n };\n\n reader.readAsDataURL(file);\n },\n _resizeIos: function _resizeIos(file, ratio1, ratio2, xhr) {\n var self = this,\n maxSize = parseFloat(self.cfgs.size) || 1000,\n dataLength = 0;\n\n canvasResize(file, {\n width: self.cfgs.width * ratio1,\n height: 0,\n crop: false,\n quality: self.cfgs.quality * ratio2,\n callback: function callback(data, width, height) {\n if (data.length < maxSize * 1024 * 1024) {\n xhr.open('POST', self.cfgs.url, true);\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n xhr.send('Filedata=' + encodeURIComponent(data) + '&title=' + self.cfgs.params.title + '&uploadtype=' + self.cfgs.params.uploadtype);\n } else {\n self.compress++;\n\n if (file.type === 'image/png') {\n self._resizeIos(file, Math.pow(.8, self.compress), 1, xhr);\n } else {\n self._resizeIos(file, 1, Math.pow(.8, self.compress), xhr);\n }\n }\n }\n });\n },\n _delete: function _delete(fileDelete, target) {\n var self = this,\n filesArr = [];\n\n if (!self.filesFilter.length && typeof fileDelete === 'string') {\n self._hidePreview(fileDelete);\n return;\n }\n\n $.each(self.filesFilter, function (index, file) {\n if (typeof fileDelete === 'string') {\n if (file.index != fileDelete) {\n filesArr.push(file);\n } else {\n self._hidePreview(fileDelete);\n file.aborted = true;\n self.cfgs.onDelete(file);\n }\n } else {\n if (file != fileDelete) {\n filesArr.push(file);\n } else {\n if (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.cfgs.autoHide) {\n self._hidePreview(file.index);\n }\n }\n }\n });\n\n self.filesFilter = filesArr;\n self.files = filesArr;\n self._checkPogress(target);\n },\n _hidePreview: function _hidePreview(index) {\n var self = this,\n itemLen = 0;\n\n self.container.find('[node-id=\"' + index + '\"]').fadeOut('slow', function () {\n $(this).remove();\n itemLen = self.container.find('[node-id]').length;\n\n if (!itemLen) {\n self.tplContainer.html('').hide();\n }\n });\n },\n _checkPogress: function _checkPogress(target, fileFailure) {\n var self = this;\n\n self.count--;\n\n if (fileFailure) {\n self.failFiles.push(fileFailure);\n }\n\n if (!self.filesFilter.length) {\n if (!self.disabled) {\n self.cfgs.onComplete('全部图片上传成功');\n }\n\n self.enable();\n } else if (!self.count && self.failFiles.length) {\n self.cfgs.onComplete('部分图片未上传成功,请重新上传', self.failFiles);\n self.enable();\n } else if (target) {\n self.enable();\n }\n },\n _showError: function _showError(error, msg, append) {\n if (typeof this.cfgs.onError === 'function') {\n this.cfgs.onError(msg);\n return;\n }\n\n if (error.length) {\n if (append) {\n error.append(msg).show();\n } else {\n error.html(msg).show();\n }\n } else {\n setTimeout(function () {\n alert(msg);\n }, 0);\n }\n },\n /**\n * 禁用图片上传\n */\n disable: function disable() {\n this.disabled = false;\n },\n /**\n * 启用图片上传\n */\n enable: function enable() {\n this.disabled = true;\n }\n };\n ;regist(\"Upload\", Upload);\n})(typeof Zepto !== 'undefined' ? Zepto : jQuery, window, document);\n\n/***/ }),\n\n/***/ 14:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n;(function ($, window, document, undefined) {\n function regist(mName, module) {\n if (typeof window.brickjs === \"undefined\") {\n window.brickjs = {};\n }\n brickjs[mName] = module;\n }\n ; /** \n * 移动设备及浏览器检测\n * @fileOverview\n * @author jianjun.wang@condenast.com.cn\n * @version 0.1.0\n * @example <a href=\"../useragent/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n */\n /** \n * @class\n * @author jianjun.wang@condenast.com.cn\n * @description 移动设备及浏览器检测\n * @since version 0.1.0\n * @example <a href=\"../useragent/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n */\n var UserAgent = {\n /** \n * @description {Boolean} 是否桌面电脑\n * @field\n */\n isDesktop: false,\n /** \n * @description {Boolean} 是否Windows系统\n * @field\n */\n isWindows: false,\n /** \n * @description {Boolean} 是否Linux系统\n * @field\n */\n isLinux: false,\n /** \n * @description {Boolean} 是否Mac系统\n * @field\n */\n isMac: false,\n\n /** \n * @description {Boolean} 是否平板设备\n * @field\n */\n isTablet: false,\n /** \n * @description {Boolean} 是否iPad设备\n * @field\n */\n isiPad: false,\n /** \n * @description {Boolean} 是否Android平板\n * @field\n */\n isAndroidTablet: false,\n\n /** \n * @description {Boolean} 是否移动手机设备\n * @field\n */\n isMobile: false,\n /** \n * @description {Boolean} 是否iOS系统\n * @field\n */\n isiOS: false,\n /** \n * @description {Boolean} 是否Android系统\n * @field\n */\n isAndroid: false,\n /** \n * @description {Boolean} 是否iPhone手机\n * @field\n */\n isiPhone: false, //简化, ipod也归于iphone\n /** \n * @description {Boolean} 是否WindowsPhone手机\n * @field\n */\n isWindowsPhone: false,\n /** \n * @description {Boolean} 是否微信浏览器\n * @field\n */\n isWeChat: false,\n /** \n * @description {Boolean} 是否微博浏览器\n * @field\n */\n isWeibo: false,\n\n /** \n * @description {Float} IE浏览器版本号,默认为 0\n * @field\n */\n ie: 0, //默认为0,监测到浏览器直接返回版本号\n /** \n * @description {Float} Firefox浏览器版本号,默认为 0\n * @field\n */\n firefox: 0,\n /** \n * @description {Float} Chrome浏览器版本号,默认为 0\n * @field\n */\n chrome: 0,\n /** \n * @description {Float} Safari浏览器版本号,默认为 0\n * @field\n */\n safari: 0,\n /** \n * @description {Float} Opera浏览器版本号,默认为 0\n * @field\n */\n opera: 0,\n /** \n * @description {Float} UC浏览器版本号,默认为 0\n * @field\n */\n uc: 0,\n /** \n * @description {Float} MQQ浏览器版本号,默认为 0\n * @field\n */\n mqq: 0,\n /** \n * @description {Float} Baidu浏览器版本号,默认为 0\n * @field\n */\n baidu: 0,\n /** \n * @description {Float} Android系统自带浏览器版本号,默认为 0,没有匹配到其它浏览器都认为是Android浏览器\n * @field\n */\n androidBrowser: 0,\n\n /** \n * @description {String} 浏览器名称,可能的值:IE|Firefox|Chrome|Safari|Opera|UC|MQQ|Baidu|Weibo|MicroMessenger|Android|unknown\n * @field\n */\n browser: \"\",\n /** \n * @description {String} 浏览器引擎名称,可能的值:trident|applewebkit|presto|gecko\n * @field\n */\n engine: \"\",\n /** \n * @description {String} iOS或者Android系统版本号,不支持其它系统\n * @field\n */\n osVersion: 0, //只支持ios android,PC不做支持 \n\n _versions: {\n ie: /msie\\s([\\d\\.]+[\\d])|trident\\/\\d+\\.\\d+;\\s+[rv:]+(\\d+\\.\\d)/i,\n firefox: /firefox\\/([\\d\\w\\.\\-]+)/i,\n chrome: /(chrome|crios)\\/([\\d\\w\\.\\-]+)/i,\n safari: /version\\/([\\d\\w\\.\\-]+)/i,\n opera: /version\\/([\\d\\w\\.\\-]+)/i,\n uc: /ucbrowser\\/([\\d\\w\\.\\-]+)/i,\n mqq: /mqqbrowser\\/([\\d\\w\\.\\-]+)/i,\n baidu: /baidubrowser\\/([\\d\\w\\.\\-]+)/i,\n androidBrowser: /version\\/([\\d\\w\\.\\-]+)/i\n },\n _browsers: {\n ie: /msie|trident/i,\n firefox: /firefox/i,\n chrome: /chrome|crios/i,\n safari: /safari/i,\n opera: /opera/i,\n uc: /ucbrowser/i,\n mqq: /mqqbrowser/i,\n baidu: /baidubrowser/i,\n weibo: /weibo/i,\n wechat: /micromessenger/i\n },\n _platforms: {\n windows: /windows nt/i,\n windowsPhone: /windows phone/i,\n mac: /macintosh/i,\n linux: /linux/i,\n iPad: /ipad/i,\n iPod: /ipod/i,\n iPhone: /iphone/i,\n android: /android/i\n },\n _osVersion: {\n iOS: /(iphone\\sos|cpu\\sos)\\s([\\d\\w\\_\\-]+)/i,\n android: /android\\s([\\d\\w\\.\\-]+)/i\n },\n _engine: {\n trident: /trident/i,\n gecko: /gecko/i,\n applewebkit: /applewebkit/i,\n presto: /presto/i\n },\n _init: function _init() {\n this.ua = navigator.userAgent.toLowerCase();\n\n this._getPlatform();\n\n this.browser = this._getBrowser();\n this._getBroserVersion();\n\n this.isAndroidTablet = this.isAndroid && new RegExp(\"tablet\", \"i\").test(this.ua);\n this._testMobile();\n this._getOSVersion();\n this._getEngine();\n },\n _toFixedVersion: function _toFixedVersion(ver, floatLength) {\n var ver = (\"\" + ver).replace(/_/g, \".\");\n var floatLength = floatLength || 1;\n ver = String(ver).split(\".\");\n ver = ver[0] + \".\" + (ver[1] || \"0\");\n ver = Number(ver).toFixed(floatLength);\n return ver;\n },\n _getBrowser: function _getBrowser() {\n var ua = this.ua;\n switch (true) {\n case this._browsers.ie.test(ua):\n this.ie = true;\n return \"IE\";\n case this._browsers.firefox.test(ua):\n this.firefox = true;\n return \"Firefox\";\n case this._browsers.opera.test(ua):\n this.opera = true;\n return \"Opera\";\n case this._browsers.uc.test(ua):\n this.uc = true;\n return \"UC\";\n case this._browsers.baidu.test(ua):\n this.baidu = true;\n return \"Baidu\";\n case this._browsers.weibo.test(ua):\n this.isWeibo = true;\n return \"Weibo\";\n //有些版本的微信中也包含 MQQBrowser\n case this._browsers.wechat.test(ua):\n this.isWeChat = true;\n return \"MicroMessenger\";\n case this._browsers.mqq.test(ua):\n this.mqq = true;\n return \"MQQ\";\n //chrome浏览器也有safari\n case this._browsers.chrome.test(ua):\n this.chrome = true;\n return \"Chrome\";\n case !this.isAndroid && this._browsers.safari.test(ua):\n this.safari = true;\n return \"Safari\";\n case this.isAndroid:\n this.androidBrowser = true;\n return \"Android\";\n default:\n return 'unknown';\n }\n },\n _getBroserVersion: function _getBroserVersion() {\n var ua = this.ua;\n switch (true) {\n case this.ie:\n this._versions.ie.test(ua);\n this.ie = RegExp.$2 ? this._toFixedVersion(RegExp.$2, 1) : this._toFixedVersion(RegExp.$1, 1);\n break;\n case this.firefox:\n this._versions.firefox.test(ua);\n this.firefox = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.opera:\n this._versions.opera.test(ua);\n this.opera = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.uc:\n this._versions.uc.test(ua);\n this.uc = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.baidu:\n this._versions.baidu.test(ua);\n this.baidu = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.mqq:\n this._versions.mqq.test(ua);\n this.mqq = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.chrome:\n this._versions.chrome.test(ua);\n this.chrome = RegExp.$2 ? this._toFixedVersion(RegExp.$2, 1) : 0;\n break;\n case this.safari:\n this._versions.safari.test(ua);\n this.safari = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.androidBrowser:\n this._versions.androidBrowser.test(ua);\n this.androidBrowser = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n }\n },\n _getOSVersion: function _getOSVersion() {\n var ua = this.ua;\n switch (true) {\n case this._osVersion.iOS.test(ua):\n this.osVersion = RegExp.$2.replace(/_/g, \".\");\n this.isiOS = true;\n break;\n case this._osVersion.android.test(ua):\n this.osVersion = RegExp.$1;\n break;\n }\n },\n _getPlatform: function _getPlatform() {\n var ua = this.ua;\n\n switch (true) {\n case this._platforms.windows.test(ua):\n this.isWindows = true;\n break;\n case this._platforms.windowsPhone.test(ua):\n this.isWindowsPhone = true;\n break;\n case this._platforms.mac.test(ua):\n this.isMac = true;\n break;\n case this._platforms.iPad.test(ua):\n this.isiPad = true;\n break;\n case this._platforms.iPhone.test(ua) || this._platforms.iPod.test(ua):\n this.isiPhone = true;\n break;\n case this._platforms.android.test(ua):\n this.isAndroid = true;\n break;\n case this._platforms.linux.test(ua):\n this.isLinux = true;\n break;\n }\n },\n _testMobile: function _testMobile() {\n var ua = this.ua;\n\n switch (true) {\n case this.isWindows:\n case this.isLinux:\n case this.isMac:\n this.isDesktop = true;\n break;\n\n case this.isiPad:\n case this.isAndroidTablet:\n this.isTablet = true;\n break;\n case this.isAndroid:\n case this.isiPhone:\n case this.isWindowsPhone:\n this.isMobile = true;\n break;\n }\n\n if (/mobile/i.test(ua) && !this.isTablet) {\n this.isMobile = true;\n this.isDesktop = false;\n this.isTablet = false;\n }\n },\n _getEngine: function _getEngine() {\n var ua = this.ua;\n switch (true) {\n case this._engine.trident.test(ua):\n this.engine = \"trident\";\n break;\n case this._engine.applewebkit.test(ua):\n this.engine = \"applewebkit\";\n break;\n case this._engine.presto.test(ua):\n this.engine = \"presto\";\n break;\n case this._engine.gecko.test(ua):\n this.engine = \"gecko\";\n break;\n }\n },\n /**\n * 是否包含指定关键字,可以用于判断特定浏览器或者App\n * @param {String} str 匹配的关键字\n * @returns {Boolean} true: 包含 | false: 未包含\n */\n contains: function contains(str) {\n var reg = new RegExp(str, 'i');\n return reg.test(this.ua);\n },\n /**\n * 获取浏览器的UserAgent\n * @returns {String} UserAgent字符串\n */\n getUserAgent: function getUserAgent() {\n return this.ua;\n }\n };\n UserAgent._init();\n ;regist(\"UserAgent\", UserAgent);\n})(typeof Zepto !== 'undefined' ? Zepto : jQuery, window, document);\n\n/***/ }),\n\n/***/ 18:\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ 25:\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(1);\n\n\n/***/ }),\n\n/***/ 8:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(14);\n__webpack_require__(13);\n$('.comment-imgs-box ul').on('click', 'li .close', function () {\n\t$(this).parent().remove();\n});\n\n/***/ })\n\n},[25]);\n\n\n// WEBPACK FOOTER //\n// js/comment.js?v=f4729b47","import '../css/comment.css';\nimport '../js/comment';\n\n\n\n// WEBPACK FOOTER //\n// ./mobile/src/router/comment.js",";(function($, window, document, undefined) {\n function regist(mName, module) {\n if (typeof window.brickjs === \"undefined\") {\n window.brickjs = {};\n }\n brickjs[mName] = module;\n }\n;\n/*\n * Binary Ajax 0.1.10\n * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/\n * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]\n */\n\nvar BinaryFile = function(strData, iDataOffset, iDataLength) {\n var data = strData;\n var dataOffset = iDataOffset || 0;\n var dataLength = 0;\n\n this.getRawData = function() {\n return data;\n }\n\n if (typeof strData == \"string\") {\n dataLength = iDataLength || data.length;\n\n this.getByteAt = function(iOffset) {\n return data.charCodeAt(iOffset + dataOffset) & 0xFF;\n }\n\n this.getBytesAt = function(iOffset, iLength) {\n var aBytes = [];\n\n for (var i = 0; i < iLength; i++) {\n aBytes[i] = data.charCodeAt((iOffset + i) + dataOffset) & 0xFF\n }\n ;\n\n return aBytes;\n }\n } else if (typeof strData == \"unknown\") {\n dataLength = iDataLength || IEBinary_getLength(data);\n\n this.getByteAt = function(iOffset) {\n return IEBinary_getByteAt(data, iOffset + dataOffset);\n }\n\n this.getBytesAt = function(iOffset, iLength) {\n return new VBArray(IEBinary_getBytesAt(data, iOffset + dataOffset, iLength)).toArray();\n }\n }\n\n this.getLength = function() {\n return dataLength;\n }\n\n this.getSByteAt = function(iOffset) {\n var iByte = this.getByteAt(iOffset);\n if (iByte > 127)\n return iByte - 256;\n else\n return iByte;\n }\n\n this.getShortAt = function(iOffset, bBigEndian) {\n var iShort = bBigEndian ?\n (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1)\n : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset)\n if (iShort < 0)\n iShort += 65536;\n return iShort;\n }\n this.getSShortAt = function(iOffset, bBigEndian) {\n var iUShort = this.getShortAt(iOffset, bBigEndian);\n if (iUShort > 32767)\n return iUShort - 65536;\n else\n return iUShort;\n }\n this.getLongAt = function(iOffset, bBigEndian) {\n var iByte1 = this.getByteAt(iOffset),\n iByte2 = this.getByteAt(iOffset + 1),\n iByte3 = this.getByteAt(iOffset + 2),\n iByte4 = this.getByteAt(iOffset + 3);\n\n var iLong = bBigEndian ?\n (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4\n : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;\n if (iLong < 0)\n iLong += 4294967296;\n return iLong;\n }\n this.getSLongAt = function(iOffset, bBigEndian) {\n var iULong = this.getLongAt(iOffset, bBigEndian);\n if (iULong > 2147483647)\n return iULong - 4294967296;\n else\n return iULong;\n }\n\n this.getStringAt = function(iOffset, iLength) {\n var aStr = [];\n\n var aBytes = this.getBytesAt(iOffset, iLength);\n for (var j = 0; j < iLength; j++) {\n aStr[j] = String.fromCharCode(aBytes[j]);\n }\n return aStr.join(\"\");\n }\n\n this.getCharAt = function(iOffset) {\n return String.fromCharCode(this.getByteAt(iOffset));\n }\n this.toBase64 = function() {\n return window.btoa(data);\n }\n this.fromBase64 = function(strBase64) {\n data = window.atob(strBase64);\n }\n}\n\n\nvar BinaryAjax = (function() {\n\n function createRequest() {\n var oHTTP = null;\n if (window.ActiveXObject) {\n oHTTP = new ActiveXObject(\"Microsoft.XMLHTTP\");\n } else if (window.XMLHttpRequest) {\n oHTTP = new XMLHttpRequest();\n }\n return oHTTP;\n }\n\n function getHead(strURL, fncCallback, fncError) {\n var oHTTP = createRequest();\n if (oHTTP) {\n if (fncCallback) {\n if (typeof(oHTTP.onload) != \"undefined\") {\n oHTTP.onload = function() {\n if (oHTTP.status == \"200\") {\n fncCallback(this);\n } else {\n if (fncError)\n fncError();\n }\n oHTTP = null;\n };\n } else {\n oHTTP.onreadystatechange = function() {\n if (oHTTP.readyState == 4) {\n if (oHTTP.status == \"200\") {\n fncCallback(this);\n } else {\n if (fncError)\n fncError();\n }\n oHTTP = null;\n }\n };\n }\n }\n oHTTP.open(\"HEAD\", strURL, true);\n oHTTP.send(null);\n } else {\n if (fncError)\n fncError();\n }\n }\n\n function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) {\n var oHTTP = createRequest();\n if (oHTTP) {\n\n var iDataOffset = 0;\n if (aRange && !bAcceptRanges) {\n iDataOffset = aRange[0];\n }\n var iDataLen = 0;\n if (aRange) {\n iDataLen = aRange[1] - aRange[0] + 1;\n }\n\n if (fncCallback) {\n if (typeof(oHTTP.onload) != \"undefined\") {\n oHTTP.onload = function() {\n if (oHTTP.status == \"200\" || oHTTP.status == \"206\" || oHTTP.status == \"0\") {\n oHTTP.binaryResponse = new BinaryFile(oHTTP.responseText, iDataOffset, iDataLen);\n oHTTP.fileSize = iFileSize || oHTTP.getResponseHeader(\"Content-Length\");\n fncCallback(oHTTP);\n } else {\n if (fncError)\n fncError();\n }\n oHTTP = null;\n };\n } else {\n oHTTP.onreadystatechange = function() {\n if (oHTTP.readyState == 4) {\n if (oHTTP.status == \"200\" || oHTTP.status == \"206\" || oHTTP.status == \"0\") {\n // IE6 craps if we try to extend the XHR object\n var oRes = {\n status: oHTTP.status,\n // IE needs responseBody, Chrome/Safari needs responseText\n binaryResponse: new BinaryFile(\n typeof oHTTP.responseBody == \"unknown\" ? oHTTP.responseBody : oHTTP.responseText, iDataOffset, iDataLen\n ),\n fileSize: iFileSize || oHTTP.getResponseHeader(\"Content-Length\")\n };\n fncCallback(oRes);\n } else {\n if (fncError)\n fncError();\n }\n oHTTP = null;\n }\n };\n }\n }\n oHTTP.open(\"GET\", strURL, true);\n\n if (oHTTP.overrideMimeType)\n oHTTP.overrideMimeType('text/plain; charset=x-user-defined');\n\n if (aRange && bAcceptRanges) {\n oHTTP.setRequestHeader(\"Range\", \"bytes=\" + aRange[0] + \"-\" + aRange[1]);\n }\n\n oHTTP.setRequestHeader(\"If-Modified-Since\", \"Sat, 1 Jan 1970 00:00:00 GMT\");\n\n oHTTP.send(null);\n } else {\n if (fncError)\n fncError();\n }\n }\n\n return function(strURL, fncCallback, fncError, aRange) {\n\n if (aRange) {\n getHead(\n strURL,\n function(oHTTP) {\n var iLength = parseInt(oHTTP.getResponseHeader(\"Content-Length\"), 10);\n var strAcceptRanges = oHTTP.getResponseHeader(\"Accept-Ranges\");\n\n var iStart, iEnd;\n iStart = aRange[0];\n if (aRange[0] < 0)\n iStart += iLength;\n iEnd = iStart + aRange[1] - 1;\n\n sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == \"bytes\"), iLength);\n }\n );\n\n } else {\n sendRequest(strURL, fncCallback, fncError);\n }\n }\n\n}());;/*\n * \n * canvasResize\n * \n * Version: 1.2.0 \n * Date (d/m/y): 02/10/12\n * Update (d/m/y): 14/05/13\n * Original author: @gokercebeci \n * Licensed under the MIT license\n * - This plugin working with binaryajax.js and exif.js \n * (It's under the MPL License http://www.nihilogic.dk/licenses/mpl-license.txt)\n * Demo: http://canvasResize.gokercebeci.com/\n * \n * - I fixed iOS6 Safari's image file rendering issue for large size image (over mega-pixel)\n * using few functions from https://github.com/stomita/ios-imagefile-megapixel\n * (detectSubsampling, )\n * And fixed orientation issue by using https://github.com/jseidelin/exif-js\n * Thanks, Shinichi Tomita and Jacob Seidelin\n */\n\n(function($) {\n var pluginName = 'canvasResize',\n methods = {\n newsize: function(w, h, W, H, C) {\n var c = C ? 'h' : '';\n if ((W && w > W) || (H && h > H)) {\n var r = w / h;\n if ((r >= 1 || H === 0) && W && !C) {\n w = W;\n h = (W / r) >> 0;\n } else if (C && r <= (W / H)) {\n w = W;\n h = (W / r) >> 0;\n c = 'w';\n } else {\n w = (H * r) >> 0;\n h = H;\n }\n }\n return {\n 'width': w,\n 'height': h,\n 'cropped': c\n };\n },\n dataURLtoBlob: function(data) {\n var mimeString = data.split(',')[0].split(':')[1].split(';')[0];\n var byteString = atob(data.split(',')[1]);\n var ab = new ArrayBuffer(byteString.length);\n var ia = new Uint8Array(ab);\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n var bb = (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder);\n if (bb) {\n // console.log('BlobBuilder'); \n bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)();\n bb.append(ab);\n return bb.getBlob(mimeString);\n } else {\n // console.log('Blob'); \n bb = new Blob([ab], {\n 'type': (mimeString)\n });\n return bb;\n }\n },\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n detectSubsampling: function(img) {\n var iw = img.width, ih = img.height;\n if (iw * ih > 1048576) { // subsampling may happen over megapixel image\n var canvas = document.createElement('canvas');\n canvas.width = canvas.height = 1;\n var ctx = canvas.getContext('2d');\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n },\n /**\n * Update the orientation according to the specified rotation angle\n */\n rotate: function(orientation, angle) {\n var o = {\n // nothing\n 1: {90: 6, 180: 3, 270: 8},\n // horizontal flip\n 2: {90: 7, 180: 4, 270: 5},\n // 180 rotate left\n 3: {90: 8, 180: 1, 270: 6},\n // vertical flip\n 4: {90: 5, 180: 2, 270: 7},\n // vertical flip + 90 rotate right\n 5: {90: 2, 180: 7, 270: 4},\n // 90 rotate right\n 6: {90: 3, 180: 8, 270: 1},\n // horizontal flip + 90 rotate right\n 7: {90: 4, 180: 5, 270: 2},\n // 90 rotate left\n 8: {90: 1, 180: 6, 270: 3}\n };\n return o[orientation][angle] ? o[orientation][angle] : orientation;\n },\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n transformCoordinate: function(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext('2d');\n switch (orientation) {\n case 1:\n // nothing\n break;\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n },\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n detectVerticalSquash: function(img, iw, ih) {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = ih;\n var ctx = canvas.getContext('2d');\n ctx.drawImage(img, 0, 0);\n var data = ctx.getImageData(0, 0, 1, ih).data;\n // search image edge pixel position in case it is squashed vertically.\n var sy = 0;\n var ey = ih;\n var py = ih;\n while (py > sy) {\n var alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n var ratio = py / ih;\n return ratio === 0 ? 1 : ratio;\n },\n callback: function(d) {\n return d;\n },\n extend: function() {\n var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;\n if (target.constructor === Boolean) {\n deep = target;\n target = arguments[1] || {};\n }\n if (al === 1) {\n target = this;\n a = 0;\n }\n var prop;\n for (; a < al; a++)\n if ((prop = arguments[a]) !== null)\n for (var i in prop) {\n if (target === prop[i])\n continue;\n if (deep && typeof prop[i] === 'object' && target[i])\n methods.extend(target[i], prop[i]);\n else if (prop[i] !== undefined)\n target[i] = prop[i];\n }\n return target;\n }\n },\n defaults = {\n width: 300,\n height: 0,\n crop: false,\n quality: 80,\n rotate: 0,\n 'callback': methods.callback\n };\n function Plugin(file, options) {\n this.file = file;\n // EXTEND\n this.options = methods.extend({}, defaults, options);\n this._defaults = defaults;\n this._name = pluginName;\n this.init();\n }\n Plugin.prototype = {\n init: function() {\n //this.options.init(this);\n var $this = this;\n var file = this.file;\n\n var reader = new FileReader();\n reader.onloadend = function(e) {\n\n var dataURL = e.target.result;\n var byteString = atob(dataURL.split(',')[1]);\n var binary = new BinaryFile(byteString, 0, byteString.length);\n var exif = EXIF.readFromBinaryFile(binary);\n\n var img = new Image();\n img.onload = function(e) {\n\n var orientation = exif['Orientation'] || 1;\n orientation = methods.rotate(orientation, $this.options.rotate);\n\n // CW or CCW ? replace width and height\n var size = (orientation >= 5 && orientation <= 8)\n ? methods.newsize(img.height, img.width, $this.options.width, $this.options.height, $this.options.crop)\n : methods.newsize(img.width, img.height, $this.options.width, $this.options.height, $this.options.crop);\n\n var iw = img.width, ih = img.height;\n var width = size.width, height = size.height;\n\n var canvas = document.createElement(\"canvas\");\n var ctx = canvas.getContext(\"2d\");\n ctx.save();\n methods.transformCoordinate(canvas, width, height, orientation);\n\n // over image size\n if (methods.detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n var d = 1024; // size of tiling canvas\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = tmpCanvas.height = d;\n var tmpCtx = tmpCanvas.getContext('2d');\n var vertSquashRatio = methods.detectVerticalSquash(img, iw, ih);\n var sy = 0;\n while (sy < ih) {\n var sh = sy + d > ih ? ih - sy : d;\n var sx = 0;\n while (sx < iw) {\n var sw = sx + d > iw ? iw - sx : d;\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n var dx = Math.floor(sx * width / iw);\n var dw = Math.ceil(sw * width / iw);\n var dy = Math.floor(sy * height / ih / vertSquashRatio);\n var dh = Math.ceil(sh * height / ih / vertSquashRatio);\n ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh);\n sx += d;\n }\n sy += d;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n\n // if rotated width and height data replacing issue \n var newcanvas = document.createElement('canvas');\n newcanvas.width = size.cropped === 'h' ? height : width;\n newcanvas.height = size.cropped === 'w' ? width : height;\n var x = size.cropped === 'h' ? (height - width) * .5 : 0;\n var y = size.cropped === 'w' ? (width - height) * .5 : 0;\n var newctx = newcanvas.getContext('2d');\n newctx.drawImage(canvas, x, y, width, height);\n\n // console.log(file, file.type);\n if (file.type === \"image/png\") {\n var data = newcanvas.toDataURL(file.type);\n } else {\n var data = newcanvas.toDataURL(\"image/jpeg\", ($this.options.quality * .01));\n }\n\n // CALLBACK\n $this.options.callback(data, newcanvas.width, newcanvas.height);\n\n // });\n };\n img.src = dataURL;\n // =====================================================\n\n };\n reader.readAsDataURL(file);\n //reader.readAsBinaryString(file);\n\n }\n };\n $[pluginName] = function(file, options) {\n if (typeof file === 'string')\n return methods[file](options);\n else\n new Plugin(file, options);\n };\n\n})(window);;/*\n * Javascript EXIF Reader 0.1.6\n * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/\n * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]\n */\n\n\nvar EXIF = (function() {\n\n var debug = false;\n\n var ExifTags = {\n\n // version tags\n 0x9000: \"ExifVersion\", // EXIF version\n 0xA000: \"FlashpixVersion\", // Flashpix format version\n\n // colorspace tags\n 0xA001: \"ColorSpace\", // Color space information tag\n\n // image configuration\n 0xA002: \"PixelXDimension\", // Valid width of meaningful image\n 0xA003: \"PixelYDimension\", // Valid height of meaningful image\n 0x9101: \"ComponentsConfiguration\", // Information about channels\n 0x9102: \"CompressedBitsPerPixel\", // Compressed bits per pixel\n\n // user information\n 0x927C: \"MakerNote\", // Any desired information written by the manufacturer\n 0x9286: \"UserComment\", // Comments by user\n\n // related file\n 0xA004: \"RelatedSoundFile\", // Name of related sound file\n\n // date and time\n 0x9003: \"DateTimeOriginal\", // Date and time when the original image was generated\n 0x9004: \"DateTimeDigitized\", // Date and time when the image was stored digitally\n 0x9290: \"SubsecTime\", // Fractions of seconds for DateTime\n 0x9291: \"SubsecTimeOriginal\", // Fractions of seconds for DateTimeOriginal\n 0x9292: \"SubsecTimeDigitized\", // Fractions of seconds for DateTimeDigitized\n\n // picture-taking conditions\n 0x829A: \"ExposureTime\", // Exposure time (in seconds)\n 0x829D: \"FNumber\", // F number\n 0x8822: \"ExposureProgram\", // Exposure program\n 0x8824: \"SpectralSensitivity\", // Spectral sensitivity\n 0x8827: \"ISOSpeedRatings\", // ISO speed rating\n 0x8828: \"OECF\", // Optoelectric conversion factor\n 0x9201: \"ShutterSpeedValue\", // Shutter speed\n 0x9202: \"ApertureValue\", // Lens aperture\n 0x9203: \"BrightnessValue\", // Value of brightness\n 0x9204: \"ExposureBias\", // Exposure bias\n 0x9205: \"MaxApertureValue\", // Smallest F number of lens\n 0x9206: \"SubjectDistance\", // Distance to subject in meters\n 0x9207: \"MeteringMode\", // Metering mode\n 0x9208: \"LightSource\", // Kind of light source\n 0x9209: \"Flash\", // Flash status\n 0x9214: \"SubjectArea\", // Location and area of main subject\n 0x920A: \"FocalLength\", // Focal length of the lens in mm\n 0xA20B: \"FlashEnergy\", // Strobe energy in BCPS\n 0xA20C: \"SpatialFrequencyResponse\", // \n 0xA20E: \"FocalPlaneXResolution\", // Number of pixels in width direction per FocalPlaneResolutionUnit\n 0xA20F: \"FocalPlaneYResolution\", // Number of pixels in height direction per FocalPlaneResolutionUnit\n 0xA210: \"FocalPlaneResolutionUnit\", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution\n 0xA214: \"SubjectLocation\", // Location of subject in image\n 0xA215: \"ExposureIndex\", // Exposure index selected on camera\n 0xA217: \"SensingMethod\", // Image sensor type\n 0xA300: \"FileSource\", // Image source (3 == DSC)\n 0xA301: \"SceneType\", // Scene type (1 == directly photographed)\n 0xA302: \"CFAPattern\", // Color filter array geometric pattern\n 0xA401: \"CustomRendered\", // Special processing\n 0xA402: \"ExposureMode\", // Exposure mode\n 0xA403: \"WhiteBalance\", // 1 = auto white balance, 2 = manual\n 0xA404: \"DigitalZoomRation\", // Digital zoom ratio\n 0xA405: \"FocalLengthIn35mmFilm\", // Equivalent foacl length assuming 35mm film camera (in mm)\n 0xA406: \"SceneCaptureType\", // Type of scene\n 0xA407: \"GainControl\", // Degree of overall image gain adjustment\n 0xA408: \"Contrast\", // Direction of contrast processing applied by camera\n 0xA409: \"Saturation\", // Direction of saturation processing applied by camera\n 0xA40A: \"Sharpness\", // Direction of sharpness processing applied by camera\n 0xA40B: \"DeviceSettingDescription\", // \n 0xA40C: \"SubjectDistanceRange\", // Distance to subject\n\n // other tags\n 0xA005: \"InteroperabilityIFDPointer\",\n 0xA420: \"ImageUniqueID\"\t\t// Identifier assigned uniquely to each image\n };\n\n var TiffTags = {\n 0x0100: \"ImageWidth\",\n 0x0101: \"ImageHeight\",\n 0x8769: \"ExifIFDPointer\",\n 0x8825: \"GPSInfoIFDPointer\",\n 0xA005: \"InteroperabilityIFDPointer\",\n 0x0102: \"BitsPerSample\",\n 0x0103: \"Compression\",\n 0x0106: \"PhotometricInterpretation\",\n 0x0112: \"Orientation\",\n 0x0115: \"SamplesPerPixel\",\n 0x011C: \"PlanarConfiguration\",\n 0x0212: \"YCbCrSubSampling\",\n 0x0213: \"YCbCrPositioning\",\n 0x011A: \"XResolution\",\n 0x011B: \"YResolution\",\n 0x0128: \"ResolutionUnit\",\n 0x0111: \"StripOffsets\",\n 0x0116: \"RowsPerStrip\",\n 0x0117: \"StripByteCounts\",\n 0x0201: \"JPEGInterchangeFormat\",\n 0x0202: \"JPEGInterchangeFormatLength\",\n 0x012D: \"TransferFunction\",\n 0x013E: \"WhitePoint\",\n 0x013F: \"PrimaryChromaticities\",\n 0x0211: \"YCbCrCoefficients\",\n 0x0214: \"ReferenceBlackWhite\",\n 0x0132: \"DateTime\",\n 0x010E: \"ImageDescription\",\n 0x010F: \"Make\",\n 0x0110: \"Model\",\n 0x0131: \"Software\",\n 0x013B: \"Artist\",\n 0x8298: \"Copyright\"\n };\n\n var GPSTags = {\n 0x0000: \"GPSVersionID\",\n 0x0001: \"GPSLatitudeRef\",\n 0x0002: \"GPSLatitude\",\n 0x0003: \"GPSLongitudeRef\",\n 0x0004: \"GPSLongitude\",\n 0x0005: \"GPSAltitudeRef\",\n 0x0006: \"GPSAltitude\",\n 0x0007: \"GPSTimeStamp\",\n 0x0008: \"GPSSatellites\",\n 0x0009: \"GPSStatus\",\n 0x000A: \"GPSMeasureMode\",\n 0x000B: \"GPSDOP\",\n 0x000C: \"GPSSpeedRef\",\n 0x000D: \"GPSSpeed\",\n 0x000E: \"GPSTrackRef\",\n 0x000F: \"GPSTrack\",\n 0x0010: \"GPSImgDirectionRef\",\n 0x0011: \"GPSImgDirection\",\n 0x0012: \"GPSMapDatum\",\n 0x0013: \"GPSDestLatitudeRef\",\n 0x0014: \"GPSDestLatitude\",\n 0x0015: \"GPSDestLongitudeRef\",\n 0x0016: \"GPSDestLongitude\",\n 0x0017: \"GPSDestBearingRef\",\n 0x0018: \"GPSDestBearing\",\n 0x0019: \"GPSDestDistanceRef\",\n 0x001A: \"GPSDestDistance\",\n 0x001B: \"GPSProcessingMethod\",\n 0x001C: \"GPSAreaInformation\",\n 0x001D: \"GPSDateStamp\",\n 0x001E: \"GPSDifferential\"\n };\n\n var StringValues = {\n ExposureProgram: {\n 0: \"Not defined\",\n 1: \"Manual\",\n 2: \"Normal program\",\n 3: \"Aperture priority\",\n 4: \"Shutter priority\",\n 5: \"Creative program\",\n 6: \"Action program\",\n 7: \"Portrait mode\",\n 8: \"Landscape mode\"\n },\n MeteringMode: {\n 0: \"Unknown\",\n 1: \"Average\",\n 2: \"CenterWeightedAverage\",\n 3: \"Spot\",\n 4: \"MultiSpot\",\n 5: \"Pattern\",\n 6: \"Partial\",\n 255: \"Other\"\n },\n LightSource: {\n 0: \"Unknown\",\n 1: \"Daylight\",\n 2: \"Fluorescent\",\n 3: \"Tungsten (incandescent light)\",\n 4: \"Flash\",\n 9: \"Fine weather\",\n 10: \"Cloudy weather\",\n 11: \"Shade\",\n 12: \"Daylight fluorescent (D 5700 - 7100K)\",\n 13: \"Day white fluorescent (N 4600 - 5400K)\",\n 14: \"Cool white fluorescent (W 3900 - 4500K)\",\n 15: \"White fluorescent (WW 3200 - 3700K)\",\n 17: \"Standard light A\",\n 18: \"Standard light B\",\n 19: \"Standard light C\",\n 20: \"D55\",\n 21: \"D65\",\n 22: \"D75\",\n 23: \"D50\",\n 24: \"ISO studio tungsten\",\n 255: \"Other\"\n },\n Flash: {\n 0x0000: \"Flash did not fire\",\n 0x0001: \"Flash fired\",\n 0x0005: \"Strobe return light not detected\",\n 0x0007: \"Strobe return light detected\",\n 0x0009: \"Flash fired, compulsory flash mode\",\n 0x000D: \"Flash fired, compulsory flash mode, return light not detected\",\n 0x000F: \"Flash fired, compulsory flash mode, return light detected\",\n 0x0010: \"Flash did not fire, compulsory flash mode\",\n 0x0018: \"Flash did not fire, auto mode\",\n 0x0019: \"Flash fired, auto mode\",\n 0x001D: \"Flash fired, auto mode, return light not detected\",\n 0x001F: \"Flash fired, auto mode, return light detected\",\n 0x0020: \"No flash function\",\n 0x0041: \"Flash fired, red-eye reduction mode\",\n 0x0045: \"Flash fired, red-eye reduction mode, return light not detected\",\n 0x0047: \"Flash fired, red-eye reduction mode, return light detected\",\n 0x0049: \"Flash fired, compulsory flash mode, red-eye reduction mode\",\n 0x004D: \"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected\",\n 0x004F: \"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected\",\n 0x0059: \"Flash fired, auto mode, red-eye reduction mode\",\n 0x005D: \"Flash fired, auto mode, return light not detected, red-eye reduction mode\",\n 0x005F: \"Flash fired, auto mode, return light detected, red-eye reduction mode\"\n },\n SensingMethod: {\n 1: \"Not defined\",\n 2: \"One-chip color area sensor\",\n 3: \"Two-chip color area sensor\",\n 4: \"Three-chip color area sensor\",\n 5: \"Color sequential area sensor\",\n 7: \"Trilinear sensor\",\n 8: \"Color sequential linear sensor\"\n },\n SceneCaptureType: {\n 0: \"Standard\",\n 1: \"Landscape\",\n 2: \"Portrait\",\n 3: \"Night scene\"\n },\n SceneType: {\n 1: \"Directly photographed\"\n },\n CustomRendered: {\n 0: \"Normal process\",\n 1: \"Custom process\"\n },\n WhiteBalance: {\n 0: \"Auto white balance\",\n 1: \"Manual white balance\"\n },\n GainControl: {\n 0: \"None\",\n 1: \"Low gain up\",\n 2: \"High gain up\",\n 3: \"Low gain down\",\n 4: \"High gain down\"\n },\n Contrast: {\n 0: \"Normal\",\n 1: \"Soft\",\n 2: \"Hard\"\n },\n Saturation: {\n 0: \"Normal\",\n 1: \"Low saturation\",\n 2: \"High saturation\"\n },\n Sharpness: {\n 0: \"Normal\",\n 1: \"Soft\",\n 2: \"Hard\"\n },\n SubjectDistanceRange: {\n 0: \"Unknown\",\n 1: \"Macro\",\n 2: \"Close view\",\n 3: \"Distant view\"\n },\n FileSource: {\n 3: \"DSC\"\n },\n Components: {\n 0: \"\",\n 1: \"Y\",\n 2: \"Cb\",\n 3: \"Cr\",\n 4: \"R\",\n 5: \"G\",\n 6: \"B\"\n }\n };\n\n function addEvent(element, event, handler) {\n if (element.addEventListener) {\n element.addEventListener(event, handler, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + event, handler);\n }\n }\n\n function imageHasData(img) {\n return !!(img.exifdata);\n }\n\n function getImageData(img, callback) {\n BinaryAjax(img.src, function(http) {\n var data = findEXIFinJPEG(http.binaryResponse);\n img.exifdata = data || {};\n if (callback) {\n callback.call(img)\n }\n });\n }\n\n function findEXIFinJPEG(file) {\n if (file.getByteAt(0) != 0xFF || file.getByteAt(1) != 0xD8) {\n return false; // not a valid jpeg\n }\n\n var offset = 2,\n length = file.getLength(),\n marker;\n\n while (offset < length) {\n if (file.getByteAt(offset) != 0xFF) {\n if (debug)\n console.log(\"Not a valid marker at offset \" + offset + \", found: \" + file.getByteAt(offset));\n return false; // not a valid marker, something is wrong\n }\n\n marker = file.getByteAt(offset + 1);\n\n // we could implement handling for other markers here, \n // but we're only looking for 0xFFE1 for EXIF data\n\n if (marker == 22400) {\n if (debug)\n console.log(\"Found 0xFFE1 marker\");\n\n return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2);\n\n // offset += 2 + file.getShortAt(offset+2, true);\n\n } else if (marker == 225) {\n // 0xE1 = Application-specific 1 (for EXIF)\n if (debug)\n console.log(\"Found 0xFFE1 marker\");\n\n return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2);\n\n } else {\n offset += 2 + file.getShortAt(offset + 2, true);\n }\n\n }\n\n }\n\n\n function readTags(file, tiffStart, dirStart, strings, bigEnd) {\n var entries = file.getShortAt(dirStart, bigEnd),\n tags = {},\n entryOffset, tag,\n i;\n\n for (i = 0; i < entries; i++) {\n entryOffset = dirStart + i * 12 + 2;\n tag = strings[file.getShortAt(entryOffset, bigEnd)];\n if (!tag && debug)\n console.log(\"Unknown tag: \" + file.getShortAt(entryOffset, bigEnd));\n tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);\n }\n return tags;\n }\n\n\n function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) {\n var type = file.getShortAt(entryOffset + 2, bigEnd),\n numValues = file.getLongAt(entryOffset + 4, bigEnd),\n valueOffset = file.getLongAt(entryOffset + 8, bigEnd) + tiffStart,\n offset,\n vals, val, n,\n numerator, denominator;\n\n switch (type) {\n case 1: // byte, 8-bit unsigned int\n case 7: // undefined, 8-bit byte, value depending on field\n if (numValues == 1) {\n return file.getByteAt(entryOffset + 8, bigEnd);\n } else {\n offset = numValues > 4 ? valueOffset : (entryOffset + 8);\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getByteAt(offset + n);\n }\n return vals;\n }\n\n case 2: // ascii, 8-bit byte\n offset = numValues > 4 ? valueOffset : (entryOffset + 8);\n return file.getStringAt(offset, numValues - 1);\n\n case 3: // short, 16 bit int\n if (numValues == 1) {\n return file.getShortAt(entryOffset + 8, bigEnd);\n } else {\n offset = numValues > 2 ? valueOffset : (entryOffset + 8);\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getShortAt(offset + 2 * n, bigEnd);\n }\n return vals;\n }\n\n case 4: // long, 32 bit int\n if (numValues == 1) {\n return file.getLongAt(entryOffset + 8, bigEnd);\n } else {\n vals = [];\n for (var n = 0; n < numValues; n++) {\n vals[n] = file.getLongAt(valueOffset + 4 * n, bigEnd);\n }\n return vals;\n }\n\n case 5:\t// rational = two long values, first is numerator, second is denominator\n if (numValues == 1) {\n numerator = file.getLongAt(valueOffset, bigEnd);\n denominator = file.getLongAt(valueOffset + 4, bigEnd);\n val = new Number(numerator / denominator);\n val.numerator = numerator;\n val.denominator = denominator;\n return val;\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n numerator = file.getLongAt(valueOffset + 8 * n, bigEnd);\n denominator = file.getLongAt(valueOffset + 4 + 8 * n, bigEnd);\n vals[n] = new Number(numerator / denominator);\n vals[n].numerator = numerator;\n vals[n].denominator = denominator;\n }\n return vals;\n }\n\n case 9: // slong, 32 bit signed int\n if (numValues == 1) {\n return file.getSLongAt(entryOffset + 8, bigEnd);\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getSLongAt(valueOffset + 4 * n, bigEnd);\n }\n return vals;\n }\n\n case 10: // signed rational, two slongs, first is numerator, second is denominator\n if (numValues == 1) {\n return file.getSLongAt(valueOffset, bigEnd) / file.getSLongAt(valueOffset + 4, bigEnd);\n } else {\n vals = [];\n for (n = 0; n < numValues; n++) {\n vals[n] = file.getSLongAt(valueOffset + 8 * n, bigEnd) / file.getSLongAt(valueOffset + 4 + 8 * n, bigEnd);\n }\n return vals;\n }\n }\n }\n\n\n function readEXIFData(file, start) {\n if (file.getStringAt(start, 4) != \"Exif\") {\n if (debug)\n console.log(\"Not valid EXIF data! \" + file.getStringAt(start, 4));\n return false;\n }\n\n var bigEnd,\n tags, tag,\n exifData, gpsData,\n tiffOffset = start + 6;\n\n // test for TIFF validity and endianness\n if (file.getShortAt(tiffOffset) == 0x4949) {\n bigEnd = false;\n } else if (file.getShortAt(tiffOffset) == 0x4D4D) {\n bigEnd = true;\n } else {\n if (debug)\n console.log(\"Not valid TIFF data! (no 0x4949 or 0x4D4D)\");\n return false;\n }\n\n if (file.getShortAt(tiffOffset + 2, bigEnd) != 0x002A) {\n if (debug)\n console.log(\"Not valid TIFF data! (no 0x002A)\");\n return false;\n }\n\n if (file.getLongAt(tiffOffset + 4, bigEnd) != 0x00000008) {\n if (debug)\n console.log(\"Not valid TIFF data! (First offset not 8)\", file.getShortAt(tiffOffset + 4, bigEnd));\n return false;\n }\n\n tags = readTags(file, tiffOffset, tiffOffset + 8, TiffTags, bigEnd);\n\n if (tags.ExifIFDPointer) {\n exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);\n for (tag in exifData) {\n switch (tag) {\n case \"LightSource\" :\n case \"Flash\" :\n case \"MeteringMode\" :\n case \"ExposureProgram\" :\n case \"SensingMethod\" :\n case \"SceneCaptureType\" :\n case \"SceneType\" :\n case \"CustomRendered\" :\n case \"WhiteBalance\" :\n case \"GainControl\" :\n case \"Contrast\" :\n case \"Saturation\" :\n case \"Sharpness\" :\n case \"SubjectDistanceRange\" :\n case \"FileSource\" :\n exifData[tag] = StringValues[tag][exifData[tag]];\n break;\n\n case \"ExifVersion\" :\n case \"FlashpixVersion\" :\n exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);\n break;\n\n case \"ComponentsConfiguration\" :\n exifData[tag] =\n StringValues.Components[exifData[tag][0]]\n + StringValues.Components[exifData[tag][1]]\n + StringValues.Components[exifData[tag][2]]\n + StringValues.Components[exifData[tag][3]];\n break;\n }\n tags[tag] = exifData[tag];\n }\n }\n\n if (tags.GPSInfoIFDPointer) {\n gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);\n for (tag in gpsData) {\n switch (tag) {\n case \"GPSVersionID\" :\n gpsData[tag] = gpsData[tag][0]\n + \".\" + gpsData[tag][1]\n + \".\" + gpsData[tag][2]\n + \".\" + gpsData[tag][3];\n break;\n }\n tags[tag] = gpsData[tag];\n }\n }\n\n return tags;\n }\n\n\n function getData(img, callback) {\n if (!img.complete)\n return false;\n if (!imageHasData(img)) {\n getImageData(img, callback);\n } else {\n if (callback) {\n callback.call(img);\n }\n }\n return true;\n }\n\n function getTag(img, tag) {\n if (!imageHasData(img))\n return;\n return img.exifdata[tag];\n }\n\n function getAllTags(img) {\n if (!imageHasData(img))\n return {};\n var a,\n data = img.exifdata,\n tags = {};\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n tags[a] = data[a];\n }\n }\n return tags;\n }\n\n function pretty(img) {\n if (!imageHasData(img))\n return \"\";\n var a,\n data = img.exifdata,\n strPretty = \"\";\n for (a in data) {\n if (data.hasOwnProperty(a)) {\n if (typeof data[a] == \"object\") {\n if (data[a] instanceof Number) {\n strPretty += a + \" : \" + data[a] + \" [\" + data[a].numerator + \"/\" + data[a].denominator + \"]\\r\\n\";\n } else {\n strPretty += a + \" : [\" + data[a].length + \" values]\\r\\n\";\n }\n } else {\n strPretty += a + \" : \" + data[a] + \"\\r\\n\";\n }\n }\n }\n return strPretty;\n }\n\n function readFromBinaryFile(file) {\n return findEXIFinJPEG(file);\n }\n\n\n return {\n readFromBinaryFile: readFromBinaryFile,\n pretty: pretty,\n getTag: getTag,\n getAllTags: getAllTags,\n getData: getData,\n Tags: ExifTags,\n TiffTags: TiffTags,\n GPSTags: GPSTags,\n StringValues: StringValues\n };\n\n})();;/** \n * @file html5图片上传\n * @author yuanmin.pu@condenast.com.cn\n * @version 0.1.0\n * @requires http://js.selfimg.com.cn/jquery/jquery-1.7.1.min.js[http://js.selfimg.com.cn/gallery/zepto/1.1.4/zepto.min.js]\n * @requires http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n * @example <a href=\"../upload/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/upload/0.1.0/upload.min.js\n */\n\n/** \n * @class\n * @author yuanmin.pu@condenast.com.cn\n * @description html5图片上传\n * @version 0.1.0\n * @requires http://js.selfimg.com.cn/jquery/jquery-1.7.1.min.js[http://js.selfimg.com.cn/gallery/zepto/1.1.4/zepto.min.js]\n * @requires http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n * @example <a href=\"../upload/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/upload/0.1.0/upload.min.js\n * @param {Object} selector 绑定的对象\n * @param {Object} cfgs 配置项\n * @param {String} [cfgs.url=http://imgsys.self.com.cn/interface] 接口地址\n * @param {Object} cfgs.params 地址参数\n * @param {Boolean} [cfgs.useCanvas=true] 是否使用canvas压缩,默认使用(ios下始终为true)\n * @param {(String|Number)} [cfgs.size=0] 大小限制,使用canvas则为压缩后的大小,默认不限制,单位M\n * @param {Number} [cfgs.limit=0] 数量限制,默认不限制\n * @param {Number} [cfgs.width=640] 宽度限制\n * @param {Number} [cfgs.quality=100] 图片质量0-100\n * @param {String} [cfgs.error] 文件检查错误输出\n * @param {Object} [cfgs.errorMsg] 文件检查错误信息\n * @param {Boolean} [cfgs.autoUpload=false] 是否自动上传\n * @param {Boolean} [cfgs.uploadBtn] 开始上传按钮,手动上传时配置\n * @param {(Object|String)} [cfgs.tpl=null] 上传列表模板:null不使用,空字符串使用默认,非空字符串使用自定义\n * @param {Object} [cfgs.tplContainer] 上传列表容器\n * @param {Boolean} [cfgs.autoHide=true] 多文件上传时自动隐藏上传成功的列表\n * @param {Function} [cfgs.onSelect] 文件选择后\n * @param {Function} [cfgs.onUploading] 整体文件上传中\n * @param {Function} [cfgs.onProgress] 文件上传进度\n * @param {Function} [cfgs.onSuccess] 文件上传成功时\n * @param {Function} [cfgs.onFailure] 文件上传失败时\n * @param {Function} [cfgs.onDelete] 文件删除后\n * @param {Function} [cfgs.onComplete] 文件全部上传完毕时\n * @param {Function} [cfgs.onError] 文件检查错误处理 function(msg) {}\n */\nfunction Upload(selector, cfgs) {\n\tthis.cfgs = {\n\t\turl: 'http://imgsys.self.com.cn/interfaces',\n\t\tparams: {},\n\t\tuseCanvas: true,\n\t\tsize: 0,\n\t\tlimit: 0,\n\t\twidth: 640,\n\t\tquality: 100,\n\t\terror: '',\n\t\terrorMsg: {\n overnum: '超出上传数量限制',\n invalidLarge: '太大了',\n invalidSmall: '太小了',\n invalidType: '是不支持的图片类型',\n forbidden: '图片上传中或者图片上传被禁用'\n },\n autoUpload: false,\n uploadBtn: '',\n tpl: '',\n tplContainer: '',\n autoHide: true,\n onSelect: function(files) {},\n onUploading: function() {},\n onProgress: function(loaded, total) {},\n onSuccess: function(response, file) {},\n onFailure: function(msg, file) {},\n onDelete: function(file) {},\n onComplete: function(msg, files) {},\n onError: null\n\t};\n\n\t$.extend(true, this.cfgs, cfgs);\n\tthis._init(selector);\n}\n\nUpload.prototype = {\n\t_init: function(selector) {\n\t\tvar self = this;\n\n\t\t/** 包含容器 */\n\t\tself.container = $(selector);\n\t\t/** 上传控件 */\n\t\tself.input = self.container.find('[type=\"file\"]');\n\t\t/** 上传列表容器 */\n\t\tself.tplContainer = self.container.find(self.cfgs.tplContainer);\n\t\t/** 文件检查错误输出对象 */\n\t\tself.error = self.container.find(self.cfgs.error);\n\t\t/** 开始上传按钮 */\n\t\tself.uploadBtn = self.container.find(self.cfgs.uploadBtn);\n self.tpl = self.cfgs.tpl || '';\n\t\tself.disabled = true;\n\t\tself.files = [];\n\t\tself.filesFilter = [];\n\t\tself.failFiles = [];\n\t\tself.count = 0; // 总文件数\n\t\tself.compress = 0; // 压缩次数\n\t\tself._bind();\n\t},\n\t_bind: function() {\n\t\tvar self = this,\n\t\t\ttempFiles = [];\n\n\t\tself.input.change(function(e) {\n\t\t\tif (!self.disabled) {\n\t\t\t\tself._showError(self.error, self.cfgs.errorMsg.forbidden);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (self.error.length) {\n\t\t\t\tself.error.html('').hide();\n\t\t\t}\n\n\t\t\tself.failFiles = [];\n\t\t\ttempFiles = [];\n\t\t\ttempFiles.push(e.target.files);\n var tempFilesLen = tempFiles[0].length;\n\n\t\t\t$.each(tempFiles, function(index1, files) {\n\t\t\t\t$.each(files, function(index2, file) {\n\t\t\t\t\tself.files.push(file);\n\t\t\t\t});\n\t\t\t});\n\t\t\t\n \n\t\t\tif (self.cfgs.limit > 0 && self.files.length > self.cfgs.limit) {\n for(var i = 0;i<tempFilesLen;i++){\n self.files.pop();\n } \n\t\t\t\tself._showError(self.error, self.cfgs.errorMsg.overnum + self.cfgs.limit);\n\t\t\t} else {\n\t\t\t\tself.filesFilter = self._filter(self.files);\n\t\t\t\tself.count = self.filesFilter.length;\n\t\t\t\tself.cfgs.onSelect(self.filesFilter);\n\n\t\t\t\tif (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.filesFilter.length) {\n\t\t\t\t\tself._createTpl(self.filesFilter);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (self.cfgs.autoUpload) {\n\t\t\t\t\tself._upload();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (self.uploadBtn.length) {\n\t\t\tself.uploadBtn.click(function() {\n\t\t\t\tif (!self.disabled) {\n\t\t\t\t\tself._showError(self.error, self.cfgs.errorMsg.forbidden);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.filesFilter.length) {\n\t\t\t\t\tvar failure = self.tplContainer.find('[node-status=\"failure\"]');\n\n\t\t\t\t\tfailure.find('[node-type=\"result\"]').hide();\n\t\t\t\t\tfailure.find('[node-type=\"progress\"]').css('width', 0);\n\t\t\t\t\tfailure.find('[node-type=\"reupload\"]').hide();\n\t\t\t\t}\n\n\t\t\t\tself.count = self.filesFilter.length;\n\t\t\t\tself.failFiles = [];\n\t\t\t\tself._upload();\n\t\t\t});\n\t\t}\n\t},\n\t_filter: function(files) {\n var self = this,\n \tfilesArr = [],\n \tmsg = [];\n\n $.each(files, function(index, file) {\n \tvar maxSize = parseFloat(self.cfgs.size),\n \t\tfileName = file.name ? file.name : '';\n\n \tif (file.type) {\n \t\tif (file.type.indexOf('image') === 0) {\n \t\t\tif (!self.cfgs.useCanvas && maxSize > 0 && file.size >= maxSize * 1048576) {\n \t\t\t\tmsg.push(fileName + self.cfgs.errorMsg.invalidLarge);\n \t\t\t} else {\n \t\t\t\tfile.index = index;\n \t\t\t\tfile.aborted = false;\n \t\t\t\tfilesArr.push(file);\n \t\t\t}\n \t\t\t} else {\n \t\t\t\tmsg.push(fileName + self.cfgs.errorMsg.invalidType);\n \t\t\t}\n \t} else {\n \t\tif (!self.cfgs.useCanvas && maxSize > 0 && file.size >= maxSize * 1048576) {\n \t\t\t\tmsg.push(fileName + self.cfgs.errorMsg.invalidLarge);\n \t\t\t} else {\n \t\t\t\tfile.index = index;\n \t\t\t\tfile.aborted = false;\n \t\t\t\tfilesArr.push(file);\n \t\t\t}\n \t}\n });\n\n if (msg.length) {\n \tself._showError(self.error, msg.join('\\n'));\n }\n\n return filesArr;\n },\n _createTpl: function(files) {\n \tvar self = this,\n \t\ttpl = '',\n \t\titems = '',\n \t\tpreviews = [],\n \t\trevoker = null;\n\n \tif (self.cfgs.tpl) {\n\t\t\ttpl = self.cfgs.tpl;\n\t\t} else {\n\t\t\ttpl = '<li node-id=$fileIndex>\\\n \t\t<p node-type=\"preview\" style=\"background-image:url($preview);\"></p>\\\n \t\t<p node-type=\"result\"></p>\\\n \t<p node-type=\"name\">$name</p>\\\n \t<p node-type=\"size\">$size</p>\\\n \t<p node-type=\"progress\"></p>\\\n \t<p node-type=\"reupload\" node-data=$fileIndex>^</p>\\\n \t<p node-type=\"close\" node-data=$fileIndex>x</p>\\\n \t</li>';\n\t\t}\n\n\t\tif (brickjs.UserAgent.isiOS) {\n\t\t\t$.each(files, function(index, file) {\n\t \t\tvar size = file.size / 1024,\n\t \t\t\tobj = {\n\t \t\t\t\tname: file.name,\n\t \t\t\t\tsize: size >= 1024 ? (size / 1024).toFixed(1) + 'M' : size.toFixed(1) + 'KB',\n\t \t\t\t\tfileIndex: file.index\n\t \t\t\t};\n\n\t \t\tcanvasResize(file, {\n\t\t width: self.cfgs.width,\n\t\t height: 0,\n\t\t crop: false,\n\t\t quality: self.cfgs.quality,\n\t\t callback: function(data, width, height) {\n\t\t \tobj.preview = data;\n \t\t\t\t\titems += self._templ(tpl, obj);\n\n \t\t\t\t\tif (index === files.length - 1) {\n \t\t\t\t\t\tself.tplContainer.html(items).show();\n \t\t\t\t\t\tself._bindTpl();\n \t\t\t\t\t}\n\t\t }\n\t\t \t});\n\t \t});\n\n\t \treturn;\n\t }\n\n \t$.each(files, function(index, file) {\n \t\tvar size = file.size / 1024,\n \t\t\tobj = {\n \t\t\t\tname: file.name,\n \t\t\t\tsize: size >= 1024 ? (size / 1024).toFixed(1) + 'M' : size.toFixed(1) + 'KB',\n \t\t\t\tfileIndex: file.index\n \t\t\t};\n\n \t\tobj.preview = self._dealObjectURL(file, true);\n \t\titems += self._templ(tpl, obj);\n \t\tpreviews.push(obj.preview);\n \t});\n\n \trevoker = setTimeout(function() {\n\t\t\t$.each(previews, function(index, val) {\n\t\t\t\tself._dealObjectURL(val);\n\t\t\t});\n\n\t\t\tclearTimeout(revoker);\n\t\t}, 5000);\n\t\tself.tplContainer.html(items).show();\n\t\tself._bindTpl();\n },\n _bindTpl: function() {\n \tvar self = this;\n\n \tself.tplContainer.on('click', '[node-type=\"close\"]', function() {\n\t\t\tself._delete($(this).attr('node-data'));\n\t\t});\n\n\t\tself.tplContainer.on('click', '[node-type=\"reupload\"]', function() {\n\t\t\tvar fileIndex = $(this).hide().attr('node-data'),\n\t\t\t\tcurrentFiles = [],\n\t\t\t\tfailure = '';\n\n\t\t\t$.each(self.filesFilter, function(index, file) {\n\t\t\t\tif (file.index == fileIndex) {\n\t\t\t\t\tfailure = self.tplContainer.find('[node-id=\"' + fileIndex + '\"]');\n\t\t\t\t\tfailure.find('[node-type=\"result\"]').hide();\n\t\t\t\t\tfailure.find('[node-type=\"progress\"]').css('width', 0);\n\t\t\t\t\tcurrentFiles.push(file);\n\t\t\t\t\tself._upload(currentFiles);\n\t\t\t\t\treturn false;\n\t\t\t\t};\n\t\t\t});\n\t\t});\n },\n _watchTpl: function(status, index, a, b) {\n \tvar self = this,\n \t\titem = '';\n\n \tif (typeof self.cfgs.tpl !== 'string' || !self.tplContainer.length) {\n \t\treturn;\n \t}\n\n \titem = self.container.find('[node-id=\"' + index + '\"]');\n\n \tswitch (status) {\n \t\tcase 'progress':\n \t\t\titem.find('[node-type=\"progress\"]').animate({width: a / b * 100 + '%'});\n \t\t\tbreak;\n \t\tcase 'success':\n \t\t\titem.attr('node-status', 'success').find('[node-type=\"result\"]').html('上传成功').show();\n \t\t\titem.find('[node-type=\"progress\"]').css('width', '100%');\n \t\t\tbreak;\n \t\tcase 'failure':\n \t\t\titem.attr('node-status', 'failure').find('[node-type=\"result\"]').html(a ? a: '上传失败').show();\n \t\t\titem.find('[node-type=\"reupload\"]').show();\n \t\t\tbreak;\n \t}\n },\n _templ: function(c, a){\n\t for (var b in a) {\n\t if (a.hasOwnProperty(b)) {\n\t c = c.replace(new RegExp('\\\\$' + b, 'ig'), a[b]);\n\t }\n\t }\n\n\t return c;\n\t},\n\t_dealObjectURL: function(file, create) {\n\t\tif (window.URL) {\n\t\t\tif (create) {\n\t\t\t\treturn window.URL.createObjectURL(file);\n\t\t\t} else {\n\t\t\t\twindow.URL.revokeObjectURL(file);\n\t\t\t}\n\t\t} else if (window.webkitURL) {\n\t\t\tif (create) {\n\t\t\t\treturn window.webkitURL.createObjectURL(file);\n\t\t\t} else {\n\t\t\t\twindow.webkitURL.revokeObjectURL(file);\n\t\t\t}\n\t\t}\n\t},\n\t_upload: function(target) {\n\t\tvar self = this,\n\t\t\tfilesFilter = self.filesFilter;\n\n\t\tif (target) {\n\t\t\tfilesFilter = target;\n\t\t}\n\n \tif (filesFilter.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tself.cfgs.onUploading();\n\t\tself.disable();\n\n\t\t$.each(filesFilter, function(index, file) {\n\t\t\tvar xhr = new XMLHttpRequest(),\n\t\t\t\tfileIndex = file.index,\n\t\t\t\tfileName = file.name ? file.name : '';\n\n \txhr.upload.addEventListener('progress', function(e) {\n \t\tself._watchTpl('progress', fileIndex, e.loaded, e.total);\n\t\t\t\tself.cfgs.onProgress(e.loaded, e.total, file);\n\t\t\t}, false);\n\n\t\t\txhr.addEventListener('error', function(e) {\n\t\t\t\tself._checkPogress(target, file);\n\t\t\t\tself._watchTpl('failure', fileIndex);\n\t\t\t\tself.cfgs.onFailure('上传失败', file);\n\t\t\t\tif(self.cfgs.autoUpload){\n\t\t\t\t\tself._delete(file, target);\n\t\t\t\t}\n\t\t\t}, false);\n\n\t\t\txhr.addEventListener('load', function(e){\n var response = eval('(' + xhr.responseText + ')'),\n \tfileAborted = file.aborted;\n \n \tif (!fileAborted) {\n\t\t\t\t\tif (response && response.status == 1) {\n\t\t\t\t\t\tself._watchTpl('success', fileIndex);\n\t\t\t\t\t\tself.cfgs.onSuccess(response, file);\n\t\t\t\t\t\tself._delete(file, target);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself._checkPogress(target, file);\n\t\t\t\t\t\tself._watchTpl('failure', fileIndex, response ? response.message : '上传失败');\n\t\t\t\t\t\tself.cfgs.onFailure(response ? response.message : '上传失败', file);\n\t\t\t\t\t}\n\t\t\t\t}\n }, false);\n\n \tif (!self.cfgs.useCanvas && !brickjs.UserAgent.isiOS) {\n \t\tvar formData = new FormData();\n\n \t\tformData.append('Filedata', file);\n\n \t\tfor (var p in self.cfgs.params) {\n\t if (self.cfgs.params.hasOwnProperty(p)) {\n\t formData.append(p, self.cfgs.params[p])\n\t }\n\t }\n\n\t xhr.open('POST', self.cfgs.url, true);\n\t\t\t\txhr.send(formData);\n \t} else if (brickjs.UserAgent.isiOS) {\n \t\tself._resizeIos(file, 1, 1, xhr);\n \t} else {\n \t\tself._resize(file, 1, 1, xhr);\n \t}\n\t\t});\n\t},\n\t_resize: function(file, ratio1, ratio2, xhr) {\n\t\tvar self = this,\n\t\t\tcanvas = document.createElement('canvas'),\n\t\t\tctx = canvas.getContext('2d'),\n\t\t\treader = new FileReader(),\n\t\t\timg = new Image(),\n\t\t\tratio = 1,\n\t\t\tdata = null,\n\t\t\tmaxSize = parseFloat(self.cfgs.size)||1000,\n\t\t\tdataLength = 0;\n\n\t\treader.onload = function(e) {\n\t\t\timg.onload = function() {\n\t\t\t\tratio = this.width > self.cfgs.width ? self.cfgs.width / this.width : 1;\n\t\t\t\tcanvas.width = this.width * ratio * ratio1;\n\t\t\t\tcanvas.height = this.height * ratio * ratio1;\n\t\t\t\tctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n\t\t\t\t\n\t\t\t\tif (file.type === 'image/png') {\n data = canvas.toDataURL(file.type);\n } else {\n data = canvas.toDataURL('image/jpeg', self.cfgs.quality / 100 * ratio2);\n }\n\n if (data.length < maxSize * 1024 * 1024) {\n \t\txhr.open('POST', self.cfgs.url, true);\n\t\t\t\t\txhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n\t\t\t\t\txhr.send('Filedata=' + encodeURIComponent(data) + '&title=' + self.cfgs.params.title + '&uploadtype=' + self.cfgs.params.uploadtype);\n \t} else {\n \t\tself.compress++;\n\n \t\tif (file.type === 'image/png' || (brickjs.UserAgent.isAndroid && !brickjs.UserAgent.chrome)) {\n \t\tself._resize(file, Math.pow(.8, self.compress), 1, xhr);\n } else {\n self._resize(file, 1, Math.pow(.8, self.compress), xhr);\n }\n \t}\n\t\t\t}\n\n\t\t\timg.src = e.target.result;\n\t\t}\n\n\t\treader.readAsDataURL(file);\n\t},\n\t_resizeIos: function(file, ratio1, ratio2, xhr) {\n\t\tvar self = this,\n\t\t\tmaxSize = parseFloat(self.cfgs.size)||1000,\n\t\t\tdataLength = 0;\n\n\t\tcanvasResize(file, {\n width: self.cfgs.width * ratio1,\n height: 0,\n crop: false,\n quality: self.cfgs.quality * ratio2,\n callback: function(data, width, height) {\n \tif (data.length < maxSize * 1024 * 1024) {\n \t\txhr.open('POST', self.cfgs.url, true);\n\t\t\t\t\txhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n\t\t\t\t\txhr.send('Filedata=' + encodeURIComponent(data) + '&title=' + self.cfgs.params.title + '&uploadtype=' + self.cfgs.params.uploadtype);\n \t} else {\n \t\tself.compress++;\n\n \t\tif (file.type === 'image/png') {\n \t\tself._resizeIos(file, Math.pow(.8, self.compress), 1, xhr);\n } else {\n self._resizeIos(file, 1, Math.pow(.8, self.compress), xhr);\n }\n \t}\n }\n \t});\n\t},\n\t_delete: function(fileDelete, target) {\n\t\tvar self = this,\n \tfilesArr = [];\n\n if (!self.filesFilter.length && typeof fileDelete === 'string') {\t\n \tself._hidePreview(fileDelete);\n\t\t\treturn;\n }\n\n $.each(self.filesFilter, function(index, file) {\n \tif (typeof fileDelete === 'string') {\n \t\tif (file.index != fileDelete) {\n\t\t\t\t\tfilesArr.push(file);\n\t\t\t\t} else {\n\t\t\t\t\tself._hidePreview(fileDelete);\n\t\t\t\t\tfile.aborted = true;\n\t\t\t\t\tself.cfgs.onDelete(file);\n\t\t\t\t}\n \t} else {\n \t\tif (file != fileDelete) {\n\t\t\t\t\tfilesArr.push(file);\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof self.cfgs.tpl === 'string' && self.tplContainer.length && self.cfgs.autoHide) {\n\t\t\t\t\t\tself._hidePreview(file.index);\n\t\t\t\t\t}\n\t\t\t\t}\n \t}\n });\n\n self.filesFilter = filesArr;\n self.files = filesArr;\n self._checkPogress(target);\n\t},\n\t_hidePreview: function(index) {\n\t\tvar self = this,\n\t\t\titemLen = 0;\n\n\t\tself.container.find('[node-id=\"' + index + '\"]').fadeOut('slow', function() {\n\t\t\t$(this).remove();\n\t\t\titemLen = self.container.find('[node-id]').length;\n\n\t\t\tif (!itemLen) {\n\t\t\t\tself.tplContainer.html('').hide();\n\t\t\t}\n\t\t});\n\t},\n\t_checkPogress: function(target, fileFailure) {\n\t\tvar self = this;\n\t\t\n\t\tself.count--;\n\t\t\n\t\tif (fileFailure) {\n\t\t\tself.failFiles.push(fileFailure);\n\t\t}\n\n\t\tif (!self.filesFilter.length) {\n\t\t\tif (!self.disabled) {\n\t\t\t\tself.cfgs.onComplete('全部图片上传成功');\n\t\t\t}\n\n\t\t\tself.enable();\n\t\t} else if (!self.count && self.failFiles.length) {\n\t\t\tself.cfgs.onComplete('部分图片未上传成功,请重新上传', self.failFiles);\n\t\t\tself.enable();\n\t\t} else if (target) {\n\t\t\tself.enable();\n\t\t}\n\t},\n\t_showError: function(error, msg, append) {\n\t\tif (typeof this.cfgs.onError === 'function') {\n\t\t\tthis.cfgs.onError(msg);\n\t\t\treturn;\n\t\t}\n\n\t\tif (error.length) {\n\t\t\tif (append) {\n\t\t\t\terror.append(msg).show();\n\t\t\t} else {\n\t\t\t\terror.html(msg).show();\n\t\t\t}\n\t\t} else {\n\t\t\tsetTimeout(function() {alert(msg);}, 0);\n\t\t}\n\t},\n\t/**\n\t * 禁用图片上传\n\t */\n\tdisable: function() {\n\t\tthis.disabled = false;\n\t},\n\t/**\n\t * 启用图片上传\n\t */\n\tenable: function() {\n\t\tthis.disabled = true;\n\t}\n};\n;regist(\"Upload\",Upload);\n})((typeof Zepto !== 'undefined' ? Zepto : jQuery), window, document)\n\n\n\n// WEBPACK FOOTER //\n// ./mobile/src/js/upload.js",";(function($, window, document, undefined) {\n function regist(mName, module) {\n if (typeof window.brickjs === \"undefined\") {\n window.brickjs = {};\n }\n brickjs[mName] = module;\n }\n;/** \n * 移动设备及浏览器检测\n * @fileOverview\n * @author jianjun.wang@condenast.com.cn\n * @version 0.1.0\n * @example <a href=\"../useragent/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n */\n/** \n * @class\n * @author jianjun.wang@condenast.com.cn\n * @description 移动设备及浏览器检测\n * @since version 0.1.0\n * @example <a href=\"../useragent/examples/demo.html\">demo.html</a>\n * @see http://js.selfimg.com.cn/brickjs/useragent/0.1.0/useragent.min.js\n */\nvar UserAgent = {\n /** \n * @description {Boolean} 是否桌面电脑\n * @field\n */\n isDesktop: false,\n /** \n * @description {Boolean} 是否Windows系统\n * @field\n */\n isWindows: false,\n /** \n * @description {Boolean} 是否Linux系统\n * @field\n */\n isLinux: false,\n /** \n * @description {Boolean} 是否Mac系统\n * @field\n */\n isMac: false,\n\n /** \n * @description {Boolean} 是否平板设备\n * @field\n */\n isTablet: false,\n /** \n * @description {Boolean} 是否iPad设备\n * @field\n */\n isiPad: false,\n /** \n * @description {Boolean} 是否Android平板\n * @field\n */\n isAndroidTablet: false,\n\n /** \n * @description {Boolean} 是否移动手机设备\n * @field\n */\n isMobile: false,\n /** \n * @description {Boolean} 是否iOS系统\n * @field\n */\n isiOS: false,\n /** \n * @description {Boolean} 是否Android系统\n * @field\n */\n isAndroid: false,\n /** \n * @description {Boolean} 是否iPhone手机\n * @field\n */\n isiPhone: false, //简化, ipod也归于iphone\n /** \n * @description {Boolean} 是否WindowsPhone手机\n * @field\n */\n isWindowsPhone: false,\n /** \n * @description {Boolean} 是否微信浏览器\n * @field\n */\n isWeChat: false,\n /** \n * @description {Boolean} 是否微博浏览器\n * @field\n */\n isWeibo: false,\n\n /** \n * @description {Float} IE浏览器版本号,默认为 0\n * @field\n */\n ie: 0, //默认为0,监测到浏览器直接返回版本号\n /** \n * @description {Float} Firefox浏览器版本号,默认为 0\n * @field\n */\n firefox: 0,\n /** \n * @description {Float} Chrome浏览器版本号,默认为 0\n * @field\n */\n chrome: 0,\n /** \n * @description {Float} Safari浏览器版本号,默认为 0\n * @field\n */\n safari: 0,\n /** \n * @description {Float} Opera浏览器版本号,默认为 0\n * @field\n */\n opera: 0,\n /** \n * @description {Float} UC浏览器版本号,默认为 0\n * @field\n */\n uc: 0,\n /** \n * @description {Float} MQQ浏览器版本号,默认为 0\n * @field\n */\n mqq: 0,\n /** \n * @description {Float} Baidu浏览器版本号,默认为 0\n * @field\n */\n baidu: 0,\n /** \n * @description {Float} Android系统自带浏览器版本号,默认为 0,没有匹配到其它浏览器都认为是Android浏览器\n * @field\n */\n androidBrowser: 0,\n\n /** \n * @description {String} 浏览器名称,可能的值:IE|Firefox|Chrome|Safari|Opera|UC|MQQ|Baidu|Weibo|MicroMessenger|Android|unknown\n * @field\n */\n browser: \"\",\n /** \n * @description {String} 浏览器引擎名称,可能的值:trident|applewebkit|presto|gecko\n * @field\n */\n engine: \"\",\n /** \n * @description {String} iOS或者Android系统版本号,不支持其它系统\n * @field\n */\n osVersion: 0, //只支持ios android,PC不做支持 \n\n _versions: {\n ie: /msie\\s([\\d\\.]+[\\d])|trident\\/\\d+\\.\\d+;\\s+[rv:]+(\\d+\\.\\d)/i,\n firefox: /firefox\\/([\\d\\w\\.\\-]+)/i,\n chrome: /(chrome|crios)\\/([\\d\\w\\.\\-]+)/i,\n safari: /version\\/([\\d\\w\\.\\-]+)/i,\n opera: /version\\/([\\d\\w\\.\\-]+)/i,\n uc: /ucbrowser\\/([\\d\\w\\.\\-]+)/i,\n mqq: /mqqbrowser\\/([\\d\\w\\.\\-]+)/i,\n baidu: /baidubrowser\\/([\\d\\w\\.\\-]+)/i,\n androidBrowser: /version\\/([\\d\\w\\.\\-]+)/i\n },\n _browsers: {\n ie: /msie|trident/i,\n firefox: /firefox/i,\n chrome: /chrome|crios/i,\n safari: /safari/i,\n opera: /opera/i,\n uc: /ucbrowser/i,\n mqq: /mqqbrowser/i,\n baidu: /baidubrowser/i,\n weibo: /weibo/i,\n wechat: /micromessenger/i\n },\n _platforms: {\n windows: /windows nt/i,\n windowsPhone: /windows phone/i,\n mac: /macintosh/i,\n linux: /linux/i,\n iPad: /ipad/i,\n iPod: /ipod/i,\n iPhone: /iphone/i,\n android: /android/i\n },\n _osVersion: {\n iOS: /(iphone\\sos|cpu\\sos)\\s([\\d\\w\\_\\-]+)/i,\n android: /android\\s([\\d\\w\\.\\-]+)/i\n },\n _engine: {\n trident: /trident/i,\n gecko: /gecko/i,\n applewebkit: /applewebkit/i,\n presto: /presto/i\n },\n _init: function() {\n this.ua = navigator.userAgent.toLowerCase();\n\n this._getPlatform();\n\n this.browser = this._getBrowser();\n this._getBroserVersion();\n\n this.isAndroidTablet = this.isAndroid && new RegExp(\"tablet\", \"i\").test(this.ua);\n this._testMobile();\n this._getOSVersion();\n this._getEngine();\n },\n _toFixedVersion: function(ver, floatLength) {\n var ver = (\"\" + ver).replace(/_/g, \".\");\n var floatLength = floatLength || 1;\n ver = String(ver).split(\".\");\n ver = ver[0] + \".\" + (ver[1] || \"0\");\n ver = Number(ver).toFixed(floatLength);\n return ver;\n },\n _getBrowser: function() {\n var ua = this.ua;\n switch (true) {\n case this._browsers.ie.test(ua):\n this.ie = true;\n return \"IE\";\n case this._browsers.firefox.test(ua):\n this.firefox = true;\n return \"Firefox\";\n case this._browsers.opera.test(ua):\n this.opera = true;\n return \"Opera\";\n case this._browsers.uc.test(ua):\n this.uc = true;\n return \"UC\";\n case this._browsers.baidu.test(ua):\n this.baidu = true;\n return \"Baidu\";\n case this._browsers.weibo.test(ua):\n this.isWeibo = true;\n return \"Weibo\";\n //有些版本的微信中也包含 MQQBrowser\n case this._browsers.wechat.test(ua):\n this.isWeChat = true;\n return \"MicroMessenger\";\n case this._browsers.mqq.test(ua):\n this.mqq = true;\n return \"MQQ\";\n //chrome浏览器也有safari\n case this._browsers.chrome.test(ua):\n this.chrome = true;\n return \"Chrome\";\n case !this.isAndroid && this._browsers.safari.test(ua):\n this.safari = true;\n return \"Safari\";\n case this.isAndroid:\n this.androidBrowser = true;\n return \"Android\";\n default:\n return 'unknown';\n }\n },\n _getBroserVersion: function() {\n var ua = this.ua;\n switch (true) {\n case this.ie:\n this._versions.ie.test(ua);\n this.ie = RegExp.$2 ? this._toFixedVersion(RegExp.$2, 1) : this._toFixedVersion(RegExp.$1, 1);\n break;\n case this.firefox:\n this._versions.firefox.test(ua);\n this.firefox = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.opera:\n this._versions.opera.test(ua);\n this.opera = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.uc:\n this._versions.uc.test(ua);\n this.uc = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.baidu:\n this._versions.baidu.test(ua);\n this.baidu = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.mqq:\n this._versions.mqq.test(ua);\n this.mqq = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.chrome:\n this._versions.chrome.test(ua);\n this.chrome = RegExp.$2 ? this._toFixedVersion(RegExp.$2, 1) : 0;\n break;\n case this.safari:\n this._versions.safari.test(ua);\n this.safari = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n case this.androidBrowser:\n this._versions.androidBrowser.test(ua);\n this.androidBrowser = RegExp.$1 ? this._toFixedVersion(RegExp.$1, 1) : 0;\n break;\n }\n },\n _getOSVersion: function() {\n var ua = this.ua;\n switch (true) {\n case this._osVersion.iOS.test(ua):\n this.osVersion = RegExp.$2.replace(/_/g, \".\");\n this.isiOS = true;\n break;\n case this._osVersion.android.test(ua):\n this.osVersion = RegExp.$1;\n break;\n }\n },\n _getPlatform: function() {\n var ua = this.ua;\n\n switch (true) {\n case this._platforms.windows.test(ua):\n this.isWindows = true;\n break;\n case this._platforms.windowsPhone.test(ua):\n this.isWindowsPhone = true;\n break;\n case this._platforms.mac.test(ua):\n this.isMac = true;\n break;\n case this._platforms.iPad.test(ua):\n this.isiPad = true;\n break;\n case this._platforms.iPhone.test(ua) || this._platforms.iPod.test(ua):\n this.isiPhone = true;\n break;\n case this._platforms.android.test(ua):\n this.isAndroid = true;\n break;\n case this._platforms.linux.test(ua):\n this.isLinux = true;\n break;\n }\n },\n _testMobile: function() {\n var ua = this.ua;\n\n switch (true) {\n case this.isWindows:\n case this.isLinux:\n case this.isMac:\n this.isDesktop = true;\n break;\n\n case this.isiPad:\n case this.isAndroidTablet:\n this.isTablet = true;\n break;\n case this.isAndroid:\n case this.isiPhone:\n case this.isWindowsPhone:\n this.isMobile = true;\n break;\n }\n\n if (/mobile/i.test(ua) && !this.isTablet) {\n this.isMobile = true;\n this.isDesktop = false;\n this.isTablet = false;\n }\n },\n _getEngine: function() {\n var ua = this.ua;\n switch (true) {\n case this._engine.trident.test(ua):\n this.engine = \"trident\";\n break;\n case this._engine.applewebkit.test(ua):\n this.engine = \"applewebkit\";\n break;\n case this._engine.presto.test(ua):\n this.engine = \"presto\";\n break;\n case this._engine.gecko.test(ua):\n this.engine = \"gecko\";\n break;\n }\n },\n /**\n * 是否包含指定关键字,可以用于判断特定浏览器或者App\n * @param {String} str 匹配的关键字\n * @returns {Boolean} true: 包含 | false: 未包含\n */\n contains: function(str) {\n var reg = new RegExp(str, 'i');\n return reg.test(this.ua);\n },\n /**\n * 获取浏览器的UserAgent\n * @returns {String} UserAgent字符串\n */\n getUserAgent: function() {\n return this.ua;\n }\n}\nUserAgent._init();\n;regist(\"UserAgent\",UserAgent);\n})((typeof Zepto !== 'undefined' ? Zepto : jQuery), window, document)\n \n\n\n// WEBPACK FOOTER //\n// ./mobile/src/js/useragent.js","require('./useragent');\nrequire('./upload');\n$('.comment-imgs-box ul').on('click','li .close',function(){\n\t$(this).parent().remove();\n})\n\n\n\n\n// WEBPACK FOOTER //\n// ./mobile/src/js/comment.js"],"sourceRoot":""}
|