Commits

eriiicam committed 443be7f

modernizr 2.0b

Comments (0)

Files changed (1)

static/js/modernizr.js

-/*!
- * Modernizr v1.6
- * http://www.modernizr.com
- *
- * Developed by: 
- * - Faruk Ates  http://farukat.es/
- * - Paul Irish  http://paulirish.com/
- *
- * Copyright (c) 2009-2010
- * Dual-licensed under the BSD or MIT licenses.
- * http://www.modernizr.com/license/
- */
-
- 
-/*
- * Modernizr is a script that detects native CSS3 and HTML5 features
- * available in the current UA and provides an object containing all
- * features with a true/false value, depending on whether the UA has
- * native support for it or not.
- * 
- * Modernizr will also add classes to the <html> element of the page,
- * one for each feature it detects. If the UA supports it, a class
- * like "cssgradients" will be added. If not, the class name will be
- * "no-cssgradients". This allows for simple if-conditionals in your
- * CSS, giving you fine control over the look & feel of your website.
- * 
- * @author        Faruk Ates
- * @author        Paul Irish
- * @copyright     (c) 2009-2010 Faruk Ates.
- * @contributor   Ben Alman
- */
-
-window.Modernizr = (function(window,doc,undefined){
-    
-    var version = '1.6',
-    
-    ret = {},
-
-    /**
-     * !! DEPRECATED !!
-     * 
-     * enableHTML5 is a private property for advanced use only. If enabled,
-     * it will make Modernizr.init() run through a brief while() loop in
-     * which it will create all HTML5 elements in the DOM to allow for
-     * styling them in Internet Explorer, which does not recognize any
-     * non-HTML4 elements unless created in the DOM this way.
-     * 
-     * enableHTML5 is ON by default.
-     * 
-     * The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be
-     * replaced in 2.0 in lieu of the modular, configurable nature of 2.0.
-     */
-    enableHTML5 = true,
-    
-    
-    docElement = doc.documentElement,
-
-    /**
-     * Create our "modernizr" element that we do most feature tests on.
-     */
-    mod = 'modernizr',
-    m = doc.createElement( mod ),
-    m_style = m.style,
-
-    /**
-     * Create the input element for various Web Forms feature tests.
-     */
-    f = doc.createElement( 'input' ),
-    
-    smile = ':)',
-    
-    tostring = Object.prototype.toString,
-    
-    // List of property values to set for css tests. See ticket #21
-    prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
-
-    // Following spec is to expose vendor-specific style properties as:
-    //   elem.style.WebkitBorderRadius
-    // and the following would be incorrect:
-    //   elem.style.webkitBorderRadius
-    
-    // Webkit ghosts their properties in lowercase but Opera & Moz do not.
-    // Microsoft foregoes prefixes entirely <= IE8, but appears to 
-    //   use a lowercase `ms` instead of the correct `Ms` in IE9
-    
-    // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
-    domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
-
-    ns = {'svg': 'http://www.w3.org/2000/svg'},
-
-    tests = {},
-    inputs = {},
-    attrs = {},
-    
-    classes = [],
-    
-    featurename, // used in testing loop
-    
-    
-    
-    // todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead
-    testMediaQuery = function(mq){
-
-      var st = document.createElement('style'),
-          div = doc.createElement('div'),
-          ret;
-
-      st.textContent = mq + '{#modernizr{height:3px}}';
-      (doc.head || doc.getElementsByTagName('head')[0]).appendChild(st);
-      div.id = 'modernizr';
-      docElement.appendChild(div);
-
-      ret = div.offsetHeight === 3;
-
-      st.parentNode.removeChild(st);
-      div.parentNode.removeChild(div);
-
-      return !!ret;
-
-    },
-    
-    
-    /**
-      * isEventSupported determines if a given element supports the given event
-      * function from http://yura.thinkweb2.com/isEventSupported/
-      */
-    isEventSupported = (function(){
-
-      var TAGNAMES = {
-        'select':'input','change':'input',
-        'submit':'form','reset':'form',
-        'error':'img','load':'img','abort':'img'
-      };
-
-      function isEventSupported(eventName, element) {
-
-        element = element || document.createElement(TAGNAMES[eventName] || 'div');
-        eventName = 'on' + eventName;
-
-        // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
-        var isSupported = (eventName in element);
-
-        if (!isSupported) {
-          // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
-          if (!element.setAttribute) {
-            element = document.createElement('div');
-          }
-          if (element.setAttribute && element.removeAttribute) {
-            element.setAttribute(eventName, '');
-            isSupported = typeof element[eventName] == 'function';
-
-            // If property was created, "remove it" (by setting value to `undefined`)
-            if (typeof element[eventName] != 'undefined') {
-              element[eventName] = undefined;
-            }
-            element.removeAttribute(eventName);
-          }
-        }
-
-        element = null;
-        return isSupported;
-      }
-      return isEventSupported;
-    })();
-    
-    
-    // hasOwnProperty shim by kangax needed for Safari 2.0 support
-    var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
-    if (typeof _hasOwnProperty !== 'undefined' && typeof _hasOwnProperty.call !== 'undefined') {
-      hasOwnProperty = function (object, property) {
-        return _hasOwnProperty.call(object, property);
-      };
-    }
-    else {
-      hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
-        return ((property in object) && typeof object.constructor.prototype[property] === 'undefined');
-      };
-    }
-    
-    /**
-     * set_css applies given styles to the Modernizr DOM node.
-     */
-    function set_css( str ) {
-        m_style.cssText = str;
-    }
-
-    /**
-     * set_css_all extrapolates all vendor-specific css strings.
-     */
-    function set_css_all( str1, str2 ) {
-        return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
-    }
-
-    /**
-     * contains returns a boolean for if substr is found within str.
-     */
-    function contains( str, substr ) {
-        return (''+str).indexOf( substr ) !== -1;
-    }
-
-    /**
-     * test_props is a generic CSS / DOM property test; if a browser supports
-     *   a certain property, it won't return undefined for it.
-     *   A supported CSS property returns empty string when its not yet set.
-     */
-    function test_props( props, callback ) {
-        for ( var i in props ) {
-            if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], m ) ) ) {
-                return true;
-            }
-        }
-    }
-
-    /**
-     * test_props_all tests a list of DOM properties we want to check against.
-     *   We specify literally ALL possible (known and/or likely) properties on 
-     *   the element including the non-vendor prefixed one, for forward-
-     *   compatibility.
-     */
-    function test_props_all( prop, callback ) {
-      
-        var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
-            props   = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' ');
-
-        return !!test_props( props, callback );
-    }
-    
-
-    /**
-     * Tests
-     */
-
-    tests['flexbox'] = function() {
-        /**
-         * set_prefixed_value_css sets the property of a specified element
-         * adding vendor prefixes to the VALUE of the property.
-         * @param {Element} element
-         * @param {string} property The property name. This will not be prefixed.
-         * @param {string} value The value of the property. This WILL be prefixed.
-         * @param {string=} extra Additional CSS to append unmodified to the end of
-         * the CSS string.
-         */
-        function set_prefixed_value_css(element, property, value, extra) {
-            property += ':';
-            element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
-        }
-
-        /**
-         * set_prefixed_property_css sets the property of a specified element
-         * adding vendor prefixes to the NAME of the property.
-         * @param {Element} element
-         * @param {string} property The property name. This WILL be prefixed.
-         * @param {string} value The value of the property. This will not be prefixed.
-         * @param {string=} extra Additional CSS to append unmodified to the end of
-         * the CSS string.
-         */
-        function set_prefixed_property_css(element, property, value, extra) {
-            element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
-        }
-
-        var c = doc.createElement('div'),
-            elem = doc.createElement('div');
-
-        set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;');
-        set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;');
-
-        c.appendChild(elem);
-        docElement.appendChild(c);
-
-        var ret = elem.offsetWidth === 42;
-
-        c.removeChild(elem);
-        docElement.removeChild(c);
-
-        return ret;
-    };
-    
-    // On the S60 and BB Storm, getContext exists, but always returns undefined
-    // http://github.com/Modernizr/Modernizr/issues/issue/97/ 
-    
-    tests['canvas'] = function() {
-        var elem = doc.createElement( 'canvas' );
-        return !!(elem.getContext && elem.getContext('2d'));
-    };
-    
-    tests['canvastext'] = function() {
-        return !!(ret['canvas'] && typeof doc.createElement( 'canvas' ).getContext('2d').fillText == 'function');
-    };
-    
-    
-    tests['webgl'] = function(){
-
-        var elem = doc.createElement( 'canvas' ); 
-        
-        try {
-            if (elem.getContext('webgl')){ return true; }
-        } catch(e){	}
-        
-        try {
-            if (elem.getContext('experimental-webgl')){ return true; }
-        } catch(e){	}
-
-        return false;
-    };
-    
-    /*
-     * The Modernizr.touch test only indicates if the browser supports
-     *    touch events, which does not necessarily reflect a touchscreen
-     *    device, as evidenced by tablets running Windows 7 or, alas,
-     *    the Palm Pre / WebOS (touch) phones.
-     *    
-     * Additionally, Chrome (desktop) used to lie about its support on this,
-     *    but that has since been rectified: http://crbug.com/36415
-     *    
-     * We also test for Firefox 4 Multitouch Support.
-     *
-     * For more info, see: http://modernizr.github.com/Modernizr/touch.html
-     */
-     
-    tests['touch'] = function() {
-
-        return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)');
-
-    };
-
-
-    /**
-     * geolocation tests for the new Geolocation API specification.
-     *   This test is a standards compliant-only test; for more complete
-     *   testing, including a Google Gears fallback, please see:
-     *   http://code.google.com/p/geo-location-javascript/
-     * or view a fallback solution using google's geo API:
-     *   http://gist.github.com/366184
-     */
-    tests['geolocation'] = function() {
-        return !!navigator.geolocation;
-    };
-
-    // Per 1.6: 
-    // This used to be Modernizr.crosswindowmessaging but the longer
-    // name has been deprecated in favor of a shorter and property-matching one.
-    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
-    // and in the first release thereafter disappear entirely.
-    tests['postmessage'] = function() {
-      return !!window.postMessage;
-    };
-
-    // Web SQL database detection is tricky:
-
-    // In chrome incognito mode, openDatabase is truthy, but using it will 
-    //   throw an exception: http://crbug.com/42380
-    // We can create a dummy database, but there is no way to delete it afterwards. 
-    
-    // Meanwhile, Safari users can get prompted on any database creation.
-    //   If they do, any page with Modernizr will give them a prompt:
-    //   http://github.com/Modernizr/Modernizr/issues/closed#issue/113
-    
-    // We have chosen to allow the Chrome incognito false positive, so that Modernizr
-    //   doesn't litter the web with these test databases. As a developer, you'll have
-    //   to account for this gotcha yourself.
-    tests['websqldatabase'] = function() {
-      var result = !!window.openDatabase;
-      /*
-      if (result){
-        try {
-          result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
-        } catch(e) {
-        }
-      }
-      */
-      return result;
-    };
-    
-    // Vendors have inconsistent prefixing with the experimental Indexed DB:
-    // - Firefox is shipping indexedDB in FF4 as moz_indexedDB
-    // - Webkit's implementation is accessible through webkitIndexedDB
-    // We test both styles.
-    tests['indexedDB'] = function(){
-      for (var i = -1, len = domPrefixes.length; ++i < len; ){ 
-        var prefix = domPrefixes[i].toLowerCase();
-        if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){
-          return true;
-        } 
-      }
-      return false;
-    };
-
-    // documentMode logic from YUI to filter out IE8 Compat Mode
-    //   which false positives.
-    tests['hashchange'] = function() {
-      return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 );
-    };
-
-    // Per 1.6: 
-    // This used to be Modernizr.historymanagement but the longer
-    // name has been deprecated in favor of a shorter and property-matching one.
-    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
-    // and in the first release thereafter disappear entirely.
-    tests['history'] = function() {
-      return !!(window.history && history.pushState);
-    };
-
-    tests['draganddrop'] = function() {
-        return  isEventSupported('drag') && 
-                isEventSupported('dragstart') && 
-                isEventSupported('dragenter') &&
-                isEventSupported('dragover') &&
-                isEventSupported('dragleave') &&
-                isEventSupported('dragend') &&
-                isEventSupported('drop');
-    };
-    
-    tests['websockets'] = function(){
-        return ('WebSocket' in window);
-    };
-    
-    
-    // http://css-tricks.com/rgba-browser-support/
-    tests['rgba'] = function() {
-        // Set an rgba() color and check the returned value
-        
-        set_css(  'background-color:rgba(150,255,150,.5)' );
-        
-        return contains( m_style.backgroundColor, 'rgba' );
-    };
-    
-    tests['hsla'] = function() {
-        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
-        //   except IE9 who retains it as hsla
-        
-        set_css('background-color:hsla(120,40%,100%,.5)' );
-        
-        return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' );
-    };
-    
-    tests['multiplebgs'] = function() {
-        // Setting multiple images AND a color on the background shorthand property
-        //  and then querying the style.background property value for the number of
-        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
-        
-        set_css( 'background:url(//:),url(//:),red url(//:)' );
-        
-        // If the UA supports multiple backgrounds, there should be three occurrences
-        //   of the string "url(" in the return value for elem_style.background
-
-        return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background);
-    };
-    
-    
-    // In testing support for a given CSS property, it's legit to test:
-    //    elem.style[styleName] !== undefined
-    // If the property is supported it will return an empty string,
-    // if unsupported it will return undefined.
-    // We'll take advantage of this quick test and skip setting a style 
-    // on our modernizr element, but instead just testing undefined vs
-    // empty string.
-    // The legacy set_css_all calls will remain in the source 
-    // (however, commented) for clarity, yet functionally they are 
-    // no longer needed.
-    
-
-    tests['backgroundsize'] = function() {
-        return test_props_all( 'backgroundSize' );
-    };
-    
-    tests['borderimage'] = function() {
-        //  set_css_all( 'border-image:url(m.png) 1 1 stretch' );
-        return test_props_all( 'borderImage' );
-    };
-    
-    
-    // Super comprehensive table about all the unique implementations of 
-    // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
-    
-    tests['borderradius'] = function() {
-        //  set_css_all( 'border-radius:10px' );
-        return test_props_all( 'borderRadius', '', function( prop ) {
-            return contains( prop, 'orderRadius' );
-        });
-    };
-    
-    
-    tests['boxshadow'] = function() {
-        //  set_css_all( 'box-shadow:#000 1px 1px 3px' );
-        return test_props_all( 'boxShadow' );
-    };
-    
-    // Note: FF3.0 will false positive on this test 
-    tests['textshadow'] = function(){
-        return doc.createElement('div').style.textShadow === '';
-    };
-    
-    
-    tests['opacity'] = function() {
-        // Browsers that actually have CSS Opacity implemented have done so
-        //  according to spec, which means their return values are within the
-        //  range of [0.0,1.0] - including the leading zero.
-        
-        set_css_all( 'opacity:.5' );
-        
-        return contains( m_style.opacity, '0.5' );
-    };
-    
-    
-    tests['cssanimations'] = function() {
-        //  set_css_all( 'animation:"animate" 2s ease 2', 'position:relative' );
-        return test_props_all( 'animationName' );
-    };
-    
-    
-    tests['csscolumns'] = function() {
-        //  set_css_all( 'column-count:3' );
-        return test_props_all( 'columnCount' );
-    };
-    
-    
-    tests['cssgradients'] = function() {
-        /**
-         * For CSS Gradients syntax, please see:
-         * http://webkit.org/blog/175/introducing-css-gradients/
-         * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
-         * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
-         * http://dev.w3.org/csswg/css3-images/#gradients-
-         */
-        
-        var str1 = 'background-image:',
-            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
-            str3 = 'linear-gradient(left top,#9f9, white);';
-        
-        set_css(
-            (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
-        );
-        
-        return contains( m_style.backgroundImage, 'gradient' );
-    };
-    
-    
-    tests['cssreflections'] = function() {
-        //  set_css_all( 'box-reflect:right 1px' );
-        return test_props_all( 'boxReflect' );
-    };
-    
-    
-    tests['csstransforms'] = function() {
-        //  set_css_all( 'transform:rotate(3deg)' );
-        return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
-    };
-    
-    
-    tests['csstransforms3d'] = function() {
-        //  set_css_all( 'perspective:500' );
-        
-        var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
-        
-        // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
-        //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome (yet?).
-        //   As a result, Webkit typically recognizes the syntax but will sometimes throw a false
-        //   positive, thus we must do a more thorough check:
-        if (ret){
-          
-          // Webkit allows this media query to succeed only if the feature is enabled.    
-          // "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }"      
-          ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)');
-        }
-        return ret;
-    };
-    
-    
-    tests['csstransitions'] = function() {
-        //  set_css_all( 'transition:all .5s linear' );
-        return test_props_all( 'transitionProperty' );
-    };
-
-
-    // @font-face detection routine by Diego Perini
-    // http://javascript.nwbox.com/CSSSupport/
-    tests['fontface'] = function(){
-
-        var 
-        sheet,
-        head = doc.head || doc.getElementsByTagName('head')[0] || docElement,
-        style = doc.createElement("style"),
-        impl = doc.implementation || { hasFeature: function() { return false; } };
-        
-        style.type = 'text/css';
-        head.insertBefore(style, head.firstChild);
-        sheet = style.sheet || style.styleSheet;
-
-        // removing it crashes IE browsers
-        //head.removeChild(style);
-
-        var supportAtRule = impl.hasFeature('CSS2', '') ?
-                function(rule) {
-                    if (!(sheet && rule)) return false;
-                    var result = false;
-                    try {
-                        sheet.insertRule(rule, 0);
-                        result = !(/unknown/i).test(sheet.cssRules[0].cssText);
-                        sheet.deleteRule(sheet.cssRules.length - 1);
-                    } catch(e) { }
-                    return result;
-                } :
-                function(rule) {
-                    if (!(sheet && rule)) return false;
-                    sheet.cssText = rule;
-                    
-                    return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) &&
-                      sheet.cssText
-                            .replace(/\r+|\n+/g, '')
-                            .indexOf(rule.split(' ')[0]) === 0;
-                };
-
-
-        // DEPRECATED - allow for a callback
-        ret._fontfaceready = function(fn){
-          fn(ret.fontface);
-        };
-        
-        return supportAtRule('@font-face { font-family: "font"; src: "font.ttf"; }');
-        
-    };
-    
-
-    // These tests evaluate support of the video/audio elements, as well as
-    // testing what types of content they support.
-    //
-    // We're using the Boolean constructor here, so that we can extend the value
-    // e.g.  Modernizr.video     // true
-    //       Modernizr.video.ogg // 'probably'
-    //
-    // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
-    //                     thx to NielsLeenheer and zcorpan
-    
-    // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
-    //   Modernizr does not normalize for that.
-    
-    tests['video'] = function() {
-        var elem = doc.createElement('video'),
-            bool = !!elem.canPlayType;
-        
-        if (bool){  
-            bool      = new Boolean(bool);  
-            bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"');
-            
-            // Workaround required for IE9, which doesn't report video support without audio codec specified.
-            //   bug 599718 @ msft connect
-            var h264 = 'video/mp4; codecs="avc1.42E01E';
-            bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
-            
-            bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
-        }
-        return bool;
-    };
-    
-    tests['audio'] = function() {
-        var elem = doc.createElement('audio'),
-            bool = !!elem.canPlayType;
-        
-        if (bool){  
-            bool      = new Boolean(bool);  
-            bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"');
-            bool.mp3  = elem.canPlayType('audio/mpeg;');
-            
-            // Mimetypes accepted: 
-            //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
-            //   http://bit.ly/iphoneoscodecs
-            bool.wav  = elem.canPlayType('audio/wav; codecs="1"');
-            bool.m4a  = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
-        }
-        return bool;
-    };
-
-
-    // Both localStorage and sessionStorage are
-    //   tested via the `in` operator because otherwise Firefox will
-    //   throw an error: https://bugzilla.mozilla.org/show_bug.cgi?id=365772
-    //   if cookies are disabled
-    
-    // They require try/catch because of possible firefox configuration:
-    //   http://github.com/Modernizr/Modernizr/issues#issue/92
-    
-    // FWIW miller device resolves to [object Storage] in all supporting browsers
-    //   except for IE who does [object Object]
-    
-    // IE8 Compat mode supports these features completely:
-    //   http://www.quirksmode.org/dom/html5.html
-    
-    tests['localstorage'] = function() {
-        try {
-          return ('localStorage' in window) && window.localStorage !== null;
-        } catch(e) {
-          return false;
-        }
-    };
-
-    tests['sessionstorage'] = function() {
-        try {
-            return ('sessionStorage' in window) && window.sessionStorage !== null;
-        } catch(e){
-            return false;
-        }
-    };
-
-
-    tests['webWorkers'] = function () {
-        return !!window.Worker;
-    };
-
-
-    tests['applicationcache'] =  function() {
-        return !!window.applicationCache;
-    };
-
- 
-    // Thanks to Erik Dahlstrom
-    tests['svg'] = function(){
-        return !!doc.createElementNS && !!doc.createElementNS(ns.svg, "svg").createSVGRect;
-    };
-
-    tests['inlinesvg'] = function() {
-      var div = document.createElement('div');
-      div.innerHTML = '<svg/>';
-      return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
-    };
-
-    // Thanks to F1lt3r and lucideer
-    // http://github.com/Modernizr/Modernizr/issues#issue/35
-    tests['smil'] = function(){
-        return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'animate')));
-    };
-
-    tests['svgclippaths'] = function(){
-        // Possibly returns a false positive in Safari 3.2?
-        return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'clipPath')));
-    };
-
-
-    // input features and input types go directly onto the ret object, bypassing the tests loop.
-    // Hold this guy to execute in a moment.
-    function webforms(){
-    
-        // Run through HTML5's new input attributes to see if the UA understands any.
-        // We're using f which is the <input> element created early on
-        // Mike Taylr has created a comprehensive resource for testing these attributes
-        //   when applied to all input types: 
-        //   http://miketaylr.com/code/input-type-attr.html
-        // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
-        ret['input'] = (function(props) {
-            for (var i = 0,len=props.length;i<len;i++) {
-                attrs[ props[i] ] = !!(props[i] in f);
-            }
-            return attrs;
-        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
-
-        // Run through HTML5's new input types to see if the UA understands any.
-        //   This is put behind the tests runloop because it doesn't return a
-        //   true/false like all the other tests; instead, it returns an object
-        //   containing each input type with its corresponding true/false value 
-        
-        // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
-        ret['inputtypes'] = (function(props) {
-            for (var i = 0, bool, len=props.length ; i < len ; i++) {
-              
-                f.setAttribute('type', props[i]);
-                bool = f.type !== 'text';
-                
-                // Chrome likes to falsely purport support, so we feed it a textual value;
-                // if that doesnt succeed then we know there's a custom UI
-                if (bool){  
-
-                    f.value = smile;
-     
-                    if (/^range$/.test(f.type) && f.style.WebkitAppearance !== undefined){
-                      
-                      docElement.appendChild(f);
-                      var defaultView = doc.defaultView;
-                      
-                      // Safari 2-4 allows the smiley as a value, despite making a slider
-                      bool =  defaultView.getComputedStyle && 
-                              defaultView.getComputedStyle(f, null).WebkitAppearance !== 'textfield' && 
-                      
-                              // Mobile android web browser has false positive, so must
-                              // check the height to see if the widget is actually there.
-                              (f.offsetHeight !== 0);
-                              
-                      docElement.removeChild(f);
-                              
-                    } else if (/^(search|tel)$/.test(f.type)){
-                      // Spec doesnt define any special parsing or detectable UI 
-                      //   behaviors so we pass these through as true
-                      
-                      // Interestingly, opera fails the earlier test, so it doesn't
-                      //  even make it here.
-                      
-                    } else if (/^(url|email)$/.test(f.type)) {
-
-                      // Real url and email support comes with prebaked validation.
-                      bool = f.checkValidity && f.checkValidity() === false;
-                      
-                    } else {
-                      // If the upgraded input compontent rejects the :) text, we got a winner
-                      bool = f.value != smile;
-                    }
-                }
-                
-                inputs[ props[i] ] = !!bool;
-            }
-            return inputs;
-        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
-
-    }
-
-
-
-    // End of test definitions
-
-
-
-    // Run through all tests and detect their support in the current UA.
-    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
-    for ( var feature in tests ) {
-        if ( hasOwnProperty( tests, feature ) ) {
-            // run the test, throw the return value into the Modernizr,
-            //   then based on that boolean, define an appropriate className
-            //   and push it into an array of classes we'll join later.
-            featurename  = feature.toLowerCase();
-            ret[ featurename ] = tests[ feature ]();
-
-            classes.push( ( ret[ featurename ] ? '' : 'no-' ) + featurename );
-        }
-    }
-    
-    // input tests need to run.
-    if (!ret.input) webforms();
-    
-
-   
-    // Per 1.6: deprecated API is still accesible for now:
-    ret.crosswindowmessaging = ret.postmessage;
-    ret.historymanagement = ret.history;
-
-
-
-    /**
-     * Addtest allows the user to define their own feature tests
-     * the result will be added onto the Modernizr object,
-     * as well as an appropriate className set on the html element
-     * 
-     * @param feature - String naming the feature
-     * @param test - Function returning true if feature is supported, false if not
-     */
-    ret.addTest = function (feature, test) {
-      feature = feature.toLowerCase();
-      
-      if (ret[ feature ]) {
-        return; // quit if you're trying to overwrite an existing test
-      } 
-      test = !!(test());
-      docElement.className += ' ' + (test ? '' : 'no-') + feature; 
-      ret[ feature ] = test;
-      return ret; // allow chaining.
-    };
-
-    /**
-     * Reset m.style.cssText to nothing to reduce memory footprint.
-     */
-    set_css( '' );
-    m = f = null;
-
-    // Enable HTML 5 elements for styling in IE. 
-    // fyi: jscript version does not reflect trident version
-    //      therefore ie9 in ie7 mode will still have a jScript v.9
-    if ( enableHTML5 && window.attachEvent && (function(){ var elem = doc.createElement("div");
-                                      elem.innerHTML = "<elem></elem>";
-                                      return elem.childNodes.length !== 1; })()) {
-        // iepp v1.6 by @jon_neal : code.google.com/p/ie-print-protector
-        (function(f,l){var j="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",n=j.split("|"),k=n.length,g=new RegExp("<(/*)("+j+")","gi"),h=new RegExp("\\b("+j+")\\b(?!.*[;}])","gi"),m=l.createDocumentFragment(),d=l.documentElement,i=d.firstChild,b=l.createElement("style"),e=l.createElement("body");b.media="all";function c(p){var o=-1;while(++o<k){p.createElement(n[o])}}c(l);c(m);function a(t,s){var r=t.length,q=-1,o,p=[];while(++q<r){o=t[q];s=o.media||s;p.push(a(o.imports,s));p.push(o.cssText)}return p.join("")}f.attachEvent("onbeforeprint",function(){var r=-1;while(++r<k){var o=l.getElementsByTagName(n[r]),q=o.length,p=-1;while(++p<q){if(o[p].className.indexOf("iepp_")<0){o[p].className+=" iepp_"+n[r]}}}i.insertBefore(b,i.firstChild);b.styleSheet.cssText=a(l.styleSheets,"all").replace(h,".iepp_$1");m.appendChild(l.body);d.appendChild(e);e.innerHTML=m.firstChild.innerHTML.replace(g,"<$1bdo")});f.attachEvent("onafterprint",function(){e.innerHTML="";d.removeChild(e);i.removeChild(b);d.appendChild(m.firstChild)})})(this,document);
-    }
-
-    // Assign private properties to the return object with prefix
-    ret._enableHTML5     = enableHTML5;
-    ret._version         = version;
-
-    // Remove "no-js" class from <html> element, if it exists:
-    docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js';
-
-    // Add the new classes to the <html> element.
-    docElement.className += ' ' + classes.join( ' ' );
-    
-    return ret;
-
-})(this,this.document);
+window.Modernizr=function(B,e,o){function C(a,b){for(var c in a)if(j[a[c]]!==o&&(!b||b(a[c],D)))return true}function p(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1);c=(a+" "+P.join(c+" ")+c).split(" ");return!!C(c,b)}function Q(){g.input=function(a){for(var b=0,c=a.length;b<c;b++)G[a[b]]=!!(a[b]in i);return G}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" "));g.inputtypes=function(a){for(var b=0,c,k=a.length;b<k;b++){i.setAttribute("type",a[b]);if(c=i.type!==
+"text"){i.value=H;if(/^range$/.test(i.type)&&i.style.WebkitAppearance!==o){m.appendChild(i);c=e.defaultView;c=c.getComputedStyle&&c.getComputedStyle(i,null).WebkitAppearance!=="textfield"&&i.offsetHeight!==0;m.removeChild(i)}else/^(search|tel)$/.test(i.type)||(c=/^(url|email)$/.test(i.type)?i.checkValidity&&i.checkValidity()===false:i.value!=H)}I[a[b]]=!!c}return I}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var g={},m=e.documentElement,J=e.head||
+e.getElementsByTagName("head")[0],D=e.createElement("modernizr"),j=D.style,i=e.createElement("input"),H=":)",t=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),P="Webkit Moz O ms Khtml".split(" "),d={},I={},G={},K=[],w,R=function(){var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return function(b,c){c=c||e.createElement(a[b]||"div");b="on"+b;var k=b in c;if(!k){c.setAttribute||(c=e.createElement("div"));if(c.setAttribute&&c.removeAttribute){c.setAttribute(b,
+"");k=typeof c[b]==="function";typeof c[b]===o||(c[b]=o);c.removeAttribute(b)}}return k}}(),E={}.hasOwnProperty,L;L=typeof E!==o&&typeof E.call!==o?function(a,b){return E.call(a,b)}:function(a,b){return b in a&&typeof a.constructor.prototype[b]===o};d.flexbox=function(){var a=e.createElement("div"),b=e.createElement("div");(function(k,h,r,x){h+=":";k.style.cssText=(h+t.join(r+";"+h)).slice(0,-h.length)+(x||"")})(a,"display","box","width:42px;padding:0;");b.style.cssText=t.join("box-flex:1;")+"width:10px;";
+a.appendChild(b);m.appendChild(a);var c=b.offsetWidth===42;a.removeChild(b);m.removeChild(a);return c};d.hashchange=function(){return R("hashchange",B)&&(e.documentMode===o||e.documentMode>7)};d.rgba=function(){j.cssText="background-color:rgba(150,255,150,.5)";return(""+j.backgroundColor).indexOf("rgba")!==-1};d.hsla=function(){j.cssText="background-color:hsla(120,40%,100%,.5)";return(""+j.backgroundColor).indexOf("rgba")!==-1||(""+j.backgroundColor).indexOf("hsla")!==-1};d.multiplebgs=function(){j.cssText=
+"background:url(//:),url(//:),red url(//:)";return/(url\s*\(.*?){3}/.test(j.background)};d.backgroundsize=function(){return p("backgroundSize")};d.borderimage=function(){return p("borderImage")};d.borderradius=function(){return p("borderRadius","",function(a){return(""+a).indexOf("orderRadius")!==-1})};d.boxshadow=function(){return p("boxShadow")};d.textshadow=function(){return e.createElement("div").style.textShadow===""};d.opacity=function(){var a=t.join("opacity:.55;")+"";j.cssText=a;return/^0.55$/.test(j.opacity)};
+d.cssanimations=function(){return p("animationName")};d.csscolumns=function(){return p("columnCount")};d.cssgradients=function(){var a=("background-image:"+t.join("gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:")+t.join("linear-gradient(left top,#9f9, white);background-image:")).slice(0,-17);j.cssText=a;return(""+j.backgroundImage).indexOf("gradient")!==-1};d.cssreflections=function(){return p("boxReflect")};d.csstransforms=function(){return!!C(["transformProperty",
+"WebkitTransform","MozTransform","OTransform","msTransform"])};d.csstransforms3d=function(){var a=!!C(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);if(a&&"webkitPerspective"in m.style){var b="@media ("+t.join("transform-3d),(")+"modernizr)";a=e.createElement("style");var c=e.createElement("div");a.textContent=b+"{#modernizr{height:3px}}";J.appendChild(a);c.id="modernizr";m.appendChild(c);b=c.offsetHeight===3;a.parentNode.removeChild(a);c.parentNode.removeChild(c);
+a=!!b}return a};d.csstransitions=function(){return p("transitionProperty")};d.fontface=function(){var a,b=J||m,c=e.createElement("style"),k=e.implementation||{hasFeature:function(){return false}};c.type="text/css";b.insertBefore(c,b.firstChild);a=c.sheet||c.styleSheet;b=k.hasFeature("CSS2","")?function(h){if(!(a&&h))return false;var r=false;try{a.insertRule(h,0);r=!/unknown/i.test(a.cssRules[0].cssText);a.deleteRule(a.cssRules.length-1)}catch(x){}return r}:function(h){if(!(a&&h))return false;a.cssText=
+h;return a.cssText.length!==0&&!/unknown/i.test(a.cssText)&&a.cssText.replace(/\r+|\n+/g,"").indexOf(h.split(" ")[0])===0};g._fontfaceready=function(h){h(g.fontface)};return b('@font-face { font-family: "font"; src: "font.ttf"; }')};d.video=function(){var a=e.createElement("video"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('video/ogg; codecs="theora"');b.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"')||a.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');b.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return b};
+d.audio=function(){var a=e.createElement("audio"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('audio/ogg; codecs="vorbis"');b.mp3=a.canPlayType("audio/mpeg;");b.wav=a.canPlayType('audio/wav; codecs="1"');b.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}return b};for(var F in d)if(L(d,F)){w=F.toLowerCase();g[w]=d[F]();K.push((g[w]?"":"no-")+w)}g.input||Q();g.crosswindowmessaging=g.postmessage;g.historymanagement=g.history;g.addTest=function(a,b){a=a.toLowerCase();if(!g[a]){b=
+!!b();m.className+=" "+(b?"":"no-")+a;g[a]=b;return g}};j.cssText="";D=f=null;B.attachEvent&&function(){var a=e.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function c(q){for(var l=-1;++l<r;)q.createElement(h[l])}function k(q,l){for(var s=-1,n=q.length,y,M=[];++s<n;){y=q[s];if((l=y.media||l)!="screen")M.push(k(y.imports,l),y.cssText)}return M.join("")}var h="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video".split("|"),
+r=h.length,x=RegExp("(^|\\s)(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video)","gi"),S=RegExp("<(/*)(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video)","gi"),T=RegExp("(^|[^\\n]*?\\s)(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video)([^\\n]*)({[\\n\\w\\W]*?})",
+"gi"),N=b.createDocumentFragment(),z=b.documentElement,O=z.firstChild,v=b.createElement("body"),A=b.createElement("style"),u;c(b);c(N);O.insertBefore(A,O.firstChild);A.media="print";a.attachEvent("onbeforeprint",function(){var q=-1,l=k(b.styleSheets,"all"),s=[],n;for(u=u||b.body;(n=T.exec(l))!=null;)s.push((n[1]+n[2]+n[3]).replace(x,"$1.iepp_$2")+n[4]);for(A.styleSheet.cssText=s.join("\n");++q<r;){l=b.getElementsByTagName(h[q]);s=l.length;for(n=-1;++n<s;)if(l[n].className.indexOf("iepp_")<0)l[n].className+=
+" iepp_"+h[q]}N.appendChild(u);z.appendChild(v);v.className=u.className;v.innerHTML=u.innerHTML.replace(S,"<$1font")});a.attachEvent("onafterprint",function(){v.innerHTML="";z.removeChild(v);z.appendChild(u);A.styleSheet.cssText=""})}(B,e);g._enableHTML5=true;g._version="1.6";m.className=m.className.replace(/\bno-js\b/,"")+" js";m.className+=" "+K.join(" ");return g}(this,this.document);