<commit_before>/*
 * blueimp Gallery Fullscreen JS 1.2.0
 * https://github.com/blueimp/Gallery
 *
 * Copyright 2013, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

/* global define, window, document */

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Register as an anonymous AMD module:
        define([
            './blueimp-helper',
            './blueimp-gallery'
        ], factory);
    } else {
        // Browser globals:
        factory(
            window.blueimp.helper || window.jQuery,
            window.blueimp.Gallery
        );
    }
}(function ($, Gallery) {
    'use strict';

    $.extend(Gallery.prototype.options, {
        // Defines if the gallery should open in fullscreen mode:
        fullScreen: true
    });

    var initialize = Gallery.prototype.initialize,
        close = Gallery.prototype.close;

    $.extend(Gallery.prototype, {

        getFullScreenElement: function () {
            return document.fullscreenElement ||
                document.webkitFullscreenElement ||
                document.mozFullScreenElement ||
                document.msFullscreenElement;
        },

        requestFullScreen: function (element) {
            if (element.requestFullscreen) {
                element.requestFullscreen();
            } else if (element.webkitRequestFullscreen) {
                element.webkitRequestFullscreen();
            } else if (element.mozRequestFullScreen) {
                element.mozRequestFullScreen();
            } else if (element.msRequestFullscreen) {
                element.msRequestFullscreen();
            }
        },

        exitFullScreen: function () {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitCancelFullScreen) {
                document.webkitCancelFullScreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        },

        initialize: function () {
            initialize.call(this);
            if (this.options.fullScreen && !this.getFullScreenElement()) {
                this.requestFullScreen(this.container[0]);
            }
        },

        close: function () {
            if (this.getFullScreenElement() === this.container[0]) {
                this.exitFullScreen();
            }
            close.call(this);
        }

    });

    return Gallery;
}));
<commit_msg>Update blueimp-gallery-fullscreen.js<commit_after>/*
 * blueimp Gallery Fullscreen JS 1.2.0
 * https://github.com/blueimp/Gallery
 *
 * Copyright 2013, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

/* global define, window, document */

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Register as an anonymous AMD module:
        define([
            './blueimp-helper',
            './blueimp-gallery'
        ], factory);
    } else {
        // Browser globals:
        factory(
            window.blueimp.helper || window.jQuery,
            window.blueimp.Gallery
        );
    }
}(function ($, Gallery) {
    'use strict';

    $.extend(Gallery.prototype.options, {
        // Defines if the gallery should open in fullscreen mode:
        fullScreen: false
    });

    var initialize = Gallery.prototype.initialize,
        close = Gallery.prototype.close;

    $.extend(Gallery.prototype, {

        getFullScreenElement: function () {
            return document.fullscreenElement ||
                document.webkitFullscreenElement ||
                document.mozFullScreenElement ||
                document.msFullscreenElement;
        },

        requestFullScreen: function (element) {
            if (element.requestFullscreen) {
                element.requestFullscreen();
            } else if (element.webkitRequestFullscreen) {
                element.webkitRequestFullscreen();
            } else if (element.mozRequestFullScreen) {
                element.mozRequestFullScreen();
            } else if (element.msRequestFullscreen) {
                element.msRequestFullscreen();
            }
        },

        exitFullScreen: function () {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitCancelFullScreen) {
                document.webkitCancelFullScreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        },

        initialize: function () {
            initialize.call(this);
            if (this.options.fullScreen && !this.getFullScreenElement()) {
                this.requestFullScreen(this.container[0]);
            }
        },

        close: function () {
            if (this.getFullScreenElement() === this.container[0]) {
                this.exitFullScreen();
            }
            close.call(this);
        }

    });

    return Gallery;
}));
<|endoftext|>


<commit_before>const BinarySocket  = require('../../../base/socket');
const Client        = require('../../../base/client');
const localize      = require('../../../../_common/localize').localize;
const State         = require('../../../../_common/storage').State;
const createElement = require('../../../../_common/utility').createElement;
const Url           = require('../../../../_common/url');

const WelcomePage = (() => {
    const onLoad = () => {

        BinarySocket.wait('authorize', 'landing_company', 'get_settings').then(() => {
            if (Client.hasAccountType('real')) {
                Url.defaultRedirectUrl();
            }

            const landing_company   = State.getResponse('landing_company');
            const jp_account_status = State.getResponse('get_settings.jp_account_status.status');
            const upgrade_btn       = document.getElementById('upgrade_btn');
            const upgrade_info      = Client.getUpgradeInfo(landing_company, jp_account_status);
            const show_welcome_msg  = upgrade_info.can_upgrade;

            const allowed_currencies = Client.getLandingCompanyValue({ real: 1 }, landing_company, 'legal_allowed_currencies');

            if (allowed_currencies && allowed_currencies.length > 0) {
                for (let i=0; i < allowed_currencies.length; i++) {
                    const el = document.getElementById(allowed_currencies[i]);
                    if (el) {
                        el.classList.remove('invisible');
                    }
                }
            }

            const setButtonLink = (url, msg) => {
                if (upgrade_btn) {
                    upgrade_btn.html(createElement('span', { text: localize(msg) })).setAttribute('href', Url.urlFor(url));
                    upgrade_btn.classList.remove('button-disabled');
                }
            };

            const welcome_msg = document.getElementById('welcome_container');
            if (welcome_msg) {
                welcome_msg.setVisibility(1);
            }

            if (show_welcome_msg) {
                setButtonLink(upgrade_info.upgrade_link, 'Upgrade now');
            }
        });
    };

    return {
        onLoad,
    };
})();

module.exports = WelcomePage;
<commit_msg>use commonFunction getElementById<commit_after>const BinarySocket   = require('../../../base/socket');
const Client         = require('../../../base/client');
const localize       = require('../../../../_common/localize').localize;
const State          = require('../../../../_common/storage').State;
const createElement  = require('../../../../_common/utility').createElement;
const getElementById = require('../../../../_common/common_functions').getElementById;
const Url            = require('../../../../_common/url');

const WelcomePage = (() => {
    const onLoad = () => {

        BinarySocket.wait('authorize', 'landing_company', 'get_settings').then(() => {
            if (Client.hasAccountType('real')) {
                Url.defaultRedirectUrl();
            }

            const landing_company   = State.getResponse('landing_company');
            const jp_account_status = State.getResponse('get_settings.jp_account_status.status');
            const upgrade_btn       = getElementById('upgrade_btn');
            const upgrade_info      = Client.getUpgradeInfo(landing_company, jp_account_status);
            const show_welcome_msg  = upgrade_info.can_upgrade;

            const allowed_currencies = Client.getLandingCompanyValue({ real: 1 }, landing_company, 'legal_allowed_currencies');

            if (allowed_currencies && allowed_currencies.length > 0) {
                for (let i=0; i < allowed_currencies.length; i++) {
                    const el = getElementById(allowed_currencies[i]);
                    if (el) {
                        el.classList.remove('invisible');
                    }
                }
            }

            const setButtonLink = (url, msg) => {
                if (upgrade_btn) {
                    upgrade_btn.html(createElement('span', { text: localize(msg) })).setAttribute('href', Url.urlFor(url));
                    upgrade_btn.classList.remove('button-disabled');
                }
            };

            const welcome_msg = getElementById('welcome_container');
            if (welcome_msg) {
                welcome_msg.setVisibility(1);
            }

            if (show_welcome_msg) {
                setButtonLink(upgrade_info.upgrade_link, 'Upgrade now');
            }
        });
    };

    return {
        onLoad,
    };
})();

module.exports = WelcomePage;
<|endoftext|>


<commit_before>/**
 * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested values for
 * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
 * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
 * from the lookup menu, that value becomes the value of the input field.
 *
 * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is
 * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then
 * re-enable lookups.
 *
 * See the [OOUI demos][1] for an example.
 *
 * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#LookupElement-try-inputting-an-integer
 *
 * @class
 * @abstract
 * @mixins OO.ui.mixin.RequestManager
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.
 *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
 * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
 * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
 *  By default, the lookup menu is not generated and displayed until the user begins to type.
 * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can
 *  take it over into the input with simply pressing return) automatically or not.
 */
OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
	// Configuration initialization
	config = $.extend( { highlightFirst: true }, config );

	// Mixin constructors
	OO.ui.mixin.RequestManager.call( this, config );

	// Properties
	this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
	this.lookupMenu = new OO.ui.MenuSelectWidget( {
		widget: this,
		input: this,
		$floatableContainer: config.$container || this.$element
	} );

	this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;

	this.lookupsDisabled = false;
	this.lookupInputFocused = false;
	this.lookupHighlightFirstItem = config.highlightFirst;

	// Events
	this.$input.on( {
		focus: this.onLookupInputFocus.bind( this ),
		blur: this.onLookupInputBlur.bind( this ),
		mousedown: this.onLookupInputMouseDown.bind( this )
	} );
	this.connect( this, { change: 'onLookupInputChange' } );
	this.lookupMenu.connect( this, {
		toggle: 'onLookupMenuToggle',
		choose: 'onLookupMenuItemChoose'
	} );

	// Initialization
	this.$input.attr( {
		role: 'combobox',
		'aria-owns': this.lookupMenu.getElementId(),
		'aria-autocomplete': 'list'
	} );
	this.$element.addClass( 'oo-ui-lookupElement' );
	this.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );
	this.$overlay.append( this.lookupMenu.$element );
};

/* Setup */

OO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );

/* Methods */

