<commit_before>define([
    'json.sortify',
    '/common/common-util.js',
    '/common/hyperscript.js',
    '/common/common-interface.js',
    '/customize/messages.js'
], function (Sortify, Util, h, UI, Messages) {
    var Comments = {};

/*
{
    authors: {
        "id": {
            name: "",
            curvePublic: "",
            avatar: "",
            profile: ""
        }
    },
    data: {
        "uid": {
            m: [{
                u: id,
                m: "str", // comment
                t: +new Date,
                v: "str" // value of the commented content
            }],
            (deleted: undefined/true,)
        }
    }
}
*/

    var COMMENTS = {
        authors: {},
        data: {}
    };

    var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); };

    // XXX function duplicated from www/code/markers.js
    var authorUid = function (existing) {
        if (!Array.isArray(existing)) { existing = []; }
        var n;
        var i = 0;
        while (!n || existing.indexOf(n) !== -1 && i++ < 1000) {
            n = Math.floor(Math.random() * 1000000);
        }
        // If we can't find a valid number in 1000 iterations, use 0...
        if (existing.indexOf(n) !== -1) { n = 0; }
        return n;
    };
    var getAuthorId = function (Env, curve) {
        var existing = Object.keys(Env.comments.authors || {}).map(Number);
        if (!Env.common.isLoggedIn()) { return authorUid(existing); }

        var uid;
        existing.some(function (id) {
            var author = Env.comments.authors[id] || {};
            if (author.curvePublic !== curve) { return; }
            uid = Number(id);
            return true;
        });
        return uid || authorUid(existing);
    };

    var updateAuthorData = function (Env) {
        var userData = Env.metadataMgr.getUserData();
        var myAuthorId = getAuthorId(Env, userData.curvePublic);
        var data = Env.comments.authors[myAuthorId] = Env.comments.authors[myAuthorId] || {};
        data.name = userData.name;
        data.avatar = userData.avatar;
        data.profile = userData.profile;
        data.curvePublic = userData.curvePublic;
        console.log(data);
        return myAuthorId;
    };

    var updateMetadata = function (Env) {
        var md = Util.clone(Env.metadataMgr.getMetadata());
        md.comments = Util.clone(Env.comments);
        Env.metadataMgr.updateMetadata(md);
    };

    Messages.comments_submit = "Submit"; // XXX
    Messages.comments_reply = "Reply"; // XXX
    Messages.comments_resolve = "Resolve"; // XXX

    var getCommentForm = function (Env, reply, _cb) {
        var cb = Util.once(_cb);
        var userData = Env.metadataMgr.getUserData();
        var name = Util.fixHTML(userData.name || Messages.anonymous);
        var avatar = h('span.cp-avatar');
        var textarea = h('textarea');
        Env.common.displayAvatar($(avatar), userData.avatar, name);

        var cancel = h('button.btn.btn-cancel', [
            h('i.fa.fa-times'),
            Messages.cancel
        ]);
        var submit = h('button.btn.btn-primary', [
            h('i.fa.fa-paper-plane-o'),
            Messages.comments_submit
        ]);

        var done = false;

        $(submit).click(function (e) {
            e.stopPropagation();
            cb(textarea.value);
        });
        $(cancel).click(function (e) {
            e.stopPropagation();
            cb();
        });

        $(textarea).keydown(function (e) {
            if (e.which === 27) {
                $(cancel).click();
            }
            if (e.which === 13 && e.ctrlKey) {
                $(submit).click();
            }
        });

        return h('div.cp-comment-form' + (reply ? '.cp-comment-reply' : ''), [
            h('div.cp-comment-form-input', [
                avatar,
                textarea
            ]),
            h('div.cp-comment-form-actions', [
                cancel,
                submit
            ])
        ]);
    };

    var redrawComments = function (Env) {
        // Don't redraw if there were no change
        var str = Sortify(Env.comments || {});
        if (str === Env.oldComments) { return; }
        Env.oldComments = str;

        // XXX don't wipe inputs?

        var $oldInput = Env.$container.find('.cp-comment-form');
        if ($oldInput.length !== 1) { $oldInput = undefined; }

        Env.$container.html('');

        var show = false;

        if ($oldInput && !$oldInput.attr('data-uid')) {
            show = true;
            Env.$container.append($oldInput);
        }

        var order = Env.$inner.find('comment').map(function (i, el) {
            return el.getAttribute('data-uid');
        }).toArray();
        var done = [];

        order.forEach(function (key) {
            // Avoir duplicates
            if (done.indexOf(key) !== -1) { return; }
            done.push(key);

            var obj = Env.comments.data[key];
            if (!obj || obj.deleted || !Array.isArray(obj.m) || !obj.m.length) {
                return;
            }
            show = true;

            var content = [];
            obj.m.forEach(function (msg, i) {
                var author = (Env.comments.authors || {})[msg.u] || {};
                var name = Util.fixHTML(author.name || Messages.anonymous);
                var date = new Date(msg.t);
                var avatar = h('span.cp-avatar');
                Env.common.displayAvatar($(avatar), author.avatar, name);

                content.push(h('div.cp-comment'+(i === 0 ? '' : '.cp-comment-reply'), [
                    h('div.cp-comment-header', [
                        avatar,
                        h('span.cp-comment-metadata', [
                            h('span.cp-comment-author', name),
                            h('span.cp-comment-time', date.toLocaleString())
                        ])
                    ]),
                    h('div.cp-comment-content', [
                        msg.m
                    ])
                ]));

            });

            var reply = h('button.btn.btn-secondary', [
                h('i.fa.fa-reply'),
                Messages.comments_reply
            ]);
            var resolve = h('button.btn.btn-primary', [
                h('i.fa.fa-check'),
                Messages.comments_resolve
            ]);

            var actions;
            content.push(actions = h('div.cp-comment-actions', [
                reply,
                resolve
            ]));
            var $actions = $(actions);

            var div;
            Env.$container.append(div = h('div.cp-comment-container', {
                'data-uid': key,
                tabindex: 1
            }, content));
            var $div = $(div);

            $(reply).click(function (e) {
                e.stopPropagation();
                $actions.hide();
                var form = getCommentForm(Env, true, function (val) {
                    $(form).remove();
                    $actions.css('display', '');
                    if (!val) { return; }
                    var obj = Env.comments.data[key];
                    if (!obj || !Array.isArray(obj.m)) { return; }

                    // Get the value of the commented text
                    var res = Env.$inner.find('comment[data-uid="'+key+'"]').toArray();
                    var value = res.map(function (el) {
                        return el.innerText;
                    }).join('\n');

                    // Push the reply
                    var myId = updateAuthorData(Env);
                    obj.m.push({
                        u: myId,
                        t: +new Date(),
                        m: val,
                        v: value
                    });

                    // Send to chainpad
                    updateMetadata(Env);
                    Env.framework.localChange();
                });
                $div.append(form);
            });

            UI.confirmButton(resolve, {
                classes: 'btn-danger-alt'
            }, function () {
                // Delete the comment
                delete Env.comments.data[key];

                // Send to chainpad
                updateMetadata(Env);
                Env.framework.localChange();
            });

            $div.click(function () {
                Env.$container.find('.cp-comment-active').removeClass('cp-comment-active');
                $div.addClass('cp-comment-active');
                $actions.css('display', '');
                Env.$container.find('.cp-comment-form').remove();
                // XXX highlight (and scroll to) the comment in the doc?
            });
        });

        if (show) {
            Env.$container.show();
        } else {
            Env.$container.hide();
        }
    };

    var onChange = function (Env) {
        var md = Util.clone(Env.metadataMgr.getMetadata());
        Env.comments = md.comments;
        var changed = false;
        if (!Env.comments || !Env.comments.data) {
            changed = true;
            Env.comments = Util.clone(COMMENTS);
        }
        if (Env.ready === 0) {
            Env.ready = true;
            if (changed) {
                updateMetadata(Env);
                Env.framework.localChange();
            }
        }
        redrawComments(Env);
    };

    // Check if comments have been deleted from the document but not from metadata
    var checkDeleted = function (Env) {
        if (!Env.comments || !Env.comments.data) { return; }

        // If there is no comment stored in the metadata, abort
        var comments = Object.keys(Env.comments.data || {}).filter(function (id) {
            return !Env.comments.data[id].deleted;
        });

        var changed = false;

        // Get the comments from the document
        var uids = Env.$inner.find('comment').map(function (i, el) {
            var id = el.getAttribute('data-uid');
            // Empty comment: remove from dom
            if (!el.innerText && el.parentElement) {
                el.parentElement.removeChild(el);
                changed = true;
                return;
            }
            // Comment not in the metadata: uncomment (probably an undo)
            if (comments.indexOf(id) === -1) {
                console.error(id, el);
                Env.editor.execCommand('uncomment', {id:id});
                changed = true;
                return;
            }
            return id;
        }).toArray();

        // Check if a comment has been deleted
        comments.forEach(function (uid) {
            if (uids.indexOf(uid) !== -1) { return; }
            // comment has been deleted
            var data = Env.comments.data[uid];
            if (!data) { return; }
            //data.deleted = true;
            delete Env.comments.data[uid];
            changed = true;
        });

        if (changed) {
            updateMetadata(Env);
        }
    };

    var addAddCommentHandler = function (Env) {
        Env.editor.plugins.comments.addComment = function (uid, addMark) {
            if (!Env.comments) { Env.comments = Util.clone(COMMENTS); }

            // Get all comments ID contained within the selection
            var sel = Env.editor.getSelectedHtml().$.querySelectorAll('comment');
            if (sel.length) {
                // Abort if our selection contains a comment
                console.error("Your selection contains a comment");
                UI.warn(Messages.error);
                // XXX show error
                return;
            }

/*
sel.forEach(function (el) {
    // For each comment ID, check if the comment will be deleted
    // if we add a comment on our selection
    var id = el.getAttribute('data-uid');

    // Get all nodes for this comment
    var all = Env.$inner.find('comment[data-uid="'+id+'"]');
    // Get our selection
    var sel = Env.ifrWindow.getSelection();
    if (!sel.containsNode) {
        // IE doesn't support this method, always allow comments for them...
        sel.containsNode = function () { return false; };
    }

    var notDeleted = all.some(function (i, el) {
        // If this node is completely outside of the selection, continue
        if (!sel.containsNode(el, true)) { return true; }
    });

    // only continue if notDeleted is true (at least one node for
    // this comment won't be deleted)
});
*/
            Env.$container.find('.cp-comment-form').remove();
            var form = getCommentForm(Env, false, function (val) {
                $(form).remove();
                if (!val) { return; }
                if (!editor.getSelection().getSelectedText()) {
                    // text has been deleted by another user while we were typing our comment?
                    return void UI.warn(Messages.error);
                }
                var myId = updateAuthorData(Env);
                Env.comments.data[uid] = {
                    m: [{
                        u: myId,
                        t: +new Date(),
                        m: val,
                        v: canonicalize(editor.getSelection().getSelectedText())
                    }]
                };
                updateMetadata(Env);

                addMark();

                Env.framework.localChange();
            });
            Env.$container.prepend(form).show();;
        };
    };

    var onContentUpdate = function (Env) {
        if (!Env.ready) { return; }
        // Check deleted
        checkDeleted(Env);
    };
    var localChange = function (Env) {
        if (!Env.ready) { return; }
        // Check deleted
        checkDeleted(Env);
    };

    var ready = function (Env) {
        Env.ready = 0;
    };

    Comments.create = function (cfg) {
        var Env = cfg;
        Env.comments = Util.clone(COMMENTS);

        addAddCommentHandler(Env);

        $(window).click(function (e) {
            if ($(e.target).closest('.cp-comment-container').length) {
                return;
            }
            Env.$container.find('.cp-comment-active').removeClass('cp-comment-active');
        });

        var call = function (f) {
            return function () {
                try {
                    [].unshift.call(arguments, Env);
                    return f.apply(null, arguments);
                } catch (e) {
                    console.error(e);
                }
            };
        };

        Env.metadataMgr.onChange(call(onChange));

        return {
            onContentUpdate: call(onContentUpdate),
            localChange: call(localChange),
            ready: call(ready)
        };
    };

    return Comments;
});
<commit_msg>Fix comments replies<commit_after>define([
    'json.sortify',
    '/common/common-util.js',
    '/common/hyperscript.js',
    '/common/common-interface.js',
    '/customize/messages.js'
], function (Sortify, Util, h, UI, Messages) {
    var Comments = {};

/*
{
    authors: {
        "id": {
            name: "",
            curvePublic: "",
            avatar: "",
            profile: ""
        }
    },
    data: {
        "uid": {
            m: [{
                u: id,
                m: "str", // comment
                t: +new Date,
                v: "str" // value of the commented content
            }],
            (deleted: undefined/true,)
        }
    }
}
*/

    var COMMENTS = {
        authors: {},
        data: {}
    };

    var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); };

    // XXX function duplicated from www/code/markers.js
    var authorUid = function (existing) {
        if (!Array.isArray(existing)) { existing = []; }
        var n;
        var i = 0;
        while (!n || existing.indexOf(n) !== -1 && i++ < 1000) {
            n = Math.floor(Math.random() * 1000000);
        }
        // If we can't find a valid number in 1000 iterations, use 0...
        if (existing.indexOf(n) !== -1) { n = 0; }
        return n;
    };
    var getAuthorId = function (Env, curve) {
        var existing = Object.keys(Env.comments.authors || {}).map(Number);
        if (!Env.common.isLoggedIn()) { return authorUid(existing); }

        var uid;
        existing.some(function (id) {
            var author = Env.comments.authors[id] || {};
            if (author.curvePublic !== curve) { return; }
            uid = Number(id);
            return true;
        });
        return uid || authorUid(existing);
    };

    var updateAuthorData = function (Env) {
        var userData = Env.metadataMgr.getUserData();
        var myAuthorId = getAuthorId(Env, userData.curvePublic);
        var data = Env.comments.authors[myAuthorId] = Env.comments.authors[myAuthorId] || {};
        data.name = userData.name;
        data.avatar = userData.avatar;
        data.profile = userData.profile;
        data.curvePublic = userData.curvePublic;
        console.log(data);
        return myAuthorId;
    };

    var updateMetadata = function (Env) {
        var md = Util.clone(Env.metadataMgr.getMetadata());
        md.comments = Util.clone(Env.comments);
        Env.metadataMgr.updateMetadata(md);
    };

    Messages.comments_submit = "Submit"; // XXX
    Messages.comments_reply = "Reply"; // XXX
    Messages.comments_resolve = "Resolve"; // XXX

    var getCommentForm = function (Env, reply, _cb) {
        var cb = Util.once(_cb);
        var userData = Env.metadataMgr.getUserData();
        var name = Util.fixHTML(userData.name || Messages.anonymous);
        var avatar = h('span.cp-avatar');
        var textarea = h('textarea');
        Env.common.displayAvatar($(avatar), userData.avatar, name);

        var cancel = h('button.btn.btn-cancel', [
            h('i.fa.fa-times'),
            Messages.cancel
        ]);
        var submit = h('button.btn.btn-primary', [
            h('i.fa.fa-paper-plane-o'),
            Messages.comments_submit
        ]);

        var done = false;

        $(submit).click(function (e) {
            e.stopPropagation();
            cb(textarea.value);
        });
        $(cancel).click(function (e) {
            e.stopPropagation();
            cb();
        });

        $(textarea).keydown(function (e) {
            if (e.which === 27) {
                $(cancel).click();
            }
            if (e.which === 13 && e.ctrlKey) {
                $(submit).click();
            }
        });

        return h('div.cp-comment-form' + (reply ? '.cp-comment-reply' : ''), [
            h('div.cp-comment-form-input', [
                avatar,
                textarea
            ]),
            h('div.cp-comment-form-actions', [
                cancel,
                submit
            ])
        ]);
    };

    var redrawComments = function (Env) {
        // Don't redraw if there were no change
        var str = Sortify(Env.comments || {});
        if (str === Env.oldComments) { return; }
        Env.oldComments = str;

        // XXX don't wipe inputs?

        var $oldInput = Env.$container.find('.cp-comment-form');
        if ($oldInput.length !== 1) { $oldInput = undefined; }

        Env.$container.html('');

        var show = false;

        if ($oldInput && !$oldInput.attr('data-uid')) {
            show = true;
            Env.$container.append($oldInput);
        }

        var order = Env.$inner.find('comment').map(function (i, el) {
            return el.getAttribute('data-uid');
        }).toArray();
        var done = [];

        order.forEach(function (key) {
            // Avoir duplicates
            if (done.indexOf(key) !== -1) { return; }
            done.push(key);

            var obj = Env.comments.data[key];
            if (!obj || obj.deleted || !Array.isArray(obj.m) || !obj.m.length) {
                return;
            }
            show = true;

            var content = [];
            obj.m.forEach(function (msg, i) {
                var author = (Env.comments.authors || {})[msg.u] || {};
                var name = Util.fixHTML(author.name || Messages.anonymous);
                var date = new Date(msg.t);
                var avatar = h('span.cp-avatar');
                Env.common.displayAvatar($(avatar), author.avatar, name);

                content.push(h('div.cp-comment'+(i === 0 ? '' : '.cp-comment-reply'), [
                    h('div.cp-comment-header', [
                        avatar,
                        h('span.cp-comment-metadata', [
                            h('span.cp-comment-author', name),
                            h('span.cp-comment-time', date.toLocaleString())
                        ])
                    ]),
                    h('div.cp-comment-content', [
                        msg.m
                    ])
                ]));

            });

            var reply = h('button.btn.btn-secondary', [
                h('i.fa.fa-reply'),
                Messages.comments_reply
            ]);
            var resolve = h('button.btn.btn-primary', [
                h('i.fa.fa-check'),
                Messages.comments_resolve
            ]);

            var actions;
            content.push(actions = h('div.cp-comment-actions', [
                reply,
                resolve
            ]));
            var $actions = $(actions);

            var div;
            Env.$container.append(div = h('div.cp-comment-container', {
                'data-uid': key,
                tabindex: 1
            }, content));
            var $div = $(div);

            $(reply).click(function (e) {
                e.stopPropagation();
                $actions.hide();
                var form = getCommentForm(Env, true, function (val) {
                    $(form).remove();
                    $actions.css('display', '');
                    if (!val) { return; }
                    var obj = Env.comments.data[key];
                    if (!obj || !Array.isArray(obj.m)) { return; }

                    // Get the value of the commented text
                    var res = Env.$inner.find('comment[data-uid="'+key+'"]').toArray();
                    var value = res.map(function (el) {
                        return el.innerText;
                    }).join('\n');

                    // Push the reply
                    var myId = updateAuthorData(Env);
                    obj.m.push({
                        u: myId,
                        t: +new Date(),
                        m: val,
                        v: value
                    });

                    // Send to chainpad
                    updateMetadata(Env);
                    Env.framework.localChange();
                });
                $div.append(form);
            });

            UI.confirmButton(resolve, {
                classes: 'btn-danger-alt'
            }, function () {
                // Delete the comment
                delete Env.comments.data[key];

                // Send to chainpad
                updateMetadata(Env);
                Env.framework.localChange();
            });

            $div.click(function () {
                if ($div.hasClass('cp-comment-active')) { return; }
                Env.$container.find('.cp-comment-active').removeClass('cp-comment-active');
                $div.addClass('cp-comment-active');
                $actions.css('display', '');
                Env.$container.find('.cp-comment-form').remove();
                // XXX highlight (and scroll to) the comment in the doc?
            });
        });

        if (show) {
            Env.$container.show();
        } else {
            Env.$container.hide();
        }
    };

    var onChange = function (Env) {
        var md = Util.clone(Env.metadataMgr.getMetadata());
        Env.comments = md.comments;
        var changed = false;
        if (!Env.comments || !Env.comments.data) {
            changed = true;
            Env.comments = Util.clone(COMMENTS);
        }
        if (Env.ready === 0) {
            Env.ready = true;
            if (changed) {
                updateMetadata(Env);
                Env.framework.localChange();
            }
        }
        redrawComments(Env);
    };

    // Check if comments have been deleted from the document but not from metadata
    var checkDeleted = function (Env) {
        if (!Env.comments || !Env.comments.data) { return; }

        // If there is no comment stored in the metadata, abort
        var comments = Object.keys(Env.comments.data || {}).filter(function (id) {
            return !Env.comments.data[id].deleted;
        });

        var changed = false;

        // Get the comments from the document
        var uids = Env.$inner.find('comment').map(function (i, el) {
            var id = el.getAttribute('data-uid');
            // Empty comment: remove from dom
            if (!el.innerText && el.parentElement) {
                el.parentElement.removeChild(el);
                changed = true;
                return;
            }
            // Comment not in the metadata: uncomment (probably an undo)
            if (comments.indexOf(id) === -1) {
                console.error(id, el);
                Env.editor.execCommand('uncomment', {id:id});
                changed = true;
                return;
            }
            return id;
        }).toArray();

        // Check if a comment has been deleted
        comments.forEach(function (uid) {
            if (uids.indexOf(uid) !== -1) { return; }
            // comment has been deleted
            var data = Env.comments.data[uid];
            if (!data) { return; }
            //data.deleted = true;
            delete Env.comments.data[uid];
            changed = true;
        });

        if (changed) {
            updateMetadata(Env);
        }
    };

    var addAddCommentHandler = function (Env) {
        Env.editor.plugins.comments.addComment = function (uid, addMark) {
            if (!Env.comments) { Env.comments = Util.clone(COMMENTS); }

            // Get all comments ID contained within the selection
            var sel = Env.editor.getSelectedHtml().$.querySelectorAll('comment');
            if (sel.length) {
                // Abort if our selection contains a comment
                console.error("Your selection contains a comment");
                UI.warn(Messages.error);
                // XXX show error
                return;
            }

/*
sel.forEach(function (el) {
    // For each comment ID, check if the comment will be deleted
    // if we add a comment on our selection
    var id = el.getAttribute('data-uid');

    // Get all nodes for this comment
    var all = Env.$inner.find('comment[data-uid="'+id+'"]');
    // Get our selection
    var sel = Env.ifrWindow.getSelection();
    if (!sel.containsNode) {
        // IE doesn't support this method, always allow comments for them...
        sel.containsNode = function () { return false; };
    }

    var notDeleted = all.some(function (i, el) {
        // If this node is completely outside of the selection, continue
        if (!sel.containsNode(el, true)) { return true; }
    });

    // only continue if notDeleted is true (at least one node for
    // this comment won't be deleted)
});
*/
            Env.$container.find('.cp-comment-form').remove();
            var form = getCommentForm(Env, false, function (val) {
                $(form).remove();
                if (!val) { return; }
                if (!editor.getSelection().getSelectedText()) {
                    // text has been deleted by another user while we were typing our comment?
                    return void UI.warn(Messages.error);
                }
                var myId = updateAuthorData(Env);
                Env.comments.data[uid] = {
                    m: [{
                        u: myId,
                        t: +new Date(),
                        m: val,
                        v: canonicalize(editor.getSelection().getSelectedText())
                    }]
                };
                updateMetadata(Env);

                addMark();

                Env.framework.localChange();
            });
            Env.$container.prepend(form).show();;
        };
    };

    var onContentUpdate = function (Env) {
        if (!Env.ready) { return; }
        // Check deleted
        checkDeleted(Env);
    };
    var localChange = function (Env) {
        if (!Env.ready) { return; }
        // Check deleted
        checkDeleted(Env);
    };

    var ready = function (Env) {
        Env.ready = 0;
    };

    Comments.create = function (cfg) {
        var Env = cfg;
        Env.comments = Util.clone(COMMENTS);

        addAddCommentHandler(Env);

        $(window).click(function (e) {
            if ($(e.target).closest('.cp-comment-container').length) {
                return;
            }
            Env.$container.find('.cp-comment-active').removeClass('cp-comment-active');
        });

        var call = function (f) {
            return function () {
                try {
                    [].unshift.call(arguments, Env);
                    return f.apply(null, arguments);
                } catch (e) {
                    console.error(e);
                }
            };
        };

        Env.metadataMgr.onChange(call(onChange));

        return {
            onContentUpdate: call(onContentUpdate),
            localChange: call(localChange),
            ready: call(ready)
        };
    };

    return Comments;
});
<|endoftext|>


