<commit_before>/* @license
 * Copyright 2020 Google LLC. All Rights Reserved.
 * 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.
 */

const {applyKarmaHacks} = require('./shared-assets/scripts/karma-hacks.js');

applyKarmaHacks();

module.exports = function(config) {
  // @see http://karma-runner.github.io/4.0/config/configuration-file.html
  config.set({
    basePath: '',
    plugins: [
      require.resolve('@open-wc/karma-esm'),
      'karma-*',
    ],
    frameworks: ['esm', 'mocha', 'chai'],
    files: [
      {
        pattern: 'node_modules/focus-visible/dist/focus-visible.js',
        watched: false
      },
      {pattern: 'node_modules/@ungap/event-target/min.js', watched: false},
      {pattern: 'shared-assets/**/*', included: false},
      {
        pattern: 'lib/test/**/*-spec.js',
        included: false,
        watched: true,
        type: 'module'
      },
      {pattern: 'lib/test/index.js', watched: true, type: 'module'}
    ],
    autoWatchBatchDelay: 1000,
    restartOnFileChange: true,

    browserDisconnectTimeout: 300000,
    browserNoActivityTimeout: 360000,
    captureTimeout: 420000,
    concurrency: 10,

    // @see https://github.com/open-wc/open-wc/tree/master/packages/karma-esm#configuration
    esm: {
      nodeResolve: true,
      compatibility: 'auto',
      preserveSymlinks: true,
    },

    client: {
      mocha: {
        reporter: 'html',
        ui: 'tdd',
        timeout: 60000,
      },
    },

    reporters: ['mocha'],

    mochaReporter: {output: 'autowatch'},

    // Note setting --browsers on the command-line always overrides this list.
    browsers: [
      'ChromeHeadlessNoSandbox',
    ],

    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox'],
      }
    },
  });

  if (process.env.USE_BROWSER_STACK) {
    if (!process.env.BROWSER_STACK_USERNAME ||
        !process.env.BROWSER_STACK_ACCESS_KEY) {
      throw new Error(
          'BROWSER_STACK_USERNAME and BROWSER_STACK_ACCESS_KEY must be set with USE_BROWSER_STACK');
    }

    const browserStackLaunchers = {
      'Chrome (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Chrome',
        browser_version: 'latest',
      },
      'Chrome (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Chrome',
        browser_version: 'latest-1',
      },
      'Edge (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Edge',
        browser_version: 'latest',
      },
      'Edge (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Edge',
        browser_version: 'latest-1',
      },
      'Firefox (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Firefox',
        browser_version: 'latest',
      },
      'Firefox (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Firefox',
        browser_version: 'latest-1',
      },
      'Safari (latest)': {
        base: 'BrowserStack',
        os: 'OS X',
        os_version: 'Catalina',
        browser: 'safari',
        browser_version: 'latest',
        // BrowserStack occassionally fails to tunnel localhost for Safari
        // instances, causing them to time out:
        url: 'http://127.0.0.1:9876'
      },
      'iOS Safari (iOS 13)': {
        base: 'BrowserStack',
        os: 'iOS',
        os_version: '13',
        device: 'iPhone 8',
        browser: 'iPhone',
        real_mobile: 'true',
        // BrowserStack seems to drop the port when redirecting to this special
        // domain so we go there directly instead:
        url: 'http://bs-local.com:9876'
      },
      'iOS Safari (iOS 14)': {
        base: 'BrowserStack',
        os: 'iOS',
        os_version: '14',
        device: 'iPhone 11',
        browser: 'iPhone',
        real_mobile: 'true',
        // BrowserStack seems to drop the port when redirecting to this special
        // domain so we go there directly instead:
        url: 'http://bs-local.com:9876'
      },
    };

    config.set({
      browserStack: {
        idleTimeout: 600,
        name: '<model-viewer> Unit Tests',
        project: '<model-viewer>',
        build: process.env.BROWSER_STACK_BUILD_NAME
      },

      reporters: ['BrowserStack', 'mocha'],

      customLaunchers: browserStackLaunchers,
      browsers: [...config.browsers, ...Object.keys(browserStackLaunchers)],
    });
  }
};<commit_msg>remove ios13 testing while BrowserStack's test runner is down (#2570)<commit_after>/* @license
 * Copyright 2020 Google LLC. All Rights Reserved.
 * 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.
 */

const {applyKarmaHacks} = require('./shared-assets/scripts/karma-hacks.js');

applyKarmaHacks();

module.exports = function(config) {
  // @see http://karma-runner.github.io/4.0/config/configuration-file.html
  config.set({
    basePath: '',
    plugins: [
      require.resolve('@open-wc/karma-esm'),
      'karma-*',
    ],
    frameworks: ['esm', 'mocha', 'chai'],
    files: [
      {
        pattern: 'node_modules/focus-visible/dist/focus-visible.js',
        watched: false
      },
      {pattern: 'node_modules/@ungap/event-target/min.js', watched: false},
      {pattern: 'shared-assets/**/*', included: false},
      {
        pattern: 'lib/test/**/*-spec.js',
        included: false,
        watched: true,
        type: 'module'
      },
      {pattern: 'lib/test/index.js', watched: true, type: 'module'}
    ],
    autoWatchBatchDelay: 1000,
    restartOnFileChange: true,

    browserDisconnectTimeout: 300000,
    browserNoActivityTimeout: 360000,
    captureTimeout: 420000,
    concurrency: 10,

    // @see https://github.com/open-wc/open-wc/tree/master/packages/karma-esm#configuration
    esm: {
      nodeResolve: true,
      compatibility: 'auto',
      preserveSymlinks: true,
    },

    client: {
      mocha: {
        reporter: 'html',
        ui: 'tdd',
        timeout: 60000,
      },
    },

    reporters: ['mocha'],

    mochaReporter: {output: 'autowatch'},

    // Note setting --browsers on the command-line always overrides this list.
    browsers: [
      'ChromeHeadlessNoSandbox',
    ],

    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox'],
      }
    },
  });

  if (process.env.USE_BROWSER_STACK) {
    if (!process.env.BROWSER_STACK_USERNAME ||
        !process.env.BROWSER_STACK_ACCESS_KEY) {
      throw new Error(
          'BROWSER_STACK_USERNAME and BROWSER_STACK_ACCESS_KEY must be set with USE_BROWSER_STACK');
    }

    const browserStackLaunchers = {
      'Chrome (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Chrome',
        browser_version: 'latest',
      },
      'Chrome (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Chrome',
        browser_version: 'latest-1',
      },
      'Edge (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Edge',
        browser_version: 'latest',
      },
      'Edge (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Edge',
        browser_version: 'latest-1',
      },
      'Firefox (latest)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Firefox',
        browser_version: 'latest',
      },
      'Firefox (latest-1)': {
        base: 'BrowserStack',
        os: 'Windows',
        os_version: '10',
        browser: 'Firefox',
        browser_version: 'latest-1',
      },
      'Safari (latest)': {
        base: 'BrowserStack',
        os: 'OS X',
        os_version: 'Catalina',
        browser: 'safari',
        browser_version: 'latest',
        // BrowserStack occassionally fails to tunnel localhost for Safari
        // instances, causing them to time out:
        url: 'http://127.0.0.1:9876'
      },
      // 'iOS Safari (iOS 13)': {
      //   base: 'BrowserStack',
      //   os: 'iOS',
      //   os_version: '13',
      //   device: 'iPhone 8',
      //   browser: 'iPhone',
      //   real_mobile: 'true',
      //   // BrowserStack seems to drop the port when redirecting to this special
      //   // domain so we go there directly instead:
      //   url: 'http://bs-local.com:9876'
      // },
      'iOS Safari (iOS 14)': {
        base: 'BrowserStack',
        os: 'iOS',
        os_version: '14',
        device: 'iPhone 11',
        browser: 'iPhone',
        real_mobile: 'true',
        // BrowserStack seems to drop the port when redirecting to this special
        // domain so we go there directly instead:
        url: 'http://bs-local.com:9876'
      },
    };

    config.set({
      browserStack: {
        idleTimeout: 600,
        name: '<model-viewer> Unit Tests',
        project: '<model-viewer>',
        build: process.env.BROWSER_STACK_BUILD_NAME
      },

      reporters: ['BrowserStack', 'mocha'],

      customLaunchers: browserStackLaunchers,
      browsers: [...config.browsers, ...Object.keys(browserStackLaunchers)],
    });
  }
};<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const gutil = require('gulp-util');
const watchify = require('watchify');
const exit = require('gulp-exit');
const cssModulesify = require('css-modulesify');
const postcssModulesLocalByDefault = require('postcss-modules-local-by-default');
const postcssModulesExtractImports = require('postcss-modules-extract-imports');
const postCssModulesScope = require('postcss-modules-scope');
const precss = require('precss');
const autoprefixer = require('autoprefixer');

