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

/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
*/

var exec  = require('./exec'),
    Q     = require('q'),
    path  = require('path'),
    build = require('./build'),
    appinfo = require('./appinfo'),
    ROOT = path.join(__dirname, '..', '..');

/**
 * Returns a promise for the list of the device ID's found
 */
module.exports.list = function() {
    return exec('adb devices')
    .then(function(output) {
        var response = output.split('\n');
        var device_list = [];
        for (var i = 1; i < response.length; i++) {
            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
            }
        }
        return device_list;
    });
}

/*
 * Installs a previously built application on the device
 * and launches it.
 * Returns a promise.
 */
module.exports.install = function(target) {
    var launchName;
    return this.list()
    .then(function(device_list) {
        if (!device_list || !device_list.length)
            return Q.reject('ERROR: Failed to deploy to device, no devices found.');

        // default device
        target = typeof target !== 'undefined' ? target : device_list[0];

        if (device_list.indexOf(target) < 0)
            return Q.reject('ERROR: Unable to find target \'' + target + '\'.');

        var apk_path = build.get_apk();
        launchName = appinfo.getActivityName();
        console.log('Installing app on device...');
        var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
        return exec(cmd);
    }).then(function(output) {
        if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output);

        //unlock screen
        var cmd = 'adb -s ' + target + ' shell input keyevent 82';
        return exec(cmd);
    }, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); })
    .then(function() {
        // launch the application
        console.log('Launching application...');
        var cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
        return exec(cmd);
    }).then(function() {
        console.log('LANCH SUCCESS');
    }, function(err) {
        return Q.reject('ERROR: Failed to launch application on device: ' + err);
    });
}
<commit_msg>Fix type "LANCH" -> "LAUNCH"<commit_after>#!/usr/bin/env node

/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
*/

var exec  = require('./exec'),
    Q     = require('q'),
    path  = require('path'),
    build = require('./build'),
    appinfo = require('./appinfo'),
    ROOT = path.join(__dirname, '..', '..');

/**
 * Returns a promise for the list of the device ID's found
 */
module.exports.list = function() {
    return exec('adb devices')
    .then(function(output) {
        var response = output.split('\n');
        var device_list = [];
        for (var i = 1; i < response.length; i++) {
            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
            }
        }
        return device_list;
    });
}

/*
 * Installs a previously built application on the device
 * and launches it.
 * Returns a promise.
 */
module.exports.install = function(target) {
    var launchName;
    return this.list()
    .then(function(device_list) {
        if (!device_list || !device_list.length)
            return Q.reject('ERROR: Failed to deploy to device, no devices found.');

        // default device
        target = typeof target !== 'undefined' ? target : device_list[0];

        if (device_list.indexOf(target) < 0)
            return Q.reject('ERROR: Unable to find target \'' + target + '\'.');

        var apk_path = build.get_apk();
        launchName = appinfo.getActivityName();
        console.log('Installing app on device...');
        var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
        return exec(cmd);
    }).then(function(output) {
        if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output);

        //unlock screen
        var cmd = 'adb -s ' + target + ' shell input keyevent 82';
        return exec(cmd);
    }, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); })
    .then(function() {
        // launch the application
        console.log('Launching application...');
        var cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
        return exec(cmd);
    }).then(function() {
        console.log('LAUNCH SUCCESS');
    }, function(err) {
        return Q.reject('ERROR: Failed to launch application on device: ' + err);
    });
}
<|endoftext|>


<commit_before>// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("channels")
require("jquery")
require("popper")
require("bootstrap")

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
<commit_msg>Configure js sentry sdk<commit_after>// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("channels")
require("jquery")
require("popper")
require("bootstrap")

// https://docs.sentry.io/platforms/javascript/

// When using npm, import Sentry
import * as Sentry from '@sentry/browser';

Sentry.init({ dsn: 'https://185a236f4b994411a9f33c3c714cb34e@sentry.io/1424888' });

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
<|endoftext|>


<commit_before>/**
 * Angular Tag cloud
 * Author : Damian Hamill
 * Repo: https://github.com/damianham/ngtagcloud
 *
 * See Also: https://github.com/zeeshanhyder, https://github.com/lucaong/jQCloud
 */

angular.module('ngTagCloud',[])

