<commit_before>import React, { Component } from 'react';
import { Container, Button, Form, Message } from 'semantic-ui-react'
import Title from './Title';

class Home extends Component {

  constructor(props) {
    super(props);

    this.redditStateKey = "redditState";

    const { state, code } = this.props.location.query;
    if (state !== undefined && code !== undefined) {
      if (state === localStorage.getItem(this.redditStateKey, "")) {
        const { subject, message, users } = localStorage;
        if (subject !== undefined && message !== undefined && users !== undefined) {
          this.props.sendMessages(subject, message, JSON.parse(users), 'yummy ramen', code);
        }
      }
    }

    this.subjectKey = "subject";
    this.messageKey = "message";
    this.usersKey = "users";

    const redditState = this.createState();
    localStorage.setItem(this.redditStateKey, redditState);

    const base = window.location.origin;
    const url = `https://www.reddit.com/api/v1/authorize?scope=identity,privatemessages&response_type=code&redirect_uri=${base}&client_id=-Q-lrceF3GNtHw&state=${redditState}&duration=permanent`

    this.state = {
      subject: '',
      message: '',
      users: '',
      subjectEmpty: false,
      messageEmpty: false,
      usersOver10: false,
      noUsers: false,
      url
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.errorContent = this.errorContent.bind(this);
  }

  createState() {
    let state = "";
    const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (let i = 0; i < 5; i++) {
        state += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    return state;
  }

  redirectError() {
    console.log("error");
  }

  handleSubmit(e) {
    // validate input
    const subject = this.state.subject.trim();
    const message = this.state.message.trim();

    let users = this.state.users.split('\n');
    let cleanUsers = [];
    let cleanUser = '';
    for (let i = 0; i < users.length; i++) {
      cleanUser = users[i].trim();
      if (cleanUser !== '') {
        cleanUsers.push(cleanUser) ;
      }
    }

    let uniqueUsers = new Set(cleanUsers);
    cleanUsers = [...uniqueUsers];

    const subjectEmpty = subject === '';
    const messageEmpty = message === '';
    const usersOver10 = cleanUsers.length > 10;
    const noUsers = cleanUsers.length <= 0;

    if (subjectEmpty || messageEmpty || usersOver10 || noUsers) {
      this.setState({
        subjectEmpty,
        messageEmpty,
        usersOver10,
        noUsers
      });
    } else {
      localStorage.setItem(this.subjectKey, this.state.subject);
      localStorage.setItem(this.messageKey, this.state.message);
      localStorage.setItem(this.usersKey, JSON.stringify(cleanUsers));
      window.location = this.state.url;
    }

    e.preventDefault();
  }

  errorContent() {
    let errorMessages = [];
    if (this.state.subjectEmpty) {
      errorMessages.push('Subject cannot be empty');
    }
    if (this.state.messageEmpty) {
      errorMessages.push('Message cannot be empty');
    }
    if (this.state.usersOver10) {
      errorMessages.push('Can only message up to 10 users');
    }
    if (this.state.noUsers) {
      errorMessages.push('Users cannot be empty');
    }
    return errorMessages.join(' | ');
  }

  messageForm() {
    return (
    <Form onSubmit={this.handleSubmit} error={this.state.subjectEmpty || this.state.messageEmpty || this.state.usersOver10 || this.state.noUsers}>
      <Message
        error
        header='Error'
        content={this.errorContent()}
      />
      <Form.Field error={this.state.subjectEmpty} >
        Subject
        <input
          maxLength="99"
          name='subject'
          onChange={(e) => this.setState({subject: e.target.value, subjectEmpty: e.target.value.trim() === ''})}
          value={this.state.subject}/>
      </Form.Field>
      <Form.TextArea error={this.state.messageEmpty} name='message' label='Message' onChange={(e) => this.setState({message: e.target.value, messageEmpty: e.target.value.trim() === ''})} value={this.state.message} />
      <Form.TextArea error={this.state.usersOver10 || this.state.noUsers} name='users' placeholder='Add one user per line' label='Users (up to 10)' onChange={(e) => this.setState({users: e.target.value, noUsers: e.target.value.trim() === ''})} value={this.state.users} />
      <Button fluid={true} type='submit'>Send</Button>
    </Form>
    )
  }

  githubStarButton() {
    return (
      Star
    );
  }

  render() {
    return (

              <Container text>
                <Title />
                {this.githubStarButton()}
                {this.messageForm()}
              </Container>

    );
  }
}

export default Home;
<commit_msg>hardcode redirect uri<commit_after>import React, { Component } from 'react';
import { Container, Button, Form, Message } from 'semantic-ui-react'
import Title from './Title';

class Home extends Component {

  constructor(props) {
    super(props);

    this.redditStateKey = "redditState";

    const { state, code } = this.props.location.query;
    if (state !== undefined && code !== undefined) {
      if (state === localStorage.getItem(this.redditStateKey, "")) {
        const { subject, message, users } = localStorage;
        if (subject !== undefined && message !== undefined && users !== undefined) {
          this.props.sendMessages(subject, message, JSON.parse(users), 'yummy ramen', code);
        }
      }
    }

    this.subjectKey = "subject";
    this.messageKey = "message";
    this.usersKey = "users";

    const redditState = this.createState();
    localStorage.setItem(this.redditStateKey, redditState);

    const redirectUri = "http://benawad.com/nukool";
    const url = `https://www.reddit.com/api/v1/authorize?scope=identity,privatemessages&response_type=code&redirect_uri=${redirectUri}&client_id=-Q-lrceF3GNtHw&state=${redditState}&duration=permanent`

    this.state = {
      subject: '',
      message: '',
      users: '',
      subjectEmpty: false,
      messageEmpty: false,
      usersOver10: false,
      noUsers: false,
      url
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.errorContent = this.errorContent.bind(this);
  }

  createState() {
    let state = "";
    const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (let i = 0; i < 5; i++) {
        state += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    return state;
  }

  redirectError() {
    console.log("error");
  }

  handleSubmit(e) {
    // validate input
    const subject = this.state.subject.trim();
    const message = this.state.message.trim();

    let users = this.state.users.split('\n');
    let cleanUsers = [];
    let cleanUser = '';
    for (let i = 0; i < users.length; i++) {
      cleanUser = users[i].trim();
      if (cleanUser !== '') {
        cleanUsers.push(cleanUser) ;
      }
    }

    let uniqueUsers = new Set(cleanUsers);
    cleanUsers = [...uniqueUsers];

    const subjectEmpty = subject === '';
    const messageEmpty = message === '';
    const usersOver10 = cleanUsers.length > 10;
    const noUsers = cleanUsers.length <= 0;

    if (subjectEmpty || messageEmpty || usersOver10 || noUsers) {
      this.setState({
        subjectEmpty,
        messageEmpty,
        usersOver10,
        noUsers
      });
    } else {
      localStorage.setItem(this.subjectKey, this.state.subject);
      localStorage.setItem(this.messageKey, this.state.message);
      localStorage.setItem(this.usersKey, JSON.stringify(cleanUsers));
      window.location = this.state.url;
    }

    e.preventDefault();
  }

  errorContent() {
    let errorMessages = [];
    if (this.state.subjectEmpty) {
      errorMessages.push('Subject cannot be empty');
    }
    if (this.state.messageEmpty) {
      errorMessages.push('Message cannot be empty');
    }
    if (this.state.usersOver10) {
      errorMessages.push('Can only message up to 10 users');
    }
    if (this.state.noUsers) {
      errorMessages.push('Users cannot be empty');
    }
    return errorMessages.join(' | ');
  }

  messageForm() {
    return (
    <Form onSubmit={this.handleSubmit} error={this.state.subjectEmpty || this.state.messageEmpty || this.state.usersOver10 || this.state.noUsers}>
      <Message
        error
        header='Error'
        content={this.errorContent()}
      />
      <Form.Field error={this.state.subjectEmpty} >
        Subject
        <input
          maxLength="99"
          name='subject'
          onChange={(e) => this.setState({subject: e.target.value, subjectEmpty: e.target.value.trim() === ''})}
          value={this.state.subject}/>
      </Form.Field>
      <Form.TextArea error={this.state.messageEmpty} name='message' label='Message' onChange={(e) => this.setState({message: e.target.value, messageEmpty: e.target.value.trim() === ''})} value={this.state.message} />
      <Form.TextArea error={this.state.usersOver10 || this.state.noUsers} name='users' placeholder='Add one user per line' label='Users (up to 10)' onChange={(e) => this.setState({users: e.target.value, noUsers: e.target.value.trim() === ''})} value={this.state.users} />
      <Button fluid={true} type='submit'>Send</Button>
    </Form>
    )
  }

  githubStarButton() {
    return (
      Star
    );
  }

  render() {
    return (

              <Container text>
                <Title />
                {this.githubStarButton()}
                {this.messageForm()}
              </Container>

    );
  }
}

export default Home;
<|endoftext|>


<commit_before>import React from 'react';
import { Link } from 'react-router';
import CircularProgressbar from 'react-circular-progressbar';
import userSettings from '../containers/userSettings';

class Home extends React.Component {
  constructor() {
    super();
}

goToRepos() {
  this.context.router.push('/repos');
}

grabUserInfo() {
  fetch(`https://api.github.com/users/${this.props.username}`, {
    method: 'GET'
  })
  .then((res) => {return res.json(); })
  .then((response) => { alert(response.public_repos); })
  .catch(() => { alert('nah')})
}

  render(){
    return(

Mod 1 Repost:

22

Mod 1 Commits:

134

You VS Last Mod:

            <CircularProgressbar
              percentage={60}
              strokeWidth={20} />

14

Followers

            <button
            onClick={() => this.grabUserInfo()}
            ></button>

        <Link to='/repos'
          className='back back-right'>

        </Link>

    );
  }
};

export default userSettings(Home);
<commit_msg>Add api call to get all events of a user.<commit_after>import React from 'react';
import { Link } from 'react-router';
import CircularProgressbar from 'react-circular-progressbar';
import userSettings from '../containers/userSettings';

class Home extends React.Component {
  constructor() {
    super();
    this.state = {
      events: []
    }
}

goToRepos() {
  this.context.router.push('/repos');
}

grabUserInfo() {
  fetch(`https://api.github.com/users/${this.props.username}/events?page=0&callback`, {
    method: 'GET'
  })
  .then((res) => {return res.json(); })
  .then((response) => { console.log(response); })
  .catch(() => { alert('nah')})
}

  render(){
    return(

Mod 1 Repost:

22

Mod 1 Commits:

134

You VS Last Mod:

            <CircularProgressbar
              percentage={60}
              strokeWidth={20} />

14

Followers

            <button
            onClick={() => this.grabUserInfo()}
            ></button>

        <Link to='/repos'
          className='back back-right'>

        </Link>

    );
  }
};

export default userSettings(Home);
<|endoftext|>


<commit_before>'use strict'

var $ = window.jQuery

module.exports = MenuItem

/**
 * MenuItem Class
 * @class
 * @param {String} name The item name
 * @param {object} options The menu item options
 * @example

  tinymce.activeEditor.addMenuItem(new MenuItem('myAction',{
    icon: 'text',
    text: 'My Action',
    visible: true,
    disabled: true,
    onclick: function(){
     window.alert('overiden default onclick action')
    }
  }))

 */
function MenuItem (name, options) {
  this.name = name
  for (var key in options) {
    if (key !== 'visible' && key !== 'disabled') {
      this[key] = options[key]
    }
  }
  if (!options.id) {
    this.id = 'mce-plugin-headersfooters-' + camel2Dash(name)
  }
  if (options.visible === false) this.hide()
  if (options.disabled) this.disable()
}

/**
 * Returns the menu item UI control as a jquery object
 * @method
 * @returns {Array} the jquery object wrapped in jquery array of lenght 1
 * @example

    var menuElement = ui.menuItems.insertHeader.getUIControl()
    menuElement.css('color','red')

 */
MenuItem.prototype.getUIControl = function () {
  return $('#' + this.id)
}

/**
 * By default on click, the menu item logs on console it has been clicked and returns it to allow chainable behavior.
 * This method should be overriden after instanciation.
 * Be caution when ovveriding, please returns the menu item in the method to not break the chainable behavior allowed by the default implementation.
 * @method
 * @returns void
 */
MenuItem.prototype.onclick = function () {
  console.info('%s menu item has been clicked', this.name)
  return this
}

/**
 * Show the menu item UI control and returns it to allow chainable behavior.
 * @method
 * @returns {MenuItem} the menu item
 */
MenuItem.prototype.show = function () {
  this.getUIControl().show()
  return this
}

/**
 * Hide the menu item UI control and returns it to allow chainable behavior.
 * @method
 * @returns {MenuItem} the menu item
 */
MenuItem.prototype.hide = function () {
  this.getUIControl().hide()
  return this
}

/**
 * Disable the menu item and returns it to allow chainable behavior.
 * @method
 * @returns {MenuItem} the menu item.
 */
MenuItem.prototype.disable = function () {
  this.getUIControl().addClass('mce-disabled')
  return this
}

/**
 * Enable the menu item and returns it to allow chainable behavior.
 * @method
 * @returns {MenuItem} the menu item
 */
MenuItem.prototype.enable = function () {
  this.getUIControl().removeClass('mce-disabled')
  return this
}

/**
 * Converts a camel cased string to a dashed string
 * @function
 * @inner
 * @param {String} inputStr The input string to dasherize
 * @example
 *
    var s = 'helloWorld'
    camel2Dash(s)
    // -> hello-world

 */
function camel2Dash (inputStr) {
  if (!inputStr.replace) throw new Error('The replace() method is not available.')
  return inputStr.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
}
<commit_msg>define a promise to wait menu item rendering event from menusController plugin, and promisify MenuItem's methods<commit_after>'use strict'

var q = require('q')
var $ = window.jQuery

module.exports = MenuItem

/**
 * MenuItem Class
 * @class
 * @param {String} name The item name
 * @param {object} options The menu item options
 * @example
  tinymce.activeEditor.addMenuItem(new MenuItem('myAction',{
    icon: 'text',
    text: 'My Action',
    visible: true,
    disabled: true,
    onclick: function(){
     window.alert('overiden default onclick action')
    }
  }))
 */
function MenuItem (name, options) {
  this.name = name
  _setUIControlPromise(this)
  for (var key in options) {
    if (key !== 'visible' && key !== 'disabled') {
      this[key] = options[key]
    }
  }
  if (!options.id) {
    this.id = 'mce-plugin-headersfooters-' + camel2Dash(name)
  }
  if (options.visible === false) this.hide()
  if (options.disabled) this.disable()
}

/**
 * Returns the menu item UI control as a jquery object
 * @method
 * @returns {Promise} A promise resolved by the jquery wrapper of the menu item's node element
 * @example

    var menuElement = ui.menuItems.insertHeader.getUIControl()
    menuElement.css('color','red')

 */
MenuItem.prototype.getUIControl = function () {
  var that = this
  return this._renderingPromise.then(function () {
    return $('#' + that.id)
  })
}

/**
 * By default on click, the menu item logs on console it has been clicked and returns it to allow chainable behavior.
 * This method should be overriden after instanciation.
 * Be caution when ovveriding, please returns the menu item in the method to not break the chainable behavior allowed by the default implementation.
 * @method
 * @returns void
 */
MenuItem.prototype.onclick = function () {
  console.info('%s menu item has been clicked', this.name)
  return this
}

/**
 * Show the menu item UI control and returns it to allow chainable behavior.
 * @method
 * @returns {Promise} A promise resolved by the menu item
 */
MenuItem.prototype.show = function () {
  return this.getUIControl().then(function (uiControl) {
    uiControl.show()
    return uiControl
  })
}

/**
 * Hide the menu item UI control and returns it to allow chainable behavior.
 * @method
 * @returns {Promise} A promise resolved by the menu item
 */
MenuItem.prototype.hide = function () {
  return this.getUIControl().then(function (uiControl) {
    uiControl.hide()
    return uiControl
  })
}

/**
 * Disable the menu item and returns it to allow chainable behavior.
 * @method
 * @returns {Promise} A promise resolved by the menu item
 */
MenuItem.prototype.disable = function () {
  return this.getUIControl().then(function (uiControl) {
    uiControl.addClass('mce-disabled')
    return uiControl
  })
}

/**
 * Enable the menu item and returns it to allow chainable behavior.
 * @method
 * @returns {Promise} A promise resolved by the menu item
 */
MenuItem.prototype.enable = function () {
  return this.getUIControl().then(function (uiControl) {
    uiControl.removeClass('mce-disabled')
    return uiControl
  })
}

/**
 * Create a promise that will be resolved when the menu item will be rendered the first time.
 * This promise will be used by all methods needing to get the UI control (node element)
 * It returns nothing and it must be called on top of the MenuItem constructor
 * @method
 * @memberof MenuItem
 * @private
 * @param {MenuItem} that The context for the private method
 * @returns void
 */
function _setUIControlPromise (that) {
  var d = q.defer()
  var $body = $('body')
  console.log('$body', $body)
  $body.on('menusController:mceMenuRendered', function (evt, menuLabel) {
    $body.on('menusController:mceMenuItemRendered', function (evt, itemID) {
      if (itemID === that.id) d.resolve()
    })
  })
  that._renderingPromise = d.promise
}

/**
 * Converts a camel cased string to a dashed string
 * @function
 * @inner
 * @param {String} inputStr The input string to dasherize
 * @example
 *
    var s = 'helloWorld'
    camel2Dash(s)
    // -> hello-world

 */
function camel2Dash (inputStr) {
  if (!inputStr.replace) throw new Error('The replace() method is not available.')
  return inputStr.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
}
<|endoftext|>


<commit_before>import { withScriptjs, withGoogleMap, GoogleMap, TrafficLayer } from "react-google-maps";
const { SearchBox } = require("react-google-maps/lib/components/places/SearchBox");
import React from 'react';

const TrafficMapComponent = /*withScriptjs(*/withGoogleMap((props) => {
  var childs = [ props.markers ];
  if(props.showSearchBox) {
    var inputBox =
        React.createElement("input",
            { type:"text",
            placeholder : props.searchBoxText,
            style : {
                boxSizing: `border-box`,
                border: `1px solid transparent`,
                width: `240px`,
                height: `30px`,
                marginTop: `10px`,
                padding: `0 12px`,
                borderRadius: `3px`,
                boxShadow: `0 1px 6px rgba(0, 0, 0, 0.3)`,
                fontSize: `14px`,
                outline: `none`,
                textOverflow: `ellipses`}
            });

    var searchBox =
        React.createElement(SearchBox,
            { ref : props.onSearchBoxMounted,
            bounds : props.bounds,
            controlPosition : google.maps.ControlPosition.TOP_LEFT,
            onPlacesChanged : props.onPlacesChanged },
            inputBox
        );

    childs = [ searchBox, ...childs ];
  };

  if(props.showTrafficLayer) {
      var traffic = React.createElement(TrafficLayer, {  });
      childs = [ traffic, ...childs ]
  };

  return (
    React.createElement(
        GoogleMap,
        { defaultZoom : props.defaultZoom,
          onZoomChanged : props.onZoomChanged,
          onIdle : props.onIdle,
          defaultCenter : props.defaultCenter,
          onClick: props.onClick,
          center : props.center,
          options: props.options,
          ref : props.onMapMounted },
        childs))
})/*)*/;

export class GoogleMapComponent extends React.PureComponent {
    refs = {}
    searchBoxRef = {}
    state = {
      isMarkerShown: false,
    }

    componentDidMount() {
      this.delayedShowMarker()
    }

    delayedShowMarker = () => {
      setTimeout(() => {
        this.setState({ isMarkerShown: true })
      }, 3000)
    }

    render() {
      var loading = React.createElement("div", { className : this.props.mapLoadingContainer, style : { width: `100%` }}, "Loading");
      var container = React.createElement("div", { className : this.props.mapContainer});
      var mapElement = React.createElement("div", { style : { height: `100%` }});
      return (
        React.createElement(
          TrafficMapComponent,
          { key:"map",
            isMarkerShown: this.state.isMarkerShown,
            defaultZoom: this.props.defaultZoom,
            onZoomChanged: this.props.onZoomChanged,
            defaultCenter: this.props.defaultCenter,
            searchBoxText: this.props.searchBoxText,
            showSearchBox: this.props.showSearchBox,
            showTrafficLayer: this.props.showTrafficLayer,
            center: this.props.center,
            options: this.props.options,
            onPlacesChanged: () => {
                this.props.onPlacesChanged(this.searchBoxRef.getPlaces())
            },
            onIdle: this.props.onIdle,
            onMapMounted: this.props.onMapMounted,
            onSearchBoxMounted: ref => {
                this.searchBoxRef = ref;
            },
            markers: this.props.markers,
            onMarkerClick: () => {
                this.setState({ isMarkerShown: false })
                this.delayedShowMarker()
            },
            onClick: this.props.onClick,
            googleMapURL: "https://maps.googleapis.com/maps/api/js?key=" + this.props.apiKey + "&v=3.exp&libraries=geometry,drawing,places",
            loadingElement: loading,
            containerElement: container,
            mapElement: mapElement
          }))
    }
  }<commit_msg>Added withScriptjs again.<commit_after>import { withScriptjs, withGoogleMap, GoogleMap, TrafficLayer } from "react-google-maps";
const { SearchBox } = require("react-google-maps/lib/components/places/SearchBox");
import React from 'react';

const TrafficMapComponent = withScriptjs(withGoogleMap((props) => {
  var childs = [ props.markers ];
  if(props.showSearchBox) {
    var inputBox =
        React.createElement("input",
            { type:"text",
            placeholder : props.searchBoxText,
            style : {
                boxSizing: `border-box`,
                border: `1px solid transparent`,
                width: `240px`,
                height: `30px`,
                marginTop: `10px`,
                padding: `0 12px`,
                borderRadius: `3px`,
                boxShadow: `0 1px 6px rgba(0, 0, 0, 0.3)`,
                fontSize: `14px`,
                outline: `none`,
                textOverflow: `ellipses`}
            });

    var searchBox =
        React.createElement(SearchBox,
            { ref : props.onSearchBoxMounted,
            bounds : props.bounds,
            controlPosition : google.maps.ControlPosition.TOP_LEFT,
            onPlacesChanged : props.onPlacesChanged },
            inputBox
        );

    childs = [ searchBox, ...childs ];
  };

  if(props.showTrafficLayer) {
      var traffic = React.createElement(TrafficLayer, {  });
      childs = [ traffic, ...childs ]
  };

  return (
    React.createElement(
        GoogleMap,
        { defaultZoom : props.defaultZoom,
          onZoomChanged : props.onZoomChanged,
          onIdle : props.onIdle,
          defaultCenter : props.defaultCenter,
          onClick: props.onClick,
          center : props.center,
          options: props.options,
          ref : props.onMapMounted },
        childs))
}));

export class GoogleMapComponent extends React.PureComponent {
    refs = {}
    searchBoxRef = {}
    state = {
      isMarkerShown: false,
    }

    componentDidMount() {
      this.delayedShowMarker()
    }

    delayedShowMarker = () => {
      setTimeout(() => {
        this.setState({ isMarkerShown: true })
      }, 3000)
    }

    render() {
      var loading = React.createElement("div", { className : this.props.mapLoadingContainer, style : { width: `100%` }}, "Loading");
      var container = React.createElement("div", { className : this.props.mapContainer});
      var mapElement = React.createElement("div", { style : { height: `100%` }});
      return (
        React.createElement(
          TrafficMapComponent,
          { key:"map",
            isMarkerShown: this.state.isMarkerShown,
            defaultZoom: this.props.defaultZoom,
            onZoomChanged: this.props.onZoomChanged,
            defaultCenter: this.props.defaultCenter,
            searchBoxText: this.props.searchBoxText,
            showSearchBox: this.props.showSearchBox,
            showTrafficLayer: this.props.showTrafficLayer,
            center: this.props.center,
            options: this.props.options,
            onPlacesChanged: () => {
                this.props.onPlacesChanged(this.searchBoxRef.getPlaces())
            },
            onIdle: this.props.onIdle,
            onMapMounted: this.props.onMapMounted,
            onSearchBoxMounted: ref => {
                this.searchBoxRef = ref;
            },
            markers: this.props.markers,
            onMarkerClick: () => {
                this.setState({ isMarkerShown: false })
                this.delayedShowMarker()
            },
            onClick: this.props.onClick,
            googleMapURL: "https://maps.googleapis.com/maps/api/js?key=" + this.props.apiKey + "&v=3.exp&libraries=geometry,drawing,places",
            loadingElement: loading,
            containerElement: container,
            mapElement: mapElement
          }))
    }
  }<|endoftext|>


<commit_before>require('normalize.css/normalize.css');
require('styles/App.scss');

import React from 'react';
//获取图片相关数据
let imageDatas = require('../data/imageDatas.json');

//利用自执行函数，将图片名信息转成图片URL信息
imageDatas = (function genImageURL(imageDatasArr){
	for(var i = 0,j = imageDatasArr.length;i<j;i++){
		var singleImageData = imageDatasArr[i];

		singleImageData.imageURL = require('../images/' + singleImageData.fileName);

		imageDatasArr[i] = singleImageData;
	}
	return imageDatasArr;
})(imageDatas);

//imageDatas =genImageURL(imageDatas);

let yeomanImage = require('../images/yeoman.png');

var ImgFigure = React.createClass({
	render:function(){
		return (

					//这里的this.props相当于ImgFigure对象

{this.props.data.title}

		);
	}
});

class AppComponent extends React.Component {
	Constant:{
		centerPos:{
			left:0,
			right:0
		},
		hPosRange:{
			leftSecX:[0,0],
			rightSecx:[0,0],
			y:[0,0]
		},
		vPosRange:{
			topY:[0,0],
			x:[0,0]
		}
	}
	/*
	 *重新布局所有图片
     *@param centerIndex 指定居中排布哪个图片
     *
	 */
	rearrange:function(centerIndex){

	}

	getInitialStage:function(){
		return{
			imgsArrangeArr:[

			]
		}
	}

	//组件加载以后，为每张图片计算其位置的范围
  	ComponentDidMount:function(){

  		//拿到舞台大小
  		var stageDOM = React.findDOMNode(this.refs.stage),
  			stageW = stageDom.scrollWidth,
  			stageH = stageDom.scrollHeight,
  			halfStageW = Math.ceil(stageW / 2),
  			halfStageH = Math.ceil(stageH / 2);

  		//拿到一个imageFigure的大小
  		var ImgFigureDOM = React.findDOMNode(this.refs.ImgFigur0),
  			imgW = imgFigureDOM.scrollWidth,
  			imgH = imgFigureDOM.scrollHeight,
  			halfImgW = Math.ceil(imgW / 2),
  			halfImgH = Math.ceil(imgH / 2);
  	}

  	this.Constant.centerPos = {
  		left:halfStageW - halfImgW,
  		top:halfStageH - halfImgH
  	}
  	//计算左右侧图片排布位置的取值范围
  	this.Constant.hPosRange.leftSecX[0] = -halfImgW;
  	this.Constant.hPosRange.leftSecX[1] = halfStageW -halfImgW*3;
  	this.Constant.hPosRange.rightSecX[0] = halfStageW = halfImgW;
  	this.Constant.hPosRange.rightSecX[1] = stageW - halfImgW;
  	this.Constant.hPosRange.y[0] = -halfImgH;
  	this.Constant.hPosRange.y[1] = stageH - halfImgH;
	//计算上侧图片排布位置的取值范围
  	this.Constant.vPosRange.topY[0] = -halfImgH;
  	this.Constant.vPosRange.topY[1] = halfStageH -halfImgH * 3;
  	this.Constant.vPosRange.x[0] = halfImgW - imgW;
  	this.Constant.vPosRange.x[1] = halfImgW;
  	this.rearrange(0);

  	render() {
		var controllerUnits = [],
		imgFigures = [];
		//遍历imageDatas里的值给data方便ImgFigure里的标签调用
		imageDatas.forEach(function(value,index){

			if(!this.state.imgsArrangeArr[index]){
				this.stage.imgsArrangeArr[index] = {
					pos:{
						left:0,
						top:0
					}
				}
			}

			imgFigures.push(<ImgFigure ref={'imgFigure' + index} data={value}/>);
		}.bind(this));

	    return (

					{imgFigures}

					{controllerUnits}

	    );
	  }
	}

AppComponent.defaultProps = {
};

export default AppComponent;
<commit_msg>half finished<commit_after>require('normalize.css/normalize.css');
require('styles/App.scss');

import React from 'react';
var ReactDOM = require('react-dom');
//获取图片相关数据
let imageDatas = require('../data/imageDatas.json');

//利用自执行函数，将图片名信息转成图片URL信息
imageDatas = (function genImageURL(imageDatasArr){
	for(var i = 0,j = imageDatasArr.length;i<j;i++){
		var singleImageData = imageDatasArr[i];

		singleImageData.imageURL = require('../images/' + singleImageData.fileName);

		imageDatasArr[i] = singleImageData;
	}
	return imageDatasArr;
})(imageDatas);

//imageDatas =genImageURL(imageDatas);

/*
 *获取区间一个随机值
 */
function getRangeRandom(low,high){
	return Math.ceil(Math.random() * (high - low) + low);
}

let yeomanImage = require('../images/yeoman.png');

class ImgFigure extends React.Component{
	constructor(props) {
	  super(props);
	  this.state = {
	  	data: props.data,
	  	arrange:props.arrange
	  };
	}
	ComponentDidMount(){
  		this.timerID = setInterval(
  		  () => this.tick(),
  		  1000
  		);
  	}

	componentWillUnmount() {
  		 clearInterval(this.timerID);
  	}

  	tick(){
  		this.setState({

  		});
  	}
	render(){

		var styleObj = {};

		//如果props属性中指定了这张图片的位置，则使用
		if(this.state.arrange.pos){
			styleObj = this.state.arrange.pos;
		}

		return (

					//这里的this.props相当于

{this.state.data.title}

		);
	}
};

class AppComponent extends React.Component {
 	constructor(props) {
	    super(props);
	    this.state = {
	    	imgsArrangeArr:[
				{
					pos:{
						left:'0',
						top:'0'
					}
				}
			],
	        Constant:{
					centerPos:{
						left:'0',
						right:'0'
					},
					hPosRange:{
						leftSecX:[0,0],
						rightSecx:[0,0],
						y:[0,0]
					},
					vPosRange:{
						topY:[0,0],
						x:[0,0]
					}
				}

				/*重新布局所有图片
			     *@param centerIndex 指定居中排布哪个图片
			     */

	    };
  	}

	// getInitialStage(){
	// 	return{
	// 		imgsArrangeArr:[
	// 			{

	// 				pos:{
	// 					left:'0',
	// 					top:'0'
	// 				}
	// 			}
	// 		]
	// 	};
	// }

	rearrange(centerIndex){

		var imgsArrangeArr = this.state.imgsArrangeArr,
			Constant = this.state.Constant,
			centerPos = Constant.centerPos,
			hPosRange = Constant.hPosRange,
			vPosRange = Constant.vPosRange,
			hPosRangeLeftSecX = hPosRange.leftSecX,
			hPosRangeRightSecX = hPosRange.rightSecx,
			hPosRangeY = hPosRange.y,
			vPosRangeTopY = vPosRange.topY,
			vPosRangeX = vPosRange.x,

			imgsArrangeTopArr = [],
			topImgNum = Math.ceil(Math.random() * 2),//取一个或者不取
			topImgSpliceIndex = 0,

			imgsArrangeCenterArr = imgsArrangeArr.splice(centerIndex,1);

			//首先居中centerIndex的图片
			imgsArrangeCenterArr[0].pos = centerPos;

			//取出要布局上侧的图片的状态信息
			topImgSpliceIndex = Math.ceil(Math.random() * (imgsArrangeArr.length - topImgNum));

			imgsArrangeTopArr = imgsArrangeArr.splice(topImgSpliceIndex,topImgNum);

			//布局位于上侧的图片
			imgsArrangeTopArr.forEach(function(value,index){
				imgsArrangeTopArr[index].pos = {
					top:getRangeRandom(vPosRangeTopY[0],vPosRangeTopY[1]),
					left:getRangeRandom(vPosRangeX[0],vPosRangeX[1])
				}
			});
			//布局左右两侧图片
			for(var i=0,j=imgsArrangeArr.length,k = j / 2;i<j;i++){
				var hPosRangeLORX = null;

				if(i<k){
					hPosRangeLORX = hPosRangeLeftSecX;
				} else {
					hPosRangeLORX = hPosRangeRightSecX;
				}

				imgsArrangeArr[i].pos = {
					top:getRangeRandom(hPosRangeY[0],hPosRangeY[1]),
					left:getRangeRandom(hPosRangeLORX[0],hPosRangeLORX[1])
				}
				//alert(hPosRangeY[0]+hPosRangeY[1]);
			}

			if(imgsArrangeTopArr && imgsArrangeTopArr[0]){
				imgsArrangeArr.splice(topImgSpliceIndex,0,imgsArrangeTopArr[0]);
			}

			imgsArrangeArr.splice(centerIndex,0,imgsArrangeCenterArr[0]);

			this.setState({
				imgsArrangeArr:imgsArrangeArr
			});
	}

	//组件加载以后，为每张图片计算其位置的范围
  	componentDidMount(){
  		this.timerID = setTimeout(
  		  () => this.tick(),
  		  10
  		);

  		var stageDOM = ReactDOM.findDOMNode(this.refs.stage),
  			stageW = stageDOM.scrollWidth,
  			stageH = stageDOM.scrollHeight,
  			halfStageW = Math.ceil(stageW / 2),
  			halfStageH = Math.ceil(stageH / 2);

  		//拿到一个imageFigure的大小
  		var imgFigureDOM = ReactDOM.findDOMNode(this.refs.imgFigure0),
  			imgH = imgFigureDOM.scrollHeight,
  			imgW = imgFigureDOM.scrollWidth,
  			halfImgW = Math.ceil(imgW / 2),
  			halfImgH = Math.ceil(imgH / 2);

  		this.setState({
  			Constant:{
				centerPos:{
		  			left:halfStageW - halfImgW,
		  			top:halfStageH - halfImgH
		  		},
				hPosRange:{
					leftSecX:[-halfImgW,halfStageW - halfImgW*3],
					rightSecx:[halfStageW +  halfImgW,stageW - halfImgW],
					y:[-halfImgH,stageH - halfImgH]
				},
				vPosRange:{
					topY:[-halfImgH,halfStageH -halfImgH * 3],
					x:[halfStageW - imgW,halfStageW]
				}
			}

  		});

  		// this.state.Constant.centerPos = {
  		// 	left:halfStageW - halfImgW,
  		// 	top:halfStageH - halfImgH
  		// }

  	  	//计算左右侧图片排布位置的取值范围
  	  	// this.state.Constant.hPosRange.leftSecX[0] = -halfImgW;
  	  	// this.state.Constant.hPosRange.leftSecX[1] = halfStageW - halfImgW*3;
  	  	// this.state.Constant.hPosRange.rightSecX[0] = halfStageW +  halfImgW;
  	  	// this.state.Constant.hPosRange.rightSecX[1] = stageW - halfImgW;

  	  	// this.state.Constant.hPosRange.y[0] = -halfImgH;
  	  	// this.state.Constant.hPosRange.y[1] = stageH - halfImgH;

  		//计算上侧图片排布位置的取值范围
  	  	// this.state.Constant.vPosRange.topY[0] = -halfImgH;
  	  	// this.state.Constant.vPosRange.topY[1] = halfStageH -halfImgH * 3;
  	  	// this.state.Constant.vPosRange.x[0] = halfStageW - imgW;
  	  	// this.state.Constant.vPosRange.x[1] = halfStageW;

  	}

  	componentWillUnmount() {
  		 clearInterval(this.timerID);
  	}

  	tick(){
		this.rearrange(0);
  		//拿到舞台大小

  	}

  	render() {

		var controllerUnits = [],
		imgFigures = [];
		//遍历imageDatas里的值给data方便ImgFigure里的标签调用
		imageDatas.forEach(function(value,index){

			if(!this.state.imgsArrangeArr[index]){
				this.state.imgsArrangeArr[index] = {
					pos:{
						left:'0',
						top:'0'
					}
				}
			}

			imgFigures.push(<ImgFigure ref={'imgFigure' + index} data={value} arrange={this.state.imgsArrangeArr[index]}/>);
		}.bind(this));

	    return (

					{imgFigures}

					{controllerUnits}

	    );
	  }
	}

AppComponent.defaultProps = {
};

export default AppComponent;
<|endoftext|>


<commit_before>var eachBlog = require('../each/blog');
var request = require('request');

eachBlog(function(user, blog, next){

  if (user.isDisabled || blog.isDisabled) return next();

  if (!blog.domain) {
    console.log('x http://'+ blog.handle +'.blot.im');
    return next();
  }

  var options = {

    // Change this to https is the
    // user requries SSL to visit blog
    uri: 'http://' + blog.domain + '/verify/domain-setup',

    timeout: 1000,

    // The request module has a known bug
    // which leaks memory and event emitters
    // during redirects. We cap the maximum
    // redirects to 5 to avoid encountering
    // errors when it creates 10+ emitters
    // for a URL with 10+ redirects...
    maxRedirects: 5
  };

  request(options, function(err, res, body){

    if (err) {return next();}

    if (body !== blog.handle) return next();

    console.log('YES https://' + blog.domain + ' (' + blog.handle + ')');

    next();
  });

}, process.exit);<commit_msg>updated script for listing blogs<commit_after>var eachBlog = require('../each/blog');
var request = require('request');

var custom_domain = {custom: []};
var sub_domain = {custom: []};

eachBlog(function(user, blog, next){

  if (user.isDisabled || blog.isDisabled) return next();

  console.log('...', blog.handle);

  if (!blog.domain) {

    if (blog.template.indexOf('SITE') !== -1) {
      sub_domain[blog.template] = sub_domain[blog.template] || [];
      sub_domain[blog.template].push(blog.handle);
    } else {
      sub_domain.custom.push(blog.handle);
    }

    return next();
  }

  var options = {

    // Change this to https is the
    // user requries SSL to visit blog
    uri: 'http://' + blog.domain + '/verify/domain-setup',

    timeout: 1000,

    // The request module has a known bug
    // which leaks memory and event emitters
    // during redirects. We cap the maximum
    // redirects to 5 to avoid encountering
    // errors when it creates 10+ emitters
    // for a URL with 10+ redirects...
    maxRedirects: 5
  };

  request(options, function(err, res, body){

    if (err) {return next();}

    if (body !== blog.handle) return next();

    if (blog.template.indexOf('SITE') !== -1) {
      blog.template = blog.template.slice('SITE:'.length);
      custom_domain[blog.template] = custom_domain[blog.template] || [];
      custom_domain[blog.template].push(blog.domain);
    } else {
      custom_domain.custom.push(blog.domain);
    }

    next();
  });

}, function(){

  console.log();
  console.log();
  console.log();
  console.log('CUSTOM DOMAINS');
  console.log('--------------');

  for (var i in custom_domain) {

    var list = custom_domain[i];

    console.log(i);

    list.forEach(function(d){
      console.log('- https://' + d);
    });

    console.log();

  }

  // console.log('SUB DOMAINS');
  // console.log('-----------');
  // console.log(sub_domain);
});<|endoftext|>


<commit_before>require('normalize.css');
require('styles/App.css');

import React from 'react/addons';

let yeomanImage = require('../images/yeoman.png');

var Concert = React.createClass({
  render: function () {
    return (

          {this.props.concert.artist}
           -
          {this.props.concert.venue}
           -
          {this.props.concert.date}

          <button className="btn btn-xs btn-danger glyphicon glyphicon-remove"
            ></button>

    );
  }
});

var ConcertList = React.createClass({
  render: function () {
    var rows = [];
    this.props.concertList.concerts.forEach(function (concertIter) {

      rows.push(<Concert concert={concertIter} key={concertIter.description}/>);

    });
    return (

{this.props.concertList.concertType.description}

{rows}

    );
  }
});

var ConcertLists = React.createClass({
  render: function () {
    var columns = [];
    this.props.concertLists.forEach(function (concertListIter) {

      columns.push(

          <ConcertList concertList={concertListIter}/>

      );

    });
    return (

{columns}

    );
  }
});

var NewConcertForm = React.createClass({
  handleSubmit: function (e) {
    e.preventDefault();

    var artistNode=React.findDOMNode(this.refs.artist);
    var artist = artistNode.value.trim();
    var venueNode=React.findDOMNode(this.refs.venue);
    var venue = venueNode.value.trim();
    var dateNode=React.findDOMNode(this.refs.date);
    var date = dateNode.value.trim();
    if (!artist || !venue || !date) {
      return;
    }
    this.props.onConcertSubmit({artist: artist, venue: venue, date: date});
    artistNode.value = '';
    venueNode.value = '';
    dateNode.value = '';
    return;
  },

  render: function () {
    return (

          <form name="addConcertForm" noValidate className="form-inline" role="form" onSubmit={this.handleSubmit}>

              Artist
              <input type="text" placeholder="Künstler"
                     required ref="artist"/>

              Ort
              <input type="text"  placeholder="Ort" required ref="venue"/>

              Datum
              <input type="datetime"  placeholder="Datum" required ref="date"/>

            <button
              className="btn btn-success glyphicon glyphicon-plus"
              type="submit"></button>
          </form>

    );
  }
});

var ConcertPicker = React.createClass({
  getInitialState: function () {
    return {
      concertLists: CONCERTLISTS,
      newConcert: {}
    };
  },
  handleConcertSubmit: function (concert) {
    //FIXME dreckig!
    var allConcerts = this.state.concertLists[1].concerts;
    var allConcertsPlusOne = allConcerts.concat([concert]);

    var allThreeLists = this.state.concertLists;
    allThreeLists[1].concerts = allConcertsPlusOne;

    this.setState({
      concertLists: allThreeLists,
      newConcert: {}
    });
  },
  render: function () {
    return (

        <ConcertLists concertLists={this.state.concertLists} newConcert={this.state.newConcert}/>
        <NewConcertForm onConcertSubmit={this.handleConcertSubmit}
                        newConcert={this.state.newConcert}/>

    );
  }
});

var CONCERTLISTS = [
  {
    concertType: {id: 'MAYBE', description: 'Vielleicht'},
    concerts: [
      {
        artist: 'Slayer',
        venue: 'Duesseldorf Stahlwerk',
        date: '12.02.2016'
      }
    ]
  },
  {
    concertType: {id: 'ALL', description: 'Alle Konzerte'},
    concerts: [
      {
        artist: 'Kolmogoroth',
        venue: 'Köln Blue Shell',
        date: '12.07.2016'
      }
    ]
  },
  {
    concertType: {id: 'MUSTGO', description: 'Auf jeden Fall hingehen'},
    concerts: [
      {
        artist: 'Backstreet Boys',
        venue: 'Mettmann Baumarkt',
        date: '12.01.2016'
      }
    ]
  }

];

//Hmmm raff ich das?
class AppComponent extends React.Component {
  render() {
    return (

            <ConcertPicker  />

    );
  }
}

AppComponent.defaultProps = {};

export default AppComponent;
<commit_msg>Adding and Removing refactored and working<commit_after>require('normalize.css');
require('styles/App.css');

import React from 'react/addons';

import lodash from 'lodash';

let yeomanImage = require('../images/yeoman.png');

var Concert = React.createClass({
  handleRemoveConcert: function(e) {
    e.preventDefault();
    this.props.onRemoveConcert(this.props.concertType, this.props.concert);
  },

  render: function () {
    return (

          {this.props.concert.artist}
           -
          {this.props.concert.venue}
           -
          {this.props.concert.date}

          <button className="btn btn-xs btn-danger glyphicon glyphicon-remove" onClick={this.handleRemoveConcert}
            ></button>

    );
  }
});

var ConcertList = React.createClass({
  render: function () {
    var rows = [];
    var concertType = this.props.concertType;
    var removeCallback = this.props.onRemoveConcert;
    this.props.concertList.concerts.forEach(function (concertIter) {

      rows.push(<Concert concert={concertIter} concertType={concertType} key={concertIter.description} onRemoveConcert={removeCallback}/>);

    });
    return (

{this.props.concertList.concertType.description}

{rows}

    );
  }
});

var ConcertLists = React.createClass({
  render: function () {
    var columns = [];
    var removeCallback = this.props.onRemoveConcert
    this.props.concertLists.forEach(function (concertListIter) {
      columns.push(

          <ConcertList concertList = {concertListIter} concertType = {concertListIter.concertType} onRemoveConcert = {removeCallback}/>

      );

    });
    return (

{columns}

    );
  }
});

var NewConcertForm = React.createClass({
  handleSubmit: function (e) {
    e.preventDefault();

    var artistNode=React.findDOMNode(this.refs.artist);
    var artist = artistNode.value.trim();
    var venueNode=React.findDOMNode(this.refs.venue);
    var venue = venueNode.value.trim();
    var dateNode=React.findDOMNode(this.refs.date);
    var date = dateNode.value.trim();
    if (!artist || !venue || !date) {
      return;
    }
    this.props.onConcertSubmit({artist: artist, venue: venue, date: date});
    artistNode.value = '';
    venueNode.value = '';
    dateNode.value = '';
    return;
  },

  render: function () {
    return (

          <form name="addConcertForm" noValidate className="form-inline" role="form" onSubmit={this.handleSubmit}>

              Artist
              <input type="text" placeholder="Künstler"
                     required ref="artist"/>

              Ort
              <input type="text"  placeholder="Ort" required ref="venue"/>

              Datum
              <input type="datetime"  placeholder="Datum" required ref="date"/>

            <button
              className="btn btn-success glyphicon glyphicon-plus"
              type="submit"></button>
          </form>

    );
  }
});

var ConcertPicker = React.createClass({
  getInitialState: function () {
    return {
      concertLists: CONCERTLISTS,
      newConcert: {}
    };
  },

  handleConcertSubmit: function (concert) {

    //FIXME dreckig!

    var ALLE_KONZERTE = {id: 'ALL', description: 'Alle Konzerte'};
    var allConcertList = this.findListForConcertType(ALLE_KONZERTE);

    var allConcertsPlusOne = allConcertList.concerts.concat([concert]);

    var allThreeLists = this.state.concertLists;
    allThreeLists[this.findIndexForConcertList(allConcertList)].concerts = allConcertsPlusOne;

    this.setState({
      concertLists: allThreeLists,
      newConcert: {}
    });
  },

  findListForConcertType: function(concertType) {
    return _.find(this.state.concertLists,function(obj){return obj.concertType.id == concertType.id})
  },

  findIndexForConcertList: function(concertList) {
    return _.indexOf(this.state.concertLists, concertList);
  },

  handleRemoveConcert: function (concertType, concert) {
    var myList = this.findListForConcertType(concertType);
    var listWithRemoval = _.remove(myList, function(concertIter) {
      return concert === concertIter;

    });
    var allThreeLists = this.state.concertLists;
    var idx = this.findIndexForConcertList(myList);
    allThreeLists[idx].concerts = listWithRemoval;

    this.setState({
      concertLists: allThreeLists,
      newConcert: {}
    });
  },

  render: function () {
    return (

        <ConcertLists concertLists={this.state.concertLists} newConcert={this.state.newConcert} onRemoveConcert={this.handleRemoveConcert}/>
        <NewConcertForm onConcertSubmit={this.handleConcertSubmit}
                        newConcert={this.state.newConcert}/>

    );
  }
});

var CONCERTLISTS = [
  {
    concertType: {id: 'MAYBE', description: 'Vielleicht'},
    concerts: [
      {
        artist: 'Slayer',
        venue: 'Duesseldorf Stahlwerk',
        date: '12.02.2016'
      }
    ]
  },
  {
    concertType: {id: 'ALL', description: 'Alle Konzerte'},
    concerts: [
      {
        artist: 'Kolmogoroth',
        venue: 'Köln Blue Shell',
        date: '12.07.2016'
      }
    ]
  },
  {
    concertType: {id: 'MUSTGO', description: 'Auf jeden Fall hingehen'},
    concerts: [
      {
        artist: 'Backstreet Boys',
        venue: 'Mettmann Baumarkt',
        date: '12.01.2016'
      }
    ]
  }

];

//Hmmm raff ich das?
class AppComponent extends React.Component {
  render() {
    return (

            <ConcertPicker  />

    );
  }
}

AppComponent.defaultProps = {};

export default AppComponent;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

arequire = function(modelName) {
  var THIS = this === GLOBAL ? X : this;
  return function(ret) {
    var m = THIS.lookup(modelName)
    ret(m);
  };
};
<commit_msg>Added warning to NullModelDAO for missing models in packaged apps<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

arequire = function(modelName) {
  var THIS = this === GLOBAL ? X : this;
  return function(ret) {
    var m = THIS.lookup(modelName)
    if ( ! m ) console.warn("Model missing from package:", modelName);
    ret(m);
  };
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Simple template system modelled after JSP's.
 *
 * Syntax:
 *    <% code %>: code inserted into template, but nothing implicitly output
 *    <%= comma-separated-values %>: all values are appended to template output
 *    <%# expression %>: dynamic (auto-updating) expression is output
 *    \<new-line>: ignored
 *    %%value(<whitespace>|<): output a single value to the template output
 *    $$feature(<whitespace>|<): output the View or Action for the current Value
 */

MODEL({
  name: 'TemplateParser',
  extends: 'grammar',

  methods: {
    START: sym('markup'),

    markup: repeat0(alt(
      sym('comment'),
      sym('foamTag'),
      sym('create child'),
      sym('simple value'),
      sym('live value tag'),
      sym('raw values tag'),
      sym('values tag'),
      sym('code tag'),
      sym('ignored newline'),
      sym('newline'),
      sym('single quote'),
      sym('text')
    )),

    'comment': seq1(1, '<!--', repeat0(not('-->', anyChar)), '-->'),

    'foamTag': sym('foamTag_'),
    'foamTag_': function() { }, // placeholder until gets filled in after HTMLParser is built

    'create child': seq(
      '$$',
      repeat(notChars(' $\r\n<{,.')),
      optional(JSONParser.export('objAsString'))),

    'simple value': seq('%%', repeat(notChars(' ()-"\r\n><:;,')), optional('()')),

    'live value tag': seq('<%#', repeat(not('%>', anyChar)), '%>'),

    'raw values tag': alt(
      seq('<%=', repeat(not('%>', anyChar)), '%>'),
      seq('{{{', repeat(not('}}}', anyChar)), '}}}')
    ),

    'values tag': seq('{{', repeat(not('}}', anyChar)), '}}'),

    'code tag': seq('<%', repeat(not('%>', anyChar)), '%>'),
    'ignored newline': alt(
      literal('\\\r\\\n'),
      literal('\\\n')
    ),
    newline: alt(
      literal('\r\n'),
      literal('\n')
    ),
    'single quote': literal("'"),
    text: anyChar
  }
});

var TemplateOutput = {
  /**
   * obj - Parent object.  If objects are output and have an initHTML() method, then they
   * are added to the parent by calling obj.addChild().
   **/
  // TODO(kgr): redesign, I think this is actually broken.  If we call appendHTML() of
  // a sub-view then it will be added to the wrong parent.
  create: function(obj) {
    console.assert(obj, 'Owner required when creating TemplateOutput.');
    var buf = [];
    var f = function templateOut(/* arguments */) {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        var o = arguments[i];
        if ( typeof o === 'string' ) {
          buf.push(o);
        } else if ( o && 'Element' === o.name_ ) {
          // Temporary bridge for working with foam.u2 Views
          var s = o.createOutputStream();
          o.output(s);
          buf.push(s.toString());
          // Needs to be bound, since o is a loop variable and will otherwise
          // be the final element of the arguments array, not the correct one.
          obj.addChild({ initHTML: o.load.bind(o) });
        } else {
          if ( o && o.toView_ ) o = o.toView_();
          if ( ! ( o === null || o === undefined ) ) {
            if ( o.appendHTML ) {
              o.appendHTML(this);
            } else if ( o.toHTML ) {
              buf.push(o.toHTML());
            } else {
              buf.push(o);
            }
            if ( o.initHTML && obj && obj.addChild ) obj.addChild(o);
          }
        }
      }
    };

    f.toString = function() {
      if ( buf.length === 0 ) return '';
      if ( buf.length > 1 ) buf = [buf.join('')];
      return buf[0];
    }

    return f;
  }
};

// Called from generated template code.
function elementFromString(str) {
  return str.element || ( str.element = HTMLParser.create().parseString(str).children[0] );
}

var ConstantTemplate = function(str) {
  var TemplateOutputCreate = TemplateOutput.create.bind(TemplateOutput);
  var f = function(opt_out) {
    var out = opt_out ? opt_out : TemplateOutputCreate(this);
    out(str);
    return out.toString();
  };

  f.toString = function() {
    return 'ConstantTemplate("' + str.replace(/\n/g, "\\n").replace(/"/g, '\\"').replace(/\r/g, '') + '")';
  };

  return f;
};

var TemplateCompiler = {
  __proto__: TemplateParser,

  out: [],

  simple: true, // True iff the template is just one string literal.

  push: function() { this.simple = false; this.pushSimple.apply(this, arguments); },

  pushSimple: function() { this.out.push.apply(this.out, arguments); }

}.addActions({
  markup: function (v) {
    var wasSimple = this.simple;
    var ret = wasSimple ? null : this.out.join('');
    this.out = [];
    this.simple = true;
    return [wasSimple, ret];
  },

  'create child': function(v) {
    var name = v[1].join('');
    this.push(
      "', self.createTemplateView('", name, "'",
      v[2] ? ', ' + v[2] : '',
      "),\n'");
  },
  foamTag: function(e) {
    // A Feature
    var fName = e.getAttribute('f');
    if ( fName ) {
      this.push("', self.createTemplateView('", fName, "',{}).fromElement(FOAM(");
      this.push(JSONUtil.where(NOT_TRANSIENT).stringify(e));
      this.push('))');
    }
    // A Model
    else {
      this.push("', (function() { var tagView = X.foam.ui.FoamTagView.create({element: FOAM(");
      this.push(JSONUtil.where(NOT_TRANSIENT).stringify(e));
      this.push(')}, Y); self.addDataChild(tagView); return tagView; })() ');
    }

    this.push(",\n'");
  },
  'simple value': function(v) { this.push("',\n self.", v[1].join(''), v[2], ",\n'"); },
  'raw values tag': function (v) { this.push("',\n", v[1].join(''), ",\n'"); },
  'values tag':     function (v) { this.push("',\nescapeHTML(", v[1].join(''), "),\n'"); },
  'live value tag': function (v) { this.push("',\nself.dynamicTag('span', function() { return ", v[1].join(''), "; }.bind(this)),\n'"); },
  'code tag': function (v) { this.push("');\n", v[1].join(''), ";out('"); },
  'single quote': function () { this.pushSimple("\\'"); },
  newline: function () { this.pushSimple('\\n'); },
  text: function(v) { this.pushSimple(v); }
});

MODEL({
  name: 'TemplateUtil',

  constants: {
    HEADER: 'var self = this, X = this.X, Y = this.Y;' +
        'var out = opt_out ? opt_out : TOC(this);' +
        "out('",
    FOOTERS: {
      html: "');return out.toString();",
      css: "');return X.foam.grammars.CSSDecl.create({model:this.model_}).parser.parseString(out.toString());"
    },
  },

  methods: {
    /** Create a method which only compiles the template when first used. **/
    lazyCompile: function(t) {
      var delegate;

      var f = function() {
        if ( ! delegate ) {
          if ( ! t.template )
            throw 'Must arequire() template model before use for ' + this.name_ + '.' + t.name;
          else
            delegate = TemplateUtil.compile(Template.isInstance(t) ? t : Template.create(t), this.model_);
        }

        return delegate.apply(this, arguments);
      };

      f.toString = function() { return delegate ? delegate.toString() : t.toString(); };

      return f;
    },

    compile_: function(t, code, model) {
      var args = ['opt_out'];
      for ( var i = 0 ; i < t.args.length ; i++ ) {
        args.push(t.args[i].name);
      }
      return eval(
        '(function() { ' +
          'var escapeHTML = XMLUtil.escape, TOC = TemplateOutput.create.bind(TemplateOutput); ' +
          'return function(' + args.join(',') + '){' + code + '};})()' +
          (model && model.id ? '\n\n//# sourceURL=' + model.id.replace(/\./g, '/') + '.' + t.name + '\n' : ''));
    },
    parseCSS: function(t, model) {
      var parser = this.CSSParser_ || ( this.CSSParser_ = X.foam.grammars.CSSDecl.create());
      parser.model = model;
      return parser.parser.parseString(t).toString();
    },
    parseU2: function(t, model) {
      // TODO: temporary hack until onLoad() gets called sooner
      X.foam.u2.ElementParser.getPrototype();
      if ( ! X.foam.u2.ElementParser.parser__ )
        X.foam.u2.ElementParser.onLoad();

      var parser = this.U2Parser_ || ( this.U2Parser_ = X.foam.u2.ElementParser.parser__.create() );
      parser.modelName_ = cssClassize(model.id);
      return parser.parseString(t.trim()).toString();
    },
    compile: function(t, model) {
      if ( t.name !== 'CSS' ) {
        if ( model.isSubModel(X.lookup('foam.u2.Element')) ) {
          return eval('(function() { return ' + this.parseU2(t.template, model) + '; })()');
        }
        if ( t.template.startsWith('#U2') ) {
          var code = '(function() { return ' + this.parseU2(t.template.substring(3), model) + '; })()';
          return eval(code);
        }
      }
      // Parse result: [isSimple, maybeCode]: [true, null] or [false, codeString].
      var parseResult = TemplateCompiler.parseString(t.template);

      // Simple case, just a string literal
      if ( parseResult[0] )
        return ConstantTemplate(t.language === 'css' ?
            this.parseCSS(t.template, model) :
            t.template) ;

      var code = this.HEADER + parseResult[1] + this.FOOTERS[t.language];

      // Need to compile an actual method
      try {
        return this.compile_(t, code, model);
      } catch (err) {
        console.log('Template Error: ', err);
        console.log(parseResult);
        return function() {};
      }
    },

    /**
     * Combinator which takes a template which expects an output parameter and
     * converts it into a function which returns a string.
     */
    stringifyTemplate: function (template) {
      return function() {
        var buf = [];

        this.output(buf.push.bind(buf), obj);

        return buf.join('');
      };
    },

    expandTemplate: function(self, t, opt_X) {
      /*
       * If a template is supplied as a function, treat it as a multiline string.
       * Parse function arguments to populate template.args.
       * Load template from file if external.
       * Setup template future.
       */
      var X = opt_X || self.X;

      if ( typeof t === 'function' ) {
        t = X.Template.create({
          name: t.name,
          // ignore first argument, which should be 'opt_out'
          args: t.toString().match(/\((.*?)\)/)[1].split(',').slice(1).map(function(a) {
            return X.Arg.create({name: a.trim()});
          }),
          template: multiline(t)});
      } else if ( typeof t === 'string' ) {
        t = docTemplate = X.Template.create({
          name: 'body',
          template: t
        });
      } else if ( ! t.template && ! t.code ) {
        t = X.Template.create(t);
        var future = afuture();
        var path   = self.sourcePath;

        t.futureTemplate = future.get;
        path = path.substring(0, path.lastIndexOf('/')+1);
        path += t.path ? t.path : self.name + '_' + t.name + '.ft';

        if ( typeof vm == "undefined" || ! vm.runInThisContext ) {
          var xhr = new XMLHttpRequest();
          xhr.open("GET", path);
          xhr.asend(function(data) {
            t.template = data;
            future.set(Template.create(t));
          });
        } else {
          var fs = require('fs');
          fs.readFile(path, function(err, data) {
            t.template = data.toString();
            future.set(Template.create(t));
          });
        }
      } else if ( typeof t.template === 'function' ) {
        t.template = multiline(t.template);
      }

      if ( ! t.futureTemplate ) t.futureTemplate = aconstant(t);

      // We haven't FOAMalized the template, and there's no crazy multiline functions.
      // Note that Model and boostrappy models must use this case, as Template is not
      // yet defined at bootstrap time. Use a Template object definition with a bare
      // string template body in those cases.
      if ( ! t.template$ ) {
        t = ( typeof X.Template !== 'undefined' ) ? JSONUtil.mapToObj(X, t, X.Template) : t ;
      }

      return t;
    },

    expandModelTemplates: function(self) {
      var templates = self.templates;
      for ( var i = 0; i < templates.length; i++ ) {
        templates[i] = TemplateUtil.expandTemplate(self, templates[i]);
      }
    }
  }
});

/** Is actually synchronous but is replaced in ChromeApp with an async version. **/
var aeval = function(src) {
  return aconstant(eval('(' + src + ')'));
};

var aevalTemplate = function(t, model) {
  return aseq(
    t.futureTemplate,
    function(ret, t) {
      ret(TemplateUtil.lazyCompile(t));
    });
};

var escapeHTML = XMLUtil.escape, TOC = TemplateOutput.create.bind(TemplateOutput);
<commit_msg>TemplateUtil now passes Template to parseU2 so that it can parse depending on templates name (ie. initE vs toE).<commit_after>/**
 * @license
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Simple template system modelled after JSP's.
 *
 * Syntax:
 *    <% code %>: code inserted into template, but nothing implicitly output
 *    <%= comma-separated-values %>: all values are appended to template output
 *    <%# expression %>: dynamic (auto-updating) expression is output
 *    \<new-line>: ignored
 *    %%value(<whitespace>|<): output a single value to the template output
 *    $$feature(<whitespace>|<): output the View or Action for the current Value
 */

MODEL({
  name: 'TemplateParser',
  extends: 'grammar',

  methods: {
    START: sym('markup'),

    markup: repeat0(alt(
      sym('comment'),
      sym('foamTag'),
      sym('create child'),
      sym('simple value'),
      sym('live value tag'),
      sym('raw values tag'),
      sym('values tag'),
      sym('code tag'),
      sym('ignored newline'),
      sym('newline'),
      sym('single quote'),
      sym('text')
    )),

    'comment': seq1(1, '<!--', repeat0(not('-->', anyChar)), '-->'),

    'foamTag': sym('foamTag_'),
    'foamTag_': function() { }, // placeholder until gets filled in after HTMLParser is built

    'create child': seq(
      '$$',
      repeat(notChars(' $\r\n<{,.')),
      optional(JSONParser.export('objAsString'))),

    'simple value': seq('%%', repeat(notChars(' ()-"\r\n><:;,')), optional('()')),

    'live value tag': seq('<%#', repeat(not('%>', anyChar)), '%>'),

    'raw values tag': alt(
      seq('<%=', repeat(not('%>', anyChar)), '%>'),
      seq('{{{', repeat(not('}}}', anyChar)), '}}}')
    ),

    'values tag': seq('{{', repeat(not('}}', anyChar)), '}}'),

    'code tag': seq('<%', repeat(not('%>', anyChar)), '%>'),
    'ignored newline': alt(
      literal('\\\r\\\n'),
      literal('\\\n')
    ),
    newline: alt(
      literal('\r\n'),
      literal('\n')
    ),
    'single quote': literal("'"),
    text: anyChar
  }
});

var TemplateOutput = {
  /**
   * obj - Parent object.  If objects are output and have an initHTML() method, then they
   * are added to the parent by calling obj.addChild().
   **/
  // TODO(kgr): redesign, I think this is actually broken.  If we call appendHTML() of
  // a sub-view then it will be added to the wrong parent.
  create: function(obj) {
    console.assert(obj, 'Owner required when creating TemplateOutput.');
    var buf = [];
    var f = function templateOut(/* arguments */) {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        var o = arguments[i];
        if ( typeof o === 'string' ) {
          buf.push(o);
        } else if ( o && 'Element' === o.name_ ) {
          // Temporary bridge for working with foam.u2 Views
          var s = o.createOutputStream();
          o.output(s);
          buf.push(s.toString());
          // Needs to be bound, since o is a loop variable and will otherwise
          // be the final element of the arguments array, not the correct one.
          obj.addChild({ initHTML: o.load.bind(o) });
        } else {
          if ( o && o.toView_ ) o = o.toView_();
          if ( ! ( o === null || o === undefined ) ) {
            if ( o.appendHTML ) {
              o.appendHTML(this);
            } else if ( o.toHTML ) {
              buf.push(o.toHTML());
            } else {
              buf.push(o);
            }
            if ( o.initHTML && obj && obj.addChild ) obj.addChild(o);
          }
        }
      }
    };

    f.toString = function() {
      if ( buf.length === 0 ) return '';
      if ( buf.length > 1 ) buf = [buf.join('')];
      return buf[0];
    }

    return f;
  }
};

// Called from generated template code.
function elementFromString(str) {
  return str.element || ( str.element = HTMLParser.create().parseString(str).children[0] );
}

var ConstantTemplate = function(str) {
  var TemplateOutputCreate = TemplateOutput.create.bind(TemplateOutput);
  var f = function(opt_out) {
    var out = opt_out ? opt_out : TemplateOutputCreate(this);
    out(str);
    return out.toString();
  };

  f.toString = function() {
    return 'ConstantTemplate("' + str.replace(/\n/g, "\\n").replace(/"/g, '\\"').replace(/\r/g, '') + '")';
  };

  return f;
};

var TemplateCompiler = {
  __proto__: TemplateParser,

  out: [],

  simple: true, // True iff the template is just one string literal.

  push: function() { this.simple = false; this.pushSimple.apply(this, arguments); },

  pushSimple: function() { this.out.push.apply(this.out, arguments); }

}.addActions({
  markup: function (v) {
    var wasSimple = this.simple;
    var ret = wasSimple ? null : this.out.join('');
    this.out = [];
    this.simple = true;
    return [wasSimple, ret];
  },

  'create child': function(v) {
    var name = v[1].join('');
    this.push(
      "', self.createTemplateView('", name, "'",
      v[2] ? ', ' + v[2] : '',
      "),\n'");
  },
  foamTag: function(e) {
    // A Feature
    var fName = e.getAttribute('f');
    if ( fName ) {
      this.push("', self.createTemplateView('", fName, "',{}).fromElement(FOAM(");
      this.push(JSONUtil.where(NOT_TRANSIENT).stringify(e));
      this.push('))');
    }
    // A Model
    else {
      this.push("', (function() { var tagView = X.foam.ui.FoamTagView.create({element: FOAM(");
      this.push(JSONUtil.where(NOT_TRANSIENT).stringify(e));
      this.push(')}, Y); self.addDataChild(tagView); return tagView; })() ');
    }

    this.push(",\n'");
  },
  'simple value': function(v) { this.push("',\n self.", v[1].join(''), v[2], ",\n'"); },
  'raw values tag': function (v) { this.push("',\n", v[1].join(''), ",\n'"); },
  'values tag':     function (v) { this.push("',\nescapeHTML(", v[1].join(''), "),\n'"); },
  'live value tag': function (v) { this.push("',\nself.dynamicTag('span', function() { return ", v[1].join(''), "; }.bind(this)),\n'"); },
  'code tag': function (v) { this.push("');\n", v[1].join(''), ";out('"); },
  'single quote': function () { this.pushSimple("\\'"); },
  newline: function () { this.pushSimple('\\n'); },
  text: function(v) { this.pushSimple(v); }
});

MODEL({
  name: 'TemplateUtil',

  constants: {
    HEADER: 'var self = this, X = this.X, Y = this.Y;' +
        'var out = opt_out ? opt_out : TOC(this);' +
        "out('",
    FOOTERS: {
      html: "');return out.toString();",
      css: "');return X.foam.grammars.CSSDecl.create({model:this.model_}).parser.parseString(out.toString());"
    },
  },

  methods: {
    /** Create a method which only compiles the template when first used. **/
    lazyCompile: function(t) {
      var delegate;

      var f = function() {
        if ( ! delegate ) {
          if ( ! t.template )
            throw 'Must arequire() template model before use for ' + this.name_ + '.' + t.name;
          else
            delegate = TemplateUtil.compile(Template.isInstance(t) ? t : Template.create(t), this.model_);
        }

        return delegate.apply(this, arguments);
      };

      f.toString = function() { return delegate ? delegate.toString() : t.toString(); };

      return f;
    },

    compile_: function(t, code, model) {
      var args = ['opt_out'];
      for ( var i = 0 ; i < t.args.length ; i++ ) {
        args.push(t.args[i].name);
      }
      return eval(
        '(function() { ' +
          'var escapeHTML = XMLUtil.escape, TOC = TemplateOutput.create.bind(TemplateOutput); ' +
          'return function(' + args.join(',') + '){' + code + '};})()' +
          (model && model.id ? '\n\n//# sourceURL=' + model.id.replace(/\./g, '/') + '.' + t.name + '\n' : ''));
    },
    parseCSS: function(t, model) {
      var parser = this.CSSParser_ || ( this.CSSParser_ = X.foam.grammars.CSSDecl.create());
      parser.model = model;
      return parser.parser.parseString(t).toString();
    },
    parseU2: function(_, t, model) {
      // TODO: temporary hack until onLoad() gets called sooner
      X.foam.u2.ElementParser.getPrototype();
      if ( ! X.foam.u2.ElementParser.parser__ )
        X.foam.u2.ElementParser.onLoad();

      var parser = this.U2Parser_ || ( this.U2Parser_ = X.foam.u2.ElementParser.parser__.create() );
      parser.modelName_ = cssClassize(model.id);
      return parser.parseString(t.trim()).toString();
    },
    compile: function(t, model) {
      if ( t.name !== 'CSS' ) {
        // TODO: this doesn't work
        if ( model.isSubModel(X.lookup('foam.u2.Element')) ) {
          return eval('(function() { return ' + this.parseU2(t, t.template, model) + '; })()');
        }
        if ( t.template.startsWith('#U2') ) {
          var code = '(function() { return ' + this.parseU2(t, t.template.substring(3), model) + '; })()';
          return eval(code);
        }
      }
      // Parse result: [isSimple, maybeCode]: [true, null] or [false, codeString].
      var parseResult = TemplateCompiler.parseString(t.template);

      // Simple case, just a string literal
      if ( parseResult[0] )
        return ConstantTemplate(t.language === 'css' ?
            this.parseCSS(t.template, model) :
            t.template) ;

      var code = this.HEADER + parseResult[1] + this.FOOTERS[t.language];

      // Need to compile an actual method
      try {
        return this.compile_(t, code, model);
      } catch (err) {
        console.log('Template Error: ', err);
        console.log(parseResult);
        return function() {};
      }
    },

    /**
     * Combinator which takes a template which expects an output parameter and
     * converts it into a function which returns a string.
     */
    stringifyTemplate: function (template) {
      return function() {
        var buf = [];

        this.output(buf.push.bind(buf), obj);

        return buf.join('');
      };
    },

    expandTemplate: function(self, t, opt_X) {
      /*
       * If a template is supplied as a function, treat it as a multiline string.
       * Parse function arguments to populate template.args.
       * Load template from file if external.
       * Setup template future.
       */
      var X = opt_X || self.X;

      if ( typeof t === 'function' ) {
        t = X.Template.create({
          name: t.name,
          // ignore first argument, which should be 'opt_out'
          args: t.toString().match(/\((.*?)\)/)[1].split(',').slice(1).map(function(a) {
            return X.Arg.create({name: a.trim()});
          }),
          template: multiline(t)});
      } else if ( typeof t === 'string' ) {
        t = docTemplate = X.Template.create({
          name: 'body',
          template: t
        });
      } else if ( ! t.template && ! t.code ) {
        t = X.Template.create(t);
        var future = afuture();
        var path   = self.sourcePath;

        t.futureTemplate = future.get;
        path = path.substring(0, path.lastIndexOf('/')+1);
        path += t.path ? t.path : self.name + '_' + t.name + '.ft';

        if ( typeof vm == "undefined" || ! vm.runInThisContext ) {
          var xhr = new XMLHttpRequest();
          xhr.open("GET", path);
          xhr.asend(function(data) {
            t.template = data;
            future.set(Template.create(t));
          });
        } else {
          var fs = require('fs');
          fs.readFile(path, function(err, data) {
            t.template = data.toString();
            future.set(Template.create(t));
          });
        }
      } else if ( typeof t.template === 'function' ) {
        t.template = multiline(t.template);
      }

      if ( ! t.futureTemplate ) t.futureTemplate = aconstant(t);

      // We haven't FOAMalized the template, and there's no crazy multiline functions.
      // Note that Model and boostrappy models must use this case, as Template is not
      // yet defined at bootstrap time. Use a Template object definition with a bare
      // string template body in those cases.
      if ( ! t.template$ ) {
        t = ( typeof X.Template !== 'undefined' ) ? JSONUtil.mapToObj(X, t, X.Template) : t ;
      }

      return t;
    },

    expandModelTemplates: function(self) {
      var templates = self.templates;
      for ( var i = 0; i < templates.length; i++ ) {
        templates[i] = TemplateUtil.expandTemplate(self, templates[i]);
      }
    }
  }
});

/** Is actually synchronous but is replaced in ChromeApp with an async version. **/
var aeval = function(src) {
  return aconstant(eval('(' + src + ')'));
};

var aevalTemplate = function(t, model) {
  return aseq(
    t.futureTemplate,
    function(ret, t) {
      ret(TemplateUtil.lazyCompile(t));
    });
};

var escapeHTML = XMLUtil.escape, TOC = TemplateOutput.create.bind(TemplateOutput);
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import styled from 'styled-components'
import {
  PRIMARY_COLOR,
  FONT_FAMILY_SECONDARY,
  BOX_SHADOW_1
} from '../util/constants'

const TabListOuter = styled.div`
  display: flex;
  flex-direction: row;

  background: #fff;
  box-shadow: ${BOX_SHADOW_1}
`

export const TabList = ({
  children,
  activeIndex,
  onClick
}) => {
  const kids = React.Children.map(children, (child, index) => {
    return React.cloneElement(child, {
      active: activeIndex === index,
      onClick: () => onClick(index)
    })
  })

  return <TabListOuter>{kids}</TabListOuter>
}

const TabOuter = styled.div`
  padding: 16px 0;
  flex: 1;

  text-align:center;
  text-transform: uppercase;
  cursor: pointer;
  font-family: ${FONT_FAMILY_SECONDARY};

  ${({ active }) => {
    if (active) {
      return `border-bottom: 4px solid ${PRIMARY_COLOR};`
    }

    return `border-bottom: 4px solid transparent;`
  }}

  transition: border-bottom .2s ease-in;
`

export const Tab = ({
  children,
  onClick,
  active
}) => {
  return (
    <TabOuter
      onClick={onClick}
      active={active}
    >
      {children}
    </TabOuter>
  )
}

export const TabPanels = ({ children, activeIndex }) => {
  return (

{children[activeIndex]}

  )
}

export class Tabs extends Component {
  constructor (props) {
    super(props)

    this.state = { activeIndex: 0 }
  }

  render () {
    const children = React.Children.map(this.props.children, child => {
      if (child.type === TabPanels) {
        return React.cloneElement(child, { activeIndex: this.state.activeIndex })
      } else if (child.type === TabList) {
        return React.cloneElement(child, {
          activeIndex: this.state.activeIndex,
          onClick: activeIndex => this.setState({ activeIndex })
        })
      }

      return child
    })

    return (

{children}

    )
  }
}

export default Tabs
<commit_msg>Add support for styled tab sub components<commit_after>import React, { Component } from 'react'
import styled from 'styled-components'
import {
  PRIMARY_COLOR,
  FONT_FAMILY_SECONDARY,
  BOX_SHADOW_1
} from '../util/constants'

const TabListOuter = styled.div`
  display: flex;
  flex-direction: row;

  background: #fff;
  box-shadow: ${BOX_SHADOW_1}
`

export const TabList = ({
  className,
  children,
  activeIndex,
  onClick
}) => {
  const kids = React.Children.map(children, (child, index) => {
    return React.cloneElement(child, {
      active: activeIndex === index,
      onClick: () => onClick(index)
    })
  })

  return <TabListOuter className={className}>{kids}</TabListOuter>
}

const TabOuter = styled.div`
  padding: 16px 0;
  flex: 1;

  text-align:center;
  text-transform: uppercase;
  cursor: pointer;
  font-family: ${FONT_FAMILY_SECONDARY};

  ${({ active }) => {
    if (active) {
      return `border-bottom: 4px solid ${PRIMARY_COLOR};`
    }

    return `border-bottom: 4px solid transparent;`
  }}

  transition: border-bottom .2s ease-in;
`

export const Tab = ({
  children,
  onClick,
  active
}) => {
  return (
    <TabOuter
      onClick={onClick}
      active={active}
    >
      {children}
    </TabOuter>
  )
}

export const TabPanels = ({ children, activeIndex }) => {
  return (

{children[activeIndex]}

  )
}

export class Tabs extends Component {
  constructor (props) {
    super(props)

    this.state = { activeIndex: 0 }
  }

  render () {
    const children = React.Children.map(this.props.children, child => {
      if (
        child.type === TabPanels ||
        (child.type.displayName && child.type.displayName.indexOf('TabPanels') !== -1) // Hack for styled components
      ) {
        return React.cloneElement(child, { activeIndex: this.state.activeIndex })
      } else if (
        child.type === TabList ||
        (child.type.displayName && child.type.displayName.indexOf('TabList') !== -1) // Hack for styled components
      ) {
        return React.cloneElement(child, {
          activeIndex: this.state.activeIndex,
          onClick: activeIndex => this.setState({ activeIndex })
        })
      }

      return child
    })

    return (

{children}

    )
  }
}

export default Tabs
<|endoftext|>


<commit_before>module.exports = {
    // Keys and other mathematical constants
    KEY_ESC: 27,
    KEY_ENTER: 13,
    KEY_CHAT: 13,
    KEY_FIREFOOD: 119,
    KEY_SPLIT: 32,
    KEY_LEFT: 37,
    KEY_UP: 38,
    KEY_RIGHT: 39,
    KEY_DOWN: 40,
    borderDraw: false,
    spin: -Math.PI,
    enemySpin: -Math.PI,
    mobile: false,
    foodSides: 10,
    virusSides: 20,

    // Canvas
    screenWidth: window.innerWidth,
    screenHeight: window.innerHeight,
    gameWidth: 0,
    gameHeight: 0,
    xoffset: -0,
    yoffset: -0,
    gameStart: false,
    disconnected: false,
    died: false,
    kicked: false,
    continuity: false,
    startPingTime: 0,
    toggleMassState: 0,
    backgroundColor: '#f2fbff',
    lineColor: '#000000',
};
<commit_msg>add KEY_SPACE<commit_after>module.exports = {
    // Keys and other mathematical constants
    KEY_ESC: 27,
    KEY_ENTER: 13,
    KEY_CHAT: 13,
    KEY_FIREFOOD: 119,
    KEY_SPLIT: 32,
    KEY_LEFT: 37,
    KEY_UP: 38,
    KEY_RIGHT: 39,
    KEY_DOWN: 40,
    KEY_SPACE: 121,

    borderDraw: false,
    spin: -Math.PI,
    enemySpin: -Math.PI,
    mobile: false,
    foodSides: 10,
    virusSides: 20,

    // Canvas
    screenWidth: window.innerWidth,
    screenHeight: window.innerHeight,
    gameWidth: 0,
    gameHeight: 0,
    xoffset: -0,
    yoffset: -0,
    gameStart: false,
    disconnected: false,
    died: false,
    kicked: false,
    continuity: false,
    startPingTime: 0,
    toggleMassState: 0,
    backgroundColor: '#f2fbff',
    lineColor: '#000000',
};
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var isObject = require( '@stdlib/assert/is-plain-object' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isURI = require( '@stdlib/assert/is-uri' );

// MAIN //

/**
* Validates function options.
*
* @param {Object} opts - destination object
* @param {Options} options - options to validate
* @param {string} [options.className] - element class name
* @param {string} [options.align] - element alignment
* @param {string} [options.raw] - raw equation text
* @param {string} [options.label] - equation label
* @param {string} [options.src] - image source URL
* @param {string} [options.alt] - alternative image text
* @returns {(Error|null)} error object or null
*
* @example
* var opts = {};
* var options = {};
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/
function validate( opts, options ) {
	if ( !isObject( options ) ) {
		return new TypeError( 'invalid input argument. Options argument must be an object. Value: `' + options + '`.' );
	}
	if ( hasOwnProp( options, 'className' ) ) {
		opts.className = options.className;
		if ( !isString( opts.className ) ) {
			return new TypeError( 'invalid option. `className` option must be a string primitive. Option: `' + opts.className + '`.' );
		}
	}
	if ( hasOwnProp( options, 'align' ) ) {
		opts.align = options.align;
		if ( !isString( opts.align ) ) {
			return new TypeError( 'invalid option. `align` option must be a string primitive. Option: `' + opts.align + '`.' );
		}
	}
	if ( hasOwnProp( options, 'raw' ) ) {
		opts.raw = options.raw;
		if ( !isString( opts.raw ) ) {
			return new TypeError( 'invalid option. `raw` option must be a string primitive. Option: `' + opts.raw + '`.' );
		}
	}
	if ( hasOwnProp( options, 'label' ) ) {
		opts.label = options.label;
		if ( !isString( opts.label ) ) {
			return new TypeError( 'invalid option. `label` option must be a string primitive. Option: `' + opts.label + '`.' );
		}
	}
	if ( hasOwnProp( options, 'src' ) ) {
		opts.src = options.src;
		if ( !isURI( opts.src ) ) {
			return new TypeError( 'invalid option. `src` option must be a valid URI. Option: `' + opts.src + '`.' );
		}
	}
	if ( hasOwnProp( options, 'alt' ) ) {
		opts.alt = options.alt;
		if ( !isString( opts.alt ) ) {
			return new TypeError( 'invalid option. `alt` option must be a string primitive. Option: `' + opts.alt + '`.' );
		}
	}
	return null;
} // end FUNCTION validate()

// EXPORTS //

module.exports = validate;
<commit_msg>Update JSDoc example<commit_after>'use strict';

// MODULES //

var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var isObject = require( '@stdlib/assert/is-plain-object' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isURI = require( '@stdlib/assert/is-uri' );

// MAIN //

/**
* Validates function options.
*
* @private
* @param {Object} opts - destination object
* @param {Options} options - options to validate
* @param {string} [options.className] - element class name
* @param {string} [options.align] - element alignment
* @param {string} [options.raw] - raw equation text
* @param {string} [options.label] - equation label
* @param {string} [options.src] - image source URL
* @param {string} [options.alt] - alternative image text
* @returns {(Error|null)} error object or null
*
* @example
* var opts = {};
* var options = {
*     'className': 'equation',
*     'align': 'center',
*     'raw': '\\operatorname{erf}(x) = \\frac{2}{\\sqrt\\pi}\\int_0^x e^{-t^2}\\,\\mathrm dt'
*     'label': 'eqn:erf',
*     'src': 'https://cdn.rawgit.com/stdlib-js/stdlib/master/lib/node_modules/@stdlib/math/base/special/erf/docs/img/eqn.svg'
*     'alt': 'Error function.'
* };
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/
function validate( opts, options ) {
	if ( !isObject( options ) ) {
		return new TypeError( 'invalid input argument. Options argument must be an object. Value: `' + options + '`.' );
	}
	if ( hasOwnProp( options, 'className' ) ) {
		opts.className = options.className;
		if ( !isString( opts.className ) ) {
			return new TypeError( 'invalid option. `className` option must be a string primitive. Option: `' + opts.className + '`.' );
		}
	}
	if ( hasOwnProp( options, 'align' ) ) {
		opts.align = options.align;
		if ( !isString( opts.align ) ) {
			return new TypeError( 'invalid option. `align` option must be a string primitive. Option: `' + opts.align + '`.' );
		}
	}
	if ( hasOwnProp( options, 'raw' ) ) {
		opts.raw = options.raw;
		if ( !isString( opts.raw ) ) {
			return new TypeError( 'invalid option. `raw` option must be a string primitive. Option: `' + opts.raw + '`.' );
		}
	}
	if ( hasOwnProp( options, 'label' ) ) {
		opts.label = options.label;
		if ( !isString( opts.label ) ) {
			return new TypeError( 'invalid option. `label` option must be a string primitive. Option: `' + opts.label + '`.' );
		}
	}
	if ( hasOwnProp( options, 'src' ) ) {
		opts.src = options.src;
		if ( !isURI( opts.src ) ) {
			return new TypeError( 'invalid option. `src` option must be a valid URI. Option: `' + opts.src + '`.' );
		}
	}
	if ( hasOwnProp( options, 'alt' ) ) {
		opts.alt = options.alt;
		if ( !isString( opts.alt ) ) {
			return new TypeError( 'invalid option. `alt` option must be a string primitive. Option: `' + opts.alt + '`.' );
		}
	}
	return null;
} // end FUNCTION validate()

// EXPORTS //

module.exports = validate;
<|endoftext|>


<commit_before>(function () {
    angular.module('ng-smooth-scroll', [])
    .directive('ngSmoothScroll', [function () {

        return {
            restrict: 'A',
            link: function (scope, element) {
                console.log('[smoothScrol] init');

                var trigger=angular.element('.scroll-to', element);

                trigger.on('click', function () {
                    var $this = angular.element(this);
                    target = $(this).attr('href');

                    console.log(name);
                    console.log(target.slice(1));
                    console.log($("[name=one"));

                    // $('html, body').animate({
                    //     scrollTop: target.offset().top
                    // }, 1000);

                    return false;
                });
            }
        }
    }]);
}());
<commit_msg>simple jquery solution complete<commit_after>(function () {
    angular.module('ng-smooth-scroll', [])
    .directive('ngSmoothScroll', [function () {

        return {
            restrict: 'A',
            link: function (scope, element) {
                console.log('[smoothScrol] init');

                var trigger = angular.element('.scroll-to', element);

                trigger.on('click', function () {
                    var $this = angular.element(this),
                        targetHref = $this.attr('href'),
                        targetLocation = $("a[name=" + targetHref.slice(1) + "]");

                    $('html, body').animate({
                        scrollTop: targetLocation.offset().top
                    }, 800);

                    return false;
                });
            }
        }
    }]);
}());<|endoftext|>