module.exports = function (taskName, srcDir, bundleJs, bundleCss, buildDir, standalone, babelConfig, logNamespace) {

    if (!logNamespace) logNamespace = bundleJs;

    gulp.task(taskName, () => bundle(build()).pipe(exit()));

    gulp.task(taskName + ':release', () => bundle(build({
            browserify: {
                debug: false
            },
            cssModulesify: {
                generateScopedName: cssModulesify.generateShortName
            }
        }), {
            writeSourcemaps: false,
            uglify: {
                compress: {
                    global_defs: {
                        DEBUG: false
                    }
                }
            }
        }).pipe(exit()));

    gulp.task(taskName + ':watch', () => {

        let b = build();
        b.on('update', bundle.bind(global, b, null));
        bundle(b);

    });

    function build (options) {

        if (options === undefined) options = {};
        let browserifyOptions = options.browserify || {};
        let cssModulesifyOptions = options.cssModulesify || {};

        var b = watchify(browserify(Object.assign({
            entries: srcDir + '/' + bundleJs,
            debug: true,
            bundleExternal: true,
            standalone: standalone,
            cache: {},
            packageCache: {},
        }, browserifyOptions)));

        b.on('log', gutil.log.bind(gutil, '[' + gutil.colors.cyan(logNamespace) + ']'));

        b.transform('babelify', Object.assign({ sourceMapRelative: '.' }, babelConfig));

        b.plugin(cssModulesify, Object.assign({
            output: buildDir + '/' + bundleCss,
            use: [
                postcssModulesLocalByDefault,
                postcssModulesExtractImports,
                postCssModulesScope,
                precss,
                autoprefixer
            ]
        }, cssModulesifyOptions));

        return b;

    }

    function bundle ( b, options ) {

        if (options == null) {
            options = {
                writeSourcemaps: true,
                uglify: {
                    compress: {
                        global_defs: {
                            DEBUG: true
                        }
                    }
                }
            };
        }

        b = b.bundle()
                .on('error', log_error('Browserify'))
                .pipe(source(bundleJs))
                .pipe(buffer());

        if (options.writeSourcemaps) {
            b = b.pipe(sourcemaps.init({ loadMaps: true }));
        }

        b = b.pipe(uglify(options.uglify));

        if (options.writeSourcemaps) {
            b = b.on('error', log_error('Sourcemaps')).pipe(sourcemaps.write('./'));
        }

        return b.pipe(gulp.dest(buildDir));

    }

    function log_error ( prefix ) {
        let log = gutil.log.bind(gutil, '[' + gutil.colors.cyan(logNamespace) + ']', gutil.colors.red(prefix));
        return function ( err ) {
            log(gutil.colors.red(err.toString()));
        };
    }

}
<commit_msg>optimized bundle dev builds<commit_after>'use strict';

const gulp = require('gulp');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const gutil = require('gulp-util');
const watchify = require('watchify');
const exit = require('gulp-exit');
const cssModulesify = require('css-modulesify');
const postcssModulesLocalByDefault = require('postcss-modules-local-by-default');
const postcssModulesExtractImports = require('postcss-modules-extract-imports');
const postCssModulesScope = require('postcss-modules-scope');
const precss = require('precss');
const autoprefixer = require('autoprefixer');

module.exports = function (taskName, srcDir, bundleJs, bundleCss, buildDir, standalone, babelConfig, logNamespace) {

    if (!logNamespace) logNamespace = bundleJs;

    gulp.task(taskName, () => bundle(build()).pipe(exit()));

    gulp.task(taskName + ':release', () => bundle(build({
            browserify: {
                debug: false
            },
            cssModulesify: {
                generateScopedName: cssModulesify.generateShortName
            }
        }), {
            writeSourcemaps: false,
            uglify: {
                preserveComments: 'license',
                compress: {
                    global_defs: {
                        DEBUG: false
                    }
                }
            }
        }).pipe(exit()));

    gulp.task(taskName + ':watch', () => {

        let b = build();
        b.on('update', bundle.bind(global, b, null));
        bundle(b);

    });

    function build (options) {

        if (options === undefined) options = {};
        let browserifyOptions = options.browserify || {};
        let cssModulesifyOptions = options.cssModulesify || {};

        var b = watchify(browserify(Object.assign({
            entries: srcDir + '/' + bundleJs,
            debug: true,
            bundleExternal: true,
            standalone: standalone,
            cache: {},
            packageCache: {},
        }, browserifyOptions)));

        b.on('log', gutil.log.bind(gutil, '[' + gutil.colors.cyan(logNamespace) + ']'));

        b.transform('babelify', Object.assign({ sourceMapRelative: '.' }, babelConfig));

        b.plugin(cssModulesify, Object.assign({
            output: buildDir + '/' + bundleCss,
            use: [
                postcssModulesLocalByDefault,
                postcssModulesExtractImports,
                postCssModulesScope,
                precss,
                autoprefixer
            ]
        }, cssModulesifyOptions));

        return b;

    }

    function bundle ( b, options ) {

        if (options == null) {
            options = {
                writeSourcemaps: true,
                uglify: {
                    mangle: false,
                    preserveComments: 'all',
                    compress: {
                        sequences     : false, // true,  // join consecutive statemets with the “comma operator”
                        properties    : false, // true,  // optimize property access: a["foo"] → a.foo
                        dead_code     : false, // true,  // discard unreachable code
                        drop_debugger : false, // true,  // discard “debugger” statements
                        unsafe        : false, // some unsafe optimizations (see below)
                        conditionals  : false, // true,  // optimize if-s and conditional expressions
                        comparisons   : false, // true,  // optimize comparisons
                        evaluate      : false, // true,  // evaluate constant expressions
                        booleans      : false, // true,  // optimize boolean expressions
                        loops         : false, // true,  // optimize loops
                        unused        : false, // true,  // drop unused variables/functions
                        hoist_funs    : false, // true,  // hoist function declarations
                        hoist_vars    : false, // hoist variable declarations
                        if_return     : false, // true,  // optimize if-s followed by return/continue
                        join_vars     : false, // true,  // join var declarations
                        cascade       : false, // true,  // try to cascade `right` into `left` in sequences
                        side_effects  : false, // true,  // drop side-effect-free statements
                        warnings      : true,  // warn about potentially dangerous optimizations/code
                        global_defs: {         // global definitions
                            DEBUG: true
                        }
                    }
                }
            };
        }

        b = b.bundle()
                .on('error', log_error('Browserify'))
                .pipe(source(bundleJs))
                .pipe(buffer());

        if (options.writeSourcemaps) {
            b = b.pipe(sourcemaps.init({
                loadMaps: false,
                debug: true,
                addComment: true,
            }));
        }

        b = b.pipe(uglify(options.uglify));

        if (options.writeSourcemaps) {
            b = b.on('error', log_error('Sourcemaps')).pipe(sourcemaps.write('./'));
        }

        return b.pipe(gulp.dest(buildDir));

    }

    function log_error ( prefix ) {
        let log = gutil.log.bind(gutil, '[' + gutil.colors.cyan(logNamespace) + ']', gutil.colors.red(prefix));
        return function ( err ) {
            log(gutil.colors.red(err.toString()));
        };
    }

}
<|endoftext|>


<commit_before>var dest = './dist';
var src = './app';

module.exports = {
	browserSync: {
		notify: true,
		minify: false,
		browser: 'google chrome',
		server: {
			// We're serving the src folder as well,
			// for sass sourcemap linking
			baseDir: [dest, src]
		},
		files: [
			dest + '/**',
			'!' + dest + '/**.map', // Exclude Map files
		]
	},
	lint: {
		src: [
			src + '**/*.{js,es6}',
			'./gulp/**/*.js',
		],
	},
	link: {
		src: 'data',
		dest: dest + '/data',
		opts: {force: true},
	},
	del: {
		dest: dest,
	},
	sass: {
		src: src + '/styles/**/*.scss',
		dest: dest,
		AUTOPREFIXER_BROWSERS: [
			'ie >= 11',
			'ie_mob >= 11',
			'ff >= 30',
			'chrome >= 34',
			'safari >= 8',
			'opera >= 23',
			'ios >= 8',
			'android >= 4.4',
		],
	},
	fonts: {
		src: [src + '/styles/fonts/**', src + '/styles/ionicons/font/*.woff'],
		dest: dest + '/fonts'
	},
	markup: {
		src: src + '/index.html',
		dest: dest
	},
	browserify: {
		// Enable source maps
		debug: true,
		// Additional file extentions to make optional
		// extensions: ['.es6'],
		// A separate bundle will be generated for each
		// bundle config in the list below
		bundleConfigs: [{
			entries: src + '/app.es6',
			dest: dest,
			outputName: 'app.js',
			mapfile: dest + '/app.js.map',
			transforms: ['6to5-browserify'],
		}]
	}
};
<commit_msg>Update autoPrefixer list<commit_after>var dest = './dist';
var src = './app';

