<commit_before>/*!
 * jQuery onCreate plugin v1.2-dev
 * http://jquery.com/
 *
 * Copyright 2014 CROmetrics
 * Released under the MIT license
 * https://github.com/eclecto/jQuery-onCreate/blob/master/LICENSE
 *
 * Date: 2014-11-24T09:46Z
 */

/* jshint expr: true */
/* global jQuery, console, window, document, $, setInterval, clearInterval */

(function ($, MutationObserver, document, window) {
    // MutationObserver = false; // Test C/B fallbacks.
    // Check for the existence of jQuery.
    if (!$.fn.jquery) {
        window.console = window.console || {
            log: function () {},
            warn: function () {}
        };
        window.console.warn('jQuery is undefined. onCreate can not initialize.');
        return;
    }

    // Constants.
    var CREATE = 'create',
        MODIFY = 'modify';

    // Observer class.
    function Observer(mutcallback, type) {
        var realObserver;

        this.observe = function (element) {
            if (MutationObserver) {
                realObserver = realObserver || new MutationObserver(mutcallback);
                var init = (type === MODIFY ? {
                    attributes: true
                } : {
                    childList: true,
                    subtree: true
                });
                realObserver.observe(element, init);
            } else {
                realObserver = setInterval(mutcallback, 50);
            }
        };

        this.disconnect = function () {
            if (realObserver) {
                if (MutationObserver) {
                    realObserver.disconnect();
                } else {
                    clearInterval(realObserver);
                }
            }
        };
    }

    function debug() {
        if ($.onCreate.debug) {
            var warn = Function.prototype.bind.call(console.warn, console);
            warn.apply(console, arguments);
        }
    }

    // Create a map of an element's attributes so we can poll for changes (non-MutationObserver browsers)
    function attributeMap(element) {
        var map = {};

        if (element.attributes) {
            $.each(element.attributes, function (index, attr) {
                map[attr.name] = attr.value;
            });
        }

        return map;
    }

    var methods = {
        attach: function (options) {
            var type = options.type,
                callback = options.callback,
                multi = options.multi || false,
                selector = options.selector,
                watchedattrs = options.attrs ? options.attrs.split(' ') : null,
                match = options.match,
                mapCompare;
            // Get/initiate this element's callback data and the array of callbacks for the current selector.
            this.data('on' + type) || this.data('on' + type, {});
            var oc = this.data('on' + type);
            if (selector) {
                oc[selector] = oc[selector] || {
                    callbacks: []
                };
            } else {
                oc.callbacks = oc.callbacks || [];
                oc.ignore = false;
            }

            var current = selector ? oc[selector] : oc,
                cblist = current.callbacks,

                // Add the callback to the array of callbacks for the current selector.
                newcb = {
                    callback: callback,
                    multi: multi,
                    // Create a universally unique identifier for the current parent/child relationship.
                    uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                        var r = Math.random() * 16 | 0,
                            v = c == 'x' ? r : (r & 0x3 | 0x8);
                        return v.toString(16);
                    })
                };
            if (watchedattrs) newcb.attrs = watchedattrs;
            if (match) newcb.match = match;
            cblist.unshift(newcb);

            // Create an attribute map for non-MutationObserver browsers so we can track changes.
            if (type === MODIFY /*&& !MutationObserver*/ ) {
                oc.attributeMap = attributeMap(this[0]);

                mapCompare = function (map1, map2) {
                    var mutations = [];
                    $.each(map1, function (key, value) {
                        if (typeof (map2[key]) === 'undefined' || value !== map2[key]) {
                            mutations.push({
                                attributeName: key
                            });
                        }
                    });
                    $.each(map2, function (key, value) {
                        if (typeof (map1[key]) === 'undefined') {
                            mutations.push({
                                attributeName: key
                            });
                        }
                    });
                    return mutations;
                };
            }

            if (current.observer === undefined) {
                // Store `this` to a variable to use as a context
                var $this = this,
                    observer, i, attrmatch,
                    // This method filters out elements that have already been processed by the current callback.
                    filter = function (index, element) {
                        if ($(element).attr('data-oc-processed-' + cblist[i].uuid)) {
                            return false;
                        } else {
                            return true;
                        }
                    },
                    checkattrs = function (index, mutation) {
                        var attrname = mutation.attributeName,
                            attrval = $this.attr(attrname),
                            curMatch = cblist[i].match;
                        if (!cblist[i].attrs || cblist[i].attrs.indexOf(attrname) > -1) {
                            if (typeof (curMatch) !== 'undefined') {
                                if (attrval.search(curMatch) >= 0) {
                                    attrmatch = true;
                                    return false;
                                }
                            } else {
                                attrmatch = true;
                                return false;
                            }
                        }
                    },

                    // Define our callback for when a mutation is detected.
                    mutcallback = function (mutations) {
                        // For modify listeners we set an Ignore property, so if callbacks also modify attributes we don't risk creating an infinite loop.
                        if (type === MODIFY) {
                            if (!oc.ignore) {
                                oc.ignore = true;
                            } else {
                                return;
                            }
                        }

                        // Find elements that have not already been processed by this observer.
                        var selected = type === CREATE ? $(selector, $this) : $this;

                        if (selected.length > 0) {
                            for (i = cblist.length - 1; i >= 0; i--) {
                                var elements = type === CREATE ? selected.filter(filter) : selected;

                                // Validate changed attributes for modify observers.
                                if (type === MODIFY) {
                                    attrmatch = false;
                                    if (!MutationObserver) {
                                        var newmap = attributeMap($this[0]);
                                        mutations = mapCompare(newmap, oc.attributeMap);
                                    }
                                    $.each(mutations, checkattrs);
                                }

                                if (elements.length > 0 && (type === CREATE || attrmatch)) {
                                    if (type === CREATE || multi === false) elements.attr('data-oc-processed-' + cblist[i].uuid, true);
                                    cblist[i].callback.call($this, elements);
                                    // Remove callback from the list if it only runs once.
                                    if (!cblist[i].multi) {
                                        cblist.splice(i, 1);
                                    }
                                }
                            }
                        }

                        // We've safely iterated through the callbacks, so don't ignore this master callback anymore.
                        if (oc.ignore) oc.ignore = false;
                        if (cblist.length === 0) {
                            if (observer) {
                                observer.disconnect();
                            } else {
                                return true;
                            }
                        }
                    };
                // Sanity Check: If this is a create listener, run the callback on initialization to see if there is already a valid element.
                if (type === CREATE && mutcallback()) {
                    return this;
                }

                observer = current.observer = new Observer(mutcallback, type);
                observer.observe($this[0]);
            }
            return this;
        },
        detach: function (options) {
            var current, i,
                type = options.type,
                oc = this.data('on' + type),
                callback = options.callback,
                selector = options.selector,
                watchedattrs = options.attrs ? options.attrs.split(' ') : null;
            if ((type === CREATE && typeof (selector) === 'undefined') || (type === MODIFY && typeof (callback) === 'undefined')) {
                // Detach everything.
                if (type === CREATE) {
                    for (i in oc) {
                        current = oc[i];
                        if (current.observer) current.observer.disconnect();
                        delete oc[i];
                    }
                } else if (oc.observer) oc.observer.disconnect();
                // Remove all the onCreate data but leave the original object intact so any future attachments will go faster.
            } else {
                if (type === MODIFY || typeof (selector) === 'string' && oc[selector]) {
                    current = (type === MODIFY ? oc : oc[selector]);
                    if (typeof (callback) === 'undefined') {
                        current.observer.disconnect();
                        delete oc[selector];
                    } else if (typeof (callback) === 'function') {
                        var cblist = current.callbacks;
                        for (i = cblist.length - 1; i >= 0; i--) {
                            if (cblist[i].callback === callback) {
                                cblist.splice(i, 1);
                                break;
                            }
                        }
                        if (cblist.length === 0) {
                            if (current.observer) {
                                current.observer.disconnect();
                            } else {
                                return true;
                            }
                        }
                    } else {
                        debug('OnCreate: Invalid callback.');
                    }
                }
            }
            return this;
        }
    };

    $.fn.extend({
        onCreate: function () {

            if (this.length === 0) {
                debug("OnCreate: No valid parent elements.");
                return this;
            }

            var args = Array.prototype.slice.call(arguments);

            if (typeof (args[0]) !== 'string') {
                debug("OnCreate: Invalid argument. You must pass a string representing either an onCreate method or a jQuery selector.");
                return this;
            }

            if (methods[args[0]]) {
                return methods[args[0]].call(this, {
                    type: CREATE,
                    selector: args[1],
                    callback: args[2],
                    multi: args[3]
                });
            } else
            // Default init functionality.
            if (typeof (args[0]) === 'string' && typeof (args[1]) === 'function') {
                return methods.attach.call(this, {
                    type: CREATE,
                    selector: args[0],
                    callback: args[1],
                    multi: args[2]
                });
            } else {
                console.log(args[0] + " is not a valid onCreate method or no callback was given.");
                return this;
            }
        },

        // onModify. Usage: .onModify([attributes[, match,]], callback, multi)
        onModify: function () {

            if (this.length === 0) {
                debug("OnModify: Empty object received.");
                return this;
            }

            var args = Array.prototype.slice.call(arguments),
                method;
            if (methods[args[0]]) {
                method = args.shift();
            } else {
                method = 'attach';
            }

            if (typeof (args[0]) === 'function') {
                return methods[method].call(this, {
                    type: MODIFY,
                    callback: args[0],
                    multi: args[1]
                });
            } else if (typeof (args[0]) === 'string') {
                if (typeof (args[1]) === 'function') {
                    return methods[method].call(this, {
                        type: MODIFY,
                        attrs: args[0],
                        callback: args[1],
                        multi: args[2]
                    });
                } else if (typeof (args[1]) === 'string' || args[1] instanceof RegExp) {
                    return methods[method].call(this, {
                        type: MODIFY,
                        attrs: args[0],
                        match: args[1],
                        callback: args[2],
                        multi: args[3]
                    });
                }
            } else if (method === 'attach') {
                console.log(args[0] + " is not a valid onCreate method or no callback was given.");
                return this;
            } else {
                methods[method].call(this, {
                    type: MODIFY
                });
            }
        }
    });
    // Use $.onCreate as a shortcut to onCreate at the document level.
    $.onCreate = function (selector, callback, multi) {
        $(document).onCreate(selector, callback, multi);
    };
    $.onCreate.debug = false;
})(jQuery || $, window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false, document, window);<commit_msg>Updated date<commit_after>/*!
 * jQuery onCreate plugin v1.2-dev
 * http://jquery.com/
 *
 * Copyright 2014 CROmetrics
 * Released under the MIT license
 * https://github.com/eclecto/jQuery-onCreate/blob/master/LICENSE
 *
 * Date: 2014-12-17T16:10Z
 */

