<commit_before>// GATT Battery Service UUIDs
var BATTERY_SERVICE_UUID    = '0000180f-0000-1000-8000-00805f9b34fb';
var BATTERY_LEVEL_CHRC_UUID = '00002a19-0000-1000-8000-00805f9b34fb';

// The currently displayed service and characteristics.
var batteryService;
var batteryLevelCharacteristic;

// A mapping from device addresses to device names for found devices that expose
// a Battery service.
var batteryDevicesMap = {};

/**
 * Updates the UI based on the selected service.
 * @param {chrome.bluetoothLowEnergy.Service} service The selected GATT service
 *     to display.
 */
function selectService(service) {
  // Hide or show the appropriate elements based on whether or not
  // |serviceId| is undefined.
  document.getElementById('no-devices-error').hidden = !!service;
  document.getElementById('device-info-fields').hidden = !service;

  clearAllFields();

  batteryService = service;

  // Disable notifications from the currently selected Battery Level
  // characteristic.
  if (batteryLevelCharacteristic) {
    chrome.bluetoothLowEnergy.stopCharacteristicNotifications(
        batteryLevelCharacteristic.instanceId);
  }

  batteryLevelCharacteristic = undefined;

  if (!service) {
    console.log('No service selected.');
    return;
  }

  console.log('GATT service selected: ' + service.instanceId);

  // Get the characteristics of the selected service.
  chrome.bluetoothLowEnergy.getCharacteristics(service.instanceId,
                                               function (chrcs) {
    if (chrome.runtime.lastError) {
      console.log(chrome.runtime.lastError.message);
      return;
    }

    // Make sure that the same service is still selected.
    if (service.instanceId != batteryService.instanceId)
      return;

    if (chrcs.length == 0) {
      console.log('Service has no characteristics: ' + service.instanceId);
      return;
    }

    chrcs.forEach(function (chrc) {
      // This service should have only one characteristic.
      if (chrc.uuid != BATTERY_LEVEL_CHRC_UUID) {
        console.log('Found unexpected characteristic: ' + chrc.instanceId +
                    ' with UUID: ' + chrc.uuid);
        return;
      }

      console.log('Setting Battery Level characteristic: ' + chrc.instanceId);
      batteryLevelCharacteristic = chrc;

      // Enable notifications from the characteristic.
      chrome.bluetoothLowEnergy.startCharacteristicNotifications(
          chrc.instanceId,
          function () {
        if (chrome.runtime.lastError &&
            chrome.runtime.lastError.message != 'Already notifying') {
          console.log('Failed to enable Battery Level notifications: ' +
                      chrome.runtime.lastError.message);
          return;
        }

        console.log('Battery Level notifications enabled! Sending request to ' +
                    'read current battery level.');

        // Read the value of the characteristic once and store it. The Battery
        // Level characteristic must support both reads and notifications, so
        // we will track the value via both.
        chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                          function (readChrc) {
          if (chrome.runtime.lastError) {
            console.log(chrome.runtime.lastError.message);
            return;
          }

          // Make sure that the same characteristic is still selected.
          if (readChrc.instanceId != batteryLevelCharacteristic.instanceId)
            return;

          // No need the update the value here, as a successful read will trigger
          // the onCharacteristicValueChanged event. We will perform the update in
          // the listener instead.
          console.log('Request to read battery level complete.');
        });
      });
    });
  });
}

/**
 * Updates the Battery Level field based on the value of the currently selected
 * Battery Level characteristic.
 */
function updateBatteryLevelValue() {
  if (!batteryLevelCharacteristic) {
    console.log('No Battery Level Characteristic selected');
    return;
  }

  // Value field might be undefined  if the read request failed or no
  // notification has been received yet.
  if (!batteryLevelCharacteristic.value) {
    console.log('No Battery Level value received yet');
    return;
  }

  var valueBytes = new Uint8Array(batteryLevelCharacteristic.value);

  // The value should contain a single byte.
  if (valueBytes.length != 1) {
    console.log('Invalid Battery Level value length: ' + valueBytes.length);
    return;
  }

  var batteryLevel = valueBytes[0];

  // Set the text content
  setFieldValue('battery-level', batteryLevel + ' %');

  // Update the battery level image.
  var batteryLevelBox = document.getElementById('battery-level-box');

  var levelClass;
  if (batteryLevel > 65)
    levelClass = 'high';
  else if (batteryLevel > 30)
    levelClass = 'medium';
  else
    levelClass = 'low';

  batteryLevelBox.className = 'level ' + levelClass;
  batteryLevelBox.style.width = batteryLevel + '%';
}

/**
 * Helper functions to set the values of Battery Service UI fields.
 */
function setFieldValue(id, value) {
  var finalValue = (value === undefined) ? '-' : value;
  console.log('Setting field with ID "' + id + '" to value: "' + value + '"');

  var div = document.getElementById(id);
  div.innerHTML = '';
  div.appendChild(document.createTextNode(finalValue));
}

function clearAllFields() {
  setFieldValue('battery-level', undefined);
}

/**
 * Updates the dropdown menu based on the contents of |batteryDevicesMap|.
 */
function updateDeviceSelector() {
  var deviceSelector = document.getElementById('device-selector');
  var placeHolder = document.getElementById('placeholder');
  var addresses = Object.keys(batteryDevicesMap);

  deviceSelector.innerHTML = '';
  placeHolder.innerHTML = '';
  deviceSelector.appendChild(placeHolder);

  // Clear the drop-down menu.
  if (addresses.length == 0) {
    console.log('No devices found with "Battery Service"');
    placeHolder.appendChild(document.createTextNode('No connected devices'));
    return;
  }

  // Hide the placeholder and populate
  placeHolder.appendChild(document.createTextNode('Connected devices found'));

  for (var i = 0; i < addresses.length; i++) {
    var address = addresses[i];
    var deviceOption = document.createElement('option');
    deviceOption.setAttribute('value', address);
    deviceOption.appendChild(document.createTextNode(
        batteryDevicesMap[address]));
    deviceSelector.appendChild(deviceOption);
  }
}

/**
 * This is the entry point of the application. Initialize UI state and set up
 * the relevant Bluetooth Low Energy event listeners.
 */
