<commit_before>const React = require('react');
const PropTypes = require('prop-types');
const createClass = require('create-react-class');

const sizerStyle = {
	position: 'absolute',
	top: 0,
	left: 0,
	visibility: 'hidden',
	height: 0,
	overflow: 'scroll',
	whiteSpace: 'pre',
};

const id = '_' + Math.random().toString(36).substr(2, 9);
const AutosizeInput = createClass({
	propTypes: {
		className: PropTypes.string,               // className for the outer element
		defaultValue: PropTypes.any,               // default field value
		inputClassName: PropTypes.string,          // className for the input element
		inputStyle: PropTypes.object,              // css styles for the input element
		minWidth: PropTypes.oneOfType([            // minimum width for input element
			PropTypes.number,
			PropTypes.string,
		]),
		onAutosize: PropTypes.func,                // onAutosize handler: function(newWidth) {}
		onChange: PropTypes.func,                  // onChange handler: function(newValue) {}
		placeholder: PropTypes.string,             // placeholder text
		placeholderIsMinWidth: PropTypes.bool,     // don't collapse size to less than the placeholder
		style: PropTypes.object,                   // css styles for the outer element
		value: PropTypes.any,                      // field value
	},
	getDefaultProps () {
		return {
			minWidth: 1,
		};
	},
	getInitialState () {
		return {
			inputWidth: this.props.minWidth,
		};
	},
	componentDidMount () {
		this.mounted = true;
		this.copyInputStyles();
		this.updateInputWidth();
	},
	componentDidUpdate (prevProps, prevState) {
		if (prevState.inputWidth !== this.state.inputWidth) {
			if (typeof this.props.onAutosize === 'function') {
				this.props.onAutosize(this.state.inputWidth);
			}
		}
		this.updateInputWidth();
	},
	componentWillUnmount () {
		this.mounted = false;
	},
	inputRef (el) {
		this.input = el;
	},
	placeHolderSizerRef (el) {
		this.placeHolderSizer = el;
	},
	sizerRef (el) {
		this.sizer = el;
	},
	copyInputStyles () {
		if (!this.mounted || !window.getComputedStyle) {
			return;
		}
		const inputStyle = this.input && window.getComputedStyle(this.input);
		if (!inputStyle) {
			return;
		}
		const widthNode = this.sizer;
		widthNode.style.fontSize = inputStyle.fontSize;
		widthNode.style.fontFamily = inputStyle.fontFamily;
		widthNode.style.fontWeight = inputStyle.fontWeight;
		widthNode.style.fontStyle = inputStyle.fontStyle;
		widthNode.style.letterSpacing = inputStyle.letterSpacing;
		widthNode.style.textTransform = inputStyle.textTransform;
		if (this.props.placeholder) {
			const placeholderNode = this.placeHolderSizer;
			placeholderNode.style.fontSize = inputStyle.fontSize;
			placeholderNode.style.fontFamily = inputStyle.fontFamily;
			placeholderNode.style.fontWeight = inputStyle.fontWeight;
			placeholderNode.style.fontStyle = inputStyle.fontStyle;
			placeholderNode.style.letterSpacing = inputStyle.letterSpacing;
			placeholderNode.style.textTransform = inputStyle.textTransform;
		}
	},
	updateInputWidth () {
		if (!this.mounted || !this.sizer || typeof this.sizer.scrollWidth === 'undefined') {
			return;
		}
		let newInputWidth;
		if (this.props.placeholder && (!this.props.value || (this.props.value && this.props.placeholderIsMinWidth))) {
			newInputWidth = Math.max(this.sizer.scrollWidth, this.placeHolderSizer.scrollWidth) + 2;
		} else {
			newInputWidth = this.sizer.scrollWidth + 2;
		}
		if (newInputWidth < this.props.minWidth) {
			newInputWidth = this.props.minWidth;
		}
		if (newInputWidth !== this.state.inputWidth) {
			this.setState({
				inputWidth: newInputWidth,
			});
		}
	},
	getInput () {
		return this.input;
	},
	focus () {
		this.input.focus();
	},
	blur () {
		this.input.blur();
	},
	select () {
		this.input.select();
	},
	render () {
		const sizerValue = [this.props.defaultValue, this.props.value, ''].reduce(function (previousValue, currentValue) {
			if (previousValue !== null && previousValue !== undefined) {
				return previousValue;
			}
			return currentValue;
		});

		const wrapperStyle = this.props.style || {};
		if (!wrapperStyle.display) wrapperStyle.display = 'inline-block';
		const inputStyle = Object.assign({}, this.props.inputStyle);
		inputStyle.width = this.state.inputWidth + 'px';
		inputStyle.boxSizing = 'content-box';
		const inputProps = Object.assign({}, this.props);
		inputProps.className = this.props.inputClassName;
		inputProps.style = inputStyle;
		// ensure props meant for `AutosizeInput` don't end up on the `input`
		delete inputProps.inputClassName;
		delete inputProps.inputStyle;
		delete inputProps.minWidth;
		delete inputProps.onAutosize;
		delete inputProps.placeholderIsMinWidth;
		return (

				<input id={id} {...inputProps} ref={this.inputRef} />

{sizerValue}

				{this.props.placeholder
					?
{this.props.placeholder}

					: null
				}

		);
	},
});

module.exports = AutosizeInput;
<commit_msg>Clean up IE11 clear fix<commit_after>const React = require('react');
const PropTypes = require('prop-types');
const createClass = require('create-react-class');

const sizerStyle = {
	position: 'absolute',
	top: 0,
	left: 0,
	visibility: 'hidden',
	height: 0,
	overflow: 'scroll',
	whiteSpace: 'pre',
};

