<commit_before>import Vue from 'vue'

import Positionable from './positionable'

import Stackable from './stackable'
import { consoleError } from '../util/console'

/* eslint-disable object-property-newline */
const dimensions = {
  activator: {
    top: 0, left: 0,
    bottom: 0, right: 0,
    width: 0, height: 0,
    offsetTop: 0, scrollHeight: 0
  },
  content: {
    top: 0, left: 0,
    bottom: 0, right: 0,
    width: 0, height: 0,
    offsetTop: 0, scrollHeight: 0
  },
  hasWindow: false
}
/* eslint-enable object-property-newline */

/**
 * Menuable
 *
 * @mixin
 *
 * Used for fixed or absolutely positioning
 * elements within the DOM
 * Can calculate X and Y axis overflows
 * As well as be manually positioned
 */
/* @vue/component */
export default Vue.extend({
  name: 'menuable',

  mixins: [
    Positionable,
    Stackable
  ],

  props: {
    activator: {
      default: null,
      validator: val => {
        return ['string', 'object'].includes(typeof val)
      }
    },
    allowOverflow: Boolean,
    inputActivator: Boolean,
    light: Boolean,
    dark: Boolean,
    maxWidth: {
      type: [Number, String],
      default: 'auto'
    },
    minWidth: [Number, String],
    nudgeBottom: {
      type: [Number, String],
      default: 0
    },
    nudgeLeft: {
      type: [Number, String],
      default: 0
    },
    nudgeRight: {
      type: [Number, String],
      default: 0
    },
    nudgeTop: {
      type: [Number, String],
      default: 0
    },
    nudgeWidth: {
      type: [Number, String],
      default: 0
    },
    offsetOverflow: Boolean,
    positionX: {
      type: Number,
      default: null
    },
    positionY: {
      type: Number,
      default: null
    },
    zIndex: {
      type: [Number, String],
      default: null
    }
  },

  data: () => ({
    absoluteX: 0,
    absoluteY: 0,
    dimensions: Object.assign({}, dimensions),
    isContentActive: false,
    pageYOffset: 0,
    stackClass: 'v-menu__content--active',
    stackMinZIndex: 6
  }),

  computed: {
    computedLeft () {
      const a = this.dimensions.activator
      const c = this.dimensions.content
      const minWidth = Math.max(a.width, c.width)
      let left = 0

      if (this.left) left += a.left - (minWidth - a.width)
      if (this.isAttached) left += a.offsetLeft
      else left += a.left
      if (this.offsetX) left += this.left ? -a.width : a.width
      if (this.nudgeLeft) left -= parseInt(this.nudgeLeft)
      if (this.nudgeRight) left += parseInt(this.nudgeRight)

      return left
    },
    computedTop () {
      const a = this.dimensions.activator
      const c = this.dimensions.content
      let top = 0

      if (this.top) top += a.bottom - c.height
      if (this.isAttached) top += a.offsetTop
      else top += a.top + this.pageYOffset
      if (this.offsetY) top += this.top ? -a.height : a.height
      if (this.nudgeTop) top -= parseInt(this.nudgeTop)
      if (this.nudgeBottom) top += parseInt(this.nudgeBottom)

      return top
    },
    hasActivator () {
      return !!this.$slots.activator || !!this.$scopedSlots.activator || this.activator || this.inputActivator
    },
    isAttached () {
      return this.attach !== false
    }
  },

  watch: {
    disabled (val) {
      val && this.callDeactivate()
    },
    isActive (val) {
      if (this.disabled) return

      val ? this.callActivate() : this.callDeactivate()
    }
  },

  beforeMount () {
    this.checkForWindow()
  },

  methods: {
    absolutePosition () {
      return {
        offsetTop: 0,
        offsetLeft: 0,
        scrollHeight: 0,
        top: this.positionY || this.absoluteY,
        bottom: this.positionY || this.absoluteY,
        left: this.positionX || this.absoluteX,
        right: this.positionX || this.absoluteX,
        height: 0,
        width: 0
      }
    },
    activate () {},
    calcLeft () {
      return `${this.isAttached
        ? this.computedLeft
        : this.calcXOverflow(this.computedLeft)
      }px`
    },
    calcTop () {
      return `${this.isAttached
        ? this.computedTop
        : this.calcYOverflow(this.computedTop)
      }px`
    },
    calcXOverflow (left) {
      const parsedMaxWidth = isNaN(parseInt(this.maxWidth))
        ? 0
        : parseInt(this.maxWidth)
      const innerWidth = this.getInnerWidth()
      const maxWidth = Math.max(
        this.dimensions.content.width,
        parsedMaxWidth
      )
      const totalWidth = left + maxWidth
      const availableWidth = totalWidth - innerWidth

      if ((!this.left || this.right) && availableWidth > 0) {
        left = (
          innerWidth -
          maxWidth -
          (innerWidth > 600 ? 30 : 12) // Account for scrollbar
        )
      }

      if (left < 0) left = 12

      return left + this.getOffsetLeft()
    },
    calcYOverflow (top) {
      const documentHeight = this.getInnerHeight()
      const toTop = this.pageYOffset + documentHeight
      const activator = this.dimensions.activator
      const contentHeight = this.dimensions.content.height
      const totalHeight = top + contentHeight
      const isOverflowing = toTop < totalHeight

      // If overflowing bottom and offset
      // TODO: set 'bottom' position instead of 'top'
      if (isOverflowing &&
        this.offsetOverflow &&
        // If we don't have enough room to offset
        // the overflow, don't offset
        activator.top > contentHeight
      ) {
        top = this.pageYOffset + (activator.top - contentHeight)
      // If overflowing bottom
      } else if (isOverflowing && !this.allowOverflow) {
        top = toTop - contentHeight - 12
      // If overflowing top
      } else if (top < this.pageYOffset && !this.allowOverflow) {
        top = this.pageYOffset + 12
      }

      return top < 12 ? 12 : top
    },
    callActivate () {
      if (!this.hasWindow) return

      this.activate()
    },
    callDeactivate () {
      this.isContentActive = false

      this.deactivate()
    },
    checkForWindow () {
      if (!this.hasWindow) {
        this.hasWindow = typeof window !== 'undefined'
      }
    },
    checkForPageYOffset () {
      if (this.hasWindow) {
        this.pageYOffset = this.getOffsetTop()
      }
    },
    deactivate () {},
    getActivator (e) {
      if (this.inputActivator) {
        return this.$el.querySelector('.v-input__slot')
      }

      if (this.activator) {
        return typeof this.activator === 'string'
          ? document.querySelector(this.activator)
          : this.activator
      }

      if (this.$refs.activator) {
        return this.$refs.activator.children.length > 0
          ? this.$refs.activator.children[0]
          : this.$refs.activator
      }

      if (e) {
        this.activatedBy = e.currentTarget || e.target
        return this.activatedBy
      }

      if (this.activatedBy) return this.activatedBy

      consoleError('No activator found')
    },
    getInnerHeight () {
      if (!this.hasWindow) return 0

      return window.innerHeight ||
        document.documentElement.clientHeight
    },
    getInnerWidth () {
      if (!this.hasWindow) return 0

      return window.innerWidth
    },
    getOffsetLeft () {
      if (!this.hasWindow) return 0

      return window.pageXOffset ||
        document.documentElement.scrollLeft
    },
    getOffsetTop () {
      if (!this.hasWindow) return 0

      return window.pageYOffset ||
        document.documentElement.scrollTop
    },
    getRoundedBoundedClientRect (el) {
      const rect = el.getBoundingClientRect()
      return {
        top: Math.round(rect.top),
        left: Math.round(rect.left),
        bottom: Math.round(rect.bottom),
        right: Math.round(rect.right),
        width: Math.round(rect.width),
        height: Math.round(rect.height)
      }
    },
    measure (el) {
      if (!el || !this.hasWindow) return null

      const rect = this.getRoundedBoundedClientRect(el)

      // Account for activator margin
      if (this.isAttached) {
        const style = window.getComputedStyle(el)

        rect.left = parseInt(style.marginLeft)
        rect.top = parseInt(style.marginTop)
      }

      return rect
    },
    sneakPeek (cb) {
      requestAnimationFrame(() => {
        const el = this.$refs.content

        if (!el || this.isShown(el)) return cb()

        el.style.display = 'inline-block'
        cb()
        el.style.display = 'none'
      })
    },
    startTransition () {
      return new Promise(resolve => requestAnimationFrame(() => {
        this.isContentActive = this.hasJustFocused = this.isActive
        resolve()
      }))
    },
    isShown (el) {
      return el.style.display !== 'none'
    },
    updateDimensions () {
      this.checkForWindow()
      this.checkForPageYOffset()

      const dimensions = {}

      // Activator should already be shown
      if (!this.hasActivator || this.absolute) {
        dimensions.activator = this.absolutePosition()
      } else {
        const activator = this.getActivator()
        dimensions.activator = this.measure(activator)
        dimensions.activator.offsetLeft = activator.offsetLeft
        if (this.isAttached) {
          // account for css padding causing things to not line up
          // this is mostly for v-autocomplete, hopefully it won't break anything
          dimensions.activator.offsetTop = activator.offsetTop
        } else {
          dimensions.activator.offsetTop = 0
        }
      }

      // Display and hide to get dimensions
      this.sneakPeek(() => {
        dimensions.content = this.measure(this.$refs.content)

        this.dimensions = dimensions
      })
    }
  }
})
<commit_msg>fix(menuable): account for top+left<commit_after>import Vue from 'vue'

import Positionable from './positionable'

import Stackable from './stackable'
import { consoleError } from '../util/console'

/* eslint-disable object-property-newline */
const dimensions = {
  activator: {
    top: 0, left: 0,
    bottom: 0, right: 0,
    width: 0, height: 0,
    offsetTop: 0, scrollHeight: 0
  },
  content: {
    top: 0, left: 0,
    bottom: 0, right: 0,
    width: 0, height: 0,
    offsetTop: 0, scrollHeight: 0
  },
  hasWindow: false
}
/* eslint-enable object-property-newline */

/**
 * Menuable
 *
 * @mixin
 *
 * Used for fixed or absolutely positioning
 * elements within the DOM
 * Can calculate X and Y axis overflows
 * As well as be manually positioned
 */