function main() {
  // Set up the UI to look like no device was initially selected.
  selectService(undefined);

  // Request information about the local Bluetooth adapter to be displayed in
  // the UI.
  var updateAdapterState = function (adapterState) {
    var addressField = document.getElementById('adapter-address');
    var nameField = document.getElementById('adapter-name');

    var setAdapterField = function (field, value) {
      field.innerHTML = '';
      field.appendChild(document.createTextNode(value));
    };

    if (!adapterState) {
      setAdapterField(nameField, 'No adapter');
      setAdapterField(addressField, 'unknown');
      return;
    }

    setAdapterField(addressField,
                    adapterState.address ? adapterState.address : 'unknown');
    setAdapterField(nameField,
                    adapterState.name ? adapterState.name : 'Local Adapter');
  };

  chrome.bluetooth.getAdapterState(function (adapterState) {
    if (chrome.runtime.lastError)
      console.log(chrome.runtime.lastError.message);

    updateAdapterState(adapterState);
  });

  chrome.bluetooth.onAdapterStateChanged.addListener(updateAdapterState);

  // Initialize |batteryDevicesMap|.
  chrome.bluetooth.getDevices(function (devices) {
    if (chrome.runtime.lastError) {
      console.log(chrome.runtime.lastError.message);
    }

    if (devices) {
      devices.forEach(function (device) {
        // See if the device exposes a Battery service.
        chrome.bluetoothLowEnergy.getServices(device.address,
                                              function (services) {
          if (chrome.runtime.lastError) {
            console.log(chrome.runtime.lastError.message);
            return;
          }

          if (!services)
            return;

          var found = false;
          services.forEach(function (service) {
            if (service.uuid == BATTERY_SERVICE_UUID) {
              console.log('Found Battery service!');
              found = true;
            }
          });

          if (!found)
            return;

          console.log('Found device with Battery service: ' +
                      device.address);
          batteryDevicesMap[device.address] =
              (device.name ? device.name : device.address);

          updateDeviceSelector();
        });
      });
    }
  });

  // Set up the device selector.
  var deviceSelector = document.getElementById('device-selector');
  deviceSelector.onchange = function () {
    var selectedValue = deviceSelector[deviceSelector.selectedIndex].value;

    // If |selectedValue| is empty, unselect everything.
    if (!selectedValue) {
      selectService(undefined);
      return;
    }

    // Request all GATT services of the selected device to see if it still has
    // a Battery service and pick the first one to display.
    chrome.bluetoothLowEnergy.getServices(selectedValue, function (services) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        selectService(undefined);
        return;
      }

      var foundService = undefined;
      services.forEach(function (service) {
        if (service.uuid == BATTERY_SERVICE_UUID)
          foundService = service;
      });

      selectService(foundService);
    });
  };

  // Track GATT services as they are added.
  chrome.bluetoothLowEnergy.onServiceAdded.addListener(function (service) {
    // Ignore, if the service is not a Battery service.
    if (service.uuid != BATTERY_SERVICE_UUID)
      return;

    // Add the device of the service to the device map and update the UI.
    console.log('New Battery service added: ' + service.instanceId);
    if (batteryDevicesMap.hasOwnProperty(service.deviceAddress))
      return;

    // Looks like it's a brand new device. Get information about the device so
    // that we can display the device name in the drop-down menu.
    chrome.bluetooth.getDevice(service.deviceAddress, function (device) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        return;
      }

      batteryDevicesMap[device.address] =
          (device.name ? device.name : device.address);
      updateDeviceSelector();
    });
  });

  // Track GATT services as they are removed.
  chrome.bluetoothLowEnergy.onServiceRemoved.addListener(function (service) {
    // Ignore, if the service is not a Battery service.
    if (service.uuid != BATTERY_SERVICE_UUID)
      return;

    // See if this is the currently selected service. If so, unselect it.
    console.log('Battery service removed: ' + service.instanceId);
    var selectedRemoved = false;
    if (batteryService && batteryService.instanceId == service.instanceId) {
      console.log('The selected service disappeared!');
      selectService(undefined);
      selectedRemoved = true;
    }

    // Remove the associated device from the map only if it has no other Battery
    // services exposed (this will usually be the case)
    if (!batteryDevicesMap.hasOwnProperty(service.deviceAddress))
      return;

    chrome.bluetooth.getDevice(service.deviceAddress, function (device) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        return;
      }

      chrome.bluetoothLowEnergy.getServices(device.address,
                                            function (services) {
        if (chrome.runtime.lastError) {
          // Error obtaining services. Remove the device from the map.
          console.log(chrome.runtime.lastError.message);
          delete batteryDevicesMap[device.address];
          updateDeviceSelector();
          return;
        }

        var found = false;
        for (var i = 0; i < services.length; i++) {
          if (services[i].uuid == BATTERY_SERVICE_UUID) {
            found = true;
            break;
          }
        }

        if (found)
          return;

        console.log('Removing device: ' + device.address);
        delete batteryDevicesMap[device.address];
        updateDeviceSelector();
        if (selectedRemoved)
          deviceSelector.onchange();  // Forcefully select the next device.
      });
    });
  });

  // Track GATT services as they change.
  chrome.bluetoothLowEnergy.onServiceChanged.addListener(function (service) {
    // This only matters if the selected service changed.
    if (!batteryService || service.instanceId != batteryService.instanceId)
      return;

    console.log('The selected service has changed');

    // Reselect the service to force an updated.
    selectService(service);
  });

  // Track GATT characteristic value changes. This event will be triggered after
  // successful characteristic value reads and received notifications and
  // indications.
  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function (chrc) {
    if (batteryLevelCharacteristic &&
        chrc.instanceId == batteryLevelCharacteristic.instanceId) {
      console.log('Battery Level value changed');
      batteryLevelCharacteristic = chrc;
      updateBatteryLevelValue();
      return;
    }
  });
}

document.addEventListener('DOMContentLoaded', main);
<commit_msg>Reset battery level when new device is selected.<commit_after>// GATT Battery Service UUIDs
var BATTERY_SERVICE_UUID    = '0000180f-0000-1000-8000-00805f9b34fb';
var BATTERY_LEVEL_CHRC_UUID = '00002a19-0000-1000-8000-00805f9b34fb';

// The currently displayed service and characteristics.
var batteryService;
var batteryLevelCharacteristic;

// A mapping from device addresses to device names for found devices that expose
// a Battery service.
var batteryDevicesMap = {};

/**
 * Updates the UI based on the selected service.
 * @param {chrome.bluetoothLowEnergy.Service} service The selected GATT service
 *     to display.
 */
function selectService(service) {
  // Hide or show the appropriate elements based on whether or not
  // |serviceId| is undefined.
  document.getElementById('no-devices-error').hidden = !!service;
  document.getElementById('device-info-fields').hidden = !service;

  clearAllFields();

  batteryService = service;

  // Disable notifications from the currently selected Battery Level
  // characteristic.
  if (batteryLevelCharacteristic) {
    chrome.bluetoothLowEnergy.stopCharacteristicNotifications(
        batteryLevelCharacteristic.instanceId);
  }

  batteryLevelCharacteristic = undefined;
  updateBatteryLevelValue();  // Initialize to unknown

  if (!service) {
    console.log('No service selected.');
    return;
  }

  console.log('GATT service selected: ' + service.instanceId);

  // Get the characteristics of the selected service.
  chrome.bluetoothLowEnergy.getCharacteristics(service.instanceId,
                                               function (chrcs) {
    if (chrome.runtime.lastError) {
      console.log(chrome.runtime.lastError.message);
      return;
    }

    // Make sure that the same service is still selected.
    if (service.instanceId != batteryService.instanceId)
      return;

    if (chrcs.length == 0) {
      console.log('Service has no characteristics: ' + service.instanceId);
      return;
    }

    chrcs.forEach(function (chrc) {
      // This service should have only one characteristic.
      if (chrc.uuid != BATTERY_LEVEL_CHRC_UUID) {
        console.log('Found unexpected characteristic: ' + chrc.instanceId +
                    ' with UUID: ' + chrc.uuid);
        return;
      }

      console.log('Setting Battery Level characteristic: ' + chrc.instanceId);
      batteryLevelCharacteristic = chrc;

      // Enable notifications from the characteristic.
      chrome.bluetoothLowEnergy.startCharacteristicNotifications(
          chrc.instanceId,
          function () {
        if (chrome.runtime.lastError &&
            chrome.runtime.lastError.message != 'Already notifying') {
          console.log('Failed to enable Battery Level notifications: ' +
                      chrome.runtime.lastError.message);
          return;
        }

        console.log('Battery Level notifications enabled! Sending request to ' +
                    'read current battery level.');

        // Read the value of the characteristic once and store it. The Battery
        // Level characteristic must support both reads and notifications, so
        // we will track the value via both.
        chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                          function (readChrc) {
          if (chrome.runtime.lastError) {
            console.log(chrome.runtime.lastError.message);
            return;
          }

          // Make sure that the same characteristic is still selected.
          if (readChrc.instanceId != batteryLevelCharacteristic.instanceId)
            return;

          // No need the update the value here, as a successful read will trigger
          // the onCharacteristicValueChanged event. We will perform the update in
          // the listener instead.
          console.log('Request to read battery level complete.');
        });
      });
    });
  });
}

/**
 * Updates the battery level UI based on the given value.
 */
function updateBatteryLevelUI(level, unknown) {
  // Set the text content
  setFieldValue('battery-level', unknown ? '-' : level + ' %');

  // Update the battery level image.
  var batteryLevelBox = document.getElementById('battery-level-box');

  var levelClass;
  if (level> 65)
    levelClass = 'high';
  else if (level > 30)
    levelClass = 'medium';
  else
    levelClass = 'low';

  batteryLevelBox.className = 'level ' + levelClass;
  batteryLevelBox.style.width = level + '%';
}

/**
 * Updates the Battery Level field based on the value of the currently selected
 * Battery Level characteristic.
 */
function updateBatteryLevelValue() {
  if (!batteryLevelCharacteristic) {
    console.log('No Battery Level Characteristic selected');
    updateBatteryLevelUI(0, true);
    return;
  }

  // Value field might be undefined  if the read request failed or no
  // notification has been received yet.
  if (!batteryLevelCharacteristic.value) {
    console.log('No Battery Level value received yet');
    return;
  }

  var valueBytes = new Uint8Array(batteryLevelCharacteristic.value);

  // The value should contain a single byte.
  if (valueBytes.length != 1) {
    console.log('Invalid Battery Level value length: ' + valueBytes.length);
    return;
  }

  var batteryLevel = valueBytes[0];
  updateBatteryLevelUI(batteryLevel, false);
}

/**
 * Helper functions to set the values of Battery Service UI fields.
 */
function setFieldValue(id, value) {
  var finalValue = (value === undefined) ? '-' : value;
  console.log('Setting field with ID "' + id + '" to value: "' + value + '"');

  var div = document.getElementById(id);
  div.innerHTML = '';
  div.appendChild(document.createTextNode(finalValue));
}

function clearAllFields() {
  setFieldValue('battery-level', undefined);
}

/**
 * Updates the dropdown menu based on the contents of |batteryDevicesMap|.
 */