/**
 * Handle input focus event.
 *
 * @protected
 * @param {jQuery.Event} e Input focus event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {
	this.lookupInputFocused = true;
	this.populateLookupMenu();
};

/**
 * Handle input blur event.
 *
 * @protected
 * @param {jQuery.Event} e Input blur event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {
	this.closeLookupMenu();
	this.lookupInputFocused = false;
};

/**
 * Handle input mouse down event.
 *
 * @protected
 * @param {jQuery.Event} e Input mouse down event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {
	// Only open the menu if the input was already focused.
	// This way we allow the user to open the menu again after closing it with Esc
	// by clicking in the input. Opening (and populating) the menu when initially
	// clicking into the input is handled by the focus handler.
	if ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {
		this.populateLookupMenu();
	}
};

/**
 * Handle input change event.
 *
 * @protected
 * @param {string} value New input value
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {
	if ( this.lookupInputFocused ) {
		this.populateLookupMenu();
	}
};

/**
 * Handle the lookup menu being shown/hidden.
 *
 * @protected
 * @param {boolean} visible Whether the lookup menu is now visible.
 */
OO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {
	if ( !visible ) {
		// When the menu is hidden, abort any active request and clear the menu.
		// This has to be done here in addition to closeLookupMenu(), because
		// MenuSelectWidget will close itself when the user presses Esc.
		this.abortLookupRequest();
		this.lookupMenu.clearItems();
	}
};

/**
 * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.
 *
 * @protected
 * @param {OO.ui.MenuOptionWidget} item Selected item
 */
OO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {
	this.setValue( item.getData() );
};

/**
 * Get lookup menu.
 *
 * @private
 * @return {OO.ui.MenuSelectWidget}
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {
	return this.lookupMenu;
};

/**
 * Disable or re-enable lookups.
 *
 * When lookups are disabled, calls to #populateLookupMenu will be ignored.
 *
 * @param {boolean} disabled Disable lookups
 */
OO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {
	this.lookupsDisabled = !!disabled;
};

/**
 * Open the menu. If there are no entries in the menu, this does nothing.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {
	if ( !this.lookupMenu.isEmpty() ) {
		this.lookupMenu.toggle( true );
	}
	return this;
};

/**
 * Close the menu, empty it, and abort any pending request.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {
	this.lookupMenu.toggle( false );
	this.abortLookupRequest();
	this.lookupMenu.clearItems();
	return this;
};

/**
 * Request menu items based on the input's current value, and when they arrive,
 * populate the menu with these items and show the menu.
 *
 * If lookups have been disabled with #setLookupsDisabled, this function does nothing.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {
	var widget = this,
		value = this.getValue();

	if ( this.lookupsDisabled || this.isReadOnly() ) {
		return;
	}

	// If the input is empty, clear the menu, unless suggestions when empty are allowed.
	if ( !this.allowSuggestionsWhenEmpty && value === '' ) {
		this.closeLookupMenu();
	// Skip population if there is already a request pending for the current value
	} else if ( value !== this.lookupQuery ) {
		this.getLookupMenuItems()
			.done( function ( items ) {
				widget.lookupMenu.clearItems();
				if ( items.length ) {
					widget.lookupMenu
						.addItems( items )
						.toggle( true );
					widget.initializeLookupMenuSelection();
				} else {
					widget.lookupMenu.toggle( false );
				}
			} )
			.fail( function () {
				widget.lookupMenu.clearItems();
			} );
	}

	return this;
};

/**
 * Highlight the first selectable item in the menu, if configured.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {
	if ( this.lookupHighlightFirstItem && !this.lookupMenu.findSelectedItem() ) {
		this.lookupMenu.highlightItem( this.lookupMenu.findFirstSelectableItem() );
	}
};

/**
 * Get lookup menu items for the current query.
 *
 * @private
 * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of
 *   the done event. If the request was aborted to make way for a subsequent request, this promise
 *   will not be rejected: it will remain pending forever.
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {
	return this.getRequestData().then( function ( data ) {
		return this.getLookupMenuOptionsFromData( data );
	}.bind( this ) );
};

/**
 * Abort the currently pending lookup request, if any.
 *
 * @private
 */
OO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {
	this.abortRequest();
};

/**
 * Get a new request object of the current lookup query value.
 *
 * @protected
 * @method
 * @abstract
 * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
 */
OO.ui.mixin.LookupElement.prototype.getLookupRequest = null;

/**
 * Pre-process data returned by the request from #getLookupRequest.
 *
 * The return value of this function will be cached, and any further queries for the given value
 * will use the cache rather than doing API requests.
 *
 * @protected
 * @method
 * @abstract
 * @param {Mixed} response Response from server
 * @return {Mixed} Cached result data
 */
OO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;

/**
 * Get a list of menu option widgets from the (possibly cached) data returned by
 * #getLookupCacheDataFromResponse.
 *
 * @protected
 * @method
 * @abstract
 * @param {Mixed} data Cached result data, usually an array
 * @return {OO.ui.MenuOptionWidget[]} Menu items
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;

/**
 * Set the read-only state of the widget.
 *
 * This will also disable/enable the lookups functionality.
 *
 * @param {boolean} readOnly Make input read-only
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {
	// Parent method
	// Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget
	OO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );

	// During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor
	if ( this.isReadOnly() && this.lookupMenu ) {
		this.closeLookupMenu();
	}

	return this;
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {
	return this.getValue();
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequest = function () {
	return this.getLookupRequest();
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {
	return this.getLookupCacheDataFromResponse( response );
};
<commit_msg>Allow menu config to be passed to LookupElement<commit_after>/**
 * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested values for
 * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
 * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
 * from the lookup menu, that value becomes the value of the input field.
 *
 * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is
 * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then
 * re-enable lookups.
 *
 * See the [OOUI demos][1] for an example.
 *
 * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#LookupElement-try-inputting-an-integer
 *
 * @class
 * @abstract
 * @mixins OO.ui.mixin.RequestManager
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.
 *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
 * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
 * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.MenuSelectWidget menu select widget}
 * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
 *  By default, the lookup menu is not generated and displayed until the user begins to type.
 * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can
 *  take it over into the input with simply pressing return) automatically or not.
 */
OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
	// Configuration initialization
	config = $.extend( { highlightFirst: true }, config );

	// Mixin constructors
	OO.ui.mixin.RequestManager.call( this, config );

	// Properties
	this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
	this.lookupMenu = new OO.ui.MenuSelectWidget( $.extend( {
		widget: this,
		input: this,
		$floatableContainer: config.$container || this.$element
	}, config.menu ) );

	this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;

	this.lookupsDisabled = false;
	this.lookupInputFocused = false;
	this.lookupHighlightFirstItem = config.highlightFirst;

	// Events
	this.$input.on( {
		focus: this.onLookupInputFocus.bind( this ),
		blur: this.onLookupInputBlur.bind( this ),
		mousedown: this.onLookupInputMouseDown.bind( this )
	} );
	this.connect( this, { change: 'onLookupInputChange' } );
	this.lookupMenu.connect( this, {
		toggle: 'onLookupMenuToggle',
		choose: 'onLookupMenuItemChoose'
	} );

	// Initialization
	this.$input.attr( {
		role: 'combobox',
		'aria-owns': this.lookupMenu.getElementId(),
		'aria-autocomplete': 'list'
	} );
	this.$element.addClass( 'oo-ui-lookupElement' );
	this.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );
	this.$overlay.append( this.lookupMenu.$element );
};

/* Setup */

OO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );

/* Methods */

/**
 * Handle input focus event.
 *
 * @protected
 * @param {jQuery.Event} e Input focus event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {
	this.lookupInputFocused = true;
	this.populateLookupMenu();
};

/**
 * Handle input blur event.
 *
 * @protected
 * @param {jQuery.Event} e Input blur event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {
	this.closeLookupMenu();
	this.lookupInputFocused = false;
};

/**
 * Handle input mouse down event.
 *
 * @protected
 * @param {jQuery.Event} e Input mouse down event
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {
	// Only open the menu if the input was already focused.
	// This way we allow the user to open the menu again after closing it with Esc
	// by clicking in the input. Opening (and populating) the menu when initially
	// clicking into the input is handled by the focus handler.
	if ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {
		this.populateLookupMenu();
	}
};

/**
 * Handle input change event.
 *
 * @protected
 * @param {string} value New input value
 */
OO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {
	if ( this.lookupInputFocused ) {
		this.populateLookupMenu();
	}
};

/**
 * Handle the lookup menu being shown/hidden.
 *
 * @protected
 * @param {boolean} visible Whether the lookup menu is now visible.
 */
OO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {
	if ( !visible ) {
		// When the menu is hidden, abort any active request and clear the menu.
		// This has to be done here in addition to closeLookupMenu(), because
		// MenuSelectWidget will close itself when the user presses Esc.
		this.abortLookupRequest();
		this.lookupMenu.clearItems();
	}
};

/**
 * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.
 *
 * @protected
 * @param {OO.ui.MenuOptionWidget} item Selected item
 */
OO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {
	this.setValue( item.getData() );
};

/**
 * Get lookup menu.
 *
 * @private
 * @return {OO.ui.MenuSelectWidget}
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {
	return this.lookupMenu;
};

/**
 * Disable or re-enable lookups.
 *
 * When lookups are disabled, calls to #populateLookupMenu will be ignored.
 *
 * @param {boolean} disabled Disable lookups
 */
OO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {
	this.lookupsDisabled = !!disabled;
};

