<commit_before>VISH.Editor.Customization = (function(V,$,undefined){

	var init = function(){
		 var editor_logo = VISH.Configuration.getConfiguration().editor_logo;
		if(editor_logo != null && imageExist(editor_logo) ){
			$("#presentation_details_logo").attr("src", editor_logo );
		}

		var repository_image = VISH.Configuration.getConfiguration().repository_image;
		if( repository_image != null && imageExist(repository_image) ){
			$("img[src$='/images/logos/repositoryimg.png']").attr("src", repository_image);
		}

		var menu_logo = VISH.Configuration.getConfiguration().menu_logo;
		if(menu_logo != null && imageExist(menu_logo) ){
			$("#menuButton").attr("src",menu_logo);
		}

		var repository_name = VISH.Configuration.getConfiguration().repository_name;
		if(repository_name != null ){
			$("#tab_pic_repo").html(repository_name);
			$("#tab_object_repo").html(repository_name);
			$("#tab_video_repo").html(repository_name);
		}

	};

	var imageExist =  function(url){
   		var img = new Image();
   		img.src = url;
   		return img.height != 0;
	};

	return {
			init 		: init
	};

}) (VISH,jQuery);<commit_msg>Add customziation without authoritzation<commit_after>VISH.Editor.Customization = (function(V,$,undefined){

	var init = function(){
		 var editor_logo = VISH.Configuration.getConfiguration().editor_logo;
		if(editor_logo != null){
			$("#presentation_details_logo").attr("src", editor_logo );
		}

		var repository_image = VISH.Configuration.getConfiguration().repository_image;
		imageExist(repository_image);
		if( repository_image != null ){
			$("img[src$='/images/logos/repositoryimg.png']").attr("src", repository_image);
		}

		var menu_logo = VISH.Configuration.getConfiguration().menu_logo;
		if( menu_logo != null ){
			$("#menuButton").attr("src",menu_logo);
		}

		var repository_name = VISH.Configuration.getConfiguration().repository_name;
		if(repository_name != null ){
			$("#tab_pic_repo").html(repository_name);
			$("#tab_object_repo").html(repository_name);
			$("#tab_video_repo").html(repository_name);
		}

	};

	var imageExist =  function(url, callback){
   		var img = new Image();
	    img.onload = function(){
	    	callback = true;
	    };
	    img.onerror =function(){
	    	callback = false;
	    };
	    img.src = url;
		}

	return {
			init 		: init,
			imageExist	: imageExist
	};

}) (VISH,jQuery);<|endoftext|>


<commit_before>Ext.define('devilry_student.controller.GroupInfo', {
    extend: 'Ext.app.Controller',

    requires: [
        'Ext.window.MessageBox',
        'devilry_student.view.add_delivery.AddDeliveryPanel'
    ],

    views: [
        'groupinfo.Overview',
        'groupinfo.DeadlinePanel',
        'groupinfo.DeliveryPanel',
        'groupinfo.GroupMetadata'
    ],

    models: ['GroupInfo'],

    refs: [{
        ref: 'overview',
        selector: 'viewport groupinfo'
    }, {
        ref: 'deadlinesContainer',
        selector: 'viewport groupinfo #deadlinesContainer'
    }, {
        ref: 'metadataContainer',
        selector: 'viewport groupinfo #metadataContainer'
    }, {
        ref: 'titleBox',
        selector: 'viewport groupinfo #titleBox'
    }],

    init: function() {
        this.control({
            'viewport groupinfo #deadlinesContainer': {
                render: this._onRender
            },
            'viewport groupinfo groupmetadata': {
                active_feedback_link_clicked: this._onActiveFeedbackLink
            }
        });
    },

    _onRender: function() {
        this._reload();
    },

    _reload: function() {
        var group_id = this.getOverview().group_id;
        this.getOverview().setLoading(true);
        this.getGroupInfoModel().load(group_id, {
            scope: this,
            success: this._onGroupInfoLoadSuccess,
            failure: this._onGroupInfoLoadFailure
        });
    },

    _onGroupInfoLoadSuccess: function(groupInfoRecord) {
        this._setBreadcrumbs(groupInfoRecord);
        this._populateDeadlinesContainer(groupInfoRecord.get('deadlines'), groupInfoRecord.get('active_feedback'));
        this._populateMetadata(groupInfoRecord);
        this._populateTitleBox(groupInfoRecord);
        this.groupInfoRecord = groupInfoRecord;

        var delivery_id = this.getOverview().delivery_id;
        if(delivery_id != undefined) {
            this._hightlightSelectedDelivery(delivery_id);
        }

        if(this.getOverview().add_delivery) {
            this._addDelivery();
        }
        this.getOverview().setLoading(false);
    },

    _onGroupInfoLoadFailure: function() {
        this.setLoading(false);
        this._showLoadError(gettext('Failed to load group. Try to reload the page'));
    },

    _showLoadError: function(message) {
        Ext.MessageBox.alert(gettext('Error'), message);
    },

    _populateDeadlinesContainer: function(deadlines, active_feedback) {
        this.getDeadlinesContainer().removeAll();
        Ext.Array.each(deadlines, function(deadline) {
            this.getDeadlinesContainer().add({
                xtype: 'groupinfo_deadline',
                deadline: deadline,
                active_feedback: active_feedback
            });
        }, this);
    },

    _populateTitleBox: function(groupInfoRecord) {
        this.getTitleBox().update({
            groupinfo: groupInfoRecord.data
        });
    },

    _populateMetadata: function(groupInfoRecord) {
        this.getMetadataContainer().removeAll();
        this.getMetadataContainer().add({
            xtype: 'groupmetadata',
            data: {
                groupinfo: groupInfoRecord.data,
                examiner_term: gettext('examiner')
            }
        });
    },

    _onActiveFeedbackLink: function() {
        var group_id = this.groupInfoRecord.get('id');
        var delivery_id = this.groupInfoRecord.get('active_feedback').delivery_id;
        this._hightlightSelectedDelivery(delivery_id);
        this.application.route.setHashWithoutEvent(Ext.String.format('/group/{0}/{1}', group_id, delivery_id));
    },

    _hightlightSelectedDelivery: function(delivery_id) {
        var itemid = Ext.String.format('#delivery-{0}', delivery_id);
        var deliveryPanel = this.getOverview().down(itemid);
        if(deliveryPanel) {
            var container = deliveryPanel.up('groupinfo_deadline');
            container.expand();
            //deliveryPanel.el.scrollIntoView(this.getOverview().body, false, true);
            deliveryPanel.el.scrollIntoView(this.getDeadlinesContainer().body, false, true);
        } else {
            this._showLoadError(interpolate(gettext('Invalid delivery: %s'), [delivery_id]));
        }
    },

    _setBreadcrumbs: function(groupInfoRecord, extra) {
        var subject = groupInfoRecord.get('breadcrumbs').subject;
        var period = groupInfoRecord.get('breadcrumbs').period;
        var assignment = groupInfoRecord.get('breadcrumbs').assignment;
        var periodpath = [subject.short_name, period.short_name].join('.');

        var breadcrumbs = [{
            url: '#/browse/',
            text: gettext('Browse')
        }, {
            url: Ext.String.format('#/browse/{0}', period.id),
            text: periodpath
        }];

        if(extra) {
            breadcrumbs.push({
                url: Ext.String.format('#/group/{0}/', groupInfoRecord.get('id')),
                text: assignment.short_name
            });
            this.application.breadcrumbs.set(breadcrumbs, extra);
        } else {
            this.application.breadcrumbs.set(breadcrumbs, assignment.short_name);
        }

        var title = [periodpath, assignment.shortname].join('.');
        if(extra) {
            title += ' - ' + extra;
        }
        this.application.setTitle(title);
    },

    _addDelivery: function() {
        if(!this.groupInfoRecord.get('is_open')) {
            // NOTE: We use an error message since the user do not get this through normal UI navigation
            this._showLoadError(interpolate(gettext('Can not add %(deliveries_term)s on closed groups.'), {
                deliveries_term: gettext('deliveries')
            }, true));
            return;
        }
        var deadlines = this.groupInfoRecord.get('deadlines');
        var latest_deadline = this._getLatestDeadline();
        if(typeof latest_deadline == 'undefined') {
            // NOTE: We use an error message since the user do not get this through normal UI navigation
            this._showLoadError(interpolate(gettext('Can not add %(deliveries_term)s on a group without a %(deadline_term)s.'), {
                deliveries_term: gettext('deliveries'),
                deadline_term: gettext('deadline')
            }, true));
            return;
        }
        var deadlinePanel = this._getDeadlinePanelById(latest_deadline.id);
        deadlinePanel.down('#addDeliveryPanelContainer').removeAll();
        deadlinePanel.down('#addDeliveryPanelContainer').add({
            xtype: 'add_delivery',
            groupInfoRecord: this.groupInfoRecord,
            listeners: {
                scope: this,
                deliveryCancelled: this._onAddDeliveryCancel,
                deliveryFinished: this._onAddDeliveryFinished
            }
        });
        deadlinePanel.expand();
        deadlinePanel.hideDeliveries();
        this._setBreadcrumbs(this.groupInfoRecord, interpolate(gettext('Add %(delivery_term)s'), {
            delivery_term: gettext('delivery'),
        }, true));
    },

    _removeAddDeliveriesPanel: function(delivery_id) {
        var deadlinePanel = this._getDeadlinePanelById(this._getLatestDeadline().id)
        deadlinePanel.down('#addDeliveryPanelContainer').removeAll();
        deadlinePanel.showDeliveries();
        var token = Ext.String.format('/group/{0}/{1}', this.groupInfoRecord.get('id'), delivery_id || '');
        this.application.route.navigate(token);
    },

    _onAddDeliveryCancel: function() {
        this._removeAddDeliveriesPanel();
    },

    _onAddDeliveryFinished: function(delivery_id) {
        this._removeAddDeliveriesPanel(delivery_id);
    },

    _getLatestDeadline: function() {
        var deadlines = this.groupInfoRecord.get('deadlines');
        if(deadlines.length == 0) {
            return undefined;
        } else {
            return deadlines[0];
        }
    },

    _getDeadlinePanelById: function(deadline_id) {
        var selector = Ext.String.format('#deadline-{0}', deadline_id);
        return this.getOverview().down(selector);
    }
});
<commit_msg>devilry_student: Better focus on add delivery panel.<commit_after>Ext.define('devilry_student.controller.GroupInfo', {
    extend: 'Ext.app.Controller',

    requires: [
        'Ext.window.MessageBox',
        'devilry_student.view.add_delivery.AddDeliveryPanel'
    ],

    views: [
        'groupinfo.Overview',
        'groupinfo.DeadlinePanel',
        'groupinfo.DeliveryPanel',
        'groupinfo.GroupMetadata'
    ],

    models: ['GroupInfo'],

    refs: [{
        ref: 'overview',
        selector: 'viewport groupinfo'
    }, {
        ref: 'deadlinesContainer',
        selector: 'viewport groupinfo #deadlinesContainer'
    }, {
        ref: 'metadataContainer',
        selector: 'viewport groupinfo #metadataContainer'
    }, {
        ref: 'titleBox',
        selector: 'viewport groupinfo #titleBox'
    }],

    init: function() {
        this.control({
            'viewport groupinfo #deadlinesContainer': {
                render: this._onRender
            },
            'viewport groupinfo groupmetadata': {
                active_feedback_link_clicked: this._onActiveFeedbackLink
            }
        });
    },

    _onRender: function() {
        this._reload();
    },

    _reload: function() {
        var group_id = this.getOverview().group_id;
        this.getOverview().setLoading(true);
        this.getGroupInfoModel().load(group_id, {
            scope: this,
            success: this._onGroupInfoLoadSuccess,
            failure: this._onGroupInfoLoadFailure
        });
    },

    _onGroupInfoLoadSuccess: function(groupInfoRecord) {
        this._setBreadcrumbs(groupInfoRecord);
        this._populateDeadlinesContainer(groupInfoRecord.get('deadlines'), groupInfoRecord.get('active_feedback'));
        this._populateMetadata(groupInfoRecord);
        this._populateTitleBox(groupInfoRecord);
        this.groupInfoRecord = groupInfoRecord;

        var delivery_id = this.getOverview().delivery_id;
        if(delivery_id != undefined) {
            this._hightlightSelectedDelivery(delivery_id);
        }

        if(this.getOverview().add_delivery) {
            this._addDelivery();
        }
        this.getOverview().setLoading(false);
    },

    _onGroupInfoLoadFailure: function() {
        this.setLoading(false);
        this._showLoadError(gettext('Failed to load group. Try to reload the page'));
    },

    _showLoadError: function(message) {
        Ext.MessageBox.alert(gettext('Error'), message);
    },

    _populateDeadlinesContainer: function(deadlines, active_feedback) {
        this.getDeadlinesContainer().removeAll();
        Ext.Array.each(deadlines, function(deadline) {
            this.getDeadlinesContainer().add({
                xtype: 'groupinfo_deadline',
                deadline: deadline,
                active_feedback: active_feedback
            });
        }, this);
    },

    _populateTitleBox: function(groupInfoRecord) {
        this.getTitleBox().update({
            groupinfo: groupInfoRecord.data
        });
    },

    _populateMetadata: function(groupInfoRecord) {
        this.getMetadataContainer().removeAll();
        this.getMetadataContainer().add({
            xtype: 'groupmetadata',
            data: {
                groupinfo: groupInfoRecord.data,
                examiner_term: gettext('examiner')
            }
        });
    },

    _onActiveFeedbackLink: function() {
        var group_id = this.groupInfoRecord.get('id');
        var delivery_id = this.groupInfoRecord.get('active_feedback').delivery_id;
        this._hightlightSelectedDelivery(delivery_id);
        this.application.route.setHashWithoutEvent(Ext.String.format('/group/{0}/{1}', group_id, delivery_id));
    },

    _hightlightSelectedDelivery: function(delivery_id) {
        var itemid = Ext.String.format('#delivery-{0}', delivery_id);
        var deliveryPanel = this.getOverview().down(itemid);
        if(deliveryPanel) {
            var container = deliveryPanel.up('groupinfo_deadline');
            container.expand();
            //deliveryPanel.el.scrollIntoView(this.getOverview().body, false, true);
            deliveryPanel.el.scrollIntoView(this.getDeadlinesContainer().body, false, true);
        } else {
            this._showLoadError(interpolate(gettext('Invalid delivery: %s'), [delivery_id]));
        }
    },

    _setBreadcrumbs: function(groupInfoRecord, extra) {
        var subject = groupInfoRecord.get('breadcrumbs').subject;
        var period = groupInfoRecord.get('breadcrumbs').period;
        var assignment = groupInfoRecord.get('breadcrumbs').assignment;
        var periodpath = [subject.short_name, period.short_name].join('.');

        var breadcrumbs = [{
            url: '#/browse/',
            text: gettext('Browse')
        }, {
            url: Ext.String.format('#/browse/{0}', period.id),
            text: periodpath
        }];

        if(extra) {
            breadcrumbs.push({
                url: Ext.String.format('#/group/{0}/', groupInfoRecord.get('id')),
                text: assignment.short_name
            });
            this.application.breadcrumbs.set(breadcrumbs, extra);
        } else {
            this.application.breadcrumbs.set(breadcrumbs, assignment.short_name);
        }

        var title = [periodpath, assignment.shortname].join('.');
        if(extra) {
            title += ' - ' + extra;
        }
        this.application.setTitle(title);
    },

    _addDelivery: function() {
        if(!this.groupInfoRecord.get('is_open')) {
            // NOTE: We use an error message since the user do not get this through normal UI navigation
            this._showLoadError(interpolate(gettext('Can not add %(deliveries_term)s on closed groups.'), {
                deliveries_term: gettext('deliveries')
            }, true));
            return;
        }
        var deadlines = this.groupInfoRecord.get('deadlines');
        var latest_deadline = this._getLatestDeadline();
        if(typeof latest_deadline == 'undefined') {
            // NOTE: We use an error message since the user do not get this through normal UI navigation
            this._showLoadError(interpolate(gettext('Can not add %(deliveries_term)s on a group without a %(deadline_term)s.'), {
                deliveries_term: gettext('deliveries'),
                deadline_term: gettext('deadline')
            }, true));
            return;
        }
        var deadlinePanel = this._getDeadlinePanelById(latest_deadline.id);
        deadlinePanel.down('#addDeliveryPanelContainer').removeAll();
        deadlinePanel.down('#addDeliveryPanelContainer').add({
            xtype: 'add_delivery',
            groupInfoRecord: this.groupInfoRecord,
            listeners: {
                scope: this,
                deliveryCancelled: this._onAddDeliveryCancel,
                deliveryFinished: this._onAddDeliveryFinished
            }
        });
        this._setBreadcrumbs(this.groupInfoRecord, interpolate(gettext('Add %(delivery_term)s'), {
            delivery_term: gettext('delivery'),
        }, true));
        this._focusOnAddDeliveryPanel();
    },

    _removeAddDeliveriesPanel: function(delivery_id) {
        this._removeFocusFromDeliveryPanel();
        var token = Ext.String.format('/group/{0}/{1}', this.groupInfoRecord.get('id'), delivery_id || '');
        this.application.route.navigate(token);
    },

    _focusOnAddDeliveryPanel: function() {
        Ext.Array.each(this.getDeadlinesContainer().query('groupinfo_deadline'), function(panel) {
            panel.hide();
        }, this);
        var latest_deadline = this._getLatestDeadline();
        var deadlinePanel = this._getDeadlinePanelById(latest_deadline.id);
        deadlinePanel.show();
        deadlinePanel.expand();
        deadlinePanel.hideDeliveries();
        this.getMetadataContainer().hide();
    },

    _removeFocusFromDeliveryPanel: function() {
        Ext.Array.each(this.getDeadlinesContainer().query('groupinfo_deadline'), function(panel) {
            panel.show();
            panel.collapse();
        }, this);
        var deadlinePanel = this._getDeadlinePanelById(this._getLatestDeadline().id)
        deadlinePanel.down('#addDeliveryPanelContainer').removeAll();
        deadlinePanel.showDeliveries();
        this.getMetadataContainer().show();
    },

    _onAddDeliveryCancel: function() {
        this._removeAddDeliveriesPanel();
    },

    _onAddDeliveryFinished: function(delivery_id) {
        this._removeAddDeliveriesPanel(delivery_id);
    },

    _getLatestDeadline: function() {
        var deadlines = this.groupInfoRecord.get('deadlines');
        if(deadlines.length == 0) {
            return undefined;
        } else {
            return deadlines[0];
        }
    },

    _getDeadlinePanelById: function(deadline_id) {
        var selector = Ext.String.format('#deadline-{0}', deadline_id);
        return this.getOverview().down(selector);
    }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.export',
  name: 'ClientGoogleSheetsExportService',

  implements: [
    'foam.nanos.export.GoogleSheetsExport'
  ],

  properties: [
    {
      class: 'Stub',
      of: 'foam.nanos.export.GoogleSheetsExport',
      name: 'delegate'
    }
  ]
});
<commit_msg>Year fixed<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.export',
  name: 'ClientGoogleSheetsExportService',

  implements: [
    'foam.nanos.export.GoogleSheetsExport'
  ],

  properties: [
    {
      class: 'Stub',
      of: 'foam.nanos.export.GoogleSheetsExport',
      name: 'delegate'
    }
  ]
});
<|endoftext|>


