<commit_before>import React from 'react';
import { subscribe } from 'horizon-react';
import { Row, Col, Table, Well } from 'react-bootstrap';

// import PageHeader from '../../_partials/page-header';
import InvitationItem from './InvitationItem';

/**
  *
  * A list of all invitations
  *
  * @param  {Object} horizon - horizon The horizon object
  *
  * @return {ReactComponent}
  */

const mapDataToProps = {
  invitations: (hz) => hz('invitations')
};

const InvitationList = (props) => (

Add Invitation

    <Row>
      <Col md={12}>
        <Well>

                Returned RSVP?
                Guests
                Plus Allowed
                Plus Bringing

            {props.invitations.map(
              invitation => (
                <InvitationItem
                  key={invitation.id}
                  invitation={invitation}
                />
              )
            )}

        </Well>
      </Col>
    </Row>

);

export default subscribe({
  mapDataToProps
})(InvitationList);
<commit_msg>Corrected header<commit_after>import React from 'react';
import { subscribe } from 'horizon-react';
import { Row, Col, Table, Well } from 'react-bootstrap';

// import PageHeader from '../../_partials/page-header';
import InvitationItem from './InvitationItem';

/**
  *
  * A list of all invitations
  *
  * @param  {Object} horizon - horizon The horizon object
  *
  * @return {ReactComponent}
  */

const mapDataToProps = {
  invitations: (hz) => hz('invitations')
};

const InvitationList = (props) => (

Invitations

    <Row>
      <Col md={12}>
        <Well>

                Returned RSVP?
                Guests
                Plus Allowed
                Plus Bringing

            {props.invitations.map(
              invitation => (
                <InvitationItem
                  key={invitation.id}
                  invitation={invitation}
                />
              )
            )}

        </Well>
      </Col>
    </Row>

);

export default subscribe({
  mapDataToProps
})(InvitationList);
<|endoftext|>


<commit_before>import xs from 'xstream'
import { i, a, h, p, div, br, label, input, code, table, tr, td, b, h2, button, svg, h1, th, thead, tbody, li, span, img, em } from '@cycle/dom'
import { log } from '../../utils/logger'
import { merge } from 'ramda'
import dropRepeats from 'xstream/extra/dropRepeats'
import { stateDebug } from '../../utils/utils'

export function CompoundInfo(sources) {

    const state$ = sources.onion.state$
    const props$ = sources.props

    const click$ = sources.DOM.select('.zoom').events('click').mapTo(1)
    const zoomed$ = click$
        .fold((x, y) => x + y, 0)
        .map(count => (count % 2 == 0) ? false : true)

    function entry(key, value) {
        return [
            span('.col .s4', { style: { fontWeight: 'lighter' } }, key),
            span('.col .s8', (value.length != 0) ? value : '')
        ]
    }

    const blur$ = props$
        .filter(props => props.common.blur != undefined)
        .map(props => ({ filter : 'blur(' + props.common.blur + 'px)'}) )
        .startWith({ filter : 'blur(0px)'})

    const detail = (sample, props, blur) => {
        let hStyle = { style: { margin: '0px', fontWeight: 'bold' } }
        let pStyle = { style: { margin: '0px' } }
        let hStylewBlur = { style: merge(blur, { margin: '0px', fontWeight: 'bold' } ) }
        let pStylewBlur = { style: merge(blur, { margin: '0px' } ) }
        let urlSourire = props.sourire.url
        let url = urlSourire + encodeURIComponent(sample.smiles).replace(/%20/g, '+')
        return div('.col .s12', [
            div('.col .s6 .l4', { style: { margin: '15px 0px 0px 0px' } }, [
                p(pStylewBlur, entry('Name: ', sample.compoundname)),
                p(pStylewBlur, entry('JNJS: ', sample.jnjs)),
                p(pStylewBlur, entry('JNJB: ', sample.jnjb)),
                p(pStyle, entry('Type: ', sample.Type)),
            ]),
            div('.col .s6 .l4', { style: { margin: '15px 0px 0px 0px' } }, [
                p('.s12', pStyle, entry('InchiKey: ', sample.inchikey)),
                p('.s12', pStyle, entry('Targets: ', sample.targets.join(', ')))
             ]),
             div('.col .s4 .offset-s8 .l4', { style: merge(blur, { margin: '20px 0px 0px 0px' } ) }, [
                (sample.smiles != null && sample.smiles != 'NA' && sample.smiles != 'No Smiles')
                    ? img('.col .s12 .valign', { props: { src: url } })
                    : ''
            ]),
        ])
    }

    const vdom$ = xs.combine(state$, zoomed$, props$, blur$)
        .map(([sample, zoom, props, blur]) => {
            let urlSourire = props.sourire.url
            let bgcolor = props.table.bgcolor //'rgba(20,20,20,0.08 )' //(sample.zhang >= 0) ? 'rgba(44,123,182, 0.08)' : 'rgba(215,25,28, 0.08)'
            let url = urlSourire + encodeURIComponent(sample.smiles).replace(/%20/g, '+')
            let zhangRounded = (sample.zhang != null) ? sample.zhang.toFixed(3) : 'NA'

            return li('.collection-item  .zoom', { style: { 'background-color': bgcolor } },
                [
                    div('.row', { style: { fontWeight: 'small' } }, [
                        div('.col .s1 .left-align', { style: { fontWeight: 'bold' } }, [sample.targets.length]),
                        // div('.col .s2', [sample.id]),
                        // div('.col .s1', [sample.protocolname]),
                        div('.col .s2', {style : blur}, [(sample.jnjs != "NA") ? sample.jnjs : '']),
                        div('.col .s3', {style : blur}, [sample.compoundname]),
                        div('.col .s3 .center-align', {style : blur}, [
                            ((sample.smiles != null && sample.smiles != 'NA' && sample.smiles != 'No Smiles') && zoom == false)
                                ? img({ props: { src: url, height: 50, 'object-fit': 'contain' } })
                                : ''
                        ]),
                    ]),
                    (zoom) ? div('.row', [detail(sample, props, blur)]) : div()
                ])
        })
        .startWith(li('.collection-itm .zoom', [p('Just one item!!!')]))

    return {
        DOM: vdom$
    };

}<commit_msg>Added known targets to compound table<commit_after>import xs from 'xstream'
import { i, a, h, p, div, br, label, input, code, table, tr, td, b, h2, button, svg, h1, th, thead, tbody, li, span, img, em } from '@cycle/dom'
import { log } from '../../utils/logger'
import { merge } from 'ramda'
import dropRepeats from 'xstream/extra/dropRepeats'
import { stateDebug } from '../../utils/utils'

export function CompoundInfo(sources) {

    const state$ = sources.onion.state$
    const props$ = sources.props

    const click$ = sources.DOM.select('.zoom').events('click').mapTo(1)
    const zoomed$ = click$
        .fold((x, y) => x + y, 0)
        .map(count => (count % 2 == 0) ? false : true)

    function entry(key, value) {
        return [
            span('.col .s4', { style: { fontWeight: 'lighter' } }, key),
            span('.col .s8', (value.length != 0) ? value : '')
        ]
    }

    const blur$ = props$
        .filter(props => props.common.blur != undefined)
        .map(props => ({ filter: 'blur(' + props.common.blur + 'px)' }))
        .startWith({ filter: 'blur(0px)' })

    const detail = (sample, props, blur) => {
        let hStyle = { style: { margin: '0px', fontWeight: 'bold' } }
        let pStyle = { style: { margin: '0px' } }
        let hStylewBlur = { style: merge(blur, { margin: '0px', fontWeight: 'bold' }) }
        let pStylewBlur = { style: merge(blur, { margin: '0px' }) }
        let urlSourire = props.sourire.url
        let url = urlSourire + encodeURIComponent(sample.smiles).replace(/%20/g, '+')
        return div('.col .s12', [
            div('.col .s6 .l4', { style: { margin: '15px 0px 0px 0px' } }, [
                p(pStylewBlur, entry('Name: ', sample.compoundname)),
                p(pStylewBlur, entry('JNJS: ', sample.jnjs)),
                p(pStylewBlur, entry('JNJB: ', sample.jnjb)),
                p(pStyle, entry('Type: ', sample.Type)),
            ]),
            div('.col .s6 .l4', { style: { margin: '15px 0px 0px 0px' } }, [
                p('.s12', pStyle, entry('InchiKey: ', sample.inchikey)),
                p('.s12', pStyle, entry('Targets: ', sample.targets.join(', ')))
            ]),
            div('.col .s4 .offset-s8 .l4', { style: merge(blur, { margin: '20px 0px 0px 0px' }) }, [
                (sample.smiles != null && sample.smiles != 'NA' && sample.smiles != 'No Smiles')
                    ? img('.col .s12 .valign', { props: { src: url } })
                    : ''
            ]),
        ])
    }

    const vdom$ = xs.combine(state$, zoomed$, props$, blur$)
        .map(([sample, zoom, props, blur]) => {
            let urlSourire = props.sourire.url
            let bgcolor = props.table.bgcolor //'rgba(20,20,20,0.08 )' //(sample.zhang >= 0) ? 'rgba(44,123,182, 0.08)' : 'rgba(215,25,28, 0.08)'
            let url = urlSourire + encodeURIComponent(sample.smiles).replace(/%20/g, '+')
            let zhangRounded = (sample.zhang != null) ? sample.zhang.toFixed(3) : 'NA'

            return li('.collection-item  .zoom', { style: { 'background-color': bgcolor } },
                [
                    div('.row', { style: { fontWeight: 'small' } }, [
                        div('.col .s1 .left-align', { style: { fontWeight: 'bold' } }, [sample.targets.length]),
                        div('.col .s2', { style: blur }, [(sample.jnjs != "NA") ? sample.jnjs : '']),
                        div('.col .s3', { style: blur }, [sample.compoundname]),
                        div('.col .s3 .truncate', { style: blur }, [sample.targets.join(", ")]),
                        div('.col .s3 .center-align', { style: blur }, [
                            ((sample.smiles != null && sample.smiles != 'NA' && sample.smiles != 'No Smiles') && zoom == false)
                                ? img({ props: { src: url, height: 50, 'object-fit': 'contain' } })
                                : ''
                        ]),
                    ]),
                    (zoom) ? div('.row', [detail(sample, props, blur)]) : div()
                ])
        })
        .startWith(li('.collection-itm .zoom', [p('Just one item!!!')]))

    return {
        DOM: vdom$
    };

}<|endoftext|>