<commit_before>/**
 * This is responsible for the IQR integration of the SMQTK ImageSpace plugin.
 * This adds 4 new events, 1 new route, and wraps 3 existing methods:
 * New events:
 * 1) Click to start a new IQR session
 *    This creates an IQR session on the server side and re-renders the search view.
 * 2) Click to refine an existing IQR session
 *    When the user has initialized an IQR session and selected some pos/negative examples
 *    and want to refine it will PUT to the refine endpoint and then change the URL
 *    to enter the main entrypoint (fetching the new results).
 *    In a refined state pagination will still work since the collection is now an IqrImageCollection.
 * 3) Click to load an existing IQR session
 *    When the user clicks this they are presented with a hierarchy widget of the directory
 *    storing their IQR sessions. On clicking an IQR session they are forced to the state that session
 *    was in when they last used it.
 * 4) Click to save an IQR session
 *    The notion of a "saved" IQR session is simply one that gets named by a user (see the above event).
 *    This is due to the (unsolved) issue of when to invalidate a session. As such, the save event just
 *    brings up the Edit Item widget for that particular IQR session item.
 * New route:
 *   The refine route mimics the search route with the exception of the classification parameter
 *   having no effect and should be removed. This is in place just so the user can permalink
 *   results from a given refinement.
 * Wrapped methods:
 * 1) Wrapping SearchView.render:
 *    This is wrapped to replace the captions of Image results with an AnnotationWidgetView
 *    when the user is in an IQR session.
 * 2) Wrapping LayoutHeaderView.render:
 *    This is wrapped just to allow a notice for the user when they are in the middle of an IQR session.
 * 3) Wrapping ItemListWidget.render:
 *    This is wrapped because of the Hierarchy Widget usage when loading an existing IQR session.
 *    For now, it's difficult to hook in to filter the items listed in the widget so we wrap render
 *    and remove the items we don't want (hacky). Specifically, we only want to show IQR sessions which
 *    have a name that isn't their SID (this is the indication that a user saved the session).
 **/