.directive('ngTagCloud', ['$timeout', '$log',function($timeout, $log) {
    var directive = {
        restrict: 'EA',
        scope: {
          tagOverflow: '=?',
          tagData: '=',
          tagLink: '@',
          tagClick: '&'
        },
        template: "

",
        link: link
      };

      return directive;

      function link($scope, element, attrs, controller) {

        var container;

        var wrap_text = function(link, tagtext) {
          if (typeof(link) === 'undefined') return tagtext;

          // replace {{tag}} in the link with the tagtext
          return link.replace('__tag__',tagtext);
        }

        var buildCloud = function(tagdata) {
          //console.log('build cloud with',tagdata);

          if (tagdata.length < 1) return;

       // Make sure every weight is a number before sorting
          for (var i = 0; i < tagdata.length; i++) {
            tagdata[i].weight = parseFloat(tagdata[i].weight, 10);
          }

          // Sort tagdata from the word with the highest weight to the one with the lowest
          tagdata.sort(function(a, b) { if (a.weight  b.weight) {return -1;} else {return 0;} });

          var cloud_div = container.find('div');
          var maxweight = tagdata[0].weight;
          var minweight = tagdata[tagdata.length - 1].weight;
          var weight;

          //console.log('container div', cloud_div);

          cloud_div.empty();

          angular.forEach(tagdata, function(tag) {

            // Check if min(weight) > max(weight) otherwise use default
            if (maxweight > minweight) {
              // Linearly map the original weight to a discrete scale from 1 to 10
              weight = Math.round((tag.weight - minweight) /  (maxweight - minweight) * 9.0) + 1;
            } else {
              weight = 5;
            }

            var elem = document.createElement("span");
            //console.log('tag click == ', typeof($scope.tagClick))
            if ($scope.tagClick !== undefined && $scope.tagClick !== "" && typeof($scope.tagClick) === "function") {
              // append a tag and bind it's onclick event to the click handler

              elem.onclick = function(){
                $scope.tagClick({text: tag.text});
              };

              // append the tag text
              elem.append(tag.text);

            } else if ( (tag.link !== undefined && tag.link !== "" && typeof(tag.link) === "string") ||
                ($scope.tagLink !== undefined && $scope.tagLink !== "" && typeof($scope.tagLink) === "string") )
            {
              // Append href if there's a link associated with the tag
              // or if the directive has a link attribute

              var href;

              if (tag.link !== undefined && tag.link !== "" && typeof(tag.link) === "string") {
                // use the link for this tag
                href =  encodeURI(tag.link).replace(/'/g, "%27");
              } else {
                // else use the link attribute
                href = wrap_text($scope.tagLink,tag.text);
              }

              var tag_link = document.createElement("a");
              tag_link.href = href;
              tag_link.appendChild(document.createTextNode(tag.text));
              elem.append(tag_link);

            } else {
                // append the tag text
                elem.append(tag.text);
            }

            elem.classList.add('w' + weight);

            //console.log('append',elem);
            cloud_div.append(elem);
          });

          $scope.$apply();
        }

        var getData = function($scope) {

          if (typeof($scope.tagData) === 'undefined' || $scope.tagData === "") {
            $log.error("ngTagCloud: data attribute is missing. Usage <ng-tag-cloud tag-data='expression'></ng-tag-cloud>\n" +
                "See: https://github.com/damianham/ngtagcloud");
            return false;
          }
          $scope.$watchCollection('tagData', function (newValue, oldValue) {
            $timeout(function(){
                buildCloud(newValue);
            }, 10);
          });
          return true;
        }

        if (getData($scope) === false) return;

        // Reference to the container element
        container = angular.element(element);

        //console.log('tag cloud container', container);

      }

    }])

<commit_msg>don't sort the collection so the watcher is not repeatedly fired<commit_after>/**
 * Angular Tag cloud
 * Author : Damian Hamill
 * Repo: https://github.com/damianham/ngtagcloud
 *
 * See Also: https://github.com/zeeshanhyder, https://github.com/lucaong/jQCloud
 */

angular.module('ngTagCloud',[])

.directive('ngTagCloud', ['$timeout', '$log',function($timeout, $log) {
    var directive = {
        restrict: 'EA',
        scope: {
          tagOverflow: '=?',
          tagData: '=',
          tagLink: '@',
          tagClick: '&'
        },
        template: "

",
        link: link
      };

      return directive;

      function link($scope, element, attrs, controller) {

        var container;

        var wrap_text = function(link, tagtext) {
          if (typeof(link) === 'undefined') {
            return tagtext;
          }

          // replace __tag__ in the link with the tagtext
          return link.replace('__tag__',tagtext);
        }

        var buildCloud = function(tagdata) {
          //console.log('build cloud with',tagdata);

          if (tagdata.length < 1) return;

          var maxweight = 0;
          var minweight = 0;

          // Make sure every weight is a number and get the min and max
          for (var i = 0; i < tagdata.length; i++) {
            tagdata[i].weight = parseFloat(tagdata[i].weight, 10);
            if (tagdata[i].weight > maxweight) {
              maxweight = tagdata[i].weight;
            } else if (minweight > 0 && minweight > tagdata[i].weight) {
              minweight = tagdata[i].weight;
            }
          }

          var cloud_div = container.find('div');

          var weight;

          //console.log('container div', cloud_div);

          cloud_div.empty();

          angular.forEach(tagdata, function(tag) {

            // Check if min(weight) > max(weight) otherwise use default
            if (maxweight > minweight) {
              // Linearly map the original weight to a discrete scale from 1 to 10
              weight = Math.round((tag.weight - minweight) /  (maxweight - minweight) * 9.0) + 1;
            } else {
              weight = 5;
            }

            var elem = document.createElement("span");
            //console.log('tag click == ', typeof($scope.tagClick))
            if ($scope.tagClick !== undefined && $scope.tagClick !== "" && typeof($scope.tagClick) === "function") {
              // append a tag and bind it's onclick event to the click handler

              elem.onclick = function(){
                $scope.tagClick({text: tag.text});
              };

              // append the tag text
              elem.append(tag.text);

            } else if ( (tag.link !== undefined && tag.link !== "" && typeof(tag.link) === "string") ||
                ($scope.tagLink !== undefined && $scope.tagLink !== "" && typeof($scope.tagLink) === "string") )
            {
              // Append href if there's a link associated with the tag
              // or if the directive has a link attribute

              var href;

              if (tag.link !== undefined && tag.link !== "" && typeof(tag.link) === "string") {
                // use the link for this tag
                href =  encodeURI(tag.link).replace(/'/g, "%27");
              } else {
                // else use the link attribute
                href = wrap_text($scope.tagLink,tag.text);
              }

              var tag_link = document.createElement("a");
              tag_link.href = href;
              tag_link.appendChild(document.createTextNode(tag.text));
              elem.append(tag_link);

            } else {
                // append the tag text
                elem.append(tag.text);
            }

            elem.classList.add('w' + weight);

            //console.log('append',elem);
            cloud_div.append(elem);
          });

          $scope.$apply();
        }

        var getData = function($scope) {

          if (typeof($scope.tagData) === 'undefined' || $scope.tagData === "") {
            $log.error("ngTagCloud: data attribute is missing. Usage <ng-tag-cloud tag-data='expression'></ng-tag-cloud>\n" +
                "See: https://github.com/damianham/ngtagcloud");
            return false;
          }
          $scope.$watchCollection('tagData', function (newValue, oldValue) {
            $timeout(function(){
                buildCloud(newValue);
            }, 1000);
          });
          return true;
        }

        if (getData($scope) === false) return;

        // Reference to the container element
        container = angular.element(element);

        //console.log('tag cloud container', container);

      }

    }])

<|endoftext|>


<commit_before>/**
 * Copyright 2015-present 650 Industries. All rights reserved.
 *
 * @providesModule HomeScreen
 */
'use strict';

import React from 'react';
import {
  ActivityIndicator,
  Linking,
  ListView,
  NativeModules,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import ResponsiveImage from '@exponent/react-native-responsive-image';

import Browser from 'Browser';
import BrowserActions from 'BrowserActions';
import ExColors from 'ExColors';
import ExUrls from 'ExUrls';
import FeaturedExperiences from 'FeaturedExperiences';
import FriendlyUrls from 'FriendlyUrls';
import HomeUrlBar from 'HomeUrlBar';
import Button from 'react-native-button';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

let {
  ExponentConstants,
  ExponentKernel,
} = NativeModules;

class HomeScreen extends React.Component {

  static getDataProps(data) {
    return {
      currentUrl: data.browser.foregroundTaskUrl,
      history: data.browser.history,
      isLoading: data.browser.isKernelLoading,
    };
  }

  static getDispatchActions(dispatch) {
    return {
      browserActions: bindActionCreators(BrowserActions, dispatch),
    };
  }

  constructor(props, context) {
    super(props, context);
    let dataSource = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2,
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
    });
    this.state = {
      dataSource: this._cloneDataSourceWithProps(dataSource, props),
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState(state => ({
      dataSource: this._cloneDataSourceWithProps(state.dataSource, nextProps),
    }));
  }

  _cloneDataSourceWithProps(dataSource, props) {
    let { history } = props;
    return dataSource.cloneWithRowsAndSections({
      recent: history.toArray(),
      featured: FeaturedExperiences.getFeatured(),
    });
  }

  render() {
    let hasRecentLinks = this.props.history.size > 0;
    let activityIndicator = (
      <ActivityIndicator
        hidesWhenStopped
        animating={this.props.isLoading}
        style={styles.activityIndicator}
        color="white"
      />
    );

    return (
      <View {...this.props} style={[styles.container, this.props.style]}>
        <StatusBar
          barStyle="light-content"
          hidden={false}
          animated
        />
        <View style={styles.header}>
          <ResponsiveImage
            sources={{
              2: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-logo@2x.png' },
              3: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-logo@3x.png' },
            }}
            style={styles.logo}
          />
          <View>
            <ResponsiveImage
              sources={{
                2: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-wordmark@2x.png' },
                3: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-wordmark@3x.png' },
              }}
              style={styles.exponent}
            />
          </View>
          {activityIndicator}
        </View>
        <HomeUrlBar
          url={FriendlyUrls.toFriendlyString(this.props.currentUrl, false)}
          onSubmit={this._handleUrlSubmit}
          onRefresh={this._refresh}
          style={styles.urlBar}
        />

        <ListView
          enableEmptySections
          dataSource={this.state.dataSource}
          renderSectionHeader={this._renderSectionHeader}
          renderRow={this._renderHistoryItem}
          renderSeparator={this._renderHistoryItemSeparator}
          alwaysBounceVertical={hasRecentLinks}
          removeClippedSubviews
          style={styles.historyList}
        />

        <View style={styles.bottomBar}>
          <Text style={styles.bottomBarText}>v{ExponentConstants.exponentVersion}</Text>
        </View>
      </View>
    );
  }

  _renderSectionHeader = (sectionData, sectionId) => {
    switch (sectionId) {
    case 'featured':
      return (
        <View style={styles.historyHeader}>
          <Text style={styles.historyHeaderText}>Featured</Text>
        </View>
      );
    case 'recent':
      if (this.props.history.size > 0) {
        return (
          <View style={styles.historyHeader}>
            <View style={{ flexDirection: 'row', justifyContent: 'space-between'}}>
              <Text style={styles.historyHeaderText}>Recent</Text>
              <Button
                onPress={() => this.props.browserActions.clearHistoryAsync()}
                style={styles.historyClearButton}>
                Clear
              </Button>
            </View>
            <View style={styles.historyHeaderBorder} />
          </View>
        );
      } else {
        return null;
      }
    }
  };

  _renderHistoryItem = (item, sectionId, rowId, highlightRow) => {
    let key = `${item.url}-${item.time}`;
    return (
      <HomeListItem
        key={key}
        activeOpacity={1}
        delayPressIn={50}
        onPressIn={() => {
          highlightRow(sectionId, rowId);
        }}
        onPressOut={() => {
          highlightRow(null);
        }}
        onPress={() => {
          this._loadUrlAsync(item.url).done();
        }}
        highlightedStyle={styles.highlightedHistoryItem}
        style={styles.historyItem}>
        <View>
          {item.manifest &&
            <Text style={styles.historyName}>
              {item.manifest.name}
            </Text>
          }
          <Text style={styles.url}>
            {FriendlyUrls.toFriendlyString(item.url)}
          </Text>
        </View>
      </HomeListItem>
    );
  };

  _renderHistoryItemSeparator = (sectionId, rowId, adjacentRowHighlighted) => {
    let highlightedStyle = adjacentRowHighlighted ? { marginLeft: 0 } : null;
    return (
      <View
        key={`sep-${sectionId}-${rowId}`}
        style={[styles.historyItemSeparator, highlightedStyle]}
      />
    );
  };

  _handleUrlSubmit = (event) => {
    let url = event.nativeEvent.text.trim();
    if (url.toLowerCase() === 'dev menu' || url.toLowerCase() === 'dm') {
      ExponentKernel.addDevMenu();
    } else {
      url = ExUrls.normalizeUrl(url);
      if (url) {
        this._loadUrlAsync(url, true).done();
      }
    }
  };

  async _loadUrlAsync(url, isFromUrlBar = false) {
    if (isFromUrlBar) {
      // since the user typed this into the exponent url bar, don't validate that we can open it,
      // just try to open it.
      ExponentKernel.openURL(url);
    } else {
      let canOpen = await Linking.canOpenURL(url);
      if (canOpen) {
        Linking.openURL(url);
      }
    }
  }

  _refresh() {
    Browser.refresh();
  }
}

export default connect(
  data => HomeScreen.getDataProps(data),
  dispatch => HomeScreen.getDispatchActions(dispatch),
)(HomeScreen);

class HomeListItem extends React.Component {
  state = {
    isHighlighted: false,
  };

  render() {
    let {
      style,
      highlightedStyle,
      ...props,
    } = this.props;
    return (
      <TouchableOpacity
        {...props}
        onPressIn={this._handlePressIn}
        onPressOut={this._handlePressOut}
        style={[style, this.state.isHighlighted && highlightedStyle]}
      />
    );
  }

  _handlePressIn = (event) => {
    this.setState({ isHighlighted: true });
    if (this.props.onPressIn) {
      this.props.onPressIn(event);
    }
  };

  _handlePressOut = (event) => {
    this.setState({ isHighlighted: false });
    if (this.props.onPressOut) {
      this.props.onPressOut(event);
    }
  };
}

let styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 22,
  },
  header: {
    marginTop: 8,
    marginBottom: 8,
    marginLeft: 12,
    flexDirection: 'row',
  },
  logo: {
    width: 19.5,
    height: 17,
    marginTop: 4,
    marginRight: 12,
  },
  exponent: {
    width: 92,
    height: 20,
    marginTop: 4,
  },
  activityIndicator: {
    alignSelf: 'flex-end',
    marginTop: 2,
    marginLeft: 12,
  },
  urlBar: {
    marginTop: 4,
    marginBottom: 3,
  },
  backButton: {
    color: '#fff',
  },
  historyClearButton: {
    color: '#999999',
    fontSize: 14,
    fontWeight: '200',
    marginRight: 6,
    marginTop: 2,
  },
  historyList: {
    flex: 1,
    backgroundColor: 'white',
    overflow: 'hidden',
  },
  historyHeader: {
    paddingTop: 8,
    paddingBottom: 8,
    paddingHorizontal: 12,
    overflow: 'hidden',
    backgroundColor: '#f0f0f0',
  },
  historyHeaderText: {
    color: '#595c68',
    fontSize: 18,
    fontWeight: '600',
  },
  historyItem: {
    backgroundColor: '#ffffff',
    paddingVertical: 12,
    paddingHorizontal: 22,
  },
  highlightedHistoryItem: {
    backgroundColor: ExColors.selectedRow,
  },
  url: {
    color: '#9ca0a6',
    fontSize: 12,
    marginTop: 1,
    marginBottom: 4,
  },
  historyName: {
    color: '#595c68',
    fontSize: 16,
    marginBottom: 1,
    marginTop: 4,
  },
  historyItemSeparator: {
    height: StyleSheet.hairlineWidth,
    backgroundColor: '#f0f0f0',
    marginLeft: 16,
  },
  emptyHistoryText: {
    color: 'rgba(255, 255, 255, 0.5)',
    fontSize: 16,
    fontWeight: 'bold',
    alignSelf: 'center',
    marginTop: 12,
  },
  bottomBar: {
    height: 24,
    paddingVertical: 4,
    paddingHorizontal: 16,
    backgroundColor: 'white',
    alignItems: 'flex-start',
  },
  bottomBarText: {
    color: '#8da5ba',
    fontSize: 10,
  },
});
<commit_msg>Disable removeClippedSubviews; it's broken on RN iOS for now<commit_after>/**
 * Copyright 2015-present 650 Industries. All rights reserved.
 *
 * @providesModule HomeScreen
 */
