<commit_before>var
	kind = require('enyo/kind');

var
	FittableRows = require('layout/FittableRows'),
	Button = require('moonstone/Button'),
	Divider = require('moonstone/Divider'),
	Input = require('moonstone/Input'),
	InputDecorator = require('moonstone/InputDecorator'),
	Marquee = require('moonstone/Marquee'),
	MarqueeDecorator = Marquee.Decorator,
	MarqueeItem = Marquee.Item,
	MarqueeSupport = Marquee.Support,
	MarqueeText = Marquee.Text,
	Scroller = require('moonstone/Scroller');

module.exports = kind({
	name: 'moon.sample.MarqueeSample',
	kind: FittableRows,
	classes: 'moon enyo-unselectable enyo-fit moon-marquee-sample',
	components: [
		{kind: Scroller, fit: true, components: [
			{classes: 'moon-marquee-sample-wrapper', components: [

				{kind: Divider, content: 'Marquee on start:'},
				{kind: MarqueeDecorator, marqueeOnRender: true, components: [
					{name: 'marqueeStartOnRender1', kind: MarqueeText, classes: 'moon-marquee-start-on-render', content: 'This first long text for the marquee test starts the marquee on page render'},
					{name: 'marqueeStartOnRender2', kind: MarqueeText, classes: 'moon-marquee-start-on-render', content: 'This second long text for the marquee test is syncronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnRender3', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This third long text for the marquee test is not syncronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on focus:'},
				{kind: MarqueeDecorator, marqueeOnSpotlight: true, components: [
					{name: 'marqueeStartOnFocus1', kind: MarqueeText, spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This first long text for the marquee test starts the marquee on focus'},
					{name: 'marqueeStartOnFocus2', kind: MarqueeText, spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This second long text for the marquee test is syncronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnFocus3', marqueeOnSpotlight: true, mixins: [MarqueeSupport, MarqueeItem], spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This third long text for the marquee test is not syncronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on Hover:'},
				{kind: MarqueeDecorator, marqueeOnHover: true, marqueeOnSpotlight: false, components: [
					{name: 'marqueeStartOnHover1', kind: MarqueeText, classes: 'moon-marquee-start-on-hover', content: 'This first long text for the marquee test starts the marquee on mouse hover'},
					{name: 'marqueeStartOnHover2', kind: MarqueeText, classes: 'moon-marquee-start-on-hover', content: 'This second long text for the marquee test is syncronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnHover3', marqueeOnHover: true, marqueeOnSpotlight: false, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-hover', content: 'This third long text for the marquee test is not syncronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on content changed:'},
				{kind: InputDecorator, components: [
					{kind: Input, placeholder: 'JUST TYPE', oninput: 'contentChange'}

				]},
				{kind: Button, content: 'Start marquee', ontap: 'start'},
				{kind: Button, content: 'Stop marquee', ontap: 'stop'},
				{name: 'marqueeContent1', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text is for marquee content change test for the separate marquee case'},
				{name: 'marqueeContent2', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', centered: true, content: 'Centered text for separate marquee case'},
				{name: 'marqueeContainer1', mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{name: 'marqueeContent3', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for marquee content change test for syncronized case'},
					{name: 'marqueeContent4', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is short text for marquee'},
					{name: 'marqueeContent5', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', centered: true, content: 'This is centered text for marquee'}
				]},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee speed:'},
				{name: 'marqueeSpeed', marqueeOnRender: true, marqueeSpeed: 180, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for fast marquee speed test, which is twice as fast as normal marquee'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee pause:'},
				{name: 'marqueePause1', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text for marquee has a 1000ms pause time'},
				{name: 'marqueePause2', marqueeOnRender: true, marqueePause: 2000, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text for marquee has a 2000ms pause time'},
				{tag: 'br'},

				{kind: Divider, content: 'Disabled Text marquee:'},
				{name: 'marqueeDisabled', marqueeOnRender: true, disabled: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for the marquee test with a disabled property'},
				{tag: 'br'},

				{kind: Divider, content: 'Disabled Wrap Instead Of Marquee:'},
				{name: 'marqueeDisabledWrap', wrapInsteadOfMarquee: true, disabled: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for disabled text which wraps because wrapInsteadOfMarquee is set to true'},
				{tag: 'br'},

				{kind: Divider, content: 'LTR Languages:'},
				{mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'The quick brown fox jumped over the lazy dog.  The bean bird flies at sundown.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'Η γρήγορη καφέ αλεπού πήδηξε πάνω από το μεσημέρι. Το πουλί πετά σε φασολιών δύση του ηλίου.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'ਤੁਰੰਤ ਭੂਰਾ Fox ਆਲਸੀ ਕੁੱਤੇ ਨੂੰ ਵੱਧ ਗਈ. ਬੀਨ ਪੰਛੀ ਸੂਰਜ ਡੁੱਬਣ \'ਤੇ ਉਡਾਣ ਭਰਦੀ ਹੈ.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '速い茶色のキツネは、怠け者の犬を飛び越えた。豆の鳥は日没で飛ぶ。'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '那只敏捷的棕色狐狸跃过那只懒狗。豆鸟飞日落。'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '빠른 갈색 여우가 게으른 개를 뛰어 넘었다.콩 조류 일몰에 파리.'}
				]},
				{tag: 'br'},

				{kind: Divider, content: 'RTL Languages:'},
				{mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'שועל החום הזריז קפץ מעל הכלב העצלן.ציפור עפה השעועית עם שקיעה.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'قفز الثعلب البني السريع فوق الكلب الكسول. الطيور تطير في الفول عند غروب الشمس.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'فوری بھوری لومڑی سست کتے پر چھلانگ لگا. بین پرندوں سوریاست میں پرواز.'}
				]}
			]}
		]}
	],
	contentChange: function (sender, ev) {
		this.$.marqueeContent1.setContent(sender.getValue());
		this.$.marqueeContent2.setContent(sender.getValue());
		this.$.marqueeContent3.setContent(sender.getValue());
	},
	start: function (sender, ev) {
		this.$.marqueeContent1.startMarquee();
		this.$.marqueeContent2.startMarquee();
		this.$.marqueeContainer1.startMarquee();
	},
	stop: function (sender, ev) {
		this.$.marqueeContent1.stopMarquee();
		this.$.marqueeContent2.stopMarquee();
		this.$.marqueeContainer1.stopMarquee();
	}
});
<commit_msg>ENYO-3223: Spelling (allthethings)<commit_after>var
	kind = require('enyo/kind');

var
	FittableRows = require('layout/FittableRows'),
	Button = require('moonstone/Button'),
	Divider = require('moonstone/Divider'),
	Input = require('moonstone/Input'),
	InputDecorator = require('moonstone/InputDecorator'),
	Marquee = require('moonstone/Marquee'),
	MarqueeDecorator = Marquee.Decorator,
	MarqueeItem = Marquee.Item,
	MarqueeSupport = Marquee.Support,
	MarqueeText = Marquee.Text,
	Scroller = require('moonstone/Scroller');

module.exports = kind({
	name: 'moon.sample.MarqueeSample',
	kind: FittableRows,
	classes: 'moon enyo-unselectable enyo-fit moon-marquee-sample',
	components: [
		{kind: Scroller, fit: true, components: [
			{classes: 'moon-marquee-sample-wrapper', components: [

				{kind: Divider, content: 'Marquee on start:'},
				{kind: MarqueeDecorator, marqueeOnRender: true, components: [
					{name: 'marqueeStartOnRender1', kind: MarqueeText, classes: 'moon-marquee-start-on-render', content: 'This first long text for the marquee test starts the marquee on page render'},
					{name: 'marqueeStartOnRender2', kind: MarqueeText, classes: 'moon-marquee-start-on-render', content: 'This second long text for the marquee test is synchronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnRender3', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This third long text for the marquee test is not synchronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on focus:'},
				{kind: MarqueeDecorator, marqueeOnSpotlight: true, components: [
					{name: 'marqueeStartOnFocus1', kind: MarqueeText, spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This first long text for the marquee test starts the marquee on focus'},
					{name: 'marqueeStartOnFocus2', kind: MarqueeText, spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This second long text for the marquee test is synchronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnFocus3', marqueeOnSpotlight: true, mixins: [MarqueeSupport, MarqueeItem], spotlight: true, classes: 'moon-marquee-start-on-focus', content: 'This third long text for the marquee test is not synchronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on Hover:'},
				{kind: MarqueeDecorator, marqueeOnHover: true, marqueeOnSpotlight: false, components: [
					{name: 'marqueeStartOnHover1', kind: MarqueeText, classes: 'moon-marquee-start-on-hover', content: 'This first long text for the marquee test starts the marquee on mouse hover'},
					{name: 'marqueeStartOnHover2', kind: MarqueeText, classes: 'moon-marquee-start-on-hover', content: 'This second long text for the marquee test is synchronized with the first marquee text'}
				]},
				{name: 'marqueeStartOnHover3', marqueeOnHover: true, marqueeOnSpotlight: false, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-hover', content: 'This third long text for the marquee test is not synchronized with first and second marquee texts'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee on content changed:'},
				{kind: InputDecorator, components: [
					{kind: Input, placeholder: 'JUST TYPE', oninput: 'contentChange'}

				]},
				{kind: Button, content: 'Start marquee', ontap: 'start'},
				{kind: Button, content: 'Stop marquee', ontap: 'stop'},
				{name: 'marqueeContent1', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text is for marquee content change test for the separate marquee case'},
				{name: 'marqueeContent2', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', centered: true, content: 'Centered text for separate marquee case'},
				{name: 'marqueeContainer1', mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{name: 'marqueeContent3', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for marquee content change test for synchronized case'},
					{name: 'marqueeContent4', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is short text for marquee'},
					{name: 'marqueeContent5', mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', centered: true, content: 'This is centered text for marquee'}
				]},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee speed:'},
				{name: 'marqueeSpeed', marqueeOnRender: true, marqueeSpeed: 180, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for fast marquee speed test, which is twice as fast as normal marquee'},
				{tag: 'br'},

				{kind: Divider, content: 'Marquee pause:'},
				{name: 'marqueePause1', marqueeOnRender: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text for marquee has a 1000ms pause time'},
				{name: 'marqueePause2', marqueeOnRender: true, marqueePause: 2000, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This long text for marquee has a 2000ms pause time'},
				{tag: 'br'},

				{kind: Divider, content: 'Disabled Text marquee:'},
				{name: 'marqueeDisabled', marqueeOnRender: true, disabled: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for the marquee test with a disabled property'},
				{tag: 'br'},

				{kind: Divider, content: 'Disabled Wrap Instead Of Marquee:'},
				{name: 'marqueeDisabledWrap', wrapInsteadOfMarquee: true, disabled: true, mixins: [MarqueeSupport, MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'This is long text for disabled text which wraps because wrapInsteadOfMarquee is set to true'},
				{tag: 'br'},

				{kind: Divider, content: 'LTR Languages:'},
				{mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'The quick brown fox jumped over the lazy dog.  The bean bird flies at sundown.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'Η γρήγορη καφέ αλεπού πήδηξε πάνω από το μεσημέρι. Το πουλί πετά σε φασολιών δύση του ηλίου.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'ਤੁਰੰਤ ਭੂਰਾ Fox ਆਲਸੀ ਕੁੱਤੇ ਨੂੰ ਵੱਧ ਗਈ. ਬੀਨ ਪੰਛੀ ਸੂਰਜ ਡੁੱਬਣ \'ਤੇ ਉਡਾਣ ਭਰਦੀ ਹੈ.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '速い茶色のキツネは、怠け者の犬を飛び越えた。豆の鳥は日没で飛ぶ。'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '那只敏捷的棕色狐狸跃过那只懒狗。豆鸟飞日落。'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: '빠른 갈색 여우가 게으른 개를 뛰어 넘었다.콩 조류 일몰에 파리.'}
				]},
				{tag: 'br'},

				{kind: Divider, content: 'RTL Languages:'},
				{mixins: [MarqueeSupport], marqueeOnRender: true, components: [
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'שועל החום הזריז קפץ מעל הכלב העצלן.ציפור עפה השעועית עם שקיעה.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'قفز الثعلب البني السريع فوق الكلب الكسول. الطيور تطير في الفول عند غروب الشمس.'},
					{marqueeOnRender: true, mixins: [MarqueeItem], classes: 'moon-marquee-start-on-render', content: 'فوری بھوری لومڑی سست کتے پر چھلانگ لگا. بین پرندوں سوریاست میں پرواز.'}
				]}
			]}
		]}
	],
	contentChange: function (sender, ev) {
		this.$.marqueeContent1.setContent(sender.getValue());
		this.$.marqueeContent2.setContent(sender.getValue());
		this.$.marqueeContent3.setContent(sender.getValue());
	},
	start: function (sender, ev) {
		this.$.marqueeContent1.startMarquee();
		this.$.marqueeContent2.startMarquee();
		this.$.marqueeContainer1.startMarquee();
	},
	stop: function (sender, ev) {
		this.$.marqueeContent1.stopMarquee();
		this.$.marqueeContent2.stopMarquee();
		this.$.marqueeContainer1.stopMarquee();
	}
});
<|endoftext|>


<commit_before>// @flow

/**
 * Gets the data attribute. the name must be kebab-case.
 */
export const getDataAttribute = (el: HTMLElement, name: string) => el.getAttribute(`data-vv-${name}`);

/**
 * Checks if the value is either null or undefined.
 */
export const isNullOrUndefined = (value: mixed): boolean => {
  return value === null || value === undefined;
};

/**
 * Sets the data attribute.
 */
export const setDataAttribute = (el: HTMLElement, name: string, value: string): void => el.setAttribute(`data-vv-${name}`, value);

/**
 * Creates a proxy object if available in the environment.
 */
export const createProxy = (target: Object, handler: Object) => {
  if (typeof Proxy === 'undefined') {
    return target;
  }

  return new Proxy(target, handler);
};

/**
 * Creates the default flags object.
 */
export const createFlags = (): Object => ({
  untouched: true,
  touched: false,
  dirty: false,
  pristine: true,
  valid: null,
  invalid: null,
  validated: false,
  pending: false,
  required: false
});

/**
 * Shallow object comparison.
 */
export const isEqual = (lhs: any, rhs: any): boolean => {
  if (lhs instanceof RegExp && rhs instanceof RegExp) {
    return isEqual(lhs.source, rhs.source) && isEqual(lhs.flags, rhs.flags);
  }

  if (Array.isArray(lhs) && Array.isArray(rhs)) {
    if (lhs.length !== rhs.length) return false;

    for (let i = 0; i < lhs.length; i++) {
      if (!isEqual(lhs[i], rhs[i])) {
        return false;
      }
    }

    return true;
  }

  // if both are objects, compare each key recursively.
  if (isObject(lhs) && isObject(rhs)) {
    return Object.keys(lhs).every(key => {
      return isEqual(lhs[key], rhs[key]);
    }) && Object.keys(rhs).every(key => {
      return isEqual(lhs[key], rhs[key]);
    });
  }

  return lhs === rhs;
};

/**
 * Determines the input field scope.
 */
export const getScope = (el: HTMLInputElement) => {
  let scope = getDataAttribute(el, 'scope');
  if (isNullOrUndefined(scope) && el.form) {
    scope = getDataAttribute(el.form, 'scope');
  }

  return !isNullOrUndefined(scope) ? scope : null;
};

/**
 * Gets the value in an object safely.
 */
export const getPath = (path: string, target: ?Object, def: any = undefined) => {
  if (!path || !target) return def;

  let value = target;
  path.split('.').every(prop => {
    if (! Object.prototype.hasOwnProperty.call(value, prop) && value[prop] === undefined) {
      value = def;

      return false;
    }

    value = value[prop];

    return true;
  });

  return value;
};

/**
 * Checks if path exists within an object.
 */
export const hasPath = (path: string, target: Object) => {
  let obj = target;
  return path.split('.').every(prop => {
    if (! Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }

    obj = obj[prop];

    return true;
  });
};

/**
 * Parses a rule string expression.
 */
export const parseRule = (rule: string): Object => {
  let params = [];
  const name = rule.split(':')[0];

  if (~rule.indexOf(':')) {
    params = rule.split(':').slice(1).join(':').split(',');
  }

  return { name, params };
};

/**
 * Debounces a function.
 */
export const debounce = (fn: () => any, wait: number = 0, immediate: boolean = false) => {
  if (wait === 0) {
    return fn;
  }

  let timeout;

  return (...args: any[]) => {
    const later = () => {
      timeout = null;
      if (!immediate) fn(...args);
    };
    /* istanbul ignore next */
    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    /* istanbul ignore next */
    if (callNow) fn(...args);
  };
};

/**
 * Normalizes the given rules expression.
 */
export const normalizeRules = (rules: string | { [string]: boolean | any[] }) => {
  // if falsy value return an empty object.
  if (!rules) {
    return {};
  }

  if (isObject(rules)) {
    // $FlowFixMe
    return Object.keys(rules).reduce((prev, curr) => {
      let params = [];
      // $FlowFixMe
      if (rules[curr] === true) {
        params = [];
      } else if (Array.isArray(rules[curr])) {
        params = rules[curr];
      } else {
        params = [rules[curr]];
      }

      // $FlowFixMe
      if (rules[curr] !== false) {
        prev[curr] = params;
      }

      return prev;
    }, {});
  }

  if (typeof rules !== 'string') {
    warn('rules must be either a string or an object.');
    return {};
  }

  return rules.split('|').reduce((prev, rule) => {
    const parsedRule = parseRule(rule);
    if (!parsedRule.name) {
      return prev;
    }

    prev[parsedRule.name] = parsedRule.params;
    return prev;
  }, {});
};

/**
 * Emits a warning to the console.
 */
export const warn = (message: string) => {
  console.warn(`[vee-validate] ${message}`); // eslint-disable-line
};

/**
 * Creates a branded error object.
 */
export const createError = (message: string): Error => new Error(`[vee-validate] ${message}`);

/**
 * Checks if the value is an object.
 */
export const isObject = (obj: any): boolean => obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj);

/**
 * Checks if a function is callable.
 */
export const isCallable = (func: any): boolean => typeof func === 'function';

/**
 * Check if element has the css class on it.
 */
export const hasClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    return el.classList.contains(className);
  }

  return !!el.className.match(new RegExp(`(\\s|^)${className}(\\s|$)`));
};

/**
 * Adds the provided css className to the element.
 */
export const addClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    el.classList.add(className);
    return;
  }

  if (!hasClass(el, className)) {
    el.className += ` ${className}`;
  }
};

/**
 * Remove the provided css className from the element.
 */
export const removeClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    el.classList.remove(className);
    return;
  }

  if (hasClass(el, className)) {
    const reg = new RegExp(`(\\s|^)${className}(\\s|$)`);
    el.className = el.className.replace(reg, ' ');
  }
};

/**
 * Adds or removes a class name on the input depending on the status flag.
 */
export const toggleClass = (el: ?HTMLElement, className: ?string, status: boolean) => {
  if (!el || !className) return;

  if (status) {
    return addClass(el, className);
  }

  removeClass(el, className);
};

/**
 * Converts an array-like object to array, provides a simple polyfill for Array.from
 */
export const toArray = (arrayLike: { length: number }) => {
  if (isCallable(Array.from)) {
    return Array.from(arrayLike);
  }

  const array = [];
  const length = arrayLike.length;
  for (let i = 0; i < length; i++) {
    array.push(arrayLike[i]);
  }

  return array;
};

/**
 * Assign polyfill from the mdn.
 */
export const assign = (target: Object, ...others: any[]) => {
  /* istanbul ignore else */
  if (isCallable(Object.assign)) {
    return Object.assign(target, ...others);
  }

  /* istanbul ignore next */
  if (target == null) {
    throw new TypeError('Cannot convert undefined or null to object');
  }

  /* istanbul ignore next */
  const to = Object(target);
  /* istanbul ignore next */
  others.forEach(arg => {
    // Skip over if undefined or null
    if (arg != null) {
      Object.keys(arg).forEach(key => {
        to[key] = arg[key];
      });
    }
  });
  /* istanbul ignore next */
  return to;
};

/**
 * Generates a unique id.
 */
export const uniqId = (): string => `_${Math.random().toString(36).substr(2, 9)}`;

/**
 * finds the first element that satisfies the predicate callback, polyfills array.find
 */
export const find = (arrayLike: { length: number }, predicate: (any) => boolean) => {
  const array = toArray(arrayLike);

  if (isCallable(array.find)) {
    return array.find(predicate);
  }

  let result;
  array.some(item => {
    if (predicate(item)) {
      result = item;
      return true;
    }

    return false;
  });

  return result;
};

/**
 * Returns a suitable event name for the input element.
 */
export const getInputEventName = (el: HTMLInputElement) => {
  if (el && (el.tagName === 'SELECT' || ~['radio', 'checkbox', 'file'].indexOf(el.type))) {
    return 'change';
  }

  return 'input';
};

export const isBuiltInComponent = (vnode: Object): boolean => {
  if (!vnode) {
    return false;
  }

  const tag = vnode.componentOptions.tag;

  return /keep-alive|transition|transition-group/.test(tag);
};

export const makeEventsArray = (events: string) => {
  return (typeof events === 'string' && events.length) ? events.split('|') : [];
};

export const makeDelayObject = (events: string[], delay: Object | number) => {
  const delayObject = {};

  // We already have a valid delay object
  if (typeof delay === 'object' && !('global' in delay) && !('local' in delay) && Object.keys(delay).length) return delay;

  const globalDelay = (typeof delay === 'object' && 'global' in delay) ? delay.global : delay || 0;
  const localDelay = (typeof delay === 'object' && 'local' in delay) ? delay.local : {};

  events.forEach(e => {
    delayObject[e] = (typeof globalDelay === 'object') ? localDelay[e] || globalDelay[e] || 0 : localDelay[e] || globalDelay;
  });

  return delayObject;
};

export const deepParseInt = (input: Object | string | number) => {
  if (typeof input === 'number') return input;

  if (typeof input === 'string') return parseInt(input);

  const map = {};
  for (const element in input) {
    map[element] = parseInt(input[element]);
  }

  return map;
};
<commit_msg>make uniqId more deterministic closes #1000<commit_after>// @flow

/**
 * Gets the data attribute. the name must be kebab-case.
 */
export const getDataAttribute = (el: HTMLElement, name: string) => el.getAttribute(`data-vv-${name}`);

/**
 * Checks if the value is either null or undefined.
 */
export const isNullOrUndefined = (value: mixed): boolean => {
  return value === null || value === undefined;
};

/**
 * Sets the data attribute.
 */
export const setDataAttribute = (el: HTMLElement, name: string, value: string): void => el.setAttribute(`data-vv-${name}`, value);

/**
 * Creates a proxy object if available in the environment.
 */
export const createProxy = (target: Object, handler: Object) => {
  if (typeof Proxy === 'undefined') {
    return target;
  }

  return new Proxy(target, handler);
};

/**
 * Creates the default flags object.
 */
export const createFlags = (): Object => ({
  untouched: true,
  touched: false,
  dirty: false,
  pristine: true,
  valid: null,
  invalid: null,
  validated: false,
  pending: false,
  required: false
});

/**
 * Shallow object comparison.
 */
export const isEqual = (lhs: any, rhs: any): boolean => {
  if (lhs instanceof RegExp && rhs instanceof RegExp) {
    return isEqual(lhs.source, rhs.source) && isEqual(lhs.flags, rhs.flags);
  }

  if (Array.isArray(lhs) && Array.isArray(rhs)) {
    if (lhs.length !== rhs.length) return false;

    for (let i = 0; i < lhs.length; i++) {
      if (!isEqual(lhs[i], rhs[i])) {
        return false;
      }
    }

    return true;
  }

  // if both are objects, compare each key recursively.
  if (isObject(lhs) && isObject(rhs)) {
    return Object.keys(lhs).every(key => {
      return isEqual(lhs[key], rhs[key]);
    }) && Object.keys(rhs).every(key => {
      return isEqual(lhs[key], rhs[key]);
    });
  }

  return lhs === rhs;
};

/**
 * Determines the input field scope.
 */
export const getScope = (el: HTMLInputElement) => {
  let scope = getDataAttribute(el, 'scope');
  if (isNullOrUndefined(scope) && el.form) {
    scope = getDataAttribute(el.form, 'scope');
  }

  return !isNullOrUndefined(scope) ? scope : null;
};

/**
 * Gets the value in an object safely.
 */
export const getPath = (path: string, target: ?Object, def: any = undefined) => {
  if (!path || !target) return def;

  let value = target;
  path.split('.').every(prop => {
    if (! Object.prototype.hasOwnProperty.call(value, prop) && value[prop] === undefined) {
      value = def;

      return false;
    }

    value = value[prop];

    return true;
  });

  return value;
};

/**
 * Checks if path exists within an object.
 */
export const hasPath = (path: string, target: Object) => {
  let obj = target;
  return path.split('.').every(prop => {
    if (! Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }

    obj = obj[prop];

    return true;
  });
};

/**
 * Parses a rule string expression.
 */
export const parseRule = (rule: string): Object => {
  let params = [];
  const name = rule.split(':')[0];

  if (~rule.indexOf(':')) {
    params = rule.split(':').slice(1).join(':').split(',');
  }

  return { name, params };
};

/**
 * Debounces a function.
 */
export const debounce = (fn: () => any, wait: number = 0, immediate: boolean = false) => {
  if (wait === 0) {
    return fn;
  }

  let timeout;

  return (...args: any[]) => {
    const later = () => {
      timeout = null;
      if (!immediate) fn(...args);
    };
    /* istanbul ignore next */
    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    /* istanbul ignore next */
    if (callNow) fn(...args);
  };
};

/**
 * Normalizes the given rules expression.
 */
export const normalizeRules = (rules: string | { [string]: boolean | any[] }) => {
  // if falsy value return an empty object.
  if (!rules) {
    return {};
  }

  if (isObject(rules)) {
    // $FlowFixMe
    return Object.keys(rules).reduce((prev, curr) => {
      let params = [];
      // $FlowFixMe
      if (rules[curr] === true) {
        params = [];
      } else if (Array.isArray(rules[curr])) {
        params = rules[curr];
      } else {
        params = [rules[curr]];
      }

      // $FlowFixMe
      if (rules[curr] !== false) {
        prev[curr] = params;
      }

      return prev;
    }, {});
  }

  if (typeof rules !== 'string') {
    warn('rules must be either a string or an object.');
    return {};
  }

  return rules.split('|').reduce((prev, rule) => {
    const parsedRule = parseRule(rule);
    if (!parsedRule.name) {
      return prev;
    }

    prev[parsedRule.name] = parsedRule.params;
    return prev;
  }, {});
};

/**
 * Emits a warning to the console.
 */
export const warn = (message: string) => {
  console.warn(`[vee-validate] ${message}`); // eslint-disable-line
};

/**
 * Creates a branded error object.
 */
export const createError = (message: string): Error => new Error(`[vee-validate] ${message}`);

/**
 * Checks if the value is an object.
 */
export const isObject = (obj: any): boolean => obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj);

/**
 * Checks if a function is callable.
 */
export const isCallable = (func: any): boolean => typeof func === 'function';

/**
 * Check if element has the css class on it.
 */
export const hasClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    return el.classList.contains(className);
  }

  return !!el.className.match(new RegExp(`(\\s|^)${className}(\\s|$)`));
};

/**
 * Adds the provided css className to the element.
 */
export const addClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    el.classList.add(className);
    return;
  }

  if (!hasClass(el, className)) {
    el.className += ` ${className}`;
  }
};

/**
 * Remove the provided css className from the element.
 */
export const removeClass = (el: HTMLElement, className: string) => {
  if (el.classList) {
    el.classList.remove(className);
    return;
  }

  if (hasClass(el, className)) {
    const reg = new RegExp(`(\\s|^)${className}(\\s|$)`);
    el.className = el.className.replace(reg, ' ');
  }
};

/**
 * Adds or removes a class name on the input depending on the status flag.
 */
export const toggleClass = (el: ?HTMLElement, className: ?string, status: boolean) => {
  if (!el || !className) return;

  if (status) {
    return addClass(el, className);
  }

  removeClass(el, className);
};

/**
 * Converts an array-like object to array, provides a simple polyfill for Array.from
 */
export const toArray = (arrayLike: { length: number }) => {
  if (isCallable(Array.from)) {
    return Array.from(arrayLike);
  }

  const array = [];
  const length = arrayLike.length;
  for (let i = 0; i < length; i++) {
    array.push(arrayLike[i]);
  }

  return array;
};

/**
 * Assign polyfill from the mdn.
 */
export const assign = (target: Object, ...others: any[]) => {
  /* istanbul ignore else */
  if (isCallable(Object.assign)) {
    return Object.assign(target, ...others);
  }

  /* istanbul ignore next */
  if (target == null) {
    throw new TypeError('Cannot convert undefined or null to object');
  }

  /* istanbul ignore next */
  const to = Object(target);
  /* istanbul ignore next */
  others.forEach(arg => {
    // Skip over if undefined or null
    if (arg != null) {
      Object.keys(arg).forEach(key => {
        to[key] = arg[key];
      });
    }
  });
  /* istanbul ignore next */
  return to;
};

let id = 0;
let idTemplate = '{id}';

/**
 * Generates a unique id.
 */
export const uniqId = (): string => {
  // handle too many uses of uniqId, although unlikely.
  if (id >= 9999) {
    id = 0;
    // shift the template.
    idTemplate.replace('{id}', '_{id}');
  }

  id++;
  const newId = idTemplate.replace('{id}', String(id));

  return newId;
};

/**
 * finds the first element that satisfies the predicate callback, polyfills array.find
 */
export const find = (arrayLike: { length: number }, predicate: (any) => boolean) => {
  const array = toArray(arrayLike);

  if (isCallable(array.find)) {
    return array.find(predicate);
  }

  let result;
  array.some(item => {
    if (predicate(item)) {
      result = item;
      return true;
    }

    return false;
  });

  return result;
};

/**
 * Returns a suitable event name for the input element.
 */
export const getInputEventName = (el: HTMLInputElement) => {
  if (el && (el.tagName === 'SELECT' || ~['radio', 'checkbox', 'file'].indexOf(el.type))) {
    return 'change';
  }

  return 'input';
};

export const isBuiltInComponent = (vnode: Object): boolean => {
  if (!vnode) {
    return false;
  }

  const tag = vnode.componentOptions.tag;

  return /keep-alive|transition|transition-group/.test(tag);
};

export const makeEventsArray = (events: string) => {
  return (typeof events === 'string' && events.length) ? events.split('|') : [];
};

export const makeDelayObject = (events: string[], delay: Object | number) => {
  const delayObject = {};

  // We already have a valid delay object
  if (typeof delay === 'object' && !('global' in delay) && !('local' in delay) && Object.keys(delay).length) return delay;

  const globalDelay = (typeof delay === 'object' && 'global' in delay) ? delay.global : delay || 0;
  const localDelay = (typeof delay === 'object' && 'local' in delay) ? delay.local : {};

  events.forEach(e => {
    delayObject[e] = (typeof globalDelay === 'object') ? localDelay[e] || globalDelay[e] || 0 : localDelay[e] || globalDelay;
  });

  return delayObject;
};

export const deepParseInt = (input: Object | string | number) => {
  if (typeof input === 'number') return input;

  if (typeof input === 'string') return parseInt(input);

  const map = {};
  for (const element in input) {
    map[element] = parseInt(input[element]);
  }

  return map;
};
<|endoftext|>


<commit_before>"use strict";

var rateLimiter = exports,
    _ = require("lodash"),
    LimitsEvaluator = require("./limits-evaluator"),
    httpProxy = require('http-proxy'),
    http = require("http"),
    log4js = require('log4js'),
    EventEmitter = require('events').EventEmitter;

rateLimiter.RateLimiter = RateLimiter;
var logger = log4js.getLogger();

// http://nodejs.org/docs/v0.10.35/api/http.html#http_agent_maxsockets
// in v0.12 maxSockets default was changed to Infinity
http.globalAgent.maxSockets = Infinity;

function RateLimiter(settings) {
    this.settings = settings;
    log4js.configure(settings.log4js);

    this.evaluator = new LimitsEvaluator(settings);
    this.proxyEvent = new EventEmitter();

    this.initProxy();
}

RateLimiter.prototype = {

    initProxy: function () {
        logger.info("New worker is being spawned.");
        var _this = this;
        this.proxy = httpProxy.createProxyServer({});

        this.proxy.on('proxyReq', function (proxyReq, req, res, options) {
            _this.requestForwarded(proxyReq, req, res, options);
        });
        this.proxy.on('proxyRes', function (proxyRes, req, res) {
            _this.requestServed(proxyRes, req, res);
        });
        this.proxy.on('error', function (err, req, res, options) {
            _this.requestFailed(err, req, res, options);
        });

        var server = http.createServer(function (req, res) {
            var resultMethod = _this.evaluator.evaluate(req);
            resultMethod(_this, req, res);
        });
        server.listen(_this.settings.listenPort, function () {
            logger.info("New worker successfully spawned.");
            if (process.send) {
                logger.info("New worker sends 'online' message.");
                process.send('online');
            }
        });
        this.server = server;

        this.processEventListeners = {};

        this.processEventListeners['SIGTERM'] = function () {
            _this.terminate(0);
        };

        this.processEventListeners['message'] = function (message) {
            if (message === 'shutdown') {
                _this.terminate(0);
            }
        };

        this.processEventListeners['uncaughtException'] = function(err) {
            logger.error('uncaughtException handler received: ' + err);
            _this.proxyEvent.emit('uncaughtException', err);
            if (err !== 'TestError') {
                _this.terminate(1);
            }
        };

        for (var listener in this.processEventListeners) {
            if (this.processEventListeners.hasOwnProperty(listener)) {
                process.on(listener, this.processEventListeners[listener]);
            }
        }
    },

    forward: function (req, res) {
        logger.debug(req.headers['x-forwarded-for'] + " " + req.method + " " + req.url + " " + this.evaluator.counter.getGlobalRequestCount());
        this.proxy.web(req, res, {
            target: this.settings.forwardUrl
        });
    },

    reject: function (req, res, errorCode) {
        errorCode = errorCode || 429;
        res.writeHead(errorCode, "Rejected by the rate limiter");
        res.write("Request has been rejected by the rate limiter");
        res.end();
    },

    respondWithHealthcheck: function (req, res) {
        res.writeHead(200, "Rate-Limiter is running");
        res.write("OK");
        res.end();
    },

    terminate: function (value) {
        this.close(function () {
            logger.info("Old worker proxy process is terminated.");
            process.exit(value);
        });
    },

    close: function (done) {
        logger.info("Old worker proxy is being closed, will serve active requests but no new request will be accepted.");
        if (process.send) {
            logger.info("Old worker proxy sends 'offline' message.");
            process.send('offline');
        }

        var _this = this;
        this.server.close(function () {
            logger.info("Old worker proxy is closed.");

            for (var listener in _this.processEventListeners) {
                if (_this.processEventListeners.hasOwnProperty(listener)) {
                    process.removeListener(listener, _this.processEventListeners[listener]);
                }
            }
            done();
        });
    },

    requestForwarded: function (proxyReq, req) {
        if ("bucket" in req) {
            proxyReq.setHeader(this.settings.bucketHeaderName, req.bucket.name);
        }
    },

    requestServed: function (proxyRes, req, res) {
        this.evaluator.counter.decrement(req.bucket, req.ip);
        this.proxyEvent.emit('served', req.bucket);
    },

    requestFailed: function (err, req, res, options) {
        logger.error('proxy error', err);

        this.evaluator.counter.decrement(req.bucket, req.ip);
        this.proxyEvent.emit('failed', err);

        if (res.headersSent) {
            logger.error('Headers are sent already, cannot change HTTP response by now');
        } else {
            res.writeHead(500, {
                'Content-Type': 'text/plain'
            });
        }
        res.end('An internal error has occurred.');
    }
};
<commit_msg>Properly export Ratelimiter<commit_after>"use strict";

var _ = require("lodash"),
    LimitsEvaluator = require("./limits-evaluator"),
    httpProxy = require('http-proxy'),
    http = require("http"),
    log4js = require('log4js'),
    EventEmitter = require('events').EventEmitter;

module.exports.RateLimiter = RateLimiter;
var logger = log4js.getLogger();

// http://nodejs.org/docs/v0.10.35/api/http.html#http_agent_maxsockets
// in v0.12 maxSockets default was changed to Infinity
http.globalAgent.maxSockets = Infinity;

function RateLimiter(settings) {
    this.settings = settings;
    log4js.configure(settings.log4js);

    this.evaluator = new LimitsEvaluator(settings);
    this.proxyEvent = new EventEmitter();

    this.initProxy();
}

RateLimiter.prototype = {

    initProxy: function () {
        logger.info("New worker is being spawned.");
        var _this = this;
        this.proxy = httpProxy.createProxyServer({});

        this.proxy.on('proxyReq', function (proxyReq, req, res, options) {
            _this.requestForwarded(proxyReq, req, res, options);
        });
        this.proxy.on('proxyRes', function (proxyRes, req, res) {
            _this.requestServed(proxyRes, req, res);
        });
        this.proxy.on('error', function (err, req, res, options) {
            _this.requestFailed(err, req, res, options);
        });

        var server = http.createServer(function (req, res) {
            var resultMethod = _this.evaluator.evaluate(req);
            resultMethod(_this, req, res);
        });
        server.listen(_this.settings.listenPort, function () {
            logger.info("New worker successfully spawned.");
            if (process.send) {
                logger.info("New worker sends 'online' message.");
                process.send('online');
            }
        });
        this.server = server;

        this.processEventListeners = {};

        this.processEventListeners['SIGTERM'] = function () {
            _this.terminate(0);
        };

        this.processEventListeners['message'] = function (message) {
            if (message === 'shutdown') {
                _this.terminate(0);
            }
        };

        this.processEventListeners['uncaughtException'] = function(err) {
            logger.error('uncaughtException handler received: ' + err);
            _this.proxyEvent.emit('uncaughtException', err);
            if (err !== 'TestError') {
                _this.terminate(1);
            }
        };

        for (var listener in this.processEventListeners) {
            if (this.processEventListeners.hasOwnProperty(listener)) {
                process.on(listener, this.processEventListeners[listener]);
            }
        }
    },

    forward: function (req, res) {
        logger.debug(req.headers['x-forwarded-for'] + " " + req.method + " " + req.url + " " + this.evaluator.counter.getGlobalRequestCount());
        this.proxy.web(req, res, {
            target: this.settings.forwardUrl
        });
    },

    reject: function (req, res, errorCode) {
        errorCode = errorCode || 429;
        res.writeHead(errorCode, "Rejected by the rate limiter");
        res.write("Request has been rejected by the rate limiter");
        res.end();
    },

    respondWithHealthcheck: function (req, res) {
        res.writeHead(200, "Rate-Limiter is running");
        res.write("OK");
        res.end();
    },

    terminate: function (value) {
        this.close(function () {
            logger.info("Old worker proxy process is terminated.");
            process.exit(value);
        });
    },

    close: function (done) {
        logger.info("Old worker proxy is being closed, will serve active requests but no new request will be accepted.");
        if (process.send) {
            logger.info("Old worker proxy sends 'offline' message.");
            process.send('offline');
        }

        var _this = this;
        this.server.close(function () {
            logger.info("Old worker proxy is closed.");

            for (var listener in _this.processEventListeners) {
                if (_this.processEventListeners.hasOwnProperty(listener)) {
                    process.removeListener(listener, _this.processEventListeners[listener]);
                }
            }
            done();
        });
    },

    requestForwarded: function (proxyReq, req) {
        if ("bucket" in req) {
            proxyReq.setHeader(this.settings.bucketHeaderName, req.bucket.name);
        }
    },

    requestServed: function (proxyRes, req, res) {
        this.evaluator.counter.decrement(req.bucket, req.ip);
        this.proxyEvent.emit('served', req.bucket);
    },

    requestFailed: function (err, req, res, options) {
        logger.error('proxy error', err);

        this.evaluator.counter.decrement(req.bucket, req.ip);
        this.proxyEvent.emit('failed', err);

        if (res.headersSent) {
            logger.error('Headers are sent already, cannot change HTTP response by now');
        } else {
            res.writeHead(500, {
                'Content-Type': 'text/plain'
            });
        }
        res.end('An internal error has occurred.');
    }
};
<|endoftext|>


<commit_before><commit_msg>8.3 argumentos e parametros de funcao<commit_after><|endoftext|>


<commit_before>/* HTML5 Uploader */

/* Taken from http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding */
function htmlEscape(str) {
    return String(str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}

function onComplete(dat, f, d, uid)
{
    console.log(dat);
    var dsp = dat.split("|");
    if(Number(dsp[0]) === Number(uid) && dsp.length === 3)
    {
        var data = dsp[2];
        if(data == "error") {
            d.innerHTML = "
Error uploading file! ( "+htmlEscape(f.name)+" )
";
        } else if (data == "size") {
            d.innerHTML = "
File is too big! ( "+htmlEscape(f.name)+" )
";
        } else if (data == "rate") {
            d.innerHTML = "
Only 6 files per minute! ( "+htmlEscape(f.name)+" )
";
        } else {
            var ext = htmlEscape(f.name.split('.').pop().toLowerCase());
            d.innerHTML = "http://s.watfile.com/"+data+'.'+ext+" ( "+htmlEscape(f.name)+" )";
        }
        d.innerHTML = "
"+d.innerHTML+"
";
        document.getElementsByTagName("ul")[0].appendChild(d);
    } else {
        d.innerHTML = "

Error uploading file! ( "+htmlEscape(f.name)+" )

";
        document.getElementsByTagName("ul")[0].appendChild(d);
    }
}

function upload(file, xhr) {

    var dOutput = document.createElement("ul");
    document.getElementsByTagName("ul")[0].appendChild(dOutput);
    if(file.size > 10485761)
    {
        dOutput.innerHTML = "

File is too big! ( "+htmlEscape(file.name)+" )

";
        return;
    }

    // Firefox 3.6, Chrome 6, WebKit
    if(window.FileReader) {

        dOutput.innerHTML = "
Uploading... ( "+htmlEscape(file.name)+" )
";

        // Once the process of reading file
        this.loadEnd = function() {
            var upid = String(Math.floor(Math.random()*1000000000));

            // Firefox 3.6 provides a feature sendAsBinary ()
            if(xhr.sendAsBinary != null) {
                var boundary = 'xxxxxxxxx';
                var body = '--' + boundary + "\r\n";
                body += "Content-Disposition: form-data; name='upload'; filename='" + file.name + "'\r\n";
                body += "Content-Type: application/octet-stream\r\n\r\n";
                body += reader.result + "\r\n";
                body += '--' + boundary + '--';
                xhr.open('POST', 'upload?up=true', true);
                xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                xhr.setRequestHeader('UP-FILENAME', file.name);
                xhr.setRequestHeader('UP-SIZE', file.size);
                xhr.setRequestHeader('UP-TYPE', file.type);
                xhr.setRequestHeader('UP-ID', upid);
                xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
                xhr.sendAsBinary(body);
            // Chrome 7 sends data but you must use the base64_decode on the PHP side
            } else {
                xhr.open('POST', 'upload?up=true&base64=true', true);
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                xhr.setRequestHeader('UP-FILENAME', file.name);
                xhr.setRequestHeader('UP-SIZE', file.size);
                xhr.setRequestHeader('UP-TYPE', file.type);
                xhr.setRequestHeader('UP-ID', upid);
                xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
                xhr.send(window.btoa(reader.result));
            }
        }

        // Loading errors
        this.loadError = function(event) {
            switch(event.target.error.code) {
                case event.target.error.NOT_FOUND_ERR:
                    dOutput.innerHTML = '
File not found! ( '+htmlEscape(file.name)+' )
';
                    break;
                case event.target.error.NOT_READABLE_ERR:
                    dOutput.innerHTML = '
File not readable! ( '+htmlEscape(file.name)+' )
';
                    break;
                case event.target.error.ABORT_ERR:
                    break;
                default:
                    dOutput.innerHTML = '
Read error! ( '+htmlEscape(file.name)+' )
';
            }
        }

        // Reading Progress
        this.loadProgress = function(event) {
        if (event.lengthComputable) {
                var percentage = Math.round((event.loaded * 100) / event.total);
                if (percentage === 100)
                    dOutput.innerHTML = '
Processing... ( '+htmlEscape(file.name)+' )
';
                else
                    dOutput.innerHTML = '
Uploading : '+percentage+'% ( '+htmlEscape(file.name)+' )
';
            }
        }

    var reader = new FileReader();
    // Firefox 3.6, WebKit
    if(reader.addEventListener) {
        reader.addEventListener('loadend', this.loadEnd, false);
        reader.addEventListener('error', this.loadError, false);
        reader.addEventListener('progress', this.loadProgress, false);
    } else {
        reader.onloadend = this.loadEnd;
        reader.onerror = this.loadError;
        reader.onprogress = this.loadProgress;
    }
    // The function that starts reading the file as a binary string
    reader.readAsBinaryString(file);

    // Safari 5 does not support FileReader
    } else {
        var upid = Math.floor(Math.random()*1000000000);
        dOutput.innerHTML = "
Uploading... ( "+htmlEscape(file.name)+" )
";
        xhr = new XMLHttpRequest();
        xhr.open('POST', 'upload?up=true', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.setRequestHeader('UP-FILENAME', file.name);
        xhr.setRequestHeader('UP-SIZE', file.size);
        xhr.setRequestHeader('UP-TYPE', file.type);
        xhr.setRequestHeader('UP-ID', upid);
        xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
        xhr.send(file);
    }
}

var tid;
function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files;
    var xhrs = new Array();
    for (var i = 0; i<files.length; i++) {
        var file = files[i];
        xhrs[i] = new XMLHttpRequest();
        console.log(file);
        upload(file, xhrs[i]);
    }
    document.getElementById('dropzone').style.display='none';
}
function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    clearTimeout(tid);
    document.getElementById('dropzone').style.display='block';
}
function handleDragOff(evt) {
    tid=setTimeout(function() {
        evt.stopPropagation();
        document.getElementById('dropzone').style.display='none';
    }, 0);
}

window.addEventListener('dragover', handleDragOver, false);
window.addEventListener('drop', handleFileSelect, false);
window.addEventListener('dragleave', handleDragOff, false);
document.getElementById("elem").onchange = function() { var xhrs = new Array(); for(var i = 0; i<this.files.length; i++) { xhrs[i] = new XMLHttpRequest(); upload(this.files[i], xhrs[i]); } };
document.getElementById("select").addEventListener("click", function (e) { document.getElementById("elem").click(); e.preventDefault(); }, false);
<commit_msg>Fixed javascript progress bar<commit_after>/* HTML5 Uploader */

/* Taken from http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding */
function htmlEscape(str) {
    return String(str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}

function onComplete(dat, f, d, uid)
{
    console.log(dat);
    var dsp = dat.split("|");
    if(Number(dsp[0]) === Number(uid) && dsp.length === 3)
    {
        var data = dsp[2];
        if(data == "error") {
            d.innerHTML = "
Error uploading file! ( "+htmlEscape(f.name)+" )
";
        } else if (data == "size") {
            d.innerHTML = "
File is too big! ( "+htmlEscape(f.name)+" )
";
        } else if (data == "rate") {
            d.innerHTML = "
Only 6 files per minute! ( "+htmlEscape(f.name)+" )
";
        } else {
            var ext = htmlEscape(f.name.split('.').pop().toLowerCase());
            d.innerHTML = "http://s.watfile.com/"+data+'.'+ext+" ( "+htmlEscape(f.name)+" )";
        }
        d.innerHTML = "
"+d.innerHTML+"
";
        document.getElementsByTagName("ul")[0].appendChild(d);
    } else {
        d.innerHTML = "

Error uploading file! ( "+htmlEscape(f.name)+" )

";
        document.getElementsByTagName("ul")[0].appendChild(d);
    }
}

function upload(file, xhr) {

    var dOutput = document.createElement("ul");
    document.getElementsByTagName("ul")[0].appendChild(dOutput);
    if(file.size > 10485761)
    {
        dOutput.innerHTML = "

File is too big! ( "+htmlEscape(file.name)+" )

";
        return;
    }

    // Firefox 3.6, Chrome 6, WebKit
    if(window.FileReader) {

        dOutput.innerHTML = "
Uploading... ( "+htmlEscape(file.name)+" )
";

        // Once the process of reading file
        this.loadEnd = function() {
            var upid = String(Math.floor(Math.random()*1000000000));

            // Firefox 3.6 provides a feature sendAsBinary ()
            if(xhr.sendAsBinary != null) {
                var boundary = 'xxxxxxxxx';
                var body = '--' + boundary + "\r\n";
                body += "Content-Disposition: form-data; name='upload'; filename='" + file.name + "'\r\n";
                body += "Content-Type: application/octet-stream\r\n\r\n";
                body += reader.result + "\r\n";
                body += '--' + boundary + '--';
                xhr.open('POST', 'upload?up=true', true);
                xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                xhr.setRequestHeader('UP-FILENAME', file.name);
                xhr.setRequestHeader('UP-SIZE', file.size);
                xhr.setRequestHeader('UP-TYPE', file.type);
                xhr.setRequestHeader('UP-ID', upid);
                xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
                xhr.upload.addEventListener('progress', loadProgress, false);
                xhr.sendAsBinary(body);
            // Chrome 7 sends data but you must use the base64_decode on the PHP side
            } else {
                xhr.open('POST', 'upload?up=true&base64=true', true);
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                xhr.setRequestHeader('UP-FILENAME', file.name);
                xhr.setRequestHeader('UP-SIZE', file.size);
                xhr.setRequestHeader('UP-TYPE', file.type);
                xhr.setRequestHeader('UP-ID', upid);
                xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
                xhr.upload.addEventListener('progress', loadProgress, false);
                xhr.send(window.btoa(reader.result));
            }
        }

        // Loading errors
        this.loadError = function(event) {
            switch(event.target.error.code) {
                case event.target.error.NOT_FOUND_ERR:
                    dOutput.innerHTML = '
File not found! ( '+htmlEscape(file.name)+' )
';
                    break;
                case event.target.error.NOT_READABLE_ERR:
                    dOutput.innerHTML = '
File not readable! ( '+htmlEscape(file.name)+' )
';
                    break;
                case event.target.error.ABORT_ERR:
                    break;
                default:
                    dOutput.innerHTML = '
Read error! ( '+htmlEscape(file.name)+' )
';
            }
        }

        // Reading Progress
        this.loadProgress = function(event) {
        if (event.lengthComputable) {
                var percentage = Math.round((event.loaded * 100) / event.total);
                if (percentage === 100)
                    dOutput.innerHTML = '
Processing... ( '+htmlEscape(file.name)+' )
';
                else
                    dOutput.innerHTML = '
Uploading : '+percentage+'% ( '+htmlEscape(file.name)+' )
';
            }
        }

    var reader = new FileReader();
    // Firefox 3.6, WebKit
    if(reader.addEventListener) {
        reader.addEventListener('loadend', this.loadEnd, false);
        reader.addEventListener('error', this.loadError, false);
    } else {
        reader.onloadend = this.loadEnd;
        reader.onerror = this.loadError;
    }

    // The function that starts reading the file as a binary string
    reader.readAsBinaryString(file);

    // Safari 5 does not support FileReader
    } else {
        var upid = Math.floor(Math.random()*1000000000);
        dOutput.innerHTML = "
Uploading... ( "+htmlEscape(file.name)+" )
";
        xhr = new XMLHttpRequest();
        xhr.open('POST', 'upload?up=true', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.setRequestHeader('UP-FILENAME', file.name);
        xhr.setRequestHeader('UP-SIZE', file.size);
        xhr.setRequestHeader('UP-TYPE', file.type);
        xhr.setRequestHeader('UP-ID', upid);
        xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { onComplete(xhr.responseText, file, dOutput, upid); }; };
        xhr.send(file);
    }
}

var tid;
function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files;
    var xhrs = new Array();
    for (var i = 0; i<files.length; i++) {
        var file = files[i];
        xhrs[i] = new XMLHttpRequest();
        console.log(file);
        upload(file, xhrs[i]);
    }
    document.getElementById('dropzone').style.display='none';
}
function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    clearTimeout(tid);
    document.getElementById('dropzone').style.display='block';
}
function handleDragOff(evt) {
    tid=setTimeout(function() {
        evt.stopPropagation();
        document.getElementById('dropzone').style.display='none';
    }, 0);
}

window.addEventListener('dragover', handleDragOver, false);
window.addEventListener('drop', handleFileSelect, false);
window.addEventListener('dragleave', handleDragOff, false);
document.getElementById("elem").onchange = function() { var xhrs = new Array(); for(var i = 0; i<this.files.length; i++) { xhrs[i] = new XMLHttpRequest(); upload(this.files[i], xhrs[i]); } };
document.getElementById("select").addEventListener("click", function (e) { document.getElementById("elem").click(); e.preventDefault(); }, false);
<|endoftext|>


<commit_before>'use strict';

var path = require('path')
var url = require('url')
var _ = require('lodash')

var domainParser = require('domain-parser')
var Promise = require("bluebird")
var debug = require('debug')('MarkSearch:addPage')
var save2db = require(path.join('..', '..', 'db', 'save2db'))
var archiveUrl = require(path.join('..', 'archive.is'))
var safeBrowsingCheck = require(path.join('..', 'safeBrowsing'))
var collapseWhiteSpace = require(path.join('..', '..', 'utils', 'collapseWhiteSpace'))

function addPage(req, res, next) {
  /****
   * Parsing the url to get the href from url.parse as that will
   * add a trailing slash to the end of the href if it's just a url
   * without a path. Doing this so that we dont save the same url
   * twice - e.g. if they saved http://foo.com, and then later
   * saved http://foo.com/, that would be a seperate site, which
   * is not what we want, so use url.parse to automatically add
   * the trailing slash.
   */
  var parsedUrl = url.parse(req.params.pageUrl)
  var pageUrl = parsedUrl.href
  var pageTitle = collapseWhiteSpace(req.body.pageTitle)
  var pageText = collapseWhiteSpace(req.body.pageText)
  var pageDescription = collapseWhiteSpace(req.body.pageDescription)
  debug('addPage running')
  /******
   *  When saving a page, we’re saving:
   *  URL (as _id) - String - e.g. 'http://popurls.com/'
   *  pageTitle - String
   *  pageText - String
   *  pageDescription - String
   *  dateCreated - Number - e.g. Date.now()
   *  Archive.is link (as archiveLink) - String - e.g. 'https://archive.is/pFvwT'
   *  SafeBrowsing details (as safeBrowsing) - Object - e.g. {safeBrowsing: {possiblyUnsafe: true, details: ‘malware'}}
   ******/
    //do some validation on this
    //console.log('hello colors test'.red);
  debug(pageUrl)
  //debug(req.body)
  debug('url domain')
  /****
   * Get the domain from the parsedUrl.hostname and remove any subdomains
   */
  var domain = domainParser(parsedUrl.hostname).domainName
  debug('tld.getDomain')
  debug(domain)
  var pageDoc = {
    _id: pageUrl,
    pageTitle: pageTitle,
    pageText: pageText,
    pageDescription: pageDescription,
    pageDomain: domain,
    dateCreated: Date.now(),
    archiveLink: null,
    safeBrowsing: {
      possiblyUnsafe: false,
      details: null
    }
  }
  //debug('pageDoc')
  //debug(pageDoc)
  var db = req.app.get('pagesDB')
  var appName = req.app.get('marksearchAppName')
  var appVersion = req.app.get('marksearchVersion')
  /****
   * We're doing two save's rather than one so that the basic page details are
   * available to search straight away, as the archiveURL and the safeBrowsing
   * details rely on a request to a third party server and could end up taking a
   * while (e.g. could take up to 10 seconds for a server to respond), the extra
   * stuff of the archive url and the safe browsing details are not as important
   * and can be added to the page details and resaved later in the second save to db
   */
  save2db(db, pageDoc)
      .then(pageDocAndHttpStatus =>{
        /*****
         * if it wasn't already there, we added it, if it was already there, we updated it.
         * Send appropriate status code for either
         * http://httpstatus.es/201
         * http://httpstatus.es/204
         * http://stackoverflow.com/questions/2342579/
         *****/
        res.status(pageDocAndHttpStatus.httpStatusCode).end()
        /****
         * update the quick-search index
         * We dont wait for the index to update as they are unlikely to search for text
         * straight away from the page they just saved.
         * Note: there will likely only ever be one user connecting, so there shouldn't be any
         * performance issues with re-building index straight away after each save
         */
        return [
          pageDocAndHttpStatus.returnedDoc,
          db.search({fields: ['pageTitle', 'pageDescription', 'pageText'], build: true})
        ]
      })
      /****
       * Get archiveUrl & safeBrowsingCheck running in parallel, rather than in sequence,
       * so dont have to wait for archiveUrl to finish before starting safeBrowsingCheck
       */
      .spread( (returnedDoc, searchBuild) => {
        return [archiveUrl(returnedDoc), safeBrowsingCheck(appName, appVersion, returnedDoc)]
      })
      .spread( (archiveReturnedDoc, safeBrowsingReturnedDoc) => {
        archiveReturnedDoc.safeBrowsing = safeBrowsingReturnedDoc.safeBrowsing
        return save2db(db, archiveReturnedDoc)
      })
      .catch(err => {
        /****
         * There was an error with the database, send back an appropriate
         * http error code
         */
        console.log(`There was an error with the database`)
        console.error(err)
        res.status(503).end()
      })
}

module.exports = addPage<commit_msg>Monday, 1 February 2016 at 6:52:58 PM<commit_after>'use strict';

var path = require('path')
var url = require('url')
var _ = require('lodash')

var domainParser = require('domain-parser')
var Promise = require("bluebird")
var debug = require('debug')('MarkSearch:addPage')
var save2db = require(path.join('..', '..', 'db', 'save2db'))
var archiveUrl = require(path.join('..', 'archive.is'))
var safeBrowsingCheck = require(path.join('..', 'safeBrowsing'))
var collapseWhiteSpace = require(path.join('..', '..', 'utils', 'collapseWhiteSpace'))

function addPage(req, res, next) {
  /****
   * Parsing the url to get the href from url.parse as that will
   * add a trailing slash to the end of the href if it's just a url
   * without a path. Doing this so that we dont save the same url
   * twice - e.g. if they saved http://foo.com, and then later
   * saved http://foo.com/, that would be intepreted as a seperate
   * site, which is not what we want, so use url.parse to
   * automatically add the trailing slash.
   */
  var parsedUrl = url.parse(req.params.pageUrl)
  var pageUrl = parsedUrl.href
  var pageTitle = collapseWhiteSpace(req.body.pageTitle)
  var pageText = collapseWhiteSpace(req.body.pageText)
  var pageDescription = collapseWhiteSpace(req.body.pageDescription)
  debug('addPage running')
  /******
   *  When saving a page, we’re saving:
   *  URL (as _id) - String - e.g. 'http://popurls.com/'
   *  pageTitle - String
   *  pageText - String
   *  pageDescription - String
   *  dateCreated - Number - e.g. Date.now()
   *  Archive.is link (as archiveLink) - String - e.g. 'https://archive.is/pFvwT'
   *  SafeBrowsing details (as safeBrowsing) - Object - e.g. {safeBrowsing: {possiblyUnsafe: true, details: ‘malware'}}
   ******/
    //do some validation on this
    //console.log('hello colors test'.red);
  debug(pageUrl)
  //debug(req.body)
  debug('url domain')
  /****
   * Get the domain from the parsedUrl.hostname and remove any subdomains
   */
  var domain = domainParser(parsedUrl.hostname).domainName
  debug('tld.getDomain')
  debug(domain)
  var pageDoc = {
    _id: pageUrl,
    pageTitle: pageTitle,
    pageText: pageText,
    pageDescription: pageDescription,
    pageDomain: domain,
    dateCreated: Date.now(),
    archiveLink: null,
    safeBrowsing: {
      possiblyUnsafe: false,
      details: null
    }
  }
  //debug('pageDoc')
  //debug(pageDoc)
  var db = req.app.get('pagesDB')
  var appName = req.app.get('marksearchAppName')
  var appVersion = req.app.get('marksearchVersion')
  /****
   * We're doing two save's rather than one so that the basic page details are
   * available to search straight away, as the archiveURL and the safeBrowsing
   * details rely on a request to a third party server and could end up taking a
   * while (e.g. could take up to 10 seconds for a server to respond), the extra
   * stuff of the archive url and the safe browsing details are not as important
   * and can be added to the page details and resaved later in the second save to db
   */
  save2db(db, pageDoc)
      .then(pageDocAndHttpStatus =>{
        /*****
         * if it wasn't already there, we added it, if it was already there, we updated it.
         * Send appropriate status code for either
         * http://httpstatus.es/201
         * http://httpstatus.es/204
         * http://stackoverflow.com/questions/2342579/
         *****/
        res.status(pageDocAndHttpStatus.httpStatusCode).end()
        /****
         * update the quick-search index
         * We dont wait for the index to update as they are unlikely to search for text
         * straight away from the page they just saved.
         * Note: there will likely only ever be one user connecting, so there shouldn't be any
         * performance issues with re-building index straight away after each save
         */
        return [
          pageDocAndHttpStatus.returnedDoc,
          db.search({fields: ['pageTitle', 'pageDescription', 'pageText'], build: true})
        ]
      })
      /****
       * Get archiveUrl & safeBrowsingCheck running in parallel, rather than in sequence,
       * so dont have to wait for archiveUrl to finish before starting safeBrowsingCheck
       */
      .spread( (returnedDoc, searchBuild) => {
        return [archiveUrl(returnedDoc), safeBrowsingCheck(appName, appVersion, returnedDoc)]
      })
      .spread( (archiveReturnedDoc, safeBrowsingReturnedDoc) => {
        archiveReturnedDoc.safeBrowsing = safeBrowsingReturnedDoc.safeBrowsing
        return save2db(db, archiveReturnedDoc)
      })
      .catch(err => {
        /****
         * There was an error with the database, send back an appropriate
         * http error code
         */
        console.log(`There was an error with the database`)
        console.error(err)
        res.status(503).end()
      })
}

module.exports = addPage<|endoftext|>


<commit_before>import './index.scss';
// import {library, dom, config} from '@fortawesome/fontawesome-svg-core'
// import {
//   faTachometerAlt,
//   faFolder,
//   faCopyright,
//   faEdit,
//   faList,
//   faPlus,
//   faTh,
//   faUsers, faGamepad, faComments, faFile, faGlobe, faTags, faDatabase, faTrash, faCopy, faUpload, faFolderPlus, faSync
// } from '@fortawesome/free-solid-svg-icons'
//
// library.add(faTachometerAlt, faFolder, faCopyright, faEdit, faList, faPlus, faTh, faUsers, faGamepad, faComments, faFile, faGlobe, faTags, faDatabase, faTrash, faCopy, faUpload, faFolderPlus, faSync)
// config.keepOriginalSource = false;
// console.log(dom);
//dom.watch()
<commit_msg>refactor(js): delete dead code<commit_after>import './index.scss';
<|endoftext|>