<commit_before>import React from 'react'
import { Message } from 'semantic-ui-react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
import ShorthandExample from 'docs/src/components/ComponentDoc/ShorthandExample'

const DropdownUsageExamples = () => (
  <ExampleSection title='Usage'>
    <ComponentExample
      title='Open On Focus'
      description='A dropdown that opens when it is focussed on.'
      examplePath='modules/Dropdown/Usage/DropdownExampleOpenOnFocus'
    />

    <ComponentExample
      title='Close On Blur'
      description='A dropdown that closes when it blurs'
      examplePath='modules/Dropdown/Usage/DropdownExampleCloseOnBlur'
    />

    <ComponentExample
      title='Close On Change'
      description='A multiple selection dropdown can close when the user changes its value.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCloseOnChange'
    />

    <ComponentExample
      title='Select On Navigation'
      description='A dropdown can choose whether or not to change the value when navigating the menu with arrow keys.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSelectOnNavigation'
    />
    <ComponentExample
      title='Controlled'
      description='A dropdown can behave like an controlled input.'
      examplePath='modules/Dropdown/Usage/DropdownExampleControlled'
    />
    <ComponentExample
      title='Uncontrolled'
      description='A dropdown can behave like an uncontrolled input.'
      examplePath='modules/Dropdown/Usage/DropdownExampleUncontrolled'
    />
    <ComponentExample
      title='No Results Message'
      description='You can change the no results message.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCustomNoResultsMessage'
    />
    <ComponentExample
      description='You can remove the no results message.'
      examplePath='modules/Dropdown/Usage/DropdownExampleRemoveNoResultsMessage'
    />
    <ComponentExample
      title='Remote'
      description="A dropdown's options can be controlled from outside based on search change."
      examplePath='modules/Dropdown/Usage/DropdownExampleRemote'
    />
    <ComponentExample
      title='Allow Additions'
      description='Using allowAdditions gives users the ability to add their own options.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAllowAdditions'
    />
    <ComponentExample
      description='allowAdditions can be used with multiple.'
      examplePath='modules/Dropdown/Usage/DropdownExampleMultipleAllowAdditions'
    />
    <ComponentExample
      description='You can provide a custom additionLabel as a string.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAdditionLabelString'
    />
    <ComponentExample
      description='Or provide additionLabel as a component.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAdditionLabelComponent'
    />
    <ComponentExample
      title='Trigger'
      description='A dropdown can render a node in place of the text.'
      examplePath='modules/Dropdown/Usage/DropdownExampleTrigger'
    />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleTriggerImage' />
    <ComponentExample
      title='Multiple Custom Label'
      description='A "multiple" dropdown can render customized label for selected items.'
      examplePath='modules/Dropdown/Usage/DropdownExampleMultipleCustomLabel'
    />
    <ComponentExample
      title='Item Content'
      description='A dropdown item can be rendered differently inside the menu.'
      examplePath='modules/Dropdown/Usage/DropdownExampleItemContent'
    />
    <ShorthandExample
      title='Search Input'
      description='A dropdown implements a search input shorthand.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSearchInput'
    />
    <ComponentExample
      title='Search Query'
      description='A dropdown allows to pass you the search query.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSearchQuery'
    >
      <Message info>
        This example also shows how to override default bevahiour of the search query and keep
        entered value after selection.
      </Message>
    </ComponentExample>
    <ComponentExample
      title='Search Deburr'
      description='A dropdown allows the search to ignore diacritics.'
      examplePath='modules/Dropdown/Usage/DropdownExampleDeburrSearch'
    />
    <ComponentExample
      title='Custom Search Function'
      description='A dropdown allows you to provide your own search function.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCustomSearchFunction'
    />
    <ComponentExample
      title='Upward'
      description='A dropdown can open its menu upward.'
      examplePath='modules/Dropdown/Usage/DropdownExampleUpwardSelection'
    />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleUpwardInline' />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleUpward' />
    <ComponentExample
      title='Wrap Selection'
      description={[
        'A dropdown can enable or disable wrapping the selection to the start',
        ' when it reaches the end and vice versa',
      ].join('')}
      examplePath='modules/Dropdown/Usage/DropdownExampleWrapSelectionFalse'
    />
  </ExampleSection>
)

export default DropdownUsageExamples
<commit_msg>docs(Dropdown): fix typo in message<commit_after>import React from 'react'
import { Message } from 'semantic-ui-react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
import ShorthandExample from 'docs/src/components/ComponentDoc/ShorthandExample'

const DropdownUsageExamples = () => (
  <ExampleSection title='Usage'>
    <ComponentExample
      title='Open On Focus'
      description='A dropdown that opens when it is focussed on.'
      examplePath='modules/Dropdown/Usage/DropdownExampleOpenOnFocus'
    />

    <ComponentExample
      title='Close On Blur'
      description='A dropdown that closes when it blurs'
      examplePath='modules/Dropdown/Usage/DropdownExampleCloseOnBlur'
    />

    <ComponentExample
      title='Close On Change'
      description='A multiple selection dropdown can close when the user changes its value.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCloseOnChange'
    />

    <ComponentExample
      title='Select On Navigation'
      description='A dropdown can choose whether or not to change the value when navigating the menu with arrow keys.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSelectOnNavigation'
    />
    <ComponentExample
      title='Controlled'
      description='A dropdown can behave like an controlled input.'
      examplePath='modules/Dropdown/Usage/DropdownExampleControlled'
    />
    <ComponentExample
      title='Uncontrolled'
      description='A dropdown can behave like an uncontrolled input.'
      examplePath='modules/Dropdown/Usage/DropdownExampleUncontrolled'
    />
    <ComponentExample
      title='No Results Message'
      description='You can change the no results message.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCustomNoResultsMessage'
    />
    <ComponentExample
      description='You can remove the no results message.'
      examplePath='modules/Dropdown/Usage/DropdownExampleRemoveNoResultsMessage'
    />
    <ComponentExample
      title='Remote'
      description="A dropdown's options can be controlled from outside based on search change."
      examplePath='modules/Dropdown/Usage/DropdownExampleRemote'
    />
    <ComponentExample
      title='Allow Additions'
      description='Using allowAdditions gives users the ability to add their own options.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAllowAdditions'
    />
    <ComponentExample
      description='allowAdditions can be used with multiple.'
      examplePath='modules/Dropdown/Usage/DropdownExampleMultipleAllowAdditions'
    />
    <ComponentExample
      description='You can provide a custom additionLabel as a string.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAdditionLabelString'
    />
    <ComponentExample
      description='Or provide additionLabel as a component.'
      examplePath='modules/Dropdown/Usage/DropdownExampleAdditionLabelComponent'
    />
    <ComponentExample
      title='Trigger'
      description='A dropdown can render a node in place of the text.'
      examplePath='modules/Dropdown/Usage/DropdownExampleTrigger'
    />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleTriggerImage' />
    <ComponentExample
      title='Multiple Custom Label'
      description='A "multiple" dropdown can render customized label for selected items.'
      examplePath='modules/Dropdown/Usage/DropdownExampleMultipleCustomLabel'
    />
    <ComponentExample
      title='Item Content'
      description='A dropdown item can be rendered differently inside the menu.'
      examplePath='modules/Dropdown/Usage/DropdownExampleItemContent'
    />
    <ShorthandExample
      title='Search Input'
      description='A dropdown implements a search input shorthand.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSearchInput'
    />
    <ComponentExample
      title='Search Query'
      description='A dropdown allows to pass you the search query.'
      examplePath='modules/Dropdown/Usage/DropdownExampleSearchQuery'
    >
      <Message info>
        This example also shows how to override default behaviour of the search query and keep
        entered value after selection.
      </Message>
    </ComponentExample>
    <ComponentExample
      title='Search Deburr'
      description='A dropdown allows the search to ignore diacritics.'
      examplePath='modules/Dropdown/Usage/DropdownExampleDeburrSearch'
    />
    <ComponentExample
      title='Custom Search Function'
      description='A dropdown allows you to provide your own search function.'
      examplePath='modules/Dropdown/Usage/DropdownExampleCustomSearchFunction'
    />
    <ComponentExample
      title='Upward'
      description='A dropdown can open its menu upward.'
      examplePath='modules/Dropdown/Usage/DropdownExampleUpwardSelection'
    />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleUpwardInline' />
    <ComponentExample examplePath='modules/Dropdown/Usage/DropdownExampleUpward' />
    <ComponentExample
      title='Wrap Selection'
      description={[
        'A dropdown can enable or disable wrapping the selection to the start',
        ' when it reaches the end and vice versa',
      ].join('')}
      examplePath='modules/Dropdown/Usage/DropdownExampleWrapSelectionFalse'
    />
  </ExampleSection>
)

export default DropdownUsageExamples
<|endoftext|>