<commit_before>define([
    'preact',
    'htm',
    'jquery',
    'd3',
    'kb_lib/jsonRpc/genericClient',

    // For effect
    'd3_sankey',
    'css!./SankeyGraph.css'
], (
    preact,
    htm,
    $,
    d3,
    GenericClient
) => {
    const {Component} = preact;
    const html = htm.bind(preact.h);

    const NODE_HEIGHT = 38;
    const DEFAULT_MAX_HEIGHT = 400;

    const TYPES = {
        selected: {
            color: '#FF9800',
            name: 'Current version'
        },
        core: {
            color: '#FF9800',
            name: 'All Versions of this Data'
        },
        ref: {
            color: '#C62828',
            name: 'Data Referencing this Data'
        },
        included: {
            color: '#2196F3',
            name: 'Data Referenced by this Data'
        },
        none: {
            color: '#FFFFFF',
            name: ''
        },
        copied: {
            color: '#4BB856',
            name: 'Copied From'
        }
    };

    // Utility functions.

    function makeLink(source, target, value) {
        return {
            source,
            target,
            value
        };
    }

    function getTimeStampStr(objInfoTimeStamp) {
        const monthLookup = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        if (!objInfoTimeStamp) {
            return '';
        }
        let date = new Date(objInfoTimeStamp);
        let seconds = Math.floor((new Date() - date) / 1000);

        // f-ing safari, need to add extra ':' delimiter to parse the timestamp
        if (isNaN(seconds)) {
            const tokens = objInfoTimeStamp.split('+'); // this is just the date without the GMT offset
            const newTimestamp = `${tokens[0]  }+${  tokens[0].substr(0, 2)  }:${  tokens[1].substr(2, 2)}`;
            date = new Date(newTimestamp);
            seconds = Math.floor((new Date() - date) / 1000);
            if (isNaN(seconds)) {
                // just in case that didn't work either, then parse without the timezone offset, but
                // then just show the day and forget the fancy stuff...
                date = new Date(tokens[0]);
                return `${monthLookup[date.getMonth()]  } ${  date.getDate()  }, ${  date.getFullYear()}`;
            }
        }

        // keep it simple, just give a date
        return `${monthLookup[date.getMonth()]  } ${  date.getDate()  }, ${  date.getFullYear()}`;
    }

    class SankeyGraph extends Component {
        constructor(props) {
            super(props);
            this.ref = preact.createRef();
            this.state = {
                height: null
            };
        }
        componentDidMount() {
            const node = this.ref.current;
            this.setState({
                width: node.clientWidth
            }, () => {
                this.renderGraph(node);
            });
        }

        async nodeMouseover(d) {
            const wsClient = new GenericClient({
                module: 'Workspace',
                url: this.props.runtime.config('services.Workspace.url'),
                token: this.props.runtime.service('session').getAuthToken()
            });
            if (d.isFake) {
                //
                // TODO: What is this?
                //
                // const info = d.info;
                // let text = '

';
                // text +=
                //     '
Object Details

';
                // text += `<tr><td><b>Name</b></td><td>${  info[1]  }</td></tr>`;
                // text += '

	';
                // text +=
                //     '
Provenance

';
                // text += '
N/A
';
                // text += '
';
                // text += '

';
                // $container.find('#objdetailsdiv').html(text);
            } else {
                const [objdata] = await wsClient.callFunc('get_object_provenance', [[{
                    ref: d.objId
                }]]);

                this.props.onNodeOver({
                    ref: d.objId,
                    info: d.info,
                    objdata
                });
            }
        }

        nodeMouseout() {
            this.props.onNodeOut();
        }

        renderGraph(graphNode) {
            const $graphNode = $(graphNode);

            // TODO: eliminate the "- 27" which is to ensure there is no horizontal scrolling.
            const width = this.state.width - 27;
            const {graph, objRefToNodeIdx} = this.props;
            const height = this.props.graph.nodes.length * NODE_HEIGHT;
            // TODO: eliminate the "+ 15", required to ensure bounding container does not overflow
            this.setState({
                height: Math.min(height + 15, DEFAULT_MAX_HEIGHT)
            });

            if (graph.links.length === 0) {
                // in order to render, we need at least two nodes
                graph.nodes.push({
                    node: 1,
                    name: 'No references found',
                    info: [-1, 'No references found', 'No Type', 0, 0, 'N/A', 0, 'N/A', 0, 0, {}],
                    nodeType: 'none',
                    objId: '-1',
                    isFake: true
                });
                objRefToNodeIdx['-1'] = 1;
                graph.links.push(makeLink(0, 1, 1));
            }

            // if (height < 450) {
            //     $graphNode.height(height + 40);
            // }
            /*var zoom = d3.behavior.zoom()
                 .translate([0, 0])
                 .scale(1)
                 .scaleExtent([1, 8])
                 .on("zoom", function() {
                 features.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
                 //features.select(".state-border").style("stroke-width", 1.5 / d3.event.scale + "px");
                 //features.select(".county-border").style("stroke-width", .5 / d3.event.scale + "px");
                 });
                 */
            // append the svg canvas to the page
            d3.select($graphNode[0]).html('');
            $graphNode.show();
            const svg = d3.select($graphNode[0]).append('svg');
            svg.attr('width', width)
                .attr('height', height)
                .append('g');
                // .attr('transform', `translate(${margin.left},${margin.top})`);

            // Set the sankey diagram properties
            const sankey = d3
                .sankey()
                .nodeWidth(25)
                .nodePadding(40)
                .size([width, height]);

            const path = sankey.link();
            sankey
                .nodes(this.props.graph.nodes)
                .links(this.props.graph.links)
                .layout(40);

            // add in the links
            const link = svg
                .append('g')
                .selectAll('.link')
                .data(this.props.graph.links)
                .enter()
                .append('path')
                .attr('class', 'sankeylink')
                .attr('d', path)
                .style('stroke-width', () => {
                    return 10; /*Math.max(1, d.dy);*/
                })
                .sort((a, b) => {
                    return b.dy - a.dy;
                });

            // add the link titles
            link.append('title').text((d) => {
                if (d.source.nodeType === 'copied') {
                    d.text = `${d.target.name  } copied from ${  d.source.name}`;
                } else if (d.source.nodeType === 'core') {
                    d.text = `${d.target.name  } is a newer version of ${  d.source.name}`;
                } else if (d.source.nodeType === 'ref') {
                    d.text = `${d.source.name  } references ${  d.target.name}`;
                } else if (d.source.nodeType === 'included') {
                    d.text = `${d.target.name  } references ${  d.source.name}`;
                }
                return d.text;
            });
            $(link).tooltip({delay: {show: 0, hide: 100}});

            // add in the nodes
            const node = svg
                .append('g')
                .selectAll('.node')
                .data(this.props.graph.nodes)
                .enter()
                .append('g')
                .attr('class', 'sankeynode')
                .attr('transform', (d) => {
                    return `translate(${  d.x  },${  d.y  })`;
                })
                .call(
                    d3.behavior
                        .drag()
                        .origin((d) => {
                            return d;
                        })
                        .on('dragstart', function () {
                            this.parentNode.appendChild(this);
                        })
                        .on('drag', function (d) {
                            d.x = Math.max(0, Math.min(width - d.dx, d3.event.x));
                            d.y = Math.max(0, Math.min(height - d.dy, d3.event.y));
                            d3.select(this).attr('transform', `translate(${  d.x  },${  d.y  })`);
                            sankey.relayout();
                            link.attr('d', path);
                        })
                )
                .on('click', (d) => {
                    console.log('CLICKY');
                })
                .on('dblclick', (d) => {
                    console.log('dbl clicky');
                    if (d3.event.defaultPrevented) {
                        return;
                    }
                    // TODO: toggle switch between redirect vs redraw

                    // alternate redraw
                    //self.$elem.find('#objgraphview').hide();
                    //self.buildDataAndRender({ref:d['objId']});

                    //alternate reload page so we can go forward and back
                    if (d.isFake) {
                        // Oh, no!
                        alert('Cannot expand this node.');
                    } else {
                        //if (d.info[1].indexOf(' ') >= 0) {
                        //    // TODO: Fix this
                        //    window.location.href = "#provenance/" + encodeURI(d.info[7] + "/" + d.info[0]);
                        //} else {
                        // TODO: Fix this
                        const path = `provenance/${encodeURI(`${d.info[6]}/${d.info[0]}/${d.info[4]}`)}`;
                        const url = `${window.location.origin}/#${path}`;
                        console.log('HERE');
                        window.open(url);
                        this.props.runtime.navigate(path);
                        //}
                    }
                })
                .on('mouseover', this.nodeMouseover.bind(this))
                .on('mouseout', this.nodeMouseout.bind(this));

            // add the rectangles for the nodes
            node.append('rect')
                .attr('y', () => {
                    return -5;
                })
                .attr('height', (d) => {
                    return Math.abs(d.dy) + 10;
                })
                .attr('width', sankey.nodeWidth())
                .style('fill', (d) => {
                    return (d.color = TYPES[d['nodeType']].color);
                })
                .style('stroke', (d) => {
                    return 0 * d3.rgb(d.color).darker(2);
                })
                .append('title')
                .html((d) => {
                    //0:obj_id, 1:obj_name, 2:type ,3:timestamp, 4:version, 5:username saved_by, 6:ws_id, 7:ws_name, 8 chsum, 9 size, 10:usermeta
                    const info = d.info;
                    let text =
                        `${info[1]
                        } (${
                            info[6]
                        }/${
                            info[0]
                        }/${
                            info[4]
                        })\n` +
                        '--------------\n' +
                        `  type:  ${
                            info[2]
                        }\n` +
                        `  saved on:  ${
                            getTimeStampStr(info[3])
                        }\n` +
                        `  saved by:  ${
                            info[5]
                        }\n`;
                    let found = false;
                    const metadata = '  metadata:\n';
                    for (const m in info[10]) {
                        text += `     ${  m  } : ${  info[10][m]  }\n`;
                        found = true;
                    }
                    if (found) {
                        text += metadata;
                    }
                    return text;
                });

            // add in the title for the nodes
            node.append('text')
                .attr('y', (d) => {
                    return d.dy / 2;
                })
                .attr('dy', '.35em')
                .attr('text-anchor', 'end')
                .attr('transform', null)
                .text((d) => {
                    return d.name;
                })
                .filter((d) => {
                    return d.x < width / 2;
                })
                .attr('x', 6 + sankey.nodeWidth())
                .attr('text-anchor', 'start');
            return this;
        }

        render() {
            const style = {};
            if (this.state.height !== null) {
                style.height = this.state.height;
            }
            return html`

            `;
        }
    }

    return SankeyGraph;
});
<commit_msg>add resizing of graph; add documentation<commit_after>define([
    'preact',
    'htm',
    'jquery',
    'd3',
    'kb_lib/jsonRpc/genericClient',
    'ResizeObserver',

    // For effect
    'd3_sankey',
    'css!./SankeyGraph.css'
], (
    preact,
    htm,
    $,
    d3,
    GenericClient,
    ResizeObserver
) => {
    const {Component} = preact;
    const html = htm.bind(preact.h);

    // The height of the graph is calculated as the product of the total # of nodes and
    // the following factor. This roughly sizes the graph height to scale with the size of
    // the graph. A larger factor results in a taller graph, and taller nodes.
    const HEIGHT_CALC_NODE_FACTOR = 40;

    // The graph container is resizable, with a size dynamically set to be either the actual
    // height of the graph or 400 if the graph is taller than 400px. The container is resizable,
    // so the user can expand it to the full graph. The graph is scrollable inside the container.
    // If we don't constrain the graph height like this, for a large graph, the user will not be
    // able to even see the detail tables below it.
    const DEFAULT_MAX_HEIGHT = 400;

    const TYPES = {
        selected: {
            color: '#FF9800',
            name: 'Current version'
        },
        core: {
            color: '#FF9800',
            name: 'All Versions of this Data'
        },
        ref: {
            color: '#C62828',
            name: 'Data Referencing this Data'
        },
        included: {
            color: '#2196F3',
            name: 'Data Referenced by this Data'
        },
        none: {
            color: '#FFFFFF',
            name: ''
        },
        copied: {
            color: '#4BB856',
            name: 'Copied From'
        }
    };

    // Utility functions.

    function makeLink(source, target, value) {
        return {
            source,
            target,
            value
        };
    }

    function getTimeStampStr(objInfoTimeStamp) {
        const monthLookup = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        if (!objInfoTimeStamp) {
            return '';
        }
        let date = new Date(objInfoTimeStamp);
        let seconds = Math.floor((new Date() - date) / 1000);

        // f-ing safari, need to add extra ':' delimiter to parse the timestamp
        if (isNaN(seconds)) {
            const tokens = objInfoTimeStamp.split('+'); // this is just the date without the GMT offset
            const newTimestamp = `${tokens[0]  }+${  tokens[0].substr(0, 2)  }:${  tokens[1].substr(2, 2)}`;
            date = new Date(newTimestamp);
            seconds = Math.floor((new Date() - date) / 1000);
            if (isNaN(seconds)) {
                // just in case that didn't work either, then parse without the timezone offset, but
                // then just show the day and forget the fancy stuff...
                date = new Date(tokens[0]);
                return `${monthLookup[date.getMonth()]  } ${  date.getDate()  }, ${  date.getFullYear()}`;
            }
        }

        // keep it simple, just give a date
        return `${monthLookup[date.getMonth()]  } ${  date.getDate()  }, ${  date.getFullYear()}`;
    }

    class SankeyGraph extends Component {
        constructor(props) {
            super(props);
            this.ref = preact.createRef();
            this.state = {
                height: null
            };
            this.resizeObserver = new ResizeObserver(this.onContainerResize.bind(this));
        }
        componentDidMount() {
            const node = this.ref.current;
            this.setState({
                width: node.clientWidth
            }, () => {
                this.renderGraph(node);
                this.resizeObserver.observe(node);
            });
        }

        componentWillUnmount() {
            if (this.resizeObserver && this.ref.current) {
                this.resizeObserver.unobserve(this.ref.current);
            }
        }

        onContainerResize() {
            if (this.ref.current) {
                this.setWidth(this.ref.current);
            }
        }

        async nodeMouseover(d) {
            const wsClient = new GenericClient({
                module: 'Workspace',
                url: this.props.runtime.config('services.Workspace.url'),
                token: this.props.runtime.service('session').getAuthToken()
            });
            if (d.isFake) {
                //
                // TODO: What is this?
                //
                // const info = d.info;
                // let text = '

';
                // text +=
                //     '
Object Details

';
                // text += `<tr><td><b>Name</b></td><td>${  info[1]  }</td></tr>`;
                // text += '

	';
                // text +=
                //     '
Provenance

';
                // text += '
N/A
';
                // text += '
';
                // text += '

';
                // $container.find('#objdetailsdiv').html(text);
            } else {
                const [objdata] = await wsClient.callFunc('get_object_provenance', [[{
                    ref: d.objId
                }]]);

                this.props.onNodeOver({
                    ref: d.objId,
                    info: d.info,
                    objdata
                });
            }
        }

        nodeMouseout() {
            this.props.onNodeOut();
        }

        setWidth(element) {
            this.setState({
                width: element.clientWidth
            }, () => {
                // Crude, but works. When this is rewritten with modern
                // d3 and a supported d3 plugin, can redress this with
                // propery d3 updating.
                this.renderGraph(element);
            });
        }

        renderGraph(graphNode) {
            const $graphNode = $(graphNode);

            // TODO: eliminate the "- 27" which is to ensure there is no horizontal scrolling.
            const width = this.state.width - 27;
            const {graph, objRefToNodeIdx} = this.props;
            const height = this.props.graph.nodes.length * HEIGHT_CALC_NODE_FACTOR;
            // TODO: eliminate the "+ 15", required to ensure bounding container does not overflow
            this.setState({
                height: Math.min(height + 15, DEFAULT_MAX_HEIGHT)
            });

            if (graph.links.length === 0) {
                // in order to render, we need at least two nodes
                graph.nodes.push({
                    node: 1,
                    name: 'No references found',
                    info: [-1, 'No references found', 'No Type', 0, 0, 'N/A', 0, 'N/A', 0, 0, {}],
                    nodeType: 'none',
                    objId: '-1',
                    isFake: true
                });
                objRefToNodeIdx['-1'] = 1;
                graph.links.push(makeLink(0, 1, 1));
            }

            // TODO: This was previously disabled, not sure why. We should consider
            // reviving it.
            /*var zoom = d3.behavior.zoom()
                 .translate([0, 0])
                 .scale(1)
                 .scaleExtent([1, 8])
                 .on("zoom", function() {
                 features.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
                 //features.select(".state-border").style("stroke-width", 1.5 / d3.event.scale + "px");
                 //features.select(".county-border").style("stroke-width", .5 / d3.event.scale + "px");
                 });
                 */
            // append the svg canvas to the page
            d3.select($graphNode[0]).html('');
            $graphNode.show();
            const svg = d3.select($graphNode[0]).append('svg');

            svg.attr('width', width)
                .attr('height', height)
                .append('g');
                // removed for simplicity, not sure it really adds very much.
                // we use the container to add padding for layout. It is fine
                // and preferred to have the graph start at 0,0.
                // .attr('transform', `translate(${margin.left},${margin.top})`);

            // Set the sankey diagram properties
            const sankey = d3
                .sankey()
                .nodeWidth(25)
                .nodePadding(40)
                .size([width, height]);

            const path = sankey.link();
            sankey
                .nodes(this.props.graph.nodes)
                .links(this.props.graph.links)
                .layout(40);

            // add in the links
            const link = svg
                .append('g')
                .selectAll('.link')
                .data(this.props.graph.links)
                .enter()
                .append('path')
                .attr('class', 'sankeylink')
                .attr('d', path)
                .style('stroke-width', () => {
                    return 10; /*Math.max(1, d.dy);*/
                })
                .sort((a, b) => {
                    return b.dy - a.dy;
                });

            // add the link titles
            link.append('title').text((d) => {
                if (d.source.nodeType === 'copied') {
                    d.text = `${d.target.name  } copied from ${d.source.name}`;
                } else if (d.source.nodeType === 'core') {
                    d.text = `${d.target.name  } is a newer version of ${d.source.name}`;
                } else if (d.source.nodeType === 'ref') {
                    d.text = `${d.source.name  } references ${d.target.name}`;
                } else if (d.source.nodeType === 'included') {
                    d.text = `${d.target.name  } references ${d.source.name}`;
                }
                return d.text;
            });
            $(link).tooltip({delay: {show: 0, hide: 100}});

            // add in the nodes
            const node = svg
                .append('g')
                .selectAll('.node')
                .data(this.props.graph.nodes)
                .enter()
                .append('g')
                .attr('class', 'sankeynode')
                .attr('transform', (d) => {
                    return `translate(${d.x},${d.y})`;
                })
                .call(
                    d3.behavior
                        .drag()
                        .origin((d) => {
                            return d;
                        })
                        .on('dragstart', function () {
                            this.parentNode.appendChild(this);
                        })
                        .on('drag', function (d) {
                            d.x = Math.max(0, Math.min(width - d.dx, d3.event.x));
                            d.y = Math.max(0, Math.min(height - d.dy, d3.event.y));
                            d3.select(this).attr('transform', `translate(${d.x},${d.y})`);
                            sankey.relayout();
                            link.attr('d', path);
                        })
                )
                .on('click', (d) => {
                    console.log('CLICKY');
                })
                .on('dblclick', (d) => {
                    console.log('dbl clicky');
                    if (d3.event.defaultPrevented) {
                        return;
                    }
                    // TODO: toggle switch between redirect vs redraw

                    // alternate redraw
                    //self.$elem.find('#objgraphview').hide();
                    //self.buildDataAndRender({ref:d['objId']});

                    //alternate reload page so we can go forward and back
                    if (d.isFake) {
                        // Oh, no!
                        alert('Cannot expand this node.');
                    } else {
                        //if (d.info[1].indexOf(' ') >= 0) {
                        //    // TODO: Fix this
                        //    window.location.href = "#provenance/" + encodeURI(d.info[7] + "/" + d.info[0]);
                        //} else {
                        // TODO: Fix this
                        const path = `provenance/${encodeURI(`${d.info[6]}/${d.info[0]}/${d.info[4]}`)}`;
                        const url = `${window.location.origin}/#${path}`;
                        console.log('HERE');
                        window.open(url);
                        this.props.runtime.navigate(path);
                        //}
                    }
                })
                .on('mouseover', this.nodeMouseover.bind(this))
                .on('mouseout', this.nodeMouseout.bind(this));

            // add the rectangles for the nodes
            node.append('rect')
                .attr('y', () => {
                    return -5;
                })
                .attr('height', (d) => {
                    return Math.abs(d.dy) + 10;
                })
                .attr('width', sankey.nodeWidth())
                .style('fill', (d) => {
                    return (d.color = TYPES[d['nodeType']].color);
                })
                .style('stroke', (d) => {
                    return 0 * d3.rgb(d.color).darker(2);
                })
                .append('title')
                .html((d) => {
                    //0:obj_id, 1:obj_name, 2:type ,3:timestamp, 4:version, 5:username saved_by, 6:ws_id, 7:ws_name, 8 chsum, 9 size, 10:usermeta
                    const info = d.info;
                    let text =
                        `${info[1]
                        } (${
                            info[6]
                        }/${
                            info[0]
                        }/${
                            info[4]
                        })\n` +
                        '--------------\n' +
                        `  type:  ${
                            info[2]
                        }\n` +
                        `  saved on:  ${
                            getTimeStampStr(info[3])
                        }\n` +
                        `  saved by:  ${
                            info[5]
                        }\n`;
                    let found = false;
                    const metadata = '  metadata:\n';
                    for (const m in info[10]) {
                        text += `     ${  m  } : ${  info[10][m]  }\n`;
                        found = true;
                    }
                    if (found) {
                        text += metadata;
                    }
                    return text;
                });

            // add in the title for the nodes
            node.append('text')
                .attr('y', (d) => {
                    return d.dy / 2;
                })
                .attr('dy', '.35em')
                .attr('text-anchor', 'end')
                .attr('transform', null)
                .text((d) => {
                    return d.name;
                })
                .filter((d) => {
                    return d.x < width / 2;
                })
                .attr('x', 6 + sankey.nodeWidth())
                .attr('text-anchor', 'start');
            return this;
        }

        render() {
            const style = {};
            if (this.state.height !== null) {
                style.height = this.state.height;
            }
            return html`

            `;
        }
    }

    return SankeyGraph;
});
<|endoftext|>


