<commit_before>/**
* This file is part of taolin project (http://taolin.fbk.eu)
* Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
* Authors: SoNet Group (see AUTHORS.txt)
*
* Taolin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* Taolin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Taolin. If not, see <http://www.gnu.org/licenses/>.
*
*/

CommentWindow = function(model_alias, foreign_id) {

    var fm = Ext.util.Format;
    this.model = fm.lowercase(model_alias) + 's';  // Format model's name in order to use it in the ajax request (e.g.: 'Board' -> 'boards')
    this.f_id = foreign_id;

    this.store = new Ext.data.JsonStore({
        url: this.model + '/getcomments/' + this.f_id
        ,root: 'comments'
        ,method: 'GET'
        ,fields: ['id','user_id','body', {name: 'created', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 'user_name', 'user_surname']
        ,autoLoad: true
        ,listeners:{
            load: {
                fn: function(){
                    this.center();
                    var details = this.store.reader.jsonData.details;
                    $("#commented-event")
                        .css({
                            'background':'#ECEFF5',
                            'margin':'auto auto',
                            'padding':'10px 5px'
                        }) // Styling
                        .html(details.smilize().urlize());

                    // check if the window is out of the browser view
                    var pos = this.getPosition(true);
                    this.setPosition(pos[0], pos[1] > 0 ? pos[1] : 0);
                }
                ,scope: this
            }
        }
    });

    var logSource = fm.htmlEncode('{"source": "comment", "id": "{id}"}');
    this.view = new Ext.DataView({
        store: this.store
        ,tpl: new Ext.XTemplate(
            '<tpl for=".">',
                '
',
                    '
',
                        '
',
                            '',
                                '
',
                                    '',
                                '
',
                            '	',
                            '',
                                '{user_name} {user_surname} {[values.body.urlize().smilize()]}',
                                '
{created:naturalDate(true)}
',
                            '	',
                            /*'<tpl if="this.isOwner(user_id)">',
                                '',
                                    '',
                                '	',
                            '</tpl>',*/
                        '
',
                    '
',
                '
',
            '</tpl>'
            ,{
                compiled: true
            }
        )
        ,emptyText: '

No comment yet! Be the first to comment!

'
	    ,itemSelector: 'div.comment'
        ,height: 300
        ,autoScroll: true
    });

    this.form = new Ext.form.FormPanel({
        autoWidth: true
        ,autoHeight: true
        ,buttonAlign: 'center'
        ,style: 'padding: 10px 20px'
        ,labelAlign: 'top'
        ,border: false
        ,frame: false
        ,cls: 'form_settings'
        ,layoutConfig: {
            // layout-specific configs go here
            labelSeparator: ''
        }
        ,items: [{
            xtype: 'textarea'
            ,fieldLabel: 'Add your comment
Please note that in this early version, you can NOT delete comments! Read your comment very carefully before submitting it!'
            ,grow: true
            ,growMin: 25
            ,growMax: 200
            ,name: 'comment'
            ,anchor: '100%'
        }],
        buttons: [{
            text: 'Comment'
            ,handler: function(){

                var store = this.view.store;
                var model = this.model;

                this.form.getForm().submit(
                    {
                        url: model + '/addcomment',
                        waitMsg:'Adding comment...',
                        params:{
                            foreign_id: this.f_id
                        },
                        success: function(form,action){
                            form.reset(); // Cleaning form
                            store.reload();
                            eventManager.fireEvent("addcomment", model);
                        }
                    }
                );

            }
            ,scope: this
            ,formBind: true
        },{
            text: 'Close'
            ,handler: function(){
                this.close();
            }
            ,scope: this
        }]
    });

    CommentWindow.superclass.constructor.call(this, {
        title: 'Comments'
        ,id: 'comments_window'
        ,autoHeight: true
        ,width: 500
        ,resizable: true
        ,iconCls:'chatwindowicon'
        ,constrain: true
        ,items: [{
            html: '

'
        },{
            items: this.view
            ,border: false
            ,autoScroll: true
        },{
            items: this.form
            ,border: false
        }]
    });

    this.show();
}

Ext.extend(CommentWindow, Ext.Window);
<commit_msg>Fixed a bug in the CommentWindow<commit_after>/**
* This file is part of taolin project (http://taolin.fbk.eu)
* Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
* Authors: SoNet Group (see AUTHORS.txt)
*
* Taolin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* Taolin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Taolin. If not, see <http://www.gnu.org/licenses/>.
*
*/

CommentWindow = function(model_alias, foreign_id) {

    var fm = Ext.util.Format;
    this.model = fm.lowercase(model_alias) + 's';  // Format model's name in order to use it in the ajax request (e.g.: 'Board' -> 'boards')
    this.f_id = foreign_id;

    this.store = new Ext.data.JsonStore({
        url: this.model + '/getcomments/' + this.f_id
        ,root: 'comments'
        ,method: 'GET'
        ,fields: ['id','user_id','body', {name: 'created', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 'user_name', 'user_surname']
        ,autoLoad: true
        ,listeners:{
            load: {
                fn: function(){
                    this.center();
                    var details = this.store.reader.jsonData.details;
                    $("#commented-event")
                        .css({
                            'background':'#ECEFF5',
                            'margin':'auto auto',
                            'padding':'10px 5px'
                        }) // Styling
                        .html(details.smilize().urlize());

                    // check if the window is out of the browser view
                    var pos = this.getPosition(true);
                    this.setPosition(pos[0], pos[1] > 0 ? pos[1] : 0);
                }
                ,scope: this
            }
        }
    });

    var logSource = fm.htmlEncode('{"source": "comment", "id": "{id}"}');
    this.view = new Ext.DataView({
        store: this.store
        ,tpl: new Ext.XTemplate(
            '<tpl for=".">',
                '
',
                    '
',
                        '
',
                            '',
                                '
',
                                    '',
                                '
',
                            '	',
                            '',
                                '{user_name} {user_surname} {[values.body.urlize().smilize()]}',
                                '
{created:naturalDate(true)}
',
                            '	',
                            /*'<tpl if="this.isOwner(user_id)">',
                                '',
                                    '',
                                '	',
                            '</tpl>',*/
                        '
',
                    '
',
                '
',
            '</tpl>'
            ,{
                compiled: true
            }
        )
        ,emptyText: '

No comment yet! Be the first to comment!

'
	    ,itemSelector: 'div.comment'
        ,height: 300
        ,autoScroll: true
    });

    this.form = new Ext.form.FormPanel({
        autoWidth: true
        ,autoHeight: true
        ,buttonAlign: 'center'
        ,style: 'padding: 10px 20px'
        ,labelAlign: 'top'
        ,border: false
        ,frame: false
        ,cls: 'form_settings'
        ,layoutConfig: {
            // layout-specific configs go here
            labelSeparator: ''
        }
        ,items: [{
            xtype: 'textarea'
            ,fieldLabel: 'Add your comment
Please note that in this early version, you can NOT delete comments! Read your comment very carefully before submitting it!'
            ,grow: true
            ,growMin: 25
            ,growMax: 200
            ,name: 'comment'
            ,anchor: '100%'
        }],
        buttons: [{
            text: 'Comment'
            ,handler: function(){

                var store = this.view.store;
                var model = this.model;

                this.form.getForm().submit(
                    {
                        url: model + '/addcomment',
                        waitMsg:'Adding comment...',
                        params:{
                            foreign_id: this.f_id
                        },
                        success: function(form,action){
                            form.reset(); // Cleaning form
                            store.reload();
                            eventManager.fireEvent("addcomment", model);
                        }
                    }
                );

            }
            ,scope: this
            ,formBind: true
        },{
            text: 'Close'
            ,handler: function(){
                this.close();
            }
            ,scope: this
        }]
    });

    CommentWindow.superclass.constructor.call(this, {
        title: 'Comments'
        ,id: 'comments_window'
        ,autoHeight: true
        ,width: 500
        ,resizable: true
        ,iconCls:'chatwindowicon'
        ,constrain: true
        ,items: [{
            html: '

'
        },{
            items: this.view
            ,border: false
            ,autoScroll: true
        },{
            items: this.form
            ,border: false
        }]
    });

    this.show();
}

Ext.extend(CommentWindow, Ext.Window);
<|endoftext|>


<commit_before>/**
* This file is part of taolin project (http://taolin.fbk.eu)
* Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
* Authors: SoNet Group (see AUTHORS.txt)
*
* Taolin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* Taolin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Taolin. If not, see <http://www.gnu.org/licenses/>.
*
*/

function openCommentWindow(model, foreign_key, logparams){

    var comments_window = Ext.getCmp('comments_window');

    if(comments_window) // if not exist
        comments_window.close();

    new CommentWindow(model, foreign_key, logparams); // Open a new comment window
}

CommentWindow = function(model_alias, foreign_id, logparams) {

    if (!logparams)
        alert('No logparams!');
    var fm = Ext.util.Format
        ,t = this;
    t.model = fm.lowercase(model_alias) + 's';  // Format model's name in order to use it in the ajax request (e.g.: 'Board' -> 'boards')
    t.f_id = foreign_id;

    t.store = new Ext.data.JsonStore({
        url: t.model + '/getcomments/' + t.f_id
        ,root: 'comments'
        ,baseParams: {src:Ext.util.JSON.encode(logparams)}
        ,fields: ['id','user_id','body', {name: 'created', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 'user_name', 'user_surname']
        ,autoLoad: true
        ,listeners:{
            load: {
                fn: function(store, records, options){
                    var data = store.reader.jsonData
                        ,details = data.details
                        //this is not about comments, but commented event!
                        ,aDate = data.created.split(" ")[0].split('-')
                        ,created = fm.date(
                            // IE doesn't like '2000-02-01'-like date (it requires 'February 01, 2000')
                            new Date(aDate[0], aDate[1] - 1, aDate[2]),
                            'd F, Y'
                        );

                    /* If this is the first time that the window is loaded
                     * then create the commented event's html
                     */
                    if ( !$("#commented-event").html().length )
                        $("#commented-event")
                            .empty()
                            .append(
                                $('
')
                                .css({
                                    'margin-bottom': '3px',
                                    'font-size': '90%',
                                    'font-variant': 'small-caps'
                                })
                                .text(created)
                            )
                            .append(
                                $('
')
                                .html(details.smilize().urlize())
                            )
                            .css({
                                background:'#ECEFF5',
                                margin:'auto auto',
                                padding:'10px 5px'
                            }); // Styling

                    // Center the window
                    this.center();

                    // check if the window is out of the browser view
                    var pos = this.getPosition(true);
                    this.setPosition(pos[0], pos[1] > 0 ? pos[1] : 0);
                }
                ,scope: this
            }
        }
    });

    var uiLogSource = '{source: \'comment\', id: {id}}';
    t.view = new Ext.DataView({
        store: this.store
        ,tpl: new Ext.XTemplate(
            '<tpl for=".">',
                '
',
                    '
',
                        '
',
                            '',
                                '
',
                                    '',
                                '
',
                            '	',
                            '',
                                '{user_name} {user_surname} {[values.body.urlize().smilize()]}',
                                '
{created:naturalDate(true)}
',
                            '	',
                            '<tpl if="isOwner(user_id)">',
                                '',
                                    '',
                                '	',
                            '</tpl>',
                        '
',
                    '
',
                '
',
            '</tpl>'
            ,{
                compiled: true
                ,parentId: 'comments_window'
            }
        )
        ,emptyText: '
No comment yet! Be the first to comment!
'
	    ,itemSelector: 'div.comment'
        ,height: 300
    });

    t.form = new Ext.form.FormPanel({
        autoWidth: true
        ,autoHeight: true
        ,buttonAlign: 'center'
        ,style: 'padding: 10px 20px'
        ,labelAlign: 'top'
        ,border: false
        ,frame: false
        ,cls: 'form_settings'
        ,layoutConfig: {
            // layout-specific configs go here
            labelSeparator: ''
        }
        ,items: [{
            xtype: 'textarea'
            ,fieldLabel: 'Add your comment'
            ,grow: true
            ,growMin: 25
            ,growMax: 200
            ,name: 'comment'
            ,anchor: '100%'
        }],
        buttons: [{
            text: 'Comment'
            ,handler: function(){
                var store = this.view.store
                    ,model = this.model;

                this.form.getForm().submit(
                    {
                        url: model + '/addcomment',
                        waitMsg:'Adding comment...',
                        params:{
                            foreign_id: this.f_id
                        },
                        success: function(form,action){
                            form.reset(); // Cleaning form
                            store.reload();
                            eventManager.fireEvent("addcomment", model);
                        }
                    }
                );

            }
            ,scope: this
            ,formBind: true
        },{
            text: 'Close'
            ,handler: function(){
                this.close();
            }
            ,scope: this
        }]
    });

    t.deleteComment = function(c_id){
        var model = this.model
            ,store = this.view.store;
        Ext.MessageBox.confirm('Confirm', 'Do you really want to do delete this comment?', function(btn){
            if(btn == 'yes'){
                Ext.Ajax.request({
                    url : model+'/delcomment/'+c_id ,
                    method: 'GET',
                    success: function(result, request){
                            eventManager.fireEvent("removecomment", model);
                            store.reload();
                    },
                    failure: function(){
                        Ext.Msg.show({
                            title: 'Warning!',
                            msg: 'Problem found in data transmission',
                            width: 400,
                            icon: Ext.MessageBox.WARNING
                        });
                    }
                });
            }
        });
    }

    CommentWindow.superclass.constructor.call(t, {
        title: 'Comments'
        ,id: 'comments_window'
        ,autoHeight: true
        ,width: 500
        ,resizable: true
        ,iconCls:'comment-icon'
        ,constrain: true
        ,items: [{
            html: '

'
        },{
            items: t.view
            ,border: false
            ,autoScroll: true
        },{
            items: t.form
            ,border: false
        }]
    });

    t.show();
}

Ext.extend(CommentWindow, Ext.Window);
<commit_msg>Focusing textarea on comment window open. Closes #73<commit_after>/**
* This file is part of taolin project (http://taolin.fbk.eu)
* Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
* Authors: SoNet Group (see AUTHORS.txt)
*
* Taolin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* Taolin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Taolin. If not, see <http://www.gnu.org/licenses/>.
*
*/

function openCommentWindow(model, foreign_key, logparams){

    var comments_window = Ext.getCmp('comments_window');

    if(comments_window) // if not exist
        comments_window.close();

    new CommentWindow(model, foreign_key, logparams); // Open a new comment window
}

CommentWindow = function(model_alias, foreign_id, logparams) {

    if (!logparams)
        alert('No logparams!');
    var fm = Ext.util.Format
        ,t = this;
    t.model = fm.lowercase(model_alias) + 's';  // Format model's name in order to use it in the ajax request (e.g.: 'Board' -> 'boards')
    t.f_id = foreign_id;

    t.store = new Ext.data.JsonStore({
        url: t.model + '/getcomments/' + t.f_id
        ,root: 'comments'
        ,baseParams: {src:Ext.util.JSON.encode(logparams)}
        ,fields: ['id','user_id','body', {name: 'created', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 'user_name', 'user_surname']
        ,autoLoad: true
        ,listeners:{
            load: {
                fn: function(store, records, options){
                    var data = store.reader.jsonData
                        ,details = data.details
                        //this is not about comments, but commented event!
                        ,aDate = data.created.split(" ")[0].split('-')
                        ,created = fm.date(
                            // IE doesn't like '2000-02-01'-like date (it requires 'February 01, 2000')
                            new Date(aDate[0], aDate[1] - 1, aDate[2]),
                            'd F, Y'
                        );

                    /* If this is the first time that the window is loaded
                     * then create the commented event's html
                     */
                    if ( !$("#commented-event").html().length )
                        $("#commented-event")
                            .empty()
                            .append(
                                $('
')
                                .css({
                                    'margin-bottom': '3px',
                                    'font-size': '90%',
                                    'font-variant': 'small-caps'
                                })
                                .text(created)
                            )
                            .append(
                                $('
')
                                .html(details.smilize().urlize())
                            )
                            .css({
                                background:'#ECEFF5',
                                margin:'auto auto',
                                padding:'10px 5px'
                            }); // Styling

                    // Center the window
                    this.center();

                    // check if the window is out of the browser view
                    var pos = this.getPosition(true);
                    this.setPosition(pos[0], pos[1] > 0 ? pos[1] : 0);
                }
                ,scope: this
            }
        }
    });

    var uiLogSource = '{source: \'comment\', id: {id}}';
    t.view = new Ext.DataView({
        store: this.store
        ,tpl: new Ext.XTemplate(
            '<tpl for=".">',
                '
',
                    '
',
                        '
',
                            '',
                                '
',
                                    '',
                                '
',
                            '	',
                            '',
                                '{user_name} {user_surname} {[values.body.urlize().smilize()]}',
                                '
{created:naturalDate(true)}
',
                            '	',
                            '<tpl if="isOwner(user_id)">',
                                '',
                                    '',
                                '	',
                            '</tpl>',
                        '
',
                    '
',
                '
',
            '</tpl>'
            ,{
                compiled: true
                ,parentId: 'comments_window'
            }
        )
        ,emptyText: '
No comment yet! Be the first to comment!
'
	    ,itemSelector: 'div.comment'
        ,height: 300
    });

    t.form = new Ext.form.FormPanel({
        autoWidth: true
        ,autoHeight: true
        ,buttonAlign: 'center'
        ,style: 'padding: 10px 20px'
        ,labelAlign: 'top'
        ,border: false
        ,frame: false
        ,cls: 'form_settings'
        ,layoutConfig: {
            // layout-specific configs go here
            labelSeparator: ''
        }
        ,items: [{
            xtype: 'textarea'
            ,id: 'comment_field'
            ,fieldLabel: 'Add your comment'
            ,grow: true
            ,growMin: 25
            ,growMax: 200
            ,name: 'comment'
            ,anchor: '100%'
        }],
        buttons: [{
            text: 'Comment'
            ,handler: function(){
                var store = this.view.store
                    ,model = this.model;

                this.form.getForm().submit(
                    {
                        url: model + '/addcomment',
                        waitMsg:'Adding comment...',
                        params:{
                            foreign_id: this.f_id
                        },
                        success: function(form,action){
                            form.reset(); // Cleaning form
                            store.reload();
                            eventManager.fireEvent("addcomment", model);
                        }
                    }
                );

            }
            ,scope: this
            ,formBind: true
        },{
            text: 'Close'
            ,handler: function(){
                this.close();
            }
            ,scope: this
        }]
    });

    t.deleteComment = function(c_id){
        var model = this.model
            ,store = this.view.store;
        Ext.MessageBox.confirm('Confirm', 'Do you really want to do delete this comment?', function(btn){
            if(btn == 'yes'){
                Ext.Ajax.request({
                    url : model+'/delcomment/'+c_id ,
                    method: 'GET',
                    success: function(result, request){
                            eventManager.fireEvent("removecomment", model);
                            store.reload();
                    },
                    failure: function(){
                        Ext.Msg.show({
                            title: 'Warning!',
                            msg: 'Problem found in data transmission',
                            width: 400,
                            icon: Ext.MessageBox.WARNING
                        });
                    }
                });
            }
        });
    }

    CommentWindow.superclass.constructor.call(t, {
        title: 'Comments'
        ,id: 'comments_window'
        ,autoHeight: true
        ,width: 500
        ,resizable: true
        ,iconCls:'comment-icon'
        ,constrain: true
        ,defaultButton: 'comment_field'
        ,items: [{
            html: '

'
        },{
            items: t.view
            ,border: false
            ,autoScroll: true
        },{
            items: t.form
            ,border: false
        }]
    });

    t.show();
}

Ext.extend(CommentWindow, Ext.Window);
<|endoftext|>


<commit_before>import {AoiInfobar} from '../components/AoiInfobar';
import React from 'react';
import {expect} from 'chai';
import sinon from 'sinon';
import {mount, shallow} from 'enzyme';

describe('AoiInfobar component', () => {
    const getProps = () => {
        return {
            aoiInfo: {
                geojson: {},
                geomType: null,
                title: null,
                description: null,
            },
            zoomToSelection: {
                disabled: true,
                click: false
            },
            resetMap: {
                disabled: true,
                click: false
            },
            toggleZoomToSelection: (bool) => {},
            clickZoomToSelection: () => {},
            toggleResetMap: (bool) => {},
            clickResetMap: () => {},
        }
    };

    const geojson = { "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
         "geometry": {
           "type": "Polygon",
           "coordinates": [
             [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
               [100.0, 1.0], [100.0, 0.0] ]
             ]
         },}]};

    it('should not display the infobar by default', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        expect(wrapper.find('div')).to.have.length(2);
        expect(wrapper.find('aoiInfobar')).to.have.length(0);
    });

    // it('should display the default topbar information',() => {
    //     let props = getProps();
    //     const wrapper = mount(<AoiInfobar {...props}/>);

    // });

    // it('should display the default detailbar information', () => {
    //     let props = getProps();
    //     const wrapper = mount(<AoiInfobar {...props}/>);
    //     expect(wrapper.find('.detailBar')).to.have.length(1);
    //     expect(wrapper.find('i')).to.have.length(3);
    //     expect(wrapper.find('i').last().text()).to.equal('warning');
    //     expect(wrapper.find('.detailText')).to.have.length(1);
    //     expect(wrapper.find('.aoiTitle').text()).to.equal('');
    //     expect(wrapper.find('.aoiDescription').text()).to.equal('No AOI Set');
    // });

    it('should handle aoiInfo update', () => {
        let props = getProps();
        props.toggleResetMap = sinon.spy();
        props.toggleZoomToSelection = sinon.spy()
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        wrapper.setProps(nextProps);

        expect(wrapper.find('div')).to.have.length(8);
        expect(wrapper.find('.aoiInfoWrapper')).to.have.length(1);
        expect(wrapper.find('.topBar')).to.have.length(1);
        expect(wrapper.find('.aoiInfoTitle').text()).to.equal('Area Of Interest (AOI)');
        expect(wrapper.find('.simpleButton .inactiveButton')).to.have.length(2);
        expect(wrapper.find('.simpleButton').first().text()).to.equal(' ZOOM TO SELECTION');
        expect(wrapper.find('.simpleButton').last().text()).to.equal(' RESET VIEW');
        expect(wrapper.find('.fa-search-plus')).to.have.length(1);
        expect(wrapper.find('.fa-refresh')).to.have.length(1);

        expect(wrapper.find('.aoiTitle').text()).to.equal('fake title');
        expect(wrapper.find('.aoiDescription').text()).to.equal('fake description');
        expect(wrapper.find('.material-icons').first().text()).to.equal('crop_square');
        expect(props.toggleResetMap.calledWith(false)).to.equal(true);
        expect(props.toggleZoomToSelection.calledWith(false)).to.equal(true);
    });

    it('should handle zoomToSelection state update', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        nextProps.zoomToSelection.disabled = false;
        wrapper.instance().updateZoomToSelectionState = sinon.spy(wrapper.instance(), 'updateZoomToSelectionState');
        wrapper.setProps(nextProps);
        expect(wrapper.instance().updateZoomToSelectionState.calledOnce).to.equal(true);
        expect(wrapper.find('.simpleButton .activeButton')).to.have.length(1);
    });

    it('should handle resetMap state update', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        nextProps.resetMap.disabled = false;
        wrapper.instance().updateResetMapState = sinon.spy(wrapper.instance(), 'updateResetMapState');
        wrapper.setProps(nextProps);
        expect(wrapper.instance().updateResetMapState.calledOnce).to.equal(true);
        expect(wrapper.find('.simpleButton .activeButton')).to.have.length(1);
    });

    // it('clicking on disabled buttons should do nothing', () => {
    //     let props = getProps();
    //     props.clickResetMap = sinon.spy();
    //     props.clickZoomToSelection = sinon.spy();
    //     const wrapper = mount(<AoiInfobar {...props}/>);
    //     wrapper.find('.simpleButton').first().simulate('click');
    //     wrapper.find('.simpleButton').last().simulate('click');
    //     expect(props.clickZoomToSelection.calledOnce).to.equal(false);
    //     expect(props.clickResetMap.calledOnce).to.equal(false);
    // });

    it('clicking on active buttons should execute click functions', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        nextProps.clickResetMap = sinon.spy();
        nextProps.clickZoomToSelection = sinon.spy();
        nextProps.zoomToSelection.disabled = false,
        nextProps.resetMap.disabled = false,
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        wrapper.setProps(nextProps);
        wrapper.find('.simpleButton').first().simulate('click');
        wrapper.find('.simpleButton').last().simulate('click');
        expect(nextProps.clickZoomToSelection.calledOnce).to.equal(true);
        expect(nextProps.clickResetMap.calledOnce).to.equal(true);
    })
});<commit_msg>remove old code<commit_after>import {AoiInfobar} from '../components/AoiInfobar';
import React from 'react';
import {expect} from 'chai';
import sinon from 'sinon';
import {mount, shallow} from 'enzyme';

describe('AoiInfobar component', () => {
    const getProps = () => {
        return {
            aoiInfo: {
                geojson: {},
                geomType: null,
                title: null,
                description: null,
            },
            zoomToSelection: {
                disabled: true,
                click: false
            },
            resetMap: {
                disabled: true,
                click: false
            },
            toggleZoomToSelection: (bool) => {},
            clickZoomToSelection: () => {},
            toggleResetMap: (bool) => {},
            clickResetMap: () => {},
        }
    };

    const geojson = { "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
         "geometry": {
           "type": "Polygon",
           "coordinates": [
             [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
               [100.0, 1.0], [100.0, 0.0] ]
             ]
         },}]};

    it('should not display the infobar by default', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        expect(wrapper.find('div')).to.have.length(2);
        expect(wrapper.find('aoiInfobar')).to.have.length(0);
    });

    it('should handle aoiInfo update', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        wrapper.setProps(nextProps);

        expect(wrapper.find('div')).to.have.length(8);
        expect(wrapper.find('.aoiInfoWrapper')).to.have.length(1);
        expect(wrapper.find('.topBar')).to.have.length(1);
        expect(wrapper.find('.aoiInfoTitle').text()).to.equal('Area Of Interest (AOI)');
        expect(wrapper.find('.simpleButton .activeButton')).to.have.length(1);
        expect(wrapper.find('.simpleButton').first().text()).to.equal(' ZOOM TO SELECTION');
        // expect(wrapper.find('.simpleButton').last().text()).to.equal(' RESET VIEW');
        expect(wrapper.find('.fa-search-plus')).to.have.length(1);
        // expect(wrapper.find('.fa-refresh')).to.have.length(1);

        expect(wrapper.find('.aoiTitle').text()).to.equal('fake title');
        expect(wrapper.find('.aoiDescription').text()).to.equal('fake description');
        expect(wrapper.find('.material-icons').first().text()).to.equal('crop_square');
    });

    it('clicking on active buttons should execute click functions', () => {
        let props = getProps();
        const wrapper = mount(<AoiInfobar {...props}/>);
        let nextProps = getProps();
        // nextProps.clickResetMap = sinon.spy();
        nextProps.clickZoomToSelection = sinon.spy();
        nextProps.zoomToSelection.disabled = false,
        // nextProps.resetMap.disabled = false,
        nextProps.aoiInfo.geojson = geojson;
        nextProps.aoiInfo.description = 'fake description';
        nextProps.aoiInfo.geomType = 'Polygon';
        nextProps.aoiInfo.title = 'fake title';
        wrapper.setProps(nextProps);
        wrapper.find('.activeButton').simulate('click');
        expect(nextProps.clickZoomToSelection.calledOnce).to.equal(true);
        // expect(nextProps.clickResetMap.calledOnce).to.equal(true);
    })
});<|endoftext|>