<commit_before>var app = (function () {
  'use strict';

  var app = {},
    serverUrl = 'http://localhost:3000/',
    config = {
      iceServers: [{
        url: 'stun:stun.l.google.com:19302'
      }]
    },
    socket = io(serverUrl),
    pc,
    sendChannel,
    channelOpened = false,
    tabId;

  app.states = {
    stopped: 'stopped',
    starting: 'starting',
    started: 'started',
    stopping: 'stopping'
  };
  app.extensionState = app.states.stopped;

  function getTabMedia(successCallback) {
    chrome.tabs.query({active: true, currentWindow: true}, function () {
      var constraints = {
        audio: false,
        video: true,
        videoConstraints: {
          mandatory: {
            chromeMediaSource: 'tab'
          }
        }
      };

      chrome.tabCapture.capture(constraints, successCallback);
    });
  }

  function room() {
    return '666';
  }

  function pub(peerName) {
    return {
      name: peerName,
      role: 'pub'
    }
  }

  function sub(peerName) {
    return {
      name: peerName,
      role: 'sub'
    }
  }

  app.createRoom = function (peerName) {
    console.log('create room, socket id', socket.id, peerName);
    socket.emit('join', pub(peerName), room());
  };

  app.sendMessageToChannel = function (text) {
    if (channelOpened) {
      sendChannel.send(text);
    }
  };

// run start(true) to initiate a call
  app.start = function () {
    app.extensionState = app.states.starting;
    pc = new RTCPeerConnection(config, {optional: [{RtpDataChannels: true}]});

    sendChannel = pc.createDataChannel('RTCDataChannel', {reliable: false});
    setChannelEvents(sendChannel, 'sendChannel');

    attachDebugger();

    setPeerConnectionEvents(pc);

    getTabMedia(function (stream) {
      pc.addStream(stream);

      console.log('Offer conection to view process page');
      pc.createOffer(gotDescription);

      function gotDescription(desc) {
        pc.setLocalDescription(new RTCSessionDescription(desc));
        console.log('Local sdp: ', desc);
        console.log('Send sdp, socket id', socket.id);
        socket.emit('message', {"sdp": desc});
      }
    }, function (error) {
      console.log('Error', error);
    })
  };

  app.stop = function () {
    app.extensionState = app.states.stopping;
    chrome.debugger.detach({tabId: tabId});
    //todo
    app.extensionState = app.states.stopped;
  };

  function attachDebugger() {
    chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
      var version = "1.0";
      tabId = tabs[0].id;
      chrome.debugger.attach({tabId: tabId}, version, onAttach.bind(null, tabId));

      function onAttach() {
        if (chrome.runtime.lastError) {
          alert(chrome.runtime.lastError.message);
        }
      }

      chrome.debugger.sendCommand({tabId: tabId}, "Network.enable");
      chrome.debugger.sendCommand({tabId: tabId}, "Console.enable");
      chrome.debugger.onEvent.addListener(onEvent);

      function onEvent(debuggeeId, message, params) {
        if (tabId != debuggeeId.tabId)
          return;
        if (message === 'Console.messageAdded') {
          console.log(params.message.text);
          app.sendMessageToChannel(params.message.text);
        }
      }
    });
  }

  function setPeerConnectionEvents(pc) {
    // send any ice candidates to the other peer
    pc.onicecandidate = function (evt) {
      console.log('Local candidate: ', evt);
      socket.emit('message', {'candidate': evt.candidate});
    };
  }

  function setChannelEvents(channel) {
    channel.onmessage = function (event) {
      console.debug('Ext: ', event.data);
    };
    channel.onopen = function () {
      channelOpened = true;
      console.debug('Channel opened');
    };
    channel.onclose = function (e) {
      channelOpened = false;
      console.error(e);
    };
    channel.onerror = function (e) {
      console.error(e);
    };
  }

  socket.on('message', function (message) {
    if (message.sdp) {
      console.log('Remote sdp: ', message.sdp);
      pc.setRemoteDescription(new RTCSessionDescription(message.sdp));
    } else {
      console.log('Remote candidate: ', message.candidate);
      if(message.candidate){
        pc.addIceCandidate(new RTCIceCandidate(message.candidate));
      }

      app.extensionState = app.states.started;
    }
  });

  socket.on('joined', function (peer, room) {
    console.log('Join: ' + peer + ' : room ' + room);
    chrome.extension.sendMessage({roomUID: room});
  });

  socket.on('ready', function (message) {
    console.log('ready message');
  });

  return app;
})();

chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
  'use strict';

  console.log('Get message from popup: ' + msg.method);

  switch (msg.method) {
    case 'createRoom':
      app.createRoom(msg.name);
      break;
    case 'toggleStart':
      if (app.states.stopped === app.extensionState) {
        app.start();
      } else if (app.states.started === app.extensionState) {
        app.stop();
      }
      break;
    case 'join':
      chrome.tabs.create({'url': chrome.extension.getURL('index.html')}, function(tab) {
        // Tab opened.
      });
      break;
  }
});
<commit_msg>simple network messages<commit_after>var app = (function () {
  'use strict';

  var app = {},
    serverUrl = 'http://localhost:3000/',
    config = {
      iceServers: [{
        url: 'stun:stun.l.google.com:19302'
      }]
    },
    socket = io(serverUrl),
    pc,
    sendChannel,
    channelOpened = false,
    tabId;

  app.states = {
    stopped: 'stopped',
    starting: 'starting',
    started: 'started',
    stopping: 'stopping'
  };
  app.extensionState = app.states.stopped;

  function getTabMedia(successCallback) {
    chrome.tabs.query({active: true, currentWindow: true}, function () {
      var constraints = {
        audio: false,
        video: true,
        videoConstraints: {
          mandatory: {
            chromeMediaSource: 'tab'
          }
        }
      };

      chrome.tabCapture.capture(constraints, successCallback);
    });
  }

  function room() {
    return null;
  }

  function pub(peerName) {
    return {
      name: peerName,
      role: 'pub'
    }
  }

  function sub(peerName) {
    return {
      name: peerName,
      role: 'sub'
    }
  }

  app.createRoom = function (peerName) {
    console.log('create room, socket id', socket.id, peerName);
    socket.emit('join', pub(peerName), room());
  };

  app.sendMessageToChannel = function (text) {
    if (channelOpened) {
      sendChannel.send(text);
    }
  };

// run start(true) to initiate a call
  app.start = function () {
    app.extensionState = app.states.starting;
    pc = new RTCPeerConnection(config, {optional: [{RtpDataChannels: true}]});

    sendChannel = pc.createDataChannel('RTCDataChannel', {reliable: false});
    setChannelEvents(sendChannel, 'sendChannel');

    attachDebugger();

    setPeerConnectionEvents(pc);

    getTabMedia(function (stream) {
      pc.addStream(stream);

      console.log('Offer conection to view process page');
      pc.createOffer(gotDescription);

      function gotDescription(desc) {
        pc.setLocalDescription(new RTCSessionDescription(desc));
        console.log('Local sdp: ', desc);
        console.log('Send sdp, socket id', socket.id);
        socket.emit('message', {"sdp": desc});
      }
    }, function (error) {
      console.log('Error', error);
    })
  };

  app.stop = function () {
    app.extensionState = app.states.stopping;
    chrome.debugger.detach({tabId: tabId});
    //todo
    app.extensionState = app.states.stopped;
  };

  function attachDebugger() {
    chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
      var version = "1.0";
      tabId = tabs[0].id;
      chrome.debugger.attach({tabId: tabId}, version, onAttach.bind(null, tabId));

      function onAttach() {
        if (chrome.runtime.lastError) {
          alert(chrome.runtime.lastError.message);
        }
      }

      chrome.debugger.sendCommand({tabId: tabId}, "Network.enable");
      chrome.debugger.sendCommand({tabId: tabId}, "Console.enable");
      chrome.debugger.onEvent.addListener(onEvent);

      function onEvent(debuggeeId, message, params) {
        var text;

        if (tabId != debuggeeId.tabId) {
          return;
        }

        if (message === 'Console.messageAdded') {
          console.debug(params.message.text);
          text = JSON.stringify({kind: 'console', obj: params.message});

          app.sendMessageToChannel(text);
        } else if (message === 'Network.requestWillBeSent') {
          console.debug(params.request);
          text = JSON.stringify({
            kind: 'network.request',
            obj: params.request
          });

          app.sendMessageToChannel(text);
        } else if (message === 'Network.responseReceived') {
          console.debug(params.response);
          text = JSON.stringify({
            kind: 'network.response', obj: params.response
          });

          app.sendMessageToChannel(text);
        }
      }
    });
  }

  function setPeerConnectionEvents(pc) {
    // send any ice candidates to the other peer
    pc.onicecandidate = function (evt) {
      console.log('Local candidate: ', evt);
      socket.emit('message', {'candidate': evt.candidate});
    };
  }

  function setChannelEvents(channel) {
    channel.onmessage = function (event) {
      console.debug('Ext: ', event.data);
    };
    channel.onopen = function () {
      channelOpened = true;
      console.debug('Channel opened');
    };
    channel.onclose = function (e) {
      channelOpened = false;
      console.error(e);
    };
    channel.onerror = function (e) {
      console.error(e);
    };
  }

  socket.on('message', function (message) {
    if (message.sdp) {
      console.log('Remote sdp: ', message.sdp);
      pc.setRemoteDescription(new RTCSessionDescription(message.sdp));
    } else {
      console.log('Remote candidate: ', message.candidate);
      if(message.candidate){
        pc.addIceCandidate(new RTCIceCandidate(message.candidate));
      }

      app.extensionState = app.states.started;
    }
  });

  socket.on('joined', function (peer, room) {
    console.log('Join: ' + peer + ' : room ' + room);
    chrome.extension.sendMessage({roomUID: room});
  });

  socket.on('ready', function (message) {
    console.log('ready message');
  });

  return app;
})();

chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
  'use strict';

  console.log('Get message from popup: ' + msg.method);

  switch (msg.method) {
    case 'createRoom':
      app.createRoom(msg.name);
      break;
    case 'toggleStart':
      if (app.states.stopped === app.extensionState) {
        app.start();
      } else if (app.states.started === app.extensionState) {
        app.stop();
      }
      break;
    case 'join':
      chrome.tabs.create({'url': chrome.extension.getURL('index.html')}, function(tab) {
        // Tab opened.
      });
      break;
  }
});
<|endoftext|>


<commit_before>'use strict';

