function has(name) {
        if (has[name] !== undef) {
          // Return cached feature test result.
          return has[name];
        }
        var isSupported;
        if (name == "bug-string-char-index") {
          // IE <= 7 doesn't support accessing string characters using square
          // bracket notation. IE 8 only supports this for primitives.
          isSupported = "a"[0] != "a";
        } else if (name == "json") {
          // Indicates whether both `JSON.stringify` and `JSON.parse` are
          // supported.
          isSupported = has("json-stringify") && has("json-parse");
        } else {
          var value,
              serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
          // Test `JSON.stringify`.
          if (name == "json-stringify") {
            var stringify = exports.stringify,
                stringifySupported = typeof stringify == "function" && isExtended;
            if (stringifySupported) {
              // A test function object with a custom `toJSON` method.
              (value = function () {
                return 1;
              }).toJSON = value;
              try {
                stringifySupported =
                // Firefox 3.1b1 and b2 serialize string, number, and boolean
                // primitives as object literals.
                stringify(0) === "0" &&
                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
                // literals.
                stringify(new Number()) === "0" && stringify(new String()) == '""' &&
                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
                // does not define a canonical JSON representation (this applies to
                // objects with `toJSON` properties as well, *unless* they are nested
                // within an object or array).
                stringify(getClass) === undef &&
                // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
                // FF 3.1b3 pass this test.
                stringify(undef) === undef &&
                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
                // respectively, if the value is omitted entirely.
                stringify() === undef &&
                // FF 3.1b1, 2 throw an error if the given value is not a number,
                // string, array, object, Boolean, or `null` literal. This applies to
                // objects with custom `toJSON` methods as well, unless they are nested
                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
                // methods entirely.
                stringify(value) === "1" && stringify([value]) == "[1]" &&
                // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
                // `"[null]"`.
                stringify([undef]) == "[null]" &&
                // YUI 3.0.0b1 fails to serialize `null` literals.
                stringify(null) == "null" &&
                // FF 3.1b1, 2 halts serialization if an array contains a function:
                // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
                // elides non-JSON values from objects and arrays, unless they
                // define custom `toJSON` methods.
                stringify([undef, getClass, null]) == "[null,null,null]" &&
                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences
                // where character escape codes are expected (e.g., `\b` => `\u0008`).
                stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
                stringify(null, value) === "1" && stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
                // serialize extended years.
                stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
                // The milliseconds are optional in ES 5, but required in 5.1.
                stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
                // four-digit years instead of six-digit years. Credits: @Yaffle.
                stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
                // values less than 1000. Credits: @Yaffle.
                stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
              } catch (exception) {
                stringifySupported = false;
              }
            }
            isSupported = stringifySupported;
          }
          // Test `JSON.parse`.
          if (name == "json-parse") {
            var parse = exports.parse;
            if (typeof parse == "function") {
              try {
                // FF 3.1b1, b2 will throw an exception if a bare literal is provided.
                // Conforming implementations should also coerce the initial argument to
                // a string prior to parsing.
                if (parse("0") === 0 && !parse(false)) {
                  // Simple parsing test.
                  value = parse(serialized);
                  var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
                  if (parseSupported) {
                    try {
                      // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
                      parseSupported = !parse('"\t"');
                    } catch (exception) {}
                    if (parseSupported) {
                      try {
                        // FF 4.0 and 4.0.1 allow leading `+` signs and leading
                        // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
                        // certain octal literals.
                        parseSupported = parse("01") !== 1;
                      } catch (exception) {}
                    }
                    if (parseSupported) {
                      try {
                        // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
                        // points. These environments, along with FF 3.1b1 and 2,
                        // also allow trailing commas in JSON objects and arrays.
                        parseSupported = parse("1.") !== 1;
                      } catch (exception) {}
                    }
                  }
                }
              } catch (exception) {
                parseSupported = false;
              }
            }
            isSupported = parseSupported;
          }
        }
        return has[name] = !!isSupported;
      }
// implementations are spec-compliant. Based on work by Ken Snyder.
implementations are spec-compliant. Based on work by Ken Snyder.
implementations are spec - compliant . Based on work by Ken Snyder .
function has(name) {
        if (has[name] !== undef) {
          return has[name];
        }
        var isSupported;
        if (name == "bug-string-char-index") {
          isSupported = "a"[0] != "a";
        } else if (name == "json") {
          isSupported = has("json-stringify") && has("json-parse");
        } else {
          var value,
              serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
          if (name == "json-stringify") {
            var stringify = exports.stringify,
                stringifySupported = typeof stringify == "function" && isExtended;
            if (stringifySupported) {
              (value = function () {
                return 1;
              }).toJSON = value;
              try {
                stringifySupported =
                stringify(0) === "0" &&
                stringify(new Number()) === "0" && stringify(new String()) == '""' &&
                stringify(getClass) === undef &&
                stringify(undef) === undef &&
                stringify() === undef &&
                stringify(value) === "1" && stringify([value]) == "[1]" &&
                stringify([undef]) == "[null]" &&
                stringify(null) == "null" &&
                stringify([undef, getClass, null]) == "[null,null,null]" &&
                stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
                stringify(null, value) === "1" && stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
                stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
                stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
                stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
                stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
              } catch (exception) {
                stringifySupported = false;
              }
            }
            isSupported = stringifySupported;
          }
          if (name == "json-parse") {
            var parse = exports.parse;
            if (typeof parse == "function") {
              try {
                if (parse("0") === 0 && !parse(false)) {
                  value = parse(serialized);
                  var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
                  if (parseSupported) {
                    try {
                      parseSupported = !parse('"\t"');
                    } catch (exception) {}
                    if (parseSupported) {
                      try {
                        parseSupported = parse("01") !== 1;
                      } catch (exception) {}
                    }
                    if (parseSupported) {
                      try {
                        parseSupported = parse("1.") !== 1;
                      } catch (exception) {}
                    }
                  }
                }
              } catch (exception) {
                parseSupported = false;
              }
            }
            isSupported = parseSupported;
          }
        }
        return has[name] = !!isSupported;
      }
