<commit_before>import $ from 'cheerio'
import _ from './_'

export default function(xml) {
  return $('item description', xml).map(parse).get()
}

function parse() {
  const tmp = {}
  $(this).text()
    .replace(/\r/g, '')
    .replace(/&/g, '&')
    .replace(/'/g, "'")
    .replace(/•/g, '*')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .match(/\n[^]+?
/g)
    .forEach(s => {
      const match = s
        .replace(/\<.+?\>/g, '')
        .match(/(.+?): ([^]*)/)

      if (!match)
        return

      const [, key, val] = match
      tmp[key.toLowerCase()] = val.trim()
    })

  const {cost, name, rarity} = tmp
  const num = tmp['set number'].slice(1)
  const type = tmp.type.replace('-', '—')
  const pt = type.includes('Creature')
    ? tmp['pow/tgh']
    : ''
  const text = tmp['rules text']

  const color = cost.match(/\D*$/)[0].replace(/X/g, '')
  const cmc = (parseInt(cost) | 0) + color.length
  const colors = color.replace(/(.)\1+/g, '$1').split('')

  return { cmc, colors, cost, name, num, pt, rarity, text, type }
}
<commit_msg>color identity<commit_after>import $ from 'cheerio'
import _ from './_'

export default function(xml) {
  return $('item description', xml).map(parse).get()
}

function parse() {
  const tmp = {}
  $(this).text()
    .replace(/\r/g, '')
    .replace(/&/g, '&')
    .replace(/'/g, "'")
    .replace(/•/g, '*')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .match(/\n[^]+?
/g)
    .forEach(s => {
      const match = s
        .replace(/\<.+?\>/g, '')
        .match(/(.+?): ([^]*)/)

      if (!match)
        return

      const [, key, val] = match
      tmp[key.toLowerCase()] = val.trim()
    })

  const {cost, name, rarity} = tmp
  const num = tmp['set number'].slice(1)
  const type = tmp.type.replace('-', '—')
  const pt = type.includes('Creature')
    ? tmp['pow/tgh']
    : ''
  const text = tmp['rules text'] || ''

  const color = cost.match(/\D*$/)[0].replace(/X/g, '')
  const cmc = (parseInt(cost) | 0) + color.length
  const cid = color.replace(/(.)\1+/g, '$1').split('')
  const colors = text.startsWith('Devoid') ? [] : cid

  return { cid, cmc, colors, cost, name, num, pt, rarity, text, type }
}
<|endoftext|>


<commit_before>/**
 * @file Anchor component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import Theme from '../Theme';

import Util from '../_vendors/Util';

class Anchor extends Component {

    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            focused: false
        };

    }

    clickHandler = e => {
        const {disabled, isLoading, onClick} = this.props;
        !disabled && !isLoading && onClick && onClick(e);
    };

    focusHandler = e => {
        this.setState({
            focused: true
        }, () => {
            const {onFocus} = this.props;
            onFocus && onFocus(e);
        });
    };

    blurHandler = e => {
        this.setState({
            focused: false
        }, () => {
            const {onBlur} = this.props;
            onBlur && onBlur(e);
        });
    };

    render() {

        const {

                children, className, style, theme,
                iconCls, rightIconCls, disabled, isLoading, tip, tipPosition,
                parentEl,

                ...restProps

            } = this.props,
            {focused} = this.state,

            anchorClassName = classNames('anchor', {
                focused: focused,
                [`theme-${theme}`]: theme,
                [className]: className
            }),

            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider tipContent={tip}
                         parentEl={parentEl}
                         position={tipPosition}>

                    {
                        isLoading && loadingIconPosition === 'left' ?
                            <CircularLoading className="anchor-icon anchor-icon-left button-loading-icon"
                                             size="small"/>
                            :
                            (
                                iconCls ?
                                    <i className={`anchor-icon anchor-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {children}

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="anchor-icon anchor-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`anchor-icon anchor-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

            </TipProvider>
        );

    }
}

Anchor.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    href: PropTypes.string,
    alt: PropTypes.string,
    target: PropTypes.string,

    disabled: PropTypes.bool,
    readOnly: PropTypes.bool,
    isLoading: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.string,

    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onBlur: PropTypes.func

};

Anchor.defaultProps = {

    theme: Theme.DEFAULT,

    href: 'javascript:void(0)',
    target: '_blank',

    disabled: false,
    readOnly: false,
    isLoading: false

};

export default Anchor;
<commit_msg>update Anchor<commit_after>/**
 * @file Anchor component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';

import Theme from '../Theme';
import Util from '../_vendors/Util';

class Anchor extends Component {

    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            focused: false
        };

    }

    handleClick = e => {
        const {disabled, isLoading, onClick} = this.props;
        !disabled && !isLoading && onClick && onClick(e);
    };

    handleFocus = e => {
        this.setState({
            focused: true
        }, () => {
            const {onFocus} = this.props;
            onFocus && onFocus(e);
        });
    };

    handleBlur = e => {
        this.setState({
            focused: false
        }, () => {
            const {onBlur} = this.props;
            onBlur && onBlur(e);
        });
    };

    render() {

        const {

                children, className, style, theme,
                iconCls, rightIconCls, disabled, isLoading, tip, tipPosition, parentEl,

                ...restProps

            } = this.props,
            {focused} = this.state,
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider tipContent={tip}
                         parentEl={parentEl}
                         position={tipPosition}>

                <a {...restProps}
                   className={classNames('anchor', {
                       focused: focused,
                       [`theme-${theme}`]: theme,
                       [className]: className
                   })}
                   style={style}
                   disabled={disabled || isLoading}
                   onClick={this.handleClick}
                   onFocus={this.handleFocus}
                   onBlur={this.handleBlur}>

                    {
                        isLoading && loadingIconPosition === 'left' ?
                            <CircularLoading className="anchor-icon anchor-icon-left button-loading-icon"
                                             size="small"/>
                            :
                            (
                                iconCls ?
                                    <i className={`anchor-icon anchor-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {children}

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="anchor-icon anchor-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`anchor-icon anchor-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

            </TipProvider>
        );

    }
}

Anchor.propTypes = {

    children: PropTypes.any,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    href: PropTypes.string,
    alt: PropTypes.string,
    target: PropTypes.string,

    disabled: PropTypes.bool,
    readOnly: PropTypes.bool,
    isLoading: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.string,

    parentEl: PropTypes.object,

    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onBlur: PropTypes.func

};

Anchor.defaultProps = {

    theme: Theme.DEFAULT,

    href: 'javascript:void(0)',
    target: '_blank',

    disabled: false,
    readOnly: false,
    isLoading: false

};

export default Anchor;
<|endoftext|>


<commit_before>$(document).ready(function () {

    function caseWidth() {
        return $('[data-name="hnm"]').width();
    }

    $(function () {
        $(".c-ui__logo").html("Case width: " + caseWidth + "px.");
    });

	$(".o-featured__case").hover(function () {
	    var dark = $(this).attr("data-isDark");
	    if (dark == "0") {
	        $(".c-ui__nav-items.js-invert").addClass("invert");
	    }
	    else {
	        $(".c-ui__nav-items.js-invert").removeClass("invert");
	    }
	}, function () {
	    var dark = $(this).attr("data-isDark");
	    if (dark == "0") {
	        $(".c-ui__nav-items.js-invert").addClass("invert");
	    }
	    else {
	        $(".c-ui__nav-items.js-invert").removeClass("invert");
	    }
	});
});

/*($('[data-name="hnm"]').offset().left > $(window).width() - 60 - $('[data-name="hnm"]').width()) && ($('[data-name="hnm"]').offset().left < $(window).width() - 60)
var child = o - featured__background
$('[data-name="hnm"]').children(".o-featured__background").eq(0).width();*/<commit_msg>syntax error again<commit_after>$(document).ready(function () {

    function caseWidth() {
        return $('[data-name="hnm"]').width();
    }

    $(function () {
        $(".c-ui__logo").html("Case width: " + caseWidth() + "px.");
    });

	$(".o-featured__case").hover(function () {
	    var dark = $(this).attr("data-isDark");
	    if (dark == "0") {
	        $(".c-ui__nav-items.js-invert").addClass("invert");
	    }
	    else {
	        $(".c-ui__nav-items.js-invert").removeClass("invert");
	    }
	}, function () {
	    var dark = $(this).attr("data-isDark");
	    if (dark == "0") {
	        $(".c-ui__nav-items.js-invert").addClass("invert");
	    }
	    else {
	        $(".c-ui__nav-items.js-invert").removeClass("invert");
	    }
	});
});

/*($('[data-name="hnm"]').offset().left > $(window).width() - 60 - $('[data-name="hnm"]').width()) && ($('[data-name="hnm"]').offset().left < $(window).width() - 60)
var child = o - featured__background
$('[data-name="hnm"]').children(".o-featured__background").eq(0).width();*/<|endoftext|>


<commit_before>var appStore = [
{
  name: 'The Old Reader',
  tags: ['web', 'popular', 'advanced'],
  description: 'The Old Reader was built to be a Google Reader replacement, and it does it well!',
  url: 'http://theoldreader.com/',
  icon: 'http://theoldreader.com/favicon.ico',
  registration: {
    name: 'The Old Reader',
    url: 'http://theoldreader.com/feeds/subscribe?url={feed}'
  },
  installed: false
},
{
  name: 'NewsBlur',
  tags: ['web', 'mobile', 'advanced', 'open source'],
  description: 'NewsBlur is a personal news reader bringing people together to talk about the world.',
  url: 'http://www.newsblur.com/',
  icon: 'http://newsblur.com/favicon.ico',
  registration: {
    name: 'NewsBlur',
    url: 'http://www.newsblur.com/?url={url}'
  },
    installed: true
},
{
  name: 'Rivered',
  tags: ['web'],
  description: 'An uncluttered River of News; no unread item count, no complexity. Just the content you subscribe to.',
  url: 'http://www.rivered.io/',
  icon: 'http://www.rivered.io/favicon.ico',
  registration: {
    name: 'Rivered',
    url: 'http://www.rivered.io/add?url={url}'
  }
},
{
  name: 'Bloglovin',
  tags: ['web', 'iOS', 'blog'],
  description: 'Bloglovin was created to make reading blogs awesome.',
  url: 'http://www.bloglovin.com/',
  icon: 'http://www.bloglovin.com/images/favicon.ico',
  registration: {
    name: 'Bloglovin',
    url: 'http://www.bloglovin.com/search/{url}'
  }
},
{
  name: 'Blogtrottr',
  tags: ['email', 'digests'],
  description: 'Blogtrottr delivers updates from all of your favourite news, feeds, and blogs directly to your email inbox.',
  url: 'http://blogtrottr.com/',
  icon: 'http://blogtrottr.com/favicon.ico',
  registration: {
    name: 'Blogtrottr',
    url: 'http://blogtrottr.com/?subscribe={feed}'
  }
},
{
  name: 'BazQux Reader',
  tags: ['web', 'comments'],
  description: 'RSS feed reader that shows comments to posts and supports reading of Facebook and Google+ pages.',
  url: 'https://bazqux.com/',
  icon: 'https://bazqux.com/favicon.ico',
  registration: {
    name: 'BazQux',
    url: 'https://bazqux.com/add?url={url}'
  }
},
{
  name: 'Feedleap',
  tags: ['web', 'kippt', 'bookmark', 'open source'],
  description: 'FeedLeap lets you subscribe to your favorite RSS feeds and store new entries as Clips in any Kippt List you want.',
  url: 'https://feedleap.herokuapp.com',
  icon: 'https://feedleap.herokuapp.com/static/favicon.ico',
  registration: {
    name: 'Feedleap',
    url: 'https://feedleap.herokuapp.com/feeds/new/?feed={feed}&source=subtome'
  }
},
{
  name: 'FeedHQ',
  tags: ['web', 'mobile', 'open source'],
  description: 'FeedHQ is a feed reader built with readability and mobility in mind',
  url: 'https://feedhq.org/',
  icon: 'https://feedhq.org/static/core/img/icon-rss.png',
  registration: {
    name: 'FeedHQ',
    url: 'https://feedhq.org/subscribe/?feeds={feeds}&url={url}'
  }
},
{
  name: 'Feedbin',
  tags: ['web'],
  description: 'A fast, simple RSS feed reader that delivers a great reading experience.',
  url: 'https://feedbin.me/',
  icon: 'https://feedbin.me/favicon.ico',
  registration: {
    name: 'Feedbin',
    url: 'https://feedbin.me/?subscribe={feed}'
  }
},
{
  name: 'Feedly',
  tags: ['chrome', 'firefox', 'mobile'],
  description: 'Feedly is a news aggregator application for various Web browsers and mobile devices running iOS and Android.',
  url: 'http://feedly.com/',
  icon: 'http://feedly.com/favicon.ico',
  registration: {
    name: 'Feedly',
    url: 'http://www.feedly.com/home#subscription/feed/{feed}'
  }
},
{
  name: 'Msgboy',
  tags: ['chrome', 'open source'],
  description: 'Msgboy delivers a custom feed of stories in realtime, all based on websites you\'ve bookmarked and visited most often',
  url: 'http://www.msgboy.com/',
  icon: 'https://raw.github.com/superfeedr/msgboy/master/views/img/icon16.png',
  registration: {
    name: 'Msgboy',
    url: 'chrome-extension://ligglcbjgpiljeoenbhnnfdipkealakb/data/html/subscribe.html?url={url}'
  }
},
{
  name: 'InoReader',
  tags: ['web', 'advanced'],
  description: 'Light and Fast RSS/Atom Reader inspired by Google Reader',
  url: 'https://inoreader.com/',
  icon: 'https://inoreader.com/images/icons/72_x_72_pixels.png',
  registration: {
    name: 'InoReader',
    url: 'https://www.inoreader.com/?add_feed={feed}'
  }
},
{
  name: 'ReadHQ',
  tags: ['web', 'mobile'],
  description: "ReadHQ is a new RSS reader which allows you to import, add, manage, organize and enjoy your feeds.",
  url:"https://www.readhq.com",
  icon:"https://www.readhq.com/favicon.ico",
  registration:{
    name: "ReadHQ",
    url: 'https://www.readhq.com/api/v1/subtome?url={url}'
  }
},
{
  name: "MnmlRdr",
  tags: ["web", "mobile", "minimal", "lightweight"],
  description: "A fast and lightweight feed reader without \"feature clutter\" so you can focus on the content.",
  url:"https://mnmlrdr.com/",
  icon:"https://mnmlrdr.com/static/images/logo.png",
  registration:{
    name: "MnmlRdr",
    url: "https://mnmlrdr.com/settings/subscriptions/add?feed={url}"
  }
}
];
<commit_msg>adding player.fm<commit_after>var appStore = [
{
  name: 'The Old Reader',
  tags: ['web', 'popular', 'advanced'],
  description: 'The Old Reader was built to be a Google Reader replacement, and it does it well!',
  url: 'http://theoldreader.com/',
  icon: 'http://theoldreader.com/favicon.ico',
  registration: {
    name: 'The Old Reader',
    url: 'http://theoldreader.com/feeds/subscribe?url={feed}'
  },
  installed: false
},
{
  name: 'NewsBlur',
  tags: ['web', 'mobile', 'advanced', 'open source'],
  description: 'NewsBlur is a personal news reader bringing people together to talk about the world.',
  url: 'http://www.newsblur.com/',
  icon: 'http://newsblur.com/favicon.ico',
  registration: {
    name: 'NewsBlur',
    url: 'http://www.newsblur.com/?url={url}'
  },
    installed: true
},
{
  name: 'Rivered',
  tags: ['web'],
  description: 'An uncluttered River of News; no unread item count, no complexity. Just the content you subscribe to.',
  url: 'http://www.rivered.io/',
  icon: 'http://www.rivered.io/favicon.ico',
  registration: {
    name: 'Rivered',
    url: 'http://www.rivered.io/add?url={url}'
  }
},
{
  name: 'Bloglovin',
  tags: ['web', 'iOS', 'blog'],
  description: 'Bloglovin was created to make reading blogs awesome.',
  url: 'http://www.bloglovin.com/',
  icon: 'http://www.bloglovin.com/images/favicon.ico',
  registration: {
    name: 'Bloglovin',
    url: 'http://www.bloglovin.com/search/{url}'
  }
},
{
  name: 'Blogtrottr',
  tags: ['email', 'digests'],
  description: 'Blogtrottr delivers updates from all of your favourite news, feeds, and blogs directly to your email inbox.',
  url: 'http://blogtrottr.com/',
  icon: 'http://blogtrottr.com/favicon.ico',
  registration: {
    name: 'Blogtrottr',
    url: 'http://blogtrottr.com/?subscribe={feed}'
  }
},
{
  name: 'BazQux Reader',
  tags: ['web', 'comments'],
  description: 'RSS feed reader that shows comments to posts and supports reading of Facebook and Google+ pages.',
  url: 'https://bazqux.com/',
  icon: 'https://bazqux.com/favicon.ico',
  registration: {
    name: 'BazQux',
    url: 'https://bazqux.com/add?url={url}'
  }
},
{
  name: 'Feedleap',
  tags: ['web', 'kippt', 'bookmark', 'open source'],
  description: 'FeedLeap lets you subscribe to your favorite RSS feeds and store new entries as Clips in any Kippt List you want.',
  url: 'https://feedleap.herokuapp.com',
  icon: 'https://feedleap.herokuapp.com/static/favicon.ico',
  registration: {
    name: 'Feedleap',
    url: 'https://feedleap.herokuapp.com/feeds/new/?feed={feed}&source=subtome'
  }
},
{
  name: 'FeedHQ',
  tags: ['web', 'mobile', 'open source'],
  description: 'FeedHQ is a feed reader built with readability and mobility in mind',
  url: 'https://feedhq.org/',
  icon: 'https://feedhq.org/static/core/img/icon-rss.png',
  registration: {
    name: 'FeedHQ',
    url: 'https://feedhq.org/subscribe/?feeds={feeds}&url={url}'
  }
},
{
  name: 'Feedbin',
  tags: ['web'],
  description: 'A fast, simple RSS feed reader that delivers a great reading experience.',
  url: 'https://feedbin.me/',
  icon: 'https://feedbin.me/favicon.ico',
  registration: {
    name: 'Feedbin',
    url: 'https://feedbin.me/?subscribe={feed}'
  }
},
{
  name: 'Feedly',
  tags: ['chrome', 'firefox', 'mobile'],
  description: 'Feedly is a news aggregator application for various Web browsers and mobile devices running iOS and Android.',
  url: 'http://feedly.com/',
  icon: 'http://feedly.com/favicon.ico',
  registration: {
    name: 'Feedly',
    url: 'http://www.feedly.com/home#subscription/feed/{feed}'
  }
},
{
  name: 'Msgboy',
  tags: ['chrome', 'open source'],
  description: 'Msgboy delivers a custom feed of stories in realtime, all based on websites you\'ve bookmarked and visited most often',
  url: 'http://www.msgboy.com/',
  icon: 'https://raw.github.com/superfeedr/msgboy/master/views/img/icon16.png',
  registration: {
    name: 'Msgboy',
    url: 'chrome-extension://ligglcbjgpiljeoenbhnnfdipkealakb/data/html/subscribe.html?url={url}'
  }
},
{
  name: 'InoReader',
  tags: ['web', 'advanced'],
  description: 'Light and Fast RSS/Atom Reader inspired by Google Reader',
  url: 'https://inoreader.com/',
  icon: 'https://inoreader.com/images/icons/72_x_72_pixels.png',
  registration: {
    name: 'InoReader',
    url: 'https://www.inoreader.com/?add_feed={feed}'
  }
},
{
  name: 'ReadHQ',
  tags: ['web', 'mobile'],
  description: "ReadHQ is a new RSS reader which allows you to import, add, manage, organize and enjoy your feeds.",
  url:"https://www.readhq.com",
  icon:"https://www.readhq.com/favicon.ico",
  registration:{
    name: "ReadHQ",
    url: 'https://www.readhq.com/api/v1/subtome?url={url}'
  }
},
{
  name: "MnmlRdr",
  tags: ["web", "mobile", "minimal", "lightweight"],
  description: "A fast and lightweight feed reader without \"feature clutter\" so you can focus on the content.",
  url:"https://mnmlrdr.com/",
  icon:"https://mnmlrdr.com/static/images/logo.png",
  registration:{
    name: "MnmlRdr",
    url: "https://mnmlrdr.com/settings/subscriptions/add?feed={url}"
  }
},
{
  name: "Player FM",
  tags: ["podcast", "mobile", "web"],
  description: "Listen to talk shows on hundreds of topics, everything from Politics to Pokemon! ",
  url:"http://player.fm/",
  icon:"http://player.fm/favicon.ico",
  registration:{
    name: "Player FM",
    url: "http://player.fm/series?url={feed}&referrer={url}&related_feeds={feeds}"
  }
}
];
<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in t<commit_msg>Found an issue with the letter 'a', so I fixed it.<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in th<|endoftext|>


<commit_before>var gulp          = require('gulp'),
    gulpif        = require('gulp-if'),
    concat        = require('gulp-concat'),
    rimraf        = require('gulp-rimraf'),
    templateCache = require('gulp-angular-templatecache'),
    minifyHtml    = require('gulp-minify-html'),
    es            = require('event-stream'),
    sass          = require('gulp-sass'),
    rename        = require('gulp-rename'),
    ngAnnotate    = require('gulp-ng-annotate'),
    uglify        = require('gulp-uglify'),
    minifyCSS     = require('gulp-minify-css'),
    webserver     = require('gulp-webserver'),
    argv          = require('yargs').argv;

var paths = {
  appJavascript:    ['app/js/app.js', 'app/js/**/*.js'],
  appTemplates:     'app/js/**/**.tpl.html',
  appMainSass:      'app/scss/main.scss',
  appStyles:        'app/scss/**/*.scss',
  indexHtml:        'app/index.html',
  vendorJavascript: ['vendor/js/angular.js', 'vendor/js/**/*.js'],
  tmpFolder:        '.tmp',
  tmpJavascript:    '.tmp/js',
  tmpCss:           '.tmp/css',
  distFolder:       'dist',
  distJavascript:   'dist/js',
  distCss:          'dist/css'
};

gulp.task('scripts', function() {
  return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
    .pipe(gulpif(/html$/, buildTemplates()))
    .pipe(concat('app.js'))
    .pipe(gulpif(argv.production, ngAnnotate()))
    .pipe(gulpif(argv.production, uglify()))
    .pipe(gulpif(argv.production, gulp.dest(paths.distJavascript), gulp.dest(paths.tmpJavascript)));
});

gulp.task('styles', function() {
  return gulp.src(paths.appMainSass)
    .pipe(sass())
    .pipe(gulpif(argv.production, minifyCSS()))
    .pipe(rename('app.css'))
    .pipe(gulpif(argv.production, gulp.dest(paths.distCss), gulp.dest(paths.tmpCss)));
});

gulp.task('indexHtml', function() {
  return gulp.src(paths.indexHtml)
    .pipe(gulpif(argv.production, gulp.dest(paths.distFolder), gulp.dest(paths.tmpFolder)))
});

gulp.task('clean', function() {
  return gulp.src([paths.tmpFolder, paths.distFolder], {read: false})
    .pipe(rimraf());
});

gulp.task('watch', ['webserver'], function() {
  gulp.watch(paths.appJavascript, ['scripts']);
  gulp.watch(paths.appTemplates, ['scripts']);
  gulp.watch(paths.vendorJavascript, ['scripts']);
  gulp.watch(paths.indexHtml, ['indexHtml']);
  gulp.watch(paths.appStyles, ['styles']);
});

gulp.task('webserver', ['scripts', 'styles', 'indexHtml'], function() {
  gulp.src(paths.tmpFolder)
    .pipe(webserver({
      port: 5000,
      proxies: [
        {
          source: '/api', target: 'http://localhost:8080/api'
        }
      ]
    }));
});

gulp.task('default', ['scripts', 'styles', 'indexHtml']);

function buildTemplates() {
  return es.pipeline(
    minifyHtml({
      empty: true,
      spare: true,
      quotes: true
    }),
    templateCache()
  );
}<commit_msg>Fix bad module for templates<commit_after>var gulp          = require('gulp'),
    gulpif        = require('gulp-if'),
    concat        = require('gulp-concat'),
    rimraf        = require('gulp-rimraf'),
    templateCache = require('gulp-angular-templatecache'),
    minifyHtml    = require('gulp-minify-html'),
    es            = require('event-stream'),
    sass          = require('gulp-sass'),
    rename        = require('gulp-rename'),
    ngAnnotate    = require('gulp-ng-annotate'),
    uglify        = require('gulp-uglify'),
    minifyCSS     = require('gulp-minify-css'),
    webserver     = require('gulp-webserver'),
    argv          = require('yargs').argv;

var paths = {
  appJavascript:    ['app/js/app.js', 'app/js/**/*.js'],
  appTemplates:     'app/js/**/**.tpl.html',
  appMainSass:      'app/scss/main.scss',
  appStyles:        'app/scss/**/*.scss',
  indexHtml:        'app/index.html',
  vendorJavascript: ['vendor/js/angular.js', 'vendor/js/**/*.js'],
  tmpFolder:        '.tmp',
  tmpJavascript:    '.tmp/js',
  tmpCss:           '.tmp/css',
  distFolder:       'dist',
  distJavascript:   'dist/js',
  distCss:          'dist/css'
};

gulp.task('scripts', function() {
  return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
    .pipe(gulpif(/html$/, buildTemplates()))
    .pipe(concat('app.js'))
    .pipe(gulpif(argv.production, ngAnnotate()))
    .pipe(gulpif(argv.production, uglify()))
    .pipe(gulpif(argv.production, gulp.dest(paths.distJavascript), gulp.dest(paths.tmpJavascript)));
});

gulp.task('styles', function() {
  return gulp.src(paths.appMainSass)
    .pipe(sass())
    .pipe(gulpif(argv.production, minifyCSS()))
    .pipe(rename('app.css'))
    .pipe(gulpif(argv.production, gulp.dest(paths.distCss), gulp.dest(paths.tmpCss)));
});

gulp.task('indexHtml', function() {
  return gulp.src(paths.indexHtml)
    .pipe(gulpif(argv.production, gulp.dest(paths.distFolder), gulp.dest(paths.tmpFolder)));
});

gulp.task('clean', function() {
  return gulp.src([paths.tmpFolder, paths.distFolder], {read: false})
    .pipe(rimraf());
});

gulp.task('watch', ['webserver'], function() {
  gulp.watch(paths.appJavascript, ['scripts']);
  gulp.watch(paths.appTemplates, ['scripts']);
  gulp.watch(paths.vendorJavascript, ['scripts']);
  gulp.watch(paths.indexHtml, ['indexHtml']);
  gulp.watch(paths.appStyles, ['styles']);
});

gulp.task('webserver', ['scripts', 'styles', 'indexHtml'], function() {
  gulp.src(paths.tmpFolder)
    .pipe(webserver({
      port: 5000,
      proxies: [
        {
          source: '/api', target: 'http://localhost:8080/api'
        }
      ]
    }));
});

gulp.task('default', ['scripts', 'styles', 'indexHtml']);

function buildTemplates() {
  return es.pipeline(
    minifyHtml({
      empty: true,
      spare: true,
      quotes: true
    }),
    templateCache({
      module: 'app'
    })
  );
}
<|endoftext|>


<commit_before>//============== Eventhandler ==================//

window.addEventListener('load', function() {					// warte darauf, dass der Inhalt geladen wurde
	document.addEventListener('keydown', function(event) {
		if (event.keyCode === 27) {								// Escape wurde gedrueckt
			hideZoom();											// verstecke das Bildfenster
		}
	}, false);

	document.getElementById('newcityform').addEventListener('submit', function(event) {
		var formemail  = document.getElementById('formemail');
		var emailerror = document.getElementById('emailerror');
		emailerror.style.visibility = 'hidden';
		if (formemail.value.substring(formemail.value.length-20,
									  formemail.value.length) != "@beuth-hochschule.de") {		// wenn die letzten 20 Zeichen nicht dem String entsprechen
			emailerror.style.visibility = 'visible';
			event.preventDefault();																// Abbruch
		}
	}, false);

	document.getElementById('submitForm').addEventListener('click', function() {
		document.getElementbyId('cityform').submit();
	}, false);

	document.getElementById('zoom').getElementsByTagName('a')[0].addEventListener('click', hideZoom, false);

	/*var trs = document.getElementsByTagName('tr');
	for (var x=0; x<trs.length; x++) {
		trs[x].addEventListener('mouseover', function() {
			var tds = this.getElementsByTagName('td');
			tds[10].style.visibility = 'visible';
		}, false);
		trs[x].addEventListener('mouseout', function() {
			var tds = this.getElementsByTagName('td');
			tds[10].style.visibility = 'hidden';
		}, false);
	}*/

	var trs = document.getElementsByTagName('tr');
	for (var x=1; x<trs.length; x++) {
		var entry = document.getElementById('entry'+x+'list');
		var zLink = document.getElementById('entry'+x+'zoomlink');
		var eLink = document.getElementById('entry'+x+'editlink');
		var sLink = document.getElementById('entry'+x+'savelink');
		var dLink1 = document.getElementById('entry'+x+'deletelink1');
		var dLink2 = document.getElementById('entry'+x+'deletelink2');
		entry.addEventListener('change', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			checkSelect(id);
		}, false);
		zLink.addEventListener('click', function() {
			var image = this.getElementsByTagName('img')[0].src;
			showZoom(image);
		}, false);
		eLink.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			editEntry(id);
		}, false);
		sLink.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			saveEntry(id);
		}, false);
		dLink1.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			deleteEntry(id);
		}, false);
		dLink2.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			deleteEntry(id);
		}, false);
	}

	document.getElementById('newcityformlist').addEventListener('change', function(event) {
		checkSelect('newcityform');
	}, false);

	initialize();
}, false);