angular.module('backAnd.controllers')
    .controller('menuController', ['$scope', 'Global', 'menuService', '$timeout', '$rootScope', '$http', '$location', '$route',
        function($scope, Global, menuService, $timeout, $rootScope, $http, $location, $route) {

            $scope.global = Global;
            /*set contentType*/
$scope.global.url = "dashboard/my-website"
            $scope.templateUrl = function() {
                return "views/" + $scope.global.url + ".html";
            }
            /**/
            $scope.init = function() {
                console.log("fff")
                if (!localStorage.getItem('Authorization')) {
                    $location.path('/login');
                } else {
                    $location.path('/');
                    $http.defaults.headers.common['Authorization'] = localStorage.getItem('Authorization');
                    menuService.queryjsonp({},
                        function success(data) {
                            $scope.pages = data.workspace.pages;

                            $timeout(function() {
                                adminLteInit();
                            });
                        },
                        function err(error) {
                            if (error.status == 401) {
                                localStorage.removeItem("Authorization");
                                window.location.reload();
                            }
                        });
                }
            }
            $scope.setCurrentTable = function(table, index, partType) {
                console.log(partType)
                if (partType == "table")
                    $scope.global.url = "tables"
                if (partType == "dashbboard")
                    $scope.global.url = "dashboard/my-website"

                $scope.curTable = index;
                $scope.global.currentTable = table;
                //$rootScope.$broadcast('loadData');
            }
            $scope.$on('load', function() {
                $scope.init();
            });

        }
    ])
<commit_msg>dashboard chrts example<commit_after>'use strict';

angular.module('backAnd.controllers')
    .controller('menuController', ['$scope', 'Global', 'menuService', '$timeout', '$rootScope', '$http', '$location', '$route',
        function($scope, Global, menuService, $timeout, $rootScope, $http, $location, $route) {

            $scope.global = Global;
            /*set contentType*/
//$scope.global.url = "dashboard/my-website"
            $scope.templateUrl = function() {
                return "views/" + $scope.global.url + ".html";
            }
            /**/
            $scope.init = function() {
                console.log("fff")
                if (!localStorage.getItem('Authorization')) {
                    $location.path('/login');
                } else {
                    $location.path('/');
                    $http.defaults.headers.common['Authorization'] = localStorage.getItem('Authorization');
                    menuService.queryjsonp({},
                        function success(data) {
                            $scope.pages = data.workspace.pages;

                            $timeout(function() {
                                adminLteInit();
                            });
                        },
                        function err(error) {
                            if (error.status == 401) {
                                localStorage.removeItem("Authorization");
                                window.location.reload();
                            }
                        });
                }
            }
            $scope.setCurrentTable = function(table, index, partType) {
                console.log(partType)
                if (partType == "table")
                    $scope.global.url = "tables"
                if (partType == "dashboard")
                    $scope.global.url = "dashboard/my-website"

                $scope.curTable = index;
                $scope.global.currentTable = table;
                //$rootScope.$broadcast('loadData');
            }
            $scope.$on('load', function() {
                $scope.init();
            });

        }
    ])
<|endoftext|>


<commit_before>// ==UserScript==
// @name Monster Minigame AutoScript
// @author /u/mouseasw for creating and maintaining the script, /u/WinneonSword for the Greasemonkey support, and every contributor on the GitHub repo for constant enhancements.
// @version 1.3
// @namespace https://github.com/mouseas/steamSummerMinigame
// @description A script that runs the Steam Monster Minigame for you.
// @match http://steamcommunity.com/minigame/towerattack*
// @updateURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
// @downloadURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
// ==/UserScript==

// IMPORTANT: Update the @version property above to a higher number such as 1.1 and 1.2 when you update the script! Otherwise, Tamper / Greasemonkey users will not update automatically.

var isAlreadyRunning = false;

// disable particle effects - this drastically reduces the game's memory leak
if (window.g_Minigame !== undefined) {
	window.g_Minigame.CurrentScene().DoClickEffect = function() {};
	window.g_Minigame.CurrentScene().SpawnEmitter = function(emitter) {
		emitter.emit = false;
		return emitter;
	}
}

// disable enemy flinching animation when they get hit
if (window.CEnemy !== undefined) {
	window.CEnemy.prototype.TakeDamage = function() {};
	window.CEnemySpawner.prototype.TakeDamage = function() {};
	window.CEnemyBoss.prototype.TakeDamage = function() {};
}

if (thingTimer !== undefined) {
	window.clearTimeout(thingTimer);
}

function doTheThing() {
	if (isAlreadyRunning || g_Minigame === undefined || !g_Minigame.CurrentScene().m_bRunning || !g_Minigame.CurrentScene().m_rgPlayerTechTree) {
		return;
	}
	isAlreadyRunning = true;

	goToLaneWithBestTarget();

	useGoodLuckCharmIfRelevant();
	useMedicsIfRelevant();
	useMoraleBoosterIfRelevant();
	useClusterBombIfRelevant();
	useNapalmIfRelevant();

	// TODO use abilities if available and a suitable target exists
	// - Tactical Nuke on a Spawner if below 50% and above 25% of its health
	// - Cluster Bomb and Napalm if the current lane has a spawner and 2+ creeps
	// - Metal Detector if a boss, miniboss, or spawner death is imminent (predicted in > 2 and < 7 seconds)
	// - Morale Booster if available and lane has > 2 live enemies
	// - Decrease Cooldowns if another player used a long-cooldown ability < 10 seconds ago (any ability but Medics or a consumable)

	// TODO purchase abilities and upgrades intelligently

	attemptRespawn();

	isAlreadyRunning = false;
}

var ABILITIES = {
	"GOOD_LUCK": 6,
	"MEDIC": 7,
	"METAL_DETECTOR": 8,
	"COOLDOWN": 9,
	"NUKE": 10,
	"CLUSTER_BOMB": 11,
	"NAPALM": 12
};

var ITEMS = {
	"REVIVE": 13,
	"GOLD_RAIN": 17,
	"GOD_MODE": 21,
	"REFLECT_DAMAGE":24
}

function goToLaneWithBestTarget() {
	// We can overlook spawners if all spawners are 40% hp or higher and a creep is under 10% hp
	var spawnerOKThreshold = 0.4;
	var creepSnagThreshold = 0.1;

	var targetFound = false;
	var lowHP = 0;
	var lowLane = 0;
	var lowTarget = 0;
	var lowPercentageHP = 0;

	var ENEMY_TYPE = {
		"SPAWNER":0,
		"CREEP":1,
		"BOSS":2,
		"MINIBOSS":3,
		"TREASURE":4
	}

	// determine which lane and enemy is the optimal target
	var enemyTypePriority = [
		ENEMY_TYPE.TREASURE,
		ENEMY_TYPE.BOSS,
		ENEMY_TYPE.MINIBOSS,
		ENEMY_TYPE.SPAWNER,
		ENEMY_TYPE.CREEP
		];

	var skippingSpawner = false;
	var skippedSpawnerLane = 0;
	var skippedSpawnerTarget = 0;

	for (var k = 0; !targetFound && k < enemyTypePriority.length; k++) {
		var enemies = [];

		// gather all the enemies of the specified type.
		for (var i = 0; i < 3; i++) {
			for (var j = 0; j < 4; j++) {
				var enemy = g_Minigame.CurrentScene().GetEnemy(i, j);
				if (enemy && enemy.m_data.type == enemyTypePriority[k]) {
					enemies[enemies.length] = enemy;
				}
			}
		}

		// target the enemy of the specified type with the lowest hp
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i] && !enemies[i].m_bIsDestroyed) {
				if(lowHP < 1 || enemies[i].m_flDisplayedHP < lowHP) {
					targetFound = true;
					lowHP = enemies[i].m_flDisplayedHP;
					lowLane = enemies[i].m_nLane;
					lowTarget = enemies[i].m_nID;
				}
				var percentageHP = enemies[i].m_flDisplayedHP / enemies[i].m_data.max_hp;
				if(lowPercentageHP == 0 || percentageHP < lowPercentageHP) {
					lowPercentageHP = percentageHP;
				}
			}
		}

		// If we just finished looking at spawners,
		// AND none of them were below our threshold,
		// remember them and look for low creeps (so don't quit now)
		if (enemyTypePriority[k] == ENEMY_TYPE.SPAWNER && lowPercentageHP > spawnerOKThreshold) {
			skippedSpawnerLane = lowLane;
			skippedSpawnerTarget = lowTarget;
			skippingSpawner = true;
			targetFound = false;
		}

		// If we skipped a spawner and just finished looking at creeps,
		// AND the lowest was above our snag threshold,
		// just go back to the spawner!
		if (skippingSpawner && enemyTypePriority[k] == ENEMY_TYPE.CREEP && lowPercentageHP > creepSnagThreshold ) {
			lowLane = skippedSpawnerLane;
			lowTarget = skippedSpawnerTarget;
		}
	}

	// go to the chosen lane
	if (targetFound) {
		if (g_Minigame.CurrentScene().m_nExpectedLane != lowLane) {
			//console.log('switching langes');
			g_Minigame.CurrentScene().TryChangeLane(lowLane);
		}

		// target the chosen enemy
		if (g_Minigame.CurrentScene().m_nTarget != lowTarget) {
			//console.log('switching targets');
			g_Minigame.CurrentScene().TryChangeTarget(lowTarget);
		}
	}
}

function useMedicsIfRelevant() {
	var myMaxHealth = g_Minigame.CurrentScene().m_rgPlayerTechTree.max_hp;

	// check if health is below 50%
	var hpPercent = g_Minigame.CurrentScene().m_rgPlayerData.hp / myMaxHealth;
	if (hpPercent > 0.5 || g_Minigame.CurrentScene().m_rgPlayerData.hp < 1) {
		return; // no need to heal - HP is above 50% or already dead
	}

	// check if Medics is purchased and cooled down
	if (hasPurchasedAbility(ABILITIES.MEDIC) && !isAbilityCoolingDown(ABILITIES.MEDIC)) {

		// Medics is purchased, cooled down, and needed. Trigger it.
		console.log('Medics is purchased, cooled down, and needed. Trigger it.');
		triggerAbility(ABILITIES.MEDIC);
	} else if (hasItem(ITEMS.GOD_MODE) && !isAbilityCoolingDown(ITEMS.GOD_MODE)) {

		console.log('We have god mode, cooled down, and needed. Trigger it.');
		triggerItem(ITEMS.GOD_MODE);
	}
};

