<commit_before>/*
 * Global javascript utilities
 */

var static_url = "";

/*
 * A simple function to initialize the value of the global variable
 * 'media_url' (corresponding to django's MEDIA_URL variable).
 */
function set_static_url(url) {
    static_url = url;
}

/*
 * Shortcut function that construct an url from the media_url and the
 * given value.
 */
function get_static_url(value) {
    return static_url + value;
}

function modalbox(e, css, defhref, defcb, defclosecb) {
    e.preventDefault();
    var $this = $(this);
    var href = (defhref != undefined) ? defhref : $this.attr('href');
    var modalcb = (defcb != undefined) ? defcb : $this.attr('modalcb');
    var closecb = (defclosecb != undefined) ? defclosecb : $this.attr("closecb");

    if (href.indexOf('#') == 0) {
        $(href).modal('open');
        return;
    }
    $.ajax({
        type: "GET",
        url: href
    }).done(function(data) {
        var $div = $('
', {
            id: "modalbox", 'class': "modal", html: data
        });

        $div.modal({show: false});
        $div.one('shown.bs.modal', function() {
            $(".help").popover({
                container: "#modalbox",
                trigger: "hover"
            }).click(function(e) {e.preventDefault();});
            if (modalcb != undefined) {
                if (typeof modalcb === "function") modalcb(); else eval(modalcb + '()');
            }
        }).on('hidden.bs.modal', function(e) {
            var $target = $(e.target);

            if (!$target.is($(this))) {
                return;
            }
            $("#modalbox").remove();
            if (closecb != undefined) {
                if (typeof closecb === "function") closecb(); else eval(closecb + '()');
            }
        });
        $div.modal('show');

        if (css != undefined) {
            $div.css(css);
        }
    });
}

function modalbox_autowidth(e) {
    modalbox.apply(this, [e, {
        width: 'auto',
        'margin-left': function() { return -($(this).width() / 2); }
    }]);
}

/*
 * Simple shorcut do create a bootstrap alert box (error mode)
 */