<commit_before>/**
 * JQuery MultiDraggable Plugin
 *
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 *
 * Written by Sudheer Someshwara <sudheer.someshwara@gmail.com>. Changes made by Sprout to make use of jsPlumb.
 *
 * MultiDraggable is a jQuery plugin which extends jQuery UI Draggable to add multi drag and live functionality.
 *
**/
(function ($, undefined) {
   $.fn.multiDraggable = function (opts) {
   	var initLeftOffset = []
   	    ,initTopOffset = [];
   	var clickedNode;
   	return this.each(function () {
	         if (!$(this).data("init")) {
	            $(this).data("init", true).draggable(opts,{
	                helper: function() {
	                	clickedNode = this;
	            		var div = "
";
	            		$(opts.container).append(div);
	            		var scrollLeft = $(opts.container).scrollLeft();
	            		var scrollTop = $(opts.container).scrollTop();
						var pos = $(this).position();
						$.each($(opts.groupSel).add(this) || {}, function(key,value) {
							var elemPos = $(value).position();
							initLeftOffset[key] = elemPos.left - pos.left;
							initTopOffset[key] = elemPos.top - pos.top;
							var cloneNode = value.cloneNode(true);
							cloneNode.id += "_clone";
							$(cloneNode).addClass("silhouettes");
							$("#clone").append(cloneNode);
							clonePos = $(cloneNode).offset();
							$(cloneNode).offset({
								top: clonePos.top - pos.top - scrollTop,
								left: clonePos.left - pos.left - scrollLeft
							});
						});
						return $("#clone");
	            	},
			        start: function (event,ui) {
			        	opts.startNative ? opts.startNative() : {};
					},
					drag: function(event,ui) {
						opts.dragNative ? opts.dragNative() : {};
					},
					stop: function(event,ui) {
						var pos = $(ui.helper).offset();
						$.each($(opts.groupSel).add(clickedNode) || {}, function(key,value) {
							$(value).offset({left: pos.left + initLeftOffset[key],
							top: pos.top + initTopOffset[key]});
							jsPlumb.repaint($(this));
						});
						$("#clone").remove();
						opts.stopNative ? opts.stopNative() : {};
					},
				});
	        }
 	 });
   };
 }(jQuery));<commit_msg>Fixed wrong clone offset when dragging a node<commit_after>/**
 * JQuery MultiDraggable Plugin
 *
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 *
 * Written by Sudheer Someshwara <sudheer.someshwara@gmail.com>. Changes made by Sprout to make use of jsPlumb.
 *
 * MultiDraggable is a jQuery plugin which extends jQuery UI Draggable to add multi drag and live functionality.
 *
**/
(function ($, undefined) {
   $.fn.multiDraggable = function (opts) {
   	var initLeftOffset = []
   	    ,initTopOffset = [];
   	var clickedNode;
   	return this.each(function () {
	         if (!$(this).data("init")) {
	            $(this).data("init", true).draggable(opts,{
	                helper: function() {
	                	clickedNode = this;
	            		var div = "
";
	            		$(opts.container).append(div);
						var pos = $(this).position();
						$.each($(opts.groupSel).add(this) || {}, function(key,value) {
							var elemPos = $(value).position();
							initLeftOffset[key] = elemPos.left - pos.left;
							initTopOffset[key] = elemPos.top - pos.top;
							var cloneNode = value.cloneNode(true);
							cloneNode.id += "_clone";
							$(cloneNode).addClass("silhouettes");
							$("#clone").append(cloneNode);
							clonePos = $(cloneNode).offset();
							$(cloneNode).offset({
								top: clonePos.top - pos.top,
								left: clonePos.left - pos.left,
							});
						});
						return $("#clone");
	            	},
			        start: function (event,ui) {
			        	opts.startNative ? opts.startNative() : {};
					},
					drag: function(event,ui) {
						opts.dragNative ? opts.dragNative() : {};
					},
					stop: function(event,ui) {
						var pos = $(ui.helper).offset();
						$.each($(opts.groupSel).add(clickedNode) || {}, function(key,value) {
							$(value).offset({left: pos.left + initLeftOffset[key],
							top: pos.top + initTopOffset[key]});
							jsPlumb.repaint($(this));
						});
						$("#clone").remove();
						opts.stopNative ? opts.stopNative() : {};
					},
				});
	        }
 	 });
   };
 }(jQuery));<|endoftext|>


