<commit_before>// ==UserScript==
// @name        YouTube Improvements
// @description Make your youtube experience (slightly) less cancerous.
// @namespace   notareal@em.ail
// @include     https://www.youtube.com/feed/subscriptions/
// @include     http://www.youtube.com/feed/subscriptions/
// @include     https://www.youtube.com/watch*
// @include     http://www.youtube.com/watch*
// @version     1.17
// @grant       GM_addStyle
// @license     MIT License (Expat); opensource.org/licenses/MIT
// ==/UserScript==

/**

let i = $('#comment-section-renderer-items'); // get comments

i.getElementsByClassName('comment-renderer-text'); // get comment text

i.getElementsByClassName('comment-renderer-text')[0] // find what you want
.children[0].textContent // actual comment text

.parentElement.parentElement.parentElement // get el to be removed (class="comment-thread-renderer")
.remove() // built into yt (remove element)

*/

'use strict';

// comment filter
const blacklistedKeywords = [
  // advertisements and shit
  'bit.ly', // scams
  'goo.gl', // scams
  'dl.dropbox.com/s/', //scam
  'my channel', // adcunts

  // general cancer
  'turn subtitles', // 7 year olds
  //'\ud83d\ude02', // emoji
  'cyka blyat',
  'insert obligatory ', // metacancer
  '\ud83c\udd7e', // such unicode
  '\ud83c\udd70', // much cancer
  '1051541451431641621571721571511441234567881234567812345678123678326470547', // eaugh

  // early cancer
  'i\'m early',
  'im early',
  'i\'m so early',
  'this early',
  'notification', // new variation of the 'first' bullshit

  // likespam
  '1 like', // possibly too broad
  '1 sub', // possibly too broad
  '1 comment', // possibly too broad
  'dislike', // WOW 2 MINUTES 5 DISLIKES SUCH MEME
  'let\'s do the alphabet', // why..
  'lets do the alphabet', // just why....
  'likes for no reason',
  'like and in ',
  'can i get likes',
];
const blacklistedRegexes = [
  // early cancer
  /\b\d view\b/i, // only [n] view(s)?!?!?
  /first$/i, // slightly paranoid safe variant of the old 'first' filter
  /frist$/i, // literally hitler
  /[0-9]+ likes and ([0-9]+|no|zero) views/i, // YUTUB BOOG GUISE?
  /under [0-9]+ (club|views)/i,
  /^[A-Za-z]$/, // match single-word comments. don't use \w+ because it'd match any letter in any language

  // general cancer
  /\b[Xx]D+\b/,
  /\bfat\b/i,
  /\bkys\b/i,
  /^I have a request/, // siivagunner meme that got stale

  // likespam
  /^like if/i, // doesn't match "it's like if [...]"
];
const blacklistAllcaps = true;

function processComment(str) {
  const lostr = str.toLowerCase();
  for (let i = 0; i < blacklistedKeywords.length; i++) {
    if (lostr.indexOf(blacklistedKeywords[i]) > -1) {
      return true; // unsafe
    }
  }
  for (let i = 0; i < blacklistedRegexes.length; i++) {
    if (blacklistedRegexes[i].test(str)) {
      return true; // unsafe
    }
  }
  if (blacklistAllcaps && (str.toUpperCase() === str) && /[A-Z]/.test(str)) { // if string is uppercase and contains at least one letter (/g not needed)
    return true;
  }

  return false; // safe
}

function handleNode(csi) {
  const origcontent = csi.children[0].textContent;
  if (processComment(origcontent)) {
    // grab topmost element to remove
    let el = csi.parentElement.parentElement.parentElement;
    if (el.parentElement.parentElement.className.startsWith('comment-replies-renderer') || // is[is.length-1].parentElement.parentElement.parentElement.parentElement.parentElement
        el.className.startsWith('comment-replies-renderer') // already in view for whatever reason
       ) { // reply thread (startswith for vve-check workaround)
      el = csi.parentElement.parentElement;
    }

    // remove all child elements
    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }

    // add the 'Comment removed. Be proud!' text
    const asp = document.createElement('span');
    asp.setAttribute('style', 'color: rgb(170, 170, 170);');
    asp.title = origcontent;
    const it = document.createElement('i');
    it.textContent = 'Comment removed. Be proud!';
    asp.appendChild(it);
    el.appendChild(asp);
    //el.textContent = 'Comment removed. Be proud!'
  }
}

if (!document.location.href.startsWith('https://www.youtube.com/feed/subscriptions/')) { // isn't the sub box

  // remove recommended videos
  const vCounts = document.querySelectorAll('.stat.view-count');

  for (let i of vCounts) {
    if (i.textContent.startsWith('Recommended') || i.textContent.startsWith('Recomendado')) {
      i.parentNode.parentNode.parentNode.parentNode.removeChild(i.parentNode.parentNode.parentNode); //delete the video
    }
  }

  // comment CSS fix
  GM_addStyle(`.comment-renderer-text-content > b {
      font-weight: bold;
  }
  /*space after comma for tags*/
  .watch-meta-item .watch-info-tag-list li::after {
      content: ", ";
  }`);

}

// convert vid titles to titlecase if theyre uppercase

const lowers = [/\sA\s/g, /\sAn\s/g, /\sThe\s/g, /\sAnd\s/g, /\sBut\s/g, /\sOr\s/g, /\sFor\s/g, /\sNor\s/g, /\sAs\s/g, /\sAt\s/g,
  /\sBy\s/g, /\sFor\s/g, /\sFrom\s/g, /\sIn\s/g, /\sInto\s/g, /\sNear\s/g, /\sOf\s/g, /\sOn\s/g, /\sOnto\s/g, /\sTo\s/g, /\sWith\s/g];
const lowered = ['a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'as', 'at',
  'by', 'for', 'from', 'in', 'into', 'near', 'of', 'on', 'onto', 'to', 'with'];
const lowersLen = lowers.length;

const uppers  = ['ID', 'TV'];

function titleCase(str) {
  str = str.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
    return (uppers.indexOf(txt) != -1) ? txt : (txt[0].toUpperCase() + txt.substr(1).toLowerCase());
  });

  // Certain minor words should be left lowercase unless  they are the first -- or last words in the string -- TODO: why the last words as well?

  for (let i = 0; i < lowersLen; i++) {
    str = str.replace(lowers[i], ' ' + lowered[i] + ' ');
  }

  return str;
}

function handleCase(el) {
  if (el.textContent.toUpperCase() === el.textContent) {
    el.textContent = titleCase(el.textContent);
  }
}

// dirty hack to check for an inserted node from http://stackoverflow.com/a/10343915
GM_addStyle(`
@keyframes cccnodeInserted {
    from {
        outline-color: #fff;
    }
    to {
        outline-color: #000;
    }
}

.comment-renderer-text {
    animation-duration: 0.01s;
    animation-name: cccnodeInserted;
}

@keyframes cccvideoTitle {
    from {
        outline-color: #fff;
    }
    to {
        outline-color: #000;
    }
}

.yt-lockup-title > a {
    animation-duration: 0.01s;
    animation-name: cccvideoTitle;
}
`);

document.addEventListener('animationstart', function(event){
  if (event.animationName == 'cccnodeInserted'){
    handleNode(event.target);
  } else if (event.animationName == 'cccvideoTitle') {
    handleCase(event.target);
  }
}, true);
<commit_msg>add a few scam filters to yt improvements<commit_after>// ==UserScript==
// @name        YouTube Improvements
// @description Make your youtube experience (slightly) less cancerous.
// @namespace   notareal@em.ail
// @include     https://www.youtube.com/feed/subscriptions/
// @include     http://www.youtube.com/feed/subscriptions/
// @include     https://www.youtube.com/watch*
// @include     http://www.youtube.com/watch*
// @version     1.18
// @grant       GM_addStyle
// @license     MIT License (Expat); opensource.org/licenses/MIT
// ==/UserScript==

/**

let i = $('#comment-section-renderer-items'); // get comments

i.getElementsByClassName('comment-renderer-text'); // get comment text

i.getElementsByClassName('comment-renderer-text')[0] // find what you want
.children[0].textContent // actual comment text

.parentElement.parentElement.parentElement // get el to be removed (class="comment-thread-renderer")
.remove() // built into yt (remove element)

*/

'use strict';

// comment filter
const blacklistedKeywords = [
  // advertisements and shit
  'bit.ly', // scams
  'goo.gl', // scams
  'dl.dropbox.com/s/', //scam
  'disq.us', // scam
  'adf.ly', // just in case
  'my channel', // adcunts

  // general cancer
  'turn subtitles', // 7 year olds
  //'\ud83d\ude02', // emoji
  'cyka blyat',
  'insert obligatory ', // metacancer
  '\ud83c\udd7e', // such unicode
  '\ud83c\udd70', // much cancer
  '1051541451431641621571721571511441234567881234567812345678123678326470547', // eaugh

  // early cancer
  'i\'m early',
  'im early',
  'i\'m so early',
  'this early',
  'notification', // new variation of the 'first' bullshit

  // likespam
  '1 like', // possibly too broad
  '1 sub', // possibly too broad
  '1 comment', // possibly too broad
  'dislike', // WOW 2 MINUTES 5 DISLIKES SUCH MEME
  'let\'s do the alphabet', // why..
  'lets do the alphabet', // just why....
  'likes for no reason',
  'like and in ',
  'can i get likes',
];
const blacklistedRegexes = [
  // early cancer
  /\b\d view\b/i, // only [n] view(s)?!?!?
  /first$/i, // slightly paranoid safe variant of the old 'first' filter
  /frist$/i, // literally hitler
  /[0-9]+ likes and ([0-9]+|no|zero) views/i, // YUTUB BOOG GUISE?
  /under [0-9]+ (club|views)/i,
  /^[A-Za-z]$/, // match single-word comments. don't use \w+ because it'd match any letter in any language

  // general cancer
  /\b[Xx]D+\b/,
  /\bfat\b/i,
  /\bkys\b/i,
  /^I have a request/, // siivagunner meme that got stale

  // likespam
  /^like if/i, // doesn't match "it's like if [...]"
];
const blacklistAllcaps = true;

function processComment(str) {
  const lostr = str.toLowerCase();
  for (let i = 0; i < blacklistedKeywords.length; i++) {
    if (lostr.indexOf(blacklistedKeywords[i]) > -1) {
      return true; // unsafe
    }
  }
  for (let i = 0; i < blacklistedRegexes.length; i++) {
    if (blacklistedRegexes[i].test(str)) {
      return true; // unsafe
    }
  }
  if (blacklistAllcaps && (str.toUpperCase() === str) && /[A-Z]/.test(str)) { // if string is uppercase and contains at least one letter (/g not needed)
    return true;
  }

  return false; // safe
}