const AutosizeInput = createClass({
	propTypes: {
		className: PropTypes.string,               // className for the outer element
		defaultValue: PropTypes.any,               // default field value
		inputClassName: PropTypes.string,          // className for the input element
		inputStyle: PropTypes.object,              // css styles for the input element
		minWidth: PropTypes.oneOfType([            // minimum width for input element
			PropTypes.number,
			PropTypes.string,
		]),
		onAutosize: PropTypes.func,                // onAutosize handler: function(newWidth) {}
		onChange: PropTypes.func,                  // onChange handler: function(newValue) {}
		placeholder: PropTypes.string,             // placeholder text
		placeholderIsMinWidth: PropTypes.bool,     // don't collapse size to less than the placeholder
		style: PropTypes.object,                   // css styles for the outer element
		value: PropTypes.any,                      // field value
	},
	getDefaultProps () {
		return {
			minWidth: 1,
		};
	},
	getInitialState () {
		return {
			inputWidth: this.props.minWidth,
			inputId: '_' + Math.random().toString(36).substr(2, 12),
		};
	},
	componentDidMount () {
		this.mounted = true;
		this.copyInputStyles();
		this.updateInputWidth();
	},
	componentDidUpdate (prevProps, prevState) {
		if (prevState.inputWidth !== this.state.inputWidth) {
			if (typeof this.props.onAutosize === 'function') {
				this.props.onAutosize(this.state.inputWidth);
			}
		}
		this.updateInputWidth();
	},
	componentWillUnmount () {
		this.mounted = false;
	},
	inputRef (el) {
		this.input = el;
	},
	placeHolderSizerRef (el) {
		this.placeHolderSizer = el;
	},
	sizerRef (el) {
		this.sizer = el;
	},
	copyInputStyles () {
		if (!this.mounted || !window.getComputedStyle) {
			return;
		}
		const inputStyle = this.input && window.getComputedStyle(this.input);
		if (!inputStyle) {
			return;
		}
		const widthNode = this.sizer;
		widthNode.style.fontSize = inputStyle.fontSize;
		widthNode.style.fontFamily = inputStyle.fontFamily;
		widthNode.style.fontWeight = inputStyle.fontWeight;
		widthNode.style.fontStyle = inputStyle.fontStyle;
		widthNode.style.letterSpacing = inputStyle.letterSpacing;
		widthNode.style.textTransform = inputStyle.textTransform;
		if (this.props.placeholder) {
			const placeholderNode = this.placeHolderSizer;
			placeholderNode.style.fontSize = inputStyle.fontSize;
			placeholderNode.style.fontFamily = inputStyle.fontFamily;
			placeholderNode.style.fontWeight = inputStyle.fontWeight;
			placeholderNode.style.fontStyle = inputStyle.fontStyle;
			placeholderNode.style.letterSpacing = inputStyle.letterSpacing;
			placeholderNode.style.textTransform = inputStyle.textTransform;
		}
	},
	updateInputWidth () {
		if (!this.mounted || !this.sizer || typeof this.sizer.scrollWidth === 'undefined') {
			return;
		}
		let newInputWidth;
		if (this.props.placeholder && (!this.props.value || (this.props.value && this.props.placeholderIsMinWidth))) {
			newInputWidth = Math.max(this.sizer.scrollWidth, this.placeHolderSizer.scrollWidth) + 2;
		} else {
			newInputWidth = this.sizer.scrollWidth + 2;
		}
		if (newInputWidth < this.props.minWidth) {
			newInputWidth = this.props.minWidth;
		}
		if (newInputWidth !== this.state.inputWidth) {
			this.setState({
				inputWidth: newInputWidth,
			});
		}
	},
	getInput () {
		return this.input;
	},
	focus () {
		this.input.focus();
	},
	blur () {
		this.input.blur();
	},
	select () {
		this.input.select();
	},
	render () {
		const sizerValue = [this.props.defaultValue, this.props.value, ''].reduce(function (previousValue, currentValue) {
			if (previousValue !== null && previousValue !== undefined) {
				return previousValue;
			}
			return currentValue;
		});

		const wrapperStyle = this.props.style || {};
		if (!wrapperStyle.display) wrapperStyle.display = 'inline-block';
		const inputStyle = Object.assign({}, this.props.inputStyle);
		inputStyle.width = this.state.inputWidth + 'px';
		inputStyle.boxSizing = 'content-box';
		const inputProps = Object.assign({}, this.props);
		inputProps.className = this.props.inputClassName;
		inputProps.style = inputStyle;
		// ensure props meant for `AutosizeInput` don't end up on the `input`
		delete inputProps.inputClassName;
		delete inputProps.inputStyle;
		delete inputProps.minWidth;
		delete inputProps.onAutosize;
		delete inputProps.placeholderIsMinWidth;
		return (


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

const sizerStyle = {
	position: 'absolute',
	top: 0,
	left: 0,
	visibility: 'hidden',
	height: 0,
	overflow: 'scroll',
	whiteSpace: 'pre',
};

const INPUT_PROPS_BLACKLIST = [
	'extraWidth',
	'injectStyles',
	'inputClassName',
	'inputRef',
	'inputStyle',
	'minWidth',
	'onAutosize',
	'placeholderIsMinWidth',
];

const cleanInputProps = (inputProps) => {
	INPUT_PROPS_BLACKLIST.forEach(field => delete inputProps[field]);
	return inputProps;
};

const copyStyles = (styles, node) => {
	node.style.fontSize = styles.fontSize;
	node.style.fontFamily = styles.fontFamily;
	node.style.fontWeight = styles.fontWeight;
	node.style.fontStyle = styles.fontStyle;
	node.style.letterSpacing = styles.letterSpacing;
	node.style.textTransform = styles.textTransform;
};

const isIE = (typeof window !== 'undefined' && window.navigator) ? /MSIE |Trident\/|Edge\//.test(window.navigator.userAgent) : false;

const generateId = () => {
	// we only need an auto-generated ID for stylesheet injection, which is only
	// used for IE. so if the browser is not IE, this should return undefined.
	return isIE ? '_' + Math.random().toString(36).substr(2, 12) : undefined;
};

class AutosizeInput extends Component {
	static getDerivedStateFromProps(props, state) {
		const { id } = props;
		return id !== state.prevId ? { inputId: id || generateId(), prevId: id } : null;
	}
	constructor (props) {
		super(props);
		this.state = {
			inputWidth: props.minWidth,
			inputId: props.id || generateId(),
			prevId: props.id,
		};
	}
	componentDidMount () {
		this.mounted = true;
		this.copyInputStyles();
		this.updateInputWidth();
	}
	componentDidUpdate (prevProps, prevState) {
		if (prevState.inputWidth !== this.state.inputWidth) {
			if (typeof this.props.onAutosize === 'function') {
				this.props.onAutosize(this.state.inputWidth);
			}
		}
		this.updateInputWidth();
	}
	componentWillUnmount () {
		this.mounted = false;
	}
	inputRef = (el) => {
		this.input = el;
		if (typeof this.props.inputRef === 'function') {
			this.props.inputRef(el);
		}
	};
	placeHolderSizerRef = (el) => {
		this.placeHolderSizer = el;
	};
	sizerRef = (el) => {
		this.sizer = el;
	};
	copyInputStyles () {
		if (!this.mounted || !window.getComputedStyle) {
			return;
		}
		const inputStyles = this.input && window.getComputedStyle(this.input);
		if (!inputStyles) {
			return;
		}
		copyStyles(inputStyles, this.sizer);
		if (this.placeHolderSizer) {
			copyStyles(inputStyles, this.placeHolderSizer);
		}
	}
	updateInputWidth () {
		if (!this.mounted || !this.sizer || typeof this.sizer.scrollWidth === 'undefined') {
			return;
		}
		let newInputWidth;
		if (this.props.placeholder && (!this.props.value || (this.props.value && this.props.placeholderIsMinWidth))) {
			newInputWidth = Math.max(this.sizer.scrollWidth, this.placeHolderSizer.scrollWidth) + 2;
		} else {
			newInputWidth = this.sizer.scrollWidth + 2;
		}
		// add extraWidth to the detected width. for number types, this defaults to 16 to allow for the stepper UI
		const extraWidth = (this.props.type === 'number' && this.props.extraWidth === undefined)
			? 16 : parseInt(this.props.extraWidth) || 0;
		newInputWidth += extraWidth;
		if (newInputWidth < this.props.minWidth) {
			newInputWidth = this.props.minWidth;
		}
		if (newInputWidth !== this.state.inputWidth) {
			this.setState({
				inputWidth: newInputWidth,
			});
		}
	}
	getInput () {
		return this.input;
	}
	focus () {
		this.input.focus();
	}
	blur () {
		this.input.blur();
	}
	select () {
		this.input.select();
	}
	renderStyles () {
		// this method injects styles to hide IE's clear indicator, which messes
		// with input size detection. the stylesheet is only injected when the
		// browser is IE, and can also be disabled by the `injectStyles` prop.
		const { injectStyles } = this.props;
		return isIE && injectStyles ? (


<commit_before>/**
 * @author Pedro Sanders
 * @since v1
 */
const { connectionException } = require('@routr/utils/exception_helpers')
const {
  sendResponse,
  hasSDP,
  extractRTPEngineParams
} = require('@routr/core/processor/processor_utils')
const { Status } = require('@routr/core/status')
const config = require('@routr/core/config_util')()
const RTPEngineConnector = require('@routr/rtpengine/connector')
const ContentTypeHeader = Java.type('javax.sip.header.ContentTypeHeader')
const CallIdHeader = Java.type('javax.sip.header.CallIdHeader')
const FromHeader = Java.type('javax.sip.header.FromHeader')
const Request = Java.type('javax.sip.message.Request')
const LocatorUtils = require('@routr/location/utils')
const postal = require('postal')

const {
  getEdgeAddr,
  configureContact,
  configureRoute,
  configureVia,
  configureProxyAuthorization,
  configureRequestURI,
  configureMaxForwards,
  configurePrivacy,
  configureRecordRoute,
  configureIdentity,
  configureXHeaders,
  configureCSeq,
  isInDialog
} = require('@routr/core/processor/request_utils')
const { directionFromRequest } = require('@routr/rtpengine/utils')
const { RoutingType } = require('@routr/core/routing_type')
const ObjectId = Java.type('org.bson.types.ObjectId')
const Response = Java.type('javax.sip.message.Response')
const ViaHeader = Java.type('javax.sip.header.ViaHeader')
const ToHeader = Java.type('javax.sip.header.ToHeader')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')
const ConcurrentHashMap = Java.type('java.util.concurrent.ConcurrentHashMap')
const requestStore = new ConcurrentHashMap()
const isInviteOrAck = r =>
  r.getMethod() === Request.INVITE || r.getMethod() === Request.ACK

const LOG = LogManager.getLogger()

class RequestHandler {
  constructor (sipProvider, contextStorage) {
    this.sipProvider = sipProvider
    this.contextStorage = contextStorage
    if (config.spec.ex_rtpEngine.enabled)
      this.rtpeConnector = new RTPEngineConnector(config.spec.ex_rtpEngine)

    postal.subscribe({
      channel: 'locator',
      topic: 'endpoint.find.reply',
      callback: data => {
        const requestInfo = requestStore.get(data.requestId)

        if (requestInfo === null) return

        const transaction = requestInfo.serverTransaction
        const routeInfo = requestInfo.routeInfo
        const request = requestInfo.request

        const response = data.response

        if (response.status == Status.NOT_FOUND) {
          return sendResponse(transaction, Response.TEMPORARILY_UNAVAILABLE)
        }

        // Call forking
        response.data.forEach(route =>
          this.processRoute(transaction, request, route, routeInfo)
        )
        requestStore.remove(data.requestId)
      }
    })
  }

  doProcess (transaction, request, routeInfo) {
    const aor = config.spec.useToAsAOR
      ? request
          .getHeader(ToHeader.NAME)
          .getAddress()
          .getURI()
      : request.getRequestURI()

    // Hack :(
    // This forces the processor to look for an existing binding for endpoints
    // using ".invalid" in the host part of the contact(i.e: SIP.js)
    if (isInDialog(request) && !aor.toString().includes('.invalid')) {
      LOG.debug(
        `core.processor.RequestHandler.doProcess [Processing in-dialog message]`
      )
      this.processRoute(transaction, request, null, routeInfo)
    } else {
      LOG.debug(
        `core.processor.RequestHandler.doProcess [Processing dialog-creating message]`
      )
      const requestId = new ObjectId().toString()
      requestStore.put(requestId, {
        serverTransaction: transaction,
        request,
        routeInfo
      })
      postal.publish({
        channel: 'locator',
        topic: 'endpoint.find',
        data: {
          addressOfRecord: aor,
          requestId: requestId
        }
      })
    }
  }

  async processRoute (transaction, request, route, routeInfo) {
    LOG.debug('Incoming request <== \n' + request)
    try {
      // Request origin transport
      const originTransport = request
        .getHeader(ViaHeader.NAME)
        .getTransport()
        .toLowerCase()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originTransport = ${originTransport}]`
      )

      // Determining origin address
      const originAddr = request.getHeader(ViaHeader.NAME).getHost()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originAddr = ${originAddr}]`
      )

      // Determining Listening point for the originating SIP endpoint
      const originListeningPoint = this.sipProvider.getListeningPoint(
        originTransport
      )
      const originInterfaceAddr = {
        host: getEdgeAddr(
          originAddr,
          originListeningPoint.getIPAddress().toString(),
          null
        ),
        port: originListeningPoint.getPort(),
        transport: originTransport
      }

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originInterfaceAddr = ${JSON.stringify(
          originInterfaceAddr
        )}]`
      )

      // Next hop transport protocol
      const targetTransport = route
        ? route.transport
        : request
            .getRequestURI()
            .getParameter('transport')
            .toLowerCase()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetTransport = ${targetTransport}]`
      )

      // Determining target address
      const targetAddr =
        route && route.contactURI
          ? LocatorUtils.aorAsObj(route.contactURI).getHost()
          : request.getRequestURI().getHost()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetAddr = ${targetAddr}]`
      )

      // Listening point for the destination SIP endpoint
      const targetListeningPoint = this.sipProvider.getListeningPoint(
        targetTransport
      )
      const targetInterfaceAddr = {
        host: getEdgeAddr(
          targetAddr,
          targetListeningPoint.getIPAddress().toString(),
          route
        ),
        port: targetListeningPoint.getPort(),
        transport: targetTransport
      }

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetInterfaceAddr = ${JSON.stringify(
          targetInterfaceAddr
        )}]`
      )

      let requestOut = configureMaxForwards(request)
      requestOut = configureContact(requestOut)
      requestOut = configureProxyAuthorization(requestOut)
      requestOut = configureRoute(
        requestOut,
        originInterfaceAddr,
        targetInterfaceAddr
      )
      requestOut = configureVia(
        requestOut,
        targetInterfaceAddr,
        targetTransport
      )

      if (!isInDialog(request)) {
        requestOut = configureRequestURI(requestOut, routeInfo, route)
        requestOut = configurePrivacy(requestOut, routeInfo)
        requestOut = configureIdentity(requestOut, route)
        requestOut = configureXHeaders(requestOut, route)
        requestOut = configureRecordRoute(
          requestOut,
          originInterfaceAddr,
          targetInterfaceAddr
        )
      } else if (route) {
        requestOut = configureRequestURI(requestOut, null, route)
      }

      if (
        routeInfo &&
        routeInfo.getRoutingType() === RoutingType.DOMAIN_EGRESS_ROUTING
      ) {
        // XXX: Please document this situation :(
        requestOut = configureCSeq(requestOut)
      }

      let bridgingNote
      if (
        config.spec.ex_rtpEngine.enabled &&
        isInviteOrAck(request) &&
        hasSDP(request)
      ) {
        // The note must be taken from the original request else it won't
        // have the correct transport.
        bridgingNote = directionFromRequest(request, route)
        const obj = await this.rtpeConnector.offer(
          bridgingNote,
          extractRTPEngineParams(request)
        )
        requestOut.setContent(
          obj.sdp,
          requestOut.getHeader(ContentTypeHeader.NAME)
        )
      }

      if (
        request.getMethod() === Request.BYE &&
        config.spec.ex_rtpEngine.enabled
      ) {
        const callId = request.getHeader(CallIdHeader.NAME).getCallId()
        const fromTag = request.getHeader(FromHeader.NAME).getTag()
        await this.rtpeConnector.delete(callId, fromTag)
      }

      LOG.debug('Outgoing request ==> \n' + requestOut)
      this.sendRequest(transaction, request, requestOut, bridgingNote)
    } catch (e) {
      sendResponse(transaction, Response.SERVER_INTERNAL_ERROR)
    }
  }

  sendRequest (serverTransaction, request, requestOut, bridgingNote) {
    // Does not need a transaction
    if (request.getMethod().equals(Request.ACK)) {
      return this.sipProvider.sendRequest(requestOut)
    }
    try {
      // The request must be cloned or the stack will not fork the call
      const clientTransaction = this.sipProvider.getNewClientTransaction(
        requestOut.clone()
      )
      clientTransaction.sendRequest()

      LOG.debug(
        `core.processor.RequestHandler.sendRequest [clientTransactionId is ${clientTransaction.getBranchId()}]`
      )
      LOG.debug(
        `core.processor.RequestHandler.sendRequest [serverTransactionId is ${serverTransaction.getBranchId()}]`
      )

      this.saveContext(
        request,
        requestOut,
        clientTransaction,
        serverTransaction,
        bridgingNote
      )
    } catch (e) {
      connectionException(
        e,
        requestOut.getRequestURI().getHost(),
        serverTransaction
      )
    }
  }

  saveContext (
    request,
    requestOut,
    clientTransaction,
    serverTransaction,
    bridgingNote
  ) {
    // Transaction context
    const context = {}
    context.clientTransaction = clientTransaction
    context.serverTransaction = serverTransaction
    context.method = request.getMethod()
    context.requestIn = request
    context.requestOut = requestOut
    context.bridgingNote = bridgingNote
    this.contextStorage.addContext(context)
  }
}

module.exports = RequestHandler
<commit_msg>Cleanup<commit_after>/**
 * @author Pedro Sanders
 * @since v1
 */
const { connectionException } = require('@routr/utils/exception_helpers')
const {
  sendResponse,
  hasSDP,
  extractRTPEngineParams
} = require('@routr/core/processor/processor_utils')
const { Status } = require('@routr/core/status')
const config = require('@routr/core/config_util')()
const RTPEngineConnector = require('@routr/rtpengine/connector')
const ContentTypeHeader = Java.type('javax.sip.header.ContentTypeHeader')
const CallIdHeader = Java.type('javax.sip.header.CallIdHeader')
const FromHeader = Java.type('javax.sip.header.FromHeader')
const Request = Java.type('javax.sip.message.Request')
const LocatorUtils = require('@routr/location/utils')
const postal = require('postal')

const {
  getEdgeAddr,
  configureContact,
  configureRoute,
  configureVia,
  configureProxyAuthorization,
  configureRequestURI,
  configureMaxForwards,
  configurePrivacy,
  configureRecordRoute,
  configureIdentity,
  configureXHeaders,
  configureCSeq,
  isInDialog
} = require('@routr/core/processor/request_utils')
const { directionFromRequest } = require('@routr/rtpengine/utils')
const { RoutingType } = require('@routr/core/routing_type')
const ObjectId = Java.type('org.bson.types.ObjectId')
const Response = Java.type('javax.sip.message.Response')
const ViaHeader = Java.type('javax.sip.header.ViaHeader')
const ToHeader = Java.type('javax.sip.header.ToHeader')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')
const ConcurrentHashMap = Java.type('java.util.concurrent.ConcurrentHashMap')
const requestStore = new ConcurrentHashMap()
const isInviteOrAck = r =>
  r.getMethod() === Request.INVITE || r.getMethod() === Request.ACK

const LOG = LogManager.getLogger()

class RequestHandler {
  constructor (sipProvider, contextStorage) {
    this.sipProvider = sipProvider
    this.contextStorage = contextStorage
    if (config.spec.ex_rtpEngine.enabled)
      this.rtpeConnector = new RTPEngineConnector(config.spec.ex_rtpEngine)

    postal.subscribe({
      channel: 'locator',
      topic: 'endpoint.find.reply',
      callback: data => {
        const requestInfo = requestStore.get(data.requestId)

        if (requestInfo === null) return

        const transaction = requestInfo.serverTransaction
        const routeInfo = requestInfo.routeInfo
        const request = requestInfo.request

        const response = data.response

        if (response.status == Status.NOT_FOUND) {
          return sendResponse(transaction, Response.TEMPORARILY_UNAVAILABLE)
        }

        // Call forking
        response.data.forEach(route =>
          this.processRoute(transaction, request, route, routeInfo)
        )
        requestStore.remove(data.requestId)
      }
    })
  }

  doProcess (transaction, request, routeInfo) {
    const aor = config.spec.useToAsAOR
      ? request
          .getHeader(ToHeader.NAME)
          .getAddress()
          .getURI()
      : request.getRequestURI()

    // Hack :(
    // This forces the processor to look for an existing binding for endpoints
    // using ".invalid" in the host part of the contact(i.e: SIP.js)
    if (isInDialog(request) && !aor.toString().includes('.invalid')) {
      LOG.debug(
        `core.processor.RequestHandler.doProcess [Processing in-dialog message]`
      )
      this.processRoute(transaction, request, null, routeInfo)
    } else {
      LOG.debug(
        `core.processor.RequestHandler.doProcess [Processing dialog-creating message]`
      )
      const requestId = new ObjectId().toString()
      requestStore.put(requestId, {
        serverTransaction: transaction,
        request,
        routeInfo
      })
      postal.publish({
        channel: 'locator',
        topic: 'endpoint.find',
        data: {
          addressOfRecord: aor,
          requestId: requestId
        }
      })
    }
  }

  async processRoute (transaction, request, route, routeInfo) {
    LOG.debug('Incoming request <== \n' + request)
    try {
      // Request origin transport
      const originTransport = request
        .getHeader(ViaHeader.NAME)
        .getTransport()
        .toLowerCase()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originTransport = ${originTransport}]`
      )

      // Determining origin address
      const originAddr = request.getHeader(ViaHeader.NAME).getHost()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originAddr = ${originAddr}]`
      )

      // Determining Listening point for the originating SIP endpoint
      const originListeningPoint = this.sipProvider.getListeningPoint(
        originTransport
      )
      const originInterfaceAddr = {
        host: getEdgeAddr(
          originAddr,
          originListeningPoint.getIPAddress().toString(),
          null
        ),
        port: originListeningPoint.getPort(),
        transport: originTransport
      }

      LOG.debug(
        `core.processor.RequestHandler.processRoute [originInterfaceAddr = ${JSON.stringify(
          originInterfaceAddr
        )}]`
      )

      // Next hop transport protocol
      const targetTransport = route
        ? route.transport
        : request
            .getRequestURI()
            .getParameter('transport')
            .toLowerCase()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetTransport = ${targetTransport}]`
      )

      // Determining target address
      const targetAddr =
        route && route.contactURI
          ? LocatorUtils.aorAsObj(route.contactURI).getHost()
          : request.getRequestURI().getHost()

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetAddr = ${targetAddr}]`
      )

      // Listening point for the destination SIP endpoint
      const targetListeningPoint = this.sipProvider.getListeningPoint(
        targetTransport
      )
      const targetInterfaceAddr = {
        host: getEdgeAddr(
          targetAddr,
          targetListeningPoint.getIPAddress().toString(),
          route
        ),
        port: targetListeningPoint.getPort(),
        transport: targetTransport
      }

      LOG.debug(
        `core.processor.RequestHandler.processRoute [targetInterfaceAddr = ${JSON.stringify(
          targetInterfaceAddr
        )}]`
      )

      let requestOut = configureMaxForwards(request)
      requestOut = configureContact(requestOut)
      requestOut = configureProxyAuthorization(requestOut)
      requestOut = configureRoute(
        requestOut,
        originInterfaceAddr,
        targetInterfaceAddr
      )
      requestOut = configureVia(
        requestOut,
        targetInterfaceAddr,
        targetTransport
      )

      if (!isInDialog(request)) {
        requestOut = configureRequestURI(requestOut, routeInfo, route)
        requestOut = configurePrivacy(requestOut, routeInfo)
        requestOut = configureIdentity(requestOut, route)
        requestOut = configureXHeaders(requestOut, route)
        requestOut = configureRecordRoute(
          requestOut,
          originInterfaceAddr,
          targetInterfaceAddr
        )
      } else if (route) {
        requestOut = configureRequestURI(requestOut, null, route)
      }

      if (
        routeInfo &&
        routeInfo.getRoutingType() === RoutingType.DOMAIN_EGRESS_ROUTING
      ) {
        // XXX: Please document this situation :(
        requestOut = configureCSeq(requestOut)
      }

      let bridgingNote
      if (
        config.spec.ex_rtpEngine.enabled &&
        isInviteOrAck(request) &&
        hasSDP(request)
      ) {
        // The note must be taken from the original request else it won't
        // have the correct transport.
        bridgingNote = directionFromRequest(request, route)
        const obj = await this.rtpeConnector.offer(
          bridgingNote,
          extractRTPEngineParams(request)
        )
        requestOut.setContent(
          obj.sdp,
          requestOut.getHeader(ContentTypeHeader.NAME)
        )
      }

      if (
        request.getMethod() === Request.BYE &&
        config.spec.ex_rtpEngine.enabled
      ) {
        const callId = request.getHeader(CallIdHeader.NAME).getCallId()
        const fromTag = request.getHeader(FromHeader.NAME).getTag()
        await this.rtpeConnector.delete(callId, fromTag)
      }

      LOG.debug('Outgoing request ==> \n' + requestOut)
      this.sendRequest(transaction, request, requestOut, bridgingNote)
    } catch (e) {
      sendResponse(transaction, Response.SERVER_INTERNAL_ERROR)
      LOG.error(e.message || e)
    }
  }

  sendRequest (serverTransaction, request, requestOut, bridgingNote) {
    // Does not need a transaction
    if (request.getMethod().equals(Request.ACK)) {
      return this.sipProvider.sendRequest(requestOut)
    }
    try {
      // The request must be cloned or the stack will not fork the call
      const clientTransaction = this.sipProvider.getNewClientTransaction(
        requestOut.clone()
      )
      clientTransaction.sendRequest()

      LOG.debug(
        `core.processor.RequestHandler.sendRequest [clientTransactionId is ${clientTransaction.getBranchId()}]`
      )
      LOG.debug(
        `core.processor.RequestHandler.sendRequest [serverTransactionId is ${serverTransaction.getBranchId()}]`
      )

      this.saveContext(
        request,
        requestOut,
        clientTransaction,
        serverTransaction,
        bridgingNote
      )
    } catch (e) {
      connectionException(
        e,
        requestOut.getRequestURI().getHost(),
        serverTransaction
      )
    }
  }

  saveContext (
    request,
    requestOut,
    clientTransaction,
    serverTransaction,
    bridgingNote
  ) {
    // Transaction context
    const context = {}
    context.clientTransaction = clientTransaction
    context.serverTransaction = serverTransaction
    context.method = request.getMethod()
    context.requestIn = request
    context.requestOut = requestOut
    context.bridgingNote = bridgingNote
    this.contextStorage.addContext(context)
  }
}