<commit_before>/* SpinButton control
 *
 * Adds bells and whistles to any ordinary textbox to
 * make it look and feel like a SpinButton Control.
 *
 * Originally written by George Adamson, Software Unity (george.jquery@softwareunity.com) August 2006.
 * - Added min/max options
 * - Added step size option
 * - Added bigStep (page up/down) option
 *
 * Modifications made by Mark Gibson, (mgibson@designlinks.net) September 2006:
 * - Converted to jQuery plugin
 * - Allow limited or unlimited min/max values
 * - Allow custom class names, and add class to input element
 * - Removed global vars
 * - Reset (to original or through config) when invalid value entered
 * - Repeat whilst holding mouse button down (with initial pause, like keyboard repeat)
 * - Support mouse wheel in Firefox
 * - Fix double click in IE
 * - Refactored some code and renamed some vars
 *
 * Modifications by Jeff Schiller, June 2009:
 * - provide callback function for when the value changes based on the following
 *   http://www.mail-archive.com/jquery-en@googlegroups.com/msg36070.html
 * Modifications by Jeff Schiller, July 2009:
 * - improve styling for widget in Opera
 * - consistent key-repeat handling cross-browser
 *
 * Tested in IE6, Opera9, Firefox 1.5
 * v1.0  11 Aug 2006 - George Adamson	- First release
 * v1.1     Aug 2006 - George Adamson	- Minor enhancements
 * v1.2  27 Sep 2006 - Mark Gibson		- Major enhancements
 * v1.3a 28 Sep 2006 - George Adamson	- Minor enhancements
 * v1.4  18 Jun 2009 - Jeff Schiller    - Added callback function
 * v1.5  06 Jul 2009 - Jeff Schiller    - Fixes for Opera.
 * v1.6  13 Oct 2009 - Alexis Deveria   - Added stepfunc function
 *                                        Fast-repeat for keys and live updating as you type.

 Sample usage:

	// Create group of settings to initialise spinbutton(s). (Optional)
	var myOptions = {
					min: 0,						// Set lower limit.
					max: 100,					// Set upper limit.
					step: 1,					// Set increment size.
					spinClass: mySpinBtnClass,	// CSS class to style the spinbutton. (Class also specifies url of the up/down button image.)
					upClass: mySpinUpClass,		// CSS class for style when mouse over up button.
					downClass: mySpinDnClass	// CSS class for style when mouse over down button.
					}

	$(document).ready(function(){

		// Initialise INPUT element(s) as SpinButtons: (passing options if desired)
		$("#myInputElement").SpinButton(myOptions);

	});

 */