/**
 * Open the menu. If there are no entries in the menu, this does nothing.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {
	if ( !this.lookupMenu.isEmpty() ) {
		this.lookupMenu.toggle( true );
	}
	return this;
};

/**
 * Close the menu, empty it, and abort any pending request.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {
	this.lookupMenu.toggle( false );
	this.abortLookupRequest();
	this.lookupMenu.clearItems();
	return this;
};

/**
 * Request menu items based on the input's current value, and when they arrive,
 * populate the menu with these items and show the menu.
 *
 * If lookups have been disabled with #setLookupsDisabled, this function does nothing.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {
	var widget = this,
		value = this.getValue();

	if ( this.lookupsDisabled || this.isReadOnly() ) {
		return;
	}

	// If the input is empty, clear the menu, unless suggestions when empty are allowed.
	if ( !this.allowSuggestionsWhenEmpty && value === '' ) {
		this.closeLookupMenu();
	// Skip population if there is already a request pending for the current value
	} else if ( value !== this.lookupQuery ) {
		this.getLookupMenuItems()
			.done( function ( items ) {
				widget.lookupMenu.clearItems();
				if ( items.length ) {
					widget.lookupMenu
						.addItems( items )
						.toggle( true );
					widget.initializeLookupMenuSelection();
				} else {
					widget.lookupMenu.toggle( false );
				}
			} )
			.fail( function () {
				widget.lookupMenu.clearItems();
			} );
	}

	return this;
};

/**
 * Highlight the first selectable item in the menu, if configured.
 *
 * @private
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {
	if ( this.lookupHighlightFirstItem && !this.lookupMenu.findSelectedItem() ) {
		this.lookupMenu.highlightItem( this.lookupMenu.findFirstSelectableItem() );
	}
};

/**
 * Get lookup menu items for the current query.
 *
 * @private
 * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of
 *   the done event. If the request was aborted to make way for a subsequent request, this promise
 *   will not be rejected: it will remain pending forever.
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {
	return this.getRequestData().then( function ( data ) {
		return this.getLookupMenuOptionsFromData( data );
	}.bind( this ) );
};

/**
 * Abort the currently pending lookup request, if any.
 *
 * @private
 */
OO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {
	this.abortRequest();
};

/**
 * Get a new request object of the current lookup query value.
 *
 * @protected
 * @method
 * @abstract
 * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
 */
OO.ui.mixin.LookupElement.prototype.getLookupRequest = null;

/**
 * Pre-process data returned by the request from #getLookupRequest.
 *
 * The return value of this function will be cached, and any further queries for the given value
 * will use the cache rather than doing API requests.
 *
 * @protected
 * @method
 * @abstract
 * @param {Mixed} response Response from server
 * @return {Mixed} Cached result data
 */
OO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;

/**
 * Get a list of menu option widgets from the (possibly cached) data returned by
 * #getLookupCacheDataFromResponse.
 *
 * @protected
 * @method
 * @abstract
 * @param {Mixed} data Cached result data, usually an array
 * @return {OO.ui.MenuOptionWidget[]} Menu items
 */
OO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;

/**
 * Set the read-only state of the widget.
 *
 * This will also disable/enable the lookups functionality.
 *
 * @param {boolean} readOnly Make input read-only
 * @chainable
 */
