<commit_before>/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// @ts-check

const child_process = require('child_process');
const path = require('path');
const chokidar = require('chokidar');
const fs = require('fs');
const { workspace } = require('../workspace');

/**
 * @typedef {{
 *   command: string,
 *   args: string[],
 *   shell: boolean,
 *   env?: NodeJS.ProcessEnv,
 *   cwd?: string,
 * }} Step
 */

/**
 * @typedef {{
 *   files: string,
 *   from: string,
 *   to: string,
 *   ignored?: string[],
 * }} CopyFile
 */

/**
 * @typedef {{
 *   committed: boolean,
 *   inputs: string[],
 *   mustExist?: string[],
 *   script: string,
 * }} OnChange
 */

/** @type {Step[]} */
const steps = [];
/** @type {OnChange[]} */
const onChanges = [];
/** @type {CopyFile[]} */
const copyFiles = [];

const watchMode = process.argv.slice(2).includes('--watch');
const lintMode = process.argv.slice(2).includes('--lint');
const ROOT = path.join(__dirname, '..', '..');

/**
 * @param {string} relative
 * @returns {string}
 */
function filePath(relative) {
  return path.join(ROOT, ...relative.split('/'));
}

/**
 * @param {string} path
 * @returns {string}
 */
function quotePath(path) {
  return "\"" + path + "\"";
}

async function runWatch() {
  function runOnChanges(paths, mustExist = [], nodeFile) {
    nodeFile = filePath(nodeFile);
    function callback() {
      for (const fileMustExist of mustExist) {
        if (!fs.existsSync(filePath(fileMustExist)))
          return;
      }
      child_process.spawnSync('node', [nodeFile], { stdio: 'inherit' });
    }
    chokidar.watch([...paths, ...mustExist, nodeFile].map(filePath)).on('all', callback);
    callback();
  }

  for (const { files, from, to, ignored } of copyFiles) {
    const watcher = chokidar.watch([filePath(files)], { ignored });
    watcher.on('all', (event, file) => {
      copyFile(file, from, to);
    });
  }
  /** @type{import('child_process').ChildProcess[]} */
  const spawns = [];
  for (const step of steps)
    spawns.push(child_process.spawn(step.command, step.args, {
      stdio: 'inherit',
      shell: step.shell,
      env: {
        ...process.env,
        ...step.env,
      },
      cwd: step.cwd,
    }));
  process.on('exit', () => spawns.forEach(s => s.kill()));
  for (const onChange of onChanges)
    runOnChanges(onChange.inputs, onChange.mustExist, onChange.script);
}

async function runBuild() {
  /**
   * @param {Step} step
   */
  function runStep(step) {
    const out = child_process.spawnSync(step.command, step.args, {
      stdio: 'inherit',
      shell: step.shell,
      env: {
        ...process.env,
        ...step.env
      },
      cwd: step.cwd,
    });
    if (out.status)
      process.exit(out.status);
  }

  for (const { files, from, to, ignored } of copyFiles) {
    const watcher = chokidar.watch([filePath(files)], {
      ignored
    });
    watcher.on('add', file => {
      copyFile(file, from, to);
    });
    await new Promise(x => watcher.once('ready', x));
    watcher.close();
  }
  for (const step of steps)
    runStep(step);
  for (const onChange of onChanges) {
    if (!onChange.committed)
      runStep({ command: 'node', args: [filePath(onChange.script)], shell: false });
  }
}

/**
 * @param {string} file
 * @param {string} from
 * @param {string} to
 */
function copyFile(file, from, to) {
  const destination = path.resolve(filePath(to), path.relative(filePath(from), file));
  fs.mkdirSync(path.dirname(destination), { recursive: true });
  fs.copyFileSync(file, destination);
}

// Update test runner.
steps.push({
  command: 'npm',
  args: ['ci', '--save=false', '--fund=false', '--audit=false'],
  shell: true,
  cwd: path.join(__dirname, '..', '..', 'tests', 'playwright-test', 'stable-test-runner'),
});

// Build injected scripts.
const webPackFiles = [
  'packages/playwright-core/src/server/injected/webpack.config.js',
  'packages/playwright-core/src/web/traceViewer/webpack.config.js',
  'packages/playwright-core/src/web/traceViewer/webpack-sw.config.js',
  'packages/playwright-core/src/web/recorder/webpack.config.js',
  'packages/html-reporter/webpack.config.js',
  'packages/html-reporter/tests/webpack.config.js',
];
for (const file of webPackFiles) {
  steps.push({
    command: 'npx',
    args: ['webpack', '--config', quotePath(filePath(file)), ...(watchMode ? ['--watch', '--stats', 'none'] : [])],
    shell: true,
    env: {
      NODE_ENV: watchMode ? 'development' : 'production'
    }
  });
}

// Run Babel.
for (const pkg of workspace.packages()) {
  if (!fs.existsSync(path.join(pkg.path, 'src')))
    continue;
  steps.push({
    command: 'npx',
    args: [
      'babel',
      ...(watchMode ? ['-w', '--source-maps'] : []),
      '--extensions', '.ts',
      '--out-dir', quotePath(path.join(pkg.path, 'lib')),
      '--ignore', '"packages/playwright-core/src/server/injected/**/*"',
      quotePath(path.join(pkg.path, 'src'))],
    shell: true,
  });
}

// Generate channels.
onChanges.push({
  committed: false,
  inputs: [
    'packages/playwright-core/src/protocol/protocol.yml'
  ],
  script: 'utils/generate_channels.js',
});

// Generate types.
onChanges.push({
  committed: false,
  inputs: [
    'docs/src/api/',
    'docs/src/test-api/',
    'docs/src/test-reporter-api/',
    'utils/generate_types/overrides.d.ts',
    'utils/generate_types/overrides-test.d.ts',
    'utils/generate_types/overrides-testReporter.d.ts',
    'utils/generate_types/exported.json',
    'packages/playwright-core/src/server/chromium/protocol.d.ts',
  ],
  mustExist: [
    'packages/playwright-core/lib/server/deviceDescriptors.js',
    'packages/playwright-core/lib/server/deviceDescriptorsSource.json',
  ],
  script: 'utils/generate_types/index.js',
});

// The recorder and trace viewer have an app_icon.png that needs to be copied.
copyFiles.push({
  files: 'packages/playwright-core/src/server/chromium/*.png',
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
});

// Babel doesn't touch JS files, so copy them manually.
// For example: diff_match_patch.js
copyFiles.push({
  files: 'packages/playwright-core/src/**/*.js',
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
  ignored: ['**/.eslintrc.js', '**/webpack*.config.js', '**/injected/**/*']
});

copyFiles.push({
  files: 'packages/playwright-test/src/**/*.js',
  from: 'packages/playwright-test/src',
  to: 'packages/playwright-test/lib',
  ignored: ['**/.eslintrc.js']
});

// Sometimes we require JSON files that babel ignores.
// For example, deviceDescriptorsSource.json
copyFiles.push({
  files: 'packages/playwright-core/src/**/*.json',
  ignored: ['**/injected/**/*'],
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
});

if (lintMode) {
  // Run TypeScript for type chekcing.
  steps.push({
    command: 'npx',
    args: ['tsc', ...(watchMode ? ['-w'] : []), '-p', quotePath(filePath('.'))],
    shell: true,
  });
}