$.fn.SpinButton = function(cfg){
	return this.each(function(){

		this.repeating = false;

		// Apply specified options or defaults:
		// (Ought to refactor this some day to use $.extend() instead)
		this.spinCfg = {
			//min: cfg && cfg.min ? Number(cfg.min) : null,
			//max: cfg && cfg.max ? Number(cfg.max) : null,
			min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null,	// Fixes bug with min:0
			max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
			step: cfg && cfg.step ? Number(cfg.step) : 1,
			stepfunc: cfg && cfg.stepfunc ? cfg.stepfunc : false,
			page: cfg && cfg.page ? Number(cfg.page) : 10,
			upClass: cfg && cfg.upClass ? cfg.upClass : 'up',
			downClass: cfg && cfg.downClass ? cfg.downClass : 'down',
			reset: cfg && cfg.reset ? cfg.reset : this.value,
			delay: cfg && cfg.delay ? Number(cfg.delay) : 500,
			interval: cfg && cfg.interval ? Number(cfg.interval) : 100,
			_btn_width: 20,
			_btn_height: 12,
			_direction: null,
			_delay: null,
			_repeat: null,
			callback: cfg && cfg.callback ? cfg.callback : null,
		};

		this.adjustValue = function(i){
			var v;
			if(isNaN(this.value)) {
				v = this.spinCfg.reset;
			} else if($.isFunction(this.spinCfg.stepfunc)) {
				v = this.spinCfg.stepfunc(this, i);
			} else {
				v = Number(this.value) + Number(i);
			}
			if (this.spinCfg.min !== null) v = Math.max(v, this.spinCfg.min);
			if (this.spinCfg.max !== null) v = Math.min(v, this.spinCfg.max);
			this.value = v;
			if ($.isFunction(this.spinCfg.callback)) this.spinCfg.callback(this);
		};

		$(this)
		.addClass(cfg && cfg.spinClass ? cfg.spinClass : 'spin-button')

		.mousemove(function(e){
			// Determine which button mouse is over, or not (spin direction):
			var x = e.pageX || e.x;
			var y = e.pageY || e.y;
			var el = e.target || e.srcElement;
			var direction =
				(x > coord(el,'offsetLeft') + el.offsetWidth - this.spinCfg._btn_width)
				? ((y < coord(el,'offsetTop') + this.spinCfg._btn_height) ? 1 : -1) : 0;

			if (direction !== this.spinCfg._direction) {
				// Style up/down buttons:
				switch(direction){
					case 1: // Up arrow:
						$(this).removeClass(this.spinCfg.downClass).addClass(this.spinCfg.upClass);
						break;
					case -1: // Down arrow:
						$(this).removeClass(this.spinCfg.upClass).addClass(this.spinCfg.downClass);
						break;
					default: // Mouse is elsewhere in the textbox
						$(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
				}

				// Set spin direction:
				this.spinCfg._direction = direction;
			}
		})

		.mouseout(function(){
			// Reset up/down buttons to their normal appearance when mouse moves away:
			$(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
			this.spinCfg._direction = null;
		})

		.mousedown(function(e){
			if (this.spinCfg._direction != 0) {
				// Respond to click on one of the buttons:
				var self = this;
				var adjust = function() {
					self.adjustValue(self.spinCfg._direction * self.spinCfg.step);
				};

				adjust();

				// Initial delay before repeating adjustment
				self.spinCfg._delay = window.setTimeout(function() {
					adjust();
					// Repeat adjust at regular intervals
					self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
				}, self.spinCfg.delay);
			}
		})

		.mouseup(function(e){
			// Cancel repeating adjustment
			window.clearInterval(this.spinCfg._repeat);
			window.clearTimeout(this.spinCfg._delay);
		})

		.dblclick(function(e) {
			if ($.browser.msie)
				this.adjustValue(this.spinCfg._direction * this.spinCfg.step);
		})

		.keydown(function(e){
			// Respond to up/down arrow keys.
			switch(e.keyCode){
				case 38: this.adjustValue(this.spinCfg.step);  break; // Up
				case 40: this.adjustValue(-this.spinCfg.step); break; // Down
				case 33: this.adjustValue(this.spinCfg.page);  break; // PageUp
				case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
			}
		})

		/*
		http://unixpapa.com/js/key.html describes the current state-of-affairs for
		key repeat events:
		- Safari 3.1 changed their model so that keydown is reliably repeated going forward
		- Firefox and Opera still only repeat the keypress event, not the keydown
		*/
		.keypress(function(e){
			if (this.repeating) {
				// Respond to up/down arrow keys.
				switch(e.keyCode){
					case 38: this.adjustValue(this.spinCfg.step);  break; // Up
					case 40: this.adjustValue(-this.spinCfg.step); break; // Down
					case 33: this.adjustValue(this.spinCfg.page);  break; // PageUp
					case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
				}
			}
			// we always ignore the first keypress event (use the keydown instead)
			else {
				this.repeating = true;
			}
		})

		// clear the 'repeating' flag
		.keyup(function(e) {
			this.repeating = false;
			this.adjustValue(0);
		})

		.bind("mousewheel", function(e){
			// Respond to mouse wheel in IE. (It returns up/dn motion in multiples of 120)
			if (e.wheelDelta >= 120)
				this.adjustValue(this.spinCfg.step);
			else if (e.wheelDelta <= -120)
				this.adjustValue(-this.spinCfg.step);

			e.preventDefault();
		})

		.change(function(e){
			this.adjustValue(0);
		});

		if (this.addEventListener) {
			// Respond to mouse wheel in Firefox
			this.addEventListener('DOMMouseScroll', function(e) {
				if (e.detail > 0)
					this.adjustValue(-this.spinCfg.step);
				else if (e.detail < 0)
					this.adjustValue(this.spinCfg.step);

				e.preventDefault();
			}, false);
		}
	});

	function coord(el,prop) {
		var c = el[prop], b = document.body;

		while ((el = el.offsetParent) && (el != b)) {
			if (!$.browser.msie || (el.currentStyle.position != 'relative'))
				c += el[prop];
		}

		return c;
	}
};
<commit_msg>Updated jQuerySpinBtn to prevent unwanted input field updates, possibly fixing issue 74<commit_after>/* SpinButton control
 *
 * Adds bells and whistles to any ordinary textbox to
 * make it look and feel like a SpinButton Control.
 *
 * Originally written by George Adamson, Software Unity (george.jquery@softwareunity.com) August 2006.
 * - Added min/max options
 * - Added step size option
 * - Added bigStep (page up/down) option
 *
 * Modifications made by Mark Gibson, (mgibson@designlinks.net) September 2006:
 * - Converted to jQuery plugin
 * - Allow limited or unlimited min/max values
 * - Allow custom class names, and add class to input element
 * - Removed global vars
 * - Reset (to original or through config) when invalid value entered
 * - Repeat whilst holding mouse button down (with initial pause, like keyboard repeat)
 * - Support mouse wheel in Firefox
 * - Fix double click in IE
 * - Refactored some code and renamed some vars
 *
 * Modifications by Jeff Schiller, June 2009:
 * - provide callback function for when the value changes based on the following
 *   http://www.mail-archive.com/jquery-en@googlegroups.com/msg36070.html
 * Modifications by Jeff Schiller, July 2009:
 * - improve styling for widget in Opera
 * - consistent key-repeat handling cross-browser
 * Modifications by Alexis Deveria, October 2009:
 * - provide "stepfunc" callback option to allow custom function to run when changing a value
 * - Made adjustValue(0) only run on certain keyup events, not all.
 *
 * Tested in IE6, Opera9, Firefox 1.5
 * v1.0  11 Aug 2006 - George Adamson	- First release
 * v1.1     Aug 2006 - George Adamson	- Minor enhancements
 * v1.2  27 Sep 2006 - Mark Gibson		- Major enhancements
 * v1.3a 28 Sep 2006 - George Adamson	- Minor enhancements
 * v1.4  18 Jun 2009 - Jeff Schiller    - Added callback function
 * v1.5  06 Jul 2009 - Jeff Schiller    - Fixes for Opera.
 * v1.6  13 Oct 2009 - Alexis Deveria   - Added stepfunc function
 * v1.7  21 Oct 2009 - Alexis Deveria   - Minor fixes
 *                                        Fast-repeat for keys and live updating as you type.

 Sample usage:

	// Create group of settings to initialise spinbutton(s). (Optional)
	var myOptions = {
					min: 0,						// Set lower limit.
					max: 100,					// Set upper limit.
					step: 1,					// Set increment size.
					spinClass: mySpinBtnClass,	// CSS class to style the spinbutton. (Class also specifies url of the up/down button image.)
					upClass: mySpinUpClass,		// CSS class for style when mouse over up button.
					downClass: mySpinDnClass	// CSS class for style when mouse over down button.
					}

	$(document).ready(function(){

		// Initialise INPUT element(s) as SpinButtons: (passing options if desired)
		$("#myInputElement").SpinButton(myOptions);

	});

 */
$.fn.SpinButton = function(cfg){
	return this.each(function(){

		this.repeating = false;

		// Apply specified options or defaults:
		// (Ought to refactor this some day to use $.extend() instead)
		this.spinCfg = {
			//min: cfg && cfg.min ? Number(cfg.min) : null,
			//max: cfg && cfg.max ? Number(cfg.max) : null,
			min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null,	// Fixes bug with min:0
			max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
			step: cfg && cfg.step ? Number(cfg.step) : 1,
			stepfunc: cfg && cfg.stepfunc ? cfg.stepfunc : false,
			page: cfg && cfg.page ? Number(cfg.page) : 10,
			upClass: cfg && cfg.upClass ? cfg.upClass : 'up',
			downClass: cfg && cfg.downClass ? cfg.downClass : 'down',
			reset: cfg && cfg.reset ? cfg.reset : this.value,
			delay: cfg && cfg.delay ? Number(cfg.delay) : 500,
			interval: cfg && cfg.interval ? Number(cfg.interval) : 100,
			_btn_width: 20,
			_btn_height: 12,
			_direction: null,
			_delay: null,
			_repeat: null,
			callback: cfg && cfg.callback ? cfg.callback : null,
		};

		this.adjustValue = function(i){
			var v;
			if(isNaN(this.value)) {
				v = this.spinCfg.reset;
			} else if($.isFunction(this.spinCfg.stepfunc)) {
				v = this.spinCfg.stepfunc(this, i);
			} else {
				v = Number(this.value) + Number(i);
			}
			if (this.spinCfg.min !== null) v = Math.max(v, this.spinCfg.min);
			if (this.spinCfg.max !== null) v = Math.min(v, this.spinCfg.max);
			this.value = v;
			if ($.isFunction(this.spinCfg.callback)) this.spinCfg.callback(this);
		};

		$(this)
		.addClass(cfg && cfg.spinClass ? cfg.spinClass : 'spin-button')

		.mousemove(function(e){
			// Determine which button mouse is over, or not (spin direction):
			var x = e.pageX || e.x;
			var y = e.pageY || e.y;
			var el = e.target || e.srcElement;
			var direction =
				(x > coord(el,'offsetLeft') + el.offsetWidth - this.spinCfg._btn_width)
				? ((y < coord(el,'offsetTop') + this.spinCfg._btn_height) ? 1 : -1) : 0;

			if (direction !== this.spinCfg._direction) {
				// Style up/down buttons:
				switch(direction){
					case 1: // Up arrow:
						$(this).removeClass(this.spinCfg.downClass).addClass(this.spinCfg.upClass);
						break;
					case -1: // Down arrow:
						$(this).removeClass(this.spinCfg.upClass).addClass(this.spinCfg.downClass);
						break;
					default: // Mouse is elsewhere in the textbox
						$(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
				}

				// Set spin direction:
				this.spinCfg._direction = direction;
			}
		})

		.mouseout(function(){
			// Reset up/down buttons to their normal appearance when mouse moves away:
			$(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
			this.spinCfg._direction = null;
		})

		.mousedown(function(e){
			if (this.spinCfg._direction != 0) {
				// Respond to click on one of the buttons:
				var self = this;
				var adjust = function() {
					self.adjustValue(self.spinCfg._direction * self.spinCfg.step);
				};

				adjust();

				// Initial delay before repeating adjustment
				self.spinCfg._delay = window.setTimeout(function() {
					adjust();
					// Repeat adjust at regular intervals
					self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
				}, self.spinCfg.delay);
			}
		})

		.mouseup(function(e){
			// Cancel repeating adjustment
			window.clearInterval(this.spinCfg._repeat);
			window.clearTimeout(this.spinCfg._delay);
		})

		.dblclick(function(e) {
			if ($.browser.msie)
				this.adjustValue(this.spinCfg._direction * this.spinCfg.step);
		})

		.keydown(function(e){
			// Respond to up/down arrow keys.
			switch(e.keyCode){
				case 38: this.adjustValue(this.spinCfg.step);  break; // Up
				case 40: this.adjustValue(-this.spinCfg.step); break; // Down
				case 33: this.adjustValue(this.spinCfg.page);  break; // PageUp
				case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
			}
		})

		/*
		http://unixpapa.com/js/key.html describes the current state-of-affairs for
		key repeat events:
		- Safari 3.1 changed their model so that keydown is reliably repeated going forward
		- Firefox and Opera still only repeat the keypress event, not the keydown
		*/
		.keypress(function(e){
			if (this.repeating) {
				// Respond to up/down arrow keys.
				switch(e.keyCode){
					case 38: this.adjustValue(this.spinCfg.step);  break; // Up
					case 40: this.adjustValue(-this.spinCfg.step); break; // Down
					case 33: this.adjustValue(this.spinCfg.page);  break; // PageUp
					case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
				}
			}
			// we always ignore the first keypress event (use the keydown instead)
			else {
				this.repeating = true;
			}
		})

		// clear the 'repeating' flag
		.keyup(function(e) {
			this.repeating = false;
			switch(e.keyCode){
				case 38: // Up
				case 40: // Down
				case 33: // PageUp
				case 34: // PageDown
				case 13: this.adjustValue(0); break; // Enter/Return
			}
		})

		.bind("mousewheel", function(e){
			// Respond to mouse wheel in IE. (It returns up/dn motion in multiples of 120)
			if (e.wheelDelta >= 120)
				this.adjustValue(this.spinCfg.step);
			else if (e.wheelDelta <= -120)
				this.adjustValue(-this.spinCfg.step);

			e.preventDefault();
		})

		.change(function(e){
			this.adjustValue(0);
		});

		if (this.addEventListener) {
			// Respond to mouse wheel in Firefox
			this.addEventListener('DOMMouseScroll', function(e) {
				if (e.detail > 0)
					this.adjustValue(-this.spinCfg.step);
				else if (e.detail < 0)
					this.adjustValue(this.spinCfg.step);

				e.preventDefault();
			}, false);
		}
	});

	function coord(el,prop) {
		var c = el[prop], b = document.body;

		while ((el = el.offsetParent) && (el != b)) {
			if (!$.browser.msie || (el.currentStyle.position != 'relative'))
				c += el[prop];
		}

		return c;
	}
};
<|endoftext|>


<commit_before>/**
 * @fileoverview Pick Manager - singleton to manage currently picked object(s)
 *
 * @author Tony Parisi
 */

goog.provide('Vizi.PickManager');

Vizi.PickManager.handleMouseMove = function(event)
{
    // console.log("PICKER Mouse move " + x + ", " + y);

    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseMove)
    {
        Vizi.PickManager.clickedObject.onMouseMove(event);
    }
    else
    {
        var oldObj = Vizi.PickManager.overObject;
        Vizi.PickManager.overObject = Vizi.PickManager.objectFromMouse(event);

        if (Vizi.PickManager.overObject != oldObj)
        {
    		if (oldObj)
    		{
    			Vizi.Graphics.instance.setCursor(null);

    			if (oldObj.onMouseOut)
                {
                    oldObj.onMouseOut(event);
                }
    		}

            if (Vizi.PickManager.overObject)
            {
	        	if (Vizi.PickManager.overObject.overCursor)
	        	{
	        		Vizi.Graphics.instance.setCursor(Vizi.PickManager.overObject.overCursor);
	        	}

	        	if (Vizi.PickManager.overObject.onMouseOver)
	        	{
	        		Vizi.PickManager.overObject.onMouseOver(event);
	        	}
            }
        }
    }
}

Vizi.PickManager.handleMouseDown = function(event)
{
    // console.log("PICKER Mouse down " + x + ", " + y);

    Vizi.PickManager.clickedObject = Vizi.PickManager.objectFromMouse(event);
    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseDown)
    {
        Vizi.PickManager.clickedObject.onMouseDown(event);
    }
}

Vizi.PickManager.handleMouseUp = function(event)
{
    // console.log("PICKER Mouse up " + x + ", " + y);

    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseUp)
    {
        Vizi.PickManager.clickedObject.onMouseUp(event);
    }

    Vizi.PickManager.clickedObject = null;
}

Vizi.PickManager.handleMouseScroll = function(event)
{
    // console.log("PICKER Mouse up " + x + ", " + y);

    if (Vizi.PickManager.overObject && Vizi.PickManager.overObject.onMouseScroll)
    {
        Vizi.PickManager.overObject.onMouseScroll(event);
    }

    Vizi.PickManager.clickedObject = null;
}

Vizi.PickManager.objectFromMouse = function(event)
{
	var intersected = Vizi.Graphics.instance.objectFromMouse(event);
	if (intersected.object)
	{
    	if (intersected.object.picker)
    	{
    		return intersected.object.picker;
    	}
    	else
    	{
    		return Vizi.PickManager.findObjectPicker(intersected.object.object);
    	}
	}
	else
	{
		return null;
	}
}

Vizi.PickManager.findObjectPicker = function(object)
{
	while (object)
	{
		if (object.data && object.data.picker)
		{
			return object.data.picker;
		}
		else
		{
			object = object.parent;
		}
	}

	return null;
}

Vizi.PickManager.clickedObject = null;
Vizi.PickManager.overObject  =  null;<commit_msg>Comments Cleanup<commit_after>/**
 * @fileoverview Pick Manager - singleton to manage currently picked object(s)
 *
 * @author Tony Parisi
 */

goog.provide('Vizi.PickManager');

Vizi.PickManager.handleMouseMove = function(event)
{
    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseMove)
    {
        Vizi.PickManager.clickedObject.onMouseMove(event);
    }
    else
    {
        var oldObj = Vizi.PickManager.overObject;
        Vizi.PickManager.overObject = Vizi.PickManager.objectFromMouse(event);

        if (Vizi.PickManager.overObject != oldObj)
        {
    		if (oldObj)
    		{
    			Vizi.Graphics.instance.setCursor(null);

    			if (oldObj.onMouseOut)
                {
                    oldObj.onMouseOut(event);
                }
    		}

            if (Vizi.PickManager.overObject)
            {
	        	if (Vizi.PickManager.overObject.overCursor)
	        	{
	        		Vizi.Graphics.instance.setCursor(Vizi.PickManager.overObject.overCursor);
	        	}

	        	if (Vizi.PickManager.overObject.onMouseOver)
	        	{
	        		Vizi.PickManager.overObject.onMouseOver(event);
	        	}
            }
        }
    }
}

