<commit_before>// Agency Theme JavaScript

var geocoder;
var map;
var placesService;
var infoWindow;
var markersArray = [];

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function(){
            $('.navbar-toggle:visible').click();
    });

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

})(jQuery); // End of use strict

function initMap() {

    /* Map Setup */
    var latlng = new google.maps.LatLng(53.181957, -3.876466);
    var mapOptions = {
        zoom: 6,
        center: latlng
    }

    /* Initialize Google Services */
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    geocoder = new google.maps.Geocoder();
    placesService = new google.maps.places.PlacesService(map);
    infoWindow = new google.maps.InfoWindow();
}

function findRestaurants() {

    /* Get information user entered */
    var location = document.getElementById("location-entry").value;
    var recipe = document.getElementById("recipe-entry").value;

    /* Convert location into coordinates and retrieve restaurants */
    geocoder.geocode( {'address': location}, function(results, status) {
        if (status == 'OK') {
            console.log(results);
            placesService.nearbySearch({
                location: results[0].geometry.location,
                radius: 10000,
                type: ['restaurant']
            }, callback);

            // Set the correct zoom
            map.setCenter(results[0].geometry.location);
            map.fitBounds(results[0].geometry.viewport);
        } else {
            alert('Geocode was not successful for the following reason: ' + status);
        }
    });
}

function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {

        clearMarkers();

        for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
            addToList(results[i]);
            console.log(results[i]);
        }
    }
}

/* Place a marker on the map with restaurant name */
function createMarker(place) {

    var marker = new google.maps.Marker({
        map: map,
        position: place.geometry.location
    });

    // Push marker to array
    markersArray.push(marker);

    google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(place.name);
        infoWindow.open(map,this);
    });
}

function addToList(place) {

    $('.list-group').append('' + place.name + '');

}

/**
 * Remove all markers from the map
 */
function clearMarkers() {
    for(var i = 0; i < markersArray.length; i++) {
        markersArray[i].setMap(null);
    }
}

<commit_msg>When hovering a restaurant, the map icon will change colours.<commit_after>// Agency Theme JavaScript

var geocoder;
var map;
var placesService;
var infoWindow;
var markersArray = [];

(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function(){
            $('.navbar-toggle:visible').click();
    });

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    $('.list-group-item').hover();

})(jQuery); // End of use strict

function initMap() {

    /* Map Setup */
    var latlng = new google.maps.LatLng(53.181957, -3.876466);
    var mapOptions = {
        zoom: 6,
        center: latlng
    };

    /* Initialize Google Services */
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    geocoder = new google.maps.Geocoder();
    placesService = new google.maps.places.PlacesService(map);
    infoWindow = new google.maps.InfoWindow();
}

function findRestaurants() {

    /* Get information user entered */
    var location = document.getElementById("location-entry").value;
    var recipe = document.getElementById("recipe-entry").value;

    /* Convert location into coordinates and retrieve restaurants */
    geocoder.geocode( {'address': location}, function(results, status) {
        if (status == 'OK') {
            console.log(results);
            placesService.nearbySearch({
                location: results[0].geometry.location,
                radius: 10000,
                type: ['restaurant']
            }, callback);

            // Set the correct zoom
            map.setCenter(results[0].geometry.location);
            map.fitBounds(results[0].geometry.viewport);
        } else {
            alert('Geocode was not successful for the following reason: ' + status);
        }
    });
}

function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {

        clearMarkers();

        for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
            console.log(results[i]);
        }
    }
}

/**
 * Place a marker on the map with restaurant name
 * @param place Place object from Google Places
 */
function createMarker(place) {

    var marker = new google.maps.Marker({
        map: map,
        position: place.geometry.location
    });

    marker.setIcon('http://maps.google.com/mapfiles/ms/icons/red-dot.png');

    // Push marker to array
    markersArray.push(marker);

    google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(place.name);
        infoWindow.open(map,this);
    });

    addToList(place, marker);
}

function addToList(place, marker) {

    $('.list-group').append('' + place.name + '');
    $('#' + place.id).hover(function() {
        marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')
    }, function() {
        marker.setIcon('http://maps.google.com/mapfiles/ms/icons/red-dot.png')
    });
}

/**
 * Remove all markers from the map and clear the list of restaurants
 */
function clearMarkers() {

    // Remove markers from the map
    for(var i = 0; i < markersArray.length; i++) {
        markersArray[i].setMap(null);
    }

    // Reset the markers array
    markersArray.length = 0;

    // Reset the restaurant list
    $('.list-group').html('');
}

<|endoftext|>


<commit_before>var http = require('http');
var path = require('path');
var url = require('url');
var qs = require('querystring');
var util = require('util');
var cp = require('child_process');
var fs = require('fs');

// @see http://labs.telasocial.com/nodejs-forever-daemon/
// forever -o app/logs/nodejs-deamon.log -e app/logs/nodejs-deamon.log bin/deamon.js

/* Hashmap for running sub processes */
var processes = {};

/* Create server */
var server = http.createServer(function (req, resp) {
    var parsedUrl = url.parse(req.url);
    var params = qs.parse(parsedUrl.query);

    if ('/spawn' === parsedUrl.pathname && params.measurementId) {
        var php = spawn(params.measurementId);

        jsonResponse(resp, 200, {
            pid: php.pid,
            msg: 'process with pid ' + php.pid + ' started for measurement '
        });
    } else if ('/kill' === parsedUrl.pathname && params.measurementId) {
        var res = kill(params.measurementId);

        jsonResponse(resp, res ? 200 : 404, {
            status: res,
            msg: 'killing process for measurement ' + params.measurementId
        });
    } else {
        jsonResponse(resp, 404, {
            msg: 'Not found. Try /spawn?measurementId=123 or /kill?measurementId=123'
        });
    }
});
server.listen(1025);
console.log('wlanthermo deamon server now listens on port 1025');

/* Span process */
function spawn(measurementId) {
    if (processes[measurementId]) {
        kill(measurementId);
    }

    var php  = cp.spawn('php', [__dirname + '/../app/console', 'app:measurement', measurementId]);
    php.stdout.on('data', function (data) {
        util.log('[OUT pid ' + php.pid + ', measurementId ' + measurementId + ']: ' + data);
    });
    php.stderr.on('data', function (data) {
        util.log('[ERR pid ' + php.pid + ', measurementId ' + measurementId + ']: ' + data);
    });
    php.on('exit', function (code) {
        util.log('[EXIT pid ' + php.pid + ', measurementId ' + measurementId + ']: code ' + code);
    });

    setTimeout(function() {
        processes[measurementId] = php;
    }, 0);

    return php;
};

/* Kill process */
var kill = function(measurementId) {
    var php = processes[measurementId];
    if (php) {
        php.kill('SIGINT');
        delete processes[measurementId];
        return true;
    } else {
        return false;
    }
};

/* Output a JSON response */
var jsonResponse = function(resp, status, obj) {
    resp.writeHead(status, {
        'Content-Type': 'application/json; charset=utf-8'
    });
    obj.status = status;
    resp.write(JSON.stringify(obj));
    resp.end();
};

/* Clean shutdown */
var onExit = function () {
    processes && util.log('wlanthermo deamon server shuts down');

    for (var key in processes) {
        if (processes.hasOwnProperty(key)) {
            processes[key].kill('SIGINT');
        }
    }

    processes = null;

    process.exit(0);
};
process.on('SIGINT', onExit);
process.on('exit', onExit);
<commit_msg>Deamon now only listens on localhost<commit_after>var http = require('http');
var path = require('path');
var url = require('url');
var qs = require('querystring');
var util = require('util');
var cp = require('child_process');
var fs = require('fs');

// @see http://labs.telasocial.com/nodejs-forever-daemon/
// forever -o app/logs/nodejs-deamon.log -e app/logs/nodejs-deamon.log bin/deamon.js

/* Hashmap for running sub processes */
var processes = {};

/* Port */
var port = 1025;

/* Create server */
var server = http.createServer(function (req, resp) {
    var parsedUrl = url.parse(req.url);
    var params = qs.parse(parsedUrl.query);

    if ('/spawn' === parsedUrl.pathname && params.measurementId) {
        var php = spawn(params.measurementId);

        jsonResponse(resp, 200, {
            pid: php.pid,
            msg: 'process with pid ' + php.pid + ' started for measurement '
        });
    } else if ('/kill' === parsedUrl.pathname && params.measurementId) {
        var res = kill(params.measurementId);

        jsonResponse(resp, res ? 200 : 404, {
            status: res,
            msg: 'killing process for measurement ' + params.measurementId
        });
    } else {
        jsonResponse(resp, 404, {
            msg: 'Not found. Try /spawn?measurementId=123 or /kill?measurementId=123'
        });
    }
});
server.listen(port, 'localhost');
console.log('wlanthermo deamon server now listens on port ' + port);

/* Span process */
function spawn(measurementId) {
    if (processes[measurementId]) {
        kill(measurementId);
    }

    var php  = cp.spawn('php', [__dirname + '/../app/console', 'app:measurement', measurementId]);
    php.stdout.on('data', function (data) {
        util.log('[OUT pid ' + php.pid + ', measurementId ' + measurementId + ']: ' + data);
    });
    php.stderr.on('data', function (data) {
        util.log('[ERR pid ' + php.pid + ', measurementId ' + measurementId + ']: ' + data);
    });
    php.on('exit', function (code) {
        util.log('[EXIT pid ' + php.pid + ', measurementId ' + measurementId + ']: code ' + code);
    });

    setTimeout(function() {
        processes[measurementId] = php;
    }, 0);

    return php;
};

/* Kill process */
var kill = function(measurementId) {
    var php = processes[measurementId];
    if (php) {
        php.kill('SIGINT');
        delete processes[measurementId];
        return true;
    } else {
        return false;
    }
};

/* Output a JSON response */
var jsonResponse = function(resp, status, obj) {
    resp.writeHead(status, {
        'Content-Type': 'application/json; charset=utf-8'
    });
    obj.status = status;
    resp.write(JSON.stringify(obj));
    resp.end();
};

/* Clean shutdown */
var onExit = function () {
    processes && util.log('wlanthermo deamon server shuts down');

    for (var key in processes) {
        if (processes.hasOwnProperty(key)) {
            processes[key].kill('SIGINT');
        }
    }

    processes = null;

    process.exit(0);
};
process.on('SIGINT', onExit);
process.on('exit', onExit);
<|endoftext|>


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

