text: // The validateJSON plugin depends on the caret plugin, the JSON lint parser,
  // and the JSON lint formatter from jsonlint.com.
  (function($) {
      /**
       * Helper Function for Caret positioning
       * Gratefully borrowed from the Masked Input Plugin by Josh Bush
       * http://digitalbush.com/projects/masked-input-plugin
       **/
      if (typeof $.fn.caret === "undefined") {
          $.fn.caret = function(begin, end) {
              if (this.length === 0) {
                  return;
              }
              if (typeof begin === 'number') {
                  end = (typeof end === 'number') ? end : begin;
                  return this.each(function() {
                      if (this.setSelectionRange) {
                          this.focus();
                          this.setSelectionRange(begin, end);
                      } else if (this.createTextRange) {
                          var range = this.createTextRange();
                          range.collapse(true);
                          range.moveEnd('character', end);
                          range.moveStart('character', begin);
                          range.select();
                      }
                  });
              } else {
                  if (this[0].setSelectionRange) {
                      begin = this[0].selectionStart;
                      end = this[0].selectionEnd;
                  } else if (document.selection && document.selection.createRange) {
                      var range = document.selection.createRange();
                      begin = -range.duplicate().moveStart('character', -100000);
                      end = begin + range.text.length;
                  }
                  return {
                      "begin": begin,
                      "end": end
                  };
              }
          };
      }
  })(jQuery);
  
  // JSON lint plugin gratefully swiped from
  // [GitHub](https://github.com/umbrae/jsonlintdotcom)
  (function($) {
      $.fn.validateJSON = function(options) {
  
          var settings, jsl;
  
          // Defaults, extended with options
          settings = $.extend({
              'reformat': true,
              'compress': false,
              'onSuccess': function() {},
              'onError': function(error) {}
          }, options);
  
          jsl = typeof(jsl) === 'undefined' ? {} : jsl;
  
          /**
           * JSON Lint Parser gratefully provided by Zach Carter
           * https://github.com/zaach/jsonlint
           **/
          jsl.parser = function() {
              var a = !0,
                  b = !1,
                  c = {},
                  d = function() {
                      var a = {
                              trace: function() {},
                              yy: {},
                              symbols_: {
                                  error: 2,
                                  JSONString: 3,
                                  STRING: 4,
                                  JSONNumber: 5,
                                  NUMBER: 6,
                                  JSONNullLiteral: 7,
                                  NULL: 8,
                                  JSONBooleanLiteral: 9,
                                  TRUE: 10,
                                  FALSE: 11,
                                  JSONText: 12,
                                  JSONObject: 13,
                                  EOF: 14,
                                  JSONArray: 15,
                                  JSONValue: 16,
                                  "{": 17,
                                  "}": 18,
                                  JSONMemberList: 19,
                                  JSONMember: 20,
                                  ":": 21,
                                  ",": 22,
                                  "[": 23,
                                  "]": 24,
                                  JSONElementList: 25,
                                  $accept: 0,
                                  $end: 1
                              },
                              terminals_: {
                                  2: "error",
                                  4: "STRING",
                                  6: "NUMBER",
                                  8: "NULL",
                                  10: "TRUE",
                                  11: "FALSE",
                                  14: "EOF",
                                  17: "{",
                                  18: "}",
                                  21: ":",
                                  22: ",",
                                  23: "[",
                                  24: "]"
                              },
                              productions_: [0, [3, 1],
                                  [5, 1],
                                  [7, 1],
                                  [9, 1],
                                  [9, 1],
                                  [12, 2],
                                  [12, 2],
                                  [16, 1],
                                  [16, 1],
                                  [16, 1],
                                  [16, 1],
                                  [16, 1],
                                  [16, 1],
                                  [13, 2],
                                  [13, 3],
                                  [20, 3],
                                  [19, 1],
                                  [19, 3],
                                  [15, 2],
                                  [15, 3],
                                  [25, 1],
                                  [25, 3]
                              ],
                              performAction: function(a, b, c, d, e, f, g) {
                                  var h = f.length - 1;
                                  switch (e) {
                                      case 1:
                                          this.$ = a;
                                          break;
                                      case 2:
                                          this.$ = Number(a);
                                          break;
                                      case 3:
                                          this.$ = null;
                                          break;
                                      case 4:
                                          this.$ = !0;
                                          break;
                                      case 5:
                                          this.$ = !1;
                                          break;
                                      case 6:
                                          return this.$ = f[h - 1];
                                      case 7:
                                          return this.$ = f[h - 1];
                                      case 8:
                                          this.$ = f[h];
                                          break;
                                      case 9:
                                          this.$ = f[h];
                                          break;
                                      case 10:
                                          this.$ = f[h];
                                          break;
                                      case 11:
                                          this.$ = f[h];
                                          break;
                                      case 12:
                                          this.$ = f[h];
                                          break;
                                      case 13:
                                          this.$ = f[h];
                                          break;
                                      case 14:
                                          this.$ = {};
                                          break;
                                      case 15:
                                          this.$ = f[h - 1];
                                          break;
                                      case 16:
                                          this.$ = [f[h - 2], f[h]];
                                          break;
                                      case 17:
                                          this.$ = {}, this.$[f[h][0]] = f[h][1];
                                          break;
                                      case 18:
                                          this.$ = f[h - 2], f[h - 2][f[h][0]] = f[h][1];
                                          break;
                                      case 19:
                                          this.$ = [];
                                          break;
                                      case 20:
                                          this.$ = f[h - 1];
                                          break;
                                      case 21:
                                          this.$ = [f[h]];
                                          break;
                                      case 22:
                                          this.$ = f[h - 2], f[h - 2].push(f[h])
                                  }
                              },
                              table: [{
                                  12: 1,
                                  13: 2,
                                  15: 3,
                                  17: [1, 4],
                                  23: [1, 5]
                              }, {
                                  1: [3]
                              }, {
                                  14: [1, 6]
                              }, {
                                  14: [1, 7]
                              }, {
                                  3: 11,
                                  4: [1, 12],
                                  18: [1, 8],
                                  19: 9,
                                  20: 10
                              }, {
                                  3: 18,
                                  4: [1, 12],
                                  5: 19,
                                  6: [1, 25],
                                  7: 16,
                                  8: [1, 22],
                                  9: 17,
                                  10: [1, 23],
                                  11: [1, 24],
                                  13: 20,
                                  15: 21,
                                  16: 15,
                                  17: [1, 4],
                                  23: [1, 5],
                                  24: [1, 13],
                                  25: 14
                              }, {
                                  1: [2, 6]
                              }, {
                                  1: [2, 7]
                              }, {
                                  14: [2, 14],
                                  18: [2, 14],
                                  22: [2, 14],
                                  24: [2, 14]
                              }, {
                                  18: [1, 26],
                                  22: [1, 27]
                              }, {
                                  18: [2, 17],
                                  22: [2, 17]
                              }, {
                                  21: [1, 28]
                              }, {
                                  18: [2, 1],
                                  21: [2, 1],
                                  22: [2, 1],
                                  24: [2, 1]
                              }, {
                                  14: [2, 19],
                                  18: [2, 19],
                                  22: [2, 19],
                                  24: [2, 19]
                              }, {
                                  22: [1, 30],
                                  24: [1, 29]
                              }, {
                                  22: [2, 21],
                                  24: [2, 21]
                              }, {
                                  18: [2, 8],
                                  22: [2, 8],
                                  24: [2, 8]
                              }, {
                                  18: [2, 9],
                                  22: [2, 9],
                                  24: [2, 9]
                              }, {
                                  18: [2, 10],
                                  22: [2, 10],
                                  24: [2, 10]
                              }, {
                                  18: [2, 11],
                                  22: [2, 11],
                                  24: [2, 11]
                              }, {
                                  18: [2, 12],
                                  22: [2, 12],
                                  24: [2, 12]
                              }, {
                                  18: [2, 13],
                                  22: [2, 13],
                                  24: [2, 13]
                              }, {
                                  18: [2, 3],
                                  22: [2, 3],
                                  24: [2, 3]
                              }, {
                                  18: [2, 4],
                                  22: [2, 4],
                                  24: [2, 4]
                              }, {
                                  18: [2, 5],
                                  22: [2, 5],
                                  24: [2, 5]
                              }, {
                                  18: [2, 2],
                                  22: [2, 2],
                                  24: [2, 2]
                              }, {
                                  14: [2, 15],
                                  18: [2, 15],
                                  22: [2, 15],
                                  24: [2, 15]
                              }, {
                                  3: 11,
                                  4: [1, 12],
                                  20: 31
                              }, {
                                  3: 18,
                                  4: [1, 12],
                                  5: 19,
                                  6: [1, 25],
                                  7: 16,
                                  8: [1, 22],
                                  9: 17,
                                  10: [1, 23],
                                  11: [1, 24],
                                  13: 20,
                                  15: 21,
                                  16: 32,
                                  17: [1, 4],
                                  23: [1, 5]
                              }, {
                                  14: [2, 20],
                                  18: [2, 20],
                                  22: [2, 20],
                                  24: [2, 20]
                              }, {
                                  3: 18,
                                  4: [1, 12],
                                  5: 19,
                                  6: [1, 25],
                                  7: 16,
                                  8: [1, 22],
                                  9: 17,
                                  10: [1, 23],
                                  11: [1, 24],
                                  13: 20,
                                  15: 21,
                                  16: 33,
                                  17: [1, 4],
                                  23: [1, 5]
                              }, {
                                  18: [2, 18],
                                  22: [2, 18]
                              }, {
                                  18: [2, 16],
                                  22: [2, 16]
                              }, {
                                  22: [2, 22],
                                  24: [2, 22]
                              }],
                              defaultActions: {
                                  6: [2, 6],
                                  7: [2, 7]
                              },
                              parseError: function(a, b) {
                                  throw new Error(a)
                              },
                              parse: function(a) {
                                  function o() {
                                      var a;
                                      a = b.lexer.lex() || 1, typeof a != "number" && (a = b.symbols_[a] || a);
                                      return a
                                  }
  
                                  function n(a) {
                                      c.length = c.length - 2 * a, d.length = d.length - a, e.length = e.length - a
                                  }
                                  var b = this,
                                      c = [0],
                                      d = [null],
                                      e = [],
                                      f = this.table,
                                      g = "",
                                      h = 0,
                                      i = 0,
                                      j = 0,
                                      k = 2,
                                      l = 1;
                                  this.lexer.setInput(a), this.lexer.yy = this.yy, this.yy.lexer = this.lexer, typeof this.lexer.yylloc == "undefined" && (this.lexer.yylloc = {});
                                  var m = this.lexer.yylloc;
                                  e.push(m), typeof this.yy.parseError == "function" && (this.parseError = this.yy.parseError);
                                  var p, q, r, s, t, u, v = {},
                                      w, x, y, z;
                                  for (;;) {
                                      r = c[c.length - 1], this.defaultActions[r] ? s = this.defaultActions[r] : (p == null && (p = o()), s = f[r] && f[r][p]);
                                      if (typeof s == "undefined" || !s.length || !s[0]) {
                                          if (!j) {
                                              z = [];
                                              for (w in f[r]) this.terminals_[w] && w > 2 && z.push("'" + this.terminals_[w] + "'");
                                              var A = "";
                                              this.lexer.showPosition ? A = "Parse error on line " + (h + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + z.join(", ") : A = "Parse error on line " + (h + 1) + ": Unexpected " + (p == 1 ? "end of input" : "'" + (this.terminals_[p] || p) + "'"), this.parseError(A, {
                                                  text: this.lexer.match,
                                                  token: this.terminals_[p] || p,
                                                  line: this.lexer.yylineno,
                                                  loc: m,
                                                  expected: z
                                              })
                                          }
                                          if (j == 3) {
                                              if (p == l) throw new Error(A || "Parsing halted.");
                                              i = this.lexer.yyleng, g = this.lexer.yytext, h = this.lexer.yylineno, m = this.lexer.yylloc, p = o()
                                          }
                                          for (;;) {
                                              if (k.toString() in f[r]) break;
                                              if (r == 0) throw new Error(A || "Parsing halted.");
                                              n(1), r = c[c.length - 1]
                                          }
                                          q = p, p = k, r = c[c.length - 1], s = f[r] && f[r][k], j = 3
                                      }
                                      if (s[0] instanceof Array && s.length > 1) throw new Error("Parse Error: multiple actions possible at state: " + r + ", token: " + p);
                                      switch (s[0]) {
                                          case 1:
                                              c.push(p), d.push(this.lexer.yytext), e.push(this.lexer.yylloc), c.push(s[1]), p = null, q ? (p = q, q = null) : (i = this.lexer.yyleng, g = this.lexer.yytext, h = this.lexer.yylineno, m = this.lexer.yylloc, j > 0 && j--);
                                              break;
                                          case 2:
                                              x = this.productions_[s[1]][1], v.$ = d[d.length - x], v._$ = {
                                                  first_line: e[e.length - (x || 1)].first_line,
                                                  last_line: e[e.length - 1].last_line,
                                                  first_column: e[e.length - (x || 1)].first_column,
                                                  last_column: e[e.length - 1].last_column
                                              }, u = this.performAction.call(v, g, i, h, this.yy, s[1], d, e);
                                              if (typeof u != "undefined") return u;
                                              x && (c = c.slice(0, -1 * x * 2), d = d.slice(0, -1 * x), e = e.slice(0, -1 * x)), c.push(this.productions_[s[1]][0]), d.push(v.$), e.push(v._$), y = f[c[c.length - 2]][c[c.length - 1]], c.push(y);
                                              break;
                                          case 3:
                                              return !0
                                      }
                                  }
                                  return !0
                              }
                          },
                          f = function() {
                              var a = {
                                  EOF: 1,
                                  parseError: function(a, b) {
                                      if (this.yy.parseError) this.yy.parseError(a, b);
                                      else throw new Error(a)
                                  },
                                  setInput: function(a) {
                                      this._input = a, this._more = this._less = this.done = !1, this.yylineno = this.yyleng = 0, this.yytext = this.matched = this.match = "", this.conditionStack = ["INITIAL"], this.yylloc = {
                                          first_line: 1,
                                          first_column: 0,
                                          last_line: 1,
                                          last_column: 0
                                      };
                                      return this
                                  },
                                  input: function() {
                                      var a = this._input[0];
                                      this.yytext += a, this.yyleng++, this.match += a, this.matched += a;
                                      var b = a.match(/\n/);
                                      b && this.yylineno++, this._input = this._input.slice(1);
                                      return a
                                  },
                                  unput: function(a) {
                                      this._input = a + this._input;
                                      return this
                                  },
                                  more: function() {
                                      this._more = !0;
                                      return this
                                  },
                                  pastInput: function() {
                                      var a = this.matched.substr(0, this.matched.length - this.match.length);
                                      return (a.length > 20 ? "..." : "") + a.substr(-20).replace(/\n/g, "")
                                  },
                                  upcomingInput: function() {
                                      var a = this.match;
                                      a.length < 20 && (a += this._input.substr(0, 20 - a.length));
                                      return (a.substr(0, 20) + (a.length > 20 ? "..." : "")).replace(/\n/g, "")
                                  },
                                  showPosition: function() {
                                      var a = this.pastInput(),
                                          b = Array(a.length + 1).join("-");
                                      return a + this.upcomingInput() + "\n" + b + "^"
                                  },
                                  next: function() {
                                      if (this.done) return this.EOF;
                                      this._input || (this.done = !0);
                                      var a, b, c, d;
                                      this._more || (this.yytext = "", this.match = "");
                                      var e = this._currentRules();
                                      for (var f = 0; f < e.length; f++) {
                                          b = this._input.match(this.rules[e[f]]);
                                          if (b) {
                                              d = b[0].match(/\n.*/g), d && (this.yylineno += d.length), this.yylloc = {
                                                  first_line: this.yylloc.last_line,
                                                  last_line: this.yylineno + 1,
                                                  first_column: this.yylloc.last_column,
                                                  last_column: d ? d[d.length - 1].length - 1 : this.yylloc.last_column + b[0].length
                                              }, this.yytext += b[0], this.match += b[0], this.matches = b, this.yyleng = this.yytext.length, this._more = !1, this._input = this._input.slice(b[0].length), this.matched += b[0], a = this.performAction.call(this, this.yy, this, e[f], this.conditionStack[this.conditionStack.length - 1]);
                                              if (a) return a;
                                              return
                                          }
                                      }
                                      if (this._input === "") return this.EOF;
                                      this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), {
                                          text: "",
                                          token: null,
                                          line: this.yylineno
                                      })
                                  },
                                  lex: function() {
                                      var a = this.next();
                                      return typeof a != "undefined" ? a : this.lex()
                                  },
                                  begin: function(a) {
                                      this.conditionStack.push(a)
                                  },
                                  popState: function() {
                                      return this.conditionStack.pop()
                                  },
                                  _currentRules: function() {
                                      return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules
                                  }
                              };
                              a.performAction = function(a, b, c, d) {
                                  var e = d;
                                  switch (c) {
                                      case 0:
                                          break;
                                      case 1:
                                          return 6;
                                      case 2:
                                          b.yytext = b.yytext.substr(1, b.yyleng - 2);
                                          return 4;
                                      case 3:
                                          return 17;
                                      case 4:
                                          return 18;
                                      case 5:
                                          return 23;
                                      case 6:
                                          return 24;
                                      case 7:
                                          return 22;
                                      case 8:
                                          return 21;
                                      case 9:
                                          return 10;
                                      case 10:
                                          return 11;
                                      case 11:
                                          return 8;
                                      case 12:
                                          return 14;
                                      case 13:
                                          return "INVALID"
                                  }
                              }, a.rules = [/^\s+/, /^-?([0-9]|[1-9][0-9]+)(\.[0-9]+)?([eE][-+]?[0-9]+)?\b/, /^"(\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^\0-\x09\x0a-\x1f"\\])*"/, /^\{/, /^\}/, /^\[/, /^\]/, /^,/, /^:/, /^true\b/, /^false\b/, /^null\b/, /^$/, /^./], a.conditions = {
                                  INITIAL: {
                                      rules: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
                                      inclusive: !0
                                  }
                              };
                              return a
                          }();
                      a.lexer = f;
                      return a
                  }();
              typeof a != "undefined" && typeof c != "undefined" && (c.parser = d, c.parse = function() {
                  return d.parse.apply(d, arguments)
              }, c.main = function(b) {
                  if (!b[1]) throw new Error("Usage: " + b[0] + " FILE");
                  if (typeof process != "undefined") var d = a("fs").readFileSync(a("path").join(process.cwd(), b[1]), "utf8");
                  else var e = a("file").path(a("file").cwd()),
                      d = e.join(b[1]).read({
                          charset: "utf-8"
                      });
                  return c.parser.parse(d)
              }, typeof b != "undefined" && a.main === b && c.main(typeof process != "undefined" ? process.argv.slice(1) : a("system").args));
              return c
          }()
  
          /**
           * jsl.format - Provide json reformatting in a character-by-character approach, so that even invalid JSON may be reformatted (to the best of its ability).
           *
           **/
          jsl.format = (function() {
  
              function repeat(s, count) {
                  return new Array(count + 1).join(s);
              }
  
              function formatJson(json) {
                  var i = 0,
                      il = 0,
                      tab = "    ",
                      newJson = "",
                      indentLevel = 0,
                      inString = false,
                      currentChar = null;
  
                  for (i = 0, il = json.length; i < il; i += 1) {
                      currentChar = json.charAt(i);
  
                      switch (currentChar) {
                          case '{':
                          case '[':
                              if (!inString) {
                                  newJson += currentChar + "\n" + repeat(tab, indentLevel + 1);
                                  indentLevel += 1;
                              } else {
                                  newJson += currentChar;
                              }
                              break;
                          case '}':
                          case ']':
                              if (!inString) {
                                  indentLevel -= 1;
                                  newJson += "\n" + repeat(tab, indentLevel) + currentChar;
                              } else {
                                  newJson += currentChar;
                              }
                              break;
                          case ',':
                              if (!inString) {
                                  newJson += ",\n" + repeat(tab, indentLevel);
                              } else {
                                  newJson += currentChar;
                              }
                              break;
                          case ':':
                              if (!inString) {
                                  newJson += ": ";
                              } else {
                                  newJson += currentChar;
                              }
                              break;
                          case ' ':
                          case "\n":
                          case "\t":
                              if (inString) {
                                  newJson += currentChar;
                              }
                              break;
                          case '"':
                              if (i > 0 && json.charAt(i - 1) !== '\\') {
                                  inString = !inString;
                              }
                              newJson += currentChar;
                              break;
                          default:
                              newJson += currentChar;
                              break;
                      }
                  }
  
                  return newJson;
              }
  
              return {
                  "formatJson": formatJson
              };
  
          }());
  
  
          /**
           * Get the Nth position of a character in a string
           * @searchStr the string to search through
           * @char the character to find
           * @pos int the nth character to find, 1 based.
           *
           * @return int the position of the character found
           **/
          function getNthPos(searchStr, char, pos) {
              var i, charCount = 0,
                  strArr = searchStr.split(char);
  
              if (pos === 0) {
                  return 0;
              }
  
              for (i = 0; i < pos; i++) {
                  if (i >= strArr.length) {
                      return -1;
                  }
  
                  // +1 because we split out some characters
                  charCount += strArr[i].length + char.length;
              }
  
              return charCount;
          }
  
  
          /**
           * Validate the JSON we've been given, displaying an error or success message.
           * @return void
           **/
          function validate() {
              var el, val, valid, lineNum, lineMatches, lineStart, lineEnd, result;
  
              el = $(this);
              val = el.val().trim();
              valid = false;
  
              try {
                  result = jsl.parser.parse(val);
  
                  if (result) {
                      if (settings.reformat) {
                          el.val(JSON.stringify(JSON.parse(val), null, "    "));
                      }
  
                      if (settings.compress) {
                          el.val(JSON.stringify(JSON.parse(val), null, ""));
                      }
                      valid = true;
  
                  } else {
                      result = {};
                      valid = false;
                  }
              } catch (parseException) {
  
                  /**
                   * If we failed to validate, run our manual formatter and then re-validate so that we
                   * can get a better line number. On a successful validate, we don't want to run our
                   * manual formatter because the automatic one is faster and probably more reliable.
                   **/
                  try {
                      if (settings.reformat) {
                          val = jsl.format.formatJson(val);
                          el.val(val);
                          result = jsl.parser.parse(el.val());
                      }
                  } catch (e) {
                      parseException = e;
                  }
  
                  lineMatches = parseException.message.match(/line ([0-9]*)/);
                  if (lineMatches && typeof lineMatches === "object" && lineMatches.length > 1) {
                      lineNum = parseInt(lineMatches[1], 10);
  
                      if (lineNum === 1) {
                          lineStart = 0;
                      } else {
                          lineStart = getNthPos(val, "\n", lineNum - 1);
                      }
  
                      lineEnd = val.indexOf("\n", lineStart);
                      if (lineEnd < 0) {
                          lineEnd = val.length;
                      }
  
                      result = JSON.stringify(parseException);
                      el.focus().caret(lineStart, lineEnd);
                  }
  
                  valid = false;
              }
  
              return {
                  valid: valid,
                  json: result
              };
          }
          // Do it
          return this.each(function() {
              var resp = validate.apply(this);
  
              // Call the handler
              settings[(resp.valid ? 'onSuccess' : 'onError')].apply(this, [resp]);
          });
  
      };
  })(jQuery);