Vizi.PickManager.handleMouseDown = function(event)
{
    Vizi.PickManager.clickedObject = Vizi.PickManager.objectFromMouse(event);
    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseDown)
    {
        Vizi.PickManager.clickedObject.onMouseDown(event);
    }
}

Vizi.PickManager.handleMouseUp = function(event)
{
    if (Vizi.PickManager.clickedObject && Vizi.PickManager.clickedObject.onMouseUp)
    {
        Vizi.PickManager.clickedObject.onMouseUp(event);
    }

    Vizi.PickManager.clickedObject = null;
}

Vizi.PickManager.handleMouseScroll = function(event)
{
    if (Vizi.PickManager.overObject && Vizi.PickManager.overObject.onMouseScroll)
    {
        Vizi.PickManager.overObject.onMouseScroll(event);
    }

    Vizi.PickManager.clickedObject = null;
}

Vizi.PickManager.objectFromMouse = function(event)
{
	var intersected = Vizi.Graphics.instance.objectFromMouse(event);
	if (intersected.object)
	{
    	if (intersected.object.picker)
    	{
    		return intersected.object.picker;
    	}
    	else
    	{
    		return Vizi.PickManager.findObjectPicker(intersected.object.object);
    	}
	}
	else
	{
		return null;
	}
}

