<commit_before>function hide_covers() {
    // Remove covers
    $(".mix_element div.cover").remove()
    // Add class so cards can be restyled
    $(".mix_card.half_card").addClass("ext-coverless_card")

    // Remove covers on track page
    $("#cover_art").remove()
    // Remove covers in the sidebar of a track page
    $(".card.sidebar_mix .cover").remove()
    $(".card.sidebar_mix").addClass("ext-coverless_card")
}

function filter() {
    chrome.storage.local.get("state", function(result) {
        if(result["state"] == "on") {
            hide_covers()
        }
    });
}
// Make sure that when we navigate the site (which doesn't refresh the page), the filter is still run
$('#body_container').bind('DOMSubtreeModified',filter);
filter();
<commit_msg>Use MutationObserver API to catch dom updates<commit_after>function hide_covers() {
    // Remove covers
    $(".mix_element div.cover").remove()
    // Add class so cards can be restyled
    $(".mix_card.half_card").addClass("ext-coverless_card")

    // Remove covers on track page
    $("#cover_art").remove()
    // Remove covers in the sidebar of a track page
    $(".card.sidebar_mix .cover").remove()
    $(".card.sidebar_mix").addClass("ext-coverless_card")
}

function filter() {
    chrome.storage.local.get("state", function(result) {
        if(result["state"] == "on") {
            hide_covers()
        }
    });
}
// Make sure that when we navigate the site (which doesn't refresh the page), the filter is still run
var observer = new MutationObserver(filter)
observer.observe(document.getElementById("main"), {childList: true, subtree: true})
filter();
<|endoftext|>


<commit_before>/* Spy factory */
define(['./nainwak', 'utils/log'], function (nainwak, log) {
    function Spy(conf) {  /*user, channel*/
        //IDS = url.parseQueryParams(frame.location).IDS,
        var frame = conf.infoFrame,
            infoLoaded = function () {
                var contentWindow = frame.contentWindow,
                    doc = contentWindow.document,
                    location = contentWindow.location,
                    url = location.origin + location.pathname,
                    page = nainwak.pages.byUrl(url),
                    result;

                if (page) {
                    // TODO: do something useful with the result
                    log('Analyzing ' + page.name);
                    result = page.analyze(doc);
                    log(result);
                }
            },
            isEnabled = false,
            enable = function (value) {
                var oldEnabled = isEnabled;

                // update the status (and convert to boolean, just in case)
                isEnabled = !!value;

                if (oldEnabled === isEnabled) {  // nothing to do
                    return;
                }

                // register or unregister the load event handler
                if (isEnabled) {
                    frame.addEventListener('load', infoLoaded, false);
                } else {
                    frame.removeEventListener('load', infoLoaded, false);
                }
            };

        // start enabled
        enable(true);

        return Object.freeze({
            get enabled() {
                return isEnabled;
            },
            set enabled(value) {
                enable(value);
            }
        });
    }

    return Spy;
});
<commit_msg>Removed an obsolete comment<commit_after>/* Spy factory */
define(['./nainwak', 'utils/log'], function (nainwak, log) {
    function Spy(conf) {
        var frame = conf.infoFrame,
            //IDS = url.parseQueryParams(frame.location).IDS,
            infoLoaded = function () {
                var contentWindow = frame.contentWindow,
                    doc = contentWindow.document,
                    location = contentWindow.location,
                    url = location.origin + location.pathname,
                    page = nainwak.pages.byUrl(url),
                    result;

                if (page) {
                    // TODO: do something useful with the result
                    log('Analyzing ' + page.name);
                    result = page.analyze(doc);
                    log(result);
                }
            },
            isEnabled = false,
            enable = function (value) {
                var oldEnabled = isEnabled;

                // update the status (and convert to boolean, just in case)
                isEnabled = !!value;

                if (oldEnabled === isEnabled) {  // nothing to do
                    return;
                }

                // register or unregister the load event handler
                if (isEnabled) {
                    frame.addEventListener('load', infoLoaded, false);
                } else {
                    frame.removeEventListener('load', infoLoaded, false);
                }
            };

        // start enabled
        enable(true);

        return Object.freeze({
            get enabled() {
                return isEnabled;
            },
            set enabled(value) {
                enable(value);
            }
        });
    }

    return Spy;
});
<|endoftext|>


<commit_before>
/**
 * Fluder 0.1.0
 * A unidirectional data flow tool based on flux.
 *
 * url: https://github.com/coderwin/Fluder
 * author: chenjiancj2011@outlook.com
 * weibo: imChenJian
 * date: 2016-08-10
 */

/**
 * workflow Queue
 */
import Queue from './queue';

/**
 * custom Event
 */
import EventEmitter from 'events';

/**
 * Fluder
 */
export default new class Fluder {
    /**
     * 构造函数
     * @return {object} 返回Fluder实例对象
     */
    constructor() {
        /**
         * store handlers 注册Map
         * @type {Object}
         */
        this._registers = {};

        /**
         * dispatch栈
         * @type {Array}
         */
        this._dispatchStack = [];

        /**
         * 初始化
         */
        this._init();
    }

    _init() {
        /**
         * 中间件，集中处理action payload和storeId
         */
        this._middleware = new Queue((payload) => {
            /**
             * 中间件队列执行完后触发Store handler的调用
             */
            this._invoke(payload);

        }, true);
    }

    /**
     * action对handler的调用(内部调用)
     * @param  {object} payload 此时的payload包含action和action对应的storeId
     * @return {void}           无返回值
     */
    _invoke(payload) {
        /**
         * storeId: 用于map到register里面注册的handler
         * @type {string}
         */
        let {
            storeId
        } = payload;
        /**
         * store和它对应的handler
         * @type {object}
         */
        let {
            store,
            handlers
        } = this._registers[storeId];

        /**
         * action payload
         * @type {object}
         */
        payload = payload.payload;

        /**
         * 在当前storeId的store Map到对应的handler
         * @type {function}
         */
        let handler = handlers[payload.type];

        if (typeof handler === 'function') {
            // Invoke store handler
            /**
             * TODO
             * result应该为store数据的copy，暂时没做深度copy，后续把Store改写成Immutable数据结构
             * view-controller里面对result的修改不会影响到store里的数据
             */
            let result;
            let _result = handler.call(store, payload)
            /**
             * 可以没有返回值，只是set Store里面的值
             * 这里把payload传给change的Store，可以做相应的渲染优化[局部渲染]
             */
            // if (result !== undefined) {
            store.emitChange(payload, result);
            // }
        }
    }

    /**
     * 更新Action栈以及记录当前ActionID
     */
    _startDispatch(storeId) {
        this._dispatchStack || (this._dispatchStack = []);
        this._dispatchStack.push(storeId);
        this._currentDispatch = storeId;
    }

    /**
     * Action执行完更新Action栈以及删除当前ActionID
     */
    _endDispatch() {
        this._dispatchStack.pop();
        this._currentDispatch = null;
    }

    register(storeId, regs){
        this._registers[storeId] = regs;
    }

    enter(middleware){
        this._middleware.enter(middleware)
    }

    /**
     * 触发action(内部调用)
     * @param  {string} storeId store/action唯一标示
     * @param  {object} action  action数据
     * @return {void}           无返回值
     */
    dispatch(storeId, payload) {
        /**
         * 在当前Action触发的Store handler回调函数中再次发起了当前Action，这样会造成A-A循环调用,出现栈溢出
         */
        if (this._currentDispatch == storeId) {
            throw Error('action '+(payload.value&&payload.value.actionType)+' __invoke__ myself!')
        }
        /**
         * 在当前Action触发的Store handler回调函数中再次触发了当前Action栈中的Action，出现A-B-C-A式循环调用，也会出现栈溢出
         */
        if (this._dispatchStack.indexOf(storeId) != -1) {
            throw Error(this._dispatchStack.join(' -> ') + storeId + ' : action __invoke__ to a circle!');
        }
        /**
         * 更新Action栈以及记录当前ActionID
         */
        this._startDispatch(storeId);
        /**
         * Action的触发必须有ActionType，原因是ActionType和Store handlers Map的key一一对应
         */
        if (!payload.type) {
            throw new Error('action type does not exist in \n' + JSON.stringify(payload, null, 2));
        }
        /**
         * 发出action的时候 统一走一遍中间件
         */
        this._middleware.execute({
            storeId,
            payload
        });
        /**
         * Action执行完更新Action栈以及删除当前ActionID
         */
        this._endDispatch()
    }
}
<commit_msg>added "catchError tool" for @_invoke<commit_after>
/**
 * Fluder 0.1.0
 * A unidirectional data flow tool based on flux.
 *
 * url: https://github.com/coderwin/Fluder
 * author: chenjiancj2011@outlook.com
 * weibo: imChenJian
 * date: 2016-08-10
 */

/**
 * workflow Queue
 */
import Queue from './queue';

/**
 * catchError
 */
import {catchError} from './tools'

/**
 * custom Event
 */
import EventEmitter from 'events'

/**
 * Fluder
 */