/* jshint expr: true */
/* global jQuery, console, window, document, $, setInterval, clearInterval */

(function ($, MutationObserver, document, window) {
    // MutationObserver = false; // Test C/B fallbacks.
    // Check for the existence of jQuery.
    if (!$.fn.jquery) {
        window.console = window.console || {
            log: function () {},
            warn: function () {}
        };
        window.console.warn('jQuery is undefined. onCreate can not initialize.');
        return;
    }

    // Constants.
    var CREATE = 'create',
        MODIFY = 'modify';

    // Observer class.
    function Observer(mutcallback, type) {
        var realObserver;

        this.observe = function (element) {
            if (MutationObserver) {
                realObserver = realObserver || new MutationObserver(mutcallback);
                var init = (type === MODIFY ? {
                    attributes: true
                } : {
                    childList: true,
                    subtree: true
                });
                realObserver.observe(element, init);
            } else {
                realObserver = setInterval(mutcallback, 50);
            }
        };

        this.disconnect = function () {
            if (realObserver) {
                if (MutationObserver) {
                    realObserver.disconnect();
                } else {
                    clearInterval(realObserver);
                }
            }
        };
    }

    function debug() {
        if ($.onCreate.debug) {
            var warn = Function.prototype.bind.call(console.warn, console);
            warn.apply(console, arguments);
        }
    }

    // Create a map of an element's attributes so we can poll for changes (non-MutationObserver browsers)
    function attributeMap(element) {
        var map = {};

        if (element.attributes) {
            $.each(element.attributes, function (index, attr) {
                map[attr.name] = attr.value;
            });
        }

        return map;
    }

    var methods = {
        attach: function (options) {
            var type = options.type,
                callback = options.callback,
                multi = options.multi || false,
                selector = options.selector,
                watchedattrs = options.attrs ? options.attrs.split(' ') : null,
                match = options.match,
                mapCompare;
            // Get/initiate this element's callback data and the array of callbacks for the current selector.
            this.data('on' + type) || this.data('on' + type, {});
            var oc = this.data('on' + type);
            if (selector) {
                oc[selector] = oc[selector] || {
                    callbacks: []
                };
            } else {
                oc.callbacks = oc.callbacks || [];
                oc.ignore = false;
            }

            var current = selector ? oc[selector] : oc,
                cblist = current.callbacks,

                // Add the callback to the array of callbacks for the current selector.
                newcb = {
                    callback: callback,
                    multi: multi,
                    // Create a universally unique identifier for the current parent/child relationship.
                    uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                        var r = Math.random() * 16 | 0,
                            v = c == 'x' ? r : (r & 0x3 | 0x8);
                        return v.toString(16);
                    })
                };
            if (watchedattrs) newcb.attrs = watchedattrs;
            if (match) newcb.match = match;
            cblist.unshift(newcb);

            // Create an attribute map for non-MutationObserver browsers so we can track changes.
            if (type === MODIFY /*&& !MutationObserver*/ ) {
                oc.attributeMap = attributeMap(this[0]);

                mapCompare = function (map1, map2) {
                    var mutations = [];
                    $.each(map1, function (key, value) {
                        if (typeof (map2[key]) === 'undefined' || value !== map2[key]) {
                            mutations.push({
                                attributeName: key
                            });
                        }
                    });
                    $.each(map2, function (key, value) {
                        if (typeof (map1[key]) === 'undefined') {
                            mutations.push({
                                attributeName: key
                            });
                        }
                    });
                    return mutations;
                };
            }

            if (current.observer === undefined) {
                // Store `this` to a variable to use as a context
                var $this = this,
                    observer, i, attrmatch,
                    // This method filters out elements that have already been processed by the current callback.
                    filter = function (index, element) {
                        if ($(element).attr('data-oc-processed-' + cblist[i].uuid)) {
                            return false;
                        } else {
                            return true;
                        }
                    },
                    checkattrs = function (index, mutation) {
                        var attrname = mutation.attributeName,
                            attrval = $this.attr(attrname),
                            curMatch = cblist[i].match;
                        if (!cblist[i].attrs || cblist[i].attrs.indexOf(attrname) > -1) {
                            if (typeof (curMatch) !== 'undefined') {
                                if (attrval.search(curMatch) >= 0) {
                                    attrmatch = true;
                                    return false;
                                }
                            } else {
                                attrmatch = true;
                                return false;
                            }
                        }
                    },

                    // Define our callback for when a mutation is detected.
                    mutcallback = function (mutations) {
                        // For modify listeners we set an Ignore property, so if callbacks also modify attributes we don't risk creating an infinite loop.
                        if (type === MODIFY) {
                            if (!oc.ignore) {
                                oc.ignore = true;
                            } else {
                                return;
                            }
                        }

                        // Find elements that have not already been processed by this observer.
                        var selected = type === CREATE ? $(selector, $this) : $this;

                        if (selected.length > 0) {
                            for (i = cblist.length - 1; i >= 0; i--) {
                                var elements = type === CREATE ? selected.filter(filter) : selected;

                                // Validate changed attributes for modify observers.
                                if (type === MODIFY) {
                                    attrmatch = false;
                                    if (!MutationObserver) {
                                        var newmap = attributeMap($this[0]);
                                        mutations = mapCompare(newmap, oc.attributeMap);
                                    }
                                    $.each(mutations, checkattrs);
                                }

                                if (elements.length > 0 && (type === CREATE || attrmatch)) {
                                    if (type === CREATE || multi === false) elements.attr('data-oc-processed-' + cblist[i].uuid, true);
                                    cblist[i].callback.call($this, elements);
                                    // Remove callback from the list if it only runs once.
                                    if (!cblist[i].multi) {
                                        cblist.splice(i, 1);
                                    }
                                }
                            }
                        }

                        // We've safely iterated through the callbacks, so don't ignore this master callback anymore.
                        if (oc.ignore) oc.ignore = false;
                        if (cblist.length === 0) {
                            if (observer) {
                                observer.disconnect();
                            } else {
                                return true;
                            }
                        }
                    };
                // Sanity Check: If this is a create listener, run the callback on initialization to see if there is already a valid element.
                if (type === CREATE && mutcallback()) {
                    return this;
                }

                observer = current.observer = new Observer(mutcallback, type);
                observer.observe($this[0]);
            }
            return this;
        },
        detach: function (options) {
            var current, i,
                type = options.type,
                oc = this.data('on' + type),
                callback = options.callback,
                selector = options.selector,
                watchedattrs = options.attrs ? options.attrs.split(' ') : null;
            if ((type === CREATE && typeof (selector) === 'undefined') || (type === MODIFY && typeof (callback) === 'undefined')) {
                // Detach everything.
                if (type === CREATE) {
                    for (i in oc) {
                        current = oc[i];
                        if (current.observer) current.observer.disconnect();
                        delete oc[i];
                    }
                } else if (oc.observer) oc.observer.disconnect();
                // Remove all the onCreate data but leave the original object intact so any future attachments will go faster.
            } else {
                if (type === MODIFY || typeof (selector) === 'string' && oc[selector]) {
                    current = (type === MODIFY ? oc : oc[selector]);
                    if (typeof (callback) === 'undefined') {
                        current.observer.disconnect();
                        delete oc[selector];
                    } else if (typeof (callback) === 'function') {
                        var cblist = current.callbacks;
                        for (i = cblist.length - 1; i >= 0; i--) {
                            if (cblist[i].callback === callback) {
                                cblist.splice(i, 1);
                                break;
                            }
                        }
                        if (cblist.length === 0) {
                            if (current.observer) {
                                current.observer.disconnect();
                            } else {
                                return true;
                            }
                        }
                    } else {
                        debug('OnCreate: Invalid callback.');
                    }
                }
            }
            return this;
        }
    };

    $.fn.extend({
        onCreate: function () {

            if (this.length === 0) {
                debug("OnCreate: No valid parent elements.");
                return this;
            }

            var args = Array.prototype.slice.call(arguments);

            if (typeof (args[0]) !== 'string') {
                debug("OnCreate: Invalid argument. You must pass a string representing either an onCreate method or a jQuery selector.");
                return this;
            }

            if (methods[args[0]]) {
                return methods[args[0]].call(this, {
                    type: CREATE,
                    selector: args[1],
                    callback: args[2],
                    multi: args[3]
                });
            } else
            // Default init functionality.
            if (typeof (args[0]) === 'string' && typeof (args[1]) === 'function') {
                return methods.attach.call(this, {
                    type: CREATE,
                    selector: args[0],
                    callback: args[1],
                    multi: args[2]
                });
            } else {
                console.log(args[0] + " is not a valid onCreate method or no callback was given.");
                return this;
            }
        },

        // onModify. Usage: .onModify([attributes[, match,]], callback, multi)
        onModify: function () {

            if (this.length === 0) {
                debug("OnModify: Empty object received.");
                return this;
            }

            var args = Array.prototype.slice.call(arguments),
                method;
            if (methods[args[0]]) {
                method = args.shift();
            } else {
                method = 'attach';
            }

            if (typeof (args[0]) === 'function') {
                return methods[method].call(this, {
                    type: MODIFY,
                    callback: args[0],
                    multi: args[1]
                });
            } else if (typeof (args[0]) === 'string') {
                if (typeof (args[1]) === 'function') {
                    return methods[method].call(this, {
                        type: MODIFY,
                        attrs: args[0],
                        callback: args[1],
                        multi: args[2]
                    });
                } else if (typeof (args[1]) === 'string' || args[1] instanceof RegExp) {
                    return methods[method].call(this, {
                        type: MODIFY,
                        attrs: args[0],
                        match: args[1],
                        callback: args[2],
                        multi: args[3]
                    });
                }
            } else if (method === 'attach') {
                console.log(args[0] + " is not a valid onCreate method or no callback was given.");
                return this;
            } else {
                methods[method].call(this, {
                    type: MODIFY
                });
            }
        }
    });
    // Use $.onCreate as a shortcut to onCreate at the document level.
    $.onCreate = function (selector, callback, multi) {
        $(document).onCreate(selector, callback, multi);
    };
    $.onCreate.debug = false;
})(jQuery || $, window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false, document, window);<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013 takeshi morita

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var NumConverter = {};
NumConverter.NumCodeSet = {
0:  '!', //0
1:  '#', //1
2:  '$', //10
3:  '%', //11
4:  '&', //100
5:  "'", //101
6:  '(', //110
7:  ')', //111
8:  '*', //1000
9:  '+', //1001
10: ',', //1010
11: '-', //1011
12: '.', //1100
13: '/', //1101
14: '0', //1110
15: '1', //1111
16: '2', //10000
17: '3', //10001
18: '4', //10010
19: '5', //10011
20: '6', //10100
21: '7', //10101
22: '8', //10110
23: '9', //10111
24: ':', //11000
25: ';', //11001
26: '<', //11010
27: '=', //11011
28: '>', //11100
29: '?', //11101
30: '@', //11110
31: 'A', //11111
32: 'B', //100000
33: 'C', //100001
34: 'D', //100010
35: 'E', //100011
36: 'F', //100100
37: 'G', //100101
38: 'H', //100110
39: 'I', //100111
40: 'J', //101000
41: 'K', //101001
42: 'L', //101010
43: 'M', //101011
44: 'N', //101100
45: 'O', //101101
46: 'P', //101110
47: 'Q', //101111
48: 'R', //110000
49: 'S', //110001
50: 'T', //110010
51: 'U', //110011
52: 'V', //110100
53: 'W', //110101
54: 'X', //110110
55: 'Y', //110111
56: 'Z', //111000
57: '[', //111001
58: ']', //111010
59: '^', //111011
60: '_', //111100
61: '`', //111101
62: 'a', //111110
63: 'b', //111111
64: 'c', //1000000
65: 'd', //1000001
66: 'e', //1000010
67: 'f', //1000011
68: 'g', //1000100
69: 'h', //1000101
70: 'i', //1000110
71: 'j', //1000111
72: 'k', //1001000
73: 'l', //1001001
74: 'm', //1001010
75: 'n', //1001011
76: 'o', //1001100
77: 'p', //1001101
78: 'q', //1001110
79: 'r', //1001111
80: 's', //1010000
81: 't', //1010001
82: 'u', //1010010
83: 'v', //1010011
84: 'w', //1010100
85: 'x', //1010101
86: 'y', //1010110
87: 'z', //1010111
88: '{', //1011000
89: '|', //1011001
90: '}', //1011010
91: '~', //1011011
92: "\t",//1011100
93: "\n",//1011101
94: "\r",//1011110
95: " ", //1011111
}