module.exports = RequestHandler
<|endoftext|>


<commit_before>if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i] == obj){
                return i;
            }
        }
        return -1;
    }
}

RouterClass = function(routes) {
  this.url = window.location.toString().split('/').slice(0, 3).join('/');

  var OrderedHash = function() {
    this.keys = [];
    this.values = [];

    this.set = function(key, value) {
      var index = this.keys.indexOf(key);
      if(index >= 0) {
        this.values[index] = value;
      } else {
        this.keys.push(key);
        this.values.push(value);
      }
    };

    this.get = function(key) {
      var index = this.keys.indexOf(key);
      if(index >= 0) {
        return this.values[index];
      } else {
        return null;
      }
    };

    this.each = function(callback) {
      for(var i = 0; i < this.keys.length; i++) {
        callback(this.keys[i], this.values[i]);
      }
    };
  };

  this.resolveArguments = function(def, allArgs) {
    var i;
    var args = allArgs;
    var options = {};
    var urlOptions = new OrderedHash();

    // extract options
    if (allArgs.length > 0) {
      var last = allArgs[allArgs.length-1];
      if (typeof(last) === "object") {
        options = last;
        args = [];
        for (i = 0; i < allArgs.length - 1; i++) {
          args.push(allArgs[i]);
        }
      }
    }

    for (i = 0; i < args.length; i++) {
      var key = def.keys[i];
      var value = args[i];
      urlOptions.set(key, value);
    }

    for (var k in options) {
      if (true) { // mute JSlint
        urlOptions.set(k, options[k]);
      }
    }

    return urlOptions;
  };

  this.cleanupPath = function(path) {
    return path.replace(/\(.*(\:[a-z0-9_]+).*\)/g, "").replace(/[\(\)]/g, "");
  };

  this.bindRoute = function(key, def) {
    this[key] = function() {
      var args = this.resolveArguments(def, arguments);
      var path = def.path;
      var data = [];

      args.each(function(k,v) {
        if(path.search(k) >= 0) {
          path = path.replace(new RegExp(':'+k), encodeURIComponent(v));
        } else {
          data.push(k + '=' + encodeURIComponent(v));
        }
      });

      var route = this.cleanupPath(path);

      if (data.length > 0) {
        data = data.join('&');
        if (route.indexOf('?') > 0) {
          route += data;
        } else {
          route += '?' + data;
        }
      }
      return route;
    };

    this[key + '_path'] = function() {
      return this[key].apply(this, arguments);
    };

    this[key + '_url'] = function() {
      var route = this[key + '_path'].apply(this, arguments);
      return this.url + route;
    };
  };

  for (var key in routes) {
    if (true) { // mute JSlint
      this.bindRoute(key, routes[key]);
    }
  }

  this.named_routes = routes;
};