//============== Hauptfunktionen ===============//

function initialize() {
	window.setTimeout(slideshow, 1000);						// Slideshow mit einer Verzoegerung von 1000ms starten.
	var today = new Date();									// neues Datum erzeugen
	var dd = today.getDate();								// hole den Tag
	var mm = today.getMonth()+1;							// hole den Monat; +1 weil hier Januar mit 0 gezaehlt wird
	var yyyy = today.getFullYear();							// hole das Jahr
	var formdate = document.getElementById('formdate');		// formdate-input ansprechen
	    formdate.value = yyyy + "-" + mm + "-" + dd;		// formdate auf das heutige Datum setzen
	fillLists();											// alle Staedte-Listen auffuellen
}

function fillLists() {
	var trs = document.getElementById('table').getElementsByTagName('tr');
	for (var i=1; i<trs.length-1; i++) {
		addCities(document.getElementById('entry'+i+'list'));
	}
	addCities(document.getElementById('newcityformlist'));
}

function editEntry(entry) {
	var tr = document.getElementById(entry);				// DIV mit angegebenem Namen ansprechen
	var td = tr.getElementsByTagName('td');					// dessen td-Elemente ansprechen
	for (var i = 0; i < td.length; i++) {					// fuer alle td-Elemente
		if (td[i].className === 'edit') {					// wenn die jeweilige Klasse bearbeitbar ist
			td[i].style.display = 'table-cell';				// dann zeige sie an
		} else if (td[i].className === 'editable') {		// wenn die jeweilige Klasse nicht bearbeitbar ist
			td[i].style.display = 'none';					// dann verstecke sie
		}
	}
}

