手机网页版JS压缩上传图片--base64位 兼容IOS和安卓

首先,我用到了一款插件,是纯JS压缩上传插件,第一次用CSDN,不太会用,我把插件所有代码拷贝在文章末尾。
加载JS插件<script src="__JS__/dist/lrz.mobile.min.js">script>


页面上传图片:

    <div class="fileupload-buttonbar">
        <a type="button" class="am-btn am-btn-sm am-fl " style="  line-height: 0.2;"><img
                src="__IMG__/image.png">a>

        <div class="fileinput-button" style="width: 100%">
            <input type="file" name="files" class="btn" id="choose"
                   style="left: 35px;position:absolute;z-index: 1;width: 35px;height:40px;opacity: 0;cursor: pointer;"
                   data-url="{:U('Core/File/uploadPictureBase64')}" multiple/>div>

        <style>
            .img-list li {
                float: left;
                position: relative;
                display: inline-block;
                width: 100px;
                height: 100px;
                margin: 5px 5px 20px 5px;
                border: 1px solid rgb(100, 149, 198);
                background: #fff no-repeat center;
                background-size: cover;
                border-radius: 5px;
            }
        style>
    div>
    
    
    <p class="submitweibo" url="{:U('Mob/Weibo/doSend')}">
        <button style="float: right" type="submit" class="am-btn am-btn-primary am-btn-block">发布button>
    p>
    
div>
<ul class="img-list am-fl" style="padding-left:0px;">
    
ul>

图片id存放,隐藏input,放在页面的form表单内即可。

<input type="hidden" id="img_ids" name="attach_ids" value="">



js代码