require('./proof')(1, function (step, Strata, tmp, load, serialize, objectify, assert) {
    var strata = new Strata({ directory: tmp, leafSize: 3, branchSize: 3 })
    step(function () {
        serialize(__dirname + '/fixtures/empties-many.before.json', tmp, step())
    }, function () {
        strata.open(step())
    }, function () {
        strata.mutator('eu', step())
    }, function (cursor) {
        step(function () {
            cursor.remove(cursor.index, step())
        }, function () {
            cursor.unlock()
        })
    }, function () {
        strata.balance(step())
    }, function () {
        objectify(tmp, step())
        load(__dirname + '/fixtures/empties-many.after.json', step())
    }, function (actual, expected) {
        assert(actual, expected, 'after')
        strata.close(step())
    })
})
<commit_msg>Use `vivify` in `t/merge/empties-many.t.js`.<commit_after>#!/usr/bin/env node

require('./proof')(1, function (step, Strata, tmp, load, serialize, vivify, assert) {
    var strata = new Strata({ directory: tmp, leafSize: 3, branchSize: 3 })
    step(function () {
        serialize(__dirname + '/fixtures/empties-many.before.json', tmp, step())
    }, function () {
        strata.open(step())
    }, function () {
        strata.mutator('eu', step())
    }, function (cursor) {
        step(function () {
            cursor.remove(cursor.index, step())
        }, function () {
            cursor.unlock()
        })
    }, function () {
        strata.balance(step())
    }, function () {
        vivify(tmp, step())
        load(__dirname + '/fixtures/empties-many.after.json', step())
    }, function (actual, expected) {
        assert(actual, expected, 'after')
        strata.close(step())
    })
})
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var gutil = require('gulp-util');
var through2 = require('through2');
var exec = require('child_process').exec;
var path = require('path');

module.exports = function ccm() {

  var ccReporter = path.join(__dirname, 'node_modules', '.bin', 'codeclimate-test-reporter');
  return through2.obj(function handleFile(file, encoding, next) {
    exec(util.format('CODECLIMATE_REPO_TOKEN=%s %s < "%s"', process.env.CODE_CLIMATE_TOKEN, ccReporter, file.path))
      .then(function execCompleted(stdout, stderr) {
        if (stderr) {
          next(new gutil.PluginError({
            message: stderr
          }));
          return;
        }
        gutil.log('Coverage file posted: "%s"', file.path);
        next();
      })
      .catch(next);
  });
};
<commit_msg>chore(npm): fix exec api<commit_after>'use strict';

var util = require('util');
var gutil = require('gulp-util');
var through2 = require('through2');
var exec = require('child_process').exec;
var path = require('path');

module.exports = function ccm() {

  var ccReporter = path.join(__dirname, 'node_modules', '.bin', 'codeclimate-test-reporter');
  return through2.obj(function handleFile(file, encoding, next) {
    exec(util.format('CODECLIMATE_REPO_TOKEN=%s %s < "%s"', process.env.CODE_CLIMATE_TOKEN, ccReporter, file.path), function(err) {
      if (err) {
        next(new gutil.PluginError({
          message: err
        }));
        return;
      }
      gutil.log('Coverage file posted: "%s"', file.path);
      next();
    });
  });
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 * @generate-docs
 */

'use strict';

const Platform = require('../../Utilities/Platform');
const React = require('react');
const StyleSheet = require('../../StyleSheet/StyleSheet');

import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {ViewProps} from '../View/ViewPropTypes';
import SwitchNativeComponent from './SwitchNativeComponent';
import AndroidSwitchNativeComponent from './AndroidSwitchNativeComponent';

type SwitchChangeEvent = SyntheticEvent<
  $ReadOnly<{|
    value: boolean,
  |}>,
>;

export type Props = $ReadOnly<{|
  ...ViewProps,

  /**
   * Whether the switch is disabled. Defaults to false.
   */
  disabled?: ?boolean,

  /**
   * Boolean value of the switch. Defaults to false.
   */
  value?: ?boolean,

  /**
   * Custom color for the switch thumb.
   */
  thumbColor?: ?ColorValue,

  /**
   * Custom colors for the switch track.
   *
   * NOTE: On iOS when the switch value is false, the track shrinks into the
   * border. If you want to change the color of the background exposed by the
   * shrunken track, use `ios_backgroundColor`.
   */
  trackColor?: ?$ReadOnly<{|
    false?: ?ColorValue,
    true?: ?ColorValue,
  |}>,

  /**
   * On iOS, custom color for the background. This background color can be seen
   * either when the switch value is false or when the switch is disabled (and
   * the switch is translucent).
   */
  ios_backgroundColor?: ?ColorValue,

  /**
   * Called when the user tries to change the value of the switch.
   *
   * Receives the change event as an argument. If you want to only receive the
   * new value, use `onValueChange` instead.
   */
  onChange?: ?(event: SwitchChangeEvent) => Promise<void> | void,

  /**
   * Called when the user tries to change the value of the switch.
   *
   * Receives the new value as an argument. If you want to instead receive an
   * event, use `onChange`.
   */
  onValueChange?: ?(value: boolean) => Promise<void> | void,
|}>;

/**
 * A visual toggle between two mutually exclusive states.
 *
 * This is a controlled component that requires an `onValueChange` callback that
 * updates the `value` prop in order for the component to reflect user actions.
 * If the `value` prop is not updated, the component will continue to render the
 * supplied `value` prop instead of the expected result of any user actions.
 */
class Switch extends React.Component<Props> {
  _nativeSwitchRef: ?React.ElementRef<
    typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
  >;
  _lastNativeValue: ?boolean;

  render(): React.Node {
    const {
      disabled,
      ios_backgroundColor,
      onChange,
      onValueChange,
      style,
      thumbColor,
      trackColor,
      value,
      ...props
    } = this.props;

    // Support deprecated color props.
    let _thumbColor = thumbColor;
    let _trackColorForFalse = trackColor?.false;
    let _trackColorForTrue = trackColor?.true;

    // TODO: Remove support for these props after a couple releases.
    const {thumbTintColor, tintColor, onTintColor} = (props: $FlowFixMe);
    if (thumbTintColor != null) {
      _thumbColor = thumbTintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `thumbTintColor` is deprecated, use `thumbColor` instead.',
        );
      }
    }
    if (tintColor != null) {
      _trackColorForFalse = tintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `tintColor` is deprecated, use `trackColor` instead.',
        );
      }
    }
    if (onTintColor != null) {
      _trackColorForTrue = onTintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `onTintColor` is deprecated, use `trackColor` instead.',
        );
      }
    }

    if (Platform.OS === 'android') {
      const platformProps = {
        enabled: disabled !== true,
        on: value === true,
        style,
        thumbTintColor: _thumbColor,
        trackColorForFalse: _trackColorForFalse,
        trackColorForTrue: _trackColorForTrue,
        trackTintColor:
          value === true ? _trackColorForTrue : _trackColorForFalse,
      };

      return (
        <AndroidSwitchNativeComponent
          {...props}
          {...platformProps}
          accessibilityRole={props.accessibilityRole ?? 'switch'}
          onChange={this._handleChange}
          onResponderTerminationRequest={returnsFalse}
          onStartShouldSetResponder={returnsTrue}
          ref={this._handleSwitchNativeComponentRef}
        />
      );
    }

    const platformProps = {
      disabled,
      onTintColor: _trackColorForTrue,
      style: StyleSheet.compose(
        {height: 31, width: 51},
        StyleSheet.compose(
          style,
          ios_backgroundColor == null
            ? null
            : {
                backgroundColor: ios_backgroundColor,
                borderRadius: 16,
              },
        ),
      ),
      thumbTintColor: _thumbColor,
      tintColor: _trackColorForFalse,
      value: value === true,
    };

    return (
      <SwitchNativeComponent
        {...props}
        {...platformProps}
        accessibilityRole={props.accessibilityRole ?? 'switch'}
        onChange={this._handleChange}
        onResponderTerminationRequest={returnsFalse}
        onStartShouldSetResponder={returnsTrue}
        ref={this._handleSwitchNativeComponentRef}
      />
    );
  }

  componentDidUpdate() {
    // This is necessary in case native updates the switch and JS decides
    // that the update should be ignored and we should stick with the value
    // that we have in JS.
    const nativeProps = {};
    const value = this.props.value === true;

    if (this._lastNativeValue !== value && typeof value === 'boolean') {
      nativeProps.value = value;
    }

    if (
      Object.keys(nativeProps).length > 0 &&
      this._nativeSwitchRef &&
      this._nativeSwitchRef.setNativeProps
    ) {
      this._nativeSwitchRef.setNativeProps(nativeProps);
    }
  }

  _handleChange = (event: SwitchChangeEvent) => {
    if (this.props.onChange != null) {
      this.props.onChange(event);
    }

    if (this.props.onValueChange != null) {
      this.props.onValueChange(event.nativeEvent.value);
    }

    this._lastNativeValue = event.nativeEvent.value;
    this.forceUpdate();
  };

  _handleSwitchNativeComponentRef = (
    ref: ?React.ElementRef<
      typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
    >,
  ) => {
    this._nativeSwitchRef = ref;
  };
}

const returnsFalse = () => false;
const returnsTrue = () => true;

module.exports = Switch;
<commit_msg>Use commands instead of setNativeProps for AndroidSwitch<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 * @generate-docs
 */

'use strict';

const Platform = require('../../Utilities/Platform');
const React = require('react');
const StyleSheet = require('../../StyleSheet/StyleSheet');

import AndroidSwitchNativeComponent, {
  Commands as AndroidSwitchCommands,
} from './AndroidSwitchNativeComponent';

import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {ViewProps} from '../View/ViewPropTypes';
import SwitchNativeComponent from './SwitchNativeComponent';

type SwitchChangeEvent = SyntheticEvent<
  $ReadOnly<{|
    value: boolean,
  |}>,
>;

export type Props = $ReadOnly<{|
  ...ViewProps,

  /**
   * Whether the switch is disabled. Defaults to false.
   */
  disabled?: ?boolean,

  /**
   * Boolean value of the switch. Defaults to false.
   */
  value?: ?boolean,

  /**
   * Custom color for the switch thumb.
   */
  thumbColor?: ?ColorValue,

  /**
   * Custom colors for the switch track.
   *
   * NOTE: On iOS when the switch value is false, the track shrinks into the
   * border. If you want to change the color of the background exposed by the
   * shrunken track, use `ios_backgroundColor`.
   */
  trackColor?: ?$ReadOnly<{|
    false?: ?ColorValue,
    true?: ?ColorValue,
  |}>,

  /**
   * On iOS, custom color for the background. This background color can be seen
   * either when the switch value is false or when the switch is disabled (and
   * the switch is translucent).
   */
  ios_backgroundColor?: ?ColorValue,

  /**
   * Called when the user tries to change the value of the switch.
   *
   * Receives the change event as an argument. If you want to only receive the
   * new value, use `onValueChange` instead.
   */
  onChange?: ?(event: SwitchChangeEvent) => Promise<void> | void,

  /**
   * Called when the user tries to change the value of the switch.
   *
   * Receives the new value as an argument. If you want to instead receive an
   * event, use `onChange`.
   */
  onValueChange?: ?(value: boolean) => Promise<void> | void,
|}>;