function saveEntry(entry) {
	var tr = document.getElementById(entry);											// DIV mit angegebenem Namen ansprechen
	var td = tr.getElementsByTagName('td');												// dessen td-Elemente ansprechen
	    td[0].innerHTML = formatDate(td[1].getElementsByTagName('input')[0].value);		// td mit Index 0 auf bearbeitetes Feld setzen
	    td[2].innerHTML = td[3].getElementsByTagName('input')[0].value + " °C";		// usw...
	var td5 = td[5].getElementsByTagName('select')[0];									// td mit Index 5 abkuerzen
	    td[4].innerHTML = td5.options[td5.selectedIndex].innerHTML;
	    td[8].innerHTML = td[9].getElementsByTagName('input')[0].value;
	for (var i = 0; i < td.length; i++) {												// fuer alle td-Elemente
		if (td[i].className === 'edit') {												// wenn die jeweilige Klasse bearbeitbar ist
			td[i].style.display = 'none';												// dann verstecke sie
		} else if (td[i].className === 'editable') {									// wenn die jeweilige Klasse nicht bearbeitbar ist
			td[i].style.display = 'table-cell';											// dann zeige sie an
		}
	}
}

function deleteEntry(entry) {
	if (confirm("Eintrag wirklich löschen?")) {				// Wenn Ja/Nein-Dialog bestaetigt wurde
		var tr = document.getElementById(entry);			// DIV mit angegebenem Namen ansprechen
		var td = tr.getElementsByTagName('td');				// dessen td-Elemente ansprechen
		for (var i = 0; i < td.length; i++) {				// fuer alle td-Elemente
			td[i].style.display = 'none';					// verstecke alle Elemente (temporaer -
		}													//  spaeter werden sie in der DB geloescht)
	}
}