%global% = new RouterClass(%routes%);
<commit_msg>do not break for-each loops<commit_after>RouterClass = function(routes) {
  this.url = window.location.toString().split('/').slice(0, 3).join('/');

  var OrderedHash = function() {
    this.keys = [];
    this.values = [];

    this.indexOfKey = function(key) {
      for(var i=0; i<this.keys.length; i++){
          if(this.keys[i] == key){
              return i;
          }
      }
      return -1;
    };

    this.set = function(key, value) {
      var index = this.indexOfKey(key);
      if(index >= 0) {
        this.values[index] = value;
      } else {
        this.keys.push(key);
        this.values.push(value);
      }
    };

    this.get = function(key) {
      var index = this.indexOfKey(key);
      if(index >= 0) {
        return this.values[index];
      } else {
        return null;
      }
    };

    this.each = function(callback) {
      for(var i = 0; i < this.keys.length; i++) {
        callback(this.keys[i], this.values[i]);
      }
    };
  };

  this.resolveArguments = function(def, allArgs) {
    var i;
    var args = allArgs;
    var options = {};
    var urlOptions = new OrderedHash();

    // extract options
    if (allArgs.length > 0) {
      var last = allArgs[allArgs.length-1];
      if (typeof(last) === "object") {
        options = last;
        args = [];
        for (i = 0; i < allArgs.length - 1; i++) {
          args.push(allArgs[i]);
        }
      }
    }

    for (i = 0; i < args.length; i++) {
      var key = def.keys[i];
      var value = args[i];
      urlOptions.set(key, value);
    }

    for (var k in options) {
      if (true) { // mute JSlint
        urlOptions.set(k, options[k]);
      }
    }

    return urlOptions;
  };

  this.cleanupPath = function(path) {
    return path.replace(/\(.*(\:[a-z0-9_]+).*\)/g, "").replace(/[\(\)]/g, "");
  };

  this.bindRoute = function(key, def) {
    this[key] = function() {
      var args = this.resolveArguments(def, arguments);
      var path = def.path;
      var data = [];

      args.each(function(k,v) {
        if(path.search(k) >= 0) {
          path = path.replace(new RegExp(':'+k), encodeURIComponent(v));
        } else {
          data.push(k + '=' + encodeURIComponent(v));
        }
      });

      var route = this.cleanupPath(path);

      if (data.length > 0) {
        data = data.join('&');
        if (route.indexOf('?') > 0) {
          route += data;
        } else {
          route += '?' + data;
        }
      }
      return route;
    };

    this[key + '_path'] = function() {
      return this[key].apply(this, arguments);
    };

    this[key + '_url'] = function() {
      var route = this[key + '_path'].apply(this, arguments);
      return this.url + route;
    };
  };

  for (var key in routes) {
    if (true) { // mute JSlint
      this.bindRoute(key, routes[key]);
    }
  }

  this.named_routes = routes;
};

%global% = new RouterClass(%routes%);
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Couchfriends
 * www.couchfriends.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Ball object
 * @constructor
 */
BreakOut.Ball = function (settings) {

    BreakOut.Element.call(this, settings);

    this.name = 'ball';

    this.stats = {
        radius: settings.radius || 15,
        prevPosition: {
            x: 0,
            y: 0
        },
        speed: {
            x: -5,
            y: 5
        },
        maxSpeed: {
            x: 5,
            y: 5
        }
    };
    this.collisionList = ['paddle', 'brick', 'ball'];

};

BreakOut.Ball.prototype = Object.create(BreakOut.Element.prototype);

BreakOut.Ball.prototype.init = function () {

    this.object = new PIXI.Graphics();
    this.object.beginFill(0xff9900, 1);
    this.object.drawCircle(0, 0, this.stats.radius);
};