function build_alert_box(msg, level) {
    return $('
 \
×' + msg + "
");
}

function build_error_alert(msg) {
    return build_alert_box(msg, 'error');
}

function build_success_alert(msg) {
    return build_alert_box(msg, 'success');
}

/*
 * '.keys()' method support for old browsers :p
 */
if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

/*
 * Clean all errors in a given form.
 */
function clean_form_errors(formid) {
    $("#" + formid + " div.error").removeClass("error");
    $("#" + formid + " span.help-block").remove();
}

/*
 * Display validation errors for a given form.
 */
function display_form_errors(formid, data) {
    clean_form_errors(formid);
    $.each(data.form_errors, function(id, value) {
        var fullid = "id_" + (data.prefix ? data.prefix + "-" : "") + id;
        var $widget = $("#" + formid + " #" + fullid);
        var spanid = fullid + "-error";
        var $span = $("#" + spanid);

        if (!$widget.parents(".form-group").hasClass("has-error")) {
            $widget.parents(".form-group").addClass("has-error");
        }
        if (!$span.length) {
            $span = $("", {
                "class": "help-block",
                "html": value[0],
                "id": spanid
            });
            $widget.parents(".controls").append($span);
        } else {
            $span.html(value[0]);
        }
    });
}

/*
 * Simple function that sends a form using an 'ajax' post request.
 *
 * The function is intended to be used in a modal environment.
 */
function simple_ajax_form_post(e, options) {
    e.preventDefault();
    var $form = (options.formid != undefined) ? $("#" + options.formid) : $("form");
    var defaults = {reload_on_success: true, reload_mode: 'full', modal: true};
    var opts = $.extend({}, defaults, options);
    var args = $form.serialize();

    if (options.extradata != undefined) {
        args += "&" + options.extradata;
    }
    $.ajax({
        type: "POST",
        global: false,
        url: $form.attr("action"),
        data: args
    }).done(function(data) {
        if (opts.modal) {
            $("#modalbox").modal('hide');
        }
        if (opts.success_cb != undefined) {
            opts.success_cb(data);
            return;
        }
        if (opts.reload_on_success) {
            if (opts.reload_mode == 'full') {
                window.location.reload();
            } else {
                histomanager.update(true);
            }
        }
        if (data) {
            $("body").notify('success', data, 2000);
        }
    }).fail(function(jqxhr) {
        var data = $.parseJSON(jqxhr.responseText);
        if (data.form_errors) {
            display_form_errors(options.formid, data);
        } else {
            if (opts.modal) {
                $('.modal-body').prepend(build_error_alert(data));
            } else {
                $('body').notify('error', data);
            }
        }
        if (opts.error_cb) {
            opts.error_cb(data);
        }
    });
}

/*
 * The following code prevents a bug under IE7 because fullpath is
 * returned instead of a relative one. (even if mootools uses
 * getAttribute("href", 2), this is not working for AJAX requests)
 */
function gethref(obj) {
    var url = $(obj).attr("href");
    var re = new RegExp("^(https?):");
    var scheme = re.exec(url);

    if (scheme != null) {
        var baseurl = scheme[0] + "://" + location.host + location.pathname;
        return url.replace(baseurl, "");
    }
    return url;
};

/*
 * Extract the current URL parameters into a dictionnary.
 *
 * Ref:
 * http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
 */
function parse_qs(raw) {
    if (raw == "") return {};
    var res = {};

    for (var i = 0; i < raw.length; i++) {
        var p = raw[i].split('=');

        if (p.length != 2) continue;
        res[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return res;
}

/*
 * Extract a specific URL parameter using its name.
 *
 * Ref: http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
 */
function get_parameter_by_name(url, name) {
    var name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(url);

    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

/*
 * Return the target associated to an event object.
 */
function get_target(e, tag) {
    var $target = $(e.target);

    if (tag === undefined || $target.is(tag)) {
        return $target;
    }
    return $target.parent();
}

/*
 * Send a simple AJAX request.
 */
function simple_ajax_request(e, uoptions) {
    var $this = $(this);
    var defaults = {};
    var options = $.extend({}, defaults, uoptions);

    if (e != undefined) e.preventDefault();
    $.ajax({
        url: $this.attr("href"),
        dataType: 'json'
    }).done(function(data) {
        if (options.ok_cb) options.ok_cb(data);
        if (data) {
            $("body").notify("success", data, 2000);
        }
    });
}

/*
 * Simple function that redirect ajax requests to the login page if
 * the status code received with a response is equal to 278.
 */
function ajax_login_redirect(xhr) {
    if (xhr.status != 278) {
        return;
    }
    var params = "?next=" + window.location.pathname;

    window.location.href =
        xhr.getResponseHeader("Location").replace(/\?.*$/, params);
}

function activate_widget(e) {
    var $this = $(this);
    var widget_id = $this.attr("id").substr(0, $this.attr("id").length - 4);
    var $widget = $('#' + widget_id);

    if ($this.prop("checked")) {
        $widget.attr('disabled', true);
    } else {
        $widget.attr('disabled', false);
    }
}

/*
 * Default error handler for AJAX requests.
 */
function default_ajax_error_handler(event, jqxhr, settings) {
    try {
        var data = $.parseJSON(jqxhr.responseText);
    } catch (x) {
        var data = gettext("Internal error");
    }
    $('body').notify('error', data);
}

$(document).ready(function() {
    $(document).ajaxSuccess(function(e, xhr, settings) { ajax_login_redirect(xhr); });
    $(document).ajaxError(default_ajax_error_handler);
    $(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
    $(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
    $(document).on('click', '.activator', activate_widget);
    $(".help").popover({trigger: 'hover'}).click(function(e) {e.preventDefault();});
});
<commit_msg>Delete a JS rule related to margin of some modal-boxes<commit_after>/*
 * Global javascript utilities
 */

var static_url = "";

/*
 * A simple function to initialize the value of the global variable
 * 'media_url' (corresponding to django's MEDIA_URL variable).
 */
function set_static_url(url) {
    static_url = url;
}

/*
 * Shortcut function that construct an url from the media_url and the
 * given value.
 */
function get_static_url(value) {
    return static_url + value;
}

function modalbox(e, css, defhref, defcb, defclosecb) {
    e.preventDefault();
    var $this = $(this);
    var href = (defhref != undefined) ? defhref : $this.attr('href');
    var modalcb = (defcb != undefined) ? defcb : $this.attr('modalcb');
    var closecb = (defclosecb != undefined) ? defclosecb : $this.attr("closecb");

    if (href.indexOf('#') == 0) {
        $(href).modal('open');
        return;
    }
    $.ajax({
        type: "GET",
        url: href
    }).done(function(data) {
        var $div = $('
', {
            id: "modalbox", 'class': "modal", html: data
        });

        $div.modal({show: false});
        $div.one('shown.bs.modal', function() {
            $(".help").popover({
                container: "#modalbox",
                trigger: "hover"
            }).click(function(e) {e.preventDefault();});
            if (modalcb != undefined) {
                if (typeof modalcb === "function") modalcb(); else eval(modalcb + '()');
            }
        }).on('hidden.bs.modal', function(e) {
            var $target = $(e.target);

            if (!$target.is($(this))) {
                return;
            }
            $("#modalbox").remove();
            if (closecb != undefined) {
                if (typeof closecb === "function") closecb(); else eval(closecb + '()');
            }
        });
        $div.modal('show');

        if (css != undefined) {
            $div.css(css);
        }
    });
}

function modalbox_autowidth(e) {
    modalbox.apply(this, [e]);
}

/*
 * Simple shorcut do create a bootstrap alert box (error mode)
 */
function build_alert_box(msg, level) {
    return $('
 \
×' + msg + "
");
}

function build_error_alert(msg) {
    return build_alert_box(msg, 'error');
}

function build_success_alert(msg) {
    return build_alert_box(msg, 'success');
}

/*
 * '.keys()' method support for old browsers :p
 */
if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

/*
 * Clean all errors in a given form.
 */
function clean_form_errors(formid) {
    $("#" + formid + " div.error").removeClass("error");
    $("#" + formid + " span.help-block").remove();
}

/*
 * Display validation errors for a given form.
 */
function display_form_errors(formid, data) {
    clean_form_errors(formid);
    $.each(data.form_errors, function(id, value) {
        var fullid = "id_" + (data.prefix ? data.prefix + "-" : "") + id;
        var $widget = $("#" + formid + " #" + fullid);
        var spanid = fullid + "-error";
        var $span = $("#" + spanid);

        if (!$widget.parents(".form-group").hasClass("has-error")) {
            $widget.parents(".form-group").addClass("has-error");
        }
        if (!$span.length) {
            $span = $("", {
                "class": "help-block",
                "html": value[0],
                "id": spanid
            });
            $widget.parents(".controls").append($span);
        } else {
            $span.html(value[0]);
        }
    });
}

/*
 * Simple function that sends a form using an 'ajax' post request.
 *
 * The function is intended to be used in a modal environment.
 */
function simple_ajax_form_post(e, options) {
    e.preventDefault();
    var $form = (options.formid != undefined) ? $("#" + options.formid) : $("form");
    var defaults = {reload_on_success: true, reload_mode: 'full', modal: true};
    var opts = $.extend({}, defaults, options);
    var args = $form.serialize();

    if (options.extradata != undefined) {
        args += "&" + options.extradata;
    }
    $.ajax({
        type: "POST",
        global: false,
        url: $form.attr("action"),
        data: args
    }).done(function(data) {
        if (opts.modal) {
            $("#modalbox").modal('hide');
        }
        if (opts.success_cb != undefined) {
            opts.success_cb(data);
            return;
        }
        if (opts.reload_on_success) {
            if (opts.reload_mode == 'full') {
                window.location.reload();
            } else {
                histomanager.update(true);
            }
        }
        if (data) {
            $("body").notify('success', data, 2000);
        }
    }).fail(function(jqxhr) {
        var data = $.parseJSON(jqxhr.responseText);
        if (data.form_errors) {
            display_form_errors(options.formid, data);
        } else {
            if (opts.modal) {
                $('.modal-body').prepend(build_error_alert(data));
            } else {
                $('body').notify('error', data);
            }
        }
        if (opts.error_cb) {
            opts.error_cb(data);
        }
    });
}

/*
 * The following code prevents a bug under IE7 because fullpath is
 * returned instead of a relative one. (even if mootools uses
 * getAttribute("href", 2), this is not working for AJAX requests)
 */
function gethref(obj) {
    var url = $(obj).attr("href");
    var re = new RegExp("^(https?):");
    var scheme = re.exec(url);

    if (scheme != null) {
        var baseurl = scheme[0] + "://" + location.host + location.pathname;
        return url.replace(baseurl, "");
    }
    return url;
};

/*
 * Extract the current URL parameters into a dictionnary.
 *
 * Ref:
 * http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
 */
function parse_qs(raw) {
    if (raw == "") return {};
    var res = {};

    for (var i = 0; i < raw.length; i++) {
        var p = raw[i].split('=');

        if (p.length != 2) continue;
        res[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return res;
}

/*
 * Extract a specific URL parameter using its name.
 *
 * Ref: http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
 */
function get_parameter_by_name(url, name) {
    var name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(url);

    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

/*
 * Return the target associated to an event object.
 */
function get_target(e, tag) {
    var $target = $(e.target);

    if (tag === undefined || $target.is(tag)) {
        return $target;
    }
    return $target.parent();
}

/*
 * Send a simple AJAX request.
 */
function simple_ajax_request(e, uoptions) {
    var $this = $(this);
    var defaults = {};
    var options = $.extend({}, defaults, uoptions);

    if (e != undefined) e.preventDefault();
    $.ajax({
        url: $this.attr("href"),
        dataType: 'json'
    }).done(function(data) {
        if (options.ok_cb) options.ok_cb(data);
        if (data) {
            $("body").notify("success", data, 2000);
        }
    });
}

/*
 * Simple function that redirect ajax requests to the login page if
 * the status code received with a response is equal to 278.
 */
function ajax_login_redirect(xhr) {
    if (xhr.status != 278) {
        return;
    }
    var params = "?next=" + window.location.pathname;

    window.location.href =
        xhr.getResponseHeader("Location").replace(/\?.*$/, params);
}

function activate_widget(e) {
    var $this = $(this);
    var widget_id = $this.attr("id").substr(0, $this.attr("id").length - 4);
    var $widget = $('#' + widget_id);

    if ($this.prop("checked")) {
        $widget.attr('disabled', true);
    } else {
        $widget.attr('disabled', false);
    }
}

/*
 * Default error handler for AJAX requests.
 */
function default_ajax_error_handler(event, jqxhr, settings) {
    try {
        var data = $.parseJSON(jqxhr.responseText);
    } catch (x) {
        var data = gettext("Internal error");
    }
    $('body').notify('error', data);
}

$(document).ready(function() {
    $(document).ajaxSuccess(function(e, xhr, settings) { ajax_login_redirect(xhr); });
    $(document).ajaxError(default_ajax_error_handler);
    $(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
    $(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
    $(document).on('click', '.activator', activate_widget);
    $(".help").popover({trigger: 'hover'}).click(function(e) {e.preventDefault();});
});
<|endoftext|>


<commit_before>/* 전체 서버 상태 2017-01-02 */
var allServerViewHost = function() {
    $.blockUI(blockUI_opt_all);
    $("[id^=base]").hide();
    $("#base_server").show();

    var server_data = '';
    zbxApi.allServerViewHost.get().done(function(data, status, jqXHR) {
        server_data = zbxApi.getDiskItem.success(data);
        serverOverView(server_data);
    });
}

function serverOverView(server_data) {
    $.blockUI(blockUI_opt_all);
    var serverStatus = '';
    var serverName = '';
    var serverIP = '';
    var serverPerCPU = 0;
    var serverPerMemory = 0;
    var serverPerDisk = 0;
    var serverOS = '-';
    var serverCPU = '-';
    var serverRAM = '-';
    var hostid = '';

    var tableDataObj = new Object();
    var tableDataArr = [];

    var serverOverViewHTML = '';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '상태	';
    serverOverViewHTML += '서버명	';
    serverOverViewHTML += 'IP주소	';
    serverOverViewHTML += 'CPU(%)	';
    serverOverViewHTML += '메모리(%)	';
    serverOverViewHTML += '디스크(%)	';
    serverOverViewHTML += '운영체제	';
    serverOverViewHTML += 'CPU	';
    serverOverViewHTML += 'RAM	';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';

    $.each(server_data.result, function(k, v) {
        serverStatus = '';
        serverName = v.name;
        serverIP = v.interfaces[0].ip;
        hostid = v.hostid;
        console.log("호스트 정보 : " + hostid);
        var osInfo = v.inventory.os;    //serverOS = v.inventory.os;
        if (osInfo === undefined) {
            serverOS = '-';
        }
        else {
            if (osInfo.match('Linux')) {
                serverOS = 'Linux';
            }
            else if (osInfo.match('Window')) {
                serverOS = 'Windows';
            }
            else {
                serverOS = '-';
            }
        }

        try {
            serverPerCPU = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
            serverPerCPU = Math.floor(serverPerCPU * 100) / 100;

            if (serverPerCPU == 100)
                serverPerCPU = 0;
        } catch (e) {
            console.log(e);
        }

        try {
            serverPerMemory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
            serverPerMemory = Math.floor(serverPerMemory * 100) / 100;
        } catch (e) {
            console.log(e);
        }

        var value;
        try {
            // TODO pfree to pused.
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
        } catch (e) {
            console.log(e);
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
        }
        serverPerDisk = 100 - value;

        if (serverPerDisk == 100)
            serverPerDisk = 0;
        serverPerDisk = Math.floor(serverPerDisk * 100) / 100;

        var infoArr = v.inventory.hardware;     //serverCPU + serverRAM = v.inventory.hardware
        if (infoArr === undefined || infoArr == '') {
            serverCPU = '-';
            serverRAM = '-';
        } else {
            var splitInfo = infoArr.split(",");
            serverCPU = splitInfo[0].slice(4);
            serverRAM = splitInfo[1].slice(5);
        }

        var tableDataObj = new Object();
        tableDataObj.hostid = hostid;
        tableDataObj.status = serverStatus;
        tableDataObj.name = serverName;
        tableDataObj.ip = serverIP;
        tableDataObj.perCPU = serverPerCPU;
        tableDataObj.perMemory = serverPerMemory;
        tableDataObj.perDisk = serverPerDisk;
        tableDataObj.OS = serverOS;
        tableDataObj.CPU = serverCPU;
        tableDataObj.RAM = serverRAM;
        tableDataArr.push(tableDataObj);

        serverOverViewHTML += '
';
        serverOverViewHTML += '' + serverStatus + '	';
        serverOverViewHTML += '' + serverName + '	';
        serverOverViewHTML += '' + serverIP + '	';
        serverOverViewHTML += '
' + serverPerCPU + '%
	';
        serverOverViewHTML += '
' + serverPerMemory + '%
	';
        serverOverViewHTML += '
' + serverPerDisk + '%
	';
        serverOverViewHTML += '' + serverOS + '	';
        serverOverViewHTML += '' + serverCPU + '	';
        serverOverViewHTML += '' + serverRAM + '	';
        serverOverViewHTML += '
';
    });

    serverOverViewHTML += '
';
    $("#serverList").empty();
    $("#serverList").append(serverOverViewHTML);

    $.each(server_data.result, function(k, v) {
        hostid = v.hostid;
        var item_id = '';

        //화면 이동
        $("#Name_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_")+1);
            $("#info_" + hostid).click();
        });

        $("#PerCPU_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#cpu_" + hostid).click();
        });

        $("#PerMemory_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#memory_" + hostid).click();
        });

        $("#PerDisk_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#disk_" + hostid).click();
        });
    });

    //테이블의 th col 클릭시 정렬된 테이블 내용 생성
    var $table = $("#serverList");
    $('th', $table).each(function (column) {
        $(this).click(function() {
            var sortTable = '';
            var currentThObj = $(this);
            var MAX_COUNT = tableDataArr.length;

            if($(this).is('.sorting_desc')){
                console.log(" >>>>> sorting_desc <<<<<");
                tableDataArr.sort(function (a, b) {
                    if(column == 0) {
                        return a.name  b.name ? 1 : 0;
                    }
                });
                currentThObj.removeClass("sorting_desc").addClass("sorting_asc");
            }else{
                tableDataArr.sort(function (a, b) {
                    console.log(" >>>>> sorting_asc <<<<<");
                    if(column == 0){
                        return a.name > b.name ? -1 : a.name < b.name ? 1 : 0;
                    }
                });
                currentThObj.removeClass("sorting_asc").addClass("sorting_desc");
            }//end else
            $('tbody', $table).empty();

            for(var i=0; i<MAX_COUNT; i++){
                var hostid = tableDataArr[i].hostid;
                sortTable += '
';
                sortTable += '' + tableDataArr[i].status + '	';
                sortTable += '' + tableDataArr[i].name + '	';
                sortTable += '' + tableDataArr[i].ip + '	';
                sortTable += '
' + tableDataArr[i].perCPU + '%
	';
                sortTable += '
' + tableDataArr[i].perMemory + '%
	';
                sortTable += '
' + tableDataArr[i].perDisk + '%
	';
                sortTable += '' + tableDataArr[i].OS + '	';
                sortTable += '' + tableDataArr[i].CPU + '	';
                sortTable += '' + tableDataArr[i].RAM + '	';
                sortTable += '
';
            }//end for
            $('tbody', $table).append(sortTable);

        })//end click function
    }) //end each

    //page reloag
    $("#reload_serverOverview").click(function(){
        //int.allServerViewHost();
        console.log("reload_serverOverview");

        var cpu = '';
        var memory = '';
        var disk = '';
        var ROW_COUNT = tableDataArr.length;
        //alert("ROW_COUNT : " + ROW_COUNT);

        for(var i=0; i<ROW_COUNT; i++){
            var hostid = tableDataArr[i].hostid;
            try {
                cpu = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
                cpu = Math.floor(cpu * 100) / 100;

                if (cpu == 100)
                    cpu = 0;
            } catch (e) {
                console.log(e);
            }
            console.log("perCPU_"+hostid + " >> " + $("#perCPU_"+hostid).width() +" / " + $("#perCPU_"+hostid).html());
            $("#perCPU_"+hostid).width(cpu+"%");
            $("#perCPU_"+hostid).html(cpu+"%");

            try {
                memory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
                memory = Math.floor(memory * 100) / 100;
            } catch (e) {
                console.log(e);
            }
            if(memory == 0)
                memory = 0;
            console.log("perMemory_"+hostid + " >> " + $("#perMemory_"+hostid).width() +" / " + $("#perMemory_"+hostid).html());
            $("#perMemory_"+hostid).width(memory+"%");
            $("#perMemory_"+hostid).html(memory+"%");

            var value;
            try {
                // TODO pfree to pused.
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
            }
            disk = 100 - value;

            if (disk == 100)
                disk = 0;
            disk = Math.floor(disk * 100) / 100;
            console.log("perDisk_"+hostid + " >> " + $("#perDisk_"+hostid).width() +" / " + $("#perDisk_"+hostid).html());
            $("#perDisk_"+hostid).width(disk+"%");
            $("#perDisk_"+hostid).html(disk+"%");
            console.log("================================");
        }
    });

    $(function ($) {
        $('#reload_serverOverview_selecter').change(function () {
            var selectVal = $(this).val();
            if (selectVal != 0) {
                $("#reload_serverOverview").attr({
                    "disabled": "disabled"
                });
            } else {
                $("#reload_serverOverview").removeAttr("disabled");
            }
        });
    });

    //자동 새로고침
    setInterval('$("#reload_serverOverview").click()', PAGE_RELOAD_TIME);

    $.unblockUI(blockUI_opt_all);
};<commit_msg>2017.02.21<commit_after>/* 전체 서버 상태 2017-01-02 */
var allServerViewHost = function() {
    $.blockUI(blockUI_opt_all);
    $("[id^=base]").hide();
    $("#base_server").show();

    var server_data = '';
    zbxApi.allServerViewHost.get().done(function(data, status, jqXHR) {
        server_data = zbxApi.getDiskItem.success(data);
        serverOverView(server_data);
    });
}

function serverOverView(server_data) {
    $.blockUI(blockUI_opt_all);
    var serverStatus = '';
    var hostid = '';
    var serverName = '';
    var serverIP = '';
    var serverPerCPU = 0;
    var serverPerMemory = 0;
    var serverPerDisk = 0;
    var serverOS = '-';
    var serverCPU = '-';
    var serverRAM = '-';

    var tableDataObj = new Object();
    var tableDataArr = [];

    var serverOverViewHTML = '';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '상태	';
    serverOverViewHTML += '서버명	';
    serverOverViewHTML += 'IP주소	';
    serverOverViewHTML += 'CPU(%)	';
    serverOverViewHTML += '메모리(%)	';
    serverOverViewHTML += '디스크(%)	';
    serverOverViewHTML += '운영체제	';
    serverOverViewHTML += 'CPU	';
    serverOverViewHTML += 'RAM	';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';

    $.each(server_data.result, function(k, v) {
        serverStatus = '';
        serverName = v.name;
        serverIP = v.interfaces[0].ip;
        hostid = v.hostid;
        console.log("호스트 정보 : " + hostid);
        var osInfo = v.inventory.os;    //serverOS = v.inventory.os;
        if (osInfo === undefined) {
            serverOS = '-';
        }
        else {
            if (osInfo.match('Linux')) {
                serverOS = 'Linux';
            }
            else if (osInfo.match('Window')) {
                serverOS = 'Windows';
            }
            else {
                serverOS = '-';
            }
        }

        try {
            serverPerCPU = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
            serverPerCPU = Math.floor(serverPerCPU * 100) / 100;

            if (serverPerCPU == 100)
                serverPerCPU = 0;
        } catch (e) {
            console.log(e);
        }

        try {
            serverPerMemory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
            serverPerMemory = Math.floor(serverPerMemory * 100) / 100;
        } catch (e) {
            console.log(e);
        }

        var value;
        try {
            // TODO pfree to pused.
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
        } catch (e) {
            console.log(e);
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
        }
        serverPerDisk = 100 - value;

        if (serverPerDisk == 100)
            serverPerDisk = 0;
        serverPerDisk = Math.floor(serverPerDisk * 100) / 100;

        var infoArr = v.inventory.hardware;     //serverCPU + serverRAM = v.inventory.hardware
        if (infoArr === undefined || infoArr == '') {
            serverCPU = '-';
            serverRAM = '-';
        } else {
            var splitInfo = infoArr.split(",");
            serverCPU = splitInfo[0].slice(4);
            serverRAM = splitInfo[1].slice(5);
        }

        var tableDataObj = new Object();
        tableDataObj.hostid = hostid;
        tableDataObj.status = serverStatus;
        tableDataObj.name = serverName;
        tableDataObj.ip = serverIP;
        tableDataObj.perCPU = serverPerCPU;
        tableDataObj.perMemory = serverPerMemory;
        tableDataObj.perDisk = serverPerDisk;
        tableDataObj.OS = serverOS;
        tableDataObj.CPU = serverCPU;
        tableDataObj.RAM = serverRAM;
        tableDataArr.push(tableDataObj);

        serverOverViewHTML += '
';
        serverOverViewHTML += '' + serverStatus + '	';
        serverOverViewHTML += '' + serverName + '	';
        serverOverViewHTML += '' + serverIP + '	';
        serverOverViewHTML += '
' + serverPerCPU + '%
	';
        serverOverViewHTML += '
' + serverPerMemory + '%
	';
        serverOverViewHTML += '
' + serverPerDisk + '%
	';
        serverOverViewHTML += '' + serverOS + '	';
        serverOverViewHTML += '' + serverCPU + '	';
        serverOverViewHTML += '' + serverRAM + '	';
        serverOverViewHTML += '
';
    });

    serverOverViewHTML += '
';
    $("#serverList").empty();
    $("#serverList").append(serverOverViewHTML);

    $.each(server_data.result, function(k, v) {
        hostid = v.hostid;
        var item_id = '';

        //화면 이동
        $("#Name_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_")+1);
            $("#info_" + hostid).click();
        });

        $("#PerCPU_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#cpu_" + hostid).click();
        });

        $("#PerMemory_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#memory_" + hostid).click();
        });

        $("#PerDisk_" + hostid).dblclick(function () {
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#disk_" + hostid).click();
        });
    });

    //테이블의 th col 클릭시 정렬된 테이블 내용 생성
    var $table = $("#serverList");
    $('th', $table).each(function (column) {
        $(this).click(function() {
            var sortTable = '';
            var currentThObj = $(this);
            var MAX_COUNT = tableDataArr.length;

            if($(this).is('.sorting_desc')){
                console.log(" >>>>> sorting_desc <<<<<");
                tableDataArr.sort(function (a, b) {
                    if(column == 0) {
                        return a.name  b.name ? 1 : 0;
                    }
                });
                currentThObj.removeClass("sorting_desc").addClass("sorting_asc");
            }else{
                tableDataArr.sort(function (a, b) {
                    console.log(" >>>>> sorting_asc <<<<<");
                    if(column == 0){
                        return a.name > b.name ? -1 : a.name < b.name ? 1 : 0;
                    }
                });
                currentThObj.removeClass("sorting_asc").addClass("sorting_desc");
            }//end else
            $('tbody', $table).empty();

            for(var i=0; i<MAX_COUNT; i++){
                var hostid = tableDataArr[i].hostid;
                sortTable += '
';
                sortTable += '' + tableDataArr[i].status + '	';
                sortTable += '' + tableDataArr[i].name + '	';
                sortTable += '' + tableDataArr[i].ip + '	';
                sortTable += '
' + tableDataArr[i].perCPU + '%
	';
                sortTable += '
' + tableDataArr[i].perMemory + '%
	';
                sortTable += '
' + tableDataArr[i].perDisk + '%
	';
                sortTable += '' + tableDataArr[i].OS + '	';
                sortTable += '' + tableDataArr[i].CPU + '	';
                sortTable += '' + tableDataArr[i].RAM + '	';
                sortTable += '
';
            }//end for
            $('tbody', $table).append(sortTable);

        })//end click function
    }) //end each

    //page reloag
    $("#reload_serverOverview").click(function(){
        //int.allServerViewHost();
        console.log("reload_serverOverview");

        var cpu = '';
        var memory = '';
        var disk = '';
        var ROW_COUNT = tableDataArr.length;
        //alert("ROW_COUNT : " + ROW_COUNT);

        for(var i=0; i<ROW_COUNT; i++){
            var hostid = tableDataArr[i].hostid;
            try {
                cpu = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
                cpu = Math.floor(cpu * 100) / 100;

                if (cpu == 100)
                    cpu = 0;
            } catch (e) {
                console.log(e);
            }
            console.log("perCPU_"+hostid + " >> " + $("#perCPU_"+hostid).width() +" / " + $("#perCPU_"+hostid).html());
            $("#perCPU_"+hostid).width(cpu+"%");
            $("#perCPU_"+hostid).html(cpu+"%");

            try {
                memory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
                memory = Math.floor(memory * 100) / 100;
            } catch (e) {
                console.log(e);
            }
            if(memory == 0)
                memory = 0;
            console.log("perMemory_"+hostid + " >> " + $("#perMemory_"+hostid).width() +" / " + $("#perMemory_"+hostid).html());
            $("#perMemory_"+hostid).width(memory+"%");
            $("#perMemory_"+hostid).html(memory+"%");

            var value;
            try {
                // TODO pfree to pused.
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
            }
            disk = 100 - value;

            if (disk == 100)
                disk = 0;
            disk = Math.floor(disk * 100) / 100;
            console.log("perDisk_"+hostid + " >> " + $("#perDisk_"+hostid).width() +" / " + $("#perDisk_"+hostid).html());
            $("#perDisk_"+hostid).width(disk+"%");
            $("#perDisk_"+hostid).html(disk+"%");
            console.log("================================");
        }
    });

    $(function ($) {
        $('#reload_serverOverview_selecter').change(function () {
            var selectVal = $(this).val();
            if (selectVal != 0) {
                $("#reload_serverOverview").attr({
                    "disabled": "disabled"
                });
            } else {
                $("#reload_serverOverview").removeAttr("disabled");
            }
        });
    });

    //자동 새로고침
    setInterval('$("#reload_serverOverview").click()', PAGE_RELOAD_TIME);

    $.unblockUI(blockUI_opt_all);
};<|endoftext|>