function slideshow() {
	var images = document.getElementById('slideshow').getElementsByTagName('img');		// spreche alle Bilder im DIV 'slideshow' an
	if (typeof(counter) != "number") {													// wenn Counter noch nicht gesetzt
		counter = 0;
	}
	counter++;																			// Index auf naechstes Bild setzen
	if (counter < images.length) {														// wenn noch nicht alle Bilder angezeigt werden
		fadeIn(0, images);																// starte das einblenden des Bildes
	} else {
		for (var x = 1; x<images.length; x++) {
			images[x].style.opacity = 0;
			images[x].style.filter = 'alpha(opacity=0)';
		}
		counter = 0;
		fadeIn(0, images);
	}
}

function fadeIn(step, obj) {
	obj[counter].style.opacity = step/100;												// setze die Transparenz des Objekts auf 1/100 von Step
	obj[counter].style.filter = 'alpha(opacity=' + step + ')';							// setze die Transparenz des Objekts auf 1/100 von Step

	step += 2;

	if (step <= 100) {
		window.setTimeout(function () { fadeIn(step, obj); }, 1);						// Objekt noch nicht ganz sichtbar, ruft sich selbst auf
	} else {
		window.setTimeout(slideshow, 8000);												// Objekt jetzt sichtbar, starte naechstes Objekt nach 8000ms
	}
}

function checkSelect(id) {
	var element = document.getElementById(id+"list");									// select mit angegebenem Namen ansprechen
	var i = element.selectedIndex;														// hole den Index des aktuell ausgewaehlten Eintrags
	var selValue = element.options[i].value;											// hole den Text des aktuell ausgewaehlten Eintrags
	if (selValue === "neuestadt") {														// wenn eine neue Stadt eingetragen werden soll
		var userInput = prompt("Geben Sie den Namen der neuen Stadt ein:");
		if (userInput != "" && userInput != null) {
			var opt = createOption(formatValue(userInput), userInput);					// erstelle neue Option mit der Benutzereingabe
			element.add(opt, element[i]);												// fuege neue Option hinzu
			element.options[i].selected = 'selected';									// selektiere den neuen Eintrag
		}
	}
}

function addCities(select) {															// damit man nicht alle Staedte mehrfach eintragen muss
	select.add(createOption('', 'Stadt', true));
	select.add(createOption('berlin', 'Berlin'));
	select.add(createOption('koeln', 'Köln'));
	select.add(createOption('frankfurt', 'Frankfurt'));
	select.add(createOption('hamburg', 'Hamburg'));
	select.add(createOption('muenchen', 'München'));
	select.add(createOption('neuestadt', 'Neue Stadt...'));
}

function showZoom(img) {
	var y = document.getElementById('zoomImage').src = img;
	document.getElementById('zoomwrap').style.visibility = 'visible';
}

function hideZoom() {
	var z = document.getElementById('zoomwrap').style.visibility = 'hidden';
}

//============== Helferfunktionen ==============//

function formatValue(str) {									// ersetze alle dt. Umlaute und gib das Wort in Kleinbuchstaben zurueck
	return str.toLowerCase().replace(/\u00e4/g, "ae").replace(/\u00f6/g, "oe").replace(/\u00fc/g, "ue").replace(/\u00df/g, "ss").replace(/ /g, "_");
}

function formatDate(date) {									// uebersetze ein Datum vom ISO 8601-Format in die dt. Schreibweise und gib es zurueck
	return date.replace(/(\d\d\d\d)-(\d\d)-(\d\d)/i, "$3.$2.$1");
}

function createOption(value, text, disabled) {				// neue Option erstellen
	var option = document.createElement("option");
	    option.value = value;
	    option.text = text;
	    option.disabled = disabled ? true : false;			// kurzform fuer if() {..} else {...}
	return option;
}<commit_msg>created shortcut for getElementById<commit_after>//============== Eventhandler ==================//
var byId = function(id) {
	return document.getElementById(id);
}

window.addEventListener('load', function() {					// warte darauf, dass der Inhalt geladen wurde
	document.addEventListener('keydown', function(event) {
		if (event.keyCode === 27) {								// Escape wurde gedrueckt
			hideZoom();											// verstecke das Bildfenster
		}
	}, false);

	byId('newcityform').addEventListener('submit', function(event) {
		var formemail  = byId('formemail');
		var emailerror = byId('emailerror');
		emailerror.style.visibility = 'hidden';
		if (formemail.value.substring(formemail.value.length-20,
									  formemail.value.length) != "@beuth-hochschule.de") {		// wenn die letzten 20 Zeichen nicht dem String entsprechen
			emailerror.style.visibility = 'visible';
			event.preventDefault();																// Abbruch
		}
	}, false);

	byId('submitForm').addEventListener('click', function() {
		byId('cityform').submit();
	}, false);

	byId('zoom').getElementsByTagName('a')[0].addEventListener('click', hideZoom, false);

	/*var trs = document.getElementsByTagName('tr');
	for (var x=0; x<trs.length; x++) {
		trs[x].addEventListener('mouseover', function() {
			var tds = this.getElementsByTagName('td');
			tds[10].style.visibility = 'visible';
		}, false);
		trs[x].addEventListener('mouseout', function() {
			var tds = this.getElementsByTagName('td');
			tds[10].style.visibility = 'hidden';
		}, false);
	}*/

	var trs = document.getElementsByTagName('tr');
	for (var x=1; x<trs.length; x++) {
		var entry = byId('entry'+x+'list');
		var zLink = byId('entry'+x+'zoomlink');
		var eLink = byId('entry'+x+'editlink');
		var sLink = byId('entry'+x+'savelink');
		var dLink1 = byId('entry'+x+'deletelink1');
		var dLink2 = byId('entry'+x+'deletelink2');
		entry.addEventListener('change', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			checkSelect(id);
		}, false);
		zLink.addEventListener('click', function() {
			var image = this.getElementsByTagName('img')[0].src;
			showZoom(image);
		}, false);
		eLink.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			editEntry(id);
		}, false);
		sLink.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			saveEntry(id);
		}, false);
		dLink1.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			deleteEntry(id);
		}, false);
		dLink2.addEventListener('click', function() {
			var id = this.parentNode.parentNode.getAttribute('id');
			deleteEntry(id);
		}, false);
	}

	byId('newcityformlist').addEventListener('change', function(event) {
		checkSelect('newcityform');
	}, false);

	initialize();
}, false);

//============== Hauptfunktionen ===============//

function initialize() {
	window.setTimeout(slideshow, 1000);						// Slideshow mit einer Verzoegerung von 1000ms starten.
	var today = new Date();									// neues Datum erzeugen
	var dd = today.getDate();								// hole den Tag
	var mm = today.getMonth()+1;							// hole den Monat; +1 weil hier Januar mit 0 gezaehlt wird
	var yyyy = today.getFullYear();							// hole das Jahr
	var formdate = byId('formdate');		// formdate-input ansprechen
	    formdate.value = yyyy + "-" + mm + "-" + dd;		// formdate auf das heutige Datum setzen
	fillLists();											// alle Staedte-Listen auffuellen
}

function fillLists() {
	var trs = byId('table').getElementsByTagName('tr');
	for (var i=1; i<trs.length-1; i++) {
		addCities(byId('entry'+i+'list'));
	}
	addCities(byId('newcityformlist'));
}

function editEntry(entry) {
	var tr = byId(entry);				// DIV mit angegebenem Namen ansprechen
	var td = tr.getElementsByTagName('td');					// dessen td-Elemente ansprechen
	for (var i = 0; i < td.length; i++) {					// fuer alle td-Elemente
		if (td[i].className === 'edit') {					// wenn die jeweilige Klasse bearbeitbar ist
			td[i].style.display = 'table-cell';				// dann zeige sie an
		} else if (td[i].className === 'editable') {		// wenn die jeweilige Klasse nicht bearbeitbar ist
			td[i].style.display = 'none';					// dann verstecke sie
		}
	}
}

function saveEntry(entry) {
	var tr = byId(entry);											// DIV mit angegebenem Namen ansprechen
	var td = tr.getElementsByTagName('td');												// dessen td-Elemente ansprechen
	    td[0].innerHTML = formatDate(td[1].getElementsByTagName('input')[0].value);		// td mit Index 0 auf bearbeitetes Feld setzen
	    td[2].innerHTML = td[3].getElementsByTagName('input')[0].value + " °C";		// usw...
	var td5 = td[5].getElementsByTagName('select')[0];									// td mit Index 5 abkuerzen
	    td[4].innerHTML = td5.options[td5.selectedIndex].innerHTML;
	    td[8].innerHTML = td[9].getElementsByTagName('input')[0].value;
	for (var i = 0; i < td.length; i++) {												// fuer alle td-Elemente
		if (td[i].className === 'edit') {												// wenn die jeweilige Klasse bearbeitbar ist
			td[i].style.display = 'none';												// dann verstecke sie
		} else if (td[i].className === 'editable') {									// wenn die jeweilige Klasse nicht bearbeitbar ist
			td[i].style.display = 'table-cell';											// dann zeige sie an
		}
	}
}

