<commit_before>/* globals __dirname */
var b = require('substance-bundler')
var path = require('path')
var fs = require('fs')

// postcss extensions
var postcssScss = require('postcss-scss')
var postcssSassVariables = require('postcss-simple-vars')
var postcssNested = require('postcss-nested')
var postcssSassyImport = require('postcss-sassy-import')
var postcssSassExtend = require('postcss-sass-extend')
var postcssSassyMixins = require('postcss-sassy-mixins')
var postcssReporter = require('postcss-reporter')

// this is not run all the time
// we use it to pre-bundle vendor libraries,
// to speed up bundling within this project
// and to work around problems with using rollup on these projects
function _buildVendor() {
  _minifiedVendor('./node_modules/sanitize-html/index.js', 'sanitize-html', {
    exports: ['default']
  })
  _minifiedVendor('./.make/brace.js', 'brace')
  _minifiedVendor('./node_modules/emojione/lib/js/emojione.js', 'emojione', {
    standalone: true
  })
}

function _minifiedVendor(src, name, opts = {}) {
  let tmp = `./vendor/${name}.js`
  let _opts = Object.assign({
    dest: tmp,
    debug: false
  })
  if (opts.exports) {
    _opts.exports = opts.exports
  }
  if (opts.standalone) {
    _opts.browserify = { standalone: name }
  }
  b.browserify(src, _opts)
  if (opts.minify !== false) {
    b.minify(tmp, {
      debug: false
    })
    b.rm(tmp)
  }
}

function _copyAssets() {
  b.copy('./node_modules/font-awesome', './build/font-awesome')
  b.copy('./vendor/brace.*', './build/web/')
  b.copy('./vendor/emojione.*', './build/web/')
  b.copy('./node_modules/emojione/assets/png', './build/web/emojione/png')
  b.copy('./node_modules/substance/dist/substance.js*', './build/web/')
}

// we need this only temporarily, or if we need to work on an
// unpublished version of substance
function _buildSubstance() {
  if (!fs.existsSync(path.join(__dirname, 'node_modules/substance/dist/substance.js'))){
    b.make('substance', 'browser:pure')
  }
}

function _buildDocument() {
  b.css('src/pagestyle/stencila.scss', 'build/stencila.css', {
    parser: postcssScss,
    // don't use predefined postcss plugins
    builtins: false,
    // ... but instead use these:
    plugins: [
      postcssSassyImport(),
      postcssSassExtend(),
      postcssSassyMixins(),
      postcssNested(),
      postcssSassVariables(),
      postcssReporter()
    ],
  })
  b.js('src/document/document.js', {
    dest: 'build/stencila-document.js',
    format: 'umd', moduleName: 'stencilaDocument',
    // Ignoring stencila-js for now because
    // it needs to be re-designed to be really browser compatible
    alias: {
      'stencila-js': path.join(__dirname, 'vendor/stencila-js.stub.js'),
      'brace': path.join(__dirname, 'vendor/brace.min.js'),
      'sanitize-html': path.join(__dirname, 'vendor/sanitize-html.min.js'),
    },
    // TODO: here we need to apply different strategies for
    // different bundles (e.g. hosted without substance, but electron one with substance)
    external: ['substance', 'emojione', 'brace'],
    commonjs: true,
    json: true
  })
}

function _buildExamples() {
  b.copy('./examples/*/*.html', './build/')
  b.js('examples/document/app.js', {
    dest: 'build/examples/document/app.js',
    format: 'umd', moduleName: 'documentExample',
    external: ['stencila-document']
  })
}

b.task('clean', () => {
  b.rm('build')
})

// This is used to generate the files in ./vendor/
b.task('vendor', _buildVendor)

// ATTENTION: this is not necessary after switching to a published version of substance
b.task('substance', () => {
  _buildSubstance()
})

b.task('assets', ['substance'], () => {
  _copyAssets()
})

b.task('document', ['assets'], () => {
  _buildDocument()
})

b.task('examples', ['assets', 'document'], () => {
  _buildExamples()
})

b.task('default', ['clean', 'assets', 'document', 'examples'])

b.serve({ static: true, route: '/', folder: 'build' })
<commit_msg>Use external substance for example.<commit_after>/* globals __dirname */
var b = require('substance-bundler')
var path = require('path')
var fs = require('fs')

// postcss extensions
var postcssScss = require('postcss-scss')
var postcssSassVariables = require('postcss-simple-vars')
var postcssNested = require('postcss-nested')
var postcssSassyImport = require('postcss-sassy-import')
var postcssSassExtend = require('postcss-sass-extend')
var postcssSassyMixins = require('postcss-sassy-mixins')
var postcssReporter = require('postcss-reporter')

// this is not run all the time
// we use it to pre-bundle vendor libraries,
// to speed up bundling within this project
// and to work around problems with using rollup on these projects
function _buildVendor() {
  _minifiedVendor('./node_modules/sanitize-html/index.js', 'sanitize-html', {
    exports: ['default']
  })
  _minifiedVendor('./.make/brace.js', 'brace')
  _minifiedVendor('./node_modules/emojione/lib/js/emojione.js', 'emojione', {
    standalone: true
  })
}

function _minifiedVendor(src, name, opts = {}) {
  let tmp = `./vendor/${name}.js`
  let _opts = Object.assign({
    dest: tmp,
    debug: false
  })
  if (opts.exports) {
    _opts.exports = opts.exports
  }
  if (opts.standalone) {
    _opts.browserify = { standalone: name }
  }
  b.browserify(src, _opts)
  if (opts.minify !== false) {
    b.minify(tmp, {
      debug: false
    })
    b.rm(tmp)
  }
}

function _copyAssets() {
  b.copy('./node_modules/font-awesome', './build/font-awesome')
  b.copy('./vendor/brace.*', './build/web/')
  b.copy('./vendor/emojione.*', './build/web/')
  b.copy('./node_modules/emojione/assets/png', './build/web/emojione/png')
  b.copy('./node_modules/substance/dist/substance.js*', './build/web/')
}

// we need this only temporarily, or if we need to work on an
// unpublished version of substance
function _buildSubstance() {
  if (!fs.existsSync(path.join(__dirname, 'node_modules/substance/dist/substance.js'))){
    b.make('substance', 'browser:pure')
  }
}

function _buildDocument() {
  b.css('src/pagestyle/stencila.scss', 'build/stencila.css', {
    parser: postcssScss,
    // don't use predefined postcss plugins
    builtins: false,
    // ... but instead use these:
    plugins: [
      postcssSassyImport(),
      postcssSassExtend(),
      postcssSassyMixins(),
      postcssNested(),
      postcssSassVariables(),
      postcssReporter()
    ],
  })
  b.js('src/document/document.js', {
    dest: 'build/stencila-document.js',
    format: 'umd', moduleName: 'stencilaDocument',
    // Ignoring stencila-js for now because
    // it needs to be re-designed to be really browser compatible
    alias: {
      'stencila-js': path.join(__dirname, 'vendor/stencila-js.stub.js'),
      'brace': path.join(__dirname, 'vendor/brace.min.js'),
      'sanitize-html': path.join(__dirname, 'vendor/sanitize-html.min.js'),
    },
    // TODO: here we need to apply different strategies for
    // different bundles (e.g. hosted without substance, but electron one with substance)
    external: ['substance', 'emojione', 'brace'],
    commonjs: true,
    json: true
  })
}

function _buildExamples() {
  b.copy('./examples/*/*.html', './build/')
  b.js('examples/document/app.js', {
    dest: 'build/examples/document/app.js',
    format: 'umd', moduleName: 'documentExample',
    external: ['stencila-document', 'substance']
  })
}

b.task('clean', () => {
  b.rm('build')
})

// This is used to generate the files in ./vendor/
b.task('vendor', _buildVendor)

// ATTENTION: this is not necessary after switching to a published version of substance
b.task('substance', () => {
  _buildSubstance()
})

b.task('assets', ['substance'], () => {
  _copyAssets()
})

b.task('document', ['assets'], () => {
  _buildDocument()
})

b.task('examples', ['assets', 'document'], () => {
  _buildExamples()
})

b.task('default', ['clean', 'assets', 'document', 'examples'])

b.serve({ static: true, route: '/', folder: 'build' })
<|endoftext|>


<commit_before>const version = require('child_process').execSync('git describe --always', { cwd: __dirname }).toString().trim();

function moduleFiles(name) {
  return { is: 'group', path: name, elements: [
    { is: 'group', name: "src", path: "src", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] }
    ]},
    { is: 'group', name: "tst", path: "tst", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] },
      { is: 'file', name: "data/**" , tags: ["rsc"] }
    ]}
  ]}
}

