<commit_before>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
import Vue from 'vue'
import CommonMixin from '../util/common-mixin'

/**
 * This module provides common properties used across various vue components related to attribute editting.
 */
export default {
  mixins: [CommonMixin],
  computed: {
    relevantAttributeData: {
      get() {
        return this.$store.state.zap.attributes
          .filter((a) => {
            let relevantList =
              a.side === 'client'
                ? this.selectionClients
                : this.selectionServers
            return relevantList.includes(this.selectedClusterId)
          })
          .filter((attribute) => {
            return this.individualClusterFilterString == ''
              ? true
              : attribute.label
                  .toLowerCase()
                  .includes(this.individualClusterFilterString.toLowerCase())
          })
      },
    },
    selection: {
      get() {
        return this.$store.state.zap.attributeView.selectedAttributes
      },
    },
    selectionSingleton: {
      get() {
        return this.$store.state.zap.attributeView.selectedSingleton
      },
    },
    selectionBounded: {
      get() {
        return this.$store.state.zap.attributeView.selectedBounded
      },
    },
    selectionStorageOption: {
      get() {
        return this.$store.state.zap.attributeView.storageOption
      },
    },
    selectionDefault: {
      get() {
        return this.$store.state.zap.attributeView.defaultValue
      },
    },
    selectedReporting: {
      get() {
        return this.$store.state.zap.attributeView.selectedReporting
      },
    },
    selectionMin: {
      get() {
        return this.$store.state.zap.attributeView.reportingMin
      },
    },
    selectionMax: {
      get() {
        return this.$store.state.zap.attributeView.reportingMax
      },
    },
    selectionReportableChange: {
      get() {
        return this.$store.state.zap.attributeView.reportableChange
      },
    },
    defaultValueValidation: {
      get() {
        return this.$store.state.zap.attributeView.defaultValueValidationIssues
      },
    },
    individualClusterFilterString: {
      get() {
        return this.$store.state.zap.clusterManager
          .individualClusterFilterString
      },
    },
  },
  watch:{
    selectedCluster(){
      const disabledAttributes = this.relevantAttributeData.filter( singleItem => {
        let indexOfValue = this.selection.indexOf(
          this.hashAttributeIdClusterId(singleItem.id, this.selectedCluster.id)
        )
        if (indexOfValue === -1) {
          return true
        } else {
          return false
        }
      });
      console.log('mehtest',disabledAttributes);
      // setTimeout(()=>{
        disabledAttributes.forEach(singleAttribute => {
          let editContext = {
            action: 'boolean',
            endpointTypeId: this.selectedEndpointTypeId,
            id: singleAttribute.id,
            value: false,
            listType: "selectedAttributes",
            clusterRef: this.selectedCluster.id,
            attributeSide: singleAttribute.side,
            reportMinInterval: singleAttribute.reportMinInterval,
            reportMaxInterval: singleAttribute.reportMaxInterval,
          }
          this.$store.dispatch('zap/updateSelectedAttribute', editContext)
      // },500)
    })
    }
  },
  methods: {
    handleLocalChange(localChanges, listType, attributeData, clusterId) {
      this.handleAttributeDefaultChange(
        localChanges,
        listType,
        attributeData,
        clusterId
      )
    },
    handleLocalSelection(selectedList, listType, attributeData, clusterId) {
      let hash = this.hashAttributeIdClusterId(attributeData.id, clusterId)

      this.setAttributeSelection(
        selectedList.includes(hash),
        listType,
        attributeData,
        clusterId
      )
    },
    setAttributeSelection(enable, listType, attributeData, clusterId) {
      let editContext = {
        action: 'boolean',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: enable,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
        reportableChange: attributeData.reportableChange,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
    },
    isDefaultValueValid(id) {
      return this.defaultValueValidation[id] != null
        ? this.defaultValueValidation[id].length === 0
        : true
    },
    getDefaultValueErrorMessage(id) {
      return this.defaultValueValidation[id] != null
        ? this.defaultValueValidation[id].reduce(
            (validationIssueString, currentVal) => {
              return validationIssueString + '\n' + currentVal
            },
            ''
          )
        : ''
    },
    initializeBooleanEditableList(
      originatingList,
      editableList,
      attrClusterHash
    ) {
      if (originatingList.includes(attrClusterHash)) {
        if (!editableList.includes(attrClusterHash)) {
          editableList.push(attrClusterHash)
        }
      } else {
        if (editableList.includes(attrClusterHash)) {
          let index = editableList.indexOf(attrClusterHash)
          editableList.splice(index, 1)
        }
      }
    },
    handleAttributeDefaultChange(newValue, listType, attributeData, clusterId) {
      // if (newValue) {
      let editContext = {
        action: 'text',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: newValue,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
      // }
    },
    toggleAttributeSelection(list, listType, attributeData, clusterId) {
      // We determine the ID that we need to toggle within the list.
      // This ID comes from hashing the base ZCL attribute and cluster data.
      let indexOfValue = list.indexOf(
        this.hashAttributeIdClusterId(attributeData.id, clusterId)
      )
      let addedValue
      if (indexOfValue === -1) {
        addedValue = true
      } else {
        addedValue = false
      }

      let editContext = {
        action: 'boolean',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: addedValue,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
    },

    initializeTextEditableList(originatingList, editableList, attrClusterHash) {
      let data = originatingList[attrClusterHash]
      editableList[attrClusterHash] = data
    },

    setEditableAttribute(attributeData, selectedClusterId) {
      let initContext = {
        action: 'init',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: 'init',
        listType: 'init',
        clusterRef: selectedClusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store
        .dispatch('zap/initSelectedAttribute', initContext)
        .then(() => {
          this.$store.dispatch('zap/setAttributeEditting', {
            attributeId: attributeData.id,
            editState: true,
          })
        })
    },
    setEditableAttributeReporting(attributeId, selectedClusterId) {
      this.$store.dispatch('zap/setAttributeReportingEditting', {
        attributeId: attributeId,
        editState: true,
      })
    },

    resetAttributeReporting(attributeId) {
      this.$store.dispatch('zap/setAttributeReportingEditting', {
        attributeId: attributeId,
        editState: false,
      })
    },
    resetAttribute(attributeId) {
      this.$store.dispatch('zap/setAttributeEditting', {
        attributeId: attributeId,
        editState: false,
      })
    },

    sortByText(x, y, ascendingA, ascendingB, callback = (i, j) => 0) {
      return x.toLowerCase() > y.toLowerCase()
        ? 1
        : x.toLowerCase() < y.toLowerCase()
        ? -1
        : callback(ascendingA, ascendingB)
    },
    sortByBoolean(
      x,
      y,
      ascendingA,
      ascendingB,
      singletonList,
      callback = (i, j) => 0
    ) {
      let i = this.hashAttributeIdClusterId(x.id, this.selectedCluster.id)
      let j = this.hashAttributeIdClusterId(y.id, this.selectedCluster.id)
      if (singletonList.indexOf(i) != -1 && singletonList.indexOf(j) != -1) {
        return callback(ascendingA, ascendingB)
      } else {
        if (singletonList.indexOf(i) != -1) return 1
        else if (singletonList.indexOf(j) != -1) return -1
        else return callback(ascendingA, ascendingB)
      }
    },

    sortByClusterAndManufacturerCode(x, y) {
      if (x['manufacturerCode'] == y['manufacturerCode']) {
        return x['code'] > y['code'] ? 1 : x['code'] < y['code'] ? -1 : 0
      } else {
        return x['manufacturerCode'] > y['manufacturerCode']
          ? 1
          : x['manufacturerCode'] < y['manufacturerCode']
          ? -1
          : 0
      }
    },
  },
}
<commit_msg>fixing minor issues<commit_after>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
import Vue from 'vue'
import CommonMixin from '../util/common-mixin'

/**
 * This module provides common properties used across various vue components related to attribute editting.
 */
export default {
  mixins: [CommonMixin],
  computed: {
    relevantAttributeData: {
      get() {
        return this.$store.state.zap.attributes
          .filter((a) => {
            let relevantList =
              a.side === 'client'
                ? this.selectionClients
                : this.selectionServers
            return relevantList.includes(this.selectedClusterId)
          })
          .filter((attribute) => {
            return this.individualClusterFilterString == ''
              ? true
              : attribute.label
                  .toLowerCase()
                  .includes(this.individualClusterFilterString.toLowerCase())
          })
      },
    },
    selection: {
      get() {
        return this.$store.state.zap.attributeView.selectedAttributes
      },
    },
    selectionSingleton: {
      get() {
        return this.$store.state.zap.attributeView.selectedSingleton
      },
    },
    selectionBounded: {
      get() {
        return this.$store.state.zap.attributeView.selectedBounded
      },
    },
    selectionStorageOption: {
      get() {
        return this.$store.state.zap.attributeView.storageOption
      },
    },
    selectionDefault: {
      get() {
        return this.$store.state.zap.attributeView.defaultValue
      },
    },
    selectedReporting: {
      get() {
        return this.$store.state.zap.attributeView.selectedReporting
      },
    },
    selectionMin: {
      get() {
        return this.$store.state.zap.attributeView.reportingMin
      },
    },
    selectionMax: {
      get() {
        return this.$store.state.zap.attributeView.reportingMax
      },
    },
    selectionReportableChange: {
      get() {
        return this.$store.state.zap.attributeView.reportableChange
      },
    },
    defaultValueValidation: {
      get() {
        return this.$store.state.zap.attributeView.defaultValueValidationIssues
      },
    },
    individualClusterFilterString: {
      get() {
        return this.$store.state.zap.clusterManager
          .individualClusterFilterString
      },
    },
  },
  watch:{
    selectedCluster(){
      const disabledAttributes = this.relevantAttributeData.filter( singleItem => {
        let indexOfValue = this.selection.indexOf(
          this.hashAttributeIdClusterId(singleItem.id, this.selectedCluster.id)
        )
        if (indexOfValue === -1) {
          return true
        } else {
          return false
        }
      });
        disabledAttributes.forEach(singleAttribute => {
          let editContext = {
            action: 'boolean',
            endpointTypeId: this.selectedEndpointTypeId,
            id: singleAttribute.id,
            value: false,
            listType: "selectedAttributes",
            clusterRef: this.selectedCluster.id,
            attributeSide: singleAttribute.side,
            reportMinInterval: singleAttribute.reportMinInterval,
            reportMaxInterval: singleAttribute.reportMaxInterval,
          }
          this.$store.dispatch('zap/updateSelectedAttribute', editContext)
    })
    }
  },
  methods: {
    handleLocalChange(localChanges, listType, attributeData, clusterId) {
      this.handleAttributeDefaultChange(
        localChanges,
        listType,
        attributeData,
        clusterId
      )
    },
    handleLocalSelection(selectedList, listType, attributeData, clusterId) {
      let hash = this.hashAttributeIdClusterId(attributeData.id, clusterId)

      this.setAttributeSelection(
        selectedList.includes(hash),
        listType,
        attributeData,
        clusterId
      )
    },
    setAttributeSelection(enable, listType, attributeData, clusterId) {
      let editContext = {
        action: 'boolean',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: enable,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
        reportableChange: attributeData.reportableChange,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
    },
    isDefaultValueValid(id) {
      return this.defaultValueValidation[id] != null
        ? this.defaultValueValidation[id].length === 0
        : true
    },
    getDefaultValueErrorMessage(id) {
      return this.defaultValueValidation[id] != null
        ? this.defaultValueValidation[id].reduce(
            (validationIssueString, currentVal) => {
              return validationIssueString + '\n' + currentVal
            },
            ''
          )
        : ''
    },
    initializeBooleanEditableList(
      originatingList,
      editableList,
      attrClusterHash
    ) {
      if (originatingList.includes(attrClusterHash)) {
        if (!editableList.includes(attrClusterHash)) {
          editableList.push(attrClusterHash)
        }
      } else {
        if (editableList.includes(attrClusterHash)) {
          let index = editableList.indexOf(attrClusterHash)
          editableList.splice(index, 1)
        }
      }
    },
    handleAttributeDefaultChange(newValue, listType, attributeData, clusterId) {
      // if (newValue) {
      let editContext = {
        action: 'text',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: newValue,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
      // }
    },
    toggleAttributeSelection(list, listType, attributeData, clusterId) {
      // We determine the ID that we need to toggle within the list.
      // This ID comes from hashing the base ZCL attribute and cluster data.
      let indexOfValue = list.indexOf(
        this.hashAttributeIdClusterId(attributeData.id, clusterId)
      )
      let addedValue
      if (indexOfValue === -1) {
        addedValue = true
      } else {
        addedValue = false
      }

      let editContext = {
        action: 'boolean',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: addedValue,
        listType: listType,
        clusterRef: clusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store.dispatch('zap/updateSelectedAttribute', editContext)
    },

    initializeTextEditableList(originatingList, editableList, attrClusterHash) {
      let data = originatingList[attrClusterHash]
      editableList[attrClusterHash] = data
    },

    setEditableAttribute(attributeData, selectedClusterId) {
      let initContext = {
        action: 'init',
        endpointTypeId: this.selectedEndpointTypeId,
        id: attributeData.id,
        value: 'init',
        listType: 'init',
        clusterRef: selectedClusterId,
        attributeSide: attributeData.side,
        reportMinInterval: attributeData.reportMinInterval,
        reportMaxInterval: attributeData.reportMaxInterval,
      }
      this.$store
        .dispatch('zap/initSelectedAttribute', initContext)
        .then(() => {
          this.$store.dispatch('zap/setAttributeEditting', {
            attributeId: attributeData.id,
            editState: true,
          })
        })
    },
    setEditableAttributeReporting(attributeId, selectedClusterId) {
      this.$store.dispatch('zap/setAttributeReportingEditting', {
        attributeId: attributeId,
        editState: true,
      })
    },

    resetAttributeReporting(attributeId) {
      this.$store.dispatch('zap/setAttributeReportingEditting', {
        attributeId: attributeId,
        editState: false,
      })
    },
    resetAttribute(attributeId) {
      this.$store.dispatch('zap/setAttributeEditting', {
        attributeId: attributeId,
        editState: false,
      })
    },

    sortByText(x, y, ascendingA, ascendingB, callback = (i, j) => 0) {
      return x.toLowerCase() > y.toLowerCase()
        ? 1
        : x.toLowerCase() < y.toLowerCase()
        ? -1
        : callback(ascendingA, ascendingB)
    },
    sortByBoolean(
      x,
      y,
      ascendingA,
      ascendingB,
      singletonList,
      callback = (i, j) => 0
    ) {
      let i = this.hashAttributeIdClusterId(x.id, this.selectedCluster.id)
      let j = this.hashAttributeIdClusterId(y.id, this.selectedCluster.id)
      if (singletonList.indexOf(i) != -1 && singletonList.indexOf(j) != -1) {
        return callback(ascendingA, ascendingB)
      } else {
        if (singletonList.indexOf(i) != -1) return 1
        else if (singletonList.indexOf(j) != -1) return -1
        else return callback(ascendingA, ascendingB)
      }
    },

    sortByClusterAndManufacturerCode(x, y) {
      if (x['manufacturerCode'] == y['manufacturerCode']) {
        return x['code'] > y['code'] ? 1 : x['code'] < y['code'] ? -1 : 0
      } else {
        return x['manufacturerCode'] > y['manufacturerCode']
          ? 1
          : x['manufacturerCode'] < y['manufacturerCode']
          ? -1
          : 0
      }
    },
  },
}
<|endoftext|>


<commit_before>/**
 *
 * @copyright Copyright (c) 2020, Daniel Calviño Sánchez (danxuliu@gmail.com)
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

if (window.MediaStream) {
	// Event implementations do not support advanced parameters like "options"
	// or "useCapture".
	const originalMediaStreamDispatchEvent = window.MediaStream.prototype.dispatchEvent
	const originalMediaStreamAddEventListener = window.MediaStream.prototype.addEventListener
	const originalMediaStreamRemoveEventListener = window.MediaStream.prototype.removeEventListener

	window.MediaStream.prototype.dispatchEvent = function(event) {
		if (this._listeners && this._listeners[event.type]) {
			this._listeners[event.type].forEach(listener => {
				listener.apply(this, [event])
			})
		}

		return originalMediaStreamDispatchEvent.apply(this, arguments)
	}

	let isMediaStreamDispatchEventSupported

	window.MediaStream.prototype.addEventListener = function(type, listener) {
		if (isMediaStreamDispatchEventSupported === undefined) {
			isMediaStreamDispatchEventSupported = false
			const testDispatchEventSupportHandler = () => {
				isMediaStreamDispatchEventSupported = true
			}
			originalMediaStreamAddEventListener.apply(this, ['test-dispatch-event-support', testDispatchEventSupportHandler])
			originalMediaStreamDispatchEvent.apply(this, [new Event('test-dispatch-event-support')])
			originalMediaStreamRemoveEventListener(this, ['test-dispatch-event-support', testDispatchEventSupportHandler])

			console.debug('Is MediaStream.dispatchEvent() supported?: ', isMediaStreamDispatchEventSupported)
		}

		if (!isMediaStreamDispatchEventSupported) {
			if (!this._listeners) {
				this._listeners = []
			}

			if (!this._listeners.hasOwnProperty(type)) {
				this._listeners[type] = [listener]
			} else if (!this._listeners[type].includes(listener)) {
				this._listeners[type].push(listener)
			}
		}

		return originalMediaStreamAddEventListener.apply(this, arguments)
	}

	window.MediaStream.prototype.removeEventListener = function(type, listener) {
		if (this._listeners && this._listeners[type]) {
			const index = this._listeners[type].indexOf(listener)
			if (index >= 0) {
				this._listeners[type].splice(index, 1)
			}
		}

		return originalMediaStreamRemoveEventListener.apply(this, arguments)
	}
}
<commit_msg>Dispatch "addtrack" and "removetrack" events in MediaStream shim<commit_after>/**
 *
 * @copyright Copyright (c) 2020, Daniel Calviño Sánchez (danxuliu@gmail.com)
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

if (window.MediaStream) {
	const originalMediaStreamAddTrack = window.MediaStream.prototype.addTrack
	window.MediaStream.prototype.addTrack = function(track) {
		let addTrackEventDispatched = false
		const testAddTrackEvent = () => {
			addTrackEventDispatched = true
		}
		this.addEventListener('addtrack', testAddTrackEvent)

		originalMediaStreamAddTrack.apply(this, arguments)

		this.removeEventListener('addtrack', testAddTrackEvent)

		if (!addTrackEventDispatched) {
			this.dispatchEvent(new MediaStreamTrackEvent('addtrack', { track: track }))
		}
	}

	const originalMediaStreamRemoveTrack = window.MediaStream.prototype.removeTrack
	window.MediaStream.prototype.removeTrack = function(track) {
		let removeTrackEventDispatched = false
		const testRemoveTrackEvent = () => {
			removeTrackEventDispatched = true
		}
		this.addEventListener('removetrack', testRemoveTrackEvent)

		originalMediaStreamRemoveTrack.apply(this, arguments)

		this.removeEventListener('removetrack', testRemoveTrackEvent)

		if (!removeTrackEventDispatched) {
			this.dispatchEvent(new MediaStreamTrackEvent('removetrack', { track: track }))
		}
	}

	// Event implementations do not support advanced parameters like "options"
	// or "useCapture".
	const originalMediaStreamDispatchEvent = window.MediaStream.prototype.dispatchEvent
	const originalMediaStreamAddEventListener = window.MediaStream.prototype.addEventListener
	const originalMediaStreamRemoveEventListener = window.MediaStream.prototype.removeEventListener

	window.MediaStream.prototype.dispatchEvent = function(event) {
		if (this._listeners && this._listeners[event.type]) {
			this._listeners[event.type].forEach(listener => {
				listener.apply(this, [event])
			})
		}

		return originalMediaStreamDispatchEvent.apply(this, arguments)
	}

	let isMediaStreamDispatchEventSupported

	window.MediaStream.prototype.addEventListener = function(type, listener) {
		if (isMediaStreamDispatchEventSupported === undefined) {
			isMediaStreamDispatchEventSupported = false
			const testDispatchEventSupportHandler = () => {
				isMediaStreamDispatchEventSupported = true
			}
			originalMediaStreamAddEventListener.apply(this, ['test-dispatch-event-support', testDispatchEventSupportHandler])
			originalMediaStreamDispatchEvent.apply(this, [new Event('test-dispatch-event-support')])
			originalMediaStreamRemoveEventListener(this, ['test-dispatch-event-support', testDispatchEventSupportHandler])

			console.debug('Is MediaStream.dispatchEvent() supported?: ', isMediaStreamDispatchEventSupported)
		}

		if (!isMediaStreamDispatchEventSupported) {
			if (!this._listeners) {
				this._listeners = []
			}

			if (!this._listeners.hasOwnProperty(type)) {
				this._listeners[type] = [listener]
			} else if (!this._listeners[type].includes(listener)) {
				this._listeners[type].push(listener)
			}
		}

		return originalMediaStreamAddEventListener.apply(this, arguments)
	}

	window.MediaStream.prototype.removeEventListener = function(type, listener) {
		if (this._listeners && this._listeners[type]) {
			const index = this._listeners[type].indexOf(listener)
			if (index >= 0) {
				this._listeners[type].splice(index, 1)
			}
		}

		return originalMediaStreamRemoveEventListener.apply(this, arguments)
	}
}
<|endoftext|>


<commit_before>export default function Viewmodel$clearCache ( keypath, dontTeardownWrapper ) {
	var cacheMap, wrapper, computation;

	if ( !dontTeardownWrapper ) {
		// Is there a wrapped property at this keypath?
		if ( wrapper = this.wrapped[ keypath ] ) {
			// Did we unwrap it?
			if ( wrapper.teardown() !== false ) {
				// Is this right?
				// What's the meaning of returning false from teardown?
				// Could there be a GC ramification if this is a "real" ractive.teardown()?
				this.wrapped[ keypath ] = null;
			}
		}
	}

	this.cache[ keypath ] = undefined;

	if ( cacheMap = this.cacheMap[ keypath ] ) {
		while ( cacheMap.length ) {
			this.clearCache( cacheMap.pop() );
		}
	}
}
<commit_msg>linting<commit_after>export default function Viewmodel$clearCache ( keypath, dontTeardownWrapper ) {
	var cacheMap, wrapper;

	if ( !dontTeardownWrapper ) {
		// Is there a wrapped property at this keypath?
		if ( wrapper = this.wrapped[ keypath ] ) {
			// Did we unwrap it?
			if ( wrapper.teardown() !== false ) {
				// Is this right?
				// What's the meaning of returning false from teardown?
				// Could there be a GC ramification if this is a "real" ractive.teardown()?
				this.wrapped[ keypath ] = null;
			}
		}
	}

	this.cache[ keypath ] = undefined;

	if ( cacheMap = this.cacheMap[ keypath ] ) {
		while ( cacheMap.length ) {
			this.clearCache( cacheMap.pop() );
		}
	}
}
<|endoftext|>


<commit_before>'use strict';

var mongodb = require('mongodb');
var connection = null;
var MongoClient = mongodb.MongoClient;
var mongo = {};

function init (env, cb, forceNewConnection) {

  function maybe_connect (cb) {

    if (connection != null && !forceNewConnection) {
      console.log('Reusing MongoDB connection handler');
      // If there is a valid callback, then return the Mongo-object
      mongo.db = connection;

      if (cb && cb.call) {
        cb(null, mongo);
      }
    } else {
      if (!env.storageURI) {
        throw new Error('MongoDB connection string is missing. Please set MONGODB_URI environment variable');
      }

      console.log('Setting up new connection to MongoDB');
      var timeout = 30 * 1000;
      var options = {
        reconnectInterval: 10000
        , reconnectTries: 500
        , connectTimeoutMS: timeout
        , socketTimeoutMS: timeout
        , useNewUrlParser: true
      };

      var connect_with_retry = function(i) {

        MongoClient.connect(env.storageURI, options)
          .then(client => {
              console.log('Successfully established a connected to MongoDB');

              var dbName = env.storageURI.split('/').pop().split('?');
              dbName = dbName[0]; // drop Connection Options
              mongo.db = client.db(dbName);
              connection = mongo.db;
              mongo.client = client;
              // If there is a valid callback, then invoke the function to perform the callback

              if (cb && cb.call) {
                cb(null, mongo);
              }
            })
            .catch(err => {
              if (err.message && err.message.includes('AuthenticationFailed')) {
                console.log('Authentication to Mongo failed');
                cb(new Error('MongoDB authentication failed! Double check the URL has the right username and password in MONGO_CONNECTION.'), null);
                return;
              }

              if (err.name && err.name === "MongoNetworkError") {
                var timeout = (i > 15) ? 60000 : i * 3000;
                console.log('Error connecting to MongoDB: %j - retrying in ' + timeout / 1000 + ' sec', err);
                setTimeout(connect_with_retry, timeout, i + 1);
                if (i == 1) cb(new Error('MongoDB authentication failed! Double check the MONGO_CONNECTION setting in Heroku.'), null);
              } else {
                cb(new Error('MONGODB_URI ' + env.storageURI + ' seems invalid: ' + err.message));
              }
            });

          };

        return connect_with_retry(1);

      }
    }

    mongo.collection = function get_collection (name) {
      return connection.collection(name);
    };

    mongo.ensureIndexes = function ensureIndexes (collection, fields) {
      fields.forEach(function(field) {
        console.info('ensuring index for: ' + field);
        collection.createIndex(field, { 'background': true }, function(err) {
          if (err) {
            console.error('unable to ensureIndex for: ' + field + ' - ' + err);
          }
        });
      });
    };

    return maybe_connect(cb);
  }

  module.exports = init;
<commit_msg>Fix MONGODB_URI reference in error message<commit_after>'use strict';

var mongodb = require('mongodb');
var connection = null;
var MongoClient = mongodb.MongoClient;
var mongo = {};

function init (env, cb, forceNewConnection) {

  function maybe_connect (cb) {

    if (connection != null && !forceNewConnection) {
      console.log('Reusing MongoDB connection handler');
      // If there is a valid callback, then return the Mongo-object
      mongo.db = connection;

      if (cb && cb.call) {
        cb(null, mongo);
      }
    } else {
      if (!env.storageURI) {
        throw new Error('MongoDB connection string is missing. Please set MONGODB_URI environment variable');
      }

      console.log('Setting up new connection to MongoDB');
      var timeout = 30 * 1000;
      var options = {
        reconnectInterval: 10000
        , reconnectTries: 500
        , connectTimeoutMS: timeout
        , socketTimeoutMS: timeout
        , useNewUrlParser: true
      };

      var connect_with_retry = function(i) {

        MongoClient.connect(env.storageURI, options)
          .then(client => {
              console.log('Successfully established a connected to MongoDB');

              var dbName = env.storageURI.split('/').pop().split('?');
              dbName = dbName[0]; // drop Connection Options
              mongo.db = client.db(dbName);
              connection = mongo.db;
              mongo.client = client;
              // If there is a valid callback, then invoke the function to perform the callback

              if (cb && cb.call) {
                cb(null, mongo);
              }
            })
            .catch(err => {
              if (err.message && err.message.includes('AuthenticationFailed')) {
                console.log('Authentication to Mongo failed');
                cb(new Error('MongoDB authentication failed! Double check the URL has the right username and password in MONGODB_URI.'), null);
                return;
              }

              if (err.name && err.name === "MongoNetworkError") {
                var timeout = (i > 15) ? 60000 : i * 3000;
                console.log('Error connecting to MongoDB: %j - retrying in ' + timeout / 1000 + ' sec', err);
                setTimeout(connect_with_retry, timeout, i + 1);
                if (i == 1) cb(new Error('MongoDB connection failed! Double check the MONGODB_URI setting in Heroku.'), null);
              } else {
                cb(new Error('MONGODB_URI ' + env.storageURI + ' seems invalid: ' + err.message));
              }
            });

          };

        return connect_with_retry(1);

      }
    }

    mongo.collection = function get_collection (name) {
      return connection.collection(name);
    };

    mongo.ensureIndexes = function ensureIndexes (collection, fields) {
      fields.forEach(function(field) {
        console.info('ensuring index for: ' + field);
        collection.createIndex(field, { 'background': true }, function(err) {
          if (err) {
            console.error('unable to ensureIndex for: ' + field + ' - ' + err);
          }
        });
      });
    };

    return maybe_connect(cb);
  }

  module.exports = init;
<|endoftext|>


<commit_before>/**
* @class
*/
OpenLayers.Icon = Class.create();
OpenLayers.Icon.prototype = {

    /** image url
    * @type String */
    url: null,

    /** @type OpenLayers.Size */
    size:null,

    /** distance in pixels to offset the image when being rendered
    * @type OpenLayers.Pixel */
    offset: null,

    /**
    * @constructor
    *
    * @param {String} url
    * @param {OpenLayers.Size} size
    * @param {OpenLayers.Pixel} offset
    */
    initialize: function(url, size, offset) {
        this.size = size;
        this.url = url;

        this.offset = offset;
        if (offset == null) {
            // default offset
            this.offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
        }

    },

    /**
    * @returns A fresh copy of the icon.
    * @type OpenLayers.Icon
    */
    clone: function() {
        return new OpenLayers.Icon(this.size, this.url, this.offset);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Icon"
}
<commit_msg>need to make sure a size has been declared before trying to set the offset. thank you automated testing for finding this one.<commit_after>/**
* @class
*/
OpenLayers.Icon = Class.create();
OpenLayers.Icon.prototype = {

    /** image url
    * @type String */
    url: null,

    /** @type OpenLayers.Size */
    size:null,

    /** distance in pixels to offset the image when being rendered
    * @type OpenLayers.Pixel */
    offset: null,

    /**
    * @constructor
    *
    * @param {String} url
    * @param {OpenLayers.Size} size
    * @param {OpenLayers.Pixel} offset
    */
    initialize: function(url, size, offset) {
        this.size = size;
        this.url = url;

        this.offset = offset;
        if ((size != null) && (offset == null)) {
            // default offset
            this.offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
        }

    },

    /**
    * @returns A fresh copy of the icon.
    * @type OpenLayers.Icon
    */
    clone: function() {
        return new OpenLayers.Icon(this.size, this.url, this.offset);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Icon"
}
<|endoftext|>


<commit_before>Vps.Connection = Ext.extend(Ext.data.Connection, {
    _progressData    : { },

    /**
     * Options:
     * - mask (true für body, sonst element)
     * - maskText (default Loading...)
     * - progress
     * - progressTitle (default Progress)
     * - ignoreErrors (don't show error messages, but call failure callback)
     */
    request: function(options)
    {

        Vps.requestSentSinceLastKeepAlive = true;
        Vps.Connection.runningRequests++;

        if (options.mask) {
            if (options.mask instanceof Ext.Element) {
                options.mask.mask(options.maskText || trlVps('Loading...'));
            } else {
                if (Vps.Connection.masks == 0) {
                    if (Ext.get('loading')) {
                        Ext.getBody().mask();
                    } else {
                        Ext.getBody().mask(options.maskText || trlVps('Loading...'));
                    }
                }
                Vps.Connection.masks++;
            }
        }

        if (options.url.match(/[\/a-zA-Z0-9]*\/json[a-zA-Z0-9\-]+(\/|\?|)/)) {
            options.vpsCallback = {
                success: options.success,
                failure: options.failure,
                callback: options.callback,
                scope: options.scope
            };
            options.success = this.vpsJsonSuccess;
            options.failure = this.vpsJsonFailure;
            options.callback = this.vpsCallback;
            options.scope = this;
        } else {
            options.vpsCallback = {
                success: options.success,
                failure: options.failure,
                callback: options.callback,
                scope: options.scope
            };
            options.success = this.vpsNoJsonSuccess;
            options.failure = this.vpsNoJsonFailure;
            options.callback = this.vpsCallback;
            options.scope = this;
        }
        if (!options.params) options.params = {};
        options.params.application_max_assets_mtime = Vps.application.maxAssetsMTime;
        if (!options.url.match(':\/\/')) {
            //absolute url incl. http:// erstellen
            //wird benötigt wenn fkt über mozrepl aufgerufen wird
            var u = location.protocol + '/'+'/' + location.host;
            if (options.url.substr(0, 1) == '/') {
                options.url = u + options.url;
            } else {
                options.url = u + '/' + options.url;
            }
        }

        if (options.progress) {
            var progressNum = Math.floor(Math.random() * 1000000000) + 1;
            options.params.progressNum = progressNum;
        }

        var ret = Vps.Connection.superclass.request.call(this, options);

        if (options.progress) {
            this._showProgress(options);
        }

        return ret;
    },

    _showProgress: function(options)
    {
        var progressNum = options.params.progressNum;

        this._progressData[progressNum] = {
            progressBar: this._createProgressDialog({
                title: options.progressTitle || trlVps('Progress'),
                transId: this.transId,
                requestOptions: options,
                showCancel: options.showCancel
            }),
            breakStatusRequests: false
        };
        this._progressData[progressNum].progressBar.updateProgress(0, '0%', '');

        this._doProgressStatusRequest.defer(1500, this, [ progressNum ]);
    },

    _doProgressStatusRequest: function(progressNum)
    {
        this.request({
            url: '/vps/json-progress-status',
            params: { progressNum: progressNum },
            success: function(response, options, r) {
                var progressNum = options.params.progressNum;
                if (!this._progressData[progressNum]) return;

                if (typeof r.finished != 'undefined') {
                    if (r.finished) {
                        this._progressData[progressNum].progressBar.updateProgress(
                            1, '100%', trlVps('Finished')
                        );
                        return;
                    }

                    this._progressData[progressNum].progressBar.updateProgress(
                        r.percent / 100,
                        Math.floor(r.percent)+'%',
                        r.text ? r.text : ''
                    );
                }

                if (!this._progressData[progressNum].breakStatusRequests) {
                    // recursing
                    this._doProgressStatusRequest.defer(500, this, [ progressNum ]);
                }
            },
            scope: this
        });
    },

    _createProgressDialog: function(cfg)
    {
        var progressBar = new Ext.ProgressBar({
            text:'0%',
            animate: true
        });
        cfg = Ext.applyIf(cfg, {
            title: trlVps('Progress'),
            autoCreate : true,
            resizable:false,
            constrain:true,
            constrainHeader:true,
            minimizable : false,
            maximizable : false,
            stateful: false,
            modal: true,
            shim:true,
            buttonAlign:"center",
            width:400,
            plain:true,
            footer:true,
            closable:false
        });
        var dlg = new Ext.Window(cfg);

        if (typeof cfg.showCancel == 'undefined' || cfg.showCancel) {
            dlg.addButton(
                { text: trlVps('Cancel') },
                (function(dialog) {
                    Ext.Ajax.abort(dialog.transId);

                    var responseObject = Ext.lib.Ajax.createExceptionObject(
                        dialog.transId, null, true
                    );
                    Ext.callback(
                        dialog.requestOptions.vpsCallback.failure,
                        dialog.requestOptions.vpsCallback.scope,
                        [responseObject, dialog.requestOptions]
                    );
                    dialog.requestOptions.callback.call(
                        this,
                        dialog.requestOptions,
                        false,
                        responseObject
                    );
                }).createDelegate(this, [ dlg ])
            );
        }

        dlg.render(document.body);
        dlg.myEls = { };
        dlg.myEls.bodyEl = dlg.body.createChild({
            html:'

'
        });
        dlg.myEls.bodyEl.addClass('vps-progress-window');
        dlg.myEls.msgEl = Ext.get(dlg.myEls.bodyEl.dom.childNodes[0].firstChild);

        dlg.progressBar = new Ext.ProgressBar({
            renderTo:dlg.myEls.bodyEl,
            text: '0%',
            animate: true
        });
        dlg.myEls.bodyEl.createChild({cls:'x-clear'});

        dlg.updateProgress = function(num, progressBarText, text)
        {
            this.progressBar.updateProgress(num, progressBarText, true);
            this.myEls.msgEl.update(text || ' ');
        };

        dlg.show();
        return dlg;
    },

    repeatRequest: function(options) {
        Vps.Connection.runningRequests++;
        delete options.vpsIsSuccess;
        Vps.Connection.superclass.request.call(this, options);
        if (options.progress) {
            this._showProgress(options);
        }
    },
    vpsJsonSuccess: function(response, options)
    {
        options.vpsIsSuccess = false;
        options.vpsLogin = false;

        var errorMsg = false;

        var encParams;
        if (typeof options.params == "string") {
            encParams = options.params;
        } else {
            encParams = Ext.urlEncode(options.params);
        }
        try {
            if (!response.responseText) {
                errorMsg = 'response is empty';
            } else {
                var r = Ext.decode(response.responseText);
            }
        } catch(e) {
            errorMsg = e.toString()+':
'+response.responseText;
            var errorMsgTitle = 'Javascript Parse Exception';
        }
        if (Vps.Debug.querylog && r && r.requestNum) {
            var rm = location.protocol + '/'+'/' + location.host;
            var url = options.url;
            if (url.substr(0, rm.length) == rm) {
                url = url.substr(rm.length);
            }
            var data = [[new Date(), url, encParams, r.requestNum]];
            Vps.Debug.requestsStore.loadData(data, true);
        }
        if (!errorMsg && r.exception) {
            var p;
            if (typeof options.params == "string") {
                p = options.params;
            } else {
                p = Ext.urlEncode(options.params);
            }
            errorMsg = '
'+r.exception+'
';
            var errorMsgTitle = 'PHP Exception';
        }
        if (errorMsg) {
            errorMsg = 'request-url
' + errorMsg;
            var sendMail = !r || !r.exception;
            if (options.errorText) {
                errorText = options.errorText;
            } else {
                errorText = null;
            }
            if (options.ignoreErrors) {
                Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
            } else {
                Vps.handleError({
                    url: options.url,
                    message: errorMsg,
                    title: errorMsgTitle,
                    mail: sendMail,
                    errorText: errorText,
                    checkRetry: false,
                    retry: function() {
                        this.connection.repeatRequest(this.options);
                    },
                    abort: function() {
                        Ext.callback(this.options.vpsCallback.failure, this.options.vpsCallback.scope, [this.response, this.options]);
                    },
                    scope: { connection: this, options: options, response: response }
                });
            }
            return;
        }

        if (!r.success) {
            if (r.wrongversion && !options.ignoreErrors) {
                var dlg = new Ext.Window({
                    autoCreate : true,
                    title: trlVps('Error - wrong version'),
                    resizable: false,
                    modal: true,
                    buttonAlign:"center",
                    width:250,
                    height:100,
                    plain:true,
                    closable: false,
                    html: trlVps('Because of an application update the application has to be reloaded.'),
                    buttons: [{
                        text: trlVps('OK'),
                        handler: function() {
                            location.reload();
                        },
                        scope: this
                    }, {
                        text: trlVps('Ignore'),
                        handler: function() {
                            Vps.application.maxAssetsMTime = r.maxAssetsMTime;
                            options.params.application_max_assets_mtime = Vps.application.maxAssetsMTime;
                            this.repeatRequest(options);
                        },
                        scope: this
                    }]
                });
                dlg.show();
                dlg.getEl().addClass('x-window-dlg');
                return;
            }
            if (r.login && !options.ignoreErrors) {
                options.vpsLogin = true;
                var dlg = new Vps.User.Login.Dialog({
                    message: r.message,
                    success: function() {
                        //redo action...
                        this.repeatRequest(options);
                    },
                    scope: this
                });
                Ext.getBody().unmask();
                dlg.showLogin();
                return;
            }
            if (!options.ignoreErrors) {
                if (r.error) {
                    Ext.Msg.alert(trlVps('Error'), r.error);
                } else {
                    Ext.Msg.alert(trlVps('Error'), trlVps("A Server failure occured."));
                }
            }
            Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
            return;
        }
        options.vpsIsSuccess = true;
        if (options.vpsCallback.success) {
            options.vpsCallback.success.call(options.vpsCallback.scope, response, options, r);
        }
    },
    vpsNoJsonSuccess: function(response, options)
    {
        options.vpsIsSuccess = true;
        if (options.vpsCallback.success) {
            options.vpsCallback.success.call(options.vpsCallback.scope, response, options);
        }
    },
    vpsNoJsonFailure: function(response, options)
    {
        options.vpsIsSuccess = false;
        if (options.vpsCallback.failure) {
            options.vpsCallback.failure.call(options.vpsCallback.scope, response, options);
        }
    },
    vpsJsonFailure: function(response, options)
    {
        options.vpsIsSuccess = false;

        errorMsgTitle = trlVps('Error');
        if (options.errorText) {
            errorText = options.errorText;
            errorMsg = options.errorText;
        } else {
            errorMsg = trlVps("A connection problem occured.");
            errorText = null;
        }
        if (options.ignoreErrors) {
            Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
        } else {
            Vps.handleError({
                url: options.url,
                message: errorMsg,
                title: errorMsgTitle,
                errorText: errorText,
                mail: false,
                checkRetry: true,
                retry: function() {
                    this.repeatRequest(options);
                },
                abort: function() {
                    Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
                },
                scope: this
            });
        }
    },

    vpsCallback: function(options, success, response)
    {
        //wenn login-fenster angezeigt wird keinen callback aufrufen - weil der request
        //wird ja erneut gesendet und da dann der callback aufgerufen.
        if (options.vpsLogin) return;

        if (options.mask) {
            if (options.mask instanceof Ext.Element) {
                options.mask.unmask();
            } else {
                Vps.Connection.masks--;
                if (Vps.Connection.masks == 0) {
                    Ext.getBody().unmask();
                    if (Ext.get('loading')) {
                        Ext.get('loading').fadeOut({remove: true});
                    }
                }
            }
        }

        if (options.progress) {
            this._progressData[options.params.progressNum].progressBar.hide();
            delete this._progressData[options.params.progressNum];
        }

        if(success && !options.vpsIsSuccess) {
            success = false;
        }
        Ext.callback(options.vpsCallback.callback, options.vpsCallback.scope, [options, success, response]);
        Vps.Connection.runningRequests--;
    }
});
Vps.Connection.masks = 0; //static var that hols number of masked requests
Vps.Connection.runningRequests = 0;

Ext.Ajax = new Vps.Connection({
    /**
     * The timeout in milliseconds to be used for requests. (defaults
     * to 30000)
     * @type Number
     * @property  timeout
     */
    autoAbort : false,

    /**
     * Serialize the passed form into a url encoded string
     * @return {String}
     */
    serializeForm : function(form){
        return Ext.lib.Ajax.serializeForm(form);
    }
});

<commit_msg>hide dialog after ignore<commit_after>Vps.Connection = Ext.extend(Ext.data.Connection, {
    _progressData    : { },

    /**
     * Options:
     * - mask (true für body, sonst element)
     * - maskText (default Loading...)
     * - progress
     * - progressTitle (default Progress)
     * - ignoreErrors (don't show error messages, but call failure callback)
     */
    request: function(options)
    {

        Vps.requestSentSinceLastKeepAlive = true;
        Vps.Connection.runningRequests++;

        if (options.mask) {
            if (options.mask instanceof Ext.Element) {
                options.mask.mask(options.maskText || trlVps('Loading...'));
            } else {
                if (Vps.Connection.masks == 0) {
                    if (Ext.get('loading')) {
                        Ext.getBody().mask();
                    } else {
                        Ext.getBody().mask(options.maskText || trlVps('Loading...'));
                    }
                }
                Vps.Connection.masks++;
            }
        }

        if (options.url.match(/[\/a-zA-Z0-9]*\/json[a-zA-Z0-9\-]+(\/|\?|)/)) {
            options.vpsCallback = {
                success: options.success,
                failure: options.failure,
                callback: options.callback,
                scope: options.scope
            };
            options.success = this.vpsJsonSuccess;
            options.failure = this.vpsJsonFailure;
            options.callback = this.vpsCallback;
            options.scope = this;
        } else {
            options.vpsCallback = {
                success: options.success,
                failure: options.failure,
                callback: options.callback,
                scope: options.scope
            };
            options.success = this.vpsNoJsonSuccess;
            options.failure = this.vpsNoJsonFailure;
            options.callback = this.vpsCallback;
            options.scope = this;
        }
        if (!options.params) options.params = {};
        options.params.application_max_assets_mtime = Vps.application.maxAssetsMTime;
        if (!options.url.match(':\/\/')) {
            //absolute url incl. http:// erstellen
            //wird benötigt wenn fkt über mozrepl aufgerufen wird
            var u = location.protocol + '/'+'/' + location.host;
            if (options.url.substr(0, 1) == '/') {
                options.url = u + options.url;
            } else {
                options.url = u + '/' + options.url;
            }
        }

        if (options.progress) {
            var progressNum = Math.floor(Math.random() * 1000000000) + 1;
            options.params.progressNum = progressNum;
        }

        var ret = Vps.Connection.superclass.request.call(this, options);

        if (options.progress) {
            this._showProgress(options);
        }

        return ret;
    },

    _showProgress: function(options)
    {
        var progressNum = options.params.progressNum;

        this._progressData[progressNum] = {
            progressBar: this._createProgressDialog({
                title: options.progressTitle || trlVps('Progress'),
                transId: this.transId,
                requestOptions: options,
                showCancel: options.showCancel
            }),
            breakStatusRequests: false
        };
        this._progressData[progressNum].progressBar.updateProgress(0, '0%', '');

        this._doProgressStatusRequest.defer(1500, this, [ progressNum ]);
    },

    _doProgressStatusRequest: function(progressNum)
    {
        this.request({
            url: '/vps/json-progress-status',
            params: { progressNum: progressNum },
            success: function(response, options, r) {
                var progressNum = options.params.progressNum;
                if (!this._progressData[progressNum]) return;

                if (typeof r.finished != 'undefined') {
                    if (r.finished) {
                        this._progressData[progressNum].progressBar.updateProgress(
                            1, '100%', trlVps('Finished')
                        );
                        return;
                    }

                    this._progressData[progressNum].progressBar.updateProgress(
                        r.percent / 100,
                        Math.floor(r.percent)+'%',
                        r.text ? r.text : ''
                    );
                }

                if (!this._progressData[progressNum].breakStatusRequests) {
                    // recursing
                    this._doProgressStatusRequest.defer(500, this, [ progressNum ]);
                }
            },
            scope: this
        });
    },

    _createProgressDialog: function(cfg)
    {
        var progressBar = new Ext.ProgressBar({
            text:'0%',
            animate: true
        });
        cfg = Ext.applyIf(cfg, {
            title: trlVps('Progress'),
            autoCreate : true,
            resizable:false,
            constrain:true,
            constrainHeader:true,
            minimizable : false,
            maximizable : false,
            stateful: false,
            modal: true,
            shim:true,
            buttonAlign:"center",
            width:400,
            plain:true,
            footer:true,
            closable:false
        });
        var dlg = new Ext.Window(cfg);

        if (typeof cfg.showCancel == 'undefined' || cfg.showCancel) {
            dlg.addButton(
                { text: trlVps('Cancel') },
                (function(dialog) {
                    Ext.Ajax.abort(dialog.transId);

                    var responseObject = Ext.lib.Ajax.createExceptionObject(
                        dialog.transId, null, true
                    );
                    Ext.callback(
                        dialog.requestOptions.vpsCallback.failure,
                        dialog.requestOptions.vpsCallback.scope,
                        [responseObject, dialog.requestOptions]
                    );
                    dialog.requestOptions.callback.call(
                        this,
                        dialog.requestOptions,
                        false,
                        responseObject
                    );
                }).createDelegate(this, [ dlg ])
            );
        }

        dlg.render(document.body);
        dlg.myEls = { };
        dlg.myEls.bodyEl = dlg.body.createChild({
            html:'

'
        });
        dlg.myEls.bodyEl.addClass('vps-progress-window');
        dlg.myEls.msgEl = Ext.get(dlg.myEls.bodyEl.dom.childNodes[0].firstChild);

        dlg.progressBar = new Ext.ProgressBar({
            renderTo:dlg.myEls.bodyEl,
            text: '0%',
            animate: true
        });
        dlg.myEls.bodyEl.createChild({cls:'x-clear'});

        dlg.updateProgress = function(num, progressBarText, text)
        {
            this.progressBar.updateProgress(num, progressBarText, true);
            this.myEls.msgEl.update(text || ' ');
        };

        dlg.show();
        return dlg;
    },

    repeatRequest: function(options) {
        Vps.Connection.runningRequests++;
        delete options.vpsIsSuccess;
        Vps.Connection.superclass.request.call(this, options);
        if (options.progress) {
            this._showProgress(options);
        }
    },
    vpsJsonSuccess: function(response, options)
    {
        options.vpsIsSuccess = false;
        options.vpsLogin = false;

        var errorMsg = false;

        var encParams;
        if (typeof options.params == "string") {
            encParams = options.params;
        } else {
            encParams = Ext.urlEncode(options.params);
        }
        try {
            if (!response.responseText) {
                errorMsg = 'response is empty';
            } else {
                var r = Ext.decode(response.responseText);
            }
        } catch(e) {
            errorMsg = e.toString()+':
'+response.responseText;
            var errorMsgTitle = 'Javascript Parse Exception';
        }
        if (Vps.Debug.querylog && r && r.requestNum) {
            var rm = location.protocol + '/'+'/' + location.host;
            var url = options.url;
            if (url.substr(0, rm.length) == rm) {
                url = url.substr(rm.length);
            }
            var data = [[new Date(), url, encParams, r.requestNum]];
            Vps.Debug.requestsStore.loadData(data, true);
        }
        if (!errorMsg && r.exception) {
            var p;
            if (typeof options.params == "string") {
                p = options.params;
            } else {
                p = Ext.urlEncode(options.params);
            }
            errorMsg = '
'+r.exception+'
';
            var errorMsgTitle = 'PHP Exception';
        }
        if (errorMsg) {
            errorMsg = 'request-url
' + errorMsg;
            var sendMail = !r || !r.exception;
            if (options.errorText) {
                errorText = options.errorText;
            } else {
                errorText = null;
            }
            if (options.ignoreErrors) {
                Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
            } else {
                Vps.handleError({
                    url: options.url,
                    message: errorMsg,
                    title: errorMsgTitle,
                    mail: sendMail,
                    errorText: errorText,
                    checkRetry: false,
                    retry: function() {
                        this.connection.repeatRequest(this.options);
                    },
                    abort: function() {
                        Ext.callback(this.options.vpsCallback.failure, this.options.vpsCallback.scope, [this.response, this.options]);
                    },
                    scope: { connection: this, options: options, response: response }
                });
            }
            return;
        }

        if (!r.success) {
            if (r.wrongversion && !options.ignoreErrors) {
                var dlg = new Ext.Window({
                    autoCreate : true,
                    title: trlVps('Error - wrong version'),
                    resizable: false,
                    modal: true,
                    buttonAlign:"center",
                    width:250,
                    height:100,
                    plain:true,
                    closable: false,
                    html: trlVps('Because of an application update the application has to be reloaded.'),
                    buttons: [{
                        text: trlVps('OK'),
                        handler: function() {
                            location.reload();
                        },
                        scope: this
                    }, {
                        text: trlVps('Ignore'),
                        handler: function() {
                            Vps.application.maxAssetsMTime = r.maxAssetsMTime;
                            options.params.application_max_assets_mtime = Vps.application.maxAssetsMTime;
                            this.repeatRequest(options);
                            dlg.hide();
                        },
                        scope: this
                    }]
                });
                dlg.show();
                dlg.getEl().addClass('x-window-dlg');
                return;
            }
            if (r.login && !options.ignoreErrors) {
                options.vpsLogin = true;
                var dlg = new Vps.User.Login.Dialog({
                    message: r.message,
                    success: function() {
                        //redo action...
                        this.repeatRequest(options);
                    },
                    scope: this
                });
                Ext.getBody().unmask();
                dlg.showLogin();
                return;
            }
            if (!options.ignoreErrors) {
                if (r.error) {
                    Ext.Msg.alert(trlVps('Error'), r.error);
                } else {
                    Ext.Msg.alert(trlVps('Error'), trlVps("A Server failure occured."));
                }
            }
            Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
            return;
        }
        options.vpsIsSuccess = true;
        if (options.vpsCallback.success) {
            options.vpsCallback.success.call(options.vpsCallback.scope, response, options, r);
        }
    },
    vpsNoJsonSuccess: function(response, options)
    {
        options.vpsIsSuccess = true;
        if (options.vpsCallback.success) {
            options.vpsCallback.success.call(options.vpsCallback.scope, response, options);
        }
    },
    vpsNoJsonFailure: function(response, options)
    {
        options.vpsIsSuccess = false;
        if (options.vpsCallback.failure) {
            options.vpsCallback.failure.call(options.vpsCallback.scope, response, options);
        }
    },
    vpsJsonFailure: function(response, options)
    {
        options.vpsIsSuccess = false;

        errorMsgTitle = trlVps('Error');
        if (options.errorText) {
            errorText = options.errorText;
            errorMsg = options.errorText;
        } else {
            errorMsg = trlVps("A connection problem occured.");
            errorText = null;
        }
        if (options.ignoreErrors) {
            Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
        } else {
            Vps.handleError({
                url: options.url,
                message: errorMsg,
                title: errorMsgTitle,
                errorText: errorText,
                mail: false,
                checkRetry: true,
                retry: function() {
                    this.repeatRequest(options);
                },
                abort: function() {
                    Ext.callback(options.vpsCallback.failure, options.vpsCallback.scope, [response, options]);
                },
                scope: this
            });
        }
    },

    vpsCallback: function(options, success, response)
    {
        //wenn login-fenster angezeigt wird keinen callback aufrufen - weil der request
        //wird ja erneut gesendet und da dann der callback aufgerufen.
        if (options.vpsLogin) return;

        if (options.mask) {
            if (options.mask instanceof Ext.Element) {
                options.mask.unmask();
            } else {
                Vps.Connection.masks--;
                if (Vps.Connection.masks == 0) {
                    Ext.getBody().unmask();
                    if (Ext.get('loading')) {
                        Ext.get('loading').fadeOut({remove: true});
                    }
                }
            }
        }

        if (options.progress) {
            this._progressData[options.params.progressNum].progressBar.hide();
            delete this._progressData[options.params.progressNum];
        }

        if(success && !options.vpsIsSuccess) {
            success = false;
        }
        Ext.callback(options.vpsCallback.callback, options.vpsCallback.scope, [options, success, response]);
        Vps.Connection.runningRequests--;
    }
});
Vps.Connection.masks = 0; //static var that hols number of masked requests
Vps.Connection.runningRequests = 0;

Ext.Ajax = new Vps.Connection({
    /**
     * The timeout in milliseconds to be used for requests. (defaults
     * to 30000)
     * @type Number
     * @property  timeout
     */
    autoAbort : false,

    /**
     * Serialize the passed form into a url encoded string
     * @return {String}
     */
    serializeForm : function(form){
        return Ext.lib.Ajax.serializeForm(form);
    }
});

<|endoftext|>


<commit_before>window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function (callback) {
        window.setTimeout(callback, 1000 / 30);
    };
})();

var control_canvas,
c,        // c is the fg_canvas' context 2D
halfWidth,
halfHeight,
leftPointerID = -1,
leftPointerPos = new Vector2(0, 0),
leftPointerStartPos = new Vector2(0, 0),
leftVector = new Vector2(0, 0);
arrow = new VectorLED(0, 0, 0, 0);

var touches; // collections of pointers

/////////////////////////////// ARDUINO SETUP
var IOBoard = BO.IOBoard;
var IOBoardEvent = BO.IOBoardEvent;
var Pin = BO.Pin;

//// Variables
// LED related
var led1; //-90
var led2; //0
var led3; //90
var led4; //180=-180
var LEDloopON = false;
var LEDcont = 1;
var max_val;

var frame = 0;
var lastUpdateTime = 0;
var acDelta = 0;
var msPerFrame = 10;

// Set to true to print debug messages to console
BO.enableDebugging = true;

var host = window.location.hostname;
// if the file is opened locally, set the host to "localhost"
if (window.location.protocol.indexOf("file:") === 0) {
        host = "171.65.102.132";
    }
var arduino = new IOBoard(host, 8887);
///////////////////////////// ARDUINO SETUP END

var username = "noname";
var socket;

document.addEventListener("DOMContentLoaded", init);

window.onorientationchange = resetCanvas;
window.onresize = resetCanvas;

function init() {
    setupCanvas();
    setupD3();
    setupMotionDetection();

    touches = new Collection();

    arduino.addEventListener(IOBoardEvent.READY, onReady);
}

function onReady(event) {
        // Remove the event listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);

        // Set Pin 5,6,9,10 to PWM
        arduino.setDigitalPinMode(5, Pin.PWM);
        arduino.setDigitalPinMode(6, Pin.PWM);
        arduino.setDigitalPinMode(9, Pin.PWM);
        arduino.setDigitalPinMode(10, Pin.PWM);

        // Create an LED object to interface with the LED wired
        // to the I/O board
        led1 = arduino.getDigitalPin(5);
        led2 = arduino.getDigitalPin(6);
        led3 = arduino.getDigitalPin(9);
        led4 = arduino.getDigitalPin(10);

        // jQuery part for the sliders
    $("#n_slider").slider({
        step: 1,
        min : 1,
        max : 10,
        value: 4
    });

    $('#size_value').text("Value: 4");

    $( "#size_slider" ).bind( "size_slide", function(event, ui) {
        var value = ui.value;
        $('#size_value').text("Value: " + value);
        n = value;
    });

    $("#size_slider").slider({
        step: 10,
        min : 20,
        max : 200,
        value : 80
    });

    $('#size_value').text("Value: 80");

    $( "#size_slider" ).bind( "size_slide", function(event, ui) {
        var value = ui.value;
        $('#size_value').text("Value: " + value);
        l = value;
    });

    $("#br_slider").slider({
        step: 0.05,
        min : 0.0,
        max : 1.0,
        value: 0
    });

    $('#br_value').text("Value: 0");

    $( "#br_slider" ).bind( "br_slide", function(event, ui) {
        var value = ui.value;
        $('#br_value').text("Value: " + value.toFixed(2));
        brown_const = value;
    });

        $('input[name=setUsername]').click(function(){
                        if($('input[name=usernameTxt]').val() != ""){
                                username = $('input[name=usernameTxt]').val();
                                var msg = {type:'setUsername', user:username};
                                socket.json.send(msg);
                        }
                        $('#username').slideUp("slow",function(){
                                $('#entergame').slideDown("slow");
                        });
        });

        $("input[name=gamestartBtn]").click(function(){
            resetGame();
        });

        socket = new io.connect('http://171.65.102.132:8088');
        var chat = $('#chat');
        var board = $('#board');

        socket.on('connect', function() {
                console.log("Connected");
                //chat.html("Connected!");
                socket.emit('message', {channel:'realtime'});
        });

        socket.on('message', function(message){
                chat.append(message + '
');
        });

        socket.on('postscore', function(score){
                board.empty();
                for (var i=0;i<score.length;i++){
                        if(i==0){
                                board.append(''+ score[i][0]+'  :  '+score[i][1]+'
');
                        }else{
                                board.append(score[i][0]+'  :  '+score[i][1]+ '
');
                        }
                }
                board.fadeOut('fast');
                board.fadeIn('fast');
                board.fadeOut('fast');
                board.fadeIn('fast');
        });

        socket.on('disconnect', function() {
                console.log('disconnected');
                chat.html("Disconnect!");
        });

        $("input[name=sendBtn]").click(function(){
                var msg = {type:'chat',message:username + " : " + $("input[name=chatTxt]").val()}
                socket.json.send(msg);
                $("input[name=chatTxt]").val("");
        });

    control_canvas.addEventListener('pointerdown', onPointerDown, false);
    control_canvas.addEventListener('pointermove', onPointerMove, false);
    control_canvas.addEventListener('pointerup', onPointerUp, false);
    control_canvas.addEventListener('pointerout', onPointerUp, false);

    requestAnimFrame(joystick_draw);
}

function joystick_draw() {
    c.clearRect(0, 0, control_canvas.width, control_canvas.height);

    c.beginPath();
    c.moveTo(halfWidth, halfHeight-4);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth, halfHeight+4);
    c.stroke();

    c.beginPath();
    c.moveTo(halfWidth+4, halfHeight);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth-4, halfHeight);
    c.stroke();

    drawCircles(halfWidth, halfHeight);

        //// mouse event loop
    touches.forEach(function (touch) {
        if (touch.identifier == leftPointerID) {
            var alpha = arrow.trimArrow(leftVector, max_val);

            c.beginPath();
            c.fillStyle = "rgba(250, 102, 0, 1)";
            c.arc(leftPointerPos.x, leftPointerPos.y, 16, 0, Math.PI * 2, true);
            c.fill();

            c.beginPath();
            c.moveTo(leftPointerStartPos.x,leftPointerStartPos.y);
            c.strokeStyle = "rgba(250, 102, 0, 1)";
                        c.lineTo(leftPointerStartPos.x+max_val*(arrow.int2-arrow.int4),leftPointerStartPos.y+max_val*(arrow.int1-arrow.int3));
                        c.lineWidth = 3;
                        c.stroke();

                        c.beginPath();
                        c.fillStyle = "rgba(255, 255, 255, "+alpha*(LEDcont)+")";
                    c.arc(halfWidth, halfHeight, 16, 0, Math.PI * 2, true);
                    c.fill();

                        c.beginPath();
                c.fillStyle = "#fff";
                c.fillText(alpha,halfWidth-10, halfHeight-25);

                c.beginPath();
                c.fillStyle = "#dd6600";
                var theta = leftVector.angle();
                c.fillText(theta.toFixed(0),leftPointerPos.x+10, leftPointerPos.y-20);
        }
    });

    requestAnimFrame(joystick_draw);

    //// LED control loop
    var delta = Date.now() - lastUpdateTime;
    if (acDelta > msPerFrame)
    {
        acDelta = 0;
        if(LEDloopON)
        {
                //LEDon = frame%2;
                LEDcont = 1;
                changeLED(LEDcont);
        }
        frame++;
        if (frame >= 2) {frame = 0;}
    } else
    {
        acDelta += delta;
    }
    lastUpdateTime = Date.now();
}

function drawCircles(xCenter,yCenter)
{
        var needle = new Vector2(max_val, 0);
        for(var i=0;i<24*3;i++)
        {
                c.beginPath();
                c.fillStyle = "rgba(255, 255, 255, 0.5)";
                c.lineWidth = 3;
                c.arc(xCenter + needle.x, yCenter + needle.y, 1, 0, Math.PI * 2, true);
                c.fill();
                needle.rotate(5,0);
        }
}

function givePointerType(event) {
    switch (event.pointerType) {
        case event.POINTER_TYPE_MOUSE:
            return "MOUSE";
            break;
        case event.POINTER_TYPE_PEN:
            return "PEN";
            break;
        case event.POINTER_TYPE_TOUCH:
            return "TOUCH";
            break;
    }
}

function onPointerDown(e) {
    var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: givePointerType(e) };
    leftPointerID = e.pointerId;
    //leftPointerStartPos.reset(e.clientX, e.clientY);
    leftPointerStartPos.reset(halfWidth, halfHeight);
    leftPointerPos.copyFrom(leftPointerStartPos);
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.add(e.pointerId, newPointer);
}

function onPointerMove(e) {
    if (leftPointerID == e.pointerId) {
        //leftPointerPos.reset(e.clientX, e.clientY);
        leftPointerPos.reset(e.offsetX, e.offsetY);
        leftVector.copyFrom(leftPointerPos);
        //leftVector.minusEq(leftPointerStartPos);
        leftVector.minusEq(leftPointerStartPos);
        arrow.setArrow(leftVector, max_val);
        LEDloopON = true;
    }
    else {
        if (touches.item(e.pointerId)) {
            touches.item(e.pointerId).x = e.clientX;
            touches.item(e.pointerId).y = e.clientY;
        }
    }
}

function onPointerUp(e) {
    if (leftPointerID == e.pointerId) {
        leftPointerID = -1;
        leftVector.reset(0, 0);
    }
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.remove(e.pointerId);
    LEDloopON = false;
    changeLED(0);
}

function setupCanvas() {
    control_canvas = document.getElementById('controlCanvas');
    c = control_canvas.getContext('2d');
    resetCanvas();
    c.strokeStyle = "#ffffff";
    c.lineWidth = 2;
}

// Arduino control functions
function changeLED(LEDon) {
    if(LEDon)
    {
            led1.value = arrow.int1;
            led2.value = arrow.int2;
            led3.value = arrow.int3;
            led4.value = arrow.int4;
    }
    else
    {
            led1.value = 0;
            led2.value = 0;
            led3.value = 0;
            led4.value = 0;
        }
}

function resetCanvas(e) {
    max_val = (document.getElementById("controlArea").offsetWidth-100)/2;

    // resize the canvas - but remember - this clears the canvas too.

    control_canvas.width = document.getElementById("controlArea").offsetWidth-20;
    control_canvas.height = control_canvas.width-20;

    halfWidth = (control_canvas.width)/2;
    halfHeight = (control_canvas.height)/2;

    // make sure we scroll to the top left.
    window.scrollTo(0, 0);
}<commit_msg>layout edit<commit_after>window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function (callback) {
        window.setTimeout(callback, 1000 / 30);
    };
})();

var control_canvas,
c,        // c is the fg_canvas' context 2D
halfWidth,
halfHeight,
leftPointerID = -1,
leftPointerPos = new Vector2(0, 0),
leftPointerStartPos = new Vector2(0, 0),
leftVector = new Vector2(0, 0);
arrow = new VectorLED(0, 0, 0, 0);

var touches; // collections of pointers

/////////////////////////////// ARDUINO SETUP
var IOBoard = BO.IOBoard;
var IOBoardEvent = BO.IOBoardEvent;
var Pin = BO.Pin;

//// Variables
// LED related
var led1; //-90
var led2; //0
var led3; //90
var led4; //180=-180
var LEDloopON = false;
var LEDcont = 1;
var max_val;

var frame = 0;
var lastUpdateTime = 0;
var acDelta = 0;
var msPerFrame = 10;

// Set to true to print debug messages to console
BO.enableDebugging = true;

var host = window.location.hostname;
// if the file is opened locally, set the host to "localhost"
if (window.location.protocol.indexOf("file:") === 0) {
        host = "171.65.102.132";
    }
var arduino = new IOBoard(host, 8887);
///////////////////////////// ARDUINO SETUP END

var username = "noname";
var socket;

document.addEventListener("DOMContentLoaded", init);

window.onorientationchange = resetCanvas;
window.onresize = resetCanvas;

function init() {
    setupCanvas();
    setupD3();
    setupMotionDetection();

    touches = new Collection();

    arduino.addEventListener(IOBoardEvent.READY, onReady);
}

function onReady(event) {
        // Remove the event listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);

        // Set Pin 5,6,9,10 to PWM
        arduino.setDigitalPinMode(5, Pin.PWM);
        arduino.setDigitalPinMode(6, Pin.PWM);
        arduino.setDigitalPinMode(9, Pin.PWM);
        arduino.setDigitalPinMode(10, Pin.PWM);

        // Create an LED object to interface with the LED wired
        // to the I/O board
        led1 = arduino.getDigitalPin(5);
        led2 = arduino.getDigitalPin(6);
        led3 = arduino.getDigitalPin(9);
        led4 = arduino.getDigitalPin(10);

        // jQuery part for the sliders
    $("#n_slider").slider({
        step: 1,
        min : 1,
        max : 10,
        value: 4
    });

    $('#n_value').text("Value: 4");

    $( "#n_slider" ).bind( "n_slide", function(event, ui) {
        var value = ui.value;
        $('#n_value').text("Value: " + value);
        n = value;
    });

    $("#size_slider").slider({
        step: 10,
        min : 20,
        max : 200,
        value : 80
    });

    $('#size_value').text("Value: 80");

    $( "#size_slider" ).bind( "size_slide", function(event, ui) {
        var value = ui.value;
        $('#size_value').text("Value: " + value);
        l = value;
    });

    $("#br_slider").slider({
        step: 0.05,
        min : 0.0,
        max : 1.0,
        value: 0
    });

    $('#br_value').text("Value: 0");

    $( "#br_slider" ).bind( "br_slide", function(event, ui) {
        var value = ui.value;
        $('#br_value').text("Value: " + value.toFixed(2));
        brown_const = value;
    });

        $('input[name=setUsername]').click(function(){
                        if($('input[name=usernameTxt]').val() != ""){
                                username = $('input[name=usernameTxt]').val();
                                var msg = {type:'setUsername', user:username};
                                socket.json.send(msg);
                        }
                        $('#username').slideUp("slow",function(){
                                $('#entergame').slideDown("slow");
                        });
        });

        $("input[name=gamestartBtn]").click(function(){
            resetGame();
        });

        socket = new io.connect('http://171.65.102.132:8088');
        var chat = $('#chat');
        var board = $('#board');

        socket.on('connect', function() {
                console.log("Connected");
                //chat.html("Connected!");
                socket.emit('message', {channel:'realtime'});
        });

        socket.on('message', function(message){
                chat.append(message + '
');
        });

        socket.on('postscore', function(score){
                board.empty();
                for (var i=0;i<score.length;i++){
                        if(i==0){
                                board.append(''+ score[i][0]+'  :  '+score[i][1]+'
');
                        }else{
                                board.append(score[i][0]+'  :  '+score[i][1]+ '
');
                        }
                }
                board.fadeOut('fast');
                board.fadeIn('fast');
                board.fadeOut('fast');
                board.fadeIn('fast');
        });

        socket.on('disconnect', function() {
                console.log('disconnected');
                chat.html("Disconnect!");
        });

        $("input[name=sendBtn]").click(function(){
                var msg = {type:'chat',message:username + " : " + $("input[name=chatTxt]").val()}
                socket.json.send(msg);
                $("input[name=chatTxt]").val("");
        });

    control_canvas.addEventListener('pointerdown', onPointerDown, false);
    control_canvas.addEventListener('pointermove', onPointerMove, false);
    control_canvas.addEventListener('pointerup', onPointerUp, false);
    control_canvas.addEventListener('pointerout', onPointerUp, false);

    requestAnimFrame(joystick_draw);
}

function joystick_draw() {
    c.clearRect(0, 0, control_canvas.width, control_canvas.height);

    c.beginPath();
    c.moveTo(halfWidth, halfHeight-4);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth, halfHeight+4);
    c.stroke();

    c.beginPath();
    c.moveTo(halfWidth+4, halfHeight);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth-4, halfHeight);
    c.stroke();

    drawCircles(halfWidth, halfHeight);

        //// mouse event loop
    touches.forEach(function (touch) {
        if (touch.identifier == leftPointerID) {
            var alpha = arrow.trimArrow(leftVector, max_val);

            c.beginPath();
            c.fillStyle = "rgba(250, 102, 0, 1)";
            c.arc(leftPointerPos.x, leftPointerPos.y, 16, 0, Math.PI * 2, true);
            c.fill();

            c.beginPath();
            c.moveTo(leftPointerStartPos.x,leftPointerStartPos.y);
            c.strokeStyle = "rgba(250, 102, 0, 1)";
                        c.lineTo(leftPointerStartPos.x+max_val*(arrow.int2-arrow.int4),leftPointerStartPos.y+max_val*(arrow.int1-arrow.int3));
                        c.lineWidth = 3;
                        c.stroke();

                        c.beginPath();
                        c.fillStyle = "rgba(255, 255, 255, "+alpha*(LEDcont)+")";
                    c.arc(halfWidth, halfHeight, 16, 0, Math.PI * 2, true);
                    c.fill();

                        c.beginPath();
                c.fillStyle = "#fff";
                c.fillText(alpha,halfWidth-10, halfHeight-25);

                c.beginPath();
                c.fillStyle = "#dd6600";
                var theta = leftVector.angle();
                c.fillText(theta.toFixed(0),leftPointerPos.x+10, leftPointerPos.y-20);
        }
    });

    requestAnimFrame(joystick_draw);

    //// LED control loop
    var delta = Date.now() - lastUpdateTime;
    if (acDelta > msPerFrame)
    {
        acDelta = 0;
        if(LEDloopON)
        {
                //LEDon = frame%2;
                LEDcont = 1;
                changeLED(LEDcont);
        }
        frame++;
        if (frame >= 2) {frame = 0;}
    } else
    {
        acDelta += delta;
    }
    lastUpdateTime = Date.now();
}

function drawCircles(xCenter,yCenter)
{
        var needle = new Vector2(max_val, 0);
        for(var i=0;i<24*3;i++)
        {
                c.beginPath();
                c.fillStyle = "rgba(255, 255, 255, 0.5)";
                c.lineWidth = 3;
                c.arc(xCenter + needle.x, yCenter + needle.y, 1, 0, Math.PI * 2, true);
                c.fill();
                needle.rotate(5,0);
        }
}

function givePointerType(event) {
    switch (event.pointerType) {
        case event.POINTER_TYPE_MOUSE:
            return "MOUSE";
            break;
        case event.POINTER_TYPE_PEN:
            return "PEN";
            break;
        case event.POINTER_TYPE_TOUCH:
            return "TOUCH";
            break;
    }
}

function onPointerDown(e) {
    var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: givePointerType(e) };
    leftPointerID = e.pointerId;
    //leftPointerStartPos.reset(e.clientX, e.clientY);
    leftPointerStartPos.reset(halfWidth, halfHeight);
    leftPointerPos.copyFrom(leftPointerStartPos);
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.add(e.pointerId, newPointer);
}

function onPointerMove(e) {
    if (leftPointerID == e.pointerId) {
        //leftPointerPos.reset(e.clientX, e.clientY);
        leftPointerPos.reset(e.offsetX, e.offsetY);
        leftVector.copyFrom(leftPointerPos);
        //leftVector.minusEq(leftPointerStartPos);
        leftVector.minusEq(leftPointerStartPos);
        arrow.setArrow(leftVector, max_val);
        LEDloopON = true;
    }
    else {
        if (touches.item(e.pointerId)) {
            touches.item(e.pointerId).x = e.clientX;
            touches.item(e.pointerId).y = e.clientY;
        }
    }
}

function onPointerUp(e) {
    if (leftPointerID == e.pointerId) {
        leftPointerID = -1;
        leftVector.reset(0, 0);
    }
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.remove(e.pointerId);
    LEDloopON = false;
    changeLED(0);
}

function setupCanvas() {
    control_canvas = document.getElementById('controlCanvas');
    c = control_canvas.getContext('2d');
    resetCanvas();
    c.strokeStyle = "#ffffff";
    c.lineWidth = 2;
}

// Arduino control functions
function changeLED(LEDon) {
    if(LEDon)
    {
            led1.value = arrow.int1;
            led2.value = arrow.int2;
            led3.value = arrow.int3;
            led4.value = arrow.int4;
    }
    else
    {
            led1.value = 0;
            led2.value = 0;
            led3.value = 0;
            led4.value = 0;
        }
}

function resetCanvas(e) {
    max_val = (document.getElementById("controlArea").offsetWidth-100)/2;

    // resize the canvas - but remember - this clears the canvas too.

    control_canvas.width = document.getElementById("controlArea").offsetWidth-20;
    control_canvas.height = control_canvas.width-20;

    halfWidth = (control_canvas.width)/2;
    halfHeight = (control_canvas.height)/2;

    // make sure we scroll to the top left.
    window.scrollTo(0, 0);
}<|endoftext|>


<commit_before>'use strict';

const _          = require('lodash');
const browserify = require('browserify');
const cacheify   = require('cacheify');
const uglifyify  = require('uglifyify');
const stream     = require('readable-stream');
const path       = require('path');
const babelify   = require('babelify');

const resolve_module_path = require('./utils/resolve_module_path');

const before = _.template(`
NodecaLoader.registerClientModule('<%= apiPath %>', function (N, exports, module, t) {`);
const after = '});';

module.exports = function (sandbox) {
  let exclude = [];

  _.forEach(sandbox.config.packages, pkg => {
    _.forEach(pkg.vendor, (__, name) => {
      exclude.push(name);
    });
  });

  // To check if same module was included in multiple packages
  //
  // widget_path -> [ module_path ]
  //
  sandbox.included_modules = {};

  async function browserify_concat_plugin(context) {
    if (!_.trim(context.asset.source, '\n')) return;

    let b = browserify({
      prelude: 'NodecaLoader.wrap',
      detectGlobals: false
    });

    context.asset.__queue__.forEach(file_path => {
      let s = new stream.Transform();
      s.push(context.bundler.findAsset(file_path).source);
      s.end();

      b.add(s, { basedir: path.dirname(file_path), file: file_path });
    });

    // babelify settings defined in package.json of each application
    b.transform(cacheify(babelify.configure(), sandbox.cache_db));

    if (sandbox.compression) {
      b.transform(cacheify(uglifyify, sandbox.cache_db), { global: true });
    }

    exclude.forEach(e => b.exclude(e));

    b.on('file', path => {
      context.asset.dependOnFile(path);
    });

    b.on('dep', function (row) {
      if (row.entry) {
        _.forEach(row.indexDeps, (index, dep_name) => {
          if (index) {
            let dep_path = resolve_module_path(path.dirname(row.file), dep_name);

            sandbox.included_modules[row.file] = sandbox.included_modules[row.file] || [];
            sandbox.included_modules[row.file].push(dep_path);
          }
        });
      }
    });

    let out = await new Promise((resolve, reject) => {
      b.bundle((err, result) => (err ? reject(err) : resolve(result)));
    });

    context.asset.source = String(out);
  }

  _.forEach(sandbox.config.packages, (pkg, pkg_name) => {
    let widget_js = sandbox.bundler.createClass('concat', {
      logicalPath: 'public/package-component-widget-js-' + pkg_name + '.js',
      virtual: true,
      plugins: [ browserify_concat_plugin, 'macros' ]
    });

    _.forEach(pkg.files.widget_js, file_info => {
      let asset = sandbox.bundler.createClass('file', {
        logicalPath: file_info.path,
        virtual: true,
        plugins: [ 'load_text', 'auto', 'wrapper' ],
        wrapBefore: before({ apiPath: file_info.api_path }),
        wrapAfter: after
      });

      widget_js.push(asset);
    });

    sandbox.component_client[pkg_name].js.push(widget_js);

    _.forEach(pkg.files.js, file_info => {
      sandbox.bundler.createClass('file', {
        logicalPath: file_info.path,
        plugins: [ 'load_text', 'auto', 'macros' ].concat(sandbox.compression ? [ 'uglifyjs' ] : [])
      });
    });
  });
};
<commit_msg>Replace readable-stream with stream<commit_after>'use strict';

const _          = require('lodash');
const browserify = require('browserify');
const cacheify   = require('cacheify');
const uglifyify  = require('uglifyify');
const stream     = require('stream');
const path       = require('path');
const babelify   = require('babelify');

const resolve_module_path = require('./utils/resolve_module_path');

const before = _.template(`
NodecaLoader.registerClientModule('<%= apiPath %>', function (N, exports, module, t) {`);
const after = '});';

module.exports = function (sandbox) {
  let exclude = [];

  _.forEach(sandbox.config.packages, pkg => {
    _.forEach(pkg.vendor, (__, name) => {
      exclude.push(name);
    });
  });

  // To check if same module was included in multiple packages
  //
  // widget_path -> [ module_path ]
  //
  sandbox.included_modules = {};

  async function browserify_concat_plugin(context) {
    if (!_.trim(context.asset.source, '\n')) return;

    let b = browserify({
      prelude: 'NodecaLoader.wrap',
      detectGlobals: false
    });

    context.asset.__queue__.forEach(file_path => {
      let s = new stream.Transform();
      s.push(context.bundler.findAsset(file_path).source);
      s.end();

      b.add(s, { basedir: path.dirname(file_path), file: file_path });
    });

    // babelify settings defined in package.json of each application
    b.transform(cacheify(babelify.configure(), sandbox.cache_db));

    if (sandbox.compression) {
      b.transform(cacheify(uglifyify, sandbox.cache_db), { global: true });
    }

    exclude.forEach(e => b.exclude(e));

    b.on('file', path => {
      context.asset.dependOnFile(path);
    });

    b.on('dep', function (row) {
      if (row.entry) {
        _.forEach(row.indexDeps, (index, dep_name) => {
          if (index) {
            let dep_path = resolve_module_path(path.dirname(row.file), dep_name);

            sandbox.included_modules[row.file] = sandbox.included_modules[row.file] || [];
            sandbox.included_modules[row.file].push(dep_path);
          }
        });
      }
    });

    let out = await new Promise((resolve, reject) => {
      b.bundle((err, result) => (err ? reject(err) : resolve(result)));
    });

    context.asset.source = String(out);
  }

  _.forEach(sandbox.config.packages, (pkg, pkg_name) => {
    let widget_js = sandbox.bundler.createClass('concat', {
      logicalPath: 'public/package-component-widget-js-' + pkg_name + '.js',
      virtual: true,
      plugins: [ browserify_concat_plugin, 'macros' ]
    });

    _.forEach(pkg.files.widget_js, file_info => {
      let asset = sandbox.bundler.createClass('file', {
        logicalPath: file_info.path,
        virtual: true,
        plugins: [ 'load_text', 'auto', 'wrapper' ],
        wrapBefore: before({ apiPath: file_info.api_path }),
        wrapAfter: after
      });

      widget_js.push(asset);
    });

    sandbox.component_client[pkg_name].js.push(widget_js);

    _.forEach(pkg.files.js, file_info => {
      sandbox.bundler.createClass('file', {
        logicalPath: file_info.path,
        plugins: [ 'load_text', 'auto', 'macros' ].concat(sandbox.compression ? [ 'uglifyjs' ] : [])
      });
    });
  });
};
<|endoftext|>