girder.events.once('im:appload.after', function () {
    imagespace.smqtk = imagespace.smqtk || {
        iqr: {
            sessions: new imagespace.collections.IqrSessionCollection(),

            /**
             * Returns the IqrSessionModel representing the current IQR session (via the query string).
             * IQR is currently limited to logged in users.
             **/
            findIqrSession: function () {
                var qs = imagespace.parseQueryString(),
                    session;

                if (girder.currentUser && _.has(qs, 'smqtk_iqr_session')) {
                    session = _.find(imagespace.smqtk.iqr.sessions.models, function (iqrSession) {
                        return iqrSession.get('meta').sid === qs.smqtk_iqr_session;
                    });

                    if (_.isUndefined(session)) {
                        console.error('Unable to find IQR session in client side representation');
                    } else {
                        // @todo this should be handled properly with defaults
                        session.set('meta', session.get('meta') || {
                            pos_uuids: [],
                            neg_uuids: []
                        });
                    }
                }

                return session || false;
            },

            currentIqrSession: false,

            refiningNotice: function (enable) {
                if (enable && imagespace.smqtk.iqr.currentIqrSession !== false) {
                    if (!_.has(imagespace.smqtk.iqr, 'iqrNoticeView') || _.isUndefined(imagespace.smqtk.iqr.iqrNoticeView)) {
                        imagespace.smqtk.iqr.iqrNoticeView = new imagespace.views.IqrNoticeView({
                            parentView: null
                        });

                        $('nav.navbar-fixed-top').append(imagespace.smqtk.iqr.iqrNoticeView.render().el);
                    }

                    $('#wrapper').css('margin-top', '80px');
                    $('#im-classification-narrow').hide();
                    $('#smqtk-near-duplicates').hide();
                } else {
                    if (_.has(imagespace.smqtk.iqr, 'iqrNoticeView') &&
                        !_.isUndefined(imagespace.smqtk.iqr.iqrNoticeView)) {
                        imagespace.smqtk.iqr.iqrNoticeView.destroy();
                        imagespace.smqtk.iqr.iqrNoticeView = undefined;
                    }

                    $('#wrapper').css('margin-top', '');
                    $('#im-classification-narrow').show();
                    $('#smqtk-near-duplicates').show();
                }
            },

            quitIqrSession: function () {
                if (_.has(imagespace.parseQueryString(), 'smqtk_iqr_session')) {
                    imagespace.smqtk.iqr.currentIqrSession = false;
                    imagespace.smqtk.iqr.refiningNotice(false);
                    imagespace.setQueryParams(_.omit(imagespace.parseQueryString(),
                                                     ['smqtk_iqr_session']), {
                                                         trigger: true
                                                     });
                }
            }
        }
    };

    girder.events.on('g:appload.ready', function () {
        if (girder.currentUser !== null) {
            imagespace.smqtk.iqr.sessions.fetch();
        }
    });

    imagespace.smqtk.iqr.sessions.once('g:changed', function () {
        imagespace.smqtk.iqr.currentIqrSession = imagespace.smqtk.iqr.findIqrSession();
        girder.events.trigger('im:iqr-session-loaded');
    });

    /**
     * Supplants the current imagespace.searchView with one that uses an
     * IQR Image Collection instead.
     **/
    imagespace.smqtk.iqr.RefineView = _.bind(function () {
        if (_.has(imagespace, 'searchView')) {
            imagespace.searchView.destroy();
        }

        // @todo pass these into the constructor properly
        var coll = new imagespace.collections.IqrImageCollection();
        coll.params = coll.params || {};
        coll.params.sid = imagespace.smqtk.iqr.currentIqrSession.get('meta').sid;

        imagespace.searchView = new imagespace.views.SearchView({
            parentView: this.parentView,
            collection: coll
        });
        coll.fetch(coll.params || {}, true);
    }, this);

    imagespace.smqtk.iqr.createOrUpdateRefineView = function () {
        if (imagespace.searchView.collection instanceof imagespace.collections.IqrImageCollection) {
            imagespace.searchView.collection.fetch(imagespace.searchView.collection.params || {}, true);
        } else {
            imagespace.smqtk.iqr.RefineView();
        }
    };

    /**
     * Anytime the page is changed, check if we're still in the middle of an
     * IQR session. If we are then make sure to update any refinement views if necessary,
     * otherwise clear any refinement notice that might exist from a previous session.
     **/
    imagespace.router.on('route', function (route, params) {
        if (route === 'search' && _.size(params) > 1 && params[1] &&
            params[1].indexOf('smqtk_iqr_session') !== -1) {
            if (!imagespace.smqtk.iqr.currentIqrSession) {
                girder.events.once('im:iqr-session-loaded', imagespace.smqtk.iqr.createOrUpdateRefineView);
            } else {
                imagespace.smqtk.iqr.createOrUpdateRefineView();
            }
        } else if (!_.has(imagespace.parseQueryString(), 'smqtk_iqr_session')) {
            imagespace.smqtk.iqr.currentIqrSession = false;
            imagespace.smqtk.iqr.refiningNotice(false);
        }
    });

    girder.wrap(imagespace.views.SearchView, 'render', function (render) {
        render.call(this);

        if (girder.currentUser !== null) {
            this.$('#search-controls .right-search-controls').append(girder.templates.startIqrSession({
                currentIqrSession: imagespace.smqtk.iqr.currentIqrSession
            }));

            this.$('#smqtk-iqr-quit-session').on('click', imagespace.smqtk.iqr.quitIqrSession);
        }

        if (imagespace.smqtk.iqr.currentIqrSession) {
            // Grid view is the only supported view for IQR, remove the view-mode controls
            this.$('.im-view-mode').remove();

            // Render annotation widgets on each image (replacing the caption utilities)
            _.each(this.$('.im-caption'), _.bind(function (captionDiv, i) {
                var annotationWidgetView = new imagespace.views.AnnotationWidgetView({
                    /**
                     * The parent of the annotation widget should be the individual image view.
                     * Since `this` references the SearchView - we actually want the child view
                     * that represents the i'th image.
                     **/
                    parentView: this.getChildImageView(i)
                });

                $(captionDiv).replaceWith(annotationWidgetView.render().el);
            }, this));

            imagespace.smqtk.iqr.refiningNotice(true);
        }

        return this;
    });

    // create new iqr session, re-render search view with an iqr image collection
    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-start-session'] = function (event) {
        var iqrSession = new imagespace.models.IqrSessionModel({
            meta: {
                pos_uuids: [],
                neg_uuids: []
            }
        });

        iqrSession.save().once('g:saved', _.bind(function () {
            imagespace.updateQueryParams({
                smqtk_iqr_session: iqrSession.get('meta').sid
            });

            imagespace.smqtk.iqr.sessions.add(iqrSession);
            imagespace.smqtk.iqr.currentIqrSession = iqrSession;
            imagespace.searchView.render();
        }, this));
    };

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-load-session'] = function (event) {
        girder.restRequest({
            path: 'smqtk_iqr/session_folder'
        }).done(function (resp) {
            new imagespace.views.IqrSelectSessionView({
                el: $("#g-dialog-container"),
                parentView: imagespace.searchView,
                folder: new girder.models.FolderModel(resp)
            }).render();
        });
    };

    // Remove IQR sessions with no data (see docs above)
    girder.wrap(girder.views.ItemListWidget, 'render', function (render) {
        render.call(this);

        this.collection.models = _.filter(this.collection.models, function (model) {
            return model.has('meta') &&
                model.get('name') != model.get('meta').sid
        });

        return this;
    });

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-refine'] = function (event) {
        var session = imagespace.smqtk.iqr.currentIqrSession;

        if (_.size(session.get('meta').pos_uuids) === 0) {
            alert('Refinement requires at least 1 positive example.');
            return;
        }

        $('button#smqtk-iqr-refine').append('    <i class="icon-spin5 animate-spin"></i>');

        girder.restRequest({
            path: 'smqtk_iqr/refine',
            type: 'PUT',
            contentType: 'application/json',
            data: JSON.stringify({
                sid: session.get('meta').sid,
                pos_uuids: session.get('meta').pos_uuids,
                neg_uuids: session.get('meta').neg_uuids
            })
        }).done(function () {
            imagespace.smqtk.iqr.createOrUpdateRefineView();
        }).error(console.error);
    };

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-save-session'] = function (event) {
        new girder.views.EditItemWidget({
            el: $('#g-dialog-container'),
            item: imagespace.smqtk.iqr.currentIqrSession,
            parentView: imagespace.searchView
        }).render();
    };
});
<commit_msg>Stop exposing the IQR session ID when saving<commit_after>/**
 * This is responsible for the IQR integration of the SMQTK ImageSpace plugin.
 * This adds 4 new events, 1 new route, and wraps 4 existing methods:
 * New events:
 * 1) Click to start a new IQR session
 *    This creates an IQR session on the server side and re-renders the search view.
 * 2) Click to refine an existing IQR session
 *    When the user has initialized an IQR session and selected some pos/negative examples
 *    and want to refine it will PUT to the refine endpoint and then change the URL
 *    to enter the main entrypoint (fetching the new results).
 *    In a refined state pagination will still work since the collection is now an IqrImageCollection.
 * 3) Click to load an existing IQR session
 *    When the user clicks this they are presented with a hierarchy widget of the directory
 *    storing their IQR sessions. On clicking an IQR session they are forced to the state that session
 *    was in when they last used it.
 * 4) Click to save an IQR session
 *    The notion of a "saved" IQR session is simply one that gets named by a user (see the above event).
 *    This is due to the (unsolved) issue of when to invalidate a session. As such, the save event just
 *    brings up the Edit Item widget for that particular IQR session item.
 * New route:
 *   The refine route mimics the search route with the exception of the classification parameter
 *   having no effect and should be removed. This is in place just so the user can permalink
 *   results from a given refinement.
 * Wrapped methods:
 * 1) Wrapping SearchView.render:
 *    This is wrapped to replace the captions of Image results with an AnnotationWidgetView
 *    when the user is in an IQR session.
 * 2) Wrapping LayoutHeaderView.render:
 *    This is wrapped just to allow a notice for the user when they are in the middle of an IQR session.
 * 3) Wrapping ItemListWidget.render:
 *    This is wrapped because of the Hierarchy Widget usage when loading an existing IQR session.
 *    For now, it's difficult to hook in to filter the items listed in the widget so we wrap render
 *    and remove the items we don't want (hacky). Specifically, we only want to show IQR sessions which
 *    have a name that isn't their SID (this is the indication that a user saved the session).
 * 4) Wrapping girder.views.EditItemWidget - for aesthetics.
 **/