NumConverter.CodeNumSet = {};
for(var k in NumConverter.NumCodeSet){
  NumConverter.CodeNumSet[NumConverter.NumCodeSet[k]] = k;
}

NumConverter.strToSimpleNumArray = function(str){
  var chars = str.split("");
  var ret = []
  while(chars.length > 0){
    ret.push(NumConverter.charsToNum(chars));
  }
  return ret;
}

NumConverter.simpleNumArrayToStr = function(nums){
  var ret = "";
  for(var i=0;i<nums.length;i++){
    ret += NumConverter.numToStr(nums[i]);
  }
  return ret;
}

NumConverter.strToNum = function(str){
  var chars = str.split("");
  return NumConverter.charsToNum(chars);
}

NumConverter.charsToNum = function(chars){
  var ch = chars.shift();
  var n = NumConverter.CodeNumSet[ch];
  if(n < 64){
    return n - 32;
  }
  var sign = 1;
  if(n >= 80){
    sign = -1;
    n -= 80;
  }else{
    n -= 64;
  }
  var bits = n.toString(2);
  ch = chars.shift();
  while(ch){
    n = parseInt(NumConverter.CodeNumSet[ch],10);
    if(n < 64){
      var b = n.toString(2);
      var prefix = 6 - b.length;
      while(prefix){
        b = "0" + b;
        prefix -=1;
      }
      bits = bits + b;
      break;
    }
    bits += n.toString(2).substr(2);
    ch = chars.shift();
  }
  return parseInt(bits,2) * sign;
}

NumConverter.nBitToStr = function(nBit){
  if(nBit.length <= 6){
    return NumConverter.NumCodeSet[parseInt(nBit,2).toString()];
  }
  var b5 = nBit.substr(0,5);
  var ch = NumConverter.NumCodeSet[parseInt("10" + b5,2)];
  var remain = nBit.substr(5);
  return ch + NumConverter.nBitToStr(remain);
}

NumConverter.strToNumArray = function(sortedNumsStr){
  if(!sortedNumsStr){ return [];}
  var chars = sortedNumsStr.split("");
  var arrs = []
  while(chars.length > 0){
    arrs.push(NumConverter.charsToNum(chars));
  }
  var ret = [];
  var times = 0;
  var first = true;
  var baseNum = null;
  var before = null;
  var sameVal = null;
  while(arrs.length > 0){
    var num = arrs.shift();
    if(first){
      first = false;
      bases = [num];
      before = num;
      sameVal = num;
    }else if(num < 0){
      bases = [];
      for(var i=num+1;i<0;i++){
        var val = before + sameVal;
        bases.push(val);
        before = val;
      }
    }else{
      bases = [before + num];
      before = before + num;
      samveVal = num;
    }
    for(var i=0;i<bases.length;i++){
      var indices = NumConverter.sortedNumSetToDecompress(arrs);
      for(var i=0;i<indices.length;i++){
        ret[indices[i]] = bases[i];
      }
    }
  }
  return ret;
}

NumConverter.sortedNumSetToDecompress = function(sortedNumSet){
  var ret = []
  var sameVal = null;
  var diff = sortedNumSet.shift();
  var before = 0;
  while(diff != -1){
    if(diff >= 0){
      var val = before + diff;
      ret.push(val);
      sameVal = diff;
      before = val;
      diff = sortedNumSet.shift();
    }else{
      for(var i=diff+1;i < 0;i++){
        var val = before + sameVal;
        ret.push(val);
        before = val;
      }
      diff = sortedNumSet.shift();
    }
  }
  return ret;
}

NumConverter.sortedNumSetToCompress = function(sortedNums){
  var before = 0;
  var sameCount = 1;
  var ret = [sortedNums[0]];
  var before = sortedNums[0];
  var sameVal = sortedNums[0];
  for(var i=1;i<sortedNums.length;i++){
    var diff = sortedNums[i] - before;
    if(diff == sameVal){
      sameCount+=1;
    }else{
      if(sameCount != 1){
        ret.push(sameCount * -1);
      }
      ret.push(diff);
      sameCount = 1;
      sameVal = diff;
    }
    before = sortedNums[i];
  }
  if(sameCount != 1){
    ret.push(sameCount * -1);
  }
  ret.push(-1);
  return ret;
}

NumConverter.numArrayToStr = function(nums){
  var ret = "";
  var numSet = {};
  if(nums.length == 0) return "";
  for(var i=0;i<nums.length;i++){
    if(!numSet[nums[i]]) numSet[nums[i]] = [];
    numSet[nums[i]].push(i);
  }
  var numSetSorted = [];
  for(var key in numSet){
    numSetSorted.push(parseInt(key,10));
  }
  numSetSorted.sort(function(a,b){return a - b});
  var baseNums = NumConverter.sortedNumSetToCompress(numSetSorted)
  var before = 0;
  var sameVal = baseNums[0]

  for(var i=0; i < baseNums.length;i++){
    var num = baseNums[i];
    if(i != 0 && num==-1){
      break;
    }
    if(i != 0 && num < 0){
      for(var j = num + 1; j < 0;j++){
        var current = before + sameVal;
        ret+= NumConverter.simpleNumArrayToStr(NumConverter.sortedNumSetToCompress(numSet[current]))
        before = current;
      }
    }else{
      var current = before + num;
      ret += NumConverter.numToStr(num);
      ret += NumConverter.simpleNumArrayToStr(NumConverter.sortedNumSetToCompress(numSet[current]))
      before = current;
      sameVal = num;
    }
  }
  return ret;
}

NumConverter.numToStr = function(num){
  if(num >= -32 && num < 32){
    num += 32;
    return NumConverter.NumCodeSet[num.toString()];
  }
  var bias = 64;
  if(num < 0){
    bias = 80;
  }
  var nBit = Math.abs(num).toString(2);
  if(nBit.length == 5){
    nBit = "00000" + nBit
  }else{
    var mod = nBit.length % 5;
    for(var i=0; i < (5 - mod);i++){
      nBit = "0" + nBit;
    }
  }
  var b4 = nBit.substr(0,4);
  var ch = NumConverter.NumCodeSet[parseInt(b4,2) + bias];
  var remain = nBit.substr(4);
  return ch + NumConverter.nBitToStr(remain);
}

if (typeof window === 'undefined') {
  module.exports = {
    numToStr: NumConverter.numToStr,
    strToNum: NumConverter.strToNum,
    strToSimpleNumArray: NumConverter.strToSimpleNumArray,
    simpleNumArrayToStr: NumConverter.simpleNumArrayToStr,
    numArrayToStr: NumConverter.numArrayToStr,
    strToNumArray: NumConverter.strToNumArray,
    sortedNumSetToCompress : NumConverter.sortedNumSetToCompress,
    sortedNumSetToDecompress : NumConverter.sortedNumSetToDecompress
  };
}
<commit_msg>Revert "連続数の圧縮バグ"<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013 takeshi morita

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var NumConverter = {};
NumConverter.NumCodeSet = {
0:  '!', //0
1:  '#', //1
2:  '$', //10
3:  '%', //11
4:  '&', //100
5:  "'", //101
6:  '(', //110
7:  ')', //111
8:  '*', //1000
9:  '+', //1001
10: ',', //1010
11: '-', //1011
12: '.', //1100
13: '/', //1101
14: '0', //1110
15: '1', //1111
16: '2', //10000
17: '3', //10001
18: '4', //10010
19: '5', //10011
20: '6', //10100
21: '7', //10101
22: '8', //10110
23: '9', //10111
24: ':', //11000
25: ';', //11001
26: '<', //11010
27: '=', //11011
28: '>', //11100
29: '?', //11101
30: '@', //11110
31: 'A', //11111
32: 'B', //100000
33: 'C', //100001
34: 'D', //100010
35: 'E', //100011
36: 'F', //100100
37: 'G', //100101
38: 'H', //100110
39: 'I', //100111
40: 'J', //101000
41: 'K', //101001
42: 'L', //101010
43: 'M', //101011
44: 'N', //101100
45: 'O', //101101
46: 'P', //101110
47: 'Q', //101111
48: 'R', //110000
49: 'S', //110001
50: 'T', //110010
51: 'U', //110011
52: 'V', //110100
53: 'W', //110101
54: 'X', //110110
55: 'Y', //110111
56: 'Z', //111000
57: '[', //111001
58: ']', //111010
59: '^', //111011
60: '_', //111100
61: '`', //111101
62: 'a', //111110
63: 'b', //111111
64: 'c', //1000000
65: 'd', //1000001
66: 'e', //1000010
67: 'f', //1000011
68: 'g', //1000100
69: 'h', //1000101
70: 'i', //1000110
71: 'j', //1000111
72: 'k', //1001000
73: 'l', //1001001
74: 'm', //1001010
75: 'n', //1001011
76: 'o', //1001100
77: 'p', //1001101
78: 'q', //1001110
79: 'r', //1001111
80: 's', //1010000
81: 't', //1010001
82: 'u', //1010010
83: 'v', //1010011
84: 'w', //1010100
85: 'x', //1010101
86: 'y', //1010110
87: 'z', //1010111
88: '{', //1011000
89: '|', //1011001
90: '}', //1011010
91: '~', //1011011
92: "\t",//1011100
93: "\n",//1011101
94: "\r",//1011110
95: " ", //1011111
}