'use strict';

import React from 'react';
import {
  ActivityIndicator,
  Linking,
  ListView,
  NativeModules,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import ResponsiveImage from '@exponent/react-native-responsive-image';

import Browser from 'Browser';
import BrowserActions from 'BrowserActions';
import ExColors from 'ExColors';
import ExUrls from 'ExUrls';
import FeaturedExperiences from 'FeaturedExperiences';
import FriendlyUrls from 'FriendlyUrls';
import HomeUrlBar from 'HomeUrlBar';
import Button from 'react-native-button';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

let {
  ExponentConstants,
  ExponentKernel,
} = NativeModules;

class HomeScreen extends React.Component {

  static getDataProps(data) {
    return {
      currentUrl: data.browser.foregroundTaskUrl,
      history: data.browser.history,
      isLoading: data.browser.isKernelLoading,
    };
  }

  static getDispatchActions(dispatch) {
    return {
      browserActions: bindActionCreators(BrowserActions, dispatch),
    };
  }

  constructor(props, context) {
    super(props, context);
    let dataSource = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2,
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
    });
    this.state = {
      dataSource: this._cloneDataSourceWithProps(dataSource, props),
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState(state => ({
      dataSource: this._cloneDataSourceWithProps(state.dataSource, nextProps),
    }));
  }

  _cloneDataSourceWithProps(dataSource, props) {
    let { history } = props;
    return dataSource.cloneWithRowsAndSections({
      recent: history.toArray(),
      featured: FeaturedExperiences.getFeatured(),
    });
  }

  render() {
    let hasRecentLinks = this.props.history.size > 0;
    let activityIndicator = (
      <ActivityIndicator
        hidesWhenStopped
        animating={this.props.isLoading}
        style={styles.activityIndicator}
        color="white"
      />
    );

    return (
      <View {...this.props} style={[styles.container, this.props.style]}>
        <StatusBar
          barStyle="light-content"
          hidden={false}
          animated
        />
        <View style={styles.header}>
          <ResponsiveImage
            sources={{
              2: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-logo@2x.png' },
              3: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-logo@3x.png' },
            }}
            style={styles.logo}
          />
          <View>
            <ResponsiveImage
              sources={{
                2: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-wordmark@2x.png' },
                3: { uri: 'https://s3.amazonaws.com/exp-us-standard/ios-home-header-wordmark@3x.png' },
              }}
              style={styles.exponent}
            />
          </View>
          {activityIndicator}
        </View>
        <HomeUrlBar
          url={FriendlyUrls.toFriendlyString(this.props.currentUrl, false)}
          onSubmit={this._handleUrlSubmit}
          onRefresh={this._refresh}
          style={styles.urlBar}
        />

        <ListView
          enableEmptySections
          dataSource={this.state.dataSource}
          renderSectionHeader={this._renderSectionHeader}
          renderRow={this._renderHistoryItem}
          renderSeparator={this._renderHistoryItemSeparator}
          alwaysBounceVertical={hasRecentLinks}
          removeClippedSubviews={false}
          style={styles.historyList}
        />

        <View style={styles.bottomBar}>
          <Text style={styles.bottomBarText}>v{ExponentConstants.exponentVersion}</Text>
        </View>
      </View>
    );
  }

  _renderSectionHeader = (sectionData, sectionId) => {
    switch (sectionId) {
    case 'featured':
      return (
        <View style={styles.historyHeader}>
          <Text style={styles.historyHeaderText}>Featured</Text>
        </View>
      );
    case 'recent':
      if (this.props.history.size > 0) {
        return (
          <View style={styles.historyHeader}>
            <View style={{ flexDirection: 'row', justifyContent: 'space-between'}}>
              <Text style={styles.historyHeaderText}>Recent</Text>
              <Button
                onPress={() => this.props.browserActions.clearHistoryAsync()}
                style={styles.historyClearButton}>
                Clear
              </Button>
            </View>
            <View style={styles.historyHeaderBorder} />
          </View>
        );
      } else {
        return null;
      }
    }
  };

  _renderHistoryItem = (item, sectionId, rowId, highlightRow) => {
    let key = `${item.url}-${item.time}`;
    return (
      <HomeListItem
        key={key}
        activeOpacity={1}
        delayPressIn={50}
        onPressIn={() => {
          highlightRow(sectionId, rowId);
        }}
        onPressOut={() => {
          highlightRow(null);
        }}
        onPress={() => {
          this._loadUrlAsync(item.url).done();
        }}
        highlightedStyle={styles.highlightedHistoryItem}
        style={styles.historyItem}>
        <View>
          {item.manifest &&
            <Text style={styles.historyName}>
              {item.manifest.name}
            </Text>
          }
          <Text style={styles.url}>
            {FriendlyUrls.toFriendlyString(item.url)}
          </Text>
        </View>
      </HomeListItem>
    );
  };

  _renderHistoryItemSeparator = (sectionId, rowId, adjacentRowHighlighted) => {
    let highlightedStyle = adjacentRowHighlighted ? { marginLeft: 0 } : null;
    return (
      <View
        key={`sep-${sectionId}-${rowId}`}
        style={[styles.historyItemSeparator, highlightedStyle]}
      />
    );
  };

  _handleUrlSubmit = (event) => {
    let url = event.nativeEvent.text.trim();
    if (url.toLowerCase() === 'dev menu' || url.toLowerCase() === 'dm') {
      ExponentKernel.addDevMenu();
    } else {
      url = ExUrls.normalizeUrl(url);
      if (url) {
        this._loadUrlAsync(url, true).done();
      }
    }
  };

  async _loadUrlAsync(url, isFromUrlBar = false) {
    if (isFromUrlBar) {
      // since the user typed this into the exponent url bar, don't validate that we can open it,
      // just try to open it.
      ExponentKernel.openURL(url);
    } else {
      let canOpen = await Linking.canOpenURL(url);
      if (canOpen) {
        Linking.openURL(url);
      }
    }
  }

  _refresh() {
    Browser.refresh();
  }
}

export default connect(
  data => HomeScreen.getDataProps(data),
  dispatch => HomeScreen.getDispatchActions(dispatch),
)(HomeScreen);

class HomeListItem extends React.Component {
  state = {
    isHighlighted: false,
  };

  render() {
    let {
      style,
      highlightedStyle,
      ...props,
    } = this.props;
    return (
      <TouchableOpacity
        {...props}
        onPressIn={this._handlePressIn}
        onPressOut={this._handlePressOut}
        style={[style, this.state.isHighlighted && highlightedStyle]}
      />
    );
  }

  _handlePressIn = (event) => {
    this.setState({ isHighlighted: true });
    if (this.props.onPressIn) {
      this.props.onPressIn(event);
    }
  };

  _handlePressOut = (event) => {
    this.setState({ isHighlighted: false });
    if (this.props.onPressOut) {
      this.props.onPressOut(event);
    }
  };
}

let styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 22,
  },
  header: {
    marginTop: 8,
    marginBottom: 8,
    marginLeft: 12,
    flexDirection: 'row',
  },
  logo: {
    width: 19.5,
    height: 17,
    marginTop: 4,
    marginRight: 12,
  },
  exponent: {
    width: 92,
    height: 20,
    marginTop: 4,
  },
  activityIndicator: {
    alignSelf: 'flex-end',
    marginTop: 2,
    marginLeft: 12,
  },
  urlBar: {
    marginTop: 4,
    marginBottom: 3,
  },
  backButton: {
    color: '#fff',
  },
  historyClearButton: {
    color: '#999999',
    fontSize: 14,
    fontWeight: '200',
    marginRight: 6,
    marginTop: 2,
  },
  historyList: {
    flex: 1,
    backgroundColor: 'white',
    overflow: 'hidden',
  },
  historyHeader: {
    paddingTop: 8,
    paddingBottom: 8,
    paddingHorizontal: 12,
    overflow: 'hidden',
    backgroundColor: '#f0f0f0',
  },
  historyHeaderText: {
    color: '#595c68',
    fontSize: 18,
    fontWeight: '600',
  },
  historyItem: {
    backgroundColor: '#ffffff',
    paddingVertical: 12,
    paddingHorizontal: 22,
  },
  highlightedHistoryItem: {
    backgroundColor: ExColors.selectedRow,
  },
  url: {
    color: '#9ca0a6',
    fontSize: 12,
    marginTop: 1,
    marginBottom: 4,
  },
  historyName: {
    color: '#595c68',
    fontSize: 16,
    marginBottom: 1,
    marginTop: 4,
  },
  historyItemSeparator: {
    height: StyleSheet.hairlineWidth,
    backgroundColor: '#f0f0f0',
    marginLeft: 16,
  },
  emptyHistoryText: {
    color: 'rgba(255, 255, 255, 0.5)',
    fontSize: 16,
    fontWeight: 'bold',
    alignSelf: 'center',
    marginTop: 12,
  },
  bottomBar: {
    height: 24,
    paddingVertical: 4,
    paddingHorizontal: 16,
    backgroundColor: 'white',
    alignItems: 'flex-start',
  },
  bottomBarText: {
    color: '#8da5ba',
    fontSize: 10,
  },
});
<|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before>"use strict";