function has ( name ) { if ( has [ name ] !== undef ) { return has [ name ] ; } var isSupported ; if ( name == "bug-string-char-index" ) { isSupported = "a" [ 0 ] != "a" ; } else if ( name == "json" ) { isSupported = has ( "json-stringify" ) && has ( "json-parse" ) ; } else { var value , serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}' ; if ( name == "json-stringify" ) { var stringify = exports . stringify , stringifySupported = typeof stringify == "function" && isExtended ; if ( stringifySupported ) { ( value = function ( ) { return 1 ; } ) . toJSON = value ; try { stringifySupported = stringify ( 0 ) === "0" && stringify ( new Number ( ) ) === "0" && stringify ( new String ( ) ) == '""' && stringify ( getClass ) === undef && stringify ( undef ) === undef && stringify ( ) === undef && stringify ( value ) === "1" && stringify ( [ value ] ) == "[1]" && stringify ( [ undef ] ) == "[null]" && stringify ( null ) == "null" && stringify ( [ undef , getClass , null ] ) == "[null,null,null]" && stringify ( { "a" : [ value , true , false , null , "\x00\b\n\f\r\t" ] } ) == serialized && stringify ( null , value ) === "1" && stringify ( [ 1 , 2 ] , null , 1 ) == "[\n 1,\n 2\n]" && stringify ( new Date ( - 8.64e15 ) ) == '"-271821-04-20T00:00:00.000Z"' && stringify ( new Date ( 8.64e15 ) ) == '"+275760-09-13T00:00:00.000Z"' && stringify ( new Date ( - 621987552e5 ) ) == '"-000001-01-01T00:00:00.000Z"' && stringify ( new Date ( - 1 ) ) == '"1969-12-31T23:59:59.999Z"' ; } catch ( exception ) { stringifySupported = false ; } } isSupported = stringifySupported ; } if ( name == "json-parse" ) { var parse = exports . parse ; if ( typeof parse == "function" ) { try { if ( parse ( "0" ) === 0 && ! parse ( false ) ) { value = parse ( serialized ) ; var parseSupported = value [ "a" ] . length == 5 && value [ "a" ] [ 0 ] === 1 ; if ( parseSupported ) { try { parseSupported = ! parse ( '"\t"' ) ; } catch ( exception ) { } if ( parseSupported ) { try { parseSupported = parse ( "01" ) !== 1 ; } catch ( exception ) { } } if ( parseSupported ) { try { parseSupported = parse ( "1." ) !== 1 ; } catch ( exception ) { } } } } } catch ( exception ) { parseSupported = false ; } } isSupported = parseSupported ; } } return has [ name ] = ! ! isSupported ; }
implementations are spec-compliant.
implementations are spec - compliant .
// Return cached feature test result. // IE <= 7 doesn't support accessing string characters using square // bracket notation. IE 8 only supports this for primitives. // Indicates whether both `JSON.stringify` and `JSON.parse` are // supported. // Test `JSON.stringify`. // A test function object with a custom `toJSON` method. // Firefox 3.1b1 and b2 serialize string, number, and boolean // primitives as object literals. // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object // literals. // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or // does not define a canonical JSON representation (this applies to // objects with `toJSON` properties as well, *unless* they are nested // within an object or array). // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and // FF 3.1b3 pass this test. // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, // respectively, if the value is omitted entirely. // FF 3.1b1, 2 throw an error if the given value is not a number, // string, array, object, Boolean, or `null` literal. This applies to // objects with custom `toJSON` methods as well, unless they are nested // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` // methods entirely. // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of // `"[null]"`. // YUI 3.0.0b1 fails to serialize `null` literals. // FF 3.1b1, 2 halts serialization if an array contains a function: // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 // elides non-JSON values from objects and arrays, unless they // define custom `toJSON` methods. // Simple serialization test. FF 3.1b1 uses Unicode escape sequences // where character escape codes are expected (e.g., `\b` => `\u0008`). // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly // serialize extended years. // The milliseconds are optional in ES 5, but required in 5.1. // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative // four-digit years instead of six-digit years. Credits: @Yaffle. // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond // values less than 1000. Credits: @Yaffle. // Test `JSON.parse`. // FF 3.1b1, b2 will throw an exception if a bare literal is provided. // Conforming implementations should also coerce the initial argument to // a string prior to parsing. // Simple parsing test. // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. // FF 4.0 and 4.0.1 allow leading `+` signs and leading // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow // certain octal literals. // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal // points. These environments, along with FF 3.1b1 and 2, // also allow trailing commas in JSON objects and arrays.