girder.events.once('im:appload.after', function () {
    imagespace.smqtk = imagespace.smqtk || {
        iqr: {
            sessions: new imagespace.collections.IqrSessionCollection(),

            /**
             * Returns the IqrSessionModel representing the current IQR session (via the query string).
             * IQR is currently limited to logged in users.
             **/
            findIqrSession: function () {
                var qs = imagespace.parseQueryString(),
                    session;

                if (girder.currentUser && _.has(qs, 'smqtk_iqr_session')) {
                    session = _.find(imagespace.smqtk.iqr.sessions.models, function (iqrSession) {
                        return iqrSession.get('meta').sid === qs.smqtk_iqr_session;
                    });

                    if (_.isUndefined(session)) {
                        console.error('Unable to find IQR session in client side representation');
                    } else {
                        // @todo this should be handled properly with defaults
                        session.set('meta', session.get('meta') || {
                            pos_uuids: [],
                            neg_uuids: []
                        });
                    }
                }

                return session || false;
            },

            currentIqrSession: false,

            refiningNotice: function (enable) {
                if (enable && imagespace.smqtk.iqr.currentIqrSession !== false) {
                    if (!_.has(imagespace.smqtk.iqr, 'iqrNoticeView') || _.isUndefined(imagespace.smqtk.iqr.iqrNoticeView)) {
                        imagespace.smqtk.iqr.iqrNoticeView = new imagespace.views.IqrNoticeView({
                            parentView: null
                        });

                        $('nav.navbar-fixed-top').append(imagespace.smqtk.iqr.iqrNoticeView.render().el);
                    }

                    $('#wrapper').css('margin-top', '80px');
                    $('#im-classification-narrow').hide();
                    $('#smqtk-near-duplicates').hide();
                } else {
                    if (_.has(imagespace.smqtk.iqr, 'iqrNoticeView') &&
                        !_.isUndefined(imagespace.smqtk.iqr.iqrNoticeView)) {
                        imagespace.smqtk.iqr.iqrNoticeView.destroy();
                        imagespace.smqtk.iqr.iqrNoticeView = undefined;
                    }

                    $('#wrapper').css('margin-top', '');
                    $('#im-classification-narrow').show();
                    $('#smqtk-near-duplicates').show();
                }
            },

            quitIqrSession: function () {
                if (_.has(imagespace.parseQueryString(), 'smqtk_iqr_session')) {
                    imagespace.smqtk.iqr.currentIqrSession = false;
                    imagespace.smqtk.iqr.refiningNotice(false);
                    imagespace.setQueryParams(_.omit(imagespace.parseQueryString(),
                                                     ['smqtk_iqr_session']), {
                                                         trigger: true
                                                     });
                }
            }
        }
    };

    girder.events.on('g:appload.ready', function () {
        if (girder.currentUser !== null) {
            imagespace.smqtk.iqr.sessions.fetch();
        }
    });

    imagespace.smqtk.iqr.sessions.once('g:changed', function () {
        imagespace.smqtk.iqr.currentIqrSession = imagespace.smqtk.iqr.findIqrSession();
        girder.events.trigger('im:iqr-session-loaded');
    });

    /**
     * Supplants the current imagespace.searchView with one that uses an
     * IQR Image Collection instead.
     **/
    imagespace.smqtk.iqr.RefineView = _.bind(function () {
        if (_.has(imagespace, 'searchView')) {
            imagespace.searchView.destroy();
        }

        // @todo pass these into the constructor properly
        var coll = new imagespace.collections.IqrImageCollection();
        coll.params = coll.params || {};
        coll.params.sid = imagespace.smqtk.iqr.currentIqrSession.get('meta').sid;

        imagespace.searchView = new imagespace.views.SearchView({
            parentView: this.parentView,
            collection: coll
        });
        coll.fetch(coll.params || {}, true);
    }, this);

    imagespace.smqtk.iqr.createOrUpdateRefineView = function () {
        if (imagespace.searchView.collection instanceof imagespace.collections.IqrImageCollection) {
            imagespace.searchView.collection.fetch(imagespace.searchView.collection.params || {}, true);
        } else {
            imagespace.smqtk.iqr.RefineView();
        }
    };

    /**
     * Anytime the page is changed, check if we're still in the middle of an
     * IQR session. If we are then make sure to update any refinement views if necessary,
     * otherwise clear any refinement notice that might exist from a previous session.
     **/
    imagespace.router.on('route', function (route, params) {
        if (route === 'search' && _.size(params) > 1 && params[1] &&
            params[1].indexOf('smqtk_iqr_session') !== -1) {
            if (!imagespace.smqtk.iqr.currentIqrSession) {
                girder.events.once('im:iqr-session-loaded', imagespace.smqtk.iqr.createOrUpdateRefineView);
            } else {
                imagespace.smqtk.iqr.createOrUpdateRefineView();
            }
        } else if (!_.has(imagespace.parseQueryString(), 'smqtk_iqr_session')) {
            imagespace.smqtk.iqr.currentIqrSession = false;
            imagespace.smqtk.iqr.refiningNotice(false);
        }
    });

    girder.wrap(imagespace.views.SearchView, 'render', function (render) {
        render.call(this);

        if (girder.currentUser !== null) {
            this.$('#search-controls .right-search-controls').append(girder.templates.startIqrSession({
                currentIqrSession: imagespace.smqtk.iqr.currentIqrSession
            }));

            this.$('#smqtk-iqr-quit-session').on('click', imagespace.smqtk.iqr.quitIqrSession);
        }

        if (imagespace.smqtk.iqr.currentIqrSession) {
            // Grid view is the only supported view for IQR, remove the view-mode controls
            this.$('.im-view-mode').remove();

            // Render annotation widgets on each image (replacing the caption utilities)
            _.each(this.$('.im-caption'), _.bind(function (captionDiv, i) {
                var annotationWidgetView = new imagespace.views.AnnotationWidgetView({
                    /**
                     * The parent of the annotation widget should be the individual image view.
                     * Since `this` references the SearchView - we actually want the child view
                     * that represents the i'th image.
                     **/
                    parentView: this.getChildImageView(i)
                });

                $(captionDiv).replaceWith(annotationWidgetView.render().el);
            }, this));

            imagespace.smqtk.iqr.refiningNotice(true);
        }

        return this;
    });

    // create new iqr session, re-render search view with an iqr image collection
    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-start-session'] = function (event) {
        var iqrSession = new imagespace.models.IqrSessionModel({
            meta: {
                pos_uuids: [],
                neg_uuids: []
            }
        });

        iqrSession.save().once('g:saved', _.bind(function () {
            imagespace.updateQueryParams({
                smqtk_iqr_session: iqrSession.get('meta').sid
            });

            imagespace.smqtk.iqr.sessions.add(iqrSession);
            imagespace.smqtk.iqr.currentIqrSession = iqrSession;
            imagespace.searchView.render();
        }, this));
    };

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-load-session'] = function (event) {
        girder.restRequest({
            path: 'smqtk_iqr/session_folder'
        }).done(function (resp) {
            new imagespace.views.IqrSelectSessionView({
                el: $("#g-dialog-container"),
                parentView: imagespace.searchView,
                folder: new girder.models.FolderModel(resp)
            }).render();
        });
    };

    // Remove IQR sessions with no data (see docs above)
    girder.wrap(girder.views.ItemListWidget, 'render', function (render) {
        render.call(this);

        this.collection.models = _.filter(this.collection.models, function (model) {
            return model.has('meta') &&
                model.get('name') != model.get('meta').sid
        });

        return this;
    });

    girder.wrap(girder.views.EditItemWidget, 'render', function (render) {
        render.call(this);

        // Pretend the IQR session id doesn't exist for purposes of naming
        if ($('#g-name').val() == imagespace.smqtk.iqr.currentIqrSession.get('meta').sid) {
            $('#g-name').val('');
        }

        $('#g-name').focus();

        return this;
    });

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-refine'] = function (event) {
        var session = imagespace.smqtk.iqr.currentIqrSession;

        if (_.size(session.get('meta').pos_uuids) === 0) {
            alert('Refinement requires at least 1 positive example.');
            return;
        }

        $('button#smqtk-iqr-refine').append('    <i class="icon-spin5 animate-spin"></i>');

        girder.restRequest({
            path: 'smqtk_iqr/refine',
            type: 'PUT',
            contentType: 'application/json',
            data: JSON.stringify({
                sid: session.get('meta').sid,
                pos_uuids: session.get('meta').pos_uuids,
                neg_uuids: session.get('meta').neg_uuids
            })
        }).done(function () {
            imagespace.smqtk.iqr.createOrUpdateRefineView();
        }).error(console.error);
    };

    imagespace.views.SearchView.prototype.events['click #smqtk-iqr-save-session'] = function (event) {
        new girder.views.EditItemWidget({
            el: $('#g-dialog-container'),
            item: imagespace.smqtk.iqr.currentIqrSession,
            parentView: imagespace.searchView
        }).render();
    };
});
<|endoftext|>