function handleNode(csi) {
  const origcontent = csi.children[0].textContent;
  if (processComment(origcontent)) {
    // grab topmost element to remove
    let el = csi.parentElement.parentElement.parentElement;
    if (el.parentElement.parentElement.className.startsWith('comment-replies-renderer') || // is[is.length-1].parentElement.parentElement.parentElement.parentElement.parentElement
        el.className.startsWith('comment-replies-renderer') // already in view for whatever reason
       ) { // reply thread (startswith for vve-check workaround)
      el = csi.parentElement.parentElement;
    }

    // remove all child elements
    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }

    // add the 'Comment removed. Be proud!' text
    const asp = document.createElement('span');
    asp.setAttribute('style', 'color: rgb(170, 170, 170);');
    asp.title = origcontent;
    const it = document.createElement('i');
    it.textContent = 'Comment removed. Be proud!';
    asp.appendChild(it);
    el.appendChild(asp);
    //el.textContent = 'Comment removed. Be proud!'
  }
}

if (!document.location.href.startsWith('https://www.youtube.com/feed/subscriptions/')) { // isn't the sub box

  // remove recommended videos
  const vCounts = document.querySelectorAll('.stat.view-count');

  for (let i of vCounts) {
    if (i.textContent.startsWith('Recommended') || i.textContent.startsWith('Recomendado')) {
      i.parentNode.parentNode.parentNode.parentNode.removeChild(i.parentNode.parentNode.parentNode); //delete the video
    }
  }

  // comment CSS fix
  GM_addStyle(`.comment-renderer-text-content > b {
      font-weight: bold;
  }
  /*space after comma for tags*/
  .watch-meta-item .watch-info-tag-list li::after {
      content: ", ";
  }`);

}

// convert vid titles to titlecase if theyre uppercase

const lowers = [/\sA\s/g, /\sAn\s/g, /\sThe\s/g, /\sAnd\s/g, /\sBut\s/g, /\sOr\s/g, /\sFor\s/g, /\sNor\s/g, /\sAs\s/g, /\sAt\s/g,
  /\sBy\s/g, /\sFor\s/g, /\sFrom\s/g, /\sIn\s/g, /\sInto\s/g, /\sNear\s/g, /\sOf\s/g, /\sOn\s/g, /\sOnto\s/g, /\sTo\s/g, /\sWith\s/g];
const lowered = ['a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'as', 'at',
  'by', 'for', 'from', 'in', 'into', 'near', 'of', 'on', 'onto', 'to', 'with'];
const lowersLen = lowers.length;

const uppers  = ['ID', 'TV'];

function titleCase(str) {
  str = str.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
    return (uppers.indexOf(txt) != -1) ? txt : (txt[0].toUpperCase() + txt.substr(1).toLowerCase());
  });

  // Certain minor words should be left lowercase unless  they are the first -- or last words in the string -- TODO: why the last words as well?

  for (let i = 0; i < lowersLen; i++) {
    str = str.replace(lowers[i], ' ' + lowered[i] + ' ');
  }

  return str;
}

function handleCase(el) {
  if (el.textContent.toUpperCase() === el.textContent) {
    el.textContent = titleCase(el.textContent);
  }
}

// dirty hack to check for an inserted node from http://stackoverflow.com/a/10343915
GM_addStyle(`
@keyframes cccnodeInserted {
    from {
        outline-color: #fff;
    }
    to {
        outline-color: #000;
    }
}

.comment-renderer-text {
    animation-duration: 0.01s;
    animation-name: cccnodeInserted;
}

@keyframes cccvideoTitle {
    from {
        outline-color: #fff;
    }
    to {
        outline-color: #000;
    }
}

.yt-lockup-title > a {
    animation-duration: 0.01s;
    animation-name: cccvideoTitle;
}
`);

document.addEventListener('animationstart', function(event){
  if (event.animationName == 'cccnodeInserted'){
    handleNode(event.target);
  } else if (event.animationName == 'cccvideoTitle') {
    handleCase(event.target);
  }
}, true);
<|endoftext|>


<commit_before>import run from 'ember-metal/run_loop';
import EventDispatcher from 'ember-views/system/event_dispatcher';
import jQuery from 'ember-views/system/jquery';
import View from 'ember-views/views/view';

var view, dispatcher;

// Adapted from https://github.com/jquery/jquery/blob/f30f7732e7775b6e417c4c22ced7adb2bf76bf89/test/data/testinit.js
var canDataTransfer, fireNativeWithDataTransfer;

if (document.createEvent) {
  canDataTransfer = !!document.createEvent('HTMLEvents').dataTransfer;
  fireNativeWithDataTransfer = function(node, type, dataTransfer) {
    var event = document.createEvent('HTMLEvents');
    event.initEvent(type, true, true);
    event.dataTransfer = dataTransfer;
    node.dispatchEvent(event);
  };
} else {
  canDataTransfer = !!document.createEventObject().dataTransfer;
  fireNativeWithDataTransfer = function(node, type, dataTransfer) {
    var event = document.createEventObject();
    event.dataTransfer = dataTransfer;
    node.fireEvent('on' + type, event);
  };
}

QUnit.module('EventDispatcher - jQuery integration', {
  setup() {
    run(function() {
      dispatcher = EventDispatcher.create();
      dispatcher.setup();
    });
  },

  teardown() {
    run(function() {
      if (view) { view.destroy(); }
      dispatcher.destroy();
    });
  }
});

if (canDataTransfer) {
  QUnit.test('jQuery.event.fix copies over the dataTransfer property', function() {
    var originalEvent;
    var receivedEvent;

    originalEvent = {
      type: 'drop',
      dataTransfer: 'success',
      target: document.body
    };

    receivedEvent = jQuery.event.fix(originalEvent);

    ok(receivedEvent !== originalEvent, 'attributes are copied to a new event object');
    equal(receivedEvent.dataTransfer, originalEvent.dataTransfer, 'copies dataTransfer property to jQuery event');
  });

  QUnit.test('drop handler should receive event with dataTransfer property', function() {
    var receivedEvent;
    var dropCalled = 0;

    view = View.extend({
      drop(evt) {
        receivedEvent = evt;
        dropCalled++;
      }
    }).create();

    run(function() {
      view.append();
    });

    fireNativeWithDataTransfer(view.$().get(0), 'drop', 'success');

    equal(dropCalled, 1, 'called drop handler once');
    equal(receivedEvent.dataTransfer, 'success', 'copies dataTransfer property to jQuery event');
  });
}
<commit_msg>[BUGFIX] Remove code for IE <9<commit_after>import run from 'ember-metal/run_loop';
import EventDispatcher from 'ember-views/system/event_dispatcher';
import jQuery from 'ember-views/system/jquery';
import View from 'ember-views/views/view';

var view, dispatcher;

// Adapted from https://github.com/jquery/jquery/blob/f30f7732e7775b6e417c4c22ced7adb2bf76bf89/test/data/testinit.js

var canDataTransfer = !!document.createEvent('HTMLEvents').dataTransfer;

function fireNativeWithDataTransfer(node, type, dataTransfer) {
  var event = document.createEvent('HTMLEvents');
  event.initEvent(type, true, true);
  event.dataTransfer = dataTransfer;
  node.dispatchEvent(event);
}

QUnit.module('EventDispatcher - jQuery integration', {
  setup() {
    run(function() {
      dispatcher = EventDispatcher.create();
      dispatcher.setup();
    });
  },

  teardown() {
    run(function() {
      if (view) { view.destroy(); }
      dispatcher.destroy();
    });
  }
});

if (canDataTransfer) {
  QUnit.test('jQuery.event.fix copies over the dataTransfer property', function() {
    var originalEvent;
    var receivedEvent;

    originalEvent = {
      type: 'drop',
      dataTransfer: 'success',
      target: document.body
    };

    receivedEvent = jQuery.event.fix(originalEvent);

    ok(receivedEvent !== originalEvent, 'attributes are copied to a new event object');
    equal(receivedEvent.dataTransfer, originalEvent.dataTransfer, 'copies dataTransfer property to jQuery event');
  });

  QUnit.test('drop handler should receive event with dataTransfer property', function() {
    var receivedEvent;
    var dropCalled = 0;

    view = View.extend({
      drop(evt) {
        receivedEvent = evt;
        dropCalled++;
      }
    }).create();

    run(function() {
      view.append();
    });

    fireNativeWithDataTransfer(view.$().get(0), 'drop', 'success');

    equal(dropCalled, 1, 'called drop handler once');
    equal(receivedEvent.dataTransfer, 'success', 'copies dataTransfer property to jQuery event');
  });
}
<|endoftext|>


<commit_before>/* @flow */

import type { WebpackConfig, GSConfig } from '../../types';

const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const cssCustomProperties = require('postcss-custom-properties');
const postcssCalc = require('postcss-calc');
const getAliasesForApps = require('./getAliasesForApps');