// Use Good Luck Charm if doable
function useGoodLuckCharmIfRelevant() {
	// check if Good Luck Charms is purchased and cooled down
	if (hasPurchasedAbility(ABILITIES.GOOD_LUCK)) {
		if (isAbilityCoolingDown(ABILITIES.GOOD_LUCK)) {
			return;
		}

		// Good Luck Charms is purchased, cooled down, and needed. Trigger it.
		console.log('Good Luck Charms is purchased, cooled down, and needed. Trigger it.');
		triggerAbility(ABILITIES.GOOD_LUCK);
	}
}

function useClusterBombIfRelevant() {
	//Check if Cluster Bomb is purchased and cooled down
	if (hasPurchasedAbility(11)) {
		if (isAbilityCoolingDown(11)) {
			return;
		}

		//Check lane has monsters to explode
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Bombs away if spawner and 2+ other monsters
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(11);
		}
	}
}

function useNapalmIfRelevant() {
	//Check if Napalm is purchased and cooled down
	if (hasPurchasedAbility(12)) {
		if (isAbilityCoolingDown(12)) {
			return;
		}

		//Check lane has monsters to burn
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Burn them all if spawner and 2+ other monsters
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(12);
		}
	}
}

function useMoraleBoosterIfRelevant() {
	// Check if Morale Booster is purchased
	if(hasPurchasedAbility(5)) {
		if (isAbilityCoolingDown(5)) {
			return;
		}

		//Check lane has monsters so the hype isn't wasted
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Hype everybody up!
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(5);
		}
	}
}

//If player is dead, call respawn method
function attemptRespawn() {
	if ((g_Minigame.CurrentScene().m_bIsDead) &&
			((g_Minigame.CurrentScene().m_rgPlayerData.time_died * 1000) + 5000) < (new Date().getTime())) {
		RespawnPlayer();
	}
}

function isAbilityActive(abilityId) {
	return g_Minigame.CurrentScene().bIsAbilityActive(abilityId);
}

function hasItem(itemId) {
	for ( var i = 0; i < g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items.length; ++i ) {
		var abilityItem = g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items[i];
		if (abilityItem.ability == itemId) {
			return true;
		}
	}
	return false;
}

function isAbilityCoolingDown(abilityId) {
	return g_Minigame.CurrentScene().GetCooldownForAbility(abilityId) > 0;
}

function hasPurchasedAbility(abilityId) {
	// each bit in unlocked_abilities_bitfield corresponds to an ability.
	// the above condition checks if the ability's bit is set or cleared. I.e. it checks if
	// the player has purchased the specified ability.
	return (1 << abilityId) & g_Minigame.CurrentScene().m_rgPlayerTechTree.unlocked_abilities_bitfield;
}

function triggerItem(itemId) {
	var elem = document.getElementById('abilityitem_' + itemId);
	if (elem && elem.childElements() && elem.childElements().length >= 1) {
		g_Minigame.CurrentScene().TryAbility(document.getElementById('abilityitem_' + itemId).childElements()[0]);
	}
}

function triggerAbility(abilityId) {
	var elem = document.getElementById('ability_' + abilityId);
	if (elem && elem.childElements() && elem.childElements().length >= 1) {
		g_Minigame.CurrentScene().TryAbility(document.getElementById('ability_' + abilityId).childElements()[0]);
	}
}

var thingTimer = window.setInterval(doTheThing, 1000);
<commit_msg>Fixed wrongly incremented version number.<commit_after>// ==UserScript==
// @name Monster Minigame AutoScript
// @author /u/mouseasw for creating and maintaining the script, /u/WinneonSword for the Greasemonkey support, and every contributor on the GitHub repo for constant enhancements.
// @version 1.4
// @namespace https://github.com/mouseas/steamSummerMinigame
// @description A script that runs the Steam Monster Minigame for you.
// @match http://steamcommunity.com/minigame/towerattack*
// @updateURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
// @downloadURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
// ==/UserScript==

// IMPORTANT: Update the @version property above to a higher number such as 1.1 and 1.2 when you update the script! Otherwise, Tamper / Greasemonkey users will not update automatically.

var isAlreadyRunning = false;

// disable particle effects - this drastically reduces the game's memory leak
if (window.g_Minigame !== undefined) {
	window.g_Minigame.CurrentScene().DoClickEffect = function() {};
	window.g_Minigame.CurrentScene().SpawnEmitter = function(emitter) {
		emitter.emit = false;
		return emitter;
	}
}

// disable enemy flinching animation when they get hit
if (window.CEnemy !== undefined) {
	window.CEnemy.prototype.TakeDamage = function() {};
	window.CEnemySpawner.prototype.TakeDamage = function() {};
	window.CEnemyBoss.prototype.TakeDamage = function() {};
}

if (thingTimer !== undefined) {
	window.clearTimeout(thingTimer);
}

function doTheThing() {
	if (isAlreadyRunning || g_Minigame === undefined || !g_Minigame.CurrentScene().m_bRunning || !g_Minigame.CurrentScene().m_rgPlayerTechTree) {
		return;
	}
	isAlreadyRunning = true;

	goToLaneWithBestTarget();

	useGoodLuckCharmIfRelevant();
	useMedicsIfRelevant();
	useMoraleBoosterIfRelevant();
	useClusterBombIfRelevant();
	useNapalmIfRelevant();

	// TODO use abilities if available and a suitable target exists
	// - Tactical Nuke on a Spawner if below 50% and above 25% of its health
	// - Cluster Bomb and Napalm if the current lane has a spawner and 2+ creeps
	// - Metal Detector if a boss, miniboss, or spawner death is imminent (predicted in > 2 and < 7 seconds)
	// - Morale Booster if available and lane has > 2 live enemies
	// - Decrease Cooldowns if another player used a long-cooldown ability < 10 seconds ago (any ability but Medics or a consumable)

	// TODO purchase abilities and upgrades intelligently

	attemptRespawn();

	isAlreadyRunning = false;
}

var ABILITIES = {
	"GOOD_LUCK": 6,
	"MEDIC": 7,
	"METAL_DETECTOR": 8,
	"COOLDOWN": 9,
	"NUKE": 10,
	"CLUSTER_BOMB": 11,
	"NAPALM": 12
};

var ITEMS = {
	"REVIVE": 13,
	"GOLD_RAIN": 17,
	"GOD_MODE": 21,
	"REFLECT_DAMAGE":24
}

function goToLaneWithBestTarget() {
	// We can overlook spawners if all spawners are 40% hp or higher and a creep is under 10% hp
	var spawnerOKThreshold = 0.4;
	var creepSnagThreshold = 0.1;

	var targetFound = false;
	var lowHP = 0;
	var lowLane = 0;
	var lowTarget = 0;
	var lowPercentageHP = 0;

	var ENEMY_TYPE = {
		"SPAWNER":0,
		"CREEP":1,
		"BOSS":2,
		"MINIBOSS":3,
		"TREASURE":4
	}

	// determine which lane and enemy is the optimal target
	var enemyTypePriority = [
		ENEMY_TYPE.TREASURE,
		ENEMY_TYPE.BOSS,
		ENEMY_TYPE.MINIBOSS,
		ENEMY_TYPE.SPAWNER,
		ENEMY_TYPE.CREEP
		];

	var skippingSpawner = false;
	var skippedSpawnerLane = 0;
	var skippedSpawnerTarget = 0;

	for (var k = 0; !targetFound && k < enemyTypePriority.length; k++) {
		var enemies = [];

		// gather all the enemies of the specified type.
		for (var i = 0; i < 3; i++) {
			for (var j = 0; j < 4; j++) {
				var enemy = g_Minigame.CurrentScene().GetEnemy(i, j);
				if (enemy && enemy.m_data.type == enemyTypePriority[k]) {
					enemies[enemies.length] = enemy;
				}
			}
		}

		// target the enemy of the specified type with the lowest hp
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i] && !enemies[i].m_bIsDestroyed) {
				if(lowHP < 1 || enemies[i].m_flDisplayedHP < lowHP) {
					targetFound = true;
					lowHP = enemies[i].m_flDisplayedHP;
					lowLane = enemies[i].m_nLane;
					lowTarget = enemies[i].m_nID;
				}
				var percentageHP = enemies[i].m_flDisplayedHP / enemies[i].m_data.max_hp;
				if(lowPercentageHP == 0 || percentageHP < lowPercentageHP) {
					lowPercentageHP = percentageHP;
				}
			}
		}

		// If we just finished looking at spawners,
		// AND none of them were below our threshold,
		// remember them and look for low creeps (so don't quit now)
		if (enemyTypePriority[k] == ENEMY_TYPE.SPAWNER && lowPercentageHP > spawnerOKThreshold) {
			skippedSpawnerLane = lowLane;
			skippedSpawnerTarget = lowTarget;
			skippingSpawner = true;
			targetFound = false;
		}

		// If we skipped a spawner and just finished looking at creeps,
		// AND the lowest was above our snag threshold,
		// just go back to the spawner!
		if (skippingSpawner && enemyTypePriority[k] == ENEMY_TYPE.CREEP && lowPercentageHP > creepSnagThreshold ) {
			lowLane = skippedSpawnerLane;
			lowTarget = skippedSpawnerTarget;
		}
	}

	// go to the chosen lane
	if (targetFound) {
		if (g_Minigame.CurrentScene().m_nExpectedLane != lowLane) {
			//console.log('switching langes');
			g_Minigame.CurrentScene().TryChangeLane(lowLane);
		}

		// target the chosen enemy
		if (g_Minigame.CurrentScene().m_nTarget != lowTarget) {
			//console.log('switching targets');
			g_Minigame.CurrentScene().TryChangeTarget(lowTarget);
		}
	}
}