Vizi.PickManager.findObjectPicker = function(object)
{
	while (object)
	{
		if (object.data && object.data.picker)
		{
			return object.data.picker;
		}
		else
		{
			object = object.parent;
		}
	}

	return null;
}

Vizi.PickManager.clickedObject = null;
Vizi.PickManager.overObject  =  null;<|endoftext|>


<commit_before>var config = require('./config');
var manageUsers = require('./manageUsers.js');
var request = require('request');
//var mongo = require('./mongoFunctions.js');
var adm1 = config.adm1;
var adm2 = config.adm2;

function createMessage(type, id, content, callback){
	var message = {
		recipient: {
		  id: id
		}
	};
	console.log(content);
	if(type == 'text'){
		message['message']={text: content};
	}else{
		message['message']={
			attachment:{
				type: 'template',
				payload:{
					template_type: 'button',
					text: content['text'],
					buttons: [
						content['buttons']
					]
				}
			}
		}
	}
	setImmediate(function(){
		callback(message);
	});
}

/*function createButtons(tab, callback){
	var buttons;
	for(var i = 0; i < tab.length; i++){
		var btn = tab[i];
		var singleBTN=[];
		singleBTN['type']=btn[0];
		singleBTN['title']=btn[2];
		if(btn[0]=='web_url'){
			singleBTN['url']=btn[1];
		} else if(btn[0]=='postback'){
			singleBTN['payload']=btn[1];
		}
		console.log(singleBTN);
		console.log(btn);
		buttons+=singleBTN;
	}
	setImmediate(function(){
		console.log(buttons);
		callback(buttons);
	});
}*/

function sendSubstitutions(senderID, message){
	var admMessage1 = {
		recipient: {
		  id: adm1
		},
		message: {
		  attachment:{
			  type: 'template',
			  payload:{
					template_type: 'button',
					text: 'nowa wiadomość:\n' + message,
					buttons:[
						{
							type: 'web_url',
							url: 'https://www.facebook.com/Zastępstwa-dla-szkół-573446562859405/messages',
							title: 'Odpowiedz'
						}
					]
			  }
		  }
		}
	};
	var admMessage2 = {
		recipient: {
		  id: adm2
		},
		message: {
		  attachment:{
			  type: 'template',
			  payload:{
					template_type: 'button',
					text: 'nowa wiadomość:\n' + message,
					buttons:[
						{
							type: 'web_url',
							url: 'https://www.facebook.com/Zastępstwa-dla-szkół-573446562859405/messages',
							title: 'Odpowiedz'
						}
					]
			  }
		  }
		}
	};
	var body = {
		'mode': 'classList',
		'param': 'today'
	};
	message = message.toLowerCase();
	var opt = message[0];
	var help = 'Dostępne polecenia to:\n"0 <klasa>" - zastępstwa dla klasy na dzisiaj\n"1 <klasa>" - zastępstwa dla klasy na jutro\n"2 <pytanie>" - pomoc';
	var messageData = {
		recipient: {
		  id: senderID
		},
		message: {
		  text: help
		}
	};
	var reqClass = message[2] + message[3];
	if(reqClass[1]=='g'){
		reqClass += message[4];
	}
	switch(opt){
		case '0':
			break;
		case '1':
			body['param']='tomorrow'; //masz else, więc jak dam dobrze to przejdzie, chociaż ty piszesz źle
			break;
		case '2':
			body['mode']='NO';
			var messageData = {
				recipient: {
				  id: senderID
				},
				message: {
				  text: 'Skontaktujemy się aby odpowiedzieć na pytanie.'
				}
			};
			callSendAPI(messageData);
			callSendAPI(admMessage1);
			callSendAPI(admMessage2);
			break;
		case '3':
			body['mode']='NO';
			createMessage('text', senderID, 'Jakiś tekst - test', function(message){
				callSendAPI(message);
			});
			var content={
				text: 'TEST GENERIC'
				buttons:[
					{
						type: 'web_url',
						url: 'https://domek.emadar.eu',
						title: 'Sprawdź na stronie'
					},
					{
						type: 'postback',
						title: 'Send on chat',
						payload: message
					}
				]
			}
			createMessage('generic', senderID, content, function(message){
				callSendAPI(message);
			});
			break;
		default:
			body['mode']='NO';
			callSendAPI(messageData);
			break;
	};
	if(body['mode'] != 'NO'){
		manageUsers.postCall('0000', body, function(classes){
			var is = 0;
			for(var i = 0; i < classes.length; i++){
				if(classes[i] == reqClass){
					is++;
				}
			}
			if(is > 0){
				var messageData = {
					recipient: {
					  id: senderID
					},
					message: {
					  attachment:{
						  type: 'template',
						  payload:{
								template_type: 'button',
								text: 'zastępstwa',
								buttons:[
									{
										type: 'web_url',
										url: 'https://domek.emadar.eu',
										title: 'Sprawdź na stronie'
									},
									{
										type: 'postback',
										title: 'Send on chat',
										payload: message
									}
								]
						  }
					  }
					}
				};
			} else {
				var messageData = {
					recipient: {
					  id: senderID
					},
					message: {
					  text: 'brak zastępstw'
					}
				};
			}
			callSendAPI(messageData);
		});
	}
}