module.exports = {
	browserSync: {
		notify: true,
		minify: false,
		browser: 'google chrome',
		server: {
			// We're serving the src folder as well,
			// for sass sourcemap linking
			baseDir: [dest, src]
		},
		files: [
			dest + '/**',
			'!' + dest + '/**.map', // Exclude Map files
		]
	},
	lint: {
		src: [
			src + '**/*.{js,es6}',
			'./gulp/**/*.js',
		],
	},
	link: {
		src: 'data',
		dest: dest + '/data',
		opts: {force: true},
	},
	del: {
		dest: dest,
	},
	sass: {
		src: src + '/styles/**/*.scss',
		dest: dest,
		AUTOPREFIXER_BROWSERS: [
			'ie >= 11',
			'ie_mob >= 11',
			'ff >= 33',
			'chrome >= 37',
			'safari >= 8',
			'opera >= 25',
			'ios >= 8',
			'android >= 4.4',
		],
	},
	fonts: {
		src: [src + '/styles/fonts/**', src + '/styles/ionicons/font/*.woff'],
		dest: dest + '/fonts'
	},
	markup: {
		src: src + '/index.html',
		dest: dest
	},
	browserify: {
		// Enable source maps
		debug: true,
		// Additional file extentions to make optional
		// extensions: ['.es6'],
		// A separate bundle will be generated for each
		// bundle config in the list below
		bundleConfigs: [{
			entries: src + '/app.es6',
			dest: dest,
			outputName: 'app.js',
			mapfile: dest + '/app.js.map',
			transforms: ['6to5-browserify'],
		}]
	}
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var filter = require('gulp-filter');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var confirm = require('gulp-prompt').confirm;
var prompt = require('gulp-prompt').prompt;
var rsync = require('gulp-rsync');
var replace = require('gulp-replace');
var git = require('gitty')('../');
var octophant = require('octophant');
var sequence = require('run-sequence');
var inquirer = require('inquirer');

var VERSIONED_FILES = [
  'bower.json',
  'composer.json',
  'js/foundation.core.js',
  'meteor-README.md',
  'package.js',
  'package.json'
];

var CURRENT_VERSION = require('../package.json').version;
var NEXT_VERSION;

gulp.task('deploy', function(cb) {
  sequence('deploy:prompt', 'deploy:version', 'deploy:dist', 'deploy:settings', 'deploy:commit', cb);
});

gulp.task('deploy:prompt', function(cb) {
  inquirer.prompt([{
    type: 'input',
    name: 'version',
    message: 'What version are we moving to? (Current version is ' + CURRENT_VERSION + ')'
  }], function(res) {
    NEXT_VERSION = res.version;
    cb();
  });
});

// Bumps the version number in any file that has one
gulp.task('deploy:version', function() {
  return gulp.src(VERSIONED_FILES, { base: process.cwd() })
    .pipe(replace(CURRENT_VERSION, NEXT_VERSION))
    .pipe(gulp.dest('.'));
});

// Generates compiled CSS and JS files and puts them in the dist/ folder
gulp.task('deploy:dist', ['sass:foundation', 'javascript:foundation'], function() {
  var cssFilter = filter(['*.css']);
  var jsFilter  = filter(['*.js']);

  return gulp.src(['./_build/assets/css/foundation.css', '_build/assets/js/foundation.js'])
    .pipe(cssFilter)
      .pipe(gulp.dest('./dist'))
      .pipe(minifyCss())
      .pipe(rename('foundation.min.css'))
      .pipe(gulp.dest('./dist'))
    .pipe(cssFilter.restore())
    .pipe(jsFilter)
      .pipe(gulp.dest('./dist'))
      .pipe(uglify())
      .pipe(rename('foundation.min.js'))
      .pipe(gulp.dest('./dist'));
});

// Generates a settings file
gulp.task('deploy:settings', function(cb) {
  var options = {
    title: 'Foundation for Sites Settings',
    output: './scss/settings/_settings.scss',
    groups: {
      'grid': 'The Grid',
      'off-canvas': 'Off-canvas',
      'typography-base': 'Base Typography'
    },
    sort: [
      'global',
      'breakpoints',
      'grid',
      'typography-base',
      'typography-helpers'
    ],
    imports: ['util/util']
  }

  octophant('./scss', options, cb);
});

// Writes a commit with the changes to the version numbers
gulp.task('deploy:commit', function(cb) {
  git.commitSync('Bump to version ' + NEW_VERSION, { a: true });
  git.tagSync('v' + NEW_VERSION);
  // git.push('origin', 'develop', cb);
  cb();
});

// Uploads the documentation to the live server
gulp.task('deploy:docs', ['build'], function() {
  return gulp.src('./_build/**')
    .pipe(confirm('Make sure everything looks right before you deploy.'))
    .pipe(rsync({
      root: './_build',
      hostname: 'deployer@72.32.134.77',
      destination: '/home/deployer/sites/foundation-sites-6-docs'
    }));
});

// The Customizer runs this function to generate files it needs
gulp.task('deploy:custom', ['sass:foundation', 'javascript:foundation'], function() {
  var cssFilter = filter(['*.css']);
  var jsFilter  = filter(['*.js']);

  gulp.src('./_build/assets/css/foundation.css')
      .pipe(minifyCss())
      .pipe(rename('foundation.min.css'))
      .pipe(gulp.dest('./_build/assets/css'));

  return gulp.src('_build/assets/js/foundation.js')
      .pipe(uglify())
      .pipe(rename('foundation.min.js'))
      .pipe(gulp.dest('./_build/assets/js'));
});
<commit_msg>Fix Gulp deploy:commit task not running due to variable typo<commit_after>var gulp = require('gulp');
var filter = require('gulp-filter');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var confirm = require('gulp-prompt').confirm;
var prompt = require('gulp-prompt').prompt;
var rsync = require('gulp-rsync');
var replace = require('gulp-replace');
var git = require('gitty')('../');
var octophant = require('octophant');
var sequence = require('run-sequence');
var inquirer = require('inquirer');

var VERSIONED_FILES = [
  'bower.json',
  'composer.json',
  'js/foundation.core.js',
  'meteor-README.md',
  'package.js',
  'package.json'
];

var CURRENT_VERSION = require('../package.json').version;
var NEXT_VERSION;

gulp.task('deploy', function(cb) {
  sequence('deploy:prompt', 'deploy:version', 'deploy:dist', 'deploy:settings', 'deploy:commit', cb);
});

gulp.task('deploy:prompt', function(cb) {
  inquirer.prompt([{
    type: 'input',
    name: 'version',
    message: 'What version are we moving to? (Current version is ' + CURRENT_VERSION + ')'
  }], function(res) {
    NEXT_VERSION = res.version;
    cb();
  });
});

// Bumps the version number in any file that has one
gulp.task('deploy:version', function() {
  return gulp.src(VERSIONED_FILES, { base: process.cwd() })
    .pipe(replace(CURRENT_VERSION, NEXT_VERSION))
    .pipe(gulp.dest('.'));
});

// Generates compiled CSS and JS files and puts them in the dist/ folder
gulp.task('deploy:dist', ['sass:foundation', 'javascript:foundation'], function() {
  var cssFilter = filter(['*.css']);
  var jsFilter  = filter(['*.js']);

  return gulp.src(['./_build/assets/css/foundation.css', '_build/assets/js/foundation.js'])
    .pipe(cssFilter)
      .pipe(gulp.dest('./dist'))
      .pipe(minifyCss())
      .pipe(rename('foundation.min.css'))
      .pipe(gulp.dest('./dist'))
    .pipe(cssFilter.restore())
    .pipe(jsFilter)
      .pipe(gulp.dest('./dist'))
      .pipe(uglify())
      .pipe(rename('foundation.min.js'))
      .pipe(gulp.dest('./dist'));
});

// Generates a settings file
gulp.task('deploy:settings', function(cb) {
  var options = {
    title: 'Foundation for Sites Settings',
    output: './scss/settings/_settings.scss',
    groups: {
      'grid': 'The Grid',
      'off-canvas': 'Off-canvas',
      'typography-base': 'Base Typography'
    },
    sort: [
      'global',
      'breakpoints',
      'grid',
      'typography-base',
      'typography-helpers'
    ],
    imports: ['util/util']
  }

  octophant('./scss', options, cb);
});

// Writes a commit with the changes to the version numbers
gulp.task('deploy:commit', function(cb) {
  git.commitSync('Bump to version ' + NEXT_VERSION, { a: true });
  git.tagSync('v' + NEXT_VERSION);
  // git.push('origin', 'develop', cb);
  cb();
});

// Uploads the documentation to the live server
gulp.task('deploy:docs', ['build'], function() {
  return gulp.src('./_build/**')
    .pipe(confirm('Make sure everything looks right before you deploy.'))
    .pipe(rsync({
      root: './_build',
      hostname: 'deployer@72.32.134.77',
      destination: '/home/deployer/sites/foundation-sites-6-docs'
    }));
});

// The Customizer runs this function to generate files it needs
gulp.task('deploy:custom', ['sass:foundation', 'javascript:foundation'], function() {
  var cssFilter = filter(['*.css']);
  var jsFilter  = filter(['*.js']);

  gulp.src('./_build/assets/css/foundation.css')
      .pipe(minifyCss())
      .pipe(rename('foundation.min.css'))
      .pipe(gulp.dest('./_build/assets/css'));

  return gulp.src('_build/assets/js/foundation.js')
      .pipe(uglify())
      .pipe(rename('foundation.min.js'))
      .pipe(gulp.dest('./_build/assets/js'));
});
<|endoftext|>


<commit_before>/*!
 *  opentok-whiteboard (http://github.com/aullman/opentok-whiteboard)
 *
 *  Shared Whiteboard that works with OpenTok
 *
 *  @Author: Adam Ullman (http://github.com/aullman)
 *  @Copyright (c) 2014 Adam Ullman
 *  @License: Released under the MIT license (http://opensource.org/licenses/MIT)
**/

var OpenTokWhiteboard = angular.module('opentok-whiteboard', ['opentok'])
.directive('otWhiteboard', ['OTSession', '$window', function (OTSession, $window) {
    return {
        restrict: 'E',
        template: '<canvas></canvas>' +

            '
' +

            '<input type="button" ng-class="{OT_color: true, OT_selected: c[\'background-color\'] === color}" ' +
            'ng-repeat="c in colors" ng-style="c" ng-click="changeColor(c)">' +
            '</input>' +

            '<input type="button" ng-click="erase()" ng-class="{OT_erase: true, OT_selected: erasing}"' +
            ' value="Eraser"></input>' +

            '<input type="button" ng-click="capture()" class="OT_capture" value="{{captureText}}"></input>' +

            '<input type="button" ng-click="undo()" class="OT_capture" value="Undo"></input>' +

            '<input type="button" ng-click="redo()" class="OT_capture" value="Redo"></input>' +

            '<input type="button" ng-click="clear()" class="OT_clear" value="Clear"></input>',

        link: function (scope, element, attrs) {
            var canvas = element.context.querySelector("canvas"),
                select = element.context.querySelector("select"),
                input = element.context.querySelector("input"),
                client = {dragging:false},
                start = 0, //Grabs the end position of each stroke
                count = 0, //Grabs the total count of each continuous stroke
                undoStack = [], //Stores the value of start and count for each continuous stroke
                redoStack = [], //When undo pops, data is sent to redoStack
                drawHistory = [],
                drawHistoryReceivedFrom,
                drawHistoryReceived,
                batchUpdates = [],
                iOS = /(iPad|iPhone|iPod)/g.test( navigator.userAgent );

            // Create an empty project and a view for the canvas:
            $window.paper.setup(canvas);

            scope.colors = [{'background-color': 'black'},
                            {'background-color': 'blue'},
                            {'background-color': 'red'},
                            {'background-color': 'green'},
                            {'background-color': 'orange'},
                            {'background-color': 'purple'},
                            {'background-color': 'brown'}];
            scope.captureText = iOS ? 'Email' : 'Capture';

            scope.strokeCap = 'round';
            scope.strokeJoin = 'round';

            canvas.width = attrs.width || element.width();
            canvas.height = attrs.height || element.height();

            var clearCanvas = function () {
                $window.paper.project.clear();
                $window.paper.view.update();
            };

            var clearStack = function () {
                drawHistory = [];
                undoStack = [];
                redoStack = [];
                start = 0;
                count = 0;
            };

            scope.changeColor = function (color) {
                scope.color = color['background-color'];
                scope.lineWidth = 2;
                scope.erasing = false;
            };

            scope.changeColor(scope.colors[Math.floor(Math.random() * scope.colors.length)]);

            scope.clear = function () {
                clearCanvas();
                if (OTSession.session) {
                    OTSession.session.signal({
                        type: 'otWhiteboard_clear'
                    });
                }
            };

            scope.erase = function () {
                //scope.color = element.css("background-color") || "#fff";
                scope.lineWidth = 50;
                scope.erasing = true;
            };

            scope.capture = function () {
                if (iOS) {
                    // On iOS you can put HTML in a mailto: link
                    $window.location.href = "mailto:?subject=Whiteboard&Body=";
                } else {
                    // We just open the image in a new window
                    $window.open(canvas.toDataURL('image/png'));
                }
            };

            scope.undo = function () {
                if (!undoStack.length)
                    return;
                var undodata = undoStack.pop();
                undoWhiteBoard(undodata);
                redoStack.push(undodata);
                sendUpdate('otWhiteboard_undo', undodata);
            };

            var undoWhiteBoard = function (data) {
                data.visible = false;
                $window.paper.view.update();
            };

            scope.redo = function () {
                if (!redoStack.length)
                    return;
                var redodata = redoStack.pop();
                redoWhiteBoard(redodata);
                undoStack.push(redodata);
                sendUpdate('otWhiteboard_redo', redodata);
            };

            var redoWhiteBoard = function (data) {
                data.visible = true;
                $window.paper.view.update();
            };

            var draw = function (update, full) {
                if (full) {
                    // Create a new path object
                    $window.path = new $window.paper.Path();

                    // Apply properties
                    $window.path.strokeColor = update.color;
                    $window.path.strokeWidth = scope.lineWidth;
                    $window.path.strokeCap = scope.strokeCap;
                    $window.path.strokeJoin = scope.strokeJoin;

                    mode = !scope.erasing ? "eraser" : "pen";

                    if (mode=="pen"){
                        $window.path.blendMode = 'destination-out';
                    }

                    // Move to start and draw a line from there
                    start = new $window.paper.Point(update.fromX, update.fromY);
                    $window.path.moveTo(start);
                }

                $window.path.add(update.toX, update.toY);
                drawHistory.push(update);

                if (full) {
                     // Apply smoothing.
                    $window.path.smooth();

                    // End dragging.
                    client.dragging = false;

                    if (count) {
                        start = drawHistory.length;
                        undoStack.push($window.path);
                        count = 0;
                    }
                }
            };

            var drawUpdates = function (updates) {
                updates.forEach(function (update) {
                    draw(update, true);
                    drawHistory.push(update);
                });
            };

            var batchSignal = function (type, data, toConnection) {
                // We send data in small chunks so that they fit in a signal
                // Each packet is maximum ~250 chars, we can fit 8192/250 ~= 32 updates per signal
                var dataCopy = data.slice();
                var signalError = function (err) {
                  if (err) {
                    TB.error(err);
                  }
                };
                while(dataCopy.length) {
                    var dataChunk = dataCopy.splice(0, Math.min(dataCopy.length, 32));
                    var signal = {
                        type: type,
                        data: JSON.stringify(dataChunk)
                    };
                    if (toConnection) signal.to = toConnection;
                    OTSession.session.signal(signal, signalError);
                }
            };

            var updateTimeout;
            var sendUpdate = function (type, update) {
                if (OTSession.session) {
                    batchUpdates.push(update);
                    if (!updateTimeout) {
                        updateTimeout = setTimeout(function () {
                            batchSignal(type, batchUpdates);
                            batchUpdates = [];
                            updateTimeout = null;
                        }, 100);
                    }
                }
            };

            angular.element(document).on('keyup', function (event) {
                if (event.ctrlKey) {
                    if (event.keyCode === 90)
                        scope.undo();
                    if (event.keyCode === 89)
                        scope.redo();
                }
            });

            /*
             *    The Nuts
             *    During the process of drawing, we collect coordinates on every [mouse|touch]move event.
             *    These events occur as fast as the browser can create them, and is computer/browser dependent
             *
             */

            angular.element(canvas).on('mousedown mousemove mouseup mouseout touchstart touchmove touchend touchcancel',

              function (event) {
                if ((event.type === 'mousemove' || event.type === 'touchmove' || event.type === 'mouseout') && !client.dragging) {
                    // Ignore mouse move Events if we're not dragging
                    return;
                }
                event.preventDefault();

                var offset = angular.element(canvas).offset(),
                    scaleX = canvas.width / element.width(),
                    scaleY = canvas.height / element.height(),
                    offsetX = event.offsetX || event.originalEvent.pageX - offset.left ||
                       event.originalEvent.touches[0].pageX - offset.left,
                    offsetY = event.offsetY || event.originalEvent.pageY - offset.top ||
                       event.originalEvent.touches[0].pageY - offset.top,
                    x = offsetX * scaleX,
                    y = offsetY * scaleY,
                                        mode = !scope.erasing ? "eraser" : "pen",
                    start;

                switch (event.type) {
                case 'mousedown':
                case 'touchstart':
                    // Start dragging
                    client.dragging = true;

                    // Where the line
                    client.lastX = x;
                    client.lastY = y;

                    if( $window.path ) {
                        $window.path.selected = false;
                    }

                    // Create a new path object
                    $window.path = new $window.paper.Path();

                    // Apply properties
                    $window.path.strokeColor = scope.color;
                    $window.path.strokeWidth = scope.lineWidth;
                    $window.path.strokeCap = scope.strokeCap;
                    $window.path.strokeJoin = scope.strokeJoin;

                    if(mode=="pen"){
                        $window.path.blendMode = 'destination-out';
                    }

                    // Move to start and draw a line from there
                    start = new $window.paper.Point(x, y);
                    $window.path.moveTo(start);

                    break;
                case 'mousemove':
                case 'touchmove':
                    offsetX = event.offsetX || event.originalEvent.pageX - offset.left ||
                        event.originalEvent.touches[0].pageX - offset.left,
                    offsetY = event.offsetY || event.originalEvent.pageY - offset.top ||
                        event.originalEvent.touches[0].pageY - offset.top,
                    x = offsetX * scaleX,
                    y = offsetY * scaleY;
                    if (client.dragging) {

                        // Build update object
                        var update = {
                            id: OTSession.session && OTSession.session.connection &&
                                OTSession.session.connection.connectionId,
                            fromX: client.lastX,
                            fromY: client.lastY,
                            toX: x,
                            toY: y,
                            mode: mode,
                            color: scope.color,
                            lineWidth: scope.lineWidth,
                            show: 1
                        };
                        count++;
                        redoStack = [];
                        draw(update);
                        drawHistory.push(update);
                        client.lastX = x;
                        client.lastY = y;
                        sendUpdate('otWhiteboard_update', update);
                    }
                    break;
                case 'touchcancel':
                case 'mouseup':
                case 'touchend':
                case 'mouseout':

                    // Apply smoothing.
                    $window.path.smooth();

                    // End dragging.
                    client.dragging = false;
                    if (count) {
                        start = drawHistory.length;
                        undoStack.push($window.path);
                        count = 0;
                    }
                }
            });

            if (OTSession.session) {
                OTSession.session.on({
                    'signal:otWhiteboard_update': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            drawUpdates(JSON.parse(event.data));
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_undo': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            JSON.parse(event.data).forEach(function (data) {
                                undoWhiteBoard(data);
                            });
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_redo': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            JSON.parse(event.data).forEach(function (data) {
                                redoWhiteBoard(data);
                            });
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_history': function (event) {
                        // We will receive these from everyone in the room, only listen to the first
                        // person. Also the data is chunked together so we need all of that person's
                        if (!drawHistoryReceivedFrom || drawHistoryReceivedFrom === event.from.connectionId) {
                            drawHistoryReceivedFrom = event.from.connectionId;
                            drawUpdates(JSON.parse(event.data));
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_clear': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            clearCanvas();
                        }
                    },
                    connectionCreated: function (event) {
                        if (drawHistory.length > 0 && event.connection.connectionId !==
                                OTSession.session.connection.connectionId) {
                            batchSignal('otWhiteboard_history', drawHistory, event.connection);
                        }
                    }
                });
            }
        }
    };
}]);
<commit_msg>Fixes many smoothing issues<commit_after>/*!
 *  opentok-whiteboard (http://github.com/aullman/opentok-whiteboard)
 *
 *  Shared Whiteboard that works with OpenTok
 *
 *  @Author: Adam Ullman (http://github.com/aullman)
 *  @Copyright (c) 2014 Adam Ullman
 *  @License: Released under the MIT license (http://opensource.org/licenses/MIT)
**/