<commit_before>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;

  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();
    console.log("entre amigo", map)

  } else {
    console.log("entre mapaboxs");
    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);
                console.log("elimina el mapa?");
            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);
                console.log("elimina el mapa?");
            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.marker_map = function(from, to, map){
    console.log("mapa from ->", from);
    console.log("mapa to ->", to);
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });

    //L.marker([37.35337508231001,-121.93626880645752], {icon: IconStart}).bindPopup('From').addTo(map);
    //L.marker([37.44377324953697,-122.16601610183714], {icon: IconEnd}).bindPopup('to').addTo(map);
    //var leaflet_label = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true});
    //leaflet_label.bindLabel('From');
    //leaflet_label.addTo(map);
    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(map);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(map);

    var _this = this;
    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       console.log("cordenadas drag from ->",result);
       _this.cleanPolyline();
    });

    markerto.on('dragend', function(e){
        var marker = e.target;
        var result = marker.getLatLng();
        console.log("cordenadas drag to ->",result);
        _this.cleanPolyline();
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map){

    //console.log("mapa point to ->", to);
    var name = to[2];

//    var myIcon = L.divIcon({className: 'leaflet-div-icon'});
//// you can set .my-div-icon styles in CSS
//
//    L.marker([to[0], to[1]], {icon: myIcon}).addTo(map);

    //var myIcon = L.CircleMarker({
    //    iconUrl: 'assets/images/graphics/icono.svg',
    //    iconSize: [20, 20],
    //    iconAnchor: [10, 10],
    //    labelAnchor: [6, 0] // as I want the label to appear 2px past the icon (10 + 2 - 6)
    //});
    //L.marker([to[0], to[1]], {
    //    icon: myIcon
    //}).bindLabel(name, {
    //    noHide: true,
    //    direction: 'auto'
    //}).addTo(map);

    //var circle = L.circle([to[0], to[1]], 700, {
    //    color: '#000',
    //    weight: 3,
    //    fillColor: '#ffffff',
    //    fillOpacity: 1
    //}).bindLabel(name, {
    //    noHide: true,
    //    direction: 'auto'
    //}).addTo(map);

    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/icono.svg',
        iconSize: [20, 20],
        iconAnchor: [0, 0],
        popupAnchor:  [-3, -76]
    });
    var markers = [
      L.marker([to[0], to[1]], {icon: IconEnd})
    ];
    var layer = L.layerGroup(markers).addTo(map).eachLayer(function(layer){layer.showLabel()});

    //for( i in layer._layers)
    //  layer._layers[i].showLabel();

    //var myZoom = {
    //  start:  map.getZoom(),
    //  end: map.getZoom()
    //};
    ////console.log(myZoom);
    //map.on('zoomstart', function(e) {
    //   myZoom.start = map.getZoom();
    //    //console.log("start zoom 400 ", myZoom.start);
    //});
    //
    //map.on('zoomend', function(e) {
    //    myZoom.end = map.getZoom();
    //     //console.log("End zoom ", myZoom.end);
    //    var diff = myZoom.start - myZoom.end;
    //    if (diff > 0) {
    //        circle.setRadius(circle.getRadius() * 2);
    //    } else if (diff < 0) {
    //        circle.setRadius(circle.getRadius() / 2);
    //    }
    //});

    //this.polyline_creadas.push(circle);
};