BreakOut.Ball.prototype.collision = function (target) {

    // Get the direction of the bounce
    if (target.name == 'paddle' || target.name == 'brick') {

        var adjustSpeed = false;
        if (this.object.position.x < (target.object.position.x - (target.object.width / 2))) {
            this.stats.speed.x *= -1;
            this.object.position.x = (target.object.position.x - (target.object.width / 2)) - (this.object.width / 2);
        }
        else if (this.object.position.x > (target.object.position.x + (target.object.width / 2))) {
            this.stats.speed.x *= -1;
            this.object.position.x = (target.object.position.x + (target.object.width / 2)) + (this.object.width / 2);
        }
        else if (this.object.position.y < (target.object.position.y - (target.object.height / 2))) {
            adjustSpeed = true;
            this.stats.speed.y *= -1;
            this.object.position.y = (target.object.position.y - (target.object.height / 2)) - (this.object.height / 2);
        }
        else {
            adjustSpeed = true;
            this.stats.speed.y *= -1;
            this.object.position.y = (target.object.position.y + (target.object.height / 2)) + (this.object.height / 2);
        }
        if (target.name == 'paddle' && adjustSpeed == true) {
            var xPosRelative = this.object.position.x
        }

        var dx = target.object.position.x - this.object.position.x;
        var dy = target.object.position.y - this.object.position.y;

        //if(this.object.position.x < target.object.position.x) {
        //    dx -= this.object.width;
        //} else {
        //    dx += target.object.width;
        //}
        //
        //if(this.object.position.y < target.object.position.y) {
        //    dy -= this.object.height;
        //} else {
        //    dy += target.object.height;
        //}

        //if(Math.abs(dx) < Math.abs(dy)) {
        //    this.stats.speed.x *= -1;
        //    //this.object.position.x = this.prevPosition.x + this.stats.speed.x;
        //} else {
        //    this.stats.speed.y *= -1;
        //    //this.object.position.y = this.prevPosition.y + this.stats.speed.y;
        //}

        if (0) {
            // Speed velocity for paddle
            var magnitude = (this.distanceTo(paddle) - this.size.y / 2 - paddle.size.y / 2);
            var ratio = magnitude / (paddle.size.x / 2) * 2.5;

            if (this.pos.x + this.size.x / 2 < paddle.pos.x + paddle.size.x / 2) {
                // send the ball to the left if hit on the left side of the paddle, and vice versa
                ratio = -ratio;
            }

            return this.speed * ratio;
        }
        if (0) {
            if (this.object.position.y <= target.object.position.y - (target.object.height / 2)) {
                console.log('bottom');
                this.stats.speed.y = Math.abs(this.stats.speed.y);
            }
            else if (this.object.position.y >= target.object.position.y + (target.object.height / 2)) {
                console.log('top');
                this.stats.speed.y = -(Math.abs(this.stats.speed.y));
            }
            if (this.object.position.x < target.object.position.x) {
                console.log('left');
                this.stats.speed.x = -(Math.abs(this.stats.speed.x));
            }
            else if (this.object.position.x > target.object.position.x) {
                console.log('right');
                this.stats.speed.x = Math.abs(this.stats.speed.x);
            }
        }
        if (0) {
            var targetHalfWidth = target.object.width / 2;
            var ballHalfWidth = this.object.width / 2;
            var targetHalfHeight = target.object.height / 2;
            var ballHalfHeight = this.object.height / 2;
            var cRx = Math.abs(target.object.position.x - targetHalfWidth - this.object.position.x);
            var cRy = Math.abs(target.object.position.y - targetHalfHeight - this.object.position.y);

            var spacing = Math.max(target.object.width * .1, 10);
            // 25 70 10
            console.log(spacing, cRx, cRy, this.object.position.y, target.object.position.y);
            // top left corner
            if (cRx < spacing && cRy < spacing) {
                console.log('top left');
                this.stats.speed.x = -(Math.abs(this.stats.speed.x));
                this.stats.speed.y = -(Math.abs(this.stats.speed.y));
            }
            // top right corner
            else if (cRx > (targetHalfWidth + ballHalfWidth - spacing) && cRy < spacing) {
                console.log('top right');
                this.stats.speed.x = Math.abs(this.stats.speed.x);
                this.stats.speed.y = -(Math.abs(this.stats.speed.y));
            }
            // bottom right corner
            else if (cRx > (targetHalfWidth + ballHalfWidth - spacing) && cRy > (targetHalfHeight + ballHalfHeight - spacing)) {
                console.log('bottom right');
                this.stats.speed.x = Math.abs(this.stats.speed.x);
                this.stats.speed.y = Math.abs(this.stats.speed.y);
            }
            // bottom left corner
            else if (cRx < spacing && cRy > (targetHalfHeight + ballHalfHeight - spacing)) {
                console.log('bottom left');
                this.stats.speed.x = -(Math.abs(this.stats.speed.x));
                this.stats.speed.y = Math.abs(this.stats.speed.y);
            }
            // left
            else if (cRx < cRy) {
                console.log('left');
                this.stats.speed.x = -(Math.abs(this.stats.speed.x));
            }
            // right
            else if (cRx > cRy && !((cRy < targetHalfHeight || target.object.position.y > this.object.position.y))) {
                console.log('right');
                this.stats.speed.x = Math.abs(this.stats.speed.x);
            }
            // top or bottom
            else {
                if (cRy < targetHalfHeight || target.object.position.y > this.object.position.y) {
                    console.log('top');
                    this.stats.speed.y = -(Math.abs(this.stats.speed.y));
                }
                else {
                    console.log('bottom');
                    this.stats.speed.y = Math.abs(this.stats.speed.y);
                }

                if (target.name == 'paddle') {
                    var percentX = 100 / target.object.width * cRx;
                    if (percentX < 40) {
                        this.stats.speed.x = (this.stats.speed.x / 100 * percentX);
                    }
                    else if (percentX > 60) {
                        this.stats.speed.x = -(this.stats.speed.x / 100 * percentX);
                    }
                }
            }
        }

    }

    if (target.name == 'ball') {

        var ball2 = target;

        var dx = ball2.object.position.x - this.object.position.x;
        var dy = ball2.object.position.y - this.object.position.y;
        var distance = Math.sqrt(dx * dx + dy * dy);
        var minDist = ball2.stats.radius / 1.1 + this.stats.radius / 1.1;
        if (distance < minDist) {
            var angle = Math.atan2(dy, dx);
            var targetX = this.object.position.x + Math.cos(angle) * minDist;
            var targetY = this.object.position.y + Math.sin(angle) * minDist;
            var ax = (targetX - ball2.object.position.x);
            var ay = (targetY - ball2.object.position.y);
            this.stats.speed.x -= ax;
            this.stats.speed.y -= ay;
            ball2.stats.speed.x += ax;
            ball2.stats.speed.y += ay;
        }
        if (this.stats.speed.x > this.stats.maxSpeed.x) {
            this.stats.speed.x = this.stats.maxSpeed.x;
        }
        else if (this.stats.speed.x < -(this.stats.maxSpeed.x)) {
            this.stats.speed.x = -(this.stats.maxSpeed.x);
        }
        if (this.stats.speed.y > this.stats.maxSpeed.y) {
            this.stats.speed.y = this.stats.maxSpeed.y;
        }
        else if (this.stats.speed.y < -(this.stats.maxSpeed.y)) {
            this.stats.speed.y = -(this.stats.maxSpeed.y);
        }

    }
};

BreakOut.Ball.prototype.update = function (time) {

    if (!BreakOut.Element.prototype.update.call(this, time)) {
        return false;
    }
    this.object.position.x += this.stats.speed.x;
    this.object.position.y += this.stats.speed.y;
    if (this.object.position.y > (BreakOut.settings.height - this.stats.radius)) {
        this.stats.speed.y = -this.stats.speed.y;
        this.object.position.y = (BreakOut.settings.height - this.stats.radius);
    }
    else if (this.object.position.y < this.stats.radius) {
        this.stats.speed.y = Math.abs(this.stats.speed.y);
        this.object.position.y = this.stats.radius;
    }
    if (this.object.position.x > (BreakOut.settings.width - this.stats.radius)) {
        this.stats.speed.x = -this.stats.speed.x;
        this.object.position.x = (BreakOut.settings.width - this.stats.radius);
    }
    if (this.object.position.x < this.stats.radius) {
        this.stats.speed.x = Math.abs(this.stats.speed.x);
        this.object.position.x = this.stats.radius;
    }
};<commit_msg>Clean deprecated code.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Couchfriends
 * www.couchfriends.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Ball object
 * @constructor
 */
BreakOut.Ball = function (settings) {

    BreakOut.Element.call(this, settings);

    this.name = 'ball';

    this.stats = {
        radius: settings.radius || 15,
        prevPosition: {
            x: 0,
            y: 0
        },
        speed: {
            x: -5,
            y: 5
        },
        maxSpeed: {
            x: 5,
            y: 5
        }
    };
    this.collisionList = ['paddle', 'brick', 'ball'];

};

BreakOut.Ball.prototype = Object.create(BreakOut.Element.prototype);

BreakOut.Ball.prototype.init = function () {

    this.object = new PIXI.Graphics();
    this.object.beginFill(0xff9900, 1);
    this.object.drawCircle(0, 0, this.stats.radius);
};

BreakOut.Ball.prototype.collision = function (target) {

    // Get the direction of the bounce
    if (target.name == 'paddle' || target.name == 'brick') {

        var adjustSpeed = false;
        if (this.object.position.x < (target.object.position.x - (target.object.width / 2))) {
            this.stats.speed.x *= -1;
            this.object.position.x = (target.object.position.x - (target.object.width / 2)) - (this.object.width / 2);
        }
        else if (this.object.position.x > (target.object.position.x + (target.object.width / 2))) {
            this.stats.speed.x *= -1;
            this.object.position.x = (target.object.position.x + (target.object.width / 2)) + (this.object.width / 2);
        }
        else if (this.object.position.y < (target.object.position.y - (target.object.height / 2))) {
            adjustSpeed = true;
            this.stats.speed.y *= -1;
            this.object.position.y = (target.object.position.y - (target.object.height / 2)) - (this.object.height / 2);
        }
        else {
            adjustSpeed = true;
            this.stats.speed.y *= -1;
            this.object.position.y = (target.object.position.y + (target.object.height / 2)) + (this.object.height / 2);
        }
        if (target.name == 'paddle' && adjustSpeed == true) {
            var xPosRelative = this.object.position.x
        }
        if (0) {
            // Speed velocity for paddle
            var magnitude = (this.distanceTo(paddle) - this.size.y / 2 - paddle.size.y / 2);
            var ratio = magnitude / (paddle.size.x / 2) * 2.5;

            if (this.pos.x + this.size.x / 2 < paddle.pos.x + paddle.size.x / 2) {
                // send the ball to the left if hit on the left side of the paddle, and vice versa
                ratio = -ratio;
            }

            return this.speed * ratio;
        }
    }

    if (target.name == 'ball') {

        var ball2 = target;

        var dx = ball2.object.position.x - this.object.position.x;
        var dy = ball2.object.position.y - this.object.position.y;
        var distance = Math.sqrt(dx * dx + dy * dy);
        var minDist = ball2.stats.radius / 1.1 + this.stats.radius / 1.1;
        if (distance < minDist) {
            var angle = Math.atan2(dy, dx);
            var targetX = this.object.position.x + Math.cos(angle) * minDist;
            var targetY = this.object.position.y + Math.sin(angle) * minDist;
            var ax = (targetX - ball2.object.position.x);
            var ay = (targetY - ball2.object.position.y);
            this.stats.speed.x -= ax;
            this.stats.speed.y -= ay;
            ball2.stats.speed.x += ax;
            ball2.stats.speed.y += ay;
        }
        if (this.stats.speed.x > this.stats.maxSpeed.x) {
            this.stats.speed.x = this.stats.maxSpeed.x;
        }
        else if (this.stats.speed.x < -(this.stats.maxSpeed.x)) {
            this.stats.speed.x = -(this.stats.maxSpeed.x);
        }
        if (this.stats.speed.y > this.stats.maxSpeed.y) {
            this.stats.speed.y = this.stats.maxSpeed.y;
        }
        else if (this.stats.speed.y < -(this.stats.maxSpeed.y)) {
            this.stats.speed.y = -(this.stats.maxSpeed.y);
        }

    }
};

BreakOut.Ball.prototype.update = function (time) {

    if (!BreakOut.Element.prototype.update.call(this, time)) {
        return false;
    }
    this.object.position.x += this.stats.speed.x;
    this.object.position.y += this.stats.speed.y;
    if (this.object.position.y > (BreakOut.settings.height - this.stats.radius)) {
        this.stats.speed.y = -this.stats.speed.y;
        this.object.position.y = (BreakOut.settings.height - this.stats.radius);
    }
    else if (this.object.position.y < this.stats.radius) {
        this.stats.speed.y = Math.abs(this.stats.speed.y);
        this.object.position.y = this.stats.radius;
    }
    if (this.object.position.x > (BreakOut.settings.width - this.stats.radius)) {
        this.stats.speed.x = -this.stats.speed.x;
        this.object.position.x = (BreakOut.settings.width - this.stats.radius);
    }
    if (this.object.position.x < this.stats.radius) {
        this.stats.speed.x = Math.abs(this.stats.speed.x);
        this.object.position.x = this.stats.radius;
    }
};<|endoftext|>