/**
 * A visual toggle between two mutually exclusive states.
 *
 * This is a controlled component that requires an `onValueChange` callback that
 * updates the `value` prop in order for the component to reflect user actions.
 * If the `value` prop is not updated, the component will continue to render the
 * supplied `value` prop instead of the expected result of any user actions.
 */
class Switch extends React.Component<Props> {
  _nativeSwitchRef: ?React.ElementRef<
    typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
  >;
  _lastNativeValue: ?boolean;

  render(): React.Node {
    const {
      disabled,
      ios_backgroundColor,
      onChange,
      onValueChange,
      style,
      thumbColor,
      trackColor,
      value,
      ...props
    } = this.props;

    // Support deprecated color props.
    let _thumbColor = thumbColor;
    let _trackColorForFalse = trackColor?.false;
    let _trackColorForTrue = trackColor?.true;

    // TODO: Remove support for these props after a couple releases.
    const {thumbTintColor, tintColor, onTintColor} = (props: $FlowFixMe);
    if (thumbTintColor != null) {
      _thumbColor = thumbTintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `thumbTintColor` is deprecated, use `thumbColor` instead.',
        );
      }
    }
    if (tintColor != null) {
      _trackColorForFalse = tintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `tintColor` is deprecated, use `trackColor` instead.',
        );
      }
    }
    if (onTintColor != null) {
      _trackColorForTrue = onTintColor;
      if (__DEV__) {
        console.warn(
          'Switch: `onTintColor` is deprecated, use `trackColor` instead.',
        );
      }
    }

    if (Platform.OS === 'android') {
      const platformProps = {
        enabled: disabled !== true,
        on: value === true,
        style,
        thumbTintColor: _thumbColor,
        trackColorForFalse: _trackColorForFalse,
        trackColorForTrue: _trackColorForTrue,
        trackTintColor:
          value === true ? _trackColorForTrue : _trackColorForFalse,
      };

      return (
        <AndroidSwitchNativeComponent
          {...props}
          {...platformProps}
          accessibilityRole={props.accessibilityRole ?? 'switch'}
          onChange={this._handleChange}
          onResponderTerminationRequest={returnsFalse}
          onStartShouldSetResponder={returnsTrue}
          ref={this._handleSwitchNativeComponentRef}
        />
      );
    }

    const platformProps = {
      disabled,
      onTintColor: _trackColorForTrue,
      style: StyleSheet.compose(
        {height: 31, width: 51},
        StyleSheet.compose(
          style,
          ios_backgroundColor == null
            ? null
            : {
                backgroundColor: ios_backgroundColor,
                borderRadius: 16,
              },
        ),
      ),
      thumbTintColor: _thumbColor,
      tintColor: _trackColorForFalse,
      value: value === true,
    };

    return (
      <SwitchNativeComponent
        {...props}
        {...platformProps}
        accessibilityRole={props.accessibilityRole ?? 'switch'}
        onChange={this._handleChange}
        onResponderTerminationRequest={returnsFalse}
        onStartShouldSetResponder={returnsTrue}
        ref={this._handleSwitchNativeComponentRef}
      />
    );
  }

  componentDidUpdate() {
    // This is necessary in case native updates the switch and JS decides
    // that the update should be ignored and we should stick with the value
    // that we have in JS.
    const nativeProps = {};
    const value = this.props.value === true;

    if (this._lastNativeValue !== value && typeof value === 'boolean') {
      nativeProps.value = value;
    }

    if (
      Object.keys(nativeProps).length > 0 &&
      this._nativeSwitchRef &&
      this._nativeSwitchRef.setNativeProps
    ) {
      if (Platform.OS === 'android') {
        AndroidSwitchCommands.setNativeValue(
          this._nativeSwitchRef,
          nativeProps.value,
        );
      } else {
        this._nativeSwitchRef.setNativeProps(nativeProps);
      }
    }
  }

  _handleChange = (event: SwitchChangeEvent) => {
    if (this.props.onChange != null) {
      this.props.onChange(event);
    }

    if (this.props.onValueChange != null) {
      this.props.onValueChange(event.nativeEvent.value);
    }

    this._lastNativeValue = event.nativeEvent.value;
    this.forceUpdate();
  };

  _handleSwitchNativeComponentRef = (
    ref: ?React.ElementRef<
      typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
    >,
  ) => {
    this._nativeSwitchRef = ref;
  };
}

const returnsFalse = () => false;
const returnsTrue = () => true;

module.exports = Switch;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule mergeHelpers
 *
 * requiresPolyfills: Array.isArray
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 * Maximum number of levels to traverse. Will catch circular structures.
 * @const
 */
var MAX_MERGE_DEPTH = 36;

/**
 * We won't worry about edge cases like new String('x') or new Boolean(true).
 * Functions and Dates are considered terminals, and arrays are not.
 * @param {*} o The item/object/value to test.
 * @return {boolean} true iff the argument is a terminal.
 */
var isTerminal = function(o) {
  return typeof o !== 'object' || o instanceof Date || o === null;
};