treeherder.controller('JobDetailPluginCtrl',
    function JobDetailPluginCtrl($scope, $resource, $http,
                                 thServiceDomain, thUrl) {

        $scope.$watch('selectedJob', function(newValue, oldValue) {
            // preferred way to get access to the selected job
            if (newValue) {
                $scope.job = newValue;

                // fields that will show in the job detail panel
                $scope.visibleFields = {
                    "Result": $scope.job.result,
                    "Job GUID": $scope.job.job_guid,
                    "Machine Name": "" + $scope.job.machine_name + "",
                    "Machine Platform Arch": $scope.job.machine_platform_architecture,
                    "Machine Platform OS": $scope.job.machine_platform_os,
                    "Build Platform": $scope.job.build_platform,
                    "Build Arch": $scope.job.build_architecture,
                    "Build OS": $scope.job.build_os
                };
                $http.get(thServiceDomain + $scope.job.resource_uri).
                    success(function(data) {
                        $scope.logs = data.logs;

                        data.artifacts.forEach(function(artifact) {
                            if (artifact.name.contains("Job Artifact")) {
                                // we don't return the blobs with job, just
                                // resource_uris to them.  For the Job Artifact,
                                // we want that blob, so we need to fetch the
                                // detail to get the blob which has the
                                // tinderbox_printlines, etc.
                                $scope.jobArtifact = $resource(
                                    thServiceDomain + artifact.resource_uri).get();
                            } else if (artifact.name === "Structured Log") {
                                // for the structured log, we don't need the blob
                                // here, we have everything we need in the artifact
                                // as is, so just save it.
                                $scope.lvArtifact=artifact;
                                $scope.lvUrl = thUrl.getLogViewerUrl(artifact.id);
                            }
                        });
                    });
                $scope.comments = [
                    {
                        who: "spectre",
                        date: 1379709198,
                        note: "wazzon chokey?"
                    },
                    {
                        who: "fucci ca pesta",
                        date: 1379709198,
                        note: "my eyes are burning"
                    },
                    {
                        who: "camd",
                        date:  1376122980,
                        note: "happy birthday to me.  this is my day."
                    }
                ];
            }
        }, true);

        $scope.addNote = function() {
            $scope.noteJob = $scope.job;
        };
    }
);

treeherder.controller('JobNoteCtrl',
    function JobNoteCtrl($scope) {
        // bind to individual values in this scope, rather than a whole item.
        // each scope item binds to part of noteJob.
        // noteJob should probably be a copy?  or we won't change anything.
        // just display values from it, maybe...

            $scope.who = "camd";
            $scope.note = "";
            $scope.failure_classification_id = 2;
    }
);
<commit_msg>start of thJobNotes service for getting.<commit_after>"use strict";

treeherder.controller('JobDetailPluginCtrl',
    function JobDetailPluginCtrl($scope, $resource, $http,
                                 thServiceDomain, thUrl) {

        $scope.$watch('selectedJob', function(newValue, oldValue) {
            // preferred way to get access to the selected job
            if (newValue) {
                $scope.job = newValue;

                // fields that will show in the job detail panel
                $scope.visibleFields = {
                    "Result": $scope.job.result,
                    "Job GUID": $scope.job.job_guid,
                    // TODO: this needs to be a directive!!
                    "Machine Name": "" + $scope.job.machine_name + "",
                    "Machine Platform Arch": $scope.job.machine_platform_architecture,
                    "Machine Platform OS": $scope.job.machine_platform_os,
                    "Build Platform": $scope.job.build_platform,
                    "Build Arch": $scope.job.build_architecture,
                    "Build OS": $scope.job.build_os
                };
                $http.get(thServiceDomain + $scope.job.resource_uri).
                    success(function(data) {
                        $scope.logs = data.logs;

                        data.artifacts.forEach(function(artifact) {
                            if (artifact.name.contains("Job Artifact")) {
                                // we don't return the blobs with job, just
                                // resource_uris to them.  For the Job Artifact,
                                // we want that blob, so we need to fetch the
                                // detail to get the blob which has the
                                // tinderbox_printlines, etc.
                                $scope.jobArtifact = $resource(
                                    thServiceDomain + artifact.resource_uri).get();
                            } else if (artifact.name === "Structured Log") {
                                // for the structured log, we don't need the blob
                                // here, we have everything we need in the artifact
                                // as is, so just save it.
                                $scope.lvArtifact=artifact;
                                $scope.lvUrl = thUrl.getLogViewerUrl(artifact.id);
                            }
                        });
                    });
                $scope.comments = [
                    {
                        who: "spectre",
                        date: 1379709198,
                        note: "wazzon chokey?"
                    },
                    {
                        who: "fucci ca pesta",
                        date: 1379709198,
                        note: "my eyes are burning"
                    },
                    {
                        who: "camd",
                        date:  1376122980,
                        note: "happy birthday to me.  this is my day."
                    }
                ];
            }
        }, true);

        $scope.addNote = function() {
            $scope.noteJob = $scope.job;
        };
    }
);

treeherder.controller('JobNoteCtrl',
    function JobNoteCtrl($scope) {
        // bind to individual values in this scope, rather than a whole item.
        // each scope item binds to part of noteJob.
        // noteJob should probably be a copy?  or we won't change anything.
        // just display values from it, maybe...

            $scope.who = "camd";
            $scope.note = "";
            $scope.failure_classification_id = 2;
    }
);

////////////////////////
//
//  Services
//
///////////////////////

treeherder.factory('thJobNotes', function($http, thUrl) {
    var jobNotes = {
        apiPath: thUrl + "note/",
        getAll: function() {
            return $http.get(this.apiPath);
        }
    };
    return jobNotes;
});<|endoftext|>


<commit_before>const {resolve, join} = require('path');
const webpack = require('webpack');
const WorkboxPlugin = require('workbox-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const pkg = require('./package.json');

/**
 * === ENV configuration
 */
const isDev = process.argv.find(arg => arg.includes('webpack-dev-server'));
const ENV = isDev ? 'development' : 'production';
const BROWSERS = process.env.BROWSERS === 'module' ?
  ['last 2 Chrome versions', 'Safari 10'] : ['> 1%', 'last 2 versions', 'Firefox ESR', 'not ie <= 11'];
const IS_MODULE_BUILD = BROWSERS[0].includes('Chrome');
const outputPath = isDev ? resolve('src') : resolve('dist');
const processEnv = {
  NODE_ENV: JSON.stringify(ENV),
  appVersion: JSON.stringify(pkg.version)
};

/**
 * === Copy static files configuration
 */
const copyStatics = {
  copyWebcomponents: [{
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-sd-ce.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }],
  copyOthers: [{
    from: 'assets/**',
    context: resolve('./src'),
    to: outputPath
  }, {
    from: resolve('./src/index.html'),
    to: outputPath,
    flatten: true
  }, {
    from: resolve('./src/manifest.json'),
    to: outputPath,
    flatten: true
  }]
};

/**
 * Plugin configuration
 */
const plugins = isDev ? [
  new CopyWebpackPlugin(copyStatics.copyWebcomponents),
  new webpack.DefinePlugin({'process.env': processEnv})
] : [
  new WorkboxPlugin({
    globDirectory: outputPath,
    globPatterns: ['**/*.{html,js,css}'],
    swDest: join(outputPath, 'sw.js')
  }),
  new CopyWebpackPlugin(
    [].concat(copyStatics.copyWebcomponents, copyStatics.copyOthers)
  ),
  new webpack.DefinePlugin({'process.env': processEnv})
];

/**
 * === Webpack configuration
 */
module.exports = {
  entry: './src/index.js',
  output: {
    path: outputPath,
    filename: IS_MODULE_BUILD ? 'module.bundle.js' : 'bundle.js'
  },
  devtool: 'cheap-module-source-map',
  module: {
    rules: [
      {
        test: /\.js$/,
        // We need to transpile Polymer itself and other ES6 code
        // exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [[
              'env',
              {
                targets: {browsers: BROWSERS},
                debug: true
              }
            ]]
          }
        }
      },
      {
        test: /\.html$/,
        use: ['text-loader']
      },
      {
        test: /\.postcss$/,
        use: ['text-loader', 'postcss-loader']
      }
    ]
  },
  plugins,
  devServer: {
    contentBase: resolve(outputPath),
    compress: true,
    overlay: {
      errors: true
    },
    port: 3000,
    host: '0.0.0.0',
    disableHostCheck: true
  }
};
<commit_msg>Extend WorkboxJS for Fonts<commit_after>const {resolve, join} = require('path');
const webpack = require('webpack');
const WorkboxPlugin = require('workbox-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const pkg = require('./package.json');

/**
 * === ENV configuration
 */
const isDev = process.argv.find(arg => arg.includes('webpack-dev-server'));
const ENV = isDev ? 'development' : 'production';
const BROWSERS = process.env.BROWSERS === 'module' ?
  ['last 2 Chrome versions', 'Safari 10'] : ['> 1%', 'last 2 versions', 'Firefox ESR', 'not ie <= 11'];
const IS_MODULE_BUILD = BROWSERS[0].includes('Chrome');
const outputPath = isDev ? resolve('src') : resolve('dist');
const processEnv = {
  NODE_ENV: JSON.stringify(ENV),
  appVersion: JSON.stringify(pkg.version)
};

/**
 * === Copy static files configuration
 */
const copyStatics = {
  copyWebcomponents: [{
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/webcomponents-sd-ce.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }, {
    from: resolve('./node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'),
    to: join(outputPath, 'vendor'),
    flatten: true
  }],
  copyOthers: [{
    from: 'assets/**',
    context: resolve('./src'),
    to: outputPath
  }, {
    from: resolve('./src/index.html'),
    to: outputPath,
    flatten: true
  }, {
    from: resolve('./src/manifest.json'),
    to: outputPath,
    flatten: true
  }]
};

/**
 * Plugin configuration
 */
const plugins = isDev ? [
  new CopyWebpackPlugin(copyStatics.copyWebcomponents),
  new webpack.DefinePlugin({'process.env': processEnv})
] : [
  new WorkboxPlugin({
    globDirectory: outputPath,
    globPatterns: ['**/*.{html, js, css, svg, png, woff, woff2, ttf}'],
    swDest: join(outputPath, 'sw.js')
  }),
  new CopyWebpackPlugin(
    [].concat(copyStatics.copyWebcomponents, copyStatics.copyOthers)
  ),
  new webpack.DefinePlugin({'process.env': processEnv})
];

/**
 * === Webpack configuration
 */
module.exports = {
  entry: './src/index.js',
  output: {
    path: outputPath,
    filename: IS_MODULE_BUILD ? 'module.bundle.js' : 'bundle.js'
  },
  devtool: 'cheap-module-source-map',
  module: {
    rules: [
      {
        test: /\.js$/,
        // We need to transpile Polymer itself and other ES6 code
        // exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [[
              'env',
              {
                targets: {browsers: BROWSERS},
                debug: true
              }
            ]]
          }
        }
      },
      {
        test: /\.html$/,
        use: ['text-loader']
      },
      {
        test: /\.postcss$/,
        use: ['text-loader', 'postcss-loader']
      }
    ]
  },
  plugins,
  devServer: {
    contentBase: resolve(outputPath),
    compress: true,
    overlay: {
      errors: true
    },
    port: 3000,
    host: '0.0.0.0',
    disableHostCheck: true
  }
};
<|endoftext|>