<commit_before>export default '1ke1af8hb8'
<commit_msg>test: UI update<commit_after>export default '1ke1ah02da'
<|endoftext|>


<commit_before>var Conversation = function (speciesList) {
  this.lastAnswer = null;
  this.lastAction = Date.now();
  this.firstmessage = true;
  this.inFindingProcess = false;

  this.speciesList = speciesList;

  let commonNames = speciesList.map((obj) => obj.commonName);
  let scientificNames = speciesList.map((obj) => obj.scientificName);
  this.speciesNames = commonNames.concat(scientificNames);

  this.location = null;
  this.species = null;

  this.isActive = function () {
    let diff = this.lastAction - Date.now();
    let fiveMinInMs = 1000 * 60 * 5;
    return diff <= fiveMinInMs;

  };
  this.setLocation = function (location) {
    this.location = location
  };
  this.processMessage = function (message) {
    console.log("Input> " + message);
    this.lastAction = Date.now();
    var splitedMessage = message.split(/[ ,]+/);

    if (this.firstmessage || match(splitedMessage, ["hey", "moin", "hallo", "hi", "servus"])) {
      this.firstmessage = false;
      var startText = 'Hey du, ich bin BioDiv und kann weiterhelfen, wenn du seltene Muscheln / Säugetiere oder Fische in deiner Umgebung gesichtet hast. ';

      var answerOptions = ["Hilfe", "Fund melden"];

      return {answer: startText, answerOptions: answerOptions};
    }
    let yes = ["ja", "ok", "jo", "jup"];
    let no = ["nein", "nö", "ne", "auf gar keinen fall", "halt die fresse"];

    if (match(splitedMessage, yes.concat(no))) {
      var userAnswer = message;
      var answerOptions = [];

      this.lastAnswer = null;
      if (match(splitedMessage, yes)) {
        var jaText = "Ich halte Dich auf dem Laufenden. 👍";
        return {answer: jaText, answerOptions: answerOptions};
      } else {
        var neinText = "Ok, frag' einfach, wenn du wissen willst, wie der Status ist. 😁 Ich bin bis auf weiteres stumm. 🙈🙊🙉";
        return {answer: neinText, answerOptions: answerOptions};
      }

    }

    if (match([message], ["Fund melden"])) {
      var answerOptions = [];

      var helpText = 'ℹ Alles klar du, dann lass uns loslegen und deinen Fund zusammen aufnehmen! Was für eine Spezies hast du denn gesehen?';

      this.inFindingProcess = true;

      return {answer: helpText, answerOptions: answerOptions};
    }

    if (this.inFindingProcess) {

      console.log(splitedMessage);
      console.log(this.speciesCommonNames);
      console.log(this.speciesSientificNames);

      if (match([message], ["Location set"])) {
        return {
          answer: "Nun weiß ich schon wo du dich befindest, Vielleicht möchtest du noch mehr angeben?",
          answerOptions: ["Nachweisquallität", "Nachweismethode", "Fund speichern"]
        };
      }
      else if (match(splitedMessage, ["Nachweismethode"])) {
        return {
          answer: "Okay welche der folgenden Nachweismethoden wurde verwendet?",
          answerOptions: [""]
        };
      }
      else if (match(splitedMessage, ["Nachweisquallität"])) {
        return {
          answer: "Wie war die genaue Nachweisquallität?",
          answerOptions: ["Nachweisquallität", "Nachweismethode"]
        };
      }
      else if (match([message], this.speciesNames)) {

        let potentialSpecies = this.speciesList.filter((species) => {

          let nameSplits = species.commonName.split(" ");
          nameSplits = nameSplits.concat(species.scientificName.split(" "));

          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "muschel" && name.toLowerCase().trim() != "mussel")
          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "clam");
          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "fisch" && name.toLowerCase().trim() != "fish")
          console.log("nameSplits", nameSplits);
          return match(splitedMessage, nameSplits)
        });

        console.log("potentialSpecies", potentialSpecies);

        if (potentialSpecies.length == 0) {
          return {
            answer: "Irgendwas ist hier schief gelaufen :( Ich konnte irgendwie keine Spezies finden ... "
          };
        }
        else if (potentialSpecies.length == 1) {
          return {
            answer: "Sehr schön, hab ich verstanden du hast " + message + " bei dir gesehen. " +
            "\n Es wäre super wenn du mir noch deinen Standort zeigen könntest?",
            locationRequest: true
          };
        } else {
          return {
            answer: "Huch da brauch ich noch ein wenig mehr Infos.\nEs gibt mehrere Spezies, bitte wähle die richtige aus: ",
            answerOptions: potentialSpecies.map((species) => species.commonName)
          };
        }

      }

      else if (this.speciesName == null) {

        console.log("Choose species text ", this.speciesCommonNames);

        let elements = this.speciesList.map((species) => {
          "use strict";

          return {
            title: species.commonName,
            subtitle: species.scientificName,
            item_url: species.links.self,
            image_url: species.imageUrl,
            buttons: [{
              type: "postback",
              title: "Ja, bin mir sicher!",
              payload: "Ja das ist meine Spezies",
              },
              {
              type: "postback",
              title: "Mhmm, am ehsten",
              payload: "Bin mir eher unsicher...",
            }],
          }
        });

        let attachment = {
          type: "template",
          payload: {
            template_type: "generic",
            elements: elements
          }
        };

        return {
          answer: "Leider habe ich dich nicht so recht verstanden, hier einige Vorschläge was für Spezies ich so im Angebot hätte",
          attachment: attachment
        }

      }

    }

    return {
      answer: "Ich konnte dich leider nicht verstehen... 😰",
      answerOptions: ["Hilfe"]
    }

  };

  return this;
};