export default new class Fluder {
    /**
     * 构造函数
     * @return {object} 返回Fluder实例对象
     */
    constructor() {
        /**
         * store handlers 注册Map
         * @type {Object}
         */
        this._registers = {}

        /**
         * dispatch栈
         * @type {Array}
         */
        this._dispatchStack = []

        /**
         * 初始化
         */
        this._init()
    }

    _init() {

        /**
         * 中间件，集中处理action payload和storeId
         */
        this._middleware = new Queue((payload) => {

            /**
             * 中间件队列执行完后触发Store handler的调用
             */
            this._invoke(payload)

        }, true)
    }

    /**
     * action对handler的调用(内部调用)
     * @param  {object} payload 此时的payload包含action和action对应的storeId
     * @return {void}           无返回值
     */
    _invoke(payload) {

        /**
         * storeId: 用于map到register里面注册的handler
         * @type {string}
         */
        let {
            storeId
        } = payload

        /**
         * store和它对应的handler
         * @type {object}
         */
        let {
            store,
            handlers
        } = this._registers[storeId]

        /**
         * action payload
         * @type {object}
         */
        payload = payload.payload

        /**
         * 在当前storeId的store Map到对应的handler
         * @type {function}
         */
        let handler = handlers[payload.type]

        if (typeof handler === 'function') {

            /**
             * TODO
             * result应该为store数据的copy，暂时没做深度copy，后续把Store改写成Immutable数据结构
             * view-controller里面对result的修改不会影响到store里的数据
             */
            let result
            let _result = handler.call(store, payload)

            /**
             * 可以没有返回值，只是set Store里面的值
             * 这里把payload传给change的Store，可以做相应的渲染优化[局部渲染]
             */
            // if (result !== undefined) {
            store.emitChange(payload, result)
            // }
        }
    }

    /**
     * 更新Action栈以及记录当前ActionID
     */
    _startDispatch(storeId) {
        this._dispatchStack || (this._dispatchStack = [])
        this._dispatchStack.push(storeId)
        this._currentDispatch = storeId
    }

    /**
     * Action执行完更新Action栈以及删除当前ActionID
     */
    _endDispatch() {
        this._dispatchStack.pop()
        this._currentDispatch = null
    }

    /**
     * Store和handler注册
     * @param  {string} storeId store/action唯一标示
     * @param  {object} storeHandler  store和handler
     * @return {void}           无返回值
     */
    register(storeId, storeHandler){
        this._registers[storeId] = storeHandler
    }

    /**
     * 中间件入队
     * @param  {function} middleware  中间件处理函数
     * @return {void}           无返回值
     */
    enter(middleware){
        this._middleware.enter(middleware)
    }

    /**
     * 触发action(内部调用)
     * @param  {string} storeId store/action唯一标示
     * @param  {object} action  action数据
     * @return {void}           无返回值
     */
    dispatch(storeId, payload) {

        /**
         * 在当前Action触发的Store handler回调函数中再次发起了当前Action，这样会造成A-A循环调用,出现栈溢出
         */
        if (this._currentDispatch == storeId) {

            throw Error('action '+(payload.value&&payload.value.actionType)+' __invoke__ myself!')
        }

        /**
         * 在当前Action触发的Store handler回调函数中再次触发了当前Action栈中的Action，出现A-B-C-A式循环调用，也会出现栈溢出
         */
        if (this._dispatchStack.indexOf(storeId) != -1) {

            throw Error(this._dispatchStack.join(' -> ') + storeId + ' : action __invoke__ to a circle!')
        }

        /**
         * 更新Action栈以及记录当前ActionID
         */
        this._startDispatch(storeId)

        /**
         * Action的触发必须有ActionType，原因是ActionType和Store handlers Map的key一一对应
         */
        if (!payload.type) {

            throw new Error('action type does not exist in \n' + JSON.stringify(payload, null, 2))
        }

        try {

            /**
             * 发出action的时候 统一走一遍中间件
             */
            this._middleware.execute({
                storeId,
                payload
            })
        } catch (e) {

            /**
             * 执行handler的时候出错end掉当前dispatch
             */
            this._endDispatch()

            /**
             * 抛出错误信息
             */
            catchError(e)
        }

        /**
         * Action执行完更新Action栈以及删除当前ActionID
         */
        this._endDispatch()
    }
}
<|endoftext|>


<commit_before>import AttributeMarshallingMixin from './AttributeMarshallingMixin.js';
import ReactiveMixin from './ReactiveMixin.js';
import RenderUpdatesMixin from './RenderUpdatesMixin.js';
import ShadowTemplateMixin from './ShadowTemplateMixin.js';

/**
 * A general-purpose base class for web components.
 *
 * This class simply bundles a small set of mixins that are useful for creating
 * web components in a functional-reactive programming (FRP) style. It is
 * defined this way:
 *
 *    const ElementBase =
 *      AttributeMarshallingMixin(
 *      ReactiveMixin(
 *      RenderUpdatesMixin(
 *      ShadowTemplateMixin(
 *        HTMLElement
 *      ))));
 *
 * `ElementBase` is simply provided as a convenience, and the same result can be
 * achieved by applying the mixins yourself to `HTMLElement`.
 *
 * @mixes AttributeMarshallingMixin
 * @mixes ReactiveMixin
 * @mixes RenderUpdatesMixin
 * @mixes ShadowTemplateMixin
 */
const ElementBase =
  AttributeMarshallingMixin(
  ReactiveMixin(
  RenderUpdatesMixin(
  ShadowTemplateMixin(
    HTMLElement
  ))));

export default ElementBase
<commit_msg>Missing semicolon<commit_after>import AttributeMarshallingMixin from './AttributeMarshallingMixin.js';
import ReactiveMixin from './ReactiveMixin.js';
import RenderUpdatesMixin from './RenderUpdatesMixin.js';
import ShadowTemplateMixin from './ShadowTemplateMixin.js';

/**
 * A general-purpose base class for web components.
 *
 * This class simply bundles a small set of mixins that are useful for creating
 * web components in a functional-reactive programming (FRP) style. It is
 * defined this way:
 *
 *    const ElementBase =
 *      AttributeMarshallingMixin(
 *      ReactiveMixin(
 *      RenderUpdatesMixin(
 *      ShadowTemplateMixin(
 *        HTMLElement
 *      ))));
 *
 * `ElementBase` is simply provided as a convenience, and the same result can be
 * achieved by applying the mixins yourself to `HTMLElement`.
 *
 * @mixes AttributeMarshallingMixin
 * @mixes ReactiveMixin
 * @mixes RenderUpdatesMixin
 * @mixes ShadowTemplateMixin
 */
const ElementBase =
  AttributeMarshallingMixin(
  ReactiveMixin(
  RenderUpdatesMixin(
  ShadowTemplateMixin(
    HTMLElement
  ))));

export default ElementBase;
<|endoftext|>


<commit_before>/// <reference path="../../ext/ext-core-debug.js"/>
/// <reference path="../../platform/Application.js"/>
/// <reference path="../../platform/Format.js"/>
/// <reference path="../../sdata/SDataService.js"/>

Ext.namespace("Mobile.SalesLogix");

Mobile.SalesLogix.Environment = (function() {
    return {
        initiateCall: function(number) {
            setTimeout(function() {
                window.location.href = String.format("tel:{0}", number);
            }, 0);
        },
        initiateEmail: function(email) {
            setTimeout(function() {
                window.location.href = String.format("mailto:{0}", email);
            }, 0);
        },
        showMapForAddress: function(address) {
            setTimeout(function() {
                window.location.href = String.format("http://maps.google.com/maps?q={0}", address);
            }, 0);
        }
    };
})();
<commit_msg>[fixed #4218981] fixed an issue with the log to history view not showing up on iphone.<commit_after>/// <reference path="../../ext/ext-core-debug.js"/>
/// <reference path="../../platform/Application.js"/>
/// <reference path="../../platform/Format.js"/>
/// <reference path="../../sdata/SDataService.js"/>

Ext.namespace("Mobile.SalesLogix");

Mobile.SalesLogix.Environment = (function() {
    // todo: open a new browser window for these when on a mobile device?
    // on a mobile device, launching an external handler can impact a view transition, and cause issues, which the timeout takes care of.
    // not the best way, perhaps a post-transition callback should be used for launching these? check transitioning, then queue if needed?
    return {
        initiateCall: function(number) {
            setTimeout(function() {
                window.location.href = String.format("tel:{0}", number);
            }, 50);
        },
        initiateEmail: function(email) {
            setTimeout(function() {
                window.location.href = String.format("mailto:{0}", email);
            }, 50);
        },
        showMapForAddress: function(address) {
            setTimeout(function() {
                window.location.href = String.format("http://maps.google.com/maps?q={0}", address);
            }, 50);
        }
    };
})();
<|endoftext|>


<commit_before>/* commonjs package manager support */
if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){
    var jsriffle = require('jsRiffle');
    module.exports = 'ngRiffle';
}