NumConverter.CodeNumSet = {};
for(var k in NumConverter.NumCodeSet){
  NumConverter.CodeNumSet[NumConverter.NumCodeSet[k]] = k;
}

NumConverter.strToSimpleNumArray = function(str){
  var chars = str.split("");
  var ret = []
  while(chars.length > 0){
    ret.push(NumConverter.charsToNum(chars));
  }
  return ret;
}

NumConverter.simpleNumArrayToStr = function(nums){
  var ret = "";
  for(var i=0;i<nums.length;i++){
    ret += NumConverter.numToStr(nums[i]);
  }
  return ret;
}

NumConverter.strToNum = function(str){
  var chars = str.split("");
  return NumConverter.charsToNum(chars);
}

NumConverter.charsToNum = function(chars){
  var ch = chars.shift();
  var n = NumConverter.CodeNumSet[ch];
  if(n < 64){
    return n - 32;
  }
  var sign = 1;
  if(n >= 80){
    sign = -1;
    n -= 80;
  }else{
    n -= 64;
  }
  var bits = n.toString(2);
  ch = chars.shift();
  while(ch){
    n = parseInt(NumConverter.CodeNumSet[ch],10);
    if(n < 64){
      var b = n.toString(2);
      var prefix = 6 - b.length;
      while(prefix){
        b = "0" + b;
        prefix -=1;
      }
      bits = bits + b;
      break;
    }
    bits += n.toString(2).substr(2);
    ch = chars.shift();
  }
  return parseInt(bits,2) * sign;
}

NumConverter.nBitToStr = function(nBit){
  if(nBit.length <= 6){
    return NumConverter.NumCodeSet[parseInt(nBit,2).toString()];
  }
  var b5 = nBit.substr(0,5);
  var ch = NumConverter.NumCodeSet[parseInt("10" + b5,2)];
  var remain = nBit.substr(5);
  return ch + NumConverter.nBitToStr(remain);
}

NumConverter.strToNumArray = function(sortedNumsStr){
  if(!sortedNumsStr){ return [];}
  var chars = sortedNumsStr.split("");
  var arrs = []
  while(chars.length > 0){
    arrs.push(NumConverter.charsToNum(chars));
  }
  var ret = [];
  var times = 0;
  var first = true;
  var baseNum = null;
  var before = null;
  var sameVal = null;
  while(arrs.length > 0){
    var num = arrs.shift();
    if(first){
      first = false;
      bases = [num];
      before = num;
      sameVal = num;
    }else if(num < 0){
      bases = [];
      for(var i=num+1;i<0;i++){
        var val = before + sameVal;
        bases.push(val);
        before = val;
      }
    }else{
      bases = [before + num];
      before = before + num;
      samveVal = num;
    }
    for(var i=0;i<bases.length;i++){
      var indices = NumConverter.sortedNumSetToDecompress(arrs);
      for(var i=0;i<indices.length;i++){
        ret[indices[i]] = bases[i];
      }
    }
  }
  return ret;
}

NumConverter.sortedNumSetToDecompress = function(sortedNumSet){
  var ret = []
  var sameVal = null;
  var diff = sortedNumSet.shift();
  var before = 0;
  while(diff != -1){
    if(diff >= 0){
      var val = before + diff;
      ret.push(val);
      sameVal = diff;
      before = val;
      diff = sortedNumSet.shift();
    }else{
      for(var i=diff+1;i < 0;i++){
        var val = before + sameVal;
        ret.push(val);
        before = val;
      }
      diff = sortedNumSet.shift();
    }
  }
  return ret;
}

NumConverter.sortedNumSetToCompress = function(sortedNums){
  var before = 0;
  var sameCount = 1;
  var ret = [sortedNums[0]];
  var before = sortedNums[0];
  var sameVal = sortedNums[0];
  for(var i=1;i<sortedNums.length;i++){
    var diff = sortedNums[i] - before;
    if(diff == sameVal){
      sameCount+=1;
    }else{
      if(sameCount != 1){
        ret.push(sameCount * -1);
      }
      ret.push(diff);
      sameCount = 1;
      sameVal = diff;
    }
    before = sortedNums[i];
  }
  if(sameCount != 1){
    ret.push(sameCount * -1);
  }
  ret.push(-1);
  return ret;
}

NumConverter.numArrayToStr = function(nums){
  var ret = "";
  var numSet = {};
  if(nums.length == 0) return "";
  for(var i=0;i<nums.length;i++){
    if(!numSet[nums[i]]) numSet[nums[i]] = [];
    numSet[nums[i]].push(i);
  }
  var numSetSorted = [];
  for(var key in numSet){
    numSetSorted.push(parseInt(key,10));
  }
  numSetSorted.sort(function(a,b){return a - b});
  var baseNums = NumConverter.sortedNumSetToCompress(numSetSorted)
  var before = 0;
  var sameVal = baseNums[0]

  for(var i=0; i < baseNums.length;i++){
    var num = baseNums[i];
    if(i != 0 && num==-1){
      break;
    }
    if(i !=0 && i < 0){
      for(var j = num + 1; j < 0;j++){
        var current = before + sameVal;
        ret+= NumConverter.simpleNumArrayToStr(NumConverter.sortedNumSetToCompress(numSet[current]))
        before = current;
      }
    }else{
      var current = before + num;
      ret += NumConverter.numToStr(num);
      ret += NumConverter.simpleNumArrayToStr(NumConverter.sortedNumSetToCompress(numSet[current]))
      before = current;
      sameVal = num;
    }
  }
  return ret;
}

NumConverter.numToStr = function(num){
  if(num >= -32 && num < 32){
    num += 32;
    return NumConverter.NumCodeSet[num.toString()];
  }
  var bias = 64;
  if(num < 0){
    bias = 80;
  }
  var nBit = Math.abs(num).toString(2);
  if(nBit.length == 5){
    nBit = "00000" + nBit
  }else{
    var mod = nBit.length % 5;
    for(var i=0; i < (5 - mod);i++){
      nBit = "0" + nBit;
    }
  }
  var b4 = nBit.substr(0,4);
  var ch = NumConverter.NumCodeSet[parseInt(b4,2) + bias];
  var remain = nBit.substr(4);
  return ch + NumConverter.nBitToStr(remain);
}

if (typeof window === 'undefined') {
  module.exports = {
    numToStr: NumConverter.numToStr,
    strToNum: NumConverter.strToNum,
    strToSimpleNumArray: NumConverter.strToSimpleNumArray,
    simpleNumArrayToStr: NumConverter.simpleNumArrayToStr,
    numArrayToStr: NumConverter.numArrayToStr,
    strToNumArray: NumConverter.strToNumArray,
    sortedNumSetToCompress : NumConverter.sortedNumSetToCompress,
    sortedNumSetToDecompress : NumConverter.sortedNumSetToDecompress
  };
}
<|endoftext|>


<commit_before>'use strict'
const vstamp = require('vigour-stamp')

// encapsulate more in here

exports.incoming = function offsetClient (hub, socket, data, clocksy) {
// (double offset) -- maybe dont use clocksy
  const tDelta = clocksy.processResponse(data.data)
  if (socket.offset === void 0) {
    if (!vstamp.offsetConnection) {
      vstamp.offsetConnection = socket
    }
    socket.offset = tDelta
    const stamp = vstamp.create('connect')
    hub.set({ connected: true }, stamp)
    vstamp.close(stamp)
  } else {
    socket.offset = tDelta
  }
  if (vstamp.offsetConnection === socket) {
    vstamp.offset = Math.abs(tDelta) > 10 ? tDelta : 0
  }
}
<commit_msg>clean up<commit_after>'use strict'
const vstamp = require('vigour-stamp')

// encapsulate more in here

exports.incoming = function offsetClient (hub, socket, data, clocksy) {
// (double offset) -- maybe dont use clocksy
  const tDelta = clocksy.processResponse(data.data)
  if (socket.offset === void 0) {
    if (!vstamp.offsetConnection) {
      vstamp.offsetConnection = socket
    }
    socket.offset = tDelta
    const stamp = vstamp.create('connect')
    hub.set({ connected: true }, stamp)
    vstamp.close(stamp)
  } else {
    socket.offset = tDelta
  }
  if (vstamp.offsetConnection === socket) {
    vstamp.offset = Math.abs(tDelta) > 10 ? tDelta : 0
  }
}

// resolve clocks
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import Dialog from 'react-toolbox/lib/dialog';
import PureComponent from './PureComponent';
var {map, pick, mapObject, getIn, get} = require('./underscore_ext');
var platform = require('platform');
var Rx = require('./rx');
import Link from 'react-toolbox/lib/link';
import styles from './LaunchHelper.module.css';