<commit_before>"use strict";

// bitmasks
const NAMETABLE_BITMASK = 0xc00,
      NAMETABLE_RESET = ~NAMETABLE_BITMASK;

function Background( ppu ) {
	this.ppu = ppu;
	this.memory = ppu.memory;

	this.enabled = true;
	this.enabledLeft = true;
	this.enabledPixel = false;

	this.loopyV = 0;
	this.loopyT = 0;
	this.loopyW = 0;
	this.loopyX = 0;

	this.baseTable = 0;

	this.copyingVertical = false;
	this.fetchingTiles = false;
	this.fetchingTilesPhase = 0;

	this.x = 0;
	this.scanlineColors = new Uint8Array( 0x200 );
	this.palette = 0;
	this.tileLow = 0;
	this.tileHigh = 0;
	this.tileMask = 0;

	Object.preventExtensions( this );
}

Background.prototype = {
	toggle: function( flag ) {
		this.enabled = !!flag;
	},

	toggleLeft: function( flag ) {
		this.enabledLeft = !!flag;
	},

	writeAddress: function( value ) {
		if ( this.loopyW ) {
			value &= 0xff;
			this.loopyT = ( this.loopyT & 0xff00 ) | value;
			this.loopyV = this.loopyT;
		} else {
			value &= 0x3f; // only use lowest 6 bits
			value = value << 8;
			this.loopyT = ( this.loopyT & 0x00ff ) | value; // note, also resets bit 14 of loopy_t (for unknown reason)
		}

		this.loopyW = !this.loopyW;
	},

	writeScroll: function( value ) {
		if ( this.loopyW ) {
			// set vertical scroll
			this.loopyT = this.loopyT & ~0x73e0;
			this.loopyT = this.loopyT | ( (value & 0x7) << 12 );
			this.loopyT = this.loopyT | ( (value & 0xf8) << 2 );

			this.loopyW = 0;
		} else {
			// set horizontal scroll
			this.loopyT = this.loopyT & 0x7fe0;
			this.loopyT |= ( value >> 3 );

			this.loopyX = value & ( 0x7 );

			this.loopyW = 1;
		}
	},

	evaluate: function() {
		this.initLineCycle();

		if ( this.fetchingTiles ) {
			this.fetchTileData();
		}

		if ( this.ppu.enabled ) {
			switch( this.ppu.lineCycle ) {
			case 256:
				// increment coarse X position every 8th cycle
				this.incrementVY();
				break;
			case 257:
				// reset horizontal at end of scanline
				// copy horizontal bits from loopy_t to loopy_v
				this.loopyV = ( this.loopyV & 0x7be0 ) | ( this.loopyT & 0x41f );
				break;
			}

			// finish initialization of loopy_v from loopy_t at end of pre-render scanline
			if ( this.copyingVertical ) {
				// copy vertical bits from loopy_t to loopy_v
				this.loopyV = ( this.loopyV & 0x41f ) | ( this.loopyT & 0x7be0 );
			}
		}
	},

	initLineCycle: function() {
		const lineCycle = this.ppu.lineCycle;

		if ( lineCycle < 10 ) {
			switch( lineCycle ) {
			case 1:
				this.enabledPixel = this.enabledLeft && this.ppu.inLeft8px;
				this.fetchingTiles = true;
				this.fetchingTilesPhase = 1;
				break;
			case 9:
				this.enabledPixel = this.ppu.enabled;
				break;
			}
		} else if ( lineCycle > 256 ) {
			switch( lineCycle ) {
			case 321:
				this.x = -this.loopyX - 8;
				this.fetchingTiles = true;
				this.fetchingTilesPhase = 1;
				break;
			case 337:
				/* falls through */
			case 257:
				this.fetchingTiles = false;
				break;
			case 281:
				if ( this.ppu.scanline === -1 ) {
					this.copyingVertical = true;
				}
				break;
			case 304:
				if ( this.ppu.scanline === -1 ) {
					this.copyingVertical = false;
				}
				break;
			}
		}
	},

	/**
	 * Increment coarse X scroll in loopy_v.
	 */
	incrementVX: function() {
		if ((this.loopyV & 0x1f) === 31) {
			// coarse X is maxed out, wrap around to next nametable
			this.loopyV &= ( 0xffff & ~0x1f );
			this.loopyV ^= 0x0400;
		}
		else {
			// we can safely increment loopy_v (since X is in the lowest bits)
			this.loopyV += 1;
		}
	},

	/**
	 * Increment Y scroll in loopy_v.
	 * TODO optimizations
	 */
	incrementVY: function() {
		if ((this.loopyV & 0x7000) != 0x7000) {
			// fine Y < 7: increment
			this.loopyV += 0x1000;
		} else {
			// fine Y at maximum: reset fine Y, increment coarse Y
			this.loopyV &= ~0x7000;

			var coarseY = (this.loopyV & 0x03e0) >>> 5;
			if (coarseY == 29) {
				// switch vertical nametable
				coarseY = 0;
				this.loopyV ^= 0x0800;
			} else if (coarseY == 31) {
				// reset coarse Y without switching nametable
				coarseY = 0;
			} else {
				// simply increment coarse Y
				coarseY += 1;
			}

			// set coarse Y in loopy_v
			this.loopyV = (this.loopyV & ~0x03e0) | (coarseY << 5);
		}
	},

	setPixel: function() {
		var color = this.scanlineColors[ this.ppu.lineCycle - 1 ];

		if ( !this.enabledPixel ) {
			color = 0;
		}

		return color;
	},

	/**
	 * Fetch background tile data.
	 */
	fetchTileData: function() {
		if ( this.fetchingTilesPhase++ === 7 ) {
			const nametableAddress = 0x2000 | (this.loopyV & 0x0fff),
			      attrAddress = 0x23c0 | (this.loopyV & 0x0c00) | ((this.loopyV >> 4) & 0x38) | ((this.loopyV >> 2) & 0x07),
			      nameTableByte = this.memory.read( nametableAddress ),
			      attribute = this.memory.read( attrAddress ),

			      fineY = ( this.loopyV & 0x7000 ) >> 12,
			      tileAddress = ( nameTableByte << 4 ) + this.baseTable + fineY,

			      bitmapLow = this.memory.read( tileAddress ),
			      bitmapHigh = this.memory.read( tileAddress + 8 );

			var paletteMask = 3, // top left
			    paletteShift = 0,
			    palette = 0;

			if ( nametableAddress & 0x2 ) {
				// right
				paletteMask <<= 2;
				paletteShift = 2;
			}
			if ( nametableAddress & 0x40 ) {
				// bottom
				paletteMask <<= 4;
				paletteShift += 4;
			}

			palette = ( attribute & paletteMask ) >> paletteShift;

			// this.preloadTile( bitmapLow, bitmapHigh, palette );
			this.palette = palette << 2;
			this.tileLow = bitmapLow;
			this.tileHigh = bitmapHigh;
			this.tileMask = 0x80;

			this.incrementVX();

			this.fetchingTilesPhase = 0;
		}
	},

	setColor: function() {
		const low = !!( this.tileLow & this.tileMask ),
		      high = !!( this.tileHigh & this.tileMask ) << 1,
		      color = ( high | low );

		this.scanlineColors[ this.x++ & 0x1ff ] = color && ( this.palette | color );

		this.tileMask >>= 1;
	},

	setNameTable: function( index ) {
		this.loopyT = ( this.loopyT & NAMETABLE_RESET ) | ( index << 10 );
	}
};

module.exports = Background;<commit_msg>Optimized Background.evaluate<commit_after>"use strict";

// bitmasks
const NAMETABLE_BITMASK = 0xc00,
      NAMETABLE_RESET = ~NAMETABLE_BITMASK;

function Background( ppu ) {
	this.ppu = ppu;
	this.memory = ppu.memory;

	this.enabled = true;
	this.enabledLeft = true;
	this.enabledPixel = false;

	this.loopyV = 0;
	this.loopyT = 0;
	this.loopyW = 0;
	this.loopyX = 0;

	this.baseTable = 0;

	this.copyingVertical = false;
	this.fetchingTiles = false;
	this.fetchingTilesPhase = 0;

	this.x = 0;
	this.scanlineColors = new Uint8Array( 0x200 );
	this.palette = 0;
	this.tileLow = 0;
	this.tileHigh = 0;
	this.tileMask = 0;

	Object.preventExtensions( this );
}