module.exports = (gluestickConfig: GSConfig): WebpackConfig => {
  const appRoot: string = process.cwd();
  const {
    buildAssetsPath,
    assetsPath,
    sourcePath,
    appsPath,
    sharedPath,
    configPath,
    nodeModulesPath,
  } = gluestickConfig;
  const outputPath: string = path.resolve(appRoot, buildAssetsPath);

  const configuration: WebpackConfig = {
    context: appRoot,
    resolve: {
      extensions: ['.js', '.css', '.json'],
      alias: {
        ...getAliasesForApps(gluestickConfig),
        root: process.cwd(),
        src: path.join(process.cwd(), sourcePath),
        assets: path.join(process.cwd(), assetsPath),
        shared: path.join(process.cwd(), sourcePath, sharedPath),
        config: path.join(process.cwd(), sourcePath, configPath),
        apps: path.join(process.cwd(), sourcePath, appsPath),
        compiled: path.join(process.cwd(), nodeModulesPath),
      },
    },

    output: {
      // filesystem path for static files
      path: outputPath,

      // network path for static files
      publicPath: '/assets/',

      // file name pattern for entry scripts
      filename: '[name].[chunkhash].js',

      // file name pattern for chunk scripts
      chunkFilename: '[name].[hash].js',
    },

    module: {
      rules: [{
        test: /\.js$/,
        exclude: new RegExp(`(node_modules/(?!gluestick))|(${buildAssetsPath})`),
        use: [{
          loader: 'babel-loader',
          options: {
            plugins: [
              'transform-decorators-legacy',
              'transform-flow-strip-types',
            ],
            presets: [
              'react',
              'es2015',
              'stage-0',
            ],
            babelrc: false,
          },
        }],
      },
      {
        test: /\.(scss)$/,
        use: [
          'style-loader',
          'css-loader?importLoaders=2&sourceMap',
          'postcss-loader',
          'sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true',
        ],
      },
      {
        test: /\.(css)$/,
        use: [
          'style-loader',
          'css-loader?importLoaders=2&sourceMap',
          'postcss-loader',
        ],
      },
      {
        test: /\.(png|jpg|gif|ico|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          'file-loader?name=[name]-[hash].[ext]',
          'image-webpack-loader',
        ],
      },
      {
        test: /\.(woff|woff2|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          'file-loader?name=[name]-[hash].[ext]',
        ],
      },
      {
        test: /\.(svg)$/,
        use: [
          'svg-react-loader',
        ],
      }],
    },

    plugins: [
      new webpack.LoaderOptionsPlugin({
        test: /\.(scss|css)$/,
        options: {
          // A temporary workaround for `scss-loader`
          // https://github.com/jtangelder/sass-loader/issues/298
          output: {
            path: outputPath,
          },

          postcss: [
            autoprefixer({ browsers: 'last 2 version' }),
            cssCustomProperties(),
            postcssCalc(),
          ],

          // A temporary workaround for `css-loader`.
          // Can also supply `query.context` parameter.
          context: appRoot,
        },
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: `vendor${process.env.NODE_ENV === 'production' ? '-[hash]' : ''}.bundle.js`,
      }),
      new webpack.ProgressPlugin(),
    ],

    bail: true,
    node: {
      fs: 'empty',
      net: 'empty',
    },
  };

  return configuration;
};
<commit_msg>Mock DNS. (#886)<commit_after>/* @flow */

import type { WebpackConfig, GSConfig } from '../../types';

const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const cssCustomProperties = require('postcss-custom-properties');
const postcssCalc = require('postcss-calc');
const getAliasesForApps = require('./getAliasesForApps');

module.exports = (gluestickConfig: GSConfig): WebpackConfig => {
  const appRoot: string = process.cwd();
  const {
    buildAssetsPath,
    assetsPath,
    sourcePath,
    appsPath,
    sharedPath,
    configPath,
    nodeModulesPath,
  } = gluestickConfig;
  const outputPath: string = path.resolve(appRoot, buildAssetsPath);

  const configuration: WebpackConfig = {
    context: appRoot,
    resolve: {
      extensions: ['.js', '.css', '.json'],
      alias: {
        ...getAliasesForApps(gluestickConfig),
        root: process.cwd(),
        src: path.join(process.cwd(), sourcePath),
        assets: path.join(process.cwd(), assetsPath),
        shared: path.join(process.cwd(), sourcePath, sharedPath),
        config: path.join(process.cwd(), sourcePath, configPath),
        apps: path.join(process.cwd(), sourcePath, appsPath),
        compiled: path.join(process.cwd(), nodeModulesPath),
      },
    },

    output: {
      // filesystem path for static files
      path: outputPath,

      // network path for static files
      publicPath: '/assets/',

      // file name pattern for entry scripts
      filename: '[name].[chunkhash].js',

      // file name pattern for chunk scripts
      chunkFilename: '[name].[hash].js',
    },

    module: {
      rules: [{
        test: /\.js$/,
        exclude: new RegExp(`(node_modules/(?!gluestick))|(${buildAssetsPath})`),
        use: [{
          loader: 'babel-loader',
          options: {
            plugins: [
              'transform-decorators-legacy',
              'transform-flow-strip-types',
            ],
            presets: [
              'react',
              'es2015',
              'stage-0',
            ],
            babelrc: false,
          },
        }],
      },
      {
        test: /\.(scss)$/,
        use: [
          'style-loader',
          'css-loader?importLoaders=2&sourceMap',
          'postcss-loader',
          'sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true',
        ],
      },
      {
        test: /\.(css)$/,
        use: [
          'style-loader',
          'css-loader?importLoaders=2&sourceMap',
          'postcss-loader',
        ],
      },
      {
        test: /\.(png|jpg|gif|ico|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          'file-loader?name=[name]-[hash].[ext]',
          'image-webpack-loader',
        ],
      },
      {
        test: /\.(woff|woff2|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          'file-loader?name=[name]-[hash].[ext]',
        ],
      },
      {
        test: /\.(svg)$/,
        use: [
          'svg-react-loader',
        ],
      }],
    },

    plugins: [
      new webpack.LoaderOptionsPlugin({
        test: /\.(scss|css)$/,
        options: {
          // A temporary workaround for `scss-loader`
          // https://github.com/jtangelder/sass-loader/issues/298
          output: {
            path: outputPath,
          },

          postcss: [
            autoprefixer({ browsers: 'last 2 version' }),
            cssCustomProperties(),
            postcssCalc(),
          ],

          // A temporary workaround for `css-loader`.
          // Can also supply `query.context` parameter.
          context: appRoot,
        },
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: `vendor${process.env.NODE_ENV === 'production' ? '-[hash]' : ''}.bundle.js`,
      }),
      new webpack.ProgressPlugin(),
    ],

    bail: true,
    node: {
      // TODO: Move these mocks to generated app.
      dns: 'empty',
      fs: 'empty',
      net: 'empty',
    },
  };

  return configuration;
};
<|endoftext|>


<commit_before>//ExtraToolsEX ver 1.1.0 Stable
//by 7thGrader
var version = "1.1.0";

function newLevel()
{
clientMessage("MoreToolsEX 1.1.0 Stable by 7thGrader Loaded!");
}

ModPE.setItem(407, "ruby", 0, "PowerGem");
ModPE.setFoodItem(408,"magma_cream",0, 9001,"InstaHeal");
ModPE.setItem(409, "blaze_rod", 0, "SuperStick");
ModPE.setItem(410, "ender_eye", 0, "EnderWings");
ModPE.setItem(411, "book_enchanted", 0, "TimeSpellFast");
ModPE.setItem(412, "book_enchanted", 0, "TimeSpellNormal");
ModPE.setItem(413, "book_enchanted", 0, "TimeSpellSlow");
ModPE.setItem(414, "nether_star", 0, "BlockExtractor");
Item.addFurnaceRecipe(57, 407, 1);
Item.addShapedRecipe(408, 32, 0, ["ttt", "jpj", "ttt"], ["j", 407, 0, "t", 354, 0, "p", 293, 0]);
Item.addShapedRecipe(409, 1, 0, ["jpj", "tjt", "jjj"], ["j", 407, 0, "t", 46, 0, "p", 278, 0]);
Item.addShapedRecipe(410, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 276, 0, "l", 325, 10]);
Item.addShapedRecipe(411, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 277, 0, "l", 347, 0]);
Item.addShapedRecipe(412, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 279, 0, "l", 347, 0]);
Item.addShapedRecipe(413, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 247, 0, "l", 347, 0]);
Item.addShapedRecipe(414, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 278, 0, "l", 388, 0]);

function useItem(x,y,z,i,b)
{
if (i == 409)
{
explode(x,y,z,5);
}
if (i == 410)
{
Player.setCanFly(1/0);
}
if (i == 411)
{
ModPE.setGameSpeed(40);
}
if (i == 412)
{
ModPE.setGameSpeed(20);
}
if (i == 413)
{
ModPE.setGameSpeed(10);
}
if (i == 414)
{
Level.destroyBlock(x,y,z,true)
}
}
<commit_msg>oops. i forgot it's still a beta stuff.<commit_after>//ExtraToolsEX ver 1.1.0 Stable
//by 7thGrader
var version = "1.1.0b";

function newLevel()
{
clientMessage("MoreToolsEX 1.1.0b Stable by 7thGrader Loaded!");
}

ModPE.setItem(407, "ruby", 0, "PowerGem");
ModPE.setFoodItem(408,"magma_cream",0, 9001,"InstaHeal");
ModPE.setItem(409, "blaze_rod", 0, "SuperStick");
ModPE.setItem(410, "ender_eye", 0, "EnderWings");
ModPE.setItem(411, "book_enchanted", 0, "TimeSpellFast");
ModPE.setItem(412, "book_enchanted", 0, "TimeSpellNormal");
ModPE.setItem(413, "book_enchanted", 0, "TimeSpellSlow");
ModPE.setItem(414, "nether_star", 0, "BlockExtractor");
Item.addFurnaceRecipe(57, 407, 1);
Item.addShapedRecipe(408, 32, 0, ["ttt", "jpj", "ttt"], ["j", 407, 0, "t", 354, 0, "p", 293, 0]);
Item.addShapedRecipe(409, 1, 0, ["jpj", "tjt", "jjj"], ["j", 407, 0, "t", 46, 0, "p", 278, 0]);
Item.addShapedRecipe(410, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 276, 0, "l", 325, 10]);
Item.addShapedRecipe(411, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 277, 0, "l", 347, 0]);
Item.addShapedRecipe(412, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 279, 0, "l", 347, 0]);
Item.addShapedRecipe(413, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 247, 0, "l", 347, 0]);
Item.addShapedRecipe(414, 1, 0, ["jlj", "ltl", "jjj"], ["j", 407, 0, "t", 278, 0, "l", 388, 0]);

function useItem(x,y,z,i,b)
{
if (i == 409)
{
explode(x,y,z,5);
}
if (i == 410)
{
Player.setCanFly(1/0);
}
if (i == 411)
{
ModPE.setGameSpeed(40);
}
if (i == 412)
{
ModPE.setGameSpeed(20);
}
if (i == 413)
{
ModPE.setGameSpeed(10);
}
if (i == 414)
{
Level.destroyBlock(x,y,z,true)
}
}
<|endoftext|>


<commit_before>/**
 * Constant that identifies the map canvas.
 * @type {string}
 */
var MAP_ELEMENT = "map_canvas";

var channel = "mobile";

/**
 * Callback that is called when the location couldn't be retrieved.
 * @param error
 */
function errorLocationCallback (error) {
	// error callback
	userLocation.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
    alert('There was an error obtaining your position. Message: ' + error.message);
	//TODO: show hint that location couldn't be retrieved
}

function addMarker (location) {
    // calculate latitude and longitude
    var latitude = parseFloat(location.latitude._int) * Math.pow(10, location.latitude._exp);
    var longitude = parseFloat(location.longitude._int) * Math.pow(10, location.longitude._exp);

    var entryCount = location.entries.length;
    if (entryCount > 9) {
        entryCount = 0;
    }
    // if not already on the map, display marker
    if (!userLocation.markers.hasOwnProperty(location.id)) {
        var marker = new google.maps.Marker({
            map: userLocation.map,
            position: new google.maps.LatLng(latitude, longitude),
            title: location.label,
            icon: "/static/stadtgedaechtnis/img/marker_" + entryCount + ".png",
            animation: google.maps.Animation.DROP
        });

        location.marker = marker;
        createInfobox(location);

        userLocation.markers[location.id] = location;
    }
}

/**
 * Creates an infobox for this location.
 * @param location
 * @param index index of entry for this infobox
 */
function createInfobox(location) {
    if (location.entries.length > 1) {
        var infoBoxContent = "

";
        for (var i = 0; i < location.entries.length; i++) {
            infoBoxContent += "
" + location.entries[i].title + "
";
        }
        infoBoxContent += "

";
    } else {
        var infoBoxContent = "

" + location.entries[0].abstract + "

";
    }

    var infoBox = new google.maps.InfoWindow({
        content: infoBoxContent,
        maxWidth: 225
    })

    location.infobox = infoBox;
    google.maps.event.clearListeners(location.marker, 'click');
    google.maps.event.addListener(location.marker, 'click', function () {
        openEntry(location);
    });
    google.maps.event.addListener(infoBox, 'closeclick', closeEntry);
}

/**
 * Loads the complete entry for the given location and entry index.
 * @param location
 * @param index
 */
