/*!
Next JS
Copyright (c)2011 Xenophy.CO.,LTD All rights Reserved.
http://www.xenophy.com
 {{{ checkGlobalActionFile
343501
function(file, fn) {

    NX.Path.exists(file, function(exists) {

        if(!exists) {
            fn();
        } else {
            fn({
                type: 'global',
                path: file
            });
        }

    });

}
906173
function interpret(source) {
  var tree = parser.parse(source);
  var js = [
    'module.exports = function (out, globals) {',
    '  var end = false;',
    '  if (Object.getPrototypeOf(out) !== module.xjs.XjsStream.prototype) {',
    '    out = new module.xjs.XjsStream(out);',
    '    end = true;',
    '  }',
    '  if (globals && typeof globals.length === "number" && typeof globals !== "string") {',
    '    var callee = arguments.callee;',
    '    for (var i in globals) {',
    '      callee.call(this, out, globals[i]);',
    '    }',
    '    return;',
    '  }',
    '  globals = globals || {};',
    '  with (globals) {'
  ];
  interpretChildren(js, tree, '    ');
  js.push(
    '  }',
    '  if (end) {',
    '    out.end();',
    '  }',
    '}'
  );
  js = js.join('\n');
  return js;
}
317549
function bootrapSitesAndComponents() {
  const sites = siteService.sites(),
    sitesArray = _.map(Object.keys(sites), site => sites[site]);

  return highland(sitesArray)
    .flatMap(site => {
      return highland(
        bootstrapComponents(site)
          .then(function () {
            return site;
          })
          .catch(function () {
            log('debug', `Errors bootstrapping components for site: ${site.slug}`);
            return site;
          })
      );
    })
    .flatMap(site => {
      return highland(
        bootstrapPath(site.dir, site)
          .catch(function () {
            log('debug', `No bootstrap file found for site: ${site.slug}`);
            return site;
          })
      );
    })
    .collect()
    .toPromise(bluebird);
}
770339
function (orderBy) {

/*Line 195 - 'atom-filter.js' */            if (!AtomFilter.isString(orderBy)) {
/*Line 196 - 'atom-filter.js' */                return orderBy;
/*Line 197 - 'atom-filter.js' */            }

/*Line 199 - 'atom-filter.js' */            var fields = orderBy.split(',');
/*Line 200 - 'atom-filter.js' */            fields = fields.map(function (item) {
/*Line 201 - 'atom-filter.js' */                var tokens = item.split(' ');
/*Line 202 - 'atom-filter.js' */                var desc = tokens[1] || 'asc';
/*Line 203 - 'atom-filter.js' */                return {
/*Line 204 - 'atom-filter.js' */                    field: tokens[0],
/*Line 205 - 'atom-filter.js' */                    desc: /desc/i.test(desc),
/*Line 206 - 'atom-filter.js' */                    cs: /^cs/i.test(desc)
/*Line 207 - 'atom-filter.js' */                }
/*Line 208 - 'atom-filter.js' */            });

/*Line 210 - 'atom-filter.js' */            return function (a, b) {

/*Line 212 - 'atom-filter.js' */                if (a == null || a == undefined) {
/*Line 213 - 'atom-filter.js' */                    return b == null || b == undefined ? 0 : 1;
/*Line 214 - 'atom-filter.js' */                }
/*Line 215 - 'atom-filter.js' */                if (b == null || b == undefined) {
/*Line 216 - 'atom-filter.js' */                    return 1;
/*Line 217 - 'atom-filter.js' */                }

/*Line 219 - 'atom-filter.js' */                for (var i = 0; i < fields.length; i++) {
/*Line 220 - 'atom-filter.js' */                    var f = fields[i];
/*Line 221 - 'atom-filter.js' */                    var field = f.field;
/*Line 222 - 'atom-filter.js' */                    var af = a[field];
/*Line 223 - 'atom-filter.js' */                    var bf = b[field];
/*Line 224 - 'atom-filter.js' */                    if (f.desc) {
/*Line 225 - 'atom-filter.js' */                        var t = af;
/*Line 226 - 'atom-filter.js' */                        af = bf;
/*Line 227 - 'atom-filter.js' */                        bf = t;
/*Line 228 - 'atom-filter.js' */                    }
/*Line 229 - 'atom-filter.js' */                    if (af == bf)
/*Line 230 - 'atom-filter.js' */                        continue;
/*Line 231 - 'atom-filter.js' */                    if (!af) {
/*Line 232 - 'atom-filter.js' */                        return !bf ? 0 : -1;
/*Line 233 - 'atom-filter.js' */                    }
/*Line 234 - 'atom-filter.js' */                    if (!bf) {
/*Line 235 - 'atom-filter.js' */                        return !af ? 0 : 1;
/*Line 236 - 'atom-filter.js' */                    }
/*Line 237 - 'atom-filter.js' */                    if (AtomFilter.isString(af)) {
/*Line 238 - 'atom-filter.js' */                        if (f.cs) {
/*Line 239 - 'atom-filter.js' */                            return af.localeCompare(bf);
/*Line 240 - 'atom-filter.js' */                        } else {
/*Line 241 - 'atom-filter.js' */                            af = af.toLowerCase();
/*Line 242 - 'atom-filter.js' */                            bf = bf.toLowerCase();
/*Line 243 - 'atom-filter.js' */                            if (af == bf)
/*Line 244 - 'atom-filter.js' */                                continue;
/*Line 245 - 'atom-filter.js' */                            return af.localeCompare(bf);
/*Line 246 - 'atom-filter.js' */                        }
/*Line 247 - 'atom-filter.js' */                    }

/*Line 249 - 'atom-filter.js' */                }
/*Line 250 - 'atom-filter.js' */                return 0;
/*Line 251 - 'atom-filter.js' */            }
/*Line 252 - 'atom-filter.js' */        }
836926
function (options, dir, callback) {
  var copyrightFile = path.join(dir, 'share/doc', options.id, 'copyright')
  options.logger('Creating copyright file at ' + copyrightFile)

  async.waterfall([
    async.apply(readLicense, options),
    async.apply(fs.outputFile, copyrightFile)
  ], function (err) {
    callback(err && new Error('Error creating copyright file: ' + (err.message || err)))
  })
}
972740
function buildMixinsDocsList() {
  return fs.readdirSync('packages/basic-component-mixins/src').filter(file => {
    return file.indexOf('.js') == file.length - 3;
  }).map(file => {
    const fileRoot = file.replace('.js', '');
    return {
      src: `packages/basic-component-mixins/src/${file}`,
      dest: `packages/basic-component-mixins/docs/${fileRoot}.md` };
  });
}
788302
function(){
        var _replace    = "$1" + this.config.tp + "$2" + this.config.tp,
            _al         = this.config.jade.replace( /(^\s*)(script\([^\)|^\n|^\r]*\))/gm , _replace ).split( this.config.tp ),
            _url ,
            _filePath;
        for( var i = _al.length; i--; ){
            if( i % 2 ){
                _al[ i ]    = _al[ i ].replace( /\s/gi , "" );
                tool.checkFileStatus( _al[ i ].replace( /[^\:]*src=['|"]([^'|^"]*)['|"].*/gi , "$1" ) , function( exists , filePath ){
                    if( !config.filePath.fetchUrl[ filePath ] ){
                        _url    = tool.getFileTs( filePath );
                        if( exists ){
                            _filePath   = Path.parse( filePath );
                            _url = tool.uglifyJs( Path.join( config.dir.srcDir , filePath ) , _filePath.dir + "/" + _filePath.name + "." );
                            _url = config.redirectOrigin + _url;
                        }
                        config.filePath.fetchUrl[ filePath ] = _url;
                    }
                    _al[ i ] = _al[ i ].replace( /(.*src=['|"])([^'|^"]*)(['|"].*)/gi , "$1" + config.filePath.fetchUrl[ filePath ] + "$3" );
                } );
            };
        };
        return _al.join( "" );
    }
1292716
function generateDistFiles(config) {
	// Delete package.json from the cache since it can get updated by npm version
	delete require.cache[require.resolve('./package.json')];

	var pkg = require('./package.json'),
		distFilename = DIST_DIR + config.name + '.js',
		minDistFilename = distFilename.replace(/\.js$/, '.min.js'),
		minDistSourcemapFilename = minDistFilename + '.map',
		distTestingFilename = DIST_DIR + config.name + '-testing' + '.js';

	// Add copyrights and version info
	var versionComment = '/*! ' + config.name + ' v' + pkg.version + ' */\n',
		testingVersionComment = '/*! ' + config.name + '-testing v' + pkg.version + ' */\n',
		copyrightComment = cat('./config/copyright.txt');

	// concatenate files together and add version/copyright notices
	(versionComment + copyrightComment + cat(config.files)).to(distFilename);
	(testingVersionComment + copyrightComment + cat(config.testingFiles)).to(distTestingFilename);

	// create minified version with source maps
	var result = uglifyjs.minify(distFilename, {
		output: {
			comments: /^!/
		},
		outSourceMap: path.basename(minDistSourcemapFilename)
	});
	result.code.to(minDistFilename);
	result.map.to(minDistSourcemapFilename);

	// create filenames with version in them
	cp(distFilename, distFilename.replace('.js', '-' + pkg.version + '.js'));
	cp(minDistFilename, minDistFilename.replace('.min.js', '-' + pkg.version + '.min.js'));
	cp(distTestingFilename, distTestingFilename.replace('.js', '-' + pkg.version + '.js'));
}
951181
function PhotoAttribution({ username, name }) {
  if (!username) {
    return null;
  }

  const href = `https://unsplash.com/${username}?utm_medium=referral&amp;utm_campaign=photographer-credit&amp;utm_content=creditBadge`;
  const title = `Download free do whatever you want high-resolution photos from ${name}`;
  return (
    <a className="photo-attribution" href={href} target="_blank" rel="noopener noreferrer" title={title}>
      <span>
        <svg viewBox="0 0 32 32">
          <path d="M20.8 18.1c0 2.7-2.2 4.8-4.8 4.8s-4.8-2.1-4.8-4.8c0-2.7 2.2-4.8 4.8-4.8 2.7.1 4.8 2.2 4.8 4.8zm11.2-7.4v14.9c0 2.3-1.9 4.3-4.3 4.3h-23.4c-2.4 0-4.3-1.9-4.3-4.3v-15c0-2.3 1.9-4.3 4.3-4.3h3.7l.8-2.3c.4-1.1 1.7-2 2.9-2h8.6c1.2 0 2.5.9 2.9 2l.8 2.4h3.7c2.4 0 4.3 1.9 4.3 4.3zm-8.6 7.5c0-4.1-3.3-7.5-7.5-7.5-4.1 0-7.5 3.4-7.5 7.5s3.3 7.5 7.5 7.5c4.2-.1 7.5-3.4 7.5-7.5z"></path>
        </svg>
      </span>
      <span>{name}</span>
    </a>
  );
}
83029
function (module) {
        "use strict";
    
        var getResource = function (hostType, resource) {
    
            var host;
            var modulePath, filePath;
    
            if (resource.substr(0, 1) === '/') {
                resource = resource.substr(1);
            }
    
            if (hostType === 'module') {
    
                if (module.library) {
                    host = beyond.hosts.libraries[module.library.name].js;
                    library = module.library.name;
                }
                else {
                    host = beyond.hosts.application.js;
                    library = undefined;
                }
    
                modulePath = module.path;
                filePath = resource;
    
            }
            else if (hostType === 'application') {
    
                host = beyond.hosts.application.js;
                return host + resource;
    
            }
            else {
    
                var library = hostType;
                host = beyond.hosts.libraries[library];
    
                if (!host) {
                    console.warn('invalid css host on module "' + module.ID + '", resource "' + resource + '"' +
                        ', library "' + library + '" is not defined');
                    return;
                }
    
                if (resource.substr(0, 7) === 'static/') {
                    modulePath = 'main';
                    filePath = resource.substr(7);
                }
                else {
                    var overwrite = resource.split('/static/');
                    modulePath = overwrite[0];
                    filePath = overwrite[1];
                }
    
            }
    
            var overwrites = beyond.overwrites;
            var overwrited;
            if (library) {
                overwrited = overwrites[library];
            }
    
            if (!overwrited || !overwrited[modulePath] ||
                overwrited[modulePath].indexOf(filePath) === -1) {
    
                return host + modulePath + '/static/' + filePath;
            }
    
            return beyond.hosts.application.js +
                'custom/' + library + '/' +
                modulePath + '/static/' + filePath;
    
        };
    
        var setHosts = function (styles) {
    
            // find variables
            var variable;
    
            var replace = {};
    
            var regexp = /#host\.(.*?)#(.*?)[\)\s]/g;
            variable = regexp.exec(styles);
    
            var resource;
            while (variable) {
    
                // hostType can be 'application', 'module', libraryName
                var hostType = variable[1];
                resource = variable[2];
                resource = getResource(hostType, resource);
    
                var original = variable[0];
                if (original.substr(original.length - 1) === ')')
                    original = original.substr(0, original.length - 1);
    
                replace[original] = resource;
                variable = regexp.exec(styles);
    
            }
    
            // replace #host.* variables with their values
            for (var original in replace) {
    
                resource = replace[original];
    
                while (styles.indexOf(original) !== -1)
                    styles = styles.replace(original, resource);
    
            }
    
            return styles;
    
        };
    
        this.process = function (styles) {
    
            // find and replace #host...
            styles = setHosts(styles);
            return styles;
    
        };
    
    }