function useMedicsIfRelevant() {
	var myMaxHealth = g_Minigame.CurrentScene().m_rgPlayerTechTree.max_hp;

	// check if health is below 50%
	var hpPercent = g_Minigame.CurrentScene().m_rgPlayerData.hp / myMaxHealth;
	if (hpPercent > 0.5 || g_Minigame.CurrentScene().m_rgPlayerData.hp < 1) {
		return; // no need to heal - HP is above 50% or already dead
	}

	// check if Medics is purchased and cooled down
	if (hasPurchasedAbility(ABILITIES.MEDIC) && !isAbilityCoolingDown(ABILITIES.MEDIC)) {

		// Medics is purchased, cooled down, and needed. Trigger it.
		console.log('Medics is purchased, cooled down, and needed. Trigger it.');
		triggerAbility(ABILITIES.MEDIC);
	} else if (hasItem(ITEMS.GOD_MODE) && !isAbilityCoolingDown(ITEMS.GOD_MODE)) {

		console.log('We have god mode, cooled down, and needed. Trigger it.');
		triggerItem(ITEMS.GOD_MODE);
	}
};

// Use Good Luck Charm if doable
function useGoodLuckCharmIfRelevant() {
	// check if Good Luck Charms is purchased and cooled down
	if (hasPurchasedAbility(ABILITIES.GOOD_LUCK)) {
		if (isAbilityCoolingDown(ABILITIES.GOOD_LUCK)) {
			return;
		}

		// Good Luck Charms is purchased, cooled down, and needed. Trigger it.
		console.log('Good Luck Charms is purchased, cooled down, and needed. Trigger it.');
		triggerAbility(ABILITIES.GOOD_LUCK);
	}
}

function useClusterBombIfRelevant() {
	//Check if Cluster Bomb is purchased and cooled down
	if (hasPurchasedAbility(11)) {
		if (isAbilityCoolingDown(11)) {
			return;
		}

		//Check lane has monsters to explode
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Bombs away if spawner and 2+ other monsters
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(11);
		}
	}
}

function useNapalmIfRelevant() {
	//Check if Napalm is purchased and cooled down
	if (hasPurchasedAbility(12)) {
		if (isAbilityCoolingDown(12)) {
			return;
		}

		//Check lane has monsters to burn
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Burn them all if spawner and 2+ other monsters
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(12);
		}
	}
}

function useMoraleBoosterIfRelevant() {
	// Check if Morale Booster is purchased
	if(hasPurchasedAbility(5)) {
		if (isAbilityCoolingDown(5)) {
			return;
		}

		//Check lane has monsters so the hype isn't wasted
		var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
		var enemyCount = 0;
		var enemySpawnerExists = false;
		//Count each slot in lane
		for (var i = 0; i < 4; i++) {
			var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
			if (enemy) {
				enemyCount++;
				if (enemy.m_data.type == 0) {
					enemySpawnerExists = true;
				}
			}
		}
		//Hype everybody up!
		if (enemySpawnerExists && enemyCount >= 3) {
			triggerAbility(5);
		}
	}
}

//If player is dead, call respawn method
function attemptRespawn() {
	if ((g_Minigame.CurrentScene().m_bIsDead) &&
			((g_Minigame.CurrentScene().m_rgPlayerData.time_died * 1000) + 5000) < (new Date().getTime())) {
		RespawnPlayer();
	}
}

function isAbilityActive(abilityId) {
	return g_Minigame.CurrentScene().bIsAbilityActive(abilityId);
}

function hasItem(itemId) {
	for ( var i = 0; i < g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items.length; ++i ) {
		var abilityItem = g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items[i];
		if (abilityItem.ability == itemId) {
			return true;
		}
	}
	return false;
}

function isAbilityCoolingDown(abilityId) {
	return g_Minigame.CurrentScene().GetCooldownForAbility(abilityId) > 0;
}

function hasPurchasedAbility(abilityId) {
	// each bit in unlocked_abilities_bitfield corresponds to an ability.
	// the above condition checks if the ability's bit is set or cleared. I.e. it checks if
	// the player has purchased the specified ability.
	return (1 << abilityId) & g_Minigame.CurrentScene().m_rgPlayerTechTree.unlocked_abilities_bitfield;
}

function triggerItem(itemId) {
	var elem = document.getElementById('abilityitem_' + itemId);
	if (elem && elem.childElements() && elem.childElements().length >= 1) {
		g_Minigame.CurrentScene().TryAbility(document.getElementById('abilityitem_' + itemId).childElements()[0]);
	}
}

function triggerAbility(abilityId) {
	var elem = document.getElementById('ability_' + abilityId);
	if (elem && elem.childElements() && elem.childElements().length >= 1) {
		g_Minigame.CurrentScene().TryAbility(document.getElementById('ability_' + abilityId).childElements()[0]);
	}
}

var thingTimer = window.setInterval(doTheThing, 1000);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { Provider } from 'react-redux';
import CounterApp from './App';

export default class Root extends Component {
  static propTypes = {
    store: PropTypes.object.isRequired
  };

  render() {
    const { store } = this.props;
    return (
      <Provider store={store}>
        <CounterApp />
      </Provider>
    );
  }
}
<commit_msg>Rename container to App to be easer to extend the boilerplate<commit_after>import React, { Component, PropTypes } from 'react';
import { Provider } from 'react-redux';
import App from './App';

export default class Root extends Component {
  static propTypes = {
    store: PropTypes.object.isRequired
  };

  render() {
    const { store } = this.props;
    return (
      <Provider store={store}>
        <App />
      </Provider>
    );
  }
}
<|endoftext|>