function updateDeviceSelector() {
  var deviceSelector = document.getElementById('device-selector');
  var placeHolder = document.getElementById('placeholder');
  var addresses = Object.keys(batteryDevicesMap);

  deviceSelector.innerHTML = '';
  placeHolder.innerHTML = '';
  deviceSelector.appendChild(placeHolder);

  // Clear the drop-down menu.
  if (addresses.length == 0) {
    console.log('No devices found with "Battery Service"');
    placeHolder.appendChild(document.createTextNode('No connected devices'));
    return;
  }

  // Hide the placeholder and populate
  placeHolder.appendChild(document.createTextNode('Connected devices found'));

  for (var i = 0; i < addresses.length; i++) {
    var address = addresses[i];
    var deviceOption = document.createElement('option');
    deviceOption.setAttribute('value', address);
    deviceOption.appendChild(document.createTextNode(
        batteryDevicesMap[address]));
    deviceSelector.appendChild(deviceOption);
  }
}

/**
 * This is the entry point of the application. Initialize UI state and set up
 * the relevant Bluetooth Low Energy event listeners.
 */
function main() {
  // Set up the UI to look like no device was initially selected.
  selectService(undefined);

  // Request information about the local Bluetooth adapter to be displayed in
  // the UI.
  var updateAdapterState = function (adapterState) {
    var addressField = document.getElementById('adapter-address');
    var nameField = document.getElementById('adapter-name');

    var setAdapterField = function (field, value) {
      field.innerHTML = '';
      field.appendChild(document.createTextNode(value));
    };

    if (!adapterState) {
      setAdapterField(nameField, 'No adapter');
      setAdapterField(addressField, 'unknown');
      return;
    }

    setAdapterField(addressField,
                    adapterState.address ? adapterState.address : 'unknown');
    setAdapterField(nameField,
                    adapterState.name ? adapterState.name : 'Local Adapter');
  };

  chrome.bluetooth.getAdapterState(function (adapterState) {
    if (chrome.runtime.lastError)
      console.log(chrome.runtime.lastError.message);

    updateAdapterState(adapterState);
  });

  chrome.bluetooth.onAdapterStateChanged.addListener(updateAdapterState);

  // Initialize |batteryDevicesMap|.
  chrome.bluetooth.getDevices(function (devices) {
    if (chrome.runtime.lastError) {
      console.log(chrome.runtime.lastError.message);
    }

    if (devices) {
      devices.forEach(function (device) {
        // See if the device exposes a Battery service.
        chrome.bluetoothLowEnergy.getServices(device.address,
                                              function (services) {
          if (chrome.runtime.lastError) {
            console.log(chrome.runtime.lastError.message);
            return;
          }

          if (!services)
            return;

          var found = false;
          services.forEach(function (service) {
            if (service.uuid == BATTERY_SERVICE_UUID) {
              console.log('Found Battery service!');
              found = true;
            }
          });

          if (!found)
            return;

          console.log('Found device with Battery service: ' +
                      device.address);
          batteryDevicesMap[device.address] =
              (device.name ? device.name : device.address);

          updateDeviceSelector();
        });
      });
    }
  });

  // Set up the device selector.
  var deviceSelector = document.getElementById('device-selector');
  deviceSelector.onchange = function () {
    var selectedValue = deviceSelector[deviceSelector.selectedIndex].value;

    // If |selectedValue| is empty, unselect everything.
    if (!selectedValue) {
      selectService(undefined);
      return;
    }

    // Request all GATT services of the selected device to see if it still has
    // a Battery service and pick the first one to display.
    chrome.bluetoothLowEnergy.getServices(selectedValue, function (services) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        selectService(undefined);
        return;
      }

      var foundService = undefined;
      services.forEach(function (service) {
        if (service.uuid == BATTERY_SERVICE_UUID)
          foundService = service;
      });

      selectService(foundService);
    });
  };

  // Track GATT services as they are added.
  chrome.bluetoothLowEnergy.onServiceAdded.addListener(function (service) {
    // Ignore, if the service is not a Battery service.
    if (service.uuid != BATTERY_SERVICE_UUID)
      return;

    // Add the device of the service to the device map and update the UI.
    console.log('New Battery service added: ' + service.instanceId);
    if (batteryDevicesMap.hasOwnProperty(service.deviceAddress))
      return;

    // Looks like it's a brand new device. Get information about the device so
    // that we can display the device name in the drop-down menu.
    chrome.bluetooth.getDevice(service.deviceAddress, function (device) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        return;
      }

      batteryDevicesMap[device.address] =
          (device.name ? device.name : device.address);
      updateDeviceSelector();
    });
  });

  // Track GATT services as they are removed.
  chrome.bluetoothLowEnergy.onServiceRemoved.addListener(function (service) {
    // Ignore, if the service is not a Battery service.
    if (service.uuid != BATTERY_SERVICE_UUID)
      return;

    // See if this is the currently selected service. If so, unselect it.
    console.log('Battery service removed: ' + service.instanceId);
    var selectedRemoved = false;
    if (batteryService && batteryService.instanceId == service.instanceId) {
      console.log('The selected service disappeared!');
      selectService(undefined);
      selectedRemoved = true;
    }

    // Remove the associated device from the map only if it has no other Battery
    // services exposed (this will usually be the case)
    if (!batteryDevicesMap.hasOwnProperty(service.deviceAddress))
      return;

    chrome.bluetooth.getDevice(service.deviceAddress, function (device) {
      if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
        return;
      }

      chrome.bluetoothLowEnergy.getServices(device.address,
                                            function (services) {
        if (chrome.runtime.lastError) {
          // Error obtaining services. Remove the device from the map.
          console.log(chrome.runtime.lastError.message);
          delete batteryDevicesMap[device.address];
          updateDeviceSelector();
          return;
        }

        var found = false;
        for (var i = 0; i < services.length; i++) {
          if (services[i].uuid == BATTERY_SERVICE_UUID) {
            found = true;
            break;
          }
        }

        if (found)
          return;

        console.log('Removing device: ' + device.address);
        delete batteryDevicesMap[device.address];
        updateDeviceSelector();
        if (selectedRemoved)
          deviceSelector.onchange();  // Forcefully select the next device.
      });
    });
  });

  // Track GATT services as they change.
  chrome.bluetoothLowEnergy.onServiceChanged.addListener(function (service) {
    // This only matters if the selected service changed.
    if (!batteryService || service.instanceId != batteryService.instanceId)
      return;

    console.log('The selected service has changed');

    // Reselect the service to force an updated.
    selectService(service);
  });

  // Track GATT characteristic value changes. This event will be triggered after
  // successful characteristic value reads and received notifications and
  // indications.
  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function (chrc) {
    if (batteryLevelCharacteristic &&
        chrc.instanceId == batteryLevelCharacteristic.instanceId) {
      console.log('Battery Level value changed');
      batteryLevelCharacteristic = chrc;
      updateBatteryLevelValue();
      return;
    }
  });
}

document.addEventListener('DOMContentLoaded', main);
<|endoftext|>


<commit_before>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
//prompt: (bot) => bot.say('...'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}, wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`%[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {
      switch(message.text) {
      case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => 'askName')
          break;
      case 'Starters hypotheek':
      //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
          return bot.say(`Wat voor type woning zoek je? `)
          .then(() => bot.say(`%[Appartement](postback:hypotheekkeuze_appartement) %[Huis](postback:hypotheekkeuze_huis) %[Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
          .then(() => 'hypotheek_starter')
              break;
        case 'Nieuwe hypotheek':
          return bot.say(`Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`))
            .then(() => 'finish')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
          .then(()=> bot.say('Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja - graag](postback:update_ja) %[Nee, bedankt](postback:update_nee)'))
            .then(() => 'updateOntvangen')
          break;
        default:
          return bot.say(`...`)
            .then(() => 'processing')
          break;
      }
    }
},

updateOntvangen: {
    receive: (bot, message) => {
      switch(message.text) {
        case 'Ja - graag':
            return bot.say(`Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.' `)
            .then(() => 'update_ja');
          break;
          case 'Nee, bedankt':
              receive: () => 'bye'
              break;
          default:
            return bot.say(`...`)
              .then(() => 'processing')
            break;
}
}
},

update_ja: {
  prompt: (bot) => bot.say('Wat is email adres?')
  //      receive: (bot, message) => {
  //          const emailVisitor = message.text;
  //          //return bot.setProp('emailVisitor', emailVisitor)
  //           .then(()  => bot.say('Ok - dan hou ik je via ${emailVisitor} op de hoogte.'))
  //           .then(()  =>'processing')
  //  }
},