function match(splitedMessage, keyWords) {

  for (var word in splitedMessage) {
    for (var keyWord in keyWords) {
      var lowerCaseWord = splitedMessage[word].toLowerCase();
      var lowerCaseKeyword = keyWords[keyWord].toLowerCase();

      if (lowerCaseWord == lowerCaseKeyword) {
        return true;
      }
    }
  }

  return false;
}

module.exports = Conversation;
<commit_msg>- add correct payload<commit_after>var Conversation = function (speciesList) {
  this.lastAnswer = null;
  this.lastAction = Date.now();
  this.firstmessage = true;
  this.inFindingProcess = false;

  this.speciesList = speciesList;

  let commonNames = speciesList.map((obj) => obj.commonName);
  let scientificNames = speciesList.map((obj) => obj.scientificName);
  this.speciesNames = commonNames.concat(scientificNames);

  this.location = null;
  this.species = null;
  this.date = Date.now();

  this.isActive = function () {
    let diff = this.lastAction - Date.now();
    let fiveMinInMs = 1000 * 60 * 5;
    return diff <= fiveMinInMs;

  };
  this.setLocation = function (location) {
    this.location = location
  };
  this.processMessage = function (message) {
    console.log("Input> " + message);
    this.lastAction = Date.now();
    var splitedMessage = message.split(/[ ,]+/);

    if (this.firstmessage || match(splitedMessage, ["hey", "moin", "hallo", "hi", "servus"])) {
      this.firstmessage = false;
      var startText = 'Hey du, ich bin BioDiv und kann weiterhelfen, wenn du seltene Muscheln / Säugetiere oder Fische in deiner Umgebung gesichtet hast. ';

      var answerOptions = ["Hilfe", "Fund melden"];

      return {answer: startText, answerOptions: answerOptions};
    }
    let yes = ["ja", "ok", "jo", "jup"];
    let no = ["nein", "nö", "ne", "auf gar keinen fall", "halt die fresse"];

    if (match(splitedMessage, yes.concat(no))) {
      var userAnswer = message;
      var answerOptions = [];

      this.lastAnswer = null;
      if (match(splitedMessage, yes)) {
        var jaText = "Ich halte Dich auf dem Laufenden. 👍";
        return {answer: jaText, answerOptions: answerOptions};
      } else {
        var neinText = "Ok, frag' einfach, wenn du wissen willst, wie der Status ist. 😁 Ich bin bis auf weiteres stumm. 🙈🙊🙉";
        return {answer: neinText, answerOptions: answerOptions};
      }

    }

    if (match([message], ["Fund melden"])) {
      var answerOptions = [];

      var helpText = 'ℹ Alles klar du, dann lass uns loslegen und deinen Fund zusammen aufnehmen! \n \n Schreibe mir einfach was du gesehen hat.';

      this.inFindingProcess = true;

      return {answer: helpText, answerOptions: answerOptions};
    }

    if (this.inFindingProcess) {

      console.log(splitedMessage);
      console.log(this.speciesCommonNames);
      console.log(this.speciesSientificNames);

      if (match([message], ["Location set"])) {
        return {
          answer: "Nun weiß ich schon wo du dich befindest, Vielleicht möchtest du noch mehr angeben?",
          answerOptions: ["Nachweisquallität", "Nachweismethode", "Fund speichern"]
        };
      }
      else if (match(splitedMessage, ["Nachweismethode"])) {
        return {
          answer: "Okay welche der folgenden Nachweismethoden wurde verwendet?",
          answerOptions: [""]
        };
      }
      else if (match(splitedMessage, ["Nachweisquallität"])) {
        return {
          answer: "Wie war die genaue Nachweisquallität?",
          answerOptions: ["Nachweisquallität", "Nachweismethode"]
        };
      }
      else if (match([message], this.speciesNames)) {

        let potentialSpecies = this.speciesList.filter((species) => {

          let nameSplits = species.commonName.split(" ");
          nameSplits = nameSplits.concat(species.scientificName.split(" "));

          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "muschel" && name.toLowerCase().trim() != "mussel")
          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "clam");
          nameSplits = nameSplits.filter((name) => name.toLowerCase().trim() != "fisch" && name.toLowerCase().trim() != "fish")
          console.log("nameSplits", nameSplits);
          return match(splitedMessage, nameSplits)
        });

        console.log("potentialSpecies", potentialSpecies);

        if (potentialSpecies.length == 0) {
          return {
            answer: "Irgendwas ist hier schief gelaufen :( Ich konnte irgendwie keine Spezies finden ... "
          };
        }
        else if (potentialSpecies.length == 1) {
          return {
            answer: "Sehr schön, hab ich verstanden du hast " + message + " bei dir gesehen. " +
            "\n Es wäre super wenn du mir noch deinen Standort zeigen könntest?",
            locationRequest: true
          };
        } else {
          return {
            answer: "Huch da brauch ich noch ein wenig mehr Infos.\nEs gibt mehrere Spezies, bitte wähle die richtige aus: ",
            answerOptions: potentialSpecies.map((species) => species.commonName)
          };
        }

      }

      else if (this.speciesName == null) {

        console.log("Choose species text ", this.speciesCommonNames);

        let elements = this.speciesList.map((species) => {
          "use strict";

          return {
            title: species.commonName,
            subtitle: species.scientificName,
            item_url: species.links.self,
            image_url: species.imageUrl,
            buttons: [{
              type: "postback",
              title: "Ja, bin mir sicher!",
              payload: "SPECIES_ID-" + species.id,
              },
              {
              type: "postback",
              title: "Mhmm, am ehsten",
              payload: "SPECIES_ID-" + species.id,
            }],
          }
        });

        let attachment = {
          type: "template",
          payload: {
            template_type: "generic",
            elements: elements
          }
        };

        return {
          answer: "Leider habe ich dich nicht so recht verstanden, hier einige Vorschläge was für Spezies ich so im Angebot hätte",
          attachment: attachment
        }

      }

    }

    return {
      answer: "Ich konnte dich leider nicht verstehen... 😰",
      answerOptions: ["Hilfe"]
    }

  };

  return this;
};