//新上传图片
function add_img() {
    var filechooser = document.getElementById("choose");
    $("#upload").on("click", function () {
        filechooser.click();
    })
    filechooser.onchange = function () {
        if (!this.files.length) return;
        var files = Array.prototype.slice.call(this.files);
        if (files.length > 9) {
            alert("最多同时只可上传9张图片");
            return;
        }
        files.forEach(function (files, i) {
            if (!/\/(?:jpeg|png|gif)/i.test(files.type)){
                toast.error('上传图片格式不符!');
            }
            var div = ' 
  • \             \        
  • '
    ;            $('.img-list').append(div);            lrz(files, { width: 1200,                height: 900,                before: function () { console.log('压缩开始');                },                fail: function (err) { console.error(err);                },                always: function () { console.log('压缩结束');                },                done: function (results) { // 你需要的数据都在这里,可以以字符串的形式传送base64给服务端转存为图片。                    var data=results.base64;                    upload(data);                } });        }) } } function removeLi(li,file_id) { console.log(li) upAttachVal('remove', file_id, $('#img_ids')) $(li).parent('.waitbox').remove(); } //图片上传,返回id ,地址 function upload(data) { console.log(data);    var dataUrl = U('Core/File/uploadPictureBase64');    $.post(dataUrl, {data: data}, function (msg) { if (msg.status == 1) { var ids = $('#img_ids').val();            upAttachVal('add', msg.id, $('#img_ids'));            //上传成功显示图片            var div = '
  • \                removeLi(this, '+msg.id+')" style="position:absolute;right: 5px;top: -5px;color: red">\             \        
  • '
    ;            $('.loadingBox').hide();            $('.img-list').append(div);        } else { toast.error(msg.info);        } }, 'json') } function upAttachVal(type, attachId, obj) { var $attach_ids = obj;    var attachVal = $attach_ids.val();    var attachArr = attachVal.split(',');    var newArr = [];    for (var i in attachArr) { if (attachArr[i] !== '' && attachArr[i] !== attachId.toString()) { newArr.push(attachArr[i]);        } } type === 'add' && newArr.push(attachId);    if (newArr.length <= 9) { $attach_ids.val(newArr.join(','));        return newArr;    } else { return false;    } }




    后台php代码:

    public function uploadPictureBase64()
    {
    
        $aData = $_POST['data'];
    
        if ($aData == '' || $aData == 'undefined') {
            $this->ajaxReturn(array('status'=>0,'info'=>'参数错误'));
        }
    
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $aData, $result)) {
            $base64_body = substr(strstr($aData, ','), 1);
    
            empty($aExt) && $aExt = $result[2];
        } else {
            $base64_body = $aData;
        }
    
        empty($aExt) && $aExt = 'jpg';
    
        $pictureModel = D('Picture');
    
        $md5 = md5($base64_body);
        $sha1 = sha1($base64_body);
    
    
        $check = $pictureModel->where(array('md5' => $md5, 'sha1' => $sha1))->find();
    
        if ($check) {
            //已存在则直接返回信息
            $return['id'] = $check['id'];
            $return['path'] = render_picture_path($check['path']);
            $this->ajaxReturn(array('status'=>1,'id'=>$return['id'],'path'=> $return['path']));
        } else {
            //不存在则上传并返回信息
            $driver = modC('PICTURE_UPLOAD_DRIVER','local','config');
            $driver = check_driver_is_exist($driver);
            $date = date('Y-m-d');
            $saveName = uniqid();
            $savePath = '/Uploads/Picture/' . $date . '/';
    
            $path = $savePath . $saveName . '.' . $aExt;
            if($driver == 'local'){
                //本地上传
                mkdir('.' . $savePath, 0777, true);
                $data = base64_decode($base64_body);
                $rs = file_put_contents('.' . $path, $data);
            }
            else{
                $rs = false;
                //使用云存储
                $name = get_addon_class($driver);
                if (class_exists($name)) {
                    $class = new $name();
                    if (method_exists($class, 'uploadBase64')) {
                        $path = $class->uploadBase64($base64_body,$path);
                        $rs = true;
                    }
                }
            }
            if ($rs) {
                $pic['type'] = $driver;
                $pic['path'] = $path;
                $pic['md5'] = $md5;
                $pic['sha1'] = $sha1;
                $pic['status'] = 1;
                $pic['create_time'] = time();
                $id = $pictureModel->add($pic);
               $this->ajaxReturn (array('status'=>1,'id' => $id, 'path' => render_picture_path($path)));
            } else {
                $this->ajaxReturn(array('status'=>0,'图片上传失败。'));
            }
    
        }
    }


    function render_picture_path($path)
    {
        $path = get_pic_src($path);
        return is_bool(strpos($path, 'http://')) ? 'http://' . str_replace('//', '/', $_SERVER['HTTP_HOST'] . '/' . $path) : $path;
    }
    

    function get_pic_src($path)
    {
    
        //不存在http://
        $not_http_remote = (strpos($path, 'http://') === false);
        //不存在https://
        $not_https_remote = (strpos($path, 'https://') === false);
        if ($not_http_remote && $not_https_remote) {
            //本地url
            return str_replace('//', '/', getRootUrl() . $path); //防止双斜杠的出现
        } else {
            //远端url
            return $path;
        }
    }



    插件代码:

    !function (e) {
        Array.prototype.map || (Array.prototype.map = function (e, r) {
            var a, t, n;
            if (null == this)throw new TypeError(" this is null or not defined");
            var o = Object(this), i = o.length >>> 0;
            if ("function" != typeof e)throw new TypeError(e + " is not a function");
            for (r && (a = r), t = Array(i), n = 0; i > n;) {
                var l, d;
                n in o && (l = o[n], d = e.call(a, l, n, o), t[n] = d), n++
            }
            return t
        });
        var r = e.detect = function () {
            var e = function () {
            }, r = {
                browser_parsers: [{
                    regex: "^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii",
                    family_replacement: "Wii",
                    manufacturer: "Nintendo"
                }, {
                    regex: "(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
                    family_replacement: "Camino",
                    other: !0
                }, {
                    regex: "(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
                    family_replacement: "Pale Moon (Firefox Variant)",
                    other: !0
                }, {
                    regex: "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
                    family_replacement: "Firefox Mobile"
                }, {
                    regex: "(Fennec)/(\\d+)\\.(\\d+)(pre)",
                    family_replacment: "Firefox Mobile"
                }, {
                    regex: "(Fennec)/(\\d+)\\.(\\d+)",
                    family_replacement: "Firefox Mobile"
                }, {
                    regex: "Mobile.*(Firefox)/(\\d+)\\.(\\d+)",
                    family_replacement: "Firefox Mobile"
                }, {
                    regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)",
                    family_replacement: "Firefox ($1)"
                }, {
                    regex: "(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
                    family_replacement: "Firefox Alpha"
                }, {
                    regex: "(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
                    family_replacement: "Firefox Beta"
                }, {
                    regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
                    family_replacement: "Firefox Alpha"
                }, {
                    regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
                    family_replacement: "Firefox Beta"
                }, {
                    regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?",
                    family_replacement: "Firefox ($1)"
                }, {
                    regex: "(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "MicroB",
                    tablet: !0
                }, {regex: "(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?"}, {
                    regex: "(Flock)/(\\d+)\\.(\\d+)(b\\d+?)",
                    family_replacement: "Flock",
                    other: !0
                }, {
                    regex: "(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Rockmelt",
                    other: !0
                }, {
                    regex: "(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Netscape"
                }, {
                    regex: "(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)",
                    family_replacement: "Netscape"
                }, {
                    regex: "(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Netscape"
                }, {
                    regex: "(MyIBrow)/(\\d+)\\.(\\d+)",
                    family_replacement: "My Internet Browser",
                    other: !0
                }, {
                    regex: "(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    family_replacement: "Opera Tablet",
                    tablet: !0
                }, {
                    regex: "(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)",
                    family_replacement: "Opera Mobile"
                }, {regex: "Opera Mobi", family_replacement: "Opera Mobile"}, {
                    regex: "(Opera Mini)/(\\d+)\\.(\\d+)",
                    family_replacement: "Opera Mini"
                }, {
                    regex: "(Opera Mini)/att/(\\d+)\\.(\\d+)",
                    family_replacement: "Opera Mini"
                }, {
                    regex: "(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    family_replacement: "Opera"
                }, {regex: "(webOSBrowser)/(\\d+)\\.(\\d+)", family_replacement: "webOS"}, {
                    regex: "(webOS)/(\\d+)\\.(\\d+)",
                    family_replacement: "webOS"
                }, {regex: "(wOSBrowser).+TouchPad/(\\d+)\\.(\\d+)", family_replacement: "webOS TouchPad"}, {
                    regex: "(luakit)",
                    family_replacement: "LuaKit",
                    other: !0
                }, {
                    regex: "(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)",
                    family_replacement: "Lightning",
                    other: !0
                }, {
                    regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)",
                    family_replacement: "Swiftfox",
                    other: !0
                }, {
                    regex: "(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)",
                    family_replacement: "Swiftfox",
                    other: !0
                }, {
                    regex: "rekonq",
                    family_replacement: "Rekonq",
                    other: !0
                }, {
                    regex: "(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
                    family_replacement: "Conkeror",
                    other: !0
                }, {
                    regex: "(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Konqueror",
                    other: !0
                }, {
                    regex: "(WeTab)-Browser",
                    family_replacement: "WeTab",
                    other: !0
                }, {
                    regex: "(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Comodo Dragon",
                    other: !0
                }, {
                    regex: "(YottaaMonitor)",
                    family_replacement: "Yottaa Monitor",
                    other: !0
                }, {regex: "(Kindle)/(\\d+)\\.(\\d+)", family_replacement: "Kindle"}, {
                    regex: "(Symphony) (\\d+).(\\d+)",
                    family_replacement: "Symphony",
                    other: !0
                }, {
                    regex: "Minimo",
                    family_replacement: "Minimo",
                    other: !0
                }, {
                    regex: "(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Chrome Mobile"
                }, {
                    regex: "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Chrome Mobile iOS"
                }, {
                    regex: "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile",
                    family_replacement: "Chrome Mobile"
                }, {
                    regex: "(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Chrome Frame"
                }, {
                    regex: "(UC Browser)(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "UC Browser",
                    other: !0
                }, {
                    regex: "(SLP Browser)/(\\d+)\\.(\\d+)",
                    family_replacement: "Tizen Browser",
                    other: !0
                }, {
                    regex: "(Epiphany)/(\\d+)\\.(\\d+).(\\d+)",
                    family_replacement: "Epiphany",
                    other: !0
                }, {
                    regex: "(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)",
                    family_replacement: "Sogou Explorer",
                    other: !0
                }, {
                    regex: "(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)",
                    family_replacement: "PingdomBot",
                    other: !0
                }, {
                    regex: "(facebookexternalhit)/(\\d+)\\.(\\d+)",
                    family_replacement: "FacebookBot"
                }, {
                    regex: "(Twitterbot)/(\\d+)\\.(\\d+)",
                    family_replacement: "TwitterBot"
                }, {regex: "(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris|UP\\.Browser|Bunjaloo|Google Earth|Raven for Mac)/(\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\\d+)\\.(\\d+)"}, {regex: "(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\\d+)\\.(\\d+)\\.?(\\d+)?"}, {
                    regex: "(Android) Donut",
                    v2_replacement: "2",
                    v1_replacement: "1"
                }, {regex: "(Android) Eclair", v2_replacement: "1", v1_replacement: "2"}, {
                    regex: "(Android) Froyo",
                    v2_replacement: "2",
                    v1_replacement: "2"
                }, {regex: "(Android) Gingerbread", v2_replacement: "3", v1_replacement: "2"}, {
                    regex: "(Android) Honeycomb",
                    v1_replacement: "3"
                }, {
                    regex: "(IEMobile)[ /](\\d+)\\.(\\d+)",
                    family_replacement: "IE Mobile"
                }, {
                    regex: "(MSIE) (\\d+)\\.(\\d+).*XBLWP7",
                    family_replacement: "IE Large Screen"
                }, {regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?"}, {
                    regex: "(Obigo)InternetBrowser",
                    other: !0
                }, {regex: "(Obigo)\\-Browser", other: !0}, {
                    regex: "(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?",
                    other: !0
                }, {
                    regex: "(MAXTHON|Maxthon) (\\d+)\\.(\\d+)",
                    family_replacement: "Maxthon",
                    other: !0
                }, {regex: "(Maxthon|MyIE2|Uzbl|Shiira)", v1_replacement: "0", other: !0}, {
                    regex: "(PLAYSTATION) (\\d+)",
                    family_replacement: "PlayStation",
                    manufacturer: "Sony"
                }, {
                    regex: "(PlayStation Portable)[^\\d]+(\\d+).(\\d+)",
                    manufacturer: "Sony"
                }, {regex: "(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)", other: !0}, {
                    regex: "(POLARIS)/(\\d+)\\.(\\d+)",
                    family_replacement: "Polaris",
                    other: !0
                }, {
                    regex: "(Embider)/(\\d+)\\.(\\d+)",
                    family_replacement: "Polaris",
                    other: !0
                }, {
                    regex: "(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Bon Echo",
                    other: !0
                }, {
                    regex: "(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPod).*Version/(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPod)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPhone).*Version/(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPhone)",
                    family_replacement: "Mobile Safari",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    tablet: !0,
                    manufacturer: "Apple"
                }, {
                    regex: "(iPad).*Version/(\\d+)\\.(\\d+)",
                    family_replacement: "Mobile Safari",
                    tablet: !0,
                    manufacturer: "Apple"
                }, {
                    regex: "(iPad)",
                    family_replacement: "Mobile Safari",
                    tablet: !0,
                    manufacturer: "Apple"
                }, {regex: "(AvantGo) (\\d+).(\\d+)", other: !0}, {
                    regex: "(Avant)",
                    v1_replacement: "1",
                    other: !0
                }, {
                    regex: "^(Nokia)",
                    family_replacement: "Nokia Services (WAP) Browser",
                    manufacturer: "Nokia"
                }, {
                    regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)",
                    manufacturer: "Nokia"
                }, {
                    regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)",
                    manufacturer: "Nokia"
                }, {
                    regex: "(NokiaBrowser)/(\\d+)\\.(\\d+)",
                    manufacturer: "Nokia"
                }, {
                    regex: "(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)",
                    family_replacement: "NokiaBrowser",
                    manufacturer: "Nokia"
                }, {
                    regex: "(Series60)/5\\.0",
                    v2_replacement: "0",
                    v1_replacement: "7",
                    family_replacement: "NokiaBrowser",
                    manufacturer: "Nokia"
                }, {
                    regex: "(Series60)/(\\d+)\\.(\\d+)",
                    family_replacement: "Nokia OSS Browser",
                    manufacturer: "Nokia"
                }, {
                    regex: "(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Nokia Series 40 Ovi Browser",
                    manufacturer: "Nokia"
                }, {
                    regex: "(Nokia)[EN]?(\\d+)",
                    manufacturer: "Nokia"
                }, {
                    regex: "(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Blackberry WebKit",
                    tablet: !0,
                    manufacturer: "Nokia"
                }, {
                    regex: "(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
                    family_replacement: "Blackberry WebKit",
                    manufacturer: "RIM"
                }, {
                    regex: "(Black[bB]erry)\\s?(\\d+)",
                    family_replacement: "Blackberry",
                    manufacturer: "RIM"
                }, {regex: "(OmniWeb)/v(\\d+)\\.(\\d+)", other: !0}, {
                    regex: "(Blazer)/(\\d+)\\.(\\d+)",
                    family_replacement: "Palm Blazer",
                    manufacturer: "Palm"
                }, {
                    regex: "(Pre)/(\\d+)\\.(\\d+)",
                    family_replacement: "Palm Pre",
                    manufacturer: "Palm"
                }, {regex: "(Links) \\((\\d+)\\.(\\d+)", other: !0}, {
                    regex: "(QtWeb) Internet Browser/(\\d+)\\.(\\d+)",
                    other: !0
                }, {
                    regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
                    other: !0,
                    tablet: !0
                }, {
                    regex: "(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Version/\\d+\\.\\d+.\\d+ Safari/",
                    family_replacement: "WebKit Nightly"
                }, {
                    regex: "(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/",
                    family_replacement: "Safari"
                }, {regex: "(Safari)/\\d+"}, {
                    regex: "(OLPC)/Update(\\d+)\\.(\\d+)",
                    other: !0
                }, {
                    regex: "(OLPC)/Update()\\.(\\d+)",
                    v1_replacement: "0",
                    other: !0
                }, {regex: "(SEMC\\-Browser)/(\\d+)\\.(\\d+)", other: !0}, {
                    regex: "(Teleca)",
                    family_replacement: "Teleca Browser",
                    other: !0
                }, {regex: "Trident(.*)rv.(\\d+)\\.(\\d+)", family_replacement: "IE"}, {
                    regex: "(MSIE) (\\d+)\\.(\\d+)",
                    family_replacement: "IE"
                }],
                os_parsers: [{regex: "(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"}, {regex: "(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"}, {
                    regex: "(Android) Donut",
                    os_v2_replacement: "2",
                    os_v1_replacement: "1"
                }, {regex: "(Android) Eclair", os_v2_replacement: "1", os_v1_replacement: "2"}, {
                    regex: "(Android) Froyo",
                    os_v2_replacement: "2",
                    os_v1_replacement: "2"
                }, {
                    regex: "(Android) Gingerbread",
                    os_v2_replacement: "3",
                    os_v1_replacement: "2"
                }, {regex: "(Android) Honeycomb", os_v1_replacement: "3"}, {
                    regex: "(Silk-Accelerated=[a-z]{4,5})",
                    os_replacement: "Android"
                }, {regex: "(Windows Phone 6\\.5)"}, {
                    regex: "(Windows (?:NT 5\\.2|NT 5\\.1))",
                    os_replacement: "Windows XP"
                }, {regex: "(XBLWP7)", os_replacement: "Windows Phone OS"}, {
                    regex: "(Windows NT 6\\.1)",
                    os_replacement: "Windows 7"
                }, {
                    regex: "(Windows NT 6\\.0)",
                    os_replacement: "Windows Vista"
                }, {regex: "(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000)"}, {
                    regex: "(Windows NT 6\\.2)",
                    os_replacement: "Windows 8"
                }, {regex: "(Windows Phone 8)", os_replacement: "Windows Phone 8"}, {
                    regex: "(Windows NT 5\\.0)",
                    os_replacement: "Windows 2000"
                }, {regex: "(Windows Phone OS) (\\d+)\\.(\\d+)"}, {
                    regex: "(Windows ?Mobile)",
                    os_replacement: "Windows Mobile"
                }, {regex: "(WinNT4.0)", os_replacement: "Windows NT 4.0"}, {
                    regex: "(Win98)",
                    os_replacement: "Windows 98"
                }, {regex: "(Tizen)/(\\d+)\\.(\\d+)", other: !0}, {
                    regex: "(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?",
                    manufacturer: "Apple"
                }, {
                    regex: "(?:PPC|Intel) (Mac OS X)",
                    manufacturer: "Apple"
                }, {
                    regex: "(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?",
                    os_replacement: "iOS",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPhone|iPad|iPod); Opera",
                    os_replacement: "iOS",
                    manufacturer: "Apple"
                }, {
                    regex: "(iPad); Opera",
                    tablet: !0,
                    manufacturer: "Apple"
                }, {
                    regex: "(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)",
                    os_replacement: "iOS",
                    manufacturer: "Apple"
                }, {
                    regex: "(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    os_replacement: "Chrome OS"
                }, {
                    regex: "(Debian)-(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    other: !0
                }, {
                    regex: "(Linux Mint)(?:/(\\d+))?",
                    other: !0
                }, {
                    regex: "(Mandriva)(?: Linux)?/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    other: !0
                }, {
                    regex: "(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)",
                    os_replacement: "Symbian OS"
                }, {
                    regex: "(Symbian/3).+NokiaBrowser/7\\.3",
                    os_replacement: "Symbian^3 Anna"
                }, {regex: "(Symbian/3).+NokiaBrowser/7\\.4", os_replacement: "Symbian^3 Belle"}, {
                    regex: "(Symbian/3)",
                    os_replacement: "Symbian^3"
                }, {regex: "(Series 60|SymbOS|S60)", os_replacement: "Symbian OS"}, {
                    regex: "(MeeGo)",
                    other: !0
                }, {
                    regex: "Symbian [Oo][Ss]",
                    os_replacement: "Symbian OS"
                }, {
                    regex: "(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    os_replacement: "BlackBerry OS",
                    manufacturer: "RIM"
                }, {
                    regex: "(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    os_replacement: "BlackBerry OS",
                    manufacturer: "RIM"
                }, {
                    regex: "(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)",
                    os_replacement: "BlackBerry Tablet OS",
                    tablet: !0,
                    manufacturer: "RIM"
                }, {
                    regex: "(Play[Bb]ook)",
                    os_replacement: "BlackBerry Tablet OS",
                    tablet: !0,
                    manufacturer: "RIM"
                }, {
                    regex: "(Black[Bb]erry)",
                    os_replacement: "Blackberry OS",
                    manufacturer: "RIM"
                }, {
                    regex: "(webOS|hpwOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
                    os_replacement: "webOS"
                }, {
                    regex: "(SUSE|Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
                    other: !0
                }, {
                    regex: "(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\\d+)\\.(\\d+)\\.(\\d+)",
                    other: !0
                }, {regex: "(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)"}, {regex: "(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)"}, {
                    regex: "(Linux|BSD)",
                    other: !0
                }],
                mobile_os_families: ["Windows Phone 6.5", "Windows CE", "Symbian OS"],
                device_parsers: [{
                    regex: "HTC ([A-Z][a-z0-9]+) Build",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC_Touch_([A-Za-z0-9]+)",
                    device_replacement: "HTC Touch ($1)",
                    manufacturer: "HTC"
                }, {
                    regex: "USCCHTC(\\d+)",
                    device_replacement: "HTC $1 (US Cellular)",
                    manufacturer: "HTC"
                }, {
                    regex: "Sprint APA(9292)",
                    device_replacement: "HTC $1 (Sprint)",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC ([A-Za-z0-9]+ [A-Z])",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC-([A-Za-z0-9]+)",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC_([A-Za-z0-9]+)",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {
                    regex: "HTC ([A-Za-z0-9]+)",
                    device_replacement: "HTC $1",
                    manufacturer: "HTC"
                }, {regex: "(ADR[A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC"}, {
                    regex: "(HTC)",
                    manufacturer: "HTC"
                }, {
                    regex: "SonyEricsson([A-Za-z0-9]+)/",
                    device_replacement: "Ericsson $1",
                    other: !0,
                    manufacturer: "Sony"
                }, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; WOWMobile (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\-update1\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build"}, {
                    regex: "NokiaN([0-9]+)",
                    device_replacement: "Nokia N$1",
                    manufacturer: "Nokia"
                }, {
                    regex: "Nokia([A-Za-z0-9\\v-]+)",
                    device_replacement: "Nokia $1",
                    manufacturer: "Nokia"
                }, {
                    regex: "NOKIA ([A-Za-z0-9\\-]+)",
                    device_replacement: "Nokia $1",
                    manufacturer: "Nokia"
                }, {
                    regex: "Nokia ([A-Za-z0-9\\-]+)",
                    device_replacement: "Nokia $1",
                    manufacturer: "Nokia"
                }, {
                    regex: "Lumia ([A-Za-z0-9\\-]+)",
                    device_replacement: "Lumia $1",
                    manufacturer: "Nokia"
                }, {
                    regex: "Symbian",
                    device_replacement: "Nokia",
                    manufacturer: "Nokia"
                }, {
                    regex: "(PlayBook).+RIM Tablet OS",
                    device_replacement: "Blackberry Playbook",
                    tablet: !0,
                    manufacturer: "RIM"
                }, {regex: "(Black[Bb]erry [0-9]+);", manufacturer: "RIM"}, {
                    regex: "Black[Bb]erry([0-9]+)",
                    device_replacement: "BlackBerry $1",
                    manufacturer: "RIM"
                }, {
                    regex: "(Pre)/(\\d+)\\.(\\d+)",
                    device_replacement: "Palm Pre",
                    manufacturer: "Palm"
                }, {
                    regex: "(Pixi)/(\\d+)\\.(\\d+)",
                    device_replacement: "Palm Pixi",
                    manufacturer: "Palm"
                }, {
                    regex: "(Touchpad)/(\\d+)\\.(\\d+)",
                    device_replacement: "HP Touchpad",
                    manufacturer: "HP"
                }, {
                    regex: "HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)",
                    device_replacement: "HP iPAQ $1",
                    manufacturer: "HP"
                }, {
                    regex: "Palm([A-Za-z0-9]+)",
                    device_replacement: "Palm $1",
                    manufacturer: "Palm"
                }, {
                    regex: "Treo([A-Za-z0-9]+)",
                    device_replacement: "Palm Treo $1",
                    manufacturer: "Palm"
                }, {
                    regex: "webOS.*(P160UNA)/(\\d+).(\\d+)",
                    device_replacement: "HP Veer",
                    manufacturer: "HP"
                }, {regex: "(Kindle Fire)", manufacturer: "Amazon"}, {
                    regex: "(Kindle)",
                    manufacturer: "Amazon"
                }, {
                    regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
                    device_replacement: "Kindle Fire",
                    tablet: !0,
                    manufacturer: "Amazon"
                }, {regex: "(iPad) Simulator;", manufacturer: "Apple"}, {
                    regex: "(iPad);",
                    manufacturer: "Apple"
                }, {regex: "(iPod);", manufacturer: "Apple"}, {
                    regex: "(iPhone) Simulator;",
                    manufacturer: "Apple"
                }, {regex: "(iPhone);", manufacturer: "Apple"}, {
                    regex: "Nexus\\ ([A-Za-z0-9\\-]+)",
                    device_replacement: "Nexus $1"
                }, {
                    regex: "acer_([A-Za-z0-9]+)_",
                    device_replacement: "Acer $1",
                    manufacturer: "Acer"
                }, {
                    regex: "acer_([A-Za-z0-9]+)_",
                    device_replacement: "Acer $1",
                    manufacturer: "Acer"
                }, {
                    regex: "Amoi\\-([A-Za-z0-9]+)",
                    device_replacement: "Amoi $1",
                    other: !0,
                    manufacturer: "Amoi"
                }, {
                    regex: "AMOI\\-([A-Za-z0-9]+)",
                    device_replacement: "Amoi $1",
                    other: !0,
                    manufacturer: "Amoi"
                }, {
                    regex: "Asus\\-([A-Za-z0-9]+)",
                    device_replacement: "Asus $1",
                    manufacturer: "Asus"
                }, {
                    regex: "ASUS\\-([A-Za-z0-9]+)",
                    device_replacement: "Asus $1",
                    manufacturer: "Asus"
                }, {
                    regex: "BIRD\\-([A-Za-z0-9]+)",
                    device_replacement: "Bird $1",
                    other: !0
                }, {
                    regex: "BIRD\\.([A-Za-z0-9]+)",
                    device_replacement: "Bird $1",
                    other: !0
                }, {regex: "BIRD ([A-Za-z0-9]+)", device_replacement: "Bird $1", other: !0}, {
                    regex: "Dell ([A-Za-z0-9]+)",
                    device_replacement: "Dell $1",
                    manufacturer: "Dell"
                }, {
                    regex: "DoCoMo/2\\.0 ([A-Za-z0-9]+)",
                    device_replacement: "DoCoMo $1",
                    other: !0
                }, {
                    regex: "([A-Za-z0-9]+)\\_W\\;FOMA",
                    device_replacement: "DoCoMo $1",
                    other: !0
                }, {
                    regex: "([A-Za-z0-9]+)\\;FOMA",
                    device_replacement: "DoCoMo $1",
                    other: !0
                }, {
                    regex: "vodafone([A-Za-z0-9]+)",
                    device_replacement: "Huawei Vodafone $1",
                    other: !0
                }, {
                    regex: "i\\-mate ([A-Za-z0-9]+)",
                    device_replacement: "i-mate $1",
                    other: !0
                }, {
                    regex: "Kyocera\\-([A-Za-z0-9]+)",
                    device_replacement: "Kyocera $1",
                    other: !0
                }, {
                    regex: "KWC\\-([A-Za-z0-9]+)",
                    device_replacement: "Kyocera $1",
                    other: !0
                }, {
                    regex: "Lenovo\\-([A-Za-z0-9]+)",
                    device_replacement: "Lenovo $1",
                    manufacturer: "Lenovo"
                }, {
                    regex: "Lenovo\\_([A-Za-z0-9]+)",
                    device_replacement: "Lenovo $1",
                    manufacturer: "Levovo"
                }, {
                    regex: "LG/([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LG-LG([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LGE-LG([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LGE VX([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LG ([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LGE LG\\-AX([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LG\\-([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LGE\\-([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "LG([A-Za-z0-9]+)",
                    device_replacement: "LG $1",
                    manufacturer: "LG"
                }, {
                    regex: "(KIN)\\.One (\\d+)\\.(\\d+)",
                    device_replacement: "Microsoft $1"
                }, {
                    regex: "(KIN)\\.Two (\\d+)\\.(\\d+)",
                    device_replacement: "Microsoft $1"
                }, {regex: "(Motorola)\\-([A-Za-z0-9]+)", manufacturer: "Motorola"}, {
                    regex: "MOTO\\-([A-Za-z0-9]+)",
                    device_replacement: "Motorola $1",
                    manufacturer: "Motorola"
                }, {
                    regex: "MOT\\-([A-Za-z0-9]+)",
                    device_replacement: "Motorola $1",
                    manufacturer: "Motorola"
                }, {
                    regex: "Philips([A-Za-z0-9]+)",
                    device_replacement: "Philips $1",
                    manufacturer: "Philips"
                }, {
                    regex: "Philips ([A-Za-z0-9]+)",
                    device_replacement: "Philips $1",
                    manufacturer: "Philips"
                }, {
                    regex: "SAMSUNG-([A-Za-z0-9\\-]+)",
                    device_replacement: "Samsung $1",
                    manufacturer: "Samsung"
                }, {
                    regex: "SAMSUNG\\; ([A-Za-z0-9\\-]+)",
                    device_replacement: "Samsung $1",
                    manufacturer: "Samsung"
                }, {
                    regex: "Softbank/1\\.0/([A-Za-z0-9]+)",
                    device_replacement: "Softbank $1",
                    other: !0
                }, {
                    regex: "Softbank/2\\.0/([A-Za-z0-9]+)",
                    device_replacement: "Softbank $1",
                    other: !0
                }, {
                    regex: "(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)",
                    device_replacement: "Generic Smartphone"
                }, {
                    regex: "^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly\\_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)",
                    device_replacement: "Generic Feature Phone"
                }, {
                    regex: "^(htcp|htcs|htct|htc\\_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)",
                    device_replacement: "Generic Feature Phone"
                }, {
                    regex: "^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)",
                    device_replacement: "Generic Feature Phone"
                }, {
                    regex: "^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda\\_)",
                    device_replacement: "Generic Feature Phone"
                }, {
                    regex: "(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks)",
                    device_replacement: "Spider"
                }],
                mobile_browser_families: ["Firefox Mobile", "Opera Mobile", "Opera Mini", "Mobile Safari", "webOS", "IE Mobile", "Playstation Portable", "Nokia", "Blackberry", "Palm", "Silk", "Android", "Maemo", "Obigo", "Netfront", "AvantGo", "Teleca", "SEMC-Browser", "Bolt", "Iris", "UP.Browser", "Symphony", "Minimo", "Bunjaloo", "Jasmine", "Dolfin", "Polaris", "BREW", "Chrome Mobile", "Chrome Mobile iOS", "UC Browser", "Tizen Browser"]
            };
            e.parsers = ["device_parsers", "browser_parsers", "os_parsers", "mobile_os_families", "mobile_browser_families"], e.types = ["browser", "os", "device"], e.regexes = r || function () {
                var r = {};
                return e.parsers.map(function (e) {
                    r[e] = []
                }), r
            }(), e.families = function () {
                var r = {};
                return e.types.map(function (e) {
                    r[e] = []
                }), r
            }();
            var a = Array.prototype, t = (Object.prototype, Function.prototype, a.forEach);
            a.indexOf;
            var n = function (e, r) {
                for (var a = {}, t = 0; r.length > t && !(a = r[t](e)); t++);
                return a
            }, o = function (e, r) {
                i(e, function (e) {
                    i(r, function (r) {
                        delete e[r]
                    })
                })
            }, i = forEach = function (e, r, a) {
                if (null != e)if (t && e.forEach === t)e.forEach(r, a); else if (e.length === +e.length)for (var n = 0, o = e.length; o > n; n++)r.call(a, e[n], n, e); else for (var i in e)_.has(e, i) && r.call(a, e[i], i, e)
            }, l = function (e) {
                return !(!e || void 0 === e || null == e)
            }, d = function (e) {
                var r = "";
                return e = e || {}, l(e) && l(e.major) && (r += e.major, l(e.minor) && (r += "." + e.minor, l(e.patch) && (r += "." + e.patch))), r
            }, c = function (e) {
                e = e || {};
                var r = d(e);
                return r && (r = " " + r), e && l(e.family) ? e.family + r : ""
            };
            return e.parse = function (r) {
                var a = function (r) {
                    return e.regexes[r + "_parsers"].map(function (e) {
                        function a(r) {
                            var a = r.match(t);
                            if (!a)return null;
                            var i = {};
                            return i.family = (n ? n.replace("$1", a[1]) : a[1]) || "other", i.major = parseInt(o ? o : a[2]) || null, i.minor = a[3] ? parseInt(a[3]) : null, i.patch = a[4] ? parseInt(a[4]) : null, i.tablet = e.tablet, i.man = e.manufacturer || null, i
                        }
    
                        var t = RegExp(e.regex), n = e[("browser" === r ? "family" : r) + "_replacement"], o = e.major_version_replacement;
                        return a
                    })
                }, t = function () {
                }, i = a("browser"), m = a("os"), s = a("device"), p = new t;
                p.source = r, p.browser = n(r, i), l(p.browser) ? (p.browser.name = c(p.browser), p.browser.version = d(p.browser)) : p.browser = {}, p.os = n(r, m), l(p.os) ? (p.os.name = c(p.os), p.os.version = d(p.os)) : p.os = {}, p.device = n(r, s), l(p.device) ? (p.device.name = c(p.device), p.device.version = d(p.device)) : p.device = {
                    tablet: !1,
                    family: "Other"
                };
                var u = {};
                return e.regexes.mobile_browser_families.map(function (e) {
                    u[e] = !0
                }), e.regexes.mobile_os_families.map(function (e) {
                    u[e] = !0
                }), p.device.type = "Spider" === p.browser.family ? "Spider" : p.browser.tablet || p.os.tablet || p.device.tablet ? "Tablet" : u.hasOwnProperty(p.browser.family) ? "Mobile" : "Desktop", p.device.manufacturer = p.browser.man || p.os.man || p.device.man || null, o([p.browser, p.os, p.device], ["tablet", "man"]), p
            }, e
        }();
        "undefined" != typeof exports ? ("undefined" != typeof module && module.exports && (exports = module.exports = r), exports.detect = r) : e.detect = r, "function" == typeof define && define.amd && define(function () {
            return r
        })
    }(window), function () {
        function e(e) {
            return !!e.exifdata
        }
    
        function r(e, r) {
            r = r || e.match(/^data\:([^\;]+)\;base64,/im)[1] || "", e = e.replace(/^data\:([^\;]+)\;base64,/gim, "");
            for (var a = atob(e), t = a.length, n = new ArrayBuffer(t), o = new Uint8Array(n), i = 0; t > i; i++)o[i] = a.charCodeAt(i);
            return n
        }
    
        function a(e, r) {
            var a = new XMLHttpRequest;
            a.open("GET", e, !0), a.responseType = "blob", a.onload = function (e) {
                (200 == this.status || 0 === this.status) && r(this.response)
            }, a.send()
        }
    
        function t(e, t) {
            function n(r) {
                var a = o(r), n = i(r);
                e.exifdata = a || {}, e.iptcdata = n || {}, t && t.call(e)
            }
    
            if (e.src)if (/^data\:/i.test(e.src)) {
                var l = r(e.src);
                n(l)
            } else if (/^blob\:/i.test(e.src)) {
                var d = new FileReader;
                d.onload = function (e) {
                    n(e.target.result)
                }, a(e.src, function (e) {
                    d.readAsArrayBuffer(e)
                })
            } else {
                var c = new XMLHttpRequest;
                c.onload = function () {
                    if (200 != this.status && 0 !== this.status)throw"Could not load image";
                    n(c.response), c = null
                }, c.open("GET", e.src, !0), c.responseType = "arraybuffer", c.send(null)
            } else if (window.FileReader && (e instanceof window.Blob || e instanceof window.File)) {
                var d = new FileReader;
                d.onload = function (e) {
                    p && console.log("Got file of length " + e.target.result.byteLength), n(e.target.result)
                }, d.readAsArrayBuffer(e)
            }
        }
    
        function o(e) {
            var r = new DataView(e);
            if (p && console.log("Got file of length " + e.byteLength), 255 != r.getUint8(0) || 216 != r.getUint8(1))return p && console.log("Not a valid JPEG"), !1;
            for (var a, t = 2, n = e.byteLength; n > t;) {
                if (255 != r.getUint8(t))return p && console.log("Not a valid marker at offset " + t + ", found: " + r.getUint8(t)), !1;
                if (a = r.getUint8(t + 1), p && console.log(a), 225 == a)return p && console.log("Found 0xFFE1 marker"), s(r, t + 4, r.getUint16(t + 2) - 2);
                t += 2 + r.getUint16(t + 2)
            }
        }
    
        function i(e) {
            var r = new DataView(e);
            if (p && console.log("Got file of length " + e.byteLength), 255 != r.getUint8(0) || 216 != r.getUint8(1))return p && console.log("Not a valid JPEG"), !1;
            for (var a = 2, t = e.byteLength, n = function (e, r) {
                return 56 === e.getUint8(r) && 66 === e.getUint8(r + 1) && 73 === e.getUint8(r + 2) && 77 === e.getUint8(r + 3) && 4 === e.getUint8(r + 4) && 4 === e.getUint8(r + 5)
            }; t > a;) {
                if (n(r, a)) {
                    var o = r.getUint8(a + 7);
                    o % 2 !== 0 && (o += 1), 0 === o && (o = 4);
                    var i = a + 8 + o, d = r.getUint16(a + 6 + o);
                    return l(e, i, d)
                }
                a++
            }
        }
    
        function l(e, r, a) {
            for (var t, n, o, i, l, d = new DataView(e), c = {}, s = r; r + a > s;)28 === d.getUint8(s) && 2 === d.getUint8(s + 1) && (i = d.getUint8(s + 2), i in y && (o = d.getInt16(s + 3), l = o + 5, n = y[i], t = m(d, s + 5, o), c.hasOwnProperty(n) ? c[n]instanceof Array ? c[n].push(t) : c[n] = [c[n], t] : c[n] = t)), s++;
            return c
        }
    
        function d(e, r, a, t, n) {
            var o, i, l, d = e.getUint16(a, !n), m = {};
            for (l = 0; d > l; l++)o = a + 12 * l + 2, i = t[e.getUint16(o, !n)], !i && p && console.log("Unknown tag: " + e.getUint16(o, !n)), m[i] = c(e, o, r, a, n);
            return m
        }
    
        function c(e, r, a, t, n) {
            var o, i, l, d, c, s, p = e.getUint16(r + 2, !n), u = e.getUint32(r + 4, !n), g = e.getUint32(r + 8, !n) + a;
            switch (p) {
                case 1:
                case 7:
                    if (1 == u)return e.getUint8(r + 8, !n);
                    for (o = u > 4 ? g : r + 8, i = [], d = 0; u > d; d++)i[d] = e.getUint8(o + d);
                    return i;
                case 2:
                    return o = u > 4 ? g : r + 8, m(e, o, u - 1);
                case 3:
                    if (1 == u)return e.getUint16(r + 8, !n);
                    for (o = u > 2 ? g : r + 8, i = [], d = 0; u > d; d++)i[d] = e.getUint16(o + 2 * d, !n);
                    return i;
                case 4:
                    if (1 == u)return e.getUint32(r + 8, !n);
                    for (i = [], d = 0; u > d; d++)i[d] = e.getUint32(g + 4 * d, !n);
                    return i;
                case 5:
                    if (1 == u)return c = e.getUint32(g, !n), s = e.getUint32(g + 4, !n), l = new Number(c / s), l.numerator = c, l.denominator = s, l;
                    for (i = [], d = 0; u > d; d++)c = e.getUint32(g + 8 * d, !n), s = e.getUint32(g + 4 + 8 * d, !n), i[d] = new Number(c / s), i[d].numerator = c, i[d].denominator = s;
                    return i;
                case 9:
                    if (1 == u)return e.getInt32(r + 8, !n);
                    for (i = [], d = 0; u > d; d++)i[d] = e.getInt32(g + 4 * d, !n);
                    return i;
                case 10:
                    if (1 == u)return e.getInt32(g, !n) / e.getInt32(g + 4, !n);
                    for (i = [], d = 0; u > d; d++)i[d] = e.getInt32(g + 8 * d, !n) / e.getInt32(g + 4 + 8 * d, !n);
                    return i
            }
        }
    
        function m(e, r, a) {
            var t = "";
            for (n = r; n < r + a; n++)t += String.fromCharCode(e.getUint8(n));
            return t
        }
    
        function s(e, r) {
            if ("Exif" != m(e, r, 4))return p && console.log("Not valid EXIF data! " + m(e, r, 4)), !1;
            var a, t, n, o, i, l = r + 6;
            if (18761 == e.getUint16(l))a = !1; else {
                if (19789 != e.getUint16(l))return p && console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"), !1;
                a = !0
            }
            if (42 != e.getUint16(l + 2, !a))return p && console.log("Not valid TIFF data! (no 0x002A)"), !1;
            var c = e.getUint32(l + 4, !a);
            if (8 > c)return p && console.log("Not valid TIFF data! (First offset less than 8)", e.getUint32(l + 4, !a)), !1;
            if (t = d(e, l, l + c, x, a), t.ExifIFDPointer) {
                o = d(e, l, l + t.ExifIFDPointer, f, a);
                for (n in o) {
                    switch (n) {
                        case"LightSource":
                        case"Flash":
                        case"MeteringMode":
                        case"ExposureProgram":
                        case"SensingMethod":
                        case"SceneCaptureType":
                        case"SceneType":
                        case"CustomRendered":
                        case"WhiteBalance":
                        case"GainControl":
                        case"Contrast":
                        case"Saturation":
                        case"Sharpness":
                        case"SubjectDistanceRange":
                        case"FileSource":
                            o[n] = b[n][o[n]];
                            break;
                        case"ExifVersion":
                        case"FlashpixVersion":
                            o[n] = String.fromCharCode(o[n][0], o[n][1], o[n][2], o[n][3]);
                            break;
                        case"ComponentsConfiguration":
                            o[n] = b.Components[o[n][0]] + b.Components[o[n][1]] + b.Components[o[n][2]] + b.Components[o[n][3]]
                    }
                    t[n] = o[n]
                }
            }
            if (t.GPSInfoIFDPointer) {
                i = d(e, l, l + t.GPSInfoIFDPointer, h, a);
                for (n in i) {
                    switch (n) {
                        case"GPSVersionID":
                            i[n] = i[n][0] + "." + i[n][1] + "." + i[n][2] + "." + i[n][3]
                    }
                    t[n] = i[n]
                }
            }
            return t
        }
    
        var p = !1, u = this, g = function (e) {
            return e instanceof g ? e : this instanceof g ? void(this.EXIFwrapped = e) : new g(e)
        };
        "undefined" != typeof exports ? ("undefined" != typeof module && module.exports && (exports = module.exports = g), exports.EXIF = g) : u.EXIF = g;
        var f = g.Tags = {
            36864: "ExifVersion",
            40960: "FlashpixVersion",
            40961: "ColorSpace",
            40962: "PixelXDimension",
            40963: "PixelYDimension",
            37121: "ComponentsConfiguration",
            37122: "CompressedBitsPerPixel",
            37500: "MakerNote",
            37510: "UserComment",
            40964: "RelatedSoundFile",
            36867: "DateTimeOriginal",
            36868: "DateTimeDigitized",
            37520: "SubsecTime",
            37521: "SubsecTimeOriginal",
            37522: "SubsecTimeDigitized",
            33434: "ExposureTime",
            33437: "FNumber",
            34850: "ExposureProgram",
            34852: "SpectralSensitivity",
            34855: "ISOSpeedRatings",
            34856: "OECF",
            37377: "ShutterSpeedValue",
            37378: "ApertureValue",
            37379: "BrightnessValue",
            37380: "ExposureBias",
            37381: "MaxApertureValue",
            37382: "SubjectDistance",
            37383: "MeteringMode",
            37384: "LightSource",
            37385: "Flash",
            37396: "SubjectArea",
            37386: "FocalLength",
            41483: "FlashEnergy",
            41484: "SpatialFrequencyResponse",
            41486: "FocalPlaneXResolution",
            41487: "FocalPlaneYResolution",
            41488: "FocalPlaneResolutionUnit",
            41492: "SubjectLocation",
            41493: "ExposureIndex",
            41495: "SensingMethod",
            41728: "FileSource",
            41729: "SceneType",
            41730: "CFAPattern",
            41985: "CustomRendered",
            41986: "ExposureMode",
            41987: "WhiteBalance",
            41988: "DigitalZoomRation",
            41989: "FocalLengthIn35mmFilm",
            41990: "SceneCaptureType",
            41991: "GainControl",
            41992: "Contrast",
            41993: "Saturation",
            41994: "Sharpness",
            41995: "DeviceSettingDescription",
            41996: "SubjectDistanceRange",
            40965: "InteroperabilityIFDPointer",
            42016: "ImageUniqueID"
        }, x = g.TiffTags = {
            256: "ImageWidth",
            257: "ImageHeight",
            34665: "ExifIFDPointer",
            34853: "GPSInfoIFDPointer",
            40965: "InteroperabilityIFDPointer",
            258: "BitsPerSample",
            259: "Compression",
            262: "PhotometricInterpretation",
            274: "Orientation",
            277: "SamplesPerPixel",
            284: "PlanarConfiguration",
            530: "YCbCrSubSampling",
            531: "YCbCrPositioning",
            282: "XResolution",
            283: "YResolution",
            296: "ResolutionUnit",
            273: "StripOffsets",
            278: "RowsPerStrip",
            279: "StripByteCounts",
            513: "JPEGInterchangeFormat",
            514: "JPEGInterchangeFormatLength",
            301: "TransferFunction",
            318: "WhitePoint",
            319: "PrimaryChromaticities",
            529: "YCbCrCoefficients",
            532: "ReferenceBlackWhite",
            306: "DateTime",
            270: "ImageDescription",
            271: "Make",
            272: "Model",
            305: "Software",
            315: "Artist",
            33432: "Copyright"
        }, h = g.GPSTags = {
            0: "GPSVersionID",
            1: "GPSLatitudeRef",
            2: "GPSLatitude",
            3: "GPSLongitudeRef",
            4: "GPSLongitude",
            5: "GPSAltitudeRef",
            6: "GPSAltitude",
            7: "GPSTimeStamp",
            8: "GPSSatellites",
            9: "GPSStatus",
            10: "GPSMeasureMode",
            11: "GPSDOP",
            12: "GPSSpeedRef",
            13: "GPSSpeed",
            14: "GPSTrackRef",
            15: "GPSTrack",
            16: "GPSImgDirectionRef",
            17: "GPSImgDirection",
            18: "GPSMapDatum",
            19: "GPSDestLatitudeRef",
            20: "GPSDestLatitude",
            21: "GPSDestLongitudeRef",
            22: "GPSDestLongitude",
            23: "GPSDestBearingRef",
            24: "GPSDestBearing",
            25: "GPSDestDistanceRef",
            26: "GPSDestDistance",
            27: "GPSProcessingMethod",
            28: "GPSAreaInformation",
            29: "GPSDateStamp",
            30: "GPSDifferential"
        }, b = g.StringValues = {
            ExposureProgram: {
                0: "Not defined",
                1: "Manual",
                2: "Normal program",
                3: "Aperture priority",
                4: "Shutter priority",
                5: "Creative program",
                6: "Action program",
                7: "Portrait mode",
                8: "Landscape mode"
            },
            MeteringMode: {
                0: "Unknown",
                1: "Average",
                2: "CenterWeightedAverage",
                3: "Spot",
                4: "MultiSpot",
                5: "Pattern",
                6: "Partial",
                255: "Other"
            },
            LightSource: {
                0: "Unknown",
                1: "Daylight",
                2: "Fluorescent",
                3: "Tungsten (incandescent light)",
                4: "Flash",
                9: "Fine weather",
                10: "Cloudy weather",
                11: "Shade",
                12: "Daylight fluorescent (D 5700 - 7100K)",
                13: "Day white fluorescent (N 4600 - 5400K)",
                14: "Cool white fluorescent (W 3900 - 4500K)",
                15: "White fluorescent (WW 3200 - 3700K)",
                17: "Standard light A",
                18: "Standard light B",
                19: "Standard light C",
                20: "D55",
                21: "D65",
                22: "D75",
                23: "D50",
                24: "ISO studio tungsten",
                255: "Other"
            },
            Flash: {
                0: "Flash did not fire",
                1: "Flash fired",
                5: "Strobe return light not detected",
                7: "Strobe return light detected",
                9: "Flash fired, compulsory flash mode",
                13: "Flash fired, compulsory flash mode, return light not detected",
                15: "Flash fired, compulsory flash mode, return light detected",
                16: "Flash did not fire, compulsory flash mode",
                24: "Flash did not fire, auto mode",
                25: "Flash fired, auto mode",
                29: "Flash fired, auto mode, return light not detected",
                31: "Flash fired, auto mode, return light detected",
                32: "No flash function",
                65: "Flash fired, red-eye reduction mode",
                69: "Flash fired, red-eye reduction mode, return light not detected",
                71: "Flash fired, red-eye reduction mode, return light detected",
                73: "Flash fired, compulsory flash mode, red-eye reduction mode",
                77: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
                79: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
                89: "Flash fired, auto mode, red-eye reduction mode",
                93: "Flash fired, auto mode, return light not detected, red-eye reduction mode",
                95: "Flash fired, auto mode, return light detected, red-eye reduction mode"
            },
            SensingMethod: {
                1: "Not defined",
                2: "One-chip color area sensor",
                3: "Two-chip color area sensor",
                4: "Three-chip color area sensor",
                5: "Color sequential area sensor",
                7: "Trilinear sensor",
                8: "Color sequential linear sensor"
            },
            SceneCaptureType: {0: "Standard", 1: "Landscape", 2: "Portrait", 3: "Night scene"},
            SceneType: {1: "Directly photographed"},
            CustomRendered: {0: "Normal process", 1: "Custom process"},
            WhiteBalance: {0: "Auto white balance", 1: "Manual white balance"},
            GainControl: {0: "None", 1: "Low gain up", 2: "High gain up", 3: "Low gain down", 4: "High gain down"},
            Contrast: {0: "Normal", 1: "Soft", 2: "Hard"},
            Saturation: {0: "Normal", 1: "Low saturation", 2: "High saturation"},
            Sharpness: {0: "Normal", 1: "Soft", 2: "Hard"},
            SubjectDistanceRange: {0: "Unknown", 1: "Macro", 2: "Close view", 3: "Distant view"},
            FileSource: {3: "DSC"},
            Components: {0: "", 1: "Y", 2: "Cb", 3: "Cr", 4: "R", 5: "G", 6: "B"}
        }, y = {
            120: "caption",
            110: "credit",
            25: "keywords",
            55: "dateCreated",
            80: "byline",
            85: "bylineTitle",
            122: "captionWriter",
            105: "headline",
            116: "copyright",
            15: "category"
        };
        g.getData = function (r, a) {
            return (r instanceof Image || r instanceof HTMLImageElement) && !r.complete ? !1 : (e(r) ? a && a.call(r) : t(r, a), !0)
        }, g.getTag = function (r, a) {
            return e(r) ? r.exifdata[a] : void 0
        }, g.getAllTags = function (r) {
            if (!e(r))return {};
            var a, t = r.exifdata, n = {};
            for (a in t)t.hasOwnProperty(a) && (n[a] = t[a]);
            return n
        }, g.pretty = function (r) {
            if (!e(r))return "";
            var a, t = r.exifdata, n = "";
            for (a in t)t.hasOwnProperty(a) && (n += "object" == typeof t[a] ? t[a]instanceof Number ? a + " : " + t[a] + " [" + t[a].numerator + "/" + t[a].denominator + "]\r\n" : a + " : [" + t[a].length + " values]\r\n" : a + " : " + t[a] + "\r\n");
            return n
        }, g.readFromBinaryFile = function (e) {
            return o(e)
        }, "function" == typeof define && define.amd && define("exif-js", [], function () {
            return g
        })
    }.call(this);
    function JPEGEncoder(r) {
        function a(r) {
            for (var a = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99], e = 0; 64 > e; e++) {
                var t = U((a[e] * r + 50) / 100);
                1 > t ? t = 1 : t > 255 && (t = 255), k[q[e]] = t
            }
            for (var n = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99], o = 0; 64 > o; o++) {
                var i = U((n[o] * r + 50) / 100);
                1 > i ? i = 1 : i > 255 && (i = 255), p[q[o]] = i
            }
            for (var c = [1, 1.387039845, 1.306562965, 1.175875602, 1, .785694958, .5411961, .275899379], f = 0, s = 0; 8 > s; s++)for (var v = 0; 8 > v; v++)M[f] = 1 / (k[q[f]] * c[s] * c[v] * 8), j[f] = 1 / (p[q[f]] * c[s] * c[v] * 8), f++
        }
    
        function e(r, a) {
            for (var e = 0, t = 0, n = new Array, o = 1; 16 >= o; o++) {
                for (var i = 1; i <= r[o]; i++)n[a[t]] = [], n[a[t]][0] = e, n[a[t]][1] = o, t++, e++;
                e *= 2
            }
            return n
        }
    
        function t() {
            y = e(z, G), L = e(S, F), I = e(J, Q), A = e(K, V)
        }
    
        function n() {
            for (var r = 1, a = 2, e = 1; 15 >= e; e++) {
                for (var t = r; a > t; t++)C[32767 + t] = e, E[32767 + t] = [], E[32767 + t][1] = e, E[32767 + t][0] = t;
                for (var n = -(a - 1); -r >= n; n++)C[32767 + n] = e, E[32767 + n] = [], E[32767 + n][1] = e, E[32767 + n][0] = a - 1 + n;
                r <<= 1, a <<= 1
            }
        }
    
        function o() {
            for (var r = 0; 256 > r; r++)_[r] = 19595 * r, _[r + 256 >> 0] = 38470 * r, _[r + 512 >> 0] = 7471 * r + 32768, _[r + 768 >> 0] = -11059 * r, _[r + 1024 >> 0] = -21709 * r, _[r + 1280 >> 0] = 32768 * r + 8421375, _[r + 1536 >> 0] = -27439 * r, _[r + 1792 >> 0] = -5329 * r
        }
    
        function i(r) {
            for (var a = r[0], e = r[1] - 1; e >= 0;)a & 1 << e && (H |= 1 << O), e--, O--, 0 > O && (255 == H ? (c(255), c(0)) : c(H), O = 7, H = 0)
        }
    
        function c(r) {
            P.push(B[r])
        }
    
        function f(r) {
            c(r >> 8 & 255), c(255 & r)
        }
    
        function s(r, a) {
            var e, t, n, o, i, c, f, s, v, h = 0;
            const u = 8, d = 64;
            for (v = 0; u > v; ++v) {
                e = r[h], t = r[h + 1], n = r[h + 2], o = r[h + 3], i = r[h + 4], c = r[h + 5], f = r[h + 6], s = r[h + 7];
                var g = e + s, l = e - s, w = t + f, m = t - f, b = n + c, y = n - c, L = o + i, I = o - i, A = g + L, R = g - L, U = w + b, k = w - b;
                r[h] = A + U, r[h + 4] = A - U;
                var p = .707106781 * (k + R);
                r[h + 2] = R + p, r[h + 6] = R - p, A = I + y, U = y + m, k = m + l;
                var M = .382683433 * (A - k), j = .5411961 * A + M, E = 1.306562965 * k + M, C = .707106781 * U, x = l + C, P = l - C;
                r[h + 5] = P + j, r[h + 3] = P - j, r[h + 1] = x + E, r[h + 7] = x - E, h += 8
            }
            for (h = 0, v = 0; u > v; ++v) {
                e = r[h], t = r[h + 8], n = r[h + 16], o = r[h + 24], i = r[h + 32], c = r[h + 40], f = r[h + 48], s = r[h + 56];
                var H = e + s, O = e - s, T = t + f, W = t - f, N = n + c, B = n - c, _ = o + i, q = o - i, z = H + _, G = H - _, J = T + N, Q = T - N;
                r[h] = z + J, r[h + 32] = z - J;
                var S = .707106781 * (Q + G);
                r[h + 16] = G + S, r[h + 48] = G - S, z = q + B, J = B + W, Q = W + O;
                var F = .382683433 * (z - Q), K = .5411961 * z + F, V = 1.306562965 * Q + F, X = .707106781 * J, Y = O + X, Z = O - X;
                r[h + 40] = Z + K, r[h + 24] = Z - K, r[h + 8] = Y + V, r[h + 56] = Y - V, h++
            }
            var $;
            for (v = 0; d > v; ++v)$ = r[v] * a[v], D[v] = $ > 0 ? $ + .5 | 0 : $ - .5 | 0;
            return D
        }
    
        function v() {
            f(65504), f(16), c(74), c(70), c(73), c(70), c(0), c(1), c(1), c(0), f(1), f(1), c(0), c(0)
        }
    
        function h(r, a) {
            f(65472), f(17), c(8), f(a), f(r), c(3), c(1), c(17), c(0), c(2), c(17), c(1), c(3), c(17), c(1)
        }
    
        function u() {
            f(65499), f(132), c(0);
            for (var r = 0; 64 > r; r++)c(k[r]);
            c(1);
            for (var a = 0; 64 > a; a++)c(p[a])
        }
    
        function d() {
            f(65476), f(418), c(0);
            for (var r = 0; 16 > r; r++)c(z[r + 1]);
            for (var a = 0; 11 >= a; a++)c(G[a]);
            c(16);
            for (var e = 0; 16 > e; e++)c(J[e + 1]);
            for (var t = 0; 161 >= t; t++)c(Q[t]);
            c(1);
            for (var n = 0; 16 > n; n++)c(S[n + 1]);
            for (var o = 0; 11 >= o; o++)c(F[o]);
            c(17);
            for (var i = 0; 16 > i; i++)c(K[i + 1]);
            for (var s = 0; 161 >= s; s++)c(V[s])
        }
    
        function g() {
            f(65498), f(12), c(3), c(1), c(0), c(2), c(17), c(3), c(17), c(0), c(63), c(0)
        }
    
        function l(r, a, e, t, n) {
            var o, c = n[0], f = n[240];
            const v = 16, h = 63, u = 64;
            for (var d = s(r, a), g = 0; u > g; ++g)x[q[g]] = d[g];
            var l = x[0] - e;
            e = x[0], 0 == l ? i(t[0]) : (o = 32767 + l, i(t[C[o]]), i(E[o]));
            for (var w = 63; w > 0 && 0 == x[w]; w--);
            if (0 == w)return i(c), e;
            for (var m, b = 1; w >= b;) {
                for (var y = b; 0 == x[b] && w >= b; ++b);
                var L = b - y;
                if (L >= v) {
                    m = L >> 4;
                    for (var I = 1; m >= I; ++I)i(f);
                    L = 15 & L
                }
                o = 32767 + x[b], i(n[(L << 4) + C[o]]), i(E[o]), b++
            }
            return w != h && i(c), e
        }
    
        function w() {
            for (var r = String.fromCharCode, a = 0; 256 > a; a++)B[a] = r(a)
        }
    
        function m(r) {
            if (0 >= r && (r = 1), r > 100 && (r = 100), R != r) {
                var e = 0;
                e = Math.floor(50 > r ? 5e3 / r : 200 - 2 * r), a(e), R = r, console.log("Quality set to: " + r + "%")
            }
        }
    
        function b() {
            var a = (new Date).getTime();
            r || (r = 50), w(), t(), n(), o(), m(r);
            var e = (new Date).getTime() - a;
            console.log("Initialization " + e + "ms")
        }
    
        var y, L, I, A, R, U = (Math.round, Math.floor), k = new Array(64), p = new Array(64), M = new Array(64), j = new Array(64), E = new Array(65535), C = new Array(65535), D = new Array(64), x = new Array(64), P = [], H = 0, O = 7, T = new Array(64), W = new Array(64), N = new Array(64), B = new Array(256), _ = new Array(2048), q = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63], z = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], G = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], J = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125], Q = [1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250], S = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], F = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], K = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119], V = [0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, 50, 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, 243, 244, 245, 246, 247, 248, 249, 250];
        this.encode = function (r, a, e) {
            var t = (new Date).getTime();
            a && m(a), P = new Array, H = 0, O = 7, f(65496), v(), u(), h(r.width, r.height), d(), g();
            var n = 0, o = 0, c = 0;
            H = 0, O = 7, this.encode.displayName = "_encode_";
            for (var s, w, b, R, U, k, p, E, C, D = r.data, x = r.width, B = r.height, q = 4 * x, z = 0; B > z;) {
                for (s = 0; q > s;) {
                    for (U = q * z + s, k = U, p = -1, E = 0, C = 0; 64 > C; C++)E = C >> 3, p = 4 * (7 & C), k = U + E * q + p, z + E >= B && (k -= q * (z + 1 + E - B)), s + p >= q && (k -= s + p - q + 4), w = D[k++], b = D[k++], R = D[k++], T[C] = (_[w] + _[b + 256 >> 0] + _[R + 512 >> 0] >> 16) - 128, W[C] = (_[w + 768 >> 0] + _[b + 1024 >> 0] + _[R + 1280 >> 0] >> 16) - 128, N[C] = (_[w + 1280 >> 0] + _[b + 1536 >> 0] + _[R + 1792 >> 0] >> 16) - 128;
                    n = l(T, M, n, y, I), o = l(W, j, o, L, A), c = l(N, j, c, L, A), s += 32
                }
                z += 8
            }
            if (O >= 0) {
                var G = [];
                G[1] = O + 1, G[0] = (1 << O + 1) - 1, i(G)
            }
            if (f(65497), e) {
                for (var J = P.length, Q = new Uint8Array(J), S = 0; J > S; S++)Q[S] = P[S].charCodeAt();
                P = [];
                var F = (new Date).getTime() - t;
                return console.log("Encoding time: " + F + "ms"), Q
            }
            var K = "data:image/jpeg;base64," + btoa(P.join(""));
            P = [];
            var F = (new Date).getTime() - t;
            return console.log("Encoding time: " + F + "ms"), K
        }, b()
    }
    !function () {
        function r(r) {
            var a = r.naturalWidth, e = r.naturalHeight;
            if (a * e > 1048576) {
                var t = document.createElement("canvas");
                t.width = t.height = 1;
                var n = t.getContext("2d");
                return n.drawImage(r, -a + 1, 0), 0 === n.getImageData(0, 0, 1, 1).data[3]
            }
            return !1
        }
    
        function a(r, a, e) {
            var t = document.createElement("canvas");
            t.width = 1, t.height = e;
            var n = t.getContext("2d");
            n.drawImage(r, 0, 0);
            for (var o = n.getImageData(0, 0, 1, e).data, i = 0, c = e, f = e; f > i;) {
                var s = o[4 * (f - 1) + 3];
                0 === s ? c = f : i = f, f = c + i >> 1
            }
            var v = f / e;
            return 0 === v ? 1 : v
        }
    
        function e(r, a, e) {
            var n = document.createElement("canvas");
            return t(r, n, a, e), n.toDataURL("image/jpeg", a.quality || .8)
        }
    
        function t(e, t, o, i) {
            var c = e.naturalWidth, f = e.naturalHeight;
            if (c + f) {
                var s = o.width, v = o.height, h = t.getContext("2d");
                h.save(), n(t, h, s, v, o.orientation);
                var u = r(e);
                u && (c /= 2, f /= 2);
                var d = 1024, g = document.createElement("canvas");
                g.width = g.height = d;
                for (var l = g.getContext("2d"), w = i ? a(e, c, f) : 1, m = Math.ceil(d * s / c), b = Math.ceil(d * v / f / w), y = 0, L = 0; f > y;) {
                    for (var I = 0, A = 0; c > I;)l.clearRect(0, 0, d, d), l.drawImage(e, -I, -y), h.drawImage(g, 0, 0, d, d, A, L, m, b), I += d, A += m;
                    y += d, L += b
                }
                h.restore(), g = l = null
            }
        }
    
        function n(r, a, e, t, n) {
            switch (n) {
                case 5:
                case 6:
                case 7:
                case 8:
                    r.width = t, r.height = e;
                    break;
                default:
                    r.width = e, r.height = t
            }
            switch (n) {
                case 2:
                    a.translate(e, 0), a.scale(-1, 1);
                    break;
                case 3:
                    a.translate(e, t), a.rotate(Math.PI);
                    break;
                case 4:
                    a.translate(0, t), a.scale(1, -1);
                    break;
                case 5:
                    a.rotate(.5 * Math.PI), a.scale(1, -1);
                    break;
                case 6:
                    a.rotate(.5 * Math.PI), a.translate(0, -t);
                    break;
                case 7:
                    a.rotate(.5 * Math.PI), a.translate(e, -t), a.scale(-1, 1);
                    break;
                case 8:
                    a.rotate(-.5 * Math.PI), a.translate(-e, 0)
            }
        }
    
        function o(r) {
            if (window.Blob && r instanceof Blob) {
                if (!i)throw Error("No createObjectURL function found to create blob url");
                var a = new Image;
                a.src = i.createObjectURL(r), this.blob = r, r = a
            }
            if (!r.naturalWidth && !r.naturalHeight) {
                var e = this;
                r.onload = r.onerror = function () {
                    var r = e.imageLoadListeners;
                    if (r) {
                        e.imageLoadListeners = null;
                        for (var a = 0, t = r.length; t > a; a++)r[a]()
                    }
                }, this.imageLoadListeners = []
            }
            this.srcImage = r
        }
    
        var i = window.URL && window.URL.createObjectURL ? window.URL : window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;
        o.prototype.render = function (r, a, n) {
            if (this.imageLoadListeners) {
                var o = this;
                return void this.imageLoadListeners.push(function () {
                    o.render(r, a, n)
                })
            }
            a = a || {};
            var c = this.srcImage.naturalWidth, f = this.srcImage.naturalHeight, s = a.width, v = a.height, h = a.maxWidth, u = a.maxHeight, d = !this.blob || "image/jpeg" === this.blob.type;
            s && !v ? v = f * s / c << 0 : v && !s ? s = c * v / f << 0 : (s = c, v = f), h && s > h && (s = h, v = f * s / c << 0), u && v > u && (v = u, s = c * v / f << 0);
            var g = {width: s, height: v};
            for (var l in a)g[l] = a[l];
            var w = r.tagName.toLowerCase();
            "img" === w ? r.src = e(this.srcImage, g, d) : "canvas" === w && t(this.srcImage, r, g, d), "function" == typeof this.onrender && this.onrender(r), n && n(), this.blob && (this.blob = null, i.revokeObjectURL(this.srcImage.src))
        }, "function" == typeof define && define.amd ? define([], function () {
            return o
        }) : this.MegaPixImage = o
    }();
    !function () {
        function e(e, t) {
            this.file = e, this.defaults = {quality: .7, done: null, fail: null, before: null, always: null};
            for (var a in t)this.defaults[a] = t[a];
            this.defaults.quality > 1 && (this.defaults.quality = 1), this.results = {
                origin: null,
                base64: null,
                base64Len: null
            }, this.init()
        }
    
        window.URL = window.URL || window.webkitURL;
        var t = detect.parse(navigator.userAgent);
        e.prototype = {
            constructor: e, init: function () {
                var e = this;
                if ("undefined" == typeof window.URL || "function" != typeof document.createElement("canvas").getContext) {
                    var t = new Error("不支持此设备");
                    return "function" == typeof e.defaults.fail && e.defaults.fail(t), void("function" == typeof e.defaults.always && e.defaults.always())
                }
                e.create(e.file)
            }, create: function (e) {
                var a = this, i = new Image, n = a.results, s = "string" == typeof e ? e : URL.createObjectURL(e);
                i.crossOrigin = "*", i.onerror = function () {
                    var e = new Error("图片加载失败");
                    "function" == typeof a.defaults.fail && a.defaults.fail(e), "function" == typeof a.defaults.always && a.defaults.always()
                }, i.onload = function () {
                    function l(e) {
                        canvas = null, i = null, URL.revokeObjectURL(s), e.base64Len = e.base64.length, "function" == typeof a.defaults.done && a.defaults.done(e), "function" == typeof a.defaults.always && a.defaults.always()
                    }
    
                    EXIF.getData(i, function () {
                        var s, r = EXIF.getTag(this, "Orientation"), o = a.resize(this, r), h = document.createElement("canvas");
                        if (h.width = o.w, h.height = o.h, s = h.getContext("2d"), s.fillStyle = "#fff", s.fillRect(0, 0, o.w, o.h), n.origin = e, "iOS" === t.os.family && parseInt(t.os.version) < 8) {
                            var f = new MegaPixImage(i);
                            "5678".indexOf(r) > -1 ? f.render(h, {
                                width: h.height,
                                height: h.width,
                                orientation: r
                            }) : f.render(h, {
                                width: h.width,
                                height: h.height,
                                orientation: r
                            }), n.base64 = h.toDataURL("image/jpeg", a.defaults.quality), l(n)
                        } else {
                            switch (r) {
                                case 3:
                                    s.rotate(180 * Math.PI / 180), s.drawImage(i, -o.w, -o.h, o.w, o.h);
                                    break;
                                case 6:
                                    s.rotate(90 * Math.PI / 180), s.drawImage(i, 0, -o.w, o.h, o.w);
                                    break;
                                case 8:
                                    s.rotate(270 * Math.PI / 180), s.drawImage(i, -o.h, 0, o.h, o.w);
                                    break;
                                case 2:
                                    s.translate(o.w, 0), s.scale(-1, 1), s.drawImage(i, 0, 0, o.w, o.h);
                                    break;
                                case 4:
                                    s.translate(o.w, 0), s.scale(-1, 1), s.rotate(180 * Math.PI / 180), s.drawImage(i, -o.w, -o.h, o.w, o.h);
                                    break;
                                case 5:
                                    s.translate(o.w, 0), s.scale(-1, 1), s.rotate(90 * Math.PI / 180), s.drawImage(i, 0, -o.w, o.h, o.w);
                                    break;
                                case 7:
                                    s.translate(o.w, 0), s.scale(-1, 1), s.rotate(270 * Math.PI / 180), s.drawImage(i, -o.h, 0, o.h, o.w);
                                    break;
                                default:
                                    s.drawImage(i, 0, 0, o.w, o.h)
                            }
                            if ("Android" === t.os.family && t.os.version.slice(0, 3) < 4.5) {
                                var w = new JPEGEncoder;
                                n.base64 = w.encode(s.getImageData(0, 0, h.width, h.height), 100 * a.defaults.quality)
                            } else n.base64 = h.toDataURL("image/jpeg", a.defaults.quality);
                            l(n)
                        }
                    })
                }, "function" == typeof this.defaults.before && this.defaults.before(), i.src = s
            }, resize: function (e, t) {
                var a = this.defaults.width, i = this.defaults.height, n = {w: e.width, h: e.height};
                "5678".indexOf(t) > -1 && (n.w = e.height, n.h = e.width);
                var s = n.w / n.h;
                return a && i ? s >= a / i ? n.w > a && (n.w = a, n.h = Math.ceil(a / s)) : n.h > i && (n.h = i, n.w = Math.ceil(i * s)) : a ? (n.w = a, n.h = Math.ceil(a / s)) : i && (n.w = Math.ceil(i * s), n.h = i), (n.w >= 3264 || n.h >= 2448) && (n.w *= .8, n.h *= .8), n
            }
        }, window.lrz = function (t, a) {
            return new e(t, a)
        }
    }();

    注:当上传的图片被分割时,手机游览器设置一下即可,换成手机版或者电脑版。

    其中一些上传到某个地点,云或本地的,我使用的是OpenSNS的一些他们有的的内部函数,有不懂的,可以下个OpenSNS或者留言给我,我可以把所有代码发出来或者详解下。

    你可能感兴趣的:(手机,压缩,图片,上传,兼容)