hypotheekkeuze_appartement: {
receive: (bot,message)  => {
    //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
}
},
hypotheekkeuze_huis: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
  receive: () => 'askName'
},
hypotheekkeuze_vakantiewoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheektype_starter: {
    prompt: (bot) => bot.say('Pleasure meeting you - starter'),
    receive: () => 'processing'
},
hypotheektype_nieuw: {
    prompt: (bot) => bot.say(`Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`),
    receive: () => 'processing'
},

askName: {
  receive: (bot, message) => {
    switch(message.text) {
        case 'Appartement':
          return bot.say(`Nice!`)
          .then(() => 'vervolgVragen')
          break;
      case 'Huis':
          return bot.say(`Leuk :)`)
          .then(() => 'vervolgVragen')
          break;
      default:
        return bot.say(`...`)
          .then(() => 'processing')
        break;
    }
    }
},

vervolgVragen: {
  prompt: (bot) => bot.say('Hoe heet je eigelijk? Dat maakt het praten een stuk makkelijker...'),
  receive: (bot, message) => {
      const name = message.text;
      return bot.setProp('name', name)
          .then(() => bot.say(`Hoi ${name}. Ik heb nog wat vragen voor je om verder te kunnen.`))
          .then(() => 'lastCheck');
    }
},

lastCheck: {
    // prompt: (bot) => bot.say('Is er nog iets waar ik  je bij kan helpen? %[JA](postback:nogietsanders) %[NEE](postback:bye) '),
    // .then(()  => 'processing');
},

bye: {
    prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd'),
    receive: ()  => 'finish'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<commit_msg>script<commit_after>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
//prompt: (bot) => bot.say('...'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}, wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`%[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {
      switch(message.text) {
      case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => 'askName')
          break;
      case 'Starters hypotheek':
      //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
          return bot.say(`Wat voor type woning zoek je? `)
          .then(() => bot.say(`%[Appartement](postback:hypotheekkeuze_appartement) %[Huis](postback:hypotheekkeuze_huis) %[Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
          .then(() => 'hypotheek_starter')
              break;
        case 'Nieuwe hypotheek':
          return bot.say(`Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`))
            .then(() => 'finish')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
          .then(()=> bot.say('Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja - graag](postback:update_ja) %[Nee, bedankt](postback:update_nee)'))
            .then(() => 'updateOntvangen')
          break;
        default:
          return bot.say(`...`)
            .then(() => 'processing')
          break;
      }
    }
},

updateOntvangen: {
    receive: (bot, message) => {
      switch(message.text) {
        case 'Ja - graag':
            return bot.say(`Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.' `)
            .then(() => 'update_ja');
          break;
          case 'Nee, bedankt':
              receive: () => 'bye'
              break;
          default:
            return bot.say(`...`)
              .then(() => 'processing')
            break;
}
}
},

update_ja: {
  prompt: (bot) => bot.say('Wat is je email adres?')
      receive: (bot, message) => {
  //          const emailVisitor = message.text;
  //          //return bot.setProp('emailVisitor', emailVisitor)
  //           .then(()  => bot.say('Ok - dan hou ik je via ${emailVisitor} op de hoogte.'))
  //           .then(()  =>'processing')
    }
},

hypotheekkeuze_appartement: {
receive: (bot,message)  => {
    //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
}
},
hypotheekkeuze_huis: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
  receive: () => 'askName'
},
hypotheekkeuze_vakantiewoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheektype_starter: {
    prompt: (bot) => bot.say('Pleasure meeting you - starter'),
    receive: () => 'processing'
},
hypotheektype_nieuw: {
    prompt: (bot) => bot.say(`Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`),
    receive: () => 'processing'
},

askName: {
  receive: (bot, message) => {
    switch(message.text) {
        case 'Appartement':
          return bot.say(`Nice!`)
          .then(() => 'vervolgVragen')
          break;
      case 'Huis':
          return bot.say(`Leuk :)`)
          .then(() => 'vervolgVragen')
          break;
      default:
        return bot.say(`...`)
          .then(() => 'processing')
        break;
    }
    }
},

vervolgVragen: {
  prompt: (bot) => bot.say('Hoe heet je eigelijk? Dat maakt het praten een stuk makkelijker...'),
  receive: (bot, message) => {
      const name = message.text;
      return bot.setProp('name', name)
          .then(() => bot.say(`Hoi ${name}. Ik heb nog wat vragen voor je om verder te kunnen.`))
          .then(() => 'lastCheck');
    }
},

lastCheck: {
    // prompt: (bot) => bot.say('Is er nog iets waar ik  je bij kan helpen? %[JA](postback:nogietsanders) %[NEE](postback:bye) '),
    // .then(()  => 'processing');
},