<commit_before>(function() {
    var showErrorsModule;

    showErrorsModule = angular.module('showErrors', []);

    showErrorsModule.directive('showErrors', function($timeout, $interpolate, showErrorsConfig) {
        var getShowSuccess, getTrigger, linkFn;
        var errorClass = "validation-error";
        getTrigger = function(options) {
            var trigger;
            trigger = showErrorsConfig.trigger;
            if (options && (options.trigger != null)) {
                trigger = options.trigger;
            }
            return trigger;
        };
        getShowSuccess = function(options) {
            var showSuccess;
            showSuccess = showErrorsConfig.showSuccess;
            if (options && (options.showSuccess != null)) {
                showSuccess = options.showSuccess;
            }
            return showSuccess;
        };
        linkFn = function(scope, el, attrs, formCtrl) {
            var blurred, elName, options, showSuccess, toggleClasses, trigger;
            blurred = false;
            options = scope.$eval(attrs.showErrors);
            showSuccess = getShowSuccess(options);
            trigger = getTrigger(options);
            elName = $interpolate(el.attr('name'))(scope);
            if (!elName) {
                throw "show-errors element has no 'name' attribute";
            }
            el.bind(trigger, function() {
                blurred = true;
                return toggleClasses(formCtrl[elName].$invalid);
            });
            scope.$watch(function() {
                return formCtrl[elName] && formCtrl[elName].$invalid;
            }, function(invalid) {
                if (!blurred) {
                    return;
                }
                return toggleClasses(invalid);
            });
            scope.$on('show-errors-check-validity', function() {
                console.log(elName);
                return toggleClasses(formCtrl[elName].$invalid);
            });
            scope.$on('show-errors-reset', function() {
                return $timeout(function() {
                    el.removeClass(errorClass);
                    el.removeClass('has-success');
                    return blurred = false;
                }, 0, false);
            });
            return toggleClasses = function(invalid) {
                el.toggleClass(errorClass, invalid);
                if (showSuccess) {
                    return el.toggleClass('has-success', !invalid);
                }
            };
        };
        return {
            restrict: 'A',
            require: '^form',
            compile: function(elem, attrs) {
                return linkFn;
            }
        };
    });

    showErrorsModule.provider('showErrorsConfig', function() {
        var _showSuccess, _trigger;
        _showSuccess = false;
        _trigger = 'blur';
        this.showSuccess = function(showSuccess) {
            return _showSuccess = showSuccess;
        };
        this.trigger = function(trigger) {
            return _trigger = trigger;
        };
        this.$get = function() {
            return {
                showSuccess: _showSuccess,
                trigger: _trigger
            };
        };
    });
})();<commit_msg>refactor(show-errors): clean up directive<commit_after>(function() {
    var m = angular.module('showErrors', []);

    m.directive('showErrors', function($interpolate) {
        var errorClass = "validation-error";

        function linkFn(scope, el, attrs, formCtrl) {
            var blurred = false;

            function toggleClasses(invalid) {
                el.toggleClass(errorClass, invalid);
            }

            var elName = $interpolate(el.attr('name'))(scope);
            if (!elName) {
                throw "show-errors element has no 'name' attribute";
            }

            el.bind('blur', function() {
                blurred = true;
                return toggleClasses(formCtrl[elName].$invalid);
            });

            scope.$watch(function() {
                return formCtrl[elName] && formCtrl[elName].$invalid;
            }, function(invalid) {
                if (!blurred) {
                    return;
                }
                return toggleClasses(invalid);
            });

            scope.$on('show-errors-check-validity', function() {
                return toggleClasses(formCtrl[elName].$invalid);
            });

            return toggleClasses;
        }

        return {
            restrict: 'A',
            require: '^form',
            link: linkFn
        };
    });
})();<|endoftext|>


<commit_before>import QUnit from 'steal-qunit';
import 'bitcentive/models/fixtures/fixtures-socket';
import { ViewModel } from './os-projects';
import ContributionMonth from 'bitcentive/models/contribution-month/';
import { store as contributionMonthStore } from 'bitcentive/models/fixtures/contribution-months';

//ViewModel unit tests
QUnit.module('bitcentive/components/os-projects', {
  beforeEach: function() {
    this.osProject = {
      _id: "somethingCrazey",
      name: "CanJS"
    };

    this.osProject2 = {
      _id: "2-DoneJS",
      name: "DoneJS"
    };

    this.clientProject = {
      _id: "asl;dfal;sfj ;lakwj",
      name: "HualHound"
    };

    this.contributionMonth = new ContributionMonth({
      _id: "aslkfalsjklas",
      date: 124234211310000,
      monthlyOSProjects: [{
        significance: 80,
        commissioned: true,
        osProjectRef: this.osProject._id,
        osProject: this.osProject
      }],
      monthlyClientProjects: [{
        monthlyClientProjectsOSProjects: [{
          osProjectRef: this.osProject._id,
          osProject: this.osProject
        }],
        hours: 100,
        clientProjectRef: this.clientProject._id,
        clientProject: this.clientProject
      }]
    });
  }
});

QUnit.asyncTest('Can create new OS Project', function() {
  contributionMonthStore.reset();
  var vm = new ViewModel();

  vm.contributionMonth = this.contributionMonth;
  vm.selectedOSProjectId = "__new__";
  vm.newOSProjectName = "something";

  vm.addNewMonthlyOSProject().then(() => {
    QUnit.equal(vm.contributionMonth.monthlyOSProjects[1].osProjectRef.value.name , 'something');
    QUnit.equal(vm.getTotal(vm.contributionMonth.monthlyOSProjects[1]) , '0.00');
    QUnit.start();
  });
});

QUnit.asyncTest('Can add an existing OS Project to Monthly Contribution', function() {
  contributionMonthStore.reset();
  var vm = new ViewModel();
  var projectToAdd = this.osProject2;

  vm.contributionMonth = this.contributionMonth;
  vm.selectedOSProjectId = projectToAdd._id ;

  vm.addNewMonthlyOSProject().then(() => {
    QUnit.equal(vm.contributionMonth.monthlyOSProjects.length, 2);
    QUnit.equal(vm.contributionMonth.monthlyOSProjects[1].osProjectRef.value.name , projectToAdd.name);
    QUnit.start();
  });
});
<commit_msg>Fix test by binding to Ref value, then checking it<commit_after>import QUnit from 'steal-qunit';
import 'bitcentive/models/fixtures/fixtures-socket';
import { ViewModel } from './os-projects';
import ContributionMonth from 'bitcentive/models/contribution-month/';
import { store as contributionMonthStore } from 'bitcentive/models/fixtures/contribution-months';

//ViewModel unit tests
QUnit.module('bitcentive/components/os-projects', {
  beforeEach: function() {
    this.osProject = {
      _id: "somethingCrazey",
      name: "CanJS"
    };

    this.osProject2 = {
      _id: "2-DoneJS",
      name: "DoneJS"
    };

    this.clientProject = {
      _id: "asl;dfal;sfj ;lakwj",
      name: "HualHound"
    };

    this.contributionMonth = new ContributionMonth({
      _id: "aslkfalsjklas",
      date: 124234211310000,
      monthlyOSProjects: [{
        significance: 80,
        commissioned: true,
        osProjectRef: this.osProject._id,
        osProject: this.osProject
      }],
      monthlyClientProjects: [{
        monthlyClientProjectsOSProjects: [{
          osProjectRef: this.osProject._id,
          osProject: this.osProject
        }],
        hours: 100,
        clientProjectRef: this.clientProject._id,
        clientProject: this.clientProject
      }]
    });
  }
});

QUnit.test('Can create new OS Project', function(assert) {
  var done = assert.async();

  contributionMonthStore.reset();
  var vm = new ViewModel();

  vm.contributionMonth = this.contributionMonth;
  vm.selectedOSProjectId = "__new__";
  vm.newOSProjectName = "something";

  vm.addNewMonthlyOSProject().then(() => {
    QUnit.equal(vm.contributionMonth.monthlyOSProjects[1].osProjectRef.value.name , 'something');
    QUnit.equal(vm.getTotal(vm.contributionMonth.monthlyOSProjects[1]) , '0.00');
    done();
  });
});

QUnit.test('Can add an existing OS Project to Monthly Contribution', function(assert) {
  var done = assert.async();

  contributionMonthStore.reset();
  var vm = new ViewModel();
  var projectToAdd = this.osProject2;

  vm.contributionMonth = this.contributionMonth;
  vm.selectedOSProjectId = projectToAdd._id;

  vm.addNewMonthlyOSProject().then(() => {
    QUnit.equal(vm.contributionMonth.monthlyOSProjects.length, 2);
    vm.contributionMonth.monthlyOSProjects[1].osProjectRef.on('value', function(value){
      QUnit.equal(vm.contributionMonth.monthlyOSProjects[1].osProjectRef.value.name , projectToAdd.name);
      done();
    });
  });
});
<|endoftext|>


<commit_before>var _ = require('underscore');
var backbone = require('backbone');
var registry = require('datapackage-registry');

// WARN Used just for demo purposes
var VALID_DESCRIPTOR = {
  'name': 'my-dataset',

  'resources': [{
    'path': 'data.csv',

    'schema': {
      'fields': [
        {'name': 'var1', 'type': 'string'},
        {'name': 'var2', 'type': 'integer'},
        {'name': 'var3', 'type': 'number'}
      ]
    }
  }]
};

// Application state changed here
module.exports = backbone.Router.extend({
  routes: {
    '(/)': 'index',
    'validation-results/:resource(/)': 'validationResults'
  },

  /**
   * Turn off all UI views except navigation bar which is part of base layout
   */
  deactivateAll: function() {
    _.chain(_.omit(window.APP.layout, ['navbar']))
      .values()
      .invoke('deactivate');

    return this;
  },

  index: function() {
    this.deactivateAll();
    window.APP.layout.navbar.toggleBadge(true);
    window.APP.layout.download.activate();
    window.APP.layout.descriptorEdit.activate();
    window.APP.layout.descriptorEdit.layout.registryList.activate();
    window.APP.layout.errorList.activate();

    // WARN Process registry errors here
    if(!window.APP.layout.descriptorEdit.layout.registryList.collection) registry.get().then(function(D) {
      window.APP.layout.descriptorEdit.layout.registryList
        .reset(new backbone.Collection(D));
    });
  },

  validationResults: function(resource) {
    this.deactivateAll();
    window.APP.layout.navbar.toggleBadge(true);

    window.APP.layout.validationResultList
      .activate()
      .setActive(resource);
  }
});<commit_msg>Code formatting<commit_after>var _ = require('underscore');
var backbone = require('backbone');
var registry = require('datapackage-registry');