(function () {
    'use strict';

    var ngRiffleModule = angular.module('ngRiffle', []).provider('$riffle', $RiffleProvider);

    function $RiffleProvider() {

        var id = undefined;
        var providerAPIExcludes = ['Application', 'Domain', 'modelObject', 'want'];
        for(var key in jsRiffle){
          if(providerAPIExcludes.indexOf(key) === -1){
            this[key] = jsRiffle[key];
          }
        }

        this.setDomain = function(domain){
          id = domain;
        };

        var interceptors = this.interceptors = [];

        this.$get = ["$rootScope", "$q", "$log", "$injector", function ($rootScope, $q, $log, $injector) {

            /**
             * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
             */
            var reversedInterceptors = [];

            angular.forEach(interceptors, function (interceptor) {
                reversedInterceptors.unshift(
                    angular.isString(interceptor) ? $injector.get(interceptor) :  $injector.invoke(interceptor));
            });

            /**
             * @param func
             * @returns {Function}
             *
             * @description
             * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
             */
            function digestWrapper(func) {

                return function () {
                    var cb = func.apply(this, arguments);
                    $rootScope.$apply();
                    return cb;
                };
            }

            var connection;
            var sessionDeferred = $q.defer();
            var sessionPromise = sessionDeferred.promise;

            var joinFnc = digestWrapper(function () {
                $log.debug("Connection Opened: ");
                $rootScope.$broadcast("$riffle.open");
                connection.connected = true;
                sessionDeferred.resolve();
            });

            var leaveFnc = digestWrapper(function (reason, details) {
                $log.debug("Connection Closed: ", reason, details);
                connection.connected = false;
                sessionDeferred = $q.defer();
                sessionPromise = sessionDeferred.promise;
                $rootScope.$broadcast("$riffle.leave", {reason: reason, details: details});
            });

            connection = new DomainWrapper(jsRiffle.Domain(id));
            connection.want = jsRiffle.want;
            connection.modelObject = jsRiffle.modelObject;
            connection.connected = false;

            /**
             * Wraps WAMP actions, so that when they're called, the defined interceptors get called before the result is returned
             *
             * @param type
             * @param args
             * @param callback
             * @returns {*}
             */
            var interceptorWrapper = function (type, args, callback) {

                var result = function (result) {
                    return {result: result, type: type, args: args};
                };

                var error = function (error) {
                    //$log.error("$riffle error", {type: type, arguments: args, error: error});
                    return $q.reject({error: error, type: type, args: args});
                };

                // Only execute the action callback once we have an established session
                var action = sessionPromise.then(function () {
                    return callback();
                });

                var chain = [result, error];

                // Apply interceptors
                angular.forEach(reversedInterceptors, function (interceptor) {
                    if (interceptor[type + 'Response'] || interceptor[type + 'ResponseError']) {
                        chain.push(interceptor[type + 'Response'], interceptor[type + 'ResponseError']);
                    }
                });

                // We only want to return the actually result or error, not the entire information object
                chain.push(
                    function (response) {
                        return response.result;
                    }, function (response) {
                        return $q.reject(response.error);
                    }
                );

                while (chain.length) {
                    var resolved = chain.shift();
                    var rejected = chain.shift();

                    action = action.then(resolved, rejected);
                }

                return action;
            };

            function DomainWrapper(riffleDomain){
              this.conn = riffleDomain;
              this.conn.onJoin = joinFnc;
              this.conn.onLeave = leaveFnc;
            }
            DomainWrapper.prototype.join = function(){
              return this.conn.join();
            };
            DomainWrapper.prototype.leave = function(){
              return this.conn.leave();
            };
            DomainWrapper.prototype.subscribeOnScope = function(scope, channel, callback){
              var self = this;
              return this.subscribe(channel, callback).then(function(){
                scope.$on('$destroy', function () {
                  return self.unsubscribe(channel);
                });
              });
            };
            DomainWrapper.prototype.setToken = function(tok) {
                this.conn.setToken(tok);
            };
            DomainWrapper.prototype.getToken = function() {
                return this.conn.getToken();
            };
            DomainWrapper.prototype.unsubscribe = function (channel) {
              var self = this;
              return interceptorWrapper('unsubscribe', arguments, function () {
                return self.conn.unsubscribe(channel);
              });
            };
            DomainWrapper.prototype.publish = function(){
              var a = arguments
              var self = this;
              return interceptorWrapper('publish', arguments, function(){
                return self.conn.publish.apply(self.conn, a);
              });
            };
            DomainWrapper.prototype.register = function (action, handler) {
              if(typeof(handler) === 'function'){
                handler = digestWrapper(handler);
              }else{
                handler.fp = digestWrapper(handler.fp);
              }
              var self = this;
              return interceptorWrapper('register', arguments, function () {
                return self.conn.register(action, handler);
              });
            };
            DomainWrapper.prototype.subscribe = function (action, handler) {
              if(typeof(handler) === 'function'){
                handler = digestWrapper(handler);
              }else{
                handler.fp = digestWrapper(handler.fp);
              }
              var self = this;
              return interceptorWrapper('subscribe', arguments, function () {
                return self.conn.subscribe(action, handler);
              });
            };
            DomainWrapper.prototype.unregister = function (registration) {
              var self = this;
              return interceptorWrapper('unregister', arguments, function () {
                return self.conn.unregister(registration);
              });
            };
            DomainWrapper.prototype.call = function () {
              var a = arguments
              var self = this;

              return interceptorWrapper('call', arguments, function () {
                return self.conn.call.apply(self.conn, a);
              });
            };
            DomainWrapper.prototype.subdomain = function(id) {
              return new DomainWrapper(this.conn.subdomain(id));
            };
            DomainWrapper.prototype.linkDomain = function(id) {
              return new DomainWrapper(this.conn.linkDomain(id));
            };
            DomainWrapper.prototype.login = function(user) {
              user = user || {};
              var self = this;
              //deferred for knowing when process is done
              var userDeferred = $q.defer();

              //figure out auth level from user object
              var auth0 = false;
              if(!user.password){
                auth0 = true;
              }

              function resolve(){
                userDeferred.resolve(connection.user);
              }

              //if we are auth1 load user data
              function load(){
                connection.user.load().then(userDeferred.resolve, userDeferred.reject);
              }

              //if we get success from the registrar on login continue depending on auth level
              function success(domain){
                if(auth0){
                  //if auth0 then we don't have user storage
                  connection.user = new DomainWrapper(domain);
                  connection.user.join();
                  sessionPromise.then(resolve);
                }else{
                  //if auth1 use user class to wrap domain and implement user storage and load user data
                  connection.user = new User(self, domain);
                  connection.user.join();
                  sessionPromise.then(load);
                }
              }

              //attempt registration login and continue process on success
              this.conn.login(user).then(success, userDeferred.reject);

              //return the promise which will be resolved once the login process completes.
              return userDeferred.promise;
            };
            DomainWrapper.prototype.registerAccount = function(user) {
              return this.conn.registerAccount(user);
            };

            function User(app, domain) {
              DomainWrapper.call(this, domain);
              this.storage = app.subdomain("Auth");
            }
            User.prototype = Object.create(DomainWrapper.prototype);
            User.prototype.constructor = User;
            User.prototype.email = "";
            User.prototype.name = "";
            User.prototype.privateStorage = {};
            User.prototype.publicStorage = {};
            User.prototype.save = function(){
              return this.storage.call('save_user_data', this.publicStorage, this.privateStorage);
            };
            User.prototype.load = function(){
              var self = this;
              var loadDeferred = $q.defer();
              function loadUser(user){
                self.name = user.name;
                self.email = user.email;
                self.gravatar = user.gravatar;
                self.privateStorage = user.private || {};
                self.publicStorage = user.public || {};
                loadDeferred.resolve(self);
              }
              function error(error){
                loadDeferred.reject(error);
              }
              this.storage.call('get_user_data').then(loadUser, error);
              return loadDeferred.promise;
            };
            User.prototype.getPublicData = function(query){
              return this.storage.call('get_public_data', query)
            };

            /**
             * Subscription object which self manages reconnections
             * @param topic
             * @param handler
             * @param options
             * @param subscribedCallback
             * @returns {{}}
             * @constructor
            var Subscription = function (topic, handler, options, subscribedCallback) {

                var subscription = {}, unregister, onOpen, deferred = $q.defer();

                handler = digestWrapper(handler);

                onOpen = function () {
                    var p = connection.session.subscribe(topic, handler, options).then(
                        function (s) {
                            if (subscription.hasOwnProperty('id')) {
                                delete subscription.id;
                            }

                            subscription = angular.extend(s, subscription);
                            deferred.resolve(subscription);
                            return s;
                        }
                    );
                    if (subscribedCallback) {
                        subscribedCallback(p);
                    }

                };

                if (connection.isOpen) {
                    onOpen();
                }

                unregister = $rootScope.$on("$riffle.open", onOpen);

                subscription.promise = deferred.promise;
                subscription.unsubscribe = function () {
                    unregister(); //Remove the event listener, so this object can get cleaned up by gc
                    return connection.session.unsubscribe(subscription);
                };

                return subscription.promise;
            };
             */

            return connection;
        }];

        return this;

    }
})();
<commit_msg>fixing ngriffle wants<commit_after>/* commonjs package manager support */
if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){
    var jsriffle = require('jsRiffle');
    module.exports = 'ngRiffle';
}

(function () {
    'use strict';

    var ngRiffleModule = angular.module('ngRiffle', []).provider('$riffle', $RiffleProvider);

    function $RiffleProvider() {

        var id = undefined;
        var providerAPIExcludes = ['Application', 'Domain', 'modelObject', 'want'];
        for(var key in jsRiffle){
          if(providerAPIExcludes.indexOf(key) === -1){
            this[key] = jsRiffle[key];
          }
        }

        this.setDomain = function(domain){
          id = domain;
        };

        var interceptors = this.interceptors = [];

        this.$get = ["$rootScope", "$q", "$log", "$injector", function ($rootScope, $q, $log, $injector) {

            /**
             * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
             */
            var reversedInterceptors = [];

            angular.forEach(interceptors, function (interceptor) {
                reversedInterceptors.unshift(
                    angular.isString(interceptor) ? $injector.get(interceptor) :  $injector.invoke(interceptor));
            });

            /**
             * @param func
             * @returns {Function}
             *
             * @description
             * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
             */
            function digestWrapper(func) {

                return function () {
                    var cb = func.apply(this, arguments);
                    $rootScope.$apply();
                    return cb;
                };
            }

            var connection;
            var sessionDeferred = $q.defer();
            var sessionPromise = sessionDeferred.promise;

            var joinFnc = digestWrapper(function () {
                $log.debug("Connection Opened: ");
                $rootScope.$broadcast("$riffle.open");
                connection.connected = true;
                sessionDeferred.resolve();
            });

            var leaveFnc = digestWrapper(function (reason, details) {
                $log.debug("Connection Closed: ", reason, details);
                connection.connected = false;
                sessionDeferred = $q.defer();
                sessionPromise = sessionDeferred.promise;
                $rootScope.$broadcast("$riffle.leave", {reason: reason, details: details});
            });

            connection = new DomainWrapper(jsRiffle.Domain(id));
            connection.want = jsRiffle.want;
            connection.modelObject = jsRiffle.modelObject;
            connection.connected = false;

            /**
             * Wraps WAMP actions, so that when they're called, the defined interceptors get called before the result is returned
             *
             * @param type
             * @param args
             * @param callback
             * @returns {*}
             */
            var interceptorWrapper = function (type, args, callback) {

                var result = function (result) {
                    return {result: result, type: type, args: args};
                };

                var error = function (error) {
                    //$log.error("$riffle error", {type: type, arguments: args, error: error});
                    return $q.reject({error: error, type: type, args: args});
                };

                // Only execute the action callback once we have an established session
                var action = sessionPromise.then(function () {
                    return callback();
                });

                var chain = [result, error];

                // Apply interceptors
                angular.forEach(reversedInterceptors, function (interceptor) {
                    if (interceptor[type + 'Response'] || interceptor[type + 'ResponseError']) {
                        chain.push(interceptor[type + 'Response'], interceptor[type + 'ResponseError']);
                    }
                });

                // We only want to return the actually result or error, not the entire information object
                chain.push(
                    function (response) {
                        return response.result;
                    }, function (response) {
                        return $q.reject(response.error);
                    }
                );

                while (chain.length) {
                    var resolved = chain.shift();
                    var rejected = chain.shift();

                    action = action.then(resolved, rejected);
                }

                return action;
            };

            function DomainWrapper(riffleDomain){
              this.conn = riffleDomain;
              this.conn.onJoin = joinFnc;
              this.conn.onLeave = leaveFnc;
            }
            DomainWrapper.prototype.join = function(){
              return this.conn.join();
            };
            DomainWrapper.prototype.leave = function(){
              return this.conn.leave();
            };
            DomainWrapper.prototype.subscribeOnScope = function(scope, channel, callback){
              var self = this;
              return this.subscribe(channel, callback).then(function(){
                scope.$on('$destroy', function () {
                  return self.unsubscribe(channel);
                });
              });
            };
            DomainWrapper.prototype.setToken = function(tok) {
                this.conn.setToken(tok);
            };
            DomainWrapper.prototype.getToken = function() {
                return this.conn.getToken();
            };
            DomainWrapper.prototype.unsubscribe = function (channel) {
              var self = this;
              return interceptorWrapper('unsubscribe', arguments, function () {
                return self.conn.unsubscribe(channel);
              });
            };
            DomainWrapper.prototype.publish = function(){
              var a = arguments
              var self = this;
              return interceptorWrapper('publish', arguments, function(){
                return self.conn.publish.apply(self.conn, a);
              });
            };
            DomainWrapper.prototype.register = function (action, handler) {
              if(typeof(handler) === 'function'){
                handler = digestWrapper(handler);
              }else{
                handler.fp = digestWrapper(handler.fp);
              }
              var self = this;
              return interceptorWrapper('register', arguments, function () {
                return self.conn.register(action, handler);
              });
            };
            DomainWrapper.prototype.subscribe = function (action, handler) {
              if(typeof(handler) === 'function'){
                handler = digestWrapper(handler);
              }else{
                handler.fp = digestWrapper(handler.fp);
              }
              var self = this;
              return interceptorWrapper('subscribe', arguments, function () {
                return self.conn.subscribe(action, handler);
              });
            };
            DomainWrapper.prototype.unregister = function (registration) {
              var self = this;
              return interceptorWrapper('unregister', arguments, function () {
                return self.conn.unregister(registration);
              });
            };
            DomainWrapper.prototype.call = function () {
              var a = arguments
              var self = this;

              return interceptorWrapper('call', arguments, function () {
                var ret = self.conn.call.apply(self.conn, a);
                ret.then(function(ret){console.log(ret);});
                return ret;
              });
            };
            DomainWrapper.prototype.subdomain = function(id) {
              return new DomainWrapper(this.conn.subdomain(id));
            };
            DomainWrapper.prototype.linkDomain = function(id) {
              return new DomainWrapper(this.conn.linkDomain(id));
            };
            DomainWrapper.prototype.login = function(user) {
              user = user || {};
              var self = this;
              //deferred for knowing when process is done
              var userDeferred = $q.defer();

              //figure out auth level from user object
              var auth0 = false;
              if(!user.password){
                auth0 = true;
              }

              function resolve(){
                userDeferred.resolve(connection.user);
              }

              //if we are auth1 load user data
              function load(){
                connection.user.load().then(userDeferred.resolve, userDeferred.reject);
              }

              //if we get success from the registrar on login continue depending on auth level
              function success(domain){
                if(auth0){
                  //if auth0 then we don't have user storage
                  connection.user = new DomainWrapper(domain);
                  connection.user.join();
                  sessionPromise.then(resolve);
                }else{
                  //if auth1 use user class to wrap domain and implement user storage and load user data
                  connection.user = new User(self, domain);
                  connection.user.join();
                  sessionPromise.then(load);
                }
              }

              //attempt registration login and continue process on success
              this.conn.login(user).then(success, userDeferred.reject);

              //return the promise which will be resolved once the login process completes.
              return userDeferred.promise;
            };
            DomainWrapper.prototype.registerAccount = function(user) {
              return this.conn.registerAccount(user);
            };

            function User(app, domain) {
              DomainWrapper.call(this, domain);
              this.storage = app.subdomain("Auth");
            }
            User.prototype = Object.create(DomainWrapper.prototype);
            User.prototype.constructor = User;
            User.prototype.email = "";
            User.prototype.name = "";
            User.prototype.privateStorage = {};
            User.prototype.publicStorage = {};
            User.prototype.save = function(){
              return this.storage.call('save_user_data', this.publicStorage, this.privateStorage);
            };
            User.prototype.load = function(){
              var self = this;
              var loadDeferred = $q.defer();
              function loadUser(user){
                console.log('here')
                self.name = user.name;
                self.email = user.email;
                self.gravatar = user.gravatar;
                self.privateStorage = user.private || {};
                self.publicStorage = user.public || {};
                loadDeferred.resolve(self);
              }
              function error(error){
                loadDeferred.reject(error);
              }
              this.storage.call('get_user_data').then(loadUser, error);
              return loadDeferred.promise;
            };
            User.prototype.getPublicData = function(query){
              return this.storage.call('get_public_data', query)
            };

            /**
             * Subscription object which self manages reconnections
             * @param topic
             * @param handler
             * @param options
             * @param subscribedCallback
             * @returns {{}}
             * @constructor
            var Subscription = function (topic, handler, options, subscribedCallback) {

                var subscription = {}, unregister, onOpen, deferred = $q.defer();

                handler = digestWrapper(handler);

                onOpen = function () {
                    var p = connection.session.subscribe(topic, handler, options).then(
                        function (s) {
                            if (subscription.hasOwnProperty('id')) {
                                delete subscription.id;
                            }

                            subscription = angular.extend(s, subscription);
                            deferred.resolve(subscription);
                            return s;
                        }
                    );
                    if (subscribedCallback) {
                        subscribedCallback(p);
                    }

                };

                if (connection.isOpen) {
                    onOpen();
                }

                unregister = $rootScope.$on("$riffle.open", onOpen);

                subscription.promise = deferred.promise;
                subscription.unsubscribe = function () {
                    unregister(); //Remove the event listener, so this object can get cleaned up by gc
                    return connection.session.unsubscribe(subscription);
                };

                return subscription.promise;
            };
             */

            return connection;
        }];

        return this;

    }
})();
<|endoftext|>


