text: // Generated by CoffeeScript 1.12.7
  (function() {
    "use strict";
    var bom, defaults, events, isEmpty, processItem, processors, sax, setImmediate,
      bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
      extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
      hasProp = {}.hasOwnProperty;
  
    sax = require('sax');
  
    events = require('events');
  
    bom = require('./bom');
  
    processors = require('./processors');
  
    setImmediate = require('timers').setImmediate;
  
    defaults = require('./defaults').defaults;
  
    isEmpty = function(thing) {
      return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0;
    };
  
    processItem = function(processors, item, key) {
      var i, len, process;
      for (i = 0, len = processors.length; i < len; i++) {
        process = processors[i];
        item = process(item, key);
      }
      return item;
    };
  
    exports.Parser = (function(superClass) {
      extend(Parser, superClass);
  
      function Parser(opts) {
        this.parseStringPromise = bind(this.parseStringPromise, this);
        this.parseString = bind(this.parseString, this);
        this.reset = bind(this.reset, this);
        this.assignOrPush = bind(this.assignOrPush, this);
        this.processAsync = bind(this.processAsync, this);
        var key, ref, value;
        if (!(this instanceof exports.Parser)) {
          return new exports.Parser(opts);
        }
        this.options = {};
        ref = defaults["0.2"];
        for (key in ref) {
          if (!hasProp.call(ref, key)) continue;
          value = ref[key];
          this.options[key] = value;
        }
        for (key in opts) {
          if (!hasProp.call(opts, key)) continue;
          value = opts[key];
          this.options[key] = value;
        }
        if (this.options.xmlns) {
          this.options.xmlnskey = this.options.attrkey + "ns";
        }
        if (this.options.normalizeTags) {
          if (!this.options.tagNameProcessors) {
            this.options.tagNameProcessors = [];
          }
          this.options.tagNameProcessors.unshift(processors.normalize);
        }
        this.reset();
      }
  
      Parser.prototype.processAsync = function() {
        var chunk, err;
        try {
          if (this.remaining.length <= this.options.chunkSize) {
            chunk = this.remaining;
            this.remaining = '';
            this.saxParser = this.saxParser.write(chunk);
            return this.saxParser.close();
          } else {
            chunk = this.remaining.substr(0, this.options.chunkSize);
            this.remaining = this.remaining.substr(this.options.chunkSize, this.remaining.length);
            this.saxParser = this.saxParser.write(chunk);
            return setImmediate(this.processAsync);
          }
        } catch (error1) {
          err = error1;
          if (!this.saxParser.errThrown) {
            this.saxParser.errThrown = true;
            return this.emit(err);
          }
        }
      };
  
      Parser.prototype.assignOrPush = function(obj, key, newValue) {
        if (!(key in obj)) {
          if (!this.options.explicitArray) {
            return obj[key] = newValue;
          } else {
            return obj[key] = [newValue];
          }
        } else {
          if (!(obj[key] instanceof Array)) {
            obj[key] = [obj[key]];
          }
          return obj[key].push(newValue);
        }
      };
  
      Parser.prototype.reset = function() {
        var attrkey, charkey, ontext, stack;
        this.removeAllListeners();
        this.saxParser = sax.parser(this.options.strict, {
          trim: false,
          normalize: false,
          xmlns: this.options.xmlns
        });
        this.saxParser.errThrown = false;
        this.saxParser.onerror = (function(_this) {
          return function(error) {
            _this.saxParser.resume();
            if (!_this.saxParser.errThrown) {
              _this.saxParser.errThrown = true;
              return _this.emit("error", error);
            }
          };
        })(this);
        this.saxParser.onend = (function(_this) {
          return function() {
            if (!_this.saxParser.ended) {
              _this.saxParser.ended = true;
              return _this.emit("end", _this.resultObject);
            }
          };
        })(this);
        this.saxParser.ended = false;
        this.EXPLICIT_CHARKEY = this.options.explicitCharkey;
        this.resultObject = null;
        stack = [];
        attrkey = this.options.attrkey;
        charkey = this.options.charkey;
        this.saxParser.onopentag = (function(_this) {
          return function(node) {
            var key, newValue, obj, processedKey, ref;
            obj = {};
            obj[charkey] = "";
            if (!_this.options.ignoreAttrs) {
              ref = node.attributes;
              for (key in ref) {
                if (!hasProp.call(ref, key)) continue;
                if (!(attrkey in obj) && !_this.options.mergeAttrs) {
                  obj[attrkey] = {};
                }
                newValue = _this.options.attrValueProcessors ? processItem(_this.options.attrValueProcessors, node.attributes[key], key) : node.attributes[key];
                processedKey = _this.options.attrNameProcessors ? processItem(_this.options.attrNameProcessors, key) : key;
                if (_this.options.mergeAttrs) {
                  _this.assignOrPush(obj, processedKey, newValue);
                } else {
                  obj[attrkey][processedKey] = newValue;
                }
              }
            }
            obj["#name"] = _this.options.tagNameProcessors ? processItem(_this.options.tagNameProcessors, node.name, node.attributes) : node.name;
            if (_this.options.xmlns) {
              obj[_this.options.xmlnskey] = {
                uri: node.uri,
                local: node.local
              };
            }
            return stack.push(obj);
          };
        })(this);
        this.saxParser.onclosetag = (function(_this) {
          return function() {
            var cdata, emptyStr, key, node, nodeName, obj, objClone, old, s, xpath;
            obj = stack.pop();
            nodeName = obj["#name"];
            if (!_this.options.explicitChildren || !_this.options.preserveChildrenOrder) {
              delete obj["#name"];
            }
            if (obj.cdata === true) {
              cdata = obj.cdata;
              delete obj.cdata;
            }
            s = stack[stack.length - 1];
            if (obj[charkey].match(/^\s*$/) && !cdata) {
              emptyStr = obj[charkey];
              delete obj[charkey];
            } else {
              if (_this.options.trim) {
                obj[charkey] = obj[charkey].trim();
              }
              if (_this.options.normalize) {
                obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
              }
              obj[charkey] = _this.options.valueProcessors ? processItem(_this.options.valueProcessors, obj[charkey], nodeName) : obj[charkey];
              if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
                obj = obj[charkey];
              }
            }
            if (isEmpty(obj)) {
              if (typeof _this.options.emptyTag === 'function') {
                obj = _this.options.emptyTag();
              } else {
                obj = _this.options.emptyTag !== '' ? _this.options.emptyTag : emptyStr;
              }
            }
            if (_this.options.validator != null) {
              xpath = "/" + ((function() {
                var i, len, results;
                results = [];
                for (i = 0, len = stack.length; i < len; i++) {
                  node = stack[i];
                  results.push(node["#name"]);
                }
                return results;
              })()).concat(nodeName).join("/");
              (function() {
                var err;
                try {
                  return obj = _this.options.validator(xpath, s && s[nodeName], obj);
                } catch (error1) {
                  err = error1;
                  return _this.emit("error", err);
                }
              })();
            }
            if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') {
              if (!_this.options.preserveChildrenOrder) {
                node = {};
                if (_this.options.attrkey in obj) {
                  node[_this.options.attrkey] = obj[_this.options.attrkey];
                  delete obj[_this.options.attrkey];
                }
                if (!_this.options.charsAsChildren && _this.options.charkey in obj) {
                  node[_this.options.charkey] = obj[_this.options.charkey];
                  delete obj[_this.options.charkey];
                }
                if (Object.getOwnPropertyNames(obj).length > 0) {
                  node[_this.options.childkey] = obj;
                }
                obj = node;
              } else if (s) {
                s[_this.options.childkey] = s[_this.options.childkey] || [];
                objClone = {};
                for (key in obj) {
                  if (!hasProp.call(obj, key)) continue;
                  objClone[key] = obj[key];
                }
                s[_this.options.childkey].push(objClone);
                delete obj["#name"];
                if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
                  obj = obj[charkey];
                }
              }
            }
            if (stack.length > 0) {
              return _this.assignOrPush(s, nodeName, obj);
            } else {
              if (_this.options.explicitRoot) {
                old = obj;
                obj = {};
                obj[nodeName] = old;
              }
              _this.resultObject = obj;
              _this.saxParser.ended = true;
              return _this.emit("end", _this.resultObject);
            }
          };
        })(this);
        ontext = (function(_this) {
          return function(text) {
            var charChild, s;
            s = stack[stack.length - 1];
            if (s) {
              s[charkey] += text;
              if (_this.options.explicitChildren && _this.options.preserveChildrenOrder && _this.options.charsAsChildren && (_this.options.includeWhiteChars || text.replace(/\\n/g, '').trim() !== '')) {
                s[_this.options.childkey] = s[_this.options.childkey] || [];
                charChild = {
                  '#name': '__text__'
                };
                charChild[charkey] = text;
                if (_this.options.normalize) {
                  charChild[charkey] = charChild[charkey].replace(/\s{2,}/g, " ").trim();
                }
                s[_this.options.childkey].push(charChild);
              }
              return s;
            }
          };
        })(this);
        this.saxParser.ontext = ontext;
        return this.saxParser.oncdata = (function(_this) {
          return function(text) {
            var s;
            s = ontext(text);
            if (s) {
              return s.cdata = true;
            }
          };
        })(this);
      };
  
      Parser.prototype.parseString = function(str, cb) {
        var err;
        if ((cb != null) && typeof cb === "function") {
          this.on("end", function(result) {
            this.reset();
            return cb(null, result);
          });
          this.on("error", function(err) {
            this.reset();
            return cb(err);
          });
        }
        try {
          str = str.toString();
          if (str.trim() === '') {
            this.emit("end", null);
            return true;
          }
          str = bom.stripBOM(str);
          if (this.options.async) {
            this.remaining = str;
            setImmediate(this.processAsync);
            return this.saxParser;
          }
          return this.saxParser.write(str).close();
        } catch (error1) {
          err = error1;
          if (!(this.saxParser.errThrown || this.saxParser.ended)) {
            this.emit('error', err);
            return this.saxParser.errThrown = true;
          } else if (this.saxParser.ended) {
            throw err;
          }
        }
      };
  
      Parser.prototype.parseStringPromise = function(str) {
        return new Promise((function(_this) {
          return function(resolve, reject) {
            return _this.parseString(str, function(err, value) {
              if (err) {
                return reject(err);
              } else {
                return resolve(value);
              }
            });
          };
        })(this));
      };
  
      return Parser;
  
    })(events);
  
    exports.parseString = function(str, a, b) {
      var cb, options, parser;
      if (b != null) {
        if (typeof b === 'function') {
          cb = b;
        }
        if (typeof a === 'object') {
          options = a;
        }
      } else {
        if (typeof a === 'function') {
          cb = a;
        }
        options = {};
      }
      parser = new exports.Parser(options);
      return parser.parseString(str, cb);
    };
  
    exports.parseStringPromise = function(str, a) {
      var options, parser;
      if (typeof a === 'object') {
        options = a;
      }
      parser = new exports.Parser(options);
      return parser.parseStringPromise(str);
    };
  
  }).call(this);
  