watchMode ? runWatch() : runBuild();
<commit_msg>fix(watch): throttle / batch watch processing (#13054)<commit_after>/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// @ts-check

const child_process = require('child_process');
const path = require('path');
const chokidar = require('chokidar');
const fs = require('fs');
const { workspace } = require('../workspace');

/**
 * @typedef {{
 *   command: string,
 *   args: string[],
 *   shell: boolean,
 *   env?: NodeJS.ProcessEnv,
 *   cwd?: string,
 * }} Step
 */

/**
 * @typedef {{
 *   files: string,
 *   from: string,
 *   to: string,
 *   ignored?: string[],
 * }} CopyFile
 */

/**
 * @typedef {{
 *   committed: boolean,
 *   inputs: string[],
 *   mustExist?: string[],
 *   script: string,
 * }} OnChange
 */

/** @type {Step[]} */
const steps = [];
/** @type {OnChange[]} */
const onChanges = [];
/** @type {CopyFile[]} */
const copyFiles = [];

const watchMode = process.argv.slice(2).includes('--watch');
const lintMode = process.argv.slice(2).includes('--lint');
const ROOT = path.join(__dirname, '..', '..');

/**
 * @param {string} relative
 * @returns {string}
 */
function filePath(relative) {
  return path.join(ROOT, ...relative.split('/'));
}

/**
 * @param {string} path
 * @returns {string}
 */
function quotePath(path) {
  return "\"" + path + "\"";
}

async function runWatch() {
  function runOnChanges(paths, mustExist = [], nodeFile) {
    nodeFile = filePath(nodeFile);
    let timeout;
    const callback = () => {
      timeout = undefined;
      for (const fileMustExist of mustExist) {
        if (!fs.existsSync(filePath(fileMustExist)))
          return;
      }
      child_process.spawnSync('node', [nodeFile], { stdio: 'inherit' });
    };
    // chokidar will report all files as added in a sync loop, throttle those.
    const reschedule = () => {
      if (timeout)
        clearTimeout(timeout);
      timeout = setTimeout(callback, 500);
    };
    chokidar.watch([...paths, ...mustExist, nodeFile].map(filePath)).on('all', reschedule);
    callback();
  }

  for (const { files, from, to, ignored } of copyFiles) {
    const watcher = chokidar.watch([filePath(files)], { ignored });
    watcher.on('all', (event, file) => {
      copyFile(file, from, to);
    });
  }
  /** @type{import('child_process').ChildProcess[]} */
  const spawns = [];
  for (const step of steps)
    spawns.push(child_process.spawn(step.command, step.args, {
      stdio: 'inherit',
      shell: step.shell,
      env: {
        ...process.env,
        ...step.env,
      },
      cwd: step.cwd,
    }));
  process.on('exit', () => spawns.forEach(s => s.kill()));
  for (const onChange of onChanges)
    runOnChanges(onChange.inputs, onChange.mustExist, onChange.script);
}

async function runBuild() {
  /**
   * @param {Step} step
   */
  function runStep(step) {
    const out = child_process.spawnSync(step.command, step.args, {
      stdio: 'inherit',
      shell: step.shell,
      env: {
        ...process.env,
        ...step.env
      },
      cwd: step.cwd,
    });
    if (out.status)
      process.exit(out.status);
  }

  for (const { files, from, to, ignored } of copyFiles) {
    const watcher = chokidar.watch([filePath(files)], {
      ignored
    });
    watcher.on('add', file => {
      copyFile(file, from, to);
    });
    await new Promise(x => watcher.once('ready', x));
    watcher.close();
  }
  for (const step of steps)
    runStep(step);
  for (const onChange of onChanges) {
    if (!onChange.committed)
      runStep({ command: 'node', args: [filePath(onChange.script)], shell: false });
  }
}

/**
 * @param {string} file
 * @param {string} from
 * @param {string} to
 */
function copyFile(file, from, to) {
  const destination = path.resolve(filePath(to), path.relative(filePath(from), file));
  fs.mkdirSync(path.dirname(destination), { recursive: true });
  fs.copyFileSync(file, destination);
}

// Update test runner.
steps.push({
  command: 'npm',
  args: ['ci', '--save=false', '--fund=false', '--audit=false'],
  shell: true,
  cwd: path.join(__dirname, '..', '..', 'tests', 'playwright-test', 'stable-test-runner'),
});

// Build injected scripts.
const webPackFiles = [
  'packages/playwright-core/src/server/injected/webpack.config.js',
  'packages/playwright-core/src/web/traceViewer/webpack.config.js',
  'packages/playwright-core/src/web/traceViewer/webpack-sw.config.js',
  'packages/playwright-core/src/web/recorder/webpack.config.js',
  'packages/html-reporter/webpack.config.js',
  'packages/html-reporter/tests/webpack.config.js',
];
for (const file of webPackFiles) {
  steps.push({
    command: 'npx',
    args: ['webpack', '--config', quotePath(filePath(file)), ...(watchMode ? ['--watch', '--stats', 'none'] : [])],
    shell: true,
    env: {
      NODE_ENV: watchMode ? 'development' : 'production'
    }
  });
}

// Run Babel.
for (const pkg of workspace.packages()) {
  if (!fs.existsSync(path.join(pkg.path, 'src')))
    continue;
  steps.push({
    command: 'npx',
    args: [
      'babel',
      ...(watchMode ? ['-w', '--source-maps'] : []),
      '--extensions', '.ts',
      '--out-dir', quotePath(path.join(pkg.path, 'lib')),
      '--ignore', '"packages/playwright-core/src/server/injected/**/*"',
      quotePath(path.join(pkg.path, 'src'))],
    shell: true,
  });
}

// Generate channels.
onChanges.push({
  committed: false,
  inputs: [
    'packages/playwright-core/src/protocol/protocol.yml'
  ],
  script: 'utils/generate_channels.js',
});

// Generate types.
onChanges.push({
  committed: false,
  inputs: [
    'docs/src/api/',
    'docs/src/test-api/',
    'docs/src/test-reporter-api/',
    'utils/generate_types/overrides.d.ts',
    'utils/generate_types/overrides-test.d.ts',
    'utils/generate_types/overrides-testReporter.d.ts',
    'utils/generate_types/exported.json',
    'packages/playwright-core/src/server/chromium/protocol.d.ts',
  ],
  mustExist: [
    'packages/playwright-core/lib/server/deviceDescriptors.js',
    'packages/playwright-core/lib/server/deviceDescriptorsSource.json',
  ],
  script: 'utils/generate_types/index.js',
});

// The recorder and trace viewer have an app_icon.png that needs to be copied.
copyFiles.push({
  files: 'packages/playwright-core/src/server/chromium/*.png',
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
});

// Babel doesn't touch JS files, so copy them manually.
// For example: diff_match_patch.js
copyFiles.push({
  files: 'packages/playwright-core/src/**/*.js',
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
  ignored: ['**/.eslintrc.js', '**/webpack*.config.js', '**/injected/**/*']
});

copyFiles.push({
  files: 'packages/playwright-test/src/**/*.js',
  from: 'packages/playwright-test/src',
  to: 'packages/playwright-test/lib',
  ignored: ['**/.eslintrc.js']
});

// Sometimes we require JSON files that babel ignores.
// For example, deviceDescriptorsSource.json
copyFiles.push({
  files: 'packages/playwright-core/src/**/*.json',
  ignored: ['**/injected/**/*'],
  from: 'packages/playwright-core/src',
  to: 'packages/playwright-core/lib',
});

if (lintMode) {
  // Run TypeScript for type chekcing.
  steps.push({
    command: 'npx',
    args: ['tsc', ...(watchMode ? ['-w'] : []), '-p', quotePath(filePath('.'))],
    shell: true,
  });
}

watchMode ? runWatch() : runBuild();
<|endoftext|>


<commit_before>/**
 * Created by 3er on 1/9/15.
 */

var qs = require('querystring');
var path = require('path');
var fs = require('fs');
var PRIVATE = require('./config/private')

var AND = ' && ';
var FFMPEG = ' ' + PRIVATE.dir.ffmpeg + 'ffmpeg ';

//前面有可能跟路径不能带空格
var h = function (d) {
    return {
        dir: d,
        origin: d + '/h.mp4 ',
        compo: d + '/h.list ',
        output: d + '/outputh.mp4 ',
        target: 'high/'
    }
};

var m = function (d) {
    return {
        dir: d,
        origin: d + '/m.mp4 ',
        compo: d + '/m.list ',
        output: d + '/outputm.mp4 ',
        target: 'medium/'
    }
};

var l = function (d) {
    return {
        dir: d,
        origin: d + '/l.mp4 ',
        compo: d + '/l.list ',
        output: d + '/outputl.mp4 ',
        target: 'low/'
    }
};

var LOOP = function (A, f, param1, param2) {
    var ret = new String();
    for (var i = 0; i < A.length; i++) {
        ret = ret + f(A[i], param1, param2) + AND;
    }
    return ret;
};

video = {
    ULTRAFAST: 'ultrafast',
    VERYSLOW: 'veryslow',
    param: function (w, h, sw, sh, crf) {
        return '-vf setsar=sar=' + sw + '/' + sh + ',setdar=dar=16/9,scale=' + w + 'x' + h
            + ' -crf ' + crf +' -pix_fmt yuv420p -c:v libx264 -r 25 -benchmark -threads 0 -preset ' + video.VERYSLOW;
    }
};

audio = {
    param: function (a, b, vbr) {
        //TODO: vba need compilation
        return ' -c:a libfdk_aac -ar ' + a + ' -b:a ' + b + 'k ';
    }
};

origin = {
    ver: function (F, w, h, sw, sh, crf, a, b, vbr) {
        return  video.param(w, h, sw, sh, crf) + audio.param(a, b, vbr) + F.origin;
    },
    generate: function (H, M, L) {
        return this.ver(H, 1280, 720, 1, 1, 18, 48000, 128)
            + this.ver(M, 854, 480, 1280, 1281, 23, 44100, 96)
            + this.ver(L, 480, 270, 1, 1, 25, 22050, 64) + AND;
    }
};

bash = {
    cp: function (src, dest) {
        return ' cp ' + src + ' ' + dest + ' ';
    },
    mv: function (src, dest) {
        return ' mv ' + src + ' ' + dest + ' ';
    },
    rmDir: function (dir) {
        return ' rm -rf ' + dir + ' ';
    },
    cpO2O: function (F) {
        return ' cp ' + F.origin + F.output;
    },
    mvO2T: function (F, target, fileName) {
        return ' mv ' + F.output + target + F.target + fileName;
    }
};

var oped = function () {
    this.op_name = '';
    this.op_duration = 0;
    this.ed_name = '';
    this.ed_duration = 0;
};

oped.prototype.metadata = function () {
    return qs.stringify(this);
};

exports.oped = oped;

concat = {
    concat: function (F, oped) {
        return FFMPEG + '-y -f concat -i ' + F.compo + ' -c copy -metadata "'
            + oped.metadata() + '" -movflags +faststart ' + F.output;
    },

    cmd: function (A, oped) {
        return LOOP(A, this.concat, oped);
    }
};

ffmpeg = {
    input: function (path) {
        return FFMPEG + '-y -i "' + path + '" ';
    },
    streamCopy: function(F, oped) {
        return FFMPEG + '-y -i "' + F.compo + ' -c copy -metadata "'
            + oped.metadata() + '" -movflags +faststart ' + F.output;
    }
};

command = {

    addOped: function (A, oe) {
        if (oe.op_name == 'null' && oe.ed_name == 'null') {
            return LOOP(A, ffmpeg.streamCopy, oe);
        }
        else {
            return concat.cmd(A, oe);
        }
    },

    mv: function (A, target, fileName) {
        // origin h
        var ret = bash.cp(A[0].output, target + 'origin/' + fileName) + AND;
        // high/medium/low
        ret = ret + LOOP(A, bash.mvO2T, target, fileName);
        return ret;
    },

    all: function (p, oe) {
        var dir = path.dirname(p);
        var fileName = path.basename(p);
        var H = h(dir), M = m(dir), L = l(dir);
        var A = [H, M, L];

        // output: h.mp4 m.mp4 l.mp4
        var ret = ffmpeg.input(p) + origin.generate(H, M, L);
        // output: outputh.mp4 outputm.mp4 outputl.mp4
        ret = ret + this.addOped(A, oe);
        // output: rsync 4 folders
        ret = ret + this.mv(A, PRIVATE.dir.rsync, fileName);
        // rm
        ret = ret + bash.rmDir(dir) + '\n';
        return ret;
    }
};

var file = {
    content: function (opedDir, inputDir, oe, v) {
        var f;
        var VMP4 = v + '.mp4\n';
        if (oe.op_name != 'null')
            f = 'file ' + opedDir + oe.op_name + VMP4;
        else
            f = ''

        f = f + 'file ' + inputDir + VMP4;

        if (oe.ed_name != 'null')
            f = f + 'file ' + opedDir + oe.ed_name + VMP4;
        else
            f = f;
        return f;
    },

    write: function (inputPath, opedDir, oped) {
        var inputDir = path.dirname(inputPath) + '/';
        fs.writeFileSync(inputDir + 'h.list', this.content(opedDir, inputDir, oped, 'h'));
        fs.writeFileSync(inputDir + 'm.list', this.content(opedDir, inputDir, oped, 'm'));
        fs.writeFileSync(inputDir + 'l.list', this.content(opedDir, inputDir, oped, 'l'));
    }
};

exports.generate = function (filePath, oe) {
//    oe.op_name = 'null'
//    oe.ed_name = 'null'
    var cmd = command.all(filePath, oe);
    if (oe.op_name != 'null' || oe.ed_name != 'null') {
        file.write(filePath, PRIVATE.dir.oped, oe);
    }
    fs.writeFileSync(path.dirname(filePath) + '/' + 'command', cmd);
    return cmd;
};

<commit_msg>fix metadata fix quato & input <commit_after>/**
 * Created by 3er on 1/9/15.
 */

var qs = require('querystring');
var path = require('path');
var fs = require('fs');
var PRIVATE = require('./config/private')

var AND = ' && ';
var FFMPEG = ' ' + PRIVATE.dir.ffmpeg + 'ffmpeg ';

//前面有可能跟路径不能带空格
var h = function (d) {
    return {
        dir: d,
        origin: d + '/h.mp4 ',
        compo: d + '/h.list ',
        output: d + '/outputh.mp4 ',
        target: 'high/'
    }
};

var m = function (d) {
    return {
        dir: d,
        origin: d + '/m.mp4 ',
        compo: d + '/m.list ',
        output: d + '/outputm.mp4 ',
        target: 'medium/'
    }
};

var l = function (d) {
    return {
        dir: d,
        origin: d + '/l.mp4 ',
        compo: d + '/l.list ',
        output: d + '/outputl.mp4 ',
        target: 'low/'
    }
};

var LOOP = function (A, f, param1, param2) {
    var ret = new String();
    for (var i = 0; i < A.length; i++) {
        ret = ret + f(A[i], param1, param2) + AND;
    }
    return ret;
};

video = {
    ULTRAFAST: 'ultrafast',
    VERYSLOW: 'veryslow',
    param: function (w, h, sw, sh, crf) {
        return '-vf setsar=sar=' + sw + '/' + sh + ',setdar=dar=16/9,scale=' + w + 'x' + h
            + ' -crf ' + crf +' -pix_fmt yuv420p -c:v libx264 -r 25 -benchmark -threads 0 -preset ' + video.VERYSLOW;
    }
};

audio = {
    param: function (a, b, vbr) {
        //TODO: vba need compilation
        return ' -c:a libfdk_aac -ar ' + a + ' -b:a ' + b + 'k ';
    }
};

origin = {
    ver: function (F, w, h, sw, sh, crf, a, b, vbr) {
        return  video.param(w, h, sw, sh, crf) + audio.param(a, b, vbr) + F.origin;
    },
    generate: function (H, M, L) {
        return this.ver(H, 1280, 720, 1, 1, 18, 48000, 128)
            + this.ver(M, 854, 480, 1280, 1281, 23, 44100, 96)
            + this.ver(L, 480, 270, 1, 1, 25, 22050, 64) + AND;
    }
};

bash = {
    cp: function (src, dest) {
        return ' cp ' + src + ' ' + dest + ' ';
    },
    mv: function (src, dest) {
        return ' mv ' + src + ' ' + dest + ' ';
    },
    rmDir: function (dir) {
        return ' rm -rf ' + dir + ' ';
    },
    cpO2O: function (F) {
        return ' cp ' + F.origin + F.output;
    },
    mvO2T: function (F, target, fileName) {
        return ' mv ' + F.output + target + F.target + fileName;
    }
};

var oped = function () {
    this.op_name = '';
    this.op_duration = 0;
    this.ed_name = '';
    this.ed_duration = 0;
};

oped.prototype.metadata = function () {
    return qs.stringify(this);
};

exports.oped = oped;

concat = {
    concat: function (F, oped) {
        return FFMPEG + '-y -f concat -i ' + F.compo + ' -c copy -metadata comment="'
            + oped.metadata() + '" -movflags +faststart ' + F.output;
    },

    cmd: function (A, oped) {
        return LOOP(A, this.concat, oped);
    }
};

ffmpeg = {
    input: function (path) {
        return FFMPEG + '-y -i "' + path + '" ';
    },
    streamCopy: function(F, oped) {
        return FFMPEG + '-y -i "' + F.origin + '" -c copy -metadata comment="'
            + oped.metadata() + '" -movflags +faststart ' + F.output;
    }
};

command = {

    addOped: function (A, oe) {
        if (oe.op_name == 'null' && oe.ed_name == 'null') {
            return LOOP(A, ffmpeg.streamCopy, oe);
        }
        else {
            return concat.cmd(A, oe);
        }
    },

    mv: function (A, target, fileName) {
        // origin h
        var ret = bash.cp(A[0].output, target + 'origin/' + fileName) + AND;
        // high/medium/low
        ret = ret + LOOP(A, bash.mvO2T, target, fileName);
        return ret;
    },

    all: function (p, oe) {
        var dir = path.dirname(p);
        var fileName = path.basename(p);
        var H = h(dir), M = m(dir), L = l(dir);
        var A = [H, M, L];

        // output: h.mp4 m.mp4 l.mp4
        var ret = ffmpeg.input(p) + origin.generate(H, M, L);
        // output: outputh.mp4 outputm.mp4 outputl.mp4
        ret = ret + this.addOped(A, oe);
        // output: rsync 4 folders
        ret = ret + this.mv(A, PRIVATE.dir.rsync, fileName);
        // rm
        ret = ret + bash.rmDir(dir) + '\n';
        return ret;
    }
};

var file = {
    content: function (opedDir, inputDir, oe, v) {
        var f;
        var VMP4 = v + '.mp4\n';
        if (oe.op_name != 'null')
            f = 'file ' + opedDir + oe.op_name + VMP4;
        else
            f = ''

        f = f + 'file ' + inputDir + VMP4;

        if (oe.ed_name != 'null')
            f = f + 'file ' + opedDir + oe.ed_name + VMP4;
        else
            f = f;
        return f;
    },

    write: function (inputPath, opedDir, oped) {
        var inputDir = path.dirname(inputPath) + '/';
        fs.writeFileSync(inputDir + 'h.list', this.content(opedDir, inputDir, oped, 'h'));
        fs.writeFileSync(inputDir + 'm.list', this.content(opedDir, inputDir, oped, 'm'));
        fs.writeFileSync(inputDir + 'l.list', this.content(opedDir, inputDir, oped, 'l'));
    }
};

exports.generate = function (filePath, oe) {
//    oe.op_name = 'null'
//    oe.ed_name = 'null'
    var cmd = command.all(filePath, oe);
    if (oe.op_name != 'null' || oe.ed_name != 'null') {
        file.write(filePath, PRIVATE.dir.oped, oe);
    }
    fs.writeFileSync(path.dirname(filePath) + '/' + 'command', cmd);
    return cmd;
};

<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'

import {
  TextInput,
  Keyboard,
  Animated,
  PanResponder,
  Platform,
} from 'react-native'

import FlickAnimation from './libs/FlickAnimation'
import measureElement from './libs/measureElement'
import { visibleHeight } from './libs/layout'
import styles from './libs/styles'

const keyboardShowEvent = Platform.select({
  android: 'keyboardDidShow',
  ios: 'keyboardWillShow',
})

const keyboardHideEvent = Platform.select({
  android: 'keyboardDidHide',
  ios: 'keyboardWillHide',
})

const DEFAULT_MINIMUM_VELOCITY_THRESHOLD = 0.1
const DEFAULT_MINIMUM_DISTANCE_THRESHOLD = 0.24
const KEYBOARD_TRANSITION_DURATION = 160
const KEYBOARD_EXTRA_MARGIN = 75
const DEFAULT_FRICTION = 0.998
const DELTA_TIME = 240

class SlidingUpPanel extends React.PureComponent {
  static propTypes = {
    height: PropTypes.number,
    animatedValue: PropTypes.instanceOf(Animated.Value),
    draggableRange: PropTypes.shape({
      top: PropTypes.number,
      bottom: PropTypes.number,
    }),
    minimumVelocityThreshold: PropTypes.number,
    minimumDistanceThreshold: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    onDragStart: PropTypes.func,
    onDragEnd: PropTypes.func,
    allowMomentum: PropTypes.bool,
    allowDragging: PropTypes.bool,
    showBackdrop: PropTypes.bool,
    backdropOpacity: PropTypes.number,
    friction: PropTypes.number,
    children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
  }

  static defaultProps = {
    height: visibleHeight,
    animatedValue: new Animated.Value(0),
    draggableRange: { top: visibleHeight, bottom: 0 },
    minimumVelocityThreshold: DEFAULT_MINIMUM_VELOCITY_THRESHOLD,
    minimumDistanceThreshold: DEFAULT_MINIMUM_DISTANCE_THRESHOLD,
    avoidKeyboard: true,
    onDragStart: () => {},
    onDragEnd: () => {},
    allowMomentum: true,
    allowDragging: true,
    showBackdrop: true,
    backdropOpacity: 0.75,
    friction: DEFAULT_FRICTION,
  }

  // eslint-disable-next-line react/sort-comp
  _panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => this.props.allowDragging,
    onMoveShouldSetPanResponder: this._onMoveShouldSetPanResponder.bind(this),
    onPanResponderGrant: this._onPanResponderGrant.bind(this),
    onPanResponderMove: this._onPanResponderMove.bind(this),
    onPanResponderRelease: this._onPanResponderRelease.bind(this),
    onPanResponderTerminate: this._onPanResponderTerminate.bind(this),
    onShouldBlockNativeResponder: () => false,
    onPanResponderTerminationRequest: () => false,
  })

  _keyboardShowListener = Keyboard.addListener(
    keyboardShowEvent,
    this._onKeyboardShown.bind(this)
  )

  _keyboardHideListener = Keyboard.addListener(
    keyboardHideEvent,
    this._onKeyboardHiden.bind(this)
  )

  constructor(props) {
    super(props)

    this._storeKeyboardPosition = this._storeKeyboardPosition.bind(this)
    this._isInsideDraggableRange = this._isInsideDraggableRange.bind(this)
    this._triggerAnimation = this._triggerAnimation.bind(this)
    this._renderContent = this._renderContent.bind(this)
    this._renderBackdrop = this._renderBackdrop.bind(this)

    this.show = this.show.bind(this)
    this.hide = this.hide.bind(this)
    this.scrollIntoView = this.scrollIntoView.bind(this)

    const { top, bottom } = this.props.draggableRange
    const currentValue = this.props.animatedValue.__getValue()

    // If the animated value is out of bound
    if (currentValue < bottom) {
      this.props.animatedValue.setValue(bottom)
    } else if (currentValue > top) {
      this.props.animatedValue.setValue(top)
    }

    this._initialDragPosition = currentValue

    this._flick = new FlickAnimation({
      max: top,
      min: bottom,
      friction: this.props.friction,
    })

    this._animatedValueListener = this._flick.onUpdate(this._onDrag.bind(this))
  }

  componentWillReceiveProps(nextProps) {
    if (
      nextProps.friction !== this.props.friction ||
      nextProps.draggableRange.top !== this.props.draggableRange.top ||
      nextProps.draggableRange.bottom !== this.props.draggableRange.bottom
    ) {
      const { top, bottom } = nextProps.draggableRange

      this._flick.setMin(top)
      this._flick.setMax(bottom)
      this._flick.setFriction(nextProps.friction)
    }
  }

  componentWillUnmount() {
    if (this._keyboardShowListener != null) {
      this._keyboardShowListener.remove()
    }

    if (this._animatedValueListener != null) {
      this._animatedValueListener()
    }
  }

  _onMoveShouldSetPanResponder(evt, gestureState) {
    if (!this.props.allowDragging) {
      return false
    }

    const animatedValue = this.props.animatedValue.__getValue()

    return (
      this._isInsideDraggableRange(animatedValue) &&
      Math.abs(gestureState.dy) > this.props.minimumDistanceThreshold
    )
  }

  _onPanResponderGrant(evt, gestureState) {
    this._flick.stop()

    const value = this.props.animatedValue.__getValue()

    this._initialDragPosition = value
    this.props.onDragStart(value)
  }

  _onPanResponderMove(evt, gestureState) {
    const { top } = this.props.draggableRange
    const newValue = Math.min(this._initialDragPosition - gestureState.dy, top)
    this.props.animatedValue.setValue(newValue)
  }

  // Trigger when you release your finger
  _onPanResponderRelease(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue)

    if (!this.props.allowMomentum || this._flick.isActive()) {
      return
    }

    if (Math.abs(gestureState.vy) > this.props.minimumVelocityThreshold) {
      this._flick.start({
        velocity: gestureState.vy,
        fromValue: animatedValue,
      })
    }
  }

  // eslint-disable-next-line class-methods-use-this, no-unused-vars
  _onPanResponderTerminate(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue)
  }

  _onDrag(value) {
    this.props.animatedValue.setValue(value)

    const isAtBottom = this._isAtBottom(value)

    if (isAtBottom) {
      Keyboard.dismiss()
    }

    if (this._backdrop == null) {
      return
    }

    if (isAtBottom) {
      this._backdrop.setNativeProps({ pointerEvents: 'none' })
    } else if (!this._isAtBottom(this._initialDragPosition)) {
      this._backdrop.setNativeProps({ pointerEvents: 'box-only' })
    }
  }

  _onKeyboardShown(event) {
    if (!this.props.avoidKeyboard) {
      return
    }

    this._storeKeyboardPosition(event.endCoordinates.screenY)

    const node = TextInput.State.currentlyFocusedField()

    if (node != null) {
      this.scrollIntoView(node)
    }
  }

  _onKeyboardHiden() {
    this._storeKeyboardPosition(0)

    const animatedValue = this.props.animatedValue.__getValue()

    // Restore last position
    if (this._lastPosition != null && !this._isAtBottom(animatedValue)) {
      Animated.timing(this.props.animatedValue, {
        toValue: this._lastPosition,
        duration: KEYBOARD_TRANSITION_DURATION,
      }).start()
    }

    this._lastPosition = null
  }

  _isInsideDraggableRange(value) {
    const { top, bottom } = this.props.draggableRange
    return value <= top && value >= bottom
  }

  _isAtBottom(value) {
    const { bottom } = this.props.draggableRange
    return value <= bottom
  }

  _triggerAnimation(options = {}) {
    const animatedValue = this.props.animatedValue.__getValue()
    const remainingDistance = animatedValue - options.toValue
    const velocity = options.initialVelocity || remainingDistance / DELTA_TIME

    this._flick.start({ fromValue: animatedValue, velocity })
  }

  _storeKeyboardPosition(value) {
    this._keyboardYPosition = value
  }

  _renderBackdrop() {
    if (!this.props.showBackdrop) {
      return null
    }

    const { top, bottom } = this.props.draggableRange

    const backdropOpacity = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [0, this.props.backdropOpacity],
      extrapolate: 'clamp',
    })

    // This is initial pointer events. Since the pointer events
    // will keep changing when the panel moving
    const pointerEvents = !this._isAtBottom(this._initialDragPosition)
      ? 'box-only'
      : 'none'

    return (
      <Animated.View
        key="backdrop"
        pointerEvents={pointerEvents}
        ref={c => (this._backdrop = c)}
        onTouchStart={() => this._flick.stop()}
        onTouchEnd={() => this.hide()}
        style={[styles.backdrop, { opacity: backdropOpacity }]}
      />
    )
  }

  _renderContent() {
    const { top, bottom } = this.props.draggableRange
    const height = this.props.height

    const translateY = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [-bottom, -top],
      extrapolate: 'clamp',
    })

    const transform = { transform: [{ translateY }] }

    const animatedContainerStyles = [
      styles.animatedContainer,
      transform,
      { height, top: visibleHeight },
    ]

    if (typeof this.props.children === 'function') {
      return (
        <Animated.View
          key="content"
          pointerEvents="box-none"
          style={animatedContainerStyles}>
          {this.props.children(this._panResponder.panHandlers)}
        </Animated.View>
      )
    }

    return (
      <Animated.View
        key="content"
        pointerEvents="box-none"
        style={animatedContainerStyles}
        {...this._panResponder.panHandlers}>
        {this.props.children}
      </Animated.View>
    )
  }

  render() {
    return [this._renderBackdrop(), this._renderContent()]
  }

  show(mayBeValueOrOptions) {
    if (!mayBeValueOrOptions) {
      const { top } = this.props.draggableRange
      return this._triggerAnimation({ toValue: top })
    }

    if (typeof mayBeValueOrOptions === 'object') {
      return this._triggerAnimation(mayBeValueOrOptions)
    }

    return this._triggerAnimation({ toValue: mayBeValueOrOptions })
  }

  hide() {
    const { bottom } = this.props.draggableRange
    this._triggerAnimation({ toValue: bottom })
  }

  async scrollIntoView(node, options = {}) {
    if (!this._keyboardYPosition) {
      return
    }

    this._flick.stop()

    const { y } = await measureElement(node)
    const extraMargin = options.keyboardExtraMargin || KEYBOARD_EXTRA_MARGIN
    const keyboardActualPos = this._keyboardYPosition - extraMargin

    if (y > keyboardActualPos) {
      this._lastPosition = this.props.animatedValue.__getValue()

      const fromKeyboardToElement = y - keyboardActualPos
      const transitionDistance = this._lastPosition + fromKeyboardToElement

      Animated.timing(this.props.animatedValue, {
        toValue: transitionDistance,
        duration: KEYBOARD_TRANSITION_DURATION,
      }).start()
    }
  }
}

