; ( function ( window , document , undefined ) { var tests = [ ] ; class access var ModernizrProto = { _version : '3.3.1' , _config : { 'classPrefix' : '' , 'enableClasses' : true , 'enableJSClass' : true , 'usePrefixes' : true } , _q : [ ] , on : function ( test , cb ) { var self = this ; setTimeout ( function ( ) { cb ( self [ test ] ) ; } , 0 ) ; } , addTest : function ( name , fn , options ) { tests . push ( { name : name , fn : fn , options : options } ) ; } , addAsyncTest : function ( fn ) { tests . push ( { name : null , fn : fn } ) ; } } ; var Modernizr = function ( ) { } ; Modernizr . prototype = ModernizrProto ; Modernizr = new Modernizr ( ) ; var classes = [ ] ; access function param { * } obj param { string } type returns { boolean } function is ( obj , type ) { return typeof obj === type ; } ; access function testRunner ( ) { var featureNames ; var feature ; var aliasIdx ; var result ; var nameIdx ; var featureName ; var featureNameSplit ; for ( var featureIdx in tests ) { if ( tests . hasOwnProperty ( featureIdx ) ) { featureNames = [ ] ; feature = tests [ featureIdx ] ; if ( feature . name ) { featureNames . push ( feature . name . toLowerCase ( ) ) ; if ( feature . options && feature . options . aliases && feature . options . aliases . length ) { for ( aliasIdx = 0 ; aliasIdx < feature . options . aliases . length ; aliasIdx ++ ) { featureNames . push ( feature . options . aliases [ aliasIdx ] . toLowerCase ( ) ) ; } } } result = is ( feature . fn , 'function' ) ? feature . fn ( ) : feature . fn ; for ( nameIdx = 0 ; nameIdx < featureNames . length ; nameIdx ++ ) { featureName = featureNames [ nameIdx ] ; featureNameSplit = featureName . split ( '.' ) ; if ( featureNameSplit . length === 1 ) { Modernizr [ featureNameSplit [ 0 ] ] = result ; } else { if ( Modernizr [ featureNameSplit [ 0 ] ] && ! ( Modernizr [ featureNameSplit [ 0 ] ] instanceof Boolean ) ) { Modernizr [ featureNameSplit [ 0 ] ] = new Boolean ( Modernizr [ featureNameSplit [ 0 ] ] ) ; } Modernizr [ featureNameSplit [ 0 ] ] [ featureNameSplit [ 1 ] ] = result ; } classes . push ( ( result ? '' : 'no-' ) + featureNameSplit . join ( '-' ) ) ; } } } } ; Modernizr . addTest ( 'blobconstructor' , function ( ) { try { return ! ! new Blob ( ) ; } catch ( e ) { return false ; } } , { aliases : [ 'blob-constructor' ] } ) ; Modernizr . addTest ( 'eventlistener' , 'addEventListener' in window ) ; access returns { string } var omPrefixes = 'Moz O ms Webkit' ; var cssomPrefixes = ( ModernizrProto . _config . usePrefixes ? omPrefixes . split ( ' ' ) : [ ] ) ; ModernizrProto . _cssomPrefixes = cssomPrefixes ; access function param { string } str param { string } substr returns { boolean } function contains ( str , substr ) { return ! ! ~ ( '' + str ) . indexOf ( substr ) ; } ; access returns { HTMLElement | SVGElement } var docElement = document . documentElement ; access returns { boolean } var isSVG = docElement . nodeName . toLowerCase ( ) === 'svg' ; access function returns { HTMLElement | SVGElement } function createElement ( ) { if ( typeof document . createElement !== 'function' ) { return document . createElement ( arguments [ 0 ] ) ; } else if ( isSVG ) { return document . createElementNS . call ( document , 'http://www.w3.org/2000/svg' , arguments [ 0 ] ) ; } else { return document . createElement . apply ( document , arguments ) ; } } ; access var modElem = { elem : createElement ( 'modernizr' ) } ; Modernizr . _q . push ( function ( ) { delete modElem . elem ; } ) ; var mStyle = { style : modElem . elem . style } ; Modernizr . _q . unshift ( function ( ) { delete mStyle . style ; } ) ; access function returns { HTMLElement | SVGElement } function getBody ( ) { var body = document . body ; if ( ! body ) { body = createElement ( isSVG ? 'svg' : 'body' ) ; body . fake = true ; } return body ; } ; access function param { string } rule param { function } callback param { number } nodes param { string [ ] } testnames returns { boolean } function injectElementWithStyles ( rule , callback , nodes , testnames ) { var mod = 'modernizr' ; var style ; var ret ; var node ; var docOverflow ; var div = createElement ( 'div' ) ; var body = getBody ( ) ; if ( parseInt ( nodes , 10 ) ) { while ( nodes -- ) { node = createElement ( 'div' ) ; node . id = testnames ? testnames [ nodes ] : mod + ( nodes + 1 ) ; div . appendChild ( node ) ; } } style = createElement ( 'style' ) ; style . type = 'text/css' ; style . id = 's' + mod ; ( ! body . fake ? div : body ) . appendChild ( style ) ; body . appendChild ( div ) ; if ( style . styleSheet ) { style . styleSheet . cssText = rule ; } else { style . appendChild ( document . createTextNode ( rule ) ) ; } div . id = mod ; if ( body . fake ) { body . style . background = '' ; body . style . overflow = 'hidden' ; docOverflow = docElement . style . overflow ; docElement . style . overflow = 'hidden' ; docElement . appendChild ( body ) ; } ret = callback ( div , rule ) ; if ( body . fake ) { body . parentNode . removeChild ( body ) ; docElement . style . overflow = docOverflow ; docElement . offsetHeight ; } else { div . parentNode . removeChild ( div ) ; } return ! ! ret ; } ; access function param { string } name returns { string } function domToCSS ( name ) { return name . replace ( /([A-Z])/g , function ( str , m1 ) { return '-' + m1 . toLowerCase ( ) ; } ) . replace ( /^ms-/ , '-ms-' ) ; } ; access function param { array } props param { string } value supports returns { boolean | undefined } supports function nativeTestProps ( props , value ) { var i = props . length ; if ( 'CSS' in window && 'supports' in window . CSS ) { while ( i -- ) { if ( window . CSS . supports ( domToCSS ( props [ i ] ) , value ) ) { return true ; } } return false ; } else if ( 'CSSSupportsRule' in window ) { var conditionText = [ ] ; while ( i -- ) { conditionText . push ( '(' + domToCSS ( props [ i ] ) + ':' + value + ')' ) ; } conditionText = conditionText . join ( ' or ' ) ; return injectElementWithStyles ( '@supports (' + conditionText + ') { #modernizr { position: absolute; } }' , function ( node ) { return getComputedStyle ( node , null ) . position == 'absolute' ; } ) ; } return undefined ; } ; access function param { string } name returns { string } function cssToDOM ( name ) { return name . replace ( /([a-z])-([a-z])/g , function ( str , m1 , m2 ) { return m1 + m2 . toUpperCase ( ) ; } ) . replace ( /^-/ , '' ) ; } ; function testProps ( props , prefixed , value , skipValueTest ) { skipValueTest = is ( skipValueTest , 'undefined' ) ? false : skipValueTest ; if ( ! is ( value , 'undefined' ) ) { var result = nativeTestProps ( props , value ) ; if ( ! is ( result , 'undefined' ) ) { return result ; } } var afterInit , i , propsLength , prop , before ; var elems = [ 'modernizr' , 'tspan' ] ; while ( ! mStyle . style ) { afterInit = true ; mStyle . modElem = createElement ( elems . shift ( ) ) ; mStyle . style = mStyle . modElem . style ; } function cleanElems ( ) { if ( afterInit ) { delete mStyle . style ; delete mStyle . modElem ; } } propsLength = props . length ; for ( i = 0 ; i < propsLength ; i ++ ) { prop = props [ i ] ; before = mStyle . style [ prop ] ; if ( contains ( prop , '-' ) ) { prop = cssToDOM ( prop ) ; } if ( mStyle . style [ prop ] !== undefined ) { if ( ! skipValueTest && ! is ( value , 'undefined' ) ) { try { mStyle . style [ prop ] = value ; } catch ( e ) { } if ( mStyle . style [ prop ] != before ) { cleanElems ( ) ; return prefixed == 'pfx' ? prop : true ; } } else { cleanElems ( ) ; return prefixed == 'pfx' ? prop : true ; } } } cleanElems ( ) ; return false ; } ; memberof name optionName optionProp access example var domPrefixes = ( ModernizrProto . _config . usePrefixes ? omPrefixes . toLowerCase ( ) . split ( ' ' ) : [ ] ) ; ModernizrProto . _domPrefixes = domPrefixes ; access function param { function } fn param { object } that returns { function } function fnBind ( fn , that ) { return function ( ) { return fn . apply ( that , arguments ) ; } ; } ; access function param { array . < string > } props param { object } obj param { boolean | object } elem function testDOMProps ( props , obj , elem ) { var item ; for ( var i in props ) { if ( props [ i ] in obj ) { if ( elem === false ) { return props [ i ] ; } item = obj [ props [ i ] ] ; if ( is ( item , 'function' ) ) { return fnBind ( item , elem || obj ) ; } return item ; } } return false ; } ; access function param { string } prop param { string | object } prefixed param { HTMLElement | SVGElement } elem param { string } value param { boolean } skipValueTest function testPropsAll ( prop , prefixed , elem , value , skipValueTest ) { var ucProp = prop . charAt ( 0 ) . toUpperCase ( ) + prop . slice ( 1 ) , props = ( prop + ' ' + cssomPrefixes . join ( ucProp + ' ' ) + ucProp ) . split ( ' ' ) ; if ( is ( prefixed , 'string' ) || is ( prefixed , 'undefined' ) ) { return testProps ( props , prefixed , value , skipValueTest ) ; } else { props = ( prop + ' ' + ( domPrefixes ) . join ( ucProp + ' ' ) + ucProp ) . split ( ' ' ) ; return testDOMProps ( props , prefixed , elem ) ; } } ModernizrProto . testAllProps = testPropsAll ; memberof name optionName optionProp access function param { string } prop returns { string | boolean } example var atRule = function ( prop ) { var length = prefixes . length ; var cssrule = window . CSSRule ; var rule ; if ( typeof cssrule === 'undefined' ) { return undefined ; } if ( ! prop ) { return false ; } prop = prop . replace ( /^@/ , '' ) ; rule = prop . replace ( /-/g , '_' ) . toUpperCase ( ) + '_RULE' ; if ( rule in cssrule ) { return '@' + prop ; } for ( var i = 0 ; i < length ; i ++ ) { var prefix = prefixes [ i ] ; var thisRule = prefix . toUpperCase ( ) + '_' + rule ; if ( thisRule in cssrule ) { return '@-' + prefix . toLowerCase ( ) + '-' + prop ; } } return false ; } ; ModernizrProto . atRule = atRule ; memberof name optionName optionProp access function param { string } prop param { object } obj param { HTMLElement } elem returns { string | false } example var prefixed = ModernizrProto . prefixed = function ( prop , obj , elem ) { if ( prop . indexOf ( '@' ) === 0 ) { return atRule ( prop ) ; } if ( prop . indexOf ( '-' ) != - 1 ) { prop = cssToDOM ( prop ) ; } if ( ! obj ) { return testPropsAll ( prop , 'pfx' ) ; } else { return testPropsAll ( prop , obj , elem ) ; } } ; var indexeddb ; try { indexeddb = prefixed ( 'indexedDB' , window ) ; } catch ( e ) { } Modernizr . addTest ( 'indexeddb' , ! ! indexeddb ) ; if ( ! ! indexeddb ) { Modernizr . addTest ( 'indexeddb.deletedatabase' , 'deleteDatabase' in indexeddb ) ; } ; author kangax
     *  access function param { object } object param { string } property returns { boolean } var hasOwnProp ; ( function ( ) { var _hasOwnProperty = ( { } ) . hasOwnProperty ; if ( ! is ( _hasOwnProperty , 'undefined' ) && ! is ( _hasOwnProperty . call , 'undefined' ) ) { hasOwnProp = function ( object , property ) { return _hasOwnProperty . call ( object , property ) ; } ; } else { hasOwnProp = function ( object , property ) { return ( ( property in object ) && is ( object . constructor . prototype [ property ] , 'undefined' ) ) ; } ; } } ) ( ) ; access function param { string [ ] } classes function setClasses ( classes ) { var className = docElement . className ; var classPrefix = Modernizr . _config . classPrefix || '' ; if ( isSVG ) { className = className . baseVal ; } if ( Modernizr . _config . enableJSClass ) { var reJS = new RegExp ( '(^|\\s)' + classPrefix + 'no-js(\\s|$)' ) ; className = className . replace ( reJS , '$1' + classPrefix + 'js$2' ) ; } if ( Modernizr . _config . enableClasses ) { className += ' ' + classPrefix + classes . join ( ' ' + classPrefix ) ; isSVG ? docElement . className . baseVal = className : docElement . className = className ; } } ; ModernizrProto . _l = { } ; memberof name access function param { string } feature param { function } cb example ModernizrProto . on = function ( feature , cb ) { if ( ! this . _l [ feature ] ) { this . _l [ feature ] = [ ] ; } this . _l [ feature ] . push ( cb ) ; if ( Modernizr . hasOwnProperty ( feature ) ) { setTimeout ( function ( ) { Modernizr . _trigger ( feature , Modernizr [ feature ] ) ; } , 0 ) ; } } ; memberof name access function param { string } feature param { function | boolean } res ModernizrProto . _trigger = function ( feature , res ) { if ( ! this . _l [ feature ] ) { return ; } var cbs = this . _l [ feature ] ; setTimeout ( function ( ) { var i , cb ; for ( i = 0 ; i < cbs . length ; i ++ ) { cb = cbs [ i ] ; cb ( res ) ; } } , 0 ) ; delete this . _l [ feature ] ; } ; memberof name optionName optionProp access function param { string | object } feature param { function | boolean } test example function addTest ( feature , test ) { if ( typeof feature == 'object' ) { for ( var key in feature ) { if ( hasOwnProp ( feature , key ) ) { addTest ( key , feature [ key ] ) ; } } } else { feature = feature . toLowerCase ( ) ; var featureNameSplit = feature . split ( '.' ) ; var last = Modernizr [ featureNameSplit [ 0 ] ] ; if ( featureNameSplit . length == 2 ) { last = last [ featureNameSplit [ 1 ] ] ; } if ( typeof last != 'undefined' ) { return Modernizr ; } test = typeof test == 'function' ? test ( ) : test ; if ( featureNameSplit . length == 1 ) { Modernizr [ featureNameSplit [ 0 ] ] = test ; } else { if ( Modernizr [ featureNameSplit [ 0 ] ] && ! ( Modernizr [ featureNameSplit [ 0 ] ] instanceof Boolean ) ) { Modernizr [ featureNameSplit [ 0 ] ] = new Boolean ( Modernizr [ featureNameSplit [ 0 ] ] ) ; } Modernizr [ featureNameSplit [ 0 ] ] [ featureNameSplit [ 1 ] ] = test ; } setClasses ( [ ( ! ! test && test != false ? '' : 'no-' ) + featureNameSplit . join ( '-' ) ] ) ; Modernizr . _trigger ( feature , test ) ; } return Modernizr ; } Modernizr . _q . push ( function ( ) { ModernizrProto . addTest = addTest ; } ) ; Modernizr . addAsyncTest ( function ( ) { var indexeddb ; var dbname = 'detect-blob-support' ; var supportsBlob = false ; var request ; var db ; try { indexeddb = prefixed ( 'indexedDB' , window ) ; } catch ( e ) { } if ( ! ( Modernizr . indexeddb && Modernizr . indexeddb . deletedatabase ) ) { return false ; } try { indexeddb . deleteDatabase ( dbname ) . onsuccess = function ( ) { request = indexeddb . open ( dbname , 1 ) ; request . onupgradeneeded = function ( ) { request . result . createObjectStore ( 'store' ) ; } ; request . onsuccess = function ( ) { db = request . result ; try { db . transaction ( 'store' , 'readwrite' ) . objectStore ( 'store' ) . put ( new Blob ( ) , 'key' ) ; supportsBlob = true ; } catch ( e ) { supportsBlob = false ; } finally { addTest ( 'indexeddbblob' , supportsBlob ) ; db . close ( ) ; indexeddb . deleteDatabase ( dbname ) ; } } ; } ; } catch ( e ) { addTest ( 'indexeddbblob' , false ) ; } } ) ; Modernizr . addTest ( 'intl' , ! ! prefixed ( 'Intl' , window ) ) ; Modernizr . addTest ( 'json' , 'JSON' in window && 'parse' in JSON && 'stringify' in JSON ) ; Modernizr . addTest ( 'serviceworker' , 'serviceWorker' in navigator ) ; Modernizr . addTest ( 'svg' , ! ! document . createElementNS && ! ! document . createElementNS ( 'http://www.w3.org/2000/svg' , 'svg' ) . createSVGRect ) ; Modernizr . addTest ( 'svgfilters' , function ( ) { var result = false ; try { result = 'SVGFEColorMatrixElement' in window && SVGFEColorMatrixElement . SVG_FECOLORMATRIX_TYPE_SATURATE == 2 ; } catch ( e ) { } return result ; } ) ; memberof name optionName optionProp access function param { string } prop param { string } value param { boolean } skipValueTest example function testAllProps ( prop , value , skipValueTest ) { return testPropsAll ( prop , undefined , undefined , value , skipValueTest ) ; } ModernizrProto . testAllProps = testAllProps ; Modernizr . addTest ( 'cssanimations' , testAllProps ( 'animationName' , 'a' , true ) ) ; Modernizr . addTest ( 'flexbox' , testAllProps ( 'flexBasis' , '1px' , true ) ) ; Modernizr . addTest ( 'es6number' , ! ! ( Number . isFinite && Number . isInteger && Number . isSafeInteger && Number . isNaN && Number . parseInt && Number . parseFloat && Number . isInteger ( Number . MAX_SAFE_INTEGER ) && Number . isInteger ( Number . MIN_SAFE_INTEGER ) && Number . isFinite ( Number . EPSILON ) ) ) ; memberof name optionName optionProp access function param { string } rule param { function } callback param { number } nodes param { string [ ] } testnames returns { boolean } example var testStyles = ModernizrProto . testStyles = injectElementWithStyles ; memberof name optionName optionProp access function param { string | * } eventName param { Element | string } element returns { boolean } example var hasEvent = ( function ( ) { var needsFallback = ! ( 'onblur' in document . documentElement ) ; function inner ( eventName , element ) { var isSupported ; if ( ! eventName ) { return false ; } if ( ! element || typeof element === 'string' ) { element = createElement ( element || 'div' ) ; } eventName = 'on' + eventName ; isSupported = eventName in element ; if ( ! isSupported && needsFallback ) { if ( ! element . setAttribute ) { element = createElement ( 'div' ) ; } element . setAttribute ( eventName , '' ) ; isSupported = typeof element [ eventName ] === 'function' ; if ( element [ eventName ] !== undefined ) { element [ eventName ] = undefined ; } element . removeAttribute ( eventName ) ; } return isSupported ; } return inner ; } ) ( ) ; ModernizrProto . hasEvent = hasEvent ; Modernizr . addTest ( 'oninput' , function ( ) { var input = createElement ( 'input' ) ; var supportsOnInput ; input . setAttribute ( 'oninput' , 'return' ) ; if ( hasEvent ( 'oninput' , docElement ) || typeof input . oninput == 'function' ) { return true ; } try { var testEvent = document . createEvent ( 'KeyboardEvent' ) ; supportsOnInput = false ; var handler = function ( e ) { supportsOnInput = true ; e . preventDefault ( ) ; e . stopPropagation ( ) ; } ; testEvent . initKeyEvent ( 'keypress' , true , true , window , false , false , false , false , 0 , 'e' . charCodeAt ( 0 ) ) ; docElement . appendChild ( input ) ; input . addEventListener ( 'input' , handler , false ) ; input . focus ( ) ; input . dispatchEvent ( testEvent ) ; input . removeEventListener ( 'input' , handler , false ) ; docElement . removeChild ( input ) ; } catch ( e ) { supportsOnInput = false ; } return supportsOnInput ; } ) ; Modernizr . addTest ( 'filereader' , ! ! ( window . File && window . FileList && window . FileReader ) ) ; Modernizr . addTest ( 'inlinesvg' , function ( ) { var div = createElement ( 'div' ) ; div . innerHTML = '<svg/>' ; return ( typeof SVGRect != 'undefined' && div . firstChild && div . firstChild . namespaceURI ) == 'http://www.w3.org/2000/svg' ; } ) ; var url = prefixed ( 'URL' , window , false ) ; url = url && window [ url ] ; Modernizr . addTest ( 'bloburls' , url && 'revokeObjectURL' in url && 'createObjectURL' in url ) ; Modernizr . addAsyncTest ( function ( ) { if ( navigator . userAgent . indexOf ( 'MSIE 7.' ) !== - 1 ) { setTimeout ( function ( ) { addTest ( 'datauri' , false ) ; } , 10 ) ; } var datauri = new Image ( ) ; datauri . onerror = function ( ) { addTest ( 'datauri' , false ) ; } ; datauri . onload = function ( ) { if ( datauri . width == 1 && datauri . height == 1 ) { testOver32kb ( ) ; } else { addTest ( 'datauri' , false ) ; } } ; datauri . src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' ; function testOver32kb ( ) { var datauriBig = new Image ( ) ; datauriBig . onerror = function ( ) { addTest ( 'datauri' , true ) ; Modernizr . datauri = new Boolean ( true ) ; Modernizr . datauri . over32kb = false ; } ; datauriBig . onload = function ( ) { addTest ( 'datauri' , true ) ; Modernizr . datauri = new Boolean ( true ) ; Modernizr . datauri . over32kb = ( datauriBig . width == 1 && datauriBig . height == 1 ) ; } ; var base64str = 'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' ; while ( base64str . length < 33000 ) { base64str = '\r\n' + base64str ; } datauriBig . src = 'data:image/gif;base64,' + base64str ; } } ) ; Modernizr . addTest ( 'sharedworkers' , 'SharedWorker' in window ) ; Modernizr . addTest ( 'webworkers' , 'Worker' in window ) ; Modernizr . addTest ( 'typedarrays' , 'ArrayBuffer' in window ) ; Modernizr . addAsyncTest ( function ( ) { var prerequisites = ! ! ( Modernizr . blobconstructor && Modernizr . bloburls && Modernizr . webworkers && Modernizr . typedarrays ) ; if ( ! prerequisites ) { return addTest ( 'transferables' , false ) ; } try { var buffer , scriptText = 'var hello = "world"' , blob = new Blob ( [ scriptText ] , { type : 'text/javascript' } ) , url = URL . createObjectURL ( blob ) , worker = new Worker ( url ) , timeout ; worker . onerror = fail ; timeout = setTimeout ( fail , 200 ) ; buffer = new ArrayBuffer ( 1 ) ; worker . postMessage ( buffer , [ buffer ] ) ; addTest ( 'transferables' , buffer . byteLength === 0 ) ; cleanup ( ) ; } catch ( e ) { fail ( ) ; } function fail ( ) { addTest ( 'transferables' , false ) ; cleanup ( ) ; } function cleanup ( ) { if ( url ) { URL . revokeObjectURL ( url ) ; } if ( worker ) { worker . terminate ( ) ; } if ( timeout ) { clearTimeout ( timeout ) ; } } } ) ; testRunner ( ) ; delete ModernizrProto . addTest ; delete ModernizrProto . addAsyncTest ; for ( var i = 0 ; i < Modernizr . _q . length ; i ++ ) { Modernizr . _q [ i ] ( ) ; } window . Modernizr = Modernizr ; ; } ) ( window , document ) ;