var osFiles = {
		osxJre: {
			pattern: "ucsc_xena_macos_[_0-9]*_with_jre.dmg",
			description: "OSX installer, bundled JRE",
			help: "Recommended for OSX 10.7 and above"
		},
		osxNoJre: {
			pattern: "ucsc_xena_macos_[_0-9]*.dmg",
			description: "OSX installer, no JRE",
			help: "Recommended for OSX 10.6"
		},
		win32: {
			pattern: "ucsc_xena_windows_[_0-9]*.exe",
			description: "Windows 32 bit installer, bundled JRE",
			help: "Recommended for all 32 bit versions of Windows"
		},
		win64: {
			pattern: "ucsc_xena_windows-x64_[_0-9]*.exe",
			description: "Windows 64 bit installer, bundled JRE",
			help: "Recommended for all 64 bit versions of Windows"
		},
		tar: {
			pattern: "ucsc_xena_[_0-9]*.tar.gz",
			description: "Tar archive, no updater or JRE",
			help: "Recommended for linux server deployments"
		}
	}, defaults = {
		'OS X': {32: 'osxNoJre', 64: 'osxJre'},
		'Windows': {32: 'win32', 64: 'win64'},
		'Linux': {32: 'tar', 64: 'tar'}
	};

function findMatch(pattern, list) {
	var matches = list.filter(s => s.match(pattern));
	return matches.length > 0 ? matches[0] : undefined;
}

var matchPaths = serverFiles =>
	mapObject(osFiles, ({pattern}, key) =>
			  findMatch(osFiles[key].pattern, serverFiles));

var parseInt10 = s => parseInt(s, 10);

function osxArch() {
	var version = getIn(platform, ['os', 'version']),
		parts = version && version.match(/(\d*)\.(\d*)/).slice(1).map(parseInt10); // [maj, min, patch]
	return (parts && parts[0] === 10 && parts[1] <= 6) ? 32 : 64;
}

function getOs() {
	var family = getIn(platform, ['os', 'family']);
	if (family) {
		if (family.indexOf('Windows') !== -1) {
			return 'Windows';
		}
		if (family.indexOf('OS X') !== -1) {
			return 'OS X';
		}
		if (family.indexOf('Linux') !== -1) {
			return 'Linux';
		}
	}
}

var downloadDir = 'https://genome-cancer.ucsc.edu/download/public/get-xena';
var i4jLogo = `${downloadDir}/install4j_small.png`;
var updatesPath = `${downloadDir}/updates.xml`;
var downloadPath = name => `${downloadDir}/${name}`;
var getFileName = e => downloadPath(e.getAttribute('fileName'));

class XenaDownload extends React.Component {
	state = {};

	componentDidMount() {
		// Haven't been able to get the browsers to use the etags from
		// the server. It might need some other header to indicate that
		// the doc should be considered expired. This doesn't help in
		// the current deployment, because the headers for the doc have already
		// been served. A tacky work-around is to append a random query string,
		// forcing the client to bypass its cache.
		// Note that the etags do appear to work for some files, like the
		// image files.
		this.sub = Rx.Observable.ajax({method: 'GET', responseType: 'xml', url: updatesPath + '?x=' + Math.random().toString(), crossDomain: true}).subscribe(xml => {
			var files = matchPaths([...xml.response.getElementsByTagName('entry')]
								   .map(getFileName));

			this.setState({files}); //eslint-disable-line react/no-did-mount-set-state
		});
	}

	componentWillUnmount() {
		this.sub.unsubscribe();
	}

	onShowAdvanced = () => {
		this.props.onShowAdvanced(!this.props.advanced);
	}

	render() {
		var {files} = this.state,
			{isFirst, advanced} = this.props,
			os = getOs(),
			arch = os === 'OS X' ? osxArch() : getIn(platform, ['os', 'architecture']),
			defaultTarget = getIn(defaults, [os, arch]),
			defaultInstall = get(files, defaultTarget);

		return (

Supported by

					{isFirst ? 'If this is your first time, ' : 'Please '}
					{defaultInstall ?
						<Link className={styles.downloadLink} href={defaultInstall} label='click here to download and install a Local Xena hub.'/> :
						'download and run a Local Xena hub, from the list below:'}

				{defaultInstall ? {advanced ? 'Fewer options...' : 'More options...'} : null}
				{defaultInstall ?
 : null}

{map(files ? pick(osFiles, (_, k) => files[k]) : [], (info, key) =>
					 <Link className={styles.downloadList} href={files[key]} title={info.help} label={info.description}/>)}

);
	}
}

var launchingHelp = ['Launching...',

If you see a browser dialog, and click the "open" button.
];

var statusHelp = {
	undefined: [],
	down: launchingHelp,
	started: launchingHelp,
	up: ['Your local Xena Hub is running.',

To view your data, use the "Visualization" button
],
	old: ['Your local Xena Hub is out of date.',

],
	lost: ['We have lost contact with your Local Xena hub.',

To re-start it, you may reload this page.
]
};

var launch = () => {
	var i = document.getElementById('xenaLauncher');
	if (i) {
		document.body.removeChild(i);
	}
	i = document.createElement('iframe');
	i.id = 'xenaLauncher';
	document.body.appendChild(i);
	i.src = 'ucscxena://';
};

// XXX Note that we re-render on every change of the wrapped
// component. Maybe should put dialog in a separate component to
// avoid re-rendering it.
var wrap = Comp => class extends PureComponent {
	static displayName = 'LaunchHelperWrapper';

	constructor(props) {
		super(props);
		// If we just arrived on a page that requires the hub, and status is
		// 'down' but not 'lost' (i.e. user shutdown), try to start.
		this.state = {advanced: false, show: props.state.localStatus === 'down' || props.state.localStatus === 'old'};
	}

	componentDidMount() {
		if (this.props.state.localStatus === 'down') {
			launch();
		}
	}

	componentWillReceiveProps(props) {
		// If localStatus was not set (no ping yet, from server) and changes to 'down',
		// show dialog & try to launch.
		if (!this.props.state.localStatus && props.state.localStatus === 'down') {
			this.setState({show: true});
			launch();
		} else if (props.state.localStatus === 'up') {
			this.setState({show: false});
		}
	}

	onShowAdvanced = advanced => {
		this.setState({advanced});
	}

	onHide = () => {
		this.setState({show: false});
	}

	onShow = () => {
		this.setState({show: true});
	}

	setCompRef = ref => {
		this.compRef = ref;
	}

	actions = [
		{label: 'Help', target: '_blank', href: 'https://ucsc-xena.gitbook.io/project/local-xena-hub'},
		{label: 'Close', onClick: this.onHide}
	];

	render() {
		var {advanced, show} = this.state,
			{localStatus: status} = this.props.state,
			statusBadge =
				status === 'up' ? (
					lens) : (
					lens),
			[header, help] = statusHelp[status];

		return (
			<Comp ref={this.setCompRef} {...this.props} badge={statusBadge}>
				<Dialog theme={{body: styles.body}} active={show} actions={this.actions} className={styles.dialog}>

{header}

						{help}
						{status !== 'up' && status !== 'lost' ? <XenaDownload isFirst={status !== 'old'} advanced={advanced} onShowAdvanced={this.onShowAdvanced}/> : null}

A Local Xena Hub is an application on your computer for loading and storing data.

				</Dialog>
			</Comp>);
	}
};

var wrapLaunchHelper = (shouldMount, Comp) => {
	var Wrapper = wrap(Comp),
		LaunchHelperMounter = props => shouldMount(props) ? <Wrapper {...props}/> : <Comp {...props}/>;
	return LaunchHelperMounter;
};

export default wrapLaunchHelper;
<commit_msg>local hub launch window: wording change<commit_after>'use strict';

import React from 'react';
import Dialog from 'react-toolbox/lib/dialog';
import PureComponent from './PureComponent';
var {map, pick, mapObject, getIn, get} = require('./underscore_ext');
var platform = require('platform');
var Rx = require('./rx');
import Link from 'react-toolbox/lib/link';
import styles from './LaunchHelper.module.css';

var osFiles = {
		osxJre: {
			pattern: "ucsc_xena_macos_[_0-9]*_with_jre.dmg",
			description: "OSX installer, bundled JRE",
			help: "Recommended for OSX 10.7 and above"
		},
		osxNoJre: {
			pattern: "ucsc_xena_macos_[_0-9]*.dmg",
			description: "OSX installer, no JRE",
			help: "Recommended for OSX 10.6"
		},
		win32: {
			pattern: "ucsc_xena_windows_[_0-9]*.exe",
			description: "Windows 32 bit installer, bundled JRE",
			help: "Recommended for all 32 bit versions of Windows"
		},
		win64: {
			pattern: "ucsc_xena_windows-x64_[_0-9]*.exe",
			description: "Windows 64 bit installer, bundled JRE",
			help: "Recommended for all 64 bit versions of Windows"
		},
		tar: {
			pattern: "ucsc_xena_[_0-9]*.tar.gz",
			description: "Tar archive, no updater or JRE",
			help: "Recommended for linux server deployments"
		}
	}, defaults = {
		'OS X': {32: 'osxNoJre', 64: 'osxJre'},
		'Windows': {32: 'win32', 64: 'win64'},
		'Linux': {32: 'tar', 64: 'tar'}
	};

function findMatch(pattern, list) {
	var matches = list.filter(s => s.match(pattern));
	return matches.length > 0 ? matches[0] : undefined;
}

var matchPaths = serverFiles =>
	mapObject(osFiles, ({pattern}, key) =>
			  findMatch(osFiles[key].pattern, serverFiles));

var parseInt10 = s => parseInt(s, 10);

function osxArch() {
	var version = getIn(platform, ['os', 'version']),
		parts = version && version.match(/(\d*)\.(\d*)/).slice(1).map(parseInt10); // [maj, min, patch]
	return (parts && parts[0] === 10 && parts[1] <= 6) ? 32 : 64;
}

function getOs() {
	var family = getIn(platform, ['os', 'family']);
	if (family) {
		if (family.indexOf('Windows') !== -1) {
			return 'Windows';
		}
		if (family.indexOf('OS X') !== -1) {
			return 'OS X';
		}
		if (family.indexOf('Linux') !== -1) {
			return 'Linux';
		}
	}
}

var downloadDir = 'https://genome-cancer.ucsc.edu/download/public/get-xena';
var i4jLogo = `${downloadDir}/install4j_small.png`;
var updatesPath = `${downloadDir}/updates.xml`;
var downloadPath = name => `${downloadDir}/${name}`;
var getFileName = e => downloadPath(e.getAttribute('fileName'));

class XenaDownload extends React.Component {
	state = {};

	componentDidMount() {
		// Haven't been able to get the browsers to use the etags from
		// the server. It might need some other header to indicate that
		// the doc should be considered expired. This doesn't help in
		// the current deployment, because the headers for the doc have already
		// been served. A tacky work-around is to append a random query string,
		// forcing the client to bypass its cache.
		// Note that the etags do appear to work for some files, like the
		// image files.
		this.sub = Rx.Observable.ajax({method: 'GET', responseType: 'xml', url: updatesPath + '?x=' + Math.random().toString(), crossDomain: true}).subscribe(xml => {
			var files = matchPaths([...xml.response.getElementsByTagName('entry')]
								   .map(getFileName));

			this.setState({files}); //eslint-disable-line react/no-did-mount-set-state
		});
	}