export default SlidingUpPanel
<commit_msg>Fix issue drag over minimum point<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import clamp from 'clamp'

import {
  TextInput,
  Keyboard,
  Animated,
  PanResponder,
  Platform,
} from 'react-native'

import FlickAnimation from './libs/FlickAnimation'
import measureElement from './libs/measureElement'
import { visibleHeight } from './libs/layout'
import styles from './libs/styles'

const keyboardShowEvent = Platform.select({
  android: 'keyboardDidShow',
  ios: 'keyboardWillShow',
})

const keyboardHideEvent = Platform.select({
  android: 'keyboardDidHide',
  ios: 'keyboardWillHide',
})

const DEFAULT_MINIMUM_VELOCITY_THRESHOLD = 0.1
const DEFAULT_MINIMUM_DISTANCE_THRESHOLD = 0.24
const KEYBOARD_TRANSITION_DURATION = 160
const KEYBOARD_EXTRA_MARGIN = 75
const DEFAULT_FRICTION = 0.998
const DELTA_TIME = 240

class SlidingUpPanel extends React.PureComponent {
  static propTypes = {
    height: PropTypes.number,
    animatedValue: PropTypes.instanceOf(Animated.Value),
    draggableRange: PropTypes.shape({
      top: PropTypes.number,
      bottom: PropTypes.number,
    }),
    minimumVelocityThreshold: PropTypes.number,
    minimumDistanceThreshold: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    onDragStart: PropTypes.func,
    onDragEnd: PropTypes.func,
    allowMomentum: PropTypes.bool,
    allowDragging: PropTypes.bool,
    showBackdrop: PropTypes.bool,
    backdropOpacity: PropTypes.number,
    friction: PropTypes.number,
    children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
  }