<commit_before>var Script = require('./script'),
    util = require('./util'),
    conv = require('./convert'),
    key = require('./eckey'),
    base58 = require('./base58'),
    Crypto = require('./crypto-js/crypto'),
    ECPointFp = require('./jsbn/ec').ECPointFp,
    sec = require('./jsbn/sec'),
    ecparams = sec("secp256k1");

var BIP32key = function(opts) {
    if (!opts) opts = {}
    if (typeof opts == "string") {
        try {
            opts = BIP32key.prototype.deserialize(opts);
        }
        catch(e) {
            opts = BIP32key.prototype.fromMasterKey(opts);
        }
    }
    this.vbytes = opts.vbytes;
    this.depth = opts.depth;
    this.fingerprint = opts.fingerprint;
    this.i = opts.i;
    this.chaincode = opts.chaincode;
    this.key = opts.key;
    this.type = conv.bytesToString(this.vbytes) == PRIVDERIV ? 'priv' : 'pub'
    return this;
}

var PRIVDERIV = BIP32key.PRIVDERIV = '\x04\x88\xAD\xE4'
var PUBDERIV = BIP32key.PUBDERIV = '\x04\x88\xB2\x1E'

BIP32key.prototype.deserialize = function(str) {
    var bytes = base58.decode(str)
    var front = bytes.slice(0,bytes.length-4),
        back = bytes.slice(bytes.length-4);
    var checksum = Crypto.SHA256(Crypto.SHA256(front,{asBytes: true}), {asBytes: true})
                        .slice(0,4);
    if (""+checksum != ""+back) {
        throw new Error("Checksum failed");
    }
    var type = conv.bytesToString(bytes.slice(0,4)) == PRIVDERIV ? 'priv' : 'pub';
    return new BIP32key({
        type: type,
        vbytes: bytes.slice(0,4),
        depth: bytes[4],
        fingerprint: bytes.slice(5,9),
        i: util.bytesToNum(bytes.slice(9,13).reverse()),
        chaincode: bytes.slice(13,45),
        key: new key(type == 'priv' ? bytes.slice(46,78).concat([1]) : bytes.slice(45,78))
    })
}

BIP32key.prototype.serialize = function() {
    var bytes = this.vbytes.concat(
                [this.depth],
                this.fingerprint,
                util.numToBytes(this.i,4).reverse(),
                this.chaincode,
                this.type == 'priv' ? [0].concat(this.key.export('bytes').slice(0,32))
                                    : this.key)
    var checksum = Crypto.SHA256(Crypto.SHA256(bytes,{asBytes: true}), {asBytes: true})
                         .slice(0,4)
    return base58.encode(bytes.concat(checksum))
}

BIP32key.prototype.ckd = function(i) {
    var priv, pub, newkey, fingerprint, blob, I;
    if (this.type == 'priv') {
        priv = this.key.export('bytes')
        pub = this.key.getPub()
    }
    else pub = this.key

    if (i >= 2147483648) {
        if (this.priv) throw new Error("Can't do private derivation on public key!")
        blob = [0].concat(priv.slice(0,32),util.numToBytes(i,4).reverse())
    }
    else blob = pub.concat(util.numToBytes(i,4).reverse())

    I = Crypto.HMAC(Crypto.SHA512,blob,this.chaincode,{ asBytes: true })

    if (this.type == 'priv') {
        Ikey = Bitcoin.BigInteger.fromByteArrayUnsigned(I.slice(0,32))
        newkey = new key(this.key.priv.add(Ikey))
        newkey.compressed = true
        fingerprint = util.sha256ripe160(this.key.getPub()).slice(0,4)
    }
    else {
        newkey = ECPointFp.decodeFrom(ecparams.getCurve(),this.key)
                          .add(new key(I.slice(0,32).concat([1])).getPubPoint())
                          .getEncoded(true);
        fingerprint = util.sha256ripe160(this.key).slice(0,4)
    }
    return new BIP32key({
        vbytes: this.vbytes,
        type: this.type,
        depth: this.depth + 1,
        fingerprint: fingerprint,
        i: i,
        chaincode: I.slice(32),
        key: newkey
    })
}

BIP32key.prototype.clone = function() {
    return new BIP32key(this);
}

BIP32key.prototype.privtopub = BIP32key.prototype.getPub = function() {
    if (this.type == 'pub') return this.clone()
    return new BIP32key({
        vbytes: conv.stringToBytes(PUBDERIV),
        type: 'pub',
        depth: this.depth,
        fingerprint: this.fingerprint,
        i: this.i,
        chaincode: this.chaincode,
        key: this.key.getPub()
    })
}

BIP32key.prototype.fromMasterKey = function(seed) {
    var I = Bitcoin.Crypto.HMAC(Bitcoin.Crypto.SHA512,seed,"Bitcoin seed",{ asBytes: true })
    return new BIP32key({
        vbytes: conv.stringToBytes(PRIVDERIV),
        type: 'priv',
        depth: 0,
        fingerprint: [0,0,0,0],
        i: 0,
        chaincode: I.slice(32),
        key: new key(I.slice(0,32).concat([1]))
    })
}

BIP32key.prototype.getKey = function() { return this.key }

module.exports = BIP32key;
<commit_msg>missing modulo operation.<commit_after>var Script = require('./script'),
    util = require('./util'),
    conv = require('./convert'),
    key = require('./eckey'),
    base58 = require('./base58'),
    Crypto = require('./crypto-js/crypto'),
    ECPointFp = require('./jsbn/ec').ECPointFp,
    sec = require('./jsbn/sec'),
    ecparams = sec("secp256k1");

var BIP32key = function(opts) {
    if (!opts) opts = {}
    if (typeof opts == "string") {
        try {
            opts = BIP32key.prototype.deserialize(opts);
        }
        catch(e) {
            opts = BIP32key.prototype.fromMasterKey(opts);
        }
    }
    this.vbytes = opts.vbytes;
    this.depth = opts.depth;
    this.fingerprint = opts.fingerprint;
    this.i = opts.i;
    this.chaincode = opts.chaincode;
    this.key = opts.key;
    this.type = conv.bytesToString(this.vbytes) == PRIVDERIV ? 'priv' : 'pub'
    return this;
}

var PRIVDERIV = BIP32key.PRIVDERIV = '\x04\x88\xAD\xE4'
var PUBDERIV = BIP32key.PUBDERIV = '\x04\x88\xB2\x1E'

BIP32key.prototype.deserialize = function(str) {
    var bytes = base58.decode(str)
    var front = bytes.slice(0,bytes.length-4),
        back = bytes.slice(bytes.length-4);
    var checksum = Crypto.SHA256(Crypto.SHA256(front,{asBytes: true}), {asBytes: true})
                        .slice(0,4);
    if (""+checksum != ""+back) {
        throw new Error("Checksum failed");
    }
    var type = conv.bytesToString(bytes.slice(0,4)) == PRIVDERIV ? 'priv' : 'pub';
    return new BIP32key({
        type: type,
        vbytes: bytes.slice(0,4),
        depth: bytes[4],
        fingerprint: bytes.slice(5,9),
        i: util.bytesToNum(bytes.slice(9,13).reverse()),
        chaincode: bytes.slice(13,45),
        key: new key(type == 'priv' ? bytes.slice(46,78).concat([1]) : bytes.slice(45,78))
    })
}