949963
function genScript() {

//spilt 'gen new' from 'gen {{COMPONENT NAME}}'
  if (value === 'new') {
// generate a brand new project with the name
//argument 3 is now the project name
    mkdirp(argument3, function (err) {
      if (err) console.error(err)
      else
        process.chdir(argument3),

        //generte dockerfile
        fs.writeFile("Dockerfile", `FROM node:6.5

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app

RUN npm set progress=false
RUN npm install

EXPOSE 8080

CMD ["npm", "run", "startContainer"]`, function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "Dockerfile".white);
        });


        //generte deploy.js
        fs.writeFile("deploy.js", `var request = require('request');

var headers = {
  'Content-Type': 'application/json'
};

var dataString = ''{"docker_tag": '$''{process.env.CIRCLE_BRANCH}"}'';

var options = {
  url: '', // add your docker url aka 'https://registry.hub.docker.com/u/{{the rest of your url}}'
  method: 'POST',
  headers: headers,
  body: dataString
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body);
  }
}

request(options, callback);`, function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "deploy.js".white);
        });

        //generte circle.yml
        fs.writeFile("circle.yml", `machine:
  node:
    version: 6.5

dependencies:
  cache_directories:
    - node_modules
  override:
    - npm prune && npm install

test:
  override:
    - echo 'test needed'

deployment:
  staging:
    branch: [develop, master]
    commands:
      - npm run deploy`, function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "circle.yml".white);
        });

          //generte .gitignore
          fs.writeFile(".gitignore", `.DS_Store
.tmp
.git
node_modules
.settings
*.log
client/bundle.js
client/bundle.js.map
.idea`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + ".gitignore".white);
          });

      //generte webpack.config.js
      fs.writeFile("webpack.config.js", `var path = require('path'),
    webpack = require("webpack"),
    libPath = path.join(__dirname, 'client'),
    wwwPath = path.join(__dirname, 'dist'),
    pkg = require('./package.json'),
    HtmlWebpackPlugin = require('html-webpack-plugin');


const isDev = process.env.NODE_ENV !== 'production';

if (isDev) {
  module.exports = {
    entry: path.join(libPath, '/app/app.module.js'),
    output: {
      path: path.join(wwwPath),
      filename: 'bundle.js'
    },
    module: {
      loaders: [{
        test: /\\.html$/, loader: 'raw'
      }, {
        test: /\\.(png|jpg)$/,
        loader: 'file?name=img/[name].[ext]' // inline base64 URLs for <=10kb images, direct URLs for the rest
      },{
        test: /\\.scss$/,loader: 'style!css!sass'
      }, {
        test: /\\.css$/, loader: 'style!css'
      }, {
        test: /\\.js$/,
        exclude: /(node_modules)/,
        loader: "ng-annotate?add=true!babel"
      }, {
        test: [/fontawesome-webfont\\.svg/, /fontawesome-webfont\\.eot/, /fontawesome-webfont\\.ttf/, /fontawesome-webfont\\.woff/, /fontawesome-webfont\\.woff2/],
        loader: 'file?name=fonts/[name].[ext]'
      },
        { test: /\\.(ttf|otf|eot|svg|woff(2)?)$/, loader: 'url' }]
    },
    plugins: [

      new webpack.ProvidePlugin({
        'window.Masonry': 'Masonry'
      }),

      // HtmlWebpackPlugin: Simplifies creation of HTML files to serve your webpack bundles : https://www.npmjs.com/package/html-webpack-plugin
      new HtmlWebpackPlugin({
        filename: 'index.html',
        pkg: pkg,
        template: path.join(libPath, 'index.ejs'),
        inject: true
      }),

      // OccurenceOrderPlugin: Assign the module and chunk ids by occurrence count. : https://webpack.github.io/docs/list-of-plugins.html#occurenceorderplugin
      new webpack.optimize.OccurenceOrderPlugin(),

      // Deduplication: find duplicate dependencies & prevents duplicate inclusion : https://github.com/webpack/docs/wiki/optimization#deduplication
      new webpack.optimize.DedupePlugin()
    ]
  };
}else{
  module.exports = {
    entry: path.join(libPath, '/app/app.module.js'),
    context: path.resolve(__dirname, './client'),
    output: {
      filename: 'bundle.[hash].js',
      hashDigestLength: 7,
      path: path.join(wwwPath),
      publicPath: '/'
    },
    module: {
      loaders: [{
        test: /\\.html$/, loader: 'raw'
      }, {
        test: /\\.(png|jpg)$/,
        loader: 'file?name=img/[name].[ext]' // inline base64 URLs for <=10kb images, direct URLs for the rest
      },{
        test: /\\.scss$/,loader: 'style!css!sass'
      }, {
        test: /\\.css$/, loader: 'style!css'
      }, {
        test: /\\.js$/,
        exclude: /(node_modules)/,
        loader: "ng-annotate?add=true!babel"
      }, {
        test: [/fontawesome-webfont\\.svg/, /fontawesome-webfont\\.eot/, /fontawesome-webfont\\.ttf/, /fontawesome-webfont\\.woff/, /fontawesome-webfont\\.woff2/],
        loader: 'file?name=fonts/[name].[ext]'
      },
        { test: /\\.(ttf|otf|eot|svg|woff(2)?)$/, loader: 'url' }]
    },
    plugins: [

      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')
      }),

      new webpack.ProvidePlugin({
        'window.Masonry': 'Masonry'
      }),

      new webpack.optimize.CommonsChunkPlugin('common.js'),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin(),
      new webpack.optimize.AggressiveMergingPlugin(),
      new CompressionPlugin({
        asset: "[path].gz[query]",
        algorithm: "gzip",
        test: /\\.js$|\\.css$|\\.html$/,
        threshold: 10240,
        minRatio: 0.8
      }),

      // HtmlWebpackPlugin: Simplifies creation of HTML files to serve your webpack bundles : https://www.npmjs.com/package/html-webpack-plugin
      new HtmlWebpackPlugin({
        filename: 'index.html',
        pkg: pkg,
        template: path.join(libPath, 'index.ejs'),
        inject: true
      }),

      // OccurenceOrderPlugin: Assign the module and chunk ids by occurrence count. : https://webpack.github.io/docs/list-of-plugins.html#occurenceorderplugin
      new webpack.optimize.OccurenceOrderPlugin(),

      // Deduplication: find duplicate dependencies & prevents duplicate inclusion : https://github.com/webpack/docs/wiki/optimization#deduplication
      new webpack.optimize.DedupePlugin()
    ]
  };
}
`, function (err) {
        if (err) {
          return console.log(` ❌  failed to generate due to error:  ${err}`);
        }
        console.log(" 🎁  created: ".cyan + "karma.conf.js".white);
      });


      //generate package.json
      fs.writeFile("package.json", `{
  "name": "${argument3}",
  "version": "0.0.1",
  "description": "Boilerplate generated by Angular-1.5-cli.",
  "main": "index.js",
  "dependencies": {
    "angular": "1.5.7",
    "angular-animate": "1.5.7",
    "angular-mocks": "1.5.7",
    "angular-ui-router": "0.3.1",
    "bootstrap-css-only": "3.3.6",
    "lodash": "4.13.1",
    "normalize.css": "4.1.1",
    "http-server": "^0.9.0",
    "angular-1.5-cli":"^1.6.0"
  },
  "devDependencies": {
    "angular-mocks": "1.5.7",
    "babel-core": "6.10.4",
    "http-server": "0.9.0",
    "babel-loader": "6.2.4",
    "babel-preset-es2015": "6.9.0",
    "browser-sync": "2.13.0",
    "browser-sync-webpack-plugin": "1.1.4",
    "css-loader": "0.23.1",
    "file-loader": "0.9.0",
    "fs-walk": "0.0.1",
    "gulp": "3.9.1",
    "gulp-rename": "1.2.2",
    "gulp-template": "4.0.0",
    "html-webpack-plugin": "2.28.0",
    "jasmine": "2.4.1",
    "jasmine-core": "2.4.1",
    "karma": "1.1.0",
    "karma-jasmine": "1.0.2",
    "karma-phantomjs-launcher": "1.0.1",
    "karma-sourcemap-loader": "0.3.7",
    "karma-spec-reporter": "0.0.26",
    "karma-webpack": "1.7.0",
    "less": "2.7.1",
    "less-loader": "2.2.3",
    "ng-annotate-loader": "0.1.0",
    "node-libs-browser": "1.0.0",
    "node-sass": "4.4.0",
    "phantomjs-prebuilt": "2.1.7",
    "raw-loader": "0.5.1",
    "run-sequence": "1.2.1",
    "sass-loader": "4.1.1",
    "style-loader": "0.13.1",
    "url-loader": "0.5.7",
    "webpack": "1.13.1",
    "webpack-dev-server": "1.16.3",
    "webpack-stream": "3.2.0",
    "yargs": "4.7.1"
  },
  "scripts": {
    "start": "webpack && webpack-dev-server --content-base client/ --hot --inline",
    "serve": "webpack && webpack-dev-server --content-base client/ --hot --inline",
    "create Component": "gen comp",
    "build": "webpack -p --config ./webpack.config.js --progress",
    "startContainer": "npm run build && http-server ./build",
    "deploy": "node deploy.js"
  },
  "keywords": [
    "angular",
    "webpack",
    "es6"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/SwiftySpartan/Angular-1.5-cli"
  },
  "author": "Andrew Wormald",
  "license": "MIT"
}`, function (err) {
        if (err) {
          return console.log(` ❌  failed to generate due to error:  ${err}`);
        }
        console.log(" 🎁  created: ".cyan + "package.json".white);
      });

      //generate .bablerc
      fs.writeFile(".babelrc", `{
    "presets": [ "es2015"]
  }`, function (err) {
        if (err) {
          return console.log(` ❌  failed to generate due to error:  ${err}`);
        }
        console.log(" 🎁  created: ".cyan + ".bablerc".white);
      });

      // generate client directory
      mkdirp("client", function (err) {
        //within this directory create all the sub scripts (e.g. app.component.html)
        process.chdir("client"),

          mkdirp("assets/img", function (err) {
            console.log(" 🎁  created: ".cyan + "client/assets".white);
            console.log(" 🎁  created: ".cyan + "client/assets/img".white);
          });

        //generate favicon.jpg using base 64
        data = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAYAAABNChwpAAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia219thzg25abkRE/BpDc3pqvphHvRFys2weqvp+krbWKIX7nhDbzLOItiM8358pTwdirqpPFnMF2xLc1WvLyOwTAibpbmvHHcvttU57y5+XqNZrLe3lE/Pq8eUj2fXKfOe3pfOjzhJYtB/yll5SDFcSDiH+hRkH25+L+sdxKEAMZahrlSX8ukqMOWy/jXW2m6M9LDBc31B9LFuv6gVKg/0Szi3KAr1kGq1GMjU/aLbnq6/lRxc4XfJ98hTargX++DbMJBSiYMIe9Ck1YAxFkKEAG3xbYaKmDDgYyFK0UGYpfoWYXG+fAPPI6tJnNwb7ClP7IyF+D+bjOtCpkhz6CFrIa/I6sFtNl8auFXGMTP34sNwI/JhkgEtmDz14ySfaRcTIBInmKPE32kxyyE2Tv+thKbEVePDfW/byMM1Kmm0XdObS7oGD/MypMXFPXrCwOtoYjyyn7BV29/MZfsVzpLDdRtuIZnbpXzvlf+ev8MvYr/Gqk4H/kV/G3csdazLuyTMPsbFhzd1UabQbjFvDRmcWJxR3zcfHkVw9GfpbJmeev9F08WW8uDkaslwX6avlWGU6NRKz0g/SHtCy9J30o/ca9zX3Kfc19zn3BXQKRO8ud477hLnAfc1/G9mrzGlrfexZ5GLdn6ZZrrEohI2wVHhZywjbhUWEy8icMCGNCUdiBlq3r+xafL549HQ5jH+an+1y+LlYBifuxAvRN/lVVVOlwlCkdVm9NOL5BE4wkQ2SMlDZU97hX86EilU/lUmkQUztTE6mx1EEPh7OmdqBtAvv8HdWpbrJS6tJj3n0CWdM6busNzRV3S9KTYhqvNiqWmuroiKgYhshMjmhTh9ptWhsF7970j/SbMrsPE1suR5z7DMC+P/Hs+y7ijrQAlhyAgccjbhjPygfeBTjzhNqy28EdkUh8C+DU9+z2v/oyeH791OncxHOs5y2AtTc7nb/f73TWPkD/qwBnjX8BoJ98VVBg/m8AAAQASURBVEgN7VddaFxFFP7m5+7mp2lSapqyrYq1xaC7m4ekG5uqaWxFUWhLCoIgKgpSEFF8sH1RY33RB/EHxLwVfREr1p9KQa1Nk4DaWIUQtZbWakM3P5JoN1lbd3fujOdee5eby97dpTVvGbjM3HO+OfOdMzNnZhgCZRiJdgN2N8CuYcB5jfyhbpw8HYBV/XsW8ZaIqH9ectZO9uyCMd9k1YUXW3Fq3jHCPUtfYl3jMNoOGvD3GFgtgzkDmBhH5NgQEm8OANLDVlunZeqF1dEV6VrBt2uDNH0z9Uw8eG20+c9xntrtt8No8KNDSL4dHGgAtywbRvIw6fv9HSq1x3nnE5eit6txsfGRIPacTO25GL3NPis6trs6GngXDXKizxcRfyeHxBDaJgaRSPjl5dqZyObshEy9GoaZkJ0fzFpdU5engN1HwHf7AF2qQw9+ytL8HSTwvaX0QdlpdN4cZbxuQo3sDeq8/3n1z9MNXKxyCdB8N2qYGU9ZqjYwaVofLaV0QZkldKsyutABFII67/8mjKadtkuA3D5JHrZ7ylI17QxDi5Jg1ZTKuN9EaqeC0S4BBb2ftt3DNNfrqzF/tZgDgGjisn/Oto+5BLbix1/Jw2cFBO2ExA4HcLWDhPU/Jzdu2xbZdJ4cFtPq7x0LQkqr/A7KAftImKR4T1HbtyhNM8kEyabCjHvyOsaXJyLL1uaMyXkyp6bOkmxgzi58kVXHezcAuQUEPPAhxOrq0NgsYbkRcuQ0sJM4iIR5ycOF1TFu3ROTtW/M6vxWPyav1OR6/EAJ7grKINr2Ur54rZquv4uOXdnI5gXeh/UrehgGWGz5EoGlCCxFoOQt53Mk62uAVXRGFCNEJ+ZKSkdNXyF+Y6WtWTB6NSUudka29/ixRsnpDTj+s1+2IBMOIL5Fgu8jQHyxUrEzeMZWR7Lq251OKi6SGUTyMcp042GH0f+VCZ3DaDayafIvq2tmlCLtToETVgrFKzbsW+n2c2W5uuhK+cb16rsjdNquvcvqSrfI+k/cObbAH6XLxjuLPbhH7X66nl/QavdyIba4BMj7Vprz7z1AqZoWIcGcW1E1pTLuBnvkYwnGXQJ0GclweoiUM02reg2Dni6H8XQFm/8iGbdOAJYnC9an0LbGkV0mgM+o/VBfmWs5ud5Lt5PDTqdKxdlqOaMvxmTq5TBsg6x5fV7bf7gEujH6EYV37k4k3xoIvICcN4GEOEDx/7QbY2NhBoPyjFJ7VojoU2EPkyZh9WZ0/nGy+19xnmY1aNhPnsZJ+D4tyknSrCNiDxjoD22MPdMDKA9fTe08zYjEc5eMmsxpM0J2ZQ3jnRHOV84W8k9ep0f6iwQ8g4v7OGWasuTX/sfpv6doYNYA/C8WAAAAAElFTkSuQmCC';

        function decodeBase64Image(dataString) {
          var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
            response = {};
          if (matches.length !== 3) {
            return new Error('Invalid input string');
          }
          response.type = matches[1];
          response.data = new Buffer(matches[2], 'base64');
          return response;
        }

        imageBuffer = decodeBase64Image(data);

        fs.writeFile('favicon.ico', imageBuffer.data, function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "favicon.png".white);
        });

        //generate index.ejs file
        fs.writeFile(`index.ejs`, `<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title><%- htmlWebpackPlugin.options.pkg.title %></title>
</head>
<body ng-app="app" ng-strict-di ng-cloak>
    <app>
        Loading...
    </app>
</body>
<!-- {%= o.htmlWebpackPlugin.options.pkg.name + ' v' + o.htmlWebpackPlugin.options.pkg.version + ' built on ' + new Date() %} -->
</html>`, function (err) {

          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "index.ejs".white);

        });


        // generate index.html
        fs.writeFile("index.html", `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Welcome | Angular-1.5-cli</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="description" content="A cli for Angular 1.5">
  <link rel="icon" href="favicon.jpg">
  <base href="/">
</head>
<body ng-app="app" ng-strict-di ng-cloak>

<app>
  Loading...
</app>

<script src="bundle.js"></script>
</body>
</html>`, function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + "index.html".white);
        });

        mkdirp("app/components", function (err) {
          if (err) console.error(err)
          else
            process.chdir("app"),

              //build components.js
              fs.writeFile("components/components.js", `
        import angular from 'angular';

        const ComponentsModule = angular.module('app.components', [

      ]);

      export default ComponentsModule;
`, function (err) {
                if (err) {
                  return console.log(` ❌  failed to generate due to error:  ${err}`);
                }
                console.log(" 🎁  created: ".cyan + "app/components/components.js".white);
              });


          //build component.html
          fs.writeFile(`${scriptName}.component.html`, `<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300" rel="stylesheet">
      <div class="container">
    <img src="https://raw.githubusercontent.com/SwiftySpartan/Angular-1.5-cli/master/canvas1.png" class=".img-responsive center-block">
    <p>Angular-1.5-cli</p>
</div>
<div class="container-fluid main">
  <div class="col-md-1 littleGuy">
    <h1>Welcome</h1>
    <p>
      Welcome to Angular-1.5-cli! We hope you enjoy the CLI that will aid you in effecient web app development.
    </p>
  </div>
  <div class="col-md-1 littleGuy">
    <h1>Commands</h1>
    <p>Generate Project:

gen new {{PROJECT NAME}}<br>
Generates a new project using scss styling <br><br>

gen new {{PROJECT NAME}} --style:css <br>
Generates a new project using css styling <br><br>

gen -c {{COMPONENT NAME}} <br>
Generates a new component using scss styling <br><br>

gen -c {{COMPONENT NAME}} --style:css <br>
Generates a new component using css styling <br><br>
</p>
  </div>
  <div class="col-md-1 littleGuy">
    <h1>Help</h1>
    <p>
      gen h <br>
      gen -h <br>
      gen help <br>
      gen --help <br>
    </p>
  </div>
  <div class="col-md-1 littleGuy">
    <h1>Issues</h1>
    <p>
        Please report any issues on github: <br>
        https://github.com/SwiftySpartan/Angular-1.5-cli/issues
    </p>
  </div>
</div>
`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".component.html".white);
          });

          //build scss || css styling scripts
          if (argument3 === "--style:css" || argument4 === "--style:css") {
            // build component.css
            fs.writeFile(scriptName + ".component.css", `

body {
        background-color: #212121;
        color: white;
        font-size: 38px;
}

.container {
  display: block;
  width: 100%;
}

.container p {
  text-align: center;
  font-family: 'Open Sans Condensed', sans-serif;
}


.main{
background-color: #C3002F;
}
.main .littleGuy{
    background-color: #DD0031;
    width: 300px;
    height: 350px;
    position: relative;
    margin-left: 30px;
    margin-top: 30px;
    margin-bottom: 30px;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    display: block;
    text-overflow: ellipsis;
}

.main .littleGuy h1 {
  font-size: 20px;
  font-family: 'Open Sans Condensed', sans-serif;
}

.main .littleGuy p {
  font-size: 17px;
  font-family: 'Open Sans Condensed', sans-serif;
}
`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".component.css".white);
            });
          } else {
            // build component.scss
            fs.writeFile(scriptName + ".component.scss", `@import url('https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300');
@import url('https://fonts.googleapis.com/css?family=Titillium+Web:700');

body {
        background-color: #212121;
        color: white;
        font-size: 38px;
      }

.container {
  display: block;
  width: 100%;
  p {
    text-align: center;
    font-family: 'Open Sans Condensed', sans-serif;
  }
}
.main{
background-color: #C3002F;

  .littleGuy{
    background-color: #DD0031;
    width: 300px;
    height: 350px;
    position: relative;
    margin-left: 30px;
    margin-top: 30px;
    margin-bottom: 30px;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    display: block;
    text-overflow: ellipsis;
    h1 {
      font-size: 20px;
      font-family: 'Open Sans Condensed', sans-serif;

    }

    p {
      font-size: 17px;
      font-family: 'Open Sans Condensed', sans-serif;
    }
  }
}
`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".component.scss".white);
            });
          }


          //build component.js
          if (argument3 === "--style:css" || argument4 === "--style:css") {
            // build component.js with import of css folder
            fs.writeFile(scriptName + ".component.js", `import template from './app.component.html';
import './app.component.scss';

const AppComponent = {
  template
};

export default AppComponent;`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".component.js".white);
            });
          } else {
            // build component.js with import of scss folder
            fs.writeFile(scriptName + ".component.js", `import template from './app.component.html';
import './app.component.scss';

const AppComponent = {
  template
};

export default AppComponent;`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".component.js".white);
            });
          }

          //build module.js
          fs.writeFile(scriptName + ".module.js", `import 'bootstrap-css-only';
import 'normalize.css';
import angular from 'angular';
import appComponent from './app.component';
import ComponentsModule from './components/components';

angular.module('app', [
  ComponentsModule.name
]).component('app', appComponent);`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + "client/".white + scriptName.white + ".module.js".white);
          });

        });

      });
      //making client directory and sub scripts should be last in the list as then you do not need to go back up a level in the directory ladder
    });