function match(splitedMessage, keyWords) {

  for (var word in splitedMessage) {
    for (var keyWord in keyWords) {
      var lowerCaseWord = splitedMessage[word].toLowerCase();
      var lowerCaseKeyword = keyWords[keyWord].toLowerCase();

      if (lowerCaseWord == lowerCaseKeyword) {
        return true;
      }
    }
  }

  return false;
}

module.exports = Conversation;
<|endoftext|>


<commit_before><commit_msg>add account models<commit_after>'use strict'

var BaseModel = require('capital-models').BaseModel;

module.exports = class Account extends BaseModel {
    constructor(source) {
        super('account', '1.0.0');

        // Define properties.
        this.username = '';
        this.password = '';
        this.isLocked = false;
        this.config = {};

        this.copy(source);
    }
}<|endoftext|>


<commit_before>PROTOTYPE.disable = function(state) {
	if(this.destroyed) { return this; }

	if('boolean' !== typeof state) {
		state = !(this.tooltip.hasClass(CLASS_DISABLED) || this.disabled);
	}

	if(this.rendered) {
		this.tooltip.toggleClass(CLASS_DISABLED, state)
			.attr('aria-disabled', state);
	}

	this.disabled = !!state;

	return this;
};

PROTOTYPE.enable = function() { return this.disable(FALSE); };

<commit_msg>Fix disable method for unrendered tooltips. Fixes #565<commit_after>PROTOTYPE.disable = function(state) {
	if(this.destroyed) { return this; }

	if('boolean' !== typeof state) {
		state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled);
	}

	if(this.rendered) {
		this.tooltip.toggleClass(CLASS_DISABLED, state)
			.attr('aria-disabled', state);
	}

	this.disabled = !!state;

	return this;
};

PROTOTYPE.enable = function() { return this.disable(FALSE); };

<|endoftext|>


<commit_before>export default {
  modal: {
    title: "About this project:",
    paragraphs: [
      "Hello there! You are interacting with a serveless ReactJs app hosted in an S3 bucket 💥 ",
      "Behind the scenes there's an AWS pipeline that listens to new commits merged into the Master branch of this repo, which compiles the code and puts it into a public S3 bucket.",
      "There are also unit tests to make sure everyhting is Honky dory everytime anything is changed in the code.",
      "I've also made the illustrations. This project was done to play with all the above technologies."
    ]
  }
};
<commit_msg>another fix to the content<commit_after>export default {
  modal: {
    title: "About this project:",
    paragraphs: [
      "Hello there! You are interacting with a serveless ReactJs app hosted in an S3 bucket 💥 ",
      "Behind the scenes there's an AWS pipeline that listens to new commits merged into the Master branch of a repo, which compiles the code and puts it into a public S3 bucket.",
      "There are also unit tests to make sure everyhting is Honky dory everytime anything is changed in the code.",
      "I've also made the illustrations. This project was done to play with all the above technologies."
    ]
  }
};
<|endoftext|>


<commit_before>import React from 'react'
import ApiLoginManager from './ApiLoginManager'
import * as DataUtils from '../client_data'
import {SUPPORT_PLATFORM_MAP} from '../../helpers/const'

const PLATFORM_NAME = SUPPORT_PLATFORM_MAP.medium.name
const PLATFORM_LABEL = SUPPORT_PLATFORM_MAP.medium.label

function updateAccount(name, clientData, serverData) {
  let account = Object.assign({}, clientData, serverData.data)
  DataUtils.updateAccount(name, account)
  return account
}

function getUsername(account) {
  return `${account.username}`
}

export default function(props) {
  let extendFields = [
    {
      name: 'accessToken',
      type: 'text',
      label: 'ACCESS TOKEN',
      placeholder: '请输入ACCESS TOKEN',
      required: true,
      value: ''
    }, {
      name: 'proxy',
      type: 'text',
      label: '代理地址',
      placeholder: '支持常用的HTTP代理以及Shadowsocks代理，格式：socks://127.0.0.1:1080',
      required: true,
      value: 'socks://127.0.0.1:1080'
    }
  ]
  return (
    <ApiLoginManager
      {...props}
      extends={extendFields}
      platformName={PLATFORM_NAME}
      platformLabel={PLATFORM_LABEL}
      updateAccount={updateAccount}
      getUsername={getUsername}
    />
  )
}
<commit_msg>better medium placeholder<commit_after>import React from 'react'
import ApiLoginManager from './ApiLoginManager'
import * as DataUtils from '../client_data'
import {SUPPORT_PLATFORM_MAP} from '../../helpers/const'

const PLATFORM_NAME = SUPPORT_PLATFORM_MAP.medium.name
const PLATFORM_LABEL = SUPPORT_PLATFORM_MAP.medium.label

function updateAccount(name, clientData, serverData) {
  let account = Object.assign({}, clientData, serverData.data)
  DataUtils.updateAccount(name, account)
  return account
}

function getUsername(account) {
  return `${account.username}`
}

export default function(props) {
  let extendFields = [
    {
      name: 'accessToken',
      type: 'text',
      label: 'ACCESS TOKEN',
      placeholder: '前往 https://medium.com/me/settings 底部Integration tokens添加',
      required: true,
      value: ''
    }, {
      name: 'proxy',
      type: 'text',
      label: '代理地址',
      placeholder: '支持常用的HTTP代理以及Shadowsocks代理，格式：socks://127.0.0.1:1080',
      required: true,
      value: ''
    }
  ]
  return (
    <ApiLoginManager
      {...props}
      extends={extendFields}
      platformName={PLATFORM_NAME}
      platformLabel={PLATFORM_LABEL}
      updateAccount={updateAccount}
      getUsername={getUsername}
    />
  )
}
<|endoftext|>


<commit_before>'use strict';

angular.module('ddsApp').controller('FoyerRessourcesCtrl', function($scope, $state, ressourceTypes, SituationService, IndividuService) {
    $scope.momentDebutAnnee = moment().subtract('years', 1);
    $scope.momentFinAnnee = moment().startOf('month').subtract('months', 1);
    $scope.debutAnnee = $scope.momentDebutAnnee.format('MMMM YYYY');
    $scope.finAnnee = $scope.momentFinAnnee.format('MMMM YYYY');
    $scope.ressourceTypes = ressourceTypes;
    $scope.months = SituationService.getMonths();

    $scope.individuRefs = _.map($scope.situation.individus, function(individu) {
        return {
            label: IndividuService.label(individu),
            selectedRessourceTypes: {},
            ressources: [],
            individu: individu
        };
    });

    $scope.selectedRessourceTypes = {};

    $scope.$on('selectedRessourceTypes', function() {
        var hasSelectedRessources = !!_.filter($scope.selectedRessourceTypes).length;
        if (hasSelectedRessources) {
            if (1 < $scope.individuRefs.length) {
                $state.go('foyer.ressources.personnes');
            } else {
                $scope.individuRefs[0].selectedRessourceTypes = $scope.selectedRessourceTypes;
                $scope.initIndividusRessources();
                $state.go('foyer.ressources.montants');
            }
        } else {
            $state.go('foyer.patrimoine');
        }
    });

    $scope.$on('selectedPersonnes', function() {
        if (!_.filter($scope.individuRefs, 'hasRessources').length) {
            $state.go('foyer.patrimoine');
            return;
        }
        $scope.initIndividusRessources();
        $state.go('foyer.ressources.montants');
    });

    $scope.initIndividusRessources = function() {
        $scope.individuRefs.forEach(function(individuRef) {
            var previousRessources = individuRef.ressources;
            individuRef.ressources = [];
            individuRef.hasRessources = false;
            individuRef.hasRessourcesMicroTns = false;
            individuRef.hasRessourcesOtherTns = false;
            individuRef.hasRessourcesNonTns = false;

            ressourceTypes.forEach(function(ressourceType) {
                if (!individuRef.selectedRessourceTypes[ressourceType.id] || !$scope.selectedRessourceTypes[ressourceType.id]) {
                    return;
                }

                individuRef.hasRessources = true;
                if ('caMicroEntreprise' === ressourceType.id) {
                    individuRef.hasRessourcesMicroTns = true;
                } else if ('autresRevenusTns' === ressourceType.id) {
                    individuRef.hasRessourcesOtherTns = true;
                } else {
                    individuRef.hasRessourcesNonTns = true;
                }

                var ressource = _.find(previousRessources, {type: ressourceType});
                if (!ressource) {
                    ressource = {type: ressourceType};
                    if ('caMicroEntreprise' === ressourceType.id) {
                        ressource.tnsStructureType = 'auto_entrepreneur';
                        ressource.tnsActiviteType = 'bic';
                    }
                    ressource.montantAnnuel = 0;

                    if ('tns' !== ressourceType.category) {
                        ressource.months = [
                            { periode: $scope.months[0].id, montant: 0 },
                            { periode: $scope.months[1].id, montant: 0 },
                            { periode: $scope.months[2].id, montant: 0 }
                        ];
                    }
                }
                individuRef.ressources.push(ressource);
            });
        });
    };
});
<commit_msg>fix capture ressources avec plusieurs personnes<commit_after>'use strict';

angular.module('ddsApp').controller('FoyerRessourcesCtrl', function($scope, $state, ressourceTypes, SituationService, IndividuService) {
    $scope.momentDebutAnnee = moment().subtract('years', 1);
    $scope.momentFinAnnee = moment().startOf('month').subtract('months', 1);
    $scope.debutAnnee = $scope.momentDebutAnnee.format('MMMM YYYY');
    $scope.finAnnee = $scope.momentFinAnnee.format('MMMM YYYY');
    $scope.ressourceTypes = ressourceTypes;
    $scope.months = SituationService.getMonths();

    $scope.individuRefs = _.map($scope.situation.individus, function(individu) {
        return {
            label: IndividuService.label(individu),
            selectedRessourceTypes: {},
            ressources: [],
            individu: individu
        };
    });

    $scope.selectedRessourceTypes = {};

    $scope.$on('selectedRessourceTypes', function() {
        var hasSelectedRessources = !!_.filter($scope.selectedRessourceTypes).length;
        if (hasSelectedRessources) {
            if (1 < $scope.individuRefs.length) {
                $state.go('foyer.ressources.personnes');
            } else {
                $scope.individuRefs[0].selectedRessourceTypes = $scope.selectedRessourceTypes;
                $scope.initIndividusRessources();
                $state.go('foyer.ressources.montants');
            }
        } else {
            $state.go('foyer.patrimoine');
        }
    });

    $scope.$on('selectedPersonnes', function() {
        $scope.initIndividusRessources();
        if (!_.filter($scope.individuRefs, 'hasRessources').length) {
            $state.go('foyer.patrimoine');
            return;
        }
        $state.go('foyer.ressources.montants');
    });

    $scope.initIndividusRessources = function() {
        $scope.individuRefs.forEach(function(individuRef) {
            var previousRessources = individuRef.ressources;
            individuRef.ressources = [];
            individuRef.hasRessources = false;
            individuRef.hasRessourcesMicroTns = false;
            individuRef.hasRessourcesOtherTns = false;
            individuRef.hasRessourcesNonTns = false;

            ressourceTypes.forEach(function(ressourceType) {
                if (!individuRef.selectedRessourceTypes[ressourceType.id] || !$scope.selectedRessourceTypes[ressourceType.id]) {
                    return;
                }

                individuRef.hasRessources = true;
                if ('caMicroEntreprise' === ressourceType.id) {
                    individuRef.hasRessourcesMicroTns = true;
                } else if ('autresRevenusTns' === ressourceType.id) {
                    individuRef.hasRessourcesOtherTns = true;
                } else {
                    individuRef.hasRessourcesNonTns = true;
                }

                var ressource = _.find(previousRessources, {type: ressourceType});
                if (!ressource) {
                    ressource = {type: ressourceType};
                    if ('caMicroEntreprise' === ressourceType.id) {
                        ressource.tnsStructureType = 'auto_entrepreneur';
                        ressource.tnsActiviteType = 'bic';
                    }
                    ressource.montantAnnuel = 0;

                    if ('tns' !== ressourceType.category) {
                        ressource.months = [
                            { periode: $scope.months[0].id, montant: 0 },
                            { periode: $scope.months[1].id, montant: 0 },
                            { periode: $scope.months[2].id, montant: 0 }
                        ];
                    }
                }
                individuRef.ressources.push(ressource);
            });
        });
    };
});
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import Head from 'next/head';
import stringSimilarity from 'string-similarity';
import { nl2br, linkify } from '../util/text';