OO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {
	// Parent method
	// Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget
	OO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );

	// During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor
	if ( this.isReadOnly() && this.lookupMenu ) {
		this.closeLookupMenu();
	}

	return this;
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {
	return this.getValue();
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequest = function () {
	return this.getLookupRequest();
};

/**
 * @inheritdoc OO.ui.mixin.RequestManager
 */
OO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {
	return this.getLookupCacheDataFromResponse( response );
};
<|endoftext|>


<commit_before>const localize              = require('../base/localize').localize;
const compareBigUnsignedInt = require('../common_functions/string_util').compareBigUnsignedInt;

const Validation = (() => {
    'use strict';

    const forms = {};
    const error_class  = 'error-msg';
    const hidden_class = 'invisible';

    const events_map = {
        input   : 'input change',
        select  : 'change',
        checkbox: 'change',
    };

    const getFieldType = $field => (
        $field.length ? ($field.attr('type') === 'checkbox' ? 'checkbox' : $field.get(0).localName) : null
    );

    const getFieldValue = field => (field.type === 'checkbox' ? (field.$.is(':checked') ? '1' : '') : field.$.val()) || '';

    const initForm = (form_selector, fields) => {
        const $form = $(`${form_selector}:visible`);
        if ($form.length) {
            forms[form_selector] = { $form: $form };
            if (Array.isArray(fields) && fields.length) {
                forms[form_selector].fields = fields;

                fields.forEach((field) => {
                    field.$ = $form.find(field.selector);
                    if (!field.$.length || !field.validations) return;

                    field.type = getFieldType($(field.$[0])); // also handles multiple results
                    field.form = form_selector;
                    if (field.msg_element) {
                        field.$error = $form.find(field.msg_element);
                    } else {
                        const $parent = field.$.parent();
                        // Add indicator to required fields
                        if (field.validations.indexOf('req') >= 0) {
                            let $label = $parent.parent().find('label');
                            if (!$label.length) $label = $parent.find('label');
                            if ($label.find('span.required_field_asterisk').length === 0) {
                                $label.append($('<span/>', { class: 'required_field_asterisk', text: '*' }));
                            }
                        }
                        if ($parent.find(`div.${error_class}`).length === 0) {
                            $parent.append($('<div/>', { class: `${error_class} ${hidden_class}` }));
                        }
                        field.$error = $parent.find(`.${error_class}`);
                    }

                    const event = events_map[field.type];
                    if (event) {
                        field.$.unbind(event).on(event, () => {
                            checkField(field);
                            if (field.re_check_field) {
                                checkField(forms[form_selector].fields.find(fld => (
                                    fld.selector === field.re_check_field
                                )));
                            }
                        });
                    }
                });
            }
        }
    };

    // ------------------------------
    // ----- Validation Methods -----
    // ------------------------------
    const validRequired = (value, options, field) => {
        if ((typeof value === 'string' ? value.trim() : value).length) return true;
        // else
        validators_map.req.message = field.type === 'checkbox' ? 'Please select the checkbox.' : 'This field is required.';
        return false;
    };
    const validEmail        = value => /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/.test(value);
    const validPassword     = value => /(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]+/.test(value);
    const validLetterSymbol = value => !/[`~!@#$%^&*)(_=+\[}{\]\\\/";:\?><,|\d]+/.test(value);
    const validGeneral      = value => !/[`~!@#$%^&*)(_=+\[}{\]\\\/";:\?><|]+/.test(value);
    const validAddress      = value => !/[`~!#$%^&*)(_=+\[}{\]\\";:\?><|]+/.test(value);
    const validPostCode     = value => /^[a-zA-Z\d-\s]*$/.test(value);
    const validPhone        = value => /^\+?[0-9\s]*$/.test(value);
    const validRegular      = (value, options) => options.regex.test(value);
    const validEmailToken   = value => value.trim().length === 8;

    const validCompare  = (value, options) => value === $(options.to).val();
    const validNotEqual = (value, options) => value !== $(options.to).val();
    const validMin      = (value, options) => (options.min ? value.trim().length >= options.min : true);
    const validLength   = (value, options) => (
        (options.min ? value.trim().length >= options.min : true) &&
        (options.max ? value.trim().length <= options.max : true)
    );

    const validNumber = (value, options) => {
        if (options.allow_empty && value.length === 0) {
            return true;
        }

        let is_ok = true,
            message = '';

        if (!(options.type === 'float' ? /^\d+(\.\d+)?$/ : /^\d+$/).test(value) || !$.isNumeric(value)) {
            is_ok = false;
            message = localize('Should be a valid number');
        } else if (options.type === 'float' && options.decimals &&
            !(new RegExp(`^\\d+(\\.\\d{${options.decimals.replace(/ /g, '')}})?$`).test(value))) {
            is_ok = false;
            message = localize('Only [_1] decimal points are allowed.', [options.decimals]);
        } else if ('min' in options && 'max' in options && (+value < +options.min || isMoreThanMax(value, options))) {
            is_ok = false;
            message = localize('Should be between [_1] and [_2]', [options.min, options.max]);
        } else if ('min' in options && +value < +options.min) {
            is_ok = false;
            message = localize('Should be more than [_1]', [options.min]);
        } else if ('max' in options && isMoreThanMax(value, options)) {
            is_ok = false;
            message = localize('Should be less than [_1]', [options.max]);
        }

        validators_map.number.message = message;
        return is_ok;
    };

    const isMoreThanMax = (value, options) =>
        (options.type === 'float' ? +value > +options.max : compareBigUnsignedInt(value, options.max) === 1);

    const validators_map = {
        req          : { func: validRequired,     message: '' },
        email        : { func: validEmail,        message: 'Invalid email address' },
        password     : { func: validPassword,     message: 'Password should have lower and uppercase letters with numbers.' },
        general      : { func: validGeneral,      message: 'Only letters, numbers, space, hyphen, period, and apostrophe are allowed.' },
        address      : { func: validAddress,      message: 'Only letters, numbers, space, hyphen, period, and apostrophe are allowed.' },
        letter_symbol: { func: validLetterSymbol, message: 'Only letters, space, hyphen, period, and apostrophe are allowed.' },
        postcode     : { func: validPostCode,     message: 'Only letters, numbers, space, and hyphen are allowed.' },
        phone        : { func: validPhone,        message: 'Only numbers and spaces are allowed.' },
        email_token  : { func: validEmailToken,   message: 'Please submit a valid verification token.' },
        compare      : { func: validCompare,      message: 'The two passwords that you entered do not match.' },
        not_equal    : { func: validNotEqual,     message: '[_1] and [_2] cannot be the same.' },
        min          : { func: validMin,          message: 'Minimum of [_1] characters required.' },
        length       : { func: validLength,       message: 'You should enter [_1] characters.' },
        number       : { func: validNumber,       message: '' },
        regular      : { func: validRegular,      message: '' },
    };

    const pass_length = { min: 6, max: 25 };

    // --------------------
    // ----- Validate -----
    // --------------------
    const checkField = (field) => {
        if (!field.$.is(':visible') || !field.validations) return true;
        let all_is_ok = true,
            message;

        field.validations.some((valid) => {
            if (!valid) return true;
            let type,
                options = {};

            if (typeof valid === 'string') {
                type = valid;
            } else {
                type    = valid[0];
                options = valid[1];
            }

            if (type === 'password' && !validLength(getFieldValue(field), pass_length)) {
                field.is_ok = false;
                type = 'length';
                options = pass_length;
            } else {
                const validator = (type === 'custom' ? options.func : validators_map[type].func);
                field.is_ok = validator(getFieldValue(field), options, field);
            }

            if (!field.is_ok) {
                message = options.message || validators_map[type].message;
                if (type === 'length') {
                    message = localize(message, [options.min === options.max ? options.min : `${options.min}-${options.max}`]);
                } else if (type === 'min') {
                    message = localize(message, [options.min]);
                } else if (type === 'not_equal') {
                    message = localize(message, [localize(options.name1), localize(options.name2)]);
                }
                all_is_ok = false;
                return true;
            }
            return false;
        });

        if (!all_is_ok) {
            showError(field, message);
        } else {
            clearError(field);
        }

        return all_is_ok;
    };

    const clearError = (field) => {
        if (field.$error && field.$error.length) {
            field.$error.setVisibility(0);
        }
    };

    const showError = (field, message) => {
        clearError(field);
        field.$error.text(localize(message)).setVisibility(1);
    };

    const validate = (form_selector) => {
        const form = forms[form_selector];
        if (!form.fields) return true;
        form.is_ok = true;
        form.fields.forEach((field) => {
            if (!checkField(field)) {
                if (form.is_ok && !field.no_scroll) { // first error
                    $.scrollTo(field.$, 500, { offset: -10 });
                }
                form.is_ok = false;
            }
        });
        return form.is_ok;
    };

    return {
        init    : initForm,
        validate: validate,
    };
})();

module.exports = Validation;
<commit_msg>Check next validation<commit_after>const localize              = require('../base/localize').localize;
const compareBigUnsignedInt = require('../common_functions/string_util').compareBigUnsignedInt;

const Validation = (() => {
    'use strict';

    const forms = {};
    const error_class  = 'error-msg';
    const hidden_class = 'invisible';

    const events_map = {
        input   : 'input change',
        select  : 'change',
        checkbox: 'change',
    };

    const getFieldType = $field => (
        $field.length ? ($field.attr('type') === 'checkbox' ? 'checkbox' : $field.get(0).localName) : null
    );

    const getFieldValue = field => (field.type === 'checkbox' ? (field.$.is(':checked') ? '1' : '') : field.$.val()) || '';

    const initForm = (form_selector, fields) => {
        const $form = $(`${form_selector}:visible`);
        if ($form.length) {
            forms[form_selector] = { $form: $form };
            if (Array.isArray(fields) && fields.length) {
                forms[form_selector].fields = fields;

                fields.forEach((field) => {
                    field.$ = $form.find(field.selector);
                    if (!field.$.length || !field.validations) return;

                    field.type = getFieldType($(field.$[0])); // also handles multiple results
                    field.form = form_selector;
                    if (field.msg_element) {
                        field.$error = $form.find(field.msg_element);
                    } else {
                        const $parent = field.$.parent();
                        // Add indicator to required fields
                        if (field.validations.indexOf('req') >= 0) {
                            let $label = $parent.parent().find('label');
                            if (!$label.length) $label = $parent.find('label');
                            if ($label.find('span.required_field_asterisk').length === 0) {
                                $label.append($('<span/>', { class: 'required_field_asterisk', text: '*' }));
                            }
                        }
                        if ($parent.find(`div.${error_class}`).length === 0) {
                            $parent.append($('<div/>', { class: `${error_class} ${hidden_class}` }));
                        }
                        field.$error = $parent.find(`.${error_class}`);
                    }

                    const event = events_map[field.type];
                    if (event) {
                        field.$.unbind(event).on(event, () => {
                            checkField(field);
                            if (field.re_check_field) {
                                checkField(forms[form_selector].fields.find(fld => (
                                    fld.selector === field.re_check_field
                                )));
                            }
                        });
                    }
                });
            }
        }
    };

    // ------------------------------
    // ----- Validation Methods -----
    // ------------------------------
    const validRequired = (value, options, field) => {
        if ((typeof value === 'string' ? value.trim() : value).length) return true;
        // else
        validators_map.req.message = field.type === 'checkbox' ? 'Please select the checkbox.' : 'This field is required.';
        return false;
    };
    const validEmail        = value => /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/.test(value);
    const validPassword     = value => /(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]+/.test(value);
    const validLetterSymbol = value => !/[`~!@#$%^&*)(_=+\[}{\]\\\/";:\?><,|\d]+/.test(value);
    const validGeneral      = value => !/[`~!@#$%^&*)(_=+\[}{\]\\\/";:\?><|]+/.test(value);
    const validAddress      = value => !/[`~!#$%^&*)(_=+\[}{\]\\";:\?><|]+/.test(value);
    const validPostCode     = value => /^[a-zA-Z\d-\s]*$/.test(value);
    const validPhone        = value => /^\+?[0-9\s]*$/.test(value);
    const validRegular      = (value, options) => options.regex.test(value);
    const validEmailToken   = value => value.trim().length === 8;

    const validCompare  = (value, options) => value === $(options.to).val();
    const validNotEqual = (value, options) => value !== $(options.to).val();
    const validMin      = (value, options) => (options.min ? value.trim().length >= options.min : true);
    const validLength   = (value, options) => (
        (options.min ? value.trim().length >= options.min : true) &&
        (options.max ? value.trim().length <= options.max : true)
    );

    const validNumber = (value, options) => {
        if (options.allow_empty && value.length === 0) {
            return true;
        }

        let is_ok = true,
            message = '';

        if (!(options.type === 'float' ? /^\d+(\.\d+)?$/ : /^\d+$/).test(value) || !$.isNumeric(value)) {
            is_ok = false;
            message = localize('Should be a valid number');
        } else if (options.type === 'float' && options.decimals &&
            !(new RegExp(`^\\d+(\\.\\d{${options.decimals.replace(/ /g, '')}})?$`).test(value))) {
            is_ok = false;
            message = localize('Only [_1] decimal points are allowed.', [options.decimals]);
        } else if ('min' in options && 'max' in options && (+value < +options.min || isMoreThanMax(value, options))) {
            is_ok = false;
            message = localize('Should be between [_1] and [_2]', [options.min, options.max]);
        } else if ('min' in options && +value < +options.min) {
            is_ok = false;
            message = localize('Should be more than [_1]', [options.min]);
        } else if ('max' in options && isMoreThanMax(value, options)) {
            is_ok = false;
            message = localize('Should be less than [_1]', [options.max]);
        }

        validators_map.number.message = message;
        return is_ok;
    };

    const isMoreThanMax = (value, options) =>
        (options.type === 'float' ? +value > +options.max : compareBigUnsignedInt(value, options.max) === 1);

    const validators_map = {
        req          : { func: validRequired,     message: '' },
        email        : { func: validEmail,        message: 'Invalid email address' },
        password     : { func: validPassword,     message: 'Password should have lower and uppercase letters with numbers.' },
        general      : { func: validGeneral,      message: 'Only letters, numbers, space, hyphen, period, and apostrophe are allowed.' },
        address      : { func: validAddress,      message: 'Only letters, numbers, space, hyphen, period, and apostrophe are allowed.' },
        letter_symbol: { func: validLetterSymbol, message: 'Only letters, space, hyphen, period, and apostrophe are allowed.' },
        postcode     : { func: validPostCode,     message: 'Only letters, numbers, space, and hyphen are allowed.' },
        phone        : { func: validPhone,        message: 'Only numbers and spaces are allowed.' },
        email_token  : { func: validEmailToken,   message: 'Please submit a valid verification token.' },
        compare      : { func: validCompare,      message: 'The two passwords that you entered do not match.' },
        not_equal    : { func: validNotEqual,     message: '[_1] and [_2] cannot be the same.' },
        min          : { func: validMin,          message: 'Minimum of [_1] characters required.' },
        length       : { func: validLength,       message: 'You should enter [_1] characters.' },
        number       : { func: validNumber,       message: '' },
        regular      : { func: validRegular,      message: '' },
    };

    const pass_length = { min: 6, max: 25 };

    // --------------------
    // ----- Validate -----
    // --------------------
    const checkField = (field) => {
        if (!field.$.is(':visible') || !field.validations) return true;
        let all_is_ok = true,
            message;

        field.validations.some((valid) => {
            if (!valid) return false; // check next validation
            let type,
                options = {};

            if (typeof valid === 'string') {
                type = valid;
            } else {
                type    = valid[0];
                options = valid[1];
            }

            if (type === 'password' && !validLength(getFieldValue(field), pass_length)) {
                field.is_ok = false;
                type = 'length';
                options = pass_length;
            } else {
                const validator = (type === 'custom' ? options.func : validators_map[type].func);
                field.is_ok = validator(getFieldValue(field), options, field);
            }

            if (!field.is_ok) {
                message = options.message || validators_map[type].message;
                if (type === 'length') {
                    message = localize(message, [options.min === options.max ? options.min : `${options.min}-${options.max}`]);
                } else if (type === 'min') {
                    message = localize(message, [options.min]);
                } else if (type === 'not_equal') {
                    message = localize(message, [localize(options.name1), localize(options.name2)]);
                }
                all_is_ok = false;
                return true; // break on the first error found
            }
            return false; // check next validation
        });

        if (!all_is_ok) {
            showError(field, message);
        } else {
            clearError(field);
        }

        return all_is_ok;
    };

    const clearError = (field) => {
        if (field.$error && field.$error.length) {
            field.$error.setVisibility(0);
        }
    };

    const showError = (field, message) => {
        clearError(field);
        field.$error.text(localize(message)).setVisibility(1);
    };

    const validate = (form_selector) => {
        const form = forms[form_selector];
        if (!form.fields) return true;
        form.is_ok = true;
        form.fields.forEach((field) => {
            if (!checkField(field)) {
                if (form.is_ok && !field.no_scroll) { // first error
                    $.scrollTo(field.$, 500, { offset: -10 });
                }
                form.is_ok = false;
            }
        });
        return form.is_ok;
    };

    return {
        init    : initForm,
        validate: validate,
    };
})();

module.exports = Validation;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Platform } from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import {
  Container,
  Header,
  Title,
  Content,
  Text,
  Button,
  Icon,
  Left,
  Right,
  Body
} from 'native-base';

import { openDrawer } from '../../actions/drawer';
import commonStyles from '../../common/commonStyles';
import styles from './styles';

const pageTitle = 'Blank Page';
class BlankPage extends Component {
  static propTypes = {
    name: React.PropTypes.string,
    index: React.PropTypes.number,
    list: React.PropTypes.arrayOf(React.PropTypes.string)
    //  openDrawer: React.PropTypes.func
  };
  render() {
    const { props: { name, index, list } } = this;
    const platform = Platform.OS;

    return (
      <Container style={styles.container}>
        <Header style={commonStyles.header}>
          <Left>
            <Button transparent onPress={() => Actions.pop()}>
              <Icon style={commonStyles.headerText} name="ios-arrow-back" />
              {platform === 'ios'
                ? null
                : <Title style={commonStyles.headerTextAndroid}>
                    {name ? this.props.name : { pageTitle }}
                  </Title>}
            </Button>
          </Left>
          {platform === 'ios'
            ? <Body style={commonStyles.headerBody}>
                <Title style={commonStyles.headerText} allowFontScaling={false}>
                  {pageTitle}
                </Title>
              </Body>
            : null}
          {platform === 'ios' ? <Right /> : null}
        </Header>

        <Content padder>
          <Text>
            {!isNaN(index) ? list[index] : 'Create Something Awesome . . .'}
          </Text>
        </Content>
      </Container>
    );
  }
}

function bindAction(dispatch) {
  return {
    openDrawer: () => dispatch(openDrawer())
  };
}

const mapStateToProps = state => ({
  name: state.user.name,
  index: state.list.selectedIndex,
  list: state.list.list
});

export default connect(mapStateToProps, bindAction)(BlankPage);
<commit_msg>fix(): fix pageTitle error on BlankPage in Android<commit_after>import React, { Component } from 'react';
import { Platform } from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import {
  Container,
  Header,
  Title,
  Content,
  Text,
  Button,
  Icon,
  Left,
  Right,
  Body
} from 'native-base';

import { openDrawer } from '../../actions/drawer';
import commonStyles from '../../common/commonStyles';
import styles from './styles';

const pageTitle = 'Blank Page';
class BlankPage extends Component {
  static propTypes = {
    name: React.PropTypes.string,
    index: React.PropTypes.number,
    list: React.PropTypes.arrayOf(React.PropTypes.string)
    //  openDrawer: React.PropTypes.func
  };
  render() {
    const { props: { name, index, list } } = this;
    const platform = Platform.OS;

    return (
      <Container style={styles.container}>
        <Header style={commonStyles.header}>
          <Left>
            <Button transparent onPress={() => Actions.pop()}>
              <Icon style={commonStyles.headerText} name="ios-arrow-back" />
              {platform === 'ios'
                ? null
                : <Title style={commonStyles.headerTextAndroid}>
                    {name ? this.props.name : pageTitle}
                  </Title>}
            </Button>
          </Left>
          {platform === 'ios'
            ? <Body style={commonStyles.headerBody}>
                <Title style={commonStyles.headerText} allowFontScaling={false}>
                  {pageTitle}
                </Title>
              </Body>
            : null}
          {platform === 'ios' ? <Right /> : null}
        </Header>

        <Content padder>
          <Text>
            {!isNaN(index) ? list[index] : 'Create Something Awesome . . .'}
          </Text>
        </Content>
      </Container>
    );
  }
}

function bindAction(dispatch) {
  return {
    openDrawer: () => dispatch(openDrawer())
  };
}

const mapStateToProps = state => ({
  name: state.user.name,
  index: state.list.selectedIndex,
  list: state.list.list
});

export default connect(mapStateToProps, bindAction)(BlankPage);
<|endoftext|>


<commit_before>'use strict';

const fs = require('hexo-fs');
const request = require('superagent');
const prettyHrtime = require('pretty-hrtime');
const chalk = require('chalk');

module.exports = function(config, logger) {
  let user = {};
  let media = [];
  let timestamp = Date.now();
  const access_token = process.env.INSTAGRAM_WALL_TOKEN || '';

  // create cache directory
  if (!fs.existsSync('cache')) {
    fs.mkdirsSync('cache');
  }

  // try to use cache data first
  if (fs.existsSync('cache/instagram.media.json')) {
    media = fs.readFileSync('cache/instagram.media.json');
    media = JSON.parse(media);
    logger.info('hexo-instagram-wall:', chalk.cyan('Using cached data from Instagram.'));
    return media.data;
  }

  logger.info('hexo-instagram-wall:', chalk.cyan('Getting fresh data from Instagram ...'));

  const startTime = process.hrtime();

  function handleError(message, info) {
    logger.error('hexo-instagram-wall:', chalk.red(message));
    if (info) {
      logger.debug(info);
    }
    return false;
  }

  request
    .get(`https://api.instagram.com/v1/users/self?access_token=${access_token}`)
    .end(function(err, res) {
      if (err) return handleError(err.message + ': ' + err.response.body.meta.error_message);
      if (!res.ok) return handleError('Instagram responded correctly, but there was an error.', res.body);

      user = {
        data: res.body.data,
        date: timestamp,
      };

      fs.writeFileSync('cache/instagram.user.json', JSON.stringify(user));

      request
        .get(`https://api.instagram.com/v1/users/${user.data.id}/media/recent/?access_token=${access_token}`)
        .end(function(err, res) {
          if (err) return handleError(err.message + ': ' + err.response.body.meta.error_message);
          if (!res.ok) return handleError('Instagram responded correctly, but there was an error.', res.body);

          media = {
            data: res.body.data,
            date: timestamp,
          };

          fs.writeFileSync('cache/instagram.media.json', JSON.stringify(media));

          const interval = prettyHrtime(process.hrtime(startTime));

          logger.info('hexo-instagram-wall:', chalk.cyan('Fresh data has been fetched and saved from Instagram in' + interval));

          return media.data;
        });
    });
};
<commit_msg>Use cached data for a period of 24 hours<commit_after>'use strict';

const fs = require('hexo-fs');
const request = require('superagent');
const prettyHrtime = require('pretty-hrtime');
const chalk = require('chalk');

module.exports = function(config, logger) {
  let user = {};
  let media = [];
  let timestamp = Date.now();
  const access_token = process.env.INSTAGRAM_WALL_TOKEN || '';

  // create cache directory
  if (!fs.existsSync('cache')) {
    fs.mkdirsSync('cache');
  }

  // try to use cached data first
  if (fs.existsSync('cache/instagram.media.json')) {
    media = fs.readFileSync('cache/instagram.media.json');
    media = JSON.parse(media);

    // if  cached data is newer than 24 hours old,
    // use it. otherwise get new data.
    if (timestamp - media.date < 1000 * 60 * 60 * 24) {
      logger.info('hexo-instagram-wall:', chalk.cyan('Using cached data from Instagram.'));
      return media.data;
    }
    else {
      logger.info('hexo-instagram-wall:', chalk.cyan('Your cached Instagram data is too old. It\'s time to get new data!'));
    }
  }

  logger.info('hexo-instagram-wall:', chalk.cyan('Getting fresh data from Instagram ...'));

  const startTime = process.hrtime();

  function handleError(message, info) {
    logger.error('hexo-instagram-wall:', chalk.red(message));
    if (info) {
      logger.debug(info);
    }
    return false;
  }

  request
    .get(`https://api.instagram.com/v1/users/self?access_token=${access_token}`)
    .end(function(err, res) {
      if (err) return handleError(err.message + ': ' + err.response.body.meta.error_message);
      if (!res.ok) return handleError('Instagram responded correctly, but there was an error.', res.body);

      user = {
        data: res.body.data,
        date: timestamp,
      };

      fs.writeFileSync('cache/instagram.user.json', JSON.stringify(user));

      request
        .get(`https://api.instagram.com/v1/users/${user.data.id}/media/recent/?access_token=${access_token}`)
        .end(function(err, res) {
          if (err) return handleError(err.message + ': ' + err.response.body.meta.error_message);
          if (!res.ok) return handleError('Instagram responded correctly, but there was an error.', res.body);

          media = {
            data: res.body.data,
            date: timestamp,
          };

          fs.writeFileSync('cache/instagram.media.json', JSON.stringify(media));

          const interval = prettyHrtime(process.hrtime(startTime));

          logger.info('hexo-instagram-wall:', chalk.cyan('Fresh data has been fetched and saved from Instagram in ' + interval));

          return media.data;
        });
    });
};
<|endoftext|>


<commit_before>'use strict';

var Workstream = require('./workstream.model');
var objectAssign = require('object-assign');

function handleError(res, err) {
    return res.send(500, err);
}

exports.index = function (req, res) {
    Workstream.all(function (err, workstreams) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstreams);
    });
};

exports.create = function (req, res) {
    Workstream.create(req.body, function (err) {

        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(req.body);
    });
};

exports.delete = function (req, res) {
    Workstream.delete(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.updateWorkstream = function (req, res) {
    delete req.body.__v;
    Workstream.update(req.params.workstream, req.body, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.getWorkstream = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.getWorkstreamTasks = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream.tasks);
    });
};

exports.saveWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        workstream.tasks.push(req.body);
        var task = workstream.tasks[workstream.tasks.length - 1];

        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.status(200).json(task);
        })
    });
};