var OpenTokWhiteboard = angular.module('opentok-whiteboard', ['opentok'])
.directive('otWhiteboard', ['OTSession', '$window', '$timeout', function (OTSession, $window, $timeout) {
    return {
        restrict: 'E',
        template: '<canvas></canvas>' +

            '
' +

            '<input type="button" ng-class="{OT_color: true, OT_selected: c[\'background-color\'] === color}" ' +
            'ng-repeat="c in colors" ng-style="c" ng-click="changeColor(c)">' +
            '</input>' +

            '<input type="button" ng-click="erase()" ng-class="{OT_erase: true, OT_selected: erasing}"' +
            ' value="Eraser"></input>' +

            '<input type="button" ng-click="capture()" class="OT_capture" value="{{captureText}}"></input>' +

            '<input type="button" ng-click="undo()" class="OT_capture" value="Undo"></input>' +

            '<input type="button" ng-click="redo()" class="OT_capture" value="Redo"></input>' +

            '<input type="button" ng-click="clear()" class="OT_clear" value="Clear"></input>',

        link: function (scope, element, attrs) {
            var canvas = element.context.querySelector("canvas"),
                select = element.context.querySelector("select"),
                input = element.context.querySelector("input"),
                client = {dragging:false},
                start = 0, //Grabs the end position of each stroke
                count = 0, //Grabs the total count of each continuous stroke
                undoStack = [], //Stores the value of start and count for each continuous stroke
                redoStack = [], //When undo pops, data is sent to redoStack
                drawHistory = [],
                drawHistoryReceivedFrom,
                drawHistoryReceived,
                batchUpdates = [],
                iOS = /(iPad|iPhone|iPod)/g.test( navigator.userAgent );

            // Create an empty project and a view for the canvas:
            $window.paper.setup(canvas);

            scope.colors = [{'background-color': 'black'},
                            {'background-color': 'blue'},
                            {'background-color': 'red'},
                            {'background-color': 'green'},
                            {'background-color': 'orange'},
                            {'background-color': 'purple'},
                            {'background-color': 'brown'}];
            scope.captureText = iOS ? 'Email' : 'Capture';

            scope.strokeCap = 'round';
            scope.strokeJoin = 'round';
            scope.lineWidth = 2;

            canvas.width = attrs.width || element.width();
            canvas.height = attrs.height || element.height();

            var clearCanvas = function () {
                $window.paper.project.clear();
                $window.paper.view.update();
                drawHistory = [];
                undoStack = [];
                redoStack = [];
                start = 0;
                count = 0;
            };

            scope.changeColor = function (color) {
                scope.color = color['background-color'];
                scope.erasing = false;
            };

            scope.changeColor(scope.colors[Math.floor(Math.random() * scope.colors.length)]);

            scope.clear = function () {
                clearCanvas();
                if (OTSession.session) {
                    OTSession.session.signal({
                        type: 'otWhiteboard_clear'
                    });
                }
            };

            scope.erase = function () {
                scope.erasing = true;
            };

            scope.capture = function () {
                if (iOS) {
                    // On iOS you can put HTML in a mailto: link
                    $window.location.href = "mailto:?subject=Whiteboard&Body=";
                } else {
                    // We just open the image in a new window
                    $window.open(canvas.toDataURL('image/png'));
                }
            };

            scope.undo = function () {
                if (!undoStack.length)
                    return;
                var data = undoStack[undoStack.length - 1];
                undoWhiteBoard(data);
                sendUpdate('otWhiteboard_undo', data);
            };

            var undoWhiteBoard = function (data) {
                data = undoStack.pop();
                redoStack.push(data);
                data.visible = false;
                $window.paper.view.update();
            };

            scope.redo = function () {
                if (!redoStack.length)
                    return;
                var data = redoStack[redoStack.length - 1];
                redoWhiteBoard(data);
                sendUpdate('otWhiteboard_redo', data);
            };

            var redoWhiteBoard = function (data) {
                data = redoStack.pop();
                undoStack.push(data);
                data.visible = true;
                $window.paper.view.update();
            };

            var draw = function (update, remote) {
                if (update.end && scope.path) {
                    start = drawHistory.length;
                    drawHistory.push(scope.path);
                    undoStack.push(scope.path);
                    count = 0;

                    // Apply smoothing
                    scope.path.smooth({
                        type: 'continuous'
                    });

                    // End dragging.
                    client.dragging = false;

                    $timeout(function() {
                        scope.path = null;
                    }, 50);
                } else {
                    if (remote && !scope.path) {
                        // Create a new path object
                        scope.path = new $window.paper.Path();

                        // Apply properties
                        scope.path.strokeColor = update.color;
                        scope.path.strokeWidth = update.lineWidth;
                        scope.path.strokeCap = scope.strokeCap;
                        scope.path.strokeJoin = scope.strokeJoin;

                        if (update.mode === 'eraser') {
                            scope.path.blendMode = 'destination-out';
                        }

                        // Move to start and draw a line from there
                        start = new $window.paper.Point(update.fromX, update.fromY);
                        scope.path.moveTo(start);
                    }

                    scope.path.add(update.toX, update.toY);
                }
            };

            var drawUpdates = function (updates) {
                updates.forEach(function (update) {
                    draw(update, true);
                    //drawHistory.push(update);
                });
            };

            var batchSignal = function (type, data, toConnection) {
                // We send data in small chunks so that they fit in a signal
                // Each packet is maximum ~250 chars, we can fit 8192/250 ~= 32 updates per signal
                var dataCopy = data.slice();
                var signalError = function (err) {
                  if (err) {
                    TB.error(err);
                  }
                };
                while(dataCopy.length) {
                    var dataChunk = dataCopy.splice(0, Math.min(dataCopy.length, 32));
                    var signal = {
                        type: type,
                        data: JSON.stringify(dataChunk)
                    };
                    if (toConnection) signal.to = toConnection;
                    OTSession.session.signal(signal, signalError);
                }
            };

            var updateTimeout;
            var sendUpdate = function (type, update) {
                if (OTSession.session) {
                    batchUpdates.push(update);
                    if (!updateTimeout) {
                        updateTimeout = setTimeout(function () {
                            batchSignal(type, batchUpdates);
                            batchUpdates = [];
                            updateTimeout = null;
                        }, 100);
                    }
                }
            };

            angular.element(document).on('keyup', function (event) {
                if (event.ctrlKey) {
                    if (event.keyCode === 90)
                        scope.undo();
                    if (event.keyCode === 89)
                        scope.redo();
                }
            });

            /*
             *    The Nuts
             *    During the process of drawing, we collect coordinates on every [mouse|touch]move event.
             *    These events occur as fast as the browser can create them, and is computer/browser dependent
             *
             */

            angular.element(canvas).on('mousedown mousemove mouseup mouseout touchstart touchmove touchend touchcancel',

              function (event) {
                if ((event.type === 'mousemove' || event.type === 'touchmove' || event.type === 'mouseout') && !client.dragging) {
                    // Ignore mouse move Events if we're not dragging
                    return;
                }

                event.preventDefault();

                var offset = angular.element(canvas).offset(),
                    scaleX = canvas.width / element.width(),
                    scaleY = canvas.height / element.height(),
                    offsetX = event.offsetX || event.originalEvent.pageX - offset.left ||
                       event.originalEvent.touches[0].pageX - offset.left,
                    offsetY = event.offsetY || event.originalEvent.pageY - offset.top ||
                       event.originalEvent.touches[0].pageY - offset.top,
                    x = offsetX * scaleX,
                    y = offsetY * scaleY,
                    mode = scope.erasing ? 'eraser' : 'pen',
                    start;

                switch (event.type) {
                case 'mousedown':
                case 'touchstart':
                    // Start dragging
                    client.dragging = true;

                    // Where the line
                    client.lastX = x;
                    client.lastY = y;

                    if (scope.path) {
                        scope.path.selected = false;
                    }

                    // Create a new path object
                    scope.path = new $window.paper.Path();

                    // Apply properties
                    scope.path.strokeColor = scope.color;
                    scope.path.strokeWidth = scope.lineWidth;
                    scope.path.strokeCap = scope.strokeCap;
                    scope.path.strokeJoin = scope.strokeJoin;

                    if (mode === 'eraser') {
                        scope.path.strokeWidth = 50;
                        scope.path.blendMode = 'destination-out';
                    }

                    // Move to start and draw a line from there
                    start = new $window.paper.Point(x, y);
                    scope.path.moveTo(start);

                    break;
                case 'mousemove':
                case 'touchmove':
                    offsetX = event.offsetX || event.originalEvent.pageX - offset.left ||
                        event.originalEvent.touches[0].pageX - offset.left,
                    offsetY = event.offsetY || event.originalEvent.pageY - offset.top ||
                        event.originalEvent.touches[0].pageY - offset.top,
                    x = offsetX * scaleX,
                    y = offsetY * scaleY;
                    if (client.dragging) {
                        // Build update object
                        var update = {
                            id: OTSession.session && OTSession.session.connection &&
                                OTSession.session.connection.connectionId,
                            fromX: client.lastX,
                            fromY: client.lastY,
                            toX: x,
                            toY: y,
                            mode: mode,
                            color: scope.color,
                            lineWidth: mode === 'pen' ? scope.lineWidth : 50,
                            show: 1
                        };
                        count++;
                        redoStack = [];
                        draw(update);
                        //drawHistory.push(update);
                        client.lastX = x;
                        client.lastY = y;
                        sendUpdate('otWhiteboard_update', update);
                    }
                    break;
                case 'touchcancel':
                case 'mouseup':
                case 'touchend':
                case 'mouseout':
                    if (count) {
                        // End drawing the stroke
                        var update = {
                            id: OTSession.session && OTSession.session.connection &&
                                OTSession.session.connection.connectionId,
                            end: true
                        };

                        // Update local path
                        draw(update);

                        // Send update
                        sendUpdate('otWhiteboard_update', update);
                    }
                }
            });

            if (OTSession.session) {
                OTSession.session.on({
                    'signal:otWhiteboard_update': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            drawUpdates(JSON.parse(event.data));
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_undo': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            JSON.parse(event.data).forEach(function (data) {
                                undoWhiteBoard(data[1]);
                            });
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_redo': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            JSON.parse(event.data).forEach(function (data) {
                                redoWhiteBoard(data[1]);
                            });
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_history': function (event) {
                        // We will receive these from everyone in the room, only listen to the first
                        // person. Also the data is chunked together so we need all of that person's
                        if (!drawHistoryReceivedFrom || drawHistoryReceivedFrom === event.from.connectionId) {
                            drawHistoryReceivedFrom = event.from.connectionId;
                            drawUpdates(JSON.parse(event.data));
                            scope.$emit('otWhiteboardUpdate');
                        }
                    },
                    'signal:otWhiteboard_clear': function (event) {
                        if (event.from.connectionId !== OTSession.session.connection.connectionId) {
                            clearCanvas();
                        }
                    },
                    connectionCreated: function (event) {
                        if (drawHistory.length > 0 && event.connection.connectionId !==
                                OTSession.session.connection.connectionId) {
                            batchSignal('otWhiteboard_history', drawHistory, event.connection);
                        }
                    }
                });
            }
        }
    };
}]);
<|endoftext|>