//argument 4 is now the styling order


  } else if (value === '-c') {

    //go to components directory
    const rootBase = __dirname

    process.chdir(`./client/app/components`);
    // GEN COMPONENT SCRIPT
    componentsArray = [];
    genArr = [];


    function camelize(str) {
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
        return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
      }).replace(/\s+/g, '');
    }

    value = camelize(`${value}`)
    argument3 = camelize(`${argument3}`)
    argument4 = camelize(`${argument4}`)

    // sync app.component with updates
    fs.readdir(process.cwd(), function (err, items) {
      genArr = items;
      generateDirectArray(genArr);
    });


    function generateDirectArray(items) {
      for (var i = 0; i < items.length; i++) {
        if (isDirectory(items[i])) {
        } else {
          componentsArray.push(items[i]);
        }
      }
      importStringGenerator();
    }

    function isDirectory(inputString) {
      var str = inputString;
      var patt = new RegExp("[.]");
      var res = patt.test(str);
      return res;
    }

    String.prototype.capitalizeFirstLetter = function () {
      return this.charAt(0).toUpperCase() + this.slice(1);
    }

    function importStringGenerator() {
      componentsArray.push(`${argument3}`);
      genString = "";
      for (var i = 0; i < componentsArray.length; i++) {
        genString = genString + `    import ${componentsArray[i].capitalizeFirstLetter()}Module from './${componentsArray[i]}/${componentsArray[i]}.module';\r`
      }
      listString = "";
      for (var i = 0; i < componentsArray.length; i++) {

        // check if last in list in order to not include comma
        if (i === (componentsArray.length - 1)) {
          listString = listString + `     ${componentsArray[i].capitalizeFirstLetter()}Module` + `.name \r`
        } else {
          listString = listString + `     ${componentsArray[i].capitalizeFirstLetter()}Module` + '.name, \r'
        }

      }


      fs.writeFile("components.js", `import angular from 'angular';
${genString}

const ComponentsModule = angular.module('app.components',[
  ${listString}
]);

export default ComponentsModule;`, function (err) {
        if (err) {
          return console.log(` ❌  failed to update due to error:  ${err}`);
        }
        console.log(" 🔰  updated: ".cyan + "components.js".white);
      });
    }


    mkdirp(argument3, function (err) {
      console.log("Generating Component...".white)
      if (err) console.error(err)
      else
        process.chdir(argument3),

          //build component.html
          fs.writeFile(argument3 + ".component.html", `<h1> ${argument3} works! </h1>`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + argument3.white + ".component.html".white);
          });

      //build scss || css styling scripts
      if (argument3 === "--style:css" || argument4 === "--style:css") {
        // build component.css
        fs.writeFile(argument3 + ".component.css", "", function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + argument3.white + ".component.css".white);
        });
      } else {
        // build component.scss
        fs.writeFile(argument3 + ".component.scss", "", function (err) {
          if (err) {
            return console.log(` ❌  failed to generate due to error:  ${err}`);
          }
          console.log(" 🎁  created: ".cyan + argument3.white + ".component.scss".white);
        });
      }

if (argument3 === "--style:css" || argument4 === "--style:css") {
  // include component.css
  fs.writeFile(argument3 + ".component.js", `import template from './${argument3}.component.html';
import controller from './${argument3}.controller.js';
import './${argument3}.component.css';

let ${argument3}Component = {
  restrict: 'E',
  bindings: {},
  template,
  controller,
  controllerAs: '${argument3}Controller'
};
export default ${argument3}Component;`, function (err) {
    if (err) {
      return console.log(` ❌  failed to generate due to error:  ${err}`);
    }
    console.log(" 🎁  created: ".cyan + argument3.white + ".component.js".white);
  });
} else {
  // include component.scss
  fs.writeFile(argument3 + ".component.js", `import template from './${argument3}.component.html';
import controller from './${argument3}.controller.js';
import './${argument3}.component.scss';

let ${argument3}Component = {
  restrict: 'E',
  bindings: {},
  template,
  controller,
  controllerAs: '${argument3}Controller'
};
export default ${argument3}Component;`, function (err) {
    if (err) {
      return console.log(` ❌  failed to generate due to error:  ${err}`);
    }
    console.log(" 🎁  created: ".cyan + argument3.white + ".component.js".white);
  });
}



      //build module.js
      fs.writeFile(argument3 + ".module.js", `import angular from 'angular';
import ${argument3}Component from './${argument3}.component';

const ${argument3}Module = angular.module('${argument3}', [])
  .component('${argument3}', ${argument3}Component);
export default ${argument3}Module;`, function (err) {
        if (err) {
          return console.log(` ❌  failed to generate due to error:  ${err}`);
        }
        console.log(" 🎁  created: ".cyan + argument3.white + ".module.js".white);
      });

      //build controller.js
      fs.writeFile(argument3 + ".controller.js", `class ${argument3}Controller {
    constructor() {
      this.name = '${argument3}';
    }
  }

  export default ${argument3}Controller;`, function (err) {
        if (err) {
          return console.log(` ❌  failed to generate due to error:  ${err}`);
        }
        console.log(" 🎁  created: ".cyan + argument3.white + ".controller.js".white);
      });
    });


  } else if (value === 'help' || value === '-help' || value === '--help' || value === '-h') {
    // provide user with help
    console.log(`
    - gen new {{PROJECT NAME}}

    - gen new {{PROJECT NAME}} --style:css
        The default styling is set to SCSS.

    - gen -c {{COMPONENT NAME}} --style:css
        The default styling is set to SCSS.

    - gen -c {{COMPONENT NAME}}

    - gen v
    - gen -v
    - gen version
    - gen --version
        This reveals the current version number

    - gen h
    - gen -h
    - gen help
    - gen --version
        This reveals the Angular-1.5-cli command list
    `);
  } else if (value === 'v' || value === 'version' || value === '-v' || value === '--version') {
    //provide user with version number
    console.log(packagejson.version);
  } else if (value === "serve" || value === "comp") {
    if (value === "serve") {
      console.log('serving angular 1.5 app...');
      cmd.get(
        `
                webpack && webpack-dev-server --content-base client/
            `,
        function (data) {

        }
      );

    } else if (value === "comp") {

      // user chose component
      prompt.start();

      prompt.get([{
        name: 'name',
        required: true
      }], function (err, result) {
        //
        // Log the results.
        //
        var projectName = result.name
        console.log(`Would you like to use 'scss or css'?`);
        prompt.get([{
          name: 'styling',
          required: true
        }], function (err, result) {
          //
          // Log the results.
          //
          var stylingVar = '';
          if (result.styling === 'css') {
            stylingVar = '--style:css'
          } else {
            stylingVar = '--style:scss'
          }
          console.log(`Generating component: ${projectName}`);

          value = '-c';
          argument3 = projectName;
          argument4 = stylingVar;

          //
          //re-execute genScript with new values
          genScript();
          //
          //

        });

      });
    }
  } else if (value === 'copyTo' || value === 'transferTo') {

    fs.copy(`${argument3}`, `${argument4}`, function (err) {
      if (err) return console.error(err)
        console.log('Success:'.green + ' created:'.white + './dist/assets')
    });

  }else if (value === '-r' || value === 'remove') {

    function camelize(str) {
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
        return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
      }).replace(/\s+/g, '');
    }

    value = camelize(`${value}`)
    argument3 = camelize(`${argument3}`)
    argument4 = camelize(`${argument4}`)

    function camelize(str) {
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
        return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
      }).replace(/\s+/g, '');
    }

    // value = camelize(`${value}`)
    argument3 = camelize(`${argument3}`)
    argument4 = camelize(`${argument4}`)

    console.log('Delete Component');
    prompt.start();
    console.log(`Are you sure you would like to delete ${argument3}`.red);
    prompt.get([{
      name: 'Answer',
      required: true
    }], function (err, result) {
      if (err) {
        return console.log(err)
      }

      if (result.Answer === 'yes') {
        //

        process.chdir(`./client/app/components`);
        fs.remove(`./${argument3}`, err => {
          if (err) return console.error(err)

          console.log(`Deleted ${colors.red.strikethrough(`${argument3}`)}`)

        //updateComponentsJS after it has deleted the component
        updateComponentsJS()
      })

      } else if (result.Answer === 'no' || result.Answer === 'exit' || result.Answer === 'stop') {

      } else {
        console.log('Exiting...'.orange)
      }


    });

  } else if (value === 'clone') {

    process.chdir(`./client/app/components`);

    function camelize(str) {
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
        return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
      }).replace(/\s+/g, '');
    }

    value = camelize(`${value}`)
    argument3 = camelize(`${argument3}`)
    argument4 = camelize(`${argument4}`)

    //updateComponentsJS with new directory name
    updateComponentsJS(argument4);

    fs.copy(`${argument3}`, `${argument4}`, function (err) {
      if (err) return console.error(err)

      console.log("Transfer complete!")

      console.log("Renaming folders...")
      process.chdir(`./${argument4}`);
      renameComponentFiles();
    });

  }else if (value === '-s' || value === 'service') {
    process.chdir(`./client/app`);

    function camelize(str) {
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
        return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
      }).replace(/\s+/g, '');
    }

    tempValue = 'noName';

    if (argument3 === '--post' || argument3 === '--get'){
      tempValue = argument3
      argument3 = argument4
      argument4 = tempValue
    }

    argument3 = camelize(`${argument3}`)


    // check if services directory. If there is none then create one and move to it