function loadAdditionalEntry(listElement) {
    if (!listElement.data("loaded")) {
        var index = listElement.data("entry");
        var id = listElement.data("id");

        $("article#entry-more-" + index).html("");
        $("img#load-more-" + index).show();
        $.get("/entry/" + id + "/", function (data) {
            $("article#entry-more-" + index).html(data);
            $("img#load-more-" + index).hide();
            listElement.data("loaded", true);
        });
    }
}

/**
 * Opens an infobox for the first entry in this
 * location and pops up the pop up with the
 * correct heading and image. Handles click
 * events on the marker.
 * @param entry
 */
function openEntry(location) {
    var entryList = "";
    for (var i = 0; i < location.entries.length; i++) {
        // create list of entrys for slider
        entryList += '
\

\

';
        if (i > 0) {
            entryList += '
\
                \

'
        }
        entryList += '
\

' + location.entries[i].title + '
\

';
        if (i < location.entries.length - 1) {
            entryList += '
\
                \

';
        }
        entryList += '
\

';
        if (location.entries[i].image !== undefined) {
            entryList += '';
        }
        entryList += '
\
                            \

\

\

\

';
    }

    $("div.entry-list ul").html(entryList);
    var jQueryEntryList = $("section#article-section div.entry-list");

    if (location.entries.length > 1) {
        // Show next and previous buttons
        $("div.entry-slide").show();
        $("div.article-heading-row a.previous").unbind("click").click(function() {
            jQueryEntryList.data("unslider").prev();
            return false;
        });
        $("div.article-heading-row a.next").unbind("click").click(function() {
            jQueryEntryList.data("unslider").next();
            return false;
        });
    } else {
        // Hide next and previous buttons
        $("div.entry-slide").hide();
    }

    if (userLocation.currentInfobox === null) {
        // New entry opened
        var footer = $("section#article-section");

        if ($(window).width() < 768) {
            // mobile
            channel = "mobile";
            footer.css("padding", "0.8rem 0.8rem 0 0.8rem");
            jQueryEntryList.data("unslider") && jQueryEntryList.data("unslider").set(0, true);
            footer.transition({height: footerHeight}, 200, "ease");
            initializeSwiping();
            $("main").transition({paddingBottom: footerHeight, marginBottom: "-" + footerHeight}, 200, "ease", function() {
                jQueryEntryList.unslider({
                    complete: loadAdditionalEntry
                });
                jQueryEntryList.data("unslider").set(0, true);
            });
        } else {
            // desktop
            $("div.article-heading").swipe("disable");
            channel = "desktop";
            footer.css({
                height: "100%",
                width: "0%",
                padding: "0.8rem"
            });
            var map = $("section.max_map");
            var map_width = map.width();
            jQueryEntryList.data("unslider") && jQueryEntryList.data("unslider").set(0, true);
            map.transition({width: map_width - 380 + "px"}, 200, "ease");
            footer.transition({width: "380px"}, 200, "ease", function() {
                jQueryEntryList.unslider({
                    complete: loadAdditionalEntry
                });
                jQueryEntryList.data("unslider").set(0, true);
            });
            $("div.entry-list ul li").css("overflow-y", "auto");
        }
    } else {
        // Old entry already opened
        jQueryEntryList.data("unslider").set(0, true);
        userLocation.currentInfobox.close();
        jQueryEntryList.unslider({
            complete: loadAdditionalEntry
        });
        if (channel === "desktop") {
            $("div.entry-list ul li").css("overflow-y", "auto");
        } else {
            initializeSwiping();
        }
    }

    loadAdditionalEntry($("div.entry-list ul li:first"));

    userLocation.currentInfobox = location.infobox;
    location.infobox.open(userLocation.map, location.marker);

    if (location.entries.length > 1) {
        $("a.switch-entry").each(function() {
            $(this).click(function() {
                var entryIndex = $(this).data("entry");
                jQueryEntryList.data("unslider").move(entryIndex);
            });
        });
    }
}

function closeEntry() {
    var footer = $("section#article-section");

    if (channel === "mobile") {
        // mobile
        footer.transition({height: 0}, 200, "ease");
        $("main").transition({paddingBottom: "0px", marginBottom: "0px"}, 200, "ease" , function() {
            footer.css("padding", "0rem");
            $("div.entry-list ul").removeAttr("style");
        });
    } else {
        // desktop
        footer.transition({width: "0%"}, 200, "ease", function() {
            footer.css({
                height: "100%",
                padding: "0rem",
                width: "auto"
            });
            $("div.entry-list ul").removeAttr("style")
        });
        $("section.max_map").transition({width: "100%"}, 200, "ease");
        //footer.css("overflow-y", "hidden");
    }

    if (userLocation.currentInfobox !== null) {
        userLocation.currentInfobox.close();
        userLocation.currentInfobox = null;
    }
}

/**
 * Callback that is called when the viewport changed
 */
function searchForEntries () {
    // calculate bounds to search for
    var bounds = userLocation.map.getBounds()
    var max_lat = bounds.getNorthEast().lat().toFixed(10)
    var max_lon = bounds.getNorthEast().lng().toFixed(10)
    var min_lat = bounds.getSouthWest().lat().toFixed(10)
    var min_lon = bounds.getSouthWest().lng().toFixed(10)
    // get nearby locations
    $.getJSON("/services/get-nearby-locations/" + min_lat + "/" + max_lat + "/" + min_lon + "/" + max_lon + "/", function (data) {
        $.each(data, function (index, value) {
            addMarker(value);
        })
    });
}

/**
 * Location object to enable/disable tracking the location and to retrieve the current or fallback location.
 * @param trackLocation
 * @constructor
 */
function Location() {
	this.DEFAULT_LAT = 50.258;
	this.DEFAULT_LONG = 10.965;
	this.DEFAULT_LOCATION = new google.maps.LatLng(50.258, 10.965);
	this.positionMarker = null;
    this.markers = {}
    this.currentInfobox = null;
}

/**
 * Move the map to the current location or the fallback
 * @returns {google.maps.LatLng|*}
 */
Location.prototype.moveToCurrentLocationOrFallback = function () {
	if (Modernizr.geolocation) {
	    google.maps.event.addListenerOnce(this.positionMarker, 'position_changed', function() {
            this.map.setCenter(this.getPosition());
            this.map.fitBounds(this.getBounds());
            searchForEntries();
        });
	} else {
		this.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
		//TODO: show hint that browser doesn't support location
	}
};

/**
 * Moves the map to the given location
 * @param lat
 * @param long
 */
Location.prototype.moveToLocation = function(position) {
	if (this.map) {
		this.map.panTo(position);
        searchForEntries();
	}
}

var userLocation = new Location();

/**
 * Global map Options
 * @type {{center: google.maps.LatLng, zoom: number, mapTypeId: *, disableDefaultUI: boolean, zoomControl: boolean}}
 */
var mapOptions = {
	center: userLocation.DEFAULT_LOCATION,
	zoom: 17,
    mapTypeControl: true,
	mapTypeId: google.maps.MapTypeId.SATELLITE,
	disableDefaultUI: true,
	zoomControl: true
};

/**
 * Initializes the map
 */
function initialize_Map() {
	userLocation.map = new google.maps.Map(document.getElementById(MAP_ELEMENT),
		mapOptions);
    userLocation.positionMarker = new GeolocationMarker(userLocation.map)
    userLocation.moveToCurrentLocationOrFallback();
    google.maps.event.addListener(userLocation.positionMarker, 'geolocation_error', errorLocationCallback);
    google.maps.event.addListener(userLocation.map, 'idle', searchForEntries)
    google.maps.event.addListener(userLocation.map, 'click', closeEntry);
}<commit_msg>Event.preventDefault on links<commit_after>/**
 * Constant that identifies the map canvas.
 * @type {string}
 */
var MAP_ELEMENT = "map_canvas";

var channel = "mobile";

/**
 * Callback that is called when the location couldn't be retrieved.
 * @param error
 */
function errorLocationCallback (error) {
	// error callback
	userLocation.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
    alert('There was an error obtaining your position. Message: ' + error.message);
	//TODO: show hint that location couldn't be retrieved
}

function addMarker (location) {
    // calculate latitude and longitude
    var latitude = parseFloat(location.latitude._int) * Math.pow(10, location.latitude._exp);
    var longitude = parseFloat(location.longitude._int) * Math.pow(10, location.longitude._exp);

    var entryCount = location.entries.length;
    if (entryCount > 9) {
        entryCount = 0;
    }
    // if not already on the map, display marker
    if (!userLocation.markers.hasOwnProperty(location.id)) {
        var marker = new google.maps.Marker({
            map: userLocation.map,
            position: new google.maps.LatLng(latitude, longitude),
            title: location.label,
            icon: "/static/stadtgedaechtnis/img/marker_" + entryCount + ".png",
            animation: google.maps.Animation.DROP
        });

        location.marker = marker;
        createInfobox(location);

        userLocation.markers[location.id] = location;
    }
}

/**
 * Creates an infobox for this location.
 * @param location
 * @param index index of entry for this infobox
 */
function createInfobox(location) {
    if (location.entries.length > 1) {
        var infoBoxContent = "

";
        for (var i = 0; i < location.entries.length; i++) {
            infoBoxContent += "
" + location.entries[i].title + "
";
        }
        infoBoxContent += "

";
    } else {
        var infoBoxContent = "

" + location.entries[0].abstract + "

";
    }

    var infoBox = new google.maps.InfoWindow({
        content: infoBoxContent,
        maxWidth: 225
    })

    location.infobox = infoBox;
    google.maps.event.clearListeners(location.marker, 'click');
    google.maps.event.addListener(location.marker, 'click', function () {
        openEntry(location);
    });
    google.maps.event.addListener(infoBox, 'closeclick', closeEntry);
}

/**
 * Loads the complete entry for the given location and entry index.
 * @param location
 * @param index
 */
function loadAdditionalEntry(listElement) {
    if (!listElement.data("loaded")) {
        var index = listElement.data("entry");
        var id = listElement.data("id");

        $("article#entry-more-" + index).html("");
        $("img#load-more-" + index).show();
        $.get("/entry/" + id + "/", function (data) {
            $("article#entry-more-" + index).html(data);
            $("img#load-more-" + index).hide();
            listElement.data("loaded", true);
        });
    }
}

/**
 * Opens an infobox for the first entry in this
 * location and pops up the pop up with the
 * correct heading and image. Handles click
 * events on the marker.
 * @param entry
 */