module.exports.drawRouteAmigo = function(route,mode) {
      var color = '#000';
      var weight = 5;
      var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
            color = '#FF0000';
             weight = 8;

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }
        else if(mode=="BUS") {
            color = '#FEF0B5';
             weight = 8;
        }

       var color_options = {
            color: color,
            opacity: 1,
            weight: weight,
            dashArray: dasharray
        };

      route = new L.Polyline(L.PolylineUtil.decode(route, 5), color_options);
      this.polyline_creadas.push(route);
        //module.exports.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      var bounds = new L.LatLngBounds([]);
      var boxpolys = new Array(boxes.length);

      for (var i = 0; i < boxes.length; i++) {
        bounds.extend(boxes[i]);
      }
      route.addTo(this.activeMap);
      this.activeMap.fitBounds(bounds);
};

<commit_msg>adding elemtes<commit_after>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;

  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();
    console.log("entre amigo", map)

  } else {
    console.log("entre mapaboxs");
    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);
                console.log("elimina el mapa?");
            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);
                console.log("elimina el mapa?");
            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.marker_map = function(from, to, map){
    console.log("mapa from ->", from);
    console.log("mapa to ->", to);
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });

    //L.marker([37.35337508231001,-121.93626880645752], {icon: IconStart}).bindPopup('From').addTo(map);
    //L.marker([37.44377324953697,-122.16601610183714], {icon: IconEnd}).bindPopup('to').addTo(map);
    //var leaflet_label = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true});
    //leaflet_label.bindLabel('From');
    //leaflet_label.addTo(map);
    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(map);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(map);

    var _this = this;
    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       console.log("cordenadas drag from ->",result);
       _this.cleanPolyline();
    });

    markerto.on('dragend', function(e){
        var marker = e.target;
        var result = marker.getLatLng();
        console.log("cordenadas drag to ->",result);
        _this.cleanPolyline();
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map){

    //console.log("mapa point to ->", to);
    var name = to[2];

//    var myIcon = L.divIcon({className: 'leaflet-div-icon'});
//// you can set .my-div-icon styles in CSS
//
//    L.marker([to[0], to[1]], {icon: myIcon}).addTo(map);

    //var myIcon = L.CircleMarker({
    //    iconUrl: 'assets/images/graphics/icono.svg',
    //    iconSize: [20, 20],
    //    iconAnchor: [10, 10],
    //    labelAnchor: [6, 0] // as I want the label to appear 2px past the icon (10 + 2 - 6)
    //});
    //L.marker([to[0], to[1]], {
    //    icon: myIcon
    //}).bindLabel(name, {
    //    noHide: true,
    //    direction: 'auto'
    //}).addTo(map);

    //var circle = L.circle([to[0], to[1]], 700, {
    //    color: '#000',
    //    weight: 3,
    //    fillColor: '#ffffff',
    //    fillOpacity: 1
    //}).bindLabel(name, {
    //    noHide: true,
    //    direction: 'auto'
    //}).addTo(map);

    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/icono.svg',
        iconSize: [20, 20],
        iconAnchor: [0, 0],
        popupAnchor:  [-3, -76]
    });
    var markers = [
      L.marker([to[0], to[1]], {icon: IconEnd}).bindLabel(name)
    ];
    var layer = L.layerGroup(markers).addTo(map).eachLayer(function(layer){layer.showLabel()});

    //for( i in layer._layers)
    //  layer._layers[i].showLabel();

    //var myZoom = {
    //  start:  map.getZoom(),
    //  end: map.getZoom()
    //};
    ////console.log(myZoom);
    //map.on('zoomstart', function(e) {
    //   myZoom.start = map.getZoom();
    //    //console.log("start zoom 400 ", myZoom.start);
    //});
    //
    //map.on('zoomend', function(e) {
    //    myZoom.end = map.getZoom();
    //     //console.log("End zoom ", myZoom.end);
    //    var diff = myZoom.start - myZoom.end;
    //    if (diff > 0) {
    //        circle.setRadius(circle.getRadius() * 2);
    //    } else if (diff < 0) {
    //        circle.setRadius(circle.getRadius() / 2);
    //    }
    //});

    //this.polyline_creadas.push(circle);
};