bye: {
    prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd'),
    receive: ()  => 'finish'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<|endoftext|>


<commit_before>$(function() {
  $('#element').popover({
    placement: 'bottom',
    html: true,
    title: 'Share URL',
    content: '<input type="text">',
  }).click(function() {
    $(this).popover('toggle');
  });
});

var source = ace.edit("source");
source.getSession().setMode("ace/mode/clojure");

var parser = new L20nParser(L20nEventEmitter);
var compiler = new L20nCompiler(L20nEventEmitter, L20nParser);

parser.addEventListener('error', function(e) {
  $("#errors").append("
Syntax error at position " + e.pos + "

" + e.message + "
");
});
compiler.addEventListener('error', function(e) {
  $("#errors").append("
" + e.name + " in entity " + e.entry + "

" + e.message + "
");
});

source.getSession().on('change', function(e) {
  $("#output").empty();
  $("#errors").empty();
  var code = source.getValue();
  var ast = parser.parse(code);
  var entries = compiler.compile(ast);
  for (var id in entries) {
    if (entries[id].expression) {
      $("#output").append("

" + id + "()

macro

");
      continue;
    }
    var val;
    try {
      val = entries[id].toString();
    } catch (e) {
      if (e instanceof compiler.ValueError) {
        val = e.source;
      } else {
        continue;
      }
    }
    $("#output").append("

" + id + "

" + val + "

");
  }
});

function utf8_to_b64(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}

function b64_to_utf8(str) {
    return decodeURIComponent(escape(window.atob(str)));
}

var hash = window.location.hash.slice(1);
var content = (
  "<name \"L20n tinker\">\n" +
  "<welcome \"Welcome to {{ name }}\">\n"
);

if (hash) {
  content = b64_to_utf8(hash);
}
source.setValue(content);

function linkify() {
  var code = source.getValue();
  console.log(utf8_to_b64(code));
}
<commit_msg>Document JS Code<commit_after>$(function() {

  /* L20n */

  var parser = new L20nParser(L20nEventEmitter);
  var compiler = new L20nCompiler(L20nEventEmitter, L20nParser);

  parser.addEventListener('error', function(e) {
    $("#errors").append("
Syntax error at position " + e.pos + "

" + e.message + "
");
  });
  compiler.addEventListener('error', function(e) {
    $("#errors").append("
" + e.name + " in entity " + e.entry + "

" + e.message + "
");
  });

  var source = ace.edit("source");
  source.getSession().setMode("ace/mode/clojure");

  /* ACE */

  source.getSession().on('change', function(e) {
    $("#output").empty();
    $("#errors").empty();
    var code = source.getValue();
    var ast = parser.parse(code);
    var entries = compiler.compile(ast);
    for (var id in entries) {
      if (entries[id].expression) {
        $("#output").append("

" + id + "()

macro

");
        continue;
      }
      var val;
      try {
        val = entries[id].toString();
      } catch (e) {
        if (e instanceof compiler.ValueError) {
          val = e.source;
        } else {
          continue;
        }
      }
      $("#output").append("

" + id + "

" + val + "

");
    }
  });

  /* Linkify */

  function utf8_to_b64(str) {
      return window.btoa(unescape(encodeURIComponent(str)));
  }

  function b64_to_utf8(str) {
      return decodeURIComponent(escape(window.atob(str)));
  }

  function linkify() {
    var code = source.getValue();
    console.log(utf8_to_b64(code));
  }

  /* Popover */

  $('#element').popover({
    placement: 'bottom',
    html: true,
    title: 'Share URL',
    content: '<input type="text">',
  }).click(function() {
    $(this).popover('toggle');
  });

  /* Main Code */

  var hash = window.location.hash.slice(1);
  var content = (
    "<name \"L20n tinker\">\n" +
    "<welcome \"Welcome to {{ name }}\">\n"
  );

  if (hash) {
    content = b64_to_utf8(hash);
  }
  source.setValue(content);

});
<|endoftext|>


<commit_before>var module = angular.module('arpege', ['ui.bootstrap']);

// General clock to fire various events
// TODO: this could be a service broadcasting the tick event
var clock = {
    refresh: 1000,
    elapsedtime: 0,
    // callbacks to be called on each tick
    callbacks: [],
    tick: function() {
      clock.elapsedtime += clock.refresh;
      // Call the callbacks so they will do their things
      for(var i = 0; i<clock.callbacks.length; i++) {
        clock.callbacks[i]();
      }
    }
};

setInterval('clock.tick()', clock.refresh);

module.service('Character', function($rootScope){
  this.level = 1;
  this.levelup = function() {
    this.level += 1;
    $rootScope.$broadcast('NewLevel');
  };

});

// We will probably need a CharacterController to display things like XP,
// Health, Level
var LevelCtrl = function($scope, Character) {
  $scope.level = Character.level;

  $scope.$on('NewLevel', function(){
    $scope.level = Character.level;
    $scope.$apply();
  });
};

// TODO: Maybe a MainProgressService ?
var ProgressDemoCtrl = function ($scope, Character) {
  $scope.max = 10;
  $scope.progress = 0;

// TODO: change this to a reaction on the tick event.
  $scope.tick = function() {
    $scope.progress += 1;

    if($scope.progress > $scope.max) {
      $scope.progress = 0;
      Character.levelup();
    }

    // apply change to the view
    $scope.$apply();
  }
  clock.callbacks.push($scope.tick);

  $scope.random = function() {
    var value = Math.floor((Math.random() * 100) + 1);
    var type;

    if (value < 25) {
      type = 'success';
    } else if (value < 50) {
      type = 'info';
    } else if (value < 75) {
      type = 'warning';
    } else {
      type = 'danger';
    }

    $scope.showWarning = (type === 'danger' || type === 'warning');

    $scope.dynamic = value;
    $scope.type = type;
  };
  $scope.random();

  $scope.randomStacked = function() {
    $scope.stacked = [];
    var types = ['success', 'info', 'warning', 'danger'];

    for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) {
        var index = Math.floor((Math.random() * 4));
        $scope.stacked.push({
          value: Math.floor((Math.random() * 30) + 1),
          type: types[index]
        });
    }
  };
  $scope.randomStacked();
};
<commit_msg>Add level range and xp<commit_after>var module = angular.module('arpege', ['ui.bootstrap']);

// General clock to fire various events
// TODO: this could be a service broadcasting the tick event
var clock = {
    refresh: 1000,
    elapsedtime: 0,
    // callbacks to be called on each tick
    callbacks: [],
    tick: function() {
      clock.elapsedtime += clock.refresh;
      // Call the callbacks so they will do their things
      for(var i = 0; i<clock.callbacks.length; i++) {
        clock.callbacks[i]();
      }
    }
};

setInterval('clock.tick()', clock.refresh);

module.service('Character', function($rootScope){
  this.level = 1;
  this.experience = 0;

  this.levelup = function() {
    this.level += 1;
    console.log('new level'+this.level);
    $rootScope.$broadcast('NewLevel');
  };

  this.levelMaxXP = function() {
    return this.level*100+((this.level*this.level)*10);
  };

});

// We will probably need a CharacterController to display things like XP,
// Health, Level
var LevelCtrl = function($scope, Character) {
  $scope.level = Character.level;

  $scope.$on('NewLevel', function(){
    $scope.level = Character.level;
    $scope.$apply();
  });
};

// TODO: Maybe a MainProgressService ?
var ProgressDemoCtrl = function ($scope, Character) {
  $scope.max = Character.levelMaxXP();
  $scope.progress = 0;

// TODO: change this to a reaction on the tick event.
  $scope.tick = function() {
    $scope.progress += Character.level*10;

    if($scope.progress > $scope.max) {
      Character.levelup();
      $scope.progress = 0;
      $scope.max = Character.levelMaxXP();
    }
    console.log($scope.progress+'/'+$scope.max+','+Character.level);
    // apply change to the view
    $scope.$apply();
  };
  clock.callbacks.push($scope.tick);

  $scope.random = function() {
    var value = Math.floor((Math.random() * 100) + 1);
    var type;

    if (value < 25) {
      type = 'success';
    } else if (value < 50) {
      type = 'info';
    } else if (value < 75) {
      type = 'warning';
    } else {
      type = 'danger';
    }

    $scope.showWarning = (type === 'danger' || type === 'warning');

    $scope.dynamic = value;
    $scope.type = type;
  };
  $scope.random();

  $scope.randomStacked = function() {
    $scope.stacked = [];
    var types = ['success', 'info', 'warning', 'danger'];

    for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) {
        var index = Math.floor((Math.random() * 4));
        $scope.stacked.push({
          value: Math.floor((Math.random() * 30) + 1),
          type: types[index]
        });
    }
  };
  $scope.randomStacked();
};
<|endoftext|>


<commit_before>(() => {
    'use strict';

    // hjelpemetoder
    var el = id => document.getElementById(id + "");

    // modell
    var spiller = "0";
    var poengX = "0";
    var poeng0 = "0"
    var trekk = [];

    const brett = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
    const vinnerkombinasjoner = [
        ["1", "2", "3"],
        ["4", "5", "6"],
        ["7", "8", "9"],
        ["1", "5", "9"],
        ["3", "5", "7"],
        ["1", "4", "7"],
        ["2", "5", "8"],
        ["3", "6", "9"]];

    // oppdater
    var gjoerTrekk = (felt) => {
        if (ledig(felt)) {
            tegnMerke(felt);
            lagreTrekk(felt);
            fargVinner();
            giPoeng();
            byttSpiller();
        }
    };

    var ledig = felt => trekk.filter(fylt => fylt === felt);

    var tegnMerke = felt => el(felt).innerHTML = spiller;

    var lagreTrekk = felt => trekk[felt] = spiller;

    var fargVinner = () => vinnerkombinasjoner
        .filter(eietAvSpiller)
        .map(fargKombinasjon);

    var giPoeng = () => {
        if (vinnerkombinasjoner.filter(eietAvSpiller).length > 0) {
            if (spiller === "X") {
                poengX++;
                el("spiller" + spiller).innerHTML = (poengX);
            } else if (spiller === "0") {
                poeng0++;
                el("spiller" + spiller).innerHTML = (poeng0);
            }
        }
    };

    var eietAvSpiller = combo => (combo
        .filter(felt => trekk[felt] === spiller)
        .length === 3);

    var fargKombinasjon = combo => (combo
        .map(felt => el(felt).style.backgroundColor = "green"));

    var byttSpiller = () => (spiller === "0") ? spiller = "X" : spiller = "0";

    var nyttSpill = () => {
        brett.map(id => el(id).innerHTML = "&nbsp");
        brett.map(id => el(id).style.backgroundColor = "lightgray");
        trekk = [];
    }

    // hendelser
    brett.map(id => el(id).addEventListener("click", () => gjoerTrekk(id)));
    el("nyttSpill").addEventListener("click", () => nyttSpill());

})();<commit_msg>Minor change.<commit_after>(() => {
    'use strict';

    // hjelpemetoder
    var el = id => document.getElementById(id + "");

    // modell
    var spiller = "0";
    var poengX = "0";
    var poeng0 = "0"
    var trekk = [];

    const brett = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
    const vinnerkombinasjoner = [
        ["1", "2", "3"],
        ["4", "5", "6"],
        ["7", "8", "9"],
        ["1", "5", "9"],
        ["3", "5", "7"],
        ["1", "4", "7"],
        ["2", "5", "8"],
        ["3", "6", "9"]];

    // oppdater
    var gjoerTrekk = (felt) => {
        if (ledig(felt)) {
            tegnMerke(felt);
            lagreTrekk(felt);
            fargVinner();
            giPoeng();
            byttSpiller();
        }
    };

    var ledig = felt => trekk.filter(fylt => fylt === felt);

    var tegnMerke = felt => el(felt).innerHTML = spiller;

    var lagreTrekk = felt => trekk[felt] = spiller;

    var fargVinner = () => vinnerkombinasjoner
        .filter(eietAvSpiller)
        .map(fargKombinasjon);

    var giPoeng = () => {
        if (vinnerkombinasjoner.filter(eietAvSpiller).length > 0) {
            if (spiller === "X") {
                poengX++;
                el("spiller" + spiller).innerHTML = (poengX);
            } else if (spiller === "0") {
                poeng0++;
                el("spiller" + spiller).innerHTML = (poeng0);
            }
        }
    };

    var eietAvSpiller = kombo => kombo
        .filter(felt => trekk[felt] === spiller)
        .length === 3;

    var fargKombinasjon = kombo => kombo.map(felt => el(felt).style.backgroundColor = "green");

    var byttSpiller = () => (spiller === "0") ? spiller = "X" : spiller = "0";

    var nyttSpill = () => {
        brett.map(id => el(id).innerHTML = "&nbsp");
        brett.map(id => el(id).style.backgroundColor = "lightgray");
        trekk = [];
    }

    // hendelser
    brett.map(id => el(id).addEventListener("click", () => gjoerTrekk(id)));
    el("nyttSpill").addEventListener("click", () => nyttSpill());

})();<|endoftext|>


<commit_before>//The frames in the sprite sheet is 16x16px
//mario_wjlfy5.png

window.onload = function() {

var canvas = document.getElementById('game');
var ctx = canvas.getContext('2d');
canvas.width = 300;
canvas.height = 300;
var marioImage = new Image();
marioImage.src = 'images/mario_wjlfy5_large.png';
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
// ctx.beginPath();
// ctx.rect(0,0, 10,10);
// ctx.fillStyle = '#FF0000';
// ctx.fill();
// ctx.closePath();

function sprite (options) {
    var that = {}, frameIndex = 1,
        tickCount = 0,
        ticksPerFrame = options.ticksPerFrame || 0,
        numberOfFrames = options.numberOfFrames || 1;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;

    that.render = function () {
        // Clear the canvas
        that.context.clearRect(0,0, that.width, that.height);
        // Draw the animation
        that.context.drawImage (
            that.image,
            frameIndex * that.width / numberOfFrames,
            0,
            that.width / numberOfFrames,
            that.height,
            0,
            0,
            that.width / numberOfFrames,
            that.height);
    };

    that.loop = options.loop;

    that.update = function() {
        tickCount += 1;

        if (tickCount > ticksPerFrame) {
            tickCount = 0;
            if (frameIndex < numberOfFrames -1) {
                frameIndex += 1;
            }
            else if (that.loop) {
                frameIndex = 1;
            }
            else {
                frameIndex = 1;
            }
        }
    };

    return that;
}

var mario = sprite({
    context: canvas.getContext('2d'),
    width: 512,
    height: 128,
    image: marioImage,
    numberOfFrames: 4,
    ticksPerFrame: 8,
});

function gameLoop () {
    window.requestAnimationFrame(gameLoop);

    mario.update();
    mario.render();
}
marioImage.addEventListener('load', gameLoop);

};<commit_msg>add keyhandlers, add move function<commit_after>//The frames in the sprite sheet is 16x16px
//mario_wjlfy5.png

window.onload = function() {

var canvas = document.getElementById('game');
var ctx = canvas.getContext('2d');
canvas.width = 640;
canvas.height = 480;
var marioImage = new Image();
marioImage.src = 'images/mario_wjlfy5_large.png';
var rightPressed = false;
var leftPressed = false;
var marioLeft = false;
var marioRight = true;

document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
// ctx.beginPath();
// ctx.rect(0,0, 10,10);
// ctx.fillStyle = '#FF0000';
// ctx.fill();
// ctx.closePath();

function keyDownHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = true;
    }
    else if (e.keyCode == 37) {
        leftPressed = true;
    }
}

function keyUpHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = false;
    }
    else if (e.keyCode == 37) {
        leftPressed = false;
    }
}

function sprite (options) {
    var that = {}, frameIndex = 1,
        tickCount = 0,
        ticksPerFrame = options.ticksPerFrame || 0,
        numberOfFrames = options.numberOfFrames || 1;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;
    that.x = options.x;
    that.y = options.y;

    that.render = function () {
        // Clear the canvas
        that.context.clearRect(that.x, that.y, that.width, that.height);
        // Draw the animation
        that.context.drawImage (
            that.image,
            frameIndex * that.width / numberOfFrames,
            0,
            that.width / numberOfFrames,
            that.height,
            that.x,
            that.y,
            that.width / numberOfFrames,
            that.height);
    };

    that.loop = options.loop;

    that.update = function() {
        tickCount += 1;

        if (tickCount > ticksPerFrame) {
            tickCount = 0;
            if (frameIndex < numberOfFrames -1) {
                frameIndex += 1;
            }
            else if (that.loop) {
                frameIndex = 1;
            }
            else {
                frameIndex = 1;
            }
        }
    };
    //Change 128 to relevant variable expression
    that.move = function() {
        if (rightPressed === true && that.x < canvas.width - 128) {
            mario.x += 5;
        }
        else if (leftPressed === true && that.x > 0) {
            mario.x -= 5;
        }
    };

    return that;
}

var mario = sprite({
    context: canvas.getContext('2d'),
    width: 512,
    height: 128,
    image: marioImage,
    numberOfFrames: 4,
    ticksPerFrame: 8,
    x: 20,
    y: canvas.height - 148,
});

function gameLoop () {
    window.requestAnimationFrame(gameLoop);

    mario.update();
    mario.render();
    mario.move()
}
marioImage.addEventListener('load', gameLoop);

};<|endoftext|>


<commit_before>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
//prompt: (bot) => bot.say('...'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}, waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {

      switch(message.text) {
        case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => '')
        case 'hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => '')
        case 'Starters hypotheek':
          return bot.say(`Daar help ik je graag bij. Weet je al wat voor soort woning?`)
          .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
            .then(() => bot.say(`%[Appartement](postback:hypotheekkeuze_appartement) %[Tussenwoning](postback:hypotheekkeuze_tussenwoning) %[Vrijstaand](postback:hypotheekkeuze_vrijstaand)`))
            .then(() => 'processing')
          break;
        case 'Nieuwe hypotheek':
          return bot.say(`Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`))
            .then(() => 'processing')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`Sorry. Momenteel biedt Independer alleen hypotheken aan voor Starters.`)
            .then(() => 'bye')
          break;
        default:
          return bot.say(`...`)
            .then(() => 'processing')
          break;
      }
    }
},
hypotheekkeuze_appartement: {
  //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'processing'
},
hypotheekkeuze_tussenwoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'processing'
},
hypotheekkeuze_vrijstaand: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'processing'
},
hypotheektype_nieuw: {
//    prompt: (bot) => bot.say(`Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`),
    receive: () => 'bye'
},