function deleteEntry(entry) {
	if (confirm("Eintrag wirklich löschen?")) {				// Wenn Ja/Nein-Dialog bestaetigt wurde
		var tr = byId(entry);			// DIV mit angegebenem Namen ansprechen
		var td = tr.getElementsByTagName('td');				// dessen td-Elemente ansprechen
		for (var i = 0; i < td.length; i++) {				// fuer alle td-Elemente
			td[i].style.display = 'none';					// verstecke alle Elemente (temporaer -
		}													//  spaeter werden sie in der DB geloescht)
	}
}

function slideshow() {
	var images = byId('slideshow').getElementsByTagName('img');		// spreche alle Bilder im DIV 'slideshow' an
	if (typeof(counter) != "number") {													// wenn Counter noch nicht gesetzt
		counter = 0;
	}
	counter++;																			// Index auf naechstes Bild setzen
	if (counter < images.length) {														// wenn noch nicht alle Bilder angezeigt werden
		fadeIn(0, images);																// starte das einblenden des Bildes
	} else {
		for (var x = 1; x<images.length; x++) {
			images[x].style.opacity = 0;
			images[x].style.filter = 'alpha(opacity=0)';
		}
		counter = 0;
		fadeIn(0, images);
	}
}

function fadeIn(step, obj) {
	obj[counter].style.opacity = step/100;												// setze die Transparenz des Objekts auf 1/100 von Step
	obj[counter].style.filter = 'alpha(opacity=' + step + ')';							// setze die Transparenz des Objekts auf 1/100 von Step

	step += 2;

	if (step <= 100) {
		window.setTimeout(function () { fadeIn(step, obj); }, 1);						// Objekt noch nicht ganz sichtbar, ruft sich selbst auf
	} else {
		window.setTimeout(slideshow, 8000);												// Objekt jetzt sichtbar, starte naechstes Objekt nach 8000ms
	}
}

function checkSelect(id) {
	var element = byId(id+"list");									// select mit angegebenem Namen ansprechen
	var i = element.selectedIndex;														// hole den Index des aktuell ausgewaehlten Eintrags
	var selValue = element.options[i].value;											// hole den Text des aktuell ausgewaehlten Eintrags
	if (selValue === "neuestadt") {														// wenn eine neue Stadt eingetragen werden soll
		var userInput = prompt("Geben Sie den Namen der neuen Stadt ein:");
		if (userInput != "" && userInput != null) {
			var opt = createOption(formatValue(userInput), userInput);					// erstelle neue Option mit der Benutzereingabe
			element.add(opt, element[i]);												// fuege neue Option hinzu
			element.options[i].selected = 'selected';									// selektiere den neuen Eintrag
		}
	}
}

function addCities(select) {															// damit man nicht alle Staedte mehrfach eintragen muss
	select.add(createOption('', 'Stadt', true));
	select.add(createOption('berlin', 'Berlin'));
	select.add(createOption('koeln', 'Köln'));
	select.add(createOption('frankfurt', 'Frankfurt'));
	select.add(createOption('hamburg', 'Hamburg'));
	select.add(createOption('muenchen', 'München'));
	select.add(createOption('neuestadt', 'Neue Stadt...'));
}

function showZoom(img) {
	var y = byId('zoomImage').src = img;
	byId('zoomwrap').style.visibility = 'visible';
}

function hideZoom() {
	var z = byId('zoomwrap').style.visibility = 'hidden';
}

//============== Helferfunktionen ==============//

function formatValue(str) {									// ersetze alle dt. Umlaute und gib das Wort in Kleinbuchstaben zurueck
	return str.toLowerCase().replace(/\u00e4/g, "ae").replace(/\u00f6/g, "oe").replace(/\u00fc/g, "ue").replace(/\u00df/g, "ss").replace(/ /g, "_");
}

function formatDate(date) {									// uebersetze ein Datum vom ISO 8601-Format in die dt. Schreibweise und gib es zurueck
	return date.replace(/(\d\d\d\d)-(\d\d)-(\d\d)/i, "$3.$2.$1");
}

function createOption(value, text, disabled) {				// neue Option erstellen
	var option = document.createElement("option");
	    option.value = value;
	    option.text = text;
	    option.disabled = disabled ? true : false;			// kurzform fuer if() {..} else {...}
	return option;
}<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var async = require('async');
var extend = require('xtend');
var CountedReadySignal = require('ready-signal/counted');
var test = require('tape');
var util = require('util');
var TChannel = require('../../channel.js');
var parallel = require('run-parallel');
var debugLogtron = require('debug-logtron');

module.exports = allocCluster;

function allocCluster(opts) {
    opts = opts || {};

    var host = 'localhost';
    var logger = debugLogtron('tchannel', {
        enabled: true
    });

    var cluster = {
        logger: logger,
        hosts: new Array(opts.numPeers),
        channels: new Array(opts.numPeers),
        destroy: destroy,
        ready: CountedReadySignal(opts.numPeers),
        assertCleanState: assertCleanState
    };
    var channelOptions = extend({
        logger: logger
    }, opts.channelOptions || opts);

    for (var i = 0; i < opts.numPeers; i++) {
        createChannel(i);
    }

    return cluster;

    function assertCleanState(assert, expected) {
        cluster.channels.forEach(function eachChannel(chan, i) {
            var chanExpect = expected.channels[i];
            if (!chanExpect) {
                assert.fail(util.format('unexpected channel[%s]', i));
                return;
            }

            var peers = chan.peers.values();
            assert.equal(peers.length, chanExpect.peers.length, util.format(
                'channel[%s] should have %s peer(s)', i, chanExpect.peers.length));
            peers.forEach(function eachPeer(peer, j) {
                var peerExpect = chanExpect.peers[j];
                if (!peerExpect) {
                    assert.fail(util.format(
                        'unexpected channel[%s] peer[%s]', i, j));
                    return;
                }
                peer.connections.forEach(function eachConn(conn, k) {
                    var connExpect = peerExpect.connections[k];
                    if (!connExpect) {
                        assert.fail(util.format(
                            'unexpected channel[%s] peer[%s] conn[%s]', i, j, k));
                        return;
                    }
                    Object.keys(connExpect).forEach(function eachProp(prop) {
                        var desc = util.format(
                            'channel[%s] peer[%s] conn[%s] should .%s',
                            i, j, k, prop);
                        switch (prop) {
                        case 'inReqs':
                            assert.equal(Object.keys(conn.requests.in).length, connExpect.inReqs, desc);
                            break;
                        case 'outReqs':
                            assert.equal(Object.keys(conn.requests.out).length, connExpect.outReqs, desc);
                            break;
                        default:
                            assert.equal(conn[prop], connExpect[prop], desc);
                        }
                    });
                });
            });
        });
    }

    function createChannel(i) {
        var chan = TChannel(extend(channelOptions));
        var port = opts.listen && opts.listen[i] || 0;
        chan.listen(port, host);
        cluster.channels[i] = chan;
        chan.on('listening', chanReady);

        function chanReady() {
            var port = chan.address().port;
            cluster.hosts[i] = util.format('%s:%s', host, port);
            cluster.ready.signal(cluster);
        }
    }

    function destroy(cb) {
        parallel(cluster.channels.map(function(chan) {
            return function(done) {
                if (!chan.destroyed) chan.quit(done);
            };
        }), cb);
    }
}

allocCluster.test = function testCluster(desc, opts, t) {
    if (typeof opts === 'number') {
        opts = {
            numPeers: opts
        };
    }
    if (typeof opts === 'function') {
        t = opts;
        opts = {};
    }
    test(desc, function t2(assert) {
        allocCluster(opts).ready(function clusterReady(cluster) {
            assert.once('end', function testEnded() {
                cluster.destroy();
            });
            t(cluster, assert);
        });
    });
};

function ClusterPool(setup) {
    var self = this;
    self.free = [];
    self.setup = setup;
}

ClusterPool.prototype.get = function getCluster(callback) {
    var self = this;
    if (self.free.length) {
        callback(null, self.free.shift());
    } else {
        self.setup(callback);
    }
};

ClusterPool.prototype.release = function release(cluster) {
    var self = this;
    self.free.push(cluster);
};

ClusterPool.prototype.destroy = function destroy(callback) {
    var self = this;
    var free = self.free;
    self.free = [];
    async.each(free, function destroyEach(cluster, next) {
        cluster.destroy(next);
    }, callback);
};

allocCluster.Pool = ClusterPool;
<commit_msg>add .only() helper to tests<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var async = require('async');
var extend = require('xtend');
var CountedReadySignal = require('ready-signal/counted');
var test = require('tape');
var util = require('util');
var TChannel = require('../../channel.js');
var parallel = require('run-parallel');
var debugLogtron = require('debug-logtron');

module.exports = allocCluster;

function allocCluster(opts) {
    opts = opts || {};

    var host = 'localhost';
    var logger = debugLogtron('tchannel', {
        enabled: true
    });

    var cluster = {
        logger: logger,
        hosts: new Array(opts.numPeers),
        channels: new Array(opts.numPeers),
        destroy: destroy,
        ready: CountedReadySignal(opts.numPeers),
        assertCleanState: assertCleanState
    };
    var channelOptions = extend({
        logger: logger
    }, opts.channelOptions || opts);

    for (var i = 0; i < opts.numPeers; i++) {
        createChannel(i);
    }

    return cluster;

    function assertCleanState(assert, expected) {
        cluster.channels.forEach(function eachChannel(chan, i) {
            var chanExpect = expected.channels[i];
            if (!chanExpect) {
                assert.fail(util.format('unexpected channel[%s]', i));
                return;
            }

            var peers = chan.peers.values();
            assert.equal(peers.length, chanExpect.peers.length, util.format(
                'channel[%s] should have %s peer(s)', i, chanExpect.peers.length));
            peers.forEach(function eachPeer(peer, j) {
                var peerExpect = chanExpect.peers[j];
                if (!peerExpect) {
                    assert.fail(util.format(
                        'unexpected channel[%s] peer[%s]', i, j));
                    return;
                }
                peer.connections.forEach(function eachConn(conn, k) {
                    var connExpect = peerExpect.connections[k];
                    if (!connExpect) {
                        assert.fail(util.format(
                            'unexpected channel[%s] peer[%s] conn[%s]', i, j, k));
                        return;
                    }
                    Object.keys(connExpect).forEach(function eachProp(prop) {
                        var desc = util.format(
                            'channel[%s] peer[%s] conn[%s] should .%s',
                            i, j, k, prop);
                        switch (prop) {
                        case 'inReqs':
                            assert.equal(Object.keys(conn.requests.in).length, connExpect.inReqs, desc);
                            break;
                        case 'outReqs':
                            assert.equal(Object.keys(conn.requests.out).length, connExpect.outReqs, desc);
                            break;
                        default:
                            assert.equal(conn[prop], connExpect[prop], desc);
                        }
                    });
                });
            });
        });
    }

    function createChannel(i) {
        var chan = TChannel(extend(channelOptions));
        var port = opts.listen && opts.listen[i] || 0;
        chan.listen(port, host);
        cluster.channels[i] = chan;
        chan.on('listening', chanReady);

        function chanReady() {
            var port = chan.address().port;
            cluster.hosts[i] = util.format('%s:%s', host, port);
            cluster.ready.signal(cluster);
        }
    }

    function destroy(cb) {
        parallel(cluster.channels.map(function(chan) {
            return function(done) {
                if (!chan.destroyed) chan.quit(done);
            };
        }), cb);
    }
}