import AppLayout from 'components/AppLayout';
import ArticleInfo from 'components/ArticleInfo';
import ArticleItem from 'components/ArticleItem';
import CurrentReplies from 'components/CurrentReplies';
import RelatedReplies from 'components/RelatedReplies';
import ReplySearch from 'components/ReplySearch/ReplySearch.js';
import ReplyForm from 'components/ReplyForm';
import ReplyRequestReason from 'components/ReplyRequestReason';
import Hyperlinks from 'components/Hyperlinks';
import {
  load,
  loadAuth,
  submitReply,
  connectReply,
  searchReplies,
  searchRepiedArticle,
  updateArticleReplyStatus,
  voteReply,
  reset,
  voteReplyRequest,
} from 'ducks/articleDetail';

import { detailStyle, tabMenuStyle } from './article.styles';

class ArticlePage extends React.Component {
  state = {
    tab: 'search', // 'new, 'related', 'search'
  };

  static async getInitialProps({ store: { dispatch }, query: { id } }) {
    await dispatch(load(id));
    return { id };
  }

  componentDidMount() {
    const { id, dispatch } = this.props;
    return dispatch(loadAuth(id));
  }

  handleConnect = ({ target: { value: replyId } }) => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    return dispatch(connectReply(id, replyId)).then(this.scrollToReplySection);
  };

  handleSearchReply = ({ target: { value: queryString } }, after) => {
    const { dispatch } = this.props;
    dispatch(
      searchReplies({
        q: queryString,
        after,
      })
    );
    dispatch(
      searchRepiedArticle({
        q: queryString,
      })
    );
  };

  handleSubmit = reply => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    return dispatch(
      submitReply({
        ...reply,
        articleId: id,
      })
    ).then(this.scrollToReplySection);
  };

  handleReplyConnectionDelete = conn => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    return dispatch(
      updateArticleReplyStatus(id, conn.get('replyId'), 'DELETED')
    );
  };

  handleReplyConnectionRestore = conn => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    return dispatch(
      updateArticleReplyStatus(id, conn.get('replyId'), 'NORMAL')
    ).then(this.scrollToReplySection);
  };

  handleVoteReplyRequest = (replyRequestId, voteType, indexOfReplyRequests) => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    dispatch(
      voteReplyRequest(id, replyRequestId, voteType, indexOfReplyRequests)
    );
  };

  handleReplyConnectionVote = (conn, vote) => {
    const {
      dispatch,
      query: { id },
    } = this.props;
    return dispatch(voteReply(id, conn.get('replyId'), vote));
  };

  handleTabChange = tab => () => {
    this.setState({
      tab,
    });
  };

  scrollToReplySection = () => {
    if (!this._replySectionEl) return;
    this._replySectionEl.scrollIntoView({
      behavior: 'smooth',
    });
  };

  componentWillUnmount() {
    const { dispatch } = this.props;
    dispatch(reset());
  }

  renderTabMenu = () => {
    const { data } = this.props;
    const { tab } = this.state;
    const relatedReplyCount = data.get('relatedReplies').size;

    return (

        <li
          onClick={this.handleTabChange('new')}
          className={`tab ${tab === 'new' ? 'active' : ''}`}
        >
          撰寫回應

          {relatedReplyCount === 0 ? (
            '無相關回應'
          ) : (

              使用相關回應 {relatedReplyCount}

          )}

        <li
          onClick={this.handleTabChange('search')}
          className={`tab ${tab === 'search' ? 'active' : ''}`}
        >
          搜尋

    );
  };

  renderNewReplyTab = () => {
    const { data, isReplyLoading } = this.props;
    const { tab } = this.state;

    const article = data.get('article');
    const relatedReplies = data.get('relatedReplies');
    const searchArticles = data.get('searchArticles');
    const searchReplies = data.get('searchReplies');

    const articleText = article.get('text', '');
    const getArticleSimilarity = relatedArticleText =>
      stringSimilarity.compareTwoStrings(articleText, relatedArticleText);

    switch (tab) {
      case 'new':
        return (
          <ReplyForm onSubmit={this.handleSubmit} disabled={isReplyLoading} />
        );

      case 'related':
        return (
          <RelatedReplies
            onConnect={this.handleConnect}
            relatedReplies={relatedReplies}
            getArticleSimilarity={getArticleSimilarity}
          />
        );

      case 'search':
        return (
          <ReplySearch
            onConnect={this.handleConnect}
            onSearch={this.handleSearchReply}
            articles={searchArticles}
            replies={searchReplies}
          />
        );

      default:
        return null;
    }
  };

  render() {
    const { data, isLoading, isReplyLoading } = this.props;

    const article = data.get('article');
    const replyConnections = data.get('replyConnections');
    const relatedArticles = data.get('relatedArticles');

    if (isLoading && article === null) {
      return
Loading...
;
    }

    if (article === null) {
      return
Article not found.
;
    }

    const slicedArticleTitle = article.get('text').slice(0, 15);

    return (
      <AppLayout>

            <title>{slicedArticleTitle}⋯⋯ | Cofacts 真的假的</title>

訊息原文

              <ArticleInfo article={article} />

              {nl2br(
                linkify(article.get('text'), {
                  props: {
                    target: '_blank',
                  },
                })
              )}
              <Hyperlinks hyperlinks={article.get('hyperlinks')} />

              {article.get('replyRequests').map((replyRequest, index) => {
                return (
                  <ReplyRequestReason
                    key={`reason-${index}`}
                    index={index}
                    articleId={article.get('id')}
                    replyRequest={replyRequest}
                    isArticleCreator={index === 0}
                    onVoteReason={this.handleVoteReplyRequest}
                  />
                );
              })}

 (this._replySectionEl = replySectionEl)}
          >

現有回應

            <CurrentReplies
              replyConnections={replyConnections}
              disabled={isReplyLoading}
              onDelete={this.handleReplyConnectionDelete}
              onRestore={this.handleReplyConnectionRestore}
              onVote={this.handleReplyConnectionVote}
            />

增加新回應

            {this.renderTabMenu()}

{this.renderNewReplyTab()}

          {relatedArticles.size ? (

你可能也會對這些類似文章有興趣

                {relatedArticles.map(article => (
                  <ArticleItem key={article.get('id')} article={article} />
                ))}

          ) : (
            ''
          )}

      </AppLayout>
    );
  }
}

function mapStateToProps({ articleDetail }) {
  return {
    isLoading: articleDetail.getIn(['state', 'isLoading']),
    isReplyLoading: articleDetail.getIn(['state', 'isReplyLoading']),
    data: articleDetail.get('data'),
  };
}

export default connect(mapStateToProps)(ArticlePage);
<commit_msg>Fix article page's article ID loading A regression made by #149<commit_after>import React from 'react';
import { connect } from 'react-redux';
import Head from 'next/head';
import stringSimilarity from 'string-similarity';
import { nl2br, linkify } from '../util/text';

import AppLayout from 'components/AppLayout';
import ArticleInfo from 'components/ArticleInfo';
import ArticleItem from 'components/ArticleItem';
import CurrentReplies from 'components/CurrentReplies';
import RelatedReplies from 'components/RelatedReplies';
import ReplySearch from 'components/ReplySearch/ReplySearch.js';
import ReplyForm from 'components/ReplyForm';
import ReplyRequestReason from 'components/ReplyRequestReason';
import Hyperlinks from 'components/Hyperlinks';
import {
  load,
  loadAuth,
  submitReply,
  connectReply,
  searchReplies,
  searchRepiedArticle,
  updateArticleReplyStatus,
  voteReply,
  reset,
  voteReplyRequest,
} from 'ducks/articleDetail';

import { detailStyle, tabMenuStyle } from './article.styles';

class ArticlePage extends React.Component {
  state = {
    tab: 'search', // 'new, 'related', 'search'
  };

  static async getInitialProps({ store: { dispatch }, query: { id } }) {
    await dispatch(load(id));
    return { id };
  }

  componentDidMount() {
    const { id, dispatch } = this.props;
    return dispatch(loadAuth(id));
  }

  handleConnect = ({ target: { value: replyId } }) => {
    const { dispatch, id } = this.props;
    return dispatch(connectReply(id, replyId)).then(this.scrollToReplySection);
  };

  handleSearchReply = ({ target: { value: queryString } }, after) => {
    const { dispatch } = this.props;
    dispatch(
      searchReplies({
        q: queryString,
        after,
      })
    );
    dispatch(
      searchRepiedArticle({
        q: queryString,
      })
    );
  };

  handleSubmit = reply => {
    const { dispatch, id } = this.props;
    return dispatch(
      submitReply({
        ...reply,
        articleId: id,
      })
    ).then(this.scrollToReplySection);
  };

  handleReplyConnectionDelete = conn => {
    const { dispatch, id } = this.props;
    return dispatch(
      updateArticleReplyStatus(id, conn.get('replyId'), 'DELETED')
    );
  };

  handleReplyConnectionRestore = conn => {
    const { dispatch, id } = this.props;
    return dispatch(
      updateArticleReplyStatus(id, conn.get('replyId'), 'NORMAL')
    ).then(this.scrollToReplySection);
  };

  handleVoteReplyRequest = (replyRequestId, voteType, indexOfReplyRequests) => {
    const { dispatch, id } = this.props;
    dispatch(
      voteReplyRequest(id, replyRequestId, voteType, indexOfReplyRequests)
    );
  };

  handleReplyConnectionVote = (conn, vote) => {
    const { dispatch, id } = this.props;
    return dispatch(voteReply(id, conn.get('replyId'), vote));
  };

  handleTabChange = tab => () => {
    this.setState({
      tab,
    });
  };

  scrollToReplySection = () => {
    if (!this._replySectionEl) return;
    this._replySectionEl.scrollIntoView({
      behavior: 'smooth',
    });
  };

  componentWillUnmount() {
    const { dispatch } = this.props;
    dispatch(reset());
  }