<commit_before>var Visualization = Fiber.extend(function() {
    return {
        init: function(container, history) {
            this.container = container;
            this.history = history;

            this.renderer = null;
            this.scene = null;
            this.camera = null;
            this.controls = null;
            this.stats = null;

            this.gui = null;
            this.guiIteration = null;

            this.lastIteration = null;
            this.iteration = 0;

            this.snapshot = null;
            this.dirtyRegion = true;
            this.loadRegionTimeout = null;
            this.loadRegionTimeoutDuration = 500; // default (in ms)
            this.activeCells = [];
            this.predictiveCells = [];

            this._initScene();
            this._initControls();
            this._initStats();
            this._initGUI();

            this.historyUpdated();
        },

        /* Public */

        render: function() {
            if (this.stats) this.stats.begin();

            this._update();
            this.controls.update();
            this.renderer.render(this.scene, this.camera);

            if (this.stats) this.stats.end();

            requestAnimationFrame(this.render.bind(this));
        },

        historyUpdated: function() {
            var num = this.history.length(),
                guiIteration = this.guiIteration;

            var min = Number(num > 0),
                max = num;

            guiIteration.__min = min;
            guiIteration.__max = max;

            if (guiIteration.getValue() === 0) {
                guiIteration.setValue(min);
            }
        },

        /* To Override */

        setupRegion:  function() {},
        clearRegion:  function() {},
        updateRegion: function() {},

        /* Private */

        _initScene: function() {
            var container = this.container,
                width = container.width(),
                height = container.height(),
                viewAngle = 45,
                aspect = width / height,
                near = 0.1,
                far = 10000;

            var renderer = new THREE.WebGLRenderer();
            var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
            var scene = new THREE.Scene();

            camera.position.z = 5000;
            scene.add(camera);

            renderer.setSize(width, height);
            this.container.append(renderer.domElement);

            this.renderer = renderer;
            this.camera = camera;
            this.scene = scene;
        },

        _initControls: function() {
            var camera = this.camera,
                renderer = this.renderer,
                controls = new THREE.TrackballControls(camera, renderer.domElement);

            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;

            controls.noZoom = false;
            controls.noPan = false;

            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;

            controls.keys = [65, 83, 68];

            this.controls = controls;
        },

        _initStats: function() {
            var stats = new Stats(),
                domElement = $(stats.domElement);

            stats.setMode(0); // 0: fps; 1: ms

            domElement.addClass("stats");
            this.container.append(domElement);

            this.stats = stats;
        },

        _initGUI: function() {
            var gui = new dat.GUI({ autoPlace: false }),
                domElement = $(gui.domElement);

            domElement.addClass("controls");
            this.container.append(domElement);

            this.guiIteration = gui.add(this, 'iteration', 0, 0).step(1);

            this.gui = gui;
        },

        _iterationUpdated: function() {
            this.snapshot = this.history.getSnapshotAtIndex(this.iteration - 1);

            this.clearRegion();

            if (this.snapshot) {
                this.setupRegion();
                this._loadRegion();
            }
        },

        _update: function() {
            if (this.lastIteration != this.iteration) {
                this._iterationUpdated();
                this.lastIteration = this.iteration;
            }

            if (this.dirtyRegion) {
                this.updateRegion();
                this.dirtyRegion = false;
            }
        },

        _loadRegion: function() {
            var self = this,
                snapshot = this.snapshot,
                timeout = this.loadRegionTimeout,
                timeoutDuration = this.loadRegionTimeoutDuration;

            if (timeout) clearTimeout(timeout);

            timeout = setTimeout(function() {
                self.activeCells = [];
                self.predictiveCells = [];

                snapshot.getActiveCells(_.bind(function(error, activeCells) {
                    if (self.snapshot != this) return;

                    self.activeCells = activeCells;
                    self.dirtyRegion = true;
                }, snapshot));

                snapshot.getPredictiveCells(_.bind(function(error, predictiveCells) {
                    if (self.snapshot != this) return;

                    self.predictiveCells = predictiveCells;
                    self.dirtyRegion = true;
                }, snapshot));
            }, timeoutDuration);

            this.loadRegionTimeout = timeout;
        },

    };
});
<commit_msg>Added TODO<commit_after>var Visualization = Fiber.extend(function() {
    return {
        init: function(container, history) {
            this.container = container;
            this.history = history;

            this.renderer = null;
            this.scene = null;
            this.camera = null;
            this.controls = null;
            this.stats = null;

            this.gui = null;
            this.guiIteration = null;

            this.lastIteration = null;
            this.iteration = 0;

            this.snapshot = null;
            this.dirtyRegion = true;
            this.loadRegionTimeout = null;
            this.loadRegionTimeoutDuration = 500; // default (in ms)
            this.activeCells = [];
            this.predictiveCells = [];

            this._initScene();
            this._initControls();
            this._initStats();
            this._initGUI();

            this.historyUpdated();
        },

        /* Public */

        render: function() {
            if (this.stats) this.stats.begin();

            this._update();
            this.controls.update();
            this.renderer.render(this.scene, this.camera);

            if (this.stats) this.stats.end();

            requestAnimationFrame(this.render.bind(this));
        },

        historyUpdated: function() {
            var num = this.history.length(),
                guiIteration = this.guiIteration;

            var min = Number(num > 0),
                max = num;

            guiIteration.__min = min;
            guiIteration.__max = max;

            if (guiIteration.getValue() === 0) {
                guiIteration.setValue(min);
            }
        },

        /* To Override */

        setupRegion:  function() {},
        clearRegion:  function() {},
        updateRegion: function() {},

        /* Private */

        _initScene: function() {
            var container = this.container,
                width = container.width(),
                height = container.height(),
                viewAngle = 45,
                aspect = width / height,
                near = 0.1,
                far = 10000;

            var renderer = new THREE.WebGLRenderer();
            var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
            var scene = new THREE.Scene();

            camera.position.z = 5000;
            scene.add(camera);

            renderer.setSize(width, height);
            this.container.append(renderer.domElement);

            this.renderer = renderer;
            this.camera = camera;
            this.scene = scene;
        },

        _initControls: function() {
            var camera = this.camera,
                renderer = this.renderer,
                controls = new THREE.TrackballControls(camera, renderer.domElement);

            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;

            controls.noZoom = false;
            controls.noPan = false;

            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;

            controls.keys = [65, 83, 68];

            this.controls = controls;
        },

        _initStats: function() {
            var stats = new Stats(),
                domElement = $(stats.domElement);

            stats.setMode(0); // 0: fps; 1: ms

            domElement.addClass("stats");
            this.container.append(domElement);

            this.stats = stats;
        },

        _initGUI: function() {
            var gui = new dat.GUI({ autoPlace: false }),
                domElement = $(gui.domElement);

            domElement.addClass("controls");
            this.container.append(domElement);

            this.guiIteration = gui.add(this, 'iteration', 0, 0).step(1);

            this.gui = gui;
        },

        _iterationUpdated: function() {
            this.snapshot = this.history.getSnapshotAtIndex(this.iteration - 1);

            this.clearRegion();

            if (this.snapshot) {
                this.setupRegion(); // TODO: can instead call updateRegion if snapshot dimensions haven't changed
                this._loadRegion();
            }
        },

        _update: function() {
            if (this.lastIteration != this.iteration) {
                this._iterationUpdated();
                this.lastIteration = this.iteration;
            }

            if (this.dirtyRegion) {
                this.updateRegion();
                this.dirtyRegion = false;
            }
        },

        _loadRegion: function() {
            var self = this,
                snapshot = this.snapshot,
                timeout = this.loadRegionTimeout,
                timeoutDuration = this.loadRegionTimeoutDuration;

            if (timeout) clearTimeout(timeout);

            timeout = setTimeout(function() {
                self.activeCells = [];
                self.predictiveCells = [];

                snapshot.getActiveCells(_.bind(function(error, activeCells) {
                    if (self.snapshot != this) return;

                    self.activeCells = activeCells;
                    self.dirtyRegion = true;
                }, snapshot));

                snapshot.getPredictiveCells(_.bind(function(error, predictiveCells) {
                    if (self.snapshot != this) return;

                    self.predictiveCells = predictiveCells;
                    self.dirtyRegion = true;
                }, snapshot));
            }, timeoutDuration);

            this.loadRegionTimeout = timeout;
        },

    };
});
<|endoftext|>