allocCluster.test = function testCluster(desc, opts, t) {
    if (typeof opts === 'number') {
        opts = {
            numPeers: opts
        };
    }
    if (typeof opts === 'function') {
        t = opts;
        opts = {};
    }
    test(desc, function t2(assert) {
        allocCluster(opts).ready(function clusterReady(cluster) {
            assert.once('end', function testEnded() {
                cluster.destroy();
            });
            t(cluster, assert);
        });
    });
};

allocCluster.test.only = function testClusterOnly(desc, opts, t) {
    if (typeof opts === 'number') {
        opts = {
            numPeers: opts
        };
    }
    if (typeof opts === 'function') {
        t = opts;
        opts = {};
    }
    test.only(desc, function t2(assert) {
        allocCluster(opts).ready(function clusterReady(cluster) {
            assert.once('end', function testEnded() {
                cluster.destroy();
            });
            t(cluster, assert);
        });
    });
};

function ClusterPool(setup) {
    var self = this;
    self.free = [];
    self.setup = setup;
}

ClusterPool.prototype.get = function getCluster(callback) {
    var self = this;
    if (self.free.length) {
        callback(null, self.free.shift());
    } else {
        self.setup(callback);
    }
};

ClusterPool.prototype.release = function release(cluster) {
    var self = this;
    self.free.push(cluster);
};

ClusterPool.prototype.destroy = function destroy(callback) {
    var self = this;
    var free = self.free;
    self.free = [];
    async.each(free, function destroyEach(cluster, next) {
        cluster.destroy(next);
    }, callback);
};

allocCluster.Pool = ClusterPool;
<|endoftext|>


<commit_before>/**
 * @function UIDialog
 * @version 0.0.2
 */

import {keyCodes, defaultClassNames} from '../../constants';

export default function UIDialog(userOptions) {

    let DOM,
        state = {};

    const defaults = {
        dialog:         '.js-dialog',
        openBtn:        '.js-dialog-btn',
        closeBtn:       '.js-dialog-close-btn',
        isModal:        false,
        showBackdrop:   true
    };

    // Combine defaults with passed in options
    const settings = Object.assign(defaults, userOptions);

    // Create the backdrop
    const backdrop = document.createElement('div');

    backdrop.classList.add(defaultClassNames.DIALOG_BACKDROP);

    init();

    /**
     * @function init
     * @desc Initialises the dialog
     */
    function init() {

        // Save all DOM queries for future use
        DOM = {
            'page':     document.querySelectorAll('body')[0],
            'dialog':   document.querySelectorAll(settings.dialog)[0],
            'openBtn':  document.querySelectorAll(settings.openBtn)[0],
            'closeBtn': document.querySelectorAll(settings.closeBtn)[0]
        };

        // Check if the dialog exists, return if not
        if (DOM.dialog === undefined) {
            return false;
        }

        // Remove backdrop if turned off
        if (!settings.showBackdrop) {
            DOM.dialog.classList.add(defaultClassNames.NO_BACKDROP);
        }

        // Set page attribute
        DOM.page.setAttribute('data-ui-dialog', 'is-initialised');

        // Find dialog and hide if not already hidden
        DOM.dialog.classList.add(defaultClassNames.IS_HIDDEN);

        // Attach event listeners
        DOM.openBtn.addEventListener('click', show, false);
        DOM.closeBtn.addEventListener('click', hide, false);
        if (!settings.isModal) {
            backdrop.addEventListener('click', hide, false);
        }
        document.addEventListener('keydown', keyHandler, false);
    }

    /**
     * @function show
     */
    function show() {
        state.isOpen = true;
        DOM.dialog.classList.remove(defaultClassNames.IS_HIDDEN);
        DOM.page.setAttribute('data-current-dialog', settings.dialog);
        // Add the backdrop to the page
        DOM.page.appendChild(backdrop);
    };

    /**
     * @function hide
     */
    function hide() {
        state.isOpen = false;
        DOM.dialog.classList.add(defaultClassNames.IS_HIDDEN);
        DOM.page.removeAttribute('data-current-dialog');
        // Remove the backdrop from the page
        DOM.page.removeChild(backdrop);
    };

    /**
     * @function keyHandler
     * @desc Checks to see if escape (key 27) has been pressed and dialog not modal
     * @param {Event} e
     */
    function keyHandler(e) {
        if ([keyCodes.ESC_KEY].indexOf(e.which) > -1 && state.isOpen === true && !settings.isModal) {
            e.preventDefault();
            hide();
        }
    }

    // External API
    return {
        show,
        hide
    };

}
<commit_msg>use default params<commit_after>/**
 * @function UIDialog
 * @version 0.0.2
 */

import {keyCodes, defaultClassNames} from '../../constants';

const UIDialog = ({
        dialog = '.js-dialog',
        openBtn = '.js-dialog-btn',
        closeBtn = '.js-dialog-close-btn',
        isModal = false,
        showBackdrop = true
    } = {}) => {

    let DOM,
        state = {};

    // Create the backdrop
    const backdrop = document.createElement('div');

    backdrop.classList.add(defaultClassNames.DIALOG_BACKDROP);

    init();

    /**
     * @function init
     * @desc Initialises the dialog
     */
    function init() {

        // Save all DOM queries for future use
        DOM = {
            'page':     document.querySelectorAll('body')[0],
            'dialog':   document.querySelectorAll(dialog)[0],
            'openBtn':  document.querySelectorAll(openBtn)[0],
            'closeBtn': document.querySelectorAll(closeBtn)[0]
        };

        // Check if the dialog exists, return if not
        if (DOM.dialog === undefined) {
            return false;
        }

        // Remove backdrop if turned off
        if (!showBackdrop) {
            DOM.dialog.classList.add(defaultClassNames.NO_BACKDROP);
        }

        // Set page attribute
        DOM.page.setAttribute('data-ui-dialog', 'is-initialised');

        // Find dialog and hide if not already hidden
        DOM.dialog.classList.add(defaultClassNames.IS_HIDDEN);

        // Attach event listeners
        DOM.openBtn.addEventListener('click', show, false);
        DOM.closeBtn.addEventListener('click', hide, false);
        if (!isModal) {
            backdrop.addEventListener('click', hide, false);
        }
        document.addEventListener('keydown', keyHandler, false);
    }

    /**
     * @function show
     */
    function show() {
        state.isOpen = true;
        DOM.dialog.classList.remove(defaultClassNames.IS_HIDDEN);
        DOM.page.setAttribute('data-current-dialog', dialog);
        // Add the backdrop to the page
        DOM.page.appendChild(backdrop);
    };

    /**
     * @function hide
     */
    function hide() {
        state.isOpen = false;
        DOM.dialog.classList.add(defaultClassNames.IS_HIDDEN);
        DOM.page.removeAttribute('data-current-dialog');
        // Remove the backdrop from the page
        DOM.page.removeChild(backdrop);
    };

    /**
     * @function keyHandler
     * @desc Checks to see if escape (key 27) has been pressed and dialog not modal
     * @param {Event} e
     */
    function keyHandler(e) {
        if ([keyCodes.ESC_KEY].indexOf(e.which) > -1 && state.isOpen === true && !isModal) {
            e.preventDefault();
            hide();
        }
    }

    // External API
    return {
        show,
        hide
    };
};

export default UIDialog;
<|endoftext|>


<commit_before>'use strict';

var Utils = require('./utils')
  , Promise = require('./promise');

/**
 * Hooks are function that are called before and after  (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
 *
 * 1. By specifying them as options in `sequelize.define`
 * 2. By calling `hook()` with a string and your hook handler function
 * 3. By calling the function with the same name as the hook you want

 * ```js
 * // Method 1
 * sequelize.define(name, { attributes }, {
 *   hooks: {
 *     beforeBulkCreate: function () {
 *       // can be a single function
 *     },
 *     beforeValidate: [
 *       function () {},
 *       function() {} // Or an array of several
 *     ]
 *   }
 * })
 *
 * // Method 2
 * Model.hook('afterDestroy', function () {})
 *
 * // Method 3
 * Model.afterBulkUpdate(function () {})
 * ```
 *
 * @see {Sequelize#define}
 * @mixin Hooks
 */
var Hooks = module.exports = function() {};
var hookTypes = {
  beforeValidate: {params: 2},
  afterValidate: {params: 2},
  beforeCreate: {params: 2},
  afterCreate: {params: 2},
  beforeDestroy: {params: 2},
  afterDestroy: {params: 2},
  beforeUpdate: {params: 2},
  afterUpdate: {params: 2},
  beforeBulkCreate: {params: 2},
  afterBulkCreate: {params: 2},
  beforeBulkDestroy: {params: 1},
  afterBulkDestroy: {params: 1},
  beforeBulkUpdate: {params: 1},
  afterBulkUpdate: {params: 1},
  beforeFind: {params: 1},
  beforeFindAfterExpandIncludeAll: {params: 1},
  beforeFindAfterOptions: {params: 1},
  afterFind: {params: 2}
};
var hookAliases = {
  beforeDelete: 'beforeDestroy',
  afterDelete: 'afterDestroy',
  beforeBulkDelete: 'beforeBulkDestroy',
  afterBulkDelete: 'afterBulkDestroy'
};

Hooks.replaceHookAliases = function(hooks) {
  var realHookName;

  Utils._.each(hooks, function(hooksArray, name) {
    // Does an alias for this hook name exist?
    if (realHookName = hookAliases[name]) {
      // Add the hooks to the actual hook
      hooks[realHookName] = (hooks[realHookName] || []).concat(hooksArray);

      // Delete the alias
      delete hooks[name];
    }
  });

  return hooks;
};