  renderTabMenu = () => {
    const { data } = this.props;
    const { tab } = this.state;
    const relatedReplyCount = data.get('relatedReplies').size;

    return (

        <li
          onClick={this.handleTabChange('new')}
          className={`tab ${tab === 'new' ? 'active' : ''}`}
        >
          撰寫回應

          {relatedReplyCount === 0 ? (
            '無相關回應'
          ) : (

              使用相關回應 {relatedReplyCount}

          )}

        <li
          onClick={this.handleTabChange('search')}
          className={`tab ${tab === 'search' ? 'active' : ''}`}
        >
          搜尋

    );
  };

  renderNewReplyTab = () => {
    const { data, isReplyLoading } = this.props;
    const { tab } = this.state;

    const article = data.get('article');
    const relatedReplies = data.get('relatedReplies');
    const searchArticles = data.get('searchArticles');
    const searchReplies = data.get('searchReplies');

    const articleText = article.get('text', '');
    const getArticleSimilarity = relatedArticleText =>
      stringSimilarity.compareTwoStrings(articleText, relatedArticleText);

    switch (tab) {
      case 'new':
        return (
          <ReplyForm onSubmit={this.handleSubmit} disabled={isReplyLoading} />
        );

      case 'related':
        return (
          <RelatedReplies
            onConnect={this.handleConnect}
            relatedReplies={relatedReplies}
            getArticleSimilarity={getArticleSimilarity}
          />
        );

      case 'search':
        return (
          <ReplySearch
            onConnect={this.handleConnect}
            onSearch={this.handleSearchReply}
            articles={searchArticles}
            replies={searchReplies}
          />
        );

      default:
        return null;
    }
  };

  render() {
    const { data, isLoading, isReplyLoading } = this.props;

    const article = data.get('article');
    const replyConnections = data.get('replyConnections');
    const relatedArticles = data.get('relatedArticles');

    if (isLoading && article === null) {
      return
Loading...
;
    }

    if (article === null) {
      return
Article not found.
;
    }

    const slicedArticleTitle = article.get('text').slice(0, 15);

    return (
      <AppLayout>

            <title>{slicedArticleTitle}⋯⋯ | Cofacts 真的假的</title>

訊息原文

              <ArticleInfo article={article} />

              {nl2br(
                linkify(article.get('text'), {
                  props: {
                    target: '_blank',
                  },
                })
              )}
              <Hyperlinks hyperlinks={article.get('hyperlinks')} />

              {article.get('replyRequests').map((replyRequest, index) => {
                return (
                  <ReplyRequestReason
                    key={`reason-${index}`}
                    index={index}
                    articleId={article.get('id')}
                    replyRequest={replyRequest}
                    isArticleCreator={index === 0}
                    onVoteReason={this.handleVoteReplyRequest}
                  />
                );
              })}

 (this._replySectionEl = replySectionEl)}
          >

現有回應

            <CurrentReplies
              replyConnections={replyConnections}
              disabled={isReplyLoading}
              onDelete={this.handleReplyConnectionDelete}
              onRestore={this.handleReplyConnectionRestore}
              onVote={this.handleReplyConnectionVote}
            />

增加新回應

            {this.renderTabMenu()}

{this.renderNewReplyTab()}

          {relatedArticles.size ? (

你可能也會對這些類似文章有興趣

                {relatedArticles.map(article => (
                  <ArticleItem key={article.get('id')} article={article} />
                ))}

          ) : (
            ''
          )}

      </AppLayout>
    );
  }
}

function mapStateToProps({ articleDetail }) {
  return {
    isLoading: articleDetail.getIn(['state', 'isLoading']),
    isReplyLoading: articleDetail.getIn(['state', 'isReplyLoading']),
    data: articleDetail.get('data'),
  };
}

export default connect(mapStateToProps)(ArticlePage);
<|endoftext|>