function cwd_test(workspace) {
  return `${workspace}/node/node_modules/@openmicrostep`;
}
function tests(workspace) { return [
  `msbuildsystem.shared.tests/index.js`,
  `msbuildsystem.core.tests/index.js`,
  `msbuildsystem.js.tests/index.js`,
  `msbuildsystem.js.typescript.tests/index.js`,
].map(p => `${cwd_test(workspace)}/${p}`);
}
module.exports= {
  is: "project",
  name: "MSBuildSystem",
  'files=': {
    is: 'group',
    'cli=':              { is: 'group', elements: [{ is: 'file', name: "cli/src/index.ts"           },
                                                   { is: 'file', name: "cli/src/bin.ts"             }] },
    'core=':             moduleFiles('core'),
    'shared=':           { is: 'group', elements: [{ is: 'file', name: "shared/src/index.ts"        }] },
    'shared tests=':     { is: 'group', elements: [{ is: 'file', name: "shared/tst/index.ts"        }] },
    'foundation=':       { is: 'group', elements: [{ is: 'file', name: "foundation/src/index.ts"    }] },
    //'foundation tests=': { is: 'group', elements: [{ is: 'file', name: "foundation/tst/index.ts"    }] },
    'cxx=':              moduleFiles('cxx'),
    'js=' :              moduleFiles('js'),
    'typescript=':       moduleFiles('js.typescript'),
  },
  'config=': { is: "group",
    'node=': {
      is: "environment",
      npmPackage: { is: "component",
        "version": version,
      }
    },
    'module=': {
      is: "component",
      type: "javascript",
      compiler: "typescript",
      packager: "npm",
      npmPackage: { is: "component",
        "main": "index.js",
        "typings": "index.d.ts",
        devDependencies: { is: "component",
          "@types/node": "^6.0.78"
        }
      },
      tsConfig: { is: "component",
        "module": "commonjs",
        "target": "es6",
        "declaration": true,
        "experimentalDecorators": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "sourceMap": true,
        //"lib": ["es6"],
        "types": ["node"]
      },
    },
    'module tests=': {
      is: "component",
      components: ["=module"],
      tsConfig: { is: "component",
        "types": ["node", "mocha", "chai"]
      },
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "chai": "^4.1.2"
        },
        devDependencies: { is: "component",
          "@types/chai": "^4.0.4",
          "@types/mocha": "^2.2.28",
          "@types/node": "^6.0.78",
          "@openmicrostep/tests": "^0.1.0"
        },
      },
    },
  },
  'base=': {
    is: "component",
    components: ["=config:module"],
    environments: ["=config:node"],
  },
  'base tests=': {
    is: "component",
    components: ["=config:module tests"],
    environments: ["=config:node"],
  },
  'targets=': { 'is': 'group',
    'shared=': {
      is: "target",
      components: ['=base'],
      outputName: '@openmicrostep/msbuildsystem.shared',
      files: ['=files:shared'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "@openmicrostep/async": "^0.1.0"
        },
      }
    },
    'shared tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.shared.tests',
      targets: ['shared'],
      components: ['=base tests', '=::shared::'],
      files: ['=files:shared tests'],
    },
    'core=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core',
      targets: ['shared'],
      components: ['=base', '=::shared::'],
      files: ['=files:core:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "semver": "^5.5.0",
          "fs-extra": "^6.0.1",
          "source-map-support": "^0.5.6"
        },
        devDependencies: { is: "component",
          "@types/semver": "^5.5.0",
          "@types/fs-extra": "^5.0.2",
        },
      },
      exports: [{ is: 'component', name: 'cfg',
        "module=": { is: 'component', components: ['=config:module']       },
        "tests=" : { is: 'component', components: ['=config:module tests'] },
      }]
    },
    'core tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core.tests',
      targets: ['core'],
      components: ['=base tests', '=::core::'],
      files: ['=files:core:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:core:tst ? rsc'], dest: 'data', expand: true }]
    },
    'cli=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cli',
      components: ['=base', '=::core::'],
      targets: ['core'],
      files: ['=files:cli'],
      //tsConfig: [{ traceResolution: true }],,
      npmPackage: { is: "component",
        bin: { "msbuildsystem": "./bin.js" },
        dependencies: { is: "component",
          "argparse": "^1.0.10",
          "chalk": "^2.4.1"
        },
        devDependencies: { is: "component",
          "@types/argparse": "^1.0.33",
        },
      }
    },
    'foundation=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation',
      targets: ['core'],
      components: ['=base', '=::core::'],
      files: ['=files:foundation']
    },
    /*'foundation tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation.tests',
      components: ['=base tests'],
      targets: ['foundation'],
      files: ['=files:foundation tests'],
    },*/
    'cxx=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:cxx:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "fs-extra": "^4.0.1",
        },
        devDependencies: { is: "component",
          "@types/fs-extra": "^4.0.0",
        },
      },
    },
    'cxx tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx.tests',
      targets: ['cxx'],
      components: ['=base tests', '=::cxx::', '=::core::'],
      files: ['=files:cxx:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:cxx:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'js=':               {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:js:src ? tsc']
    },
    'js tests=':         {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.tests',
      targets: ['js'],
      components: ['=base tests', '=::foundation::', '=::core::', '=::js::'],
      files: ['=files:js:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:js:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'typescript=':       {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript',
      targets: ['core', 'foundation', 'js'],
      components: ['=base', '=::foundation::', '=::js::', '=::core::'],
      files: ['=files:typescript:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "typescript": "^2.8.3",
        }
      },
    },
    'typescript tests=': {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript.tests',
      components: ['=base tests', '=::core::', '=::js::', '=::typescript::'],
      targets: ['typescript'],
      files: ['=files:typescript:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:typescript:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
  },
  'commands=': { is: "group",
    "envs=": { is: "group", elements: [
      { is: "environment", name: "gitlab"  , tags: ["ci"   ] },
      { is: "environment", name: "travis"  , tags: ["ci"   , "coveralls"] },
      { is: "environment", name: "appveyor", tags: ["ci"   ] },
      { is: "environment", name: "local"   , tags: ["local"] },
    ]},
    "shell=": {
      is: "component",
      type: "basic",
      manual: true,
      environments: ["=envs"],
    },
    "cmd_no_cwd=": {
      is: "component",
      type: "cmd",
      tty: true,
      shell: true,
    },
    "cmd=": {
      is: "component",
      components: ["=cmd_no_cwd"],
      cwd: "={cwd}.absolutePath",
    },
    'cwd=': { is: 'group', elements: [{ is: 'file', name: "." }] },
    "install-deps=": { is: "task", components: ["=cmd"], cmd: "npm install -g -q coveralls nyc @openmicrostep/tests" },
    "build-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "msbuildsystem", "build", "-p", ".", "-w", "dist/1/"
    ]) },
    "tests-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/1")
    ]) },
    "build-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/1/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", ".", "-w", "dist/2/"
    ]) },
    "tests-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/2")
    ]) },
    "build-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/2/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", ".", "-w", "dist/3/"
    ]) },
    "tests-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", "-t", "10000", ...tests("dist/3")
    ]) },
    "coverage-local-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "nyc", "--no-exclude-after-remap", "--cwd", cwd_test("dist/3"), "--reporter=html", "--report-dir", `${__dirname}/../dist/coverage`, "--temp-directory", `${__dirname}/../dist/coverage/nyc_output`, "-x", "*.tests/**", "mstests",
      "-c", "-t", "20000", ...tests("dist/3")
    ]) },
    "coveralls-3=": { is: "task", components: ["=cmd"], cmd:
      `nyc --no-exclude-after-remap --cwd ${cwd_test("dist/3")} --reporter=text-lcov --report-dir ${__dirname}/../dist/coverage -x "*.tests/**" mstests -c -t 20000 ${tests("dist/3").join(' ')} | coveralls`
    },

    "deploy-shared="    : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.shared"       ]) },
    "deploy-core="      : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.core"         ]) },
    "deploy-cli="       : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.cli"          ]) },
    "deploy-foundation=": { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.foundation"   ]) },
    "deploy-js="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js"           ]) },
    "deploy-ts="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js.typescript"]) },
    "deploy=":        { is: "target", components: ["=shell"], targets: ["bootstrap"],
      preTasks: Value(["=deploy-shared","=deploy-core","=deploy-cli","=deploy-foundation","=deploy-js","=deploy-ts"]) },

    "build-tests-1=": { is: "target", components: ["=shell"], preTasks: Value(["=build-1", "=tests-1"]) },
    "build-tests-2=": { is: "target", components: ["=shell"], preTasks: Value(["=build-2", "=tests-2"]) },
    "build-tests-3=": { is: "target", components: ["=shell"], preTasks: Value(["=build-3", "=tests-3"]) },
    "bootstrap=":     { is: "target", components: ["=shell"], preTasksByEnvironment: {
      "=envs ? ci + !coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3"                                    ]),
      "=envs ? ci +  coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3", "=coveralls-3"     ]),
      "=envs ? local"          : Value(["=build-1", "=build-2", "=build-3", "=tests-3", "=coverage-local-3"]),
    } },
  }
}

<commit_msg>Force tsc to 2.8.3, will be fixed correctly later<commit_after>const version = require('child_process').execSync('git describe --always', { cwd: __dirname }).toString().trim();

function moduleFiles(name) {
  return { is: 'group', path: name, elements: [
    { is: 'group', name: "src", path: "src", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] }
    ]},
    { is: 'group', name: "tst", path: "tst", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] },
      { is: 'file', name: "data/**" , tags: ["rsc"] }
    ]}
  ]}
}

function cwd_test(workspace) {
  return `${workspace}/node/node_modules/@openmicrostep`;
}
function tests(workspace) { return [
  `msbuildsystem.shared.tests/index.js`,
  `msbuildsystem.core.tests/index.js`,
  `msbuildsystem.js.tests/index.js`,
  `msbuildsystem.js.typescript.tests/index.js`,
].map(p => `${cwd_test(workspace)}/${p}`);
}
module.exports= {
  is: "project",
  name: "MSBuildSystem",
  'files=': {
    is: 'group',
    'cli=':              { is: 'group', elements: [{ is: 'file', name: "cli/src/index.ts"           },
                                                   { is: 'file', name: "cli/src/bin.ts"             }] },
    'core=':             moduleFiles('core'),
    'shared=':           { is: 'group', elements: [{ is: 'file', name: "shared/src/index.ts"        }] },
    'shared tests=':     { is: 'group', elements: [{ is: 'file', name: "shared/tst/index.ts"        }] },
    'foundation=':       { is: 'group', elements: [{ is: 'file', name: "foundation/src/index.ts"    }] },
    //'foundation tests=': { is: 'group', elements: [{ is: 'file', name: "foundation/tst/index.ts"    }] },
    'cxx=':              moduleFiles('cxx'),
    'js=' :              moduleFiles('js'),
    'typescript=':       moduleFiles('js.typescript'),
  },
  'config=': { is: "group",
    'node=': {
      is: "environment",
      npmPackage: { is: "component",
        "version": version,
      }
    },
    'module=': {
      is: "component",
      type: "javascript",
      compiler: "typescript",
      packager: "npm",
      npmPackage: { is: "component",
        "main": "index.js",
        "typings": "index.d.ts",
        devDependencies: { is: "component",
          "@types/node": "^6.0.78"
        }
      },
      tsConfig: { is: "component",
        "module": "commonjs",
        "target": "es6",
        "declaration": true,
        "experimentalDecorators": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "sourceMap": true,
        //"lib": ["es6"],
        "types": ["node"]
      },
    },
    'module tests=': {
      is: "component",
      components: ["=module"],
      tsConfig: { is: "component",
        "types": ["node", "mocha", "chai"]
      },
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "chai": "^4.1.2"
        },
        devDependencies: { is: "component",
          "@types/chai": "^4.0.4",
          "@types/mocha": "^2.2.28",
          "@types/node": "^6.0.78",
          "@openmicrostep/tests": "^0.1.0"
        },
      },
    },
  },
  'base=': {
    is: "component",
    components: ["=config:module"],
    environments: ["=config:node"],
  },
  'base tests=': {
    is: "component",
    components: ["=config:module tests"],
    environments: ["=config:node"],
  },
  'targets=': { 'is': 'group',
    'shared=': {
      is: "target",
      components: ['=base'],
      outputName: '@openmicrostep/msbuildsystem.shared',
      files: ['=files:shared'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "@openmicrostep/async": "^0.1.0"
        },
      }
    },
    'shared tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.shared.tests',
      targets: ['shared'],
      components: ['=base tests', '=::shared::'],
      files: ['=files:shared tests'],
    },
    'core=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core',
      targets: ['shared'],
      components: ['=base', '=::shared::'],
      files: ['=files:core:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "semver": "^5.5.0",
          "fs-extra": "^6.0.1",
          "source-map-support": "^0.5.6"
        },
        devDependencies: { is: "component",
          "@types/semver": "^5.5.0",
          "@types/fs-extra": "^5.0.2",
        },
      },
      exports: [{ is: 'component', name: 'cfg',
        "module=": { is: 'component', components: ['=config:module']       },
        "tests=" : { is: 'component', components: ['=config:module tests'] },
      }]
    },
    'core tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core.tests',
      targets: ['core'],
      components: ['=base tests', '=::core::'],
      files: ['=files:core:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:core:tst ? rsc'], dest: 'data', expand: true }]
    },
    'cli=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cli',
      components: ['=base', '=::core::'],
      targets: ['core'],
      files: ['=files:cli'],
      //tsConfig: [{ traceResolution: true }],,
      npmPackage: { is: "component",
        bin: { "msbuildsystem": "./bin.js" },
        dependencies: { is: "component",
          "argparse": "^1.0.10",
          "chalk": "^2.4.1"
        },
        devDependencies: { is: "component",
          "@types/argparse": "^1.0.33",
        },
      }
    },
    'foundation=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation',
      targets: ['core'],
      components: ['=base', '=::core::'],
      files: ['=files:foundation']
    },
    /*'foundation tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation.tests',
      components: ['=base tests'],
      targets: ['foundation'],
      files: ['=files:foundation tests'],
    },*/
    'cxx=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:cxx:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "fs-extra": "^4.0.1",
        },
        devDependencies: { is: "component",
          "@types/fs-extra": "^4.0.0",
        },
      },
    },
    'cxx tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx.tests',
      targets: ['cxx'],
      components: ['=base tests', '=::cxx::', '=::core::'],
      files: ['=files:cxx:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:cxx:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'js=':               {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:js:src ? tsc']
    },
    'js tests=':         {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.tests',
      targets: ['js'],
      components: ['=base tests', '=::foundation::', '=::core::', '=::js::'],
      files: ['=files:js:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:js:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'typescript=':       {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript',
      targets: ['core', 'foundation', 'js'],
      components: ['=base', '=::foundation::', '=::js::', '=::core::'],
      files: ['=files:typescript:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "typescript": "2.8.3",
        }
      },
    },
    'typescript tests=': {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript.tests',
      components: ['=base tests', '=::core::', '=::js::', '=::typescript::'],
      targets: ['typescript'],
      files: ['=files:typescript:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:typescript:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
  },
  'commands=': { is: "group",
    "envs=": { is: "group", elements: [
      { is: "environment", name: "gitlab"  , tags: ["ci"   ] },
      { is: "environment", name: "travis"  , tags: ["ci"   , "coveralls"] },
      { is: "environment", name: "appveyor", tags: ["ci"   ] },
      { is: "environment", name: "local"   , tags: ["local"] },
    ]},
    "shell=": {
      is: "component",
      type: "basic",
      manual: true,
      environments: ["=envs"],
    },
    "cmd_no_cwd=": {
      is: "component",
      type: "cmd",
      tty: true,
      shell: true,
    },
    "cmd=": {
      is: "component",
      components: ["=cmd_no_cwd"],
      cwd: "={cwd}.absolutePath",
    },
    'cwd=': { is: 'group', elements: [{ is: 'file', name: "." }] },
    "install-deps=": { is: "task", components: ["=cmd"], cmd: "npm install -g -q coveralls nyc @openmicrostep/tests" },
    "build-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "msbuildsystem", "build", "-p", ".", "-w", "dist/1/"
    ]) },
    "tests-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/1")
    ]) },
    "build-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/1/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", ".", "-w", "dist/2/"
    ]) },
    "tests-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/2")
    ]) },
    "build-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/2/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", ".", "-w", "dist/3/"
    ]) },
    "tests-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", "-t", "10000", ...tests("dist/3")
    ]) },
    "coverage-local-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "nyc", "--no-exclude-after-remap", "--cwd", cwd_test("dist/3"), "--reporter=html", "--report-dir", `${__dirname}/../dist/coverage`, "--temp-directory", `${__dirname}/../dist/coverage/nyc_output`, "-x", "*.tests/**", "mstests",
      "-c", "-t", "20000", ...tests("dist/3")
    ]) },
    "coveralls-3=": { is: "task", components: ["=cmd"], cmd:
      `nyc --no-exclude-after-remap --cwd ${cwd_test("dist/3")} --reporter=text-lcov --report-dir ${__dirname}/../dist/coverage -x "*.tests/**" mstests -c -t 20000 ${tests("dist/3").join(' ')} | coveralls`
    },

    "deploy-shared="    : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.shared"       ]) },
    "deploy-core="      : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.core"         ]) },
    "deploy-cli="       : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.cli"          ]) },
    "deploy-foundation=": { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.foundation"   ]) },
    "deploy-js="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js"           ]) },
    "deploy-ts="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js.typescript"]) },
    "deploy=":        { is: "target", components: ["=shell"], targets: ["bootstrap"],
      preTasks: Value(["=deploy-shared","=deploy-core","=deploy-cli","=deploy-foundation","=deploy-js","=deploy-ts"]) },

    "build-tests-1=": { is: "target", components: ["=shell"], preTasks: Value(["=build-1", "=tests-1"]) },
    "build-tests-2=": { is: "target", components: ["=shell"], preTasks: Value(["=build-2", "=tests-2"]) },
    "build-tests-3=": { is: "target", components: ["=shell"], preTasks: Value(["=build-3", "=tests-3"]) },
    "bootstrap=":     { is: "target", components: ["=shell"], preTasksByEnvironment: {
      "=envs ? ci + !coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3"                                    ]),
      "=envs ? ci +  coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3", "=coveralls-3"     ]),
      "=envs ? local"          : Value(["=build-1", "=build-2", "=build-3", "=tests-3", "=coverage-local-3"]),
    } },
  }
}

<|endoftext|>


<commit_before>'use strict';

require('shelljs/make');
var path = require('path');
var http = require('http');
var fs   = require('fs');

var MOCHA      = path.join(__dirname, 'node_modules/.bin/mocha');
var BOOTLINT   = path.join(__dirname, 'node_modules/.bin/bootlint');
var FOREVER    = path.join(__dirname, 'node_modules/.bin/forever');
var MOCHA_OPTS = ' --timeout 15000 --slow 500';

(function() {
    cd(__dirname);

    function assert(result) {
        if (result.code !== 0) {
            process.exit(result.code);
        }
    }
    function assertExec(cmd) {
        assert(exec(cmd));
    }

    //
    // make test
    //
    target.test = function() {
        // without functional tests
        assertExec(MOCHA + MOCHA_OPTS + ' -i -g "functional" -R spec ./tests/');
    };

    target.suite = function() {
        assertExec(MOCHA + MOCHA_OPTS + ' -R dot ./tests/');
    };

    target.functional = function() {
        assertExec(MOCHA + MOCHA_OPTS + ' -R tap ./tests/functional_test.js');
    };

    //
    // make clean
    //
    target.clean = function() {
        rm('-rf', 'node_modules');
    };

    //
    // make run
    //
    target.run = function() {
        assertExec('node app.js');
    };

    // for functional tests
    target.start = function() {
        assertExec(FOREVER + ' --plain start app.js');
    };
    target.stop = function() {
        assertExec(FOREVER + ' stop app.js');
    };
    target.restart = function() {
        assertExec(FOREVER + ' stop app.js');
        assertExec(FOREVER + ' --plain start app.js');
    };

    //
    // make travis
    //
    target.travis = function() {
        target.suite();
        target.bootlint();
    };

    //
    // make wp-plugin
    //
    target['wp-plugin'] = function() {
        echo('node ./scripts/wp-plugin.js');
        assertExec('node ./scripts/wp-plugin.js');
    };

    target['purge-latest'] = function() {
        // TODO: Make pure JS
        echo('bash ./scripts/purge.sh');
        assertExec('bash ./scripts/purge.sh');
    };

    //
    // make bootlint
    //
    target.bootlint = function() {
        echo('+ node make start');
        var port = 3080;
        env.PORT = port;
        target.start();

        // sleep
        setTimeout(function() {
            var output = path.join(__dirname, 'lint.html');
            var file = fs.createWriteStream(output);

            // okay, not really curl, but it communicates
            echo('+ curl http://localhost:' + port + '/ > ' + output);
            var request = http.get('http://localhost:' + port + '/', function(response) {
                response.pipe(file);

                response.on('end', function() {
                    file.close();

                    echo('+ bootlint ' + output);

                    // disabling version error's until bootswatch is updated to 3.3.4
                    var res = exec(BOOTLINT + ' -d W013 ' + output);

                    echo('+ node make stop');
                    target.stop();

                    rm(output);

                    if (res.stdout.indexOf("0 lint error(s) found") < 0) {
                        process.exit(1);
                    }
                });
            });
        }, 2000);
    };

    //
    // make all
    //
    target.all = function() {
        target.test();
        target.run();
    };

    //
    // make help
    //
    target.help = function() {
        echo('Available targets:');
        echo('  all         test and run');
        echo('  test        runs unit tests');
        echo('  functional  runs functional tests');
        echo('  suite       runs unit and functional tests');
        echo('  clean       cleanup working directory');
        echo('  run         runs for development mode');
        echo('  bootlint    run Bootlint locally');
        echo('  help        shows this help message');
    };

}());
<commit_msg>Revert "fixing output reader"<commit_after>'use strict';

require('shelljs/make');
var path = require('path');
var http = require('http');
var fs   = require('fs');

var MOCHA      = path.join(__dirname, 'node_modules/.bin/mocha');
var BOOTLINT   = path.join(__dirname, 'node_modules/.bin/bootlint');
var FOREVER    = path.join(__dirname, 'node_modules/.bin/forever');
var MOCHA_OPTS = ' --timeout 15000 --slow 500';

(function() {
    cd(__dirname);

    function assert(result) {
        if (result.code !== 0) {
            process.exit(result.code);
        }
    }
    function assertExec(cmd) {
        assert(exec(cmd));
    }

    //
    // make test
    //
    target.test = function() {
        // without functional tests
        assertExec(MOCHA + MOCHA_OPTS + ' -i -g "functional" -R spec ./tests/');
    };

    target.suite = function() {
        assertExec(MOCHA + MOCHA_OPTS + ' -R dot ./tests/');
    };

    target.functional = function() {
        assertExec(MOCHA + MOCHA_OPTS + ' -R tap ./tests/functional_test.js');
    };

    //
    // make clean
    //
    target.clean = function() {
        rm('-rf', 'node_modules');
    };

    //
    // make run
    //
    target.run = function() {
        assertExec('node app.js');
    };

    // for functional tests
    target.start = function() {
        assertExec(FOREVER + ' --plain start app.js');
    };
    target.stop = function() {
        assertExec(FOREVER + ' stop app.js');
    };
    target.restart = function() {
        assertExec(FOREVER + ' stop app.js');
        assertExec(FOREVER + ' --plain start app.js');
    };

    //
    // make travis
    //
    target.travis = function() {
        target.suite();
        target.bootlint();
    };

    //
    // make wp-plugin
    //
    target['wp-plugin'] = function() {
        echo('node ./scripts/wp-plugin.js');
        assertExec('node ./scripts/wp-plugin.js');
    };

    target['purge-latest'] = function() {
        // TODO: Make pure JS
        echo('bash ./scripts/purge.sh');
        assertExec('bash ./scripts/purge.sh');
    };

    //
    // make bootlint
    //
    target.bootlint = function() {
        echo('+ node make start');
        var port = 3080;
        env.PORT = port;
        target.start();

        // sleep
        setTimeout(function() {
            var output = path.join(__dirname, 'lint.html');
            var file = fs.createWriteStream(output);

            // okay, not really curl, but it communicates
            echo('+ curl http://localhost:' + port + '/ > ' + output);
            var request = http.get('http://localhost:' + port + '/', function(response) {
                response.pipe(file);

                response.on('end', function() {
                    file.close();

                    echo('+ bootlint ' + output);

                    // disabling version error's until bootswatch is updated to 3.3.4
                    var res = exec(BOOTLINT + ' -d W013 ' + output);

                    echo('+ node make stop');
                    target.stop();

                    rm(output);

                    if (res.output.indexOf('0 lint error(s) found') < 0) {
                        process.exit(1);
                    }
                });
            });
        }, 2000);
    };

    //
    // make all
    //
    target.all = function() {
        target.test();
        target.run();
    };

    //
    // make help
    //
    target.help = function() {
        echo('Available targets:');
        echo('  all         test and run');
        echo('  test        runs unit tests');
        echo('  functional  runs functional tests');
        echo('  suite       runs unit and functional tests');
        echo('  clean       cleanup working directory');
        echo('  run         runs for development mode');
        echo('  bootlint    run Bootlint locally');
        echo('  help        shows this help message');
    };

}());
<|endoftext|>


<commit_before>function factorial(n) {
    var result = 1;
    for(var i=1; i<=n; i++){
        result = result * i;
    }
    return result;
}

function combination(n, r) {
    if(!n || n<r || !r || n < 0 || r < 0) {
        throw new Error("GO AWAY, invalid values");
    }
    var num = factorial(n);
    var denom = factorial(r)*factorial(n-r);
    return num/denom;
}
<commit_msg>Added permutation function<commit_after>function factorial(n) {
    var result = 1;
    for(var i=1; i<=n; i++){
        result = result * i;
    }
    return result;
}

function permutation(n, r) {
    if(!n || n<r || !r || n < 0 || r < 0) {
        throw new Error("GO AWAY, invalid values");
    }
    var num = factorial(n);
    var denom = factorial(n-r);
    return num/denom;
}

function combination(n, r) {
    if(!n || n<r || !r || n < 0 || r < 0) {
        throw new Error("GO AWAY, invalid values");
    }
    var num = factorial(n);
    var denom = factorial(r)*factorial(n-r);
    return num/denom;
}
<|endoftext|>


<commit_before>/** @license MIT License (c) copyright B Cavalier & J Hann */