var mergeHelpers = {

  MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,

  isTerminal: isTerminal,

  /**
   * Converts null/undefined values into empty object.
   *
   * @param {?Object=} arg Argument to be normalized (nullable optional)
   * @return {!Object}
   */
  normalizeMergeArg: function(arg) {
    return arg === undefined || arg === null ? {} : arg;
  },

  /**
   * If merging Arrays, a merge strategy *must* be supplied. If not, it is
   * likely the caller's fault. If this function is ever called with anything
   * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
   *
   * @param {*} one Array to merge into.
   * @param {*} two Array to merge from.
   */
  checkMergeArrayArgs: function(one, two) {
    invariant(
      Array.isArray(one) && Array.isArray(two),
      'Tried to merge arrays, instead got %s and %s.',
      one,
      two
    );
  },

  /**
   * @param {*} one Object to merge into.
   * @param {*} two Object to merge from.
   */
  checkMergeObjectArgs: function(one, two) {
    mergeHelpers.checkMergeObjectArg(one);
    mergeHelpers.checkMergeObjectArg(two);
  },

  /**
   * @param {*} arg
   */
  checkMergeObjectArg: function(arg) {
    invariant(
      !isTerminal(arg) && !Array.isArray(arg),
      'Tried to merge an object, instead got %s.',
      arg
    );
  },

  /**
   * @param {*} arg
   */
  checkMergeIntoObjectArg: function(arg) {
    invariant(
      (!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
      'Tried to merge into an object, instead got %s.',
      arg
    );
  },

  /**
   * Checks that a merge was not given a circular object or an object that had
   * too great of depth.
   *
   * @param {number} Level of recursion to validate against maximum.
   */
  checkMergeLevel: function(level) {
    invariant(
      level < MAX_MERGE_DEPTH,
      'Maximum deep merge depth exceeded. You may be attempting to merge ' +
      'circular structures in an unsupported way.'
    );
  },

  /**
   * Checks that the supplied merge strategy is valid.
   *
   * @param {string} Array merge strategy.
   */
  checkArrayStrategy: function(strategy) {
    invariant(
      strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
      'You must provide an array strategy to deep merge functions to ' +
      'instruct the deep merge how to resolve merging two arrays.'
    );
  },

  /**
   * Set of possible behaviors of merge algorithms when encountering two Arrays
   * that must be merged together.
   * - `clobber`: The left `Array` is ignored.
   * - `indexByIndex`: The result is achieved by recursively deep merging at
   *   each index. (not yet supported.)
   */
  ArrayStrategies: {
    Clobber: 'Clobber',
    Concat: 'Concat',
    IndexByIndex: 'IndexByIndex',
  },

};

module.exports = mergeHelpers;
<commit_msg>Revert D5255886: [JS] Stop using lodash in RN<commit_after>/**
 * @generated SignedSource<<b68d78236d45828b3f7f7fcc740782a9>>
 *
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * !! This file is a check-in of a static_upstream project!      !!
 * !!                                                            !!
 * !! You should not modify this file directly. Instead:         !!
 * !! 1) Use `fjs use-upstream` to temporarily replace this with !!
 * !!    the latest version from upstream.                       !!
 * !! 2) Make your changes, test them, etc.                      !!
 * !! 3) Use `fjs push-upstream` to copy your changes back to    !!
 * !!    static_upstream.                                        !!
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *
 * Copyright 2013-2014 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @providesModule mergeHelpers
 *
 * requiresPolyfills: Array.isArray
 */

"use strict";

var invariant = require('fbjs/lib/invariant');
var keyMirror = require('fbjs/lib/keyMirror');

/**
 * Maximum number of levels to traverse. Will catch circular structures.
 * @const
 */
var MAX_MERGE_DEPTH = 36;

/**
 * We won't worry about edge cases like new String('x') or new Boolean(true).
 * Functions are considered terminals, and arrays are not.
 * @param {*} o The item/object/value to test.
 * @return {boolean} true iff the argument is a terminal.
 */
var isTerminal = function(o) {
  return typeof o !== 'object' || o === null;
};

var mergeHelpers = {

  MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,

  isTerminal: isTerminal,

  /**
   * Converts null/undefined values into empty object.
   *
   * @param {?Object=} arg Argument to be normalized (nullable optional)
   * @return {!Object}
   */
  normalizeMergeArg: function(arg) {
    return arg === undefined || arg === null ? {} : arg;
  },

  /**
   * If merging Arrays, a merge strategy *must* be supplied. If not, it is
   * likely the caller's fault. If this function is ever called with anything
   * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
   *
   * @param {*} one Array to merge into.
   * @param {*} two Array to merge from.
   */
  checkMergeArrayArgs: function(one, two) {
    invariant(
      Array.isArray(one) && Array.isArray(two),
      'Tried to merge arrays, instead got %s and %s.',
      one,
      two
    );
  },

  /**
   * @param {*} one Object to merge into.
   * @param {*} two Object to merge from.
   */
  checkMergeObjectArgs: function(one, two) {
    mergeHelpers.checkMergeObjectArg(one);
    mergeHelpers.checkMergeObjectArg(two);
  },

  /**
   * @param {*} arg
   */
  checkMergeObjectArg: function(arg) {
    invariant(
      !isTerminal(arg) && !Array.isArray(arg),
      'Tried to merge an object, instead got %s.',
      arg
    );
  },

  /**
   * @param {*} arg
   */
  checkMergeIntoObjectArg: function(arg) {
    invariant(
      (!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
      'Tried to merge into an object, instead got %s.',
      arg
    );
  },

  /**
   * Checks that a merge was not given a circular object or an object that had
   * too great of depth.
   *
   * @param {number} Level of recursion to validate against maximum.
   */
  checkMergeLevel: function(level) {
    invariant(
      level < MAX_MERGE_DEPTH,
      'Maximum deep merge depth exceeded. You may be attempting to merge ' +
      'circular structures in an unsupported way.'
    );
  },

  /**
   * Checks that the supplied merge strategy is valid.
   *
   * @param {string} Array merge strategy.
   */
  checkArrayStrategy: function(strategy) {
    invariant(
      strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
      'You must provide an array strategy to deep merge functions to ' +
      'instruct the deep merge how to resolve merging two arrays.'
    );
  },

  /**
   * Set of possible behaviors of merge algorithms when encountering two Arrays
   * that must be merged together.
   * - `clobber`: The left `Array` is ignored.
   * - `indexByIndex`: The result is achieved by recursively deep merging at
   *   each index. (not yet supported.)
   */
  ArrayStrategies: keyMirror({
    Clobber: true,
    IndexByIndex: true
  })

};

module.exports = mergeHelpers;
<|endoftext|>


<commit_before>(function (factory, window) {
    if (typeof define === 'function' && define.amd) {
        define(['leaflet'], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory(require('leaflet'));
    }
    if (typeof window !== 'undefined' && window.L) {
        window.L.PolylineOffset = factory(L);
    }
}(function (L) {

function forEachPair(list, callback) {
    if (!list || list.length < 1) { return; }
    for (var i = 1, l = list.length; i < l; i++) {
        callback(list[i-1], list[i]);
    }
}

/**
Find the coefficients (a,b) of a line of equation y = a.x + b,
or the constant x for vertical lines
Return null if there's no equation possible
*/
function lineEquation(pt1, pt2) {
    if (pt1.x !== pt2.x) {
        var a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
        return {
            a: a,
            b: pt1.y - a * pt1.x,
        };
    }

    return pt1.y === pt2.y
        ? null
        : { x: pt1.x };
}

/**
Return the intersection point of two lines defined by two points each
Return null when there's no unique intersection
*/
function intersection(l1a, l1b, l2a, l2b) {
    var line1 = lineEquation(l1a, l1b);
    var line2 = lineEquation(l2a, l2b);

    if (line1 === null || line2 === null) {
        return null;
    }

    if (line1.hasOwnProperty('x')) {
        return line2.hasOwnProperty('x')
            ? null
            : {
                x: line1.x,
                y: line2.a * line1.x + line2.b,
            };
    }
    if (line2.hasOwnProperty('x')) {
        return {
            x: line2.x,
            y: line1.a * line2.x + line1.b,
        };
    }

    if (line1.a === line2.a) {
        return null;
    }

    var x = (line2.b - line1.b) / (line1.a - line2.a);
    return {
        x: x,
        y: line1.a * x + line1.b,
    };
}

function translatePoint(pt, dist, heading) {
    return {
        x: pt.x + dist * Math.cos(heading),
        y: pt.y + dist * Math.sin(heading),
    };
}

var PolylineOffset = {
    offsetPointLine: function(points, distance) {
        var offsetSegments = [];

        forEachPair(points, L.bind(function(a, b) {
            if (a.x === b.x && a.y === b.y) { return; }

            // angles in (-PI, PI]
            var segmentAngle = Math.atan2(a.y - b.y, a.x - b.x);
            var offsetAngle = segmentAngle - Math.PI/2;

            offsetSegments.push({
                offsetAngle: offsetAngle,
                original: [a, b],
                offset: [
                    translatePoint(a, distance, offsetAngle),
                    translatePoint(b, distance, offsetAngle)
                ]
            });
        }, this));

        return offsetSegments;
    },

    offsetPoints: function(pts, offset) {
        var offsetSegments = this.offsetPointLine(pts, offset);
        return this.joinLineSegments(offsetSegments, offset);
    },

    /**
    Join 2 line segments defined by 2 points each with a circular arc
    */
    joinSegments: function(s1, s2, offset) {
        // TODO: different join styles
        return this.circularArc(s1, s2, offset)
            .filter(function(x) { return x; })
    },

    joinLineSegments: function(segments, offset) {
        var joinedPoints = [];
        var first = segments[0];
        var last = segments[segments.length - 1];

        if (first && last) {
            joinedPoints.push(first.offset[0]);
            forEachPair(segments, L.bind(function(s1, s2) {
                joinedPoints = joinedPoints.concat(this.joinSegments(s1, s2, offset));
            }, this));
            joinedPoints.push(last.offset[1]);
        }

        return joinedPoints;
    },

    segmentAsVector: function(s) {
        return {
            x: s[1].x - s[0].x,
            y: s[1].y - s[0].y,
        };
    },

    getSignedAngle: function(s1, s2) {
        const a = this.segmentAsVector(s1);
        const b = this.segmentAsVector(s2);
        return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
    },

    /**
    Interpolates points between two offset segments in a circular form
    */
    circularArc: function(s1, s2, distance) {
        // if the segments are the same angle,
        // there should be a single join point
        if (s1.offsetAngle === s2.offsetAngle) {
            return [s1.offset[1]];
        }

        const signedAngle = this.getSignedAngle(s1.offset, s2.offset);
        // for inner angles, just find the offset segments intersection
        if ((signedAngle * distance > 0) &&
            (signedAngle * this.getSignedAngle(s1.offset, [s1.offset[0], s2.offset[1]]) > 0)) {
            return [intersection(s1.offset[0], s1.offset[1], s2.offset[0], s2.offset[1])];
        }

        // draws a circular arc with R = offset distance, C = original meeting point
        var points = [];
        var center = s1.original[1];
        // ensure angles go in the anti-clockwise direction
        var rightOffset = distance > 0;
        var startAngle = rightOffset ? s2.offsetAngle : s1.offsetAngle;
        var endAngle = rightOffset ? s1.offsetAngle : s2.offsetAngle;
        // and that the end angle is bigger than the start angle
        if (endAngle < startAngle) {
            endAngle += Math.PI * 2;
        }
        var step = Math.PI / 8;
        for (var alpha = startAngle; alpha < endAngle; alpha += step) {
            points.push(translatePoint(center, distance, alpha));
        }
        points.push(translatePoint(center, distance, endAngle));

        return rightOffset ? points.reverse() : points;
    }
}

// Modify the L.Polyline class by overwriting the projection function
L.Polyline.include({
    _projectLatlngs: function (latlngs, result, projectedBounds) {
        var isFlat = latlngs.length > 0 && latlngs[0] instanceof L.LatLng;

        if (isFlat) {
            var ring = latlngs.map(L.bind(function(ll) {
                var point = this._map.latLngToLayerPoint(ll);
                if (projectedBounds) {
                    projectedBounds.extend(point);
                }
                return point;
            }, this));

            // Offset management hack ---
            if (this.options.offset) {
                ring = L.PolylineOffset.offsetPoints(ring, this.options.offset);
            }
            // Offset management hack END ---

            result.push(ring);
        } else {
            latlngs.forEach(L.bind(function(ll) {
                this._projectLatlngs(ll, result, projectedBounds);
            }, this));
        }
    }
});

L.Polyline.include({
    setOffset: function(offset) {
        this.options.offset = offset;
        this.redraw();
        return this;
    }
});

return PolylineOffset;

}, window));
<commit_msg>Switch early return order<commit_after>(function (factory, window) {
    if (typeof define === 'function' && define.amd) {
        define(['leaflet'], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory(require('leaflet'));
    }
    if (typeof window !== 'undefined' && window.L) {
        window.L.PolylineOffset = factory(L);
    }
}(function (L) {

function forEachPair(list, callback) {
    if (!list || list.length < 1) { return; }
    for (var i = 1, l = list.length; i < l; i++) {
        callback(list[i-1], list[i]);
    }
}

/**
Find the coefficients (a,b) of a line of equation y = a.x + b,
or the constant x for vertical lines
Return null if there's no equation possible
*/
function lineEquation(pt1, pt2) {
    if (pt1.x === pt2.x) {
        return pt1.y === pt2.y ? null : { x: pt1.x };
    }

    var a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
    return {
        a: a,
        b: pt1.y - a * pt1.x,
    };
}

/**
Return the intersection point of two lines defined by two points each
Return null when there's no unique intersection
*/
function intersection(l1a, l1b, l2a, l2b) {
    var line1 = lineEquation(l1a, l1b);
    var line2 = lineEquation(l2a, l2b);

    if (line1 === null || line2 === null) {
        return null;
    }

    if (line1.hasOwnProperty('x')) {
        return line2.hasOwnProperty('x')
            ? null
            : {
                x: line1.x,
                y: line2.a * line1.x + line2.b,
            };
    }
    if (line2.hasOwnProperty('x')) {
        return {
            x: line2.x,
            y: line1.a * line2.x + line1.b,
        };
    }

    if (line1.a === line2.a) {
        return null;
    }

    var x = (line2.b - line1.b) / (line1.a - line2.a);
    return {
        x: x,
        y: line1.a * x + line1.b,
    };
}

function translatePoint(pt, dist, heading) {
    return {
        x: pt.x + dist * Math.cos(heading),
        y: pt.y + dist * Math.sin(heading),
    };
}

var PolylineOffset = {
    offsetPointLine: function(points, distance) {
        var offsetSegments = [];

        forEachPair(points, L.bind(function(a, b) {
            if (a.x === b.x && a.y === b.y) { return; }

            // angles in (-PI, PI]
            var segmentAngle = Math.atan2(a.y - b.y, a.x - b.x);
            var offsetAngle = segmentAngle - Math.PI/2;

            offsetSegments.push({
                offsetAngle: offsetAngle,
                original: [a, b],
                offset: [
                    translatePoint(a, distance, offsetAngle),
                    translatePoint(b, distance, offsetAngle)
                ]
            });
        }, this));

        return offsetSegments;
    },

    offsetPoints: function(pts, offset) {
        var offsetSegments = this.offsetPointLine(pts, offset);
        return this.joinLineSegments(offsetSegments, offset);
    },

    /**
    Join 2 line segments defined by 2 points each with a circular arc
    */
    joinSegments: function(s1, s2, offset) {
        // TODO: different join styles
        return this.circularArc(s1, s2, offset)
            .filter(function(x) { return x; })
    },

    joinLineSegments: function(segments, offset) {
        var joinedPoints = [];
        var first = segments[0];
        var last = segments[segments.length - 1];

        if (first && last) {
            joinedPoints.push(first.offset[0]);
            forEachPair(segments, L.bind(function(s1, s2) {
                joinedPoints = joinedPoints.concat(this.joinSegments(s1, s2, offset));
            }, this));
            joinedPoints.push(last.offset[1]);
        }

        return joinedPoints;
    },

    segmentAsVector: function(s) {
        return {
            x: s[1].x - s[0].x,
            y: s[1].y - s[0].y,
        };
    },

    getSignedAngle: function(s1, s2) {
        const a = this.segmentAsVector(s1);
        const b = this.segmentAsVector(s2);
        return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
    },

    /**
    Interpolates points between two offset segments in a circular form
    */
    circularArc: function(s1, s2, distance) {
        // if the segments are the same angle,
        // there should be a single join point
        if (s1.offsetAngle === s2.offsetAngle) {
            return [s1.offset[1]];
        }

        const signedAngle = this.getSignedAngle(s1.offset, s2.offset);
        // for inner angles, just find the offset segments intersection
        if ((signedAngle * distance > 0) &&
            (signedAngle * this.getSignedAngle(s1.offset, [s1.offset[0], s2.offset[1]]) > 0)) {
            return [intersection(s1.offset[0], s1.offset[1], s2.offset[0], s2.offset[1])];
        }

        // draws a circular arc with R = offset distance, C = original meeting point
        var points = [];
        var center = s1.original[1];
        // ensure angles go in the anti-clockwise direction
        var rightOffset = distance > 0;
        var startAngle = rightOffset ? s2.offsetAngle : s1.offsetAngle;
        var endAngle = rightOffset ? s1.offsetAngle : s2.offsetAngle;
        // and that the end angle is bigger than the start angle
        if (endAngle < startAngle) {
            endAngle += Math.PI * 2;
        }
        var step = Math.PI / 8;
        for (var alpha = startAngle; alpha < endAngle; alpha += step) {
            points.push(translatePoint(center, distance, alpha));
        }
        points.push(translatePoint(center, distance, endAngle));

        return rightOffset ? points.reverse() : points;
    }
}

// Modify the L.Polyline class by overwriting the projection function
L.Polyline.include({
    _projectLatlngs: function (latlngs, result, projectedBounds) {
        var isFlat = latlngs.length > 0 && latlngs[0] instanceof L.LatLng;

        if (isFlat) {
            var ring = latlngs.map(L.bind(function(ll) {
                var point = this._map.latLngToLayerPoint(ll);
                if (projectedBounds) {
                    projectedBounds.extend(point);
                }
                return point;
            }, this));

            // Offset management hack ---
            if (this.options.offset) {
                ring = L.PolylineOffset.offsetPoints(ring, this.options.offset);
            }
            // Offset management hack END ---

            result.push(ring);
        } else {
            latlngs.forEach(L.bind(function(ll) {
                this._projectLatlngs(ll, result, projectedBounds);
            }, this));
        }
    }
});

L.Polyline.include({
    setOffset: function(offset) {
        this.options.offset = offset;
        this.redraw();
        return this;
    }
});

return PolylineOffset;

}, window));
<|endoftext|>


<commit_before>/**
 * Highcharts plugin for adjustable chart height in response to legend height
 *
 * Author:        Torstein Honsi
 * Version:       1.0.7
 * Last revision: 2016-12-15
 */
(function (factory) {
  if (typeof module === 'object' && module.exports) {
    module.exports = factory;
  } else {
    factory(Highcharts);
  }
}(function (Highcharts) {
  (function (H) {
    H.wrap(H.Legend.prototype, 'render', function (proceed) {
      var chart = this.chart,
        translateY,
        addedHeight;

      proceed.call(this);

      if (this.options.adjustChartSize) { // #7

        addedHeight = this.legendHeight;
        if (!chart.originalChartHeight) {
          chart.originalChartHeight = chart.chartHeight;
        }

        if (this.options.align === 'left' || this.options.align === 'right') {
          addedHeight = Math.max(this.group.translateY + this.legendHeight - chart.originalChartHeight, 0);

          // Move the legend down
        } else if (!chart.container.attributes['height-adapted-to-legend'] && this.options.verticalAlign === 'bottom') { // #2
          translateY = this.group.attr('translateY') + this.legendHeight;
          this.group.attr('translateY', translateY);

          chart.container.setAttribute('height-adapted-to-legend', true); // #2

          if (this.group.alignAttr) {
            this.group.alignAttr.translateY = translateY;
          }
        }
        if (addedHeight) {
          //   // Adapt chart metrics
          chart.chartHeight = chart.originalChartHeight + addedHeight;
          chart.marginBottom += addedHeight;

          //   // Set the DOM element heights
          chart.container.style.height = chart.chartHeight + 'px';
          chart.renderer.boxWrapper.attr('height', chart.chartHeight); // #7

          var boxedElement = chart.renderer.box.clientWidth ? chart.renderer.box /*IE*/ : chart.renderer.box.parentElement /*FF*/ ;
          var viewBox = "0 0 " + boxedElement.clientWidth + " " + boxedElement.clientHeight;
          chart.renderer.boxWrapper.attr('viewBox', viewBox);
        }
        this.positionCheckboxes();
      }
    });
  }(Highcharts));
}));<commit_msg>revert antonpod fix, instead align legend to original chart height when verticalAlign == 'bottom'<commit_after>/**
 * Highcharts plugin for adjustable chart height in response to legend height
 *
 * Author:        Torstein Honsi
 * Version:       1.0.7
 * Last revision: 2016-12-15
 */
(function (factory) {
  if (typeof module === 'object' && module.exports) {
    module.exports = factory;
  } else {
    factory(Highcharts);
  }
}(function (Highcharts) {
  (function (H) {
    H.wrap(H.Legend.prototype, 'render', function (proceed) {
      var chart = this.chart,
        translateY,
        addedHeight;

      proceed.call(this);

      if (this.options.adjustChartSize) { // #7

        addedHeight = this.legendHeight;
        if (!chart.originalChartHeight) {
          chart.originalChartHeight = chart.chartHeight;
        }

        if (this.options.align === 'left' || this.options.align === 'right') {
          addedHeight = Math.max(this.group.translateY + this.legendHeight - chart.originalChartHeight, 0);

          // Move the legend down
        } else if (this.options.verticalAlign === 'bottom') {
          translateY = chart.originalChartHeight; // #2
          this.group.attr('translateY', translateY);

          if (this.group.alignAttr) {
            this.group.alignAttr.translateY = translateY;
          }
        }
        if (addedHeight) {
          //   // Adapt chart metrics
          chart.chartHeight = chart.originalChartHeight + addedHeight;
          chart.marginBottom += addedHeight;

          //   // Set the DOM element heights
          chart.container.style.height = chart.chartHeight + 'px';
          chart.renderer.boxWrapper.attr('height', chart.chartHeight); // #7

          var boxedElement = chart.renderer.box.clientWidth ? chart.renderer.box /*IE*/ : chart.renderer.box.parentElement /*FF*/ ;
          var viewBox = "0 0 " + boxedElement.clientWidth + " " + boxedElement.clientHeight;
          chart.renderer.boxWrapper.attr('viewBox', viewBox);
        }
        this.positionCheckboxes();
      }
    });
  }(Highcharts));
}));<|endoftext|>


<commit_before>var AjaxAdapter = function(config) {

  // writeGraph
  // --------------

  // Takes a Data.Graph and calls a webservice to persist it

  self.writeGraph = function(graph, callback) {
    $.ajax({
      type: "PUT",
      url: "/writegraph",
      data: JSON.stringify(graph),
      contentType: "application/json",
      success: function(status) {
        callback(null);
      },
      error: function(err) {
       callback(err);
      }
    });
  };

  // readGraph
  // --------------

  // Takes a query object and reads all matching nodes
  // If you'd like to make a deep fetch, you just need to specify
  // expand: true in the options hash

  self.readGraph = function(qry, targetGraph, options, callback) {
    $.ajax({
      type: "GET",
      url: config.url+"readgraph",
      data: {
        qry: JSON.stringify(qry),
        options: JSON.stringify(options)
      },
      dataType: "jsonp",
      success: function(graph) {
        callback(null, graph);
      },
      error: function(err) {
       callback(err);
      }
    });
  };

  // Expose Public API
  return self;
};
<commit_msg>Default config for AjaxAdapter.<commit_after>var AjaxAdapter = function(config) {

  config = config ? config : {url: '/'};

  // writeGraph
  // --------------

  // Takes a Data.Graph and calls a webservice to persist it

  self.writeGraph = function(graph, callback) {
    $.ajax({
      type: "PUT",
      url: "/writegraph",
      data: JSON.stringify(graph),
      contentType: "application/json",
      success: function(status) {
        callback(null);
      },
      error: function(err) {
       callback(err);
      }
    });
  };

  // readGraph
  // --------------

  // Takes a query object and reads all matching nodes
  // If you'd like to make a deep fetch, you just need to specify
  // expand: true in the options hash

  self.readGraph = function(qry, targetGraph, options, callback) {
    $.ajax({
      type: "GET",
      url: config.url+"readgraph",
      data: {
        qry: JSON.stringify(qry),
        options: JSON.stringify(options)
      },
      dataType: "jsonp",
      success: function(graph) {
        callback(null, graph);
      },
      error: function(err) {
       callback(err);
      }
    });
  };

  // Expose Public API
  return self;
};
<|endoftext|>


<commit_before>/*
  This module is intended to encapsulate all the known places where
  liquid-fire depends on non-public Ember APIs.
*/

import Ember from "ember";
var get = Ember.get;

// Given an Ember.View, return the containing element
export function containingElement(view) {
  return view._morph.contextualElement;
}

// Create a helper that wraps one of our components. We mostly do this
// just to get position-argument syntax.
export function makeHelperShim(componentName, tweak) {
  return {
    isHTMLBars: true,
    helperFunction: function liquidFireHelper(params, hash, options, env) {
      var view = env.data.view;
      var componentLookup = view.container.lookup('component-lookup:main');
      var cls = componentLookup.lookupFactory(componentName);
      hash.value = params[0];
      if (hash['class']) {
        hash.innerClass = hash['class'];
        delete hash['class'];
      }
      if (hash.id) {
        hash.innerId = hash.id;
        delete hash.id;
      }
      hash.tagName = "";
      if (tweak) {
        tweak(params, hash, options, env);
      }
      env.helpers.view.helperFunction.call(view, [cls], hash, options, env);
    }
  };
}

// We use this as {{lf-yield-inverse}} to yield to our inverse
// template, for the {{else}} case in liquid-if and liquid-unless.
export function inverseYieldHelper(params, hash, options, env) {
  var view = env.data.view;

  while (view && !get(view, 'layout')) {
    if (view._contextView) {
      view = view._contextView;
    } else {
      view = view._parentView;
    }
  }

  return view._yieldInverse(env.data.view, env, options.morph, params);
}

// We add this method to our components to help implement lf-inverse-yield.
export function inverseYieldMethod(context, options, morph, blockArguments) {
  var view = options.data.view;
  var parentView = this._parentView;
  var template = get(this, 'inverseTemplate');

  if (template) {
    view.appendChild(Ember.View, {
      isVirtual: true,
      tagName: '',
      template: template,
      _blockArguments: blockArguments,
      _contextView: parentView,
      _morph: morph,
      context: get(parentView, 'context'),
      controller: get(parentView, 'controller')
    });
  }
}

// This lets us hook into the outlet state.
export var OutletBehavior = {
  _isOutlet: true,

  setOutletState: function(state) {
    if (state.render && state.render.controller && !state._lf_model) {
      // This is a hack to compensate for Ember 1.0's remaining use of
      // mutability within the route state -- the controller is a
      // singleton whose model will keep changing on us. By locking it
      // down the first time we see the state, we can more closely
      // emulate ember 2.0 semantics.
      //
      // The Ember 2.0 component attributes shouldn't suffer this
      // problem and we can eventually drop the hack.
      state._lf_model = get(state.render.controller, 'model');
    }
    this.set('outletState', state);
  },

  _parentOutlet: function() {
    var parent = this._parentView;
    while (parent && !parent._isOutlet) {
      parent = parent._parentView;
    }
    return parent;
  },

  _linkParent: Ember.on('init', 'parentViewDidChange', function() {
    var parent = this._parentOutlet();
    if (parent) {
      this._parentOutletLink = parent;
      parent._childOutlets.push(this);
      if (parent._outletState && parent._outletState.outlets[this._outletName]) {
        this.setOutletState(parent._outletState.outlets[this._outletName]);
      }
    }
  }),

  willDestroy: function() {
    if (this._parentOutletLink) {
      this._parentOutletLink._childOutlets.removeObject(this);
    }
    this._super();
  }
};

// This lets us invoke an outlet with an explicitly passed outlet
// state, rather than inheriting it implicitly from its context.
export var StaticOutlet = Ember.OutletView.superclass.extend({
  tagName: '',

  // Disable normal outletstate propagation
  _parentOutlet: function() {},

  setStaticState: Ember.on('init', Ember.observer('staticState', function() {
    this.setOutletState(this.get('staticState'));
  }))
});

// Finds the route name from a route state so we can apply our
// matching rules to it.
export function routeName(routeState) {
  if (routeState && routeState.render) {
    return [routeState.render.name];
  }
}

// Finds the route's model from a route state so we can apply our
// matching rules to it.
export function routeModel(routeState) {
  if (routeState) {
    return [routeState._lf_model];
  }
}
<commit_msg>fix nested liquid-outlet stability<commit_after>/*
  This module is intended to encapsulate all the known places where
  liquid-fire depends on non-public Ember APIs.
*/

import Ember from "ember";
var get = Ember.get;
var set = Ember.set;

// Given an Ember.View, return the containing element
export function containingElement(view) {
  return view._morph.contextualElement;
}

// Create a helper that wraps one of our components. We mostly do this
// just to get position-argument syntax.
export function makeHelperShim(componentName, tweak) {
  return {
    isHTMLBars: true,
    helperFunction: function liquidFireHelper(params, hash, options, env) {
      var view = env.data.view;
      var componentLookup = view.container.lookup('component-lookup:main');
      var cls = componentLookup.lookupFactory(componentName);
      hash.value = params[0];
      if (hash['class']) {
        hash.innerClass = hash['class'];
        delete hash['class'];
      }
      if (hash.id) {
        hash.innerId = hash.id;
        delete hash.id;
      }
      hash.tagName = "";
      if (tweak) {
        tweak(params, hash, options, env);
      }
      env.helpers.view.helperFunction.call(view, [cls], hash, options, env);
    }
  };
}

// We use this as {{lf-yield-inverse}} to yield to our inverse
// template, for the {{else}} case in liquid-if and liquid-unless.
export function inverseYieldHelper(params, hash, options, env) {
  var view = env.data.view;

  while (view && !get(view, 'layout')) {
    if (view._contextView) {
      view = view._contextView;
    } else {
      view = view._parentView;
    }
  }

  return view._yieldInverse(env.data.view, env, options.morph, params);
}

// We add this method to our components to help implement lf-inverse-yield.
export function inverseYieldMethod(context, options, morph, blockArguments) {
  var view = options.data.view;
  var parentView = this._parentView;
  var template = get(this, 'inverseTemplate');

  if (template) {
    view.appendChild(Ember.View, {
      isVirtual: true,
      tagName: '',
      template: template,
      _blockArguments: blockArguments,
      _contextView: parentView,
      _morph: morph,
      context: get(parentView, 'context'),
      controller: get(parentView, 'controller')
    });
  }
}

// This lets us hook into the outlet state.
export var OutletBehavior = {
  _isOutlet: true,

  init: function() {
    this._super();
    this._childOutlets = [];

    // Our outlet state is named differently than a normal ember
    // outlet ("_outletState"), so that our child outlets don't
    // automatically discover it. Instead we will always push state
    // down to them, so we can version it as we wish.
    this.outletState = null;
  },

  setOutletState: function(state) {
    if (state.render && state.render.controller && !state._lf_model) {
      // This is a hack to compensate for Ember 1.0's remaining use of
      // mutability within the route state -- the controller is a
      // singleton whose model will keep changing on us. By locking it
      // down the first time we see the state, we can more closely
      // emulate ember 2.0 semantics.
      //
      // The Ember 2.0 component attributes shouldn't suffer this
      // problem and we can eventually drop the hack.
      state._lf_model = get(state.render.controller, 'model');
    }

    if (!this._diffState(state)) {
      var children = this._childOutlets;
      for (var i = 0 ; i < children.length; i++) {
        var child = children[i];
        child.setOutletState(state);
      }

    }
  },

  _diffState: function(state) {
    while (state && emptyRouteState(state)) {
      state = state.outlets.main;
    }
    var different = !sameRouteState(this.outletState, state);

    if (different) {
      set(this, 'outletState', state);
    }

    return different;
  },

  _parentOutlet: function() {
    var parent = this._parentView;
    while (parent && !parent._isOutlet) {
      parent = parent._parentView;
    }
    return parent;
  },

  _linkParent: Ember.on('init', 'parentViewDidChange', function() {
    var parent = this._parentOutlet();
    if (parent) {
      this._parentOutletLink = parent;
      parent._childOutlets.push(this);
      if (parent._outletState && parent._outletState.outlets[this._outletName]) {
        this.setOutletState(parent._outletState.outlets[this._outletName]);
      }
    }
  }),

  willDestroy: function() {
    if (this._parentOutletLink) {
      this._parentOutletLink._childOutlets.removeObject(this);
    }
    this._super();
  }
};

function emptyRouteState(state) {
  return !state.render.ViewClass && !state.render.template;
}

function sameRouteState(a, b) {
  if (!a && !b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  a = a.render;
  b = b.render;
  for (var key in a) {
    if (a.hasOwnProperty(key)) {
      // name is only here for logging & debugging. If two different
      // names result in otherwise identical states, they're still
      // identical.
      if (a[key] !== b[key] && key !== 'name') {
        return false;
      }
    }
  }
  return true;
}

// This lets us invoke an outlet with an explicitly passed outlet
// state, rather than inheriting it implicitly from its context.
export var StaticOutlet = Ember.OutletView.superclass.extend({
  tagName: '',

  setStaticState: Ember.on('init', Ember.observer('staticState', function() {
    this.setOutletState(this.get('staticState'));
  }))
});

// Finds the route name from a route state so we can apply our
// matching rules to it.
export function routeName(routeState) {
  if (routeState && routeState.render) {
    return [routeState.render.name];
  }
}

// Finds the route's model from a route state so we can apply our
// matching rules to it.
export function routeModel(routeState) {
  if (routeState) {
    return [routeState._lf_model];
  }
}
<|endoftext|>


<commit_before>import Ember from 'ember';
import { keys } from 'ember-pusher/compat';

// Need to track
// 1) channel object
// 2) event bindings which consist of
//    - handler
//    - event name
//    - a unique string representing the target
//
//  bindings: {
//    'channel-one': {
//      channel: Pusher.Channel,
//      eventBindings: {
//        Ember.Route.toString(): [
//          { handler: Function, eventName: String },
//          { handler: Function, eventName: String }
//        ]
//      }
//    }
//  }
//
//  wire(target, channelName, events)
//  ================
//  Initialize object in bindings if it's empty, with eventBindings: {}
//  If eventBindings.length for the current target is 0
//    connect to the channel
//    store channel in the hash
//  For each event in events
//    bind the channel to the eventName
//    store the handler and eventName in the eventBindings array for this channel and controller
//    the key for storing is in target._pusherTargetId()
//    (we store the eventName for when we might want to programmatically unwire)
//
//
//  unwire(route):
//  =================
//  get the channel object
//  for each  handler, eventName in eventBindings for the current route
//    call channel.unbind(eventName, handler)
//  delete the routes record in EventBindings
//  if eventBindings for this channel is empty
//    unsubscribe from the channel
//    delete the channel from bindings

export default Ember.Service.extend({
  isDisconnected: true,
  isConnected: Ember.computed.not('isDisconnected'),

  init() {
    this.pusher = null;
    this.set('bindings', {});
    this.logEvents = false;
  },

  setup(applicationKey, options) {
    Ember.assert("ember-pusher can only be setup once", !this.pusher);
    Ember.assert("You need to include the pusher libraries", !!window.Pusher);

    this.pusher = new window.Pusher(applicationKey, options);
    this.pusher.connection.bind('connected', this._didConnect.bind(this));
    this.pusher.connection.bind('disconnected', this._didDisconnect.bind(this));
    this.pusher.connection.bind('unavailable', this._didDisconnect.bind(this));
  },

  willDestroy() {
    if (this.pusher) {
      this.pusher.disconnect();
    }
  },

  // @events a hash in the form { channel-name: ['event1', 'event2'] }
  // @target any object that responds to send() and _pusherEventsId()
  wire(target, channelName, events) {
    Ember.assert("Did you forget to extend the EmberPusher.Bindings mixin in " +
        "your class receiving events?", !!target._pusherEventsId);

    let channel = this.connectChannel(channelName),
        bindings = this.get('bindings'),
        targetId = target._pusherEventsId();

    if(typeof events === 'string') {
      events = [events];
    }

    // Setup the eventBindings array for this target
    if (!bindings[channelName].eventBindings[targetId]) {
      bindings[channelName].eventBindings[targetId] = [];
    }

    // Iterate over the events and bind them
    events.forEach(eventName => {
      let normalizedEventName = Ember.String.camelize(eventName);
      let events = bindings[channelName].eventBindings[targetId];
      let found;
      let handler = function(data) {
        if (target.get('logPusherEvents')) {
          console.log(target.constructor.toString() +
            ": Pusher event received", eventName, data);
        }
        Ember.run(() => {
          target.send(normalizedEventName, data);
        });
      };

      channel.bind(eventName, handler);

      if(found = events.findBy('eventName', eventName)) {
        found.handler = handler;
      }
      else {
        events.pushObject({
          handler: handler,
          eventName: eventName,
          target: target
        });
      }
    });
  },

  connectChannel(channelName) {
    let pusher = this.pusher,
        bindings = this.get('bindings');

    if (!bindings[channelName]) {
      bindings[channelName] = { eventBindings: {} };
    }

    if (Ember.isEmpty(keys(bindings[channelName].eventBindings))) {
      bindings[channelName].channel = pusher.subscribe(channelName);

      // Spit out a bunch of logging if asked
      if (this.namespace && this.logEvents) {
        bindings[channelName].channel.bind_all((eventName, data) => {
          console.log(
            "Pusher event received on " + channelName + ":",
            eventName,
            data
          );
        });
      }
    }
    return bindings[channelName].channel;
  },

  unwire(target, channelName) {
    let pusher = this.pusher,
        bindings = this.get('bindings'),
        targetId = target._pusherEventsId(),
        channel = bindings[channelName].channel;

    if(typeof eventsToUnwire === 'string') {
      eventsToUnwire = [eventsToUnwire];
    }

    // Unbind all the events for this target
    for (let binding in bindings[channelName].eventBindings[targetId]) {
      channel.unbind(binding.eventName, binding.handler);
    }
    delete bindings[channelName].eventBindings[targetId];

    // Unsubscribe from the channel if this is the last thing listening
    if (keys(bindings[channelName].eventBindings).length === 0) {
      pusher.unsubscribe(channelName);
      delete bindings[channelName];
      return true;
    }
    return false;
  },

  channelFor(channelName) {
    return this.get('bindings')[channelName].channel;
  },

  socketId: Ember.computed('isDisconnected', function() {
    try {
      return this.pusher.connection.socket_id;
    }
    catch(error) {
      console.warn(error);
    }
  }),

  _didConnect() {
    this.set('isDisconnected', false);
  },

  _didDisconnect() {
    this.set('isDisconnected', true);
  }
});
<commit_msg>Allow unwire() of a selection of events rather than all events on a channel/target<commit_after>import Ember from 'ember';
import { keys } from 'ember-pusher/compat';

// Need to track
// 1) channel object
// 2) event bindings which consist of
//    - handler
//    - event name
//    - a unique string representing the target
//
//  bindings: {
//    'channel-one': {
//      channel: Pusher.Channel,
//      eventBindings: {
//        Ember.Route.toString(): [
//          { handler: Function, eventName: String },
//          { handler: Function, eventName: String }
//        ]
//      }
//    }
//  }
//
//  wire(target, channelName, events)
//  ================
//  Initialize object in bindings if it's empty, with eventBindings: {}
//  If eventBindings.length for the current target is 0
//    connect to the channel
//    store channel in the hash
//  For each event in events
//    bind the channel to the eventName
//    store the handler and eventName in the eventBindings array for this channel and controller
//    the key for storing is in target._pusherTargetId()
//    (we store the eventName for when we might want to programmatically unwire)
//
//
//  unwire(route):
//  =================
//  get the channel object
//  for each  handler, eventName in eventBindings for the current route
//    call channel.unbind(eventName, handler)
//  delete the routes record in EventBindings
//  if eventBindings for this channel is empty
//    unsubscribe from the channel
//    delete the channel from bindings

export default Ember.Service.extend({
  isDisconnected: true,
  isConnected: Ember.computed.not('isDisconnected'),

  init() {
    this.pusher = null;
    this.set('bindings', {});
    this.logEvents = false;
  },

  setup(applicationKey, options) {
    Ember.assert("ember-pusher can only be setup once", !this.pusher);
    Ember.assert("You need to include the pusher libraries", !!window.Pusher);

    this.pusher = new window.Pusher(applicationKey, options);
    this.pusher.connection.bind('connected', this._didConnect.bind(this));
    this.pusher.connection.bind('disconnected', this._didDisconnect.bind(this));
    this.pusher.connection.bind('unavailable', this._didDisconnect.bind(this));
  },

  willDestroy() {
    if (this.pusher) {
      this.pusher.disconnect();
    }
  },

  // @events a hash in the form { channel-name: ['event1', 'event2'] }
  // @target any object that responds to send() and _pusherEventsId()
  wire(target, channelName, events) {
    Ember.assert("Did you forget to extend the EmberPusher.Bindings mixin in " +
        "your class receiving events?", !!target._pusherEventsId);

    let channel = this.connectChannel(channelName),
        bindings = this.get('bindings'),
        targetId = target._pusherEventsId();

    if(typeof events === 'string') {
      events = [events];
    }

    // Setup the eventBindings array for this target
    if (!bindings[channelName].eventBindings[targetId]) {
      bindings[channelName].eventBindings[targetId] = [];
    }

    // Iterate over the events and bind them
    events.forEach(eventName => {
      let normalizedEventName = Ember.String.camelize(eventName);
      let events = bindings[channelName].eventBindings[targetId];
      let found;
      let handler = function(data) {
        if (target.get('logPusherEvents')) {
          console.log(target.constructor.toString() +
            ": Pusher event received", eventName, data);
        }
        Ember.run(() => {
          target.send(normalizedEventName, data);
        });
      };

      channel.bind(eventName, handler);

      if(found = events.findBy('eventName', eventName)) {
        found.handler = handler;
      }
      else {
        events.pushObject({
          handler: handler,
          eventName: eventName,
          target: target
        });
      }
    });
  },

  connectChannel(channelName) {
    let pusher = this.pusher,
        bindings = this.get('bindings');

    if (!bindings[channelName]) {
      bindings[channelName] = { eventBindings: {} };
    }

    if (Ember.isEmpty(keys(bindings[channelName].eventBindings))) {
      bindings[channelName].channel = pusher.subscribe(channelName);

      // Spit out a bunch of logging if asked
      if (this.namespace && this.logEvents) {
        bindings[channelName].channel.bind_all((eventName, data) => {
          console.log(
            "Pusher event received on " + channelName + ":",
            eventName,
            data
          );
        });
      }
    }
    return bindings[channelName].channel;
  },

  unwire(target, channelName) {
    let pusher = this.pusher,
        bindings = this.get('bindings'),
        targetId = target._pusherEventsId(),
        channel = bindings[channelName].channel;

    if(typeof eventsToUnwire === 'string') {
      eventsToUnwire = [eventsToUnwire];
    }

    eventBindings.forEach((binding, index) => {
      if(eventsToUnwire && !eventsToUnwire.contains(binding.eventName)) {
        return;
      }
      channel.unbind(binding.eventName, binding.handler);
      eventBindings.splice(index, 1);
    });

    if (Ember.isEmpty(eventBindings)) {
      delete bindings[channelName].eventBindings[targetId];
    }

    // Unsubscribe from the channel if this is the last thing listening
    if (keys(bindings[channelName].eventBindings).length === 0) {
      pusher.unsubscribe(channelName);
      delete bindings[channelName];
      return true;
    }
    return false;
  },

  channelFor(channelName) {
    return this.get('bindings')[channelName].channel;
  },

  socketId: Ember.computed('isDisconnected', function() {
    try {
      return this.pusher.connection.socket_id;
    }
    catch(error) {
      console.warn(error);
    }
  }),

  _didConnect() {
    this.set('isDisconnected', false);
  },

  _didDisconnect() {
    this.set('isDisconnected', true);
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import config from 'ember-get-config';

const { get } = Ember;

export default get(config, 'emberHook.delimiter') || '&^%^&';
<commit_msg>allow empty delimiters<commit_after>import Ember from 'ember';
import config from 'ember-get-config';

const { get } = Ember;

let delimiter = get(config, 'emberHook.delimiter');

if (typeof delimiter === 'undefined') {
  delimiter = '&^%^&';
}

export default delimiter;
<|endoftext|>


<commit_before>$(document).ready(function() {
    $(".content").load("lib/overview.php");

    $(".loader li").click(function() {
        if ($(this).data("page") === "site") {
            location.href = "../";
        } else if ($(this).data("page") === "logout") {
            location.href = "?page=logout";
        } else {
            $(".content").load("lib/" + $(this).data("page") + ".php");
            $(".loader li").removeClass("active");
            $(this).addClass("active");
        }
    });

    $(document).on("click", ".editor", function(e) {
        e.preventDefault();
        $(".content").load("lib/edit.php?id=" + $(this).data("id"));
    });

    $(document).on("click", ".clicker", function() {
        $(this).parent().children(".reveal").slideToggle();
        $(this).children("h4").children("i").toggleClass("fa-arrow-down fa-arrow-right");
    });

    $(document).on("submit", "form", function(e) {
        e.preventDefault();
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            type: form.attr("method"),
            data: form.serialize(),
            success: function(data) {
                $("#response").html(data).css("opacity", "1");
            }
        });
    });

    $(document).on("click", ".post-deleter", function(e) {
        var node = this;
        e.preventDefault();
        $.get($(this).attr("href"), null, function(success) {
            $(node).siblings(".delete-response").html(success).css("opacity", 1);
        });
    });

    $(".login form").submit(function (e) {
        e.preventDefault();
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            type: form.attr("method"),
            data: form.serialize(),
            success: function(data) {
                $("#response").html(data).css("opacity", "1");
                if(data == "Success!") {
                    location.reload();
                }
            }
        });
    });
});
<commit_msg>Removing posts now slides up instead of page reload<commit_after>$(document).ready(function() {
    $(".content").load("lib/overview.php");

    $(".loader li").click(function() {
        if ($(this).data("page") === "site") {
            location.href = "../";
        } else if ($(this).data("page") === "logout") {
            location.href = "?page=logout";
        } else {
            $(".content").load("lib/" + $(this).data("page") + ".php");
            $(".loader li").removeClass("active");
            $(this).addClass("active");
        }
    });

    $(document).on("click", ".editor", function(e) {
        e.preventDefault();
        $(".content").load("lib/edit.php?id=" + $(this).data("id"));
    });

    $(document).on("click", ".clicker", function() {
        $(this).parent().children(".reveal").slideToggle();
        $(this).children("h4").children("i").toggleClass("fa-arrow-down fa-arrow-right");
    });

    $(document).on("submit", "form", function(e) {
        e.preventDefault();
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            type: form.attr("method"),
            data: form.serialize(),
            success: function(data) {
                $("#response").html(data).css("opacity", "1");
            }
        });
    });

    $(document).on("click", ".post-deleter", function(e) {
        var node = this;
        e.preventDefault();
        $.get($(this).attr("href"), null, function(success) {
            $(node).parent("article").slideUp();
        });
    });

    $(".login form").submit(function (e) {
        e.preventDefault();
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            type: form.attr("method"),
            data: form.serialize(),
            success: function(data) {
                $("#response").html(data).css("opacity", "1");
                if(data == "Success!") {
                    location.reload();
                }
            }
        });
    });
});
<|endoftext|>