<commit_before>pc.extend(pc.fw, function () {
    var REMOTE_CAMERA_NEAR_CLIP = 0.5;
    var REMOTE_CAMERA_FAR_CLIP = 2;

    /**
     * @name pc.fw.CameraComponentSystem
     * @class Used to add and remove {@link pc.fw.CameraComponent}s from Entities.
     * It also manages the currently active camera and controls the rendering part of the frame with beginFrame()/endFrame().
     * @constructor Create a new CameraComponentSystem
     * @param {Object} context
     * @extends pc.fw.ComponentSystem
     */
    var CameraComponentSystem = function (context) {
        this.id = 'camera';
        this.description = "Renders the scene from the location of the Entity.";
        context.systems.add(this.id, this);

        this.ComponentType = pc.fw.CameraComponent;
        this.DataType = pc.fw.CameraComponentData;

        this.schema = [{
            name: "clearColor",
            displayName: "Clear Color",
            description: "Clear Color",
            type: "rgba",
            defaultValue: [0.7294117647058823, 0.7294117647058823, 0.6941176470588235, 1.0]
        }, {
            name: "projection",
            displayName: "Projection",
            description: "Projection type of camera",
            type: "enumeration",
            options: {
                enumerations: [{
                    name: 'Perspective',
                    value: 0
                }, {
                    name: 'Orthographic',
                    value: 1
                }]
            },
            defaultValue: 0
        }, {
            name: "fov",
            displayName: "Field of View",
            description: "Field of view in Y axis",
            type: "number",
            defaultValue: 45,
            options: {
                min: 0,
                max: 90
            }
        }, {
            name: "orthoHeight",
            displayName: "Ortho Height",
            description: "View window half extent of camera in Y axis",
            type: "number",
            defaultValue: 100
        }, {
            name: "nearClip",
            displayName: "Near Clip",
            description: "Near clipping distance",
            type: "number",
            defaultValue: 1,
            options: {
                min: 0
            }
        }, {
            name: "farClip",
            displayName: "Far Clip",
            description: "Far clipping distance",
            type: "number",
            defaultValue: 100000,
            options: {
                min: 0
            }
        }, {
            name: "activate",
            displayName: "Activate",
            description: "Activate camera when scene loads",
            type: "boolean",
            defaultValue: true
        },{
            name: "camera",
            exposed: false
        }, {
            name: "aspectRatio",
            exposed: false
        }, {
            name: "model",
            exposed: false
        }, {
            name: "renderTarget",
            exposed: false
        }];

        this.exposeProperties();

        this._currentEntity = null;
        this._currentNode = null;

        this.on('remove', this.onRemove, this);
        pc.fw.ComponentSystem.on('toolsUpdate', this.toolsUpdate, this);

    };
    CameraComponentSystem = pc.inherits(CameraComponentSystem, pc.fw.ComponentSystem);

    /**
    * @property
    * @name pc.fw.CameraComponentSystem#current
    * @description Get or set the current camera. Use this property to set which Camera Entity is used to render the scene. This must be set to an Entity with a {@link pc.fw.CameraComponent}.
    * @type pc.fw.Entity
    * @example
    * var e = context.root.findByName('A Camera');
    * context.systems.camera.current = e;
    */
    Object.defineProperty(CameraComponentSystem.prototype, 'current', {
        get: function () {
            return this._currentEntity;
        },
        set: function (entity) {
            if (entity === null) {
                this._currentEntity = null;
                this._currentNode = null;
                return;
            }

            if (!entity.camera) {
                throw Error("Entity must have camera Component");
            }

            this._currentEntity = entity;
            this._currentNode = entity.camera.data.camera;
        }
    });

    pc.extend(CameraComponentSystem.prototype, {
        initializeComponentData: function (component, data, properties) {
            data = data || {};
            data.camera = new pc.scene.CameraNode();
            if (data.clearColor) {
                data.clearColor = new pc.Color(data.clearColor);
            }

            if (this.context.designer && this.displayInTools(component.entity)) {
                var material = new pc.scene.BasicMaterial();
                material.color = pc.math.vec4.create(1, 1, 0, 1);
                material.update();

                var indexBuffer = new pc.gfx.IndexBuffer(this.context.graphicsDevice, pc.gfx.INDEXFORMAT_UINT8, 24);
                var indices = new Uint8Array(indexBuffer.lock());
                indices.set([0,1,1,2,2,3,3,0, // Near plane
                             4,5,5,6,6,7,7,4, // Far plane
                             0,4,1,5,2,6,3,7]); // Near to far edges
                indexBuffer.unlock();

                var format = new pc.gfx.VertexFormat(this.context.graphicsDevice, [
                    { semantic: pc.gfx.SEMANTIC_POSITION, components: 3, type: pc.gfx.ELEMENTTYPE_FLOAT32 }
                ]);

                var vertexBuffer = new pc.gfx.VertexBuffer(this.context.graphicsDevice, format, 8, pc.gfx.BUFFER_DYNAMIC);

                var mesh = new pc.scene.Mesh();
                mesh.vertexBuffer = vertexBuffer;
                mesh.indexBuffer[0] = indexBuffer;
                mesh.primitive[0].type = pc.gfx.PRIMITIVE_LINES;
                mesh.primitive[0].base = 0;
                mesh.primitive[0].count = indexBuffer.getNumIndices();
                mesh.primitive[0].indexed = true;

                var model = new pc.scene.Model();
                model.graph = data.camera;
                model.meshInstances = [ new pc.scene.MeshInstance(model.graph, mesh, material) ];

                this.context.scene.addModel(model);

                data.model = model;
            }

            properties = ['model', 'camera', 'aspectRatio', 'renderTarget', 'clearColor', 'fov', 'orthoHeight', 'activate', 'nearClip', 'farClip', 'projection'];

            CameraComponentSystem._super.initializeComponentData.call(this, component, data, properties);

            if (!window.pc.apps.designer && component.activate && !component.entity.hasLabel("pc:designer")) {
                this.current = component.entity;
            }
        },

        /**
         * Start rendering the frame for the current camera
         * @function
         * @name pc.fw.CameraComponentSystem#frameBegin
         */
        frameBegin: function () {
            var camera = this._currentNode;
            if (!camera) {
                return;
            }

            var device = this.context.graphicsDevice;
            var aspect = device.width / device.height;
            if (aspect !== camera.getAspectRatio()) {
                camera.setAspectRatio(aspect);
            }
        },

        /**
         * End rendering the frame for the current camera
         * @function
         * @name pc.fw.CameraComponentSystem#frameEnd
         */
        frameEnd: function () {
        },

        onRemove: function (entity, data) {
            // If this is the current camera then clear it
            if (this._currentEntity === entity) {
                this.current = null;
            }

            if (this.context.designer && this.displayInTools(entity)) {
                if (this.context.scene.containsModel(data.model)) {
                    this.context.scene.removeModel(data.model);
                }
            }

            entity.removeChild(data.camera);
            data.camera = null;
        },

        toolsUpdate: function (fn) {
            var components = this.store;
            for (var id in components) {
                if (components.hasOwnProperty(id)) {
                    var entity = components[id].entity;
                    var data = components[id].data;

                    if (this.displayInTools(entity)) {
                        this._updateGfx(entity.camera);
                    }
                }
            }
        },

        _updateGfx: function (component) {
            if (component.model && component.model.meshInstances.length) {
                var vertexBuffer = component.model.meshInstances[0].mesh.vertexBuffer;

                // Retrieve the characteristics of the camera frustum
                var aspectRatio = component.camera.getAspectRatio();
                var nearClip    = this.isToolsCamera(component.entity) ? REMOTE_CAMERA_NEAR_CLIP : component.nearClip; // Remote User cameras don't display full extents
                var farClip     = this.isToolsCamera(component.entity) ? REMOTE_CAMERA_FAR_CLIP : component.farClip; // Remote User cameras don't display full extents
                var fov         = component.fov * Math.PI / 180.0;
                var projection  = component.projection;

                var x, y;
                if (projection === pc.scene.Projection.PERSPECTIVE) {
                    y = Math.tan(fov / 2.0) * nearClip;
                } else {
                    y = component.camera.getOrthoHeight();
                }
                x = y * aspectRatio;

                var positions = new Float32Array(vertexBuffer.lock());
                positions[0]  = x;
                positions[1]  = -y;
                positions[2]  = -nearClip;
                positions[3]  = x;
                positions[4]  = y;
                positions[5]  = -nearClip;
                positions[6]  = -x;
                positions[7]  = y;
                positions[8]  = -nearClip;
                positions[9]  = -x;
                positions[10] = -y;
                positions[11] = -nearClip;

                if (projection === pc.scene.Projection.PERSPECTIVE) {
                    y = Math.tan(fov / 2.0) * farClip;
                    x = y * aspectRatio;
                }
                positions[12] = x;
                positions[13] = -y;
                positions[14] = -farClip;
                positions[15] = x;
                positions[16] = y;
                positions[17] = -farClip;
                positions[18] = -x;
                positions[19] = y;
                positions[20] = -farClip;
                positions[21] = -x;
                positions[22] = -y;
                positions[23] = -farClip;
                vertexBuffer.unlock();
            }
        },

        isToolsCamera: function (entity) {
            return entity.hasLabel("pc:designer");
        },

        displayInTools: function (entity) {
            return (!this.isToolsCamera(entity) || (entity.getName() === "Perspective"));
        }
    });

    return {
        CameraComponentSystem: CameraComponentSystem
    };
}());<commit_msg>Filtering camera fov and orthoHeight based on projection<commit_after>pc.extend(pc.fw, function () {
    var REMOTE_CAMERA_NEAR_CLIP = 0.5;
    var REMOTE_CAMERA_FAR_CLIP = 2;

    /**
     * @name pc.fw.CameraComponentSystem
     * @class Used to add and remove {@link pc.fw.CameraComponent}s from Entities.
     * It also manages the currently active camera and controls the rendering part of the frame with beginFrame()/endFrame().
     * @constructor Create a new CameraComponentSystem
     * @param {Object} context
     * @extends pc.fw.ComponentSystem
     */
    var CameraComponentSystem = function (context) {
        this.id = 'camera';
        this.description = "Renders the scene from the location of the Entity.";
        context.systems.add(this.id, this);

        this.ComponentType = pc.fw.CameraComponent;
        this.DataType = pc.fw.CameraComponentData;

        this.schema = [{
            name: "clearColor",
            displayName: "Clear Color",
            description: "Clear Color",
            type: "rgba",
            defaultValue: [0.7294117647058823, 0.7294117647058823, 0.6941176470588235, 1.0]
        }, {
            name: "projection",
            displayName: "Projection",
            description: "Projection type of camera",
            type: "enumeration",
            options: {
                enumerations: [{
                    name: 'Perspective',
                    value: 0
                }, {
                    name: 'Orthographic',
                    value: 1
                }]
            },
            defaultValue: 0
        }, {
            name: "fov",
            displayName: "Field of View",
            description: "Field of view in Y axis",
            type: "number",
            defaultValue: 45,
            options: {
                min: 0,
                max: 90
            },
            filter: {
                projection: 0
            }
        }, {
            name: "orthoHeight",
            displayName: "Ortho Height",
            description: "View window half extent of camera in Y axis",
            type: "number",
            defaultValue: 100,
            filter: {
                projection: 1
            }
        }, {
            name: "nearClip",
            displayName: "Near Clip",
            description: "Near clipping distance",
            type: "number",
            defaultValue: 1,
            options: {
                min: 0
            }
        }, {
            name: "farClip",
            displayName: "Far Clip",
            description: "Far clipping distance",
            type: "number",
            defaultValue: 100000,
            options: {
                min: 0
            }
        }, {
            name: "activate",
            displayName: "Activate",
            description: "Activate camera when scene loads",
            type: "boolean",
            defaultValue: true
        },{
            name: "camera",
            exposed: false
        }, {
            name: "aspectRatio",
            exposed: false
        }, {
            name: "model",
            exposed: false
        }, {
            name: "renderTarget",
            exposed: false
        }];

        this.exposeProperties();

        this._currentEntity = null;
        this._currentNode = null;

        this.on('remove', this.onRemove, this);
        pc.fw.ComponentSystem.on('toolsUpdate', this.toolsUpdate, this);

    };
    CameraComponentSystem = pc.inherits(CameraComponentSystem, pc.fw.ComponentSystem);

    /**
    * @property
    * @name pc.fw.CameraComponentSystem#current
    * @description Get or set the current camera. Use this property to set which Camera Entity is used to render the scene. This must be set to an Entity with a {@link pc.fw.CameraComponent}.
    * @type pc.fw.Entity
    * @example
    * var e = context.root.findByName('A Camera');
    * context.systems.camera.current = e;
    */
    Object.defineProperty(CameraComponentSystem.prototype, 'current', {
        get: function () {
            return this._currentEntity;
        },
        set: function (entity) {
            if (entity === null) {
                this._currentEntity = null;
                this._currentNode = null;
                return;
            }

            if (!entity.camera) {
                throw Error("Entity must have camera Component");
            }

            this._currentEntity = entity;
            this._currentNode = entity.camera.data.camera;
        }
    });

    pc.extend(CameraComponentSystem.prototype, {
        initializeComponentData: function (component, data, properties) {
            data = data || {};
            data.camera = new pc.scene.CameraNode();
            if (data.clearColor) {
                data.clearColor = new pc.Color(data.clearColor);
            }

            if (this.context.designer && this.displayInTools(component.entity)) {
                var material = new pc.scene.BasicMaterial();
                material.color = pc.math.vec4.create(1, 1, 0, 1);
                material.update();

                var indexBuffer = new pc.gfx.IndexBuffer(this.context.graphicsDevice, pc.gfx.INDEXFORMAT_UINT8, 24);
                var indices = new Uint8Array(indexBuffer.lock());
                indices.set([0,1,1,2,2,3,3,0, // Near plane
                             4,5,5,6,6,7,7,4, // Far plane
                             0,4,1,5,2,6,3,7]); // Near to far edges
                indexBuffer.unlock();

                var format = new pc.gfx.VertexFormat(this.context.graphicsDevice, [
                    { semantic: pc.gfx.SEMANTIC_POSITION, components: 3, type: pc.gfx.ELEMENTTYPE_FLOAT32 }
                ]);

                var vertexBuffer = new pc.gfx.VertexBuffer(this.context.graphicsDevice, format, 8, pc.gfx.BUFFER_DYNAMIC);

                var mesh = new pc.scene.Mesh();
                mesh.vertexBuffer = vertexBuffer;
                mesh.indexBuffer[0] = indexBuffer;
                mesh.primitive[0].type = pc.gfx.PRIMITIVE_LINES;
                mesh.primitive[0].base = 0;
                mesh.primitive[0].count = indexBuffer.getNumIndices();
                mesh.primitive[0].indexed = true;

                var model = new pc.scene.Model();
                model.graph = data.camera;
                model.meshInstances = [ new pc.scene.MeshInstance(model.graph, mesh, material) ];

                this.context.scene.addModel(model);

                data.model = model;
            }

            properties = ['model', 'camera', 'aspectRatio', 'renderTarget', 'clearColor', 'fov', 'orthoHeight', 'activate', 'nearClip', 'farClip', 'projection'];

            CameraComponentSystem._super.initializeComponentData.call(this, component, data, properties);

            if (!window.pc.apps.designer && component.activate && !component.entity.hasLabel("pc:designer")) {
                this.current = component.entity;
            }
        },

        /**
         * Start rendering the frame for the current camera
         * @function
         * @name pc.fw.CameraComponentSystem#frameBegin
         */
        frameBegin: function () {
            var camera = this._currentNode;
            if (!camera) {
                return;
            }

            var device = this.context.graphicsDevice;
            var aspect = device.width / device.height;
            if (aspect !== camera.getAspectRatio()) {
                camera.setAspectRatio(aspect);
            }
        },

        /**
         * End rendering the frame for the current camera
         * @function
         * @name pc.fw.CameraComponentSystem#frameEnd
         */
        frameEnd: function () {
        },

        onRemove: function (entity, data) {
            // If this is the current camera then clear it
            if (this._currentEntity === entity) {
                this.current = null;
            }

            if (this.context.designer && this.displayInTools(entity)) {
                if (this.context.scene.containsModel(data.model)) {
                    this.context.scene.removeModel(data.model);
                }
            }

            entity.removeChild(data.camera);
            data.camera = null;
        },

        toolsUpdate: function (fn) {
            var components = this.store;
            for (var id in components) {
                if (components.hasOwnProperty(id)) {
                    var entity = components[id].entity;
                    var data = components[id].data;

                    if (this.displayInTools(entity)) {
                        this._updateGfx(entity.camera);
                    }
                }
            }
        },

        _updateGfx: function (component) {
            if (component.model && component.model.meshInstances.length) {
                var vertexBuffer = component.model.meshInstances[0].mesh.vertexBuffer;

                // Retrieve the characteristics of the camera frustum
                var aspectRatio = component.camera.getAspectRatio();
                var nearClip    = this.isToolsCamera(component.entity) ? REMOTE_CAMERA_NEAR_CLIP : component.nearClip; // Remote User cameras don't display full extents
                var farClip     = this.isToolsCamera(component.entity) ? REMOTE_CAMERA_FAR_CLIP : component.farClip; // Remote User cameras don't display full extents
                var fov         = component.fov * Math.PI / 180.0;
                var projection  = component.projection;

                var x, y;
                if (projection === pc.scene.Projection.PERSPECTIVE) {
                    y = Math.tan(fov / 2.0) * nearClip;
                } else {
                    y = component.camera.getOrthoHeight();
                }
                x = y * aspectRatio;

                var positions = new Float32Array(vertexBuffer.lock());
                positions[0]  = x;
                positions[1]  = -y;
                positions[2]  = -nearClip;
                positions[3]  = x;
                positions[4]  = y;
                positions[5]  = -nearClip;
                positions[6]  = -x;
                positions[7]  = y;
                positions[8]  = -nearClip;
                positions[9]  = -x;
                positions[10] = -y;
                positions[11] = -nearClip;

                if (projection === pc.scene.Projection.PERSPECTIVE) {
                    y = Math.tan(fov / 2.0) * farClip;
                    x = y * aspectRatio;
                }
                positions[12] = x;
                positions[13] = -y;
                positions[14] = -farClip;
                positions[15] = x;
                positions[16] = y;
                positions[17] = -farClip;
                positions[18] = -x;
                positions[19] = y;
                positions[20] = -farClip;
                positions[21] = -x;
                positions[22] = -y;
                positions[23] = -farClip;
                vertexBuffer.unlock();
            }
        },

        isToolsCamera: function (entity) {
            return entity.hasLabel("pc:designer");
        },

        displayInTools: function (entity) {
            return (!this.isToolsCamera(entity) || (entity.getName() === "Perspective"));
        }
    });

    return {
        CameraComponentSystem: CameraComponentSystem
    };
}());<|endoftext|>


