****************************************
复制文件夹
****************************************
968111
async function copy(src, dist, options = {}) {
    let [from, to] = await Promise.all([stat(src), stat(dist)]);

    // 判断源文件是否存在
    if (!from) {
        throw new Error(`Error: '${src}' is not exists!`);
    }

    // 判断目标文件是否存在
    if (to) {
        throw new Error(`Error: '${dist}' is exists!`);
    }

    // 复制文件
    if (from.isDirectory()) {
        let files = await readdir(src);

        // 创建目标文件夹
        await mkdir(dist);

        // 拷贝下级文件
        await Promise.all(files.map(file => {
            let dir = path.join(src, file);

            // 处理排队文件
            if (options.exclude && options.exclude.test(dir)) {
                return Promise.resolve();
            }

            // 复制文件
            return copy(dir, path.join(dist, file), options);
        }));
    } else {
        await copyFile(src, dist);
    }
}
408301
async function scanFile (dir, ext, ret_absolute)
{
return new Promise( async function(resolve, reject){
    // console.log(dir);
    fs.readdir(dir, function(err, files){
        let file_arr = [];
        if( ! files ){
            return resolve(file_arr);
        }
        files.forEach(function(elm){
            if( elm.indexOf('.') > -1 ){
                if( !ext || '.'+ext.toUpperCase()==path.extname(elm).toUpperCase() ){
                    // 返回全路径
                    if( ret_absolute ){
                        elm = path.join(dir, elm);
                    }
                    // 检查文件后缀名
                    file_arr.push(elm);
                }
            }
        });
        resolve(file_arr);
    });
});
}
45592
function parsePackScript(file, context, opts) {
    var content = file.getContent();
    var packScriptFiles = [];

    var hasScriptPlaceholder
        = content.indexOf(opts.scriptPlaceholder) !== -1;
    var hasScriptAsyncPlaceholder
        = content.indexOf(opts.scriptAsyncPlaceholder) !== -1;
    var hasRequireConfigPlaceholder
        = content.indexOf(opts.resourceConfigPlaceholder) !== -1;

    var getPlaceholder = function (isLoader) {
        if (!opts.autoInsertPlaceholder) {
            return;
        }
        // 在requirejs之后 requrie.config 脚本
        if (isLoader && !hasRequireConfigPlaceholder) {
            hasRequireConfigPlaceholder = true;
            return opts.resourceConfigPlaceholder;
        }
        //在异步入口模块前插入合成后的pkg
        else if (!hasScriptAsyncPlaceholder) {
            hasScriptAsyncPlaceholder = true;
            return opts.scriptAsyncPlaceholder;
        }
    };
    /*
    //在body之前插入scriptPlaceholder
    if(!hasScriptPlaceholder){
        hasScriptPlaceholder = true;
        var rBody = /<!--([\s\S]*?)(?:-->|$)|<\/body>/ig;
         content = content.replace(rBody, function(all, comment) {
          if (comment) {
            return all;
          } else {
            return '\n' + opts.scriptPlaceholder + '\n' + all;
          }
        });
    }*/


    content = _.parseHtmlScript(content, function (found) {
        var placeholder;
        var match = found.match;

        if (found.isScriptLink) {
            var src = found.src;
            var scriptFile = context.getFileByUrl(src, file);
            var loaderName = scriptFile
                ? scriptFile.basename
                : _.ext(src).basename;

            if (found.isLoader
                || opts.loaderScripts.indexOf(loaderName) !== -1
            ) {
                placeholder = getPlaceholder(true);
                if (placeholder) {
                    return match + placeholder+'\n';
                }
            }
            else if (scriptFile && opts.packJs) {
                packScriptFiles.push({
                    file: scriptFile,
                    raw: match,
                    attrs: found.attrs
                });
            }
        }
        else if (found.isInlineScript) {
            // 对于内联脚本，如果指定了异步入口模块或者包含异步 require，则在前面插入脚本占位符
            if (found.isEntryScript
                || _.extractAsyncModuleIds(found.inlineContent).length) {
                placeholder = getPlaceholder();
                if (placeholder) {
                    return placeholder+'\n' + match;
                }
            }
        }

        return match;
    });

    if (packScriptFiles.length
        && !hasScriptPlaceholder
        && opts.autoInsertPlaceholder
    ) {
        var lastScript = packScriptFiles[packScriptFiles.length - 1].raw;
        content = content.replace(lastScript, lastScript + opts.scriptPlaceholder);
    }

    file.setContent(content);
    file._initScriptPlacedholder = true;

    return packScriptFiles;
}
446412
function unzip(src, dist) {
    if (isString(src)) {

        // 获取输出目录
        if (arguments.length === 1) {
            dist = src.replace(/\.zip$/, '');
        }

        // 校验参数
        if (isString(dist)) {
            return new Promise((resolve, reject) => {
                let archive = fs.createReadStream(src),
                    output = unarchiver.Extract({ path: dist });

                // 监听回调
                archive.on('error', reject);
                output.on('error', reject);
                output.on('close', resolve);

                // 设置管道输出
                archive.pipe(output);
            });
        }
    }
}
7376
function injectAutoLoad(file, include) {
        var depList = getDepList(file);
        var asyncList = getAsyncList(file);
        var jsList = [];
        var cssList = [];
        //将include资源添加入异步资源
        asyncList = asyncList.concat(include);
        asyncList = asyncList.filter(function (async, index) {
            //去除重复资源
            if (asyncList.indexOf(async) !== index) {
                return false;
            }
            //将样式表资源强制设定为同步加载，避免异步加载样式表
            if (async.isCssLike) {
                depList.push(async);
                return false;
            }
            return true;
        });
        //生成同步资源引用列表
        var usedPkg = {};
        var usedSync = {};
        depList.forEach(function (dep) {
            var res = ret.map.res[dep.getId()];
            res.id = dep.getId();
            usedSync[dep.getId()] = true;
            if (res.pkg && ret.map.pkg[res.pkg]) {
                if (usedPkg[res.pkg]) {
                    return true;
                }
                ret.map.pkg[res.pkg].has.forEach(function (has) {
                    usedSync[has] = true;
                });
                usedPkg[res.pkg] = true;
                res = ret.map.pkg[res.pkg];
            }
            if (dep.isJsLike)
                jsList.push(res);
            else if (dep.isCssLike)
                cssList.push(res);
        });
        asyncList = asyncList.filter(function (async) {
            return !usedSync[async.getId()];
        });
        var content = file.getContent();
        content = injectCss(cssList, content);
        if (settings.useSiteMap) {
            content = injectSiteAsync(content);
        }
        else {
            content = injectAsync(asyncList, content, usedSync, file.subpath);
        }
        content = injectJs(jsList, content);
        file.setContent(content);
    }