<commit_before>// If global `URL` constructor is available, use it
const URL_ = typeof URL === 'function' ? URL : require('url-parse')
const { Plugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator')
const RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue')
const { RequestClient } = require('@uppy/companion-client')
const XHRUpload = require('@uppy/xhr-upload')
const qsStringify = require('qs-stringify')

function resolveUrl (origin, link) {
  return new URL_(link, origin).toString()
}

function isXml (content, xhr) {
  const contentType = (xhr.headers ? xhr.headers['content-type'] : xhr.getResponseHeader('Content-Type'))
    // Get rid of mime parameters like charset=utf-8
    .replace(/;.*$/, '')
    .toLowerCase()
  if (typeof contentType === 'string') {
    if (contentType === 'application/xml' || contentType === 'text/xml') {
      return true
    }
    // GCS uses text/html for some reason
    // https://github.com/transloadit/uppy/issues/896
    if (contentType === 'text/html' && /^<\?xml /.test(content)) {
      return true
    }
  }
  return false
}

function getXmlValue (source, key) {
  const start = source.indexOf(`<${key}>`)
  const end = source.indexOf(`</${key}>`, start)
  return start !== -1 && end !== -1
    ? source.slice(start + key.length + 2, end)
    : ''
}

function assertServerError (res) {
  if (res && res.error) {
    const error = new Error(res.message)
    Object.assign(error, res.error)
    throw error
  }
  return res
}

module.exports = class AwsS3 extends Plugin {
  static VERSION = require('../package.json').version

  constructor (uppy, opts) {
    super(uppy, opts)
    this.type = 'uploader'
    this.id = this.opts.id || 'AwsS3'
    this.title = 'AWS S3'

    this.defaultLocale = {
      strings: {
        preparingUpload: 'Preparing upload...'
      }
    }

    const defaultOptions = {
      timeout: 30 * 1000,
      limit: 0,
      metaFields: [], // have to opt in
      getUploadParameters: this.getUploadParameters.bind(this)
    }

    this.opts = { ...defaultOptions, ...opts }

    this.i18nInit()

    this.client = new RequestClient(uppy, opts)
    this.prepareUpload = this.prepareUpload.bind(this)
    this.requests = new RateLimitedQueue(this.opts.limit)
  }

  setOptions (newOpts) {
    super.setOptions(newOpts)
    this.i18nInit()
  }

  i18nInit () {
    this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
    this.i18n = this.translator.translate.bind(this.translator)
    this.setPluginState() // so that UI re-renders and we see the updated locale
  }

  getUploadParameters (file) {
    if (!this.opts.companionUrl) {
      throw new Error('Expected a `companionUrl` option containing a Companion address.')
    }

    const filename = encodeURIComponent(file.meta.name)
    const type = encodeURIComponent(file.meta.type)
    const metadata = {}
    this.opts.metaFields.forEach((key) => {
      if (file.meta[key] != null) {
        metadata[key] = file.meta[key].toString()
      }
    })

    const query = qsStringify({ filename, type, metadata })
    return this.client.get(`s3/params?${query}`)
      .then(assertServerError)
  }

  validateParameters (file, params) {
    const valid = typeof params === 'object' && params &&
      typeof params.url === 'string' &&
      (typeof params.fields === 'object' || params.fields == null) &&
      (params.method == null || /^(put|post)$/i.test(params.method))

    if (!valid) {
      const err = new TypeError(`AwsS3: got incorrect result from 'getUploadParameters()' for file '${file.name}', expected an object '{ url, method, fields, headers }'.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
      console.error(err)
      throw err
    }

    return params
  }

  prepareUpload (fileIDs) {
    fileIDs.forEach((id) => {
      const file = this.uppy.getFile(id)
      this.uppy.emit('preprocess-progress', file, {
        mode: 'determinate',
        message: this.i18n('preparingUpload'),
        value: 0
      })
    })

    // Wrapping rate-limited opts.getUploadParameters in a Promise takes some boilerplate!
    const getUploadParameters = this.requests.wrapPromiseFunction((file) => {
      return this.opts.getUploadParameters(file)
    })

    return Promise.all(
      fileIDs.map((id) => {
        const file = this.uppy.getFile(id)
        return getUploadParameters(file)
          .then((params) => {
            return this.validateParameters(file, params)
          })
          .then((params) => {
            this.uppy.emit('preprocess-progress', file, {
              mode: 'determinate',
              message: this.i18n('preparingUpload'),
              value: 1
            })
            return params
          })
          .catch((error) => {
            this.uppy.emit('upload-error', file, error)
          })
      })
    ).then((responses) => {
      const updatedFiles = {}
      fileIDs.forEach((id, index) => {
        const file = this.uppy.getFile(id)
        if (!file || file.error) {
          return
        }

        const {
          method = 'post',
          url,
          fields,
          headers
        } = responses[index]
        const xhrOpts = {
          method,
          formData: method.toLowerCase() === 'post',
          endpoint: url,
          metaFields: fields ? Object.keys(fields) : []
        }

        if (headers) {
          xhrOpts.headers = headers
        }

        const updatedFile = {
          ...file,
          meta: { ...file.meta, ...fields },
          xhrUpload: xhrOpts
        }

        updatedFiles[id] = updatedFile
      })

      const { files } = this.uppy.getState()
      this.uppy.setState({
        files: {
          ...files,
          ...updatedFiles
        }
      })

      fileIDs.forEach((id) => {
        const file = this.uppy.getFile(id)
        this.uppy.emit('preprocess-complete', file)
      })
    })
  }

  install () {
    const { log } = this.uppy
    this.uppy.addPreProcessor(this.prepareUpload)

    let warnedSuccessActionStatus = false
    const xhrUploadOpts = {
      fieldName: 'file',
      responseUrlFieldName: 'location',
      timeout: this.opts.timeout,
      __queue: this.requests,
      responseType: 'text',
      // Get the response data from a successful XMLHttpRequest instance.
      // `content` is the S3 response as a string.
      // `xhr` is the XMLHttpRequest instance.
      getResponseData (content, xhr) {
        const opts = this

        // If no response, we've hopefully done a PUT request to the file
        // in the bucket on its full URL.
        if (!isXml(content, xhr)) {
          if (opts.method.toUpperCase() === 'POST') {
            if (!warnedSuccessActionStatus) {
              log('[AwsS3] No response data found, make sure to set the success_action_status AWS SDK option to 201. See https://uppy.io/docs/aws-s3/#POST-Uploads', 'warning')
              warnedSuccessActionStatus = true
            }
            // The responseURL won't contain the object key. Give up.
            return { location: null }
          }

          // responseURL is not available in older browsers.
          if (!xhr.responseURL) {
            return { location: null }
          }

          // Trim the query string because it's going to be a bunch of presign
          // parameters for a PUT request—doing a GET request with those will
          // always result in an error
          return { location: xhr.responseURL.replace(/\?.*$/, '') }
        }

        return {
          // Some S3 alternatives do not reply with an absolute URL.
          // Eg DigitalOcean Spaces uses /$bucketName/xyz
          location: resolveUrl(xhr.responseURL, getXmlValue(content, 'Location')),
          bucket: getXmlValue(content, 'Bucket'),
          key: getXmlValue(content, 'Key'),
          etag: getXmlValue(content, 'ETag')
        }
      },

      // Get the error data from a failed XMLHttpRequest instance.
      // `content` is the S3 response as a string.
      // `xhr` is the XMLHttpRequest instance.
      getResponseError (content, xhr) {
        // If no response, we don't have a specific error message, use the default.
        if (!isXml(content, xhr)) {
          return
        }
        const error = getXmlValue(content, 'Message')
        return new Error(error)
      }
    }

    // Replace getResponseData() with overwritten version.
    if (this.opts.getResponseData) {
      xhrUploadOpts.getResponseData = this.opts.getResponseData
    }

    this.uppy.use(XHRUpload, xhrUploadOpts)
  }

  uninstall () {
    const uploader = this.uppy.getPlugin('XHRUpload')
    this.uppy.removePlugin(uploader)

    this.uppy.removePreProcessor(this.prepareUpload)
  }
}
<commit_msg>Fix #2011 (#2012)<commit_after>// If global `URL` constructor is available, use it
const URL_ = typeof URL === 'function' ? URL : require('url-parse')
const { Plugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator')
const RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue')
const { RequestClient } = require('@uppy/companion-client')
const XHRUpload = require('@uppy/xhr-upload')
const qsStringify = require('qs-stringify')

function resolveUrl (origin, link) {
  return new URL_(link, origin).toString()
}

function isXml (content, xhr) {
  const rawContentType = (xhr.headers ? xhr.headers['content-type'] : xhr.getResponseHeader('Content-Type'))

  if (rawContentType === null) {
    return false
  }

  // Get rid of mime parameters like charset=utf-8
  const contentType = rawContentType.replace(/;.*$/, '').toLowerCase()
  if (typeof contentType === 'string') {
    if (contentType === 'application/xml' || contentType === 'text/xml') {
      return true
    }
    // GCS uses text/html for some reason
    // https://github.com/transloadit/uppy/issues/896
    if (contentType === 'text/html' && /^<\?xml /.test(content)) {
      return true
    }
  }
  return false
}

function getXmlValue (source, key) {
  const start = source.indexOf(`<${key}>`)
  const end = source.indexOf(`</${key}>`, start)
  return start !== -1 && end !== -1
    ? source.slice(start + key.length + 2, end)
    : ''
}

function assertServerError (res) {
  if (res && res.error) {
    const error = new Error(res.message)
    Object.assign(error, res.error)
    throw error
  }
  return res
}

module.exports = class AwsS3 extends Plugin {
  static VERSION = require('../package.json').version

  constructor (uppy, opts) {
    super(uppy, opts)
    this.type = 'uploader'
    this.id = this.opts.id || 'AwsS3'
    this.title = 'AWS S3'

    this.defaultLocale = {
      strings: {
        preparingUpload: 'Preparing upload...'
      }
    }

    const defaultOptions = {
      timeout: 30 * 1000,
      limit: 0,
      metaFields: [], // have to opt in
      getUploadParameters: this.getUploadParameters.bind(this)
    }

    this.opts = { ...defaultOptions, ...opts }

    this.i18nInit()

    this.client = new RequestClient(uppy, opts)
    this.prepareUpload = this.prepareUpload.bind(this)
    this.requests = new RateLimitedQueue(this.opts.limit)
  }

  setOptions (newOpts) {
    super.setOptions(newOpts)
    this.i18nInit()
  }

  i18nInit () {
    this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
    this.i18n = this.translator.translate.bind(this.translator)
    this.setPluginState() // so that UI re-renders and we see the updated locale
  }

  getUploadParameters (file) {
    if (!this.opts.companionUrl) {
      throw new Error('Expected a `companionUrl` option containing a Companion address.')
    }

    const filename = encodeURIComponent(file.meta.name)
    const type = encodeURIComponent(file.meta.type)
    const metadata = {}
    this.opts.metaFields.forEach((key) => {
      if (file.meta[key] != null) {
        metadata[key] = file.meta[key].toString()
      }
    })

    const query = qsStringify({ filename, type, metadata })
    return this.client.get(`s3/params?${query}`)
      .then(assertServerError)
  }

  validateParameters (file, params) {
    const valid = typeof params === 'object' && params &&
      typeof params.url === 'string' &&
      (typeof params.fields === 'object' || params.fields == null) &&
      (params.method == null || /^(put|post)$/i.test(params.method))

    if (!valid) {
      const err = new TypeError(`AwsS3: got incorrect result from 'getUploadParameters()' for file '${file.name}', expected an object '{ url, method, fields, headers }'.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)
      console.error(err)
      throw err
    }

    return params
  }

  prepareUpload (fileIDs) {
    fileIDs.forEach((id) => {
      const file = this.uppy.getFile(id)
      this.uppy.emit('preprocess-progress', file, {
        mode: 'determinate',
        message: this.i18n('preparingUpload'),
        value: 0
      })
    })

    // Wrapping rate-limited opts.getUploadParameters in a Promise takes some boilerplate!
    const getUploadParameters = this.requests.wrapPromiseFunction((file) => {
      return this.opts.getUploadParameters(file)
    })

    return Promise.all(
      fileIDs.map((id) => {
        const file = this.uppy.getFile(id)
        return getUploadParameters(file)
          .then((params) => {
            return this.validateParameters(file, params)
          })
          .then((params) => {
            this.uppy.emit('preprocess-progress', file, {
              mode: 'determinate',
              message: this.i18n('preparingUpload'),
              value: 1
            })
            return params
          })
          .catch((error) => {
            this.uppy.emit('upload-error', file, error)
          })
      })
    ).then((responses) => {
      const updatedFiles = {}
      fileIDs.forEach((id, index) => {
        const file = this.uppy.getFile(id)
        if (!file || file.error) {
          return
        }

        const {
          method = 'post',
          url,
          fields,
          headers
        } = responses[index]
        const xhrOpts = {
          method,
          formData: method.toLowerCase() === 'post',
          endpoint: url,
          metaFields: fields ? Object.keys(fields) : []
        }

        if (headers) {
          xhrOpts.headers = headers
        }

        const updatedFile = {
          ...file,
          meta: { ...file.meta, ...fields },
          xhrUpload: xhrOpts
        }

        updatedFiles[id] = updatedFile
      })

      const { files } = this.uppy.getState()
      this.uppy.setState({
        files: {
          ...files,
          ...updatedFiles
        }
      })

      fileIDs.forEach((id) => {
        const file = this.uppy.getFile(id)
        this.uppy.emit('preprocess-complete', file)
      })
    })
  }

  install () {
    const { log } = this.uppy
    this.uppy.addPreProcessor(this.prepareUpload)

    let warnedSuccessActionStatus = false
    const xhrUploadOpts = {
      fieldName: 'file',
      responseUrlFieldName: 'location',
      timeout: this.opts.timeout,
      __queue: this.requests,
      responseType: 'text',
      // Get the response data from a successful XMLHttpRequest instance.
      // `content` is the S3 response as a string.
      // `xhr` is the XMLHttpRequest instance.
      getResponseData (content, xhr) {
        const opts = this

        // If no response, we've hopefully done a PUT request to the file
        // in the bucket on its full URL.
        if (!isXml(content, xhr)) {
          if (opts.method.toUpperCase() === 'POST') {
            if (!warnedSuccessActionStatus) {
              log('[AwsS3] No response data found, make sure to set the success_action_status AWS SDK option to 201. See https://uppy.io/docs/aws-s3/#POST-Uploads', 'warning')
              warnedSuccessActionStatus = true
            }
            // The responseURL won't contain the object key. Give up.
            return { location: null }
          }

          // responseURL is not available in older browsers.
          if (!xhr.responseURL) {
            return { location: null }
          }

          // Trim the query string because it's going to be a bunch of presign
          // parameters for a PUT request—doing a GET request with those will
          // always result in an error
          return { location: xhr.responseURL.replace(/\?.*$/, '') }
        }

        return {
          // Some S3 alternatives do not reply with an absolute URL.
          // Eg DigitalOcean Spaces uses /$bucketName/xyz
          location: resolveUrl(xhr.responseURL, getXmlValue(content, 'Location')),
          bucket: getXmlValue(content, 'Bucket'),
          key: getXmlValue(content, 'Key'),
          etag: getXmlValue(content, 'ETag')
        }
      },

      // Get the error data from a failed XMLHttpRequest instance.
      // `content` is the S3 response as a string.
      // `xhr` is the XMLHttpRequest instance.
      getResponseError (content, xhr) {
        // If no response, we don't have a specific error message, use the default.
        if (!isXml(content, xhr)) {
          return
        }
        const error = getXmlValue(content, 'Message')
        return new Error(error)
      }
    }

    // Replace getResponseData() with overwritten version.
    if (this.opts.getResponseData) {
      xhrUploadOpts.getResponseData = this.opts.getResponseData
    }

    this.uppy.use(XHRUpload, xhrUploadOpts)
  }

  uninstall () {
    const uploader = this.uppy.getPlugin('XHRUpload')
    this.uppy.removePlugin(uploader)

    this.uppy.removePreProcessor(this.prepareUpload)
  }
}
<|endoftext|>


<commit_before>(function () {
    'use strict';
    angular.module('article')
        .directive('svImageUpload', function ($rootScope, taSelection) {
            return {
                templateUrl: 'scripts/article/directives/sv-image-upload.html',
                link: function ($scope, el, attrs) {
                    if (!$scope.$parent.ad) {
                        $scope.$watchCollection('$flow.files', function (images) {
                            if (!images) {
                                return;
                            }
                            if (!images.length) {
                                return
                            }
                            var lastImg = _.last(images);
                            $scope.$flow.files[0] = lastImg;
                            var file = lastImg;
                            var fileReader = new FileReader();
                            fileReader.readAsDataURL(file.file);
                            fileReader.onload = function (event) {
                                if ($scope.article) {
                                    //$scope.article.img = event.target.result;
                                    runMe(event.target.result);

                                }
                                if ($scope.event) {
                                    $scope.event.img = event.target.result;
                                }
                            };
                        });
                    };

                    function runMe(selectedImage) {
                        var selection = $rootScope.lastSelection;
                        var embed = '';
                        taSelection.insertHtml(embed, undefined, selection);
                    }
                }
            };
        });
})();
<commit_msg>Image Upload Works<commit_after>(function () {
    'use strict';
    angular.module('article')
        .directive('svImageUpload', function ($rootScope, taSelection) {
            return {
                templateUrl: 'scripts/article/directives/sv-image-upload.html',
                link: function ($scope, el, attrs) {
                    if (!$scope.$parent.ad) {
                        $scope.$watchCollection('$flow.files', function (images) {
                            if (!images) {
                                return;
                            }
                            if (!images.length) {
                                return
                            }

                            var lastImg = _.last(images);
                            $scope.$flow.files[0] = lastImg;
                            var file = lastImg;
                            var fileReader = new FileReader();
                            fileReader.readAsDataURL(file.file);
                            fileReader.onload = function (event) {
                                if ($scope.article) {
                                    //$scope.article.img = event.target.result;
                                    runMe(event.target.result);

                                }
                                if ($scope.event) {
                                    $scope.event.img = event.target.result;
                                }
                            };
                        });
                    };

                    function runMe(selectedImage) {
                        var selection = $rootScope.lastSelection;
                        var embed = '';
                        taSelection.insertHtml(embed, undefined, selection);
                    }
                }
            };
        });
})();
<|endoftext|>