	componentWillUnmount() {
		this.sub.unsubscribe();
	}

	onShowAdvanced = () => {
		this.props.onShowAdvanced(!this.props.advanced);
	}

	render() {
		var {files} = this.state,
			{isFirst, advanced} = this.props,
			os = getOs(),
			arch = os === 'OS X' ? osxArch() : getIn(platform, ['os', 'architecture']),
			defaultTarget = getIn(defaults, [os, arch]),
			defaultInstall = get(files, defaultTarget);

		return (

Supported by

					{isFirst ? 'If this is your first time, ' : 'If nothing prompts from browser, '}
					{defaultInstall ?
						<Link className={styles.downloadLink} href={defaultInstall} label='download & run a Local Xena hub.'/> :
						'download & run a Local Xena hub, from the list below:'}

				{defaultInstall ? {advanced ? 'Fewer options...' : 'More options...'} : null}
				{defaultInstall ?
 : null}

{map(files ? pick(osFiles, (_, k) => files[k]) : [], (info, key) =>
					 <Link className={styles.downloadList} href={files[key]} title={info.help} label={info.description}/>)}

);
	}
}

var launchingHelp = ['Launching...',

Please click Open UCSC xena if you see the system dialog.
];

var statusHelp = {
	undefined: [],
	down: launchingHelp,
	started: launchingHelp,
	up: ['Your local Xena Hub is running.',

To view your data, use the "Visualization" button
],
	old: ['Your local Xena Hub is out of date.',

],
	lost: ['We have lost contact with your Local Xena hub.',

To re-start it, you may reload this page.
]
};

var launch = () => {
	var i = document.getElementById('xenaLauncher');
	if (i) {
		document.body.removeChild(i);
	}
	i = document.createElement('iframe');
	i.id = 'xenaLauncher';
	document.body.appendChild(i);
	i.src = 'ucscxena://';
};

// XXX Note that we re-render on every change of the wrapped
// component. Maybe should put dialog in a separate component to
// avoid re-rendering it.
var wrap = Comp => class extends PureComponent {
	static displayName = 'LaunchHelperWrapper';

	constructor(props) {
		super(props);
		// If we just arrived on a page that requires the hub, and status is
		// 'down' but not 'lost' (i.e. user shutdown), try to start.
		this.state = {advanced: false, show: props.state.localStatus === 'down' || props.state.localStatus === 'old'};
	}

	componentDidMount() {
		if (this.props.state.localStatus === 'down') {
			launch();
		}
	}

	componentWillReceiveProps(props) {
		// If localStatus was not set (no ping yet, from server) and changes to 'down',
		// show dialog & try to launch.
		if (!this.props.state.localStatus && props.state.localStatus === 'down') {
			this.setState({show: true});
			launch();
		} else if (props.state.localStatus === 'up') {
			this.setState({show: false});
		}
	}

	onShowAdvanced = advanced => {
		this.setState({advanced});
	}

	onHide = () => {
		this.setState({show: false});
	}

	onShow = () => {
		this.setState({show: true});
	}

	setCompRef = ref => {
		this.compRef = ref;
	}

	actions = [
		{label: 'Help', target: '_blank', href: 'https://ucsc-xena.gitbook.io/project/local-xena-hub'},
		{label: 'Close', onClick: this.onHide}
	];

	render() {
		var {advanced, show} = this.state,
			{localStatus: status} = this.props.state,
			statusBadge =
				status === 'up' ? (
					lens) : (
					lens),
			[header, help] = statusHelp[status];

		return (
			<Comp ref={this.setCompRef} {...this.props} badge={statusBadge}>
				<Dialog theme={{body: styles.body}} active={show} actions={this.actions} className={styles.dialog}>

{header}

						{help}
						{status !== 'up' && status !== 'lost' ? <XenaDownload isFirst={status !== 'old'} advanced={advanced} onShowAdvanced={this.onShowAdvanced}/> : null}

A Local Xena Hub is an application on your computer for loading and storing data.

				</Dialog>
			</Comp>);
	}
};

var wrapLaunchHelper = (shouldMount, Comp) => {
	var Wrapper = wrap(Comp),
		LaunchHelperMounter = props => shouldMount(props) ? <Wrapper {...props}/> : <Comp {...props}/>;
	return LaunchHelperMounter;
};

export default wrapLaunchHelper;
<|endoftext|>


<commit_before>var _ = require('grunt').util._;
var helpers = require('../helpers');

var allPartials = helpers.getFolder('src.partials', '**/*.html');

var testEnvFiles = helpers.getFiles('src.js')
  .concat(helpers.getFiles('src.less'))
  .concat(allPartials);

var unitTestfiles = _.clone(testEnvFiles).concat(helpers.getFiles('test.unit'));
var e2eTestFiles = _.clone(testEnvFiles).concat(helpers.getFiles('test.e2e'));
var bothTestfiles = _.clone(unitTestfiles).concat(helpers.getFiles('test.e2e'));

var demoFiles = helpers.getFiles('src.js')
  .concat(helpers.getFiles('src.less'))
  .concat(helpers.getFiles('internal.ngTemplates'))
  .concat(helpers.getFolder('demoEnv', '**/*'));

function wrapHooks(tasks, type) {
  if (type === 'global') {
    tasks.unshift('test:before');
    tasks.push('test:after');
  } else {
    tasks.unshift(['test', type, 'before'].join(':'));
    tasks.push(['test', type, 'after'].join(':'));
  }

  return tasks;
}

module.exports = {
  andTestUnit: {
    files: unitTestfiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist',
      'karma:watch:run',
      helpers.withCoverage('_normalizeUnitCoverage'),
      helpers.withCoverage('makeReport')
    ], 'unit')
  },
  andTestE2e: {
    files: e2eTestFiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist',
      helpers.withCoverage('shell:deleteInstrumented'),
      helpers.withCoverage('instrument'),
      helpers.withCoverage('protractor_coverage:tdd', 'protractor:tdd'),
      helpers.withCoverage('makeReport')
    ], 'e2e'),
    options: {
      atBegin: true
    }
  },
  andTestBoth: {
    files: bothTestfiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist'
    ].concat(wrapHooks(
        [
          'karma:watch:run',
          helpers.withCoverage('_normalizeUnitCoverage')
        ],
        'unit'
    )).concat(wrapHooks(
        [
          helpers.withCoverage('shell:deleteInstrumented'),
          helpers.withCoverage('instrument'),
          helpers.withCoverage('protractor_coverage:tdd', 'protractor:tdd')
        ],
        'e2e'
    )).concat(helpers.withCoverage('makeReport')),
    'global')
  },
  partials: {
    files: allPartials,
    tasks: ['ngtemplates:dist']
  },
  demo: {
    files: demoFiles,
    tasks: [],
    options: {
      livereload: true
    }
  },
  build: {
    files: testEnvFiles,
    tasks: ['build']
  }
};
<commit_msg>feat(sass): watch sass files<commit_after>var _ = require('grunt').util._;
var helpers = require('../helpers');

var allPartials = helpers.getFolder('src.partials', '**/*.html');

var testEnvFiles = helpers.getFiles('src.js')
  .concat(helpers.getFiles('src.sass'))
  .concat(helpers.getFiles('src.less'))
  .concat(allPartials);

var unitTestfiles = _.clone(testEnvFiles).concat(helpers.getFiles('test.unit'));
var e2eTestFiles = _.clone(testEnvFiles).concat(helpers.getFiles('test.e2e'));
var bothTestfiles = _.clone(unitTestfiles).concat(helpers.getFiles('test.e2e'));

var demoFiles = helpers.getFiles('src.js')
  .concat(helpers.getFiles('src.sass'))
  .concat(helpers.getFiles('src.less'))
  .concat(helpers.getFiles('internal.ngTemplates'))
  .concat(helpers.getFolder('demoEnv', '**/*'));

function wrapHooks(tasks, type) {
  if (type === 'global') {
    tasks.unshift('test:before');
    tasks.push('test:after');
  } else {
    tasks.unshift(['test', type, 'before'].join(':'));
    tasks.push(['test', type, 'after'].join(':'));
  }

  return tasks;
}

module.exports = {
  andTestUnit: {
    files: unitTestfiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist',
      'karma:watch:run',
      helpers.withCoverage('_normalizeUnitCoverage'),
      helpers.withCoverage('makeReport')
    ], 'unit')
  },
  andTestE2e: {
    files: e2eTestFiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist',
      helpers.withCoverage('shell:deleteInstrumented'),
      helpers.withCoverage('instrument'),
      helpers.withCoverage('protractor_coverage:tdd', 'protractor:tdd'),
      helpers.withCoverage('makeReport')
    ], 'e2e'),
    options: {
      atBegin: true
    }
  },
  andTestBoth: {
    files: bothTestfiles,
    tasks: wrapHooks([
      helpers.withCoverage('shell:deleteCoverages'),
      'ngtemplates:dist'
    ].concat(wrapHooks(
        [
          'karma:watch:run',
          helpers.withCoverage('_normalizeUnitCoverage')
        ],
        'unit'
    )).concat(wrapHooks(
        [
          helpers.withCoverage('shell:deleteInstrumented'),
          helpers.withCoverage('instrument'),
          helpers.withCoverage('protractor_coverage:tdd', 'protractor:tdd')
        ],
        'e2e'
    )).concat(helpers.withCoverage('makeReport')),
    'global')
  },
  partials: {
    files: allPartials,
    tasks: ['ngtemplates:dist']
  },
  demo: {
    files: demoFiles,
    tasks: [],
    options: {
      livereload: true
    }
  },
  build: {
    files: testEnvFiles,
    tasks: ['build']
  }
};
<|endoftext|>


<commit_before>// Finds relative path between two absolute paths

'use strict';

var normalize  = require('path').normalize
  , contains   = require('es5-ext/lib/String/prototype/contains')
  , sysSep     = require('./separator')
  , normalize2 = require('./normalize')

  , re = /^[A-Z]\:[\\\/]/;