Hooks.runHooks = function(hooks) {
  var self = this
    , fn
    , fnArgs = Array.prototype.slice.call(arguments, 1)
    , hookType;

  if (typeof fnArgs[fnArgs.length - 1] === 'function') {
    fn = fnArgs.pop();
  }

  if (typeof hooks === 'string') {
    hookType = hooks;
    hooks = this.options.hooks[hooks] || [];
  }

  if (!Array.isArray(hooks)) {
    hooks = hooks === undefined ? [] : [hooks];
  }

  var promise = Promise.map(hooks, function(hook) {
    if (typeof hook === 'object') {
      hook = hook.fn;
    }

    if (hookType && hook.length > hookTypes[hookType].params) {
      hook = Promise.promisify(hook, self);
    }

    return hook.apply(self, fnArgs);
  }, {concurrency: 1}).return();

  if (fn) {
    return promise.nodeify(fn);
  }

  return promise;
};

Hooks.hook = function() {
  return Hooks.addHook.apply(this, arguments);
};

/**
 * Add a hook to the model
 *
 * @param {String}    hooktype
 * @param {String}    [name]    Provide a name for the hook function. This serves no purpose, other than the ability to be able to order hooks based on some sort of priority system in the future.
 * @param {Function}  fn        The hook function
 *
 * @alias hook
 */
Hooks.addHook = function(hookType, name, fn) {
  if (typeof name === 'function') {
    fn = name;
    name = null;
  }

  // Aliases
  hookType = hookAliases[hookType] || hookType;

  // Just in case if we override the default DAOFactory.options
  this.options.hooks[hookType] = this.options.hooks[hookType] || [];
  this.options.hooks[hookType][this.options.hooks[hookType].length] = !!name ? {name: name, fn: fn} : fn;
  return this;
};

/**
 * A hook that is run before validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeValidate', name, fn);
};

/**
 * A hook that is run after validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterValidate', name, fn);
};

/**
 * A hook that is run before creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.beforeCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeCreate', name, fn);
};

/**
 * A hook that is run after creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.afterCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterCreate', name, fn);
};

/**
 * A hook that is run before destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias beforeDelete
 */
Hooks.beforeDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDestroy', name, fn);
};

Hooks.beforeDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDelete', name, fn);
};

/**
 * A hook that is run after destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias afterDelete
 */
Hooks.afterDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDestroy', name, fn);
};

Hooks.afterDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDelete', name, fn);
};

/**
 * A hook that is run before updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeUpdate', name, fn);
};

/**
 * A hook that is run after updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterUpdate', name, fn);
};

/**
 * A hook that is run before creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.beforeBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkCreate', name, fn);
};

/**
 * A hook that is run after creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.afterBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkCreate', name, fn);
};

/**
 * A hook that is run before destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias beforeBulkDelete
 */
Hooks.beforeBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDestroy', name, fn);
};

Hooks.beforeBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDelete', name, fn);
};

/**
 * A hook that is run after destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias afterBulkDelete
 */
Hooks.afterBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDestroy', name, fn);
};

Hooks.afterBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDelete', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkUpdate', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.afterBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkUpdate', name, fn);
};

/**
 * A hook that is run before a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFind = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFind', name, fn);
};

/**
 * A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterExpandIncludeAll = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterExpandIncludeAll', name, fn);
};

/**
 * A hook that is run before a find (select) query, after all option parsing is complete
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterOptions = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterOptions', name, fn);
};

/**
 * A hook that is run after a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance(s), options, callback(err)
 */
Hooks.afterFind = function(name, fn) {
  return Hooks.addHook.call(this, 'afterFind', name, fn);
};
<commit_msg>Replace `.map()` with `.each()`<commit_after>'use strict';

var Utils = require('./utils')
  , Promise = require('./promise');

/**
 * Hooks are function that are called before and after  (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
 *
 * 1. By specifying them as options in `sequelize.define`
 * 2. By calling `hook()` with a string and your hook handler function
 * 3. By calling the function with the same name as the hook you want

 * ```js
 * // Method 1
 * sequelize.define(name, { attributes }, {
 *   hooks: {
 *     beforeBulkCreate: function () {
 *       // can be a single function
 *     },
 *     beforeValidate: [
 *       function () {},
 *       function() {} // Or an array of several
 *     ]
 *   }
 * })
 *
 * // Method 2
 * Model.hook('afterDestroy', function () {})
 *
 * // Method 3
 * Model.afterBulkUpdate(function () {})
 * ```
 *
 * @see {Sequelize#define}
 * @mixin Hooks
 */
var Hooks = module.exports = function() {};
var hookTypes = {
  beforeValidate: {params: 2},
  afterValidate: {params: 2},
  beforeCreate: {params: 2},
  afterCreate: {params: 2},
  beforeDestroy: {params: 2},
  afterDestroy: {params: 2},
  beforeUpdate: {params: 2},
  afterUpdate: {params: 2},
  beforeBulkCreate: {params: 2},
  afterBulkCreate: {params: 2},
  beforeBulkDestroy: {params: 1},
  afterBulkDestroy: {params: 1},
  beforeBulkUpdate: {params: 1},
  afterBulkUpdate: {params: 1},
  beforeFind: {params: 1},
  beforeFindAfterExpandIncludeAll: {params: 1},
  beforeFindAfterOptions: {params: 1},
  afterFind: {params: 2}
};
var hookAliases = {
  beforeDelete: 'beforeDestroy',
  afterDelete: 'afterDestroy',
  beforeBulkDelete: 'beforeBulkDestroy',
  afterBulkDelete: 'afterBulkDestroy'
};

Hooks.replaceHookAliases = function(hooks) {
  var realHookName;

  Utils._.each(hooks, function(hooksArray, name) {
    // Does an alias for this hook name exist?
    if (realHookName = hookAliases[name]) {
      // Add the hooks to the actual hook
      hooks[realHookName] = (hooks[realHookName] || []).concat(hooksArray);

      // Delete the alias
      delete hooks[name];
    }
  });

  return hooks;
};

Hooks.runHooks = function(hooks) {
  var self = this
    , fn
    , fnArgs = Array.prototype.slice.call(arguments, 1)
    , hookType;

  if (typeof fnArgs[fnArgs.length - 1] === 'function') {
    fn = fnArgs.pop();
  }

  if (typeof hooks === 'string') {
    hookType = hooks;
    hooks = this.options.hooks[hooks] || [];
  }

  if (!Array.isArray(hooks)) {
    hooks = hooks === undefined ? [] : [hooks];
  }

  var promise = Promise.each(hooks, function(hook) {
    if (typeof hook === 'object') {
      hook = hook.fn;
    }

    if (hookType && hook.length > hookTypes[hookType].params) {
      hook = Promise.promisify(hook, self);
    }

    return hook.apply(self, fnArgs);
  }).return();

  if (fn) {
    return promise.nodeify(fn);
  }

  return promise;
};

Hooks.hook = function() {
  return Hooks.addHook.apply(this, arguments);
};

/**
 * Add a hook to the model
 *
 * @param {String}    hooktype
 * @param {String}    [name]    Provide a name for the hook function. This serves no purpose, other than the ability to be able to order hooks based on some sort of priority system in the future.
 * @param {Function}  fn        The hook function
 *
 * @alias hook
 */
Hooks.addHook = function(hookType, name, fn) {
  if (typeof name === 'function') {
    fn = name;
    name = null;
  }

  // Aliases
  hookType = hookAliases[hookType] || hookType;

  // Just in case if we override the default DAOFactory.options
  this.options.hooks[hookType] = this.options.hooks[hookType] || [];
  this.options.hooks[hookType][this.options.hooks[hookType].length] = !!name ? {name: name, fn: fn} : fn;
  return this;
};

/**
 * A hook that is run before validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeValidate', name, fn);
};

/**
 * A hook that is run after validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterValidate', name, fn);
};

/**
 * A hook that is run before creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.beforeCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeCreate', name, fn);
};

/**
 * A hook that is run after creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.afterCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterCreate', name, fn);
};

/**
 * A hook that is run before destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias beforeDelete
 */
Hooks.beforeDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDestroy', name, fn);
};

Hooks.beforeDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDelete', name, fn);
};

/**
 * A hook that is run after destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias afterDelete
 */
Hooks.afterDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDestroy', name, fn);
};

Hooks.afterDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDelete', name, fn);
};

/**
 * A hook that is run before updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeUpdate', name, fn);
};

/**
 * A hook that is run after updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterUpdate', name, fn);
};

/**
 * A hook that is run before creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.beforeBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkCreate', name, fn);
};

/**
 * A hook that is run after creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.afterBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkCreate', name, fn);
};

/**
 * A hook that is run before destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias beforeBulkDelete
 */
Hooks.beforeBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDestroy', name, fn);
};

Hooks.beforeBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDelete', name, fn);
};

/**
 * A hook that is run after destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias afterBulkDelete
 */
Hooks.afterBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDestroy', name, fn);
};

Hooks.afterBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDelete', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkUpdate', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.afterBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkUpdate', name, fn);
};

/**
 * A hook that is run before a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFind = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFind', name, fn);
};

/**
 * A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterExpandIncludeAll = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterExpandIncludeAll', name, fn);
};

/**
 * A hook that is run before a find (select) query, after all option parsing is complete
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterOptions = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterOptions', name, fn);
};

/**
 * A hook that is run after a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance(s), options, callback(err)
 */