<commit_before>define(['./module'], function (services) {
    'use strict';

    services.factory('Ideas', function ($timeout, $http, $q, $rootScope) {
        var service = {
            getById: function (id, callback) {
              var result = {};
              this.getIdeas().then(function(ideas){
                findById(ideas, id, result, callback);
              });
              return result;
            },
            getIdeas: function () {
                var deferred = $q.defer();
                $http.post('/api/ideas')
                    .success(function (ideas) {
                        deferred.resolve(_.map(ideas, function(idea){
                          idea.Assignees = idea.Assignees || [];
                          idea.Voters = idea.Voters || [];
                          idea.Comments = idea.Comments || [];
                          return idea;
                        }));
                    })
                    .error(function () {
                        deferred.reject();
                    });
                return deferred.promise;
            },
            updateOrInsert: function (idea) {
                var deferred = $q.defer();
                $http.put('/api/ideas', idea)
                    .success(function (idea) {
                        deferred.resolve(idea);
                    })
                    .error(function () {
                        deferred.reject();
                    });
                return deferred.promise;
            },
            assign: function (idea, user) {
                idea.Assignees = idea.Assignees || [];
                if(!_.contains(idea.Assignees, user)) {
                  idea.Assignees.push(user);
                  this.updateOrInsert(idea);
                  $rootScope.$broadcast('ideas-updated');
                }
            },
            vote: function (idea, user) {
              idea.Voters = idea.Voters || [];
              if(!_.contains(idea.Voters, user)) {
                idea.Voters.push(user);
                this.updateOrInsert(idea);
                $rootScope.$broadcast('ideas-updated');
              }
          }
        };

        /**
         * @param {Array} data
         * @param {Number} id
         * @param {Object} result
         * @param {Function} callback
         */
        var findById = function (data, id, result, callback) {
            var idea = _.find(data, function (item) {
                return item.Id == id;
            });
            _.extend(result, idea);
            if (_.isFunction(callback)) {
                callback(result);
            }
        };

        return service;
    });
});
<commit_msg>added serverside filtering in angular service<commit_after>define(['./module'], function (services) {
    'use strict';

    services.factory('Ideas', function ($timeout, $http, $q, $rootScope) {
        var service = {
            getById: function (id, callback) {
              var result = {};
              $http.post('/api/ideas', {
                "Filter" : {
                  "Id": ''+id
                }
              }).success(function(idea){
                idea = _.first(idea);
                idea.Assignees = idea.Assignees || [];
                idea.Comments = idea.Comments || [];
                idea.Voters = idea.Voters || [];
                callback(idea);
              });
            },
            getIdeas: function () {
                var deferred = $q.defer();
                $http.post('/api/ideas')
                    .success(function (ideas) {
                        deferred.resolve(_.map(ideas, function(idea){
                          idea.Assignees = idea.Assignees || [];
                          idea.Voters = idea.Voters || [];
                          idea.Comments = idea.Comments || [];
                          return idea;
                        }));
                    })
                    .error(function () {
                        deferred.reject();
                    });
                return deferred.promise;
            },
            updateOrInsert: function (idea) {
                var deferred = $q.defer();
                $http.put('/api/ideas', idea)
                    .success(function (idea) {
                        deferred.resolve(idea);
                    })
                    .error(function () {
                        deferred.reject();
                    });
                return deferred.promise;
            },
            assign: function (idea, user) {
                idea.Assignees = idea.Assignees || [];
                if(!_.contains(idea.Assignees, user)) {
                  idea.Assignees.push(user);
                  this.updateOrInsert(idea);
                  $rootScope.$broadcast('ideas-updated');
                }
            },
            vote: function (idea, user) {
              idea.Voters = idea.Voters || [];
              if(!_.contains(idea.Voters, user)) {
                idea.Voters.push(user);
                this.updateOrInsert(idea);
                $rootScope.$broadcast('ideas-updated');
              }
          }
        };

        return service;
    });
});
<|endoftext|>