function openEntry(location) {
    var entryList = "";
    for (var i = 0; i < location.entries.length; i++) {
        // create list of entrys for slider
        entryList += '
\

\

';
        if (i > 0) {
            entryList += '
\
                \

'
        }
        entryList += '
\

' + location.entries[i].title + '
\

';
        if (i < location.entries.length - 1) {
            entryList += '
\
                \

';
        }
        entryList += '
\

';
        if (location.entries[i].image !== undefined) {
            entryList += '';
        }
        entryList += '
\
                            \

\

\

\

';
    }

    $("div.entry-list ul").html(entryList);
    var jQueryEntryList = $("section#article-section div.entry-list");

    if (location.entries.length > 1) {
        // Show next and previous buttons
        $("div.entry-slide").show();
        $("div.article-heading-row a.previous").unbind("click").click(function() {
            jQueryEntryList.data("unslider").prev();
            return false;
        });
        $("div.article-heading-row a.next").unbind("click").click(function() {
            jQueryEntryList.data("unslider").next();
            return false;
        });
    } else {
        // Hide next and previous buttons
        $("div.entry-slide").hide();
    }

    if (userLocation.currentInfobox === null) {
        // New entry opened
        var footer = $("section#article-section");

        if ($(window).width() < 768) {
            // mobile
            channel = "mobile";
            footer.css("padding", "0.8rem 0.8rem 0 0.8rem");
            jQueryEntryList.data("unslider") && jQueryEntryList.data("unslider").set(0, true);
            footer.transition({height: footerHeight}, 200, "ease");
            initializeSwiping();
            $("main").transition({paddingBottom: footerHeight, marginBottom: "-" + footerHeight}, 200, "ease", function() {
                jQueryEntryList.unslider({
                    complete: loadAdditionalEntry
                });
                jQueryEntryList.data("unslider").set(0, true);
            });
        } else {
            // desktop
            $("div.article-heading").swipe("disable");
            channel = "desktop";
            footer.css({
                height: "100%",
                width: "0%",
                padding: "0.8rem"
            });
            var map = $("section.max_map");
            var map_width = map.width();
            jQueryEntryList.data("unslider") && jQueryEntryList.data("unslider").set(0, true);
            map.transition({width: map_width - 380 + "px"}, 200, "ease");
            footer.transition({width: "380px"}, 200, "ease", function() {
                jQueryEntryList.unslider({
                    complete: loadAdditionalEntry
                });
                jQueryEntryList.data("unslider").set(0, true);
            });
            $("div.entry-list ul li").css("overflow-y", "auto");
        }
    } else {
        // Old entry already opened
        jQueryEntryList.data("unslider").set(0, true);
        userLocation.currentInfobox.close();
        jQueryEntryList.unslider({
            complete: loadAdditionalEntry
        });
        if (channel === "desktop") {
            $("div.entry-list ul li").css("overflow-y", "auto");
        } else {
            initializeSwiping();
        }
    }

    loadAdditionalEntry($("div.entry-list ul li:first"));

    userLocation.currentInfobox = location.infobox;
    location.infobox.open(userLocation.map, location.marker);

    if (location.entries.length > 1) {
        $("a.switch-entry").each(function() {
            $(this).click(function(event) {
                var entryIndex = $(this).data("entry");
                jQueryEntryList.data("unslider").move(entryIndex);
                event.preventDefault;
                return false;
            });
        });
    }
}

function closeEntry() {
    var footer = $("section#article-section");

    if (channel === "mobile") {
        // mobile
        footer.transition({height: 0}, 200, "ease");
        $("main").transition({paddingBottom: "0px", marginBottom: "0px"}, 200, "ease" , function() {
            footer.css("padding", "0rem");
            $("div.entry-list ul").removeAttr("style");
        });
    } else {
        // desktop
        footer.transition({width: "0%"}, 200, "ease", function() {
            footer.css({
                height: "100%",
                padding: "0rem",
                width: "auto"
            });
            $("div.entry-list ul").removeAttr("style")
        });
        $("section.max_map").transition({width: "100%"}, 200, "ease");
        //footer.css("overflow-y", "hidden");
    }

    if (userLocation.currentInfobox !== null) {
        userLocation.currentInfobox.close();
        userLocation.currentInfobox = null;
    }
}

/**
 * Callback that is called when the viewport changed
 */
function searchForEntries () {
    // calculate bounds to search for
    var bounds = userLocation.map.getBounds()
    var max_lat = bounds.getNorthEast().lat().toFixed(10)
    var max_lon = bounds.getNorthEast().lng().toFixed(10)
    var min_lat = bounds.getSouthWest().lat().toFixed(10)
    var min_lon = bounds.getSouthWest().lng().toFixed(10)
    // get nearby locations
    $.getJSON("/services/get-nearby-locations/" + min_lat + "/" + max_lat + "/" + min_lon + "/" + max_lon + "/", function (data) {
        $.each(data, function (index, value) {
            addMarker(value);
        })
    });
}

/**
 * Location object to enable/disable tracking the location and to retrieve the current or fallback location.
 * @param trackLocation
 * @constructor
 */
function Location() {
	this.DEFAULT_LAT = 50.258;
	this.DEFAULT_LONG = 10.965;
	this.DEFAULT_LOCATION = new google.maps.LatLng(50.258, 10.965);
	this.positionMarker = null;
    this.markers = {}
    this.currentInfobox = null;
}

/**
 * Move the map to the current location or the fallback
 * @returns {google.maps.LatLng|*}
 */
Location.prototype.moveToCurrentLocationOrFallback = function () {
	if (Modernizr.geolocation) {
	    google.maps.event.addListenerOnce(this.positionMarker, 'position_changed', function() {
            this.map.setCenter(this.getPosition());
            this.map.fitBounds(this.getBounds());
            searchForEntries();
        });
	} else {
		this.moveToLocation(this.DEFAULT_LAT, this.DEFAULT_LONG);
		//TODO: show hint that browser doesn't support location
	}
};

/**
 * Moves the map to the given location
 * @param lat
 * @param long
 */
Location.prototype.moveToLocation = function(position) {
	if (this.map) {
		this.map.panTo(position);
        searchForEntries();
	}
}

var userLocation = new Location();

/**
 * Global map Options
 * @type {{center: google.maps.LatLng, zoom: number, mapTypeId: *, disableDefaultUI: boolean, zoomControl: boolean}}
 */
var mapOptions = {
	center: userLocation.DEFAULT_LOCATION,
	zoom: 17,
    mapTypeControl: true,
	mapTypeId: google.maps.MapTypeId.SATELLITE,
	disableDefaultUI: true,
	zoomControl: true
};

/**
 * Initializes the map
 */
function initialize_Map() {
	userLocation.map = new google.maps.Map(document.getElementById(MAP_ELEMENT),
		mapOptions);
    userLocation.positionMarker = new GeolocationMarker(userLocation.map)
    userLocation.moveToCurrentLocationOrFallback();
    google.maps.event.addListener(userLocation.positionMarker, 'geolocation_error', errorLocationCallback);
    google.maps.event.addListener(userLocation.map, 'idle', searchForEntries)
    google.maps.event.addListener(userLocation.map, 'click', closeEntry);
}<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
// var favicon = require('serve-favicon');
// var logger = require('morgan');
// var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
// var compression = require('compression');
// var expressValidator = require('express-validator');

var dev_db_url = 'mongodb://localhost/root';
var mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {
	app.locals.cdn = "https://d14x7hkpd082ov.cloudfront.net";
}
else {
	app.locals.cdn = "/courtside";
}

app.locals.assets = "/courtside";

app.locals.betaUrl = "/courtside/beta/";

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

// app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// app.use(expressValidator() ); // Add this after the bodyParser middleware!
// app.use(cookieParser());

// app.use(compression()); //Compress all routes

require('./routes')(app);

app.use(express.static(path.join(__dirname, 'public')));

// catch 404 and forward to error handler
app.use(function(req, res, next) {
	var err = new Error('Not Found');
	err.status = 404;
	next(err);
});

// error handler
app.use(function(err, req, res, next) {
	// set locals, only providing error in development
	res.locals.message = err.message;
	res.locals.error = req.app.get('env') === 'development' ? err : {};

	// render the error page
	res.status(err.status || 500);
	// res.render('error');
});

module.exports = app;
<commit_msg>cdn for courtside.<commit_after>var express = require('express');
var path = require('path');
// var favicon = require('serve-favicon');
// var logger = require('morgan');
// var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
// var compression = require('compression');
// var expressValidator = require('express-validator');

var dev_db_url = 'mongodb://localhost/root';
var mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {
	app.locals.cdn = "https://d14x7hkpd082ov.cloudfront.net/courtside";
}
else {
	app.locals.cdn = "/courtside";
}

app.locals.assets = "/courtside";

app.locals.betaUrl = "/courtside/beta/";

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

// app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// app.use(expressValidator() ); // Add this after the bodyParser middleware!
// app.use(cookieParser());

// app.use(compression()); //Compress all routes

require('./routes')(app);

app.use(express.static(path.join(__dirname, 'public')));

// catch 404 and forward to error handler
app.use(function(req, res, next) {
	var err = new Error('Not Found');
	err.status = 404;
	next(err);
});

// error handler
app.use(function(err, req, res, next) {
	// set locals, only providing error in development
	res.locals.message = err.message;
	res.locals.error = req.app.get('env') === 'development' ? err : {};

	// render the error page
	res.status(err.status || 500);
	// res.render('error');
});

module.exports = app;
<|endoftext|>


<commit_before>const SECOND = 1000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;

/* eslint-disable id-length, complexity */
const TOKENS = {
	Y: 4,
	Q: 1,
	M: 4,
	D: 4,
	d: 1,
	X: 1,
	x: 1,
	H: 2,
	h: 2,
	a: 1,
	A: 1,
	m: 2,
	s: 2,
	S: 3,
	Z: 2
};
/* eslint-enable id-length */

const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

/**
 * Klasa's Timestamp class, parses the pattern once, displays the desired Date or UNIX timestamp with the selected pattern.
 */
class Timestamp {

	/**
	 * @typedef  {Object} TimestampObject
	 * @memberof Timestamp
	 * @property {string} type The type of the current variable.
	 * @property {string} [content] The content of the type. Only accessible if the type is 'literal'.
	 */

	/**
	 * Starts a new Timestamp and parses the pattern.
	 * @since 0.5.0
	 * @param {string} pattern The pattern to parse.
	 */
	constructor(pattern) {
		/**
		 * @since 0.5.0
		 * @type {string}
		 */
		this.pattern = pattern;
		/**
		 * @since 0.5.0
		 * @type {TimestampObject[]}
		 * @private
		 */
		this._template = [];
		this._patch(pattern);
	}

	/**
	 * Display the current date with the current pattern.
	 * @since 0.5.0
	 * @param {(Date|number|string)} time The time to display.
	 * @returns {string}
	 */
	display(time = Date.now()) {
		let output = '';
		const parsedTime = time instanceof Date ? time : new Date(time);
		for (const entry of this._template) {
			output += entry.content || this._parse(entry.type, parsedTime);
		}
		return output;
	}

	/**
	 * Edits the current pattern.
	 * @since 0.5.0
	 * @param {string} pattern The new pattern for this instance.
	 * @returns {Timestamp}
	 */
	edit(pattern) {
		this.pattern = pattern;
		this._template = [];
		this._patch(pattern);
		return this;
	}