<commit_before>const Pulse = require('./adt-pulse.js');
const mqtt = require('mqtt');
var config = require('/data/options.json');

var myAlarm = new Pulse(config.pulse_login.username, config.pulse_login.password);

var client = new mqtt.connect("mqtt://"+config.mqtt_host,config.mqtt_connect_options);
var alarm_state_topic = config.alarm_state_topic;
var alarm_command_topic = config.alarm_command_topic;
var zone_state_topic = config.zone_state_topic;
var smartthings_topic = config.smartthings_topic;
var smartthings = config.smartthings;

var alarm_last_state = "unknown";
var devices = {};

client.on('connect', function () {
  console.log("MQTT Sub to: "+alarm_command_topic);
  client.subscribe(alarm_command_topic)
});

client.on('message', function (topic, message) {
  console.log("Received Message" + topic + ":"+message);
  if (topic!=alarm_command_topic){
    return;
  }

  var msg = message.toString();
  var action;
  var prev_state="disarmed";

  //changing states when the alarm is on, is not tested.
  if(alarm_last_state=="armed_home") prev_state = "stay";
  if(alarm_last_state=="armed_away") prev_state = "away";

  if (msg =="arm_home"){
      action= {'newstate':'stay','prev_state':prev_state};
  }
  else if (msg ="disarm") {
     action= {'newstate':'disarm','prev_state':prev_state};
  }
  else if (msg ="arm_away") { //corrected mis-spelling of action variable
    action= {'newstate':'away','prev_state':prev_state};
  }
  myAlarm.setAlarmState(action);
});