  static defaultProps = {
    height: visibleHeight,
    animatedValue: new Animated.Value(0),
    draggableRange: { top: visibleHeight, bottom: 0 },
    minimumVelocityThreshold: DEFAULT_MINIMUM_VELOCITY_THRESHOLD,
    minimumDistanceThreshold: DEFAULT_MINIMUM_DISTANCE_THRESHOLD,
    avoidKeyboard: true,
    onDragStart: () => {},
    onDragEnd: () => {},
    allowMomentum: true,
    allowDragging: true,
    showBackdrop: true,
    backdropOpacity: 0.75,
    friction: DEFAULT_FRICTION,
  }

  // eslint-disable-next-line react/sort-comp
  _panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => this.props.allowDragging,
    onMoveShouldSetPanResponder: this._onMoveShouldSetPanResponder.bind(this),
    onPanResponderGrant: this._onPanResponderGrant.bind(this),
    onPanResponderMove: this._onPanResponderMove.bind(this),
    onPanResponderRelease: this._onPanResponderRelease.bind(this),
    onPanResponderTerminate: this._onPanResponderTerminate.bind(this),
    onShouldBlockNativeResponder: () => false,
    onPanResponderTerminationRequest: () => false,
  })

  _keyboardShowListener = Keyboard.addListener(
    keyboardShowEvent,
    this._onKeyboardShown.bind(this)
  )

  _keyboardHideListener = Keyboard.addListener(
    keyboardHideEvent,
    this._onKeyboardHiden.bind(this)
  )

  constructor(props) {
    super(props)

    this._storeKeyboardPosition = this._storeKeyboardPosition.bind(this)
    this._isInsideDraggableRange = this._isInsideDraggableRange.bind(this)
    this._triggerAnimation = this._triggerAnimation.bind(this)
    this._renderContent = this._renderContent.bind(this)
    this._renderBackdrop = this._renderBackdrop.bind(this)

    this.show = this.show.bind(this)
    this.hide = this.hide.bind(this)
    this.scrollIntoView = this.scrollIntoView.bind(this)

    const { top, bottom } = this.props.draggableRange
    const currentValue = this.props.animatedValue.__getValue()

    // If the animated value is out of bound
    if (currentValue < bottom) {
      this.props.animatedValue.setValue(bottom)
    } else if (currentValue > top) {
      this.props.animatedValue.setValue(top)
    }

    this._initialDragPosition = currentValue

    this._flick = new FlickAnimation({
      max: top,
      min: bottom,
      friction: this.props.friction,
    })

    this._animatedValueListener = this._flick.onUpdate(this._onDrag.bind(this))
  }

  componentWillReceiveProps(nextProps) {
    if (
      nextProps.friction !== this.props.friction ||
      nextProps.draggableRange.top !== this.props.draggableRange.top ||
      nextProps.draggableRange.bottom !== this.props.draggableRange.bottom
    ) {
      const { top, bottom } = nextProps.draggableRange

      this._flick.setMin(top)
      this._flick.setMax(bottom)
      this._flick.setFriction(nextProps.friction)
    }
  }

  componentWillUnmount() {
    if (this._keyboardShowListener != null) {
      this._keyboardShowListener.remove()
    }

    if (this._animatedValueListener != null) {
      this._animatedValueListener()
    }
  }

  _onMoveShouldSetPanResponder(evt, gestureState) {
    if (!this.props.allowDragging) {
      return false
    }

    const animatedValue = this.props.animatedValue.__getValue()

    return (
      this._isInsideDraggableRange(animatedValue) &&
      Math.abs(gestureState.dy) > this.props.minimumDistanceThreshold
    )
  }

  _onPanResponderGrant(evt, gestureState) {
    this._flick.stop()

    const value = this.props.animatedValue.__getValue()

    this._initialDragPosition = value
    this.props.onDragStart(value)
  }

  _onPanResponderMove(evt, gestureState) {
    const { top, bottom } = this.props.draggableRange
    const delta = this._initialDragPosition - gestureState.dy
    const newValue = clamp(delta, top, bottom)

    this.props.animatedValue.setValue(newValue)
  }

  // Trigger when you release your finger
  _onPanResponderRelease(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue)

    if (!this.props.allowMomentum || this._flick.isActive()) {
      return
    }

    if (Math.abs(gestureState.vy) > this.props.minimumVelocityThreshold) {
      this._flick.start({
        velocity: gestureState.vy,
        fromValue: animatedValue,
      })
    }
  }

  // eslint-disable-next-line class-methods-use-this, no-unused-vars
  _onPanResponderTerminate(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue)
  }

  _onDrag(value) {
    this.props.animatedValue.setValue(value)

    const isAtBottom = this._isAtBottom(value)

    if (isAtBottom) {
      Keyboard.dismiss()
    }

    if (this._backdrop == null) {
      return
    }

    if (isAtBottom) {
      this._backdrop.setNativeProps({ pointerEvents: 'none' })
    } else if (!this._isAtBottom(this._initialDragPosition)) {
      this._backdrop.setNativeProps({ pointerEvents: 'box-only' })
    }
  }

  _onKeyboardShown(event) {
    if (!this.props.avoidKeyboard) {
      return
    }

    this._storeKeyboardPosition(event.endCoordinates.screenY)

    const node = TextInput.State.currentlyFocusedField()

    if (node != null) {
      this.scrollIntoView(node)
    }
  }

  _onKeyboardHiden() {
    this._storeKeyboardPosition(0)

    const animatedValue = this.props.animatedValue.__getValue()

    // Restore last position
    if (this._lastPosition != null && !this._isAtBottom(animatedValue)) {
      Animated.timing(this.props.animatedValue, {
        toValue: this._lastPosition,
        duration: KEYBOARD_TRANSITION_DURATION,
      }).start()
    }

    this._lastPosition = null
  }

  _isInsideDraggableRange(value) {
    const { top, bottom } = this.props.draggableRange
    return value <= top && value >= bottom
  }

  _isAtBottom(value) {
    const { bottom } = this.props.draggableRange
    return value <= bottom
  }

  _triggerAnimation(options = {}) {
    const animatedValue = this.props.animatedValue.__getValue()
    const remainingDistance = animatedValue - options.toValue
    const velocity = options.initialVelocity || remainingDistance / DELTA_TIME

    this._flick.start({ fromValue: animatedValue, velocity })
  }

  _storeKeyboardPosition(value) {
    this._keyboardYPosition = value
  }

  _renderBackdrop() {
    if (!this.props.showBackdrop) {
      return null
    }

    const { top, bottom } = this.props.draggableRange

    const backdropOpacity = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [0, this.props.backdropOpacity],
      extrapolate: 'clamp',
    })

    // This is initial pointer events. Since the pointer events
    // will keep changing when the panel moving
    const pointerEvents = !this._isAtBottom(this._initialDragPosition)
      ? 'box-only'
      : 'none'

    return (
      <Animated.View
        key="backdrop"
        pointerEvents={pointerEvents}
        ref={c => (this._backdrop = c)}
        onTouchStart={() => this._flick.stop()}
        onTouchEnd={() => this.hide()}
        style={[styles.backdrop, { opacity: backdropOpacity }]}
      />
    )
  }

  _renderContent() {
    const { top, bottom } = this.props.draggableRange
    const height = this.props.height

    const translateY = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [-bottom, -top],
      extrapolate: 'clamp',
    })

    const transform = { transform: [{ translateY }] }

    const animatedContainerStyles = [
      styles.animatedContainer,
      transform,
      { height, top: visibleHeight },
    ]

    if (typeof this.props.children === 'function') {
      return (
        <Animated.View
          key="content"
          pointerEvents="box-none"
          style={animatedContainerStyles}>
          {this.props.children(this._panResponder.panHandlers)}
        </Animated.View>
      )
    }

    return (
      <Animated.View
        key="content"
        pointerEvents="box-none"
        style={animatedContainerStyles}
        {...this._panResponder.panHandlers}>
        {this.props.children}
      </Animated.View>
    )
  }

  render() {
    return [this._renderBackdrop(), this._renderContent()]
  }

  show(mayBeValueOrOptions) {
    if (!mayBeValueOrOptions) {
      const { top } = this.props.draggableRange
      return this._triggerAnimation({ toValue: top })
    }

    if (typeof mayBeValueOrOptions === 'object') {
      return this._triggerAnimation(mayBeValueOrOptions)
    }

    return this._triggerAnimation({ toValue: mayBeValueOrOptions })
  }

  hide() {
    const { bottom } = this.props.draggableRange
    this._triggerAnimation({ toValue: bottom })
  }

  async scrollIntoView(node, options = {}) {
    if (!this._keyboardYPosition) {
      return
    }

    this._flick.stop()

    const { y } = await measureElement(node)
    const extraMargin = options.keyboardExtraMargin || KEYBOARD_EXTRA_MARGIN
    const keyboardActualPos = this._keyboardYPosition - extraMargin

    if (y > keyboardActualPos) {
      this._lastPosition = this.props.animatedValue.__getValue()

      const fromKeyboardToElement = y - keyboardActualPos
      const transitionDistance = this._lastPosition + fromKeyboardToElement

      Animated.timing(this.props.animatedValue, {
        toValue: transitionDistance,
        duration: KEYBOARD_TRANSITION_DURATION,
      }).start()
    }
  }
}