	/**
	 * Parses the current variable.
	 * @since 0.5.0
	 * @param {string} type The type of variable
	 * @param {Date} time The current time.
	 * @returns {string}
	 * @private
	 */
	_parse(type, time) {
		switch (type) {
			// Dates
			case 'Y':
			case 'YY': return String(time.getFullYear()).slice(0, 2);
			case 'YYY':
			case 'YYYY': return String(time.getFullYear());
			case 'Q': return String((time.getMonth() + 1) / 3);
			case 'M':
			case 'MM': return String(time.getMonth() + 1);
			case 'MMM':
			case 'MMMM': return months[time.getMonth()];
			case 'D': return String(time.getDate());
			case 'DD': return String(time.getDate()).padStart(2, '0');
			case 'DDD':
			case 'DDDD': {
				const start = new Date(time.getFullYear(), 0, 0);
				const diff = ((time.getMilliseconds() - start.getMilliseconds()) + (start.getTimezoneOffset() - time.getTimezoneOffset())) * MINUTE;
				return String(Math.floor(diff / DAY));
			}
			case 'd': {
				const day = String(time.getDate());
				if (day.endsWith('1')) return `${day}st`;
				if (day.endsWith('2')) return `${day}nd`;
				if (day.endsWith('3')) return `${day}rd`;
				return `${day}th`;
			}
			case 'X': return String(time.valueOf() / SECOND);
			case 'x': return String(time.valueOf());

			// Times
			case 'H': return String(time.getHours());
			case 'HH': return String(time.getHours()).padStart(2, '0');
			case 'h': return String(time.getHours() % 12);
			case 'hh': return String(time.getHours() % 12).padStart(2, '0');
			case 'a': return time.getHours() < 12 ? 'am' : 'pm';
			case 'A': return time.getHours() < 12 ? 'AM' : 'PM';
			case 'm': return String(time.getMinutes());
			case 'mm': return String(time.getMinutes()).padStart(2, '0');
			case 's': return String(time.getSeconds());
			case 'ss': return String(time.getSeconds()).padStart(2, '0');
			case 'S': return String(time.getMilliseconds());
			case 'SS': return String(time.getMilliseconds()).padStart(2, '0');
			case 'SSS': return String(time.getMilliseconds()).padStart(3, '0');
			case 'Z':
			case 'ZZ': {
				const offset = time.getTimezoneOffset();
				return `${offset >= 0 ? '+' : '-'}${String(offset / -60).padStart(2, '0')}:${String(offset % 60).padStart(2, '0')}`;
			}
			default: return type;
		}
	}

	/**
	 * Parses the pattern.
	 * @since 0.5.0
	 * @param {string} pattern The pattern to parse.
	 * @private
	 */
	_patch(pattern) {
		for (let i = 0; i < pattern.length; i++) {
			let current = '';
			const currentChar = pattern[i];
			if (currentChar in TOKENS) {
				current += currentChar;
				while (pattern[i + 1] === currentChar && current.length < TOKENS[currentChar]) current += pattern[++i];
				this._template.push({ type: current });
			} else if (currentChar === '[') {
				while (i + 1 < pattern.length && pattern[i + 1] !== ']') current += pattern[++i];
				i++;
				this._template.push({ type: 'literal', content: current });
			} else {
				current += currentChar;
				while (i + 1 < pattern.length && !(pattern[i + 1] in TOKENS) && pattern[i + 1] !== '[') current += pattern[++i];
				this._template.push({ type: 'literal', content: current });
			}
		}
	}

	/**
	 * Shows the userfriendly duration of time between a period and now.
	 * @since 0.5.0
	 * @param {(Date|number|string)} earlier The time to compare.
	 * @param {boolean} [showIn] Whether the output should be prefixed.
	 * @returns {string}
	 */
	static toNow(earlier, showIn) {
		if (!(earlier instanceof Date)) earlier = new Date(earlier);
		const returnString = showIn ? 'in ' : '';
		let duration = (Date.now() - earlier) / 1000;

		// Compare the duration in seconds
		if (duration < 45) return `${returnString}seconds`;
		else if (duration < 90) return `${returnString}a minute`;

		// Compare the duration in minutes
		duration /= 60;
		if (duration < 45) return `${returnString + Math.round(duration)} minutes`;
		else if (duration < 90) return `${returnString}an hour`;

		// Compare the duration in hours
		duration /= 60;
		if (duration < 22) return `${returnString + Math.round(duration)} hours`;
		else if (duration < 36) return `${returnString}a day`;

		// Compare the duration in days
		duration /= 24;
		if (duration < 26) return `${returnString + Math.round(duration)} days`;
		else if (duration < 46) return `${returnString}a month`;
		else if (duration < 320) return `${returnString + Math.round(duration / 30)} months`;
		else if (duration < 548) return `${returnString}a year`;

		return `${returnString + Math.floor(duration / 365)} years`;
	}

}

module.exports = Timestamp;
<commit_msg>11st, 12nd, and 13rd no more<commit_after>const SECOND = 1000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;

/* eslint-disable id-length, complexity */
const TOKENS = {
	Y: 4,
	Q: 1,
	M: 4,
	D: 4,
	d: 1,
	X: 1,
	x: 1,
	H: 2,
	h: 2,
	a: 1,
	A: 1,
	m: 2,
	s: 2,
	S: 3,
	Z: 2
};
/* eslint-enable id-length */

const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

/**
 * Klasa's Timestamp class, parses the pattern once, displays the desired Date or UNIX timestamp with the selected pattern.
 */
class Timestamp {

	/**
	 * @typedef  {Object} TimestampObject
	 * @memberof Timestamp
	 * @property {string} type The type of the current variable.
	 * @property {string} [content] The content of the type. Only accessible if the type is 'literal'.
	 */

	/**
	 * Starts a new Timestamp and parses the pattern.
	 * @since 0.5.0
	 * @param {string} pattern The pattern to parse.
	 */
	constructor(pattern) {
		/**
		 * @since 0.5.0
		 * @type {string}
		 */
		this.pattern = pattern;
		/**
		 * @since 0.5.0
		 * @type {TimestampObject[]}
		 * @private
		 */
		this._template = [];
		this._patch(pattern);
	}

	/**
	 * Display the current date with the current pattern.
	 * @since 0.5.0
	 * @param {(Date|number|string)} time The time to display.
	 * @returns {string}
	 */
	display(time = Date.now()) {
		let output = '';
		const parsedTime = time instanceof Date ? time : new Date(time);
		for (const entry of this._template) {
			output += entry.content || this._parse(entry.type, parsedTime);
		}
		return output;
	}

	/**
	 * Edits the current pattern.
	 * @since 0.5.0
	 * @param {string} pattern The new pattern for this instance.
	 * @returns {Timestamp}
	 */
	edit(pattern) {
		this.pattern = pattern;
		this._template = [];
		this._patch(pattern);
		return this;
	}

	/**
	 * Parses the current variable.
	 * @since 0.5.0
	 * @param {string} type The type of variable
	 * @param {Date} time The current time.
	 * @returns {string}
	 * @private
	 */
	_parse(type, time) {
		switch (type) {
			// Dates
			case 'Y':
			case 'YY': return String(time.getFullYear()).slice(0, 2);
			case 'YYY':
			case 'YYYY': return String(time.getFullYear());
			case 'Q': return String((time.getMonth() + 1) / 3);
			case 'M':
			case 'MM': return String(time.getMonth() + 1);
			case 'MMM':
			case 'MMMM': return months[time.getMonth()];
			case 'D': return String(time.getDate());
			case 'DD': return String(time.getDate()).padStart(2, '0');
			case 'DDD':
			case 'DDDD': {
				const start = new Date(time.getFullYear(), 0, 0);
				const diff = ((time.getMilliseconds() - start.getMilliseconds()) + (start.getTimezoneOffset() - time.getTimezoneOffset())) * MINUTE;
				return String(Math.floor(diff / DAY));
			}
			case 'd': {
				const day = String(time.getDate());
				if (day !== '11' && day.endsWith('1')) return `${day}st`;
				if (day !== '12' && day.endsWith('2')) return `${day}nd`;
				if (day !== '13' && day.endsWith('3')) return `${day}rd`;
				return `${day}th`;
			}
			case 'X': return String(time.valueOf() / SECOND);
			case 'x': return String(time.valueOf());

			// Times
			case 'H': return String(time.getHours());
			case 'HH': return String(time.getHours()).padStart(2, '0');
			case 'h': return String(time.getHours() % 12);
			case 'hh': return String(time.getHours() % 12).padStart(2, '0');
			case 'a': return time.getHours() < 12 ? 'am' : 'pm';
			case 'A': return time.getHours() < 12 ? 'AM' : 'PM';
			case 'm': return String(time.getMinutes());
			case 'mm': return String(time.getMinutes()).padStart(2, '0');
			case 's': return String(time.getSeconds());
			case 'ss': return String(time.getSeconds()).padStart(2, '0');
			case 'S': return String(time.getMilliseconds());
			case 'SS': return String(time.getMilliseconds()).padStart(2, '0');
			case 'SSS': return String(time.getMilliseconds()).padStart(3, '0');
			case 'Z':
			case 'ZZ': {
				const offset = time.getTimezoneOffset();
				return `${offset >= 0 ? '+' : '-'}${String(offset / -60).padStart(2, '0')}:${String(offset % 60).padStart(2, '0')}`;
			}
			default: return type;
		}
	}

	/**
	 * Parses the pattern.
	 * @since 0.5.0
	 * @param {string} pattern The pattern to parse.
	 * @private
	 */
	_patch(pattern) {
		for (let i = 0; i < pattern.length; i++) {
			let current = '';
			const currentChar = pattern[i];
			if (currentChar in TOKENS) {
				current += currentChar;
				while (pattern[i + 1] === currentChar && current.length < TOKENS[currentChar]) current += pattern[++i];
				this._template.push({ type: current });
			} else if (currentChar === '[') {
				while (i + 1 < pattern.length && pattern[i + 1] !== ']') current += pattern[++i];
				i++;
				this._template.push({ type: 'literal', content: current });
			} else {
				current += currentChar;
				while (i + 1 < pattern.length && !(pattern[i + 1] in TOKENS) && pattern[i + 1] !== '[') current += pattern[++i];
				this._template.push({ type: 'literal', content: current });
			}
		}
	}

	/**
	 * Shows the userfriendly duration of time between a period and now.
	 * @since 0.5.0
	 * @param {(Date|number|string)} earlier The time to compare.
	 * @param {boolean} [showIn] Whether the output should be prefixed.
	 * @returns {string}
	 */
	static toNow(earlier, showIn) {
		if (!(earlier instanceof Date)) earlier = new Date(earlier);
		const returnString = showIn ? 'in ' : '';
		let duration = (Date.now() - earlier) / 1000;

		// Compare the duration in seconds
		if (duration < 45) return `${returnString}seconds`;
		else if (duration < 90) return `${returnString}a minute`;

		// Compare the duration in minutes
		duration /= 60;
		if (duration < 45) return `${returnString + Math.round(duration)} minutes`;
		else if (duration < 90) return `${returnString}an hour`;

		// Compare the duration in hours
		duration /= 60;
		if (duration < 22) return `${returnString + Math.round(duration)} hours`;
		else if (duration < 36) return `${returnString}a day`;

		// Compare the duration in days
		duration /= 24;
		if (duration < 26) return `${returnString + Math.round(duration)} days`;
		else if (duration < 46) return `${returnString}a month`;
		else if (duration < 320) return `${returnString + Math.round(duration / 30)} months`;
		else if (duration < 548) return `${returnString}a year`;

		return `${returnString + Math.floor(duration / 365)} years`;
	}

}