BIP32key.prototype.serialize = function() {
    var bytes = this.vbytes.concat(
                [this.depth],
                this.fingerprint,
                util.numToBytes(this.i,4).reverse(),
                this.chaincode,
                this.type == 'priv' ? [0].concat(this.key.export('bytes').slice(0,32))
                                    : this.key)
    var checksum = Crypto.SHA256(Crypto.SHA256(bytes,{asBytes: true}), {asBytes: true})
                         .slice(0,4)
    return base58.encode(bytes.concat(checksum))
}

BIP32key.prototype.ckd = function(i) {
    var priv, pub, newkey, fingerprint, blob, I;
    if (this.type == 'priv') {
        priv = this.key.export('bytes')
        pub = this.key.getPub()
    }
    else pub = this.key

    if (i >= 2147483648) {
        if (this.priv) throw new Error("Can't do private derivation on public key!")
        blob = [0].concat(priv.slice(0,32),util.numToBytes(i,4).reverse())
    }
    else blob = pub.concat(util.numToBytes(i,4).reverse())

    I = Crypto.HMAC(Crypto.SHA512,blob,this.chaincode,{ asBytes: true })

    if (this.type == 'priv') {
        Ikey = Bitcoin.BigInteger.fromByteArrayUnsigned(I.slice(0,32))
        newkey = new key(this.key.priv.add(Ikey).mod(ecparams.getN()))
        newkey.compressed = true
        fingerprint = util.sha256ripe160(this.key.getPub()).slice(0,4)
    }
    else {
        newkey = ECPointFp.decodeFrom(ecparams.getCurve(),this.key)
                          .add(new key(I.slice(0,32).concat([1])).getPubPoint())
                          .getEncoded(true);
        fingerprint = util.sha256ripe160(this.key).slice(0,4)
    }
    return new BIP32key({
        vbytes: this.vbytes,
        type: this.type,
        depth: this.depth + 1,
        fingerprint: fingerprint,
        i: i,
        chaincode: I.slice(32),
        key: newkey
    })
}

BIP32key.prototype.clone = function() {
    return new BIP32key(this);
}

BIP32key.prototype.privtopub = BIP32key.prototype.getPub = function() {
    if (this.type == 'pub') return this.clone()
    return new BIP32key({
        vbytes: conv.stringToBytes(PUBDERIV),
        type: 'pub',
        depth: this.depth,
        fingerprint: this.fingerprint,
        i: this.i,
        chaincode: this.chaincode,
        key: this.key.getPub()
    })
}

BIP32key.prototype.fromMasterKey = function(seed) {
    var I = Bitcoin.Crypto.HMAC(Bitcoin.Crypto.SHA512,seed,"Bitcoin seed",{ asBytes: true })
    return new BIP32key({
        vbytes: conv.stringToBytes(PRIVDERIV),
        type: 'priv',
        depth: 0,
        fingerprint: [0,0,0,0],
        i: 0,
        chaincode: I.slice(32),
        key: new key(I.slice(0,32).concat([1]))
    })
}

BIP32key.prototype.getKey = function() { return this.key }

module.exports = BIP32key;
<|endoftext|>


<commit_before>import React, { Component } from 'react';

const styles = {
  allPadding: {
    margin: '1rem 10px',
  },
};

function drawTitle({ ctx, x, y, nextLineOffset, fontSize }, year, month) {
  ctx.fillStyle = '#000';
  const previousFont = ctx.font.replace(/"/g, '');

  ctx.font = `${previousFont} Bold`;
  ctx.fillText('Financial Update', x, y);

  ctx.font = previousFont;
  const fiscalString = `Fiscal YTD - ${month} ${year}`;
  const fiscalStringWidth = ctx.measureText(fiscalString).width;
  ctx.fillText(fiscalString, x, y + nextLineOffset);

  return {
    x,
    y: y + nextLineOffset,
    fiscalStringWidth,
  };
}

function calculateNumSpacing(ctx, giving, budget) {
  const numsChars = '$1234567890,.';
  const numCharWidths = numsChars.split('').reduce((result, item) => {
    result[item] = ctx.measureText(item).width;
    return result;
  }, {});

  const longestNumWidth = Object.keys(numCharWidths).reduce((result, item) => {
    return result > numCharWidths[item] ? result : numCharWidths[item];
  }, 0);

  const calculateStrWidths = (result, figure, index) => {
    let width;
    if (figure === '$' || figure === ',' || figure === '.') {
      width = numCharWidths[figure];
    } else {
      width = longestNumWidth;
    }

    let offset = 0;
    if (index !== 0) {
      let previousFigure = result[index - 1].figure;
      let previousOffset = result[index - 1].offset;

      offset += previousOffset;
      if (
        previousFigure === '$' ||
        previousFigure === ',' ||
        previousFigure === '.'
      ) {
        offset += numCharWidths[previousFigure];
      } else {
        offset += longestNumWidth;
      }
    }

    return result.concat({
      figure,
      offset,
      width,
    });
  };

  const givingStr = `$${giving.toLocaleString()}`;
  const givingStrWidths = givingStr.split('').reduce(calculateStrWidths, []);
  const givingStrTotalWidth = givingStrWidths.reduce((result, item) => {
    return result + item.width;
  }, 0);

  const budgetStr = `$${budget.toLocaleString()}`;
  const budgetStrWidths = budgetStr.split('').reduce(calculateStrWidths, []);
  const budgetStrTotalWidth = budgetStrWidths.reduce((result, item) => {
    return result + item.width;
  }, 0);

  return {
    numCharWidths,
    longestNumWidth,
    givingStrWidths,
    budgetStrWidths,
    givingStrTotalWidth,
    budgetStrTotalWidth,
  };
}

// function drawTabularFigures(
//   { ctx, x, givingBoxTextY, budgetBoxTextY },
//   giving,
//   budget,
// ) {
//   const {
//     longestNumWidth,
//     numCharWidths,
//     givingStrWidths,
//     budgetStrWidths,
//     givingStrTotalWidth,
//     budgetStrTotalWidth,
//   } = calculateNumSpacing(ctx, giving, budget);

//   ctx.fillStyle = '#000';

//   const drawFigureWithSpacing = (item, xOffset, yOffset) => {
//     let charOffset = 0;
//     if (item.figure !== '$' && item.figure !== ',' && item.figure !== '.') {
//       charOffset = (longestNumWidth - numCharWidths[item.figure]) / 2;
//     }

//     const totalOffset = xOffset + x + item.offset + charOffset;
//     ctx.fillText(item.figure, totalOffset, yOffset);
//   };

//   // Draw Giving String //
//   // Adjust xOffset to line up budget and giving lines
//   givingStrWidths.forEach(item => {
//     let xOffset;
//     if (givingStrTotalWidth < budgetStrTotalWidth) {
//       xOffset = budgetStrTotalWidth - givingStrTotalWidth;
//     } else {
//       xOffset = 0;
//     }

//     drawFigureWithSpacing(item, xOffset, givingBoxTextY);
//   });

//   // Draw Budget String //
//   // Adjust xOffset to line up budget and giving lines
//   budgetStrWidths.forEach(item => {
//     let xOffset;
//     if (budgetStrTotalWidth < givingStrTotalWidth) {
//       xOffset = givingStrTotalWidth - budgetStrTotalWidth;
//     } else {
//       xOffset = 0;
//     }

//     drawFigureWithSpacing(item, xOffset, budgetBoxTextY);
//   });
// }

function drawGraphs(
  { ctx, x, y, nextLineOffset },
  giving,
  budget,
  maxBoxWidth,
) {
  const barHeight = 40;
  const barSpacing = 5;

  const givingRatio = giving / budget;
  const shortfall = budget - giving;

  // Giving Bar
  let givingBarWidth = giving / budget * maxBoxWidth;

  // Always show a little Giving Bar
  if (givingRatio < 0.01) {
    givingBarWidth = barSpacing;
  }

  ctx.lineWidth = 2;
  ctx.strokeStyle = '#000';
  if (shortfall > 0) {
    ctx.strokeRect(x, y, givingBarWidth, barHeight);
  } else {
    const overhang = 10;
    ctx.strokeRect(x, y, maxBoxWidth + overhang, barHeight);
  }

  // Shortfall Bar
  const shortfallBarX = x + barSpacing + givingBarWidth;
  const shortfallBarWidth = maxBoxWidth - givingBarWidth - barSpacing;

  if (shortfall > 0) {
    ctx.fillStyle = '#000';
    ctx.fillRect(shortfallBarX, y, shortfallBarWidth, barHeight);
  }

  // Bottom Bar
  const bottomBarY = y + barHeight + barSpacing;
  ctx.fillStyle = '#000';
  ctx.fillRect(x, bottomBarY, maxBoxWidth, barHeight);

  const graphTickWidth = 3;
  const cutHeight = barHeight / 2 - barSpacing / 2;
  const bottomCutY = bottomBarY + barHeight - cutHeight;
  const leftCutX = x + graphTickWidth;

  // Draw cuts in bottom bar
  if (shortfall > 0) {
    const middleGraphTickSpacing = (barSpacing - graphTickWidth) / 2;

    // 1. Giving Bar Cuts
    const leftCutWidth =
      givingBarWidth - graphTickWidth + middleGraphTickSpacing;

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomBarY, leftCutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomCutY, leftCutWidth, cutHeight);

    // 2. Shortfall Bar Cuts
    const rightCutX = leftCutX + leftCutWidth + graphTickWidth;
    const rightCutWidth =
      shortfallBarWidth - graphTickWidth + middleGraphTickSpacing;

    ctx.fillStyle = '#FFF';
    ctx.fillRect(rightCutX, bottomBarY, rightCutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(rightCutX, bottomCutY, rightCutWidth, cutHeight);
  } else {
    const cutWidth = maxBoxWidth - graphTickWidth * 2;
    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomBarY, cutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomCutY, cutWidth, cutHeight);
  }
}

function drawCanvas({ ctx }, props, maxBoxWidth, graphMargins, font) {
  const { width, height } = ctx.canvas;
  const { year, month, giving, budget } = props;

  ctx.clearRect(0, 0, width, height);

  const fontSize = font.size;
  const elementSpacing = 12;

  ctx.font = `${fontSize}px ${font.family}`;

  const titleFinish = drawTitle(
    {
      ctx,
      x: graphMargins,
      y: fontSize,
      nextLineOffset: fontSize + 3,
      fontSize,
    },
    year,
    month,
  );

  drawGraphs(
    {
      ctx,
      x: graphMargins,
      y: titleFinish.y + elementSpacing * 3,
    },
    giving,
    budget,
    titleFinish.fiscalStringWidth,
  );
}