Background.prototype = {
	toggle: function( flag ) {
		this.enabled = !!flag;
	},

	toggleLeft: function( flag ) {
		this.enabledLeft = !!flag;
	},

	writeAddress: function( value ) {
		if ( this.loopyW ) {
			value &= 0xff;
			this.loopyT = ( this.loopyT & 0xff00 ) | value;
			this.loopyV = this.loopyT;
		} else {
			value &= 0x3f; // only use lowest 6 bits
			value = value << 8;
			this.loopyT = ( this.loopyT & 0x00ff ) | value; // note, also resets bit 14 of loopy_t (for unknown reason)
		}

		this.loopyW = !this.loopyW;
	},

	writeScroll: function( value ) {
		if ( this.loopyW ) {
			// set vertical scroll
			this.loopyT = this.loopyT & ~0x73e0;
			this.loopyT = this.loopyT | ( (value & 0x7) << 12 );
			this.loopyT = this.loopyT | ( (value & 0xf8) << 2 );

			this.loopyW = 0;
		} else {
			// set horizontal scroll
			this.loopyT = this.loopyT & 0x7fe0;
			this.loopyT |= ( value >> 3 );

			this.loopyX = value & ( 0x7 );

			this.loopyW = 1;
		}
	},

	evaluate: function() {
		this.initLineCycle();

		if ( this.fetchingTiles ) {
			this.setColor();

			if ( this.ppu.enabled ) {
				this.fetchTileData();
			}
		}

		if ( this.ppu.lineCycle > 255 ) {
			switch( this.ppu.lineCycle ) {
			case 256:
				if ( this.ppu.enabled ) {
					// increment coarse X position every 8th cycle
					this.incrementVY();
				}
				break;
			case 257:
				if ( this.ppu.enabled ) {
					// reset horizontal at end of scanline
					// copy horizontal bits from loopy_t to loopy_v
					this.loopyV = ( this.loopyV & 0x7be0 ) | ( this.loopyT & 0x41f );
				}
				break;
			}

			// finish initialization of loopy_v from loopy_t at end of pre-render scanline
			if ( this.copyingVertical ) {
				if ( this.ppu.enabled ) {
					// copy vertical bits from loopy_t to loopy_v
					this.loopyV = ( this.loopyV & 0x41f ) | ( this.loopyT & 0x7be0 );
				}
			}
		}
	},

	initLineCycle: function() {
		const lineCycle = this.ppu.lineCycle;

		if ( lineCycle < 10 ) {
			switch( lineCycle ) {
			case 1:
				this.enabledPixel = this.enabledLeft && this.ppu.inLeft8px;
				this.fetchingTiles = true;
				this.fetchingTilesPhase = 1;
				break;
			case 9:
				this.enabledPixel = this.ppu.enabled;
				break;
			}
		} else if ( lineCycle > 256 ) {
			switch( lineCycle ) {
			case 321:
				this.x = -this.loopyX - 8;
				this.fetchingTiles = true;
				this.fetchingTilesPhase = 1;
				break;
			case 337:
				/* falls through */
			case 257:
				this.fetchingTiles = false;
				break;
			case 281:
				if ( this.ppu.scanline === -1 ) {
					this.copyingVertical = true;
				}
				break;
			case 304:
				if ( this.ppu.scanline === -1 ) {
					this.copyingVertical = false;
				}
				break;
			}
		}
	},

	/**
	 * Increment coarse X scroll in loopy_v.
	 */
	incrementVX: function() {
		if ((this.loopyV & 0x1f) === 31) {
			// coarse X is maxed out, wrap around to next nametable
			this.loopyV &= ( 0xffff & ~0x1f );
			this.loopyV ^= 0x0400;
		}
		else {
			// we can safely increment loopy_v (since X is in the lowest bits)
			this.loopyV += 1;
		}
	},

	/**
	 * Increment Y scroll in loopy_v.
	 * TODO optimizations
	 */
	incrementVY: function() {
		if ((this.loopyV & 0x7000) != 0x7000) {
			// fine Y < 7: increment
			this.loopyV += 0x1000;
		} else {
			// fine Y at maximum: reset fine Y, increment coarse Y
			this.loopyV &= ~0x7000;

			var coarseY = (this.loopyV & 0x03e0) >>> 5;
			if (coarseY == 29) {
				// switch vertical nametable
				coarseY = 0;
				this.loopyV ^= 0x0800;
			} else if (coarseY == 31) {
				// reset coarse Y without switching nametable
				coarseY = 0;
			} else {
				// simply increment coarse Y
				coarseY += 1;
			}

			// set coarse Y in loopy_v
			this.loopyV = (this.loopyV & ~0x03e0) | (coarseY << 5);
		}
	},

	setPixel: function() {
		var color = this.scanlineColors[ this.ppu.lineCycle - 1 ];

		if ( !this.enabledPixel ) {
			color = 0;
		}

		return color;
	},

	/**
	 * Fetch background tile data.
	 */
	fetchTileData: function() {
		if ( this.fetchingTilesPhase++ === 7 ) {
			const nametableAddress = 0x2000 | (this.loopyV & 0x0fff),
			      attrAddress = 0x23c0 | (this.loopyV & 0x0c00) | ((this.loopyV >> 4) & 0x38) | ((this.loopyV >> 2) & 0x07),
			      nameTableByte = this.memory.read( nametableAddress ),
			      attribute = this.memory.read( attrAddress ),

			      fineY = ( this.loopyV & 0x7000 ) >> 12,
			      tileAddress = ( nameTableByte << 4 ) + this.baseTable + fineY,

			      bitmapLow = this.memory.read( tileAddress ),
			      bitmapHigh = this.memory.read( tileAddress + 8 );

			var paletteMask = 3, // top left
			    paletteShift = 0,
			    palette = 0;

			if ( nametableAddress & 0x2 ) {
				// right
				paletteMask <<= 2;
				paletteShift = 2;
			}
			if ( nametableAddress & 0x40 ) {
				// bottom
				paletteMask <<= 4;
				paletteShift += 4;
			}

			palette = ( attribute & paletteMask ) >> paletteShift;

			// this.preloadTile( bitmapLow, bitmapHigh, palette );
			this.palette = palette << 2;
			this.tileLow = bitmapLow;
			this.tileHigh = bitmapHigh;
			this.tileMask = 0x80;

			this.incrementVX();

			this.fetchingTilesPhase = 0;
		}
	},

	setColor: function() {
		const low = !!( this.tileLow & this.tileMask ),
		      high = !!( this.tileHigh & this.tileMask ) << 1,
		      color = ( high | low );

		this.scanlineColors[ this.x++ & 0x1ff ] = color && ( this.palette | color );

		this.tileMask >>= 1;
	},

	setNameTable: function( index ) {
		this.loopyT = ( this.loopyT & NAMETABLE_RESET ) | ( index << 10 );
	}
};

module.exports = Background;<|endoftext|>


<commit_before>function QuestionController($scope, $interval, Restangular, navService) {
	$scope.questionCtrl = this;
	var _this = this,
	    question = Restangular.allUrl('Note'),
	    errorCount = 0,
	    running = true;

	this.questions = [];
	$scope.mainCtrl = this;

	function go(path) {
		navService.go(path);
    }

	function questionsReceived(questions){
		errorCount = 0;
		if(_this.questions.length != questions.length){
			_this.questions = questions;
		}

	}
	function questionsFailed(question){
		running = !(++errorCount > 5);
	}
	this.getQuestions = function() {
		question.getList().then(questionsReceived, questionsFailed);
	}

	this.getQuestions();

	var clock = $interval(function(){
		if(running){
			_this.getQuestions();
		}

		},100);
	//On exit lets kill our clock
	$scope.$on('$destroy', function() {
		  if (angular.isDefined(clock)) {
	        $interval.cancel(clock);
	        stop = undefined;
	      }
		})

	this.add = function() {
		question.post(this.newQuestion);
		go('');
	}
	this.voteUp = function(index) {
		var questionToUpdate = _this.questions[index]
		questionToUpdate.voteCount++;
		questionToUpdate.put();
	}
	this.voteDown = function(index) {
		var questionToUpdate = _this.questions[index]
		questionToUpdate.voteCount--;
		questionToUpdate.put();
	}
}
angular.module('jg.ngGrails').controller('questionController',
		QuestionController);<commit_msg>Now the auto update should work<commit_after>function QuestionController($scope, $interval, Restangular, navService) {
	$scope.questionCtrl = this;
	var _this = this,
	    question = Restangular.allUrl('Note'),
	    errorCount = 0,
	    running = true;

	this.questions = [];
	$scope.mainCtrl = this;

	function go(path) {
		navService.go(path);
    }

	function questionsReceived(questions){
		errorCount = 0;
		if(_this.questions.length != questions.length){
			_this.questions = questions;
		}
		else{
			angular.forEach(questions,function(value, key){
				_this.questions[key].voteCount = value.voteCount
			})
		}

	}
	function questionsFailed(question){
		running = !(++errorCount > 5);
	}
	this.getQuestions = function() {
		question.getList().then(questionsReceived, questionsFailed);
	}

	this.getQuestions();

	var clock = $interval(function(){
		if(running){
			_this.getQuestions();
		}

		},100);
	//On exit lets kill our clock
	$scope.$on('$destroy', function() {
		  if (angular.isDefined(clock)) {
	        $interval.cancel(clock);
	        stop = undefined;
	      }
		})

	this.add = function() {
		question.post(this.newQuestion);
		go('');
	}
	this.voteUp = function(index) {
		var questionToUpdate = _this.questions[index]
		questionToUpdate.voteCount++;
		questionToUpdate.put();
	}
	this.voteDown = function(index) {
		var questionToUpdate = _this.questions[index]
		questionToUpdate.voteCount--;
		questionToUpdate.put();
	}
}
angular.module('jg.ngGrails').controller('questionController',
		QuestionController);<|endoftext|>


<commit_before>'use strict'

const check = require('check-types')
const EventEmitter = require('events').EventEmitter
const events = require('./events')

const invalidTypes = {
  undefined: true, // eslint-disable-line no-undefined
  function: true,
  symbol: true
}

module.exports = eventify

/**
 * Public function `eventify`.
 *
 * Returns an event emitter and asynchronously traverses a data structure
 * (depth-first), emitting events as it encounters items. Sanely handles
 * promises, buffers, maps and other iterables.
 *
 * @param data:       The data structure to traverse.
 *
 * @option promises:  'resolve' or 'ignore', default is 'resolve'.
 *
 * @option buffers:   'toString' or 'ignore', default is 'toString'.
 *
 * @option maps:      'object' or 'ignore', default is 'object'.
 *
 * @option iterables:  'array' or 'ignore', default is 'array'.
 *
 * @option circular:   'error' or 'ignore', default is 'error'.
 *
 * @option yieldRate:  The number of data items to process per timeslice,
 *                     default is 16384.
 **/