/* @vue/component */
export default Vue.extend({
  name: 'menuable',

  mixins: [
    Positionable,
    Stackable
  ],

  props: {
    activator: {
      default: null,
      validator: val => {
        return ['string', 'object'].includes(typeof val)
      }
    },
    allowOverflow: Boolean,
    inputActivator: Boolean,
    light: Boolean,
    dark: Boolean,
    maxWidth: {
      type: [Number, String],
      default: 'auto'
    },
    minWidth: [Number, String],
    nudgeBottom: {
      type: [Number, String],
      default: 0
    },
    nudgeLeft: {
      type: [Number, String],
      default: 0
    },
    nudgeRight: {
      type: [Number, String],
      default: 0
    },
    nudgeTop: {
      type: [Number, String],
      default: 0
    },
    nudgeWidth: {
      type: [Number, String],
      default: 0
    },
    offsetOverflow: Boolean,
    positionX: {
      type: Number,
      default: null
    },
    positionY: {
      type: Number,
      default: null
    },
    zIndex: {
      type: [Number, String],
      default: null
    }
  },

  data: () => ({
    absoluteX: 0,
    absoluteY: 0,
    dimensions: Object.assign({}, dimensions),
    isContentActive: false,
    pageYOffset: 0,
    stackClass: 'v-menu__content--active',
    stackMinZIndex: 6
  }),

  computed: {
    computedLeft () {
      const a = this.dimensions.activator
      const c = this.dimensions.content
      const minWidth = Math.max(a.width, c.width)
      let left = 0

      if (this.isAttached) left += a.offsetLeft
      else left += this.left ? a.left - (minWidth - a.width) : a.left
      if (this.offsetX) left += this.left ? -a.width : a.width
      if (this.nudgeLeft) left -= parseInt(this.nudgeLeft)
      if (this.nudgeRight) left += parseInt(this.nudgeRight)

      return left
    },
    computedTop () {
      const a = this.dimensions.activator
      const c = this.dimensions.content
      let top = 0

      if (this.top) top += a.height - c.height
      if (this.isAttached) top += a.offsetTop
      else top += a.top + this.pageYOffset
      if (this.offsetY) top += this.top ? -a.height : a.height
      if (this.nudgeTop) top -= parseInt(this.nudgeTop)
      if (this.nudgeBottom) top += parseInt(this.nudgeBottom)

      return top
    },
    hasActivator () {
      return !!this.$slots.activator || !!this.$scopedSlots.activator || this.activator || this.inputActivator
    },
    isAttached () {
      return this.attach !== false
    }
  },

  watch: {
    disabled (val) {
      val && this.callDeactivate()
    },
    isActive (val) {
      if (this.disabled) return

      val ? this.callActivate() : this.callDeactivate()
    }
  },

  beforeMount () {
    this.checkForWindow()
  },

  methods: {
    absolutePosition () {
      return {
        offsetTop: 0,
        offsetLeft: 0,
        scrollHeight: 0,
        top: this.positionY || this.absoluteY,
        bottom: this.positionY || this.absoluteY,
        left: this.positionX || this.absoluteX,
        right: this.positionX || this.absoluteX,
        height: 0,
        width: 0
      }
    },
    activate () {},
    calcLeft () {
      return `${this.isAttached
        ? this.computedLeft
        : this.calcXOverflow(this.computedLeft)
      }px`
    },
    calcTop () {
      return `${this.isAttached
        ? this.computedTop
        : this.calcYOverflow(this.computedTop)
      }px`
    },
    calcXOverflow (left) {
      const parsedMaxWidth = isNaN(parseInt(this.maxWidth))
        ? 0
        : parseInt(this.maxWidth)
      const innerWidth = this.getInnerWidth()
      const maxWidth = Math.max(
        this.dimensions.content.width,
        parsedMaxWidth
      )
      const totalWidth = left + maxWidth
      const availableWidth = totalWidth - innerWidth

      if ((!this.left || this.right) && availableWidth > 0) {
        left = (
          innerWidth -
          maxWidth -
          (innerWidth > 600 ? 30 : 12) // Account for scrollbar
        )
      }

      if (left < 0) left = 12

      return left + this.getOffsetLeft()
    },
    calcYOverflow (top) {
      const documentHeight = this.getInnerHeight()
      const toTop = this.pageYOffset + documentHeight
      const activator = this.dimensions.activator
      const contentHeight = this.dimensions.content.height
      const totalHeight = top + contentHeight
      const isOverflowing = toTop < totalHeight

      // If overflowing bottom and offset
      // TODO: set 'bottom' position instead of 'top'
      if (isOverflowing &&
        this.offsetOverflow &&
        // If we don't have enough room to offset
        // the overflow, don't offset
        activator.top > contentHeight
      ) {
        top = this.pageYOffset + (activator.top - contentHeight)
      // If overflowing bottom
      } else if (isOverflowing && !this.allowOverflow) {
        top = toTop - contentHeight - 12
      // If overflowing top
      } else if (top < this.pageYOffset && !this.allowOverflow) {
        top = this.pageYOffset + 12
      }

      return top < 12 ? 12 : top
    },
    callActivate () {
      if (!this.hasWindow) return

      this.activate()
    },
    callDeactivate () {
      this.isContentActive = false

      this.deactivate()
    },
    checkForWindow () {
      if (!this.hasWindow) {
        this.hasWindow = typeof window !== 'undefined'
      }
    },
    checkForPageYOffset () {
      if (this.hasWindow) {
        this.pageYOffset = this.getOffsetTop()
      }
    },
    deactivate () {},
    getActivator (e) {
      if (this.inputActivator) {
        return this.$el.querySelector('.v-input__slot')
      }

      if (this.activator) {
        return typeof this.activator === 'string'
          ? document.querySelector(this.activator)
          : this.activator
      }

      if (this.$refs.activator) {
        return this.$refs.activator.children.length > 0
          ? this.$refs.activator.children[0]
          : this.$refs.activator
      }

      if (e) {
        this.activatedBy = e.currentTarget || e.target
        return this.activatedBy
      }

      if (this.activatedBy) return this.activatedBy

      consoleError('No activator found')
    },
    getInnerHeight () {
      if (!this.hasWindow) return 0

      return window.innerHeight ||
        document.documentElement.clientHeight
    },
    getInnerWidth () {
      if (!this.hasWindow) return 0

      return window.innerWidth
    },
    getOffsetLeft () {
      if (!this.hasWindow) return 0

      return window.pageXOffset ||
        document.documentElement.scrollLeft
    },
    getOffsetTop () {
      if (!this.hasWindow) return 0

      return window.pageYOffset ||
        document.documentElement.scrollTop
    },
    getRoundedBoundedClientRect (el) {
      const rect = el.getBoundingClientRect()
      return {
        top: Math.round(rect.top),
        left: Math.round(rect.left),
        bottom: Math.round(rect.bottom),
        right: Math.round(rect.right),
        width: Math.round(rect.width),
        height: Math.round(rect.height)
      }
    },
    measure (el) {
      if (!el || !this.hasWindow) return null

      const rect = this.getRoundedBoundedClientRect(el)

      // Account for activator margin
      if (this.isAttached) {
        const style = window.getComputedStyle(el)

        rect.left = parseInt(style.marginLeft)
        rect.top = parseInt(style.marginTop)
      }

      return rect
    },
    sneakPeek (cb) {
      requestAnimationFrame(() => {
        const el = this.$refs.content

        if (!el || this.isShown(el)) return cb()

        el.style.display = 'inline-block'
        cb()
        el.style.display = 'none'
      })
    },
    startTransition () {
      return new Promise(resolve => requestAnimationFrame(() => {
        this.isContentActive = this.hasJustFocused = this.isActive
        resolve()
      }))
    },
    isShown (el) {
      return el.style.display !== 'none'
    },
    updateDimensions () {
      this.checkForWindow()
      this.checkForPageYOffset()

      const dimensions = {}

      // Activator should already be shown
      if (!this.hasActivator || this.absolute) {
        dimensions.activator = this.absolutePosition()
      } else {
        const activator = this.getActivator()
        dimensions.activator = this.measure(activator)
        dimensions.activator.offsetLeft = activator.offsetLeft
        if (this.isAttached) {
          // account for css padding causing things to not line up
          // this is mostly for v-autocomplete, hopefully it won't break anything
          dimensions.activator.offsetTop = activator.offsetTop
        } else {
          dimensions.activator.offsetTop = 0
        }
      }

      // Display and hide to get dimensions
      this.sneakPeek(() => {
        dimensions.content = this.measure(this.$refs.content)

        this.dimensions = dimensions
      })
    }
  }
})
<|endoftext|>


<commit_before>import sanitizeHtml from 'sanitize-html';
import { Utils } from '../modules';
import { throwError } from './errors.js';

Utils.sanitizeAllowedTags = [
  'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul',
  'ol', 'nl', 'li', 'b', 'i', 'u', 'strong', 'em', 'strike',
  'code', 'hr', 'br', 'div', 'table', 'thead', 'caption',
  'tbody', 'tr', 'th', 'td', 'pre', 'img', 'figure', 'figcaption',
  'span'
]