/**
 * meld
 * Aspect Oriented Programming for Javascript
 *
 * meld is part of the cujo.js family of libraries (http://cujojs.com/)
 *
 * Licensed under the MIT License at:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @version 1.1.0
 */
(function (define) {
define(function () {

	var ap, prepend, append, iterators, slice, isArray, defineProperty, freeze;

	freeze = Object.freeze || function (o) { return o; };

	ap      = Array.prototype;
	prepend = ap.unshift;
	append  = ap.push;
	slice   = ap.slice;

	isArray = Array.isArray || function(it) {
		return Object.prototype.toString.call(it) == '[object Array]';
	};

	defineProperty = Object.defineProperty || function(obj, prop, descriptor) {
		obj[prop] = descriptor.value;
	};

	iterators = {
		// Before uses reverse iteration
		before: forEachReverse,
		around: false
	};

	// All other advice types use forward iteration
	// Around is a special case that uses recursion rather than
	// iteration.  See Advisor._callAroundAdvice
	iterators.on
		= iterators.afterReturning
		= iterators.afterThrowing
		= iterators.after
		= forEach;

	function Advisor(target, func) {

		var orig, advisor, advised;

		this.target = target;
		this.func = func;
		this.aspects = {};

		orig = this.orig = target[func];
		advisor = this;

		advised = this.advised = function() {
			var context, args, callOrig, result, afterType, exception;

			// If called as a constructor (i.e. using "new"), create a context
			// of the correct type, so that all advice types (including before!)
			// are called with the correct context.
			// NOTE: Requires ES5 Object.create()
			if(this instanceof advised) {
				// shamelessly derived from https://github.com/cujojs/wire/blob/c7c55fe50238ecb4afbb35f902058ab6b32beb8f/lib/component.js#L25
				if (!Object.create) {
					throw new Error('An ES5 environment is required for advice on constructors');
				}

				context = Object.create(orig.prototype);
				callOrig = function (args) {
					return applyConstructor(orig, context, args);
				};

			} else {
				context = this;
				callOrig = function(args) {
					return orig.apply(context, args);
				};

			}

			args = slice.call(arguments);
			afterType = 'afterReturning';

			advisor._callSimpleAdvice('before', context, args);

			try {
				result = advisor._callAroundAdvice(context, func, args, callOrigAndOn);
			} catch(e) {
				result = exception = e;
				// Switch to afterThrowing
				afterType = 'afterThrowing';
			}

			args = [result];

			callAfter(afterType, args);
			callAfter('after', args);

			if(exception) {
				throw exception;
			}

			return result;

			function callOrigAndOn(args) {
				var result = callOrig(args);
				advisor._callSimpleAdvice('on', context, args);

				return result;
			}

			function callAfter(afterType, args) {
				advisor._callSimpleAdvice(afterType, context, args);
			}
		};

		defineProperty(advised, '_advisor', { value: advisor });
	}

	Advisor.prototype = {

		/**
		 * Invoke all advice functions in the supplied context, with the supplied args
		 *
		 * @param adviceType
		 * @param context
		 * @param args
		 */
		_callSimpleAdvice: function(adviceType, context, args) {

			// before advice runs LIFO, from most-recently added to least-recently added.
			// All other advice is FIFO
			var iterator, advices;

			advices = this.aspects[adviceType];
			if(!advices) {
				return;
			}

			iterator = iterators[adviceType];

			iterator(this.aspects[adviceType], function(aspect) {
				var advice = aspect.advice;
				advice && advice.apply(context, args);
			});
		},

		/**
		 * Invoke all around advice and then the original method
		 *
		 * @param context
		 * @param method
		 * @param args
		 * @param applyOriginal
		 */
		_callAroundAdvice: function (context, method, args, applyOriginal) {
			var len, aspects;

			aspects = this.aspects.around;
			len = aspects ? aspects.length : 0;

			/**
			 * Call the next function in the around chain, which will either be another around
			 * advice, or the orig method.
			 * @param i {Number} index of the around advice
			 * @param args {Array} arguments with with to call the next around advice
			 */
			function callNext(i, args) {
				// If we exhausted all aspects, finally call the original
				// Otherwise, if we found another around, call it
				return i < 0
					? applyOriginal(args)
					: callAround(aspects[i].advice, i, args);
			}

			function callAround(around, i, args) {
				var proceedCalled, joinpoint;

				proceedCalled = 0;

				// Joinpoint is immutable
				joinpoint = freeze({
					target: context,
					method: method,
					args: args,
					proceed: proceedCall,
					proceedApply: proceedApply,
					proceedCount: proceedCount
				});

				// Call supplied around advice function
				return around.call(context, joinpoint);

				/**
				 * The number of times proceed() has been called
				 * @return {Number}
				 */
				function proceedCount() {
					return proceedCalled;
				}

				/**
				 * Proceed to the original method/function or the next around
				 * advice using original arguments or new argument list if
				 * arguments.length > 0
				 * @return {*} result of original method/function or next around advice
				 */
				function proceedCall(/* newArg1, newArg2... */) {
					return proceed(arguments.length > 0 ? slice.call(arguments) : args);
				}

				/**
				 * Proceed to the original method/function or the next around
				 * advice using original arguments or new argument list if
				 * newArgs is supplied
				 * @param [newArgs] {Array} new arguments with which to proceed
				 * @return {*} result of original method/function or next around advice
				 */
				function proceedApply(newArgs) {
					return proceed(newArgs || args);
				}

				/**
				 * Create proceed function that calls the next around advice, or
				 * the original.  May be called multiple times, for example, in retry
				 * scenarios
				 * @param [args] {Array} optional arguments to use instead of the
				 * original arguments
				 */
				function proceed(args) {
					proceedCalled++;
					return callNext(i - 1, args);
				}

			}

			return callNext(len - 1, args);
		},

		/**
		 * Adds the supplied aspect to the advised target method
		 *
		 * @param aspect
		 */
		add: function(aspect) {

			var advisor, aspects;

			advisor = this;
			aspects = advisor.aspects;

			insertAspect(aspects, aspect);

			return {
				remove: function () {
					var remaining = removeAspect(aspects, aspect);

					// If there are no aspects left, restore the original method
					if (!remaining) {
						advisor.remove();
					}
				}
			};
		},

		/**
		 * Removes the Advisor and thus, all aspects from the advised target method, and
		 * restores the original target method, copying back all properties that may have
		 * been added or updated on the advised function.
		 */
		remove: function () {
			delete this.advised._advisor;
			this.target[this.func] = this.orig;
		}
	};

	/**
	 * Returns the advisor for the target object-function pair.  A new advisor
	 * will be created if one does not already exist.
	 * @param target {*} target containing a method with tthe supplied methodName
	 * @param methodName {String} name of method on target for which to get an advisor
	 * @return {Object} existing or newly created advisor for the supplied method
	 */
	Advisor.get = function(target, methodName) {
		if(!(methodName in target)) {
			return;
		}

		var advisor, advised;

		advised = target[methodName];

		if(typeof advised !== 'function') {
			throw new Error('Advice can only be applied to functions: ' + methodName);
		}

		advisor = advised._advisor;
		if(!advisor) {
			advisor = new Advisor(target, methodName);
			target[methodName] = advisor.advised;
		}

		return advisor;
	};

	//
	// Public API
	//

	return {
		// General add aspect
		// Returns a function that will remove the newly-added aspect
		add:            addAspect,

		// Add a single, specific type of advice
		// returns a function that will remove the newly-added advice
		before:         adviceApi('before'),
		around:         adviceApi('around'),
		on:             adviceApi('on'),
		afterReturning: adviceApi('afterReturning'),
		afterThrowing:  adviceApi('afterThrowing'),
		after:          adviceApi('after')
	};

	function addAspect(target, pointcut, aspect) {
		// pointcut can be: string, Array of strings, RegExp, Function(targetObject): Array of strings
		// advice can be: object, Function(targetObject, targetMethodName)

		var pointcutType, remove;

		if(arguments.length < 3) {
			return addAspectToFunction(target, pointcut);
		} else {
			if (isArray(pointcut)) {
				remove = addAspectToAll(target, pointcut, aspect);

			} else {
				pointcutType = typeof pointcut;

				if (pointcutType === 'string') {
					if (typeof target[pointcut] === 'function') {
						remove = addAspectToMethod(target, pointcut, aspect);
					}

				} else if (pointcutType === 'function') {
					remove = addAspectToAll(target, pointcut(target), aspect);

				} else {
					remove = addAspectToMatches(target, pointcut, aspect);
				}
			}

			return remove;
		}

	}

	/**
	 * Add an aspect to a pure function, returning an advised version of it.
	 * NOTE: *only the returned function* is advised.  The original (input) function
	 * is not modified in any way.
	 * @param func {Function} function to advise
	 * @param aspect {Object} aspect to add
	 * @return {Function} advised function
	 */
	function addAspectToFunction(func, aspect) {
		var name, placeholderTarget;

		name = func.name || '_';

		placeholderTarget = {};
		placeholderTarget[name] = func;

		addAspectToMethod(placeholderTarget, name, aspect);

		return placeholderTarget[name];

	}

	function addAspectToMethod(target, method, aspect) {
		var advisor = Advisor.get(target, method);

		return advisor && advisor.add(aspect);
	}

	function addAspectToAll(target, methodArray, aspect) {
		var removers, added, f, i;

		removers = [];
		i = 0;

		while((f = methodArray[i++])) {
			added = addAspectToMethod(target, f, aspect);
			added && removers.push(added);
		}

		return createRemover(removers);
	}

	function addAspectToMatches(target, pointcut, aspect) {
		var removers = [];
		// Assume the pointcut is a an object with a .test() method
		for (var p in target) {
			// TODO: Decide whether hasOwnProperty is correct here
			// Only apply to own properties that are functions, and match the pointcut regexp
			if (typeof target[p] == 'function' && pointcut.test(p)) {
				// if(object.hasOwnProperty(p) && typeof object[p] === 'function' && pointcut.test(p)) {
				removers.push(addAspectToMethod(target, p, aspect));
			}
		}

		return createRemover(removers);
	}

	function createRemover(removers) {
		return {
			remove: function() {
				for (var i = removers.length - 1; i >= 0; --i) {
					removers[i].remove();
				}
			}
		};
	}

	// Create an API function for the specified advice type
	function adviceApi(type) {
		return function(target, method, adviceFunc) {
			var aspect = {};

			if(arguments.length === 2) {
				aspect[type] = method;
				return addAspect(target, aspect);
			} else {
				aspect[type] = adviceFunc;
				return addAspect(target, method, aspect);
			}
		};
	}

	/**
	 * Insert the supplied aspect into aspectList
	 * @param aspectList {Object} list of aspects, categorized by advice type
	 * @param aspect {Object} aspect containing one or more supported advice types
	 */
	function insertAspect(aspectList, aspect) {
		var adviceType, advice, advices;

		for(adviceType in iterators) {
			advice = aspect[adviceType];

			if(advice) {
				advices = aspectList[adviceType];
				if(!advices) {
					aspectList[adviceType] = advices = [];
				}

				advices.push({
					aspect: aspect,
					advice: advice
				});
			}
		}
	}

	/**
	 * Remove the supplied aspect from aspectList
	 * @param aspectList {Object} list of aspects, categorized by advice type
	 * @param aspect {Object} aspect containing one or more supported advice types
	 * @return {Number} Number of *advices* left on the advised function.  If
	 *  this returns zero, then it is safe to remove the advisor completely.
	 */
	function removeAspect(aspectList, aspect) {
		var adviceType, advices, remaining;

		remaining = 0;

		for(adviceType in iterators) {
			advices = aspectList[adviceType];
			if(advices) {
				remaining += advices.length;

				for (var i = advices.length - 1; i >= 0; --i) {
					if (advices[i].aspect === aspect) {
						advices.splice(i, 1);
						--remaining;
						break;
					}
				}
			}
		}

		return remaining;
	}

	function applyConstructor(C, instance, args) {
		try {
			Object.defineProperty(instance, 'constructor', {
				value: C,
				enumerable: false
			});
		} catch(e) {
			// ignore
		}

		C.apply(instance, args);

		return instance;
	}

	function forEach(array, func) {
		for (var i = 0, len = array.length; i < len; i++) {
			func(array[i]);
		}
	}

	function forEachReverse(array, func) {
		for (var i = array.length - 1; i >= 0; --i) {
			func(array[i]);
		}
	}

});
})(typeof define == 'function' && define.amd
	? define
	: function (factory) { module.exports = factory(); }
	// Boilerplate for AMD and CommonJS
);
<commit_msg>Minor code reorg. Move public api to the top for clarity<commit_after>/** @license MIT License (c) copyright B Cavalier & J Hann */