<commit_before>'use strict';

angular.module('newshoundApp')
    .factory('config', ['$location',
        function($location) {
            return {
                apiHost: function() {
                    return "https://api-dot-newshound.appspot.com/svc/newshound-api/v1";
                }
            };
        }
    ]);
<commit_msg>new domain!<commit_after>'use strict';

angular.module('newshoundApp')
    .factory('config', ['$location',
        function($location) {
            return {
                apiHost: function() {
                    return "https://api.newshound.email/svc/newshound-api/v1";
                }
            };
        }
    ]);
<|endoftext|>


<commit_before>var vows = require('vows'),
	should = require('should'),
	zombie = require('zombie');

var Server = require('../js/main');

var StaticPort = 8085;

vows.describe('Aux').addBatch({
	'A server': {
		topic: function () {
			var server = new Server({
				port: 8081,
				static_port: StaticPort,
				debug_level: "error",
				map_filepath: "maps/world_server.json",
			});
			return server;
		},
		'started': {
			topic: function (server) {
				should.exists(server);
				server.should.be.an.instanceof(Server);
				server.start(this.callback);
				return server;
			},
			'and index page': {
				topic: function (server) {
					zombie.visit("http://localhost:" + server.config.static_port + "/", {
						runScripts: false
					}, this.callback);
				},
				"should return success": function (e, browser) {
					should.not.exists(e);
					should.exists(browser);
					should.exists(browser.statusCode);
					browser.statusCode.should.equal(200);
				}
			}
		}
	}
}).export(module);<commit_msg>right tests<commit_after>var vows = require('vows'),
	should = require('should'),
	zombie = require('zombie');

var Server = require('../js/main');

var StaticPort = 8085;

vows.describe('Aux').addBatch({
	'A server': {
		topic: function () {
			var server = new Server({
				port: 8081,
				static_port: StaticPort,
				debug_level: "error",
				map_filepath: "maps/world_server.json",
			});
			return server;
		},
		'started': {
			topic: function (server) {
				should.exists(server);
				server.should.be.an.instanceof(Server);
				server.start(this.callback);
				return server;
			},
			'and index page': {
				topic: function (server) {
					zombie.visit("http://localhost:" + server.config.static_port + "/", {
						runScripts: false
					}, this.callback);
				},
				"should return success": function (e, browser, statusCode) {
					should.not.exists(e);
					should.exists(statusCode);
					statusCode.should.equal(200);
				}
			}
		}
	}
}).export(module);<|endoftext|>


<commit_before>'use strict';
angular.module('arethusa.core').service('keyCapture', [
  'configurator',
  function(configurator) {
    var self = this;

    this.conf = function() {
      return configurator.configurationFor('keyCapture');
    };

    var keyCodes = {
      shift: 16,
      ctrl: 17,
      alt: 18,
      esc: 27,
      j: 74,
      k: 75,
      w: 87,
      e: 69
    };

    this.shiftModifier = 1000;

    this.getKeyCode = function(key) {
      var keyCode = keyCodes[key.toLowerCase()];
      if (key.match(/[A-Z]/)) {
        return keyCode + self.shiftModifier;
      }
      return keyCode;
    };

    var keyPressedCallbacks = {};

    function modifiedKeyCode(event) {
      var keyCode = event.keyCode;
      if (event.shiftKey) {
        keyCode = keyCode + self.shiftModifier;
      }
      return keyCode;
    }

    var handleCallbacks = function(event) {
      var keyCode = modifiedKeyCode(event);
      var callbacks = keyPressedCallbacks[keyCode];
      if (callbacks) {
        resolveCallbacks(callbacks, event);
        resumePropagation();
      }
    };

    this.keydown = function (event) {
      // we're only acting on keyup for now
    };

    var forbiddenTags = ['INPUT'];

    this.keyup = function (event) {
      if (arethusaUtil.isIncluded(forbiddenTags, event.target.tagName)) {
        return;
      }
      var keyCode = modifiedKeyCode(event);
      handleCallbacks(event);
    };

    function Callback(callback, priority) {
      this.callback = callback;
      this.priority = priority || 0;
    }

    this.onKeyPressed = function(key, callback, priority) {
      var keyCode = self.getKeyCode(key);
      var callbacks = keyPressedCallbacks[keyCode] || [];
      callbacks.push(new Callback(callback, priority));
      keyPressedCallbacks[keyCode] = sortedByPriority(callbacks);
    };

    function sortedByPriority(callbacks) {
      return callbacks.sort(function(a, b) {
        return b.priority - a.priority;
      });
    }

    var propagationStopped = false;

    this.stopPropagation = function() {
      propagationStopped = true;
    };

    function resumePropagation() {
      propagationStopped = false;
    }

    function resolveCallbacks(callbacks, event) {
      angular.forEach(callbacks, function(callbackObj, key) {
        if (! propagationStopped) {
          callbackObj.callback(event);
        }
      });
    }
  }
]);
<commit_msg>Activate all modifiers (and combos) in keyCapture<commit_after>'use strict';
angular.module('arethusa.core').service('keyCapture', [
  'configurator',
  function(configurator) {
    var self = this;

    this.conf = function() {
      return configurator.configurationFor('keyCapture');
    };

    var keyCodes = {
      shift: 16,
      ctrl: 17,
      alt: 18,
      esc: 27,
      j: 74,
      k: 75,
      w: 87,
      e: 69
    };

    this.shiftModifier = 1000;
    this.ctrlModifier  = 2000;
    this.altModifier   = 4000;
    this.metaModifier  = 8000;

    this.getKeyCode = function(key) {
      var parsed = parseKey(key);
      var modifiers = parsed[0];
      var k = parsed[1];
      angular.forEach(modifiers, function(modifier, i) {
        var mod;
        switch (modifier) {
          case 'ctrl':  mod = self.ctrlModifier;  break;
          case 'shift': mod = self.shiftModifier; break;
          case 'alt':   mod = self.altModifier;   break;
          case 'meta':  mod = self.altModifier;   break;
        }
        k = k + mod;
      });

      return k;
    };

    function parseKey(key) {
      var parts = key.split('-');
      var k = parts.pop();
      if (k.match(/[A-Z]/)) {
        // in case someone wants to do shift-J
        if (! arethusaUtil.isIncluded(parts, 'shift')) {
          parts.push('shift');
        }
        k = k.toLowerCase();
      }

      return [parts, keyCodes[k]];
    }

    var keyPressedCallbacks = {};

    function modifiedKeyCode(event) {
      var k = event.keyCode;

      if (event.shiftKey) k = k + self.shiftModifier;
      if (event.ctrlKey)  k = k + self.ctrlModifier;
      if (event.altKey)   k = k + self.altModifier;
      if (event.metaKey)  k = k + self.metaModifier;

      return k;
    }

    var handleCallbacks = function(event) {
      var keyCode = modifiedKeyCode(event);
      var callbacks = keyPressedCallbacks[keyCode];
      if (callbacks) {
        resolveCallbacks(callbacks, event);
        resumePropagation();
      }
    };

    this.keydown = function (event) {
      // we're only acting on keyup for now
    };

    var forbiddenTags = ['INPUT'];

    this.keyup = function (event) {
      if (arethusaUtil.isIncluded(forbiddenTags, event.target.tagName)) {
        return;
      }
      var keyCode = modifiedKeyCode(event);
      handleCallbacks(event);
    };

    function Callback(callback, priority) {
      this.callback = callback;
      this.priority = priority || 0;
    }

    this.onKeyPressed = function(key, callback, priority) {
      var keyCode = self.getKeyCode(key);
      var callbacks = keyPressedCallbacks[keyCode] || [];
      callbacks.push(new Callback(callback, priority));
      keyPressedCallbacks[keyCode] = sortedByPriority(callbacks);
    };

    function sortedByPriority(callbacks) {
      return callbacks.sort(function(a, b) {
        return b.priority - a.priority;
      });
    }

    var propagationStopped = false;

    this.stopPropagation = function() {
      propagationStopped = true;
    };

    function resumePropagation() {
      propagationStopped = false;
    }

    function resolveCallbacks(callbacks, event) {
      angular.forEach(callbacks, function(callbackObj, key) {
        if (! propagationStopped) {
          callbackObj.callback(event);
        }
      });
    }
  }
]);
<|endoftext|>