vervolgVragen: {
  receive: (bot, message) => {
    switch(message.text) {
        case 'Appartement':
          return bot.say(`Top!`)
          .then(() => 'askName')
        break;
      default:
        return bot.say(`...`)
          .then(() => 'processing')
        break;
    }
    }
},

askName: {
    prompt: (bot) => bot.say('Top - maar met wie heb ik het genoegen?'),
    receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
            .then(() => bot.say(`Hoi ${name}. ik heb nog wat vragen voor je om verder te kunnen.`))
            .then(() => 'vervolgVragen');
    }
},

bye: {
    prompt: (bot) => bot.say('Bedankt voor je tijd'),
    receive: () => 'processing'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<commit_msg>scritp<commit_after>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
//prompt: (bot) => bot.say('...'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}, waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {

      switch(message.text) {
        case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => '')
        case 'hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => '')
        case 'Starters hypotheek':
          return bot.say(`Daar help ik je graag bij. Weet je al wat voor soort woning?`)
          .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
            .then(() => bot.say(`%[Appartement](postback:hypotheekkeuze_appartement) %[Tussenwoning](postback:hypotheekkeuze_tussenwoning) %[Vrijstaand](postback:hypotheekkeuze_vrijstaand)`))
            .then(() => 'vervolgVragen')
          break;
        case 'Nieuwe hypotheek':
          return bot.say(`Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`))
            .then(() => 'processing')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`Sorry. Momenteel biedt Independer alleen hypotheken aan voor Starters.`)
            .then(() => 'bye')
          break;
        default:
          return bot.say(`...`)
            .then(() => 'processing')
          break;
      }
    }
},
hypotheekkeuze_appartement: {
  //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheekkeuze_tussenwoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
  receive: () => 'askName'
},
hypotheekkeuze_vrijstaand: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheektype_nieuw: {
//    prompt: (bot) => bot.say(`Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)`),
    receive: () => 'bye'
},

vervolgVragen: {
  receive: (bot, message) => {
    switch(message.text) {
        case 'Appartement':
          return bot.say(`Top!`)
          .then(() => 'askName')
        break;
      default:
        return bot.say(`...`)
          .then(() => 'processing')
        break;
    }
    }
},

askName: {
    prompt: (bot) => bot.say('Top - maar met wie heb ik het genoegen?'),
    receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
            .then(() => bot.say(`Hoi ${name}. ik heb nog wat vragen voor je om verder te kunnen.`))
            .then(() => 'vervolgVragen');
    }
},