<commit_before>import {
  interactor,
  clickable,
  collection,
  hasClass,
  is,
  scoped,
  triggerable,
  focusable,
  property,
  attribute,
  blurrable,
  text
} from '@bigtest/interactor';

import css from '../Accordion.css';
import { selectorFromClassnameString } from '../../../tests/helpers';

const triggerCollapse = selectorFromClassnameString(`.${css.defaultCollapseButton}`);

export const AccordionInteractor = interactor(class AccordionInteractor {
  static defaultScope = `.${css.accordion}`

  label = text(`.${css.labelArea}`)
  isOpen = hasClass(`.${css.content}`, css.expanded)
  contentHeight = property(`.${css.content}`, 'offsetHeight')
  clickHeader = clickable(triggerCollapse)
  accordions = scoped(triggerCollapse, {
    gotoNext: triggerable('keydown', { keyCode: 40 }), // down arrow
    gotoPrevious: triggerable('keydown', { keyCode: 38 }), // up arrow
    gotoLast: triggerable('keydown', { keyCode: 35 }), // end key
    gotoFirst: triggerable('keydown', { keyCode: 36 }), // home key
    pressTab: triggerable('keydown', { keyCode: 9 }), // tab
    clickTrigger: clickable(),
    blurTrigger: blurrable(),
    focusTrigger: focusable(),
    isFocused: is(':focus'),
  })
});