module.exports = function (from, to) {
	var x, y, separator, sfrom, orgto;
	var prefrom = from; orgto = to;
	if (contains.call(from, '/') && contains.call(from, '\\')) {
		from = normalize2(from);
		separator = sysSep;
	}
	if (to && contains.call(to, '/') && contains.call(to, '\\')) {
		to = normalize2(to);
		separator = sysSep;
	}
	if (!separator) {
		if (contains.call(from, '/') || contains.call(to, '/')) {
			separator = '/'; sfrom = /\\/g;
		} else if (contains.call(from, '\\') || contains.call(to, '\\')) {
			separator = '\\'; sfrom = /\//g;
		} else {
			separator = sysSep;
		}
		from = normalize(from).replace(sfrom, separator);
		to = normalize(to).replace(sfrom, separator);
	}

	if (from.match(re)) {
		from = from.slice(2);
	}
	if (to && to.match(re)) {
		to = to.slice(2);
	}
	if (from.charAt(0) !== separator) {
		throw new Error("node-ext.path.relative error: "
			+ "Paths should be absolute");
	}
	if (orgto == null) {
		to = from;
		from = process.cwd() + separator;
		if (from.match(re)) {
			from = from.slice(2);
		}
	} else if (to.charAt(0) !== separator) {
		throw new Error("node-ext.path.relative error: "
			+ "Paths should be absolute");
	}

	x = from.split(separator);
	y = to.split(separator);
	while (x.length && (x[0] === y[0])) {
		x.shift(); y.shift();
	}
	return Array(x.length).join(".." + separator) + y.join(separator);
};
<commit_msg>Fixed path.relative<commit_after>// Finds relative path between two absolute paths

'use strict';

var normalize  = require('path').normalize
  , contains   = require('es5-ext/lib/String/prototype/contains')
  , sysSep     = require('./separator')
  , normalize2 = require('./normalize')

  , re = /^[A-Z]\:[\\\/]/;

module.exports = function (from, to) {
	var x, y, separator, sfrom, orgto;
	var prefrom = from; orgto = to;
	if (contains.call(from, '/') && contains.call(from, '\\')) {
		from = normalize2(from);
		separator = sysSep;
	}
	if (to && contains.call(to, '/') && contains.call(to, '\\')) {
		to = normalize2(to);
		separator = sysSep;
	}
	if (!separator) {
		if (contains.call(from, '/') || contains.call(to, '/')) {
			separator = '/'; sfrom = /\\/g;
		} else if (contains.call(from, '\\') || contains.call(to, '\\')) {
			separator = '\\'; sfrom = /\//g;
		} else {
			separator = sysSep;
		}
		from = normalize(from).replace(sfrom, separator);
		to = to && normalize(to).replace(sfrom, separator);
	}

	if (from.match(re)) {
		from = from.slice(2);
	}
	if (to && to.match(re)) {
		to = to.slice(2);
	}
	if (from.charAt(0) !== separator) {
		throw new Error("node-ext.path.relative error: "
			+ "Paths should be absolute");
	}
	if (orgto == null) {
		to = from;
		from = process.cwd() + separator;
		if (from.match(re)) {
			from = from.slice(2);
		}
	} else if (to.charAt(0) !== separator) {
		throw new Error("node-ext.path.relative error: "
			+ "Paths should be absolute");
	}

	x = from.split(separator);
	y = to.split(separator);
	while (x.length && (x[0] === y[0])) {
		x.shift(); y.shift();
	}
	return Array(x.length).join(".." + separator) + y.join(separator);
};
<|endoftext|>