1139536
function ( err ) {
    // 报错文件名
    var fileName = err.fileName;
    // 报错类型
    var name = err.name;
    // 报错信息
    var message = err.message;
    // 出错代码位置
    var loc = err.loc;

    var logInfo = '报错文件：' + fileName + '报错类型：' + name + '出错代码位置：' + loc.line + ',' + loc.column;

    util.log( logInfo );

    this.end();
}
764151
function fillFileTree (fileTree, fileList) {
  let extname

  fileList.forEach(filePath => {
    extname = path.extname(filePath)
    const linters = Object.keys(linterSuffix)

    const match = linters.some(linterName => {
      if (linterSuffix[linterName].includes(extname)) {
        fileTree[linterName].push(filePath)
        return true
      }

      return false
    })

    // 没有匹配到特定的 linter，则分配给所有 linter
    if (!match) {
      linters.forEach(linterName => {
        fileTree[linterName].push(filePath)
      })
    }
  })

  return fileTree
}
949104
function combine(file) {
      if (!file) return;

      if (pathArr.indexOf(file.path) < 0) {
        pathArr.push(file.path);

        if (file.caculateContents) {
          cont = file.caculateContents
        } else {
          return;
        }

        contents.push(cont);

        size += cont.length;
      }

      if (file.children) {
        // 遍历依赖文件并且合并
        file.children.forEach(function(fc) {
          combine(denps[fc] || {path: fc});
        });
      }
    }
137982
function resolveFile(file, pathes) {
    var strResult = '';

    for(var i = 0, len = pathes.length; i < len; i ++) {
        extName = path.extname(pathes[i]);
        switch (extName) {
            case '.js':
                strResult += resolveScripts(file, [pathes[i]]);
                break;
            case '.css':
                strResult += resolveStylesheet(file, [pathes[i]]);
                break;
            case '.html':
                strResult += resolveTemplate(file, [pathes[i]]);
                break;
            default :
                throw new PluginError("gulp-xinclude", "暂不支持类型[" + extName + "]的文件");
        }
    }
    return strResult;
}
998532
async function mapdir(src, callback) {
    let stats = await stat(src),
        result = [];

    // 判断是否存在文件夹
    if (stats) {
        let fullpath = path.cwd(src),
            data = assign(stats, { path: fullpath });


        // 执行回调
        result.push(callback ? callback(data) : data);

        // 处理文件夹
        if (stats.isDirectory() && !fullpath.endsWith('node_modules')) {
            let files = await readdir(src);

            // 遍历下级文件
            for (let file of files) {
                result = result.concat(await mapdir(path.join(src, file), callback));
            }
        }
    }

    // 返回结果
    return result;
}
1272453
function getBaesVsersion(dir, callBack) {
        fs.readdir(`${dir}/`, (err, files) => {
            let dirList = [],
                baseVersion;
            if (err) {
                console.log('第一次部署中...');
                fs.mkdir(dir, () => {
                    callBack([1, 1, 1]);
                });
            } else {
                if (files.length == 0) {
                    files = ['1.1.1'];
                }
                console.log('部署目标已存在，正在更新中...');
                files.forEach((v)=> {
                    let intV = v.replace(/\./g, '');
                    if (!!parseInt(intV)) {
                        dirList.push(intV);
                    }
                });
                baseVersion = Math.max.apply(null, dirList).toString().split('');
                callBack(baseVersion);
            }
        });
    }