function expectedGraphWidth(props, maxBoxWidth, graphMargins, font, scale) {
  const { year, month, giving, budget } = props;
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.font = `${font.size}px ${font.family}`;

  const boxEndSpacing = graphMargins * 2.5;
  const boxWidth = graphMargins + maxBoxWidth + boxEndSpacing;

  const { givingStrTotalWidth, budgetStrTotalWidth } = calculateNumSpacing(
    ctx,
    giving,
    budget,
  );

  const letterWidth = Math.max(givingStrTotalWidth, budgetStrTotalWidth);

  const title = `Fiscal YTD - ${month} ${year}`;
  const titleWidth = ctx.measureText(title).width + graphMargins * 2;

  return (
    Math.max(boxWidth + letterWidth, titleWidth) / (scale != null ? scale : 1)
  );
}

class GivingChart extends Component {
  font = {
    size: 48,
    family: 'Quattrocento Sans',
  };
  maxBoxWidth = 380;
  graphMargins = 20;
  height = 173;

  getImageData() {
    const canvas = this.refs.canvas;
    return canvas.toDataURL('image/png');
  }

  componentDidMount() {
    this.updateCanvas();
  }

  componentDidUpdate() {
    this.updateCanvas();
  }

  updateCanvas() {
    const { props, maxBoxWidth, graphMargins, font } = this;

    const ctx = this.refs.canvas.getContext('2d');
    drawCanvas(
      {
        ctx,
      },
      props,
      maxBoxWidth,
      graphMargins,
      font,
    );
  }

  render() {
    const { props, maxBoxWidth, graphMargins, font, height } = this;

    const scale = 2;
    const ppi = 300;

    const width = expectedGraphWidth(
      props,
      maxBoxWidth,
      graphMargins,
      font,
      scale,
    );

    // parseFloat to drop the extra 0's
    const widthPrint = parseFloat((width * scale / ppi).toFixed(2));
    const heightPrint = parseFloat((height * scale / ppi).toFixed(2));

    return (

        <canvas
          ref="canvas"
          style={{
            width,
            height,
          }}
          width={width * scale}
          height={height * scale}
        />

          {`Note: Chart is meant to be ${widthPrint}″ wide by ${heightPrint}″ high in print`}

    );
  }
}

export default GivingChart;
<commit_msg>Draw 100% giving plus mark<commit_after>import React, { Component } from 'react';

const styles = {
  allPadding: {
    margin: '1rem 10px',
  },
};

function drawTitle({ ctx, x, y, nextLineOffset, fontSize }, year, month) {
  ctx.fillStyle = '#000';
  const previousFont = ctx.font.replace(/"/g, '');

  ctx.font = `${previousFont} Bold`;
  ctx.fillText('Financial Update', x, y);

  ctx.font = previousFont;
  const fiscalString = `Fiscal YTD - ${month} ${year}`;
  const fiscalStringWidth = ctx.measureText(fiscalString).width;
  ctx.fillText(fiscalString, x, y + nextLineOffset);

  return {
    x,
    y: y + nextLineOffset,
    fiscalStringWidth,
  };
}

function calculateNumSpacing(ctx, giving, budget) {
  const numsChars = '$1234567890,.';
  const numCharWidths = numsChars.split('').reduce((result, item) => {
    result[item] = ctx.measureText(item).width;
    return result;
  }, {});

  const longestNumWidth = Object.keys(numCharWidths).reduce((result, item) => {
    return result > numCharWidths[item] ? result : numCharWidths[item];
  }, 0);

  const calculateStrWidths = (result, figure, index) => {
    let width;
    if (figure === '$' || figure === ',' || figure === '.') {
      width = numCharWidths[figure];
    } else {
      width = longestNumWidth;
    }

    let offset = 0;
    if (index !== 0) {
      let previousFigure = result[index - 1].figure;
      let previousOffset = result[index - 1].offset;

      offset += previousOffset;
      if (
        previousFigure === '$' ||
        previousFigure === ',' ||
        previousFigure === '.'
      ) {
        offset += numCharWidths[previousFigure];
      } else {
        offset += longestNumWidth;
      }
    }

    return result.concat({
      figure,
      offset,
      width,
    });
  };

  const givingStr = `$${giving.toLocaleString()}`;
  const givingStrWidths = givingStr.split('').reduce(calculateStrWidths, []);
  const givingStrTotalWidth = givingStrWidths.reduce((result, item) => {
    return result + item.width;
  }, 0);

  const budgetStr = `$${budget.toLocaleString()}`;
  const budgetStrWidths = budgetStr.split('').reduce(calculateStrWidths, []);
  const budgetStrTotalWidth = budgetStrWidths.reduce((result, item) => {
    return result + item.width;
  }, 0);

  return {
    numCharWidths,
    longestNumWidth,
    givingStrWidths,
    budgetStrWidths,
    givingStrTotalWidth,
    budgetStrTotalWidth,
  };
}

// function drawTabularFigures(
//   { ctx, x, givingBoxTextY, budgetBoxTextY },
//   giving,
//   budget,
// ) {
//   const {
//     longestNumWidth,
//     numCharWidths,
//     givingStrWidths,
//     budgetStrWidths,
//     givingStrTotalWidth,
//     budgetStrTotalWidth,
//   } = calculateNumSpacing(ctx, giving, budget);

//   ctx.fillStyle = '#000';

//   const drawFigureWithSpacing = (item, xOffset, yOffset) => {
//     let charOffset = 0;
//     if (item.figure !== '$' && item.figure !== ',' && item.figure !== '.') {
//       charOffset = (longestNumWidth - numCharWidths[item.figure]) / 2;
//     }

//     const totalOffset = xOffset + x + item.offset + charOffset;
//     ctx.fillText(item.figure, totalOffset, yOffset);
//   };

//   // Draw Giving String //
//   // Adjust xOffset to line up budget and giving lines
//   givingStrWidths.forEach(item => {
//     let xOffset;
//     if (givingStrTotalWidth < budgetStrTotalWidth) {
//       xOffset = budgetStrTotalWidth - givingStrTotalWidth;
//     } else {
//       xOffset = 0;
//     }

//     drawFigureWithSpacing(item, xOffset, givingBoxTextY);
//   });

//   // Draw Budget String //
//   // Adjust xOffset to line up budget and giving lines
//   budgetStrWidths.forEach(item => {
//     let xOffset;
//     if (budgetStrTotalWidth < givingStrTotalWidth) {
//       xOffset = givingStrTotalWidth - budgetStrTotalWidth;
//     } else {
//       xOffset = 0;
//     }

//     drawFigureWithSpacing(item, xOffset, budgetBoxTextY);
//   });
// }

function drawGraphs(
  { ctx, x, y, nextLineOffset, fontSize },
  giving,
  budget,
  maxBoxWidth,
) {
  const barHeight = 40;
  const barSpacing = 5;

  const givingRatio = giving / budget;
  const shortfall = budget - giving;

  // Giving Bar
  let givingBarWidth = giving / budget * maxBoxWidth;

  // Always show a little Giving Bar
  if (givingRatio < 0.01) {
    givingBarWidth = barSpacing;
  }

  ctx.lineWidth = 2;
  ctx.strokeStyle = '#000';
  if (shortfall > 0) {
    ctx.strokeRect(x, y, givingBarWidth, barHeight);
  } else {
    const overhang = 10;
    ctx.strokeRect(x, y, maxBoxWidth + overhang, barHeight);

    const overPlusTextX = x + maxBoxWidth + overhang + barSpacing;
    // Divided by 4 because font is 2x scaled
    const overPlusTextY = y + barHeight / 2 + fontSize / 4;

    ctx.fontSize = fontSize;
    ctx.fillStyle = '#000';
    ctx.fillText('+', overPlusTextX, overPlusTextY);
  }

  // Shortfall Bar
  const shortfallBarX = x + barSpacing + givingBarWidth;
  const shortfallBarWidth = maxBoxWidth - givingBarWidth - barSpacing;

  if (shortfall > 0) {
    ctx.fillStyle = '#000';
    ctx.fillRect(shortfallBarX, y, shortfallBarWidth, barHeight);
  }

  // Bottom Bar
  const bottomBarY = y + barHeight + barSpacing;
  ctx.fillStyle = '#000';
  ctx.fillRect(x, bottomBarY, maxBoxWidth, barHeight);

  const graphTickWidth = 3;
  const cutHeight = barHeight / 2 - barSpacing / 2;
  const bottomCutY = bottomBarY + barHeight - cutHeight;
  const leftCutX = x + graphTickWidth;

  // Draw cuts in bottom bar
  if (shortfall > 0) {
    const middleGraphTickSpacing = (barSpacing - graphTickWidth) / 2;

    // 1. Giving Bar Cuts
    const leftCutWidth =
      givingBarWidth - graphTickWidth + middleGraphTickSpacing;

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomBarY, leftCutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomCutY, leftCutWidth, cutHeight);

    // 2. Shortfall Bar Cuts
    const rightCutX = leftCutX + leftCutWidth + graphTickWidth;
    const rightCutWidth =
      shortfallBarWidth - graphTickWidth + middleGraphTickSpacing;

    ctx.fillStyle = '#FFF';
    ctx.fillRect(rightCutX, bottomBarY, rightCutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(rightCutX, bottomCutY, rightCutWidth, cutHeight);
  } else {
    const cutWidth = maxBoxWidth - graphTickWidth * 2;
    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomBarY, cutWidth, cutHeight);

    ctx.fillStyle = '#FFF';
    ctx.fillRect(leftCutX, bottomCutY, cutWidth, cutHeight);
  }
}

function drawCanvas({ ctx }, props, maxBoxWidth, graphMargins, font) {
  const { width, height } = ctx.canvas;
  const { year, month, giving, budget } = props;

  ctx.clearRect(0, 0, width, height);

  const fontSize = font.size;
  const elementSpacing = 12;

  ctx.font = `${fontSize}px ${font.family}`;

  const titleFinish = drawTitle(
    {
      ctx,
      x: graphMargins,
      y: fontSize,
      nextLineOffset: fontSize + 3,
      fontSize,
    },
    year,
    month,
  );

  drawGraphs(
    {
      ctx,
      x: graphMargins,
      y: titleFinish.y + elementSpacing * 3,
      fontSize,
    },
    giving,
    budget,
    titleFinish.fiscalStringWidth,
  );
}

function expectedGraphWidth(props, maxBoxWidth, graphMargins, font, scale) {
  const { year, month, giving, budget } = props;
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.font = `${font.size}px ${font.family}`;

  const boxEndSpacing = graphMargins * 2.5;
  const boxWidth = graphMargins + maxBoxWidth + boxEndSpacing;

  const { givingStrTotalWidth, budgetStrTotalWidth } = calculateNumSpacing(
    ctx,
    giving,
    budget,
  );

  const letterWidth = Math.max(givingStrTotalWidth, budgetStrTotalWidth);

  const title = `Fiscal YTD - ${month} ${year}`;
  const titleWidth = ctx.measureText(title).width + graphMargins * 2;

  return (
    Math.max(boxWidth + letterWidth, titleWidth) / (scale != null ? scale : 1)
  );
}