function sendList(senderID, message){
	var body = {
		'mode': 'getChanges',
		'param': 'today'
	};
	if(message[0]=='1'){
		body['param']='tomorrow';
	}
	var reqClass = message[2] + message[3];
	if(reqClass[1]=='g'){
		reqClass += message[4];
	}
	manageUsers.postCall('0000', body, function(obj){
		var subs = obj['substitution'];
		var msg = "";
		for(var i = 0; i < subs.length; i++){
			var oneSub = subs[i];
			if(oneSub.classes == reqClass){
				var changes = oneSub['changes'];
				if(oneSub.cancelled[0]){
					msg+='anulowanie';
				} else {
					msg+='Typ: ' + oneSub.substitution_types;
				}
				msg+='\nLekcja: ' + oneSub.periods;
				msg+='\nNauczyciel: ' + oneSub.teachers;
				if(changes){
					if(changes.teachers){
						msg+=' => ' + changes.teachers;
					}
				}
				msg+='\nPrzedmiot: ' + oneSub.subjects;
				if(changes){
					if(changes.subjects){
						msg+= ' => ' + changes.subjects;
					}
				}
				msg+='\nSala: ' + oneSub.classrooms;
				if(changes){
					if(changes.classrooms){
						msg+=' => ' + changes.classrooms;
					}
				}
				if(oneSub.groupnames){
					if(oneSub.groupnames != ""){
						msg+='\nGrupa: ' + oneSub.groupnames;
					}
				}
				if(oneSub.note){
					if(oneSub.note != ""){
						msg+='\nKomentarz: '  + oneSub.note;
					}
				}
				var messageData = {
					recipient: {
						id: senderID
					},
					message: {
						text: msg
					}
				};
				callSendAPI(messageData);
				msg='';
			}
		}
	});
}

function receivedPostback(event) {
	var senderID = event.sender.id;
	var recipientID = event.recipient.id;
	var timeOfPostback = event.timestamp;

	// The 'payload' param is a developer-defined field which is set in a postback
	// button for Structured Messages.
	var payload = event.postback.payload;

	console.log("Received postback for user %d and page %d with payload '%s' " +
	"at %d", senderID, recipientID, payload, timeOfPostback);

	sendList(senderID, payload);
}

function receivedMessage(event) {
	var senderID = event.sender.id;
	var recipientID = event.recipient.id;
	var timeOfMessage = event.timestamp;
	var message = event.message;

	console.log("Received message for user %d and page %d at %d with message:",
	senderID, recipientID, timeOfMessage);
	console.log(JSON.stringify(message));

	var messageId = message.mid;

	var messageText = message.text;
	var messageAttachments = message.attachments;
	var help = 'NIE PRZYJMUJEMY ZAŁĄCZNIKÓW\nDostępne polecenia to:\n"0 <klasa>" - zastępstwa dla klasy na dzisiaj\n"1 <klasa>" - zastępstwa dla klasy na jutro\n"2 <pytanie>" - pomoc';

	if (messageText) {
		sendSubstitutions(senderID, messageText);
	} else {
		var messageData = {
			recipient: {
			  id: senderID
			},
			message: {
			  text: help
			}
		};
		callSendAPI(messageData);
	}
}

function callSendAPI(messageData) {
  request({
    uri: 'https://graph.facebook.com/v2.7/me/messages',
    qs: { access_token: config.pageToken },
    method: 'POST',
    json: messageData

  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      var recipientId = body.recipient_id;
      var messageId = body.message_id;

      console.log("Successfully sent generic message with id %s to recipient %s",
        messageId, recipientId);
    } else {
      console.error("Unable to send message.");
      console.error(response);
      console.error(error);
    }
  });
}

/*function sendTextMessage(recipientId, messageText) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      text: messageText
    }
  };

  callSendAPI(messageData);
}*/

/*function sendGenericMessage(recipientId) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      attachment: {
        type: "template",
        payload: {
          template_type: "generic",
          elements: [{
            title: "rift",
            subtitle: "Next-generation virtual reality",
            item_url: "https://www.oculus.com/en-us/rift/",
            image_url: "http://messengerdemo.parseapp.com/img/rift.png",
            buttons: [{
              type: "web_url",
              url: "https://www.oculus.com/en-us/rift/",
              title: "Open Web URL"
            }, {
              type: "postback",
              title: "Call Postback",
              payload: "Payload for first bubble",
            }],
          }, {
            title: "touch",
            subtitle: "Your Hands, Now in VR",
            item_url: "https://www.oculus.com/en-us/touch/",
            image_url: "http://messengerdemo.parseapp.com/img/touch.png",
            buttons: [{
              type: "web_url",
              url: "https://www.oculus.com/en-us/touch/",
              title: "Open Web URL"
            }, {
              type: "postback",
              title: "Call Postback",
              payload: "Payload for second bubble",
            }]
          }]
        }
      }
    }
  };

  callSendAPI(messageData);
}*/

exports.receivedPostback=receivedPostback;
exports.receivedMessage=receivedMessage;
<commit_msg>try to fix<commit_after>var config = require('./config');
var manageUsers = require('./manageUsers.js');
var request = require('request');
//var mongo = require('./mongoFunctions.js');
var adm1 = config.adm1;
var adm2 = config.adm2;

function createMessage(type, id, content, callback){
	var message = {
		recipient: {
		  id: id
		}
	};
	console.log(content);
	if(type == 'text'){
		message['message']={text: content};
	}else{
		message['message']={
			attachment:{
				type: 'template',
				payload:{
					template_type: 'button',
					text: content['text'],
					buttons: [
						content['buttons']
					]
				}
			}
		}
	}
	setImmediate(function(){
		callback(message);
	});
}

/*function createButtons(tab, callback){
	var buttons;
	for(var i = 0; i < tab.length; i++){
		var btn = tab[i];
		var singleBTN=[];
		singleBTN['type']=btn[0];
		singleBTN['title']=btn[2];
		if(btn[0]=='web_url'){
			singleBTN['url']=btn[1];
		} else if(btn[0]=='postback'){
			singleBTN['payload']=btn[1];
		}
		console.log(singleBTN);
		console.log(btn);
		buttons+=singleBTN;
	}
	setImmediate(function(){
		console.log(buttons);
		callback(buttons);
	});
}*/

function sendSubstitutions(senderID, message){
	var admMessage1 = {
		recipient: {
		  id: adm1
		},
		message: {
		  attachment:{
			  type: 'template',
			  payload:{
					template_type: 'button',
					text: 'nowa wiadomość:\n' + message,
					buttons:[
						{
							type: 'web_url',
							url: 'https://www.facebook.com/Zastępstwa-dla-szkół-573446562859405/messages',
							title: 'Odpowiedz'
						}
					]
			  }
		  }
		}
	};
	var admMessage2 = {
		recipient: {
		  id: adm2
		},
		message: {
		  attachment:{
			  type: 'template',
			  payload:{
					template_type: 'button',
					text: 'nowa wiadomość:\n' + message,
					buttons:[
						{
							type: 'web_url',
							url: 'https://www.facebook.com/Zastępstwa-dla-szkół-573446562859405/messages',
							title: 'Odpowiedz'
						}
					]
			  }
		  }
		}
	};
	var body = {
		'mode': 'classList',
		'param': 'today'
	};
	message = message.toLowerCase();
	var opt = message[0];
	var help = 'Dostępne polecenia to:\n"0 <klasa>" - zastępstwa dla klasy na dzisiaj\n"1 <klasa>" - zastępstwa dla klasy na jutro\n"2 <pytanie>" - pomoc';
	var messageData = {
		recipient: {
		  id: senderID
		},
		message: {
		  text: help
		}
	};
	var reqClass = message[2] + message[3];
	if(reqClass[1]=='g'){
		reqClass += message[4];
	}
	switch(opt){
		case '0':
			break;
		case '1':
			body['param']='tomorrow'; //masz else, więc jak dam dobrze to przejdzie, chociaż ty piszesz źle
			break;
		case '2':
			body['mode']='NO';
			var messageData = {
				recipient: {
				  id: senderID
				},
				message: {
				  text: 'Skontaktujemy się aby odpowiedzieć na pytanie.'
				}
			};
			callSendAPI(messageData);
			callSendAPI(admMessage1);
			callSendAPI(admMessage2);
			break;
		case '3':
			body['mode']='NO';
			createMessage('text', senderID, 'Jakiś tekst - test', function(message){
				callSendAPI(message);
			});
			var content={
				'text': 'TEST GENERIC'
				'buttons':[
					{
						type: 'web_url',
						url: 'https://domek.emadar.eu',
						title: 'Sprawdź na stronie'
					},
					{
						type: 'postback',
						title: 'Send on chat',
						payload: message
					}
				]
			}
			createMessage('generic', senderID, content, function(message){
				callSendAPI(message);
			});
			break;
		default:
			body['mode']='NO';
			callSendAPI(messageData);
			break;
	};
	if(body['mode'] != 'NO'){
		manageUsers.postCall('0000', body, function(classes){
			var is = 0;
			for(var i = 0; i < classes.length; i++){
				if(classes[i] == reqClass){
					is++;
				}
			}
			if(is > 0){
				var messageData = {
					recipient: {
					  id: senderID
					},
					message: {
					  attachment:{
						  type: 'template',
						  payload:{
								template_type: 'button',
								text: 'zastępstwa',
								buttons:[
									{
										type: 'web_url',
										url: 'https://domek.emadar.eu',
										title: 'Sprawdź na stronie'
									},
									{
										type: 'postback',
										title: 'Send on chat',
										payload: message
									}
								]
						  }
					  }
					}
				};
			} else {
				var messageData = {
					recipient: {
					  id: senderID
					},
					message: {
					  text: 'brak zastępstw'
					}
				};
			}
			callSendAPI(messageData);
		});
	}
}

function sendList(senderID, message){
	var body = {
		'mode': 'getChanges',
		'param': 'today'
	};
	if(message[0]=='1'){
		body['param']='tomorrow';
	}
	var reqClass = message[2] + message[3];
	if(reqClass[1]=='g'){
		reqClass += message[4];
	}
	manageUsers.postCall('0000', body, function(obj){
		var subs = obj['substitution'];
		var msg = "";
		for(var i = 0; i < subs.length; i++){
			var oneSub = subs[i];
			if(oneSub.classes == reqClass){
				var changes = oneSub['changes'];
				if(oneSub.cancelled[0]){
					msg+='anulowanie';
				} else {
					msg+='Typ: ' + oneSub.substitution_types;
				}
				msg+='\nLekcja: ' + oneSub.periods;
				msg+='\nNauczyciel: ' + oneSub.teachers;
				if(changes){
					if(changes.teachers){
						msg+=' => ' + changes.teachers;
					}
				}
				msg+='\nPrzedmiot: ' + oneSub.subjects;
				if(changes){
					if(changes.subjects){
						msg+= ' => ' + changes.subjects;
					}
				}
				msg+='\nSala: ' + oneSub.classrooms;
				if(changes){
					if(changes.classrooms){
						msg+=' => ' + changes.classrooms;
					}
				}
				if(oneSub.groupnames){
					if(oneSub.groupnames != ""){
						msg+='\nGrupa: ' + oneSub.groupnames;
					}
				}
				if(oneSub.note){
					if(oneSub.note != ""){
						msg+='\nKomentarz: '  + oneSub.note;
					}
				}
				var messageData = {
					recipient: {
						id: senderID
					},
					message: {
						text: msg
					}
				};
				callSendAPI(messageData);
				msg='';
			}
		}
	});
}