<commit_before>'use strict';

const platforms = [
  {
    os: 'android',
    platform: /android.*/i,
  },
  {
    os: 'ios',
    platform: /(iphone|ipod|ipad)/i,
  },
  {
    os: 'windows',
    platform: /win.*/i,
  },
  {
    os: 'macos',
    platform: /mac.*/i,
  },
  {
    os: 'linux',
    platform: /linux.*/i,
  },
];

let os = 'unknown';
const found = platforms.find(target => target.platform.test(window.navigator.platform));
if (found) ({ os } = found);

module.exports = os;
<commit_msg>fix: detect-os<commit_after>'use strict';

const platforms = [
  {
    os: 'android',
    userAgent: /android/i,
  },
  {
    os: 'ios',
    platform: /(iphone|ipod|ipad)/i,
  },
  {
    os: 'windows',
    platform: /win.*/i,
  },
  {
    os: 'macos',
    platform: /mac.*/i,
  },
  {
    os: 'linux',
    platform: /linux.*/i,
  },
];

let os = 'unknown';
const found = platforms.find((target) => {
  if (target.userAgent) {
    return target.userAgent.test(window.navigator.userAgent);
  }
  return target.platform.test(window.navigator.platform);
});
if (found) ({ os } = found);

module.exports = os;
<|endoftext|>


<commit_before>/*
 * @copyright Adam Benda, 2016
 */

/**
 * @class
 * @classdesc Bonus with some images
 */

/**
 *
 * @param {Matter.Engine} engine
 * @param {number} x - x coordinate
 * @param {number} y - y coordinate
 * @param {number} randomNumber - number from 0..1
 * @returns {Ball}
 */
var Bonus = function (engine, x, y, randomNumber) {
    this.type = "Bonus";
    this.engine = engine;
    this.body = Matter.Bodies.rectangle(engine.render.options.width * x, engine.render.options.height * y, 30, 30);
    this.body.pObject = this;
    Matter.Body.setStatic(this.body, true);
    this.body.collisionFilter.mask = 1;

    this.body.render.fillStyle = "#aaaaaa";
    this.body.render.strokeStyle = "#aaaaaa";

    //Bonus texture
    var randIndex = Math.floor(randomNumber * this.textures.length);
    this.body.render.sprite.texture = "gfx/bonus/" + this.textures[randIndex % this.textures.length] + ".png";

    if (randIndex === 0) {
        //special: gravity changer
        this.eaten = function (ball, gamestate) {
            gamestate.changeGravity();
        }.bind(this);
    } else {
        //ordinary bonus = eat and get score
        this.eaten = function (ball, gamestate) {
            if (ball.type === "Player") {
                gamestate._scoreNoTime += 1000;
            }
        }.bind(this);
    }

};

Bonus.prototype.textures = ["circular", "book", "music", "pen", "phone", "pizza", "tea"];<commit_msg>More gravity change bonuses (30%+)<commit_after>/*
 * @copyright Adam Benda, 2016
 */

/**
 * @class
 * @classdesc Bonus with some images
 */

/**
 *
 * @param {Matter.Engine} engine
 * @param {number} x - x coordinate
 * @param {number} y - y coordinate
 * @param {number} randomNumber - number from 0..1
 * @returns {Ball}
 */
var Bonus = function (engine, x, y, randomNumber) {
    this.type = "Bonus";
    this.engine = engine;
    this.body = Matter.Bodies.rectangle(engine.render.options.width * x, engine.render.options.height * y, 30, 30);
    this.body.pObject = this;
    Matter.Body.setStatic(this.body, true);
    this.body.collisionFilter.mask = 1;

    this.body.render.fillStyle = "#aaaaaa";
    this.body.render.strokeStyle = "#aaaaaa";

    //Bonus texture
    var randIndex = Math.floor(randomNumber * this.textures.length);
    if (Math.random() < 0.4) {
        //I want lot of switch gravity bonuses!
        randIndex = 0;
    }
    this.body.render.sprite.texture = "gfx/bonus/" + this.textures[randIndex % this.textures.length] + ".png";

    if (randIndex === 0) {
        //special: gravity changer
        this.eaten = function (ball, gamestate) {
            gamestate.changeGravity();
        }.bind(this);
    } else {
        //ordinary bonus = eat and get score
        this.eaten = function (ball, gamestate) {
            if (ball.type === "Player") {
                gamestate._scoreNoTime += 1000;
            }
        }.bind(this);
    }

};