class GivingChart extends Component {
  font = {
    size: 48,
    family: 'Quattrocento Sans',
  };
  maxBoxWidth = 380;
  graphMargins = 20;
  height = 173;

  getImageData() {
    const canvas = this.refs.canvas;
    return canvas.toDataURL('image/png');
  }

  componentDidMount() {
    this.updateCanvas();
  }

  componentDidUpdate() {
    this.updateCanvas();
  }

  updateCanvas() {
    const { props, maxBoxWidth, graphMargins, font } = this;

    const ctx = this.refs.canvas.getContext('2d');
    drawCanvas(
      {
        ctx,
      },
      props,
      maxBoxWidth,
      graphMargins,
      font,
    );
  }

  render() {
    const { props, maxBoxWidth, graphMargins, font, height } = this;

    const scale = 2;
    const ppi = 300;

    const width = expectedGraphWidth(
      props,
      maxBoxWidth,
      graphMargins,
      font,
      scale,
    );

    // parseFloat to drop the extra 0's
    const widthPrint = parseFloat((width * scale / ppi).toFixed(2));
    const heightPrint = parseFloat((height * scale / ppi).toFixed(2));

    return (

        <canvas
          ref="canvas"
          style={{
            width,
            height,
          }}
          width={width * scale}
          height={height * scale}
        />

          {`Note: Chart is meant to be ${widthPrint}″ wide by ${heightPrint}″ high in print`}

    );
  }
}

export default GivingChart;
<|endoftext|>


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

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

import TriggerPop from '../_TriggerPop';

import Position from '../_statics/Position';
import MsgType from '../_statics/MsgType';

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

class Guide extends Component {

    static Position = Position;
    static Type = MsgType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.guide && this.refs.guide.resetPosition();
    };

    getIconCls = () => {
        switch (this.props.type) {
            case MsgType.SUCCESS:
                return 'fas fa-check-circle';
            case MsgType.WARNING:
                return 'fas fa-exclamation-triangle';
            case MsgType.ERROR:
                return 'fas fa-times-circle';
            default:
                return 'fas fa-info-circle';
        }
    };

    componentDidUpdate() {

        const {visible, isEscClose} = this.props;

        if (isEscClose && visible) {
            PopManagement.push(this);
        }

    }

    componentWillUnmount() {
        PopManagement.pop(this);
    }

    render() {

        const {

                className, contentClassName, type, iconVisible, iconCls, closeButtonVisible, closeButtonValue,
                children, onRequestClose,

                ...restProps

            } = this.props,

            guideClassName = classNames('guide', {
                'icon-hidden': !iconVisible,
                [className]: className
            }),

            guideContentClassName = classNames('guide-content', {
                'theme-default': type === MsgType.DEFAULT,
                [`theme-${type}`]: type !== MsgType.DEFAULT,
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="guide"
                        className={guideClassName}
                        contentClassName={guideContentClassName}>

                {
                    !iconVisible || type === MsgType.DEFAULT ?
                        null
                        :

                }

                    {children}

                    {
                        closeButtonVisible ?
                            <AnchorButton className="guide-close-Button"
                                          value={closeButtonValue}
                                          onClick={onRequestClose}/>
                            :
                            null
                    }

            </TriggerPop>
        );
    }

}