// Register Callbacks:
myAlarm.onDeviceUpdate(
    function(device) {
        console.log("Device callback"+ JSON.stringify(device));
    }
);

myAlarm.onStatusUpdate(
  function(device) {
      var mqtt_state = "unknown";
      var sm_alarm_value = "off";

      var status = device.status.toLowerCase();

      // smartthings bridge has no typical alarm decice with stay|away|alarm|home status.
      // we'll re-use the "alarm" and map strobe|siren|both|off to stay|away|alarm|home
      // Sorry I'm too lazy to write my own smartthngs bridge for now.

      if (status.includes('disarmed')) {
          mqtt_state = "disarmed";
          sm_alarm_value = "off";
      }
      if (status.includes('armed stay')) {
          mqtt_state = "armed_home";
          sm_alarm_value = "strobe";
      }
      if (status.includes('armed away')) {
          mqtt_state = "armed_away";
          sm_alarm_value = "siren";
      }
      if (status.includes('alarm')) {
          mqtt_state = "triggered";
          sm_alarm_value = "both";
      }
      if (status.includes('arming')) {
          mqtt_state = "pending";
          sm_alarm_value = "siren"; // temporary
      }

      if (!mqtt_state.includes(alarm_last_state) && !mqtt_state.includes('unknown')) {
         console.log((new Date()).toLocaleString()+": Pushing alarm state: "+mqtt_state+" to "+alarm_state_topic);
         client.publish(alarm_state_topic, mqtt_state,{"retain":true});
         if (smartthings){
           var sm_alarm_topic = smartthings_topic+"/ADT Alarm System/alarm/cmd";
           console.log((new Date()).toLocaleString()+": Pushing alarm state to smartthings"+sm_alarm_topic);
           client.publish(sm_alarm_topic, sm_alarm_value,{"retain":false});
         }
		  alarm_last_state = mqtt_state;
      }
  }
);