Hooks.afterFind = function(name, fn) {
  return Hooks.addHook.call(this, 'afterFind', name, fn);
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';

import Icon from '../icon/Icon';
import NavMenu from './NavMenu';

const NavItem = ({ type, link, text, onClick, icon, list, color, className }) => {
    const content = (
        <>
            {icon && <Icon fill="light" name={icon} color={color} className="mr1" />}
            {text}
        </>
    );

    if (type === 'link') {
        return (

                <NavLink className={`navigation__link ellipsis ${className}`} to={link}>
                    {content}
                </NavLink>
                {list.length ? <NavMenu list={list} /> : null}

        );
    }

    if (type === 'text') {
        return (

                <span className={`navigation__link ellipsis ${className}`}>
                    {content}
                    {list.length ? <NavMenu list={list} /> : null}

        );
    }

    if (type === 'button') {
        return (

                <button type="button" className={`w100 navigation__link ellipsis ${className}`} onClick={onClick}>
                    {content}
                </button>
                {list.length ? <NavMenu list={list} /> : null}

        );
    }

    return null;
};

NavItem.propTypes = {
    icon: PropTypes.string,
    color: PropTypes.string,
    onClick: PropTypes.func,
    type: PropTypes.oneOf(['link', 'button', 'text']),
    link: PropTypes.string,
    text: PropTypes.string,
    list: PropTypes.arrayOf(PropTypes.object),
    className: PropTypes.string
};

NavItem.defaultProps = {
    type: 'link',
    className: '',
    list: []
};

export default NavItem;
<commit_msg>Add support exact and isActive on NavLink<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';

import Icon from '../icon/Icon';
import NavMenu from './NavMenu';

const NavItem = ({ type, link, isActive, exact, text, onClick, icon, list, color, className }) => {
    const content = (

            {icon && <Icon fill="light" name={icon} color={color} className="mr1 flex-item-noshrink" />}
            {text}

    );

    if (type === 'link') {
        return (

                <NavLink className={`navigation__link ${className}`} exact={exact} isActive={isActive} to={link}>
                    {content}
                </NavLink>
                {list.length ? <NavMenu list={list} /> : null}

        );
    }

    if (type === 'text') {
        return (

                <span className={`navigation__link ${className}`}>
                    {content}
                    {list.length ? <NavMenu list={list} /> : null}

        );
    }

    if (type === 'button') {
        return (

                <button type="button" className={`w100 navigation__link ${className}`} onClick={onClick}>
                    {content}
                </button>
                {list.length ? <NavMenu list={list} /> : null}

        );
    }

    return null;
};

NavItem.propTypes = {
    isActive: PropTypes.func,
    exact: PropTypes.bool,
    icon: PropTypes.string,
    color: PropTypes.string,
    onClick: PropTypes.func,
    type: PropTypes.oneOf(['link', 'button', 'text']),
    link: PropTypes.string,
    text: PropTypes.string,
    list: PropTypes.arrayOf(PropTypes.object),
    className: PropTypes.string
};

NavItem.defaultProps = {
    type: 'link',
    className: '',
    list: []
};

export default NavItem;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import {
  Animated,
  TouchableOpacity
} from 'react-native';

import InnerButtonView from './InnerButtonView';

class AwesomeButton extends Component {
  static propTypes = {
    states: PropTypes.object.isRequired,
    buttonState: PropTypes.string,
    transitionDuration: PropTypes.number,
    spinnerColor: PropTypes.string,
    activeOpacity: PropTypes.number,
    labelStyle: PropTypes.object,
    backgroundStyle: PropTypes.object,
  }

  constructor(props) {
    super(props);
    this.state = {
      backgroundColor: new Animated.Value(0),
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      backgroundColor: new Animated.Value(0),
      startColor: this.props.states[this.props.buttonState].backgroundColor,
      endColor: this.props.states[nextProps.buttonState].backgroundColor
    });
  }

  componentDidUpdate() {
    this.startAnimation();
  }

  startAnimation() {
    Animated.timing(this.state.backgroundColor,
      {
        toValue: 1,
        duration: this.props.transitionDuration
      }
    ).start();
  }

  render() {
    let bgColor = this.state.backgroundColor.interpolate({
      inputRange: [0, 1],
      outputRange: [this.state.startColor, this.state.endColor]
    });

    bgColor = 'rgb(232, 123, 123)';

    const AnimatedView =
      (<Animated.View style={[this.props.backgroundStyle, { backgroundColor: bgColor }]}>
        <InnerButtonView
          currentStateObject={this.props.states[this.props.buttonState]}
          labelStyle={this.props.labelStyle}
          spinnerColor={this.props.spinnerColor}
        />
      </Animated.View>);

    if (this.props.states[this.props.buttonState].onPress) {
      return (
        <TouchableOpacity
          style={{ flex: 1 }}
          activeOpacity={this.props.activeOpacity}
          onPress={this.props.states[this.props.buttonState].onPress}
        >
          { AnimatedView }
        </TouchableOpacity>
      );
    }
    return { AnimatedView };
  }
}

AwesomeButton.defaultProps = {
  buttonState: 'default',
  backgroundStyle: {
    flex: 1,
    height: 40,
    backgroundColor: 'rgb(255, 0, 0)',
    borderRadius: 20
  },
  labelStyle: {
    color: '#FFFFFF'
  },
  spinnerColor: '#FFFFFF',
  transitionDuration: 250,
  activeOpacity: 0.92
};

export default AwesomeButton;

<commit_msg>Refactor<commit_after>import React, { Component, PropTypes } from 'react';
import {
  Animated,
  TouchableOpacity
} from 'react-native';

import InnerButtonView from './InnerButtonView';

class AwesomeButton extends Component {
  static propTypes = {
    states: PropTypes.object.isRequired,
    buttonState: PropTypes.string,
    transitionDuration: PropTypes.number,
    spinnerColor: PropTypes.string,
    activeOpacity: PropTypes.number,
    labelStyle: PropTypes.object,
    backgroundStyle: PropTypes.object,
  }

  constructor(props) {
    super(props);
    this.state = {
      backgroundColor: new Animated.Value(0),
      startColor: this.props.states[this.props.buttonState].backgroundColor,
      endColor: this.props.states[this.props.buttonState].backgroundColor
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      backgroundColor: new Animated.Value(0),
      startColor: this.props.states[this.props.buttonState].backgroundColor,
      endColor: this.props.states[nextProps.buttonState].backgroundColor
    });
  }

  componentDidUpdate() {
    this.startAnimation();
  }

  startAnimation() {
    Animated.timing(this.state.backgroundColor,
      {
        toValue: 1,
        duration: this.props.transitionDuration
      }
    ).start();
  }

  render() {
    const bgColor = this.state.backgroundColor.interpolate({
      inputRange: [0, 1],
      outputRange: [this.state.startColor, this.state.endColor]
    });

    const AnimatedView =
      (<Animated.View style={[this.props.backgroundStyle, { backgroundColor: bgColor }]}>
        <InnerButtonView
          currentStateObject={this.props.states[this.props.buttonState]}
          labelStyle={this.props.labelStyle}
          spinnerColor={this.props.spinnerColor}
        />
      </Animated.View>);

    if (this.props.states[this.props.buttonState].onPress) {
      return (
        <TouchableOpacity
          style={{ flex: 1 }}
          activeOpacity={this.props.activeOpacity}
          onPress={this.props.states[this.props.buttonState].onPress}
        >
          { AnimatedView }
        </TouchableOpacity>
      );
    }
    return { AnimatedView };
  }
}

AwesomeButton.defaultProps = {
  buttonState: 'default',
  backgroundStyle: {
    flex: 1,
    height: 40,
    backgroundColor: 'rgb(255, 0, 0)',
    borderRadius: 20
  },
  labelStyle: {
    color: '#FFFFFF'
  },
  spinnerColor: '#FFFFFF',
  transitionDuration: 250,
  activeOpacity: 0.92
};

export default AwesomeButton;

<|endoftext|>


<commit_before>//Function that normalizes each row of a matrix
function normalizeMatrix(m){
    for (var i = 0; i < m.length; i++) {
        m[i].normalize();
    }
}

//Function that creates a matrix of feature probabilities given a config file
function createBiomeMatrix() {

    //Keep track of number of unique biomes and features
    var biomeCount = 0;
    var featureCount = 0;
    //Mappings of biomes and features to matrix indeces
    var biomeMap = {};
    var featureMap = {};

    //Fill in the biome map
    for (var biome in biomes) {
        //js thing to ignore internal properties
        if (!biomes.hasOwnProperty(biome)) {
            continue;
        }
        biomeMap[biome] = biomeCount++;
    }

    //Fill in the feature map
    for (var feature in features) {
        if (!features.hasOwnProperty(feature)) {
            continue;
        }
        featureMap[feature] = featureCount++;
    }

    //Debug output. Let me know if I should remove this
    console.log(biomeMap);
    console.log(featureMap);

    //Create matrix to hold the values
    var biomeMatrix = [];
    for (var i = 0; i < biomeCount; i++) {
        biomeMatrix.push([]);
        for (var j = 0; j < featureCount; j++) {
            biomeMatrix[i].push(0);
        }
    }

    //Look through every biome, and every feature in that biome
    for (var biome in biomes) {
        if (!biomes.hasOwnProperty(biome)) {
            continue;
        }

        for (var feature in biomes[biome]["features"]) {
            if (!biomes[biome]["features"].hasOwnProperty(feature)) {
                continue;
            }

            //Add the probability of the feature to the correct matrix index
            biomeMatrix[biomeMap[biome]][featureMap[feature]] = biomes[biome]["features"][feature];
        }
    }

    normalizeMatrix(biomeMatrix);

    console.log(biomeMatrix);

    //Create an object holding the matrix and maps for usable information
    biomeMatrixContext = {};
    biomeMatrixContext["matrix"] = biomeMatrix;
    biomeMatrixContext["biomeMap"] = biomeMap;
    biomeMatrixContext["featureMap"] = featureMap;

    return biomeMatrixContext;
}
<commit_msg>Forgot to change parser along with the configs<commit_after>//Function that normalizes each row of a matrix
function normalizeMatrix(m){
    for (var i = 0; i < m.length; i++) {
        m[i].normalize();
    }
}

//Function that creates a matrix of feature probabilities given a config file
function createBiomeMatrix() {

    //Keep track of number of unique biomes and features
    var biomeCount = 0;
    var featureCount = 0;
    //Mappings of biomes and features to matrix indeces
    var biomeMap = {};
    var featureMap = {};

    //Fill in the biome map
    for (var biome in biomes) {
        //js thing to ignore internal properties
        if (!biomes.hasOwnProperty(biome)) {
            continue;
        }
        biomeMap[biome] = biomeCount++;
    }

    //Fill in the feature map
    for (var feature in features) {
        if (!features.hasOwnProperty(feature)) {
            continue;
        }
        featureMap[feature] = featureCount++;
    }

    //Debug output. Let me know if I should remove this
    console.log(biomeMap);
    console.log(featureMap);

    //Create matrix to hold the values
    var biomeMatrix = [];
    for (var i = 0; i < biomeCount; i++) {
        biomeMatrix.push([]);
        for (var j = 0; j < featureCount; j++) {
            biomeMatrix[i].push(0);
        }
    }

    //Look through every biome, and every feature in that biome
    for (var biome in biomes) {
        if (!biomes.hasOwnProperty(biome)) {
            continue;
        }

        for (var feature in biomes[biome].features) {
            if (!biomes[biome].features.hasOwnProperty(feature)) {
                continue;
            }

            //Add the probability of the feature to the correct matrix index
            biomeMatrix[biomeMap[biome]][featureMap[feature]] = biomes[biome].features[feature];
        }
    }

    normalizeMatrix(biomeMatrix);

    console.log(biomeMatrix);

    //Create an object holding the matrix and maps for usable information
    biomeMatrixContext = {};
    biomeMatrixContext["matrix"] = biomeMatrix;
    biomeMatrixContext["biomeMap"] = biomeMap;
    biomeMatrixContext["featureMap"] = featureMap;

    return biomeMatrixContext;
}
<|endoftext|>