Bonus.prototype.textures = ["circular", "book", "music", "pen", "phone", "pizza", "tea"];<|endoftext|>


<commit_before>/*!
    Copyright (C) 2015 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: anze@reciprocitylabs.com
    Maintained By: anze@reciprocitylabs.com
*/

(function(can, $) {

  /*  GGRC.SaveQueue
   *
   *  SaveQueue is used by CMS.Models.Cacheable to prevent firing
   *  multiple requests to the server at once. It makes sure the requests
   *  are grouped together (inside _queue) and then resolved in batches.
   *
   *  It will also try to group POST request and use the custom collection post
   *  API and then redistribute responses in order to trace in latency for
   *  throughput. This is done by a "thread" (of timeouts) per object type (per
   *  bucket) that enqueues as a regular request but then greedily dispatches
   *  requests that arrived while it was in the queue.
   *
   *  enqueue(obj: CMS.Models.Cacheable, save_args) -> null
   */
  can.Construct("GGRC.SaveQueue", {

    DELAY: 100, // Number of ms to wait before the first batch is fired
    BATCH: GGRC.config.MAX_INSTANCES || 3, // Maximum number of POST/PUT requests at any given time
    _queue: [],
    _buckets: {},
    _timeout: null,

    _enqueue_bucket: function (bucket) {
      var that = this;
      return function () {
        var objs = bucket.objs.splice(0, 100),
            body = _.map(objs, function (obj) {
              var o = {};
              o[bucket.type] = obj.serialize();
              return o;
            }),
            dfd = $.ajax({
              type: "POST",
              url: "/api/" + bucket.plural,
              data: body
            }).promise();
        dfd.always(function (data, type) {
          if (type === "error") {
            data = data.responseJSON;
            if (data === undefined) {
              return;
            }
          }
          var cb = function(single) {
            return function () {
              this.created(single[1][bucket.type]);
              return $.when(can.Model.Cacheable.resolve_deferred_bindings(this));
            };
          };
          for (var i = 0; i < objs.length; i++) {
            var single = data[i],
                obj = objs[i];
            if (single[0] >= 200 && single[0] < 300) {
              obj._save(cb(single));
            } else {
              obj._dfd.rejectWith(obj, [single]);
            }
          }
        }).always(function () {
          if (bucket.objs.length) {
            that._step(that._enqueue_bucket(bucket));
          } else {
            bucket.in_flight = false;
          }
        });

        return dfd;
      };
    },

    _step: function (elem) {
      this._queue.push(elem);
      if (typeof this._timeout === "number") {
        clearTimeout(this._timeout);
      }
      this._timeout = setTimeout(function () {
        new GGRC.SaveQueue(this._queue.splice(0, this._queue.length));
      }.bind(this), this.DELAY);
    },

    enqueue: function (obj, args) {
      var elem = function () {
          return obj._save.apply(obj, args);
      };
      if (obj.isNew()) {
        var type = obj.constructor.table_singular;
        var bucket = this._buckets[type];
        if (bucket === undefined) {
          var plural = obj.constructor.table_plural;
          bucket = {
            objs: [],
            type: type,
            plural: plural,
            in_flight: false // is there a "thread" running for this bucket
          };
          this._buckets[type] = bucket;
        }
        bucket.objs.push(obj);
        if (bucket.in_flight) {
          return;
        }
        elem = this._enqueue_bucket(bucket);
        bucket.in_flight = true;
      }
      this._step(elem);
     },
  }, {
    init: function (queue) {
      this._queue = queue;
      this._resolve();
    },
    _resolve: function() {
      if (!this._queue.length) {
        // Finished
        return;
      }
      var objs = this._queue.splice(0, this.constructor.BATCH);
      $.when.apply($, objs.map(function (f) {
        return f.apply(this);
      }.bind(this.constructor))).always(this._resolve.bind(this)); // Move on to the next one
    }
  });

})(window.can, window.can.$);
<commit_msg>Improve reject save queue<commit_after>/*!
    Copyright (C) 2015 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: anze@reciprocitylabs.com
    Maintained By: anze@reciprocitylabs.com
*/

(function(can, $) {

  /*  GGRC.SaveQueue
   *
   *  SaveQueue is used by CMS.Models.Cacheable to prevent firing
   *  multiple requests to the server at once. It makes sure the requests
   *  are grouped together (inside _queue) and then resolved in batches.
   *
   *  It will also try to group POST request and use the custom collection post
   *  API and then redistribute responses in order to trace in latency for
   *  throughput. This is done by a "thread" (of timeouts) per object type (per
   *  bucket) that enqueues as a regular request but then greedily dispatches
   *  requests that arrived while it was in the queue.
   *
   *  enqueue(obj: CMS.Models.Cacheable, save_args) -> null
   */
  can.Construct("GGRC.SaveQueue", {

    DELAY: 100, // Number of ms to wait before the first batch is fired
    BATCH: GGRC.config.MAX_INSTANCES || 3, // Maximum number of POST/PUT requests at any given time
    _queue: [],
    _buckets: {},
    _timeout: null,

    _enqueue_bucket: function (bucket) {
      var that = this;
      return function () {
        var objs = bucket.objs.splice(0, 100),
            body = _.map(objs, function (obj) {
              var o = {};
              o[bucket.type] = obj.serialize();
              return o;
            }),
            dfd = $.ajax({
              type: "POST",
              url: "/api/" + bucket.plural,
              data: body
            }).promise();
        dfd.always(function (data, type) {
          if (type === "error") {
            data = data.responseJSON;
            if (data === undefined) {
              return;
            }
          }
          var cb = function(single) {
            return function () {
              this.created(single[1][bucket.type]);
              return $.when(can.Model.Cacheable.resolve_deferred_bindings(this));
            };
          };
          for (var i = 0; i < objs.length; i++) {
            var single = data[i],
                obj = objs[i];
            if (single[0] >= 200 && single[0] < 300) {
              obj._save(cb(single));
            } else {
              obj._dfd.reject(obj, single);
            }
          }
        }).always(function () {
          if (bucket.objs.length) {
            that._step(that._enqueue_bucket(bucket));
          } else {
            bucket.in_flight = false;
          }
        });

        return dfd;
      };
    },

    _step: function (elem) {
      this._queue.push(elem);
      if (typeof this._timeout === "number") {
        clearTimeout(this._timeout);
      }
      this._timeout = setTimeout(function () {
        new GGRC.SaveQueue(this._queue.splice(0, this._queue.length));
      }.bind(this), this.DELAY);
    },

    enqueue: function (obj, args) {
      var elem = function () {
          return obj._save.apply(obj, args);
      };
      if (obj.isNew()) {
        var type = obj.constructor.table_singular;
        var bucket = this._buckets[type];
        if (bucket === undefined) {
          var plural = obj.constructor.table_plural;
          bucket = {
            objs: [],
            type: type,
            plural: plural,
            in_flight: false // is there a "thread" running for this bucket
          };
          this._buckets[type] = bucket;
        }
        bucket.objs.push(obj);
        if (bucket.in_flight) {
          return;
        }
        elem = this._enqueue_bucket(bucket);
        bucket.in_flight = true;
      }
      this._step(elem);
     },
  }, {
    init: function (queue) {
      this._queue = queue;
      this._resolve();
    },
    _resolve: function() {
      if (!this._queue.length) {
        // Finished
        return;
      }
      var objs = this._queue.splice(0, this.constructor.BATCH);
      $.when.apply($, objs.map(function (f) {
        return f.apply(this);
      }.bind(this.constructor))).always(this._resolve.bind(this)); // Move on to the next one
    }
  });

})(window.can, window.can.$);
<|endoftext|>


<commit_before>var utils = require("./utils.js")

var PROD = process.env.NODE_ENV == 'production';
var DEV = process.env.NODE_ENV == 'development';

var e = {
	DEBUG: DEV,
	DEBUG_CIRCUMVENT_PERMISSIONS: true,

	COLLECTION_DEFAULTS: {
		visible: true,
		featureType: 'C',
		colorType: 'S',
		colors: [{color: '#00C9FF'}],
		opacity: null
	},

	MIN_CROP_DISTRIBUTION_RATIO: 10000, // if max > min * r --> crop histogram

	// Reserve certain URIs and do not allow them for slugs without modification, such as:
	// "admin", short words, short numbers, MD5 hashes
	RESERVED_URI: /^(admin|[a-z0-9]{1,8}|[0-9]{1,5}|[a-f0-9]{32})$/
};

if (DEV) {
	// use local db
	e.DB_PATH = 'mongodb://localhost/geo';
} else if (PROD) {
	// import production settings
	utils.import(e, require('./config-prod.js'));
}

utils.import(e, require("./public/config.js"));

module.exports = e;<commit_msg>Minor fixes<commit_after>var utils = require("./utils.js")

var PROD = process.env.NODE_ENV == 'production';
var DEV = process.env.NODE_ENV == 'development';

var e = {
	DEBUG: DEV,
	DEBUG_CIRCUMVENT_PERMISSIONS: true,

	COLLECTION_DEFAULTS: {
		visible: true,
		featureType: 'C',
		colorType: 'S',
		colors: [{color: '#00C9FF'}],
		opacity: null
	},

	MIN_CROP_DISTRIBUTION_RATIO: 10000, // if max > min * r --> crop histogram

	// Reserve certain URIs and do not allow them for slugs without modification, such as:
	// "admin", short words, short numbers, MD5 hashes
	RESERVED_URI: /^(admin|[a-z0-9]{1,7}|[0-9]{1,5}|[a-f0-9]{32})$/
};

if (DEV) {
	// use local db
	e.DB_PATH = 'mongodb://localhost/geo';
} else if (PROD) {
	// import production settings
	utils.import(e, require('./config-prod.js'));
}

utils.import(e, require("./public/config.js"));

module.exports = e;<|endoftext|>