<commit_before>import { LightningElement, track, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'
import { registerListener, unregisterAllListeners, fireEvent} from 'c/pubsubNoPageRef';
import getFieldMappingsByObjectAndFieldSetNames
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.getFieldMappingsByObjectAndFieldSetNames';
import createDataImportFieldMapping
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.createDataImportFieldMapping';
import getObjectFieldDescribes
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.getObjectFieldDescribes';

const actions = [
    { label: 'Edit', name: 'edit' },
    { label: 'Delete', name: 'delete' },
];

const columns = [
    { label: 'Field Label', fieldName: 'xxx_Source_Field_Label_xxx', type: 'text', sortable: true },
    { label: 'Field API Name', fieldName: 'xxx_Source_Field_API_Name_xxx', type: 'text' },
    { label: 'Data Type', fieldName: 'xxx_Source_Field_Data_Type_xxx', type: 'text', fixedWidth: 125 },
        {
            label: 'Maps To', fieldName: '', type: 'text', fixedWidth: 95,
            cellAttributes: { iconName: { fieldName: 'Maps_To_Icon' }, iconPosition: 'right' }
        },
    { label: 'Field Label', fieldName: 'xxx_Target_Field_Label_xxx', type: 'text' },
    { label: 'Field API Name', fieldName: 'xxx_Target_Field_API_Name_xxx', type: 'text' },
    { label: 'Data Type', fieldName: 'xxx_Target_Field_Data_Type_xxx', type: 'text', fixedWidth: 125 },
    { type: 'action', typeAttributes: { rowActions: actions } }
];

export default class bdiFieldMappings extends LightningElement {
    @track displayFieldMappings = false;
    @track isLoading = true;
    @track columns = columns;
    @api objectMapping;
    @track fieldMappings;
    @track deploymentTimer;
    @api deploymentTimeout = 10000;

    @api diFieldDescribes;
    @api targetObjectFieldDescribes;

    @api
    get noFieldMappings() {
        return !this.fieldMappings || this.fieldMappings.length === 0;
    }

    @api
    refresh() {
        this.isLoading = true;
        this.handleFieldMappings();
        this.getModalData();
    }

    handleNavButton() {
        fireEvent(this.pageRef, 'showobjectmappings');
    }

    connectedCallback() {
        this.logBold('bdiFieldMappings | connectedCallback()');
        registerListener('showobjectmappings', this.handleShowObjectMappings, this);
        registerListener('showfieldmappings', this.handleShowFieldMappings, this);
        registerListener('deploymentResponse', this.handleDeploymentResponse, this);
        registerListener('startDeploymentTimeout', this.handleDeploymentTimeout, this);
        registerListener('refresh', this.refresh, this);
    }

    disconnectedCallback() {
        unregisterAllListeners(this);
    }

    getModalData = async() => {
        this.logBold('bdiFieldMappings | getModalData()');
        try {
            this.diFieldDescribes = await this.handleGetDataImportFieldDescribes();
            this.targetObjectFieldDescribes = await this.handleGetTargetObjectFieldDescribes();
        } catch(error) {
            if (error) {
                this.showToast('Error', error, 'error', 'sticky');
            }
        }
    }

    handleGetDataImportFieldDescribes = async() => {
        //this.logBold('bdiFieldMappingModal | handleGetDataImportFieldDescribes()');
        return getObjectFieldDescribes({objectName: 'DataImport__c'})
            .then((data) => {
                return data;
            });
    }

    handleGetTargetObjectFieldDescribes = async() => {
        //this.logBold('bdiFieldMappingModal | handleGetTargetObjectFieldDescribes()');
        let objectAPIName =
            this.objectMapping.Object_API_Name__c || this.objectMapping.npsp__Object_API_Name__c;

        return getObjectFieldDescribes({objectName: objectAPIName})
            .then((data) => {
                return data;
            });
    }

    handleDeploymentTimeout(event) {
        let that = this;
        this.deploymentTimer = setTimeout(function() {
            that.isLoading = false;
            fireEvent(this.pageRef, 'closeModal', {});
            that.showToast(
                'Field Mapping deployment is taking longer than expected.',
                'Your deployment ({0}) will continue to process in the background.',
                'warning',
                'sticky',
                [event.deploymentId]);
        }, this.deploymentTimeout, that);
    }

    handleDeploymentResponse(platformEvent) {
        console.log('handleDeploymentResponse()');
        clearTimeout(this.deploymentTimer);
        fireEvent(this.pageRef, 'refresh', {});
        fireEvent(this.pageRef, 'closeModal', {});

        const status =
            platformEvent.response.data.payload.Status__c || platformEvent.response.data.payload.npsp__Status__c;
        const deploymentId =
            platformEvent.response.data.payload.DeploymentId__c || platformEvent.response.data.payload.npsp__DeploymentId__c;
        console.log('Creating toast event');
        const evt = new ShowToastEvent({
            title: 'Deployment completed with Status: ' + status,
            message: 'Deployment Id: ' + deploymentId,
            variant: 'success',
        });
        this.dispatchEvent(evt);
        console.log('Toast event dispatched');
    }

    handleShowObjectMappings() {
        this.displayFieldMappings = false;
    }

    handleShowFieldMappings(event) {
        this.objectMapping = event.objectMapping;
        this.displayFieldMappings = true;
        this.refresh();
    }

    handleOpenModal() {
        fireEvent(this.pageRef, 'openModal', {
            objectMapping: this.objectMapping,
            row: undefined,
            fieldMappings: this.fieldMappings
        });
    }

    /*******************************************************************************
    * @description Call apex method 'getFieldMappingsByObjectMappingName' to get
    * a list of field mappings by their parent object mapping name
    *
    * @param name: Name of the object mapping received from parent component
    */
    handleFieldMappings() {
        //this.logBold('bdiFieldMappings | handleFieldMappings()');
        getFieldMappingsByObjectAndFieldSetNames({
                objectName: this.objectMapping.DeveloperName})
            .then((data) => {
                this.fieldMappings = data;
                this.isLoading = false;
            })
            .catch((error) => {
                this.isLoading = false;
                console.log(error);
                if (error && error.body) {
                    this.showToast(
                        'Error',
                        '{0}. {1}. {2}.',
                        'error',
                        'sticky',
                        [error.body.exceptionType, error.body.message, error.body.stackTrace]);
                }
            });
    }

    /*******************************************************************************
    * @description Action handler for datatable row actions (i.e. edit, delete)
    *
    * @param event: Event containing row details of the action
    */
    handleRowAction(event) {
        //this.logBold('bdiFieldMappings | handleRowAction()');
        const actionName = event.detail.action.name;
        const row = event.detail.row;

        switch (actionName) {

            case 'delete':
                this.isLoading = true;
                row.xxx_Is_Deleted_xxx = true;
                let clonedRow = JSON.stringify(row);

                createDataImportFieldMapping({fieldMappingString: clonedRow})
                    .then((deploymentId) => {
                        this.handleDeleteDeploymentId(deploymentId);
                    })
                    .catch((error) => {
                        console.log(error);
                        if (error && error.body) {
                            this.showToast(
                                'Error',
                                '{0}. {1}. {2}.',
                                'error',
                                'sticky',
                                [error.body.exceptionType, error.body.message, error.body.stackTrace]);
                        }
                    });
                break;

            case 'edit':
                fireEvent(this.pageRef, 'openModal', {
                    objectMapping: this.objectMapping,
                    row: row,
                    fieldMappings: this.fieldMappings
                });
                break;

            default:
        }
    }

    handleDeleteDeploymentId(deploymentId) {
        //tell our parent element that we have an Id to monitor
        const deploymentEvent = new CustomEvent('deployment', {
            bubbles: true,
            composed: true,
            detail: {deploymentId}
        });
        this.dispatchEvent(deploymentEvent);

        this.handleDeploymentTimeout({ deploymentId: deploymentId });
    }

    showToast(title, message, variant, mode, messageData) {
        const event = new ShowToastEvent({
            title: title,
            message: message,
            variant: variant,
            mode: mode,
            messageData: messageData
        });
        this.dispatchEvent(event);
    }

    // TODO: Delete later
    /*******************************************************************************
    * @description Parse proxy objects for debugging, mutating, etc
    *
    * @param object: Object to be parsed
    */
    log(object) {
        return JSON.parse(JSON.stringify(object));
    }

    logBold(string) {
        return console.log('%c ' + string, 'font-weight: bold; font-size: 16px;');
    }
}<commit_msg>add comments and remove console logs from bdiFieldMappings<commit_after>import { LightningElement, track, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'
import { registerListener, unregisterAllListeners, fireEvent} from 'c/pubsubNoPageRef';
import getFieldMappingsByObjectAndFieldSetNames
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.getFieldMappingsByObjectAndFieldSetNames';
import createDataImportFieldMapping
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.createDataImportFieldMapping';
import getObjectFieldDescribes
    from '@salesforce/apex/BDI_ManageAdvancedMappingCtrl.getObjectFieldDescribes';

const actions = [
    { label: 'Edit', name: 'edit' },
    { label: 'Delete', name: 'delete' },
];

const columns = [
    { label: 'Field Label', fieldName: 'xxx_Source_Field_Label_xxx', type: 'text', sortable: true },
    { label: 'Field API Name', fieldName: 'xxx_Source_Field_API_Name_xxx', type: 'text' },
    { label: 'Data Type', fieldName: 'xxx_Source_Field_Data_Type_xxx', type: 'text', fixedWidth: 125 },
        {
            label: 'Maps To', fieldName: '', type: 'text', fixedWidth: 95,
            cellAttributes: { iconName: { fieldName: 'Maps_To_Icon' }, iconPosition: 'right' }
        },
    { label: 'Field Label', fieldName: 'xxx_Target_Field_Label_xxx', type: 'text' },
    { label: 'Field API Name', fieldName: 'xxx_Target_Field_API_Name_xxx', type: 'text' },
    { label: 'Data Type', fieldName: 'xxx_Target_Field_Data_Type_xxx', type: 'text', fixedWidth: 125 },
    { type: 'action', typeAttributes: { rowActions: actions } }
];

export default class bdiFieldMappings extends LightningElement {
    @track displayFieldMappings = false;
    @track isLoading = true;
    @track columns = columns;
    @api objectMapping;
    @track fieldMappings;
    @track deploymentTimer;
    @api deploymentTimeout = 10000;

    @api diFieldDescribes;
    @api targetObjectFieldDescribes;

    @api
    get noFieldMappings() {
        return !this.fieldMappings || this.fieldMappings.length === 0;
    }

    @api
    refresh() {
        this.isLoading = true;
        this.handleFieldMappings();
        this.getModalData();
    }

    handleNavButton() {
        fireEvent(this.pageRef, 'showobjectmappings');
    }

    connectedCallback() {
        registerListener('showobjectmappings', this.handleShowObjectMappings, this);
        registerListener('showfieldmappings', this.handleShowFieldMappings, this);
        registerListener('deploymentResponse', this.handleDeploymentResponse, this);
        registerListener('startDeploymentTimeout', this.handleDeploymentTimeout, this);
        registerListener('refresh', this.refresh, this);
    }

    disconnectedCallback() {
        unregisterAllListeners(this);
    }

    /*******************************************************************************
    * @description Groups up the two calls to get data import field describes and
    * target object field describes
    */
    getModalData = async() => {
        try {
            if (!this.diFieldDescribes) {
                this.diFieldDescribes = await this.handleGetDataImportFieldDescribes();
            }
            this.targetObjectFieldDescribes = await this.handleGetTargetObjectFieldDescribes();
        } catch(error) {
            if (error) {
                this.showToast('Error', error, 'error', 'sticky');
            }
        }
    }

    /*******************************************************************************
    * @description Gets the Data Import object's field describes
    *
    * @param {string} objectName: API name of the object we need field describes for
    *
    * @return {array} data: List of FieldInfo instances
    */
    handleGetDataImportFieldDescribes = async() => {
        return getObjectFieldDescribes({objectName: 'DataImport__c'})
            .then((data) => {
                return data;
            });
    }

    /*******************************************************************************
    * @description Gets the target object's field describes
    *
    * @param {string} objectAPIName: API name of the object we need field describes for
    *
    * @return {array} data: List of FieldInfo instances
    */
    handleGetTargetObjectFieldDescribes = async() => {
        let objectAPIName =
            this.objectMapping.Object_API_Name__c || this.objectMapping.npsp__Object_API_Name__c;

        return getObjectFieldDescribes({objectName: objectAPIName})
            .then((data) => {
                return data;
            });
    }

    /*******************************************************************************
    * @description Handles the timeout toast of deployments whenever a deployment
    * that's registered with platformEventListener takes 10 seconds or longer to
    * send out a response.
    */
    handleDeploymentTimeout(event) {
        let that = this;
        this.deploymentTimer = setTimeout(function() {
            that.isLoading = false;
            fireEvent(this.pageRef, 'closeModal', {});
            that.showToast(
                'Field Mapping deployment is taking longer than expected.',
                'Your deployment ({0}) will continue to process in the background.',
                'warning',
                'sticky',
                [event.deploymentId]);
        }, this.deploymentTimeout, that);
    }

    /*******************************************************************************
    * @description Listens for an event from the platformEventListener component.
    * Upon receiving an event refreshes the field mappings records, closes the modal,
    * and creates a toast.
    *
    * @param {object} platformEvent: Object containing the platform event payload
    */
    handleDeploymentResponse(platformEvent) {
        console.log('handleDeploymentResponse()');
        clearTimeout(this.deploymentTimer);
        fireEvent(this.pageRef, 'refresh', {});
        fireEvent(this.pageRef, 'closeModal', {});

        const status =
            platformEvent.response.data.payload.Status__c || platformEvent.response.data.payload.npsp__Status__c;
        const deploymentId =
            platformEvent.response.data.payload.DeploymentId__c || platformEvent.response.data.payload.npsp__DeploymentId__c;
        console.log('Creating toast event');
        const evt = new ShowToastEvent({
            title: 'Deployment completed with Status: ' + status,
            message: 'Deployment Id: ' + deploymentId,
            variant: 'success',
        });
        this.dispatchEvent(evt);
        console.log('Toast event dispatched');
    }

    /*******************************************************************************
    * @description Hides the field mappings component and fires an event to the parent
    * object mappings component to show itself.
    */
    handleShowObjectMappings() {
        this.displayFieldMappings = false;
    }

    /*******************************************************************************
    * @description Shows the field mappings component and forces a refresh to get
    * fresh field mapping records for the currently selected object mapping.
    */
    handleShowFieldMappings(event) {
        this.objectMapping = event.objectMapping;
        this.displayFieldMappings = true;
        this.refresh();
    }

    /*******************************************************************************
    * @description Opens the field mapping modal passing in relevant details on
    * the currently selected object and child field mappings.
    */
    handleOpenModal() {
        fireEvent(this.pageRef, 'openModal', {
            objectMapping: this.objectMapping,
            row: undefined,
            fieldMappings: this.fieldMappings
        });
    }

    /*******************************************************************************
    * @description Call apex method 'getFieldMappingsByObjectMappingName' to get
    * a list of field mappings by their parent object mapping name
    */
    handleFieldMappings() {
        //this.logBold('bdiFieldMappings | handleFieldMappings()');
        getFieldMappingsByObjectAndFieldSetNames({
                objectName: this.objectMapping.DeveloperName})
            .then((data) => {
                this.fieldMappings = data;
                this.isLoading = false;
            })
            .catch((error) => {
                this.isLoading = false;
                console.log(error);
                if (error && error.body) {
                    this.showToast(
                        'Error',
                        '{0}. {1}. {2}.',
                        'error',
                        'sticky',
                        [error.body.exceptionType, error.body.message, error.body.stackTrace]);
                }
            });
    }

    /*******************************************************************************
    * @description Action handler for datatable row actions (i.e. edit, delete)
    *
    * @param event: Event containing row details of the action
    */
    handleRowAction(event) {
        //this.logBold('bdiFieldMappings | handleRowAction()');
        const actionName = event.detail.action.name;
        const row = event.detail.row;

        switch (actionName) {

            case 'delete':
                this.isLoading = true;
                row.xxx_Is_Deleted_xxx = true;
                let clonedRow = JSON.stringify(row);

                createDataImportFieldMapping({fieldMappingString: clonedRow})
                    .then((deploymentId) => {
                        this.handleDeleteDeploymentId(deploymentId);
                    })
                    .catch((error) => {
                        console.log(error);
                        if (error && error.body) {
                            this.showToast(
                                'Error',
                                '{0}. {1}. {2}.',
                                'error',
                                'sticky',
                                [error.body.exceptionType, error.body.message, error.body.stackTrace]);
                        }
                    });
                break;

            case 'edit':
                fireEvent(this.pageRef, 'openModal', {
                    objectMapping: this.objectMapping,
                    row: row,
                    fieldMappings: this.fieldMappings
                });
                break;

            default:
        }
    }

    handleDeleteDeploymentId(deploymentId) {
        //tell our parent element that we have an Id to monitor
        const deploymentEvent = new CustomEvent('deployment', {
            bubbles: true,
            composed: true,
            detail: {deploymentId}
        });
        this.dispatchEvent(deploymentEvent);

        this.handleDeploymentTimeout({ deploymentId: deploymentId });
    }

    showToast(title, message, variant, mode, messageData) {
        const event = new ShowToastEvent({
            title: title,
            message: message,
            variant: variant,
            mode: mode,
            messageData: messageData
        });
        this.dispatchEvent(event);
    }
}<|endoftext|>