module.exports = Timestamp;
<|endoftext|>


<commit_before>
'{ langjs }';

(function(root) {
    Lang.setMessages('{ messages }');
})(window);
<commit_msg>Newline removed to template.<commit_after>'{ langjs }';

(function(root) {
    Lang.setMessages('{ messages }');
})(window);
<|endoftext|>


<commit_before>///import core
///commands 修复chrome下图片不能点击的问题，出现八个角可改变大小
///commandsName  FixImgClick
///commandsTitle  修复chrome下图片不能点击的问题，出现八个角可改变大小
//修复chrome下图片不能点击的问题，出现八个角可改变大小

UE.plugins['fiximgclick'] = (function () {

    function Scale() {
        this.editor = null;
        this.resizer = null;
        this.cover = null;
        this.doc = document;
        this.prePos = {x: 0, y: 0};
        this.startPos = {x: 0, y: 0};
    }

    (function () {
        var rect = [
            //[left, top, width, height]
            [0, 0, -1, -1],
            [0, 0, 0, -1],
            [0, 0, 1, -1],
            [0, 0, -1, 0],
            [0, 0, 1, 0],
            [0, 0, -1, 1],
            [0, 0, 0, 1],
            [0, 0, 1, 1]
        ];

        Scale.prototype = {
            init: function (editor) {
                var me = this;
                me.editor = editor;
                me.startPos = this.prePos = {x: 0, y: 0};
                me.dragId = -1;

                var hands = [],
                    cover = me.cover = document.createElement('div'),
                    resizer = me.resizer = document.createElement('div');

                cover.id = me.editor.ui.id + '_imagescale_cover';
                cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;';
                domUtils.on(cover, 'mousedown click', function () {
                    me.hide();
                });

                for (i = 0; i < 8; i++) {
                    hands.push('');
                }
                resizer.id = me.editor.ui.id + '_imagescale';
                resizer.className = 'edui-editor-scale';
                resizer.innerHTML = hands.join('');
                resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';';

                me.editor.ui.getDom().appendChild(cover);
                me.editor.ui.getDom().appendChild(resizer);

                me.initStyle();
                me.initEvents();
            },
            initStyle: function () {
                utils.cssRule('imagescale', '.edui-editor-scale{position:absolute;border:1px solid #38B2CE;}' +
                    '.edui-editor-scale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}'
                    + '.edui-editor-scale .edui-editor-scale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}');
            },
            initEvents: function () {
                var me = this;

                me.startPos.x = me.startPos.y = 0;
                me.isDraging = false;
            },
            _eventHandler: function (e) {
                var me = this;
                switch (e.type) {
                    case 'mousedown':
                        var hand = e.target || e.srcElement, hand;
                        if (hand.className.indexOf('edui-editor-scale-hand') != -1 && me.dragId == -1) {
                            me.dragId = hand.className.slice(-1);
                            me.startPos.x = me.prePos.x = e.clientX;
                            me.startPos.y = me.prePos.y = e.clientY;
                            domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me));
                        }
                        break;
                    case 'mousemove':
                        if (me.dragId != -1) {
                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});
                            me.prePos.x = e.clientX;
                            me.prePos.y = e.clientY;
                            me.updateTargetElement();

                        }
                        break;
                    case 'mouseup':
                        if (me.dragId != -1) {
                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});
                            me.updateTargetElement();
                            if (me.target.parentNode) me.attachTo(me.target);
                            me.dragId = -1;
                        }
                        domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me));
                        me.editor.fireEvent('contentchange');
                        break;
                    default:
                        break;
                }
            },
            updateTargetElement: function () {
                var me = this,
                    targetPos;
                domUtils.setStyles(me.target, {
                    'width': me.resizer.style.width,
                    'height': me.resizer.style.height
                });
                me.attachTo(me.target);
            },
            updateContainerStyle: function (dir, offset) {
                var me = this,
                    dom = me.resizer, tmp;

                if (rect[dir][0] != 0) {
                    tmp = parseInt(dom.style.left) + offset.x;
                    dom.style.left = me._validScaledProp('left', tmp) + 'px';
                }
                if (rect[dir][1] != 0) {
                    tmp = parseInt(dom.style.top) + offset.y;
                    dom.style.top = me._validScaledProp('top', tmp) + 'px';
                }
                if (rect[dir][2] != 0) {
                    tmp = dom.clientWidth + rect[dir][2] * offset.x;
                    dom.style.width = me._validScaledProp('width', tmp) + 'px';
                }
                if (rect[dir][3] != 0) {
                    tmp = dom.clientHeight + rect[dir][3] * offset.y;
                    dom.style.height = me._validScaledProp('height', tmp) + 'px';
                }
            },
            _validScaledProp: function (prop, value) {
                var ele = this.resizer,
                    wrap = document;

                value = isNaN(value) ? 0 : value;
                switch (prop) {
                    case 'left':
                        return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value;
                    case 'top':
                        return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value;
                    case 'width':
                        return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value;
                    case 'height':
                        return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value;
                }
            },
            hideCover: function () {
                this.cover.style.display = 'none';
            },
            showCover: function () {
                var me = this,
                    editorPos = domUtils.getXY(me.editor.ui.getDom()),
                    iframePos = domUtils.getXY(me.editor.iframe);

                domUtils.setStyles(me.cover, {
                    'width': me.editor.iframe.offsetWidth + 'px',
                    'height': me.editor.iframe.offsetHeight + 'px',
                    'top': iframePos.y - editorPos.y + 'px',
                    'left': iframePos.x - editorPos.x + 'px',
                    'position': 'absolute',
                    'display': ''
                })
            },
            show: function (targetObj) {
                var me = this;
                me.resizer.style.display = 'block';
                if(targetObj) me.attachTo(targetObj);

                domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me));
                domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me));

                me.showCover();
                me.editor.fireEvent('afterscaleshow', me);
                me.editor.fireEvent('saveScene');
            },
            hide: function () {
                var me = this;
                me.hideCover();
                me.resizer.style.display = 'none';

                domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me));
                domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me));
                me.editor.fireEvent('afterscalehide', me);
            },
            proxy: function( fn, context ) {
                return function(e) {
                    return fn.apply( context || this, arguments);
                };
            },
            attachTo: function (targetObj) {
                var me = this,
                    target = me.target = targetObj,
                    resizer = this.resizer,
                    imgPos = domUtils.getXY(target),
                    iframePos = domUtils.getXY(me.editor.iframe),
                    editorPos = domUtils.getXY(resizer.parentNode);

                domUtils.setStyles(resizer, {
                    'width': target.width + 'px',
                    'height': target.height + 'px',
                    'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px',
                    'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px'
                });
            }
        }
    })();

    return function () {
        var me = this,
            imageScale;

        me.setOpt('imageScaleEnabled', true);

        if ( !browser.ie && me.options.imageScaleEnabled) {
            me.addListener('click', function (type, e) {

                var range = me.selection.getRange(),
                    img = range.getClosedNode();

                if (img && img.tagName == 'IMG' && me.body.contentEditable!="false") {
                    if (!imageScale) {
                        imageScale = new Scale();
                        imageScale.init(me);
                        me.ui.getDom().appendChild(imageScale.resizer);

                        var _keyDownHandler = function (e) {
                            imageScale.hide();
                            if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select();
                        }, _mouseDownHandler = function (e) {
                            var ele = e.target || e.srcElement;
                            if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-scale') == -1)) {
                                _keyDownHandler(e);
                            }
                        }, timer;

                        me.addListener('afterscaleshow', function (e) {
                            me.addListener('beforekeydown', _keyDownHandler);
                            me.addListener('beforemousedown', _mouseDownHandler);
                            domUtils.on(document, 'keydown', _keyDownHandler);
                            domUtils.on(document,'mousedown', _mouseDownHandler);
                            me.selection.getNative().removeAllRanges();
                        });
                        me.addListener('afterscalehide', function (e) {
                            me.removeListener('beforekeydown', _keyDownHandler);
                            me.removeListener('beforemousedown', _mouseDownHandler);
                            domUtils.un(document, 'keydown', _keyDownHandler);
                            domUtils.un(document,'mousedown', _mouseDownHandler);
                            var target = imageScale.target;
                            if (target.parentNode) {
                                me.selection.getRange().selectNode(target).select();
                            }
                        });
                        //TODO 有iframe的情况，mousedown不能往下传。。
                        domUtils.on(imageScale.resizer, 'mousedown', function (e) {
                            me.selection.getNative().removeAllRanges();
                            var ele = e.target || e.srcElement;
                            if (ele && ele.className.indexOf('edui-editor-scale-hand') == -1) {
                                timer = setTimeout(function () {
                                    imageScale.hide();
                                    if(imageScale.target) me.selection.getRange().selectNode(ele).select();
                                }, 200);
                            }
                        });
                        domUtils.on(imageScale.resizer, 'mouseup', function (e) {
                            var ele = e.target || e.srcElement;
                            if (ele && ele.className.indexOf('edui-editor-scale-hand') == -1) {
                                clearTimeout(timer);
                            }
                        });
                    }
                    imageScale.show(img);
                } else {
                    if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide();
                }
            });
        }

        if (browser.webkit) {
            me.addListener('click', function (type, e) {
                if (e.target.tagName == 'IMG' && me.body.contentEditable!="false") {
                    var range = new dom.Range(me.document);
                    range.selectNode(e.target).select();
                }
            });
        }
    }
})();<commit_msg>mageScaleEnabled=true时，mouseup会造成contentchange事件重复发送多次<commit_after>///import core
///commands 修复chrome下图片不能点击的问题，出现八个角可改变大小
///commandsName  FixImgClick
///commandsTitle  修复chrome下图片不能点击的问题，出现八个角可改变大小
//修复chrome下图片不能点击的问题，出现八个角可改变大小