myAlarm.onZoneUpdate(
  function(device) {

    var dev_zone_state_topic = zone_state_topic+"/"+device.name+"/state";
    var devValue = JSON.stringify(device);
    var sm_dev_zone_state_topic;

    // smartthings bridge assumes actionable devices have a topic set with cmd
    // adt/zone/DEVICE_NAME/state needs to turn Macintosh
    // smartthings/DEVICE_NAME/door/cmd
    // or
    // smartthings/DEVICE_NAME/motion/cmd

    if (smartthings){
      var contactType = "door";
      var contactValue= (device.status == "devStatOK")? "closed":"open";

      if (device.tags.includes("motion")) {
        contactType="motion";
        contactValue = (device.status == "devStatOK")? "inactive":"active";
      }
       sm_dev_zone_state_topic=smartthings_topic+"/"+device.name+"/"+contactType+"/cmd";
    }

    if (devices[device.id]==null || device.activityTs!=devices[device.id].activityTs){
        client.publish(dev_zone_state_topic, devValue, {"retain":false});
        console.log((new Date()).toLocaleString()+": Pushing  "+dev_zone_state_topic+" to "+devValue);

        if (smartthings){
          client.publish(sm_dev_zone_state_topic, contactValue, {"retain":false});
          console.log((new Date()).toLocaleString()+": Pushing to smartthings: "+sm_dev_zone_state_topic+" to "+contactValue);
        }
	  }
      devices[device.id] = device;
  }
);