export const AccordionSetInteractor = interactor(class AccordionSetInteractor {
  static defaultScope = '#testSet';
  set = collection('section', AccordionInteractor)
  tablist = is('[role="tablist"]')
  id = attribute('id')
});
<commit_msg>clean up unused imports in Accordion's interactor<commit_after>import {
  interactor,
  clickable,
  collection,
  hasClass,
  is,
  scoped,
  triggerable,
  focusable,
  property,
  attribute,
  text
} from '@bigtest/interactor';

import css from '../Accordion.css';
import { selectorFromClassnameString } from '../../../tests/helpers';

const triggerCollapse = selectorFromClassnameString(`.${css.defaultCollapseButton}`);

export const AccordionInteractor = interactor(class AccordionInteractor {
  static defaultScope = `.${css.accordion}`

  label = text(`.${css.labelArea}`)
  isOpen = hasClass(`.${css.content}`, css.expanded)
  contentHeight = property(`.${css.content}`, 'offsetHeight')
  clickHeader = clickable(triggerCollapse)
  accordions = scoped(triggerCollapse, {
    gotoNext: triggerable('keydown', { keyCode: 40 }), // down arrow
    gotoPrevious: triggerable('keydown', { keyCode: 38 }), // up arrow
    gotoLast: triggerable('keydown', { keyCode: 35 }), // end key
    gotoFirst: triggerable('keydown', { keyCode: 36 }), // home key
    pressTab: triggerable('keydown', { keyCode: 9 }), // tab
    focusTrigger: focusable(),
    isFocused: is(':focus'),
  })
});

export const AccordionSetInteractor = interactor(class AccordionSetInteractor {
  static defaultScope = '#testSet';
  set = collection('section', AccordionInteractor)
  tablist = is('[role="tablist"]')
  id = attribute('id')
});
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2015 Benjamin Cordier

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

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

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

var Interactor = function (config) {
	this.__init__(config);
};