<commit_before>var refresh_timer;
var last_update = new Date().toJSON();

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
};

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
};

var add_comment = function(grill_id){
        var form_content = $("#new_content").val()
        $("#new_content").val('');
        $.ajax({
            type: 'POST',
            url: '/grill/'+grill_id+'/add_comment/',
            data: { new_content : form_content,
                },
            dataType: 'json',
            success: function(json){
                clearInterval(refresh_timer);
                refresh_comment(grill_id);
                refresh_timer = setInterval(function(){
                    refresh_comment(grill_id);},5000);
            },
            error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
        });
        return false;
    };

function refresh_comment (grill_id) {
    var current_index = 0
    if ($($("#result_list>li")[0]).attr("id") != null)
    {
        current_index = $($("#result_list>li")[0]).attr("id").split("_")[1];
    }
    $.ajax({
        type: 'POST',
        url: '/grill/'+grill_id +'/refresh_comment/',
        data: {
            required_index: current_index*1+1,
            last_update: last_update,
        },
        dataType: 'json',
        success: function(json){
            //Update Comments
            for (var i = json.comments.length - 1; i >= 0; i--) {
                var target = json.comments[i];
                var options = {
                    year: "numeric", month: "short",
                    day: "numeric", hour: "2-digit", minute: "2-digit"
                };
                var temp_date = new Date(target.created_time);
				/*
                var ms = '
' + target.order +"번째. "+target.author;
                ms += "님이 " + temp_date.toLocaleTimeString("ko-KR",options)
                ms += "에 남긴 글
" + target.content + ' <button class="vote_up"> 추천 (+0)</button>

';*/

				var ms = '
';
				ms += '
';
				ms += '	'+target.order+'';
				ms += '
'+target.content+'
';
				ms += '
';
				ms += '
';
				ms += ''+target.author+'';
				ms += ''+temp_date.toLocaleTimeString("ko-KR", options)+'';
				ms += '
';
				ms += '
';
				ms += '<button class="vote_up a-comment-vote"> 추천 (+0) </button>';
				ms += '

';

                $("#result_list").prepend(ms);
            };

            //Update Votes
            last_update = json.last_update
            if (!json.new_votes) {
                return false;
            };
            for (var i = json.new_votes.length - 1; i >= 0; i--) {
                var target = json.new_votes[i]
                var target_order = target.grill_comment
                var target_new_like = target.new_count
                var target_button = $($("#comment_"+target_order).find("button")[0])
                target_new_like += target_button.text().trim().split('+')[1].slice(0, -1)*1;
                target_button.text("추천 (+"+target_new_like+")")
            };

        }, error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
    });
}