894931
function(e){
    var images  = this.images;
    var baseDir = path.dirname(this.get('file'));
    var files   = {};
    var equals = {};

    forEach(images, function(file, id){
      var fullPath = path.resolve(baseDir, file);
      if (files[fullPath] !== undefined) {
        equals[id] = files[fullPath];
      } else {
        //去除重复
        files[fullPath] = id;
      }
    });

    this.equals = equals;

    files = Object.keys(files);
    files.forEach(function(file){
      var fs = require('fs');
      var exists    = fs.existsSync;
      if (!exists(file)){
        Log.error('图片' + path.relative(baseDir, file) + '不存在');
      }
    });

    //获取图片大小
    Api.getImagesSize(files, this._setDef, this);
  }
122912
function copyTpl(options) {
  options.data = options.data || {};
  options.stringReplace = options.stringReplace || [];
  options.encoding = options.encoding || 'utf-8';

  if (!fs.existsSync(options.src)) {
    log.error(`${options.src} 文件不存在`);
    return;
  }

  if (fs.statSync(options.src).isDirectory()) {
    fs.mkdirsSync(options.dist);
    log.success(`${options.dist} written successfully`);
    return;
  }

  // 数据模板转换
  let content = fs.readFileSync(options.src, { encoding: options.encoding });
  try {
    content = _.template(content)(options.data);
  } catch (err) {
    log.error(`${options.src} template fail, Please check the template and the data is correct`);
  }
  for (let j = 0; j < options.stringReplace.length; j += 1) {
    content = content.replace(
      new RegExp(options.stringReplace[j].placeholder, 'g'),
      options.stringReplace[j].value
    );
  }

  // 若没有目录文件需要创建,最终创建文件
  fs.mkdirsSync(path.dirname(options.dist));
  fs.writeFileSync(options.dist, content);
  log.success(`${options.dist} written successfully`);
}
468403
async function rmdir(src) {
    let stats = await stat(src);

    // 判断是否存在文件夹
    if (stats) {
        if (stats.isDirectory()) {
            let files = await readdir(src);

            // 移除下级目录
            await Promise.all(
                files.map(file => rmdir(path.join(src, file)))
            );

            // 移除文件夹
            await removedir(src);
        } else {
            await unlink(src);
        }
    }
}
577646
function zip(source, target, options, fn) {
    var zip = new Zip;

    // 检查是否存在filter
    if(typeof filter == 'function'){
        fn = filter;
        filter = null;
    }
    // 检查是否存在回调
    fn = fn || function(){};

    // 查找文件准备执行压缩
    glob(source + '/**', options, function(err, files){
        if(err) throw err;

        // 添加文件到待压缩数据中
        files.forEach(function(item){
            if(fs.statSync(item).isFile()){
                zip.addFile(path.relative(source, item), item);
            }
        })

        // 执行压缩
        zip.saveAs(target, function(err){
            fn(err, target)
        })
    })
}
817205
function watchOnFile(file, callback) {
  let lastIndex = 0
  let timer

  function read() {
    const stat = fs.statSync(file)

    if (stat.size !== lastIndex) {
      const fd = fs.openSync(file, 'r')
      const buffer = Buffer.alloc(stat.size - lastIndex)

      try {
        fs.readSync(fd, buffer, lastIndex, stat.size - lastIndex)
        const content = buffer.toString('utf8')
        lastIndex = stat.size

        callback(content)
      } catch (error) {
        // 从头读起
        lastIndex = 0
      }
    }

    timer = setTimeout(read, 200)
  }

  read()
  return function() {
    clearTimeout(timer)
  }
}
1278068
function joinDirectory() {
  var dirs = [].slice.call(arguments, 1);
  var dir;
  for (var i = 0, len = dirs.length; i < len; i++) {
    dir = dirs[i];
    if (/^\//.test(dir)) {
      // 发现根目录, 直接返回.
      return dir;
    }
  }
  return join.apply(null, [].slice.call(arguments));
}