// WARN Used just for demo purposes
var VALID_DESCRIPTOR = {
  'name': 'my-dataset',

  'resources': [{
    'path': 'data.csv',

    'schema': {
      'fields': [
        {'name': 'var1', 'type': 'string'},
        {'name': 'var2', 'type': 'integer'},
        {'name': 'var3', 'type': 'number'}
      ]
    }
  }]
};

// Application state changed here
module.exports = backbone.Router.extend({
  routes: {
    '(/)': 'index',
    'validation-results/:resource(/)': 'validationResults'
  },

  /**
   * Turn off all UI views except navigation bar which is part of base layout
   */
  deactivateAll: function() {
    _.chain(_.omit(window.APP.layout, ['navbar']))
      .values()
      .invoke('deactivate');

    return this;
  },

  index: function() {
    this.deactivateAll();
    window.APP.layout.navbar.toggleBadge(true);
    window.APP.layout.download.activate();
    window.APP.layout.descriptorEdit.activate();
    window.APP.layout.descriptorEdit.layout.registryList.activate();
    window.APP.layout.errorList.activate();

    // WARN Process registry errors here
    if(!window.APP.layout.descriptorEdit.layout.registryList.collection)
      registry.get().then(function(D) {
        window.APP.layout.descriptorEdit.layout.registryList.reset(new backbone.Collection(D));
      });
  },

  validationResults: function(resource) {
    this.deactivateAll();
    window.APP.layout.navbar.toggleBadge(true);

    window.APP.layout.validationResultList
      .activate()
      .setActive(resource);
  }
});<|endoftext|>


<commit_before>/* global Module */

/* Magic Mirror
 * Module: MMM-Globe
 *
 * By Luke Scheffler https://github.com/LukeSkywalker92
 * MIT Licensed.
 */

Module.register("MMM-Globe", {
	// Default module config.
	defaults: {
		style: 'geoColor',
		imageSize: 600,
		ownImagePath: '',
		updateInterval: 10 * 60 * 1000
	},

	start: function () {
		self = this;
		this.url = '';
		this.imageUrls = {
			'natColor': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_natural_color.jpg',
			'geoColor': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_true_color.jpg',
			'airMass': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_rgb_airmass.jpg',
			'fullBand': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/himawari-8_band_03_sector_02.gif',
			'europeDiscNat': 'http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBNatColour_LowResolution.jpg',
			'europeDiscSnow': 'http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBSolarDay_CentralEurope.jpg',
			'centralAmericaDiscNat': 'https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/20183421830_GOES16-ABI-FD-GEOCOLOR-678x678.jpg'

		}
		this.hiResImageUrls = {
			'natColor': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_natural_color.jpg',
			'geoColor': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_true_color.jpg',
			'airMass': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_rgb_airmass.jpg',
			'fullBand': 'http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/himawari-8_band_03_sector_02.gif',
			'europeDiscNat': 'http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBNatColour_LowResolution.jpg',
			'europePartSnow': 'http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBSolarDay_CentralEurope.jpg',
			'centralAmericaDiscNat': 'https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/20183421830_GOES16-ABI-FD-GEOCOLOR-1808x1808.jpg'
		}
		console.log(this.imageUrls[this.config.style]);
		if (this.config.ownImagePath != '') {
			this.url = this.config.ownImagePath;
		} else {
			if (this.config.imageSize > 800) {
				this.url = this.hiResImageUrls[this.config.style];
			} else {
				this.url = this.imageUrls[this.config.style];
			}
			setInterval(function () {
				self.updateDom(1000);
				console.log('update')
			}, this.config.updateInterval);
		}
	},

	getStyles: function () {
		return ["MMM-Globe.css"]
	},

	// Override dom generator.

	getDom: function () {
		var wrapper = document.createElement("div");
		if (this.config.style == "europeDiscNat") {
			wrapper.style.height = 0.98 * this.config.imageSize - 1 + "px";
			wrapper.style.overflow = "hidden";
		}

		var image = document.createElement("img");
		if (this.config.ownImagePath != '') {
			image.src = this.url;
		} else if (this.config.style == "centralAmericaDiscNat"){
			image.src = this.url + '?' + new Date().getTime();
			image.className = 'MMM-Globe-image-centralAmericaDiscNat';
		} else {
			image.src = this.url + '?' + new Date().getTime();
			image.className = 'MMM-Globe-image';
		}

		image.width = this.config.imageSize.toString();
		image.height = this.config.imageSize.toString();

		wrapper.appendChild(image);
		return wrapper;
	}
});
<commit_msg>Only return last successfully loaded image wrapper<commit_after>/* global Module */

/* Magic Mirror
 * Module: MMM-Globe
 *
 * By Luke Scheffler https://github.com/LukeSkywalker92
 * MIT Licensed.
 */

const loadImage = src =>
  new Promise(resolve => {
    const image = new Image();
    image.onload = () => resolve({ image, isError: false });
    image.onerror = () => resolve({ image, isError: true });
    image.src = src;
  });

let successfullyLoadedWrapper = null;

Module.register("MMM-Globe", {
  // Default module config.
  defaults: {
    style: "geoColor",
    imageSize: 600,
    ownImagePath: "",
    updateInterval: 10 * 60 * 1000
  },

  start: function() {
    self = this;
    this.url = "";
    this.imageUrls = {
      natColor:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_natural_color.jpg",
      geoColor:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_true_color.jpg",
      airMass:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/full_disk_ahi_rgb_airmass.jpg",
      fullBand:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/himawari-8_band_03_sector_02.gif",
      europeDiscNat:
        "http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBNatColour_LowResolution.jpg",
      europeDiscSnow:
        "http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBSolarDay_CentralEurope.jpg",
      centralAmericaDiscNat:
        "https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/20183421830_GOES16-ABI-FD-GEOCOLOR-678x678.jpg"
    };
    this.hiResImageUrls = {
      natColor:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_natural_color.jpg",
      geoColor:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_true_color.jpg",
      airMass:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest_hi_res/himawari-8/full_disk_ahi_rgb_airmass.jpg",
      fullBand:
        "http://rammb.cira.colostate.edu/ramsdis/online/images/latest/himawari-8/himawari-8_band_03_sector_02.gif",
      europeDiscNat:
        "http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBNatColour_LowResolution.jpg",
      europePartSnow:
        "http://oiswww.eumetsat.org/IPPS/html/latestImages/EUMETSAT_MSG_RGBSolarDay_CentralEurope.jpg",
      centralAmericaDiscNat:
        "https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/20183421830_GOES16-ABI-FD-GEOCOLOR-1808x1808.jpg"
    };
    console.log(this.imageUrls[this.config.style]);
    if (this.config.ownImagePath != "") {
      this.url = this.config.ownImagePath;
    } else {
      if (this.config.imageSize > 800) {
        this.url = this.hiResImageUrls[this.config.style];
      } else {
        this.url = this.imageUrls[this.config.style];
      }
      setInterval(function() {
        self.updateDom(1000);
        console.log("update");
      }, this.config.updateInterval);
    }
  },

  getStyles: function() {
    return ["MMM-Globe.css"];
  },

  // Override dom generator.

  getDom: async function() {
    var wrapper = document.createElement("div");
    if (this.config.style == "europeDiscNat") {
      wrapper.style.height = 0.98 * this.config.imageSize - 1 + "px";
      wrapper.style.overflow = "hidden";
    }

    const { image, isError } = await loadImage(
      this.url + "?" + new Date().getTime()
    );

    if (this.config.style === "centralAmericaDiscNat") {
      image.className = "MMM-Globe-image-centralAmericaDiscNat";
    } else {
      image.className = "MMM-Globe-image";
    }

    image.width = this.config.imageSize.toString();
    image.height = this.config.imageSize.toString();

    if (!isError) {
	  wrapper.appendChild(image);
	  successfullyLoadedWrapper = wrapper
	  return wrapper
    } else if (successfullyLoadedWrapper) {
		return successfullyLoadedWrapper
	}

    return document.createElement("div");
  }
});
<|endoftext|>


<commit_before>/**
 * Created by admin on 2.12.2016 г..
 */
/* globals module require */

'use strict';

const passport = require('passport');

function addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName) {
    let eventId=req.params.id;

    // TODO remove before production :)
    //console.log('getIncreaseParticipatingInEventButtonAction' + req.user.username);

    if (req.isAuthenticated()) {
        data.getEventById(eventId)
            .then((dbEvent)=>{
                // TODO remove before production :)
                //console.log('getIncreaseParticipatingInEventButtonAction-eventId' + dbEvent._id);

                return data.addUsernameToEventPropertyArray(dbEvent, req.user.username, propertyArrayName);
            })
            .then((dbEventUpdated) => {
                // TODO remove before production :)
                // console.log('getIncreaseParticipatingInEventButtonAction-eventId' + dbEventUpdated._id);

                res.redirect('/categories/' + dbEventUpdated.category + '/' + dbEventUpdated._id);
            })
            .catch((error)=>{
                res.render('error-page', {
                    user: res.user,
                    error: error
                });
            });
    } else {
        res.render('auth-not-authorised-page', {
            user: res.user
        });
    }
}

