text: 'use strict';
  var SourceMapGenerator = require('source-map').SourceMapGenerator;
  var SourceMapConsumer = require('source-map').SourceMapConsumer;
  
  function unixStylePath(filePath) {
    return filePath.replace(/\\/g, '/');
  }
  
  function Concat(generateSourceMap, fileName, separator) {
    this.lineOffset = 0;
    this.columnOffset = 0;
    this.sourceMapping = generateSourceMap;
    this.contentParts = [];
  
    if (separator === undefined) {
      this.separator = bufferFrom('');
    } else {
      this.separator = bufferFrom(separator);
    }
  
    if (this.sourceMapping) {
      this._sourceMap = new SourceMapGenerator({file: unixStylePath(fileName)});
      this.separatorLineOffset = 0;
      this.separatorColumnOffset = 0;
      var separatorString = this.separator.toString();
      for (var i = 0; i < separatorString.length; i++) {
        this.separatorColumnOffset++;
        if (separatorString[i] === '\n') {
          this.separatorLineOffset++;
          this.separatorColumnOffset = 0;
        }
      }
    }
  }
  
  Concat.prototype.add = function(filePath, content, sourceMap) {
    filePath = filePath && unixStylePath(filePath);
  
    if (!Buffer.isBuffer(content)) {
      content = bufferFrom(content);
    }
  
    if (this.contentParts.length !== 0) {
      this.contentParts.push(this.separator);
    }
    this.contentParts.push(content);
  
    if (this.sourceMapping) {
      var contentString = content.toString();
      var lines = contentString.split('\n').length;
  
      if (Object.prototype.toString.call(sourceMap) === '[object String]')
        sourceMap = JSON.parse(sourceMap);
  
      if (sourceMap && sourceMap.mappings && sourceMap.mappings.length > 0) {
        var upstreamSM = new SourceMapConsumer(sourceMap);
        var _this = this;
        upstreamSM.eachMapping(function(mapping) {
          if (mapping.source) {
            _this._sourceMap.addMapping({
              generated: {
                line: _this.lineOffset + mapping.generatedLine,
                column: (mapping.generatedLine === 1 ? _this.columnOffset : 0) + mapping.generatedColumn
              },
              original: mapping.originalLine == null ? null : {
                line: mapping.originalLine,
                column: mapping.originalColumn
              },
              source: mapping.originalLine != null ? mapping.source : null,
              name: mapping.name
            });
          }
        });
        if (upstreamSM.sourcesContent) {
          upstreamSM.sourcesContent.forEach(function(sourceContent, i) {
            _this._sourceMap.setSourceContent(upstreamSM.sources[i], sourceContent);
          });
        }
      } else {
        if (sourceMap && sourceMap.sources && sourceMap.sources.length > 0)
          filePath = sourceMap.sources[0];
        if (filePath) {
          for (var i = 1; i <= lines; i++) {
            this._sourceMap.addMapping({
              generated: {
                line: this.lineOffset + i,
                column: (i === 1 ? this.columnOffset : 0)
              },
              original: {
                line: i,
                column: 0
              },
              source: filePath
            });
          }
          if (sourceMap && sourceMap.sourcesContent)
            this._sourceMap.setSourceContent(filePath, sourceMap.sourcesContent[0]);
        }
      }
      if (lines > 1)
        this.columnOffset = 0;
      if (this.separatorLineOffset === 0)
        this.columnOffset += contentString.length - Math.max(0, contentString.lastIndexOf('\n')+1);
      this.columnOffset += this.separatorColumnOffset;
      this.lineOffset += lines - 1 + this.separatorLineOffset;
    }
  };
  
  Object.defineProperty(Concat.prototype, 'content', {
    get: function content() {
      return Buffer.concat(this.contentParts);
    }
  });
  
  Object.defineProperty(Concat.prototype, 'sourceMap', {
    get: function sourceMap() {
      return this._sourceMap ? this._sourceMap.toString() : undefined;
    }
  });
  
  function bufferFrom(content) {
    try {
      return Buffer.from(content);
    } catch(e) {
      if (Object.prototype.toString.call(content) !== '[object String]') {
        throw new TypeError("separator must be a string");
      }
      return new Buffer(content);
    }
  }
  Concat.bufferFrom = bufferFrom;
  Concat.default = Concat;
  
  module.exports = Concat;
  