<commit_before>(function ($) {
    $.fn.dnnModuleDragDrop = function (options) {

        var isEditMode = $('body').hasClass('dnnEditState');
        if (!isEditMode) {
            $(function () {
                $('.DNNEmptyPane').each(function () {
                    $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
                });
                $('.contentPane').each(function () {
                    // this special code is for you -- IE8
                    this.className = this.className;
                });
            });

            return this;
        }

        //Default settings
        var settings = {
            actionMenu: "div.actionMenu",
            cursor: "move",
            draggingHintText: "DraggingHintText",
            dragHintText: "DragHintText",
            dropOnEmpty: true,
            dropHintText: "DropHintText",
            dropTargetText: "DropModuleText"
        };

        settings = $.extend(settings, options || {});
        var $self = this;
        var paneModuleIndex;
        var modulePaneName;
        var tabId = settings.tabId;
        var mid;

        var $modules = $('.DnnModule');
        var $module;

        var getModuleId = function ($mod) {
            var result = $mod.attr("class").match(/DnnModule-([0-9]+)/);
            return (result && result.length === 2) ? result[1] : null;
        };

        var getModuleIndex = function (moduleId, $pane) {
            var index = -1;
            var modules = $pane.children(".DnnModule");
            for (var i = 0; i < modules.length; i++) {
                var module = modules[i];
                mid = getModuleId($(module));

                if (moduleId == parseInt(mid)) {
                    index = i;
                    break;
                }
            }
            return index;
        };

        var updateServer = function (moduleId, $pane, callback) {
            var order;
            var paneName = $pane.attr("id").substring(4);
            var index = getModuleIndex(moduleId, $pane);

            if (paneName !== modulePaneName) {
                //Moved to new Pane
                order = index * 2;
            } else {
                //Module moved within Pane
                if (index > paneModuleIndex) {
                    //Module moved down
                    order = (index + 1) * 2;
                } else {
                    //Module moved up
                    order = index * 2;
                }
            }

            var dataVar = {
                TabId: tabId,
                ModuleId: moduleId,
                Pane: paneName,
                ModuleOrder: order
            };

            var service = $.dnnSF();
            var serviceUrl = $.dnnSF().getServiceRoot("InternalServices") + "ModuleService/";
            $.ajax({
                url: serviceUrl + 'MoveModule',
                type: 'POST',
                data: dataVar,
                beforeSend: service.setModuleHeaders,
                success: function () {
                    if (typeof callback === "function") {
                        callback.call($pane);
                    } else {
                        window.location.reload();
                    }
                },
                error: function () {
                }
            });
        };

        for (var moduleNo = 0; moduleNo < $modules.length; moduleNo++) {
            $module = $($modules[moduleNo]);
            mid = getModuleId($module);
            if (!$module.hasClass("DnnModule-Admin")) {
                //Add a drag handle
                if ($module.find(".dnnDragHint").length === 0) {
                    $module.prepend("

");
                }

                //Add a drag hint
                $module.find(".dnnDragHint").dnnHelperTip({
                    helpContent: settings.dragHintText,
                    holderId: "ModuleDragToolTip-" + mid
                });
            }
        }

        //call jQuery UI Sortable plugin
        var originalPane = null;
        var allDnnSortableEmpty = true;
        $('.dnnSortable').each(function (n, v) {
            if (!$.trim($(v).html()).length) {
                return true;
            }
            else {
                allDnnSortableEmpty = false;
                return false;
            }
        });
        if (allDnnSortableEmpty) {

            $(function () {
                $('.DNNEmptyPane').each(function () {
                    $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
                });
                $('.contentPane').each(function () {
                    // this special code is for you -- IE8
                    this.className = this.className;
                });
            });

            $self.droppable({
                tolerance: "pointer",
                /*hoverClass: 'dnnDropTarget',*/
                over: function (event, ui) {
                    $(this).append("

" + settings.dropTargetText + "(" + $(this).attr("id").substring(4) + ")" + "

");
                },
                out: function (event, ui) {
                    $(this).empty();
                },
                drop: function (event, ui) {
                    // add module
                    var dropItem = ui.draggable;
                    var pane = $(this).empty();
                    var order = 0;
                    var paneName = pane.attr("id").substring(4);
                    dropItem.remove();
                    if (dnn.controlBar) {
                        dnn.controlBar.addModule(dnn.controlBar.dragdropModule + '',
                            dnn.controlBar.dragdropPage,
                            paneName,
                            '-1',
                            order + '',
                            dnn.controlBar.dragdropVisibility + '',
                            dnn.controlBar.dragdropAddExistingModule + '',
                            dnn.controlBar.dragdropCopyModule + '');
                    }
                }
            });
            return $self;
        }

        $('div.dnnDragHint').mousedown(function () {
            $('.DNNEmptyPane').each(function () {
                $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
            });
            $('.contentPane').each(function () {
                // this special code is for you -- IE8
                this.className = this.className;
            });

        }).mouseup(function () {
            $('.dnnDropEmptyPanes').each(function () {
                $(this).removeClass('dnnDropEmptyPanes').addClass('DNNEmptyPane');
            });
            $('.contentPane').each(function () {
                // this special code is for you -- IE8
                this.className = this.className;
            });
        });

        $self.sortable({
            connectWith: ".dnnSortable",
            dropOnEmpty: settings.dropOnEmpty,
            cursor: settings.cursor,
            cursorAt: { left: 10, top: 30 },
            handle: "div.dnnDragHint",
            placeholder: "dnnDropTarget",
            tolerance: "pointer",
            helper: function (event, ui) {

                var dragTip = $('

');
                var title = $('span.Head', ui).html();
                if (!title)
                    title = "The Dragging Module";

                dragTip.html(title);
                $('body').append(dragTip);
                return dragTip;
            },

            start: function (event, ui) {
                var $pane = ui.item.parent();
                originalPane = $pane;

                modulePaneName = $pane.attr("id").substring(4);
                mid = getModuleId(ui.item);
                paneModuleIndex = getModuleIndex(mid, $pane);

                //Add drop target text
                var $dropTarget = $(".dnnDropTarget");
                $dropTarget.append("
" + settings.dropTargetText + "(" + modulePaneName + ")" + "
");

                $(settings.actionMenu).hide();
            },

            over: function (event, ui) {
                //Add drop target text
                var $dropTarget = $(".dnnDropTarget");
                $dropTarget.empty().append("
" + settings.dropTargetText + "(" + $(this).attr("id").substring(4) + ")" + "
");
            },

            stop: function (event, ui, callback) {
                var dropItem = ui.item;
                if (dnn.controlBar && dropItem.hasClass('ControlBar_ModuleDiv')) {
                    // add module
                	var pane = ui.item.parent();
                    var order = -1;
                    var paneName = pane.attr("id").substring(4);
	                if ($('div.DnnModule', pane).length > 0) {
		                var modules = $('div.DnnModule, div.ControlBar_ModuleDiv', pane);
		                for (var i = 0; i < modules.length; i++) {
			                var module = modules.get(i);
			                if ($(module).hasClass('ControlBar_ModuleDiv')) {
				                order = i;
			                }
		                }
	                }
	                dropItem.remove();
                    dnn.controlBar.addModule(dnn.controlBar.dragdropModule + '',
                        dnn.controlBar.dragdropPage,
                        paneName,
                        '-1',
                        order + '',
                        dnn.controlBar.dragdropVisibility + '',
                        dnn.controlBar.dragdropAddExistingModule + '',
                        dnn.controlBar.dragdropCopyModule + '');

                } else {
                    // move module
                    mid = getModuleId(dropItem);
                    updateServer(mid, dropItem.parent(), callback);
                    $(settings.actionMenu).show();

                    //remove the empty pane holder class for current pane
                    dropItem.parent().removeClass("dnnDropEmptyPanes");
                    // if original pane is empty, add dnnemptypane class
                    if (originalPane && $('div', originalPane).length === 0)
                        originalPane.addClass('dnnDropEmptyPanes');

                    if (!callback) {
                        // show animation
                        dropItem.css('background-color', '#fffacd');
                        setTimeout(function() {
                            dropItem.css('background', '#fffff0');
                            setTimeout(function() {
                                dropItem.css('background', 'transparent');
                            }, 300);
                        }, 2500);
                    }

                    $("div[data-tipholder=\"" + "ModuleDragToolTip-" + mid + "\"] .dnnHelpText").text(settings.dragHintText);

                    $('.dnnDropEmptyPanes').each(function () {
                        $(this).removeClass('dnnDropEmptyPanes').addClass('DNNEmptyPane');
                    });
                    $('.contentPane').each(function () {
                        // this special code is for you -- IE8
                        this.className = this.className;
                    });

                    //fire window resize to reposition action menus
                    $(window).resize();
                }
            }
        });

        return $self;
    };
})(jQuery);<commit_msg>Fixed issue where dragdrop fails for modules with friendlyname starting with number<commit_after>(function ($) {
    $.fn.dnnModuleDragDrop = function (options) {

        var isEditMode = $('body').hasClass('dnnEditState');
        if (!isEditMode) {
            $(function () {
                $('.DNNEmptyPane').each(function () {
                    $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
                });
                $('.contentPane').each(function () {
                    // this special code is for you -- IE8
                    this.className = this.className;
                });
            });

            return this;
        }

        //Default settings
        var settings = {
            actionMenu: "div.actionMenu",
            cursor: "move",
            draggingHintText: "DraggingHintText",
            dragHintText: "DragHintText",
            dropOnEmpty: true,
            dropHintText: "DropHintText",
            dropTargetText: "DropModuleText"
        };

        settings = $.extend(settings, options || {});
        var $self = this;
        var paneModuleIndex;
        var modulePaneName;
        var tabId = settings.tabId;
        var mid;

        var $modules = $('.DnnModule');
        var $module;

        var getModuleId = function ($mod) {
            var result = $mod.attr("class").match(/DnnModule-([0-9]+)(?:\W|$)/);
            return (result && result.length === 2) ? result[1] : null;
        };

        var getModuleIndex = function (moduleId, $pane) {
            var index = -1;
            var modules = $pane.children(".DnnModule");
            for (var i = 0; i < modules.length; i++) {
                var module = modules[i];
                mid = getModuleId($(module));

                if (moduleId == parseInt(mid)) {
                    index = i;
                    break;
                }
            }
            return index;
        };

        var updateServer = function (moduleId, $pane, callback) {
            var order;
            var paneName = $pane.attr("id").substring(4);
            var index = getModuleIndex(moduleId, $pane);

            if (paneName !== modulePaneName) {
                //Moved to new Pane
                order = index * 2;
            } else {
                //Module moved within Pane
                if (index > paneModuleIndex) {
                    //Module moved down
                    order = (index + 1) * 2;
                } else {
                    //Module moved up
                    order = index * 2;
                }
            }

            var dataVar = {
                TabId: tabId,
                ModuleId: moduleId,
                Pane: paneName,
                ModuleOrder: order
            };

            var service = $.dnnSF();
            var serviceUrl = $.dnnSF().getServiceRoot("InternalServices") + "ModuleService/";
            $.ajax({
                url: serviceUrl + 'MoveModule',
                type: 'POST',
                data: dataVar,
                beforeSend: service.setModuleHeaders,
                success: function () {
                    if (typeof callback === "function") {
                        callback.call($pane);
                    } else {
                        window.location.reload();
                    }
                },
                error: function () {
                }
            });
        };

        for (var moduleNo = 0; moduleNo < $modules.length; moduleNo++) {
            $module = $($modules[moduleNo]);
            mid = getModuleId($module);
            if (!$module.hasClass("DnnModule-Admin")) {
                //Add a drag handle
                if ($module.find(".dnnDragHint").length === 0) {
                    $module.prepend("

");
                }

                //Add a drag hint
                $module.find(".dnnDragHint").dnnHelperTip({
                    helpContent: settings.dragHintText,
                    holderId: "ModuleDragToolTip-" + mid
                });
            }
        }

        //call jQuery UI Sortable plugin
        var originalPane = null;
        var allDnnSortableEmpty = true;
        $('.dnnSortable').each(function (n, v) {
            if (!$.trim($(v).html()).length) {
                return true;
            }
            else {
                allDnnSortableEmpty = false;
                return false;
            }
        });
        if (allDnnSortableEmpty) {

            $(function () {
                $('.DNNEmptyPane').each(function () {
                    $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
                });
                $('.contentPane').each(function () {
                    // this special code is for you -- IE8
                    this.className = this.className;
                });
            });

            $self.droppable({
                tolerance: "pointer",
                /*hoverClass: 'dnnDropTarget',*/
                over: function (event, ui) {
                    $(this).append("

" + settings.dropTargetText + "(" + $(this).attr("id").substring(4) + ")" + "

");
                },
                out: function (event, ui) {
                    $(this).empty();
                },
                drop: function (event, ui) {
                    // add module
                    var dropItem = ui.draggable;
                    var pane = $(this).empty();
                    var order = 0;
                    var paneName = pane.attr("id").substring(4);
                    dropItem.remove();
                    if (dnn.controlBar) {
                        dnn.controlBar.addModule(dnn.controlBar.dragdropModule + '',
                            dnn.controlBar.dragdropPage,
                            paneName,
                            '-1',
                            order + '',
                            dnn.controlBar.dragdropVisibility + '',
                            dnn.controlBar.dragdropAddExistingModule + '',
                            dnn.controlBar.dragdropCopyModule + '');
                    }
                }
            });
            return $self;
        }

        $('div.dnnDragHint').mousedown(function () {
            $('.DNNEmptyPane').each(function () {
                $(this).removeClass('DNNEmptyPane').addClass('dnnDropEmptyPanes');
            });
            $('.contentPane').each(function () {
                // this special code is for you -- IE8
                this.className = this.className;
            });

        }).mouseup(function () {
            $('.dnnDropEmptyPanes').each(function () {
                $(this).removeClass('dnnDropEmptyPanes').addClass('DNNEmptyPane');
            });
            $('.contentPane').each(function () {
                // this special code is for you -- IE8
                this.className = this.className;
            });
        });

        $self.sortable({
            connectWith: ".dnnSortable",
            dropOnEmpty: settings.dropOnEmpty,
            cursor: settings.cursor,
            cursorAt: { left: 10, top: 30 },
            handle: "div.dnnDragHint",
            placeholder: "dnnDropTarget",
            tolerance: "pointer",
            helper: function (event, ui) {

                var dragTip = $('

');
                var title = $('span.Head', ui).html();
                if (!title)
                    title = "The Dragging Module";

                dragTip.html(title);
                $('body').append(dragTip);
                return dragTip;
            },

            start: function (event, ui) {
                var $pane = ui.item.parent();
                originalPane = $pane;

                modulePaneName = $pane.attr("id").substring(4);
                mid = getModuleId(ui.item);
                paneModuleIndex = getModuleIndex(mid, $pane);

                //Add drop target text
                var $dropTarget = $(".dnnDropTarget");
                $dropTarget.append("
" + settings.dropTargetText + "(" + modulePaneName + ")" + "
");

                $(settings.actionMenu).hide();
            },

            over: function (event, ui) {
                //Add drop target text
                var $dropTarget = $(".dnnDropTarget");
                $dropTarget.empty().append("
" + settings.dropTargetText + "(" + $(this).attr("id").substring(4) + ")" + "
");
            },

            stop: function (event, ui, callback) {
                var dropItem = ui.item;
                if (dnn.controlBar && dropItem.hasClass('ControlBar_ModuleDiv')) {
                    // add module
                	var pane = ui.item.parent();
                    var order = -1;
                    var paneName = pane.attr("id").substring(4);
	                if ($('div.DnnModule', pane).length > 0) {
		                var modules = $('div.DnnModule, div.ControlBar_ModuleDiv', pane);
		                for (var i = 0; i < modules.length; i++) {
			                var module = modules.get(i);
			                if ($(module).hasClass('ControlBar_ModuleDiv')) {
				                order = i;
			                }
		                }
	                }
	                dropItem.remove();
                    dnn.controlBar.addModule(dnn.controlBar.dragdropModule + '',
                        dnn.controlBar.dragdropPage,
                        paneName,
                        '-1',
                        order + '',
                        dnn.controlBar.dragdropVisibility + '',
                        dnn.controlBar.dragdropAddExistingModule + '',
                        dnn.controlBar.dragdropCopyModule + '');

                } else {
                    // move module
                    mid = getModuleId(dropItem);
                    updateServer(mid, dropItem.parent(), callback);
                    $(settings.actionMenu).show();

                    //remove the empty pane holder class for current pane
                    dropItem.parent().removeClass("dnnDropEmptyPanes");
                    // if original pane is empty, add dnnemptypane class
                    if (originalPane && $('div', originalPane).length === 0)
                        originalPane.addClass('dnnDropEmptyPanes');

                    if (!callback) {
                        // show animation
                        dropItem.css('background-color', '#fffacd');
                        setTimeout(function() {
                            dropItem.css('background', '#fffff0');
                            setTimeout(function() {
                                dropItem.css('background', 'transparent');
                            }, 300);
                        }, 2500);
                    }

                    $("div[data-tipholder=\"" + "ModuleDragToolTip-" + mid + "\"] .dnnHelpText").text(settings.dragHintText);

                    $('.dnnDropEmptyPanes').each(function () {
                        $(this).removeClass('dnnDropEmptyPanes').addClass('DNNEmptyPane');
                    });
                    $('.contentPane').each(function () {
                        // this special code is for you -- IE8
                        this.className = this.className;
                    });

                    //fire window resize to reposition action menus
                    $(window).resize();
                }
            }
        });

        return $self;
    };
})(jQuery);<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'

import SuccessIcon from 'react-icons/lib/fa/check'
import FailIcon from 'react-icons/lib/fa/close'

import Link from '../link'

const Header = ({ catalog, status, t }) => (

      {catalog.name}
      {status === 'successful' ? (

          <SuccessIcon style={{ verticalAlign: -2 }} /> {t('harvest.status.successful')}

      ) : (

          <FailIcon style={{ verticalAlign: -2 }} /> {t('harvest.status.failed')}

      )}

    <Link href={`/catalog?cid=${catalog._id}`} as={`/catalogs/${catalog._id}`} prefetch>

        {t('harvest.header.backToCatalog')}

    </Link>

)

Header.propTypes = {
  catalog: PropTypes.shape({
    _id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired
  }).isRequired,

  status: PropTypes.oneOf([
    'successful',
    'failed'
  ]).isRequired,

  t: PropTypes.func.isRequired
}

export default translate('catalogs')(Header)
<commit_msg>Move badge down on small devices<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'

import SuccessIcon from 'react-icons/lib/fa/check'
import FailIcon from 'react-icons/lib/fa/close'

import Link from '../link'

const Header = ({ catalog, status, t }) => (

      {catalog.name}
      {status === 'successful' ? (

          <SuccessIcon style={{ verticalAlign: -2 }} /> {t('harvest.status.successful')}

      ) : (

          <FailIcon style={{ verticalAlign: -2 }} /> {t('harvest.status.failed')}

      )}

    <Link href={`/catalog?cid=${catalog._id}`} as={`/catalogs/${catalog._id}`} prefetch>

        {t('harvest.header.backToCatalog')}

    </Link>

)

Header.propTypes = {
  catalog: PropTypes.shape({
    _id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired
  }).isRequired,

  status: PropTypes.oneOf([
    'successful',
    'failed'
  ]).isRequired,

  t: PropTypes.func.isRequired
}

export default translate('catalogs')(Header)
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Carousel from './Carousel';
import CarouselItem from './CarouselItem';
import CarouselControl from './CarouselControl';
import CarouselIndicators from './CarouselIndicators';
import CarouselCaption from './CarouselCaption';

const propTypes = {
  items: PropTypes.array.isRequired,
  indicators: PropTypes.bool,
  controls: PropTypes.bool,
  autoPlay: PropTypes.bool,
  activeIndex: PropTypes.number,
  next: PropTypes.func,
  previous: PropTypes.func,
  goToIndex: PropTypes.func,
};

class UncontrolledCarousel extends Component {
  constructor(props) {
    super(props);
    this.animating = false;
    this.state = { activeIndex: 0 };
    this.next = this.next.bind(this);
    this.previous = this.previous.bind(this);
    this.goToIndex = this.goToIndex.bind(this);
    this.onExiting = this.onExiting.bind(this);
    this.onExited = this.onExited.bind(this);
  }

  onExiting() {
    this.animating = true;
  }

  onExited() {
    this.animating = false;
  }

  next() {
    if (this.animating) return;
    const nextIndex = this.state.activeIndex === this.props.items.length - 1 ? 0 : this.state.activeIndex + 1;
    this.setState({ activeIndex: nextIndex });
  }

  previous() {
    if (this.animating) return;
    const nextIndex = this.state.activeIndex === 0 ? this.props.items.length - 1 : this.state.activeIndex - 1;
    this.setState({ activeIndex: nextIndex });
  }

  goToIndex(newIndex) {
    if (this.animating) return;
    this.setState({ activeIndex: newIndex });
  }

  render() {
    const { autoPlay, indicators, controls, items, goToIndex, ...props } = this.props;
    const { activeIndex } = this.state;

    const slides = items.map((item) => {
      return (
        <CarouselItem
          onExiting={this.onExiting}
          onExited={this.onExited}
          key={item.src}
          src={item.src}
          altText={item.altText}
        >
          <CarouselCaption captionText={item.caption} captionHeader={item.caption} />
        </CarouselItem>
      );
    });

    return (
      <Carousel
        activeIndex={activeIndex}
        next={this.next}
        previous={this.previous}
        ride={autoPlay && 'carousel'}
        {...props}
      >
        {indicators && <CarouselIndicators
          items={items}
          activeIndex={props.activeIndex || activeIndex}
          onClickHandler={goToIndex || this.goToIndex}
        />}
        {slides}
        {controls && <CarouselControl
          direction="prev"
          directionText="Previous"
          onClickHandler={props.previous || this.previous}
        />}
        {controls && <CarouselControl
          direction="next"
          directionText="Next"
          onClickHandler={props.next || this.next}
        />}
      </Carousel>
    );
  }
}

UncontrolledCarousel.propTypes = propTypes;
UncontrolledCarousel.defaultProps = {
  controls: true,
  indicators: true,
  autoPlay: true,
};

export default UncontrolledCarousel;
<commit_msg>fix(UncontrolledCarousel): fix autoPlay={false} (#654)<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Carousel from './Carousel';
import CarouselItem from './CarouselItem';
import CarouselControl from './CarouselControl';
import CarouselIndicators from './CarouselIndicators';
import CarouselCaption from './CarouselCaption';

const propTypes = {
  items: PropTypes.array.isRequired,
  indicators: PropTypes.bool,
  controls: PropTypes.bool,
  autoPlay: PropTypes.bool,
  activeIndex: PropTypes.number,
  next: PropTypes.func,
  previous: PropTypes.func,
  goToIndex: PropTypes.func,
};

class UncontrolledCarousel extends Component {
  constructor(props) {
    super(props);
    this.animating = false;
    this.state = { activeIndex: 0 };
    this.next = this.next.bind(this);
    this.previous = this.previous.bind(this);
    this.goToIndex = this.goToIndex.bind(this);
    this.onExiting = this.onExiting.bind(this);
    this.onExited = this.onExited.bind(this);
  }

  onExiting() {
    this.animating = true;
  }

  onExited() {
    this.animating = false;
  }

  next() {
    if (this.animating) return;
    const nextIndex = this.state.activeIndex === this.props.items.length - 1 ? 0 : this.state.activeIndex + 1;
    this.setState({ activeIndex: nextIndex });
  }

  previous() {
    if (this.animating) return;
    const nextIndex = this.state.activeIndex === 0 ? this.props.items.length - 1 : this.state.activeIndex - 1;
    this.setState({ activeIndex: nextIndex });
  }

  goToIndex(newIndex) {
    if (this.animating) return;
    this.setState({ activeIndex: newIndex });
  }

  render() {
    const { autoPlay, indicators, controls, items, goToIndex, ...props } = this.props;
    const { activeIndex } = this.state;

    const slides = items.map((item) => {
      return (
        <CarouselItem
          onExiting={this.onExiting}
          onExited={this.onExited}
          key={item.src}
          src={item.src}
          altText={item.altText}
        >
          <CarouselCaption captionText={item.caption} captionHeader={item.caption} />
        </CarouselItem>
      );
    });

    return (
      <Carousel
        activeIndex={activeIndex}
        next={this.next}
        previous={this.previous}
        ride={autoPlay ? 'carousel' : undefined}
        {...props}
      >
        {indicators && <CarouselIndicators
          items={items}
          activeIndex={props.activeIndex || activeIndex}
          onClickHandler={goToIndex || this.goToIndex}
        />}
        {slides}
        {controls && <CarouselControl
          direction="prev"
          directionText="Previous"
          onClickHandler={props.previous || this.previous}
        />}
        {controls && <CarouselControl
          direction="next"
          directionText="Next"
          onClickHandler={props.next || this.next}
        />}
      </Carousel>
    );
  }
}

UncontrolledCarousel.propTypes = propTypes;
UncontrolledCarousel.defaultProps = {
  controls: true,
  indicators: true,
  autoPlay: true,
};

export default UncontrolledCarousel;
<|endoftext|>


<commit_before>define(function() {
  "use strict";

  var $ = require("jquery");

  var $sources = $(".sources") || null;

  if ($sources) {
    var $list = $sources.find('ul');

    // Hide the fact sources list if present.
    $list.hide();

    // Toggle visibility of fact sources.
    $(".js-toggle-sources").on("click", function() {

      // Toggle visibility of fact sources list.
      $list.slideToggle();

    });
  }

});
<commit_msg>Use double-quotes for strings.<commit_after>define(function() {
  "use strict";

  var $ = require("jquery");

  var $sources = $(".sources") || null;

  if ($sources) {
    var $list = $sources.find("ul");

    // Hide the fact sources list if present.
    $list.hide();

    // Toggle visibility of fact sources.
    $(".js-toggle-sources").on("click", function() {

      // Toggle visibility of fact sources list.
      $list.slideToggle();

    });
  }

});
<|endoftext|>


<commit_before>var fs = require('fs');

function reloadCustomAvatars() {
	var path = require('path');
	var newCustomAvatars = {};
	fs.readdirSync('./config/avatars').forEach(function (file) {
		var ext = path.extname(file);
		if (ext !== '.png' && ext !== '.gif')
			return;

		var user = toId(path.basename(file, ext));
		newCustomAvatars[user] = file;
		delete Config.customavatars[user];
	});

	// Make sure the manually entered avatars exist
	for (var a in Config.customavatars)
		if (typeof Config.customavatars[a] === 'number')
			newCustomAvatars[a] = Config.customavatars[a];
		else
			fs.exists('./config/avatars/' + Config.customavatars[a], function (user, file, isExists) {
				if (isExists)
					Config.customavatars[user] = file;
			}.bind(null, a, Config.customavatars[a]));

	Config.customavatars = newCustomAvatars;
}
reloadCustomAvatars();

if (Config.watchConfig) {
	fs.watchFile('./config/config.js', function (curr, prev) {
		if (curr.mtime <= prev.mtime) return;
		reloadCustomAvatars();
	});
}

const script = function () {
/*
	FILENAME=`mktemp`
	function cleanup {
		rm -f $FILENAME
	}
	trap cleanup EXIT

	set -xe

	timeout 10 wget "$1" -nv -O $FILENAME

	FRAMES=`identify $FILENAME | wc -l`
	if [ $FRAMES -gt 1 ]; then
		EXT=".gif"
	else
		EXT=".png"
	fi

	timeout 10 convert $FILENAME -layers TrimBounds -coalesce -adaptive-resize 80x80\> -background transparent -gravity center -extent 80x80 "$2$EXT"
*/
}.toString().match(/[^]*\/\*([^]*)\*\//)[1];

var pendingAdds = {};

exports.commands = {
	customavatars: 'customavatar',
	customavatar: function (target, room, user) {
		var parts = target.split(',');
		var cmd = parts[0].trim().toLowerCase();

		if (cmd in {'':1, show:1, view:1, display:1}) {
			var message = "";
			for (var a in Config.customavatars)
				message += "" + Tools.escapeHTML(a) + ": " + Tools.escapeHTML(Config.customavatars[a]) + "
";
			return this.sendReplyBox(message);
		}

		if (!this.can('mute') && !user.vip) return false;

		switch (cmd) {
			case 'set':
				var userid = toId(parts[1]);
				var targetUser = Users.getExact(userid);
				var avatar = parts.slice(2).join(',').trim();
				if (!this.can('customavatar') && user.vip && userid !== user.userid) return false;

				if (!userid) return this.sendReply("You didn't specify a user.");
				if (Config.customavatars[userid]) return this.sendReply(userid + " already has a custom avatar.");

				var hash = require('crypto').createHash('sha512').update(userid + '\u0000' + avatar).digest('hex').slice(0, 8);
				pendingAdds[hash] = {userid: userid, avatar: avatar};
				parts[1] = hash;

				if (!targetUser) {
					this.sendReply("Warning: " + userid + " is not online.");
					this.sendReply("If you want to continue, use: /customavatar forceset, " + hash);
					return;
				}

				/* falls through */
			case 'forceset':
				if (user.avatarCooldown && !this.can('customavatar')) {
					var milliseconds = (Date.now() - user.avatarCooldown);
					var seconds = ((milliseconds / 1000) % 60);
					var minutes = ((seconds / 60) % 60);
					var remainingTime = Math.round(seconds - (5 * 60));
					if (((Date.now() - user.avatarCooldown) <= 5 * 60 * 1000)) return this.sendReply("You must wait " + (remainingTime - remainingTime * 2) + " seconds before setting another avatar.");
				}
				user.avatarCooldown = Date.now();

				var hash = parts[1].trim();
				if (!pendingAdds[hash]) return this.sendReply("Invalid hash.");

				var userid = pendingAdds[hash].userid;
				var avatar = pendingAdds[hash].avatar;
				delete pendingAdds[hash];

				require('child_process').execFile('bash', ['-c', script, '-', avatar, './config/avatars/' + userid], function (e, out, err) {
					if (e) {
						this.sendReply(userid + "'s custom avatar failed to be set. Script output:");
						(out + err).split('\n').forEach(this.sendReply.bind(this));
						return;
					}

					reloadCustomAvatars();

					var targetUser = Users.getExact(userid);
					if (targetUser) targetUser.avatar = Config.customavatars[userid];

					this.sendReply(userid + "'s custom avatar has been set.");
					room.update();
				}.bind(this));
				break;

			case 'delete':
				var userid = toId(parts[1]);
				if (!this.can('customavatar') && user.vip && userid !== user.userid) return false;
				if (!Config.customavatars[userid]) return this.sendReply(userid + " does not have a custom avatar.");

				if (Config.customavatars[userid].toString().split('.').slice(0, -1).join('.') !== userid)
					return this.sendReply(userid + "'s custom avatar (" + Config.customavatars[userid] + ") cannot be removed with this script.");

				var targetUser = Users.getExact(userid);
				if (targetUser) targetUser.avatar = 1;

				fs.unlink('./config/avatars/' + Config.customavatars[userid], function (e) {
					if (e) return this.sendReply(userid + "'s custom avatar (" + Config.customavatars[userid] + ") could not be removed: " + e.toString());

					delete Config.customavatars[userid];
					this.sendReply(userid + "'s custom avatar removed successfully");
				}.bind(this));
				break;

			default:
				return this.sendReply("Invalid command. Valid commands are `/customavatar set, user, avatar` and `/customavatar delete, user`.");
		}
	}
};
<commit_msg>Give VIP access to /customavatar<commit_after>var fs = require('fs');

function reloadCustomAvatars() {
	var path = require('path');
	var newCustomAvatars = {};
	fs.readdirSync('./config/avatars').forEach(function (file) {
		var ext = path.extname(file);
		if (ext !== '.png' && ext !== '.gif')
			return;

		var user = toId(path.basename(file, ext));
		newCustomAvatars[user] = file;
		delete Config.customavatars[user];
	});

	// Make sure the manually entered avatars exist
	for (var a in Config.customavatars)
		if (typeof Config.customavatars[a] === 'number')
			newCustomAvatars[a] = Config.customavatars[a];
		else
			fs.exists('./config/avatars/' + Config.customavatars[a], function (user, file, isExists) {
				if (isExists)
					Config.customavatars[user] = file;
			}.bind(null, a, Config.customavatars[a]));

	Config.customavatars = newCustomAvatars;
}
reloadCustomAvatars();

if (Config.watchConfig) {
	fs.watchFile('./config/config.js', function (curr, prev) {
		if (curr.mtime <= prev.mtime) return;
		reloadCustomAvatars();
	});
}

const script = function () {
/*
	FILENAME=`mktemp`
	function cleanup {
		rm -f $FILENAME
	}
	trap cleanup EXIT

	set -xe

	timeout 10 wget "$1" -nv -O $FILENAME

	FRAMES=`identify $FILENAME | wc -l`
	if [ $FRAMES -gt 1 ]; then
		EXT=".gif"
	else
		EXT=".png"
	fi

	timeout 10 convert $FILENAME -layers TrimBounds -coalesce -adaptive-resize 80x80\> -background transparent -gravity center -extent 80x80 "$2$EXT"
*/
}.toString().match(/[^]*\/\*([^]*)\*\//)[1];

var pendingAdds = {};

exports.commands = {
	customavatars: 'customavatar',
	customavatar: function (target, room, user) {
		var parts = target.split(',');
		var cmd = parts[0].trim().toLowerCase();

		if (cmd in {'':1, show:1, view:1, display:1}) {
			var message = "";
			for (var a in Config.customavatars)
				message += "" + Tools.escapeHTML(a) + ": " + Tools.escapeHTML(Config.customavatars[a]) + "
";
			return this.sendReplyBox(message);
		}

		if (!this.can('mute') && !this.can('vip')) return false;

		switch (cmd) {
			case 'set':
				var userid = toId(parts[1]);
				var targetUser = Users.getExact(userid);
				var avatar = parts.slice(2).join(',').trim();
				if (!this.can('customavatar') && this.can('vip') && userid !== user.userid) return false;

				if (!userid) return this.sendReply("You didn't specify a user.");
				if (Config.customavatars[userid]) return this.sendReply(userid + " already has a custom avatar.");

				var hash = require('crypto').createHash('sha512').update(userid + '\u0000' + avatar).digest('hex').slice(0, 8);
				pendingAdds[hash] = {userid: userid, avatar: avatar};
				parts[1] = hash;

				if (!targetUser) {
					this.sendReply("Warning: " + userid + " is not online.");
					this.sendReply("If you want to continue, use: /customavatar forceset, " + hash);
					return;
				}

				/* falls through */
			case 'forceset':
				if (user.avatarCooldown && !this.can('customavatar')) {
					var milliseconds = (Date.now() - user.avatarCooldown);
					var seconds = ((milliseconds / 1000) % 60);
					var minutes = ((seconds / 60) % 60);
					var remainingTime = Math.round(seconds - (5 * 60));
					if (((Date.now() - user.avatarCooldown) <= 5 * 60 * 1000)) return this.sendReply("You must wait " + (remainingTime - remainingTime * 2) + " seconds before setting another avatar.");
				}
				user.avatarCooldown = Date.now();

				var hash = parts[1].trim();
				if (!pendingAdds[hash]) return this.sendReply("Invalid hash.");

				var userid = pendingAdds[hash].userid;
				var avatar = pendingAdds[hash].avatar;
				delete pendingAdds[hash];

				require('child_process').execFile('bash', ['-c', script, '-', avatar, './config/avatars/' + userid], function (e, out, err) {
					if (e) {
						this.sendReply(userid + "'s custom avatar failed to be set. Script output:");
						(out + err).split('\n').forEach(this.sendReply.bind(this));
						return;
					}

					reloadCustomAvatars();

					var targetUser = Users.getExact(userid);
					if (targetUser) targetUser.avatar = Config.customavatars[userid];

					this.sendReply(userid + "'s custom avatar has been set.");
					room.update();
				}.bind(this));
				break;

			case 'delete':
				var userid = toId(parts[1]);
				if (!this.can('customavatar') && this.can('vip') && userid !== user.userid) return false;
				if (!Config.customavatars[userid]) return this.sendReply(userid + " does not have a custom avatar.");

				if (Config.customavatars[userid].toString().split('.').slice(0, -1).join('.') !== userid)
					return this.sendReply(userid + "'s custom avatar (" + Config.customavatars[userid] + ") cannot be removed with this script.");

				var targetUser = Users.getExact(userid);
				if (targetUser) targetUser.avatar = 1;

				fs.unlink('./config/avatars/' + Config.customavatars[userid], function (e) {
					if (e) return this.sendReply(userid + "'s custom avatar (" + Config.customavatars[userid] + ") could not be removed: " + e.toString());

					delete Config.customavatars[userid];
					this.sendReply(userid + "'s custom avatar removed successfully");
				}.bind(this));
				break;

			default:
				return this.sendReply("Invalid command. Valid commands are `/customavatar set, user, avatar` and `/customavatar delete, user`.");
		}
	}
};
<|endoftext|>


<commit_before>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import('resource://greasemonkey/util.js');

const Cc = Components.classes;
const Ci = Components.interfaces;
const schemeName = 'greasemonkey-script';
const ioService = Cc['@mozilla.org/network/io-service;1']
    .getService(Ci.nsIIOService);

function ScriptChannel(aUri, aScript) {
  // nsIRequest
  this.loadFlags = 0;
  this.loadGroup = null;
  this.name = aUri.spec;
  this.status = 200;

  this.content = '';
  if (aScript) {
    this.content = GM_util.getScriptSource(aScript);
  } else {
    this.status = 404;
  }

  if (aUri.spec.match(/\?.*wrapped=1/)) {
    this.content = GM_util.anonWrap(this.content);
  }

  // nsIChannel
  this.contentCharset = 'utf-8';
  this.contentLength = this.content.length;
  this.contentType = 'application/javascript';
  this.notificationCallbacks = null;
  this.originalURI = aUri;
  this.owner = null;
  this.securityInfo = null;
  this.URI = aUri;

  this.pipe = Cc['@mozilla.org/pipe;1'].createInstance(Ci.nsIPipe);
  this.pipe.init(true, true, 0, 0, null);

  var inputStreamChannel = Cc['@mozilla.org/network/input-stream-channel;1']
      .createInstance(Ci.nsIInputStreamChannel);
  inputStreamChannel.setURI(aUri);
  inputStreamChannel.contentStream = this.pipe.inputStream;
  this.channel = inputStreamChannel.QueryInterface(Ci.nsIChannel);
}

// nsIChannel
ScriptChannel.prototype.asyncOpen = function(aListener, aContext) {
  this.channel.asyncOpen(aListener, aContext);
  this.pipe.outputStream.write(this.content, this.content.length);
  this.pipe.outputStream.close();
};

function ScriptProtocol() {}

// XPCOMUtils generation
ScriptProtocol.prototype.classDescription =
    'Protocol handler for greasemonkey-script:';
ScriptProtocol.prototype.classID =
    Components.ID('{20d898f3-2fb8-4b3a-b8c7-7ad6c2c48598}');
ScriptProtocol.prototype.contractID =
    '@mozilla.org/network/protocol;1?name=' + schemeName;
ScriptProtocol.prototype.QueryInterface = XPCOMUtils.generateQI([
    Components.interfaces.nsIProtocolHandler,
    Components.interfaces.nsISupports,
    ]);

// nsIProtocolHandler
ScriptProtocol.prototype.scheme = schemeName;
ScriptProtocol.prototype.defaultPort = -1;
ScriptProtocol.prototype.protocolFlags = 0
    | Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT
    | Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE
    | Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE
    | Ci.nsIProtocolHandler.URI_NOAUTH
    | Ci.nsIProtocolHandler.URI_NON_PERSISTABLE
    | Ci.nsIProtocolHandler.URI_NORELATIVE
    ;

// nsIProtocolHandler
ScriptProtocol.prototype.allowPort = function(aPort, aScheme) {
  return false;
};

// nsIProtocolHandler
ScriptProtocol.prototype.newURI = function(aSpec, aCharset, aBaseUri) {
  var uri = Cc['@mozilla.org/network/simple-uri;1'].createInstance(Ci.nsIURI);
  uri.spec = aSpec;
  return uri;
};

// nsIProtocolHandler
ScriptProtocol.prototype.newChannel = function(aUri) {
  var m = aUri.spec.match(/greasemonkey-script:([-0-9a-f]+)\/(.*)/);
  var script = GM_util.getService().config.getMatchingScripts(function(script) {
    return script.uuid == m[1];
  })[0];
  if (aUri.spec.match(/\.user\.js($|\?)/)) {
    return new ScriptChannel(aUri, script);
  } else if (script) {
    for (var i = 0, resource = null; resource = script.resources[i]; i++) {
      if (resource.name == m[2]) {
        return ioService.newChannelFromURI(
            GM_util.getUriFromFile(resource.file));
      }
    }
  } else {
    return new ScriptChannel(aUri, script);
  }

  // Default fall-through case, send a 404.  (By using a script channel
  // w/out any script object.)(
  return new ScriptChannel(aUri);
};

const components = [ScriptProtocol];
if ("generateNSGetFactory" in XPCOMUtils) {
  var NSGetFactory = XPCOMUtils.generateNSGetFactory(components); // Gecko 2.0+
} else {
  var NSGetModule = XPCOMUtils.generateNSGetModule(components); // Gecko 1.9.x
}
<commit_msg>Remove ScriptChannel.<commit_after>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import('resource://greasemonkey/util.js');

const Cc = Components.classes;
const Ci = Components.interfaces;
const schemeName = 'greasemonkey-script';
const ioService = Cc['@mozilla.org/network/io-service;1']
    .getService(Ci.nsIIOService);

function DummyChannel(aUri, aScript) {
  // nsIRequest
  this.loadFlags = 0;
  this.loadGroup = null;
  this.name = aUri.spec;
  this.status = 404;
  this.content = '';

  // nsIChannel
  this.contentCharset = 'utf-8';
  this.contentLength = this.content.length;
  this.contentType = 'application/javascript';
  this.notificationCallbacks = null;
  this.originalURI = aUri;
  this.owner = null;
  this.securityInfo = null;
  this.URI = aUri;
}

// nsIChannel
DummyChannel.prototype.asyncOpen = function(aListener, aContext) { };

function ScriptProtocol() {}

// XPCOMUtils generation
ScriptProtocol.prototype.classDescription =
    'Protocol handler for greasemonkey-script:';
ScriptProtocol.prototype.classID =
    Components.ID('{20d898f3-2fb8-4b3a-b8c7-7ad6c2c48598}');
ScriptProtocol.prototype.contractID =
    '@mozilla.org/network/protocol;1?name=' + schemeName;
ScriptProtocol.prototype.QueryInterface = XPCOMUtils.generateQI([
    Components.interfaces.nsIProtocolHandler,
    Components.interfaces.nsISupports,
    ]);

// nsIProtocolHandler
ScriptProtocol.prototype.scheme = schemeName;
ScriptProtocol.prototype.defaultPort = -1;
ScriptProtocol.prototype.protocolFlags = 0
    | Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT
    | Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE
    | Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE
    | Ci.nsIProtocolHandler.URI_NOAUTH
    | Ci.nsIProtocolHandler.URI_NON_PERSISTABLE
    | Ci.nsIProtocolHandler.URI_NORELATIVE
    ;

// nsIProtocolHandler
ScriptProtocol.prototype.allowPort = function(aPort, aScheme) {
  return false;
};

// nsIProtocolHandler
ScriptProtocol.prototype.newURI = function(aSpec, aCharset, aBaseUri) {
  var uri = Cc['@mozilla.org/network/simple-uri;1'].createInstance(Ci.nsIURI);
  uri.spec = aSpec;
  return uri;
};

// nsIProtocolHandler
ScriptProtocol.prototype.newChannel = function(aUri) {
  var m = aUri.spec.match(/greasemonkey-script:([-0-9a-f]+)\/(.*)/);

  // Incomplete URI, send a 404.
  if (!m) return new DummyChannel(aUri);

  var script = GM_util.getService().config.getMatchingScripts(function(script) {
    return script.uuid == m[1];
  })[0];

  if (script) {
    for (var i = 0, resource = null; resource = script.resources[i]; i++) {
      if (resource.name == m[2]) {
        return ioService.newChannelFromURI(
            GM_util.getUriFromFile(resource.file));
      }
    }
  }

  // Default fall-through case, send a 404.
  return new DummyChannel(aUri);
};

const components = [ScriptProtocol];
if ("generateNSGetFactory" in XPCOMUtils) {
  var NSGetFactory = XPCOMUtils.generateNSGetFactory(components); // Gecko 2.0+
} else {
  var NSGetModule = XPCOMUtils.generateNSGetModule(components); // Gecko 1.9.x
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Loader from 'react-loader';
import { connect } from 'react-redux';
import get from 'lodash/get';
import classNames from 'classnames';
import moment from 'moment';
import pick from 'lodash/pick';

import ReservationInfoModal from '../../shared/modals/reservation-info/ReservationInfoModalContainer';
import PageWrapper from '../PageWrapper';
import ReservationCancelModal from '../../shared/modals/reservation-cancel/ReservationCancelModalContainer';
import injectT from '../../i18n/injectT';
import userReservationsPageSelector from './userReservationsPageSelector';
import ReservationList from './reservation-list/ReservationListContainer';
import * as searchUtils from '../../../src/domain/search/utils';
import client from '../../../src/common/api/client';

const PAGE_SIZE = 10;
// We request past reservations from the API by using the start and end
// parameters. When using one of these parameters, you also have to use
// the other. To get past reservations we are using the below value for
// the start parameter, and current datetime for the end parameter.
const ARBITRARY_START_DATETIME = '2000-01-01T00:00';
const UPCOMING_PARAMETERS = ['ordering'];
const PAST_PARAMETERS = ['all', 'ordering', 'start', 'end'];
const initialModelState = Object.freeze({
  data: [],
  loading: false,
  error: null,
});
const TABS = Object.freeze({
  UPCOMING: 'upcoming',
  PAST: 'past',
});

class UnconnectedUserReservationsPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      upcomingReservation: {
        ...this.initialModelState,
        loading: true,
        count: 0,
      },
      pastReservation: {
        ...this.initialModelState,
        count: 0,
      },
      tab: TABS.UPCOMING,
    };
  }

  componentDidMount() {
    this.loadUpcomingReservations();
  }

  get initialModelState() {
    return initialModelState;
  }

  get isLoading() {
    const {
      upcomingReservation, pastReservation,
    } = this.state;

    return upcomingReservation.loading || pastReservation.loading;
  }

  get filters() {
    return searchUtils.getFiltersFromUrl(this.props.location, false);
  }

  get page() {
    const filterCache = this.filters;

    return filterCache && filterCache.page ? Number(filterCache.page) : 1;
  }

  get count() {
    if (this.tab === TABS.UPCOMING) {
      return this.state.upcomingReservation.count;
    }

    if (this.tab === TABS.PAST) {
      return this.state.pastReservation.count;
    }

    return 0;
  }

  get pages() {
    return Math.round(this.count / PAGE_SIZE);
  }

  get tab() {
    return this.state.tab;
  }

  get reservations() {
    if (this.tab === TABS.UPCOMING) {
      return this.state.upcomingReservation.data;
    }

    if (this.tab === TABS.PAST) {
      return this.state.pastReservation.data;
    }

    return [];
  }

  setModel = (name, data, cb) => {
    const currentState = get(this.state, name, {});

    this.setState({
      [name]: {
        ...currentState,
        ...data,
      },
    }, cb);
  }

  loadModel = (name, params, mapResponseToState, stateName) => {
    const nameInState = stateName || name;

    this.setModel(nameInState, {
      loading: true,
    });

    client.get(name, params)
      .then((response) => {
        const defaultNextState = {
          loading: false,
          data: get(response.data, 'results', []),
        };
        const customNextState = mapResponseToState ? mapResponseToState(response) : {};

        this.setModel(nameInState, {
          ...defaultNextState,
          ...customNextState,
        });
      });
  }

  fetchReservations = (namespace, getFilters) => {
    const filters = getFilters ? getFilters(this.filters) : this.filters;
    const params = {
      ...filters,
      // Ignore default date search parameter because this view is not
      // date specific.
      date: undefined,
      page_size: PAGE_SIZE,
      include: 'resource_detail',
      is_own: true,
    };

    this.loadModel('reservation', params, response => ({
      count: response.data.count,
    }), `${namespace}Reservation`);
  };

  loadUpcomingReservations = (getFilters) => {
    const getFilterWithDefaults = (defaultFilters) => {
      const filters = { ...defaultFilters, ordering: 'begin' };

      return getFilters ? getFilters(filters) : filters;
    };

    this.fetchReservations('upcoming', getFilterWithDefaults);
  }

  loadPastReservations = (getFilters) => {
    const getFilterWithDefaults = (defaultFilters) => {
      const now = moment().format('YYYY-MM-DD[T]HH:mmZZ');
      const filters = {
        ...defaultFilters,
        all: true,
        ordering: '-begin',
        // Note that using this method to fetch a reservation has a
        // weakness: it'll also list currently ongoing reservations. By
        // common heuristics these should not be considered to be in the
        // past, but I could not find a more efficient way to find past
        // reservations.
        start: moment(ARBITRARY_START_DATETIME, 'YYYY-MM-DD[T]HH:mm').format('YYYY-MM-DD[T]HH:mmZZ'),
        end: now,
      };

      return getFilters ? getFilters(filters) : filters;
    };

    this.fetchReservations('past', getFilterWithDefaults);
  }

  handlePageChange = (newPage) => {
    const { history } = this.props;
    const filters = this.filters;
    const nextFilters = { ...filters, page: newPage };

    history.push({
      search: searchUtils.getSearchFromFilters(nextFilters),
    });

    if (this.tab === TABS.UPCOMING) {
      this.loadUpcomingReservations(defaultFilters => ({ ...defaultFilters, ...nextFilters }));
    }

    if (this.tab === TABS.PAST) {
      this.loadPastReservations(defaultFilters => ({ ...defaultFilters, ...nextFilters }));
    }
  };

  handleTabChange = (tab) => {
    if (this.tab === tab) {
      return;
    }

    const { history } = this.props;
    // Reset pagination
    const nextFilters = { };

    history.push({
      search: searchUtils.getSearchFromFilters(nextFilters),
    });

    this.setState({ tab });

    if (tab === TABS.UPCOMING) {
      this.loadUpcomingReservations(filters => pick(filters, UPCOMING_PARAMETERS));
    }

    if (tab === TABS.PAST) {
      this.loadPastReservations(filters => pick(filters, PAST_PARAMETERS));
    }
  }

  render() {
    const {
      t,
    } = this.props;

    const upcomingReservationLoading = this.state.upcomingReservation.loading;
    const upcomingReservationCount = this.state.upcomingReservation.count;

    return (

        <PageWrapper
          className="app-UserReservationPage__wrapper"
          title={t('UserReservationsPage.title')}
          transparent={false}
        >

{t('UserReservationsPage.title')}

              <button
                aria-selected={this.tab === TABS.UPCOMING}
                className={classNames('app-UserReservationPage__tab', {
                  'app-UserReservationPage__tab--active': this.tab === TABS.UPCOMING,
                })}
                onClick={() => this.handleTabChange(TABS.UPCOMING)}
                role="tab"
                type="button"
              >
                {t('ReservationListContainer.comingReservations')}
                {' '}
                {!upcomingReservationLoading ? `(${upcomingReservationCount})` : ''}
              </button>
              <button
                aria-selected={this.tab === TABS.PAST}
                className={classNames('app-UserReservationPage__tab', {
                  'app-UserReservationPage__tab--active': this.tab === TABS.PAST,
                })}
                onClick={() => this.handleTabChange(TABS.PAST)}
                role="tab"
                type="button"
              >
                {t('ReservationListContainer.pastReservations')}
              </button>

            <Loader loaded={!this.isLoading}>
              {/* In order to avoid mounting multiple instances of the
                  same component, we change data instead of component
                  instance. */}
              <ReservationList
                loading={this.isLoading}
                onPageChange={this.handlePageChange}
                page={this.page}
                pages={this.pages}
                reservations={this.reservations}
              />
            </Loader>

          <ReservationCancelModal />
          <ReservationInfoModal />
        </PageWrapper>

    );
  }
}

UnconnectedUserReservationsPage.propTypes = {
  history: PropTypes.object,
  location: PropTypes.object,
  t: PropTypes.func.isRequired,
};
UnconnectedUserReservationsPage = injectT(UnconnectedUserReservationsPage);  // eslint-disable-line

export { UnconnectedUserReservationsPage };
export default connect(userReservationsPageSelector)(
  UnconnectedUserReservationsPage,
);
<commit_msg>Replace hard coded datetime format<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Loader from 'react-loader';
import { connect } from 'react-redux';
import get from 'lodash/get';
import classNames from 'classnames';
import moment from 'moment';
import pick from 'lodash/pick';

import ReservationInfoModal from '../../shared/modals/reservation-info/ReservationInfoModalContainer';
import PageWrapper from '../PageWrapper';
import ReservationCancelModal from '../../shared/modals/reservation-cancel/ReservationCancelModalContainer';
import injectT from '../../i18n/injectT';
import userReservationsPageSelector from './userReservationsPageSelector';
import ReservationList from './reservation-list/ReservationListContainer';
import * as searchUtils from '../../../src/domain/search/utils';
import client from '../../../src/common/api/client';
import constants from '../../constants/AppConstants';

const PAGE_SIZE = 10;
// We request past reservations from the API by using the start and end
// parameters. When using one of these parameters, you also have to use
// the other. To get past reservations we are using the below value for
// the start parameter, and current datetime for the end parameter.
const ARBITRARY_START_DATETIME = '2000-01-01T00:00';
const UPCOMING_PARAMETERS = ['ordering'];
const PAST_PARAMETERS = ['all', 'ordering', 'start', 'end'];
const initialModelState = Object.freeze({
  data: [],
  loading: false,
  error: null,
});
const TABS = Object.freeze({
  UPCOMING: 'upcoming',
  PAST: 'past',
});

class UnconnectedUserReservationsPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      upcomingReservation: {
        ...this.initialModelState,
        loading: true,
        count: 0,
      },
      pastReservation: {
        ...this.initialModelState,
        count: 0,
      },
      tab: TABS.UPCOMING,
    };
  }

  componentDidMount() {
    this.loadUpcomingReservations();
  }

  get initialModelState() {
    return initialModelState;
  }

  get isLoading() {
    const {
      upcomingReservation, pastReservation,
    } = this.state;

    return upcomingReservation.loading || pastReservation.loading;
  }

  get filters() {
    return searchUtils.getFiltersFromUrl(this.props.location, false);
  }

  get page() {
    const filterCache = this.filters;

    return filterCache && filterCache.page ? Number(filterCache.page) : 1;
  }

  get count() {
    if (this.tab === TABS.UPCOMING) {
      return this.state.upcomingReservation.count;
    }

    if (this.tab === TABS.PAST) {
      return this.state.pastReservation.count;
    }

    return 0;
  }

  get pages() {
    return Math.round(this.count / PAGE_SIZE);
  }

  get tab() {
    return this.state.tab;
  }

  get reservations() {
    if (this.tab === TABS.UPCOMING) {
      return this.state.upcomingReservation.data;
    }

    if (this.tab === TABS.PAST) {
      return this.state.pastReservation.data;
    }

    return [];
  }

  setModel = (name, data, cb) => {
    const currentState = get(this.state, name, {});

    this.setState({
      [name]: {
        ...currentState,
        ...data,
      },
    }, cb);
  }

  loadModel = (name, params, mapResponseToState, stateName) => {
    const nameInState = stateName || name;

    this.setModel(nameInState, {
      loading: true,
    });

    client.get(name, params)
      .then((response) => {
        const defaultNextState = {
          loading: false,
          data: get(response.data, 'results', []),
        };
        const customNextState = mapResponseToState ? mapResponseToState(response) : {};

        this.setModel(nameInState, {
          ...defaultNextState,
          ...customNextState,
        });
      });
  }

  fetchReservations = (namespace, getFilters) => {
    const filters = getFilters ? getFilters(this.filters) : this.filters;
    const params = {
      ...filters,
      // Ignore default date search parameter because this view is not
      // date specific.
      date: undefined,
      page_size: PAGE_SIZE,
      include: 'resource_detail',
      is_own: true,
    };

    this.loadModel('reservation', params, response => ({
      count: response.data.count,
    }), `${namespace}Reservation`);
  };

  loadUpcomingReservations = (getFilters) => {
    const getFilterWithDefaults = (defaultFilters) => {
      const filters = { ...defaultFilters, ordering: 'begin' };

      return getFilters ? getFilters(filters) : filters;
    };

    this.fetchReservations('upcoming', getFilterWithDefaults);
  }

  loadPastReservations = (getFilters) => {
    const getFilterWithDefaults = (defaultFilters) => {
      const now = moment().format(constants.DATETIME_FORMAT);
      const filters = {
        ...defaultFilters,
        all: true,
        ordering: '-begin',
        // Note that using this method to fetch a reservation has a
        // weakness: it'll also list currently ongoing reservations. By
        // common heuristics these should not be considered to be in the
        // past, but I could not find a more efficient way to find past
        // reservations.
        start: moment(ARBITRARY_START_DATETIME, 'YYYY-MM-DD[T]HH:mm').format(constants.DATETIME_FORMAT),
        end: now,
      };

      return getFilters ? getFilters(filters) : filters;
    };

    this.fetchReservations('past', getFilterWithDefaults);
  }

  handlePageChange = (newPage) => {
    const { history } = this.props;
    const filters = this.filters;
    const nextFilters = { ...filters, page: newPage };

    history.push({
      search: searchUtils.getSearchFromFilters(nextFilters),
    });

    if (this.tab === TABS.UPCOMING) {
      this.loadUpcomingReservations(defaultFilters => ({ ...defaultFilters, ...nextFilters }));
    }

    if (this.tab === TABS.PAST) {
      this.loadPastReservations(defaultFilters => ({ ...defaultFilters, ...nextFilters }));
    }
  };

  handleTabChange = (tab) => {
    if (this.tab === tab) {
      return;
    }

    const { history } = this.props;
    // Reset pagination
    const nextFilters = { };

    history.push({
      search: searchUtils.getSearchFromFilters(nextFilters),
    });

    this.setState({ tab });

    if (tab === TABS.UPCOMING) {
      this.loadUpcomingReservations(filters => pick(filters, UPCOMING_PARAMETERS));
    }

    if (tab === TABS.PAST) {
      this.loadPastReservations(filters => pick(filters, PAST_PARAMETERS));
    }
  }

  render() {
    const {
      t,
    } = this.props;

    const upcomingReservationLoading = this.state.upcomingReservation.loading;
    const upcomingReservationCount = this.state.upcomingReservation.count;

    return (

        <PageWrapper
          className="app-UserReservationPage__wrapper"
          title={t('UserReservationsPage.title')}
          transparent={false}
        >

{t('UserReservationsPage.title')}

              <button
                aria-selected={this.tab === TABS.UPCOMING}
                className={classNames('app-UserReservationPage__tab', {
                  'app-UserReservationPage__tab--active': this.tab === TABS.UPCOMING,
                })}
                onClick={() => this.handleTabChange(TABS.UPCOMING)}
                role="tab"
                type="button"
              >
                {t('ReservationListContainer.comingReservations')}
                {' '}
                {!upcomingReservationLoading ? `(${upcomingReservationCount})` : ''}
              </button>
              <button
                aria-selected={this.tab === TABS.PAST}
                className={classNames('app-UserReservationPage__tab', {
                  'app-UserReservationPage__tab--active': this.tab === TABS.PAST,
                })}
                onClick={() => this.handleTabChange(TABS.PAST)}
                role="tab"
                type="button"
              >
                {t('ReservationListContainer.pastReservations')}
              </button>

            <Loader loaded={!this.isLoading}>
              {/* In order to avoid mounting multiple instances of the
                  same component, we change data instead of component
                  instance. */}
              <ReservationList
                loading={this.isLoading}
                onPageChange={this.handlePageChange}
                page={this.page}
                pages={this.pages}
                reservations={this.reservations}
              />
            </Loader>

          <ReservationCancelModal />
          <ReservationInfoModal />
        </PageWrapper>

    );
  }
}

UnconnectedUserReservationsPage.propTypes = {
  history: PropTypes.object,
  location: PropTypes.object,
  t: PropTypes.func.isRequired,
};
UnconnectedUserReservationsPage = injectT(UnconnectedUserReservationsPage);  // eslint-disable-line

export { UnconnectedUserReservationsPage };
export default connect(userReservationsPageSelector)(
  UnconnectedUserReservationsPage,
);
<|endoftext|>


<commit_before>var fs = require('fs');

function reloadCustomAvatars() {
	var path = require('path');
	var newCustomAvatars = {};
	fs.readdirSync('./config/avatars').forEach(function (file) {
		var ext = path.extname(file);
		if (ext !== '.png' && ext !== '.gif')
			return;

		var user = toId(path.basename(file, ext));
		newCustomAvatars[user] = file;
		delete Config.customAvatars[user];
	});

	// Make sure the manually entered avatars exist
	for (var a in Config.customAvatars)
		if (typeof Config.customAvatars[a] === 'number')
			newCustomAvatars[a] = Config.customAvatars[a];
		else
			fs.exists('./config/avatars/' + Config.customAvatars[a], function (user, file, isExists) {
				if (isExists)
					Config.customAvatars[user] = file;
			}.bind(null, a, Config.customAvatars[a]));

	Config.customAvatars = newCustomAvatars;
}
reloadCustomAvatars();

if (Config.watchConfig) {
	fs.watchFile('./config/config.js', function (curr, prev) {
		if (curr.mtime <= prev.mtime) return;
		reloadCustomAvatars();
	});
}

const script = function () {
/*
	FILENAME=`mktemp`
	function cleanup {
		rm -f $FILENAME
	}
	trap cleanup EXIT

	set -xe

	timeout 10 wget "$1" -nv -O $FILENAME

	FRAMES=`identify $FILENAME | wc -l`
	if [ $FRAMES -gt 1 ]; then
		EXT=".gif"
	else
		EXT=".png"
	fi

	timeout 10 convert $FILENAME -layers TrimBounds -coalesce -adaptive-resize 80x80\> -background transparent -gravity center -extent 80x80 "$2$EXT"
*/
}.toString().match(/[^]*\/\*([^]*)\*\//)[1];

var pendingAdds = {};

exports.commands = {
	customavatars: 'customavatar',
	customavatar: function (target) {
		var parts = target.split(',');
		var cmd = parts[0].trim().toLowerCase();

		if (cmd in {'':1, show:1, view:1, display:1}) {
			var message = "";
			for (var a in Config.customAvatars)
				message += "" + Tools.escapeHTML(a) + ": " + Tools.escapeHTML(Config.customAvatars[a]) + "
";
			return this.sendReplyBox(message);
		}

		if (!this.can('customavatar')) return false;

		switch (cmd) {
			case 'set':
				var userid = toId(parts[1]);
				var user = Users.getExact(userid);
				var avatar = parts.slice(2).join(',').trim();

				if (!userid) return this.sendReply("You didn't specify a user.");
				if (Config.customAvatars[userid]) return this.sendReply(userid + " already has a custom avatar.");

				var hash = require('crypto').createHash('sha512').update(userid + '\u0000' + avatar).digest('hex').slice(0, 8);
				pendingAdds[hash] = {userid: userid, avatar: avatar};
				parts[1] = hash;

				if (!user) {
					this.sendReply("Warning: " + userid + " is not online.");
					this.sendReply("If you want to continue, use: /customavatar forceset, " + hash);
					return;
				}

				/* falls through */
			case 'forceset':
				var hash = parts[1].trim();
				if (!pendingAdds[hash]) return this.sendReply("Invalid hash.");

				var userid = pendingAdds[hash].userid;
				var avatar = pendingAdds[hash].avatar;
				delete pendingAdds[hash];

				require('child_process').execFile('bash', ['-c', script, '-', avatar, './config/avatars/' + userid], function (e, out, err) {
					if (e) {
						this.sendReply(userid + "'s custom avatar failed to be set. Script output:");
						(out + err).split('\n').forEach(this.sendReply.bind(this));
						return;
					}

					reloadCustomAvatars();

					var user = Users.getExact(userid);
					if (user) user.avatar = Config.customAvatars[userid];

					this.sendReply(userid + "'s custom avatar has been set.");
				}.bind(this));
				break;

			case 'delete':
				var userid = toId(parts[1]);
				if (!Config.customAvatars[userid]) return this.sendReply(userid + " does not have a custom avatar.");

				if (Config.customAvatars[userid].toString().split('.').slice(0, -1).join('.') !== userid)
					return this.sendReply(userid + "'s custom avatar (" + Config.customAvatars[userid] + ") cannot be removed with this script.");

				var user = Users.getExact(userid);
				if (user) user.avatar = 1;

				fs.unlink('./config/avatars/' + Config.customAvatars[userid], function (e) {
					if (e) return this.sendReply(userid + "'s custom avatar (" + Config.customAvatars[userid] + ") could not be removed: " + e.toString());

					delete Config.customAvatars[userid];
					this.sendReply(userid + "'s custom avatar removed successfully");
				}.bind(this));
				break;

			default:
				return this.sendReply("Invalid command. Valid commands are `/customavatar set, user, avatar` and `/customavatar delete, user`.");
		}
	}
};
<commit_msg>Fix style in custom avatar<commit_after>var fs = require('fs');

function reloadCustomAvatars() {
	var path = require('path');
	var newCustomAvatars = {};
	fs.readdirSync('./config/avatars').forEach(function (file) {
		var ext = path.extname(file);
		if (ext !== '.png' && ext !== '.gif')
			return;

		var user = toId(path.basename(file, ext));
		newCustomAvatars[user] = file;
		delete Config.customAvatars[user];
	});

	// Make sure the manually entered avatars exist
	for (var a in Config.customAvatars) {
		if (typeof Config.customAvatars[a] === 'number') {
			newCustomAvatars[a] = Config.customAvatars[a];
		} else {
			fs.exists('./config/avatars/' + Config.customAvatars[a], function (user, file, isExists) {
				if (isExists)
					Config.customAvatars[user] = file;
			}.bind(null, a, Config.customAvatars[a]));
		}
	}

	Config.customAvatars = newCustomAvatars;
}
reloadCustomAvatars();

if (Config.watchConfig) {
	fs.watchFile('./config/config.js', function (curr, prev) {
		if (curr.mtime <= prev.mtime) return;
		reloadCustomAvatars();
	});
}

const script = function () {/*
	FILENAME=`mktemp`
	function cleanup {
		rm -f $FILENAME
	}
	trap cleanup EXIT

	set -xe

	timeout 10 wget "$1" -nv -O $FILENAME

	FRAMES=`identify $FILENAME | wc -l`
	if [ $FRAMES -gt 1 ]; then
		EXT=".gif"
	else
		EXT=".png"
	fi

	timeout 10 convert $FILENAME -layers TrimBounds -coalesce -adaptive-resize 80x80\> -background transparent -gravity center -extent 80x80 "$2$EXT"
*/
}.toString().match(/[^]*\/\*([^]*)\*\//)[1];

var pendingAdds = {};

exports.commands = {
	customavatars: 'customavatar',
	customavatar: function (target) {
		var parts = target.split(',');
		var cmd = parts[0].trim().toLowerCase();

		if (cmd in {'':1, show:1, view:1, display:1}) {
			var message = "";
			for (var a in Config.customAvatars)
				message += "" + Tools.escapeHTML(a) + ": " + Tools.escapeHTML(Config.customAvatars[a]) + "
";
			return this.sendReplyBox(message);
		}

		if (!this.can('customavatar')) return false;

		switch (cmd) {
			case 'set':
				var userid = toId(parts[1]);
				var user = Users.getExact(userid);
				var avatar = parts.slice(2).join(',').trim();

				if (!userid) return this.sendReply("You didn't specify a user.");
				if (Config.customAvatars[userid]) return this.sendReply(userid + " already has a custom avatar.");

				var hash = require('crypto').createHash('sha512').update(userid + '\u0000' + avatar).digest('hex').slice(0, 8);
				pendingAdds[hash] = {userid: userid, avatar: avatar};
				parts[1] = hash;

				if (!user) {
					this.sendReply("Warning: " + userid + " is not online.");
					this.sendReply("If you want to continue, use: /customavatar forceset, " + hash);
					return;
				}

				/* falls through */
			case 'forceset':
				var hash = parts[1].trim();
				if (!pendingAdds[hash]) return this.sendReply("Invalid hash.");

				var userid = pendingAdds[hash].userid;
				var avatar = pendingAdds[hash].avatar;
				delete pendingAdds[hash];

				require('child_process').execFile('bash', ['-c', script, '-', avatar, './config/avatars/' + userid], function (e, out, err) {
					if (e) {
						this.sendReply(userid + "'s custom avatar failed to be set. Script output:");
						(out + err).split('\n').forEach(this.sendReply.bind(this));
						return;
					}

					reloadCustomAvatars();

					var user = Users.getExact(userid);
					if (user) user.avatar = Config.customAvatars[userid];

					this.sendReply(userid + "'s custom avatar has been set.");
				}.bind(this));
				break;

			case 'delete':
				var userid = toId(parts[1]);
				if (!Config.customAvatars[userid]) return this.sendReply(userid + " does not have a custom avatar.");

				if (Config.customAvatars[userid].toString().split('.').slice(0, -1).join('.') !== userid)
					return this.sendReply(userid + "'s custom avatar (" + Config.customAvatars[userid] + ") cannot be removed with this script.");

				var user = Users.getExact(userid);
				if (user) user.avatar = 1;

				fs.unlink('./config/avatars/' + Config.customAvatars[userid], function (e) {
					if (e) return this.sendReply(userid + "'s custom avatar (" + Config.customAvatars[userid] + ") could not be removed: " + e.toString());

					delete Config.customAvatars[userid];
					this.sendReply(userid + "'s custom avatar removed successfully");
				}.bind(this));
				break;

			default:
				return this.sendReply("Invalid command. Valid commands are `/customavatar set, user, avatar` and `/customavatar delete, user`.");
		}
	}
};
<|endoftext|>


<commit_before>/**
 * Initialize new channel. It should be single for page.
 */
function Channel(endpoint) {

    var self = this;

    self.id = guid();

    self.apiEndpoint = endpoint;

    self.eventSource = null;

    /**
     *
     */
    self.subscribe = function (client) {

        self.eventSource.addEventListener(client.id, function (e) {
            try {
                var obj = JSON.parse(e.data);
                client.callback(obj);
            }
            catch (exception) {
                console.warn('Exception during JSON.parse: ', exception);
            }
        }, false);

        var url = this.apiEndpoint + 'subscribe?clientId=' + client.id + '&channelId=' + this.id;

        httpGetAsync(url, function () {
            console.info('Client[' + client.id + '] subscribed to events on channel ' + self.id);
        });
    };

    self.init = function () {

        self.eventSource = new EventSource(self.apiEndpoint + '?channelId=' + self.id);

        self.eventSource.onmessage = function (obj) {
            //console.log('onmessage [' + obj + ']');
        };

        self.eventSource.onopen = function (obj) {
            //console.log('onopen [' + obj + ']');
        };

        self.eventSource.onerror = function (obj) {
            //console.log('onerror [' + obj + ']');

            //if (self.eventSource.readyState ==  EventSource.CLOSED) {
            console.log('Error. Trying reconnect...');
            setTimeout(self.init, 500);
            //}
        };
    }
}<commit_msg>Update addEventListener<commit_after>/**
 * Initialize new channel. It should be single for page.
 */
function Channel(endpoint) {

    var self = this;

    self.id = guid();

    self.apiEndpoint = endpoint;

    self.eventSource = null;

    /**
     *
     */
    self.subscribe = function (client) {

        self.eventSource.addEventListener(client.id, function (e) {
            try {
                var obj = JSON.parse(e.data);
                client.callback(obj);
            }
            catch (exception) {
                console.warn('Exception during JSON.parse: ', exception, e);
            }
        }, false);

        var url = this.apiEndpoint + 'subscribe?clientId=' + client.id + '&channelId=' + this.id;

        httpGetAsync(url, function () {
            console.info('Client[' + client.id + '] subscribed to events on channel ' + self.id);
        });
    };

    self.init = function () {

        self.eventSource = new EventSource(self.apiEndpoint + '?channelId=' + self.id);

        self.eventSource.onmessage = function (obj) {
            //console.log('onmessage [' + obj + ']');
        };

        self.eventSource.onopen = function (obj) {
            //console.log('onopen [' + obj + ']');
        };

        self.eventSource.onerror = function (obj) {
            //console.log('onerror [' + obj + ']');

            //if (self.eventSource.readyState ==  EventSource.CLOSED) {
            console.log('Error. Trying reconnect...');
            setTimeout(self.init, 500);
            //}
        };
    }
}<|endoftext|>


<commit_before>const {result, runAction, done, error} = require('./events');

const Context = require('./Context');

const withActionLifecycle = async (context, action, fn) => {

    context.emit(runAction(action));

    try {

        const data = await fn();

        context.emit(result(data));
        context.emit(done());

        return data;

    } catch (e) {

        context.emit(error(e.message));
        throw e;
    }
};

class Action {

    constructor({name, run, description = null}) {
        this.name        = name;
        this.run         = run;
        this.description = description;
    }

    /**
     * Make an action wrapper runtime Context instance based on the given arguments
     * @param {Function} receive
     * @param {Object} args
     * @param {Context|null} [parent = null] Parent context instance
     * @returns {Context}
     */
    makeContext(args = {}, receive = null, parent = null) {

        const scope         = {action: this.name};
        const id            = parent && parent.branchId ? parent.branchId() : '0';
        const inheritedArgs = parent && parent.getInheritedArgs ? parent.getInheritedArgs() : {};

        args = {...inheritedArgs, ...args};

        return new Context({receive, args, scope, id});
    }

    /**
     * @param {Object} args
     * @param {Function|null} [receive = null] Realtime event receiver
     * @param {Context|null} [parent = null] Parent context
     * @returns {Promise}
     */
    execute(args = {}, receive = null, parent = null) {
        const context = this.makeContext(args, receive, parent);
        return withActionLifecycle(context, this, () => this.run(context));
    }
}

module.exports = Action;<commit_msg>allow override of the “run” method in Action in OOP mode<commit_after>const {result, runAction, done, error} = require('./events');

const Context = require('./Context');

const withActionLifecycle = async (context, action, fn) => {

    context.emit(runAction(action));

    try {

        const data = await fn();

        context.emit(result(data));
        context.emit(done());

        return data;

    } catch (e) {

        context.emit(error(e.message));
        throw e;
    }
};

class Action {

    constructor({name, run, description = null}) {
        this.name        = name;
        this._run        = run;
        this.description = description;
    }

    run(...args) {
        return this._run(...args);
    }

    /**
     * Make an action wrapper runtime Context instance based on the given arguments
     * @param {Function} receive
     * @param {Object} args
     * @param {Context|null} [parent = null] Parent context instance
     * @returns {Context}
     */
    makeContext(args = {}, receive = null, parent = null) {

        const scope         = {action: this.name};
        const id            = parent && parent.branchId ? parent.branchId() : '0';
        const inheritedArgs = parent && parent.getInheritedArgs ? parent.getInheritedArgs() : {};

        args = {...inheritedArgs, ...args};

        return new Context({receive, args, scope, id});
    }

    /**
     * @param {Object} args
     * @param {Function|null} [receive = null] Realtime event receiver
     * @param {Context|null} [parent = null] Parent context
     * @returns {Promise}
     */
    execute(args = {}, receive = null, parent = null) {
        const context = this.makeContext(args, receive, parent);
        return withActionLifecycle(context, this, () => this.run(context));
    }
}

module.exports = Action;<|endoftext|>


<commit_before>// from http://davidwalsh.name/vendor-prefix
module.exports = function getPrefix() {
  var styles = window.getComputedStyle(document.documentElement, '');
  var pre = (Array.prototype.slice
    .call(styles)
    .join('')
    .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
  )[1];
  if (Object.keys(styles).indexOf('transform') !== -1) {
    return '';
  } else if (pre) {
    return '-' + pre + '-';
  }
};
<commit_msg>[#5] prefer -webkit- to no prefix<commit_after>// from http://davidwalsh.name/vendor-prefix
module.exports = function getPrefix() {
  var styles = window.getComputedStyle(document.documentElement, '');
  var pre = (Array.prototype.slice
    .call(styles)
    .join('')
    .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
  )[1];
  return pre ? '-' + pre + '-' : '';
};
<|endoftext|>