function receivedPostback(event) {
	var senderID = event.sender.id;
	var recipientID = event.recipient.id;
	var timeOfPostback = event.timestamp;

	// The 'payload' param is a developer-defined field which is set in a postback
	// button for Structured Messages.
	var payload = event.postback.payload;

	console.log("Received postback for user %d and page %d with payload '%s' " +
	"at %d", senderID, recipientID, payload, timeOfPostback);

	sendList(senderID, payload);
}

function receivedMessage(event) {
	var senderID = event.sender.id;
	var recipientID = event.recipient.id;
	var timeOfMessage = event.timestamp;
	var message = event.message;

	console.log("Received message for user %d and page %d at %d with message:",
	senderID, recipientID, timeOfMessage);
	console.log(JSON.stringify(message));

	var messageId = message.mid;

	var messageText = message.text;
	var messageAttachments = message.attachments;
	var help = 'NIE PRZYJMUJEMY ZAŁĄCZNIKÓW\nDostępne polecenia to:\n"0 <klasa>" - zastępstwa dla klasy na dzisiaj\n"1 <klasa>" - zastępstwa dla klasy na jutro\n"2 <pytanie>" - pomoc';

	if (messageText) {
		sendSubstitutions(senderID, messageText);
	} else {
		var messageData = {
			recipient: {
			  id: senderID
			},
			message: {
			  text: help
			}
		};
		callSendAPI(messageData);
	}
}

function callSendAPI(messageData) {
  request({
    uri: 'https://graph.facebook.com/v2.7/me/messages',
    qs: { access_token: config.pageToken },
    method: 'POST',
    json: messageData

  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      var recipientId = body.recipient_id;
      var messageId = body.message_id;

      console.log("Successfully sent generic message with id %s to recipient %s",
        messageId, recipientId);
    } else {
      console.error("Unable to send message.");
      console.error(response);
      console.error(error);
    }
  });
}

/*function sendTextMessage(recipientId, messageText) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      text: messageText
    }
  };

  callSendAPI(messageData);
}*/

/*function sendGenericMessage(recipientId) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      attachment: {
        type: "template",
        payload: {
          template_type: "generic",
          elements: [{
            title: "rift",
            subtitle: "Next-generation virtual reality",
            item_url: "https://www.oculus.com/en-us/rift/",
            image_url: "http://messengerdemo.parseapp.com/img/rift.png",
            buttons: [{
              type: "web_url",
              url: "https://www.oculus.com/en-us/rift/",
              title: "Open Web URL"
            }, {
              type: "postback",
              title: "Call Postback",
              payload: "Payload for first bubble",
            }],
          }, {
            title: "touch",
            subtitle: "Your Hands, Now in VR",
            item_url: "https://www.oculus.com/en-us/touch/",
            image_url: "http://messengerdemo.parseapp.com/img/touch.png",
            buttons: [{
              type: "web_url",
              url: "https://www.oculus.com/en-us/touch/",
              title: "Open Web URL"
            }, {
              type: "postback",
              title: "Call Postback",
              payload: "Payload for second bubble",
            }]
          }]
        }
      }
    }
  };

  callSendAPI(messageData);
}*/

exports.receivedPostback=receivedPostback;
exports.receivedMessage=receivedMessage;
<|endoftext|>


<commit_before>Ext.namespace('Gemma');

/**
 * need to set geneId as config
 */
Gemma.GeneDetails =  Ext.extend(Ext.Panel, {

	height: 600,
	padding:10,
	defaults:{
		border:false,
		flex:0
	},
	layoutConfig:{
		align:'stretch'
	},
	layout:'vbox',
	renderHomologues: function(homologues, mainGeneSymbol){
		var homologueStr = '';
		var j, homologue;
		for (j = 0; j < homologues.length; j++) {
			homologue = homologues[j];
				homologueStr += "" +
				homologue.officialSymbol +
				" [" +
				homologue.taxonCommonName +
				"]   ";
		}
		if(homologueStr === ''){
			homologueStr = "No aliases defined";
		}
		return homologueStr;
	},

	renderGeneSets:function(geneSets){
		var geneSetLinks = [];
		var i, geneSet;
		for (i = 0; i < geneSets.length; i++) {
			if (geneSets[i] && geneSets[i].name && geneSets[i].id) {
				geneSetLinks.push(''+geneSets[i].name+'');
			}
		}
		if(geneSetLinks.length === 0){
			geneSetLinks.push('Not currently a member of any gene group');
		}
		return geneSetLinks;
	},
	initComponent: function(){
		Gemma.GeneDetails.superclass.initComponent.call(this);

		this.on('render', function(){
			if (!this.loadMask && this.getEl()) {
				this.loadMask = new Ext.LoadMask(this.getEl(), {
					msg: "Loading ...",
					msgCls: 'absolute-position-loading-mask ext-el-mask-msg x-mask-loading'
				});
			}
			this.loadMask.show();
			GeneController.loadGeneDetails(this.geneId, function(geneDetails){

			this.loadMask.hide();
				this.add([
				{
						html: '
' + geneDetails.name + '
' +
						geneDetails.officialName +
						'

'
					}, {
						layout: 'form',
						defaults: {
							border: false
						},
						items: [{
							fieldLabel: 'Taxon',
							html: geneDetails.taxonCommonName
						}, {
							fieldLabel: 'Aliases',
							html: geneDetails.aliases.join(', ')
						}, {
							fieldLabel: 'NCBI ID',
							html: geneDetails.ncbiId + ' '
						}, {
							fieldLabel: 'Homolgues',
							html: this.renderHomologues(geneDetails.homologues, geneDetails.name)
						}, {
							fieldLabel: 'Gene Groups',
							html: this.renderGeneSets(geneDetails.geneSets).join(',')
						}, {
							fieldLabel: 'Probes' + '' +
							' ',
							html: geneDetails.compositeSequenceCount + ' ' +
							' '
						}, {
							fieldLabel: 'Notes',
							html: geneDetails.description
						}]
					}]);
				this.doLayout();
			}.createDelegate(this));
		});
	}
});<commit_msg>Fixed type-o.<commit_after>Ext.namespace('Gemma');

/**
 * need to set geneId as config
 */
Gemma.GeneDetails =  Ext.extend(Ext.Panel, {

	height: 600,
	padding:10,
	defaults:{
		border:false,
		flex:0
	},
	layoutConfig:{
		align:'stretch'
	},
	layout:'vbox',
	renderHomologues: function(homologues, mainGeneSymbol){
		var homologueStr = '';
		var j, homologue;
		for (j = 0; j < homologues.length; j++) {
			homologue = homologues[j];
				homologueStr += "" +
				homologue.officialSymbol +
				" [" +
				homologue.taxonCommonName +
				"]   ";
		}
		if(homologueStr === ''){
			homologueStr = "No aliases defined";
		}
		return homologueStr;
	},

	renderGeneSets:function(geneSets){
		var geneSetLinks = [];
		var i, geneSet;
		for (i = 0; i < geneSets.length; i++) {
			if (geneSets[i] && geneSets[i].name && geneSets[i].id) {
				geneSetLinks.push(''+geneSets[i].name+'');
			}
		}
		if(geneSetLinks.length === 0){
			geneSetLinks.push('Not currently a member of any gene group');
		}
		return geneSetLinks;
	},
	initComponent: function(){
		Gemma.GeneDetails.superclass.initComponent.call(this);

		this.on('render', function(){
			if (!this.loadMask && this.getEl()) {
				this.loadMask = new Ext.LoadMask(this.getEl(), {
					msg: "Loading ...",
					msgCls: 'absolute-position-loading-mask ext-el-mask-msg x-mask-loading'
				});
			}
			this.loadMask.show();

			GeneController.loadGeneDetails(this.geneId, function(geneDetails){

			this.loadMask.hide();
				this.add([
				{
						html: '
' + geneDetails.name + '
' +
						geneDetails.officialName +
						'

'
					}, {
						layout: 'form',
						defaults: {
							border: false
						},
						items: [{
							fieldLabel: 'Taxon',
							html: geneDetails.taxonCommonName
						}, {
							fieldLabel: 'Aliases',
							html: geneDetails.aliases.join(', ')
						}, {
							fieldLabel: 'NCBI ID',
							html: geneDetails.ncbiId + ' '
						}, {
							fieldLabel: 'Homologues',
							html: this.renderHomologues(geneDetails.homologues, geneDetails.name)
						}, {
							fieldLabel: 'Gene Groups',
							html: this.renderGeneSets(geneDetails.geneSets).join(',')
						}, {
							fieldLabel: 'Probes' + '' +
							' ',
							html: geneDetails.compositeSequenceCount + ' ' +
							' '
						}, {
							fieldLabel: 'Notes',
							html: geneDetails.description
						}]
					}]);
				this.doLayout();
			}.createDelegate(this));
		});
	}
});<|endoftext|>


<commit_before>/**
 * isAuthenticated
 * @description :: Policy that inject user in `req` via JSON Web Token
 */

var passport = require('passport');

module.exports = function (req, res, next) {
  passport.authenticate('jwt', function (error, user, info) {
    if (error) return res.serverError(error);
    if (!user) return res.unauthorized(null, info.code, info.message);

    req.user = user;
    next();
  })(req, res);
};
<commit_msg>Add checking for info is exists<commit_after>/**
 * isAuthenticated
 * @description :: Policy that inject user in `req` via JSON Web Token
 */

var passport = require('passport');

module.exports = function (req, res, next) {
  passport.authenticate('jwt', function (error, user, info) {
    if (error) return res.serverError(error);
    if (!user) return res.unauthorized(null, info && info.code, info && info.message);

    req.user = user;

    next();
  })(req, res);
};
<|endoftext|>