module.exports.drawRouteAmigo = function(route,mode) {
      var color = '#000';
      var weight = 5;
      var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
            color = '#FF0000';
             weight = 8;

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }
        else if(mode=="BUS") {
            color = '#FEF0B5';
             weight = 8;
        }

       var color_options = {
            color: color,
            opacity: 1,
            weight: weight,
            dashArray: dasharray
        };

      route = new L.Polyline(L.PolylineUtil.decode(route, 5), color_options);
      this.polyline_creadas.push(route);
        //module.exports.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      var bounds = new L.LatLngBounds([]);
      var boxpolys = new Array(boxes.length);

      for (var i = 0; i < boxes.length; i++) {
        bounds.extend(boxes[i]);
      }
      route.addTo(this.activeMap);
      this.activeMap.fitBounds(bounds);
};

<|endoftext|>


<commit_before>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const React = require('react');
const Router = require('react-router');
const routes = require('router/routes');

window.jQuery = require('jquery');
window.$ = window.jQuery;

require('quick-start.md');

if (process.env.NODE_ENV !== 'production') {
    window.React = React;
}

Router.run(routes, (Handler, options) => {
    setTimeout(() => {
        ga('send', 'pageview', {
            'location': options.path,
            'title': document.title
        });
    }, 0);

    React.render(<Handler />, document.getElementById('root'));
});<commit_msg>Addthis layers test<commit_after>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const React = require('react');
const Router = require('react-router');
const routes = require('router/routes');

window.jQuery = require('jquery');
window.$ = window.jQuery;

require('quick-start.md');

if (process.env.NODE_ENV !== 'production') {
    window.React = React;
}

Router.run(routes, (Handler, options) => {
    setTimeout(() => {
        ga('send', 'pageview', {
            'location': options.path,
            'title': document.title
        });
    });

    React.render(<Handler />, document.getElementById('root'));

    // If addthis has been loaded and we route change then refresh layers.
    if (typeof addthis !== 'undefined') {
        addthis.layers.refresh();
    }
});<|endoftext|>