Utils.sanitize = function(s) {
  return sanitizeHtml(s, {
    allowedTags: Utils.sanitizeAllowedTags,
    allowedAttributes:  {
      ...sanitizeHtml.defaults.allowedAttributes,
      img: [ 'src' , 'srcset'],
      figure: ['style'],
      td: ['rowspan', 'colspan'],
      span: ['style']
    },
    allowedStyles: {
      ...sanitizeHtml.defaults.allowedStyles,
      'figure': {
        'width': [/^(?:\d|\.)+(?:px|em|%)$/]
      },
      span: {
        // From: https://gist.github.com/olmokramer/82ccce673f86db7cda5e#gistcomment-3119899
        color: [/(#([\da-f]{3}){1,2}|(rgb|hsl)a\((\d{1,3}%?,\s?){3}(1|0?\.\d+)\)|(rgb|hsl)\(\d{1,3}%?(,\s?\d{1,3}%?){2}\))/]
      }
    }
  });
};

Utils.performCheck = (operation, user, checkedObject, context, documentId, operationName, collectionName) => {

  if (!checkedObject) {
    throwError({ id: 'app.document_not_found', data: { documentId, operationName } });
  }

  if (!operation(user, checkedObject, context)) {
    throwError({ id: 'app.operation_not_allowed', data: { documentId, operationName } });
  }

};

export { Utils };
<commit_msg>Add sub and sup tags to permitted tags<commit_after>import sanitizeHtml from 'sanitize-html';
import { Utils } from '../modules';
import { throwError } from './errors.js';

Utils.sanitizeAllowedTags = [
  'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul',
  'ol', 'nl', 'li', 'b', 'i', 'u', 'strong', 'em', 'strike',
  'code', 'hr', 'br', 'div', 'table', 'thead', 'caption',
  'tbody', 'tr', 'th', 'td', 'pre', 'img', 'figure', 'figcaption',
  'span', 'sub', 'sup'
]

Utils.sanitize = function(s) {
  return sanitizeHtml(s, {
    allowedTags: Utils.sanitizeAllowedTags,
    allowedAttributes:  {
      ...sanitizeHtml.defaults.allowedAttributes,
      img: [ 'src' , 'srcset'],
      figure: ['style'],
      td: ['rowspan', 'colspan'],
      span: ['style']
    },
    allowedStyles: {
      ...sanitizeHtml.defaults.allowedStyles,
      'figure': {
        'width': [/^(?:\d|\.)+(?:px|em|%)$/]
      },
      span: {
        // From: https://gist.github.com/olmokramer/82ccce673f86db7cda5e#gistcomment-3119899
        color: [/(#([\da-f]{3}){1,2}|(rgb|hsl)a\((\d{1,3}%?,\s?){3}(1|0?\.\d+)\)|(rgb|hsl)\(\d{1,3}%?(,\s?\d{1,3}%?){2}\))/]
      }
    }
  });
};

Utils.performCheck = (operation, user, checkedObject, context, documentId, operationName, collectionName) => {

  if (!checkedObject) {
    throwError({ id: 'app.document_not_found', data: { documentId, operationName } });
  }

  if (!operation(user, checkedObject, context)) {
    throwError({ id: 'app.operation_not_allowed', data: { documentId, operationName } });
  }

};

export { Utils };
<|endoftext|>


<commit_before>var $, d3;

$(function() {
  'use strict';

  d3.json('/media', function(data) {
    var day = d3.select('#content')
      .selectAll('div')
      .data(data)
      .enter()
      .append('div')
    ;

    day.append('h2').text(function(d) { return d.date; });
    day.append('svg')
      .selectAll('g')
      .data(function(d) { return d.events; })
      .enter()
      .append('g')
      .append('text').text(function(d) { return d.filePrefix; })
      ;
  });

});
<commit_msg>put images with links on the svg<commit_after>(function($, d3) {

  // from a date as 2015-05-30_21.22.29
  // return a number from 0 to 1 depending on the time, midnight to midnight
  function timeOfDay(dateString) {
    var time = dateString.match(/_(\d{2})\.(\d{2})\.(\d{2})/);
    return (time[1] * 3600 + time[2] * 60 + parseInt(time[3],10)) / 86400;
  }

  $(function() {
    'use strict';

    d3.json('/media', function(data) {
      var day = d3.select('#content')
        .selectAll('div')
        .data(data)
        .enter()
        .append('div')
      ;

      day.append('h2').text(function(d) { return d.date; });
      day.append('svg').attr('width', 1000).attr('height', 300)
        .selectAll('g')
        .data(function(d) { return d.events; })
        .enter()
        .append('a')
          .attr('xlink:href', function(d) { return d.href + '.jpg'; })
          .append('image')
            .attr('xlink:href', function(d) { return d.href + '.jpg'; })
            .attr('x', function(d) {
              return timeOfDay(d.filePrefix) * 1000;
            })
            .attr('y', 0)
            .attr('width', 50).attr('height', 50)
      ;
    });
  });
})($, d3);
<|endoftext|>


<commit_before>/*
 * anchorizer
 *
 * Copyright 2015 Mathieu Duponchelle <mathieu.duponchelle@opencredd.com>
 * Copyright 2015 Collabora Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 */

$(document).ready(function() {
	$("h1,h2,h3,h4,h5").each(function() {
		if ($(this).attr('id'))
			return;

    		var hyphenated = $(this).text().replace(/\s/g,'-').toLowerCase();
    		$(this).attr('id',hyphenated);
    	});
});
<commit_msg>anchorizer.js: make id creation safe.<commit_after>/*
 * anchorizer
 *
 * Copyright 2015 Mathieu Duponchelle <mathieu.duponchelle@opencredd.com>
 * Copyright 2015 Collabora Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 */

$(document).ready(function() {
	$("h1,h2,h3,h4,h5").each(function() {
		if ($(this).attr('id'))
			return;

    		var hyphenated = $(this).text().trim().replace(/\s/g,'-').toLowerCase();

		hyphenated = hyphenated.replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '');

		var new_id = hyphenated;
		var counter = 0;
		while (($('#' + new_id).length)) {
			counter += 1;
			new_id = hyphenated + counter;
		}

    		$(this).attr('id', CSS.escape(new_id));
    	});
});
<|endoftext|>


<commit_before>var _ = require('../../../lib/alloy/underscore')._,
	U = require('../../../utils'),
	CU = require('../compilerUtils');

exports.parse = function(node, state) {
	return require('./base').parse(node, state, parse);
};

function parse(node, state, args) {
	var children = U.XML.getElementsFromNodes(node.childNodes),
		code = '';

	// Generate code for Tab's Window
	// TODO: assert children[0] is actually a Window - https://jira.appcelerator.org/browse/ALOY-217
	var winSymbol;
	code += CU.generateNode(children[0], {
		parent: {},
		styles: state.styles,
		post: function(n,s,a) {
			winSymbol = s.parent.symbol;
		}
	});

	// Generate the code for the Tab itself, with the Window in it
	code += require('./default').parse(node, {
		parent: {},
		styles: state.styles,
		extraStyle: CU.createVariableStyle('window', winSymbol)
	}).code;

	// Update the parsing state
	return {
		parent: {},
		styles: state.styles,
		code: code
	}
};<commit_msg>fixes ALOY-217, improves error output<commit_after>var _ = require('../../../lib/alloy/underscore')._,
	U = require('../../../utils'),
	CU = require('../compilerUtils');

exports.parse = function(node, state) {
	return require('./base').parse(node, state, parse);
};

function parse(node, state, args) {
	var children = U.XML.getElementsFromNodes(node.childNodes),
		err = [
			'Tab must have only one child element.',
			'Valid elements:',
			'    <Window>',
			'    <Require>, which must contain only one top-level element and that element must be a <Window>'
		],
		code = '';

	if (children.length !== 1) {
		U.die(err);
	}

	// Generate code for Tab's Window
	// TODO: assert children[0] is actually a Window - https://jira.appcelerator.org/browse/ALOY-217
	var child = children[0],
		childArgs = CU.getParserArgs(child),
		winSymbol;

	switch(childArgs.fullname) {
		case 'Alloy.Require':
			var inspect = CU.inspectRequireNode(child);
			if (inspect.length !== 1) {
				err.unshift('Tab <Require> child element contains ' + inspect.length + ' top-level elements.');
				U.die(err);
			} else if (inspect.names[0] !== 'Ti.UI.Window') {
				err.unshift('Invalid Tab <Require> child "' + inspect.names[0] + '"');
				U.die(err);
			}
			break;
		case 'Ti.UI.Window':
			break;
		default:
			err.unshift('Invalid Tab child "' + childArgs.fullname + '"');
			U.die(err);
			break;
	}

	code += CU.generateNode(child, {
		parent: {},
		styles: state.styles,
		post: function(n,s,a) {
			winSymbol = s.parent.symbol;
		}
	});

	// Generate the code for the Tab itself, with the Window in it
	code += require('./default').parse(node, {
		parent: {},
		styles: state.styles,
		extraStyle: CU.createVariableStyle('window', winSymbol)
	}).code;

	// Update the parsing state
	return {
		parent: {},
		styles: state.styles,
		code: code
	}
};<|endoftext|>


<commit_before>// Greater than validator
window.ParsleyValidator.addValidator('gt',
	function (value, requirement) {
        return parseFloat(value) > parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'gt', 'This value should be greater');

// Greater than or equal to validator
window.ParsleyValidator.addValidator('ge',
	function (value, requirement) {
        return parseFloat(value) >= parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'ge', 'This value should be greater or equal');

// Less than validator
window.ParsleyValidator.addValidator('lt',
	function (value, requirement) {
        return parseFloat(value) < parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'lt', 'This value should be less');

// Less than or equal to validator
window.ParsleyValidator.addValidator('le',
	function (value, requirement) {
        return parseFloat(value) <= parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'le', 'This value should be less or equal');
<commit_msg>notequalto validator is added<commit_after>//  Not equal to validator
window.ParsleyValidator.addValidator('notequalto',
    function (value, requirement) {
        return value !== $(requirement).val();
    }, 32)
    .addMessage('en', 'notequalto', 'This value should not be the same.');

// Greater than validator
window.ParsleyValidator.addValidator('gt',
	function (value, requirement) {
        return parseFloat(value) > parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'gt', 'This value should be greater');

// Greater than or equal to validator
window.ParsleyValidator.addValidator('ge',
	function (value, requirement) {
        return parseFloat(value) >= parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'ge', 'This value should be greater or equal');

// Less than validator
window.ParsleyValidator.addValidator('lt',
	function (value, requirement) {
        return parseFloat(value) < parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'lt', 'This value should be less');

// Less than or equal to validator
window.ParsleyValidator.addValidator('le',
	function (value, requirement) {
        return parseFloat(value) <= parseFloat($(requirement).val());
    }, 32)
    .addMessage('en', 'le', 'This value should be less or equal');
<|endoftext|>


<commit_before>var _sutil = CT.stream.util = {
	// for single channel av
	blob_to_b64: function(blob, cb) {
		blob ? _sutil.read(blob, cb) : cb();
	},
	b64_to_blob: function(b64, cb) {
		b64 ? fetch(b64.video || b64).then(function(res) {
			return res.blob();
		}).then(cb) : cb();
	},
	blob_to_buffer: function(blob, cb) {
		blob ? _sutil.read(blob, cb, true) : cb();
	},
	b64_to_buffer: function(b64, cb) {
		_sutil.b64_to_blob(b64, function(blob) {
			_sutil.blob_to_buffer(blob, cb);
		});
	},
	// some browsers may require separate audio/video
	blobs_to_b64s: function(blobs, cb) {
		_sutil.blob_to_b64(blobs.video, function(b64video) {
			_sutil.blob_to_b64(blobs.audio, function(b64audio) {
				cb({ video: b64video, audio: b64audio });
			});
		});
	},
	b64s_to_blobs: function(b64s, cb) {
		_sutil.b64_to_blob(b64s.video, function(vblob) {
			_sutil.b64_to_blob(b64s.audio, function(ablob) {
				cb({ video: vblob, audio: ablob });
			});
		});
	},
	blobs_to_buffers: function(blobs, cb) {
		_sutil.blob_to_buffer(blobs.video, function(videobuffer) {
			_sutil.blob_to_buffer(blobs.audio, function(audiobuffer) {
				cb({ video: videobuffer, audio: audiobuffer });
			});
		});
	},
	b64s_to_buffers: function(b64s, cb) {
		_sutil.b64s_to_blobs(b64s, function(blobs) {
			_sutil.blobs_to_buffers(blobs, cb);
		});
	},
	// core functions
	read: function(blob, cb, buffer) {
		var signature = "read" + (buffer ? "buffer" : "url"),
			fr = new FileReader();
		CT.log.startTimer(signature);
		fr.onloadend = function() {
			CT.log.endTimer(signature, fr.result.length || fr.result.byteLength);
			cb(fr.result);
		};
		buffer ? fr.readAsArrayBuffer(blob) : fr.readAsDataURL(blob);
	},
	avRecorder: function(stream) {
		return new MediaRecorder(stream, CT.stream.opts.mropts);
	},
	videoRecorder: function(stream) {
		var r = new MediaStreamRecorder(stream);
		r.mimeType = CT.stream.opts.codecs.video;
		r.recorderType = WhammyRecorder;
		return r;
	},
	audioRecorder: function(stream) {
		var r = new MediaStreamRecorder(stream);
		r.mimeType = CT.stream.opts.codecs.audio;
		r.recorderType = StereoAudioRecorder;
		r.audioChannels = 1;
		return r;
	},
	_multi: function(ondata, onrecorder) {
		return function(stream) {
			CT.log.endTimer("record", "got data!");
			var vrec = _sutil.videoRecorder(stream),
				arec = _sutil.audioRecorder(stream),
				segment = 0, segments = [], addseg = function() {
					if (segment > segments.length - 1) {
						segments.push({
							audio: null,
							video: null
						});
					}
				}, checkseg = function() {
					var seg = segments[segment];
					if (seg && seg.audio && seg.video) {
						ondata(seg, segment);
						segment = (segment + 1) % CT.stream.opts.segments;
						if (!segment)
							segments.length = 0;
					}
				};
			vrec.onStartedDrawingNonBlankFrames = function() {
				CT.log("STARTING AUDIO");
				vrec.clearOldRecordedFrames();
				arec.start(CT.stream.opts.chunk);
			};
			arec.ondataavailable = function(blob) {
				CT.log("AUDIO");
				addseg();
				segments[segment].audio = blob;
				checkseg();
			};
			vrec.ondataavailable = function(blob) {
				CT.log("VIDEO");
				addseg();
				segments[segment].video = blob;
				checkseg();
			};
			vrec.start(CT.stream.opts.chunk);
			onrecorder && onrecorder({
				stop: function() {
					arec.stop();
					vrec.stop();
				},
				save: vrec.save
			}, stream);
		};
	},
	_single: function(ondata, onrecorder) {
		return function(stream) {
			var segment = 0, recorder = _sutil.avRecorder(stream);
			recorder.ondataavailable = function(blobevent) {
				CT.log("ondataavailable!!");
				segment = (segment + 1) % CT.stream.opts.segments;
				ondata && ondata({ video: blobevent.data }, segment);
			};
			recorder.onerror = function(e) {
				CT.log("error! " + e.message);
			};
			recorder.start(CT.stream.opts.chunk);
			onrecorder && onrecorder(recorder, stream);
		};
	},
	record: function(ondata, onrecorder, onfail) {
		var recorder = CT.stream.opts.merged
			? _sutil._single : _sutil._multi;
		CT.log.startTimer("record", "(attempt)");
		navigator.mediaDevices.getUserMedia({
			video: true, audio: true
		}).then(recorder(ondata, onrecorder))["catch"](onfail || function(err) {
			CT.log.endTimer("record", "got error: " + err);
		});
	}
};<commit_msg>CT.stream.util: stop passing extra recorder events when recorder is disabled, as in ctstream plugin<commit_after>var _sutil = CT.stream.util = {
	// for single channel av
	blob_to_b64: function(blob, cb) {
		blob ? _sutil.read(blob, cb) : cb();
	},
	b64_to_blob: function(b64, cb) {
		b64 ? fetch(b64.video || b64).then(function(res) {
			return res.blob();
		}).then(cb) : cb();
	},
	blob_to_buffer: function(blob, cb) {
		blob ? _sutil.read(blob, cb, true) : cb();
	},
	b64_to_buffer: function(b64, cb) {
		_sutil.b64_to_blob(b64, function(blob) {
			_sutil.blob_to_buffer(blob, cb);
		});
	},
	// some browsers may require separate audio/video
	blobs_to_b64s: function(blobs, cb) {
		_sutil.blob_to_b64(blobs.video, function(b64video) {
			_sutil.blob_to_b64(blobs.audio, function(b64audio) {
				cb({ video: b64video, audio: b64audio });
			});
		});
	},
	b64s_to_blobs: function(b64s, cb) {
		_sutil.b64_to_blob(b64s.video, function(vblob) {
			_sutil.b64_to_blob(b64s.audio, function(ablob) {
				cb({ video: vblob, audio: ablob });
			});
		});
	},
	blobs_to_buffers: function(blobs, cb) {
		_sutil.blob_to_buffer(blobs.video, function(videobuffer) {
			_sutil.blob_to_buffer(blobs.audio, function(audiobuffer) {
				cb({ video: videobuffer, audio: audiobuffer });
			});
		});
	},
	b64s_to_buffers: function(b64s, cb) {
		_sutil.b64s_to_blobs(b64s, function(blobs) {
			_sutil.blobs_to_buffers(blobs, cb);
		});
	},
	// core functions
	read: function(blob, cb, buffer) {
		var signature = "read" + (buffer ? "buffer" : "url"),
			fr = new FileReader();
		CT.log.startTimer(signature);
		fr.onloadend = function() {
			CT.log.endTimer(signature, fr.result.length || fr.result.byteLength);
			cb(fr.result);
		};
		buffer ? fr.readAsArrayBuffer(blob) : fr.readAsDataURL(blob);
	},
	avRecorder: function(stream) {
		return new MediaRecorder(stream, CT.stream.opts.mropts);
	},
	videoRecorder: function(stream) {
		var r = new MediaStreamRecorder(stream);
		r.mimeType = CT.stream.opts.codecs.video;
		r.recorderType = WhammyRecorder;
		return r;
	},
	audioRecorder: function(stream) {
		var r = new MediaStreamRecorder(stream);
		r.mimeType = CT.stream.opts.codecs.audio;
		r.recorderType = StereoAudioRecorder;
		r.audioChannels = 1;
		return r;
	},
	_multi: function(ondata, onrecorder) {
		return function(stream) {
			CT.log.endTimer("record", "got data!");
			var vrec = _sutil.videoRecorder(stream),
				arec = _sutil.audioRecorder(stream),
				segment = 0, segments = [], addseg = function() {
					if (segment > segments.length - 1) {
						segments.push({
							audio: null,
							video: null
						});
					}
				}, checkseg = function() {
					var seg = segments[segment];
					if (seg && seg.audio && seg.video) {
						ondata(seg, segment);
						segment = (segment + 1) % CT.stream.opts.segments;
						if (!segment)
							segments.length = 0;
					}
				};
			vrec.onStartedDrawingNonBlankFrames = function() {
				CT.log("STARTING AUDIO");
				vrec.clearOldRecordedFrames();
				arec.start(CT.stream.opts.chunk);
			};
			arec.ondataavailable = function(blob) {
				CT.log("AUDIO");
				addseg();
				segments[segment].audio = blob;
				checkseg();
			};
			vrec.ondataavailable = function(blob) {
				CT.log("VIDEO");
				addseg();
				segments[segment].video = blob;
				checkseg();
			};
			vrec.start(CT.stream.opts.chunk);
			onrecorder && onrecorder({
				stop: function() {
					arec.stop();
					vrec.stop();
				},
				save: vrec.save
			}, stream);
		};
	},
	_single: function(ondata, onrecorder) {
		return function(stream) {
			var segment = 0, recorder = _sutil.avRecorder(stream);
			recorder.ondataavailable = function(blobevent) {
				CT.log("ondataavailable!!");
				segment = (segment + 1) % CT.stream.opts.segments;
				!recorder._stopped && ondata &&
					ondata({ video: blobevent.data }, segment);
			};
			recorder.onerror = function(e) {
				CT.log("error! " + e.message);
			};
			recorder.start(CT.stream.opts.chunk);
			onrecorder && onrecorder(recorder, stream);
		};
	},
	record: function(ondata, onrecorder, onfail) {
		var recorder = CT.stream.opts.merged
			? _sutil._single : _sutil._multi;
		CT.log.startTimer("record", "(attempt)");
		navigator.mediaDevices.getUserMedia({
			video: true, audio: true
		}).then(recorder(ondata, onrecorder))["catch"](onfail || function(err) {
			CT.log.endTimer("record", "got error: " + err);
		});
	}
};<|endoftext|>


<commit_before>#!/usr/bin/env node

var yaml = require("yamljs");
var glob = require('glob');

// define the required arguments
opt = require('node-getopt').create([
  ['', 'cluster=NAME', 'name of cluster to join'],
  ['', 'storage-type=TYPE', 'storage service type, supports: etcd'],
  ['', 'storage-host=IP', 'ip address of storage host'],
  ['', 'storage-port=PORT', 'port of storage service'],
  ['', 'service=SERVICE', 'for a multi service image, specify the service to start'],
  ['', 'force-address=IP', 'manually set the advertised IP of this instance'],
  ['', 'no-dns', 'don\'t use the ClusterDNS service'],
  ['', 'usermode', 'always run services as the calling user'],
  //['', 'eval', 'format output suitable to eval in the host shell'],
  ['', 'just-yml', 'just dump the generated cluster init.yml and nothing else'],
  ['i', 'info', 'display information about this vcc image'],
  ['h', 'help', 'display this help'],
  ['v', 'version', 'show version']
]); // parse command line

var options = opt.parseSystem().options;

if (options.help) {
    opt.showHelp();
    process.exit(1);
}

if ((options.version || options.info)) {
    // version command
    if (options.version) {
        console.log("vccjs tool 0.1");
        console.log("▒▒▒▒▒▒▒▓");
        console.log("▒▒▒▒▒▒▒▓▓▓");
        console.log("▒▓▓▓▓▓▓░░░▓");
        console.log("▒▓░░░░▓░░░░▓");
        console.log("▓░░░░░░▓░▓░▓");
        console.log("▓░░░░░░▓░░░▓");
        console.log("▓░░▓░░░▓▓▓▓");
        console.log("▒▓░░░░▓▒▒▒▒▓");
        console.log("▒▒▓▓▓▓▒▒▒▒▒▓");
        console.log("▒▒▒▒▒▒▒▒▓▓▓▓");
        console.log("▒▒▒▒▒▓▓▓▒▒▒▒▓");
        console.log("▒▒▒▒▓▒▒▒▒▒▒▒▒▓");
        console.log("▒▒▒▓▒▒▒▒▒▒▒▒▒▓");
        console.log("▒▒▓▒▒▒▒▒▒▒▒▒▒▒▓");
        console.log("▒▓▒▓▒▒▒▒▒▒▒▒▒▓");
        console.log("▒▓▒▓▓▓▓▓▓▓▓▓▓");
        console.log("▒▓▒▒▒▒▒▒▒▓");
        console.log("▒▒▓▒▒▒▒▒▓ ");
        process.exit(1);
    }
    // info command
    if (options.info) {
        // get some basic details about this image
        var inityml = yaml.load("/etc/init.yml");
        var info = {};
        if(!inityml.cluster.image_info) {
            console.error("This image does not define any author info in the init.yml");
        } else {
            info['Name'] = inityml.cluster.image_info.name;
            info['Version'] = inityml.cluster.image_info.version;
            info['Author'] = inityml.cluster.image_info.author;
        }
        // check for multi service image
        info['Services'] = {};
        info.Services['Default'] = inityml.cluster.service;
        info.Services['Available'] = [];
        files = glob.sync("/etc/vcc/services-*.yml");
        for (var i = files.length - 1; i >= 0; i--) {
            info.Services.Available.push(files[i].replace("/etc/vcc/services-", "").replace(".yml", ""));
        };

        // check for service providers and dependencies
        var deps = yaml.load("/etc/vcc/dependencies.yml");
        info.Services['Dependencies'] = deps;
        // print out in yaml
        console.log(yaml.stringify(info, 8));
        process.exit(1);
    }
} else {
    // check cluster name is specified
    if (!options.cluster) {
        console.error("You must specify a cluster name using --cluster=NAME");
        process.exit(1);
    }
    // check we have either --start-storage or --storage-host and --storage-port
    if (!(options['storage-host'] && options['storage-port'])) {
        console.error("You must specify --storage-host and --storage-port");
        process.exit(1);
    }
    // generate yml config with cluster name and storage details in
    // since the tool is executed within the image itself, we can just look at /etc/init.yml
    var inityml = yaml.load("/etc/init.yml");
    // storage settings
    if(!options['storage-type']) {
        inityml.cluster.kvstore.type = "etcd";
    } else {
        inityml.cluster.kvstore.type = options['storage-type'];
    }
    inityml.cluster.kvstore.host = options['storage-host'];
    inityml.cluster.kvstore.port = options['storage-port'];
    // address override
    if(options['force-address']) {
        inityml.cluster.myaddress = options['force-address'];
    }
    // cluster dns
    if(options['no-dns']) {
        inityml.cluster.nodns = true;
    }
    // set cluster name and service
    inityml.cluster.cluster = options.cluster;
    if (options.service) {
        inityml.cluster.service = options.service;
    }
    // convert to yaml and then base64 encode
    var b64inityml = new Buffer(yaml.stringify(inityml)).toString('base64');
    // generate command for starting this image
    var runcommand = "/init8js/init.js ";
    // add usermode option if required
    if (options.usermode) {
        runcommand += "usermode ";
    }
    runcommand += "b64inityml="+b64inityml;
    // output the commands in the desired format
    if (options['just-yml']) {
        console.log(yaml.stringify(inityml));
        process.exit(1);
    } else {
        console.log(runcommand);
        process.exit(0);
    }
}
<commit_msg>remove superfluous if else<commit_after>#!/usr/bin/env node

var yaml = require("yamljs");
var glob = require('glob');

// define the required arguments
opt = require('node-getopt').create([
  ['', 'cluster=NAME', 'name of cluster to join'],
  ['', 'storage-type=TYPE', 'storage service type, supports: etcd'],
  ['', 'storage-host=IP', 'ip address of storage host'],
  ['', 'storage-port=PORT', 'port of storage service'],
  ['', 'service=SERVICE', 'for a multi service image, specify the service to start'],
  ['', 'force-address=IP', 'manually set the advertised IP of this instance'],
  ['', 'no-dns', 'don\'t use the ClusterDNS service'],
  ['', 'usermode', 'always run services as the calling user'],
  //['', 'eval', 'format output suitable to eval in the host shell'],
  ['', 'just-yml', 'just dump the generated cluster init.yml and nothing else'],
  ['i', 'info', 'display information about this vcc image'],
  ['h', 'help', 'display this help'],
  ['v', 'version', 'show version']
]); // parse command line

var options = opt.parseSystem().options;

// help command
if (options.help) {
    opt.showHelp();
    process.exit(1);
}

// version command
if (options.version) {
    console.log("vccjs tool 0.1");
    console.log("▒▒▒▒▒▒▒▓");
    console.log("▒▒▒▒▒▒▒▓▓▓");
    console.log("▒▓▓▓▓▓▓░░░▓");
    console.log("▒▓░░░░▓░░░░▓");
    console.log("▓░░░░░░▓░▓░▓");
    console.log("▓░░░░░░▓░░░▓");
    console.log("▓░░▓░░░▓▓▓▓");
    console.log("▒▓░░░░▓▒▒▒▒▓");
    console.log("▒▒▓▓▓▓▒▒▒▒▒▓");
    console.log("▒▒▒▒▒▒▒▒▓▓▓▓");
    console.log("▒▒▒▒▒▓▓▓▒▒▒▒▓");
    console.log("▒▒▒▒▓▒▒▒▒▒▒▒▒▓");
    console.log("▒▒▒▓▒▒▒▒▒▒▒▒▒▓");
    console.log("▒▒▓▒▒▒▒▒▒▒▒▒▒▒▓");
    console.log("▒▓▒▓▒▒▒▒▒▒▒▒▒▓");
    console.log("▒▓▒▓▓▓▓▓▓▓▓▓▓");
    console.log("▒▓▒▒▒▒▒▒▒▓");
    console.log("▒▒▓▒▒▒▒▒▓ ");
    process.exit(1);
}
// info command
if (options.info) {
    // get some basic details about this image
    var inityml = yaml.load("/etc/init.yml");
    var info = {};
    if(!inityml.cluster.image_info) {
        console.error("This image does not define any author info in the init.yml");
    } else {
        info['Name'] = inityml.cluster.image_info.name;
        info['Version'] = inityml.cluster.image_info.version;
        info['Author'] = inityml.cluster.image_info.author;
    }
    // check for multi service image
    info['Services'] = {};
    info.Services['Default'] = inityml.cluster.service;
    info.Services['Available'] = [];
    files = glob.sync("/etc/vcc/services-*.yml");
    for (var i = files.length - 1; i >= 0; i--) {
        info.Services.Available.push(files[i].replace("/etc/vcc/services-", "").replace(".yml", ""));
    };

    // check for service providers and dependencies
    var deps = yaml.load("/etc/vcc/dependencies.yml");
    info.Services['Dependencies'] = deps;
    // print out in yaml
    console.log(yaml.stringify(info, 8));
    process.exit(1);
}

// otherwise, start the VCC!
// check cluster name is specified
if (!options.cluster) {
    console.error("You must specify a cluster name using --cluster=NAME");
    process.exit(1);
}
// check we have either --start-storage or --storage-host and --storage-port
if (!(options['storage-host'] && options['storage-port'])) {
    console.error("You must specify --storage-host and --storage-port");
    process.exit(1);
}
// generate yml config with cluster name and storage details in
// since the tool is executed within the image itself, we can just look at /etc/init.yml
var inityml = yaml.load("/etc/init.yml");
// storage settings
if(!options['storage-type']) {
    inityml.cluster.kvstore.type = "etcd";
} else {
    inityml.cluster.kvstore.type = options['storage-type'];
}
inityml.cluster.kvstore.host = options['storage-host'];
inityml.cluster.kvstore.port = options['storage-port'];
// address override
if(options['force-address']) {
    inityml.cluster.myaddress = options['force-address'];
}
// cluster dns
if(options['no-dns']) {
    inityml.cluster.nodns = true;
}
// set cluster name and service
inityml.cluster.cluster = options.cluster;
if (options.service) {
    inityml.cluster.service = options.service;
}
// convert to yaml and then base64 encode
var b64inityml = new Buffer(yaml.stringify(inityml)).toString('base64');
// generate command for starting this image
var runcommand = "/init8js/init.js ";
// add usermode option if required
if (options.usermode) {
    runcommand += "usermode ";
}
runcommand += "b64inityml="+b64inityml;
// output the commands in the desired format
if (options['just-yml']) {
    console.log(yaml.stringify(inityml));
    process.exit(1);
} else {
    console.log(runcommand);
    process.exit(0);
}<|endoftext|>


<commit_before>//Require Module
var log4js = require('log4js');
var logger = log4js.getLogger('sendNotification');
var promise = require('promised-io');
var mailer = require('emailjs');

/**
 *
 * Send notification mail.
 *
 * @param {object} mailConneciton
 * @param {object} mailOpt
 * @param {function} callback
 *
 */

function sendMail(mailConnection,mailOpt, callback) {

    mailConnection.send(mailOpt, callback);
}

module.exports = {
	sendMail: sendMail
}
<commit_msg>Complete sendMail and retrySendMail function<commit_after>//Require Module
var log4js = require('log4js');
var logger = log4js.getLogger('sendNotification');
var promise = require('promised-io');
var mailer = require('emailjs');

/**
 *
 * Send notification mail.
 *
 * @param {object} mailConneciton
 * @param {object} mailOpt
 * @param {function} callback
 * @param {object} p
 *
 */

function sendMail(mailConnection,mailOpt, callback) {

    mailConnection.send(mailOpt, callback);
}

/**
 *
 * Retry send mail action with promise seq.
 *
 * @param {function} action
 * @return {object} pRetry
 *
 */

function retrySendMail(action){

    var funList = [];

    for (var i = 0; i < 2; i++) {

        funList.push(action);
    }

    var pRetry = promise.seq(funList, {
            mailConnection: mailConnection,
            mailOpt: opt,
            retry: true
        });

        return pRetry;
}

module.exports = {
	sendMail: sendMail
    retrySendMail:retrySendMail
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Повелители стихий. Кликер
// @namespace    https://ok.elem.mobi/
// @version      1.0a
// @description  Проводит дуэли (пока что)
// @author       GoodVin
// @match        *://*.elem.mobi/*
// @match        *://elem.mobi/*
// @require      http://code.jquery.com/jquery-3.2.1.slim.min.js
// @require      https://github.com/wisegoodvin/mobclickers/raw/master/shared_functions.js
// @downloadURL  https://github.com/wisegoodvin/mobclickers/raw/master/mobelem_clicker.user.js
// @updateURL    https://github.com/wisegoodvin/mobclickers/raw/master/mobelem_clicker.user.js
// @icon         https://elem.mobi/img/favicon.ico
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==
jQuery.fn.cl = function( options ) {
	var cfg = $.extend({
		timer1 : 500,
		timer2 : 750
	}, options );
	if(this.length) {
		var ths = this[0];
		if(clicktimer) return false;
		var clickEvent = document.createEvent ('MouseEvents');
		clickEvent.initEvent ('click', true, true);
		setTimeout(function(){
			try {
				ths.dispatchEvent (clickEvent);
			} catch(e) {
				self.location.reload();
			}
		}, rand(cfg.timer1, cfg.timer2));
		clicktimer = true;
		return false;
	} else return false;
};

unsafeWindow.$ = jQuery;
unsafeWindow.hastxt = hastxt;

function attack() {
	// сейчас идёт бой
	var cards = [];
	$(".w3card").each(function(i){
		var txt = $(this).text().replace(/\s{2,}/g," ").trim().split(" ");
		cards[i] = [parseInt(txt[0],10), parseFloat(txt[2]), parseInt(txt[3]), this];
	});
	// ищем карты с рейтингом 1.5
	var idx15 = -1;
	var idx1  = -1;
	var idx05 = -1;
	var dmg = 0;
	for(i=0;i<3;i++) if(cards[i][1] == 1.5) {
		// ищем пару с максимальным уроном
		if(idx15 == -1) idx15 = i;
		else {
			dmg = cards[i][2] - cards[i][0];
			if(dmg > (cards[idx15][2] - cards[idx15][0])) idx15 = i;
		}
	}
	if(idx15 >= 0) {
		console.log('Максимальный урон, наносимый при рейтинге 1.5 будет у пары №'+(idx15+1)+': '+(cards[idx15][2]-cards[idx15][0]));
		return cl($(cards[idx15][3]).find("a:eq(1)"));
	}
	// ищем карты с рейтингом 1
	if(idx15 == -1) {
		for(i=0;i<3;i++) if(cards[i][1] == 1) {
			// ищем пару с максимальным уроном
			if(idx1 == -1) idx1 = i;
			else {
				dmg = cards[i][2] - cards[i][0];
				if(dmg > (cards[idx1][2] - cards[idx1][0])) idx1 = i;
			}
		}
		if(idx1 >= 0) {
			console.log('Максимальный урон, наносимый при рейтинге 1 будет у пары №'+(idx1+1)+': '+(cards[idx1][2]-cards[idx1][0]));
			return cl($(cards[idx1][3]).find("a:eq(1)"));
		}
		// ищем карты с рейтинго 0.5 с наименьшим уроном по игроку
		if(idx1 == -1) {
			for(i=0;i<3;i++) {
				// ищем пару с максимальным уроном
				if(idx05 == -1) idx05 = i;
				else {
					dmg = cards[i][2] - cards[i][0];
					if(dmg > (cards[idx05][2] - cards[idx05][0])) idx05 = i;
				}
			}
		}
		if(idx05 >= 0) {
			console.log('Максимальный урон, наносимый при рейтинге 0.5 будет у пары №'+(idx05+1)+': '+(cards[idx05][2]-cards[idx05][0]));
			return cl($(cards[idx05][3]).find("a:eq(1)"));
		}
	}
}

function setvar(name, val) {
	options[name] = val;
	GM_setValue("options", options);
}

function attack2() {
	var cards = [];
	var maxcard = null;
	var maxdmg = null;
	var was15 = false;
	for(i=0;i<3;i++) {
		cards[i] = getdmg(i);
		if(!cards[i]) continue;
		if(maxdmg === null || maxdmg < cards[i].dmg) {
			maxcard = cards[i];
			maxdmg = cards[i].dmg;
			if(cards[i].multi > 1) was15 = true;
		}
	}
	var enemys = /\d+/.exec($(".cntr.small:text(враги:)").text());
	var maxhops = parseInt(enemys[0], 10);
	//cntr small c_ld_red mt2 mb2
	console.log(cards);
	//return;
	if(maxcard === null) {
		setvar("hops", 0);
		console.log("Нет карт - обновляемся через 2 секунды");
		setTimeout(function(){ $("a.btn:text(обновить)").cl(); }, rand(100,250));
		return false;
	}
	if((maxdmg > 0 && was15) || (options.hops <= maxhops && was15)) {
		console.log("Были карты с рейтингом 1.5 - кликаем по ним (ней)");
		setvar("hops", 0);
		return maxcard.link.cl();
	} else {
		if(empty(options.hops)) options.hops = 0;
		// проверяем хопы - ещё моно переключиться
		if(options.hops <= maxhops) {
			console.log("Хопы ещё есть");
			if($("a:text(сменить):notext(карты)").length) {
				options.hops += 1;
				console.log("Меняем противника (пока есть на кого)");
				return $("a:text(сменить):notext(карты)").cl({timer1:100,timer2:250});
			} else {
				console.log("Нельзя менять противника - кнопка не активна. Кликаем по карте с максимальным дамагом");
				setvar("hops", 0);
				return maxcard.link.cl();
			}
		// всё, кликаем на той где есть
		} else {
			console.log("Хопы кончились (перебрали всех противников) - кликаем прям тут");
			setvar("hops", 0);
			return maxcard.link.cl();
		}
	}
}

unsafeWindow.getdmg = this.getdmg = function(idx) {
	if(empty(idx)) idx = 0;
	if(!$(".w3card").length || !$(".w3card:eq("+idx+")").length) return false;
	var pair = $(".w3card:eq("+idx+")");
	if(pair.text().replace(/\s{2,}/g,' ').indexOf("с") > -1) return false;
	var res = {mdmg: 0, multi: 0, hdmg: 0, mcard: 0, hcard: 0, pair: pair, link: pair.find("a:has(.sw):eq(1)"), dmg: 0};
	var nums = pair.text().replace("x","").replace(/\s{2,}/g,' ').trim().split(" ");
	res.mcard = res.mdmg = parseInt(nums[2], 10);
	res.hcard = res.hdmg = parseInt(nums[0], 10);
	res.multi = parseFloat(nums[1]);
	if(res.multi > 1) {
		res.mdmg += Math.round(res.mdmg / 2);
		res.hdmg -= Math.round(res.hdmg / 2);
	} else if(res.multi < 1) {
		res.mdmg -= Math.round(res.mdmg / 2);
		res.hdmg += Math.round(res.hdmg / 2);
	}
	res.dmg = res.mdmg - res.hdmg;
	return res;
};

$(function(){
	// сначала добавляем кнопку
	$('[ в'+(options.scriptenabled ? '' : 'ы')+'кл ]').appendTo("body");
	if(!options.scriptenabled) return false;

	// действия для дуэлей
	if(/^\/duel\//.test(self.location.pathname)) {
		// идёт бой
		if($(".w3card").length) return attack();

		// бой окончен - предложение вступить в дуэль ещё раз
		if($(".cntr a:not(.orange):text(еще дуэль)").length) {
			console.log("Выбираем ещё дуэль");
			return cl($(".cntr a:not(.orange):text(еще дуэль)"));
		}
		// перерыв в дуэлях
		if(hastxt(".fttl", "перерыв в дуэлях")) {
			console.log("Дуэли закончились - возвращаемся на главную страницу");
			return cl($(".small[onclick]"));
		}
		// Новая дуэль
		if(hastxt(".cntr .be .lbl", "Новая дуэль")) {
			console.log("Новая дуэль");
			return cl($(".cntr .btn"));
		}
		// напасть
		if($(".cntr a:not(.grey):text(напасть)").length) {
			console.log("Нападаем на слабого противника");
			return cl($(".cntr a:not(.grey):text(напасть)"));
		}
		// смена противника - перезагрузка страницы
		else {
			console.log("Противник слишком сильный - ищем другого. Или просто обновляем страницу");
			return cl($(".cntr a:text(искать еще)"));
		}
	}

	// действия в корне
	if("/" == self.location.pathname) {
		// таймер на дуэли
		/*if($("#duels_restore_time").length) {
			var ar = $("#duels_restore_time").text().split(" ");
			var secs = 5;
			for(i = 0; i < ar.length; i += 2) {
				if(ar[i+1] == 'ч') secs += parseInt(ar[i], 10) * 3600;
				if(ar[i+1] == 'м') secs += parseInt(ar[i], 10) * 60;
				if(ar[i+1] == 'с') secs += parseInt(ar[i], 10);
				if(ar[i+1] == 'c') secs += parseInt(ar[i], 10);
			}
			console.log('Установлен таймер на '+secs+' секунд до начала дуэлей!');
			setTimeout(function(){ return cl($("#duels_restore_time").closest("a")); }, secs * 1000);
		}*/
		// дуэли активны
		if($(".bttn.duels:text(дуэли:)").length) return cl($(".bttn.duels"));
		else return $("a[href*='surv']:text(арена)").cl();
	}

	// действия на арене
	if(/^\/survival\//.test(self.location.pathname)) {
		if(options.arenas >= 20) return $(".small[onclick]").cl();
		// запись
		if($("a[href*='survival/join']:text(запис)").length) {
			if(empty(options.arenas)) options.arenas = 0;
			options.arenas += 1;
			GM_setValue("options", options);
			$("a[href*='survival/join']:text(запис)").cl();
		}
		if($(".c_fe:text(бой начнется через)").length) setTimeout(function(){ self.location.reload(); }, 3000);
		if($(".w3card").length) return attack2();
		if($(".end .txt:text(вы пали)").length) {
			setTimeout(function(){ $("a.btn:text(обновить)").cl(); }, 5000);
			return false;
		}
	}
});
<commit_msg>Не большие улучшения<commit_after>// ==UserScript==
// @name         Повелители стихий. Кликер
// @namespace    https://ok.elem.mobi/
// @version      1.0b
// @description  Проводит дуэли (пока что)
// @author       GoodVin
// @match        *://*.elem.mobi/*
// @match        *://elem.mobi/*
// @require      http://code.jquery.com/jquery-3.2.1.slim.min.js
// @require      https://github.com/wisegoodvin/mobclickers/raw/master/shared_functions.js
// @downloadURL  https://github.com/wisegoodvin/mobclickers/raw/master/mobelem_clicker.user.js
// @updateURL    https://github.com/wisegoodvin/mobclickers/raw/master/mobelem_clicker.user.js
// @icon         https://elem.mobi/img/favicon.ico
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==
jQuery.fn.cl = function( options ) {
	var cfg = $.extend({
		timer1 : 500,
		timer2 : 750
	}, options );
	if(this.length) {
		var ths = this[0];
		if(clicktimer) return false;
		var clickEvent = document.createEvent ('MouseEvents');
		clickEvent.initEvent ('click', true, true);
		setTimeout(function(){
			try {
				ths.dispatchEvent (clickEvent);
			} catch(e) {
				self.location.reload();
			}
		}, rand(cfg.timer1, cfg.timer2));
		clicktimer = true;
		return false;
	} else return false;
};

unsafeWindow.$ = jQuery;
unsafeWindow.hastxt = hastxt;

function attack() {
	// сейчас идёт бой
	var cards = [];
	$(".w3card").each(function(i){
		var txt = $(this).text().replace(/\s{2,}/g," ").trim().split(" ");
		cards[i] = [parseInt(txt[0],10), parseFloat(txt[2]), parseInt(txt[3]), this];
	});
	// ищем карты с рейтингом 1.5
	var idx15 = -1;
	var idx1  = -1;
	var idx05 = -1;
	var dmg = 0;
	for(i=0;i<3;i++) if(cards[i][1] == 1.5) {
		// ищем пару с максимальным уроном
		if(idx15 == -1) idx15 = i;
		else {
			dmg = cards[i][2] - cards[i][0];
			if(dmg > (cards[idx15][2] - cards[idx15][0])) idx15 = i;
		}
	}
	if(idx15 >= 0) {
		console.log('Максимальный урон, наносимый при рейтинге 1.5 будет у пары №'+(idx15+1)+': '+(cards[idx15][2]-cards[idx15][0]));
		return cl($(cards[idx15][3]).find("a:eq(1)"));
	}
	// ищем карты с рейтингом 1
	if(idx15 == -1) {
		for(i=0;i<3;i++) if(cards[i][1] == 1) {
			// ищем пару с максимальным уроном
			if(idx1 == -1) idx1 = i;
			else {
				dmg = cards[i][2] - cards[i][0];
				if(dmg > (cards[idx1][2] - cards[idx1][0])) idx1 = i;
			}
		}
		if(idx1 >= 0) {
			console.log('Максимальный урон, наносимый при рейтинге 1 будет у пары №'+(idx1+1)+': '+(cards[idx1][2]-cards[idx1][0]));
			return cl($(cards[idx1][3]).find("a:eq(1)"));
		}
		// ищем карты с рейтинго 0.5 с наименьшим уроном по игроку
		if(idx1 == -1) {
			for(i=0;i<3;i++) {
				// ищем пару с максимальным уроном
				if(idx05 == -1) idx05 = i;
				else {
					dmg = cards[i][2] - cards[i][0];
					if(dmg > (cards[idx05][2] - cards[idx05][0])) idx05 = i;
				}
			}
		}
		if(idx05 >= 0) {
			console.log('Максимальный урон, наносимый при рейтинге 0.5 будет у пары №'+(idx05+1)+': '+(cards[idx05][2]-cards[idx05][0]));
			return cl($(cards[idx05][3]).find("a:eq(1)"));
		}
	}
}

function setvar(name, val) {
	options[name] = val;
	GM_setValue("options", options);
}

function attack2() {
	var cards = [];
	var maxcard = null;
	var maxdmg = null;
	var was15 = false;
	for(i=0;i<3;i++) {
		cards[i] = getdmg(i);
		if(!cards[i]) continue;
		if(maxdmg === null || maxdmg < cards[i].dmg) {
			maxcard = cards[i];
			maxdmg = cards[i].dmg;
			if(cards[i].multi > 1) was15 = true;
		}
	}
	var enemys = /\d+/.exec($(".cntr.small:text(враги:)").text());
	var maxhops = parseInt(enemys[0], 10);

	if(maxcard === null) {
		setvar("hops", 0);
		console.log("Нет карт - обновляемся через 2 секунды");
		setTimeout(function(){ $("a.btn:text(обновить)").cl(); }, 2000);
		return false;
	}
	if((maxdmg > 0 && was15) || (options.hops <= maxhops && was15)) {
		console.log("Были карты с рейтингом 1.5 - кликаем по ним (ней)");
		setvar("hops", 0);
		return maxcard.link.cl();
	} else {
		if(empty(options.hops)) options.hops = 0;
        console.log(options.hops,maxhops);
		// проверяем хопы - ещё моно переключиться
		if(options.hops <= maxhops) {
			console.log("Хопы ещё есть");
			if($("a:text(сменить):notext(карты)").length) {
                setvar("hops", options.hops+1);
				console.log("Меняем противника (пока есть на кого)");
				return $("a:text(сменить):notext(карты)").cl({timer1:100,timer2:250});
			} else {
				console.log("Нельзя менять противника - кнопка не активна. Кликаем по карте с максимальным дамагом");
				setvar("hops", 0);
				return maxcard.link.cl({timer1:3000,timer2:3000});
			}
		// всё, кликаем на той где есть
		} else {
			console.log("Хопы кончились (перебрали всех противников) - кликаем прям тут");
			setvar("hops", 0);
			return maxcard.link.cl();
		}
	}
}

unsafeWindow.getdmg = this.getdmg = function(idx) {
	if(empty(idx)) idx = 0;
	if(!$(".w3card").length || !$(".w3card:eq("+idx+")").length) return false;
	var pair = $(".w3card:eq("+idx+")");
	if(pair.text().replace(/\s{2,}/g,' ').indexOf("с") > -1) return false;
	var res = {mdmg: 0, multi: 0, hdmg: 0, mcard: 0, hcard: 0, pair: pair, link: pair.find("a:has(.sw):eq(1)"), dmg: 0};
	var nums = pair.text().replace("x","").replace(/\s{2,}/g,' ').trim().split(" ");
	res.mcard = res.mdmg = parseInt(nums[2], 10);
	res.hcard = res.hdmg = parseInt(nums[0], 10);
	res.multi = parseFloat(nums[1]);
	if(res.multi > 1) {
		res.mdmg += Math.round(res.mdmg / 2);
		res.hdmg -= Math.round(res.hdmg / 2);
	} else if(res.multi < 1) {
		res.mdmg -= Math.round(res.mdmg / 2);
		res.hdmg += Math.round(res.hdmg / 2);
	}
	res.dmg = res.mdmg - res.hdmg;
	return res;
};

$(function(){
	// сначала добавляем кнопки
	$('[ в'+(options.scriptenabled ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ арена: в'+(!options.noarena ? '' : 'ы')+'кл ]').appendTo("body");
	if(!options.scriptenabled) return false;

	// действия для дуэлей
	if(/^\/duel\//.test(self.location.pathname)) {
		// идёт бой
		if($(".w3card").length) return attack();

		// бой окончен - предложение вступить в дуэль ещё раз
		if($(".cntr a:not(.orange):text(еще дуэль)").length) {
			console.log("Выбираем ещё дуэль");
			return cl($(".cntr a:not(.orange):text(еще дуэль)"));
		}
		// перерыв в дуэлях
		if(hastxt(".fttl", "перерыв в дуэлях")) {
			console.log("Дуэли закончились - возвращаемся на главную страницу");
			return cl($(".small[onclick]"));
		}
		// Новая дуэль
		if(hastxt(".cntr .be .lbl", "Новая дуэль")) {
			console.log("Новая дуэль");
			return cl($(".cntr .btn"));
		}
		// напасть
		if($(".cntr a:not(.grey):text(напасть)").length) {
			console.log("Нападаем на слабого противника");
			return cl($(".cntr a:not(.grey):text(напасть)"));
		}
		// смена противника - перезагрузка страницы
		else {
			console.log("Противник слишком сильный - ищем другого. Или просто обновляем страницу");
			return cl($(".cntr a:text(искать еще)"));
		}
	}

	// действия в корне
	if("/" == self.location.pathname) {
		// дуэли активны
		if($(".bttn.duels:text(дуэли:)").length) return cl($(".bttn.duels"));
		else if(!options.noarena) return $("a[href*='surv']:text(арена)").cl();
		else {
			// таймер на дуэли
			if($("#duels_restore_time").length) {
				var ar = $("#duels_restore_time").text().split(" ");
				var secs = 5;
				for(i = 0; i < ar.length; i += 2) {
					if(ar[i+1] == 'ч') secs += parseInt(ar[i], 10) * 3600;
					if(ar[i+1] == 'м') secs += parseInt(ar[i], 10) * 60;
					if(ar[i+1] == 'с') secs += parseInt(ar[i], 10);
					if(ar[i+1] == 'c') secs += parseInt(ar[i], 10);
				}
				console.log('Установлен таймер на '+secs+' секунд до начала дуэлей!');
				setTimeout(function(){ return cl($("#duels_restore_time").closest("a")); }, secs * 1000);
			} else {
				// прочие действия на главном экране
			}
		}
	}

	// действия на арене
	if(/^\/survival\//.test(self.location.pathname) && !options.noarena) {
		if(options.arenas >= 20) return $(".small[onclick]").cl();
		// запись
		if($("a[href*='survival/join']:text(запис)").length) {
            console.log("Записываемся в очередь на бой");
			if(empty(options.arenas)) options.arenas = 0;
			options.arenas += 1;
			GM_setValue("options", options);
			$("a[href*='survival/join']:text(запис)").cl();
		}
		if($(".c_fe:text(бой начнется через)").length) {
            console.log("Стоим в очереди на начало боя");
            setTimeout(function(){ self.location.reload(); }, 3000);
        }
		if($(".w3card").length) return attack2();
		if($(".end .txt:text(вы пали)").length) {
            console.log("Сдох! Ждём конца боя");
			setTimeout(function(){ $("a.btn:text(обновить)").cl(); }, 5000);
			return false;
		}
		if($(".msg.red:text(бой не существует)").length) $("a[href*='surv']:text(арен)").cl();
	}
});
<|endoftext|>


<commit_before>"use strict";
var debug=require('debug')('mocha:audioreporter'),
    Singer = require('singer'),
    sounds=require('mario-sounds');

module.exports = mocha_audio_reporter;

function mocha_audio_reporter(runner, options) {
  var failures=0,
      player, stopTest=false;

  if(!(this instanceof mocha_audio_reporter)) {
    return new mocha_audio_reporter(runner, options);
  }

  runner.on('start', function onStart(test) {
    function onDonePlaying(err, player) {
      debug('playend!');
      currentSong=player.play(onDonePlaying);
    }
    // start playing music
    singer = new Singer();
    // play now and callback when playend
    var currentSong=singer.sing();
    currentSong.on('playing', function onPlaying() {
      debug("playing");
    })
    currentSong.on('done', onDonePlaying);
    currentSong.on('stopped', function onStopped() {
      debug("stopped");
    });
  });

  runner.on('pass', function onTestPass(test){
    // play a happy tone
    singer = new Player();
    singer.sing(sounds["smb_coin"]);
  });

  runner.on('fail', function onTestFail(test, err){
    failures++;
    // play a sad tone
    singer = new Player();
    singer.sing(sounds["smb_mariodie"]);
  });

  runner.on('end', function onTestEnd(){
    debug("runner.end");
    // stop playing music
    singer.stop();
    singer= new Singer();
    if( failures ) {
      singer.sing(sounds["smb_gameover"]);
    } else {
      singer.sing(sounds["smb_stage_clear"]);
    }
  });
}<commit_msg>refactored for singer events and made songs for each event optional<commit_after>"use strict";
var debug=require('debug')('mocha:audioreporter'),
    Singer = require('singer'),
    sounds=require('mario-sounds');

module.exports = mocha_audio_reporter;

function mocha_audio_reporter(runner, options) {
  var failures=0,
      self=this, stopTest=false;

  if(!(this instanceof mocha_audio_reporter)) {
    return new mocha_audio_reporter(runner, options);
  }
  debug("%j", options);

  self.singer = new Singer();

  runner.on('start', function onStart(test) {
    // start playing music
    self.singer.sing( options.onStart || "" );
    self.singer.on('singing', function() {
      debug("singing still");
    });
    self.singer.on('end', function onEnd() {
      debug("done singing");
    });
  });

  runner.on('pass', function onTestPass(test){
    // play a happy tone
    if( options.onPass ) {
      self.singer.sing( options.onPass );
    }
  });

  runner.on('fail', function onTestFail(test, err){
    failures++;
    // play a sad tone
    if( options.onFail ) {
      self.singer.sing( options.onFail );
    }
  });

  runner.on('end', function onTestEnd(){
    debug("runner.end");
    // stop playing music
    self.singer.stop();
    if( failures && options.onSuiteFail ) {
      self.singer.sing( options.onSuiteFail );
    } else  if( options.onSuitePass ) {
      self.singer.sing( options.onSuitePass );
    }
  });

}<|endoftext|>


<commit_before>const responses = {
  ['/oauth2/v1/tokens'](data) {
    const params = data.params || {};
    const headers = data.headers || {};

    // Success
    // -------
    if (params &&
        (params.username === 'username' ||
        params.password === 'password') &&
        params.grant_type === 'password' &&
        headers['Authorization'] === 'Basic Y2xpZW50SWQ6Y2xpZW50U2VjcmV0' &&
        headers['Content-Type'] === 'application/x-www-form-urlencoded') {

      return {
        body: {
          access_token: 'eyJhbGciOiJSUzjFfb_FkJFoIdA'
        }
      };
    }

    // Errors
    // -----
    if (headers['Authorization'] !== 'Basic Y2xpZW50SWQ6Y2xpZW50U2VjcmV0') {
      return {
        body: {
          error: 'invalid_client',
          statusCode: 400,
          error_description: 'Missing or incomplete Authorisation header'
        }
      }
    }

    if (headers['Content-Type'] !== 'application/x-www-form-urlencoded' ||
      params.grant_type !== 'password') {
        return {
          body: {
            error: 'invalid_request',
            statusCode: 400,
            error_description: 'Missing grant type'
          }
        }
    }

    if (params.username !== 'username' ||
      params.password !== 'password') {
        return {
          body: {
            error: 'invalid_grant',
            statusCode: 400,
            error_description: 'Invalid resource owner credentials'
          }
        }
    }
  },

  ['/sites'](data) {
    if (data && data.id) {
      return {
        body: {
          id: 'MzIxMzM',
          name: 'www.test.com',
          lastIterationPublishDate: '2017-02-13T10:32:28.0000000Z',
          lastIterationPublishHash: 'LgK4w_RWUHeClDakSoE7tvjZk_M'
        }
      }
    }

    return {
      body: {
        items: [{
          id: 'MzIxMzM',
          name: 'www.test.com'
        }, {
          id: 'MzIxMzI=',
          name: 'm.test.com'
        }]
      }
    };
  },

  ['/sites/scripts']() {
    return {
      body: {
        items: [
          {
            id: "NDMyNDMy",
            name: "Script 1",
            description: "My first script",
            apiVersion: "CD API v.1.8",
            content: "var pageViews = visitor.getData( 'Page viewed' );\nconsole.log( 'Number of page views: ' + pageViews);"
          },
          {
            id: "NDMyNDQ0",
            name: "Script 2",
            apiVersion: "mmcore",
            description: "My second script",
            content: "console.log( 'test' );"
          }
        ]
      }
    }
  },

  ['/sites/actions']() {
    return {
      body: {
        items: [
          {
            'id': 'NDMyNDMy',
            'name': 'Action1',
            'description': 'My first action',
            'type': 'Click_through'
          },
          {
            'id': 'NDMyNDQ0',
            'name': 'Action2',
            'description': 'My second action',
            'type': 'Page_Impressions'
          }
        ]
      }
    }
  }
};

module.exports = [{
  /**
   * regular expression of auth URL
   */
  pattern: '(.*)',

  /**
   * returns the data
   *
   * @param match array Result of the resolution of the regular expression
   * @param params object sent by 'send' function
   * @param headers object set by 'set' function
   * @param context object the context of running the fixtures function
   */
  fixtures: function (match, params, headers, context) {
    if (match[1] === 'https://api-auth-eu.maxymiser.com/oauth2/v1/tokens') {
      return {
        params: params,
        headers: headers
      }
    }
  },

  /**
   * returns the result of the GET request
   *
   * @param match array Result of the resolution of the regular expression
   * @param data  mixed Data returns by `fixtures` attribute
   */
  get: function (match, data) {
    const path = (match[1] || '').replace('https://api-eu.maxymiser.com/v1/', '');

    if (path === 'sites') {
      return responses['/sites']();
    }

    if (path === 'sites/MzIxMzM') {
      return responses['/sites']({id: 'MzIxMzM'});
    }

    if (path === 'sites/MzIxMzM/sandbox/scripts/') {
      return responses['/sites/scripts']();
    }

    if (path === 'sites/MzIxMzM/sandbox/actions') {
      return responses['/sites/actions']();
    }
  },

  /**
   * returns the result of the POST request
   *
   * @param match array Result of the resolution of the regular expression
   * @param data  mixed Data returns by `fixtures` attribute
   */
  post: function (match, data) {
    const path = match[1] || '';

    switch (path) {
      case 'https://api-auth-eu.maxymiser.com/oauth2/v1/tokens':
        return responses['/oauth2/v1/tokens'](data);
    }
  }
}];

<commit_msg>~ mock<commit_after>const responses = {
  ['/oauth2/v1/tokens'](data) {
    const params = data.params || {};
    const headers = data.headers || {};

    // Success
    // -------
    if (params &&
        (params.username === 'username' ||
        params.password === 'password') &&
        params.grant_type === 'password' &&
        headers['Authorization'] === 'Basic Y2xpZW50SWQ6Y2xpZW50U2VjcmV0' &&
        headers['Content-Type'] === 'application/x-www-form-urlencoded') {

      return {
        body: {
          access_token: 'eyJhbGciOiJSUzjFfb_FkJFoIdA'
        }
      };
    }

    // Errors
    // -----
    if (headers['Authorization'] !== 'Basic Y2xpZW50SWQ6Y2xpZW50U2VjcmV0') {
      return {
        body: {
          error: 'invalid_client',
          statusCode: 400,
          error_description: 'Missing or incomplete Authorisation header'
        }
      }
    }

    if (headers['Content-Type'] !== 'application/x-www-form-urlencoded' ||
      params.grant_type !== 'password') {
        return {
          body: {
            error: 'invalid_request',
            statusCode: 400,
            error_description: 'Missing grant type'
          }
        }
    }

    if (params.username !== 'username' ||
      params.password !== 'password') {
        return {
          body: {
            error: 'invalid_grant',
            statusCode: 400,
            error_description: 'Invalid resource owner credentials'
          }
        }
    }
  },

  ['/sites'](data) {
    if (data && data.id) {
      return {
        body: {
          id: 'MzIxMzM',
          name: 'www.test.com',
          lastIterationPublishDate: '2017-02-13T10:32:28.0000000Z',
          lastIterationPublishHash: 'LgK4w_RWUHeClDakSoE7tvjZk_M'
        }
      }
    }

    return {
      body: {
        items: [{
          id: 'MzIxMzM',
          name: 'www.test.com'
        }, {
          id: 'MzIxMzI=',
          name: 'm.test.com'
        }]
      }
    };
  },

  ['/sites/scripts']() {
    return {
      body: {
        items: [
          {
            id: "NDMyNDMy",
            name: "Script 1",
            description: "My first script",
            apiVersion: "CD API v.1.8",
            content: "var pageViews = visitor.getData( 'Page viewed' );\nconsole.log( 'Number of page views: ' + pageViews);"
          },
          {
            id: "NDMyNDQ0",
            name: "Script 2",
            apiVersion: "mmcore",
            description: "My second script",
            content: "console.log( 'test' );"
          }
        ]
      }
    }
  },

  ['/sites/actions']() {
    return {
      body: {
        items: [
          {
            'id': 'NDMyNDMy',
            'name': 'Action1',
            'description': 'My first action',
            'type': 'Click_through'
          },
          {
            'id': 'NDMyNDQ0',
            'name': 'Action2',
            'description': 'My second action',
            'type': 'Page_Impressions'
          },
          {
            'id': 'NDQ0NDMy',
            'name': 'Action3',
            'description': 'My third action',
            'type': 'Sales_Amount',
            'currency': 'GBP',
            'multiplier': 1
          }
        ]
      }
    }
  }
};

module.exports = [{
  /**
   * regular expression of auth URL
   */
  pattern: '(.*)',

  /**
   * returns the data
   *
   * @param match array Result of the resolution of the regular expression
   * @param params object sent by 'send' function
   * @param headers object set by 'set' function
   * @param context object the context of running the fixtures function
   */
  fixtures: function (match, params, headers, context) {
    if (match[1] === 'https://api-auth-eu.maxymiser.com/oauth2/v1/tokens') {
      return {
        params: params,
        headers: headers
      }
    }
  },

  /**
   * returns the result of the GET request
   *
   * @param match array Result of the resolution of the regular expression
   * @param data  mixed Data returns by `fixtures` attribute
   */
  get: function (match, data) {
    const path = (match[1] || '').replace('https://api-eu.maxymiser.com/v1/', '');

    if (path === 'sites') {
      return responses['/sites']();
    }

    if (path === 'sites/MzIxMzM') {
      return responses['/sites']({id: 'MzIxMzM'});
    }

    if (path === 'sites/MzIxMzM/sandbox/scripts/') {
      return responses['/sites/scripts']();
    }

    if (path === 'sites/MzIxMzM/sandbox/actions') {
      return responses['/sites/actions']();
    }
  },

  /**
   * returns the result of the POST request
   *
   * @param match array Result of the resolution of the regular expression
   * @param data  mixed Data returns by `fixtures` attribute
   */
  post: function (match, data) {
    const path = match[1] || '';

    switch (path) {
      case 'https://api-auth-eu.maxymiser.com/oauth2/v1/tokens':
        return responses['/oauth2/v1/tokens'](data);
    }
  }
}];

<|endoftext|>


<commit_before>'use strict';

module.exports = {
    entry: [
        './demos/index'
    ],
    resolve: {
        extensions: ['', '.js', '.jsx', '.md', '.css', '.png', '.jpg'],
        modulesDirectories: ['node_modules', 'utils'],
    },
};

module.exports.loaders = [
    {
        test: /\.css$/,
        loaders: ['style', 'css'],
    },
    {
        test: /\.md$/,
        loader: 'html!../loaders/markdown',
    },
    {
        test: /\.png$/,
        loader: 'url-loader?limit=100000&mimetype=image/png',
    },
    {
        test: /\.jpg$/,
        loader: 'file-loader',
    },
];
<commit_msg>Tidy up configuration<commit_after>'use strict';

module.exports = {
    entry: [
        './demos/index'
    ],
    resolve: {
        extensions: ['', '.js', '.jsx', '.md', '.css', '.png', '.jpg'],
    },
};

module.exports.loaders = [
    {
        test: /\.css$/,
        loaders: ['style', 'css'],
    },
    {
        test: /\.md$/,
        loader: 'html!../loaders/markdown',
    },
    {
        test: /\.png$/,
        loader: 'url-loader?limit=100000&mimetype=image/png',
    },
    {
        test: /\.jpg$/,
        loader: 'file-loader',
    },
];
<|endoftext|>


<commit_before>/**
 * @author: @AngularClass
 */

const webpack = require('webpack');
const helpers = require('./helpers');

/*
 * Webpack Plugins
 */
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

/*
 * Webpack Constants
 */
const METADATA = {
  title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
  baseUrl: '/'
};

/*
 * Webpack configuration
 *
 * See: http://webpack.github.io/docs/configuration.html#cli
 */
module.exports = {

  /*
   * Static metadata for index.html
   *
   * See: (custom attribute)
   */
  metadata: METADATA,

  /*
   * Cache generated modules and chunks to improve performance for multiple incremental builds.
   * This is enabled by default in watch mode.
   * You can pass false to disable it.
   *
   * See: http://webpack.github.io/docs/configuration.html#cache
   * cache: false,
   *
   * The entry point for the bundle
   * Our Angular.js app
   *
   * See: http://webpack.github.io/docs/configuration.html#entry
   */
  entry: {

    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'main': './src/main.browser.ts'

  },

  /*
   * Options affecting the resolving of modules.
   *
   * See: http://webpack.github.io/docs/configuration.html#resolve
   */
  resolve: {

    /*
     * An array of extensions that should be used to resolve modules.
     *
     * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
     */
    extensions: ['', '.ts', '.js'],

    // Make sure root is src
    root: helpers.root('src'),

    // remove other default values
    modulesDirectories: ['node_modules'],

    alias: {
      'angular2/core': helpers.root('node_modules/@angular/core/index.js'),
      'angular2/testing': helpers.root('node_modules/@angular/core/testing.js'),
      '@angular/testing': helpers.root('node_modules/@angular/core/testing.js'),
      'angular2/platform/browser': helpers.root('node_modules/@angular/platform-browser/index.js'),
      'angular2/router': helpers.root('node_modules/@angular/router-deprecated/index.js'),
      'angular2/http': helpers.root('node_modules/@angular/http/index.js'),
      'angular2/http/testing': helpers.root('node_modules/@angular/http/testing.js')
    },

  },

  /*
   * Options affecting the normal modules.
   *
   * See: http://webpack.github.io/docs/configuration.html#module
   */
  module: {

    /*
     * An array of applied pre and post loaders.
     *
     * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
     */
    preLoaders: [

      /*
       * Tslint loader support for *.ts files
       *
       * See: https://github.com/wbuchwalter/tslint-loader
       */
       // { test: /\.ts$/, loader: 'tslint-loader', exclude: [ helpers.root('node_modules') ] },

      /*
       * Source map loader support for *.js files
       * Extracts SourceMaps for source files that as added as sourceMappingURL comment.
       *
       * See: https://github.com/webpack/source-map-loader
       */
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [
          // these packages have problems with their sourcemaps
          helpers.root('node_modules/rxjs'),
          helpers.root('node_modules/@angular2-material'),
          helpers.root('node_modules/@angular'),
        ]
      }

    ],

    /*
     * An array of automatically applied loaders.
     *
     * IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
     * This means they are not resolved relative to the configuration file.
     *
     * See: http://webpack.github.io/docs/configuration.html#module-loaders
     */
    loaders: [

      /*
       * Typescript loader support for .ts and Angular 2 async routes via .async.ts
       *
       * See: https://github.com/s-panferov/awesome-typescript-loader
       */
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader',
        exclude: [/\.(spec|e2e)\.ts$/]
      },

      /*
       * Json loader support for *.json files.
       *
       * See: https://github.com/webpack/json-loader
       */
      {
        test: /\.json$/,
        loader: 'json-loader'
      },

      /*
       * Raw loader support for *.css files
       * Returns file content as string
       *
       * See: https://github.com/webpack/raw-loader
       */
      {
        test: /\.css$/,
        loader: 'raw-loader'
      },

      /* Raw loader support for *.html
       * Returns file content as string
       *
       * See: https://github.com/webpack/raw-loader
       */
      {
        test: /\.html$/,
        loader: 'raw-loader',
        exclude: [helpers.root('src/index.html')]
      }

    ]

  },

  /*
   * Add additional plugins to the compiler.
   *
   * See: http://webpack.github.io/docs/configuration.html#plugins
   */
  plugins: [

    /*
     * Plugin: ForkCheckerPlugin
     * Description: Do type checking in a separate process, so webpack don't need to wait.
     *
     * See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
     */
    new ForkCheckerPlugin(),

    /*
     * Plugin: OccurenceOrderPlugin
     * Description: Varies the distribution of the ids to get the smallest id length
     * for often used ids.
     *
     * See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
     * See: https://github.com/webpack/docs/wiki/optimization#minimize
     */
    new webpack.optimize.OccurenceOrderPlugin(true),

    /*
     * Plugin: CommonsChunkPlugin
     * Description: Shares common code between the pages.
     * It identifies common modules and put them into a commons chunk.
     *
     * See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
     * See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
     */
    new webpack.optimize.CommonsChunkPlugin({
      name: helpers.reverse(['polyfills', 'vendor'])
    }),

    /*
     * Plugin: CopyWebpackPlugin
     * Description: Copy files and directories in webpack.
     *
     * Copies project static assets.
     *
     * See: https://www.npmjs.com/package/copy-webpack-plugin
     */
    new CopyWebpackPlugin([{
      from: 'src/assets',
      to: 'assets'
    }]),

    /*
     * Plugin: HtmlWebpackPlugin
     * Description: Simplifies creation of HTML files to serve your webpack bundles.
     * This is especially useful for webpack bundles that include a hash in the filename
     * which changes every compilation.
     *
     * See: https://github.com/ampedandwired/html-webpack-plugin
     */
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      chunksSortMode: helpers.packageSort(['polyfills', 'vendor', 'main'])
    })

  ],

  /*
   * Include polyfills or mocks for various node stuff
   * Description: Node configuration
   *
   * See: https://webpack.github.io/docs/configuration.html#node
   */
  node: {
    global: 'window',
    crypto: 'empty',
    module: false,
    clearImmediate: false,
    setImmediate: false
  }

};
<commit_msg>chore(webpack): provide workaround for CopyWebpackPlugin<commit_after>/**
 * @author: @AngularClass
 */

const webpack = require('webpack');
const helpers = require('./helpers');

/*
 * Webpack Plugins
 */
// problem with copy-webpack-plugin
const CopyWebpackPlugin = (CopyWebpackPlugin = require('copy-webpack-plugin'), CopyWebpackPlugin.default || CopyWebpackPlugin);
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

/*
 * Webpack Constants
 */
const METADATA = {
  title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
  baseUrl: '/'
};

/*
 * Webpack configuration
 *
 * See: http://webpack.github.io/docs/configuration.html#cli
 */
module.exports = {

  /*
   * Static metadata for index.html
   *
   * See: (custom attribute)
   */
  metadata: METADATA,

  /*
   * Cache generated modules and chunks to improve performance for multiple incremental builds.
   * This is enabled by default in watch mode.
   * You can pass false to disable it.
   *
   * See: http://webpack.github.io/docs/configuration.html#cache
   * cache: false,
   *
   * The entry point for the bundle
   * Our Angular.js app
   *
   * See: http://webpack.github.io/docs/configuration.html#entry
   */
  entry: {

    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'main': './src/main.browser.ts'

  },

  /*
   * Options affecting the resolving of modules.
   *
   * See: http://webpack.github.io/docs/configuration.html#resolve
   */
  resolve: {

    /*
     * An array of extensions that should be used to resolve modules.
     *
     * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
     */
    extensions: ['', '.ts', '.js'],

    // Make sure root is src
    root: helpers.root('src'),

    // remove other default values
    modulesDirectories: ['node_modules'],

    alias: {
      'angular2/core': helpers.root('node_modules/@angular/core/index.js'),
      'angular2/testing': helpers.root('node_modules/@angular/core/testing.js'),
      '@angular/testing': helpers.root('node_modules/@angular/core/testing.js'),
      'angular2/platform/browser': helpers.root('node_modules/@angular/platform-browser/index.js'),
      'angular2/router': helpers.root('node_modules/@angular/router-deprecated/index.js'),
      'angular2/http': helpers.root('node_modules/@angular/http/index.js'),
      'angular2/http/testing': helpers.root('node_modules/@angular/http/testing.js')
    },

  },

  /*
   * Options affecting the normal modules.
   *
   * See: http://webpack.github.io/docs/configuration.html#module
   */
  module: {

    /*
     * An array of applied pre and post loaders.
     *
     * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
     */
    preLoaders: [

      /*
       * Tslint loader support for *.ts files
       *
       * See: https://github.com/wbuchwalter/tslint-loader
       */
       // { test: /\.ts$/, loader: 'tslint-loader', exclude: [ helpers.root('node_modules') ] },

      /*
       * Source map loader support for *.js files
       * Extracts SourceMaps for source files that as added as sourceMappingURL comment.
       *
       * See: https://github.com/webpack/source-map-loader
       */
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [
          // these packages have problems with their sourcemaps
          helpers.root('node_modules/rxjs'),
          helpers.root('node_modules/@angular2-material'),
          helpers.root('node_modules/@angular'),
        ]
      }

    ],

    /*
     * An array of automatically applied loaders.
     *
     * IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
     * This means they are not resolved relative to the configuration file.
     *
     * See: http://webpack.github.io/docs/configuration.html#module-loaders
     */
    loaders: [

      /*
       * Typescript loader support for .ts and Angular 2 async routes via .async.ts
       *
       * See: https://github.com/s-panferov/awesome-typescript-loader
       */
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader',
        exclude: [/\.(spec|e2e)\.ts$/]
      },

      /*
       * Json loader support for *.json files.
       *
       * See: https://github.com/webpack/json-loader
       */
      {
        test: /\.json$/,
        loader: 'json-loader'
      },

      /*
       * Raw loader support for *.css files
       * Returns file content as string
       *
       * See: https://github.com/webpack/raw-loader
       */
      {
        test: /\.css$/,
        loader: 'raw-loader'
      },

      /* Raw loader support for *.html
       * Returns file content as string
       *
       * See: https://github.com/webpack/raw-loader
       */
      {
        test: /\.html$/,
        loader: 'raw-loader',
        exclude: [helpers.root('src/index.html')]
      }

    ]

  },

  /*
   * Add additional plugins to the compiler.
   *
   * See: http://webpack.github.io/docs/configuration.html#plugins
   */
  plugins: [

    /*
     * Plugin: ForkCheckerPlugin
     * Description: Do type checking in a separate process, so webpack don't need to wait.
     *
     * See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
     */
    new ForkCheckerPlugin(),

    /*
     * Plugin: OccurenceOrderPlugin
     * Description: Varies the distribution of the ids to get the smallest id length
     * for often used ids.
     *
     * See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
     * See: https://github.com/webpack/docs/wiki/optimization#minimize
     */
    new webpack.optimize.OccurenceOrderPlugin(true),

    /*
     * Plugin: CommonsChunkPlugin
     * Description: Shares common code between the pages.
     * It identifies common modules and put them into a commons chunk.
     *
     * See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
     * See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
     */
    new webpack.optimize.CommonsChunkPlugin({
      name: helpers.reverse(['polyfills', 'vendor'])
    }),

    /*
     * Plugin: CopyWebpackPlugin
     * Description: Copy files and directories in webpack.
     *
     * Copies project static assets.
     *
     * See: https://www.npmjs.com/package/copy-webpack-plugin
     */
    new CopyWebpackPlugin([{
      from: 'src/assets',
      to: 'assets'
    }]),

    /*
     * Plugin: HtmlWebpackPlugin
     * Description: Simplifies creation of HTML files to serve your webpack bundles.
     * This is especially useful for webpack bundles that include a hash in the filename
     * which changes every compilation.
     *
     * See: https://github.com/ampedandwired/html-webpack-plugin
     */
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      chunksSortMode: helpers.packageSort(['polyfills', 'vendor', 'main'])
    })

  ],

  /*
   * Include polyfills or mocks for various node stuff
   * Description: Node configuration
   *
   * See: https://webpack.github.io/docs/configuration.html#node
   */
  node: {
    global: 'window',
    crypto: 'empty',
    module: false,
    clearImmediate: false,
    setImmediate: false
  }

};
<|endoftext|>