function eventify (data, options) {
  let ignoreCircularReferences, ignoreItems

  const references = new Map()
  const coercions = {}
  const emitter = new EventEmitter()
  let count = 0
  let yieldRate

  normaliseOptions()
  setImmediate(begin)

  return emitter

  function normaliseOptions () {
    options = options || {}

    normaliseOption('promises')
    normaliseOption('buffers')
    normaliseOption('maps')
    normaliseOption('iterables')

    if (options.circular === 'ignore') {
      ignoreCircularReferences = true
    }

    check.assert.maybe.positive(options.yieldRate)
    yieldRate = options.yieldRate || 16384
  }

  function normaliseOption (key) {
    if (options[key] !== 'ignore') {
      coercions[key] = true
    }
  }

  function begin () {
    proceed(data).then(after)

    function after () {
      emitter.emit(events.end)
    }
  }

  function proceed (datum) {
    if (++count % yieldRate !== 0) {
      return coerce(datum).then(after)
    }

    return new Promise(resolve => {
      setImmediate(() => {
        coerce(datum)
          .then(after)
          .then(resolve)
      })
    })

    function after (coerced) {
      if (isInvalidType(coerced)) {
        return
      }

      if (coerced === false || coerced === true || coerced === null) {
        return literal(coerced)
      }

      const type = typeof coerced

      if (type === 'number') {
        return value(coerced, type)
      }

      if (type === 'string') {
        return value(escapeString(coerced), type)
      }

      if (Array.isArray(coerced)) {
        return array(coerced)
      }

      return object(coerced)
    }
  }

  function coerce (datum) {
    if (check.instanceStrict(datum, Promise)) {
      return coerceThing(datum, 'promises', coercePromise).then(coerce)
    }

    if (check.instanceStrict(datum, Buffer)) {
      return coerceThing(datum, 'buffers', coerceBuffer)
    }

    if (check.instanceStrict(datum, Map)) {
      return coerceThing(datum, 'maps', coerceMap)
    }

    if (
      check.iterable(datum) &&
      check.not.string(datum) &&
      check.not.array(datum)
    ) {
      return coerceThing(datum, 'iterables', coerceIterable)
    }

    if (check.assigned(datum) && check.function(datum.toJSON)) {
      return Promise.resolve(datum.toJSON())
    }

    return Promise.resolve(datum)
  }

  function coerceThing (datum, thing, fn) {
    if (coercions[thing]) {
      return fn(datum)
    }

    return Promise.resolve()
  }

  function coercePromise (promise) {
    return promise.then(result => result)
  }

  function coerceBuffer (buffer) {
    return Promise.resolve(buffer.toString())
  }

  function coerceMap (map) {
    const result = {}

    return coerceCollection(map, result, (item, key) => {
      result[key] = item
    })
  }

  function coerceCollection (coll, target, push) {
    coll.forEach(push)

    return Promise.resolve(target)
  }

  function coerceIterable (iterable) {
    const result = []

    return coerceCollection(iterable, result, item => {
      result.push(item)
    })
  }

  function isInvalidType (datum) {
    return !! invalidTypes[typeof datum]
  }

  function literal (datum) {
    value(datum, 'literal')
  }

  function value (datum, type) {
    emitter.emit(events[type], datum)
  }

  function array (datum) {
    // For an array, collection:object and collection:array are the same.
    return collection(datum, datum, 'array', item => {
      if (isInvalidType(item)) {
        return proceed(null)
      }

      return proceed(item)
    })
  }

  function collection (obj, arr, type, action) {
    let ignoreThisItem

    if (references.has(obj)) {
      ignoreThisItem = ignoreItems = true

      if (! ignoreCircularReferences) {
        emitter.emit(events.error, new Error('Circular reference.'))
      }
    } else {
      references.set(obj, true)
    }

    emitter.emit(events[type])

    return item(0)

    function item (index) {
      if (index >= arr.length) {
        if (ignoreThisItem) {
          ignoreItems = false
        }

        if (ignoreItems) {
          return Promise.resolve()
        }

        emitter.emit(events.endPrefix + events[type])
        references.delete(obj)

        return Promise.resolve()
      }

      if (ignoreItems) {
        return item(index + 1)
      }

      return action(arr[index]).then(item.bind(null, index + 1))
    }
  }

  function object (datum) {
    // For an object, collection:object and collection:array are different.
    return collection(datum, Object.keys(datum), 'object', key => {
      const item = datum[key]

      if (isInvalidType(item)) {
        return Promise.resolve()
      }

      emitter.emit(events.property, key)

      return proceed(item)
    })
  }

  function escapeString (string) {
    string = JSON.stringify(string)
    return string.substring(1, string.length - 1)
  }
}

<commit_msg>fix(perf): shortcut primitive coercion<commit_after>'use strict'

const check = require('check-types')
const EventEmitter = require('events').EventEmitter
const events = require('./events')

const invalidTypes = {
  undefined: true, // eslint-disable-line no-undefined
  function: true,
  symbol: true
}

module.exports = eventify

/**
 * Public function `eventify`.
 *
 * Returns an event emitter and asynchronously traverses a data structure
 * (depth-first), emitting events as it encounters items. Sanely handles
 * promises, buffers, maps and other iterables.
 *
 * @param data:       The data structure to traverse.
 *
 * @option promises:  'resolve' or 'ignore', default is 'resolve'.
 *
 * @option buffers:   'toString' or 'ignore', default is 'toString'.
 *
 * @option maps:      'object' or 'ignore', default is 'object'.
 *
 * @option iterables:  'array' or 'ignore', default is 'array'.
 *
 * @option circular:   'error' or 'ignore', default is 'error'.
 *
 * @option yieldRate:  The number of data items to process per timeslice,
 *                     default is 16384.
 **/
function eventify (data, options) {
  let ignoreCircularReferences, ignoreItems

  const references = new Map()
  const coercions = {}
  const emitter = new EventEmitter()
  let count = 0
  let yieldRate

  normaliseOptions()
  setImmediate(begin)

  return emitter

  function normaliseOptions () {
    options = options || {}

    normaliseOption('promises')
    normaliseOption('buffers')
    normaliseOption('maps')
    normaliseOption('iterables')

    if (options.circular === 'ignore') {
      ignoreCircularReferences = true
    }

    check.assert.maybe.positive(options.yieldRate)
    yieldRate = options.yieldRate || 16384
  }

  function normaliseOption (key) {
    if (options[key] !== 'ignore') {
      coercions[key] = true
    }
  }

  function begin () {
    proceed(data).then(after)

    function after () {
      emitter.emit(events.end)
    }
  }

  function proceed (datum) {
    if (++count % yieldRate !== 0) {
      return coerce(datum).then(after)
    }

    return new Promise(resolve => {
      setImmediate(() => {
        coerce(datum)
          .then(after)
          .then(resolve)
      })
    })

    function after (coerced) {
      if (isInvalidType(coerced)) {
        return
      }

      if (coerced === false || coerced === true || coerced === null) {
        return literal(coerced)
      }

      const type = typeof coerced

      if (type === 'number') {
        return value(coerced, type)
      }

      if (type === 'string') {
        return value(escapeString(coerced), type)
      }

      if (Array.isArray(coerced)) {
        return array(coerced)
      }

      return object(coerced)
    }
  }

  function coerce (datum) {
    if (check.primitive(datum)) {
      return Promise.resolve(datum)
    }

    if (check.instanceStrict(datum, Promise)) {
      return coerceThing(datum, 'promises', coercePromise).then(coerce)
    }

    if (check.instanceStrict(datum, Buffer)) {
      return coerceThing(datum, 'buffers', coerceBuffer)
    }

    if (check.instanceStrict(datum, Map)) {
      return coerceThing(datum, 'maps', coerceMap)
    }

    if (
      check.iterable(datum) &&
      check.not.string(datum) &&
      check.not.array(datum)
    ) {
      return coerceThing(datum, 'iterables', coerceIterable)
    }

    if (check.function(datum.toJSON)) {
      return Promise.resolve(datum.toJSON())
    }

    return Promise.resolve(datum)
  }

  function coerceThing (datum, thing, fn) {
    if (coercions[thing]) {
      return fn(datum)
    }

    return Promise.resolve()
  }

  function coercePromise (promise) {
    return promise.then(result => result)
  }

  function coerceBuffer (buffer) {
    return Promise.resolve(buffer.toString())
  }

  function coerceMap (map) {
    const result = {}

    return coerceCollection(map, result, (item, key) => {
      result[key] = item
    })
  }

  function coerceCollection (coll, target, push) {
    coll.forEach(push)

    return Promise.resolve(target)
  }

  function coerceIterable (iterable) {
    const result = []

    return coerceCollection(iterable, result, item => {
      result.push(item)
    })
  }

  function isInvalidType (datum) {
    return !! invalidTypes[typeof datum]
  }

  function literal (datum) {
    value(datum, 'literal')
  }

  function value (datum, type) {
    emitter.emit(events[type], datum)
  }

  function array (datum) {
    // For an array, collection:object and collection:array are the same.
    return collection(datum, datum, 'array', item => {
      if (isInvalidType(item)) {
        return proceed(null)
      }

      return proceed(item)
    })
  }

  function collection (obj, arr, type, action) {
    let ignoreThisItem

    if (references.has(obj)) {
      ignoreThisItem = ignoreItems = true

      if (! ignoreCircularReferences) {
        emitter.emit(events.error, new Error('Circular reference.'))
      }
    } else {
      references.set(obj, true)
    }

    emitter.emit(events[type])

    return item(0)

    function item (index) {
      if (index >= arr.length) {
        if (ignoreThisItem) {
          ignoreItems = false
        }

        if (ignoreItems) {
          return Promise.resolve()
        }

        emitter.emit(events.endPrefix + events[type])
        references.delete(obj)

        return Promise.resolve()
      }

      if (ignoreItems) {
        return item(index + 1)
      }

      return action(arr[index]).then(item.bind(null, index + 1))
    }
  }

  function object (datum) {
    // For an object, collection:object and collection:array are different.
    return collection(datum, Object.keys(datum), 'object', key => {
      const item = datum[key]

      if (isInvalidType(item)) {
        return Promise.resolve()
      }

      emitter.emit(events.property, key)

      return proceed(item)
    })
  }

  function escapeString (string) {
    string = JSON.stringify(string)
    return string.substring(1, string.length - 1)
  }
}