<commit_before>import style from './style.css';

import classnames from 'classnames';
import React, { Component, PropTypes } from 'react';
import echarts from 'echarts';

class VerticalBarChart extends Component {
  static propTypes = {
    style: PropTypes.string,
    className: PropTypes.string,
  };

  static defaultProps = {
    className: '',
  };

  constructor(props, context) {
    super(props, context);
    this.state = {};
  }

  componentDidMount() {
    const myChart = echarts.init(document.getElementById('verticalBarChart'));
    const option = {
      title: {
        text: '题目低通过率Top10',
        position: 'right',
        textStyle: {
          fontWeight: 'normal',
        },
      },
      color: ['#3398DB'],
      tooltip: {
        trigger: 'xAxis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          data: ['2009', '2008', '2007', '2006', '2005', '2004', '2003', '2002', '2001', '2000'],
          axisTick: {
            alignWithLabel: true,
          },
        },
      ],
      yAxis: [
        {
          type: 'value',
          name: '题目通过率',
          position: 'right',
          axisLabel: {
            formatter: '{value}%',
          },
        },
      ],
      series: [
        {
          name: '题目低通过率Top10',
          type: 'bar',
          barWidth: '60%',
          data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
          itemStyle: {
            normal: {
              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
                offset: 0,
                color: 'lightBlue', // 0% 处的颜色
              }, {
                offset: 1,
                color: '#2196f3', // 100% 处的颜色
              }], false),
            },
          },
        },
      ],
    };
    myChart.setOption(option);
  }

  render() {
    const { className } = this.props;

    /* eslint-disable */
    return (

    );
  }
}

export default VerticalBarChart;
<commit_msg>chore(VerticalBarChart.js): 删除无用配置项<commit_after>import style from './style.css';

import classnames from 'classnames';
import React, { Component, PropTypes } from 'react';
import echarts from 'echarts';

class VerticalBarChart extends Component {
  static propTypes = {
    style: PropTypes.string,
    className: PropTypes.string,
  };

  static defaultProps = {
    className: '',
  };

  constructor(props, context) {
    super(props, context);
    this.state = {};
  }

  componentDidMount() {
    const myChart = echarts.init(document.getElementById('verticalBarChart'));
    const option = {
      title: {
        text: '题目低通过率Top10',
        textStyle: {
          fontWeight: 'normal',
        },
      },
      color: ['#3398DB'],
      tooltip: {
        trigger: 'xAxis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          data: ['2009', '2008', '2007', '2006', '2005', '2004', '2003', '2002', '2001', '2000'],
          axisTick: {
            alignWithLabel: true,
          },
        },
      ],
      yAxis: [
        {
          type: 'value',
          name: '题目通过率',
          position: 'right',
          axisLabel: {
            formatter: '{value}%',
          },
        },
      ],
      series: [
        {
          name: '题目低通过率Top10',
          type: 'bar',
          barWidth: '60%',
          data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
          itemStyle: {
            normal: {
              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
                offset: 0,
                color: 'lightBlue', // 0% 处的颜色
              }, {
                offset: 1,
                color: '#2196f3', // 100% 处的颜色
              }], false),
            },
          },
        },
      ],
    };
    myChart.setOption(option);
  }

  render() {
    const { className } = this.props;

    /* eslint-disable */
    return (

    );
  }
}

export default VerticalBarChart;
<|endoftext|>


<commit_before>/*
=require ../vendor/bootstrap/js/modal.js
*/
/*
 * Ajax Popup plugin
 *
 * Options:
 * - content: content HTML string or callback
 *
 * Data attributes:
 * - data-control="popup" - enables the ajax popup plugin
 * - data-ajax="popup-content.htm" - ajax content to load
 * - data-handler="widget:pluginName" - October ajax request name
 * - data-keyboard="false" - Allow popup to be closed with the keyboard
 * - data-extra-data="file_id: 1" - October ajax request data
 * - data-size="large" - Popup size, available sizes: giant, huge, large, small, tiny
 *
 * JavaScript API:
 * $('a#someLink').popup({ ajax: 'popup-content.htm' })
 * $('a#someLink').popup({ handler: 'onLoadSomePopup' })
 * $('a#someLink').popup({ handler: 'onLoadSomePopup', extraData: { id: 3 } })
 *
 * Dependences:
 * - Bootstrap Modal (modal.js)
 */