myAlarm.pulse();
<commit_msg>Update server.js (#2)<commit_after>const Pulse = require('./adt-pulse.js');
const mqtt = require('mqtt');
var config = require('/data/options.json');

var myAlarm = new Pulse(config.pulse_login.username, config.pulse_login.password);

var client = new mqtt.connect("mqtt://"+config.mqtt_host,config.mqtt_connect_options);
var alarm_state_topic = config.alarm_state_topic;
var alarm_command_topic = config.alarm_command_topic;
var zone_state_topic = config.zone_state_topic;
var smartthings_topic = config.smartthings_topic;
var smartthings = config.smartthings;

var alarm_last_state = "unknown";
var devices = {};

client.on('connect', function () {
  console.log("MQTT Sub to: "+alarm_command_topic);
  client.subscribe(alarm_command_topic)
});

client.on('message', function (topic, message) {
  console.log("Received Message" + topic + ":"+message);
  if (topic!=alarm_command_topic){
    return;
  }

  var msg = message.toString();
  var action;
  var prev_state="disarmed";

  //changing states when the alarm is on, is not tested.
  if(alarm_last_state=="armed_home") prev_state = "stay";
  if(alarm_last_state=="armed_away") prev_state = "away";

  if (msg =="arm_home"){
      action= {'newstate':'stay','prev_state':prev_state};
  }
  else if (msg =="disarm") {
     action= {'newstate':'disarm','prev_state':prev_state};
  }
  else if (msg =="arm_away") {
    action= {'newstate':'away','prev_state':prev_state};
  }
  myAlarm.setAlarmState(action);
});

// Register Callbacks:
myAlarm.onDeviceUpdate(
    function(device) {
        console.log("Device callback"+ JSON.stringify(device));
    }
);

myAlarm.onStatusUpdate(
  function(device) {
      var mqtt_state = "unknown";
      var sm_alarm_value = "off";

      var status = device.status.toLowerCase();

      // smartthings bridge has no typical alarm decice with stay|away|alarm|home status.
      // we'll re-use the "alarm" and map strobe|siren|both|off to stay|away|alarm|home
      // Sorry I'm too lazy to write my own smartthngs bridge for now.

      if (status.includes('disarmed')) {
          mqtt_state = "disarmed";
          sm_alarm_value = "off";
      }
      if (status.includes('armed stay')) {
          mqtt_state = "armed_home";
          sm_alarm_value = "strobe";
      }
      if (status.includes('armed away')) {
          mqtt_state = "armed_away";
          sm_alarm_value = "siren";
      }
      if (status.includes('alarm')) {
          mqtt_state = "triggered";
          sm_alarm_value = "both";
      }
      if (status.includes('arming')) {
          mqtt_state = "pending";
          sm_alarm_value = "siren"; // temporary
      }

      if (!mqtt_state.includes(alarm_last_state) && !mqtt_state.includes('unknown')) {
         console.log((new Date()).toLocaleString()+": Pushing alarm state: "+mqtt_state+" to "+alarm_state_topic);
         client.publish(alarm_state_topic, mqtt_state,{"retain":true});
         if (smartthings){
           var sm_alarm_topic = smartthings_topic+"/ADT Alarm System/alarm/cmd";
           console.log((new Date()).toLocaleString()+": Pushing alarm state to smartthings"+sm_alarm_topic);
           client.publish(sm_alarm_topic, sm_alarm_value,{"retain":false});
         }
		  alarm_last_state = mqtt_state;
      }
  }
);

myAlarm.onZoneUpdate(
  function(device) {

    var dev_zone_state_topic = zone_state_topic+"/"+device.name+"/state";
    var devValue = JSON.stringify(device);
    var sm_dev_zone_state_topic;

    // smartthings bridge assumes actionable devices have a topic set with cmd
    // adt/zone/DEVICE_NAME/state needs to turn Macintosh
    // smartthings/DEVICE_NAME/door/cmd
    // or
    // smartthings/DEVICE_NAME/motion/cmd

    if (smartthings){
      var contactType = "door";
      var contactValue= (device.status == "devStatOK")? "closed":"open";

      if (device.tags.includes("motion")) {
        contactType="motion";
        contactValue = (device.status == "devStatOK")? "inactive":"active";
      }
       sm_dev_zone_state_topic=smartthings_topic+"/"+device.name+"/"+contactType+"/cmd";
    }

    if (devices[device.id]==null || device.activityTs!=devices[device.id].activityTs){
        client.publish(dev_zone_state_topic, devValue, {"retain":false});
        console.log((new Date()).toLocaleString()+": Pushing  "+dev_zone_state_topic+" to "+devValue);

        if (smartthings){
          client.publish(sm_dev_zone_state_topic, contactValue, {"retain":false});
          console.log((new Date()).toLocaleString()+": Pushing to smartthings: "+sm_dev_zone_state_topic+" to "+contactValue);
        }
	  }
      devices[device.id] = device;
  }
);

myAlarm.pulse();
<|endoftext|>