Guide.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The type of notification.
     */
    type: PropTypes.oneOf(Util.enumerateValue(MsgType)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The guide alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    iconVisible: PropTypes.bool,
    iconCls: PropTypes.string,

    /**
     * If true,guide will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    showModal: PropTypes.bool,

    closeButtonVisible: PropTypes.bool,
    closeButtonValue: PropTypes.string,

    /**
     * The function of guide render.
     */
    onRender: PropTypes.func,

    /**
     * The function of guide rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of guide destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of guide destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Guide.defaultProps = {

    type: MsgType.INFO,
    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    iconVisible: false,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    showModal: false,

    closeButtonVisible: true,
    closeButtonValue: 'Close'

};

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

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

import TriggerPop from '../_TriggerPop';

import Position from '../_statics/Position';
import MsgType from '../_statics/MsgType';

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

class Guide extends Component {

    static Position = Position;
    static Type = MsgType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.guide && this.refs.guide.resetPosition();
    };

    getIconCls = () => {
        switch (this.props.type) {
            case MsgType.SUCCESS:
                return 'fas fa-check-circle';
            case MsgType.WARNING:
                return 'fas fa-exclamation-triangle';
            case MsgType.ERROR:
                return 'fas fa-times-circle';
            default:
                return 'fas fa-info-circle';
        }
    };

    componentDidUpdate() {

        const {visible, isEscClose} = this.props;

        if (isEscClose && visible) {
            PopManagement.push(this);
        }

    }

    componentWillUnmount() {
        PopManagement.pop(this);
    }

    render() {

        const {

                className, contentClassName, type, iconVisible, iconCls, closeButtonVisible, closeButtonValue,
                children, onRequestClose,

                ...restProps

            } = this.props,

            guideClassName = classNames('guide', {
                'icon-hidden': !iconVisible,
                [className]: className
            }),

            guideContentClassName = classNames('guide-content', {
                'theme-default': type === MsgType.DEFAULT,
                [`theme-${type}`]: type !== MsgType.DEFAULT,
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="guide"
                        className={guideClassName}
                        contentClassName={guideContentClassName}>

                {
                    !iconVisible || type === MsgType.DEFAULT ?
                        null
                        :

                }

                    {children}

                    {
                        closeButtonVisible ?
                            <AnchorButton className="guide-close-Button"
                                          value={closeButtonValue}
                                          onClick={onRequestClose}/>
                            :
                            null
                    }

            </TriggerPop>
        );
    }

}

Guide.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The type of notification.
     */
    type: PropTypes.oneOf(Util.enumerateValue(MsgType)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The guide alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    iconVisible: PropTypes.bool,
    iconCls: PropTypes.string,

    /**
     * If true,guide will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    showModal: PropTypes.bool,

    closeButtonVisible: PropTypes.bool,
    closeButtonValue: PropTypes.string,

    /**
     * The function of guide render.
     */
    onRender: PropTypes.func,

    /**
     * The function of guide rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of guide destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of guide destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Guide.defaultProps = {

    type: MsgType.INFO,
    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    iconVisible: true,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    showModal: false,

    closeButtonVisible: true,
    closeButtonValue: 'Close'

};

export default Guide;<|endoftext|>


<commit_before>// @flow weak

import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';
import { easing } from '../styles/transitions';

function isDirty(obj) {
  return obj && obj.value && obj.value.length > 0;
}

export const styleSheet = createStyleSheet('Input', (theme) => {
  return {
    wrapper: {
      display: 'flex',
      position: 'relative',
    },
    formControl: {
      marginTop: 10,
      marginBottom: 10,
    },
    inkbar: {
      '&:after': {
        backgroundColor: theme.palette.accent.A200,
        left: 0,
        bottom: -1,
        // Doing the other way around crash on IE11 "''"" https://github.com/cssinjs/jss/issues/242
        content: '""',
        height: 2,
        position: 'absolute',
        width: '100%',
        transform: 'scaleX(0)',
        transition: theme.transitions.create(
          'transform',
          '200ms',
          null,
          easing.easeOut,
        ),
      },
      '&$focused:after': {
        transform: 'scaleX(1)',
      },
    },
    focused: {},
    error: {
      '&:after': {
        backgroundColor: theme.palette.error[500],
        transform: 'scaleX(1)', // error is always underlined in red
      },
    },
    input: {
      font: 'inherit',
      padding: '6px 0',
      border: 0,
      display: 'block',
      verticalAlign: 'middle',
      whiteSpace: 'normal',
      background: 'none',
      lineHeight: 1,
      appearance: 'textfield', // Improve type search style.
      color: theme.palette.text.primary,
      '&:focus': {
        outline: 0,
      },
      '&::-webkit-search-decoration': { // Remove the padding when type=search.
        appearance: 'none',
      },
    },
    disabled: {
      color: theme.palette.text.disabled,
      cursor: 'not-allowed',
    },
    underline: {
      borderBottom: `1px solid ${theme.palette.text.divider}`,
      '&$disabled': {
        borderBottomStyle: 'dotted',
      },
    },
  };
});

/**
 * Input
 */
export default class Input extends Component {
  static propTypes = {
    /**
     * The CSS class name of the wrapper element.
     */
    className: PropTypes.string,
    /**
     * The element or component used for the root node.
     */
    component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    disabled: PropTypes.bool,
    error: PropTypes.bool,
    /**
     * The CSS class name of the input element.
     */
    inputClassName: PropTypes.string,
    /**
     * @ignore
     */
    onBlur: PropTypes.func,
    /**
     * @ignore
     */
    onChange: PropTypes.func,
    /**
     * @ignore
     */
    onClean: PropTypes.func,
    /**
     * @ignore
     */
    onDirty: PropTypes.func,
    /**
     * @ignore
     */
    onFocus: PropTypes.func,
    /**
     * Input type.
     */
    type: PropTypes.string,
    /**
     * If set to true, the input will have an underline.
     */
    underline: PropTypes.bool,
    /**
     * The input value, required for a controlled component.
     */
    value: PropTypes.string,
  };

  static defaultProps = {
    component: 'input',
    disabled: false,
    type: 'text',
    underline: true,
  };

  static contextTypes = {
    muiFormControl: PropTypes.object,
    styleManager: customPropTypes.muiRequired,
  };

  state = {
    focused: false,
  };

  componentWillMount() {
    if (this.isControlled()) {
      this.checkDirty(this.props);
    }
  }

  componentDidMount() {
    if (!this.isControlled()) {
      this.checkDirty(this.input);
    }
  }

  componentWillUpdate(nextProps) {
    if (this.isControlled()) {
      this.checkDirty(nextProps);
    }
  }

  // Holds the input reference
  input = null;

  focus = () => this.input.focus();

  handleFocus = (event) => {
    this.setState({ focused: true });
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  };

  handleBlur = (event) => {
    this.setState({ focused: false });
    if (this.props.onBlur) {
      this.props.onBlur(event);
    }
  };

  handleChange = (event) => {
    if (!this.isControlled()) {
      this.checkDirty(this.input);
    }
    if (this.props.onChange) {
      this.props.onChange(event);
    }
  };

  isControlled() {
    return typeof this.props.value === 'string';
  }

  checkDirty(obj) {
    const { muiFormControl } = this.context;

    if (isDirty(obj)) {
      if (muiFormControl && muiFormControl.onDirty) {
        muiFormControl.onDirty();
      }
      if (this.props.onDirty) {
        this.props.onDirty();
      }
      return;
    }

    if (muiFormControl && muiFormControl.onClean) {
      muiFormControl.onClean();
    }
    if (this.props.onClean) {
      this.props.onClean();
    }
  }

  render() {
    const {
      className: classNameProp,
      component: ComponentProp,
      inputClassName: inputClassNameProp,
      disabled,
      error: errorProp,
      onBlur, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      onChange, // eslint-disable-line no-unused-vars
      underline,
      ...other
    } = this.props;

    const { muiFormControl, styleManager } = this.context;
    const classes = styleManager.render(styleSheet);

    let error = errorProp;

    if (typeof error === 'undefined' && muiFormControl) {
      error = muiFormControl.error;
    }

    const wrapperClassName = classNames(classes.wrapper, {
      [classes.formControl]: muiFormControl,
      [classes.inkbar]: underline,
      [classes.focused]: this.state.focused,
      [classes.error]: error,
    }, classNameProp);

    const inputClassName = classNames(classes.input, {
      [classes.underline]: underline,
      [classes.disabled]: disabled,
    }, inputClassNameProp);

    const required = muiFormControl && muiFormControl.required === true;

    return (

        <ComponentProp
          ref={(c) => { this.input = c; }}
          className={inputClassName}
          onBlur={this.handleBlur}
          onFocus={this.handleFocus}
          onChange={this.handleChange}
          disabled={disabled}
          aria-required={required ? true : undefined}
          {...other}
        />

    );
  }
}
<commit_msg>Allow input to accept a string or a number<commit_after>// @flow weak

import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';
import { easing } from '../styles/transitions';

function isDirty(obj) {
  return obj && obj.value && obj.value.length > 0;
}

export const styleSheet = createStyleSheet('Input', (theme) => {
  return {
    wrapper: {
      display: 'flex',
      position: 'relative',
    },
    formControl: {
      marginTop: 10,
      marginBottom: 10,
    },
    inkbar: {
      '&:after': {
        backgroundColor: theme.palette.accent.A200,
        left: 0,
        bottom: -1,
        // Doing the other way around crash on IE11 "''"" https://github.com/cssinjs/jss/issues/242
        content: '""',
        height: 2,
        position: 'absolute',
        width: '100%',
        transform: 'scaleX(0)',
        transition: theme.transitions.create(
          'transform',
          '200ms',
          null,
          easing.easeOut,
        ),
      },
      '&$focused:after': {
        transform: 'scaleX(1)',
      },
    },
    focused: {},
    error: {
      '&:after': {
        backgroundColor: theme.palette.error[500],
        transform: 'scaleX(1)', // error is always underlined in red
      },
    },
    input: {
      font: 'inherit',
      padding: '6px 0',
      border: 0,
      display: 'block',
      verticalAlign: 'middle',
      whiteSpace: 'normal',
      background: 'none',
      lineHeight: 1,
      appearance: 'textfield', // Improve type search style.
      color: theme.palette.text.primary,
      '&:focus': {
        outline: 0,
      },
      '&::-webkit-search-decoration': { // Remove the padding when type=search.
        appearance: 'none',
      },
    },
    disabled: {
      color: theme.palette.text.disabled,
      cursor: 'not-allowed',
    },
    underline: {
      borderBottom: `1px solid ${theme.palette.text.divider}`,
      '&$disabled': {
        borderBottomStyle: 'dotted',
      },
    },
  };
});

/**
 * Input
 */
export default class Input extends Component {
  static propTypes = {
    /**
     * The CSS class name of the wrapper element.
     */
    className: PropTypes.string,
    /**
     * The element or component used for the root node.
     */
    component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    disabled: PropTypes.bool,
    error: PropTypes.bool,
    /**
     * The CSS class name of the input element.
     */
    inputClassName: PropTypes.string,
    /**
     * @ignore
     */
    onBlur: PropTypes.func,
    /**
     * @ignore
     */
    onChange: PropTypes.func,
    /**
     * @ignore
     */
    onClean: PropTypes.func,
    /**
     * @ignore
     */
    onDirty: PropTypes.func,
    /**
     * @ignore
     */
    onFocus: PropTypes.func,
    /**
     * Input type.
     */
    type: PropTypes.string,
    /**
     * If set to true, the input will have an underline.
     */
    underline: PropTypes.bool,
    /**
     * The input value, required for a controlled component.
     */
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  };

  static defaultProps = {
    component: 'input',
    disabled: false,
    type: 'text',
    underline: true,
  };

  static contextTypes = {
    muiFormControl: PropTypes.object,
    styleManager: customPropTypes.muiRequired,
  };

  state = {
    focused: false,
  };

  componentWillMount() {
    if (this.isControlled()) {
      this.checkDirty(this.props);
    }
  }

  componentDidMount() {
    if (!this.isControlled()) {
      this.checkDirty(this.input);
    }
  }

  componentWillUpdate(nextProps) {
    if (this.isControlled()) {
      this.checkDirty(nextProps);
    }
  }

  // Holds the input reference
  input = null;

  focus = () => this.input.focus();

  handleFocus = (event) => {
    this.setState({ focused: true });
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  };

  handleBlur = (event) => {
    this.setState({ focused: false });
    if (this.props.onBlur) {
      this.props.onBlur(event);
    }
  };

  handleChange = (event) => {
    if (!this.isControlled()) {
      this.checkDirty(this.input);
    }
    if (this.props.onChange) {
      this.props.onChange(event);
    }
  };

  isControlled() {
    return typeof this.props.value === 'string';
  }

  checkDirty(obj) {
    const { muiFormControl } = this.context;

    if (isDirty(obj)) {
      if (muiFormControl && muiFormControl.onDirty) {
        muiFormControl.onDirty();
      }
      if (this.props.onDirty) {
        this.props.onDirty();
      }
      return;
    }

    if (muiFormControl && muiFormControl.onClean) {
      muiFormControl.onClean();
    }
    if (this.props.onClean) {
      this.props.onClean();
    }
  }

  render() {
    const {
      className: classNameProp,
      component: ComponentProp,
      inputClassName: inputClassNameProp,
      disabled,
      error: errorProp,
      onBlur, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      onChange, // eslint-disable-line no-unused-vars
      underline,
      ...other
    } = this.props;

    const { muiFormControl, styleManager } = this.context;
    const classes = styleManager.render(styleSheet);

    let error = errorProp;

    if (typeof error === 'undefined' && muiFormControl) {
      error = muiFormControl.error;
    }

    const wrapperClassName = classNames(classes.wrapper, {
      [classes.formControl]: muiFormControl,
      [classes.inkbar]: underline,
      [classes.focused]: this.state.focused,
      [classes.error]: error,
    }, classNameProp);

    const inputClassName = classNames(classes.input, {
      [classes.underline]: underline,
      [classes.disabled]: disabled,
    }, inputClassNameProp);

    const required = muiFormControl && muiFormControl.required === true;

    return (

        <ComponentProp
          ref={(c) => { this.input = c; }}
          className={inputClassName}
          onBlur={this.handleBlur}
          onFocus={this.handleFocus}
          onChange={this.handleChange}
          disabled={disabled}
          aria-required={required ? true : undefined}
          {...other}
        />

    );
  }
}
<|endoftext|>


<commit_before>'use babel'

// Dependencies
const EmojiData = require('emoji-data-2016');
const CSON = require('cson');
const fs = require('fs');

// Variables & Constants
const meta = require('../package.json');
const outputDir = "snippets"
const emojiAll = EmojiData.all()
var snippets = {};

// Main
console.log(`${meta.name} v${meta.version}\nThe MIT License\n`)

fs.exists(outputDir, (exists) => {
  if (!exists) {
    console.log(`\u1F4AB ./${outputDir}`)
    fs.mkdirSync(outputDir)
  }
  writeSnippets("css", ".source.css, .source.sass", "content: '\\\\", "';");
  writeSnippets("html", ".text.html", "&#x");
  writeSnippets("javascript", ".source.js", "\\\\u");
  writeSnippets("ruby", ".source.ruby", "\\\\u{", "}");
});

// Functions
function writeSnippets(type, scope, prefix = "", suffix = "") {
    for (let i = 0; i < emojiAll.length; i++) {
        let name, unicode;

        if (typeof emojiAll[i].name != 'undefined' && emojiAll[i].name != null ) {
            name = emojiAll[i].name.toLowerCase().replace(/\s/g, "-");
        } else {
            name = emojiAll[i].short_name;
        }

        unicode = emojiAll[i].unified.replace(/-/g, prefix);
        emoji = emojiAll[i].render();

        snippets[emoji] = {
            "body": `${prefix}${unicode}${suffix}`,
            "prefix": `ji:${name}`
        };
    }

    let json = { }
    json[scope] = snippets;

    // Object to CSON
    output = CSON.stringify(json, null, 2);

    // Save file
    fs.writeFile(`${outputDir}/emoji-${type}.cson`, output, (err) => {
      if (err) throw err;
      console.log(`\u2705 emoji-${type}.cson`)
    });
}
<commit_msg>pass linter<commit_after>'use babel';

// Dependencies
const EmojiData = require('emoji-data-2016');
const CSON = require('cson');
const fs = require('fs');

// Variables & Constants
const meta = require('../package.json');
const outputDir = "snippets";
const emojiAll = EmojiData.all();
var snippets = {};

// Main
console.log(`${meta.name} v${meta.version}\nThe MIT License\n`);

fs.exists(outputDir, (exists) => {
  if (!exists) {
    console.log(`\u1F4AB ./${outputDir}`);
    fs.mkdirSync(outputDir);
  }
  writeSnippets("css", ".source.css, .source.sass", "content: '\\\\", "';");
  writeSnippets("html", ".text.html", "&#x");
  writeSnippets("javascript", ".source.js", "\\\\u");
  writeSnippets("ruby", ".source.ruby", "\\\\u{", "}");
});

// Functions
function writeSnippets(type, scope, prefix = "", suffix = "") {
    for (let i = 0; i < emojiAll.length; i++) {
        let name, unicode;

        if (typeof emojiAll[i].name != 'undefined' && emojiAll[i].name !== null ) {
            name = emojiAll[i].name.toLowerCase().replace(/\s/g, "-");
        } else {
            name = emojiAll[i].short_name;
        }

        unicode = emojiAll[i].unified.replace(/-/g, prefix);
        emoji = emojiAll[i].render();

        snippets[emoji] = {
            "body": `${prefix}${unicode}${suffix}`,
            "prefix": `ji:${name}`
        };
    }

    let json = {};
    json[scope] = snippets;

    // Object to CSON
    output = CSON.stringify(json, null, 2);

    // Save file
    fs.writeFile(`${outputDir}/emoji-${type}.cson`, output, (err) => {
      if (err) throw err;
      console.log(`\u2705 emoji-${type}.cson`);
    });
}
<|endoftext|>