/**
 * meld
 * Aspect Oriented Programming for Javascript
 *
 * meld is part of the cujo.js family of libraries (http://cujojs.com/)
 *
 * Licensed under the MIT License at:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @version 1.1.0
 */
(function (define) {
define(function () {

	var meld, ap, prepend, append, iterators, slice, isArray, defineProperty, freeze;

	//
	// Public API
	//

	meld = {
		// General add aspect
		// Returns a function that will remove the newly-added aspect
		add:            addAspect,

		// Add a single, specific type of advice
		// returns a function that will remove the newly-added advice
		before:         adviceApi('before'),
		around:         adviceApi('around'),
		on:             adviceApi('on'),
		afterReturning: adviceApi('afterReturning'),
		afterThrowing:  adviceApi('afterThrowing'),
		after:          adviceApi('after')
	};

	freeze = Object.freeze || function (o) { return o; };

	ap      = Array.prototype;
	prepend = ap.unshift;
	append  = ap.push;
	slice   = ap.slice;

	isArray = Array.isArray || function(it) {
		return Object.prototype.toString.call(it) == '[object Array]';
	};

	defineProperty = Object.defineProperty || function(obj, prop, descriptor) {
		obj[prop] = descriptor.value;
	};

	iterators = {
		// Before uses reverse iteration
		before: forEachReverse,
		around: false
	};

	// All other advice types use forward iteration
	// Around is a special case that uses recursion rather than
	// iteration.  See Advisor._callAroundAdvice
	iterators.on
		= iterators.afterReturning
		= iterators.afterThrowing
		= iterators.after
		= forEach;

	function Advisor(target, func) {

		var orig, advisor, advised;

		this.target = target;
		this.func = func;
		this.aspects = {};

		orig = this.orig = target[func];
		advisor = this;

		advised = this.advised = function() {
			var context, args, callOrig, result, afterType, exception;

			// If called as a constructor (i.e. using "new"), create a context
			// of the correct type, so that all advice types (including before!)
			// are called with the correct context.
			// NOTE: Requires ES5 Object.create()
			if(this instanceof advised) {
				// shamelessly derived from https://github.com/cujojs/wire/blob/c7c55fe50238ecb4afbb35f902058ab6b32beb8f/lib/component.js#L25
				if (!Object.create) {
					throw new Error('An ES5 environment is required for advice on constructors');
				}

				context = Object.create(orig.prototype);
				callOrig = function (args) {
					return applyConstructor(orig, context, args);
				};

			} else {
				context = this;
				callOrig = function(args) {
					return orig.apply(context, args);
				};

			}

			args = slice.call(arguments);
			afterType = 'afterReturning';

			advisor._callSimpleAdvice('before', context, args);

			try {
				result = advisor._callAroundAdvice(context, func, args, callOrigAndOn);
			} catch(e) {
				result = exception = e;
				// Switch to afterThrowing
				afterType = 'afterThrowing';
			}

			args = [result];

			callAfter(afterType, args);
			callAfter('after', args);

			if(exception) {
				throw exception;
			}

			return result;

			function callOrigAndOn(args) {
				var result = callOrig(args);
				advisor._callSimpleAdvice('on', context, args);

				return result;
			}

			function callAfter(afterType, args) {
				advisor._callSimpleAdvice(afterType, context, args);
			}
		};

		defineProperty(advised, '_advisor', { value: advisor });
	}

	Advisor.prototype = {

		/**
		 * Invoke all advice functions in the supplied context, with the supplied args
		 *
		 * @param adviceType
		 * @param context
		 * @param args
		 */
		_callSimpleAdvice: function(adviceType, context, args) {

			// before advice runs LIFO, from most-recently added to least-recently added.
			// All other advice is FIFO
			var iterator, advices;

			advices = this.aspects[adviceType];
			if(!advices) {
				return;
			}

			iterator = iterators[adviceType];

			iterator(this.aspects[adviceType], function(aspect) {
				var advice = aspect.advice;
				advice && advice.apply(context, args);
			});
		},

		/**
		 * Invoke all around advice and then the original method
		 *
		 * @param context
		 * @param method
		 * @param args
		 * @param applyOriginal
		 */
		_callAroundAdvice: function (context, method, args, applyOriginal) {
			var len, aspects;

			aspects = this.aspects.around;
			len = aspects ? aspects.length : 0;

			/**
			 * Call the next function in the around chain, which will either be another around
			 * advice, or the orig method.
			 * @param i {Number} index of the around advice
			 * @param args {Array} arguments with with to call the next around advice
			 */
			function callNext(i, args) {
				// If we exhausted all aspects, finally call the original
				// Otherwise, if we found another around, call it
				return i < 0
					? applyOriginal(args)
					: callAround(aspects[i].advice, i, args);
			}

			function callAround(around, i, args) {
				var proceedCalled, joinpoint;

				proceedCalled = 0;

				// Joinpoint is immutable
				joinpoint = freeze({
					target: context,
					method: method,
					args: args,
					proceed: proceedCall,
					proceedApply: proceedApply,
					proceedCount: proceedCount
				});

				// Call supplied around advice function
				return around.call(context, joinpoint);

				/**
				 * The number of times proceed() has been called
				 * @return {Number}
				 */
				function proceedCount() {
					return proceedCalled;
				}

				/**
				 * Proceed to the original method/function or the next around
				 * advice using original arguments or new argument list if
				 * arguments.length > 0
				 * @return {*} result of original method/function or next around advice
				 */
				function proceedCall(/* newArg1, newArg2... */) {
					return proceed(arguments.length > 0 ? slice.call(arguments) : args);
				}

				/**
				 * Proceed to the original method/function or the next around
				 * advice using original arguments or new argument list if
				 * newArgs is supplied
				 * @param [newArgs] {Array} new arguments with which to proceed
				 * @return {*} result of original method/function or next around advice
				 */
				function proceedApply(newArgs) {
					return proceed(newArgs || args);
				}

				/**
				 * Create proceed function that calls the next around advice, or
				 * the original.  May be called multiple times, for example, in retry
				 * scenarios
				 * @param [args] {Array} optional arguments to use instead of the
				 * original arguments
				 */
				function proceed(args) {
					proceedCalled++;
					return callNext(i - 1, args);
				}

			}

			return callNext(len - 1, args);
		},

		/**
		 * Adds the supplied aspect to the advised target method
		 *
		 * @param aspect
		 */
		add: function(aspect) {

			var advisor, aspects;

			advisor = this;
			aspects = advisor.aspects;

			insertAspect(aspects, aspect);

			return {
				remove: function () {
					var remaining = removeAspect(aspects, aspect);

					// If there are no aspects left, restore the original method
					if (!remaining) {
						advisor.remove();
					}
				}
			};
		},

		/**
		 * Removes the Advisor and thus, all aspects from the advised target method, and
		 * restores the original target method, copying back all properties that may have
		 * been added or updated on the advised function.
		 */
		remove: function () {
			delete this.advised._advisor;
			this.target[this.func] = this.orig;
		}
	};

	/**
	 * Returns the advisor for the target object-function pair.  A new advisor
	 * will be created if one does not already exist.
	 * @param target {*} target containing a method with tthe supplied methodName
	 * @param methodName {String} name of method on target for which to get an advisor
	 * @return {Object} existing or newly created advisor for the supplied method
	 */
	Advisor.get = function(target, methodName) {
		if(!(methodName in target)) {
			return;
		}

		var advisor, advised;

		advised = target[methodName];

		if(typeof advised !== 'function') {
			throw new Error('Advice can only be applied to functions: ' + methodName);
		}

		advisor = advised._advisor;
		if(!advisor) {
			advisor = new Advisor(target, methodName);
			target[methodName] = advisor.advised;
		}

		return advisor;
	};

	function addAspect(target, pointcut, aspect) {
		// pointcut can be: string, Array of strings, RegExp, Function(targetObject): Array of strings
		// advice can be: object, Function(targetObject, targetMethodName)

		var pointcutType, remove;

		if(arguments.length < 3) {
			return addAspectToFunction(target, pointcut);
		} else {
			if (isArray(pointcut)) {
				remove = addAspectToAll(target, pointcut, aspect);

			} else {
				pointcutType = typeof pointcut;

				if (pointcutType === 'string') {
					if (typeof target[pointcut] === 'function') {
						remove = addAspectToMethod(target, pointcut, aspect);
					}

				} else if (pointcutType === 'function') {
					remove = addAspectToAll(target, pointcut(target), aspect);

				} else {
					remove = addAspectToMatches(target, pointcut, aspect);
				}
			}

			return remove;
		}

	}

	/**
	 * Add an aspect to a pure function, returning an advised version of it.
	 * NOTE: *only the returned function* is advised.  The original (input) function
	 * is not modified in any way.
	 * @param func {Function} function to advise
	 * @param aspect {Object} aspect to add
	 * @return {Function} advised function
	 */
	function addAspectToFunction(func, aspect) {
		var name, placeholderTarget;

		name = func.name || '_';

		placeholderTarget = {};
		placeholderTarget[name] = func;

		addAspectToMethod(placeholderTarget, name, aspect);

		return placeholderTarget[name];

	}

	function addAspectToMethod(target, method, aspect) {
		var advisor = Advisor.get(target, method);

		return advisor && advisor.add(aspect);
	}

	function addAspectToAll(target, methodArray, aspect) {
		var removers, added, f, i;

		removers = [];
		i = 0;

		while((f = methodArray[i++])) {
			added = addAspectToMethod(target, f, aspect);
			added && removers.push(added);
		}

		return createRemover(removers);
	}

	function addAspectToMatches(target, pointcut, aspect) {
		var removers = [];
		// Assume the pointcut is a an object with a .test() method
		for (var p in target) {
			// TODO: Decide whether hasOwnProperty is correct here
			// Only apply to own properties that are functions, and match the pointcut regexp
			if (typeof target[p] == 'function' && pointcut.test(p)) {
				// if(object.hasOwnProperty(p) && typeof object[p] === 'function' && pointcut.test(p)) {
				removers.push(addAspectToMethod(target, p, aspect));
			}
		}

		return createRemover(removers);
	}

	function createRemover(removers) {
		return {
			remove: function() {
				for (var i = removers.length - 1; i >= 0; --i) {
					removers[i].remove();
				}
			}
		};
	}

	// Create an API function for the specified advice type
	function adviceApi(type) {
		return function(target, method, adviceFunc) {
			var aspect = {};

			if(arguments.length === 2) {
				aspect[type] = method;
				return addAspect(target, aspect);
			} else {
				aspect[type] = adviceFunc;
				return addAspect(target, method, aspect);
			}
		};
	}

	/**
	 * Insert the supplied aspect into aspectList
	 * @param aspectList {Object} list of aspects, categorized by advice type
	 * @param aspect {Object} aspect containing one or more supported advice types
	 */
	function insertAspect(aspectList, aspect) {
		var adviceType, advice, advices;

		for(adviceType in iterators) {
			advice = aspect[adviceType];

			if(advice) {
				advices = aspectList[adviceType];
				if(!advices) {
					aspectList[adviceType] = advices = [];
				}

				advices.push({
					aspect: aspect,
					advice: advice
				});
			}
		}
	}

	/**
	 * Remove the supplied aspect from aspectList
	 * @param aspectList {Object} list of aspects, categorized by advice type
	 * @param aspect {Object} aspect containing one or more supported advice types
	 * @return {Number} Number of *advices* left on the advised function.  If
	 *  this returns zero, then it is safe to remove the advisor completely.
	 */
	function removeAspect(aspectList, aspect) {
		var adviceType, advices, remaining;

		remaining = 0;

		for(adviceType in iterators) {
			advices = aspectList[adviceType];
			if(advices) {
				remaining += advices.length;

				for (var i = advices.length - 1; i >= 0; --i) {
					if (advices[i].aspect === aspect) {
						advices.splice(i, 1);
						--remaining;
						break;
					}
				}
			}
		}

		return remaining;
	}

	function applyConstructor(C, instance, args) {
		try {
			// Try to define a constructor, but don't care if it fails
			defineProperty(instance, 'constructor', {
				value: C,
				enumerable: false
			});
		} catch(e) {
			// ignore
		}

		C.apply(instance, args);

		return instance;
	}

	function forEach(array, func) {
		for (var i = 0, len = array.length; i < len; i++) {
			func(array[i]);
		}
	}

	function forEachReverse(array, func) {
		for (var i = array.length - 1; i >= 0; --i) {
			func(array[i]);
		}
	}

	return meld;

});
})(typeof define == 'function' && define.amd
	? define
	: function (factory) { module.exports = factory(); }
	// Boilerplate for AMD and CommonJS
);
<|endoftext|>