<|endoftext|>


<commit_before>/**
 * Inji js core
 *
 * @author Alexey Krupskiy <admin@inji.ru>
 * @link http://inji.ru/
 * @copyright 2015 Alexey Krupskiy
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
 */

function Inji() {
  this.options = {};
  this.onLoadCallbacks = [];
  this.loaded = false;
  this.listeners = {};
  this.loadedScripts = {};
}
Inji.prototype.onLoad = function (callback, start) {
  if (typeof callback == 'function') {
    if (this.loaded) {
      callback();
    } else {
      if (start) {
        this.onLoadCallbacks.unshift(callback);
      } else {
        this.onLoadCallbacks.push(callback);
      }
    }
  }
}
Inji.prototype.startCallbacks = function () {
  console.log('inji start onload');
  while (callback = this.onLoadCallbacks.shift()) {
    if (typeof callback == 'function') {
      callback();
    }
  }
  if (this.onLoadCallbacks.length != 0) {
    this.startCallbacks();
  }
  var indicator = document.getElementById('loading-indicator');
  if (indicator) {
    indicator.style.display = 'none';
  }
  inji.loaded = true;
  console.log('inji start complete');
}
Inji.prototype.start = function (options) {
  console.log('Inji start');
  for (key in options.compresedScripts) {
    inji.loadedScripts[options.compresedScripts[key]] = true;
  }
  this.options = options;
  if (options.onLoadModules) {
    this.onLoad(function () {
      for (key in options.onLoadModules) {
        if (typeof inji[key] == 'undefined') {
          inji[key] = new window[key]();
          if (typeof (inji[key].init) == 'function') {
            console.log(key + ' init');
            inji[key].init();
          }
        }
      }
    }, true)
  }
  this.loadScripts(options.scripts, 0);
}
Inji.prototype.loadScripts = function (scripts, key) {
  this.addScript(scripts[key], function () {
    if (typeof (scripts[key].name) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      if (typeof inji[scripts[key].name] == 'undefined') {
        console.log('js ' + scripts[key].name + '(' + scripts[key].file + ') loaded');
        inji[scripts[key].name] = new window[scripts[key].name]();
        if (typeof (inji[scripts[key].name].init) == 'function') {
          inji[scripts[key].name].init();
        }
      }
    } else {
      inji.loadedScripts[scripts[key]] = true;
      console.log('js ' + scripts[key] + ' loaded');
      inji.event('loadScript', scripts[key]);
    }
    if (typeof (scripts[key + 1]) != 'undefined') {
      inji.loadScripts(scripts, key + 1);
    } else {
      console.log('All scripts loaded');
      inji.startCallbacks();
    }
  });
}
Inji.prototype.addScript = function (script, callback) {
  var element = document.createElement('script');
  var src = '';
  if (typeof (script.file) != 'undefined') {
    src = script.file;
  } else {
    src = script;
  }
  if (inji.loadedScripts[src]) {
    if (typeof (callback) == 'function') {
      callback();
    }
    return true;
  }
  element.src = src;
  element.type = 'text/javascript';
  if (typeof (callback) == 'function') {
    element.onload = callback;
  }
  document.head.appendChild(element);

}
Inji.prototype.on = function (eventType, callback) {
  if (typeof this.listeners[eventType] == 'undefined') {
    this.listeners[eventType] = [];
  }
  this.listeners[eventType].push(callback);
}
Inji.prototype.event = function (eventType, object) {
  if (typeof this.listeners[eventType] != 'undefined') {
    for (key in this.listeners[eventType]) {
      this.listeners[eventType][key](eventType, object);
    }
  }
}
Inji.prototype.randomString = function (length) {
  if (!length) {
    length = 20;
  }
  var text = "";
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < length; i++)
    text += chars.charAt(Math.floor(Math.random() * chars.length));

  return text;
}
Inji.prototype.numberFormat = function (number, decimals, dec_point, thousands_sep) {
  //// Format a number with grouped thousands
  //
  // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +	 bugfix by: Michael White (http://crestidg.com)

  var i, j, kw, kd, km;

  // input sanitation & defaults
  if (isNaN(decimals = Math.abs(decimals))) {
    decimals = 2;
  }
  if (dec_point == undefined) {
    dec_point = ",";
  }
  if (thousands_sep == undefined) {
    thousands_sep = ".";
  }

  i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

  if ((j = i.length) > 3) {
    j = j % 3;
  } else {
    j = 0;
  }

  km = (j ? i.substr(0, j) + thousands_sep : "");
  kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
  //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
  kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");

  return km + kw + kd;
}
Inji.prototype.get = function (query) {
  var element = document.querySelector(query);
  if (element) {
    return new function () {
      this.element = element;
      this.attr = function (name) {
        for (var key in this.element.attributes) {
          var attr = element.attributes[key];
          if (attr.name == name) {
            return attr.value;
          }
        }
        return null;
      }
      this.data = function (name) {
        var data = this.attr('data-' + name);
        try {
          return JSON.parse(data);
        } catch (e) {
          return data;
        }

      }
    }
  }
}
var inji = new Inji();

<commit_msg>fix display loaded js without name<commit_after>/**
 * Inji js core
 *
 * @author Alexey Krupskiy <admin@inji.ru>
 * @link http://inji.ru/
 * @copyright 2015 Alexey Krupskiy
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
 */

function Inji() {
  this.options = {};
  this.onLoadCallbacks = [];
  this.loaded = false;
  this.listeners = {};
  this.loadedScripts = {};
}
Inji.prototype.onLoad = function (callback, start) {
  if (typeof callback == 'function') {
    if (this.loaded) {
      callback();
    } else {
      if (start) {
        this.onLoadCallbacks.unshift(callback);
      } else {
        this.onLoadCallbacks.push(callback);
      }
    }
  }
}
Inji.prototype.startCallbacks = function () {
  console.log('inji start onload');
  while (callback = this.onLoadCallbacks.shift()) {
    if (typeof callback == 'function') {
      callback();
    }
  }
  if (this.onLoadCallbacks.length != 0) {
    this.startCallbacks();
  }
  var indicator = document.getElementById('loading-indicator');
  if (indicator) {
    indicator.style.display = 'none';
  }
  inji.loaded = true;
  console.log('inji start complete');
}
Inji.prototype.start = function (options) {
  console.log('Inji start');
  for (key in options.compresedScripts) {
    inji.loadedScripts[options.compresedScripts[key]] = true;
  }
  this.options = options;
  if (options.onLoadModules) {
    this.onLoad(function () {
      for (key in options.onLoadModules) {
        if (typeof inji[key] == 'undefined') {
          inji[key] = new window[key]();
          if (typeof (inji[key].init) == 'function') {
            console.log(key + ' init');
            inji[key].init();
          }
        }
      }
    }, true)
  }
  this.loadScripts(options.scripts, 0);
}
Inji.prototype.loadScripts = function (scripts, key) {
  this.addScript(scripts[key], function () {
    if (typeof (scripts[key].name) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      if (typeof inji[scripts[key].name] == 'undefined') {
        console.log('js ' + scripts[key].name + '(' + scripts[key].file + ') loaded');
        inji[scripts[key].name] = new window[scripts[key].name]();
        if (typeof (inji[scripts[key].name].init) == 'function') {
          inji[scripts[key].name].init();
        }
      }
    } else if (typeof (scripts[key].file) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
        console.log('js ' + scripts[key].file + ' loaded');

    } else {
      inji.loadedScripts[scripts[key]] = true;
      console.log('js ' + scripts[key] + ' loaded');
      inji.event('loadScript', scripts[key]);
    }
    if (typeof (scripts[key + 1]) != 'undefined') {
      inji.loadScripts(scripts, key + 1);
    } else {
      console.log('All scripts loaded');
      inji.startCallbacks();
    }
  });
}
Inji.prototype.addScript = function (script, callback) {
  var element = document.createElement('script');
  var src = '';
  if (typeof (script.file) != 'undefined') {
    src = script.file;
  } else {
    src = script;
  }
  if (inji.loadedScripts[src]) {
    if (typeof (callback) == 'function') {
      callback();
    }
    return true;
  }
  element.src = src;
  element.type = 'text/javascript';
  if (typeof (callback) == 'function') {
    element.onload = callback;
  }
  document.head.appendChild(element);

}
Inji.prototype.on = function (eventType, callback) {
  if (typeof this.listeners[eventType] == 'undefined') {
    this.listeners[eventType] = [];
  }
  this.listeners[eventType].push(callback);
}
Inji.prototype.event = function (eventType, object) {
  if (typeof this.listeners[eventType] != 'undefined') {
    for (key in this.listeners[eventType]) {
      this.listeners[eventType][key](eventType, object);
    }
  }
}
Inji.prototype.randomString = function (length) {
  if (!length) {
    length = 20;
  }
  var text = "";
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < length; i++)
    text += chars.charAt(Math.floor(Math.random() * chars.length));

  return text;
}
Inji.prototype.numberFormat = function (number, decimals, dec_point, thousands_sep) {
  //// Format a number with grouped thousands
  //
  // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +	 bugfix by: Michael White (http://crestidg.com)

  var i, j, kw, kd, km;

  // input sanitation & defaults
  if (isNaN(decimals = Math.abs(decimals))) {
    decimals = 2;
  }
  if (dec_point == undefined) {
    dec_point = ",";
  }
  if (thousands_sep == undefined) {
    thousands_sep = ".";
  }

  i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

  if ((j = i.length) > 3) {
    j = j % 3;
  } else {
    j = 0;
  }

  km = (j ? i.substr(0, j) + thousands_sep : "");
  kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
  //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
  kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");

  return km + kw + kd;
}
Inji.prototype.get = function (query) {
  var element = document.querySelector(query);
  if (element) {
    return new function () {
      this.element = element;
      this.attr = function (name) {
        for (var key in this.element.attributes) {
          var attr = element.attributes[key];
          if (attr.name == name) {
            return attr.value;
          }
        }
        return null;
      }
      this.data = function (name) {
        var data = this.attr('data-' + name);
        try {
          return JSON.parse(data);
        } catch (e) {
          return data;
        }

      }
    }
  }
}
var inji = new Inji();