Interactor.prototype = {

	// Initialization
	__init__: function (config) {
		// Argument Assignment / Sanity Checks
		this.interactions 		= typeof(config.interactions) 				== "boolean" 	? config.interations 		: true,
		this.interactionElement = typeof(config.interactionElement) 		== "string" 	? config.interactionElement :'interaction',
		this.interactionEvents 	= Array.isArray(config.interactionEvents) 	== true 		? config.interactionEvents 	: ['mouseup', 'touchend'],
		this.conversions 		= typeof(config.coversions)					== "boolean" 	? config.conversions		: false,
		this.conversionElement 	= typeof(config.conversionElement) 			== "string" 	? config.conversionElement 	: 'conversion',
		this.conversionEvents 	= Array.isArray(config.conversionEvents) 	== true 		? config.conversionEvents 	: ['mouseup', 'touchend'],
		this.endpoint 			= typeof(config.endpoint) 					== "string" 	? config.endpoint 			: '/interactions',
		this.async 				= typeof(config.async) 						== "boolean" 	? config.async 				: true,
		this.records 			= [];
		this.loadTime 			= new Date();
		// Bind Events
		this.__bindEvents__();
	},

	// Create Events to Track
	__bindEvents__: function () {
		var interactor 	= this;

		// Set interactor Capture
		if (interactor.interactions === true) {
			for (var i = 0; i < interactor.interactionEvents.length; i++) {
				var ev 		= interactor.interactionEvents[i],
					targets = document.getElementsByClassName(interactor.interactionElement);
				for (var j = 0; j < targets.length; j++) {
					targets[j].addEventListener(ev, function (e) {
						e.stopPropagation();
						interactor.__addInteraction__(e, "interaction");
					});
				}
			}
		}

		// Set Conversion Capture
		if (interactor.conversions === true) {
			for (var i = 0; i < interactor.conversionEvents.length; i++) {
				var ev 		= interactor.events[i],
					targets = document.getElementsByClassName(interactor.conversionElement);
				for (var j = 0; j < targets.length; j++) {
					targets[j].addEventListener(ev, function (e) {
						e.stopPropagation();
						interactor.__addInteraction__(e, "conversion");
					});
				}
			}
		}

		// Bind onbeforeunload Event
		window.onbeforeunload = function (e) {
			interactor.__sendInteractions__();
		};
		return this;
	},

	// Add interactor Triggered By Events
	__addInteraction__: function (e, type) {
		var interactor 	= this,
			interaction 	= {
				type 			: type,
				event 			: e.type,
				targetTag 		: e.path[0].tagName,
				targetClasses 	: e.path[0].className,
				content 		: e.path[0].innerText,
				clientPosition  : {
					x 				: e.clientX,
					y 				: e.clientY
				},
				screenPosition 	: {
					x 				: e.screenX,
					y 				: e.screenY
				},
				createdAt 		: new Date()
			};
		interactor.records.push(interaction);
		return this;
	},

	// Gather additional data and send interaction(s) to server
	__sendInteractions__: function () {
		var interactor 	= this,
			data 			= {
				loadTime 		: interactor.loadTime,
				unloadTime 		: new Date(),
				language 		: window.navigator.language,
				platform 		: window.navigator.platform,
				port 			: window.location.port,
				client 			: {
					name 			: window.navigator.appVersion,
					innerWidth 		: window.innerWidth,
					innerHeight 	: window.innerHeight,
					outerWidth 		: window.outerWidth,
					outerHeight 	: window.outerHeight
				},
				page 			: {
					location 		: window.location.pathname,
					href 			: window.location.href,
					origin 			: window.location.origin,
					title 			: document.title
				},
				interactions 	: interactor.records
			},
			ajax  			= new XMLHttpRequest();
		ajax.open('POST', interactor.endpoint, interactor.async);
		ajax.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
		ajax.send(JSON.stringify(data));
	}
};<commit_msg>Version 1.2 – Updated comments and a small cleanup<commit_after>/*
The MIT License (MIT)

Copyright (c) 2015 Benjamin Cordier

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

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

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

var Interactor = function (config) {
	this.__init__(config);
};

Interactor.prototype = {

	// Initialization
	__init__: function (config) {

		// Argument Assignment / Sanity Checks
		this.interactions 		= typeof(config.interactions) 				== "boolean" 	? config.interations 		: true,
		this.interactionElement = typeof(config.interactionElement) 		== "string" 	? config.interactionElement :'interaction',
		this.interactionEvents 	= Array.isArray(config.interactionEvents) 	== true 		? config.interactionEvents 	: ['mouseup', 'touchend'],
		this.conversions 		= typeof(config.coversions)					== "boolean" 	? config.conversions		: false,
		this.conversionElement 	= typeof(config.conversionElement) 			== "string" 	? config.conversionElement 	: 'conversion',
		this.conversionEvents 	= Array.isArray(config.conversionEvents) 	== true 		? config.conversionEvents 	: ['mouseup', 'touchend'],
		this.endpoint 			= typeof(config.endpoint) 					== "string" 	? config.endpoint 			: '/interactions',
		this.async 				= typeof(config.async) 						== "boolean" 	? config.async 				: true,
		this.records 			= [];
		this.loadTime 			= new Date();

		// Call Event Binding Method
		this.__bindEvents__();

		return this;
	},

	// Create Events to Track
	__bindEvents__: function () {

		var interactor 	= this;

		// Set Interaction Capture
		if (interactor.interactions === true) {
			for (var i = 0; i < interactor.interactionEvents.length; i++) {
				var ev 		= interactor.interactionEvents[i],
					targets = document.getElementsByClassName(interactor.interactionElement);
				for (var j = 0; j < targets.length; j++) {
					targets[j].addEventListener(ev, function (e) {
						e.stopPropagation();
						interactor.__addInteraction__(e, "interaction");
					});
				}
			}
		}

		// Set Conversion Capture
		if (interactor.conversions === true) {
			for (var i = 0; i < interactor.conversionEvents.length; i++) {
				var ev 		= interactor.events[i],
					targets = document.getElementsByClassName(interactor.conversionElement);
				for (var j = 0; j < targets.length; j++) {
					targets[j].addEventListener(ev, function (e) {
						e.stopPropagation();
						interactor.__addInteraction__(e, "conversion");
					});
				}
			}
		}

		// Bind onbeforeunload Event
		window.onbeforeunload = function (e) {
			interactor.__sendInteractions__();
		};

		return this;
	},

	// Add Interaction Triggered By Events
	__addInteraction__: function (e, type) {

		var interactor 	= this,
			interaction 	= {
				type 			: type,
				event 			: e.type,
				targetTag 		: e.path[0].tagName,
				targetClasses 	: e.path[0].className,
				content 		: e.path[0].innerText,
				clientPosition  : {
					x 				: e.clientX,
					y 				: e.clientY
				},
				screenPosition 	: {
					x 				: e.screenX,
					y 				: e.screenY
				},
				createdAt 		: new Date()
			};

		// Insert Interaction Object into Records Array
		interactor.records.push(interaction);

		return this;
	},

	// Gather Additional Data and Send Interaction(s) to Server
	__sendInteractions__: function () {

		var interactor 	= this,

			data 			= {
				loadTime 		: interactor.loadTime,
				unloadTime 		: new Date(),
				language 		: window.navigator.language,
				platform 		: window.navigator.platform,
				port 			: window.location.port,
				client 			: {
					name 			: window.navigator.appVersion,
					innerWidth 		: window.innerWidth,
					innerHeight 	: window.innerHeight,
					outerWidth 		: window.outerWidth,
					outerHeight 	: window.outerHeight
				},
				page 			: {
					location 		: window.location.pathname,
					href 			: window.location.href,
					origin 			: window.location.origin,
					title 			: document.title
				},
				interactions 	: interactor.records
			},
			ajax  			= new XMLHttpRequest();

		// Send Post Request
		ajax.open('POST', interactor.endpoint, interactor.async);
		ajax.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
		ajax.send(JSON.stringify(data));
	}

};
<|endoftext|>


<commit_before>import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { MODAL_BROWSER_PROVIDERS } from 'angular2-modal/platform-browser';
import 'rxjs/add/operator/map';

import { DemoApp } from './pages/app/App';
import './index.scss';

bootstrap(DemoApp, [
    ...MODAL_BROWSER_PROVIDERS,
    ...ROUTER_PROVIDERS,
    { provide: LocationStrategy, useClass: HashLocationStrategy }
]).catch(err => console.error(err)); // eslint-disable-line
<commit_msg>chore(imports): Fixing bad imports<commit_after>import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import 'rxjs/add/operator/map';

import { DemoApp } from './pages/app/App';
import './index.scss';

bootstrap(DemoApp, [
    ...ROUTER_PROVIDERS,
    { provide: LocationStrategy, useClass: HashLocationStrategy }
]).catch(err => console.error(err)); // eslint-disable-line
<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var d3 = require('d3');
var hljs = require("highlight.js");
var datagen = require('../../utils/datagen');
var rd3 = require('../../src');
var BarChart = rd3.BarChart;
var LineChart = rd3.LineChart;
var CandlestickChart = rd3.CandlestickChart;
var PieChart = rd3.PieChart;
var AreaChart = rd3.AreaChart;
var Treemap = rd3.Treemap;
var ScatterChart= rd3.ScatterChart;

hljs.initHighlightingOnLoad();

var Demos = React.createClass({

  getInitialState: function() {
    return {
      areaData: [],
      ohlcData: []
    }
  },

  componentWillMount: function() {
    // Browser data adapted from nvd3's stacked area data
    // http://nvd3.org/examples/stackedArea.html
    var parseDate = d3.time.format("%y-%b-%d").parse;
    d3.json("data/stackedAreaData.json", function(error, data) {
      this.setState({areaData: data});
    }.bind(this));

    d3.tsv("data/AAPL_ohlc.tsv", function(error, data) {
      var series = { name: "AAPL", values: [] };

      data.map(function(d) {
        d.date = new Date(+d.date);
        d.open = +d.open;
        d.high = +d.high;
        d.low = +d.low;
        d.close = +d.close;
        series.values.push({ x: d.date, open: d.open, high: d.high, low: d.low, close: d.close});
      });
      this.setState({ ohlcData: [series] });
    }.bind(this));
  },

  render: function() {

    var lineData = [
      {
        name: 'series1',
        values: [ { x: 0, y: 20 }, { x: 1, y: 30 }, { x: 2, y: 10 }, { x: 3, y: 5 }, { x: 4, y: 8 }, { x: 5, y: 15 }, { x: 6, y: 10 } ]
      },
      {
        name: 'series2',
        values : [ { x: 0, y: 8 }, { x: 1, y: 5 }, { x: 2, y: 20 }, { x: 3, y: 12 }, { x: 4, y: 4 }, { x: 5, y: 6 }, { x: 6, y: 2 } ]
      },
      {
        name: 'series3',
        values: [ { x: 0, y: 0 }, { x: 1, y: 5 }, { x: 2, y: 8 }, { x: 3, y: 2 }, { x: 4, y: 6 }, { x: 5, y: 4 }, { x: 6, y: 2 } ]
      }
    ];

    var barData = [{label: 'A', value: 5}, {label: 'B', value: 6}, {label: 'C', value: 2}, {label: 'D', value: 11}, {label: 'E', value: 2}, {label: 'F', value: 7}];
    var pieData = [{label: "Margarita", value: 20.0}, {label: "John", value: 55.0}, {label: "Tim", value: 25.0 }];

    // 2014 Most Populous Countries
    // http://www.prb.org/pdf14/2014-world-population-data-sheet_eng.pdf
    var treemapData = [{label: 'China', value: 1364}, {label: 'India', value: 1296}, {label: 'United States', value: 318}, {label: 'Indonesia', value: 251}, {label: 'Brazil', value: 203}];

    var scatterData = [
      {
        name: "series1",
        values: [ { x: 0, y: 20 }, { x: 5, y: 7 }, { x: 8, y: 3 }, { x: 13, y: 33 }, { x: 12, y: 10 }, { x: 13, y: 15 }, { x: 24, y: 8 }, { x: 25, y: 15 }, { x: 16, y: 10 }, { x: 16, y: 10 }, { x: 19, y: 30 }, { x: 14, y: 30 }]
      },
      {
        name: "series2",
        values: [ { x: 40, y: 30 }, { x: 35, y: 37 }, { x: 48, y: 37 }, { x: 38, y: 33 }, { x: 52, y: 60 }, { x: 51, y: 55 }, { x: 54, y: 48 }, { x: 45, y: 45 }, { x: 46, y: 50 }, { x: 66, y: 50 }, { x: 39, y: 36 }, { x: 54, y: 30 }]
      },
      {
        name: "series3",
        values: [ { x: 80, y: 78 }, { x: 71, y: 58 }, { x: 78, y: 68 }, { x: 81, y: 47 },{ x: 72, y: 70 }, { x: 70, y: 88 }, { x: 81, y: 90 }, { x: 92, y: 80 }, { x: 81, y: 72 }, { x: 99, y: 95 }, { x: 67, y: 81 }, { x: 96, y: 78 }]
      }
    ];

    return (

react-d3: Multiple series charts

            <LineChart
              legend={true}
              data={lineData}
              width={500}
              height={300}
              title="Line Chart"
              yAxisLabel="Altitude"
              xAxisLabel="Elapsed Time (sec)"
            />

              {
`var lineData = [
  {
    name: "series1",
    values: [ { x: 0, y: 20 }, ..., { x: 24, y: 10 } ]
  },
  ....
  {
    name: "series2",
    values: [ { x: 70, y: 82 }, ..., { x: 76, y: 82 } ]
  }
];`
              }

              {
`<LineChart
  legend={true}
  data={lineData}
  width={500}
  height={300}
  title="Line Chart"
  yAxisLabel="Altitude"
  xAxisLabel="Elapsed Time (sec)"
/>`
              }

            <ScatterChart
              data={scatterData} width={500} height={400} title="Scatter Chart" />

              {
`var scatterData = [
  {
    name: "series1",
    values: [ { x: 0, y: 20 }, ..., { x: 24, y: 10 } ]
  },
  ....
  {
    name: "series3",
    values: [ { x: 70, y: 82 }, ..., { x: 76, y: 82 } ]
  }
];`
              }

              {
`<ScatterChart
  data={scatterData}
  width={500}
  height={400}
  title="Scatter Chart"
/>`
              }

            <AreaChart
              data={this.state.areaData}
              width={500}
              height={400}
              title="Area Chart"
              xAxisTickInterval={{unit: 'year', interval: 2}}
              xAxisLabel="Year"
              yAxisLabel="Share Price"
              xAccessor={(d)=> {
                  return new Date(d[0]);
                }
              }
              yAccessor={(d)=>d[1]}
            />

              {
`var areaData = [
  {
    name: "series1",
    values: [ { x: [object Date], y: 20.5 }, ..., { x: [object Date], y: 4.2 } ]
  },
  ...
  {
    name: "series2",
    values: [ { x: [object Date], y: 3.2 }, ..., { x: [object Date], y: 11.2 } ]
  }
];`
              }

                {
`<AreaChart
  data={areaData}
  width={400}
  height={300}
  xAxisTickInterval={{unit: 'year', interval: 2}}
  title="Area Chart"
/>`
                }

            <CandlestickChart
              data={this.state.ohlcData}
              width={500}
              height={400}
              yAxisOffset={-10}
              title="Candlestick Chart"
            />

              {
`var ohlcData = [
  {
    name: "AAPL",
    values: [ { x: [object Date], open: 451.69, high: 456.23, low: 435, close: 439.88 },
              { x: [object Date], open: 437.82, high: 453.21, low: 435.86 , close: 449.83 },
              ...
            ]
  }
];`
              }

                {
`<CandlestickChart
  data={ohlcData}
  width={500}
  height={400}
  xAxisTickInterval={{unit: 'month', interval: 1}}
  yAxisOffset={-10}
  title="Candlestick Chart"
/>`
                }

react-d3: Single series charts

            <BarChart data={barData} width={500} height={200} title="Bar Chart"/>

              {`var barData = [
  {label: 'A', value: 5},
  {label: 'B', value: 6},
  ...
  {label: 'F', value: 7}
];`}

                {`<BarChart
  data={barData}
  width={500}
  height={200}
  fill={'#3182bd'}
  title='Bar Chart'
/>`}

            <PieChart data={pieData} width={450} height={400} radius={110} innerRadius={20} title="Pie Chart" />

              {
`var pieData = [
  {label: 'Margarita', value: 20.0},
  {label: 'John', value: 55.0},
  {label: 'Tim', value: 25.0 }
];`
              }

                {
`<PieChart
  data={pieData}
  width={400}
  height={400}
  radius={100}
  innerRadius={20}
  title="Pie Chart"
/>`
                }

            <Treemap
              width={450}
              height={250}
              title="Treemap"
              data={treemapData}
              textColor="#484848"
              fontColor="12px"
            />

              {
`//2014 World Most Populous Countries (millions)
//http://www.prb.org/pdf14/2014-world-population-data-sheet_eng.pdf
var treemapData = [
  {label: "China", value: 1364},
  {label: "India", value: 1296},
...
  {label: "Brazil", value: 203}
];`
              }

                {
`<Treemap
  data={treemapData}
  width={450}
  height={250}
  textColor="#484848"
  fontSize="12px"
  title="Treemap"
/>`
                }

    );
  }

});

React.render(
  <Demos />,
  document.body
);
<commit_msg>Remove unused module in docs/example/main.js<commit_after>'use strict';

var React = require('react');
var d3 = require('d3');
var hljs = require("highlight.js");
var rd3 = require('../../src');
var BarChart = rd3.BarChart;
var LineChart = rd3.LineChart;
var CandlestickChart = rd3.CandlestickChart;
var PieChart = rd3.PieChart;
var AreaChart = rd3.AreaChart;
var Treemap = rd3.Treemap;
var ScatterChart= rd3.ScatterChart;

hljs.initHighlightingOnLoad();

var Demos = React.createClass({

  getInitialState: function() {
    return {
      areaData: [],
      ohlcData: []
    }
  },

  componentWillMount: function() {
    // Browser data adapted from nvd3's stacked area data
    // http://nvd3.org/examples/stackedArea.html
    var parseDate = d3.time.format("%y-%b-%d").parse;
    d3.json("data/stackedAreaData.json", function(error, data) {
      this.setState({areaData: data});
    }.bind(this));

    d3.tsv("data/AAPL_ohlc.tsv", function(error, data) {
      var series = { name: "AAPL", values: [] };

      data.map(function(d) {
        d.date = new Date(+d.date);
        d.open = +d.open;
        d.high = +d.high;
        d.low = +d.low;
        d.close = +d.close;
        series.values.push({ x: d.date, open: d.open, high: d.high, low: d.low, close: d.close});
      });
      this.setState({ ohlcData: [series] });
    }.bind(this));
  },

  render: function() {

    var lineData = [
      {
        name: 'series1',
        values: [ { x: 0, y: 20 }, { x: 1, y: 30 }, { x: 2, y: 10 }, { x: 3, y: 5 }, { x: 4, y: 8 }, { x: 5, y: 15 }, { x: 6, y: 10 } ]
      },
      {
        name: 'series2',
        values : [ { x: 0, y: 8 }, { x: 1, y: 5 }, { x: 2, y: 20 }, { x: 3, y: 12 }, { x: 4, y: 4 }, { x: 5, y: 6 }, { x: 6, y: 2 } ]
      },
      {
        name: 'series3',
        values: [ { x: 0, y: 0 }, { x: 1, y: 5 }, { x: 2, y: 8 }, { x: 3, y: 2 }, { x: 4, y: 6 }, { x: 5, y: 4 }, { x: 6, y: 2 } ]
      }
    ];

    var barData = [{label: 'A', value: 5}, {label: 'B', value: 6}, {label: 'C', value: 2}, {label: 'D', value: 11}, {label: 'E', value: 2}, {label: 'F', value: 7}];
    var pieData = [{label: "Margarita", value: 20.0}, {label: "John", value: 55.0}, {label: "Tim", value: 25.0 }];

    // 2014 Most Populous Countries
    // http://www.prb.org/pdf14/2014-world-population-data-sheet_eng.pdf
    var treemapData = [{label: 'China', value: 1364}, {label: 'India', value: 1296}, {label: 'United States', value: 318}, {label: 'Indonesia', value: 251}, {label: 'Brazil', value: 203}];

    var scatterData = [
      {
        name: "series1",
        values: [ { x: 0, y: 20 }, { x: 5, y: 7 }, { x: 8, y: 3 }, { x: 13, y: 33 }, { x: 12, y: 10 }, { x: 13, y: 15 }, { x: 24, y: 8 }, { x: 25, y: 15 }, { x: 16, y: 10 }, { x: 16, y: 10 }, { x: 19, y: 30 }, { x: 14, y: 30 }]
      },
      {
        name: "series2",
        values: [ { x: 40, y: 30 }, { x: 35, y: 37 }, { x: 48, y: 37 }, { x: 38, y: 33 }, { x: 52, y: 60 }, { x: 51, y: 55 }, { x: 54, y: 48 }, { x: 45, y: 45 }, { x: 46, y: 50 }, { x: 66, y: 50 }, { x: 39, y: 36 }, { x: 54, y: 30 }]
      },
      {
        name: "series3",
        values: [ { x: 80, y: 78 }, { x: 71, y: 58 }, { x: 78, y: 68 }, { x: 81, y: 47 },{ x: 72, y: 70 }, { x: 70, y: 88 }, { x: 81, y: 90 }, { x: 92, y: 80 }, { x: 81, y: 72 }, { x: 99, y: 95 }, { x: 67, y: 81 }, { x: 96, y: 78 }]
      }
    ];

    return (

react-d3: Multiple series charts

            <LineChart
              legend={true}
              data={lineData}
              width={500}
              height={300}
              title="Line Chart"
              yAxisLabel="Altitude"
              xAxisLabel="Elapsed Time (sec)"
            />

              {
`var lineData = [
  {
    name: "series1",
    values: [ { x: 0, y: 20 }, ..., { x: 24, y: 10 } ]
  },
  ....
  {
    name: "series2",
    values: [ { x: 70, y: 82 }, ..., { x: 76, y: 82 } ]
  }
];`
              }

              {
`<LineChart
  legend={true}
  data={lineData}
  width={500}
  height={300}
  title="Line Chart"
  yAxisLabel="Altitude"
  xAxisLabel="Elapsed Time (sec)"
/>`
              }

            <ScatterChart
              data={scatterData} width={500} height={400} title="Scatter Chart" />

              {
`var scatterData = [
  {
    name: "series1",
    values: [ { x: 0, y: 20 }, ..., { x: 24, y: 10 } ]
  },
  ....
  {
    name: "series3",
    values: [ { x: 70, y: 82 }, ..., { x: 76, y: 82 } ]
  }
];`
              }

              {
`<ScatterChart
  data={scatterData}
  width={500}
  height={400}
  title="Scatter Chart"
/>`
              }

            <AreaChart
              data={this.state.areaData}
              width={500}
              height={400}
              title="Area Chart"
              xAxisTickInterval={{unit: 'year', interval: 2}}
              xAxisLabel="Year"
              yAxisLabel="Share Price"
              xAccessor={(d)=> {
                  return new Date(d[0]);
                }
              }
              yAccessor={(d)=>d[1]}
            />

              {
`var areaData = [
  {
    name: "series1",
    values: [ { x: [object Date], y: 20.5 }, ..., { x: [object Date], y: 4.2 } ]
  },
  ...
  {
    name: "series2",
    values: [ { x: [object Date], y: 3.2 }, ..., { x: [object Date], y: 11.2 } ]
  }
];`
              }

                {
`<AreaChart
  data={areaData}
  width={400}
  height={300}
  xAxisTickInterval={{unit: 'year', interval: 2}}
  title="Area Chart"
/>`
                }

            <CandlestickChart
              data={this.state.ohlcData}
              width={500}
              height={400}
              yAxisOffset={-10}
              title="Candlestick Chart"
            />

              {
`var ohlcData = [
  {
    name: "AAPL",
    values: [ { x: [object Date], open: 451.69, high: 456.23, low: 435, close: 439.88 },
              { x: [object Date], open: 437.82, high: 453.21, low: 435.86 , close: 449.83 },
              ...
            ]
  }
];`
              }

                {
`<CandlestickChart
  data={ohlcData}
  width={500}
  height={400}
  xAxisTickInterval={{unit: 'month', interval: 1}}
  yAxisOffset={-10}
  title="Candlestick Chart"
/>`
                }

react-d3: Single series charts

            <BarChart data={barData} width={500} height={200} title="Bar Chart"/>

              {`var barData = [
  {label: 'A', value: 5},
  {label: 'B', value: 6},
  ...
  {label: 'F', value: 7}
];`}

                {`<BarChart
  data={barData}
  width={500}
  height={200}
  fill={'#3182bd'}
  title='Bar Chart'
/>`}

            <PieChart data={pieData} width={450} height={400} radius={110} innerRadius={20} title="Pie Chart" />

              {
`var pieData = [
  {label: 'Margarita', value: 20.0},
  {label: 'John', value: 55.0},
  {label: 'Tim', value: 25.0 }
];`
              }

                {
`<PieChart
  data={pieData}
  width={400}
  height={400}
  radius={100}
  innerRadius={20}
  title="Pie Chart"
/>`
                }

            <Treemap
              width={450}
              height={250}
              title="Treemap"
              data={treemapData}
              textColor="#484848"
              fontColor="12px"
            />

              {
`//2014 World Most Populous Countries (millions)
//http://www.prb.org/pdf14/2014-world-population-data-sheet_eng.pdf
var treemapData = [
  {label: "China", value: 1364},
  {label: "India", value: 1296},
...
  {label: "Brazil", value: 203}
];`
              }

                {
`<Treemap
  data={treemapData}
  width={450}
  height={250}
  textColor="#484848"
  fontSize="12px"
  title="Treemap"
/>`
                }

    );
  }

});

React.render(
  <Demos />,
  document.body
);
<|endoftext|>


<commit_before>const Api = require('./api-telegram');
const path = require('path');
const { kv, readFile, jsonStdin } = require('./utils.js');

async function main(dest) {
  try {
    const {
      params: { chat_id: chat_id_file, text: text_file },
      source: { telegram_key }
    } = await jsonStdin();

    const api = new Api(telegram_key);

    console.error('error', telegram_key);
    const [chat_id, text] = await Promise.all([
      readFile(path.join(dest, chat_id_file)),
      readFile(path.join(dest, text_file))
    ]);
    console.error('error', chat_id, text);
    // const {result: {chat}} = await api.sendMessage(chat_id, text)
    const resp = await api.sendMessage(chat_id, text);
    console.error('error', resp);
    const { result: { chat } } = resp;

    process.stdout.write(
      JSON.stringify({
        version: {},
        metadata: [
          kv('username', chat.username),
          kv('chat_id', chat.id.toString())
        ]
      })
    );
  } catch (e) {
    console.error(e);
    process.exit(1);
  }
}

main(process.argv.pop());
<commit_msg>implementing resource<commit_after>const Api = require('./api-telegram');
const path = require('path');

async function main(readConfig, jsonStdin, Api, readFile, dest) {
  const {
    api,
    chat_id: chat_id_file,
    text: text_file
  } = await readConfig(jsonStdin(), Api);

  const [chat_id, text] = await Promise.all([
    readFile(path.join(dest, chat_id_file)),
    readFile(path.join(dest, text_file))
  ]);

  const resp = await api.sendMessage(chat_id, text);
  // try {
  //   // console.log('at least tryiing');
  //   // const {
  //   //   params: { chat_id: chat_id_file, text: text_file },
  //   //   source: { telegram_key }
  //   // } = await jsonStdin();

  //   // const api = new Api(telegram_key);

  //   // console.error('error', telegram_key);
  //   // const [chat_id, text] = await Promise.all([
  //   //   readFile(path.join(dest, chat_id_file)),
  //   //   readFile(path.join(dest, text_file))
  //   // ]);
  //   // console.error('error', chat_id, text);
  //   // // const {result: {chat}} = await api.sendMessage(chat_id, text)
  //   // console.error('error', resp);
  const { result: { chat } } = resp;

  return {
    version: {},
    metadata: [kv('username', chat.username), kv('chat_id', chat.id.toString())]
  };
  // } catch (e) {
  //   console.error(e);
  //   return {};
  // }
  return await null;
}

module.exports = {
  main
};

const { kv, readFile, jsonStdin } = require('./utils.js');

if (require.main === module) {
  jsonStdout(
    main(readConfig, jsonStdin, Api, check, writeFile, process.argv.pop())
  );
}
<|endoftext|>


<commit_before>define([
	'goo/loaders/handlers/ComponentHandler',
	'goo/entities/components/MeshRendererComponent',
	'goo/util/rsvp',
	'goo/util/PromiseUtil',
	'goo/util/ObjectUtil'
], function(
	ComponentHandler,
	MeshRendererComponent,
	RSVP,
	pu,
	_
) {
	function MeshRendererComponentHandler() {
		ComponentHandler.apply(this, arguments);
	}

	MeshRendererComponentHandler.prototype = Object.create(ComponentHandler.prototype);
	ComponentHandler._registerClass('meshRenderer', MeshRendererComponentHandler);
	MeshRendererComponentHandler.prototype.constructor = MeshRendererComponentHandler;

	MeshRendererComponentHandler.prototype._prepare = function(config) {
		return _.defaults(config, {
			materialRefs: [],
			cullMode: 'Dynamic',
			castShadows: false,
			receiveShadows: false,
			hidden: false
		});
	};

	MeshRendererComponentHandler.prototype._create = function(entity) {
		var component = new MeshRendererComponent();
		entity.setComponent(component);
		return component;
	};

	MeshRendererComponentHandler.prototype.update = function(entity, config) {
		var that = this;

		var promise;

		var component = ComponentHandler.prototype.update.call(this, entity, config);
		var materialRefs = config.materialRefs;
		if (!materialRefs || materialRefs.length === 0) {
			console.log("No material refs");
			promise = pu.createDummyPromise([]);
		} else {
			var promises = [];
			var pushPromise = function(materialRef) {
				return promises.push(that._getMaterial(materialRef));
			};
			for (var i = 0; i < materialRefs.length; i++) {
				pushPromise(materialRefs[i]);
			}
			promise = RSVP.all(promises);
		}
		return promise.then(function(materials) {
			var key, value;
			if (component.materials && component.materials.length) {
				var selectMaterial;
				for (var i = 0; i < component.materials.length; i++) {
					var material = component.materials[i];
					if (material.name === 'gooSelectionIndicator') {
						selectMaterial = material;
						break;
					}
				}
				if (selectMaterial) {
					materials.push(selectMaterial);
				}
			}
			component.materials = materials;
			for (key in config) {
				value = config[key];
				if (key !== 'materials' && component.hasOwnProperty(key)) {
					component[key] = _.clone(value);
				}
			}
			return component;
		}).then(null, function(err) {
			return console.error("Error handling materials " + err);
		});
	};

	MeshRendererComponentHandler.prototype._getMaterial = function(ref) {
		var that = this;
		return this.getConfig(ref).then(function(config) {
			return that.updateObject(ref, config, that.options);
		});
	};

	return MeshRendererComponentHandler;
});
<commit_msg>More informative warning about missing material refs<commit_after>define([
	'goo/loaders/handlers/ComponentHandler',
	'goo/entities/components/MeshRendererComponent',
	'goo/util/rsvp',
	'goo/util/PromiseUtil',
	'goo/util/ObjectUtil'
], function(
	ComponentHandler,
	MeshRendererComponent,
	RSVP,
	pu,
	_
) {
	function MeshRendererComponentHandler() {
		ComponentHandler.apply(this, arguments);
	}

	MeshRendererComponentHandler.prototype = Object.create(ComponentHandler.prototype);
	ComponentHandler._registerClass('meshRenderer', MeshRendererComponentHandler);
	MeshRendererComponentHandler.prototype.constructor = MeshRendererComponentHandler;

	MeshRendererComponentHandler.prototype._prepare = function(config) {
		return _.defaults(config, {
			materialRefs: [],
			cullMode: 'Dynamic',
			castShadows: false,
			receiveShadows: false,
			hidden: false
		});
	};

	MeshRendererComponentHandler.prototype._create = function(entity) {
		var component = new MeshRendererComponent();
		entity.setComponent(component);
		return component;
	};

	MeshRendererComponentHandler.prototype.update = function(entity, config) {
		var that = this;

		var promise;

		var component = ComponentHandler.prototype.update.call(this, entity, config);
		var materialRefs = config.materialRefs;
		if (!materialRefs || materialRefs.length === 0) {
			console.log('No material refs in config for', entity);
			promise = pu.createDummyPromise([]);
		} else {
			var promises = [];
			var pushPromise = function(materialRef) {
				return promises.push(that._getMaterial(materialRef));
			};
			for (var i = 0; i < materialRefs.length; i++) {
				pushPromise(materialRefs[i]);
			}
			promise = RSVP.all(promises);
		}
		return promise.then(function(materials) {
			var key, value;
			if (component.materials && component.materials.length) {
				var selectMaterial;
				for (var i = 0; i < component.materials.length; i++) {
					var material = component.materials[i];
					if (material.name === 'gooSelectionIndicator') {
						selectMaterial = material;
						break;
					}
				}
				if (selectMaterial) {
					materials.push(selectMaterial);
				}
			}
			component.materials = materials;
			for (key in config) {
				value = config[key];
				if (key !== 'materials' && component.hasOwnProperty(key)) {
					component[key] = _.clone(value);
				}
			}
			return component;
		}).then(null, function(err) {
			return console.error("Error handling materials " + err);
		});
	};

	MeshRendererComponentHandler.prototype._getMaterial = function(ref) {
		var that = this;
		return this.getConfig(ref).then(function(config) {
			return that.updateObject(ref, config, that.options);
		});
	};

	return MeshRendererComponentHandler;
});
<|endoftext|>


<commit_before>(function() {
    var width = 400;
    var height = 400;
    var body = document.getElementsByTagName('body')[0];

    var div = document.createElement('div');
    div.id = 'div';
    body.appendChild(div);
    div.addEventListener('click', drawImage);

    function drawImage(event) {
        var img = new Image();
        img.setAttribute('crossOrigin','anonymous');

        img.onload = function() {
            var id = String(Math.random()).split('.')[1];
            var canvas = document.createElement('canvas');
            var ctx = canvas.getContext("2d");

            canvas.id = id;
            canvas.width = width;
            canvas.height = height;
            canvas.className = 'canvas';
            canvas.style.left = event.clientX - (width / 2) + 'px';
            canvas.style.top = event.clientY - (height / 2) + 'px';

            ctx.drawImage(img, 0, 0);
            div.appendChild(canvas);

            var options = {
                element: canvas,
                containerWidth: event.clientX,
                containerHeight: event.clientY,
                currentScale: 0.5,
                minScale: 0.1,
                maxScale: 5,
                easing: 0.8
            }

            much.add(options);
        }
        img.src = 'http://lorempixel.com/' + width + '/' + height + '/';
    }

    var GitHub = document.createElement('GitHub');
    GitHub.id = 'GitHub';
    body.appendChild(GitHub);
    GitHub.addEventListener('click', openGitHub);

    function openGitHub() {
        window.open('https://github.com/AndrusAsumets/much','_top')
    }
})();
<commit_msg>Update index.js<commit_after>(function() {
    var width = 400;
    var height = 400;
    var body = document.getElementsByTagName('body')[0];

    var div = document.createElement('div');
    div.id = 'div';
    div.innerHTML = 'Click. Drag. Pinch. Rotate. Click...';

    body.appendChild(div);
    div.addEventListener('click', drawImage);

    function drawImage(event) {
        var img = new Image();
        img.setAttribute('crossOrigin','anonymous');

        img.onload = function() {
            var id = String(Math.random()).split('.')[1];
            var canvas = document.createElement('canvas');
            var ctx = canvas.getContext("2d");

            canvas.id = id;
            canvas.width = width;
            canvas.height = height;
            canvas.className = 'canvas';
            canvas.style.left = event.clientX - (width / 2) + 'px';
            canvas.style.top = event.clientY - (height / 2) + 'px';

            ctx.drawImage(img, 0, 0);
            div.appendChild(canvas);

            var options = {
                element: canvas,
                containerWidth: event.clientX,
                containerHeight: event.clientY,
                currentScale: 0.5,
                minScale: 0.1,
                maxScale: 5,
                easing: 0.8
            }

            much.add(options);
        }
        img.src = 'http://lorempixel.com/' + width + '/' + height + '/';
    }

    var GitHub = document.createElement('GitHub');
    GitHub.id = 'GitHub';
    body.appendChild(GitHub);
    GitHub.addEventListener('click', openGitHub);

    function openGitHub() {
        window.open('https://github.com/AndrusAsumets/much','_top')
    }
})();
<|endoftext|>


<commit_before>/* jshint browser:true */
/* global Chart */
(function($) {

  // Popovers and tooltips
  $('[data-toggle="popover"]').popover({
    html : true
  });

  $('[data-toggle="tooltip"]').tooltip();

  $('.guide-example').each(function() {

    var btn = '' +
      '
' +
      '
' +
        '<button class="btn btn-ghost btn-sm" data-toggle="code">' +
          'View Code ' +
        '</button>' +
      '
';

    $(this).append($(btn));
  });

  $('[data-toggle="code"]').click(function(e) {

    e.preventDefault();

    var target = $(this).parents('.guide-example').next('.language-markup');

    if(target.is(':visible')) {
      target.velocity("slideUp", { duration: 200 });
    }else {
      target.velocity("fadeIn", {
        duration: 300,
        display: 'block'
      });
    }

  });

  //filter popover
  $('[data-toggle="filter"]').popover({
    html : true,
    placement : $(this).attr('data-placement'),
    trigger : 'click',
    content: function() {
      var target = $(this).attr('data-target');
      var $target = $(target);
      return $target.html();
    }
  });

  $('.dropdown-menu a[data-toggle="tab"]').click(function (e) {
      e.stopPropagation();
      $(this).tab('show');
  });

  $('#datetimepicker6').datepicker({
      autoclose: true,
      clearBtn: true,
      todayBtn: true,
      todayHighlight: true,
      format: 'mm/dd/yyyy'
  });

  // Select2
  $('#single-select, #multiple-select').select2({
    placeholder: 'Select a State',
    allowClear: true
  }).on("select2-open", function () {

    var $this = $(this);
    if($this.parents('[class*="has-"]').length) {

      // get all CSS-classes from the element where we found "has-*" and collect them in an array
      var classNames = $this.parents('[class*="has-"]')[0].className.split(/\s+/);

      // go through the class names, find "has-"
      for(var i = 0; i < classNames.length; ++i) {
        if(classNames[i].match("has-")) {
          $('#select2-drop').addClass(classNames[i]);
        }
      }
    }
  });

  $('.select2, .select2-multiple').select2({
    allowClear: true
  });

  setInterval(function() {
    var indicators = $('.loading-indicator');
    for (var i = 0; i < indicators.length; i++) {
      $(indicators[i]).find('.loading-bullet')
        .velocity('transition.slideRightIn', { stagger: 250 })
        .delay(750)
        .velocity({ opacity: 0 }, 500);
    }
  }, 2000);

  // Twitter Typeahead
  var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
      var matches;
      var substrRegex;

      matches = [];
      substrRegex = new RegExp(q, 'i');
      $.each(strs, function(i, str) {
        if (substrRegex.test(str)) {
          matches.push({ value: str });
        }
      });
      cb(matches);
    };
  };

  var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
    'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
    'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
    'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
    'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
    'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
    'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
    'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
    'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
  ];

  $('.form-group .form-control-suggest').typeahead({
      hint: true,
      highlight: true,
      minLength: 1
    },
    {
      name: 'states',
      displayKey: 'value',
      source: substringMatcher(states)
  });

  var data = {
    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
    datasets: [
      {
        label: 'My First dataset',
        fillColor: 'rgba(0,154,87,0.5)',
        strokeColor: 'rgba(0,154,87,0.8)',
        highlightFill: 'rgba(0,154,87,0.75)',
        highlightStroke: 'rgba(0,154,87,1)',
        data: [65, 59, 80, 81, 56, 55, 40]
      },
      {
        label: 'My Second dataset',
        fillColor: 'rgba(0,147,232,0.5)',
        strokeColor: 'rgba(0,147,232,0.8)',
        highlightFill: 'rgba(0,147,232,0.75)',
        highlightStroke: 'rgba(0,147,232,1)',
        data: [28, 48, 40, 19, 86, 27, 90]
      },
      {
        label: 'My Third dataset',
        fillColor: 'rgba(212,208,8,0.5)',
        strokeColor: 'rgba(212,208,8,0.8)',
        highlightFill: 'rgba(212,208,8,0.75)',
        highlightStroke: 'rgba(212,208,8,1)',
        data: [18, 98, 19, 55, 20, 34, 70]
      }
    ]
  };

  var $chart1 = $('#guideChart1');
  if($chart1[0]) {
    var ctx = $chart1[0].getContext('2d');
    new Chart(ctx).Bar(data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }

  $("#nav").tocify({
    selectors: ".guide-section-header, .guide-subsection-title",
    theme: 'bootstrap',
    scrollTo: 100
  });

})(jQuery);
<commit_msg>remove typeahead from docs example<commit_after>/* jshint browser:true */
/* global Chart */
(function($) {

  // Popovers and tooltips
  $('[data-toggle="popover"]').popover({
    html : true
  });

  $('[data-toggle="tooltip"]').tooltip();

  $('.guide-example').each(function() {

    var btn = '' +
      '
' +
      '
' +
        '<button class="btn btn-ghost btn-sm" data-toggle="code">' +
          'View Code ' +
        '</button>' +
      '
';

    $(this).append($(btn));
  });

  $('[data-toggle="code"]').click(function(e) {

    e.preventDefault();

    var target = $(this).parents('.guide-example').next('.language-markup');

    if(target.is(':visible')) {
      target.velocity("slideUp", { duration: 200 });
    }else {
      target.velocity("fadeIn", {
        duration: 300,
        display: 'block'
      });
    }

  });

  //filter popover
  $('[data-toggle="filter"]').popover({
    html : true,
    placement : $(this).attr('data-placement'),
    trigger : 'click',
    content: function() {
      var target = $(this).attr('data-target');
      var $target = $(target);
      return $target.html();
    }
  });

  $('.dropdown-menu a[data-toggle="tab"]').click(function (e) {
      e.stopPropagation();
      $(this).tab('show');
  });

  $('#datetimepicker6').datepicker({
      autoclose: true,
      clearBtn: true,
      todayBtn: true,
      todayHighlight: true,
      format: 'mm/dd/yyyy'
  });

  // Select2
  $('#single-select, #multiple-select').select2({
    placeholder: 'Select a State',
    allowClear: true
  }).on("select2-open", function () {

    var $this = $(this);
    if($this.parents('[class*="has-"]').length) {

      // get all CSS-classes from the element where we found "has-*" and collect them in an array
      var classNames = $this.parents('[class*="has-"]')[0].className.split(/\s+/);

      // go through the class names, find "has-"
      for(var i = 0; i < classNames.length; ++i) {
        if(classNames[i].match("has-")) {
          $('#select2-drop').addClass(classNames[i]);
        }
      }
    }
  });

  $('.select2, .select2-multiple').select2({
    allowClear: true
  });

  setInterval(function() {
    var indicators = $('.loading-indicator');
    for (var i = 0; i < indicators.length; i++) {
      $(indicators[i]).find('.loading-bullet')
        .velocity('transition.slideRightIn', { stagger: 250 })
        .delay(750)
        .velocity({ opacity: 0 }, 500);
    }
  }, 2000);

  var data = {
    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
    datasets: [
      {
        label: 'My First dataset',
        fillColor: 'rgba(0,154,87,0.5)',
        strokeColor: 'rgba(0,154,87,0.8)',
        highlightFill: 'rgba(0,154,87,0.75)',
        highlightStroke: 'rgba(0,154,87,1)',
        data: [65, 59, 80, 81, 56, 55, 40]
      },
      {
        label: 'My Second dataset',
        fillColor: 'rgba(0,147,232,0.5)',
        strokeColor: 'rgba(0,147,232,0.8)',
        highlightFill: 'rgba(0,147,232,0.75)',
        highlightStroke: 'rgba(0,147,232,1)',
        data: [28, 48, 40, 19, 86, 27, 90]
      },
      {
        label: 'My Third dataset',
        fillColor: 'rgba(212,208,8,0.5)',
        strokeColor: 'rgba(212,208,8,0.8)',
        highlightFill: 'rgba(212,208,8,0.75)',
        highlightStroke: 'rgba(212,208,8,1)',
        data: [18, 98, 19, 55, 20, 34, 70]
      }
    ]
  };

  var $chart1 = $('#guideChart1');
  if($chart1[0]) {
    var ctx = $chart1[0].getContext('2d');
    new Chart(ctx).Bar(data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }

  $("#nav").tocify({
    selectors: ".guide-section-header, .guide-subsection-title",
    theme: 'bootstrap',
    scrollTo: 100
  });

})(jQuery);
<|endoftext|>