exports.updateWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(400);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        var updatedTask = objectAssign(task, req.body);

        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.status(200).json(updatedTask);
        });
    });
};

exports.deleteWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        task.remove();
        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.json(200);
        });
    });
};

exports.getWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(400);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        return res.status(200).json(task);
    });
};
<commit_msg>Revert "fix a bug - was getting error of exception: Mod on _id not allowed"<commit_after>'use strict';

var Workstream = require('./workstream.model');
var objectAssign = require('object-assign');

function handleError(res, err) {
    return res.send(500, err);
}

exports.index = function (req, res) {
    Workstream.all(function (err, workstreams) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstreams);
    });
};

exports.create = function (req, res) {
    Workstream.create(req.body, function (err) {

        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(req.body);
    });
};

exports.delete = function (req, res) {
    Workstream.delete(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.updateWorkstream = function (req, res) {
    Workstream.update(req.params.workstream, req.body, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.getWorkstream = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream);
    });
};

exports.getWorkstreamTasks = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        return res.status(200).json(workstream.tasks);
    });
};

exports.saveWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function(err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        workstream.tasks.push(req.body);
        var task = workstream.tasks[workstream.tasks.length - 1];

        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.status(200).json(task);
        })
    });
};

exports.updateWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(400);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        var updatedTask = objectAssign(task, req.body);

        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.status(200).json(updatedTask);
        });
    });
};