<commit_before>'use strict';
const os = require('os');
const path = require('path');
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const shell = electron.shell;
const appName = app.getName();

function sendAction(action, data) {
	const win = BrowserWindow.getAllWindows()[0];

	if (process.platform === 'darwin') {
		win.restore();
	}

	win.webContents.send(action, data);
}

const viewSubmenu = [
	{
		label: 'Reset Text Size',
		accelerator: 'CmdOrCtrl+0',
		click() {
			sendAction('zoom-reset');
		}
	},
	{
		label: 'Increase Text Size',
		accelerator: 'CmdOrCtrl+Plus',
		click() {
			sendAction('zoom-in');
		}
	},
	{
		label: 'Decrease Text Size',
		accelerator: 'CmdOrCtrl+-',
		click() {
			sendAction('zoom-out');
		}
	}
];

const helpSubmenu = [
	{
		label: `${appName} Website`,
		click() {
			shell.openExternal('https://github.com/sindresorhus/anatine');
		}
	},
	{
		label: 'Report an Issue...',
		click() {
			const body = `
<!-- Please succinctly describe your issue and steps to reproduce it. -->

-

${app.getName()} ${app.getVersion()}
Electron ${process.versions.electron}
${process.platform} ${process.arch} ${os.release()}`;

			shell.openExternal(`https://github.com/sindresorhus/anatine/issues/new?body=${encodeURIComponent(body)}`);
		}
	}
];