module.exports = (data) => {
    return {

        getCreateEventPage(req, res) {
            let categoryName = req.params.categoryName;

            if(!categoryName) {
                categoryName = 'ski';
            }

            if (req.isAuthenticated()) {
                res.render('./events/add-event-page', {
                    user: req.user,
                    category: categoryName
                });

                return;
            }

            res.render('auth-not-authorised-page');
        },

        getEventsPage(req, res){
            let categoryName=req.params.category;
            let eventId=req.params.id;

            console.log('categoryName: ' + categoryName);
            console.log('eventId: ' + eventId);

            if(!categoryName && !eventId){
                data.getAllEvents(req, res)
                    .then((events) => {
                        res.render('./events/all-categories-page', {
                            user: req.user,
                            category: 'all',
                            events: events
                        });
                    })
                    .catch((error) => {
                        throw error;
                    });

            } else if (categoryName && !eventId) {
                data.getEventByCategoryName(categoryName)
                    .then((events) => {
                        // TODO remove before production :)
                        //console.log(events);
                        res.render('./events/single-category-page', {
                            user: req.user,
                            category: categoryName,
                            events: events
                        });
                    })
                    .catch((error) => {
                        throw error;
                    });

            } else if (categoryName && eventId) {
                data.getEventByCategoryAndId(categoryName, eventId)
                    .then((event) => {
                        data.getLatestPicturesByCategory(event.category, 5)
                            .then((picturesFromGallery) => {
                                event['latestPicturesFromGallery'] = picturesFromGallery;

                                console.log(event.latestPicturesFromGallery);
                                //return event;

                                res.render('./events/single-event-page', {
                                            user: req.user,
                                            category: event.category,
                                            event: event
                                });
                            });

                    })
                    // .then((eventWithPicturesFromGallery) => {
                    //     // TODO remove before production :)
                    //     console.log(eventWithPicturesFromGallery);
                    //     res.render('./events/single-event-page', {
                    //         user: req.user,
                    //         category: event.category,
                    //         event: eventWithPicturesFromGallery
                    //     });
                    // })
                    .catch((error) => {
                        throw error;
                    });
            }
        },

        getIncreaseInterestedInEventButtonAction(req, res) {
            let propertyArrayName='interestedIn';
            addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName);
        },

        getIncreaseParticipatingInEventButtonAction(req, res) {
            let propertyArrayName='participatingIn';
            addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName);
        },

        createEvent(req, res) {
            let body = req.body,
                nowDt = new Date(),
                eventIsHidden = false,
                categoryName = req.params.categoryName,
                picture =  { src: req.body.eventPicture };

            data.createAndSaveEvent(body.title, categoryName, picture, req.user, body.body, nowDt, eventIsHidden, req)
                .then((dbEvent) => {

                    // res.redirect(201, '/categories/ski');
                    // res.status(400).send(err);
                    // res.redirect('/update-info');
                    // TODO remove before production :)
                    //console.log('createAndSaveEvent in controller - then-' + JSON.stringify(dbEvent));
                    data.putEventInUsersEvents(dbEvent, req.user, data.updateUserInfo);

                    return dbEvent;
                })
                .then((dbEvent)=>{
                    // TODO remove before production :)
                    //console.log('createAndSaveEvent in controller - thenthen-after putEventInUsersEvents');
                    // return data.addUsernameToEventSureParticipatingList(dbEvent, req.user.username);
                    return data.addUsernameToEventPropertyArray(dbEvent, req.user.username, 'participatingIn')
                })
                .then((dbEventUpdated)=>{
                    // TODO remove before production :)
                    console.log('after addUsernameToEventSureParticipatingList-' + JSON.stringify(dbEventUpdated));
                    res.redirect('/categories/ski');
                })
                .catch((error) => {
                    var statusCode = 400;

                    // TODO delete duplicated index and try to save event again
                    if(error.code == 11000) {
                        statusCode = 409;
                    }
                    //res.status(statusCode).send(error.errmsg);

                    res.render('error-page', {
                        user: res.user,
                        error: error
                    });

                });

        },

        createCommentToEventButtonAction(req, res) {

            if (!req.isAuthenticated()) {
                res.render('auth-not-authorised-page');
                return;
            }

            let body = req.body,
                nowDt = new Date(),
                commentIsHidden = false,
                categoryName = req.params.category,
                eventId = req.params.id,
                meta = { like: 0 };

            if (!body.comment.trim() || body.comment.length > 100) {
                res.redirect('/categories/' + categoryName + '/' + body.event._id);
                return;
            }

            console.log('createCommentToEventButtonAction');

            data.getEventById(eventId)
                .then((dbEvent) => {
                    return data.createCommentAndAddToEvent(dbEvent, data, req.user, body.comment, nowDt, commentIsHidden, meta)
                })
                .then((dbEventUpdated) => {
                    res.redirect('/events/' + dbEventUpdated.category + '/' + dbEventUpdated._id);
                })
                .catch((error) => {
                    res.render('error-page', {
                        user: res.user,
                        error: error
                    });
                });
        },
    };
};<commit_msg>bug fix url categories->events<commit_after>/**
 * Created by admin on 2.12.2016 г..
 */
/* globals module require */

'use strict';

const passport = require('passport');

function addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName) {
    let eventId=req.params.id;

    // TODO remove before production :)
    //console.log('getIncreaseParticipatingInEventButtonAction' + req.user.username);

    if (req.isAuthenticated()) {
        data.getEventById(eventId)
            .then((dbEvent)=>{
                // TODO remove before production :)
                //console.log('getIncreaseParticipatingInEventButtonAction-eventId' + dbEvent._id);

                return data.addUsernameToEventPropertyArray(dbEvent, req.user.username, propertyArrayName);
            })
            .then((dbEventUpdated) => {
                // TODO remove before production :)
                // console.log('getIncreaseParticipatingInEventButtonAction-eventId' + dbEventUpdated._id);

                res.redirect('/events/' + dbEventUpdated.category + '/' + dbEventUpdated._id);
            })
            .catch((error)=>{
                res.render('error-page', {
                    user: res.user,
                    error: error
                });
            });
    } else {
        res.render('auth-not-authorised-page', {
            user: res.user
        });
    }
}

module.exports = (data) => {
    return {

        getCreateEventPage(req, res) {
            let categoryName = req.params.categoryName;

            if(!categoryName) {
                categoryName = 'ski';
            }

            if (req.isAuthenticated()) {
                res.render('./events/add-event-page', {
                    user: req.user,
                    category: categoryName
                });

                return;
            }

            res.render('auth-not-authorised-page');
        },

        getEventsPage(req, res){
            let categoryName=req.params.category;
            let eventId=req.params.id;

            console.log('categoryName: ' + categoryName);
            console.log('eventId: ' + eventId);

            if(!categoryName && !eventId){
                data.getAllEvents(req, res)
                    .then((events) => {
                        data.getLatestPicturesByCategory('', 5)
                            .then((picturesFromGallery) => {
                                events['latestPicturesFromGallery'] = picturesFromGallery;

                                console.log('latestPicturesFromGallery-' + picturesFromGallery);

                                res.render('./events/all-categories-page', {
                                    user: req.user,
                                    category: 'all',
                                    events: events
                                });
                            })
                    })
                    .catch((error) => {
                        throw error;
                    });

            } else if (categoryName && !eventId) {
                console.log('getEventsPage');

                data.getEventByCategoryName(categoryName)
                    .then((events) => {
                        data.getLatestPicturesByCategory(categoryName, 5)
                            .then((picturesFromGallery) => {
                                events['latestPicturesFromGallery'] = picturesFromGallery;

                                // TODO remove before production :)
                                console.log('latestPicturesFromGallery' + events.latestPicturesFromGallery);

                                res.render('./events/single-category-page', {
                                    user: req.user,
                                    category: categoryName,
                                    events: events
                                });
                            });
                        // console.log('getEventsPage');
                        // res.render('./events/single-category-page', {
                        //     user: req.user,
                        //     category: categoryName,
                        //     events: events
                        // });
                    })
                    .catch((error) => {
                        throw error;
                    });

            } else if (categoryName && eventId) {
                data.getEventByCategoryAndId(categoryName, eventId)
                    .then((event) => {
                        data.getLatestPicturesByCategory(event.category, 5)
                            .then((picturesFromGallery) => {
                                event['latestPicturesFromGallery'] = picturesFromGallery;

                                console.log(event.latestPicturesFromGallery);
                                //return event;

                                res.render('./events/single-event-page', {
                                            user: req.user,
                                            category: event.category,
                                            event: event
                                });
                            });

                    })
                    // .then((eventWithPicturesFromGallery) => {
                    //     // TODO remove before production :)
                    //     console.log(eventWithPicturesFromGallery);
                    //     res.render('./events/single-event-page', {
                    //         user: req.user,
                    //         category: event.category,
                    //         event: eventWithPicturesFromGallery
                    //     });
                    // })
                    .catch((error) => {
                        throw error;
                    });
            }
        },

        getIncreaseInterestedInEventButtonAction(req, res) {
            let propertyArrayName='interestedIn';
            addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName);
        },

        getIncreaseParticipatingInEventButtonAction(req, res) {
            let propertyArrayName='participatingIn';
            addUsernameToEventPropertyArrayExecutor(req, res, data, propertyArrayName);
        },

        createEvent(req, res) {
            let body = req.body,
                nowDt = new Date(),
                eventIsHidden = false,
                categoryName = req.params.categoryName,
                picture =  { src: req.body.eventPicture };

            data.createAndSaveEvent(body.title, categoryName, picture, req.user, body.body, nowDt, eventIsHidden, req)
                .then((dbEvent) => {

                    // res.redirect(201, '/events/ski');
                    // res.status(400).send(err);
                    // res.redirect('/update-info');
                    // TODO remove before production :)
                    //console.log('createAndSaveEvent in controller - then-' + JSON.stringify(dbEvent));
                    data.putEventInUsersEvents(dbEvent, req.user, data.updateUserInfo);

                    return dbEvent;
                })
                .then((dbEvent)=>{
                    // TODO remove before production :)
                    //console.log('createAndSaveEvent in controller - thenthen-after putEventInUsersEvents');
                    // return data.addUsernameToEventSureParticipatingList(dbEvent, req.user.username);
                    return data.addUsernameToEventPropertyArray(dbEvent, req.user.username, 'participatingIn')
                })
                .then((dbEventUpdated)=>{
                    // TODO remove before production :)
                    console.log('after addUsernameToEventSureParticipatingList-' + JSON.stringify(dbEventUpdated));
                    res.redirect('/events/ski');
                })
                .catch((error) => {
                    var statusCode = 400;

                    // TODO delete duplicated index and try to save event again
                    if(error.code == 11000) {
                        statusCode = 409;
                    }
                    //res.status(statusCode).send(error.errmsg);

                    res.render('error-page', {
                        user: res.user,
                        error: error
                    });

                });

        },

        createCommentToEventButtonAction(req, res) {

            if (!req.isAuthenticated()) {
                res.render('auth-not-authorised-page');
                return;
            }

            let body = req.body,
                nowDt = new Date(),
                commentIsHidden = false,
                categoryName = req.params.category,
                eventId = req.params.id,
                meta = { like: 0 };

            if (!body.comment.trim() || body.comment.length > 100) {
                res.redirect('/events/' + categoryName + '/' + body.event._id);
                return;
            }

            console.log('createCommentToEventButtonAction');

            data.getEventById(eventId)
                .then((dbEvent) => {
                    return data.createCommentAndAddToEvent(dbEvent, data, req.user, body.comment, nowDt, commentIsHidden, meta)
                })
                .then((dbEventUpdated) => {
                    res.redirect('/events/' + dbEventUpdated.category + '/' + dbEventUpdated._id);
                })
                .catch((error) => {
                    res.render('error-page', {
                        user: res.user,
                        error: error
                    });
                });
        },
    };
};<|endoftext|>