function vote_up(grill_id, order) {
    console.log("grill_id : " + grill_id + "/"+typeof(grill_id))
    console.log("order : " + order + "/"+typeof(order) )
    $.ajax({
        type: 'POST',
        url: '/grill/' + grill_id + '/vote_comment/',
        data: {
            grill_comment_order: order,
            is_up: true,
        },
        dataType: 'json',
        success: function(json){
            clearInterval(refresh_timer);
            refresh_comment(grill_id);
            refresh_timer = setInterval(function(){
                refresh_comment(grill_id);},5000);
        }, error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
    });
}

$(document).ready(function(){
            var csrftoken = getCookie('csrftoken');
            var grill_id = document.URL.split("/")[4].split("#")[0]*1;
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });

            refresh_timer = setInterval(function(){refresh_comment(grill_id);},5000);

            $(document).on('click','button.vote_up',function(){
                $(this).attr('disabled',true);
                vote_up(grill_id, $($(this)).parentsUntil("#result_list")[3].id.split("_")[1]*1);

            })

            $("#new_content").on('keyup',function(event){
                console.log(140 - $($("#new_content")[0]).val().length)
            })

            $("#add_comment_button").click(function(event){
                console.log("HI")
                event.preventDefault();
                add_comment(grill_id);
            });

        });
<commit_msg>#12 : prevent XSS by replacing <, >, &<commit_after>var refresh_timer;
var last_update = new Date().toJSON();

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
};

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
};

var add_comment = function(grill_id){
        var form_content = $("#new_content").val().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
        $("#new_content").val('');
        $.ajax({
            type: 'POST',
            url: '/grill/'+grill_id+'/add_comment/',
            data: { new_content : form_content,
                },
            dataType: 'json',
            success: function(json){
                clearInterval(refresh_timer);
                refresh_comment(grill_id);
                refresh_timer = setInterval(function(){
                    refresh_comment(grill_id);},5000);
            },
            error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
        });
        return false;
    };

function refresh_comment (grill_id) {
    var current_index = 0
    if ($($("#result_list>li")[0]).attr("id") != null)
    {
        current_index = $($("#result_list>li")[0]).attr("id").split("_")[1];
    }
    $.ajax({
        type: 'POST',
        url: '/grill/'+grill_id +'/refresh_comment/',
        data: {
            required_index: current_index*1+1,
            last_update: last_update,
        },
        dataType: 'json',
        success: function(json){
            //Update Comments
            for (var i = json.comments.length - 1; i >= 0; i--) {
                var target = json.comments[i];
                var options = {
                    year: "numeric", month: "short",
                    day: "numeric", hour: "2-digit", minute: "2-digit"
                };
                var temp_date = new Date(target.created_time);
				/*
                var ms = '
' + target.order +"번째. "+target.author;
                ms += "님이 " + temp_date.toLocaleTimeString("ko-KR",options)
                ms += "에 남긴 글
" + target.content + ' <button class="vote_up"> 추천 (+0)</button>

';*/

				var ms = '
';
				ms += '
';
				ms += '	'+target.order+'';
				ms += '
'+target.content+'
';
				ms += '
';
				ms += '
';
				ms += ''+target.author+'';
				ms += ''+temp_date.toLocaleTimeString("ko-KR", options)+'';
				ms += '
';
				ms += '
';
				ms += '<button class="vote_up a-comment-vote"> 추천 (+0) </button>';
				ms += '

';

                $("#result_list").prepend(ms);
            };

            //Update Votes
            last_update = json.last_update
            if (!json.new_votes) {
                return false;
            };
            for (var i = json.new_votes.length - 1; i >= 0; i--) {
                var target = json.new_votes[i]
                var target_order = target.grill_comment
                var target_new_like = target.new_count
                var target_button = $($("#comment_"+target_order).find("button")[0])
                target_new_like += target_button.text().trim().split('+')[1].slice(0, -1)*1;
                target_button.text("추천 (+"+target_new_like+")")
            };

        }, error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
    });
}

function vote_up(grill_id, order) {
    console.log("grill_id : " + grill_id + "/"+typeof(grill_id))
    console.log("order : " + order + "/"+typeof(order) )
    $.ajax({
        type: 'POST',
        url: '/grill/' + grill_id + '/vote_comment/',
        data: {
            grill_comment_order: order,
            is_up: true,
        },
        dataType: 'json',
        success: function(json){
            clearInterval(refresh_timer);
            refresh_comment(grill_id);
            refresh_timer = setInterval(function(){
                refresh_comment(grill_id);},5000);
        }, error:function(request,status,error){
            console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);}
    });
}

$(document).ready(function(){
            var csrftoken = getCookie('csrftoken');
            var grill_id = document.URL.split("/")[4].split("#")[0]*1;
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });

            refresh_timer = setInterval(function(){refresh_comment(grill_id);},5000);

            $(document).on('click','button.vote_up',function(){
                $(this).attr('disabled',true);
                vote_up(grill_id, $($(this)).parentsUntil("#result_list")[3].id.split("_")[1]*1);

            })

            $("#new_content").on('keyup',function(event){
                console.log(140 - $($("#new_content")[0]).val().length)
            })

            $("#add_comment_button").click(function(event){
                console.log("HI")
                event.preventDefault();
                add_comment(grill_id);
            });

        });
<|endoftext|>


<commit_before>/*
 This file is a part of libertysoil.org website
 Copyright (C) 2015  Loki Education (Social Enterprise)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
export function defaultSelector(state) {
  const data = state.toJS();

  data.is_logged_in = !!data.current_user.id;

  if (data.is_logged_in) {
    const current_user_id = data.current_user.id;

    data.current_user_tags = data.current_user.hashtags;
    data.current_user.user = data.users[current_user_id];
    data.current_user.likes = data.likes[current_user_id] || [];
    data.current_user.favourites = data.favourites[current_user_id] || [];

    data.i_am_following = data.following[current_user_id];
  } else {
    data.current_user = null;
  }

  return data;
}

export { default as createSelector } from './createSelector';
export { default as currentUserSelector } from './currentUser';
<commit_msg>Remove defaultSelector<commit_after>/*
 This file is a part of libertysoil.org website
 Copyright (C) 2015  Loki Education (Social Enterprise)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
export { default as createSelector } from './createSelector';
export { default as currentUserSelector } from './currentUser';
<|endoftext|>