UE.plugins['fiximgclick'] = (function () {

    var elementUpdated = false;
    function Scale() {
        this.editor = null;
        this.resizer = null;
        this.cover = null;
        this.doc = document;
        this.prePos = {x: 0, y: 0};
        this.startPos = {x: 0, y: 0};
    }

    (function () {
        var rect = [
            //[left, top, width, height]
            [0, 0, -1, -1],
            [0, 0, 0, -1],
            [0, 0, 1, -1],
            [0, 0, -1, 0],
            [0, 0, 1, 0],
            [0, 0, -1, 1],
            [0, 0, 0, 1],
            [0, 0, 1, 1]
        ];

        Scale.prototype = {
            init: function (editor) {
                var me = this;
                me.editor = editor;
                me.startPos = this.prePos = {x: 0, y: 0};
                me.dragId = -1;

                var hands = [],
                    cover = me.cover = document.createElement('div'),
                    resizer = me.resizer = document.createElement('div');

                cover.id = me.editor.ui.id + '_imagescale_cover';
                cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;';
                domUtils.on(cover, 'mousedown click', function () {
                    me.hide();
                });

                for (i = 0; i < 8; i++) {
                    hands.push('');
                }
                resizer.id = me.editor.ui.id + '_imagescale';
                resizer.className = 'edui-editor-scale';
                resizer.innerHTML = hands.join('');
                resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';';

                me.editor.ui.getDom().appendChild(cover);
                me.editor.ui.getDom().appendChild(resizer);

                me.initStyle();
                me.initEvents();
            },
            initStyle: function () {
                utils.cssRule('imagescale', '.edui-editor-scale{position:absolute;border:1px solid #38B2CE;}' +
                    '.edui-editor-scale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}'
                    + '.edui-editor-scale .edui-editor-scale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}'
                    + '.edui-editor-scale .edui-editor-scale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}');
            },
            initEvents: function () {
                var me = this;

                me.startPos.x = me.startPos.y = 0;
                me.isDraging = false;
            },
            _eventHandler: function (e) {
                var me = this;
                switch (e.type) {
                    case 'mousedown':
                        var hand = e.target || e.srcElement, hand;
                        if (hand.className.indexOf('edui-editor-scale-hand') != -1 && me.dragId == -1) {
                            me.dragId = hand.className.slice(-1);
                            me.startPos.x = me.prePos.x = e.clientX;
                            me.startPos.y = me.prePos.y = e.clientY;
                            domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me));
                        }
                        break;
                    case 'mousemove':
                        if (me.dragId != -1) {
                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});
                            me.prePos.x = e.clientX;
                            me.prePos.y = e.clientY;
                            elementUpdated = true;
                            me.updateTargetElement();

                        }
                        break;
                    case 'mouseup':
                        if (me.dragId != -1) {
                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});
                            me.updateTargetElement();
                            if (me.target.parentNode) me.attachTo(me.target);
                            me.dragId = -1;
                        }
                        domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me));
                        //修复只是点击挪动点，但没有改变大小，不应该触发contentchange
                        if(elementUpdated){
                            elementUpdated = false;
                            me.editor.fireEvent('contentchange');
                        }

                        break;
                    default:
                        break;
                }
            },
            updateTargetElement: function () {
                var me = this,
                    targetPos;
                domUtils.setStyles(me.target, {
                    'width': me.resizer.style.width,
                    'height': me.resizer.style.height
                });
                me.attachTo(me.target);
            },
            updateContainerStyle: function (dir, offset) {
                var me = this,
                    dom = me.resizer, tmp;

                if (rect[dir][0] != 0) {
                    tmp = parseInt(dom.style.left) + offset.x;
                    dom.style.left = me._validScaledProp('left', tmp) + 'px';
                }
                if (rect[dir][1] != 0) {
                    tmp = parseInt(dom.style.top) + offset.y;
                    dom.style.top = me._validScaledProp('top', tmp) + 'px';
                }
                if (rect[dir][2] != 0) {
                    tmp = dom.clientWidth + rect[dir][2] * offset.x;
                    dom.style.width = me._validScaledProp('width', tmp) + 'px';
                }
                if (rect[dir][3] != 0) {
                    tmp = dom.clientHeight + rect[dir][3] * offset.y;
                    dom.style.height = me._validScaledProp('height', tmp) + 'px';
                }
            },
            _validScaledProp: function (prop, value) {
                var ele = this.resizer,
                    wrap = document;

                value = isNaN(value) ? 0 : value;
                switch (prop) {
                    case 'left':
                        return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value;
                    case 'top':
                        return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value;
                    case 'width':
                        return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value;
                    case 'height':
                        return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value;
                }
            },
            hideCover: function () {
                this.cover.style.display = 'none';
            },
            showCover: function () {
                var me = this,
                    editorPos = domUtils.getXY(me.editor.ui.getDom()),
                    iframePos = domUtils.getXY(me.editor.iframe);

                domUtils.setStyles(me.cover, {
                    'width': me.editor.iframe.offsetWidth + 'px',
                    'height': me.editor.iframe.offsetHeight + 'px',
                    'top': iframePos.y - editorPos.y + 'px',
                    'left': iframePos.x - editorPos.x + 'px',
                    'position': 'absolute',
                    'display': ''
                })
            },
            show: function (targetObj) {
                var me = this;
                me.resizer.style.display = 'block';
                if(targetObj) me.attachTo(targetObj);

                domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me));
                domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me));

                me.showCover();
                me.editor.fireEvent('afterscaleshow', me);
                me.editor.fireEvent('saveScene');
            },
            hide: function () {
                var me = this;
                me.hideCover();
                me.resizer.style.display = 'none';

                domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me));
                domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me));
                me.editor.fireEvent('afterscalehide', me);
            },
            proxy: function( fn, context ) {
                return function(e) {
                    return fn.apply( context || this, arguments);
                };
            },
            attachTo: function (targetObj) {
                var me = this,
                    target = me.target = targetObj,
                    resizer = this.resizer,
                    imgPos = domUtils.getXY(target),
                    iframePos = domUtils.getXY(me.editor.iframe),
                    editorPos = domUtils.getXY(resizer.parentNode);

                domUtils.setStyles(resizer, {
                    'width': target.width + 'px',
                    'height': target.height + 'px',
                    'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px',
                    'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px'
                });
            }
        }
    })();

    return function () {
        var me = this,
            imageScale;

        me.setOpt('imageScaleEnabled', true);

        if ( !browser.ie && me.options.imageScaleEnabled) {
            me.addListener('click', function (type, e) {

                var range = me.selection.getRange(),
                    img = range.getClosedNode();

                if (img && img.tagName == 'IMG' && me.body.contentEditable!="false") {
                    if (!imageScale) {
                        imageScale = new Scale();
                        imageScale.init(me);
                        me.ui.getDom().appendChild(imageScale.resizer);

                        var _keyDownHandler = function (e) {
                            imageScale.hide();
                            if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select();
                        }, _mouseDownHandler = function (e) {
                            var ele = e.target || e.srcElement;
                            if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-scale') == -1)) {
                                _keyDownHandler(e);
                            }
                        }, timer;

                        me.addListener('afterscaleshow', function (e) {
                            me.addListener('beforekeydown', _keyDownHandler);
                            me.addListener('beforemousedown', _mouseDownHandler);
                            domUtils.on(document, 'keydown', _keyDownHandler);
                            domUtils.on(document,'mousedown', _mouseDownHandler);
                            me.selection.getNative().removeAllRanges();
                        });
                        me.addListener('afterscalehide', function (e) {
                            me.removeListener('beforekeydown', _keyDownHandler);
                            me.removeListener('beforemousedown', _mouseDownHandler);
                            domUtils.un(document, 'keydown', _keyDownHandler);
                            domUtils.un(document,'mousedown', _mouseDownHandler);
                            var target = imageScale.target;
                            if (target.parentNode) {
                                me.selection.getRange().selectNode(target).select();
                            }
                        });
                        //TODO 有iframe的情况，mousedown不能往下传。。
                        domUtils.on(imageScale.resizer, 'mousedown', function (e) {
                            me.selection.getNative().removeAllRanges();
                            var ele = e.target || e.srcElement;
                            if (ele && ele.className.indexOf('edui-editor-scale-hand') == -1) {
                                timer = setTimeout(function () {
                                    imageScale.hide();
                                    if(imageScale.target) me.selection.getRange().selectNode(ele).select();
                                }, 200);
                            }
                        });
                        domUtils.on(imageScale.resizer, 'mouseup', function (e) {
                            var ele = e.target || e.srcElement;
                            if (ele && ele.className.indexOf('edui-editor-scale-hand') == -1) {
                                clearTimeout(timer);
                            }
                        });
                    }
                    imageScale.show(img);
                } else {
                    if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide();
                }
            });
        }

        if (browser.webkit) {
            me.addListener('click', function (type, e) {
                if (e.target.tagName == 'IMG' && me.body.contentEditable!="false") {
                    var range = new dom.Range(me.document);
                    range.selectNode(e.target).select();
                }
            });
        }
    }
})();<|endoftext|>


<commit_before>const
    {app} = require('electron'),
    fs = require('fs-extra'),
    Path = require('path'),
    klaw = require('klaw-sync');

var PluginManager = {
    loadedPlugins: {},

    LoadPlugins: function(mod, appEvents) {
        var pluginFolders = fs.readdirSync( Path.resolve(app.getAppPath() + '/plugins') )

        pluginFolders.forEach((pluginFolder) => {
            var pluginPath = Path.resolve('plugins', pluginFolder),
                stat = fs.statSync(pluginPath);

            if(stat && stat.isDirectory()) {
                loadPlugin(pluginPath, mod, appEvents);
            }
        });
    }
}

function loadPlugin(dir, mod) {
    const pluginManifestPath = Path.resolve(dir, 'package.json');

    // Register the plugin
    var pluginManifest = fs.readJsonSync(pluginManifestPath);
    PluginManager.loadedPlugins[pluginManifest.name] = {
        manifest: pluginManifest,
        module: mod.require(dir)
    };

    // Execute the plugin's initial script
    PluginManager.loadedPlugins[pluginManifest.name].module()
    console.log('Plugin:', pluginManifest.name, 'loaded');
}

module.exports = PluginManager;
<commit_msg>Refactor small bit of PluginManager code and debug log the number of plugins found<commit_after>const
    {app} = require('electron'),
    fs = require('fs-extra'),
    Path = require('path'),
    klaw = require('klaw-sync');

var PluginManager = {
    loadedPlugins: {},

    LoadPlugins: function(mod, appEvents) {
        const appPath = Path.resolve(app.getAppPath() + '/plugins');
        var pluginFolders = fs.readdirSync( appPath )
        console.log('Loading ' + pluginFolders.length + ' plugins from ' + appPath)

        pluginFolders.forEach((pluginFolder) => {
            var pluginPath = Path.resolve('plugins', pluginFolder),
                stat = fs.statSync(pluginPath);

            if(stat && stat.isDirectory()) {
                loadPlugin(pluginPath, mod, appEvents);
            }
        });
    }
}

function loadPlugin(dir, mod) {
    const pluginManifestPath = Path.resolve(dir, 'package.json');

    // Register the plugin
    var pluginManifest = fs.readJsonSync(pluginManifestPath);
    PluginManager.loadedPlugins[pluginManifest.name] = {
        manifest: pluginManifest,
        module: mod.require(dir)
    };

    // Execute the plugin's initial script
    PluginManager.loadedPlugins[pluginManifest.name].module()
    console.log('Plugin:', pluginManifest.name, 'loaded');
}

module.exports = PluginManager;
<|endoftext|>