fs.stat('services', function(err, stat) {
  if(err == null) {
      // FILE EXISTS
      process.chdir('services');



      if (argument4 === '--get') {
        //create a GET service

        mkdirp(`${argument3}`, function (err) {
          process.chdir(`${argument3}`);
          fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor($http, $q) {
    ngInject';

    //INIT DEPENDENCIES
    this.$http = $http;
    this.$q = $q;
  }

  getData() {
    const defer = this.$q.defer();
    this.$http.get('https://angular-1-5-cli.firebaseio.com/data.json')
      .then((response) => {
      const data = response.data;
    defer.resolve(data);
  })
  .catch((response) => {
      defer.reject(response.statusText);
  });
    return defer.promise;
  }
}

export default ${argument3}Service;`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);
            // Re-Create Services.js
            // 1. get list of all services
            // 2. write them into the services
            updateServicesJS(argument3)
          });
        });


      } else if (argument4 === '--post') {
        //create a POST service
        mkdirp(`${argument3}`, function (err) {
          process.chdir(argument3)

          fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor($http, $q) {
    'ngInject';

    //INIT DEPENDENCIES
    this.$http = $http;
    this.$q = $q;
  }

  getData(data) {
    const defer = this.$q.defer();
    this.$http.post('http://httpbin.org/post', data)
      .then((response) => {
      const data = response.data;
    defer.resolve(data);
  })
  .catch((response) => {
      defer.reject(response.statusText);
  });
    return defer.promise;
  }
}

export default ${argument3}Service;`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);
            // Re-Create Services.js
            // 1. get list of all services
            // 2. write them into the services
            updateServicesJS(argument3)
          });
        });
      } else {
        // no type specified
        mkdirp(`${argument3}`, function (err) {
          process.chdir(argument3)

          fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor() {
    'ngInject';

  }
}

export default ${argument3}Service;`, function (err) {
            if (err) {
              return console.log(` ❌  failed to generate due to error:  ${err}`);
            }
            console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);
            // Re-Create Services.js
            // 1. get list of all services
            // 2. write them into the services
            updateServicesJS(argument3)
          });
        });

      }


  } else if(err.code == 'ENOENT') {
      // FILE DOES NOT EXIST
      mkdirp("services", function (err) {
        console.log(" 🎁  created: ".cyan + "services/config".white);
        process.chdir('services');

        if (argument4 === '--get') {
          //create a GET service

          mkdirp(`${argument3}`, function (err) {
            process.chdir(`${argument3}`);
            fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor($http, $q) {
    'ngInject';

    //INIT DEPENDENCIES
    this.$http = $http;
    this.$q = $q;
  }

  getData() {
    const defer = this.$q.defer();
    this.$http.get('https://angular-1-5-cli.firebaseio.com/data.json')
      .then((response) => {
      const data = response.data;
    defer.resolve(data);
  })
  .catch((response) => {
      defer.reject(response.statusText);
  });
    return defer.promise;
  }
}

export default ${argument3}Service;`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);
              // Re-Create Services.js
              // 1. get list of all services
              // 2. write them into the services

              updateServicesJS(argument3)
            });
          });


        } else if (argument4 === '--post') {
          //create a POST service
          mkdirp(`${argument3}`, function (err) {
            process.chdir(argument3)

            fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor($http, $q) {
    'ngInject';

    //INIT DEPENDENCIES
    this.$http = $http;
    this.$q = $q;
  }

  getData(data) {
    const defer = this.$q.defer();
    this.$http.post('http://httpbin.org/post', data)
      .then((response) => {
      const data = response.data;
    defer.resolve(data);
  })
  .catch((response) => {
      defer.reject(response.statusText);
  });
    return defer.promise;
  }
}

export default ${argument3}Service;`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);

              // Re-Create Services.js
              // 1. get list of all services
              // 2. write them into the services

              updateServicesJS(argument3)
            });
          });
        } else {
          // no type specified
          mkdirp(`${argument3}`, function (err) {
            process.chdir(argument3)

            fs.writeFile(`${argument3}.js`, `class ${argument3}Service {
  constructor() {
    'ngInject';

  }
}

export default ${argument3}Service;`, function (err) {
              if (err) {
                return console.log(` ❌  failed to generate due to error:  ${err}`);
              }
              console.log(" 🎁  created: ".cyan + `${argument3}.js`.white);
              // Re-Create Services.js
              // 1. get list of all services
              // 2. write them into the services

              updateServicesJS(argument3)
            });
          });

        }



        });

  } else {
      console.log('Error: ', err.code);
  }
});






    // take name given and typ and create service (POST or GET request)





  }else if (value === 'update' && argument3 === 'components.js') {
    updateComponentsJS()
  } else {
    //promt user to find out what they want to generate
    console.log(`You can always type 'gen new {{PROJECT NAME}} for a new project or 'gen -c {{COMPONENT NAME}}'`.white);
    prompt.start();

    console.log(`Would you like to generate a 'project' or 'component' ?`.red);
    prompt.get([{
      name: 'type',
      required: true
    }], function (err, result) {
      //
      // Log the results.
      //
      if (result.type === `project` || result.type === `Project`) {
        // user chose project
        prompt.start();

        prompt.get([{
          name: 'name',
          required: true
        }], function (err, result) {
          //
          // Log the results.
          //
          var projectName = result.name
          console.log(`Would you like to use 'scss or css'?`);
          prompt.get([{
            name: 'styling',
            required: true
          }], function (err, result) {
            //
            // Log the results.
            //
            var stylingVar = '';
            if (result.styling === 'css') {
              stylingVar = '--style:css'
            } else {
              stylingVar = '--style:scss'
            }
            console.log(`Generating project: ${projectName}`);

            value = 'new';
            argument3 = projectName;
            argument4 = stylingVar;


            //
            //re-execute genScript with new values
            genScript();
            //
            //

          });
        });
      } else if (result.type === `component` || result.type === `Component`) {
        // user chose component
        prompt.start();

        prompt.get([{
          name: 'name',
          required: true
        }], function (err, result) {
          //
          // Log the results.
          //
          var projectName = result.name
          console.log(`Would you like to use 'scss or css'?`);
          prompt.get([{
            name: 'styling',
            required: true
          }], function (err, result) {
            //
            // Log the results.
            //
            var stylingVar = '';
            if (result.styling === 'css') {
              stylingVar = '--style:css'
            } else {
              stylingVar = '--style:scss'
            }
            console.log(`Generating component: ${projectName}`);

            value = '-c';
            argument3 = projectName;
            argument4 = stylingVar;

            //
            //re-execute genScript with new values
            genScript();
            //
            //

          });

        });
      } else {
        console.log(`Please try again. Unfortunately I do not understand what you would like me to do for you...`.red);
      }
    });
  }
//end of genScript
}
750457
function genLogsAndFile(model, pkg, tdef, deployUnit) {
    var descMeta = tdef.findMetaDataByID('description');
    var desc = chalk.gray.italic('-none-');
    if (descMeta) {
      if (descMeta.value.length > 50) {
        desc = descMeta.value.substr(0, 50) + '...';
      } else {
        desc = descMeta.value;
      }
    }

    console.log(chalk.yellow('TypeDefinition'));
    console.log('     ' + chalk.gray('namespace ') + pkg);
    console.log('     ' + chalk.gray('name      ') + tdef.name);
    console.log('     ' + chalk.gray('version   ') + tdef.version);
    console.log('     ' + chalk.gray('desc      ') + desc);
    console.log();

    if (tdef.dictionaryType) {
      // dictionary logging
      var dicTable = new Table({
        head: [chalk.yellow('Dictionary'), chalk.cyan('Datatype'), chalk.cyan('Default value'), chalk.cyan('Optional?'), chalk.cyan('Fragmented?')]
      });
      tdef.dictionaryType.attributes.array.forEach(function (attr) {
        dicTable.push([
          attr.name,
          attr.datatype,
          attr.defaultValue ? attr.defaultValue : chalk.gray.italic('-none-'),
          attr.optional ? chalk.green('✔'):chalk.yellow('✘'),
          attr.fragmentDependant ? chalk.green('✔'):chalk.yellow('✘')
        ]);
      });
      if (dicTable.length > 0) {
        console.log(dicTable.toString());
      }
    }

    if (tdef.provided) {
      // inputs port logging
      var inputs = tdef.provided.array.map(function (port) {
        return chalk.white(port.name);
      });
      if (inputs.length > 0) {
        var inputsTable = new Table({
          head: [chalk.yellow('Inputs')].concat(inputs)
        });
        console.log(inputsTable.toString());
      }
    }
    if (tdef.required) {
      // outputs port logging
      var outputs = tdef.required.array.map(function (port) {
        return chalk.white(port.name);
      });
      if (outputs.length > 0) {
        var outputsTable = new Table({
          head: [chalk.yellow('Outputs')].concat(outputs)
        });
        console.log(outputsTable.toString());
      }
    }

    console.log();
    console.log(chalk.yellow('DeployUnit'));
    console.log('     ' + chalk.gray('hashcode  ') + deployUnit.hashcode);
    console.log('     ' + chalk.gray('name      ') + deployUnit.name);
    console.log('     ' + chalk.gray('version   ') + deployUnit.version);
    console.log('     ' + chalk.gray('platform  ') + deployUnit.findFiltersByID('platform').value);

    if (!quiet) {
      process.stdout.write((!quiet ? '\n' : '') + chalk.green('Model generation done'));
    }

    var factory = new kevoree.factory.DefaultKevoreeFactory(),
      jsonSerializer = factory.createJSONSerializer(),
      filepath = path.resolve(dirPath, 'kevlib.json'),
      prettyModel = JSON.stringify(JSON.parse(jsonSerializer.serialize(model)), null, 4);

    fs.writeFile(filepath, prettyModel, function (err) {
      if (err) {
        errHandler(err);
      } else {
        if (!quiet) {
          console.log('\nModel saved at %s', path.relative(process.cwd(), filepath));
        }
        callback();
      }
    });
  }
1103524
function getGlobs() {

  // Look globally and locally for matching glob pattern
  const dirs = [
    `${process.cwd()}/node_modules/`, // local (where they ran the command from)
    `${__dirname}/..`,  // global, if scoped package (where this code exists)
    `${__dirname}/../..`, // global, if not scoped package
  ];

  let globs = [];

  dirs.forEach(dir => {
    const legacyPattern = path.join(dir, '*/skyux-builder*/package.json');
    const newPattern = path.join(dir, '@skyux-sdk/builder*/package.json');

    logger.verbose(`Looking for modules in ${legacyPattern} and ${newPattern}`);

    globs = globs.concat([
      ...glob.sync(legacyPattern),
      ...glob.sync(newPattern)
    ]);
  });

  return globs;
}
1364748
function betterTrim(snippetEl) {
		// Helper functions
		function trimLeft(val) {
			// Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
			return val.replace(/^[\s\uFEFF\xA0]+/g, '');
		}
		function trimLineBreaks(input) {
			var lines = input.split('\n');

			// Trim line-breaks from the beginning
			for (var i = 0; i < lines.length; i++) {
				if (lines[i].trim() === '') {
					lines.splice(i--, 1);
				} else break;
			}

			// Trim line-breaks from the end
			for (var i = lines.length-1; i >= 0; i--) {
				if (lines[i].trim() === '') {
					lines.splice(i, 1);
				} else break;
			}

			return lines.join('\n');
		}

		// Main function for betterTrim()
		return (function(snippetEl) {
			var content = trimLineBreaks(snippetEl.innerHTML);
			var lines = content.split('\n');
			// Calculate the minimum amount to remove on each line start of the snippet (can be 0)
			var pad = lines.reduce(function(acc, line) {
				if (line.length > 0 && trimLeft(line).length > 0 && acc > line.length - trimLeft(line).length) {
					return line.length - trimLeft(line).length;
				}
				return acc;
			}, Number.POSITIVE_INFINITY);
			// Slice each line with this amount
			return lines.map(function(line, index) {
				return line.slice(pad);
			})
			.join('\n');
		})(snippetEl);
	}