exports.deleteWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(err);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        task.remove();
        workstream.save(function (err) {
            if (err) {
                return res.status(400).json(err);
            }

            return res.json(200);
        });
    });
};

exports.getWorkstreamTask = function (req, res) {
    Workstream.findById(req.params.workstream, function (err, workstream) {
        if (err) {
            return res.status(400).json(400);
        }

        var task = workstream.tasks.id(req.params.task);

        if (!task) {
            return res.json(404);
        }

        return res.status(200).json(task);
    });
};
<|endoftext|>


<commit_before>var fs = require('fs-extra');
var path = require('path');
var quickTemp = require('quick-temp');
var execSync = require('child_process').execSync;
var merge = require('ember-cli-lodash-subset').merge;
var Configstore = require('configstore');
var traverse = require('traverse');

var contents = require('./blueprint-shim');

/**
 * A simple tool to make behavior consistent between the package manager commands.
 *
 * @method commandGenerator
 * @param {Path} program The path to the command.
 * @return {Function} A command helper.
 */
function commandGenerator(program) {
  var networkSubcommands = ['install', 'update', 'upgrade'];

  return function(subcommand) {
    var options = arguments.length >= 2 ? arguments[arguments.length-1] : {};
    var args = Array.prototype.slice.call(arguments, 1, -1);

    var invocation = [];

    // Make network tasks more resilient on Travis CI.
    if (process.env.TRAVIS === 'true' && ~networkCommands.indexOf(subcommand)) {
      invocation.push('travis_retry');
    }

    invocation.push(program);
    invocation.push(subcommand);
    invocation = invocation.concat(args);

    execSync(invocation.join(' '), options);
  };
}

/**
 * The `bower` command helper.
 *
 * @method bower
 * @param {String} subcommand The subcommand to be passed into bower.
 * @param {String} [...arguments] Arguments to be passed into the bower subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var bower = commandGenerator(require.resolve('bower/bin/bower'));

/**
 * The `npm` command helper.
 *
 * @method npm
 * @param {String} subcommand The subcommand to be passed into npm.
 * @param {String} [...arguments] Arguments to be passed into the npm subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var npm = commandGenerator(require.resolve('npm/bin/npm-cli.js'));

/**
 * The `yarn` command helper.
 *
 * @method yarn
 * @param {String} subcommand The subcommand to be passed into yarn.
 * @param {String} [...arguments] Arguments to be passed into the yarn subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var yarn = commandGenerator(require.resolve('yarn/bin/yarn.js'));

// This lookup exists to make it possible to look the commands up based upon context.
var commands = {
  bower: bower,
  npm: npm,
  yarn: yarn
};

// The definition list of translation terms.
var lookups = {
  path: {
    bower: 'bower_components',
    npm: 'node_modules',
    yarn: 'node_modules'
  },
  manifest: {
    bower: 'bower.json',
    npm: 'package.json',
    yarn: 'package.json'
  },
  upgrade: {
    bower: 'update',
    npm: 'install',
    yarn: 'upgrade'
  }
};

/**
 * The `translate` command is used to turn a consistent argument into
 * appropriate values based upon the context in which it is used. It's
 * a convenience helper to avoid littering lookups throughout the code.
 *
 * @method translate
 * @param {String} type Either 'yarn' or 'bower'.
 * @param {String} lookup Either 'path', 'manifest', or 'upgrade'.
 */
function translate(type, lookup) { return lookups[lookup][type]; }

/**
 * The PackageCache wraps all package management functions. It also
 * handles initial global state setup.
 *
 * @class PackageCache
 * @constructor
 */
function PackageCache() {
  this._conf = new Configstore('package-cache');

  // Wrap the Configstore in a pretty interface.
  Object.defineProperty(this, 'dirs', {
    get: function() {
      return this._conf.get('dirs');
    },
    set: function(newValue) {
      return this._conf.set('dirs', newValue);
    }
  });

  // Either use the version from the cache or start fresh.
  this.dirs = this.dirs || {
    app: {
      bower_components: null,
      node_modules: null
    },
    addon: {
      bower_components: null,
      node_modules: null
    }
  };

  this._cleanDirs();

  // These are the caches we're going to be building today.
  var caches = [
    ['app', 'bower'],
    ['app', 'yarn'],
    ['addon', 'bower'],
    ['addon', 'yarn']
  ];

  caches.forEach(function(tuple) {
    // Compare any existing manifest to the ideal per current blueprint.
    var identical = this.checkManifest.apply(this, tuple);

    if (identical) {
      // Use what we have, but opt in to SemVer drift.
      this.upgrade.apply(this, tuple);
    } else {
      // Tell the package manager to start semi-fresh.
      this.writeManifest.apply(this, tuple);
      this.install.apply(this, tuple);
    }
  }.bind(this));

  // Set up the default Ember CLI link.
  // Easier to do this every time than try and lock it out.
  var emberCLIPath = path.resolve(__dirname, '../..');
  // yarn('link', { cwd: emberCLIPath });
}