bye: {
    prompt: (bot) => bot.say('Bedankt voor je tijd'),
    receive: () => 'processing'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<|endoftext|>


<commit_before>var x = 0;
var y = 0;
var operation = "";

$(".display").text("0");

function appendNum(num, modifiedVar) {
    modifiedVar = modifiedVar * 10 + num;
    return modifiedVar;
}

function minus(num) {

}

function display(x) {
    $(".display").text(x);
}

$(".plus").click(function() {
    operation = "+";
    display(x);
});

$(".minus").click(function() {

    display(x);
});

$(".posneg").click(function() {
    x = -x;
    display(x);
});

$(".equals").click(function() {
    if (operation === "+")
    {
        x += y;
        $(".display").text(x);
        operation = "";
    }
});

$(".CE").click(function() {
    $(".display").text("0");
    x = 0;
    y = 0;
    operation = "";
});

// number buttons
$(".one").click(function() {
    if (operation === "")
    {
        x = appendNum(1, x);
        display(x);
    }
    else
    {
        y = appendNum(1,y);
        display(y);
    }

});
$(".two").click(function() {
    if (operation === "")
    {
        x = appendNum(2, x);
        display(x);
    }
    else
    {
        y = appendNum(2,y);
        display(y);
    }

});
$(".three").click(function() {
    if (operation === "")
    {
        x = appendNum(3, x);
        display(x);
    }
    else
    {
        y = appendNum(3,y);
        display(y);
    }

});
$(".four").click(function() {
    if (operation === "")
    {
        x = appendNum(4, x);
        display(x);
    }
    else
    {
        y = appendNum(4,y);
        display(y);
    }

});
$(".five").click(function() {
    if (operation === "")
    {
        x = appendNum(5, x);
        display(x);
    }
    else
    {
        y = appendNum(5,y);
        display(y);
    }

});
$(".six").click(function() {
    if (operation === "")
    {
        x = appendNum(6, x);
        display(x);
    }
    else
    {
        y = appendNum(6,y);
        display(y);
    }

});
$(".seven").click(function() {
    if (operation === "")
    {
        x = appendNum(7, x);
        display(x);
    }
    else
    {
        y = appendNum(7,y);
        display(y);
    }

});
$(".eight").click(function() {
    if (operation === "")
    {
        x = appendNum(8, x);
        display(x);
    }
    else
    {
        y = appendNum(8,y);
        display(y);
    }

});
$(".nine").click(function() {
    if (operation === "")
    {
        x = appendNum(9, x);
        display(x);
    }
    else
    {
        y = appendNum(9,y);
        display(y);
    }

});
$(".zero").click(function() {
    if (operation === "")
    {
        x = appendNum(0, x);
        display(x);
    }
    else
    {
        y = appendNum(0,y);
        display(y);
    }

});<commit_msg>added equals<commit_after>var x = 0;
var y = 0;
var operation = "";

$(".display").text("0");

function appendNum(num, modifiedVar) {
    modifiedVar = modifiedVar * 10 + num;
    return modifiedVar;
}

function minus(num) {

}

function display(x) {
    $(".display").text(x);
}

$(".plus").click(function() {
    operation = "+";
    display(x);
});

$(".minus").click(function() {

    display(x);
});

$(".posneg").click(function() {
    x = -x;
    display(x);
});

$(".equals").click(function() {
    if (operation === "+")
    {
        x += y;
    }
    else if (operation === "-")
    {
        x -= y;
    }
    else if (operation === "/")
    {
        x /= y;
    }
    else if (operation === "*")
    {
        x *= y;
    }
    display(x);
    operation = "";
    y = 0;
});

$(".CE").click(function() {
    $(".display").text("0");
    x = 0;
    y = 0;
    operation = "";
});

// number buttons
$(".one").click(function() {
    if (operation === "")
    {
        x = appendNum(1, x);
        display(x);
    }
    else
    {
        y = appendNum(1,y);
        display(y);
    }

});
$(".two").click(function() {
    if (operation === "")
    {
        x = appendNum(2, x);
        display(x);
    }
    else
    {
        y = appendNum(2,y);
        display(y);
    }

});
$(".three").click(function() {
    if (operation === "")
    {
        x = appendNum(3, x);
        display(x);
    }
    else
    {
        y = appendNum(3,y);
        display(y);
    }

});
$(".four").click(function() {
    if (operation === "")
    {
        x = appendNum(4, x);
        display(x);
    }
    else
    {
        y = appendNum(4,y);
        display(y);
    }

});
$(".five").click(function() {
    if (operation === "")
    {
        x = appendNum(5, x);
        display(x);
    }
    else
    {
        y = appendNum(5,y);
        display(y);
    }

});
$(".six").click(function() {
    if (operation === "")
    {
        x = appendNum(6, x);
        display(x);
    }
    else
    {
        y = appendNum(6,y);
        display(y);
    }

});
$(".seven").click(function() {
    if (operation === "")
    {
        x = appendNum(7, x);
        display(x);
    }
    else
    {
        y = appendNum(7,y);
        display(y);
    }

});
$(".eight").click(function() {
    if (operation === "")
    {
        x = appendNum(8, x);
        display(x);
    }
    else
    {
        y = appendNum(8,y);
        display(y);
    }

});
$(".nine").click(function() {
    if (operation === "")
    {
        x = appendNum(9, x);
        display(x);
    }
    else
    {
        y = appendNum(9,y);
        display(y);
    }

});
$(".zero").click(function() {
    if (operation === "")
    {
        x = appendNum(0, x);
        display(x);
    }
    else
    {
        y = appendNum(0,y);
        display(y);
    }

});<|endoftext|>


<commit_before>'use strict';
//
// const _ = require('lodash');
// const Script = require('smooch-bot').Script;
// const scriptRules = require('./script.json')
//
// // function wait(ms) {
// // return new Promise((resolve) => {
// // setTimeout(resolve, ms);
// // });
// // },
//
// module.exports = new Script({
//
// //  processing: {
// // prompt: (bot) => bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)'),
// //  receive: () => 'processing'
// //  },
//
// // start: {
// //     receive: (bot,message) => {
// //         //const opening = message.text.trim().toUpperCase();
// //         return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
// //         .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
// //         .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
// //         .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
// //         .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
// //         .then(() => 'selecteerHypotheek');
// //     }
// // },
//
// // speak: {
// //           receive: (bot, message) => {
// //
// //               const upperText = message.text.trim().toUpperCase();
// //
// //               function updateSilent() {
// //                   switch (upperText) {
// //                       case "CONNECT ME":
// //                           return bot.setProp("silent", true);
// //                       case "DISCONNECT":
// //                           return bot.setProp("silent", false);
// //                       default:
// //                           return Promise.resolve();
// //                   }
// //               }
// //
// //               function getSilent() {
// //                   return bot.getProp("silent");
// //               }
// //
// //               function processMessage(isSilent) {
// //                   if (isSilent) {
// //                       return Promise.resolve("speak");
// //                   }
// //
// //
// //                   /*  CREATE EXTRA JSON FILE FOR HYPO AND INCLUDE IT */
// //                   if (!_.has(scriptRules, upperText)) {
// //                       return bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)').then(() => 'speak');
// //                   }
// //
// //                   var response = scriptRules[upperText];
// //                   var lines = response.split('\n');
// //
// //                   var p = Promise.resolve();
// //                   _.each(lines, function(line) {
// //                       line = line.trim();
// //                       p = p.then(function() {
// //                           console.log(line);
// //                           return wait(50).then(function() {
// //                               return bot.say(line);
// //                           });
// //                       });
// //                   });
// //
// //                   return p.then(() => 'speak');
// //               }
// //
// //               return updateSilent()
// //                   .then(getSilent)
// //                   .then(processMessage);
// //           }
// // },
//
// // selecteerHypotheek: {
// //     receive: (bot, message) => {
// //       switch(message.text) {
// //       case 'Hoi':
// //             return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
// //             .then(() => 'askName')
// //           break;
// //       case 'Starters Hypotheek':
// //           return bot.say(`Wat voor type woning zoek je? `)
// //           .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
// //           .then(() => 'woningType')
// //               break;
// //         case 'Nieuwe hypotheek':
// //           return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
// //           .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
// //             .then(() => 'finish')
// //           break;
// //         case 'Hypotheek oversluiten':
// //           return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
// //           .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
// //             .then(() => 'updateOntvangen')
// //           break;
// //         default:
// //           return bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`)
// //             .then(() => 'processing')
// //           break;
// //       }
// //     }
// // },
//
// // updateOntvangen: {
// //     receive: (bot, message) => {
// //       switch(message.text) {
// //         case 'Ja, dat wil ik wel':
// //             return bot.say(`👍 Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.`)
// //             .then(() => 'update_ja');
// //           break;
// //           case 'Nee, dat hoeft niet':
// //               receive: () => 'bye'
// //               break;
// //           default:
// //             receive: ()  => 'processing'
// //             break;
// //       }
// //     }
// // },
//
// // update_ja: {
// //   prompt: (bot) => bot.say('Wat is je email adres?'),
// //       receive: (bot, message) => {
// //           const emailer=message.text;
// //           return bot.setProp('emailer', emailer)
// //               .then(()  => bot.say(`Ok - ✉  dan hou ik je via ${emailer} op de hoogte.`))
// //               .then(()  =>'lastCheck')
// //     }
// // },
//
// // update_nee: {
// //   receive: () => 'bye'
// // },
//
// // hypotheekStarter: {
// //     receive: () => 'askName'
// // },
//
// // hypotheektype_nieuw: {
// //     prompt: (bot) => bot.say('Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)'),
// //     receive: () => 'processing'
// // },
//
// // woningType: {
// //   receive: (bot, message) => {
// //     switch(message.text) {
// //         case '🏬 Appartement':
// //           return bot.say(`Nice!`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //       case '🏠 Huis':
// //           return bot.say(`Leuk`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //     case '📭 Vakantiewoning':
// //           return bot.say(`Gezellig`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //       default:
// //         receive: ()  => 'processing'
// //         break;
// //         }
// //     }
// // },
//
// // vervolgVragen: {
// //   prompt: (bot) => bot.say('Hoe heet je eigelijk? 😋'),
// //           receive: (bot, message) => {
// //               const Name = message.text.trim().toUpperCase();
// //               return bot.setProp('Name', Name)
// //                   .then(() => bot.say(`Hoi ${Name}. 📋 Ik heb nog wat vragen voor je om verder te kunnen.`))
// //                   .then(() => 'processing')
// //             }
// // },
//
// // lastCheck: {
// //     prompt: (bot) => bot.say(' Is er nog iets waar ik  je bij kan helpen?  🔶  %[Ik zoek meer informatie](postback:meerInfo) %[Nee hoor](postback:bye)'),
// //           receive: (bot, message) => {
// //             switch(message.text) {
// //               case 'Nee hoor':
// //                   receive: ()  => 'bye'
// //                   break;
// //              case 'Ik zoek meer informatie':
// //                   receive: () => 'processing'
// //                   break;
// //             case 'Nee':
// //                   receive: () => 'bye'
// //                   break;
// //             default:
// //               receive:() => 'processing'
// //               break;
// //             }
// //         }
// // },
//
// // meerInfo: {
// //   prompt: (bot) => bot.say('bestand'),
// //    receive: () => 'processing'
// // },
//
// // bye: {
// //     prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd ⏲'),
// //     receive: ()  => 'finish'
// // },
//
// // error: {
// // prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// // receive: () => 'pri'
// // },
//
// // finish: {
// // receive: () => 'finish'
// // }
//
// });
<commit_msg>script<commit_after>'use strict';
//
const _ = require('lodash');
const Script = require('smooch-bot').Script;
const scriptRules = require('./script.json')
//
// // function wait(ms) {
// // return new Promise((resolve) => {
// // setTimeout(resolve, ms);
// // });
// // },
//
// module.exports = new Script({
//
// //  processing: {
// // prompt: (bot) => bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)'),
// //  receive: () => 'processing'
// //  },
//
// // start: {
// //     receive: (bot,message) => {
// //         //const opening = message.text.trim().toUpperCase();
// //         return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
// //         .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
// //         .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
// //         .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
// //         .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
// //         .then(() => 'selecteerHypotheek');
// //     }
// // },
//
// // speak: {
// //           receive: (bot, message) => {
// //
// //               const upperText = message.text.trim().toUpperCase();
// //
// //               function updateSilent() {
// //                   switch (upperText) {
// //                       case "CONNECT ME":
// //                           return bot.setProp("silent", true);
// //                       case "DISCONNECT":
// //                           return bot.setProp("silent", false);
// //                       default:
// //                           return Promise.resolve();
// //                   }
// //               }
// //
// //               function getSilent() {
// //                   return bot.getProp("silent");
// //               }
// //
// //               function processMessage(isSilent) {
// //                   if (isSilent) {
// //                       return Promise.resolve("speak");
// //                   }
// //
// //
// //                   /*  CREATE EXTRA JSON FILE FOR HYPO AND INCLUDE IT */
// //                   if (!_.has(scriptRules, upperText)) {
// //                       return bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)').then(() => 'speak');
// //                   }
// //
// //                   var response = scriptRules[upperText];
// //                   var lines = response.split('\n');
// //
// //                   var p = Promise.resolve();
// //                   _.each(lines, function(line) {
// //                       line = line.trim();
// //                       p = p.then(function() {
// //                           console.log(line);
// //                           return wait(50).then(function() {
// //                               return bot.say(line);
// //                           });
// //                       });
// //                   });
// //
// //                   return p.then(() => 'speak');
// //               }
// //
// //               return updateSilent()
// //                   .then(getSilent)
// //                   .then(processMessage);
// //           }
// // },
//
// // selecteerHypotheek: {
// //     receive: (bot, message) => {
// //       switch(message.text) {
// //       case 'Hoi':
// //             return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
// //             .then(() => 'askName')
// //           break;
// //       case 'Starters Hypotheek':
// //           return bot.say(`Wat voor type woning zoek je? `)
// //           .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
// //           .then(() => 'woningType')
// //               break;
// //         case 'Nieuwe hypotheek':
// //           return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
// //           .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
// //             .then(() => 'finish')
// //           break;
// //         case 'Hypotheek oversluiten':
// //           return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
// //           .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
// //             .then(() => 'updateOntvangen')
// //           break;
// //         default:
// //           return bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`)
// //             .then(() => 'processing')
// //           break;
// //       }
// //     }
// // },
//
// // updateOntvangen: {
// //     receive: (bot, message) => {
// //       switch(message.text) {
// //         case 'Ja, dat wil ik wel':
// //             return bot.say(`👍 Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.`)
// //             .then(() => 'update_ja');
// //           break;
// //           case 'Nee, dat hoeft niet':
// //               receive: () => 'bye'
// //               break;
// //           default:
// //             receive: ()  => 'processing'
// //             break;
// //       }
// //     }
// // },
//
// // update_ja: {
// //   prompt: (bot) => bot.say('Wat is je email adres?'),
// //       receive: (bot, message) => {
// //           const emailer=message.text;
// //           return bot.setProp('emailer', emailer)
// //               .then(()  => bot.say(`Ok - ✉  dan hou ik je via ${emailer} op de hoogte.`))
// //               .then(()  =>'lastCheck')
// //     }
// // },
//
// // update_nee: {
// //   receive: () => 'bye'
// // },
//
// // hypotheekStarter: {
// //     receive: () => 'askName'
// // },
//
// // hypotheektype_nieuw: {
// //     prompt: (bot) => bot.say('Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)'),
// //     receive: () => 'processing'
// // },
//
// // woningType: {
// //   receive: (bot, message) => {
// //     switch(message.text) {
// //         case '🏬 Appartement':
// //           return bot.say(`Nice!`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //       case '🏠 Huis':
// //           return bot.say(`Leuk`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //     case '📭 Vakantiewoning':
// //           return bot.say(`Gezellig`)
// //           .then(() => 'vervolgVragen')
// //           break;
// //       default:
// //         receive: ()  => 'processing'
// //         break;
// //         }
// //     }
// // },
//
// // vervolgVragen: {
// //   prompt: (bot) => bot.say('Hoe heet je eigelijk? 😋'),
// //           receive: (bot, message) => {
// //               const Name = message.text.trim().toUpperCase();
// //               return bot.setProp('Name', Name)
// //                   .then(() => bot.say(`Hoi ${Name}. 📋 Ik heb nog wat vragen voor je om verder te kunnen.`))
// //                   .then(() => 'processing')
// //             }
// // },
//
// // lastCheck: {
// //     prompt: (bot) => bot.say(' Is er nog iets waar ik  je bij kan helpen?  🔶  %[Ik zoek meer informatie](postback:meerInfo) %[Nee hoor](postback:bye)'),
// //           receive: (bot, message) => {
// //             switch(message.text) {
// //               case 'Nee hoor':
// //                   receive: ()  => 'bye'
// //                   break;
// //              case 'Ik zoek meer informatie':
// //                   receive: () => 'processing'
// //                   break;
// //             case 'Nee':
// //                   receive: () => 'bye'
// //                   break;
// //             default:
// //               receive:() => 'processing'
// //               break;
// //             }
// //         }
// // },
//
// // meerInfo: {
// //   prompt: (bot) => bot.say('bestand'),
// //    receive: () => 'processing'
// // },
//
// // bye: {
// //     prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd ⏲'),
// //     receive: ()  => 'finish'
// // },
//
// // error: {
// // prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// // receive: () => 'pri'
// // },
//
// // finish: {
// // receive: () => 'finish'
// // }
//
// });
<|endoftext|>