71171
function() {

      /**@see https://github.com/geraintluff/uri-templates
      * but with all the de-substitution stuff removed
      */
      var uriTemplateGlobalModifiers = {
        "+": true,
        "#": true,
        ".": true,
        "/": true,
        ";": true,
        "?": true,
        "&": true
      },
      uriTemplateSuffices = {
        "*": true
      };

      function notReallyPercentEncode(string) {
        return encodeURI(string).replace(/%25[0-9][0-9]/g, function (doubleEncoded) {
          return "%" + doubleEncoded.substring(3);
        });
      }

      function uriTemplateSubstitution(spec) {
        var modifier = "";
        if (uriTemplateGlobalModifiers[spec.charAt(0)]) {
          modifier = spec.charAt(0);
          spec = spec.substring(1);
        }
        var separator = "";
        var prefix = "";
        var shouldEscape = true;
        var showVariables = false;
        var trimEmptyString = false;
        if (modifier === '+') {
          shouldEscape = false;
        } else if (modifier === ".") {
          prefix = ".";
          separator = ".";
        } else if (modifier === "/") {
          prefix = "/";
          separator = "/";
        } else if (modifier === '#') {
          prefix = "#";
          shouldEscape = false;
        } else if (modifier === ';') {
          prefix = ";";
          separator = ";";
          showVariables = true;
          trimEmptyString = true;
        } else if (modifier === '?') {
          prefix = "?";
          separator = "&";
          showVariables = true;
        } else if (modifier === '&') {
          prefix = "&";
          separator = "&";
          showVariables = true;
        }

        var varNames = [];
        var varList = spec.split(",");
        var varSpecs = [];
        var varSpecMap = {};
        var i = 0, l = varList.length;
        for (i = 0; i < l; i++) {
          var varName = varList[i];
          var truncate = null;
          if (varName.indexOf(":") !== -1) {
            var parts = varName.split(":");
            varName = parts[0];
            truncate = parseInt(parts[1], 10);
          }
          var suffices = {};
          while (uriTemplateSuffices[varName.charAt(varName.length - 1)]) {
            suffices[varName.charAt(varName.length - 1)] = true;
            varName = varName.substring(0, varName.length - 1);
          }
          var varSpec = {
            truncate: truncate,
            name: varName,
            suffices: suffices
          };
          varSpecs.push(varSpec);
          varSpecMap[varName] = varSpec;
          varNames.push(varName);
        }
        var subFunction = function (valueFunction) {
          var result = "";
          var startIndex = 0;
          var i = 0, l = varSpecs.length;
          for (i = 0; i < l; i++) {
            var varSpec = varSpecs[i];
            var value = valueFunction(varSpec.name);
            if (value === null || value === undefined || (Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0)) {
              startIndex++;
              continue;
            }
            if (i === startIndex) {
              result += prefix;
            } else {
              result += (separator || ",");
            }
            if (Array.isArray(value)) {
              if (showVariables) {
                result += varSpec.name + "=";
              }
              var j = 0;
              l = value.length;
              for (j = 0; j < l; j++) {
                if (j > 0) {
                  result += varSpec.suffices['*'] ? (separator || ",") : ",";
                  if (varSpec.suffices['*'] && showVariables) {
                    result += varSpec.name + "=";
                  }
                }
                result += shouldEscape ? encodeURIComponent(value[j]).replace(/!/g, "%21") : notReallyPercentEncode(value[j]);
              }
            } else if (typeof value === "object") {
              if (showVariables && !varSpec.suffices['*']) {
                result += varSpec.name + "=";
              }
              var first = true;
              for (var key in value) {
                if (!first) {
                  result += varSpec.suffices['*'] ? (separator || ",") : ",";
                }
                first = false;
                result += shouldEscape ? encodeURIComponent(key).replace(/!/g, "%21") : notReallyPercentEncode(key);
                result += varSpec.suffices['*'] ? '=' : ",";
                result += shouldEscape ? encodeURIComponent(value[key]).replace(/!/g, "%21") : notReallyPercentEncode(value[key]);
              }
            } else {
              if (showVariables) {
                result += varSpec.name;
                if (!trimEmptyString || value !== "") {
                  result += "=";
                }
              }
              if (varSpec.truncate !== null) {
                value = value.substring(0, varSpec.truncate);
              }
              result += shouldEscape ? encodeURIComponent(value).replace(/!/g, "%21"): notReallyPercentEncode(value);
            }
          }
          return result;
        };
        subFunction.varNames = varNames;
        return {
          prefix: prefix,
          substitution: subFunction
        };
      }

      function UriTemplate(template) {
        if (!(this instanceof UriTemplate)) {
          return new UriTemplate(template);
        }
        var parts = template.split("{");
        var textParts = [parts.shift()];
        var prefixes = [];
        var substitutions = [];
        var varNames = [];
        while (parts.length > 0) {
          var part = parts.shift();
          var spec = part.split("}")[0];
          var remainder = part.substring(spec.length + 1);
          var funcs = uriTemplateSubstitution(spec);
          substitutions.push(funcs.substitution);
          prefixes.push(funcs.prefix);
          textParts.push(remainder);
          varNames = varNames.concat(funcs.substitution.varNames);
        }
        this.fill = function (valueFunction) {
          var result = textParts[0];
          var i=0, l = substitutions.length;
          for (i = 0; i < l; i++) {
            var substitution = substitutions[i];
            result += substitution(valueFunction);
            result += textParts[i + 1];
          }
          return result;
        };
        this.varNames = varNames;
        this.template = template;
      }
      UriTemplate.prototype = {
        toString: function () {
          return this.template;
        },
        fillFromObject: function (obj) {
          return this.fill(function (varName) {
            return obj[varName];
          });
        }
      };
      var ValidatorContext = function ValidatorContext(parent, collectMultiple, errorMessages, checkRecursive, trackUnknownProperties) {
        this.missing = [];
        this.missingMap = {};
        this.formatValidators = parent ? Object.create(parent.formatValidators) : {};
        this.schemas = parent ? Object.create(parent.schemas) : {};
        this.collectMultiple = collectMultiple;
        this.errors = [];
        this.handleError = collectMultiple ? this.collectError : this.returnError;
        if (checkRecursive) {
          this.checkRecursive = true;
          this.scanned = [];
          this.scannedFrozen = [];
          this.scannedFrozenSchemas = [];
          this.scannedFrozenValidationErrors = [];
          this.validatedSchemasKey = 'tv4_validation_id';
          this.validationErrorsKey = 'tv4_validation_errors_id';
        }
        if (trackUnknownProperties) {
          this.trackUnknownProperties = true;
          this.knownPropertyPaths = {};
          this.unknownPropertyPaths = {};
        }
        this.errorMessages = errorMessages;
        this.definedKeywords = {};
        if (parent) {
          for (var key in parent.definedKeywords) {
            this.definedKeywords[key] = parent.definedKeywords[key].slice(0);
          }
        }
      };
      ValidatorContext.prototype.defineKeyword = function (keyword, keywordFunction) {
        this.definedKeywords[keyword] = this.definedKeywords[keyword] || [];
        this.definedKeywords[keyword].push(keywordFunction);
      };
      ValidatorContext.prototype.createError = function (code, messageParams, dataPath, schemaPath, subErrors) {
        var messageTemplate = this.errorMessages[code] || ErrorMessagesDefault[code];
        if (typeof messageTemplate !== 'string') {
          return new ValidationError(code, "Unknown error code " + code + ": " + JSON.stringify(messageParams), messageParams, dataPath, schemaPath, subErrors);
        }
        // Adapted from Crockford's supplant()
        var message = messageTemplate.replace(/\{([^{}]*)\}/g, function (whole, varName) {
          var subValue = messageParams[varName];
          return typeof subValue === 'string' || typeof subValue === 'number' ? subValue : whole;
        });
        return new ValidationError(code, message, messageParams, dataPath, schemaPath, subErrors);
      };
      ValidatorContext.prototype.returnError = function (error) {
        return error;
      };
      ValidatorContext.prototype.collectError = function (error) {
        if (error) {
          this.errors.push(error);
        }
        return null;
      };
      ValidatorContext.prototype.prefixErrors = function (startIndex, dataPath, schemaPath) {
        var i = 0, l = this.errors.length;
        for (i = startIndex; i < l; i++) {
          this.errors[i] = this.errors[i].prefixWith(dataPath, schemaPath);
        }
        return this;
      };
      ValidatorContext.prototype.banUnknownProperties = function () {
        for (var unknownPath in this.unknownPropertyPaths) {
          var error = this.createError(ErrorCodes.UNKNOWN_PROPERTY, {path: unknownPath}, unknownPath, "");
          var result = this.handleError(error);
          if (result) {
            return result;
          }
        }
        return null;
      };

      ValidatorContext.prototype.addFormat = function (format, validator) {
        if (typeof format === 'object') {
          for (var key in format) {
            this.addFormat(key, format[key]);
          }
          return this;
        }
        this.formatValidators[format] = validator;
      };
      ValidatorContext.prototype.resolveRefs = function (schema, urlHistory) {
        if (schema['$ref'] !== undefined) {
          urlHistory = urlHistory || {};
          if (urlHistory[schema['$ref']]) {
            return this.createError(ErrorCodes.CIRCULAR_REFERENCE, {urls: Object.keys(urlHistory).join(', ')}, '', '');
          }
          urlHistory[schema['$ref']] = true;
          schema = this.getSchema(schema['$ref'], urlHistory);
        }
        return schema;
      };
      ValidatorContext.prototype.getSchema = function (url, urlHistory) {
        var schema;
        if (this.schemas[url] !== undefined) {
          schema = this.schemas[url];
          return this.resolveRefs(schema, urlHistory);
        }
        var baseUrl = url;
        var fragment = "";
        if (url.indexOf('#') !== -1) {
          fragment = url.substring(url.indexOf("#") + 1);
          baseUrl = url.substring(0, url.indexOf("#"));
        }
        if (typeof this.schemas[baseUrl] === 'object') {
          schema = this.schemas[baseUrl];
          var pointerPath = decodeURIComponent(fragment);
          if (pointerPath === "") {
            return this.resolveRefs(schema, urlHistory);
          } else if (pointerPath.charAt(0) !== "/") {
            return undefined;
          }
          var parts = pointerPath.split("/").slice(1);
          var i = 0, l = parts.length;
          for (i = 0; i < l; i++) {
            var component = parts[i].replace(/~1/g, "/").replace(/~0/g, "~");
            if (schema[component] === undefined) {
              schema = undefined;
              break;
            }
            schema = schema[component];
          }
          if (schema !== undefined) {
            return this.resolveRefs(schema, urlHistory);
          }
        }
        if (this.missing[baseUrl] === undefined) {
          this.missing.push(baseUrl);
          this.missing[baseUrl] = baseUrl;
          this.missingMap[baseUrl] = baseUrl;
        }
      };
      ValidatorContext.prototype.searchSchemas = function (schema, url) {
        if (Array.isArray(schema)) {
          var i = 0, l = schema.length;
          for (i = 0; i < l; i++) {
            this.searchSchemas(schema[i], url);
          }
        } else if (schema && typeof schema === "object") {
          if (typeof schema.id === "string") {
            if (isTrustedUrl(url, schema.id)) {
              if (this.schemas[schema.id] === undefined) {
                this.schemas[schema.id] = schema;
              }
            }
          }
          for (var key in schema) {
            if (key !== "enum") {
              if (typeof schema[key] === "object") {
                this.searchSchemas(schema[key], url);
              } else if (key === "$ref") {
                var uri = getDocumentUri(schema[key]);
                if (uri && this.schemas[uri] === undefined && this.missingMap[uri] === undefined) {
                  this.missingMap[uri] = uri;
                }
              }
            }
          }
        }
      };
      ValidatorContext.prototype.addSchema = function (url, schema) {
        // overload
        if (typeof url !== 'string' || typeof schema === 'undefined') {
          if (typeof url === 'object' && typeof url.id === 'string') {
            schema = url;
            url = schema.id;
          }
          else {
            return;
          }
        }
        if (url === getDocumentUri(url) + "#") {
          // Remove empty fragment
          url = getDocumentUri(url);
        }
        this.schemas[url] = schema;
        delete this.missingMap[url];
        normSchema(schema, url);
        this.searchSchemas(schema, url);
      };

      ValidatorContext.prototype.getSchemaMap = function () {
        var map = {};
        for (var key in this.schemas) {
          map[key] = this.schemas[key];
        }
        return map;
      };

      ValidatorContext.prototype.getSchemaUris = function (filterRegExp) {
        var list = [];
        for (var key in this.schemas) {
          if (!filterRegExp || filterRegExp.test(key)) {
            list.push(key);
          }
        }
        return list;
      };

      ValidatorContext.prototype.getMissingUris = function (filterRegExp) {
        var list = [];
        for (var key in this.missingMap) {
          if (!filterRegExp || filterRegExp.test(key)) {
            list.push(key);
          }
        }
        return list;
      };

      ValidatorContext.prototype.dropSchemas = function () {
        this.schemas = {};
        this.reset();
      };
      ValidatorContext.prototype.reset = function () {
        this.missing = [];
        this.missingMap = {};
        this.errors = [];
      };

      ValidatorContext.prototype.validateAll = function (data, schema, dataPathParts, schemaPathParts, dataPointerPath) {
        var topLevel;
        schema = this.resolveRefs(schema);
        if (!schema) {
          return null;
        } else if (schema instanceof ValidationError) {
          this.errors.push(schema);
          return schema;
        }

        var startErrorCount = this.errors.length;
        var frozenIndex, scannedFrozenSchemaIndex = null, scannedSchemasIndex = null;
        if (this.checkRecursive && data && typeof data === 'object') {
          topLevel = !this.scanned.length;
          if (data[this.validatedSchemasKey]) {
            var schemaIndex = data[this.validatedSchemasKey].indexOf(schema);
            if (schemaIndex !== -1) {
              this.errors = this.errors.concat(data[this.validationErrorsKey][schemaIndex]);
              return null;
            }
          }
          if (Object.isFrozen(data)) {
            frozenIndex = this.scannedFrozen.indexOf(data);
            if (frozenIndex !== -1) {
              var frozenSchemaIndex = this.scannedFrozenSchemas[frozenIndex].indexOf(schema);
              if (frozenSchemaIndex !== -1) {
                this.errors = this.errors.concat(this.scannedFrozenValidationErrors[frozenIndex][frozenSchemaIndex]);
                return null;
              }
            }
          }
          this.scanned.push(data);
          if (Object.isFrozen(data)) {
            if (frozenIndex === -1) {
              frozenIndex = this.scannedFrozen.length;
              this.scannedFrozen.push(data);
              this.scannedFrozenSchemas.push([]);
            }
            scannedFrozenSchemaIndex = this.scannedFrozenSchemas[frozenIndex].length;
            this.scannedFrozenSchemas[frozenIndex][scannedFrozenSchemaIndex] = schema;
            this.scannedFrozenValidationErrors[frozenIndex][scannedFrozenSchemaIndex] = [];
          } else {
            if (!data[this.validatedSchemasKey]) {
              try {
                Object.defineProperty(data, this.validatedSchemasKey, {
                  value: [],
                  configurable: true
                });
                Object.defineProperty(data, this.validationErrorsKey, {
                  value: [],
                  configurable: true
                });
              } catch (e) {
                // IE 7/8 workaround
                data[this.validatedSchemasKey] = [];
                data[this.validationErrorsKey] = [];
              }
            }
            scannedSchemasIndex = data[this.validatedSchemasKey].length;
            data[this.validatedSchemasKey][scannedSchemasIndex] = schema;
            data[this.validationErrorsKey][scannedSchemasIndex] = [];
          }
        }

        var errorCount = this.errors.length;
        var error = this.validateBasic(data, schema, dataPointerPath) || this.validateNumeric(data, schema, dataPointerPath) || this.validateString(data, schema, dataPointerPath) || this.validateArray(data, schema, dataPointerPath) || this.validateObject(data, schema, dataPointerPath) || this.validateCombinations(data, schema, dataPointerPath) || this.validateHypermedia(data, schema, dataPointerPath) || this.validateFormat(data, schema, dataPointerPath) || this.validateDefinedKeywords(data, schema, dataPointerPath) || null;

        if (topLevel) {
          while (this.scanned.length) {
            var item = this.scanned.pop();
            delete item[this.validatedSchemasKey];
          }
          this.scannedFrozen = [];
          this.scannedFrozenSchemas = [];
        }

        if (error || errorCount !== this.errors.length) {
          while ((dataPathParts && dataPathParts.length) || (schemaPathParts && schemaPathParts.length)) {
            var dataPart = (dataPathParts && dataPathParts.length) ? "" + dataPathParts.pop() : null;
            var schemaPart = (schemaPathParts && schemaPathParts.length) ? "" + schemaPathParts.pop() : null;
            if (error) {
              error = error.prefixWith(dataPart, schemaPart);
            }
            this.prefixErrors(errorCount, dataPart, schemaPart);
          }
        }

        if (scannedFrozenSchemaIndex !== null) {
          this.scannedFrozenValidationErrors[frozenIndex][scannedFrozenSchemaIndex] = this.errors.slice(startErrorCount);
        } else if (scannedSchemasIndex !== null) {
          data[this.validationErrorsKey][scannedSchemasIndex] = this.errors.slice(startErrorCount);
        }

        return this.handleError(error);
      };
      ValidatorContext.prototype.validateFormat = function (data, schema) {
        if (typeof schema.format !== 'string' || !this.formatValidators[schema.format]) {
          return null;
        }
        var errorMessage = this.formatValidators[schema.format].call(null, data, schema);
        if (typeof errorMessage === 'string' || typeof errorMessage === 'number') {
          return this.createError(ErrorCodes.FORMAT_CUSTOM, {message: errorMessage}).prefixWith(null, "format");
        } else if (errorMessage && typeof errorMessage === 'object') {
          return this.createError(ErrorCodes.FORMAT_CUSTOM, {message: errorMessage.message || "?"}, errorMessage.dataPath || null, errorMessage.schemaPath || "/format");
        }
        return null;
      };
      ValidatorContext.prototype.validateDefinedKeywords = function (data, schema, dataPointerPath) {
        for (var key in this.definedKeywords) {
          if (typeof schema[key] === 'undefined') {
            continue;
          }
          var validationFunctions = this.definedKeywords[key];
          var i = 0, l = validationFunctions.length;
          for (i = 0; i < l; i++) {
            var func = validationFunctions[i];
            var result = func(data, schema[key], schema, dataPointerPath);
            if (typeof result === 'string' || typeof result === 'number') {
              return this.createError(ErrorCodes.KEYWORD_CUSTOM, {key: key, message: result}).prefixWith(null, "format");
            } else if (result && typeof result === 'object') {
              var code = result.code;
              if (typeof code === 'string') {
                if (!ErrorCodes[code]) {
                  throw new Error('Undefined error code (use defineError): ' + code);
                }
                code = ErrorCodes[code];
              } else if (typeof code !== 'number') {
                code = ErrorCodes.KEYWORD_CUSTOM;
              }
              var messageParams = (typeof result.message === 'object') ? result.message : {key: key, message: result.message || "?"};
              var schemaPath = result.schemaPath ||( "/" + key.replace(/~/g, '~0').replace(/\//g, '~1'));
              return this.createError(code, messageParams, result.dataPath || null, schemaPath);
            }
          }
        }
        return null;
      };

      function recursiveCompare(A, B) {
        if (A === B) {
          return true;
        }
        if (typeof A === "object" && typeof B === "object") {
          if (Array.isArray(A) !== Array.isArray(B)) {
            return false;
          } else if (Array.isArray(A)) {
            if (A.length !== B.length) {
              return false;
            }
            var i = 0, l = A.length;
            for (i = 0; i < l; i++) {
              if (!recursiveCompare(A[i], B[i])) {
                return false;
              }
            }
          } else {
            var key;
            for (key in A) {
              if (B[key] === undefined && A[key] !== undefined) {
                return false;
              }
            }
            for (key in B) {
              if (A[key] === undefined && B[key] !== undefined) {
                return false;
              }
            }
            for (key in A) {
              if (!recursiveCompare(A[key], B[key])) {
                return false;
              }
            }
          }
          return true;
        }
        return false;
      }

      ValidatorContext.prototype.validateBasic = function validateBasic(data, schema, dataPointerPath) {
        var error = this.validateType(data, schema, dataPointerPath);
        if (error) {
          return error.prefixWith(null, "type");
        }
        /*if (error = this.validateEnum(data, schema, dataPointerPath)) {
        return error.prefixWith(null, "type");
      }*/
      return null;
    };

    ValidatorContext.prototype.validateType = function validateType(data, schema) {
      if (schema.type === undefined) {
        return null;
      }
      var dataType = typeof data;
      if (data === null) {
        dataType = "null";
      } else if (Array.isArray(data)) {
        dataType = "array";
      }
      var allowedTypes = schema.type;
      if (typeof allowedTypes !== "object") {
        allowedTypes = [allowedTypes];
      }

      var i = 0, l = allowedTypes.length;
      for (i = 0; i < l; i++) {
        var type = allowedTypes[i];
        if (type === dataType || (type === "integer" && dataType === "number" && (data % 1 === 0))) {
          return null;
        }
      }
      return this.createError(ErrorCodes.INVALID_TYPE, {type: dataType, expected: allowedTypes.join("/")});
    };

    ValidatorContext.prototype.validateEnum = function validateEnum(data, schema) {
      if (schema["enum"] === undefined) {
        return null;
      }
      var i = 0, l = schema["enum"].length;
      for (i = 0; i < l; i++) {
        var enumVal = schema["enum"][i];
        if (recursiveCompare(data, enumVal)) {
          return null;
        }
      }
      return this.createError(ErrorCodes.ENUM_MISMATCH, {value: (typeof JSON !== 'undefined') ? JSON.stringify(data) : data});
    };

    ValidatorContext.prototype.validateNumeric = function validateNumeric(data, schema, dataPointerPath) {
      return this.validateMultipleOf(data, schema, dataPointerPath) || this.validateMinMax(data, schema, dataPointerPath) || this.validateNaN(data, schema, dataPointerPath) || null;
    };

    var CLOSE_ENOUGH_LOW = Math.pow(2, -51);
    var CLOSE_ENOUGH_HIGH = 1 - CLOSE_ENOUGH_LOW;
    ValidatorContext.prototype.validateMultipleOf = function validateMultipleOf(data, schema) {
      var multipleOf = schema.multipleOf || schema.divisibleBy;
      if (multipleOf === undefined) {
        return null;
      }
      if (typeof data === "number") {
        var remainder = (data/multipleOf)%1;
        if (remainder >= CLOSE_ENOUGH_LOW && remainder < CLOSE_ENOUGH_HIGH) {
          return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF, {value: data, multipleOf: multipleOf});
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateMinMax = function validateMinMax(data, schema) {
      if (typeof data !== "number") {
        return null;
      }
      if (schema.minimum !== undefined) {
        if (data < schema.minimum) {
          return this.createError(ErrorCodes.NUMBER_MINIMUM, {value: data, minimum: schema.minimum}).prefixWith(null, "minimum");
        }
        if (schema.exclusiveMinimum && data === schema.minimum) {
          return this.createError(ErrorCodes.NUMBER_MINIMUM_EXCLUSIVE, {value: data, minimum: schema.minimum}).prefixWith(null, "exclusiveMinimum");
        }
      }
      if (schema.maximum !== undefined) {
        if (data > schema.maximum) {
          return this.createError(ErrorCodes.NUMBER_MAXIMUM, {value: data, maximum: schema.maximum}).prefixWith(null, "maximum");
        }
        if (schema.exclusiveMaximum && data === schema.maximum) {
          return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE, {value: data, maximum: schema.maximum}).prefixWith(null, "exclusiveMaximum");
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateNaN = function validateNaN(data) {
      if (typeof data !== "number") {
        return null;
      }
      if (isNaN(data) === true || data === Infinity || data === -Infinity) {
        return this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER, {value: data}).prefixWith(null, "type");
      }
      return null;
    };

    ValidatorContext.prototype.validateString = function validateString(data, schema, dataPointerPath) {
      return this.validateStringLength(data, schema, dataPointerPath) || this.validateStringPattern(data, schema, dataPointerPath) || null;
    };

    ValidatorContext.prototype.validateStringLength = function validateStringLength(data, schema) {
      if (typeof data !== "string") {
        return null;
      }
      if (schema.minLength !== undefined) {
        if (data.length < schema.minLength) {
          return this.createError(ErrorCodes.STRING_LENGTH_SHORT, {length: data.length, minimum: schema.minLength}).prefixWith(null, "minLength");
        }
      }
      if (schema.maxLength !== undefined) {
        if (data.length > schema.maxLength) {
          return this.createError(ErrorCodes.STRING_LENGTH_LONG, {length: data.length, maximum: schema.maxLength}).prefixWith(null, "maxLength");
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateStringPattern = function validateStringPattern(data, schema) {
      if (typeof data !== "string" || schema.pattern === undefined) {
        return null;
      }
      var regexp = new RegExp(schema.pattern);
      if (!regexp.test(data)) {
        return this.createError(ErrorCodes.STRING_PATTERN, {pattern: schema.pattern}).prefixWith(null, "pattern");
      }
      return null;
    };
    ValidatorContext.prototype.validateArray = function validateArray(data, schema, dataPointerPath) {
      if (!Array.isArray(data)) {
        return null;
      }
      return this.validateArrayLength(data, schema, dataPointerPath) || this.validateArrayUniqueItems(data, schema, dataPointerPath) || this.validateArrayItems(data, schema, dataPointerPath) || null;
    };

    ValidatorContext.prototype.validateArrayLength = function validateArrayLength(data, schema) {
      var error;
      if (schema.minItems !== undefined) {
        if (data.length < schema.minItems) {
          error = (this.createError(ErrorCodes.ARRAY_LENGTH_SHORT, {length: data.length, minimum: schema.minItems})).prefixWith(null, "minItems");
          if (this.handleError(error)) {
            return error;
          }
        }
      }
      if (schema.maxItems !== undefined) {
        if (data.length > schema.maxItems) {
          error = (this.createError(ErrorCodes.ARRAY_LENGTH_LONG, {length: data.length, maximum: schema.maxItems})).prefixWith(null, "maxItems");
          if (this.handleError(error)) {
            return error;
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateArrayUniqueItems = function validateArrayUniqueItems(data, schema) {
      if (schema.uniqueItems) {
        var i = 0, l = data.length;
        for (i = 0; i < l; i++) {
          var j = 0;
          for (j = i + 1; j < l; j++) {
            if (recursiveCompare(data[i], data[j])) {
              var error = (this.createError(ErrorCodes.ARRAY_UNIQUE, {match1: i, match2: j})).prefixWith(null, "uniqueItems");
              if (this.handleError(error)) {
                return error;
              }
            }
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateArrayItems = function validateArrayItems(data, schema, dataPointerPath) {
      if (schema.items === undefined) {
        return null;
      }
      var error, i;
      if (Array.isArray(schema.items)) {
        var l = data.length;
        for (i = 0; i < l; i++) {
          if (i < schema.items.length) {
            if (error = this.validateAll(data[i], schema.items[i], [i], ["items", i], dataPointerPath + "/" + i)) {
              return error;
            }
          } else if (schema.additionalItems !== undefined) {
            if (typeof schema.additionalItems === "boolean") {
              if (!schema.additionalItems) {
                error = (this.createError(ErrorCodes.ARRAY_ADDITIONAL_ITEMS, {})).prefixWith("" + i, "additionalItems");
                if (this.handleError(error)) {
                  return error;
                }
              }
            } else if (error = this.validateAll(data[i], schema.additionalItems, [i], ["additionalItems"], dataPointerPath + "/" + i)) {
              return error;
            }
          }
        }
      } else {
        var l = data.length;
        for (i = 0; i < l; i++) {
          if (error = this.validateAll(data[i], schema.items, [i], ["items"], dataPointerPath + "/" + i)) {
            return error;
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateObject = function validateObject(data, schema, dataPointerPath) {
      if (typeof data !== "object" || data === null || Array.isArray(data)) {
        return null;
      }
      return this.validateObjectMinMaxProperties(data, schema, dataPointerPath) || this.validateObjectRequiredProperties(data, schema, dataPointerPath) || this.validateObjectProperties(data, schema, dataPointerPath) || this.validateObjectDependencies(data, schema, dataPointerPath) || null;
    };

    ValidatorContext.prototype.validateObjectMinMaxProperties = function validateObjectMinMaxProperties(data, schema) {
      var keys = Object.keys(data);
      var error;
      if (schema.minProperties !== undefined) {
        if (keys.length < schema.minProperties) {
          error = this.createError(ErrorCodes.OBJECT_PROPERTIES_MINIMUM, {propertyCount: keys.length, minimum: schema.minProperties}).prefixWith(null, "minProperties");
          if (this.handleError(error)) {
            return error;
          }
        }
      }
      if (schema.maxProperties !== undefined) {
        if (keys.length > schema.maxProperties) {
          error = this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM, {propertyCount: keys.length, maximum: schema.maxProperties}).prefixWith(null, "maxProperties");
          if (this.handleError(error)) {
            return error;
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateObjectRequiredProperties = function validateObjectRequiredProperties(data, schema) {
      if (schema.required !== undefined) {
        var i = 0, l = schema.required.length;
        for (i = 0; i < l; i++) {
          var key = schema.required[i];
          if (data[key] === undefined) {
            var error = this.createError(ErrorCodes.OBJECT_REQUIRED, {key: key}).prefixWith(null, "" + i).prefixWith(null, "required");
            if (this.handleError(error)) {
              return error;
            }
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateObjectProperties = function validateObjectProperties(data, schema, dataPointerPath) {
      var error;
      for (var key in data) {
        var keyPointerPath = dataPointerPath + "/" + key.replace(/~/g, '~0').replace(/\//g, '~1');
        var foundMatch = false;
        if (schema.properties !== undefined && schema.properties[key] !== undefined) {
          foundMatch = true;
          if (error = this.validateAll(data[key], schema.properties[key], [key], ["properties", key], keyPointerPath)) {
            return error;
          }
        }
        if (schema.patternProperties !== undefined) {
          for (var patternKey in schema.patternProperties) {
            var regexp = new RegExp(patternKey);
            if (regexp.test(key)) {
              foundMatch = true;
              if (error = this.validateAll(data[key], schema.patternProperties[patternKey], [key], ["patternProperties", patternKey], keyPointerPath)) {
                return error;
              }
            }
          }
        }
        if (!foundMatch) {
          if (schema.additionalProperties !== undefined) {
            if (this.trackUnknownProperties) {
              this.knownPropertyPaths[keyPointerPath] = true;
              delete this.unknownPropertyPaths[keyPointerPath];
            }
            if (typeof schema.additionalProperties === "boolean") {
              if (!schema.additionalProperties) {
                error = this.createError(ErrorCodes.OBJECT_ADDITIONAL_PROPERTIES, {}).prefixWith(key, "additionalProperties");
                if (this.handleError(error)) {
                  return error;
                }
              }
            } else {
              if (error = this.validateAll(data[key], schema.additionalProperties, [key], ["additionalProperties"], keyPointerPath)) {
                return error;
              }
            }
          } else if (this.trackUnknownProperties && !this.knownPropertyPaths[keyPointerPath]) {
            this.unknownPropertyPaths[keyPointerPath] = true;
          }
        } else if (this.trackUnknownProperties) {
          this.knownPropertyPaths[keyPointerPath] = true;
          delete this.unknownPropertyPaths[keyPointerPath];
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateObjectDependencies = function validateObjectDependencies(data, schema, dataPointerPath) {
      var error;
      if (schema.dependencies !== undefined) {
        for (var depKey in schema.dependencies) {
          if (data[depKey] !== undefined) {
            var dep = schema.dependencies[depKey];
            if (typeof dep === "string") {
              if (data[dep] === undefined) {
                error = this.createError(ErrorCodes.OBJECT_DEPENDENCY_KEY, {key: depKey, missing: dep}).prefixWith(null, depKey).prefixWith(null, "dependencies");
                if (this.handleError(error)) {
                  return error;
                }
              }
            } else if (Array.isArray(dep)) {
              var i = 0, l = dep.lenth;
              for (i = 0; i < l; i++) {
                var requiredKey = dep[i];
                if (data[requiredKey] === undefined) {
                  error = this.createError(ErrorCodes.OBJECT_DEPENDENCY_KEY, {key: depKey, missing: requiredKey}).prefixWith(null, "" + i).prefixWith(null, depKey).prefixWith(null, "dependencies");
                  if (this.handleError(error)) {
                    return error;
                  }
                }
              }
            } else {
              if (error = this.validateAll(data, dep, [], ["dependencies", depKey], dataPointerPath)) {
                return error;
              }
            }
          }
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateCombinations = function validateCombinations(data, schema, dataPointerPath) {
      return this.validateAllOf(data, schema, dataPointerPath) || this.validateAnyOf(data, schema, dataPointerPath) || this.validateOneOf(data, schema, dataPointerPath) || this.validateNot(data, schema, dataPointerPath) || null;
    };

    ValidatorContext.prototype.validateAllOf = function validateAllOf(data, schema, dataPointerPath) {
      if (schema.allOf === undefined) {
        return null;
      }
      var error;
      var i = 0, l = schema.allOf.length;
      for (i = 0; i < l; i++) {
        var subSchema = schema.allOf[i];
        if (error = this.validateAll(data, subSchema, [], ["allOf", i], dataPointerPath)) {
          return error;
        }
      }
      return null;
    };

    ValidatorContext.prototype.validateAnyOf = function validateAnyOf(data, schema, dataPointerPath) {
      if (schema.anyOf === undefined) {
        return null;
      }
      var errors = [];
      var startErrorCount = this.errors.length;
      var oldUnknownPropertyPaths, oldKnownPropertyPaths;
      if (this.trackUnknownProperties) {
        oldUnknownPropertyPaths = this.unknownPropertyPaths;
        oldKnownPropertyPaths = this.knownPropertyPaths;
      }
      var errorAtEnd = true;
      var i = 0, l = schema.anyOf.length;
      for (i = 0; i < l; i++) {
        if (this.trackUnknownProperties) {
          this.unknownPropertyPaths = {};
          this.knownPropertyPaths = {};
        }
        var subSchema = schema.anyOf[i];

        var errorCount = this.errors.length;
        var error = this.validateAll(data, subSchema, [], ["anyOf", i], dataPointerPath);

        if (error === null && errorCount === this.errors.length) {
          this.errors = this.errors.slice(0, startErrorCount);

          if (this.trackUnknownProperties) {
            for (var knownKey in this.knownPropertyPaths) {
              oldKnownPropertyPaths[knownKey] = true;
              delete oldUnknownPropertyPaths[knownKey];
            }
            for (var unknownKey in this.unknownPropertyPaths) {
              if (!oldKnownPropertyPaths[unknownKey]) {
                oldUnknownPropertyPaths[unknownKey] = true;
              }
            }
            // We need to continue looping so we catch all the
            // property definitions, but we don't want to return an
            // error
            errorAtEnd = false;
            continue;
          }

          return null;
        }
        if (error) {
          errors.push(error.prefixWith(null, "" + i).prefixWith(null, "anyOf"));
        }
      }
      if (this.trackUnknownProperties) {
        this.unknownPropertyPaths = oldUnknownPropertyPaths;
        this.knownPropertyPaths = oldKnownPropertyPaths;
      }
      if (errorAtEnd) {
        errors = errors.concat(this.errors.slice(startErrorCount));
        this.errors = this.errors.slice(0, startErrorCount);
        return this.createError(ErrorCodes.ANY_OF_MISSING, {}, "", "/anyOf", errors);
      }
    };

    ValidatorContext.prototype.validateOneOf = function validateOneOf(data, schema, dataPointerPath) {
      if (schema.oneOf === undefined) {
        return null;
      }
      var validIndex = null;
      var errors = [];
      var startErrorCount = this.errors.length;
      var oldUnknownPropertyPaths, oldKnownPropertyPaths;
      if (this.trackUnknownProperties) {
        oldUnknownPropertyPaths = this.unknownPropertyPaths;
        oldKnownPropertyPaths = this.knownPropertyPaths;
      }
      var i = 0, l = schema.oneOf.length;
      for (i = 0; i < l; i++) {
        if (this.trackUnknownProperties) {
          this.unknownPropertyPaths = {};
          this.knownPropertyPaths = {};
        }
        var subSchema = schema.oneOf[i];

        var errorCount = this.errors.length;
        var error = this.validateAll(data, subSchema, [], ["oneOf", i], dataPointerPath);

        if (error === null && errorCount === this.errors.length) {
          if (validIndex === null) {
            validIndex = i;
          } else {
            this.errors = this.errors.slice(0, startErrorCount);
            return this.createError(ErrorCodes.ONE_OF_MULTIPLE, {index1: validIndex, index2: i}, "", "/oneOf");
          }
          if (this.trackUnknownProperties) {
            for (var knownKey in this.knownPropertyPaths) {
              oldKnownPropertyPaths[knownKey] = true;
              delete oldUnknownPropertyPaths[knownKey];
            }
            for (var unknownKey in this.unknownPropertyPaths) {
              if (!oldKnownPropertyPaths[unknownKey]) {
                oldUnknownPropertyPaths[unknownKey] = true;
              }
            }
          }
        } else if (error) {
          errors.push(error);
        }
      }
      if (this.trackUnknownProperties) {
        this.unknownPropertyPaths = oldUnknownPropertyPaths;
        this.knownPropertyPaths = oldKnownPropertyPaths;
      }
      if (validIndex === null) {
        errors = errors.concat(this.errors.slice(startErrorCount));
        this.errors = this.errors.slice(0, startErrorCount);
        return this.createError(ErrorCodes.ONE_OF_MISSING, {}, "", "/oneOf", errors);
      } else {
        this.errors = this.errors.slice(0, startErrorCount);
      }
      return null;
    };

    ValidatorContext.prototype.validateNot = function validateNot(data, schema, dataPointerPath) {
      if (schema.not === undefined) {
        return null;
      }
      var oldErrorCount = this.errors.length;
      var oldUnknownPropertyPaths, oldKnownPropertyPaths;
      if (this.trackUnknownProperties) {
        oldUnknownPropertyPaths = this.unknownPropertyPaths;
        oldKnownPropertyPaths = this.knownPropertyPaths;
        this.unknownPropertyPaths = {};
        this.knownPropertyPaths = {};
      }
      var error = this.validateAll(data, schema.not, null, null, dataPointerPath);
      var notErrors = this.errors.slice(oldErrorCount);
      this.errors = this.errors.slice(0, oldErrorCount);
      if (this.trackUnknownProperties) {
        this.unknownPropertyPaths = oldUnknownPropertyPaths;
        this.knownPropertyPaths = oldKnownPropertyPaths;
      }
      if (error === null && notErrors.length === 0) {
        return this.createError(ErrorCodes.NOT_PASSED, {}, "", "/not");
      }
      return null;
    };

    ValidatorContext.prototype.validateHypermedia = function validateCombinations(data, schema, dataPointerPath) {
      if (!schema.links) {
        return null;
      }
      var error;
      var i = 0, l = schema.links.length;
      for (i = 0; i < l; i++) {
        var ldo = schema.links[i];
        if (ldo.rel === "describedby") {
          var template = new UriTemplate(ldo.href);
          var allPresent = true;
          var j = 0, ll = template.varNames.length;
          for (j = 0; j < ll; j++) {
            if (!(template.varNames[j] in data)) {
              allPresent = false;
              break;
            }
          }
          if (allPresent) {
            var schemaUrl = template.fillFromObject(data);
            var subSchema = {"$ref": schemaUrl};
            if (error = this.validateAll(data, subSchema, [], ["links", i], dataPointerPath)) {
              return error;
            }
          }
        }
      }
    };

    // parseURI() and resolveUrl() are from https://gist.github.com/1088850
    // - released as public domain by author ("Yaffle") - see comments on
    // gist

    function parseURI(url) {
      var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
      // authority = '//' + user + ':' + pass '@' + hostname + ':' port
      return (m ? {
        href     : m[0] || '',
        protocol : m[1] || '',
        authority: m[2] || '',
        host     : m[3] || '',
        hostname : m[4] || '',
        port     : m[5] || '',
        pathname : m[6] || '',
        search   : m[7] || '',
        hash     : m[8] || ''
      } : null);
    }

    function resolveUrl(base, href) {// RFC 3986

      function removeDotSegments(input) {
        var output = [];
        input.replace(/^(\.\.?(\/|$))+/, '')
        .replace(/\/(\.(\/|$))+/g, '/')
        .replace(/\/\.\.$/, '/../')
        .replace(/\/?[^\/]*/g, function (p) {
          if (p === '/..') {
            output.pop();
          } else {
            output.push(p);
          }
        });
        return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
      }

      href = parseURI(href || '');
      base = parseURI(base || '');

      return !href || !base ? null : (href.protocol || base.protocol) +
      (href.protocol || href.authority ? href.authority : base.authority) +
      removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
      (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
      href.hash;
    }

    function getDocumentUri(uri) {
      return uri.split('#')[0];
    }
    function normSchema(schema, baseUri) {
      if (schema && typeof schema === "object") {
        if (baseUri === undefined) {
          baseUri = schema.id;
        } else if (typeof schema.id === "string") {
          baseUri = resolveUrl(baseUri, schema.id);
          schema.id = baseUri;
        }
        if (Array.isArray(schema)) {
          var i = 0, l = schema.length;
          for (i = 0; i < l; i++) {
            normSchema(schema[i], baseUri);
          }
        } else {
          if (typeof schema['$ref'] === "string") {
            schema['$ref'] = resolveUrl(baseUri, schema['$ref']);
          }
          for (var key in schema) {
            if (key !== "enum") {
              normSchema(schema[key], baseUri);
            }
          }
        }
      }
    }

    var ErrorCodes = {
      INVALID_TYPE: 0,
      ENUM_MISMATCH: 1,
      ANY_OF_MISSING: 10,
      ONE_OF_MISSING: 11,
      ONE_OF_MULTIPLE: 12,
      NOT_PASSED: 13,
      // Numeric errors
      NUMBER_MULTIPLE_OF: 100,
      NUMBER_MINIMUM: 101,
      NUMBER_MINIMUM_EXCLUSIVE: 102,
      NUMBER_MAXIMUM: 103,
      NUMBER_MAXIMUM_EXCLUSIVE: 104,
      NUMBER_NOT_A_NUMBER: 105,
      // String errors
      STRING_LENGTH_SHORT: 200,
      STRING_LENGTH_LONG: 201,
      STRING_PATTERN: 202,
      // Object errors
      OBJECT_PROPERTIES_MINIMUM: 300,
      OBJECT_PROPERTIES_MAXIMUM: 301,
      OBJECT_REQUIRED: 302,
      OBJECT_ADDITIONAL_PROPERTIES: 303,
      OBJECT_DEPENDENCY_KEY: 304,
      // Array errors
      ARRAY_LENGTH_SHORT: 400,
      ARRAY_LENGTH_LONG: 401,
      ARRAY_UNIQUE: 402,
      ARRAY_ADDITIONAL_ITEMS: 403,
      // Custom/user-defined errors
      FORMAT_CUSTOM: 500,
      KEYWORD_CUSTOM: 501,
      // Schema structure
      CIRCULAR_REFERENCE: 600,
      // Non-standard validation options
      UNKNOWN_PROPERTY: 1000
    };
    var ErrorCodeLookup = {};
    for (var key in ErrorCodes) {
      ErrorCodeLookup[ErrorCodes[key]] = key;
    }
    // TODO: bundle this
    var ErrorMessagesDefault = {
      INVALID_TYPE: "Invalid type: {type} (expected {expected})",
      ENUM_MISMATCH: "No enum match for: {value}",
      ANY_OF_MISSING: "Data does not match any schemas from \"anyOf\"",
      ONE_OF_MISSING: "Data does not match any schemas from \"oneOf\"",
      ONE_OF_MULTIPLE: "Data is valid against more than one schema from \"oneOf\": indices {index1} and {index2}",
      NOT_PASSED: "Data matches schema from \"not\"",
      // Numeric errors
      NUMBER_MULTIPLE_OF: "Value {value} is not a multiple of {multipleOf}",
      NUMBER_MINIMUM: "Value {value} is less than minimum {minimum}",
      NUMBER_MINIMUM_EXCLUSIVE: "Value {value} is equal to exclusive minimum {minimum}",
      NUMBER_MAXIMUM: "Value {value} is greater than maximum {maximum}",
      NUMBER_MAXIMUM_EXCLUSIVE: "Value {value} is equal to exclusive maximum {maximum}",
      NUMBER_NOT_A_NUMBER: "Value {value} is not a valid number",
      // String errors
      STRING_LENGTH_SHORT: "String is too short ({length} chars), minimum {minimum}",
      STRING_LENGTH_LONG: "String is too long ({length} chars), maximum {maximum}",
      STRING_PATTERN: "String does not match pattern: {pattern}",
      // Object errors
      OBJECT_PROPERTIES_MINIMUM: "Too few properties defined ({propertyCount}), minimum {minimum}",
      OBJECT_PROPERTIES_MAXIMUM: "Too many properties defined ({propertyCount}), maximum {maximum}",
      OBJECT_REQUIRED: "Missing required property: {key}",
      OBJECT_ADDITIONAL_PROPERTIES: "Additional properties not allowed",
      OBJECT_DEPENDENCY_KEY: "Dependency failed - key must exist: {missing} (due to key: {key})",
      // Array errors
      ARRAY_LENGTH_SHORT: "Array is too short ({length}), minimum {minimum}",
      ARRAY_LENGTH_LONG: "Array is too long ({length}), maximum {maximum}",
      ARRAY_UNIQUE: "Array items are not unique (indices {match1} and {match2})",
      ARRAY_ADDITIONAL_ITEMS: "Additional items not allowed",
      // Format errors
      FORMAT_CUSTOM: "Format validation failed ({message})",
      KEYWORD_CUSTOM: "Keyword failed: {key} ({message})",
      // Schema structure
      CIRCULAR_REFERENCE: "Circular $refs: {urls}",
      // Non-standard validation options
      UNKNOWN_PROPERTY: "Unknown property (not in schema)"
    };

    function ValidationError(code, message, params, dataPath, schemaPath, subErrors) {
      Error.call(this);
      if (code === undefined) {
        throw new Error ("No code supplied for error: "+ message);
      }
      this.message = message;
      this.params = params;
      this.code = code;
      this.dataPath = dataPath || "";
      this.schemaPath = schemaPath || "";
      this.subErrors = subErrors || null;

      var err = new Error(this.message);
      this.stack = err.stack || err.stacktrace;
      if (!this.stack) {
        try {
          throw err;
        }
        catch(err2) {
          this.stack = err2.stack || err2.stacktrace;
        }
      }
    }
    ValidationError.prototype = Object.create(Error.prototype);
    ValidationError.prototype.constructor = ValidationError;
    ValidationError.prototype.name = 'ValidationError';

    ValidationError.prototype.prefixWith = function (dataPrefix, schemaPrefix) {
      if (dataPrefix !== null) {
        dataPrefix = dataPrefix.replace(/~/g, "~0").replace(/\//g, "~1");
        this.dataPath = "/" + dataPrefix + this.dataPath;
      }
      if (schemaPrefix !== null) {
        schemaPrefix = schemaPrefix.replace(/~/g, "~0").replace(/\//g, "~1");
        this.schemaPath = "/" + schemaPrefix + this.schemaPath;
      }
      if (this.subErrors !== null) {
        var i = 0, l = this.subErrors.length;
        for (i = 0; i < l; i++) {
          this.subErrors[i].prefixWith(dataPrefix, schemaPrefix);
        }
      }
      return this;
    };

    function isTrustedUrl(baseUrl, testUrl) {
      if(testUrl.substring(0, baseUrl.length) === baseUrl){
        var remainder = testUrl.substring(baseUrl.length);
        if ((testUrl.length > 0 && testUrl.charAt(baseUrl.length - 1) === "/") || remainder.charAt(0) === "#" || remainder.charAt(0) === "?") {
          return true;
        }
      }
      return false;
    }

    var languages = {};
    function createApi(language) {
      var globalContext = new ValidatorContext();
      var currentLanguage = language || 'en';
      var api = {
        addFormat: function () {
          globalContext.addFormat.apply(globalContext, arguments);
        },
        language: function (code) {
          if (!code) {
            return currentLanguage;
          }
          if (!languages[code]) {
            code = code.split('-')[0]; // fall back to base
            // language
          }
          if (languages[code]) {
            currentLanguage = code;
            return code; // so you can tell if fall-back has
            // happened
          }
          return false;
        },
        addLanguage: function (code, messageMap) {
          var key;
          for (key in ErrorCodes) {
            if (messageMap[key] && !messageMap[ErrorCodes[key]]) {
              messageMap[ErrorCodes[key]] = messageMap[key];
            }
          }
          var rootCode = code.split('-')[0];
          if (!languages[rootCode]) { // use for base language if
            // not yet defined
            languages[code] = messageMap;
            languages[rootCode] = messageMap;
          } else {
            languages[code] = Object.create(languages[rootCode]);
            for (key in messageMap) {
              if (typeof languages[rootCode][key] === 'undefined') {
                languages[rootCode][key] = messageMap[key];
              }
              languages[code][key] = messageMap[key];
            }
          }
          return this;
        },
        freshApi: function (language) {
          var result = createApi();
          if (language) {
            result.language(language);
          }
          return result;
        },
        validate: function (data, schema, checkRecursive, banUnknownProperties) {
          var context = new ValidatorContext(globalContext, false, languages[currentLanguage], checkRecursive, banUnknownProperties);
          if (typeof schema === "string") {
            schema = {"$ref": schema};
          }
          context.addSchema("", schema);
          var error = context.validateAll(data, schema, null, null, "");
          if (!error && banUnknownProperties) {
            error = context.banUnknownProperties();
          }
          this.error = error;
          this.missing = context.missing;
          this.valid = (error === null);
          return this.valid;
        },
        validateResult: function () {
          var result = {};
          this.validate.apply(result, arguments);
          return result;
        },
        validateMultiple: function (data, schema, checkRecursive, banUnknownProperties) {
          var context = new ValidatorContext(globalContext, true, languages[currentLanguage], checkRecursive, banUnknownProperties);
          if (typeof schema === "string") {
            schema = {"$ref": schema};
          }
          context.addSchema("", schema);
          context.validateAll(data, schema, null, null, "");
          if (banUnknownProperties) {
            context.banUnknownProperties();
          }
          var result = {};
          result.errors = context.errors;
          result.missing = context.missing;
          result.valid = (result.errors.length === 0);
          return result;
        },
        addSchema: function () {
          return globalContext.addSchema.apply(globalContext, arguments);
        },
        getSchema: function () {
          return globalContext.getSchema.apply(globalContext, arguments);
        },
        getSchemaMap: function () {
          return globalContext.getSchemaMap.apply(globalContext, arguments);
        },
        getSchemaUris: function () {
          return globalContext.getSchemaUris.apply(globalContext, arguments);
        },
        getMissingUris: function () {
          return globalContext.getMissingUris.apply(globalContext, arguments);
        },
        dropSchemas: function () {
          globalContext.dropSchemas.apply(globalContext, arguments);
        },
        defineKeyword: function () {
          globalContext.defineKeyword.apply(globalContext, arguments);
        },
        defineError: function (codeName, codeNumber, defaultMessage) {
          if (typeof codeName !== 'string' || !/^[A-Z]+(_[A-Z]+)*$/.test(codeName)) {
            // TODO message bundle this
            throw new Error('Code name must be a string in UPPER_CASE_WITH_UNDERSCORES');
          }
          if (typeof codeNumber !== 'number' || codeNumber%1 !== 0 || codeNumber < 10000) {
            // TODO message bundle this
            throw new Error('Code number must be an integer > 10000');
          }
          if (typeof ErrorCodes[codeName] !== 'undefined') {
            // TODO message bundle this
            throw new Error('Error already defined: ' + codeName + ' as ' + ErrorCodes[codeName]);
          }
          if (typeof ErrorCodeLookup[codeNumber] !== 'undefined') {
            // TODO message bundle this
            throw new Error('Error code already used: ' + ErrorCodeLookup[codeNumber] + ' as ' + codeNumber);
          }
          ErrorCodes[codeName] = codeNumber;
          ErrorCodeLookup[codeNumber] = codeName;
          ErrorMessagesDefault[codeName] = ErrorMessagesDefault[codeNumber] = defaultMessage;
          for (var langCode in languages) {
            var language = languages[langCode];
            if (language[codeName]) {
              language[codeNumber] = language[codeNumber] || language[codeName];
            }
          }
        },
        reset: function () {
          globalContext.reset();
          this.error = null;
          this.missing = [];
          this.valid = true;
        },
        missing: [],
        error: null,
        valid: true,
        normSchema: normSchema,
        resolveUrl: resolveUrl,
        getDocumentUri: getDocumentUri,
        errorCodes: ErrorCodes
      };
      return api;
    }

    var tv4 = createApi();
    tv4.addLanguage('en-us', ErrorMessagesDefault);  // changed to US
    // Engilsh

    // legacy property
    tv4.tv4 = tv4;

    return tv4;
  }
589711
function zip() {
  var dist = 'dist';
  var ext = '.html';

  function getHtmlFiles(dir) {
    return fs.readdirSync(dir)
      .filter(function(file) {
        var fileExt = path.join(dir, file);
        var isHtml = path.extname(fileExt) == ext;
        return fs.statSync(fileExt).isFile() && isHtml;
      });
  }

  var htmlFiles = getHtmlFiles(dist);

  var moveTasks = htmlFiles.map(function(file){
    var sourcePath = path.join(dist, file);
    var fileName = path.basename(sourcePath, ext);

    var moveHTML = gulp.src(sourcePath)
      .pipe($.rename(function (path) {
        path.dirname = fileName;
        return path;
      }));

    var moveImages = gulp.src(sourcePath)
      .pipe($.htmlSrc({ selector: 'img'}))
      .pipe($.rename(function (path) {
        path.dirname = fileName + path.dirname.replace('dist', '');
        return path;
      }));

    return merge(moveHTML, moveImages)
      .pipe($.zip(fileName+ '.zip'))
      .pipe(gulp.dest('dist'));
  });

  return merge(moveTasks);
}
592899
def togpx(self):
        
        metadata = create_elem('metadata')
        if self.name:
            metadata.append(create_elem('name', text=self.name))
        if self.desc:
            metadata.append(create_elem('desc', text=self.desc))
        if self.author:
            element = create_elem('author')
            if self.author['name']:
                element.append(create_elem('name', text=self.author['name']))
            if self.author['email']:
                attr = dict(zip(self.author['email'].split('@'),
                                ('id', 'domain')))
                element.append(create_elem('email', attr))
            if self.author['link']:
                element.append(create_elem('link', text=self.author['link']))
            metadata.append(element)
        if self.copyright:
            if self.copyright['name']:
                author = {'author': self.copyright['name']}
            else:
                author = None
            element = create_elem('copyright', author)
            if self.copyright['year']:
                element.append(create_elem('year',
                                           text=self.copyright['year']))
            if self.copyright['license']:
                license = create_elem('license')
                element.append(license)
            metadata.append(element)
        if self.link:
            for link in self.link:
                if isinstance(link, basestring):
                    element = create_elem('link', {'href': link})
                else:
                    element = create_elem('link', {'href': link['href']})
                    if link['text']:
                        element.append(create_elem('text', text=link['text']))
                    if link['type']:
                        element.append(create_elem('type', text=link['type']))
                metadata.append(element)
        if isinstance(self.time, (time.struct_time, tuple)):
            text = time.strftime('%Y-%m-%dT%H:%M:%S%z', self.time)
        elif isinstance(self.time, utils.Timestamp):
            text = self.time.isoformat()
        else:
            text = time.strftime('%Y-%m-%dT%H:%M:%S%z')
        metadata.append(create_elem('time', text=text))
        if self.keywords:
            metadata.append(create_elem('keywords', text=self.keywords))
        if self.bounds:
            if not isinstance(self.bounds, dict):
                latitudes = list(map(attrgetter('latitude'), self.bounds))
                longitudes = list(map(attrgetter('longitude'), self.bounds))
                bounds = {
                    'minlat': str(min(latitudes)),
                    'maxlat': str(max(latitudes)),
                    'minlon': str(min(longitudes)),
                    'maxlon': str(max(longitudes)),
                }
            else:
                bounds = dict((k, str(v)) for k, v in self.bounds.items())
            metadata.append(create_elem('bounds', bounds))
        if self.extensions:
            element = create_elem('extensions')
            for i in self.extensions:
                element.append(i)
            metadata.append(self.extensions)
        return metadata