<|endoftext|>


<commit_before>var tinyurlgen = {

    //Is the current page being processed
    processing : false,
    //The XMLHTTPRequest Object
    request : null,
    //Does the link need to be previewable?
    preview : false,
    // Is this the first time the add-on has been run?
    firstRun : true,
    //TinyURL options
    settings : {
        createpreviewbydefault : false,
        showpageoption : true,
        showlinkoption : true
    },
    //TinyURL localised strings object
    stringsobj : null,
    //A reference to the object that was context clicked
    contextobj : null,

    //A reference to the clipboard object (don't initialise it right away
    clipboard : null,

    //A function to copy the returned URL to the clipboard
    copytoclipboard : function(text){

        // If a link to the clipboard has not yet been created...
        if(!tinyurlgen.clipboard)
        {
            // Create a link to the clipboard if required
            tinyurlgen.clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
        }

        //Copy text to clipboard
        clipboard.copyString(text);
    },

    //A function to ease Component Class interfacing
    cc : function(cName, ifaceName){

        return Components.classes[cName].getService(Components.interfaces[ifaceName]);
    },

    init : function(){
        //Get the broswer XUL Object
        var appcontent = document.getElementById("appcontent");   // browser
        //If it exists...
        if(appcontent){
            //Attach a listener that resets the processing state as a new page is loaded
            appcontent.addEventListener("DOMContentLoaded", tinyurlgen.reset, false);
        }
        //Attach listener event to context menu to show and hide menuitem
        var contextMenu = document.getElementById("contentAreaContextMenu");
        if(contextMenu){
            contextMenu.addEventListener("popupshowing", function(){
                var pageoption = document.getElementById('tinyurlgen-context-page-option');
                var linkoption = document.getElementById('tinyurlgen-context-link-option');
                var pagehidden = !tinyurlgen.settings.showpageoption;
                var linkhidden = true;
                var el;
                if(document.popupNode && tinyurlgen.settings.showlinkoption){
                    el = document.popupNode;
                    while(el){
                        if(el.localName && el.localName.toLowerCase() == 'a'){
                            if(el.href != ''){
                                tinyurlgen.contextobj = el;
                                linkhidden = false;
                            }
                            break;
                        }
                        else{
                            el = el.parentNode;
                        }
                    }
                }

                pageoption.hidden = pagehidden;
                linkoption.hidden = linkhidden;
            }, false);
        }

        //Load and apply settings
        tinyurlgen.applysettings();

        const tinyurlTBItem = "tinyurlgen-status-bar-icon";

        if(tinyurlgen.firstRun){
            // First run - add icon to addon bar and show it
            setTimeout("tinyurlgen.addicontoaddonbar();", 5);
        }

        var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
        .getService(Components.interfaces.nsIXULAppInfo);
        tinyurlgen.FFVersion = appInfo.version;
    },

    addicontoaddonbar : function(){

        const addonbarId = "addon-bar";
        const iconId = "tinyurlgen-status-bar-icon";

        // Get references to the addon bar and icon
        var addonbar = document.getElementById(addonbarId);
        var icon = document.getElementById(iconId);

        // If the addon bar is found, but the icon is not
        if (addonbar && !icon)
        {
            // Add the icon to the toolbar's 'set' property
            var newSet = addonbar.currentSet + "," + iconId;
            addonbar.setAttribute("currentset", newSet);
            addonbar.currentSet = newSet;
            // Make sure the change persists
            document.persist(addonbarId, "currentset");
            // Show the addon bar
            setToolbarVisibility(addonbar, true);
            try {
                BrowserToolboxCustomizeDone(true);
            } catch (e) {}
        }

    },

    applysettings : function(){

        //Load settings from config
        var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);

        tinyurlgen.settings.createpreviewbydefault = prefManager.getBoolPref("extensions.tinyurlgen.createpreviewbydefault");
        tinyurlgen.settings.showpageoption = prefManager.getBoolPref("extensions.tinyurlgen.showcontextoptionforpage");
        tinyurlgen.settings.showlinkoption = prefManager.getBoolPref("extensions.tinyurlgen.showcontextoptionforlinks");

        tinyurlgen.firstRun = prefManager.getBoolPref("extensions.tinyurlgen.firstrun");
        if(tinyurlgen.firstRun){
            prefManager.setBoolPref("extensions.tinyurlgen.firstrun", false);
        }

        //Get button references
        var create = document.getElementById('tinyurlgen-button-create');
        var createwithpreview = document.getElementById('tinyurlgen-button-create-with-preview');
        //If Create Previewable link by default...
        if(tinyurlgen.settings.createpreviewbydefault){
            //Set to default
            createwithpreview.setAttribute("default", true);
            //Unset default
            create.setAttribute("default", "false");
            //Move option to top
            createwithpreview.parentNode.insertBefore(createwithpreview, create);
        }
        else{
            //Set to default
            create.setAttribute("default", true);
            //Unset default
            createwithpreview.setAttribute("default", "false");
            //Move option to top
            create.parentNode.insertBefore(create, createwithpreview);
        }
    },

    //A function to generate a TinyURL
    generate : function(evt){

        //If the page is already being process, end execution
        if(tinyurlgen.processing){
            return false;
        }

        if(evt.target.id == 'tinyurlgen-context-link-option'){
            //Get linked page URL
            var url = tinyurlgen.contextobj.href;
            tinyurlgen.contextobj = null;
        }
        else{
            //Get current page URL
            var url = content.document.location.href;
        }

        //Encode URL
        url = encodeURIComponent(url);

        //Set state to processing
        tinyurlgen.setstate('processing');

        //Create XMLHTTPRequest Object
        tinyurlgen.request = new XMLHttpRequest();
        //Set onload handler
        tinyurlgen.request.onload = tinyurlgen.handleresponse;
        //Constuct request
        tinyurlgen.request.open("GET", "http://tinyurl.com/api-create.php?url=" + url, true);
        //Send request
        tinyurlgen.request.send(null);
    },

    generateplain : function(evt){

        tinyurlgen.generate(evt);
    },

    generatepreview : function(evt){

        tinyurlgen.preview = true;
        tinyurlgen.generate(evt);
    },

    generatedefault : function(evt){

        //If the icon was 'right clicked', end execution
        if(evt.button == 2){
            return false;
        }

        //If Create Previewable link by default
        if(tinyurlgen.settings.createpreviewbydefault){
            //Set preview to true
            tinyurlgen.preview = true;
        }
        tinyurlgen.generate(evt);
    },

    getwindow : function(winName){

        return Components.classes["@mozilla.org/appshell/window-mediator;1"]
        .getService(Components.interfaces.nsIWindowMediator)
        .getMostRecentWindow(winName);
    },

    handleresponse : function(){

        //Collect XMLHTTPRequest response
        var response = tinyurlgen.request.responseText;
        //Destroy XMLHTTPRequest Object
        tinyurlgen.request = null;

        //Check that the response is valid
        if(response.match(/http\:\/\/tinyurl.com\//gi)){
            //Is this a previewable link?
            if(tinyurlgen.preview){
                //Make link previewable
                response = response.replace(/http\:\/\/tinyurl.com\//gi, 'http://preview.tinyurl.com/')
            }
            //Set current state (complete)
            tinyurlgen.setstate('complete');
            //Copy URL to clipboard
            tinyurlgen.copytoclipboard(response);
            //Reset state in 5 seconds
            setTimeout('tinyurlgen.reset();', 5000);
        }
        else{
            //Set current state (error)
            tinyurlgen.setstate('error');
            setTimeout('tinyurlgen.reset();', 5000);
        }
    },

    reset : function(){

        //If a TinyURL is not being generated
        if(!tinyurlgen.processing){
            //Reset the icon
            tinyurlgen.setstate(null);
        }
    },

    setstate : function(state){

        //Define variables
        var icon;
        var title, src, processing;

        //Get relevant titles and icons
        switch(state){
            //TinyURL retrieved successfully
            case 'complete':
                src = 'okay.png';
                title = tinyurlgen.string('state.complete');
                processing = false;
                break;

            //Error occurred when retrieving TinyURL
            case 'error':
                src = 'error.png';
                title = tinyurlgen.string('state.error');
                processing = false;
                break;

            //Currently retrieving TinyURL
            case 'processing':
                src = 'process.gif';
                title = tinyurlgen.string('state.processing');
                processing = true;
                break;

            //Reset to default state
            default:
                src = 'link.png';
                title = tinyurlgen.string('state.default');
                processing = false;
                break;
        }

        //Reset processing state
        tinyurlgen.processing = processing;

        //If processing complete, reset 'preview' flag
        if(!processing){
            tinyurlgen.preview = false;
        }

        //Get icon object
        icon = document.getElementById('tinyurlgen-status-bar-icon');
        if(icon){
            if(icon.nodeName.toLowerCase() == 'toolbarbutton'){
                icon.setAttribute('class', 'toolbarbutton-1 ' + state);
            }
            else{
                icon.setAttribute('src', 'chrome://tinyurlgen/skin/' + src);
            }
            icon.setAttribute('tooltiptext', title);
        }
    },

    showoptions : function(){

        //Get reference to window object
        var win = tinyurlgen.getwindow("TinyURL:Options");
        //If window is already open...
        if(win){
            //Focus it
            win.focus();
        }
        //If not
        else{
            //Create new dialog window
            var parentWindow = (!window.opener || window.opener.closed) ? window : window.opener;
            parentWindow.openDialog("chrome://tinyurlgen/content/options.xul", "_blank", "resizable=no,dialog=no,centerscreen");
        }
    },

    string : function(stringname){

        if(!tinyurlgen.stringobj){
            var localeService = this.cc("@mozilla.org/intl/nslocaleservice;1", "nsILocaleService");
            var bundleService = this.cc("@mozilla.org/intl/stringbundle;1", "nsIStringBundleService");
            var appLocale = localeService.getApplicationLocale();
            tinyurlgen.stringobj = bundleService.createBundle("chrome://tinyurlgen/locale/tinyurl.properties", appLocale);
        }

        return tinyurlgen.stringobj.GetStringFromName(stringname);
    }
}

//Reset state as new page loads
window.addEventListener('load', tinyurlgen.init, false);<commit_msg>Clipboard move fixed<commit_after>var tinyurlgen = {

    //Is the current page being processed
    processing : false,
    //The XMLHTTPRequest Object
    request : null,
    //Does the link need to be previewable?
    preview : false,
    // Is this the first time the add-on has been run?
    firstRun : true,
    //TinyURL options
    settings : {
        createpreviewbydefault : false,
        showpageoption : true,
        showlinkoption : true
    },
    //TinyURL localised strings object
    stringsobj : null,
    //A reference to the object that was context clicked
    contextobj : null,
    //A reference to the clipboard object (don't initialise it right away
    clipboard : null,

    //A function to copy the returned URL to the clipboard
    copytoclipboard : function(text){

        // If a link to the clipboard has not yet been created...
        if(!tinyurlgen.clipboard)
        {
            // Create a link to the clipboard if required
            tinyurlgen.clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
        }

        //Copy text to clipboard
        tinyurlgen.clipboard.copyString(text);
    },

    //A function to ease Component Class interfacing
    cc : function(cName, ifaceName){

        return Components.classes[cName].getService(Components.interfaces[ifaceName]);
    },

    init : function(){
        //Get the broswer XUL Object
        var appcontent = document.getElementById("appcontent");   // browser
        //If it exists...
        if(appcontent){
            //Attach a listener that resets the processing state as a new page is loaded
            appcontent.addEventListener("DOMContentLoaded", tinyurlgen.reset, false);
        }
        //Attach listener event to context menu to show and hide menuitem
        var contextMenu = document.getElementById("contentAreaContextMenu");
        if(contextMenu){
            contextMenu.addEventListener("popupshowing", function(){
                var pageoption = document.getElementById('tinyurlgen-context-page-option');
                var linkoption = document.getElementById('tinyurlgen-context-link-option');
                var pagehidden = !tinyurlgen.settings.showpageoption;
                var linkhidden = true;
                var el;
                if(document.popupNode && tinyurlgen.settings.showlinkoption){
                    el = document.popupNode;
                    while(el){
                        if(el.localName && el.localName.toLowerCase() == 'a'){
                            if(el.href != ''){
                                tinyurlgen.contextobj = el;
                                linkhidden = false;
                            }
                            break;
                        }
                        else{
                            el = el.parentNode;
                        }
                    }
                }

                pageoption.hidden = pagehidden;
                linkoption.hidden = linkhidden;
            }, false);
        }

        //Load and apply settings
        tinyurlgen.applysettings();

        const tinyurlTBItem = "tinyurlgen-status-bar-icon";

        if(tinyurlgen.firstRun){
            // First run - add icon to addon bar and show it
            setTimeout("tinyurlgen.addicontoaddonbar();", 5);
        }

        var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
        .getService(Components.interfaces.nsIXULAppInfo);
        tinyurlgen.FFVersion = appInfo.version;
    },

    addicontoaddonbar : function(){

        const addonbarId = "addon-bar";
        const iconId = "tinyurlgen-status-bar-icon";

        // Get references to the addon bar and icon
        var addonbar = document.getElementById(addonbarId);
        var icon = document.getElementById(iconId);

        // If the addon bar is found, but the icon is not
        if (addonbar && !icon)
        {
            // Add the icon to the toolbar's 'set' property
            var newSet = addonbar.currentSet + "," + iconId;
            addonbar.setAttribute("currentset", newSet);
            addonbar.currentSet = newSet;
            // Make sure the change persists
            document.persist(addonbarId, "currentset");
            // Show the addon bar
            setToolbarVisibility(addonbar, true);
            try {
                BrowserToolboxCustomizeDone(true);
            } catch (e) {}
        }

    },

    applysettings : function(){

        //Load settings from config
        var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);

        tinyurlgen.settings.createpreviewbydefault = prefManager.getBoolPref("extensions.tinyurlgen.createpreviewbydefault");
        tinyurlgen.settings.showpageoption = prefManager.getBoolPref("extensions.tinyurlgen.showcontextoptionforpage");
        tinyurlgen.settings.showlinkoption = prefManager.getBoolPref("extensions.tinyurlgen.showcontextoptionforlinks");

        tinyurlgen.firstRun = prefManager.getBoolPref("extensions.tinyurlgen.firstrun");
        if(tinyurlgen.firstRun){
            prefManager.setBoolPref("extensions.tinyurlgen.firstrun", false);
        }

        //Get button references
        var create = document.getElementById('tinyurlgen-button-create');
        var createwithpreview = document.getElementById('tinyurlgen-button-create-with-preview');
        //If Create Previewable link by default...
        if(tinyurlgen.settings.createpreviewbydefault){
            //Set to default
            createwithpreview.setAttribute("default", true);
            //Unset default
            create.setAttribute("default", "false");
            //Move option to top
            createwithpreview.parentNode.insertBefore(createwithpreview, create);
        }
        else{
            //Set to default
            create.setAttribute("default", true);
            //Unset default
            createwithpreview.setAttribute("default", "false");
            //Move option to top
            create.parentNode.insertBefore(create, createwithpreview);
        }
    },

    //A function to generate a TinyURL
    generate : function(evt){

        //If the page is already being process, end execution
        if(tinyurlgen.processing){
            return false;
        }

        if(evt.target.id == 'tinyurlgen-context-link-option'){
            //Get linked page URL
            var url = tinyurlgen.contextobj.href;
            tinyurlgen.contextobj = null;
        }
        else{
            //Get current page URL
            var url = content.document.location.href;
        }

        //Encode URL
        url = encodeURIComponent(url);

        //Set state to processing
        tinyurlgen.setstate('processing');

        //Create XMLHTTPRequest Object
        tinyurlgen.request = new XMLHttpRequest();
        //Set onload handler
        tinyurlgen.request.onload = tinyurlgen.handleresponse;
        //Constuct request
        tinyurlgen.request.open("GET", "http://tinyurl.com/api-create.php?url=" + url, true);
        //Send request
        tinyurlgen.request.send(null);
    },

    generateplain : function(evt){

        tinyurlgen.generate(evt);
    },

    generatepreview : function(evt){

        tinyurlgen.preview = true;
        tinyurlgen.generate(evt);
    },

    generatedefault : function(evt){

        //If the icon was 'right clicked', end execution
        if(evt.button == 2){
            return false;
        }

        //If Create Previewable link by default
        if(tinyurlgen.settings.createpreviewbydefault){
            //Set preview to true
            tinyurlgen.preview = true;
        }
        tinyurlgen.generate(evt);
    },

    getwindow : function(winName){

        return Components.classes["@mozilla.org/appshell/window-mediator;1"]
        .getService(Components.interfaces.nsIWindowMediator)
        .getMostRecentWindow(winName);
    },

    handleresponse : function(){

        //Collect XMLHTTPRequest response
        var response = tinyurlgen.request.responseText;
        //Destroy XMLHTTPRequest Object
        tinyurlgen.request = null;

        //Check that the response is valid
        if(response.match(/http\:\/\/tinyurl.com\//gi)){
            //Is this a previewable link?
            if(tinyurlgen.preview){
                //Make link previewable
                response = response.replace(/http\:\/\/tinyurl.com\//gi, 'http://preview.tinyurl.com/')
            }
            //Set current state (complete)
            tinyurlgen.setstate('complete');
            //Copy URL to clipboard
            tinyurlgen.copytoclipboard(response);
            //Reset state in 5 seconds
            setTimeout('tinyurlgen.reset();', 5000);
        }
        else{
            //Set current state (error)
            tinyurlgen.setstate('error');
            setTimeout('tinyurlgen.reset();', 5000);
        }
    },

    reset : function(){

        //If a TinyURL is not being generated
        if(!tinyurlgen.processing){
            //Reset the icon
            tinyurlgen.setstate(null);
        }
    },

    setstate : function(state){

        //Define variables
        var icon;
        var title, src, processing;

        //Get relevant titles and icons
        switch(state){
            //TinyURL retrieved successfully
            case 'complete':
                src = 'okay.png';
                title = tinyurlgen.string('state.complete');
                processing = false;
                break;

            //Error occurred when retrieving TinyURL
            case 'error':
                src = 'error.png';
                title = tinyurlgen.string('state.error');
                processing = false;
                break;

            //Currently retrieving TinyURL
            case 'processing':
                src = 'process.gif';
                title = tinyurlgen.string('state.processing');
                processing = true;
                break;

            //Reset to default state
            default:
                src = 'link.png';
                title = tinyurlgen.string('state.default');
                processing = false;
                break;
        }

        //Reset processing state
        tinyurlgen.processing = processing;

        //If processing complete, reset 'preview' flag
        if(!processing){
            tinyurlgen.preview = false;
        }

        //Get icon object
        icon = document.getElementById('tinyurlgen-status-bar-icon');
        if(icon){
            if(icon.nodeName.toLowerCase() == 'toolbarbutton'){
                icon.setAttribute('class', 'toolbarbutton-1 ' + state);
            }
            else{
                icon.setAttribute('src', 'chrome://tinyurlgen/skin/' + src);
            }
            icon.setAttribute('tooltiptext', title);
        }
    },

    showoptions : function(){

        //Get reference to window object
        var win = tinyurlgen.getwindow("TinyURL:Options");
        //If window is already open...
        if(win){
            //Focus it
            win.focus();
        }
        //If not
        else{
            //Create new dialog window
            var parentWindow = (!window.opener || window.opener.closed) ? window : window.opener;
            parentWindow.openDialog("chrome://tinyurlgen/content/options.xul", "_blank", "resizable=no,dialog=no,centerscreen");
        }
    },

    string : function(stringname){

        if(!tinyurlgen.stringobj){
            var localeService = this.cc("@mozilla.org/intl/nslocaleservice;1", "nsILocaleService");
            var bundleService = this.cc("@mozilla.org/intl/stringbundle;1", "nsIStringBundleService");
            var appLocale = localeService.getApplicationLocale();
            tinyurlgen.stringobj = bundleService.createBundle("chrome://tinyurlgen/locale/tinyurl.properties", appLocale);
        }

        return tinyurlgen.stringobj.GetStringFromName(stringname);
    }
}

//Reset state as new page loads
window.addEventListener('load', tinyurlgen.init, false);<|endoftext|>


<commit_before>(function($) {
  window.baseUrl = "/api/v2/projects/";
  var editingCard = null;
  var render_from_server_paragraph = {
    // status: ['rendered', 'rendering', 'editing']
    //   rendering => rendered
    //   rendered => editing
    //   editing => rendering
    emit: function(div, item) {
      if (item.text == "") {
        div.data('status', 'rendered');
        return div.empty();
      } else {
        div.data('status', 'rendering');
        renderWiki(item.text, function(html) {
          if (div.data('status') == 'rendering') {
            div.data('status', 'rendered');
            div.html(html);
          }
        });
        return div.html('');
      }
    },
    bind: function(div, item) {
      div.bind('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        if (div.data('status') == 'rendering') {
          alert("rendering " + item.text);
        } else {
          div.data('status', 'editing');
          div.trigger(wikimate.events.EDIT);
        }
      });
    }
  }

  $.extend(wikimate.plugins, {
    paragraph: render_from_server_paragraph,
    macro: render_from_server_paragraph,
    body_macro: render_from_server_paragraph,
    html: render_from_server_paragraph
  });

  var mingle_wiki_parser = {
    parse: function(desc) {
      function nextId(index) {
        return 'story_item_' + index;
      }
      return _.map(wiki_parser.parse(desc), function(text, i) {
        if (typeof(text) == 'string') {
          return {id: nextId(i), type: 'paragraph', text: text};
        } else {
          return $.extend({id: nextId(i)}, text);
        }
      });
    },
  };

  function renderWiki(content, onSuccess) {
    var card_id = editingCard.find('card id').text();
    var paramStr = $.param({
      content_provider: {
        id: card_id,
        type: 'card'
      },
      content: content
    });
    jQuery.ajax({
      url: window.baseUrl + project() + "/render?" + paramStr,
      dataType: 'html',
      success: onSuccess,
      failure: ajaxCallFailed
    });
  };

  function requestCard(uri, onSuccess) {
    jQuery.ajax({
      url: window.baseUrl + uri + '.xml',
      dataType: 'xml',
      success: onSuccess,
      failure: ajaxCallFailed
    });
  };

  function updateCardDescription(event, action) {
    var desc = $.map($('.wikimate .item'), function(item) {
      return $(item).data('item').text.trim();
    }).join("\n\n");

    updatingCardDescription();
    var url = window.baseUrl + project() + "/cards/" + number() + ".xml";
    $.ajax({
      url: url,
      dataType: 'xml',
      data: {card: {description: desc}},
      type: 'PUT',
      success: function(r) {
        updatedCardDescription();
      },
      failure: ajaxCallFailed
    })
  };

  function updatingCardDescription() {
    $('.wikimate').css('border-left', '2px solid yellow');
  };
  function updatedCardDescription() {
    $('.wikimate').css('border-left', '2px solid orange');
  };
  function ajaxCallFailed(ajax) {
    console.log("Ajax call failed");
    console.log(ajax);
    $('.wikimate').css('border-left', '2px solid red');
  };

  function parseCardDescription(description) {
    return step('Parsing description', function() {
      return mingle_wiki_parser.parse(description);
    });
  };

  function loadCard(project, number) {
    updatingCardDescription();
    step('Loading ' + project + ' card #' + number + ' description', function() {
      requestCard(project + '/cards/' + number, function(xmlDoc) {
        editingCard = $(xmlDoc);
        var story = parseCardDescription(editingCard.find('card description').text());
        $('#content').empty().wikimate({story: story, change: updateCardDescription});
        updatedCardDescription();
      });
    });
  };

  function cardPageMatch() {
    return window.location.href.match(/\/projects\/([\da-z_]+)\/cards\/(\d+)$/);
  };

  function project() {
    var match = cardPageMatch();
    if (match) {
      return match[1];
    }
    return undefined;
  };
  function number() {
    var match = cardPageMatch();
    if (match) {
      return match[2];
    }
    return undefined;
  };

  function step(msg, func) {
    $('#wiki').append(msg + "
");
    return func.call();
  };

  if (project() && number()) {
    console.log("on card show page: " + project() + " #" + number());
    loadCard(project(), number());
  }
})(jQuery);
<commit_msg>avoid replace wikimate toolbar element when rendering html respond from server side<commit_after>(function($) {
  window.baseUrl = "/api/v2/projects/";
  var editingCard = null;
  var render_from_server_paragraph = {
    // status: ['rendered', 'rendering', 'editing']
    //   rendering => rendered
    //   rendered => editing
    //   editing => rendering
    emit: function(div, item) {
      if (item.text == "") {
        div.data('status', 'rendered');
        return div.empty();
      } else {
        div.data('status', 'rendering');
        renderWiki(item.text, function(html) {
          if (div.data('status') == 'rendering') {
            div.data('status', 'rendered');
            div.find('img').remove();
            div.append(html);
          }
        });
        return div.html('');
      }
    },
    bind: function(div, item) {
      div.bind('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        if (div.data('status') == 'rendering') {
          alert("rendering " + item.text);
        } else {
          div.data('status', 'editing');
          div.trigger(wikimate.events.EDIT);
        }
      });
    }
  }

  $.extend(wikimate.plugins, {
    paragraph: render_from_server_paragraph,
    macro: render_from_server_paragraph,
    body_macro: render_from_server_paragraph,
    html: render_from_server_paragraph
  });

  var mingle_wiki_parser = {
    parse: function(desc) {
      function nextId(index) {
        return 'story_item_' + index;
      }
      return _.map(wiki_parser.parse(desc), function(text, i) {
        if (typeof(text) == 'string') {
          return {id: nextId(i), type: 'paragraph', text: text};
        } else {
          return $.extend({id: nextId(i)}, text);
        }
      });
    },
  };

  function renderWiki(content, onSuccess) {
    var card_id = editingCard.find('card id').text();
    var paramStr = $.param({
      content_provider: {
        id: card_id,
        type: 'card'
      },
      content: content
    });
    jQuery.ajax({
      url: window.baseUrl + project() + "/render?" + paramStr,
      dataType: 'html',
      success: onSuccess,
      failure: ajaxCallFailed
    });
  };

  function requestCard(uri, onSuccess) {
    jQuery.ajax({
      url: window.baseUrl + uri + '.xml',
      dataType: 'xml',
      success: onSuccess,
      failure: ajaxCallFailed
    });
  };

  function updateCardDescription(event, action) {
    var desc = $.map($('.wikimate .item'), function(item) {
      return $(item).data('item').text.trim();
    }).join("\n\n");

    updatingCardDescription();
    var url = window.baseUrl + project() + "/cards/" + number() + ".xml";
    $.ajax({
      url: url,
      dataType: 'xml',
      data: {card: {description: desc}},
      type: 'PUT',
      success: function(r) {
        updatedCardDescription();
      },
      failure: ajaxCallFailed
    })
  };

  function updatingCardDescription() {
    $('.wikimate').css('border-left', '2px solid yellow');
  };
  function updatedCardDescription() {
    $('.wikimate').css('border-left', '2px solid orange');
  };
  function ajaxCallFailed(ajax) {
    console.log("Ajax call failed");
    console.log(ajax);
    $('.wikimate').css('border-left', '2px solid red');
  };

  function parseCardDescription(description) {
    return step('Parsing description', function() {
      return mingle_wiki_parser.parse(description);
    });
  };

  function loadCard(project, number) {
    updatingCardDescription();
    step('Loading ' + project + ' card #' + number + ' description', function() {
      requestCard(project + '/cards/' + number, function(xmlDoc) {
        editingCard = $(xmlDoc);
        var story = parseCardDescription(editingCard.find('card description').text());
        $('#content').empty().wikimate({story: story, change: updateCardDescription});
        updatedCardDescription();
      });
    });
  };

  function cardPageMatch() {
    return window.location.href.match(/\/projects\/([\da-z_]+)\/cards\/(\d+)$/);
  };

  function project() {
    var match = cardPageMatch();
    if (match) {
      return match[1];
    }
    return undefined;
  };
  function number() {
    var match = cardPageMatch();
    if (match) {
      return match[2];
    }
    return undefined;
  };

  function step(msg, func) {
    $('#wiki').append(msg + "
");
    return func.call();
  };

  if (project() && number()) {
    console.log("on card show page: " + project() + " #" + number());
    loadCard(project(), number());
  }
})(jQuery);
<|endoftext|>