+function ($) { "use strict";

    // POPUP CLASS DEFINITION
    // ============================

    var Popup = function(element, options) {
        var self = this
        this.options    = options
        this.$el        = $(element)
        this.$container = null
        this.$modal     = null
        this.$backdrop  = null
        this.isOpen     = false
        this.firstDiv   = null
        this.allowHide  = true

        this.lastScrollPos = -1;

        this.$container = this.createPopupContainer()
        this.$content = this.$container.find('.modal-content:first')
        this.$modal = this.$container.modal({ show: false, backdrop: false, keyboard: this.options.keyboard })

        /*
         * Duplicate the popup reference on the .control-popup container
         */
        this.$container.data('oc.popup', this)

        /*
         * Hook in to BS Modal events
         */
        this.$modal.on('hide.bs.modal', function(){
            self.triggerEvent('hide.oc.popup')
            self.isOpen = false
            self.setBackdrop(false)
        })

        this.$modal.on('hidden.bs.modal', function(){
            self.triggerEvent('hidden.oc.popup')
            self.$container.remove()
            self.$el.data('oc.popup', null)
            $(document.body).removeClass('modal-open')
        })

        this.$modal.on('show.bs.modal', function(){
            self.isOpen = true
            self.setBackdrop(true)
            $(document.body).addClass('modal-open')
        })

        this.$modal.on('shown.bs.modal', function(){
            self.triggerEvent('shown.oc.popup')
            $(document).trigger('render')
        })

        this.$modal.on('close.oc.popup', function(){
            self.hide()
            return false
        })

        this.init()
    }

    Popup.DEFAULTS = {
        ajax: null,
        handler: null,
        keyboard: true,
        extraData: {},
        content: null,
        size: null,
        adaptiveHeight: false,
        zIndex: null
    }

    Popup.prototype.init = function() {
        var self = this

        /*
         * Do not allow the same popup to open twice
         */
        if (self.isOpen)
            return

        /*
         * Show loading panel
         */
        this.setBackdrop(true)

        if (!this.options.content)
            this.setLoading(true)

        /*
         * October AJAX
         */
        if (this.options.handler) {
            this.$el.request(this.options.handler, {
                data: paramToObj('data-extra-data', this.options.extraData),
                success: function(data, textStatus, jqXHR) {
                    this.success(data, textStatus, jqXHR).done(function(){
                        self.setContent(data.result)
                        $(window).trigger('ajaxUpdateComplete', [this, data, textStatus, jqXHR])
                        self.triggerEvent('popupComplete') // Deprecated
                        self.triggerEvent('complete.oc.popup')
                    })
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    this.error(jqXHR, textStatus, errorThrown).done(function(){
                        self.hide()
                        self.triggerEvent('popupError') // Deprecated
                        self.triggerEvent('error.oc.popup')
                    })
                }
            })

        }

        /*
         * Regular AJAX
         */
        else if (this.options.ajax) {

            $.ajax({
                url: this.options.ajax,
                data: this.options.extraData,
                success: function(data) {
                    self.setContent(data)
                },
                cache: false
            })

        }

        /*
         * Specified content
         */
        else if (this.options.content) {

            var content = typeof this.options.content == 'function'
                ? this.options.content.call(this.$el[0], this)
                : this.options.content

            this.setContent(content)
        }
    }

    Popup.prototype.createPopupContainer = function() {
        var
            modal = $('
').prop({
                class: 'control-popup modal fade',
                role: 'dialog',
                tabindex: -1
            }),
            modalDialog = $('
').addClass('modal-dialog'),
            modalContent = $('
').addClass('modal-content');

        if (this.options.size)
            modalDialog.addClass('size-' + this.options.size)

        if (this.options.adaptiveHeight)
            modalDialog.addClass('adaptive-height')

        if (this.options.zIndex !== null)
            modal.css('z-index', this.options.zIndex + 20)

        return modal.append(modalDialog.append(modalContent))
    }

    Popup.prototype.setContent = function(contents) {
        this.$content.html(contents)
        this.setLoading(false)
        this.show()

        // Duplicate the popup object reference on to the first div
        // inside the popup. Eg: $('#firstDiv').popup('hide')
        this.firstDiv = this.$content.find('>div:first')
        if (this.firstDiv.length > 0)
            this.firstDiv.data('oc.popup', this)

        if (form.length) {
            var $firstField = form.find('input[type="text"], input[type="number"], input[type="email"], textarea').first()
            window.setTimeout(function () {
                $firstField.focus()
            }, 300)
        }
    }

    Popup.prototype.setBackdrop = function(val) {
        if (val && !this.$backdrop) {
            this.$backdrop = $('
')

            this.$modal.on('click.dismiss.bs.modal', $.proxy(function (e) {
              if (this.ignoreBackdropClick) {
                this.ignoreBackdropClick = false
                return
              }
              if (e.target !== e.currentTarget) return
              this.options.backdrop == 'static'
                ? this.$element[0].focus()
                : this.hide()
            }, this))

            if (this.options.zIndex !== null)
                this.$backdrop.css('z-index', this.options.zIndex)

            this.$backdrop.appendTo(document.body);

            this.$backdrop.addClass('in')
            this.$backdrop.append($('
'));
        }
        else if (!val && this.$backdrop) {
            this.$backdrop.remove()
            this.$backdrop = null
        }
    }

    Popup.prototype.setLoading = function(val) {
        if (!this.$backdrop)
            return;

        var self = this
        if (val) {
            setTimeout(function(){ self.$backdrop.addClass('loading'); }, 100)
        }
        else {
            this.$backdrop.removeClass('loading');
        }
    }

    Popup.prototype.hideLoading = function(val) {
        this.setLoading(false)

        // Wait for animations to complete
        var self = this
        setTimeout(function() { self.setBackdrop(false) }, 250)
        setTimeout(function() { self.hide() }, 500)
    }

    Popup.prototype.triggerEvent = function(eventName, params) {
        if (!params)
            params = [this.$el, this.$modal]

        var eventObject = jQuery.Event(eventName, { relatedTarget: this.$container.get(0) })

        this.$el.trigger(eventObject, params)

        if (this.firstDiv)
            this.firstDiv.trigger(eventObject, params)
    }

    Popup.prototype.reload = function() {
        this.init()
    }

    Popup.prototype.show = function() {
        this.$modal.modal('show')

        this.lastScrollPos = $(window).scrollTop();

        $('body').addClass('lock-screen');

        this.$modal.on('click.dismiss.popup', '[data-dismiss="popup"]', $.proxy(this.hide, this))
        this.triggerEvent('popupShow') // Deprecated
        this.triggerEvent('show.oc.popup')
    }

    Popup.prototype.hide = function() {
        this.triggerEvent('popupHide') // Deprecated
        this.triggerEvent('hide.oc.popup')

        $('body').removeClass('lock-screen');

        $(window).scrollTop(this.lastScrollPos);

        if (this.allowHide)
            this.$modal.modal('hide')
    }

    /*
     * Hide the popup without destroying it,
     * you should call .hide() once finished
     */
    Popup.prototype.visible = function(val) {
        if (val)
            this.$modal.addClass('in')
        else
            this.$modal.removeClass('in')
        this.setBackdrop(val)
    }

    Popup.prototype.toggle = function() {
        this.triggerEvent('popupToggle', [this.$modal]) // Deprecated
        this.triggerEvent('toggle.oc.popup', [this.$modal])

        this.$modal.modal('toggle')
    }

    /*
     * Lock the popup from closing
     */
    Popup.prototype.lock = function(val) {
        this.allowHide = !val
    }

    // POPUP PLUGIN DEFINITION
    // ============================

    var old = $.fn.popup

    $.fn.popup = function (option) {
        var args = Array.prototype.slice.call(arguments, 1)
        return this.each(function () {
            var $this   = $(this)
            var data    = $this.data('oc.popup')
            var options = $.extend({}, Popup.DEFAULTS, $this.data(), typeof option == 'object' && option)
            if (!data) $this.data('oc.popup', (data = new Popup(this, options)))
            else if (typeof option == 'string') data[option].apply(data, args)
            else data.reload()
        })
    }

    $.fn.popup.Constructor = Popup

    $.popup = function (option) {
        return $('').popup(option)
    }

    // POPUP NO CONFLICT
    // =================

    $.fn.popup.noConflict = function () {
        $.fn.popup = old
        return this
    }

    // POPUP DATA-API
    // ===============

    function paramToObj(name, value) {
        if (value === undefined) value = ''
        if (typeof value == 'object') return value

        try {
            return JSON.parse(JSON.stringify(eval("({" + value + "})")))
        }
        catch (e) {
            throw new Error('Error parsing the '+name+' attribute value. '+e)
        }
    }

    $(document).on('click.oc.popup', '[data-control="popup"]', function() {
        $(this).popup()

        return false
    });

    /*
     * Only use the popup loading indicator if the handlers are an exact match.
     */
    $(document)
        .on('ajaxPromise', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').removeClass('in').popup('setLoading', true)
        })
        .on('ajaxFail', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').addClass('in').popup('setLoading', false)
        })
        .on('ajaxDone', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').popup('hideLoading')
        })

}(window.jQuery);
<commit_msg>Fix for popup<commit_after>/*
=require ../vendor/bootstrap/js/modal.js
*/
/*
 * Ajax Popup plugin
 *
 * Options:
 * - content: content HTML string or callback
 *
 * Data attributes:
 * - data-control="popup" - enables the ajax popup plugin
 * - data-ajax="popup-content.htm" - ajax content to load
 * - data-handler="widget:pluginName" - October ajax request name
 * - data-keyboard="false" - Allow popup to be closed with the keyboard
 * - data-extra-data="file_id: 1" - October ajax request data
 * - data-size="large" - Popup size, available sizes: giant, huge, large, small, tiny
 *
 * JavaScript API:
 * $('a#someLink').popup({ ajax: 'popup-content.htm' })
 * $('a#someLink').popup({ handler: 'onLoadSomePopup' })
 * $('a#someLink').popup({ handler: 'onLoadSomePopup', extraData: { id: 3 } })
 *
 * Dependences:
 * - Bootstrap Modal (modal.js)
 */

+function ($) { "use strict";

    // POPUP CLASS DEFINITION
    // ============================

    var Popup = function(element, options) {
        var self = this
        this.options    = options
        this.$el        = $(element)
        this.$container = null
        this.$modal     = null
        this.$backdrop  = null
        this.isOpen     = false
        this.firstDiv   = null
        this.allowHide  = true

        this.lastScrollPos = -1;

        this.$container = this.createPopupContainer()
        this.$content = this.$container.find('.modal-content:first')
        this.$modal = this.$container.modal({ show: false, backdrop: false, keyboard: this.options.keyboard })

        /*
         * Duplicate the popup reference on the .control-popup container
         */
        this.$container.data('oc.popup', this)

        /*
         * Hook in to BS Modal events
         */
        this.$modal.on('hide.bs.modal', function(){
            self.triggerEvent('hide.oc.popup')
            self.isOpen = false
            self.setBackdrop(false)
        })

        this.$modal.on('hidden.bs.modal', function(){
            self.triggerEvent('hidden.oc.popup')
            self.$container.remove()
            self.$el.data('oc.popup', null)
            $(document.body).removeClass('modal-open')
        })

        this.$modal.on('show.bs.modal', function(){
            self.isOpen = true
            self.setBackdrop(true)
            $(document.body).addClass('modal-open')
        })

        this.$modal.on('shown.bs.modal', function(){
            self.triggerEvent('shown.oc.popup')
            $(document).trigger('render')
        })

        this.$modal.on('close.oc.popup', function(){
            self.hide()
            return false
        })

        this.init()
    }

    Popup.DEFAULTS = {
        ajax: null,
        handler: null,
        keyboard: true,
        extraData: {},
        content: null,
        size: null,
        adaptiveHeight: false,
        zIndex: null
    }

    Popup.prototype.init = function() {
        var self = this

        /*
         * Do not allow the same popup to open twice
         */
        if (self.isOpen)
            return

        /*
         * Show loading panel
         */
        this.setBackdrop(true)

        if (!this.options.content)
            this.setLoading(true)

        /*
         * October AJAX
         */
        if (this.options.handler) {
            this.$el.request(this.options.handler, {
                data: paramToObj('data-extra-data', this.options.extraData),
                success: function(data, textStatus, jqXHR) {
                    this.success(data, textStatus, jqXHR).done(function(){
                        self.setContent(data.result)
                        $(window).trigger('ajaxUpdateComplete', [this, data, textStatus, jqXHR])
                        self.triggerEvent('popupComplete') // Deprecated
                        self.triggerEvent('complete.oc.popup')
                    })
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    this.error(jqXHR, textStatus, errorThrown).done(function(){
                        self.hide()
                        self.triggerEvent('popupError') // Deprecated
                        self.triggerEvent('error.oc.popup')
                    })
                }
            })

        }

        /*
         * Regular AJAX
         */
        else if (this.options.ajax) {

            $.ajax({
                url: this.options.ajax,
                data: this.options.extraData,
                success: function(data) {
                    self.setContent(data)
                },
                cache: false
            })

        }

        /*
         * Specified content
         */
        else if (this.options.content) {

            var content = typeof this.options.content == 'function'
                ? this.options.content.call(this.$el[0], this)
                : this.options.content

            this.setContent(content)
        }
    }

    Popup.prototype.createPopupContainer = function() {
        var
            modal = $('
').prop({
                class: 'control-popup modal fade',
                role: 'dialog',
                tabindex: -1
            }),
            modalDialog = $('
').addClass('modal-dialog'),
            modalContent = $('
').addClass('modal-content');

        if (this.options.size)
            modalDialog.addClass('size-' + this.options.size)

        if (this.options.adaptiveHeight)
            modalDialog.addClass('adaptive-height')

        if (this.options.zIndex !== null)
            modal.css('z-index', this.options.zIndex + 20)

        return modal.append(modalDialog.append(modalContent))
    }

    Popup.prototype.setContent = function(contents) {
        this.$content.html(contents)
        this.setLoading(false)
        this.show()

        // Duplicate the popup object reference on to the first div
        // inside the popup. Eg: $('#firstDiv').popup('hide')
        this.firstDiv = this.$content.find('>div:first')
        if (this.firstDiv.length > 0)
            this.firstDiv.data('oc.popup', this)

        var form = this.$content.find('form:first')
        if (form.length) {
            var $firstField = form.find('input[type="text"], input[type="number"], input[type="email"], textarea').first()
            window.setTimeout(function () {
                $firstField.focus()
            }, 300)
        }
    }

    Popup.prototype.setBackdrop = function(val) {
        if (val && !this.$backdrop) {
            this.$backdrop = $('
')

            this.$modal.on('click.dismiss.bs.modal', $.proxy(function (e) {
              if (this.ignoreBackdropClick) {
                this.ignoreBackdropClick = false
                return
              }
              if (e.target !== e.currentTarget) return
              this.options.backdrop == 'static'
                ? this.$element[0].focus()
                : this.hide()
            }, this))

            if (this.options.zIndex !== null)
                this.$backdrop.css('z-index', this.options.zIndex)

            this.$backdrop.appendTo(document.body);

            this.$backdrop.addClass('in')
            this.$backdrop.append($('
'));
        }
        else if (!val && this.$backdrop) {
            this.$backdrop.remove()
            this.$backdrop = null
        }
    }

    Popup.prototype.setLoading = function(val) {
        if (!this.$backdrop)
            return;

        var self = this
        if (val) {
            setTimeout(function(){ self.$backdrop.addClass('loading'); }, 100)
        }
        else {
            this.$backdrop.removeClass('loading');
        }
    }

    Popup.prototype.hideLoading = function(val) {
        this.setLoading(false)

        // Wait for animations to complete
        var self = this
        setTimeout(function() { self.setBackdrop(false) }, 250)
        setTimeout(function() { self.hide() }, 500)
    }

    Popup.prototype.triggerEvent = function(eventName, params) {
        if (!params)
            params = [this.$el, this.$modal]

        var eventObject = jQuery.Event(eventName, { relatedTarget: this.$container.get(0) })

        this.$el.trigger(eventObject, params)

        if (this.firstDiv)
            this.firstDiv.trigger(eventObject, params)
    }

    Popup.prototype.reload = function() {
        this.init()
    }

    Popup.prototype.show = function() {
        this.$modal.modal('show')

        this.lastScrollPos = $(window).scrollTop();

        $('body').addClass('lock-screen');

        this.$modal.on('click.dismiss.popup', '[data-dismiss="popup"]', $.proxy(this.hide, this))
        this.triggerEvent('popupShow') // Deprecated
        this.triggerEvent('show.oc.popup')
    }

    Popup.prototype.hide = function() {
        this.triggerEvent('popupHide') // Deprecated
        this.triggerEvent('hide.oc.popup')

        $('body').removeClass('lock-screen');

        $(window).scrollTop(this.lastScrollPos);

        if (this.allowHide)
            this.$modal.modal('hide')
    }

    /*
     * Hide the popup without destroying it,
     * you should call .hide() once finished
     */
    Popup.prototype.visible = function(val) {
        if (val)
            this.$modal.addClass('in')
        else
            this.$modal.removeClass('in')
        this.setBackdrop(val)
    }

    Popup.prototype.toggle = function() {
        this.triggerEvent('popupToggle', [this.$modal]) // Deprecated
        this.triggerEvent('toggle.oc.popup', [this.$modal])

        this.$modal.modal('toggle')
    }

    /*
     * Lock the popup from closing
     */
    Popup.prototype.lock = function(val) {
        this.allowHide = !val
    }

    // POPUP PLUGIN DEFINITION
    // ============================

    var old = $.fn.popup

    $.fn.popup = function (option) {
        var args = Array.prototype.slice.call(arguments, 1)
        return this.each(function () {
            var $this   = $(this)
            var data    = $this.data('oc.popup')
            var options = $.extend({}, Popup.DEFAULTS, $this.data(), typeof option == 'object' && option)
            if (!data) $this.data('oc.popup', (data = new Popup(this, options)))
            else if (typeof option == 'string') data[option].apply(data, args)
            else data.reload()
        })
    }

    $.fn.popup.Constructor = Popup

    $.popup = function (option) {
        return $('').popup(option)
    }

    // POPUP NO CONFLICT
    // =================

    $.fn.popup.noConflict = function () {
        $.fn.popup = old
        return this
    }

    // POPUP DATA-API
    // ===============

    function paramToObj(name, value) {
        if (value === undefined) value = ''
        if (typeof value == 'object') return value

        try {
            return JSON.parse(JSON.stringify(eval("({" + value + "})")))
        }
        catch (e) {
            throw new Error('Error parsing the '+name+' attribute value. '+e)
        }
    }

    $(document).on('click.oc.popup', '[data-control="popup"]', function() {
        $(this).popup()

        return false
    });

    /*
     * Only use the popup loading indicator if the handlers are an exact match.
     */
    $(document)
        .on('ajaxPromise', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').removeClass('in').popup('setLoading', true)
        })
        .on('ajaxFail', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').addClass('in').popup('setLoading', false)
        })
        .on('ajaxDone', '[data-popup-load-indicator]', function(event, context) {
            if ($(this).data('request') != context.handler) return
            $(this).closest('.control-popup').popup('hideLoading')
        })

}(window.jQuery);
<|endoftext|>


<commit_before>"use strict"
const SerialPort = require("serialport").SerialPort;
const fs = require("fs");
const debug = require("debug")("create2:driver");
const Repl = require("repl");

function start(io, fs, debug){
  var irobotCommand = io.of('/irobotCommand').on('connection',function(socket){
    socket.on('message', function(data) {
      console.log(data);
      commands[data.id]();
    });
  });

    const path = getAvailableDevicePaths()[0];
    if (!path) {
      return "Device cannot use";
    }
    debug(`connect to ${path}`);
    const options = {
      baudRate: 115200,
      dataBits:8,
      parity:'none', stopBits:1,
      flowControl:false
    };
    //const port = new SerialPort(path, options);
    const port = new SerialPort("/dev/cu.usbserial-DA01NMCP", options);
    //const port = new SerialPort("/dev/ttyUSB0", options);

    let inputBuffer = null;

    port.on("data", (data) => {
      if (!inputBuffer) {
        inputBuffer = data;
      } else {
        inputBuffer = Buffer.concat([inputBuffer, data]);
      }

      debug(`${inputBuffer.length} Bytes received`);
      debug(inputBuffer.toJSON().data.toString());

      if (inputBuffer.length == 80) {
        debug("===== Clear");
        inputBuffer = null;
      }
    });

    port.on("open", () => {
      debug("connected");
      main();
    });

    function close() {
      debug("close");
      port.close();
      process.exit(0);
    }

    function drive(right, left) {
      const buf = new Buffer(5);
      buf[0] = 145;
      buf.writeInt16BE(right, 1);
      buf.writeInt16BE(left, 3);
      port.write(buf);
      debug(buf.toJSON().data.toString());
    }

    function write(data) {
      let arr = new Uint8Array(data.length);
      for(let i = 0; i < data.length; i++){
        arr[i] = data[i];
      }
      port.write(arr.buffer);
    }

    function main() {
        write([128]);
        write([131]);
        write([7]);
    }

      var commands=[
        () => { drive(-255, -255); },
        () => { drive(255, 255); },
        () => { drive(-80, 80); },
        () => { drive(80, -80); },
        () => { write([7])},
        () => { write([132])},
        () => { write([131])},
        () => { write([128]) },
        () => { write([139, 0, 125, 255]) },
        () => { write([139, 0, 0, 0]) },
        //(arr) =>{ port.write(Buffer.from(arr)) },
        () => { write([140, 3, 1, 64, 16, 141, 3])},
        //(str) => {var a = str.split("").map((c) => {return  c.charCodeAt();}); a.unshift(164); port.write(Buffer.from(a)); },
        //drive,
        () => { close() },
        () => { drive(0,0); }
     ];

    function getAvailableDevicePaths() {
      const paths = fs.readdirSync("/dev").map((d) => {
        if (d.includes("tty.usb")) {
          return "/dev/" + d;
        }
      }).filter(Boolean);
      return paths;
    }
}

exports.start = start;<commit_msg>commentout roomba path settings<commit_after>"use strict"
const SerialPort = require("serialport").SerialPort;
const fs = require("fs");
const debug = require("debug")("create2:driver");
const Repl = require("repl");

function start(io, fs, debug){
  var irobotCommand = io.of('/irobotCommand').on('connection',function(socket){
    socket.on('message', function(data) {
      console.log(data);
      commands[data.id]();
    });
  });

    /*const path = getAvailableDevicePaths()[0];
    if (!path) {
      return "Device cannot use";
    }
    debug(`connect to ${path}`);*/
    const options = {
      baudRate: 115200,
      dataBits:8,
      parity:'none', stopBits:1,
      flowControl:false
    };
    //const port = new SerialPort(path, options);
    //const port = new SerialPort("/dev/cu.usbserial-DA01NMCP", options);
    const port = new SerialPort("/dev/ttyUSB0", options);

    let inputBuffer = null;

    port.on("data", (data) => {
      if (!inputBuffer) {
        inputBuffer = data;
      } else {
        inputBuffer = Buffer.concat([inputBuffer, data]);
      }

      debug(`${inputBuffer.length} Bytes received`);
      debug(inputBuffer.toJSON().data.toString());

      if (inputBuffer.length == 80) {
        debug("===== Clear");
        inputBuffer = null;
      }
    });

    port.on("open", () => {
      debug("connected");
      main();
    });

    function close() {
      debug("close");
      port.close();
      process.exit(0);
    }

    function drive(right, left) {
      const buf = new Buffer(5);
      buf[0] = 145;
      buf.writeInt16BE(right, 1);
      buf.writeInt16BE(left, 3);
      port.write(buf);
      debug(buf.toJSON().data.toString());
    }

    function write(data) {
      let arr = new Uint8Array(data.length);
      for(let i = 0; i < data.length; i++){
        arr[i] = data[i];
      }
      port.write(arr.buffer);
    }

    function main() {
        write([128]);
        write([131]);
        write([7]);
    }

      var commands=[
        () => { drive(-255, -255); },
        () => { drive(255, 255); },
        () => { drive(-80, 80); },
        () => { drive(80, -80); },
        () => { write([7])},
        () => { write([132])},
        () => { write([131])},
        () => { write([128]) },
        () => { write([139, 0, 125, 255]) },
        () => { write([139, 0, 0, 0]) },
        //(arr) =>{ port.write(Buffer.from(arr)) },
        () => { write([140, 3, 1, 64, 16, 141, 3])},
        //(str) => {var a = str.split("").map((c) => {return  c.charCodeAt();}); a.unshift(164); port.write(Buffer.from(a)); },
        //drive,
        () => { close() },
        () => { drive(0,0); }
     ];

    function getAvailableDevicePaths() {
      const paths = fs.readdirSync("/dev").map((d) => {
        if (d.includes("tty.usb")) {
          return "/dev/" + d;
        }
      }).filter(Boolean);
      return paths;
    }
}

exports.start = start;<|endoftext|>