if (process.platform !== 'darwin') {
	helpSubmenu.push({
		type: 'separator'
	}, {
		label: process.platform === 'linux' ? 'About' : `About ${appName}`,
		click() {
			electron.dialog.showMessageBox({
				title: `About ${appName}`,
				message: `${appName} ${app.getVersion()}`,
				detail: 'Created by Sindre Sorhus',
				icon: path.join(__dirname, 'static/Icon.png'),
				buttons: []
			});
		}
	});
}

const darwinTpl = [
	{
		label: appName,
		submenu: [
			{
				label: `About ${appName}`,
				role: 'about'
			},
			{
				type: 'separator'
			},
			{
				label: 'Toggle Dark Mode',
				accelerator: 'Cmd+Shift+D',
				click() {
					sendAction('toggle-dark-mode');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Log Out',
				click() {
					sendAction('log-out');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Services',
				role: 'services',
				submenu: []
			},
			{
				type: 'separator'
			},
			{
				label: `Hide ${appName}`,
				accelerator: 'Cmd+H',
				role: 'hide'
			},
			{
				label: 'Hide Others',
				accelerator: 'Cmd+Shift+H',
				role: 'hideothers'
			},
			{
				label: 'Show All',
				role: 'unhide'
			},
			{
				type: 'separator'
			},
			{
				label: `Quit ${appName}`,
				accelerator: 'Cmd+Q',
				click() {
					app.quit();
				}
			}
		]
	},
	{
		label: 'File',
		submenu: [
			{
				label: 'New Tweet...',
				accelerator: 'Cmd+N',
				click() {
					sendAction('new-tweet');
				}
			},
			{
				label: 'New Direct Message...',
				accelerator: 'Shift+Cmd+N',
				click() {
					sendAction('new-dm');
				}
			}
		]
	},
	{
		label: 'Edit',
		submenu: [
			{
				label: 'Undo',
				accelerator: 'Cmd+Z',
				role: 'undo'
			},
			{
				label: 'Redo',
				accelerator: 'Shift+Cmd+Z',
				role: 'redo'
			},
			{
				type: 'separator'
			},
			{
				label: 'Cut',
				accelerator: 'Cmd+X',
				role: 'cut'
			},
			{
				label: 'Copy',
				accelerator: 'Cmd+C',
				role: 'copy'
			},
			{
				label: 'Paste',
				accelerator: 'Cmd+V',
				role: 'paste'
			},
			// TODO: https://github.com/electron/electron/issues/5866
			{
				label: 'Paste and Match Style',
				accelerator: 'Shift+Cmd+V',
				click(el, win) {
					win.webContents.pasteAndMatchStyle();
				}
			},
			// TODO: https://github.com/electron/electron/issues/5867
			{
				label: 'Delete',
				click(el, win) {
					win.webContents.delete();
				}
			},
			{
				label: 'Select All',
				accelerator: 'Cmd+A',
				role: 'selectall'
			}
		]
	},
	{
		label: 'View',
		submenu: viewSubmenu
	},
	{
		label: 'Window',
		role: 'window',
		submenu: [
			{
				label: 'Minimize',
				accelerator: 'Cmd+M',
				role: 'minimize'
			},
			{
				label: 'Close',
				accelerator: 'Cmd+W',
				role: 'close'
			},
			{
				type: 'separator'
			},
			{
				label: 'Next Tab',
				accelerator: 'Ctrl+Tab',
				click() {
					sendAction('next-tab');
				}
			},
			{
				label: 'Previous Tab',
				accelerator: 'Ctrl+Shift+Tab',
				click() {
					sendAction('previous-tab');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Bring All to Front',
				role: 'front'
			},

			// temp workaround for:
			// https://github.com/sindresorhus/caprine/issues/5
			{
				label: 'Toggle Full Screen',
				accelerator: 'Ctrl+Cmd+F',
				click(el, win) {
					win.setFullScreen(!win.isFullScreen());
				}
			}
		]
	},
	{
		label: 'Help',
		role: 'help',
		submenu: helpSubmenu
	}
];

const otherTpl = [
	{
		label: 'File',
		submenu: [
			{
				label: 'New Tweet...',
				accelerator: 'Ctrl+N',
				click() {
					sendAction('new-tweet');
				}
			},
			{
				label: 'New Direct Message...',
				accelerator: 'Shift+Ctrl+N',
				click() {
					sendAction('new-dm');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Next Tab',
				accelerator: 'Ctrl+Tab',
				click() {
					sendAction('next-tab');
				}
			},
			{
				label: 'Previous Tab',
				accelerator: 'Ctrl+Shift+Tab',
				click() {
					sendAction('previous-tab');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Toggle Dark Mode',
				accelerator: 'Ctrl+Shift+D',
				click() {
					sendAction('toggle-dark-mode');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Log Out',
				click() {
					sendAction('log-out');
				}
			},
			{
				label: process.platform === 'linux' ? 'Quit' : 'Exit',
				click() {
					app.quit();
				}
			}
		]
	},
	{
		label: 'Edit',
		submenu: [
			{
				label: 'Undo',
				accelerator: 'Ctrl+Z',
				role: 'undo'
			},
			{
				label: 'Redo',
				accelerator: 'Shift+Ctrl+Z',
				role: 'redo'
			},
			{
				type: 'separator'
			},
			{
				label: 'Cut',
				accelerator: 'Ctrl+X',
				role: 'cut'
			},
			{
				label: 'Copy',
				accelerator: 'Ctrl+C',
				role: 'copy'
			},
			{
				label: 'Paste',
				accelerator: 'Ctrl+V',
				role: 'paste'
			},
			// TODO: https://github.com/electron/electron/issues/5866
			{
				label: 'Paste and Match Style',
				accelerator: 'Shift+Ctrl+V',
				click(el, win) {
					win.webContents.pasteAndMatchStyle();
				}
			},
			// TODO: https://github.com/electron/electron/issues/5867
			{
				label: 'Delete',
				accelerator: 'Delete',
				click(el, win) {
					win.webContents.delete();
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Select All',
				accelerator: 'Ctrl+A',
				role: 'selectall'
			}
		]
	},
	{
		label: 'View',
		submenu: viewSubmenu
	},
	{
		label: 'Help',
		role: 'help',
		submenu: helpSubmenu
	}
];

const tpl = process.platform === 'darwin' ? darwinTpl : otherTpl;

module.exports = electron.Menu.buildFromTemplate(tpl);
<commit_msg>use new MenuItem roles<commit_after>'use strict';
const os = require('os');
const path = require('path');
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const shell = electron.shell;
const appName = app.getName();

function sendAction(action, data) {
	const win = BrowserWindow.getAllWindows()[0];

	if (process.platform === 'darwin') {
		win.restore();
	}

	win.webContents.send(action, data);
}

const viewSubmenu = [
	{
		label: 'Reset Text Size',
		accelerator: 'CmdOrCtrl+0',
		click() {
			sendAction('zoom-reset');
		}
	},
	{
		label: 'Increase Text Size',
		accelerator: 'CmdOrCtrl+Plus',
		click() {
			sendAction('zoom-in');
		}
	},
	{
		label: 'Decrease Text Size',
		accelerator: 'CmdOrCtrl+-',
		click() {
			sendAction('zoom-out');
		}
	}
];

const helpSubmenu = [
	{
		label: `${appName} Website`,
		click() {
			shell.openExternal('https://github.com/sindresorhus/anatine');
		}
	},
	{
		label: 'Report an Issue...',
		click() {
			const body = `
<!-- Please succinctly describe your issue and steps to reproduce it. -->

-

${app.getName()} ${app.getVersion()}
Electron ${process.versions.electron}
${process.platform} ${process.arch} ${os.release()}`;

			shell.openExternal(`https://github.com/sindresorhus/anatine/issues/new?body=${encodeURIComponent(body)}`);
		}
	}
];

if (process.platform !== 'darwin') {
	helpSubmenu.push({
		type: 'separator'
	}, {
		label: process.platform === 'linux' ? 'About' : `About ${appName}`,
		click() {
			electron.dialog.showMessageBox({
				title: `About ${appName}`,
				message: `${appName} ${app.getVersion()}`,
				detail: 'Created by Sindre Sorhus',
				icon: path.join(__dirname, 'static/Icon.png'),
				buttons: []
			});
		}
	});
}

const darwinTpl = [
	{
		label: appName,
		submenu: [
			{
				label: `About ${appName}`,
				role: 'about'
			},
			{
				type: 'separator'
			},
			{
				label: 'Toggle Dark Mode',
				accelerator: 'Cmd+Shift+D',
				click() {
					sendAction('toggle-dark-mode');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Log Out',
				click() {
					sendAction('log-out');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Services',
				role: 'services',
				submenu: []
			},
			{
				type: 'separator'
			},
			{
				label: `Hide ${appName}`,
				accelerator: 'Cmd+H',
				role: 'hide'
			},
			{
				label: 'Hide Others',
				accelerator: 'Cmd+Shift+H',
				role: 'hideothers'
			},
			{
				label: 'Show All',
				role: 'unhide'
			},
			{
				type: 'separator'
			},
			{
				label: `Quit ${appName}`,
				accelerator: 'Cmd+Q',
				click() {
					app.quit();
				}
			}
		]
	},
	{
		label: 'File',
		submenu: [
			{
				label: 'New Tweet...',
				accelerator: 'Cmd+N',
				click() {
					sendAction('new-tweet');
				}
			},
			{
				label: 'New Direct Message...',
				accelerator: 'Shift+Cmd+N',
				click() {
					sendAction('new-dm');
				}
			}
		]
	},
	{
		label: 'Edit',
		submenu: [
			{
				label: 'Undo',
				accelerator: 'Cmd+Z',
				role: 'undo'
			},
			{
				label: 'Redo',
				accelerator: 'Shift+Cmd+Z',
				role: 'redo'
			},
			{
				type: 'separator'
			},
			{
				label: 'Cut',
				accelerator: 'Cmd+X',
				role: 'cut'
			},
			{
				label: 'Copy',
				accelerator: 'Cmd+C',
				role: 'copy'
			},
			{
				label: 'Paste',
				accelerator: 'Cmd+V',
				role: 'paste'
			},
			{
				label: 'Paste and Match Style',
				accelerator: 'Shift+Cmd+V',
				role: 'pasteandmatchstyle'
			},
			{
				label: 'Delete',
				role: 'delete'
			},
			{
				label: 'Select All',
				accelerator: 'Cmd+A',
				role: 'selectall'
			}
		]
	},
	{
		label: 'View',
		submenu: viewSubmenu
	},
	{
		label: 'Window',
		role: 'window',
		submenu: [
			{
				label: 'Minimize',
				accelerator: 'Cmd+M',
				role: 'minimize'
			},
			{
				label: 'Close',
				accelerator: 'Cmd+W',
				role: 'close'
			},
			{
				type: 'separator'
			},
			{
				label: 'Next Tab',
				accelerator: 'Ctrl+Tab',
				click() {
					sendAction('next-tab');
				}
			},
			{
				label: 'Previous Tab',
				accelerator: 'Ctrl+Shift+Tab',
				click() {
					sendAction('previous-tab');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Bring All to Front',
				role: 'front'
			},

			// temp workaround for:
			// https://github.com/sindresorhus/caprine/issues/5
			{
				label: 'Toggle Full Screen',
				accelerator: 'Ctrl+Cmd+F',
				click(el, win) {
					win.setFullScreen(!win.isFullScreen());
				}
			}
		]
	},
	{
		label: 'Help',
		role: 'help',
		submenu: helpSubmenu
	}
];

const otherTpl = [
	{
		label: 'File',
		submenu: [
			{
				label: 'New Tweet...',
				accelerator: 'Ctrl+N',
				click() {
					sendAction('new-tweet');
				}
			},
			{
				label: 'New Direct Message...',
				accelerator: 'Shift+Ctrl+N',
				click() {
					sendAction('new-dm');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Next Tab',
				accelerator: 'Ctrl+Tab',
				click() {
					sendAction('next-tab');
				}
			},
			{
				label: 'Previous Tab',
				accelerator: 'Ctrl+Shift+Tab',
				click() {
					sendAction('previous-tab');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Toggle Dark Mode',
				accelerator: 'Ctrl+Shift+D',
				click() {
					sendAction('toggle-dark-mode');
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Log Out',
				click() {
					sendAction('log-out');
				}
			},
			{
				label: process.platform === 'linux' ? 'Quit' : 'Exit',
				click() {
					app.quit();
				}
			}
		]
	},
	{
		label: 'Edit',
		submenu: [
			{
				label: 'Undo',
				accelerator: 'Ctrl+Z',
				role: 'undo'
			},
			{
				label: 'Redo',
				accelerator: 'Shift+Ctrl+Z',
				role: 'redo'
			},
			{
				type: 'separator'
			},
			{
				label: 'Cut',
				accelerator: 'Ctrl+X',
				role: 'cut'
			},
			{
				label: 'Copy',
				accelerator: 'Ctrl+C',
				role: 'copy'
			},
			{
				label: 'Paste',
				accelerator: 'Ctrl+V',
				role: 'paste'
			},
			{
				label: 'Paste and Match Style',
				accelerator: 'Shift+Ctrl+V',
				role: 'pasteandmatchstyle'
			},
			{
				label: 'Delete',
				accelerator: 'Delete',
				role: 'delete'
			},
			{
				type: 'separator'
			},
			{
				label: 'Select All',
				accelerator: 'Ctrl+A',
				role: 'selectall'
			}
		]
	},
	{
		label: 'View',
		submenu: viewSubmenu
	},
	{
		label: 'Help',
		role: 'help',
		submenu: helpSubmenu
	}
];

const tpl = process.platform === 'darwin' ? darwinTpl : otherTpl;

module.exports = electron.Menu.buildFromTemplate(tpl);
<|endoftext|>


<commit_before>(function() {
	"use strict";
	var btn1 = new Object();
	var btn2 = new Object();

	btn1.title = "Dit klopt niet";
	btn2.title = "Ja, hartstikke nep";
	var opt = {
		type: "basic",
		title: "Deze website brengt mogelijk fake news!",
		message: "Volgens onze gegevens brengt deze website mogelijk fake news.",
		iconUrl: "logo128_fake.png",
		buttons: [btn1, btn2]
	};

	function btnClick(notid, btninx) {
		if (btninx === 0) {
			window.open("https://twitter.com/intent/tweet?text=%40fdebijl%20Hey,%20de%20pagina%20op%20LINKHIER%20is%20geen%20fake%20news%20:D","_blank");
		} else {
			chrome.notifications.clear(notid);
		}
	}

	chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
		if (request.type === "notu") {
			chrome.notifications.create('thisisfakenews', opt, null)
			chrome.notifications.onButtonClicked.addListener(btnClick);
			sendResponse();
		}
	});

})();<commit_msg>Correctielink verwijst nu naar Github ipv Twitter<commit_after>(function() {
	"use strict";
	var btn1 = new Object();
	var btn2 = new Object();

	btn1.title = "Dit klopt niet";
	btn2.title = "Ja, hartstikke nep";
	var opt = {
		type: "basic",
		title: "Fake News",
		message: "Volgens onze gegevens brengt deze website mogelijk fake news. ",
		iconUrl: "logo128_fake.png",
		buttons: [btn1, btn2]
	};

	function btnClick(notid, btninx) {
		if (btninx === 0) {
			window.open("https://github.com/Fdebijl/FakeNewsBlocker/issues");
			chrome.notifications.clear(notid);
		} else {
			chrome.notifications.clear(notid);
		}
	}

	chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
		if (request.type === "notu") {
			chrome.notifications.create('thisisfakenews', opt, null)
			chrome.notifications.onButtonClicked.addListener(btnClick);
			sendResponse();
		}
	});

})();<|endoftext|>


<commit_before>"use strict";

var fs = require("fs");
var sys = require("sys");

exports.init = function() {
    var lookup = {};
    fs.readFile("mime.types", "ascii", function(err, data) {
        if (err) throw err;
        var lines = data.split("\n");
        lines.forEach(function(line) {
            if (!line.match(/^#/)) {
                var item = line.match(/^(.*?)[\s]+(.*?)$/);
                if (item) {
                    var type = item[1];
                    item[2].split(" ").forEach(function(extension) {
                        lookup[extension] = type;
                    });
                }
            }
        });
        sys.log("Mime types loaded");
    });
    return {
        type: function(extension) {
            if (lookup[extension]) {
                return lookup[extension];
            } else {
                return "application/octet-stream";
            }
        }
    }
};
<commit_msg>Making sure mime types are loaded before server starts listening<commit_after>"use strict";

var fs = require("fs");
var sys = require("sys");

exports.init = function() {
    var lookup = {};
    var data = fs.readFileSync("mime.types", "ascii");
    var lines = data.split("\n");
    lines.forEach(function(line) {
        if (!line.match(/^#/)) {
            var item = line.match(/^(.*?)[\s]+(.*?)$/);
            if (item) {
                var type = item[1];
                item[2].split(" ").forEach(function(extension) {
                    lookup[extension] = type;
                });
            }
        }
    });
    sys.log("Mime types loaded");
    return {
        type: function(extension) {
            if (lookup[extension]) {
                return lookup[extension];
            } else {
                return "application/octet-stream";
            }
        }
    }
};
<|endoftext|>


<commit_before>/**
 * This file (misc.js) contains miscellaneous methods, usually entirely self-contained
 * They are put here since they do not require their own specific file for readability
 */

let config = require('./config');
let request = require('request-promise');

/**
 *  @param {message} message  A message object as defined in discord.js
 *  @param {string[]} cmds
 */
 function urbanDefine(message, cmds) {
   let term = cmds.slice(1).join('+');

   let options = {
     uri: config.urban_url + term,
     json: true
   };

   request(options)
      .then(function (body) {
        if (body.result_type == "no_results") {
          console.log('No results for ' + term);
          message.channel.sendMessage("There are no results for: " + term.replace('+', ' '));
        } else {
          let firstDef = body.list[0];
          message.channel.sendMessage('**' + cmds.slice(1).join(' ') + ':**\n' + firstDef.definition + '\n' + firstDef.example);
        }
      }).catch(function (err) {
        console.log('Error accessing Urban Dictionary\'s API:\n' + err);
        message.channel.sendMessage("Error accessing Urban Dictionary");
      });
 }

/**
 * @param {message} message A message object as defined in discord.js
 * @param {string} user A string representation of the user either as an id or username
 */
 function getAvatar(message, user) {
   console.log("Looking for: " + user)
   let memberName = user.toLowerCase();
   let avatarURL = '';

   if (memberName.charAt(1) == '@') {
     let obj = message.guild.members.get(memberName.substring(2, memberName.length - 1));
     if (typeof obj !== 'undefined') {
      avatarURL = obj.user.displayAvatarURL;
      console.log("Found " + obj.displayName + "'s avatar at " + avatarURL);
     }
   } else {
     for (var [id, memberObj] of message.guild.members) {
       let displayName = memberObj.displayName.toLowerCase();
       let username = memberObj.user.username.toLowerCase();

       if (displayName == memberName || username == memberName) {
        avatarURL = memberObj.user.displayAvatarURL;
        console.log("Found " + memberObj.displayName + "'s avatar at " + avatarURL);
        break;
       }
     }
   }

   if (avatarURL) {
     avatarURL = avatarURL.replace('jpg', 'png');
     message.channel.sendMessage(avatarURL);
   } else {
     console.log("Could not find member " + user);
     message.channel.sendMessage("I couldn't find that member!");
   }
 }

 /**
  *  @param {message} message  A message object as defined in discord.js
  *  @param {string[]} cmds Strings that need to be joined and rated
  * Consider replacing the random function with another thing, maybe tied to stocks or time
  */
 function rate(message, cmds) {
   let str = message.content.split(' ').slice(1).join(' ');
   let rating = rateAlgorithm(str);

   if (str.toLowerCase() == 'staed') {
     message.channel.sendMessage("Staeds are great! I'll give Staed a 10/10!");
     console.log('Rated a Staed');
   } else if (str.toLowerCase() == 'sawai') {
     message.channel.sendMessage("Sawais are :put_litter_in_its_place: I'll give Sawai a 0/10");
     console.log('Rated a Sawai');
   } else {
     console.log('Rated ' + str + ' as ' + rating + '/10');
     message.channel.sendMessage("I'd rate " + str + ' ' + rating + '/10');
   }
 }

/**
 * @param {string} text A string containing the thing to be rated
 * @return {int} A number between 1 and 10 inclusive
 */
 function rateAlgorithm(text) {
   return Math.floor(Math.random() * 10 + 1);
 }

 module.exports = {urbanDefine, getAvatar, rate};
<commit_msg>Fixed possible UnhandledPromiseRejection errors<commit_after>/**
 * This file (misc.js) contains miscellaneous methods, usually entirely self-contained
 * They are put here since they do not require their own specific file for readability
 */

let config = require('./config');
let request = require('request-promise');

/**
 *  @param {message} message  A message object as defined in discord.js
 *  @param {string[]} cmds
 */
 function urbanDefine(message, cmds) {
   let term = cmds.slice(1).join('+');

   let options = {
     uri: config.urban_url + term,
     json: true
   };

   request(options)
      .then(function (body) {
        if (body.result_type == "no_results") {
          console.log('No results for ' + term);
          message.channel.send("There are no results for: " + term.replace('+', ' '))
            .catch( reason => { console.log("Rejected Urban Null Promise for " + reason); });
        } else {
          let firstDef = body.list[0];
          message.channel.send('**' + cmds.slice(1).join(' ') + ':**\n' + firstDef.definition + '\n' + firstDef.example)
            .catch( reason => { console.log("Rejected Urban Definition Promise for " + reason); });
        }
      }).catch(function (err) {
        console.log('Error accessing Urban Dictionary\'s API:\n' + err);
        message.channel.send("Error accessing Urban Dictionary")
          .catch( reason => { console.log("Rejected Urban Reject Promise for " + reason); });
      });
 }

/**
 * @param {message} message A message object as defined in discord.js
 * @param {string} user A string representation of the user either as an id or username
 */
 function getAvatar(message, user) {
   console.log("Looking for: " + user)
   let memberName = user.toLowerCase();
   let avatarURL = '';

   if (memberName.charAt(1) == '@') {
     let obj = message.guild.members.get(memberName.substring(2, memberName.length - 1));
     if (typeof obj !== 'undefined') {
      avatarURL = obj.user.displayAvatarURL;
      console.log("Found " + obj.displayName + "'s avatar at " + avatarURL);
     }
   } else {
     for (var [id, memberObj] of message.guild.members) {
       let displayName = memberObj.displayName.toLowerCase();
       let username = memberObj.user.username.toLowerCase();

       if (displayName == memberName || username == memberName) {
        avatarURL = memberObj.user.displayAvatarURL;
        console.log("Found " + memberObj.displayName + "'s avatar at " + avatarURL);
        break;
       }
     }
   }

   if (avatarURL) {
     avatarURL = avatarURL.replace('jpg', 'png');
     message.channel.send(avatarURL)
      .catch( reason => { console.log("Rejected Avatar Result for " + reason); });
   } else {
     console.log("Could not find member " + user);
     message.channel.send("I couldn't find that member!")
      .catch( reason => { console.log("Rejected Avatar Null Promise for " + reason); });
   }
 }

 /**
  *  @param {message} message  A message object as defined in discord.js
  *  @param {string[]} cmds Strings that need to be joined and rated
  * Consider replacing the random function with another thing, maybe tied to stocks or time
  */
 function rate(message, cmds) {
   let str = message.content.split(' ').slice(1).join(' ');
   let rating = rateAlgorithm(str);

   if (str.toLowerCase() == 'staed') {
     message.channel.send("Staeds are great! I'll give Staed a 10/10!")
      .catch( reason => { console.log("Rejected Rate Staed Promise for " + reason); });
     console.log('Rated a Staed');
   } else if (str.toLowerCase() == 'sawai') {
     message.channel.send("Sawais are :put_litter_in_its_place: I'll give Sawai a 0/10")
      .catch( reason => { console.log("Rejected Rate Sawai Promise for " + reason); });
     console.log('Rated a Sawai');
   } else {
     console.log('Rated ' + str + ' as ' + rating + '/10');
     message.channel.send("I'd rate " + str + ' ' + rating + '/10')
      .catch( reason => { console.log("Rejected Rate Response Promise for " + reason); });
   }
 }

/**
 * @param {string} text A string containing the thing to be rated
 * @return {int} A number between 1 and 10 inclusive
 */
 function rateAlgorithm(text) {
   return Math.floor(Math.random() * 10 + 1);
 }

 module.exports = {urbanDefine, getAvatar, rate};
<|endoftext|>


<commit_before>alert("hello from javascript") ;<commit_msg>README.md update<commit_after>alert("hello from javascript");<|endoftext|>