PackageCache.prototype = {

  /**
   * The `_cleanDirs` method deals with sync issues between the
   * Configstore and what exists on disk. Non-existent directories
   * are removed from `this.dirs`.
   *
   * @method _cleanDirs
   */
  _cleanDirs: function() {
    this.dirs = traverse(this.dirs).map(function(directory) {
      if (this.isLeaf && directory && !fs.existsSync(directory)) {
        this.update(null);
      }
    });
  },

  /**
   * The `getManifest` method processes the blueprint of the current
   * version of Ember CLI and returns the desired manifest file.
   *
   * @method getManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @return {String} The manifest file contents as desired.
   */
  getManifest: function(label, type) {
    return contents[label][translate(type, 'manifest')];
  },

  /**
   * The `readManifest` method reads the on-disk manifest for the current
   * cache and returns its value.
   *
   * @method readManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @return {String} The manifest file contents on disk.
   */
  readManifest: function(label, type) {
    var readManifestDir = this.dirs[label][translate(type, 'path')];

    if (!readManifestDir) { return null; }

    var inputPath = path.join(readManifestDir, translate(type, 'manifest'));
    return fs.readFileSync(inputPath, 'utf8');
  },

  /**
   * The `checkManifest` method compares the desired manifest to that which
   * exists in the cache.
   *
   * @method checkManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @return {Boolean} `true` if identical.
   */
  checkManifest: function(label, type) {
    var desiredManifest = this.getManifest(label, type);
    var cachedManifest = this.readManifest(label, type);

    return desiredManifest === cachedManifest;
  },

  /**
   * The `writeManifest` method generates the on-disk folder for the package cache
   * and saves the manifest into it. If it is a yarn package cache it will remove
   * the existing lock file.
   *
   * @method writeManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  writeManifest: function(label, type) {
    var outputDir = quickTemp.makeOrReuse(this.dirs[label], translate(type, 'path'));
    var keyPath = ['dirs', label, translate(type, 'path')].join('.');
    this._conf.set(keyPath, outputDir);

    var manifest = this.getManifest(label, type);
    var outputFile = path.join(outputDir, translate(type, 'manifest'));
    fs.writeFileSync(outputFile, manifest);

    // Remove the yarn.lock file so that it doesn't try to incorrectly use it as a base.
    if (type === 'yarn') {
      try {
        fs.unlinkSync(path.join(outputDir, 'yarn.lock'));
      } catch (error) {
        // Catch unexceptional error but rethrow if something is truly wrong.
        if (error.code !== 'ENOENT') {
          throw error;
        }
      }
    }
  },

  /**
   * The `install` method installs the contents of the manifest into the
   * specified package cache.
   *
   * @method install
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  install: function(label, type) {
    var executeLocation = this.dirs[label][translate(type, 'path')];
    commands[type]('install', { cwd: executeLocation });

    // FIXME: yarn doesn't like this after one round of re-installation.
    if (type === 'yarn') {
      // commands[type]('link', 'ember-cli', { cwd: executeLocation });
    }
  },

  /**
   * The `upgrade` method guarantees that the contents of the manifest are
   * allowed to drift in a SemVer compatible manner. It ensures that CI is
   * always running against the latest versions of all dependencies.
   *
   * @method upgrade
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  upgrade: function(label, type) {
    var executeLocation = this.dirs[label][translate(type, 'path')];

    // Only way to get repeatable behavior in npm: start over.
    // We turn an `upgrade` task into an `install` task.
    if (type === 'npm') {
      fs.removeSync(path.join(executeLocation, translate(type, 'path')));
      this.install(label, type);
    } else {
      commands[type](translate(type, 'upgrade'), { cwd: executeLocation });
    }
  },

  /**
   * The `destroy` method removes all evidence of the package cache.
   *
   * @method destroy
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  destroy: function(label, type) {
    quickTemp.remove(this.dirs[label], translate(type, 'path'));

    var keyPath = ['dirs', label, translate(type, 'path')].join('.');
    this._conf.set(keypath, null);
  }

};

var cache = new PackageCache();

module.exports = cache.dirs;
<commit_msg>Create API for caches.<commit_after>var fs = require('fs-extra');
var path = require('path');
var quickTemp = require('quick-temp');
var execSync = require('child_process').execSync;
var merge = require('ember-cli-lodash-subset').merge;
var Configstore = require('configstore');
var traverse = require('traverse');

/**
 * A simple tool to make behavior consistent between the package manager commands.
 *
 * @method commandGenerator
 * @param {Path} program The path to the command.
 * @return {Function} A command helper.
 */
function commandGenerator(program) {
  var networkSubcommands = ['install', 'update', 'upgrade'];

  return function(subcommand) {
    var options = arguments.length >= 2 ? arguments[arguments.length-1] : {};
    var args = Array.prototype.slice.call(arguments, 1, -1);

    var invocation = [];

    // Make network tasks more resilient on Travis CI.
    if (process.env.TRAVIS === 'true' && ~networkCommands.indexOf(subcommand)) {
      invocation.push('travis_retry');
    }

    invocation.push(program);
    invocation.push(subcommand);
    invocation = invocation.concat(args);

    execSync(invocation.join(' '), options);
  };
}

/**
 * The `bower` command helper.
 *
 * @method bower
 * @param {String} subcommand The subcommand to be passed into bower.
 * @param {String} [...arguments] Arguments to be passed into the bower subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var bower = commandGenerator(require.resolve('bower/bin/bower'));

/**
 * The `npm` command helper.
 *
 * @method npm
 * @param {String} subcommand The subcommand to be passed into npm.
 * @param {String} [...arguments] Arguments to be passed into the npm subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var npm = commandGenerator(require.resolve('npm/bin/npm-cli.js'));

/**
 * The `yarn` command helper.
 *
 * @method yarn
 * @param {String} subcommand The subcommand to be passed into yarn.
 * @param {String} [...arguments] Arguments to be passed into the yarn subcommand.
 * @param {Object} [options={}] The options passed into child_process.execSync.
 *   (https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options)
 */
var yarn = commandGenerator(require.resolve('yarn/bin/yarn.js'));

// This lookup exists to make it possible to look the commands up based upon context.
var commands = {
  bower: bower,
  npm: npm,
  yarn: yarn
};

// The definition list of translation terms.
var lookups = {
  path: {
    bower: 'bower_components',
    npm: 'node_modules',
    yarn: 'node_modules'
  },
  manifest: {
    bower: 'bower.json',
    npm: 'package.json',
    yarn: 'package.json'
  },
  upgrade: {
    bower: 'update',
    npm: 'install',
    yarn: 'upgrade'
  }
};

/**
 * The `translate` command is used to turn a consistent argument into
 * appropriate values based upon the context in which it is used. It's
 * a convenience helper to avoid littering lookups throughout the code.
 *
 * @method translate
 * @param {String} type Either 'yarn' or 'bower'.
 * @param {String} lookup Either 'path', 'manifest', or 'upgrade'.
 */
function translate(type, lookup) { return lookups[lookup][type]; }

/**
 * The PackageCache wraps all package management functions. It also
 * handles initial global state setup.
 *
 * @class PackageCache
 * @constructor
 */
function PackageCache() {
  this._conf = new Configstore('package-cache');

  // Wrap the Configstore in a pretty interface.
  Object.defineProperty(this, 'dirs', {
    get: function() {
      return this._conf.get('dirs');
    },
    set: function(newValue) {
      return this._conf.set('dirs', newValue);
    }
  });

  // Either use the version from the cache or start fresh.
  this.dirs = this.dirs || {};

  // FIXME:
  // this._cleanDirs();
}

PackageCache.prototype = {

  /**
   * The `_cleanDirs` method deals with sync issues between the
   * Configstore and what exists on disk. Non-existent directories
   * are removed from `this.dirs`.
   *
   * @method _cleanDirs
   */
  _cleanDirs: function() {
    this.dirs = traverse(this.dirs).map(function(directory) {
      if (this.isLeaf && directory && !fs.existsSync(directory)) {
        this.update(null);
      }
    });
  },

  /**
   * The `readManifest` method reads the on-disk manifest for the current
   * cache and returns its value.
   *
   * @method readManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @return {String} The manifest file contents on disk.
   */
  readManifest: function(label, type) {
    var readManifestDir = this.dirs[label];

    if (!readManifestDir) { return null; }

    var inputPath = path.join(readManifestDir, translate(type, 'manifest'));
    return fs.readFileSync(inputPath, 'utf8');
  },

  /**
   * The `checkManifest` method compares the desired manifest to that which
   * exists in the cache.
   *
   * @method checkManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @param {String} manifest The contents of the manifest file to compare to cache.
   * @return {Boolean} `true` if identical.
   */
  checkManifest: function(label, type, manifest) {
    var cachedManifest = this.readManifest(label, type);

    return manifest === cachedManifest;
  },

  /**
   * The `writeManifest` method generates the on-disk folder for the package cache
   * and saves the manifest into it. If it is a yarn package cache it will remove
   * the existing lock file.
   *
   * @method writeManifest
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @param {String} manifest The contents of the manifest file to write to disk.
   */
  writeManifest: function(label, type, manifest) {
    var outputDir = quickTemp.makeOrReuse(this.dirs, label);
    var keyPath = ['dirs', label].join('.');
    this._conf.set(keyPath, outputDir);

    var outputFile = path.join(outputDir, translate(type, 'manifest'));
    fs.writeFileSync(outputFile, manifest);

    // Remove the yarn.lock file so that it doesn't try to incorrectly use it as a base.
    if (type === 'yarn') {
      try {
        fs.unlinkSync(path.join(outputDir, 'yarn.lock'));
      } catch (error) {
        // Catch unexceptional error but rethrow if something is truly wrong.
        if (error.code !== 'ENOENT') {
          throw error;
        }
      }
    }
  },

  /**
   * The `install` method installs the contents of the manifest into the
   * specified package cache.
   *
   * @method install
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  install: function(label, type) {
    commands[type]('install', { cwd: this.dirs[label] });

    // FIXME: yarn doesn't like this after one round of re-installation.
    if (type === 'yarn') {
      // commands[type]('link', 'ember-cli', { cwd: this.dirs[label] });
    }
  },

  /**
   * The `upgrade` method guarantees that the contents of the manifest are
   * allowed to drift in a SemVer compatible manner. It ensures that CI is
   * always running against the latest versions of all dependencies.
   *
   * @method upgrade
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  upgrade: function(label, type) {
    // Only way to get repeatable behavior in npm: start over.
    // We turn an `upgrade` task into an `install` task.
    if (type === 'npm') {
      fs.removeSync(path.join(this.dirs[label], translate(type, 'path')));
      this.install(label, type);
    } else {
      commands[type](translate(type, 'upgrade'), { cwd: this.dirs[label] });
    }
  },

  // PUBLIC API BELOW

  /**
   * The `create` method adds a new package cache entry.
   *
   * @method create
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @param {String} manifest The contents of the manifest file for the cache.
   * @return {String} The directory on disk which contains the cache.
   */
  create: function(label, type, manifest) {
    // Compare any existing manifest to the ideal per current blueprint.
    var identical = this.checkManifest(label, type, manifest);

    if (identical) {
      // Use what we have, but opt in to SemVer drift.
      this.upgrade(label, type);
    } else {
      // Tell the package manager to start semi-fresh.
      this.writeManifest(label, type, manifest);
      this.install(label, type);
    }

    return this.dirs[label];

    // Set up the default Ember CLI link.
    // Easier to do this every time than try and lock it out.
    // var emberCLIPath = path.resolve(__dirname, '../..');
    // yarn('link', { cwd: emberCLIPath });
  },

  /**
   * The `update` method aliases the `create` method.
   *
   * @method update
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   * @param {String} manifest The contents of the manifest file for the cache.
   * @return {String} The directory on disk which contains the cache.
   */
  update: function(label, type, manifest) {
    return this.create.apply(this, arguments);
  },

  /**
   * The `get` method returns the directory for the cache.
   *
   * @method get
   * @param {String} label The label for the cache.
   * @return {String} The directory on disk which contains the cache.
   */
  get: function(label) {
    return this.dirs[label];
  },

  /**
   * The `destroy` method removes all evidence of the package cache.
   *
   * @method destroy
   * @param {String} label The label for the cache.
   * @param {String} type The type of package cache.
   */
  destroy: function(label) {
    quickTemp.remove(this.dirs, label);

    var keyPath = ['dirs', label].join('.');
    this._conf.set(keypath, null);
  },

  /**
   * The `clone` method duplicates a cache. Some package managers can
   * leverage a pre-existing state to speed up their installation.
   *
   * @method destroy
   * @param {String} fromLabel The label for the cache to clone.
   * @param {String} toLabel The label for the new cache.
   */
  clone: function(fromLabel, toLabel) {
    var outputDir = quickTemp.makeOrReuse(this.dirs, toLabel);
    var keyPath = ['dirs', toLabel].join('.');
    this._conf.set(keyPath, outputDir);

    fs.copySync(this.get(fromLabel), outputDir);

    return this.dirs[toLabel];
  }

};

var test = new PackageCache();
var contents = require('./blueprint-shim');
test.create('app-node', 'yarn', contents['app']['package.json']);
test.create('app-bower', 'bower', contents['app']['bower.json']);
test.create('addon-node', 'yarn', contents['addon']['package.json']);
test.create('addon-bower', 'bower', contents['addon']['bower.json']);

module.exports = PackageCache;
<|endoftext|>


<commit_before>(function() {
    'use strict';

    var colDarkGreen = "#66BB6A"; // TODO!
    var colGreen = "#66BB6A";
    var colOrange = "orange";
    var colYellow = "#FFCA28";
    var colRed = "#EF5350";
    var colBlue = "#42A5F5";
    var lastFill=null;

    var mapModule = angular.module('mapModule', []);

    mapModule.controller('MapController', [ '$scope', '$log', function($scope, $log) {

        // in caso di errore reindirizza alla pagina di errore
        if($scope.error) {
            window.location.href = '/#/error';
        }

        var elabotate = function(array) {

            //load mappe

            var snapP1PT = Snap("#SvgPovo1PT");
            Snap.load("../img/mappe/Povo1PT.svg", function(data) {
                gestisciOggetti (data);
                snapP1PT.append(data);
            }) ;
            var snapP1P1 = Snap("#SvgPovo1P1");
            Snap.load("../img/mappe/Povo1P1.svg", function(data) {
                gestisciOggetti (data);
                snapP1P1.append(data);
            } ) ;
            var snapP2PT = Snap("#SvgPovo2PT");
            Snap.load("../img/mappe/Povo2PT.svg", function(data) {
                gestisciOggetti (data);
                snapP2PT.append(data);
            } ) ;
            var snapP2P1= Snap("#SvgPovo2P1");
            Snap.load("../img/mappe/Povo2P1.svg",function(data) {
                gestisciOggetti (data);
                snapP2P1.append(data);
            } ) ;

            // funzione di gestione colorazione + append mappe

            function gestisciOggetti (data) {
                for(var i = 0, len = array.length; i < len; i++) {

                    var className=array[i].number;
                    var idClassNameSvg = "#"+className.toLowerCase();
                    var rect= data.select(idClassNameSvg);

                    var status=null;
                    if (rect!=null){

                        switch(array[i].class) {
                            case 'dark-green':
                                status = colDarkGreen;
                                break;

                            case 'green':
                                status = colGreen;
                                break;

                            case 'orange':
                                status = colOrange;
                                break;

                            case 'yellow':
                                status = colYellow;
                                break;

                            case 'red':
                                status = colRed;
                                break;
                        }

                        //colore rect

                        rect.attr('fill', status);
                        rect.attr('cursor', "pointer");

                        //colore label
                        var idLabelSvg= idClassNameSvg+"t";
                        var label= data.select(idLabelSvg);
                        if (status==colGreen || status==colRed) {
                            label.attr('fill', "white");
                        }
                        else {
                            label.attr('fill', "#lalala");
                        }

                        label.attr('cursor', "pointer");

                        //hover
                        rect.hover(function() {
                            lastFill= this.attr('fill');
                            this.attr('fill', colBlue);
                            // this.transform( 's1.3,1.3');
                        },
                                   function() {
                            this.attr('fill', lastFill);
                            lastFill= null;
                            //this.transform( 's1,1');
                        });

                        //link ai dettagli di un aula
                        rect.click(function() {
                            var aula= (this.attr('id')).toUpperCase();
                            location.href = "#/details/"+aula;
                        });

                    }
                }
            }
        };

        // aspetta che vengano caricati i dati... appena pronti, chiama elaborate
        if($scope.loading) {
            $log.warn("Data loadng... WAIT!");

            $scope.$watch('loading', function(newValue, oldValue) {

                if(!newValue && oldValue) {
                    $log.info("Data loaded!");
                    elabotate($scope.rooms);
                }
            });

        } else {
            $log.info("Data already loaded...");
            elabotate($scope.rooms);
        }

    }]);
})();
<commit_msg>Clean map controller.<commit_after>(function() {
    'use strict';

    // TODO: colors...
    var colDarkGreen = "#66BB6A";
    var colGreen = "#66BB6A";
    var colOrange = "orange";
    var colYellow = "#FFCA28";
    var colRed = "#EF5350";
    var colBlue = "#42A5F5";
    var lastFill = null;

    angular.module('mapModule', []).controller('MapController', [ '$scope', '$log', function($scope, $log) {

        // funzione di gestione colorazione + append mappe
        function gestisciOggetti(data, array) {
            for(var i = 0, len = array.length; i < len; i++) {

                var className = array[i].number;
                var idClassNameSvg = "#"+className.toLowerCase();
                var rect= data.select(idClassNameSvg);

                var status = null;
                if (rect != null){

                    switch(array[i].class) {
                        case 'dark-green':
                            status = colDarkGreen;
                            break;

                        case 'green':
                            status = colGreen;
                            break;

                        case 'orange':
                            status = colOrange;
                            break;

                        case 'yellow':
                            status = colYellow;
                            break;

                        case 'red':
                            status = colRed;
                            break;
                    }

                    rect.attr('fill', status);
                    rect.attr('cursor', "pointer");

                    // colore label
                    var idLabelSvg= idClassNameSvg+"t";
                    var label= data.select(idLabelSvg);
                    if (status==colGreen || status==colRed) {
                        label.attr('fill', "white");
                    } else {
                        label.attr('fill', "#lalala");
                    }
                    label.attr('cursor', "pointer");

                    // hover
                    rect.hover(function() {
                        lastFill= this.attr('fill');
                        this.attr('fill', colBlue);
                    }, function() {
                        this.attr('fill', lastFill);
                        lastFill= null;
                    });

                    // link ai dettagli di un aula
                    rect.click(function() {
                        var aula = (this.attr('id')).toUpperCase();
                        window.location = "#/details/" + aula;
                    });

                }
            }
        }

        // function to load the maps
        function elabotate(array) {
            var snapP1PT = Snap("#SvgPovo1PT");
            Snap.load("../img/mappe/Povo1PT.svg", function(data) {
                gestisciOggetti(data, array);
                snapP1PT.append(data);
            });
            var snapP1P1 = Snap("#SvgPovo1P1");
            Snap.load("../img/mappe/Povo1P1.svg", function(data) {
                gestisciOggetti(data, array);
                snapP1P1.append(data);
            });
            var snapP2PT = Snap("#SvgPovo2PT");
            Snap.load("../img/mappe/Povo2PT.svg", function(data) {
                gestisciOggetti(data, array);
                snapP2PT.append(data);
            });
            var snapP2P1= Snap("#SvgPovo2P1");
            Snap.load("../img/mappe/Povo2P1.svg", function(data) {
                gestisciOggetti(data, array);
                snapP2P1.append(data);
            });
        }

        // wait for the data to be loaded
        if ($scope.loading) {
            $log.info("Data loadng...");

            $scope.$watch('loading', function(newValue, oldValue) {
                if (!newValue && oldValue) {
                    $log.info("Data loaded!");
                    elabotate($scope.rooms);
                }
            });

        } else {
            $log.info("Data already loaded...");
            elabotate($scope.rooms);
        }

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