export default SlidingUpPanel
<|endoftext|>


<commit_before>/* eslint-disable no-unused-vars */
import React from 'react';
import styled from 'styled-components';
import Column from './Column';
import { divvy, passOn } from '../utils';

function RowContainer(props) {
  const { children, tagName, debug, divisions, ...rest } = props;
  const newChildren = passOn(children, [Column], (child) => {
    return {
      debug: typeof child.props.debug === 'undefined'
        ? debug
        : child.props.debug,
      divisions,
    };
  });
  return React.createElement(tagName || 'section', rest, newChildren);
}

RowContainer.propTypes = {
  children: React.PropTypes.node,
  tagName: React.PropTypes.string,
  className: React.PropTypes.string,
  debug: React.PropTypes.bool,
  divisions: React.PropTypes.number,
};

RowContainer.defaultProps = {
  divisions: 12,
};

const Row = styled(RowContainer)`
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
`;

export default Row;

<commit_msg>feat(Row): add support for all flex props (#24) (#42)<commit_after>/* eslint-disable no-unused-vars */
import React from 'react';
import styled from 'styled-components';
import Column from './Column';
import { divvy, passOn } from '../utils';

function RowContainer(props) {
  const { children, tagName, debug, divisions,
    alignContent, alignItems, alignSelf, justifyContent, order,
    ...rest } = props;
  const newChildren = passOn(children, [Column], (child) => {
    return {
      debug: typeof child.props.debug === 'undefined'
        ? debug
        : child.props.debug,
      divisions,
    };
  });
  return React.createElement(tagName || 'section', rest, newChildren);
}

RowContainer.propTypes = {
  children: React.PropTypes.node,
  className: React.PropTypes.string,
  debug: React.PropTypes.bool,
  tagName: React.PropTypes.string,
  // grid props
  divisions: React.PropTypes.number,
  // flex props
  alignContent: React.PropTypes.string,
  alignItems: React.PropTypes.string,
  alignSelf: React.PropTypes.string,
  justifyContent: React.PropTypes.string,
  order: React.PropTypes.string,
};

RowContainer.defaultProps = {
  divisions: 12,
};

const Row = styled(RowContainer)`
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  ${props => props.alignContent
    ? `align-content: ${props.alignContent};`
    : null
  }
  ${props => props.alignItems
    ? `align-items: ${props.alignItems};`
    : null
  }
  ${props => props.alignSelf
    ? `align-self: ${props.alignSelf};`
    : null
  }
  ${props => props.justifyContent
    ? `justify-content: ${props.justifyContent};`
    : null
  }
  ${props => props.order
    ? `order: ${props.order};`
    : null
  }
`;

export default Row;

<|endoftext|>


<commit_before>TestSuite.add(new YAHOO.tool.TestCase({

	test_SHA256: function () {
		Assert.areEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Crypto.SHA256(""));
		Assert.areEqual("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", Crypto.SHA256("a"));
		Assert.areEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", Crypto.SHA256("abc"));
		Assert.areEqual("f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650", Crypto.SHA256("message digest"));
		Assert.areEqual("71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73", Crypto.SHA256("abcdefghijklmnopqrstuvwxyz"));
		Assert.areEqual("db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0", Crypto.SHA256("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
		Assert.areEqual("f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e", Crypto.SHA256("12345678901234567890123456789012345678901234567890123456789012345678901234567890"));
		Assert.areEqual("40e44c26e53e584db2253ea2994025dd8f0cc07071c0e37217293031bddb8794", Crypto.SHA256("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tempor massa sit amet velit consectetur eu pellentesque felis feugiat. Mauris ullamcorper, sapien vel eleifend pulvinar, ligula lacus imperdiet mi, volutpat consequat velit dui a quam. Integer semper orci eget lectus feugiat sed adipiscing urna consectetur. In sem sem, aliquam nec vestibulum ac, aliquet quis elit. Maecenas vehicula tempor enim at dictum. Nam at sem et libero mattis hendrerit non a ante. Aliquam ut pharetra nunc. Quisque massa mi, commodo vitae semper nec, ultricies vitae ligula. Vestibulum in neque sapien. Sed vitae purus sit amet felis interdum porttitor vel sed arcu. Ut quis venenatis eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean pulvinar tellus a nunc egestas cursus. Phasellus eu velit rutrum diam cursus pulvinar. Duis consequat libero quis lectus aliquet eleifend. Curabitur mi libero, dictum at dapibus at, accumsan a dolor. Aliquam metus."));
		Assert.areEqual("f8146961d9b73d8da49ccd526fca65439cdd5b402f76971556d5f52fd129843e", Crypto.SHA256("12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
		Assert.areEqual([0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55].toString(), Crypto.SHA256("", { asBytes: true }).toString());
		Assert.areEqual("\xE3\xB0\xC4\x42\x98\xFC\x1C\x14\x9A\xFB\xF4\xC8\x99\x6F\xB9\x24\x27\xAE\x41\xE4\x64\x9B\x93\x4C\xA4\x95\x99\x1B\x78\x52\xB8\x55", Crypto.SHA256("", { asString: true }));
	}

}));
<commit_msg>Removed obsolete test file.<commit_after><|endoftext|>


<commit_before>import Component from '@ember/component';
import layout from '../templates/components/error-page';

export default Component.extend({
  layout,

  didInsertElement() {
    setTimeout(() => {
      const tom = this.element.querySelector('.tomster');
      if (tom) { tom.classList.add('hello'); }
    }, 1000);
  }
});
<commit_msg>Confirm element exists (#945)<commit_after>import Component from '@ember/component';
import layout from '../templates/components/error-page';

export default Component.extend({
  layout,

  didInsertElement() {
    setTimeout(() => {
      if (!this.element) { return; }
      const tom = this.element.querySelector('.tomster');
      if (tom) { tom.classList.add('hello'); }
    }, 1000);
  }
});
<|endoftext|>


<commit_before>"use strict"

const fs = require("fs")

console.log("Reading file...")
const source = fs.readFileSync("compress.js")
console.log("Source length: " + source.length)

var hist, i, max, symbol

console.log("Building histogram...")
hist = []
for (i = 0; i < 256; i++) hist[i] = 0

max = 0
for (i = 0; i < source.length; i++) {
  symbol = source[i]
  hist[symbol]++
  if (hist[symbol] > max) max = hist[symbol]
}

for (i = 0; i < 256; i++) {
  hist[i] = hist[i] !== 0 ? Math.round(max / hist[i]) : 0
}

var free, table

console.log("Building table...")
table = new Array(4096)
for (i = 0; i < table.length; i++) table[i] = []

free = 1
for (i = 0; i < table.length; i++) {
  for (symbol = 0; symbol < 256; symbol++) {
    if (hist[symbol] === 0) continue
    if (free < table.length && (i % hist[symbol]) === 0) {
      table[free][256] = i
      table[free][257] = symbol
      table[i][symbol] = free++
    }
  }
}

var buffer, state

console.log("Encoding...")
buffer = []
state = 0
for (i = 0; i < source.length; i++) {
  symbol = source[i]
  if (table[state][symbol] === undefined) {
    buffer.push(state) // 12 bits!
    state = 0
  }

  state = table[state][symbol]
}

if (state !== 0) buffer.push(state) // 12 bits

console.log("Target length: " + (buffer.length * 1.5))

var copy

console.log("Decoding...")
copy = []
for (i = 0; i < buffer.length; i++) {
  state = buffer[i]
  while (true) {
    if (table[state][256] === undefined) break
    copy.push(table[state][257])
    state = table[state][256]
  }
}

console.log("Copy length: " + copy.length)
fs.writeFileSync("copy.txt", Buffer.from(copy))
<commit_msg>Scrambled<commit_after>"use strict"

const fs = require("fs")

console.log("Reading file...")
const source = fs.readFileSync("compress.js")
console.log("Source length: " + source.length)

var hist, i, max, symbol

console.log("Building histogram...")
hist = []
for (i = 0; i < 256; i++) hist[i] = 0

max = 0
for (i = 0; i < source.length; i++) {
  symbol = source[i]
  hist[symbol]++
  if (hist[symbol] > max) max = hist[symbol]
}

for (i = 0; i < 256; i++) {
  hist[i] = hist[i] !== 0 ? Math.round(max / hist[i]) : 0
}

var free, table

console.log("Building table...")
table = new Array(4096)
for (i = 0; i < table.length; i++) table[i] = []

free = 1
for (i = 0; i < table.length; i++) {
  for (symbol = 0; symbol < 256; symbol++) {
    if (free >= table.length) break
    if (hist[symbol] !== 0 && (i % hist[symbol]) === 0) {
      table[free][256] = i
      table[free][257] = symbol
      table[i][symbol] = free++
    }
  }
}

var buffer, state

console.log("Encoding...")
buffer = []
state = 0 // never output as code?
for (i = 0; i < source.length; i++) {
  symbol = source[i]
  if (table[state][symbol] === undefined) {
    buffer.push(state) // 12 bits!
    state = 0
  }

  state = table[state][symbol]
}

if (state !== 0) buffer.push(state) // 12 bits

console.log("Target length: " + (buffer.length * 1.5))

var copy

console.log("Decoding...")
copy = []
for (i = 0; i < buffer.length; i++) {
  state = buffer[i]
  while (true) {
    if (table[state][256] === undefined) break
    copy.push(table[state][257])
    state = table[state][256]
  }
}

console.log("Copy length: " + copy.length)
fs.writeFileSync("copy.txt", Buffer.from(copy))
<|endoftext|>


<commit_before>import React, { useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import PropTypes from 'prop-types';
import ClassNames from 'classnames';
import { canDrag, canDrop } from './utils';

import RemoveComponent from './RemoveComponent';

const ItemTypes = { TAG: 'tag' };

const Tag = (props) => {
  const tagRef = useRef(null);
  const [{ isDragging }, drag] = useDrag(() => ({
    type: ItemTypes.TAG,
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
    item: props,
    canDrag: () => canDrag(props),
  }));

  const [, drop] = useDrop(() => ({
    accept: ItemTypes.TAG,
    drop: (item, monitor) => {
      const dragIndex = monitor.getItem().index;
      const hoverIndex = index;
      if (dragIndex === hoverIndex) {
        return;
      }

      const hoverBoundingRect = tagRef.current.getBoundingClientRect();
      const hoverMiddleX =
        (hoverBoundingRect.right - hoverBoundingRect.left) / 2;
      const clientOffset = monitor.getClientOffset();
      const hoverClientX = clientOffset.x - hoverBoundingRect.left;

      // Only perform the move when the mouse has crossed half of the items width
      /* istanbul ignore next */
      if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) {
        return;
      }
      /* istanbul ignore next */
      if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) {
        return;
      }
      props.moveTag(dragIndex, hoverIndex);
    },
    canDrop: (item) => canDrop(item),
  }));

  drag(drop(tagRef));

  const label = props.tag[props.labelField];
  const { readOnly, tag, classNames, index } = props;
  const { className = '' } = tag;
  /* istanbul ignore next */
  const opacity = isDragging ? 0 : 1;
  const tagComponent = (
    <span
      ref={tagRef}
      className={ClassNames('tag-wrapper', classNames.tag, className)}
      style={{
        opacity,
        cursor: canDrag(props) ? 'move' : 'auto',
      }}
      onClick={props.onTagClicked}
      onTouchStart={props.onTagClicked}>
      {label}
      <RemoveComponent
        tag={props.tag}
        className={classNames.remove}
        removeComponent={props.removeComponent}
        onRemove={props.onDelete}
        readOnly={readOnly}
        index={index}
        onKeyDown={onkeydown}
      />
    </span>
  );
  return tagComponent;
};

Tag.propTypes = {
  labelField: PropTypes.string,
  onDelete: PropTypes.func.isRequired,
  tag: PropTypes.shape({
    id: PropTypes.string.isRequired,
    className: PropTypes.string,
    key: PropTypes.string,
  }),
  moveTag: PropTypes.func,
  removeComponent: PropTypes.func,
  onTagClicked: PropTypes.func,
  classNames: PropTypes.object,
  readOnly: PropTypes.bool,
  index: PropTypes.number.isRequired,
};

Tag.defaultProps = {
  labelField: 'text',
  readOnly: false,
};

export default Tag;
<commit_msg>fix: remove the code for checking if source tag has crossed the destination tag by 50% (#744)<commit_after>import React, { useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import PropTypes from 'prop-types';
import ClassNames from 'classnames';
import { canDrag, canDrop } from './utils';

import RemoveComponent from './RemoveComponent';

const ItemTypes = { TAG: 'tag' };

const Tag = (props) => {
  const tagRef = useRef(null);
  const { readOnly, tag, classNames, index } = props;

  const [{ isDragging }, drag] = useDrag(() => ({
    type: ItemTypes.TAG,
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
    item: props,
    canDrag: () => canDrag(props),
  }));

  const [, drop] = useDrop(() => ({
    accept: ItemTypes.TAG,
    drop: (item, monitor) => {
      const dragIndex = item.index;
      const hoverIndex = index;
      if (dragIndex === hoverIndex) {
        return;
      }

      // Remove this until drag preview is integrated
      // const hoverBoundingRect = document
      //   .getElementsByClassName('tag-wrapper')
      //   [hoverIndex].getBoundingClientRect();
      //
      // const hoverMiddleX =
      //   (hoverBoundingRect.right - hoverBoundingRect.left) / 2;
      // const clientOffset = monitor.getClientOffset();
      // const hoverClientX = clientOffset.x - hoverBoundingRect.left;
      // Only perform the move when the mouse has crossed half of the items width
      /* istanbul ignore next */
      // if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) {
      //   return;
      // }
      // /* istanbul ignore next */
      // if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) {
      //   return;
      // }
      props.moveTag(dragIndex, hoverIndex);
    },
    canDrop: (item) => canDrop(item),
  }));

  drag(drop(tagRef));

  const label = props.tag[props.labelField];
  const { className = '' } = tag;
  /* istanbul ignore next */
  const opacity = isDragging ? 0 : 1;
  const tagComponent = (
    <span
      ref={tagRef}
      className={ClassNames('tag-wrapper', classNames.tag, className)}
      style={{
        opacity,
        cursor: canDrag(props) ? 'move' : 'auto',
      }}
      onClick={props.onTagClicked}
      onTouchStart={props.onTagClicked}>
      {label}
      <RemoveComponent
        tag={props.tag}
        className={classNames.remove}
        removeComponent={props.removeComponent}
        onRemove={props.onDelete}
        readOnly={readOnly}
        index={index}
        onKeyDown={onkeydown}
      />
    </span>
  );
  return tagComponent;
};

Tag.propTypes = {
  labelField: PropTypes.string,
  onDelete: PropTypes.func.isRequired,
  tag: PropTypes.shape({
    id: PropTypes.string.isRequired,
    className: PropTypes.string,
    key: PropTypes.string,
  }),
  moveTag: PropTypes.func,
  removeComponent: PropTypes.func,
  onTagClicked: PropTypes.func,
  classNames: PropTypes.object,
  readOnly: PropTypes.bool,
  index: PropTypes.number.isRequired,
};

Tag.defaultProps = {
  labelField: 'text',
  readOnly: false,
};

export default Tag;
<|endoftext|>


<commit_before>var Phaser = require('phaser');
var _ = require('lodash');

var self = {};

self.createColorImage = function(game, source, color="#ffffff") {
	var color = Phaser.Color.hexToColor(color);

	return game.make.image(0, 0, game.add.bitmapData(source.width, source.height).fill(color.r, color.g, color.b)
	.blendDestinationAtop()
	.draw(source, 0, 0, source.width, source.height));
}

self.blink = function(game,objs,options){
	var defaults = {
		color:"#ffffff",
		count:2,
		delay:50,
	}
	options = _.extend({},defaults,options);
	var noTint = '0xffffff';
	if(!_.isArray(objs)) objs = [objs];
	_.each(objs,function(obj,i){
		var img = self.createColorImage(game,obj);
		var originalTexture = obj.texture;
		var oldTint = obj.tint;
		var c = true;

		self.repeat(game,options.delay,options.count,function(){
			if(c){
				obj.texture = img.texture;
				obj.tint = noTint;
			} else {
				obj.texture = originalTexture;
				obj.tint = oldTint;
			}
			c = !c;
		},function(){
			obj.texture = originalTexture;
			img.destroy();
		})
	})
}

self.repeat = function(game,delay,count,callback,onComplete=null,playAtStart=false){
	var timer = game.time.create(false);
	if(playAtStart) callback();
	timer.repeat(delay,playAtStart ? count-1 : count,callback)
	timer.start();
	timer.onComplete.addOnce(function(){
		if(onComplete) onComplete();
		timer.destroy();
	});
}

self.loopUntil = function(game,delay,until,callback,onComplete=null){
	var timer = game.time.create(false);
	timer.loop(delay,callback)
	timer.start();
	timer.add(until,function(){
		if(onComplete) onComplete();
		timer.destroy();
	})
}

self.ninePatch = function(game,options){
	options = _.extend({},{width:100,key:"9window_",height:100},options);
	var group = game.add.group();
	var i = 1;
	var slices = [];
	var cSlot = 0;

	_.each([-1,0,1],function(cVal,c){ // cols
		var rSlot = 0;
		_.each([-1,0,1],function(rVal,r){ // rows
			var slicez = game.make.sprite(0,0,'gui');
			slicez.frameName = options.key+i+_.padLeft(1,4,'0');
			var slice = group.add(game.add.tileSprite(0,0,slicez.width,slicez.height,'gui',options.key+i+_.padLeft(1,4,'0')));
			slicez.destroy();

			slice.x = Math.ceil(rSlot+(rVal==-1 ? -slice.width : 0)+(rVal==1 ? options.width : 0))-r;
			slice.y = Math.ceil(cSlot+(cVal==-1 ? -slice.height : 0)+(cVal==1 ? options.height : 0))-c;
			if(rVal===0) slice.width = options.width;
			if(cVal===0) slice.height = options.height;
			slices.push(slice);
			i++;
		});
	});
	return group;
}

self.randInRange = function(point,range){
	var a = self.rand(0,360) * (Math.PI / 180);
	var d = self.rand(0,(range/2));
	return {
		x:Math.cos(a) * d,
		y:Math.sin(a) * d
	}
}

self.rand = function(min=0, max=100){
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

self.getRangeIndexByValue = function(length,current,modes,ASC=true){
	if(current>=length) return modes;
	if(current<=0) return 1;
	if(ASC) {
		return Math.ceil(current/Math.floor(length/modes));
	} else {
		return Math.ceil((length-current)/Math.floor(length/modes));
	}
}

self.getModeByValue = function(length,current,modes,ASC=true){
	return modes[self.getRangeIndexByValue(length,current,modes.length,ASC)-1];
}

self.randPorRange = function(val,por){
	var part = Math.ceil(val*por/100);
	return self.rand(val-part,val+part);
}

self.toHHMMSS = function ($) {
	var sec_num = parseInt($, 10);
	var hours   = Math.floor(sec_num / 3600);
	var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
	var seconds = sec_num - (hours * 3600) - (minutes * 60);

	if (hours<10) hours="0"+hours;
	if (minutes<10) minutes="0"+minutes;
	if (seconds<10) seconds="0"+seconds;
	return hours+':'+minutes+':'+seconds;
}

self.renameAttr = function(obj,name,replace){
	obj[replace] = obj[name];
	delete obj[name];
	return obj;
}

self.frameAtlas = function(atlas){
	var add = {
		rotated:false,
		trimmed:true
	}

	var frames = [];
	_.forEach(atlas.sprites,function(sprite,spriteName){
		var c = 0;
		_.forEach(sprite.frames,function(frame,k){
			frame = _.extend(frame,add);
			frame = self.renameAttr(frame,'s','spriteSourceSize')
			frame = self.renameAttr(frame,'f','frame')

			frame.sourceSize = {
				w:frame.spriteSourceSize.w,
				h:frame.spriteSourceSize.h
			}

			if(frame.r){
				for(var i=0;i<frame.r;i++) {
					var clone = _.clone(frame);
					clone.filename = spriteName+_.padLeft(++c, 4, '0');
					frames.push(clone);
				}
			} else {
				frame.filename = spriteName+_.padLeft(++c, 4, '0');
				frames.push(frame);
			}
		});
	});

	atlas.frames = frames;
	return _.omit(atlas,['sprites']);
}

self.ifTrue = function($,def=null){
	return $ ? $ : def;
}

self.loadAssets = function(game,assets){
	var i;
	for(i in assets.atlas) {
		game.load.atlasJSONHash(i, assets.atlas[i].image, self.ifTrue(assets.atlas[i].jsonUrl), self.ifTrue(assets.atlas[i].json));
	}
	for(i in assets.images) game.load.image(i, assets.images[i]);
	for(i in assets.sprites) game.load.spritesheet(i, assets.sprites[i].image, assets.sprites[i].width, assets.sprites[i].height, assets.sprites[i].frames);
	for(i in assets.audio) game.load.audio(i, assets.audio[i]);
}

self.copyPos = function(obj1,obj2){
	obj1.x=obj2.x;
	obj1.y=obj2.y;
}

self.$newSprite = function(game,key,options){
	var defaults = {
		x:0,
		y:0,
		frame:undefined,
		group:undefined
	};
	options = _.extend({},defaults,options);
	var tmpObj = game.add.sprite(options.x,options.y,key,options.frame,options.group);
	// prototypes
	tmpObj.$set = function(prop,val){
		if(typeof prop==='string' && !!val){
			this[prop]=val;
		} else {
			for(var i in prop){
				if(i.indexOf('.')==-1){
					this[i]=prop[i];
				} else {
					var pathObj = i.split(".");
					var c = this;
					for(var k=0;k<pathObj.length-1;k++) c=c[pathObj[k]];
					c[pathObj[pathObj.length-1]]=prop[i];
				}
			}
		}
		return this;
	};

	tmpObj.$tint = function(color='ffffff'){
		this.tint = '0x'+color.replace(/#/g,'');
		return this;
	}

	tmpObj.$into = function(group){
		group.add(this);
		return this;
	};

	tmpObj.$mid = function(){
		this.anchor.setTo(0.5);
		return this;
	}

	tmpObj.$atlasImg = function(name,frame=1){
		this.frameName = name+_.padLeft(frame,4,'0');
		return this;
	}

	tmpObj.$atlasAnims = function(name,anims){
		self._loadAltasAnimation(this,name,anims);
		return this;
	}

	tmpObj.$fixPos = function(){
		this.x = Math.floor(this.x);
		this.y = Math.floor(this.y);
		return this;
	}

	tmpObj.$copyPos = function(target){
		this.x = target.x;
		this.y = target.y;
		return this;
	};

	return tmpObj;
}

self.setAtlasFrame = function(objs,frame=0,name=''){
	if(!_.isArray(objs)) objs = [objs];
	_.map(objs,function(obj,k){
		if(!obj.name) console.error('object without name');
		obj.frameName = obj.name+_.padLeft(frame,4,'0');
	})
	return objs;
}

self.loadAltasAnimation = function(obj,name,anims,repeat={}){
	_.each(anims,function(animation,k){
		obj.animations.add(k, Phaser.Animation.generateFrameNames(name, animation.start, animation.end, '', 4), animation.rate, (repeat[k] ? true : false));
	})
}

self.por = function(val,por,plus=true,fix=0){
	return Number(((val * por / 100)*(plus ? 1 : -1)+val).toFixed(fix));
}

self.dist = function(obj1,obj2){
	return Math.sqrt(Math.pow(obj1.x-obj2.x,2)+Math.pow(obj1.y-obj2.y,2));
}

self.setBtn = function(obj,callback=null){
	if(!obj) return;
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(!obj.input) return;
	// obj.input.pixelPerfectClick = true;
	// obj.input.pixelPerfectOver = true;
	obj.input.useHandCursor = true;
	if(callback){
		obj.events.onInputUp.add(function(e){
			callback.apply(this,[e]);
		});
	}
	return obj;
}

self.setHover = function(obj,callback=null,callback2=null){
	if(!obj) return;
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(!obj.input) return;
	obj.input.useHandCursor = true;
	if(callback){
		obj.events.onInputOver.add(function(e){
			callback.apply(this,[e]);
		});
	}
	if(callback2){
		obj.events.onInputOut.add(function(e){
			callback2.apply(this,[e]);
		});
	}
	return obj;
}

self.btnAudio = function(obj,audioHover=null,audioClick=null){
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(audioHover){
		obj.events.onInputOver.add(function(e){
			audioHover.play();
		});
	}
	if(audioClick){
		obj.events.onInputUp.add(function(e){
			audioClick.play();
		});
	}
	return obj;
}

module.exports = self;
<commit_msg>Update utils.js<commit_after>var Phaser = require('phaser');
var _ = require('lodash');

var self = {};

self.createColorImage = function(game, source, color="#ffffff") {
	var color = Phaser.Color.hexToColor(color);

	return game.make.image(0, 0, game.add.bitmapData(source.width, source.height).fill(color.r, color.g, color.b)
	.blendDestinationAtop()
	.draw(source, 0, 0, source.width, source.height));
}

self.blink = function(game,objs,options){
	var defaults = {
		color:"#ffffff",
		count:2,
		delay:50,
	}
	options = _.extend({},defaults,options);
	var noTint = '0xffffff';
	if(!_.isArray(objs)) objs = [objs];
	_.each(objs,function(obj,i){
		var img = self.createColorImage(game,obj);
		var originalTexture = obj.texture;
		var oldTint = obj.tint;
		var c = true;

		self.repeat(game,options.delay,options.count,function(){
			if(c){
				obj.texture = img.texture;
				obj.tint = noTint;
			} else {
				obj.texture = originalTexture;
				obj.tint = oldTint;
			}
			c = !c;
		},function(){
			obj.texture = originalTexture;
			img.destroy();
		})
	})
}

self.repeat = function(game,delay,count,callback,onComplete=null,playAtStart=false){
	var timer = game.time.create(false);
	if(playAtStart) callback();
	timer.repeat(delay,playAtStart ? count-1 : count,callback)
	timer.start();
	timer.onComplete.addOnce(function(){
		if(onComplete) onComplete();
		timer.destroy();
	});
}

self.loopUntil = function(game,delay,until,callback,onComplete=null){
	var timer = game.time.create(false);
	timer.loop(delay,callback)
	timer.start();
	timer.add(until,function(){
		if(onComplete) onComplete();
		timer.destroy();
	})
}

self.ninePatch = function(game,options){
	options = _.extend({},{width:100,key:"9window_",height:100},options);
	var group = game.add.group();
	var i = 1;
	var slices = [];
	var cSlot = 0;

	_.each([-1,0,1],function(cVal,c){ // cols
		var rSlot = 0;
		_.each([-1,0,1],function(rVal,r){ // rows
			var slicez = game.make.sprite(0,0,'gui');
			slicez.frameName = options.key+i+_.padLeft(1,4,'0');
			var slice = group.add(game.add.tileSprite(0,0,slicez.width,slicez.height,'gui',options.key+i+_.padLeft(1,4,'0')));
			slicez.destroy();

			slice.x = Math.ceil(rSlot+(rVal==-1 ? -slice.width : 0)+(rVal==1 ? options.width : 0))-r;
			slice.y = Math.ceil(cSlot+(cVal==-1 ? -slice.height : 0)+(cVal==1 ? options.height : 0))-c;
			if(rVal===0) slice.width = options.width;
			if(cVal===0) slice.height = options.height;
			slices.push(slice);
			i++;
		});
	});
	return group;
}

self.randInRange = function(point,range){
	var a = self.rand(0,360) * (Math.PI / 180);
	var d = self.rand(0,(range/2));
	return {
		x:Math.cos(a) * d,
		y:Math.sin(a) * d
	}
}

self.rand = function(min=0, max=100){
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

self.getRangeIndexByValue = function(length,current,modes,ASC=true){
	if(current>=length) return modes;
	if(current<=0) return 1;
	if(ASC) {
		return Math.ceil(current/Math.floor(length/modes));
	} else {
		return Math.ceil((length-current)/Math.floor(length/modes));
	}
}

self.getModeByValue = function(length,current,modes,ASC=true){
	return modes[self.getRangeIndexByValue(length,current,modes.length,ASC)-1];
}

self.randPorRange = function(val,por){
	var part = Math.ceil(val*por/100);
	return self.rand(val-part,val+part);
}

self.toHHMMSS = function ($) {
	var sec_num = parseInt($, 10);
	var hours   = Math.floor(sec_num / 3600);
	var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
	var seconds = sec_num - (hours * 3600) - (minutes * 60);

	if (hours<10) hours="0"+hours;
	if (minutes<10) minutes="0"+minutes;
	if (seconds<10) seconds="0"+seconds;
	return hours+':'+minutes+':'+seconds;
}

self.renameAttr = function(obj,name,replace){
	obj[replace] = obj[name];
	delete obj[name];
	return obj;
}

self.frameAtlas = function(atlas){
	var add = {
		rotated:false,
		trimmed:true
	}

	var frames = [];
	_.forEach(atlas.sprites,function(sprite,spriteName){
		var c = 0;
		_.forEach(sprite.frames,function(frame,k){
			frame = _.extend(frame,add);
			frame = self.renameAttr(frame,'s','spriteSourceSize')
			frame = self.renameAttr(frame,'f','frame')

			frame.sourceSize = {
				w:frame.spriteSourceSize.w,
				h:frame.spriteSourceSize.h
			}

			if(frame.r){
				for(var i=0;i<frame.r;i++) {
					var clone = _.clone(frame);
					clone.filename = spriteName+_.padLeft(++c, 4, '0');
					frames.push(clone);
				}
			} else {
				frame.filename = spriteName+_.padLeft(++c, 4, '0');
				frames.push(frame);
			}
		});
	});

	atlas.frames = frames;
	return _.omit(atlas,['sprites']);
}

self.ifTrue = function($,def=null){
	return $ ? $ : def;
}

self.loadAssets = function(game,assets){
	var i;
	for(i in assets.atlas) {
		game.load.atlasJSONHash(i, assets.atlas[i].image, self.ifTrue(assets.atlas[i].jsonUrl), self.ifTrue(assets.atlas[i].json));
	}
	for(i in assets.images) game.load.image(i, assets.images[i]);
	for(i in assets.sprites) game.load.spritesheet(i, assets.sprites[i].image, assets.sprites[i].width, assets.sprites[i].height, assets.sprites[i].frames);
	for(i in assets.audio) game.load.audio(i, assets.audio[i]);
}

self.copyPos = function(obj1,obj2){
	obj1.x=obj2.x;
	obj1.y=obj2.y;
}

self.$newSprite = function(game,key,options){
	var defaults = {
		x:0,
		y:0,
		frame:undefined,
		group:undefined
	};
	options = _.extend({},defaults,options);
	var tmpObj = game.add.sprite(options.x,options.y,key,options.frame,options.group);
	// prototypes
	tmpObj.$set = function(prop,val){
		if(typeof prop==='string' && !!val){
			this[prop]=val;
		} else {
			for(var i in prop){
				if(i.indexOf('.')==-1){
					this[i]=prop[i];
				} else {
					var pathObj = i.split(".");
					var c = this;
					for(var k=0;k<pathObj.length-1;k++) c=c[pathObj[k]];
					c[pathObj[pathObj.length-1]]=prop[i];
				}
			}
		}
		return this;
	};

	tmpObj.$tint = function(color='ffffff'){
		this.tint = '0x'+color.replace(/#/g,'');
		return this;
	}

	tmpObj.$into = function(group){
		group.add(this);
		return this;
	};

	tmpObj.$mid = function(){
		this.anchor.setTo(0.5);
		return this;
	}

	tmpObj.$atlasImg = function(name,frame=1){
		this.frameName = name+_.padLeft(frame,4,'0');
		return this;
	}

	tmpObj.$atlasAnims = function(name,anims){
		self.loadAltasAnimation(this,name,anims);
		return this;
	}

	tmpObj.$fixPos = function(){
		this.x = Math.floor(this.x);
		this.y = Math.floor(this.y);
		return this;
	}

	tmpObj.$copyPos = function(target){
		this.x = target.x;
		this.y = target.y;
		return this;
	};

	return tmpObj;
}

self.setAtlasFrame = function(objs,frame=0,name=''){
	if(!_.isArray(objs)) objs = [objs];
	_.map(objs,function(obj,k){
		if(!obj.name) console.error('object without name');
		obj.frameName = obj.name+_.padLeft(frame,4,'0');
	})
	return objs;
}

self.loadAltasAnimation = function(obj,name,anims,repeat={}){
	_.each(anims,function(animation,k){
		obj.animations.add(k, Phaser.Animation.generateFrameNames(name, animation.start, animation.end, '', 4), animation.rate, (repeat[k] ? true : false));
	})
}

self.por = function(val,por,plus=true,fix=0){
	return Number(((val * por / 100)*(plus ? 1 : -1)+val).toFixed(fix));
}

self.dist = function(obj1,obj2){
	return Math.sqrt(Math.pow(obj1.x-obj2.x,2)+Math.pow(obj1.y-obj2.y,2));
}

self.setBtn = function(obj,callback=null){
	if(!obj) return;
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(!obj.input) return;
	// obj.input.pixelPerfectClick = true;
	// obj.input.pixelPerfectOver = true;
	obj.input.useHandCursor = true;
	if(callback){
		obj.events.onInputUp.add(function(e){
			callback.apply(this,[e]);
		});
	}
	return obj;
}

self.setHover = function(obj,callback=null,callback2=null){
	if(!obj) return;
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(!obj.input) return;
	obj.input.useHandCursor = true;
	if(callback){
		obj.events.onInputOver.add(function(e){
			callback.apply(this,[e]);
		});
	}
	if(callback2){
		obj.events.onInputOut.add(function(e){
			callback2.apply(this,[e]);
		});
	}
	return obj;
}

self.btnAudio = function(obj,audioHover=null,audioClick=null){
	if(!obj.inputEnabled) obj.inputEnabled = true;
	if(audioHover){
		obj.events.onInputOver.add(function(e){
			audioHover.play();
		});
	}
	if(audioClick){
		obj.events.onInputUp.add(function(e){
			audioClick.play();
		});
	}
	return obj;
}

module.exports = self;
<|endoftext|>


<commit_before>YUI.add('moodle-core-formautosubmit',
    function(Y) {
        // The CSS selectors we use
        var CSS = {
            AUTOSUBMIT : 'autosubmit'
        };

        var FORMAUTOSUBMITNAME = 'core-formautosubmit';

        var FORMAUTOSUBMIT = function() {
            FORMAUTOSUBMIT.superclass.constructor.apply(this, arguments);
        }

        //  We only want to initialize the module fully once
        var INITIALIZED = false;

        Y.extend(FORMAUTOSUBMIT, Y.Base, {

            /**
              * Initialize the module
              */
            initializer : function(config) {
                // We only apply the delegation once
                if (!INITIALIZED) {
                    INITIALIZED = true;
                    var applyto = Y.one('body');

                    // We don't listen for change events by default as using the keyboard triggers these too.
                    applyto.delegate('key', this.process_changes, 'press:13', 'select.' + CSS.AUTOSUBMIT, this);
                    applyto.delegate('click', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);

                    if (Y.UA.os == 'macintosh' && Y.UA.webkit) {
                        // Macintosh webkit browsers like change events, but non-macintosh webkit browsers don't.
                        applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
                    }
                    if (Y.UA.ios) {
                        // IOS doesn't trigger click events because it's touch-based.
                        applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
                    }
                }

                // Assign this select items 'nothing' value and lastindex (current value)
                if (this.get('selectid')) {
                    var thisselect = Y.one('select#' + this.get('selectid'));
                    if (thisselect) {
                        if (this.get('nothing')) {
                            thisselect.setData('nothing', this.get('nothing'));
                        }
                        thisselect.setData('startindex', thisselect.get('selectedIndex'));
                    } else {
                        Y.log("Warning: A single_select element was renderered, but the output is not displayed on the page.");
                    }
                }
            },

            /**
             * Check whether the select element was changed
             */
            check_changed : function(e) {
                var select = e.target.ancestor('select.' + CSS.AUTOSUBMIT, true);
                if (!select) {
                    return false;
                }

                var nothing = select.getData('nothing');
                var startindex = select.getData('startindex');
                var currentindex = select.get('selectedIndex');

                var previousindex = select.getAttribute('data-previousindex');
                select.setAttribute('data-previousindex', currentindex);
                if (!previousindex) {
                    previousindex = startindex;
                }

                // Check whether the field has changed, and is not the 'nothing' value
                if ((nothing===false || select.get('value') != nothing) && startindex != select.get('selectedIndex') && currentindex != previousindex) {
                    return select;
                }
                return false;
            },

            /**
             * Process any changes
             */
            process_changes : function(e) {
                var select = this.check_changed(e);
                if (select) {
                    var form = select.ancestor('form', true);
                    form.submit();
                }
            }
        },
        {
            NAME : FORMAUTOSUBMITNAME,
            ATTRS : {
                selectid : {
                    'value' : ''
                },
                nothing : {
                    'value' : ''
                },
                ignorechangeevent : {
                    'value' : false
                }
            }
        });

        M.core = M.core || {};
        M.core.init_formautosubmit = M.core.init_formautosubmit || function(config) {
            return new FORMAUTOSUBMIT(config);
        };
    },
    '@VERSION@', {
        requires : ['base', 'event-key']
    }
);
<commit_msg>MDL-37366 Fix JS Lint issues with moodle-core-formautosubmit<commit_after>YUI.add('moodle-core-formautosubmit',
    function(Y) {
        var CSS,
            FORMAUTOSUBMITNAME = 'core-formautosubmit',
            FORMAUTOSUBMIT,
            INITIALIZED = false;

        // The CSS selectors we use
        CSS = {
            AUTOSUBMIT : 'autosubmit'
        };

        FORMAUTOSUBMIT = function() {
            FORMAUTOSUBMIT.superclass.constructor.apply(this, arguments);
        };

        Y.extend(FORMAUTOSUBMIT, Y.Base, {

            /**
              * Initialize the module
              */
            initializer : function() {
                // Set up local variables
                var applyto,
                    thisselect;
                // We only apply the delegation once
                if (!INITIALIZED) {
                    INITIALIZED = true;
                    applyto = Y.one('body');

                    // We don't listen for change events by default as using the keyboard triggers these too.
                    applyto.delegate('key', this.process_changes, 'press:13', 'select.' + CSS.AUTOSUBMIT, this);
                    applyto.delegate('click', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);

                    if (Y.UA.os === 'macintosh' && Y.UA.webkit) {
                        // Macintosh webkit browsers like change events, but non-macintosh webkit browsers don't.
                        applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
                    }
                    if (Y.UA.ios) {
                        // IOS doesn't trigger click events because it's touch-based.
                        applyto.delegate('change', this.process_changes, 'select.' + CSS.AUTOSUBMIT, this);
                    }
                }

                // Assign this select items 'nothing' value and lastindex (current value)
                if (this.get('selectid')) {
                    thisselect = Y.one('select#' + this.get('selectid'));
                    if (thisselect) {
                        if (this.get('nothing')) {
                            thisselect.setData('nothing', this.get('nothing'));
                        }
                        thisselect.setData('startindex', thisselect.get('selectedIndex'));
                    } else {
                        Y.log("Warning: A single_select element was renderered, but the output is not displayed on the page.");
                    }
                }
            },

            /**
             * Check whether the select element was changed
             */
            check_changed : function(e) {
                var select,
                    nothing,
                    startindex,
                    currentindex,
                    previousindex;
                select = e.target.ancestor('select.' + CSS.AUTOSUBMIT, true);
                if (!select) {
                    return false;
                }

                nothing = select.getData('nothing');
                startindex = select.getData('startindex');
                currentindex = select.get('selectedIndex');

                previousindex = select.getAttribute('data-previousindex');
                select.setAttribute('data-previousindex', currentindex);
                if (!previousindex) {
                    previousindex = startindex;
                }

                // Check whether the field has changed, and is not the 'nothing' value
                if ((nothing===false || select.get('value') !== nothing)
                        && startindex !== select.get('selectedIndex') && currentindex !== previousindex) {
                    return select;
                }
                return false;
            },

            /**
             * Process any changes
             */
            process_changes : function(e) {
                var select = this.check_changed(e),
                    form;
                if (select) {
                    form = select.ancestor('form', true);
                    form.submit();
                }
            }
        },
        {
            NAME : FORMAUTOSUBMITNAME,
            ATTRS : {
                selectid : {
                    'value' : ''
                },
                nothing : {
                    'value' : ''
                },
                ignorechangeevent : {
                    'value' : false
                }
            }
        });

        M.core = M.core || {};
        M.core.init_formautosubmit = M.core.init_formautosubmit || function(config) {
            return new FORMAUTOSUBMIT(config);
        };
    },
    '@VERSION@', {
        requires : ['base', 'event-key']
    }
);
<|endoftext|>


<commit_before>var Transform = require('pipestream').Transform;
var util = require('util');
var LENGTH = 3072;

function ReplacePatternTransform(pattern, value) {
	if (!(this instanceof ReplacePatternTransform)) {
		  return new ReplacePatternTransform(options);
	  }

	Transform.call(this);

	this._pattern = pattern;
	this._value = value == null ? '' : value + '';
	this._rest = '';
}

util.inherits(ReplacePatternTransform, Transform);

var proto = ReplacePatternTransform.prototype;
proto._transform = function(chunk, encoding, callback) {
	if (chunk != null) {
		chunk = this._rest + chunk;
		var index = 0;
		var value = this._value;
		var result = chunk.replace(this._pattern, function() {
			var matcher = replace(arguments, value);
			var lastIndex = arguments.length - 1;
			index = arguments[lastIndex - 1] + arguments[lastIndex].length;
			return matcher;
		});
		index = Math.max(index, chunk.length + 1 - LENGTH);
		this._rest = chunk.substring(index);
		chunk = result.substring(0, result.length - this._rest.length);
	} else if (this._rest) {
		chunk = this._rest.replace(this._pattern, function() {
			return replace(arguments, this._value);
		});
	}

	callback(null, chunk);
};

function replace(args, replacement) {
	return replacement ? replacement.replace(/(^|.)?(\$[1-9])/g,
			function(matched, $1, $2) {
		return $1 == '\\' ? $2 : ($1 || '') + (args[$2].substring(1) || '');
	}) : '';
}

module.exports = ReplacePatternTransform;<commit_msg>replace content<commit_after>var Transform = require('pipestream').Transform;
var util = require('util');
var LENGTH = 3072;

function ReplacePatternTransform(pattern, value) {
	if (!(this instanceof ReplacePatternTransform)) {
		  return new ReplacePatternTransform(options);
	  }

	Transform.call(this);

	this._pattern = pattern;
	this._value = value == null ? '' : value + '';
	this._rest = '';
}

util.inherits(ReplacePatternTransform, Transform);

var proto = ReplacePatternTransform.prototype;
proto._transform = function(chunk, encoding, callback) {
	if (chunk != null) {
		chunk = this._rest + chunk;
		var index = 0;
		var value = this._value;
		var result = chunk.replace(this._pattern, function() {
			var matcher = replace(arguments, value);
			var lastIndex = arguments.length - 1;
			index = arguments[lastIndex - 1] + arguments[lastIndex].length;
			return matcher;
		});
		index = Math.max(index, chunk.length + 1 - LENGTH);
		this._rest = chunk.substring(index);
		chunk = result.substring(0, result.length - this._rest.length);
	} else if (this._rest) {
		chunk = this._rest.replace(this._pattern, function() {
			return replace(arguments, this._value);
		});
	}

	callback(null, chunk);
};

function replace(args, replacement) {
	return replacement ? replacement.replace(/(^|.)?(\$[1-9])/g,
			function(matched, $1, $2) {
		return $1 == '\\' ? $2 : ($1 || '') + (args[$2.substring(1)] || '');
	}) : '';
}

module.exports = ReplacePatternTransform;<|endoftext|>