<commit_before>/// <reference path="Primitives/Selector.js" />
/// CODE
/// <reference path="ListBoxItem.js"/>
/// <reference path="Enums.js"/>
/// <reference path="../Core/Input/KeyboardNavigation.js"/>

//#region ListBox
var ListBox = Nullstone.Create("ListBox", Selector);

ListBox.Instance.Init = function () {
    this.Init$Selector();
    this.DefaultStyleKey = this.constructor;
    this._FocusedIndex = -1;
};

//#region Properties

ListBox.ItemContainerStyleProperty = DependencyProperty.RegisterCore("ItemContainerStyle", function () { return Style; }, ListBox, undefined, function (d, args) { d.OnItemContainerStyleChanged(args.OldValue, args.NewValue); });
ListBox.SelectionModeProperty = DependencyProperty.RegisterCore("SelectionMode", function () { return new Enum(SelectionMode); }, ListBox, undefined, function (d, args) { d._Selection.Mode = args.NewValue; });
ListBox.IsSelectionActiveProperty = Selector.IsSelectionActiveProperty;

Nullstone.AutoProperties(ListBox, [
    ListBox.ItemContainerStyleProperty,
    ListBox.SelectionModeProperty
]);

Nullstone.AutoPropertyReadOnly(ListBox, ListBox.IsSelectionActiveProperty, true);

Nullstone.Property(ListBox, "$IsVerticalOrientation", {
    get: function () {
        var p = this.$Panel;
        if (p instanceof StackPanel || p instanceof VirtualizingStackPanel)
            return p.Orientation === Orientation.Vertical;
        return true;
    }
});

//#endregion

ListBox.Instance.SelectAll = function () {
    this._Selection.SelectAll(this.Items);
};
ListBox.Instance.ScrollIntoView = function (item) {
    var tsv = this.$TemplateScrollViewer;
    if (tsv == null)
        return;
    var items = this.Items;
    if (!items.Contains(item))
        return;

    var ihro;
    var lbiro;
    //TODO: VirtualizingStackPanel
    var virtualizing = false; // VirtualizingStackPanel.GetIsVirtualizing(this);
    if (this._IsOnCurrentPage(item, ihro, lbiro))
        return;

    var ihr = ihro.Value;
    var lbir = lbiro.Value;

    if (this.$IsVerticalOrientation) {
        if (virtualizing) {
            tsv.ScrollToVerticalOffset(this.SelectedIndex);
            return;
        }
        var verticalOffset = tsv.VerticalOffset;
        var verticalDelta = 0;
        if (ihr.GetBottom() < lbir.GetBottom()) {
            verticalDelta = lbir.GetBottom() - ihr.GetBottom();
            verticalOffset += verticalDelta;
        }
        if ((lbir.Y - verticalDelta) < ihr.Y) {
            verticalOffset -= ihr.Y - (lbir.Y - verticalDelta);
        }
        tsv.ScrollToVerticalOffset(verticalOffset);
    } else {
        if (virtualizing) {
            tsv.ScrollToHorizontalOffset(this.SelectedIndex);
            return;
        }
        var horizontalOffset = tsv.HorizontalOffset;
        var horizontalDelta = 0;
        if (ihr.GetRight() < lbir.GetRight()) {
            horizontalDelta = lbir.GetRight() - ihr.GetRight();
            horizontalOffset += horizontalDelta;
        }
        if ((ihr.X - horizontalDelta) < ihr.X) {
            horizontalOffset -= ihr.X - (lbir.X - horizontalDelta);
        }
        tsv.ScrollToHorizontalOffset(horizontalOffset);
    }
};

ListBox.Instance._NavigateByPage = function (forward) {
    var tsv = this.$TemplateScrollViewer;
    var newFocusedIndex = -1;
    var item = (this._FocusedIndex !== -1) ? this.Items.GetValueAt(this._FocusedIndex) : null;
    if (item != null && !this._IsOnCurrentPage(item)) {
        this.ScrollIntoView(item);
        if (tsv != null)
            tsv.UpdateLayout();
    }
    if (item == null) {
        newFocusedIndex = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
    } else {
        var firstItemOnCurrentPage = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
        if (firstItemOnCurrentPage !== this._FocusedIndex) {
            newFocusedIndex = firstItemOnCurrentPage;
        } else {
            if (tsv != null) {
                if (this.$IsVerticalOrientation) {
                    tsv.ScrollToVerticalOffset(Math.max(0, Math.min(tsv.ScrollableHeight,
                        tsv.VerticalOffset + (tsv.ViewportHeight * (forward ? 1 : -1)))));
                } else {
                    tsv.ScrollToHorizontalOffset(Math.max(0, Math.min(tsv.ScrollableWidth,
                        tsv.HorizontalOffset + (tsv.ViewportWidth * (forward ? 1 : -1)))));

                }
                tsv.UpdateLayout();
            }
            newFocusedIndex = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
        }
    }
    return newFocusedIndex;
};
ListBox.Instance._ScrollInDirection = function (key) {
    if (this.$TemplateScrollViewer == null)
        return;
    this.$TemplateScrollViewer._ScrollInDirection(key);
};
ListBox.Instance._IsOnCurrentPage = function (item, itemsHostRectOut, listBoxItemsRectOut) {
    if (itemsHostRectOut === undefined) itemsHostRectOut = {};
    if (listBoxItemsRectOut === undefined) listBoxItemsRectOut = {};

    var itemsHost = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this, 0), 0);

    var tsv = this.$TemplateScrollViewer;
    if (tsv != null) {
        itemsHost = tsv;
        if (tsv.$ElementScrollContentPresenter != null)
            itemsHost = tsv.$ElementScrollContentPresenter;
    }
    itemsHost = Nullstone.As(itemsHost, FrameworkElement);

    var ihro = itemsHostRectOut.Value = new Rect();
    var lbiro = listBoxItemsRectOut.Value = new Rect();
    if (itemsHost == null) {
        return false;
    }
    ihro.Width = itemsHost.RenderSize.Width;
    ihro.Height = itemsHost.RenderSize.Height;

    var lbi = this.ItemContainerGenerator.ContainerForItem(item);
    if (lbi == null)
        return false;

    lbiro.Width = lbi.RenderSize.Width;
    lbiro.Height = lbi.RenderSize.Height;

    if (itemsHost instanceof Control) {
        var padding = itemsHost.Padding;
        ihro.X = ihro.X + padding.Left;
        ihro.Y = ihro.Y + padding.Top;
        ihro.Width = ihro.Width - padding.Left - padding.Right;
        ihro.Height = ihro.Height - padding.Top - padding.Bottom;
    }

    var genXform = lbi.TransformToVisual(itemsHost);
    if (genXform != null) {
        var ptl = genXform.Transform(new Point());
        var pbr = genXform.Transform(new Point(lbi.RenderSize.Width, lbi.RenderSize.Height));
        lbiro.X = Math.min(ptl.X, pbr.X);
        lbiro.Y = Math.min(ptl.Y, pbr.Y);
        lbiro.Width = Math.abs(ptl.X - pbr.X);
        lbiro.Height = Math.abs(ptl.Y - pbr.Y);
    }

    return this.$IsVerticalOrientation
        ? ihro.X <= lbiro.Y && ihro.GetBottom() >= lbiro.GetBottom()
        : ihro.X <= lbiro.X && ihro.GetRight() >= lbiro.GetRight();
};
ListBox.Instance._GetFirstItemOnCurrentPage = function (startingIndex, forward) {
    var delta = forward ? 1 : -1;
    var fiocp = -1;
    var probeIndex = startingIndex;
    var items = this.Items;
    var itemsCount = items.GetCount();
    while (probeIndex >= 0 && probeIndex < itemsCount && !this._IsOnCurrentPage(items.GetValueAt(probeIndex))) {
        fiocp = probeIndex;
        probeIndex += delta;
    }
    while (probeIndex >= 0 && probeIndex < itemsCount && this._IsOnCurrentPage(items.GetValueAt(probeIndex))) {
        fiocp = probeIndex;
        probeIndex += delta;
    }
    return fiocp;
};

ListBox.Instance.OnItemContainerStyleChanged = function (oldStyle, newStyle) {
    var count = this.Items.GetCount();
    for (var i = 0; i < count; i++) {
        var lbi = this.ItemContainerGenerator.ContainerFromIndex(i);
        if (lbi != null && Nullstone.RefEquals(lbi.Style, oldStyle))
            lbi.Style = newStyle;
    }
};

ListBox.Instance.OnKeyDown = function (args) {
    if (args.Handled)
        return;

    var handled = false;
    var newFocusedIndex = -1;
    switch (args.Key) {
        case Key.Space:
        case Key.Enter:
            if (Key.Enter !== args.Key || KeyboardNavigation.GetAcceptsReturn(this)) {
                if ((Keyboard.Modifiers & ModifierKeys.Alt) !== ModifierKeys.Alt) {
                    var lbi = Nullstone.As(FocusManager.GetFocusedElement(), ListBoxItem);
                    if (lbi != null) {
                        if ((Keyboard.Modifiers & ModifierKeys.Control) === ModifierKeys.Control && lbi.IsSelected) {
                            this.SelectedItem = null;
                        } else {
                            this.SelectedItem = this.ItemContainerGenerator.ItemFromContainer(lbi);
                        }
                        handled = true;
                    }
                }
            }
            break;
        case Key.Home:
            newFocusedIndex = 0;
            break;
        case Key.End:
            newFocusedIndex = this.Items.GetCount() - 1;
            break;
        case Key.PageUp:
            newFocusedIndex = this._NavigateByPage(false);
            break;
        case Key.PageDown:
            newFocusedIndex = this._NavigateByPage(true);
            break;
        case Key.Left:
            if (this.$IsVerticalOrientation) {
                this._ScrollInDirection(Key.Left);
            } else {
                newFocusedIndex = this._FocusedIndex - 1;
            }
            break;
        case Key.Up:
            if (this.$IsVerticalOrientation) {
                newFocusedIndex = this._FocusedIndex - 1;
            } else {
                this._ScrollInDirection(Key.Up);
            }
            break;
        case Key.Right:
            if (this.$IsVerticalOrientation) {
                this._ScrollInDirection(Key.Right);
            } else {
                newFocusedIndex = this._FocusedIndex + 1;
            }
            break;
        case Key.Down:
            if (this.$IsVerticalOrientation) {
                newFocusedIndex = this._FocusedIndex + 1;
            } else {
                this._ScrollInDirection(Key.Down);
            }
            break;
    }

    if (newFocusedIndex !== -1 && this._FocusedIndex !== -1 && newFocusedIndex !== this._FocusedIndex && newFocusedIndex >= 0 && newFocusedIndex < this.Items.GetCount()) {
        // A key press changes the focused ListBoxItem
        var icg = this.ItemContainerGenerator;
        var lbi = icg.ContainerFromIndex(newFocusedIndex);
        var item = icg.ItemFromContainer(lbi);
        this.ScrollIntoView(item);
        if ((Keyboard.Modifiers & ModifierKeys.Control) === ModifierKeys.Control) {
            lbi.Focus();
        } else {
            this.SelectedItem = item;
        }
        handled = true;
    }
    if (handled)
        args.Handled = true;
};

//#region Overrides

ListBox.Instance.IsItemItsOwnContainer = function (item) {
    return item instanceof ListBoxItem;
};
ListBox.Instance.GetContainerForItem = function () {
    var item = new ListBoxItem();
    var ics = this.ItemContainerStyle;
    if (ics != null)
        item.Style = ics;
    return item;
};
ListBox.Instance.PrepareContainerForItem = function (element, item) {
    this.PrepareContainerForItem$Selector(element, item);
    var ics = this.ItemContainerStyle;
    if (element.Style == null && ics != null)
        element.Style = ics;
};

//#endregion

//#region Focus

ListBox.Instance.OnGotFocus = function (e) {
    this.OnGotFocus$Selector(e);
    this.$SetValueInternal(ListBox.IsSelectionActiveProperty, true);
};
ListBox.Instance.OnLostFocus = function (e) {
    this.OnLostFocus$Selector(e);
    this.$SetValueInternal(ListBox.IsSelectionActiveProperty, false);
};

//#endregion

//#region ListItem Notifications

ListBox.Instance.NotifyListItemGotFocus = function (lbi) {
    this._FocusedIndex = this.ItemContainerGenerator.IndexFromContainer(lbi);
};
ListBox.Instance.NotifyListItemLostFocus = function (lbi) {
    this._FocusedIndex = -1;
};

//#endregion

Nullstone.FinishCreate(ListBox);
//#endregion<commit_msg>Fixed call to ContainerFromItem.<commit_after>/// <reference path="Primitives/Selector.js" />
/// CODE
/// <reference path="ListBoxItem.js"/>
/// <reference path="Enums.js"/>
/// <reference path="../Core/Input/KeyboardNavigation.js"/>

//#region ListBox
var ListBox = Nullstone.Create("ListBox", Selector);

ListBox.Instance.Init = function () {
    this.Init$Selector();
    this.DefaultStyleKey = this.constructor;
    this._FocusedIndex = -1;
};

//#region Properties

ListBox.ItemContainerStyleProperty = DependencyProperty.RegisterCore("ItemContainerStyle", function () { return Style; }, ListBox, undefined, function (d, args) { d.OnItemContainerStyleChanged(args.OldValue, args.NewValue); });
ListBox.SelectionModeProperty = DependencyProperty.RegisterCore("SelectionMode", function () { return new Enum(SelectionMode); }, ListBox, undefined, function (d, args) { d._Selection.Mode = args.NewValue; });
ListBox.IsSelectionActiveProperty = Selector.IsSelectionActiveProperty;

Nullstone.AutoProperties(ListBox, [
    ListBox.ItemContainerStyleProperty,
    ListBox.SelectionModeProperty
]);

Nullstone.AutoPropertyReadOnly(ListBox, ListBox.IsSelectionActiveProperty, true);

Nullstone.Property(ListBox, "$IsVerticalOrientation", {
    get: function () {
        var p = this.$Panel;
        if (p instanceof StackPanel || p instanceof VirtualizingStackPanel)
            return p.Orientation === Orientation.Vertical;
        return true;
    }
});

//#endregion

ListBox.Instance.SelectAll = function () {
    this._Selection.SelectAll(this.Items);
};
ListBox.Instance.ScrollIntoView = function (item) {
    var tsv = this.$TemplateScrollViewer;
    if (tsv == null)
        return;
    var items = this.Items;
    if (!items.Contains(item))
        return;

    var ihro;
    var lbiro;
    //TODO: VirtualizingStackPanel
    var virtualizing = false; // VirtualizingStackPanel.GetIsVirtualizing(this);
    if (this._IsOnCurrentPage(item, ihro, lbiro))
        return;

    var ihr = ihro.Value;
    var lbir = lbiro.Value;

    if (this.$IsVerticalOrientation) {
        if (virtualizing) {
            tsv.ScrollToVerticalOffset(this.SelectedIndex);
            return;
        }
        var verticalOffset = tsv.VerticalOffset;
        var verticalDelta = 0;
        if (ihr.GetBottom() < lbir.GetBottom()) {
            verticalDelta = lbir.GetBottom() - ihr.GetBottom();
            verticalOffset += verticalDelta;
        }
        if ((lbir.Y - verticalDelta) < ihr.Y) {
            verticalOffset -= ihr.Y - (lbir.Y - verticalDelta);
        }
        tsv.ScrollToVerticalOffset(verticalOffset);
    } else {
        if (virtualizing) {
            tsv.ScrollToHorizontalOffset(this.SelectedIndex);
            return;
        }
        var horizontalOffset = tsv.HorizontalOffset;
        var horizontalDelta = 0;
        if (ihr.GetRight() < lbir.GetRight()) {
            horizontalDelta = lbir.GetRight() - ihr.GetRight();
            horizontalOffset += horizontalDelta;
        }
        if ((ihr.X - horizontalDelta) < ihr.X) {
            horizontalOffset -= ihr.X - (lbir.X - horizontalDelta);
        }
        tsv.ScrollToHorizontalOffset(horizontalOffset);
    }
};

ListBox.Instance._NavigateByPage = function (forward) {
    var tsv = this.$TemplateScrollViewer;
    var newFocusedIndex = -1;
    var item = (this._FocusedIndex !== -1) ? this.Items.GetValueAt(this._FocusedIndex) : null;
    if (item != null && !this._IsOnCurrentPage(item)) {
        this.ScrollIntoView(item);
        if (tsv != null)
            tsv.UpdateLayout();
    }
    if (item == null) {
        newFocusedIndex = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
    } else {
        var firstItemOnCurrentPage = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
        if (firstItemOnCurrentPage !== this._FocusedIndex) {
            newFocusedIndex = firstItemOnCurrentPage;
        } else {
            if (tsv != null) {
                if (this.$IsVerticalOrientation) {
                    tsv.ScrollToVerticalOffset(Math.max(0, Math.min(tsv.ScrollableHeight,
                        tsv.VerticalOffset + (tsv.ViewportHeight * (forward ? 1 : -1)))));
                } else {
                    tsv.ScrollToHorizontalOffset(Math.max(0, Math.min(tsv.ScrollableWidth,
                        tsv.HorizontalOffset + (tsv.ViewportWidth * (forward ? 1 : -1)))));

                }
                tsv.UpdateLayout();
            }
            newFocusedIndex = this._GetFirstItemOnCurrentPage(this._FocusedIndex, forward);
        }
    }
    return newFocusedIndex;
};
ListBox.Instance._ScrollInDirection = function (key) {
    if (this.$TemplateScrollViewer == null)
        return;
    this.$TemplateScrollViewer._ScrollInDirection(key);
};
ListBox.Instance._IsOnCurrentPage = function (item, itemsHostRectOut, listBoxItemsRectOut) {
    if (itemsHostRectOut === undefined) itemsHostRectOut = {};
    if (listBoxItemsRectOut === undefined) listBoxItemsRectOut = {};

    var itemsHost = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this, 0), 0);

    var tsv = this.$TemplateScrollViewer;
    if (tsv != null) {
        itemsHost = tsv;
        if (tsv.$ElementScrollContentPresenter != null)
            itemsHost = tsv.$ElementScrollContentPresenter;
    }
    itemsHost = Nullstone.As(itemsHost, FrameworkElement);

    var ihro = itemsHostRectOut.Value = new Rect();
    var lbiro = listBoxItemsRectOut.Value = new Rect();
    if (itemsHost == null) {
        return false;
    }
    ihro.Width = itemsHost.RenderSize.Width;
    ihro.Height = itemsHost.RenderSize.Height;

    var lbi = this.ItemContainerGenerator.ContainerFromItem(item);
    if (lbi == null)
        return false;

    lbiro.Width = lbi.RenderSize.Width;
    lbiro.Height = lbi.RenderSize.Height;

    if (itemsHost instanceof Control) {
        var padding = itemsHost.Padding;
        ihro.X = ihro.X + padding.Left;
        ihro.Y = ihro.Y + padding.Top;
        ihro.Width = ihro.Width - padding.Left - padding.Right;
        ihro.Height = ihro.Height - padding.Top - padding.Bottom;
    }

    var genXform = lbi.TransformToVisual(itemsHost);
    if (genXform != null) {
        var ptl = genXform.Transform(new Point());
        var pbr = genXform.Transform(new Point(lbi.RenderSize.Width, lbi.RenderSize.Height));
        lbiro.X = Math.min(ptl.X, pbr.X);
        lbiro.Y = Math.min(ptl.Y, pbr.Y);
        lbiro.Width = Math.abs(ptl.X - pbr.X);
        lbiro.Height = Math.abs(ptl.Y - pbr.Y);
    }

    return this.$IsVerticalOrientation
        ? ihro.X <= lbiro.Y && ihro.GetBottom() >= lbiro.GetBottom()
        : ihro.X <= lbiro.X && ihro.GetRight() >= lbiro.GetRight();
};
ListBox.Instance._GetFirstItemOnCurrentPage = function (startingIndex, forward) {
    var delta = forward ? 1 : -1;
    var fiocp = -1;
    var probeIndex = startingIndex;
    var items = this.Items;
    var itemsCount = items.GetCount();
    while (probeIndex >= 0 && probeIndex < itemsCount && !this._IsOnCurrentPage(items.GetValueAt(probeIndex))) {
        fiocp = probeIndex;
        probeIndex += delta;
    }
    while (probeIndex >= 0 && probeIndex < itemsCount && this._IsOnCurrentPage(items.GetValueAt(probeIndex))) {
        fiocp = probeIndex;
        probeIndex += delta;
    }
    return fiocp;
};

ListBox.Instance.OnItemContainerStyleChanged = function (oldStyle, newStyle) {
    var count = this.Items.GetCount();
    for (var i = 0; i < count; i++) {
        var lbi = this.ItemContainerGenerator.ContainerFromIndex(i);
        if (lbi != null && Nullstone.RefEquals(lbi.Style, oldStyle))
            lbi.Style = newStyle;
    }
};

ListBox.Instance.OnKeyDown = function (args) {
    if (args.Handled)
        return;

    var handled = false;
    var newFocusedIndex = -1;
    switch (args.Key) {
        case Key.Space:
        case Key.Enter:
            if (Key.Enter !== args.Key || KeyboardNavigation.GetAcceptsReturn(this)) {
                if ((Keyboard.Modifiers & ModifierKeys.Alt) !== ModifierKeys.Alt) {
                    var lbi = Nullstone.As(FocusManager.GetFocusedElement(), ListBoxItem);
                    if (lbi != null) {
                        if ((Keyboard.Modifiers & ModifierKeys.Control) === ModifierKeys.Control && lbi.IsSelected) {
                            this.SelectedItem = null;
                        } else {
                            this.SelectedItem = this.ItemContainerGenerator.ItemFromContainer(lbi);
                        }
                        handled = true;
                    }
                }
            }
            break;
        case Key.Home:
            newFocusedIndex = 0;
            break;
        case Key.End:
            newFocusedIndex = this.Items.GetCount() - 1;
            break;
        case Key.PageUp:
            newFocusedIndex = this._NavigateByPage(false);
            break;
        case Key.PageDown:
            newFocusedIndex = this._NavigateByPage(true);
            break;
        case Key.Left:
            if (this.$IsVerticalOrientation) {
                this._ScrollInDirection(Key.Left);
            } else {
                newFocusedIndex = this._FocusedIndex - 1;
            }
            break;
        case Key.Up:
            if (this.$IsVerticalOrientation) {
                newFocusedIndex = this._FocusedIndex - 1;
            } else {
                this._ScrollInDirection(Key.Up);
            }
            break;
        case Key.Right:
            if (this.$IsVerticalOrientation) {
                this._ScrollInDirection(Key.Right);
            } else {
                newFocusedIndex = this._FocusedIndex + 1;
            }
            break;
        case Key.Down:
            if (this.$IsVerticalOrientation) {
                newFocusedIndex = this._FocusedIndex + 1;
            } else {
                this._ScrollInDirection(Key.Down);
            }
            break;
    }

    if (newFocusedIndex !== -1 && this._FocusedIndex !== -1 && newFocusedIndex !== this._FocusedIndex && newFocusedIndex >= 0 && newFocusedIndex < this.Items.GetCount()) {
        // A key press changes the focused ListBoxItem
        var icg = this.ItemContainerGenerator;
        var lbi = icg.ContainerFromIndex(newFocusedIndex);
        var item = icg.ItemFromContainer(lbi);
        this.ScrollIntoView(item);
        if ((Keyboard.Modifiers & ModifierKeys.Control) === ModifierKeys.Control) {
            lbi.Focus();
        } else {
            this.SelectedItem = item;
        }
        handled = true;
    }
    if (handled)
        args.Handled = true;
};

//#region Overrides

ListBox.Instance.IsItemItsOwnContainer = function (item) {
    return item instanceof ListBoxItem;
};
ListBox.Instance.GetContainerForItem = function () {
    var item = new ListBoxItem();
    var ics = this.ItemContainerStyle;
    if (ics != null)
        item.Style = ics;
    return item;
};
ListBox.Instance.PrepareContainerForItem = function (element, item) {
    this.PrepareContainerForItem$Selector(element, item);
    var ics = this.ItemContainerStyle;
    if (element.Style == null && ics != null)
        element.Style = ics;
};

//#endregion

//#region Focus

ListBox.Instance.OnGotFocus = function (e) {
    this.OnGotFocus$Selector(e);
    this.$SetValueInternal(ListBox.IsSelectionActiveProperty, true);
};
ListBox.Instance.OnLostFocus = function (e) {
    this.OnLostFocus$Selector(e);
    this.$SetValueInternal(ListBox.IsSelectionActiveProperty, false);
};

//#endregion

//#region ListItem Notifications

ListBox.Instance.NotifyListItemGotFocus = function (lbi) {
    this._FocusedIndex = this.ItemContainerGenerator.IndexFromContainer(lbi);
};
ListBox.Instance.NotifyListItemLostFocus = function (lbi) {
    this._FocusedIndex = -1;
};

//#endregion

Nullstone.FinishCreate(ListBox);
//#endregion<|endoftext|>


<commit_before>/**
	Given a view where the key is a 6-level date and value is an object,
	renders an html table conformant to the timepedia chronoscope microformat
	(http://timepedia.org/chronoscope/docs/microformats/).

	MANDATORY group_level 1-6 to control grouping

	OPTIONAL table_only [true|false] to disable/enable chronoscope (default enabled)

	@name lists.table_multi
*/
function(head, req) {
	// !json templates
	// !code lib/mustache.js
	// !code lib/stats.js

 	start({"headers":{"Content-Type" : "text/html"}});

	// group_level 6
	// key is rebuilt skipping element 4 as it's a 5-minutes span and
	// is not understood by chronoscope dtformat (better done in the template?)

	var dt = get_dtformat(parseInt(req.query.group_level));
	var table_only = (req.query.table_only && req.query.table_only=='true');

	if (!table_only) {
		send(Mustache.to_html(templates.app_head, {root:app_root(req.path)}));
	}
	send(Mustache.to_html(templates.groups_links, build_group_view(req)));

	var keys = null;
	while(row = getRow()) {
		if (keys == null) {
			keys = [];
			for (var key in row.value) {
				keys.push(key);
			}
			keys.sort();
			send(Mustache.to_html(templates.chronoscope.table_head_multi, {keys: keys, dtformat: dt.dtformat}));
		}
		var values = [];
		keys.forEach(function(k) {
			values.push(row.value[k]);
		});
		send(Mustache.to_html(templates.chronoscope.table_item_multi, {
			key: dt.f_key(row.key),
			value: values
		}));
		send('\n');
	}
	send(Mustache.to_html(templates.chronoscope.table_foot));

	if (!table_only) {
		send(Mustache.to_html(templates.script, {url:'http://api.timepedia.org/widget/'}));
		send(Mustache.to_html(templates.stylesheet, {href: 'http://api.timepedia.org/widget/Chronoscope.css'}));
		send(Mustache.to_html(templates.app_foot));
	}
}<commit_msg>added links to allow easy control of grouping<commit_after>/**
	Given a view where the key is a 6-level date and value is an object,
	renders an html table conformant to the timepedia chronoscope microformat
	(http://timepedia.org/chronoscope/docs/microformats/).

	MANDATORY group_level 1-6 to control grouping

	OPTIONAL table_only [true|false] to disable/enable chronoscope (default enabled)

	@name lists.table_multi
*/
function(head, req) {
	// !json templates
	// !code lib/mustache.js
	// !code lib/stats.js

 	start({"headers":{"Content-Type" : "text/html"}});

	var dt = get_dtformat(parseInt(req.query.group_level));
	var table_only = (req.query.table_only && req.query.table_only=='true');

	if (!table_only) {
		send(Mustache.to_html(templates.app_head, {root:app_root(req.path)}));
	}
	send(Mustache.to_html(templates.groups_links, build_group_view(req)));

	var keys = null;
	while(row = getRow()) {
		if (keys == null) {
			keys = [];
			for (var key in row.value) {
				keys.push(key);
			}
			keys.sort();
			send(Mustache.to_html(templates.chronoscope.table_head_multi, {keys: keys, dtformat: dt.dtformat}));
		}
		var values = [];
		keys.forEach(function(k) {
			values.push(row.value[k]);
		});
		send(Mustache.to_html(templates.chronoscope.table_item_multi, {
			key: dt.f_key(row.key),
			value: values
		}));
		send('\n');
	}
	send(Mustache.to_html(templates.chronoscope.table_foot));

	if (!table_only) {
		send(Mustache.to_html(templates.script, {url:'http://api.timepedia.org/widget/'}));
		send(Mustache.to_html(templates.stylesheet, {href: 'http://api.timepedia.org/widget/Chronoscope.css'}));
		send(Mustache.to_html(templates.app_foot));
	}
}<|endoftext|>


<commit_before>import 'babel-core/register';
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';

import App from './App';

injectTapEventPlugin();
ReactDOM.render(
    <App projectId={config.projectId} token={config.token} secret={config.secret} />,
    document.getElementById('root'),
);
<commit_msg>fix config injection for dev and prod<commit_after>import 'babel-core/register';
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';

import App from './App';

injectTapEventPlugin();

const config = config || {};

ReactDOM.render(
    <App projectId={config.projectId} token={config.token} secret={config.secret} />,
    document.getElementById('root'),
);
<|endoftext|>


<commit_before>#!/usr/local/bin/node

const fs = require('fs-extra')
const meow = require('meow')
const path = require('path')
const spawn = require('projector-spawn')
const promisify = require('util').promisify
const Faced = require('faced')
const faced = new Faced()

const cli = meow(
  `
  Usage: $ tomify <input>

  Options:
    --output, -o Output Path
    --resize, -r Resize Number, 1.25
    --debug, -d Debug

  Examples:
    $ tomify file1.jpg file2.jpg -o ./new-folder
`,
  {
    alias: { h: 'help', o: 'output', d: 'debug', r: 'resize' }
  }
)

/**
 * CLI
 */

if (cli.input.length === 0 && !cli.flags.input) {
  console.error('Specify at least one path')
  process.exit(1)
}
if (!cli.flags.resize) cli.flags.resize = 1
else if (typeof cli.flags.resize !== 'number') {
  console.error('resize must be a number')
  process.exit(1)
}

let dest = cli.flags.output || process.cwd()
fs.ensureDirSync(dest)
console.error('Destination: %s', dest)

/**
 * Build Toms
 */

const toms = []
for (let file of cli.input) {
  toms.push(
    new Promise((resolve, reject) =>
      findFace(file, dest).then(addTom).then(resolve).catch(reject)
    )
  )
}

Promise.all(toms)
  .then(() => console.log('Done!'))
  .catch(err => {
    if (err.stderr) console.error(err.stderr)
    else console.error(err)
    process.exit(err.code || 1)
  })

/**
 * Find all Faces
 */

function findFace(file, dest) {
  return new Promise((resolve, reject) => {
    debug('Processing %s...', file)
    faced.detect(file, (faces, image, file) => {
      if (faces.length === 0) {
        reject(new Error(`Faces not found in ${file}`))
        return
      }

      debug('Face face in %s...', file)
      const face = faces[0]
      const centerX = (face.getX() + (face.getWidth() / 2))
      const centerY = (face.getY() + (face.getHeight() / 2))
      const tomWidth = cli.flags.resize * (face.getWidth() * 1.75)
      const tomHeight = cli.flags.resize * (face.getHeight() * 1.75)
      const x = centerX - (tomWidth / 2)
      const y = centerY - (tomHeight / 2)
      resolve([dest, file, x, y, tomHeight, tomWidth])
    })
  })
}

/**
 * Add Tom to Image
 */

function addTom([dest, file, top, left, height, width]) {
  let meta = path.parse(file)
  dest = path.join(dest, `${meta.name}.gif`)
  console.error('Tomifying %s...', meta.base)
  return spawn(
    'convert',
    [
      file,
      'null:',
      '\(',
      path.join(__dirname, 'tom.gif'),
      '-resize',
      `${height}`,
      '\)',
      '-geometry',
      `+${top}+${left}`,
      '-layers',
      'composite',
      '-delete',
      0,
      '-loop',
      0,
      dest
    ],
    {
      cwd: process.cwd()
    }
  )
}

/**
 * Debug
 */

function debug(msg) {
  if (cli.flags.debug) console.error(msg)
}
<commit_msg>update help text<commit_after>#!/usr/local/bin/node

const fs = require('fs-extra')
const meow = require('meow')
const path = require('path')
const spawn = require('projector-spawn')
const promisify = require('util').promisify
const Faced = require('faced')
const faced = new Faced()

const cli = meow(
  `
  Usage: $ tomify <image>

  Options:
    --output, -o Output Path, default: $PWD
    --resize, -r Resize Tom, default: 1 (Number)
    --debug, -d Debug Mode, default: false
    --help, -h Display Help
    --version Display Version

  Examples:
    $ tomify image.jpg
        # process single image and save to $PWD/image.gif

    $ tomify person1.jpg person2.jpg --output ./new-folder
        # process multiple images, and saves to ./new-folder
`,
  {
    alias: { h: 'help', o: 'output', d: 'debug', r: 'resize' }
  }
)

/**
 * CLI
 */

if (cli.input.length === 0 && !cli.flags.input) {
  console.error('Specify at least one path')
  process.exit(1)
}
if (!cli.flags.resize) cli.flags.resize = 1
else if (typeof cli.flags.resize !== 'number') {
  console.error('resize must be a number')
  process.exit(1)
}

let dest = cli.flags.output || process.cwd()
fs.ensureDirSync(dest)
console.error('Destination: %s', dest)

/**
 * Build Toms
 */

const toms = []
for (let file of cli.input) {
  toms.push(
    new Promise((resolve, reject) =>
      findFace(file, dest).then(addTom).then(resolve).catch(reject)
    )
  )
}

Promise.all(toms)
  .then(() => console.log('Done!'))
  .catch(err => {
    if (err.stderr) console.error(err.stderr)
    else console.error(err)
    process.exit(err.code || 1)
  })

/**
 * Find all Faces
 */

function findFace(file, dest) {
  return new Promise((resolve, reject) => {
    debug('Processing %s...', file)
    faced.detect(file, (faces, image, file) => {
      if (faces.length === 0) {
        reject(new Error(`Faces not found in ${file}`))
        return
      }

      debug('Face face in %s...', file)
      const face = faces[0]
      const centerX = (face.getX() + (face.getWidth() / 2))
      const centerY = (face.getY() + (face.getHeight() / 2))
      const tomWidth = cli.flags.resize * (face.getWidth() * 1.75)
      const tomHeight = cli.flags.resize * (face.getHeight() * 1.75)
      const x = centerX - (tomWidth / 2)
      const y = centerY - (tomHeight / 2)
      resolve([dest, file, x, y, tomHeight, tomWidth])
    })
  })
}

/**
 * Add Tom to Image
 */

function addTom([dest, file, top, left, height, width]) {
  let meta = path.parse(file)
  dest = path.join(dest, `${meta.name}.gif`)
  console.error('Tomifying %s...', meta.base)
  return spawn(
    'convert',
    [
      file,
      'null:',
      '\(',
      path.join(__dirname, 'tom.gif'),
      '-resize',
      `${height}`,
      '\)',
      '-geometry',
      `+${top}+${left}`,
      '-layers',
      'composite',
      '-delete',
      0,
      '-loop',
      0,
      dest
    ],
    {
      cwd: process.cwd()
    }
  )
}

/**
 * Debug
 */

function debug(msg) {
  if (cli.flags.debug) console.error(msg)
}
<|endoftext|>


<commit_before>Package.describe({
  name: 'pntbr:insei',
  version: '0.0.1',
  summary: 'Manage Insei',
  git: 'https://github.com/goacademie/fanhui',
  documentation: 'README.md'
})
Package.onUse(function(api) {
  api.versionsFrom('1.2.1')
  api.use(['ecmascript', 'mongo'])
  api.use(['iron:router', 'templating'], 'client')
  api.addFiles('collection.js')
  api.addFiles([
    'server/slack-token.js',
    'server/record-slack-inseis.js',
    'server/model.js'
  ], 'server')
  api.addFiles([
    'client/router.js',
    'client/inseis.js',
    'client/list-inseis.html',
    'client/list-inseis.js'
  ], 'client')
  api.export('Inseis', 'server')
  api.export([
    'Inseis',
    'isInsei',
    'isSensei',
    'nickSlackFromUrl'
  ], 'client')
})
Package.onTest(function(api) {
  api.use(['ecmascript', 'tinytest'])
  api.use(['iron:router@1.0.0', 'templating'], 'client')
  api.use('pntbr:insei')
  api.addFiles('tests-stubs.js')
  api.addFiles('tests-insei.js', 'client')
})
<commit_msg>Add slack client in inseis package<commit_after>Package.describe({
  name: 'pntbr:insei',
  version: '0.0.1',
  summary: 'Manage Insei',
  git: 'https://github.com/goacademie/fanhui',
  documentation: 'README.md'
})
Package.onUse(function(api) {
  api.versionsFrom('1.2.1')
  api.use(['ecmascript', 'mongo'])
  api.use('hiukim:slack-client', 'server')
  api.use(['iron:router', 'templating'], 'client')
  api.addFiles('collection.js')
  api.addFiles([
    'server/slack-token.js',
    'server/record-slack-inseis.js',
    'server/model.js'
  ], 'server')
  api.addFiles([
    'client/router.js',
    'client/inseis.js',
    'client/list-inseis.html',
    'client/list-inseis.js'
  ], 'client')
  api.export('Inseis', 'server')
  api.export([
    'Inseis',
    'isInsei',
    'isSensei',
    'nickSlackFromUrl'
  ], 'client')
})
Package.onTest(function(api) {
  api.use(['ecmascript', 'tinytest'])
  api.use(['iron:router@1.0.0', 'templating'], 'client')
  api.use('pntbr:insei')
  api.addFiles('tests-stubs.js')
  api.addFiles('tests-insei.js', 'client')
})
<|endoftext|>


<commit_before>//$("#software_chooser_failback").hide();
$("#software_chooser_search_id").show();
$(".new_software_checkbox_block").show();

function Dropdown(referenceElement, targetInputElement, entryList, keyList) {

    this.targetInputElement = targetInputElement;
    this.referenceElement = referenceElement;
    this.isShown = false;
    this.entryList = entryList;

    this.keyList = keyList;
    this.maxResult = 5;

    this.init = function() {
        This = this
        this.targetInputElement.bind('focusin', function() {This.focusin();});
        this.targetInputElement.bind('focusout',  function() {This.focusout();});
        this.targetInputElement.bind('keypress',  function(event) {This.keypress(event);});
        this.targetInputElement.bind('input',  function() {This.change();});
        $("form").bind('keypress',  function(event) {if(event.keyCode == 13 && targetInputElement.is(":focus") ) {return false;}});

        this.maxResult = 5;
    }

    this.show = function() {
        if(this.isShown) {
            return;
        }

        this.isShown = true;
        this.panel = $(document.createElement('div'));
        this.panel.addClass("dropdown_panel");
        //this.panel.html("coucou");

        this.listContainer = $(document.createElement('div'));
        this.listContainer.addClass("list_container");
        this.panel.append(this.listContainer);

        this.resultCount = $(document.createElement('div'));
        this.resultCount.addClass("result_count");
        this.panel.append(this.resultCount);

        this.softwareAdder = $(document.createElement('div'));
        this.softwareAdder.addClass("software_adder");
        this.panel.append(this.softwareAdder);

        referenceElement.append(this.panel)
        this.updateSearch();
    }

    this.hide = function() {
        if(!this.isShown) {
            return;
        }

        this.isShown = false;
        this.panel.remove();
    }

    this.focusin = function() {

        if(this.targetInputElement.val().length > 0) {
            this.show();
        }
    }

    this.focusout = function() {

        userInput = this.targetInputElement.val();
        if(userInput.length == 0) {
            var that = this;

            window.setTimeout(function() {
            that.hide()
            }, 150);
        } else if(this.hasExactMatch) {
            this.chooseSelection();
        }

    }

    this.keypress = function(event) {

        console.log("key event"+ event.keyCode);
        if(event.keyCode == 27) {
            this.hide();
            return false;
        }
        if(event.keyCode == 13 && this.isShown) {
            this.chooseSelection();
            return false;
        }

        if(event.keyCode == 40) {
            if(this.isShown) {
                this.selectNext();
            } else {
                this.show();
            }
        }

        if(event.keyCode == 38) {
            if(this.isShown) {
                this.selectPrevious();
            }
        }

        if(event.which != 0) {
            this.show();
        }
    }

    this.change = function() {
        this.updateSearch();
    }

    this.updateSearch = function() {
        userInput = this.targetInputElement.val();
        console.log("update search: "+ userInput);

        this.hasExactMatch = false;
        this.emptyList()

        if(userInput.length == 0) {
            for(var i = 0; i < this.entryList.length; i++) {
                var entry = this.entryList[i];
                this.addLine(i,entry, '', '');
            }
        } else {
            regexp = new RegExp("^(.*)("+userInput+")(.*)$","i");

            for(var i = 0; i < this.entryList.length; i++) {
                var entry = this.entryList[i];
                var match = regexp.exec(entry);

                if(match != null) {
                    if(match[1].length == 0 && match[3].length == 0) {
                        this.hasExactMatch = true;
                    }

                    this.addLine(i, match[1], match[2], match[3]  )
                }
            }
        }

        tomComment = "";
        if(userInput.length < 3) {
            tomComment = '
The sofware name must have at least 3 characters
';
        } else if(this.activeList.length == 0 && userInput[0].toLowerCase() == userInput[0]) {
             tomComment = '
A sofware name is often prettier with a capital
';
        }
        this.softwareAdder.html("
Add "+userInput+" to Elveos
"+tomComment);

        adder = $(this.softwareAdder.children()[0]);
        adder.bind('click', function() {
                This.select('new');
                if(userInput.length > 0  && !This.hasExactMatch) {
                    This.chooseSelection();
                }
                return false;
            });

        adder.bind('mouseover', function() {
            This.select('new');
            return false;
        });

        if(this.activeList.length > 0) {
            this.select(0);

            var extraResult = this.activeList.length - this.maxResult;

            if(extraResult <= 0 ) {
                this.resultCount.html("no additional results");
            } else if (extraResult == 1) {
                this.resultCount.html("1 additionnal results");
            } else {
                this.resultCount.html(extraResult+" additionnal results");
            }

        } else {
            this.resultCount.html("no results");
            this.select("new");
        }

        if(userInput.length < 3 || this.hasExactMatch && !$(this.softwareAdder.children()[0]).hasClass('entry_disabled')) {
               $(this.softwareAdder.children()[0]).addClass('entry_disabled');
        } else if(!this.hasExactMatch && $(this.softwareAdder.children()[0]).hasClass('entry_disabled')) {
                $(this.softwareAdder.children()[0]).removeClass('entry_disabled');
        }

    }

    this.emptyList = function() {
        this.listContainer.empty();
        this.activeList = new Array();
        this.selection = -1;
    }

    this.addLine = function(index, preMatch, matchString, postMatch) {

        this.activeList.push(index);
        var currentIndex = this.activeList.length-1

        if(this.activeList.length <= this.maxResult) {
            line = $(document.createElement('p'));
            line.html(preMatch+''+matchString+''+postMatch);

            var This = this;

            line.bind('click', function() {
                console.log('click');
                This.select(currentIndex);
                This.chooseSelection();
                return false;
            });

            line.bind('mouseover', function() {
                This.select(currentIndex);
                return false;
            });

            this.listContainer.append(line);
        }

    }

    this.select = function(index) {

        if(index == "new") {
            if(userInput.length < 3 || this.hasExactMatch) {
                return;
            }

            if(!$(this.softwareAdder.children()[0]).hasClass('entry_selected')) {
                    $(this.softwareAdder.children()[0]).addClass('entry_selected');
            }

            var children = this.listContainer.children()
            for(var i = 0; i < children.length; i++) {
                var child = $(children[i]);
                if(child.hasClass('entry_selected')) {
                    child.removeClass('entry_selected');
                }
            }

            this.selection = 'new';

        } else {

            if(index >= this.activeList.length || index >= this.maxResult || index < 0) {
                return;
            }

            this.selection = index;

            if($(this.softwareAdder.children()[0]).hasClass('entry_selected')) {
                    $(this.softwareAdder.children()[0]).removeClass('entry_selected');
            }

            var children = this.listContainer.children()
            for(var i = 0; i < children.length; i++) {
                var child = $(children[i]);
                if(i == index) {
                    if(!child.hasClass('entry_selected')) {
                        child.addClass('entry_selected');
                    }
                } else {
                   if(child.hasClass('entry_selected')) {
                        child.removeClass('entry_selected');
                    }
                }
            }
        }

    }

    this.selectNext = function() {
        if(this.selection != 'new') {
            if(this.selection+1  >= this.maxResult || this.selection+1 >= this.activeList.length) {
                this.select("new");
            } else {
                this.select(this.selection+1);
            }
        }

    }

    this.selectPrevious = function() {
        if(this.selection == 'new') {
            if(this.activeList.length  > this.maxResult) {
                this.select(this.maxResult -1)
            } else {
                this.select(this.activeList.length -1)
            }
        } else {
            this.select(this.selection-1);
        }
    }

    this.chooseSelection = function() {
        if(this.selection == -1) {
            return;
        }

        this.targetInputElement.val(this.entryList[this.activeList[this.selection]]);
        this.valueChange(this.keyList[this.activeList[this.selection]]);
        this.hasExactMatch = true;
        this.hide();

    }

    this.cancel = function() {
        if(!this.hasExactMatch) {
            this.targetInputElement.val("");
        }

        this.hide();
    }

    this.valueChange = function() {
        //To overwrite
    }

    this.init()
}

var softwareNameList = ${software_name_list};
var softwareIdList = ${software_id_list};

var dropdown = new Dropdown($("#software_chooser_block_id"), $("#software_chooser_search_id"), softwareNameList,softwareIdList );

dropdown.valueChange = function(value) {
    $("#software_chooser_failback").val(value)
}

$("#software_chooser_checkbox_id").click (function () {
    var thisCheck = $(this);
    if (thisCheck.is (':checked'))
    {
        dropdown.cancel()
        $("#software_chooser_search_id").hide();
        $("#software_chooser_failback").val("")

    } else {
        $("#software_chooser_search_id").show();
    }
});

<commit_msg>improve dropdown order<commit_after>//$("#software_chooser_failback").hide();
$("#software_chooser_search_id").show();
$(".new_software_checkbox_block").show();

Array.prototype.contains = function (element) {
for (var i = 0; i < this.length; i++) {
    if (this[i] == element) {
        return true;
    }
    }
    return false;
}

function Dropdown(referenceElement, targetInputElement, entryList, keyList) {

    this.targetInputElement = targetInputElement;
    this.referenceElement = referenceElement;
    this.isShown = false;
    this.entryList = entryList;

    this.keyList = keyList;
    this.maxResult = 5;

    this.init = function() {
        This = this
        this.targetInputElement.bind('focusin', function() {This.focusin();});
        this.targetInputElement.bind('focusout',  function() {This.focusout();});
        this.targetInputElement.bind('keypress',  function(event) {This.keypress(event);});
        this.targetInputElement.bind('input',  function() {This.change();});
        $("form").bind('keypress',  function(event) {if(event.keyCode == 13 && targetInputElement.is(":focus") ) {return false;}});

        this.maxResult = 5;
    }

    this.show = function() {
        if(this.isShown) {
            return;
        }

        this.isShown = true;
        this.panel = $(document.createElement('div'));
        this.panel.addClass("dropdown_panel");
        //this.panel.html("coucou");

        this.listContainer = $(document.createElement('div'));
        this.listContainer.addClass("list_container");
        this.panel.append(this.listContainer);

        this.resultCount = $(document.createElement('div'));
        this.resultCount.addClass("result_count");
        this.panel.append(this.resultCount);

        this.softwareAdder = $(document.createElement('div'));
        this.softwareAdder.addClass("software_adder");
        this.panel.append(this.softwareAdder);

        referenceElement.append(this.panel)
        this.updateSearch();
    }

    this.hide = function() {
        if(!this.isShown) {
            return;
        }

        this.isShown = false;
        this.panel.remove();
    }

    this.focusin = function() {

        if(this.targetInputElement.val().length > 0) {
            this.show();
        }
    }

    this.focusout = function() {

        userInput = this.targetInputElement.val();
        if(userInput.length == 0) {
            var that = this;

            window.setTimeout(function() {
            that.hide()
            }, 150);
        } else if(this.hasExactMatch) {
            this.chooseSelection();
        }

    }

    this.keypress = function(event) {

        console.log("key event"+ event.keyCode);
        if(event.keyCode == 27) {
            this.hide();
            return false;
        }
        if(event.keyCode == 13 && this.isShown) {
            this.chooseSelection();
            return false;
        }

        if(event.keyCode == 40) {
            if(this.isShown) {
                this.selectNext();
            } else {
                this.show();
            }
        }

        if(event.keyCode == 38) {
            if(this.isShown) {
                this.selectPrevious();
            }
        }

        if(event.which != 0) {
            this.show();
        }
    }

    this.change = function() {
        this.updateSearch();
    }

    this.updateSearch = function() {
        userInput = this.targetInputElement.val();
        console.log("update search: "+ userInput);

        this.hasExactMatch = false;
        this.emptyList()

        if(userInput.length == 0) {
            for(var i = 0; i < this.entryList.length; i++) {
                var entry = this.entryList[i];
                this.addLine(i,entry, '', '');
            }
        } else {
            regexp1 = new RegExp("^()("+userInput+")(.*)$","i");
            this.addLinesWithRegExp(regexp1)

            regexp2 = new RegExp("^(.*)("+userInput+")(.*)$","i");
            this.addLinesWithRegExp(regexp2)

        }

        tomComment = "";
        if(userInput.length < 3) {
            tomComment = '
The sofware name must have at least 3 characters
';
        } else if(this.activeList.length == 0 && userInput[0].toLowerCase() == userInput[0]) {
             tomComment = '
A sofware name is often prettier with a capital
';
        }
        this.softwareAdder.html("
Add "+userInput+" to Elveos
"+tomComment);

        adder = $(this.softwareAdder.children()[0]);
        adder.bind('click', function() {
                This.select('new');
                if(userInput.length > 0  && !This.hasExactMatch) {
                    This.chooseSelection();
                }
                return false;
            });

        adder.bind('mouseover', function() {
            This.select('new');
            return false;
        });

        if(this.activeList.length > 0) {
            this.select(0);

            var extraResult = this.activeList.length - this.maxResult;

            if(extraResult <= 0 ) {
                this.resultCount.html("no additional results");
            } else if (extraResult == 1) {
                this.resultCount.html("1 additionnal results");
            } else {
                this.resultCount.html(extraResult+" additionnal results");
            }

        } else {
            this.resultCount.html("no results");
            this.select("new");
        }

        if(userInput.length < 3 || this.hasExactMatch && !$(this.softwareAdder.children()[0]).hasClass('entry_disabled')) {
               $(this.softwareAdder.children()[0]).addClass('entry_disabled');
        } else if(!this.hasExactMatch && $(this.softwareAdder.children()[0]).hasClass('entry_disabled')) {
                $(this.softwareAdder.children()[0]).removeClass('entry_disabled');
        }

    }

    this.emptyList = function() {
        this.listContainer.empty();
        this.activeList = new Array();
        this.selection = -1;
    }

    this.addLinesWithRegExp = function(regexp) {
        for(var i = 0; i < this.entryList.length; i++) {
                var entry = this.entryList[i];
                var match = regexp.exec(entry);

                if(match != null) {
                    if(match[1].length == 0 && match[3].length == 0) {
                        this.hasExactMatch = true;
                    }

                    this.addLine(i, match[1], match[2], match[3]  )
                }
            }
        }

    this.addLine = function(index, preMatch, matchString, postMatch) {

        if(this.activeList.contains(index)) {
            return;
        }

        this.activeList.push(index);
        var currentIndex = this.activeList.length-1

        if(this.activeList.length <= this.maxResult) {
            line = $(document.createElement('p'));
            line.html(preMatch+''+matchString+''+postMatch);

            var This = this;

            line.bind('click', function() {
                console.log('click');
                This.select(currentIndex);
                This.chooseSelection();
                return false;
            });

            line.bind('mouseover', function() {
                This.select(currentIndex);
                return false;
            });

            this.listContainer.append(line);
        }

    }

    this.select = function(index) {

        if(index == "new") {
            if(userInput.length < 3 || this.hasExactMatch) {
                return;
            }

            if(!$(this.softwareAdder.children()[0]).hasClass('entry_selected')) {
                    $(this.softwareAdder.children()[0]).addClass('entry_selected');
            }

            var children = this.listContainer.children()
            for(var i = 0; i < children.length; i++) {
                var child = $(children[i]);
                if(child.hasClass('entry_selected')) {
                    child.removeClass('entry_selected');
                }
            }

            this.selection = 'new';

        } else {

            if(index >= this.activeList.length || index >= this.maxResult || index < 0) {
                return;
            }

            this.selection = index;

            if($(this.softwareAdder.children()[0]).hasClass('entry_selected')) {
                    $(this.softwareAdder.children()[0]).removeClass('entry_selected');
            }

            var children = this.listContainer.children()
            for(var i = 0; i < children.length; i++) {
                var child = $(children[i]);
                if(i == index) {
                    if(!child.hasClass('entry_selected')) {
                        child.addClass('entry_selected');
                    }
                } else {
                   if(child.hasClass('entry_selected')) {
                        child.removeClass('entry_selected');
                    }
                }
            }
        }

    }

    this.selectNext = function() {
        if(this.selection != 'new') {
            if(this.selection+1  >= this.maxResult || this.selection+1 >= this.activeList.length) {
                this.select("new");
            } else {
                this.select(this.selection+1);
            }
        }

    }

    this.selectPrevious = function() {
        if(this.selection == 'new') {
            if(this.activeList.length  > this.maxResult) {
                this.select(this.maxResult -1)
            } else {
                this.select(this.activeList.length -1)
            }
        } else {
            this.select(this.selection-1);
        }
    }

    this.chooseSelection = function() {
        if(this.selection == -1) {
            return;
        }

        this.targetInputElement.val(this.entryList[this.activeList[this.selection]]);
        this.valueChange(this.keyList[this.activeList[this.selection]]);
        this.hasExactMatch = true;
        this.hide();

    }

    this.cancel = function() {
        if(!this.hasExactMatch) {
            this.targetInputElement.val("");
        }

        this.hide();
    }

    this.valueChange = function() {
        //To overwrite
    }

    this.init()
}

var softwareNameList = ${software_name_list};
var softwareIdList = ${software_id_list};

var dropdown = new Dropdown($("#software_chooser_block_id"), $("#software_chooser_search_id"), softwareNameList,softwareIdList );

dropdown.valueChange = function(value) {
    $("#software_chooser_failback").val(value)
}

$("#software_chooser_checkbox_id").click (function () {
    var thisCheck = $(this);
    if (thisCheck.is (':checked'))
    {
        dropdown.cancel()
        $("#software_chooser_search_id").hide();
        $("#software_chooser_failback").val("")

    } else {
        $("#software_chooser_search_id").show();
    }
});

<|endoftext|>


<commit_before>import { EventEmitter } from 'events';
import AppDispatcher from '../dispatchers/AppDispatcher';

export default class BaseStore extends EventEmitter {

    constructor(modelName, fetchMethod) {
        super();

        // the fetched data
        this._modelData = [];
        // the model name
        this._modelName = modelName;
        // the method to fetch the data of this model
        this._fetchMethod = fetchMethod;

        // the data to fetch
        this._filters = {length: 0};

        // binding
        this._delete = this._delete.bind(this);
        this._set = this._set.bind(this);
    }

    subscribe(actionSubscribe) {
        this._dispatchToken = AppDispatcher.register(actionSubscribe());
    }

    get dispatchToken() {
        return this._dispatchToken;
    }

    emitChange() {
        this.emit('CHANGE');
    }

    addChangeListener(cb) {
        this.on('CHANGE', cb)
    }

    removeChangeListener(cb) {
        this.removeListener('CHANGE', cb);
    }

    /**
     * Use the fetchMethod to fetch the data needed of this model.
     *
     * @param {number} [componentToken]: the new component
     * @return {Promise}
     */
    fetchData(componentToken) {

        return new Promise((resolve, reject) => {
            let filters = this.getFiltersSet();

            // No need to ask the server if there is no filter
            if(Array.isArray(filters) && filters.length === 0) {
                this._setModelData([]);
            }
            else {
                // Check if the new filter already exist
                let fetch = true;
                if(componentToken !== null) {
                    for (let index in this._filters) {
                        if (index !== 'length' && index != componentToken &&
                        (this._filters[index] === null || Object.is(this._filters[index], this._filters[componentToken]))) {
                            console.log(this._filters, index, componentToken, '0', 0);
                            fetch = false;
                            break;
                        }
                    }
                }
                else {
                    // If there a filter has been deleted, then only refresh if there is no "null" filter
                    for (let index in this._filters) {
                        if (index !== 'length' && this._filters[index] === null) {
                            console.log(this._filters, index);
                            fetch = false;
                            break;
                        }
                    }
                }

                // Fetch from the server only if it use usefull
                if(fetch) {
                    console.log('fetch', this._modelName, this.getFiltersSet());
                    this._fetchMethod(this.getFiltersSet())
                        .then(result => {
                            this._setModelData(result);

                            // listen model changes
                            iosocket.on(this._modelName, this._handleModelEvents);

                            resolve({
                                result: this.find(this._filters[componentToken]),
                                token: componentToken
                            });
                        })
                        .catch(error => reject(error));
                }
                else {
                    resolve({
                        result: this.find(this._filters[componentToken]),
                        token: componentToken
                    });
                }
            }
        });
    }

    /**
     * Add new filters and fetch the data to get the new asked data
     *
     * @param {Array|null} filters: new the data to get
     * @returns {Promise}
     */
    loadData(filters) {
        const componentToken = this._filters.length;
        this._filters.length++;
        this._filters[componentToken] = filters;
        // refresh the store with the new filters
        return this.fetchData(componentToken);
    }

    /**
     * Remove the data used only for the component which has this token
     * This function can be called safely with a null token
     *
     * @param {number|null} token: the component's token
     */
    unloadData(token) {
        if(this._filters[token]) {
            // Delete filter
            delete this._filters[token];
            // reload only the data needed
            this.fetchData();
        }
    }

    /**
     * From this._filters, return an array of unique filters
     * Or null if one filter is null
     *
     * @returns {Array|null}
     */
    getFiltersSet() {
        let filters = [];
        for (let filter in this._filters) {
            if (this._filters[filter] === null) {
                filters = null;
                break;
            }
            filters = [...new Set([...filters, ...this._filters[filter]])];
        }
        return filters;
    }

    /**
     * Delete an item in modelData by id
     * @param {string} id: the item id
     */
    _delete(id) {
        delete this._modelData[id];
        this.emitChange();
    }

    /**
     * Add or update an item
     * @param {string} id: the item id
     * @param {object} data: the item data
     */
    _set(id, data) {
        this._modelData[id] = data;
        this.emitChange();
    }

    /**
     * From an array of objects, create an array where the key is
     * the object id and the value is the object
     *
     * @param {Array} data: array of objects
     */
    _setModelData(data) {
        let newModelData = [];
        for (let item of data) {
            newModelData[item.id] = item;
        }
        this._modelData = newModelData;
        this.emitChange();
    }

    /**
     * Find a data in the store by his id
     *
     * @param {string} id: the requested data id
     * @returns {object|undefined}
     */
    findById(id) {
        return this._modelData[id];
    }

    /**
     * Find list of elements that match filters
     *
     * @param  {Object} filters: Object of filters
     * @return {Array} Array of elements
     */
    find(filters) {
        let out = [];

        for (let i in this._modelData) {
            let add = true;
            for (let key in filters) {
                if(this._modelData[i][key] !== filters[key]) {
                    add = false;
                    break;
                }
            }
            if(add) {
                out.push(this._modelData[i]);
            }
        }

        return out;
    }

    /**
     * Return the first element that matches the filters
     *
     * @param {Object} filters: Object of filters
     * @return {Object|null} the object found or null by default
     */
    findOne(filters) {
        for (let i in this._modelData) {
            let add = true;
            for (let key in filters) {
                if(this._modelData[i][key] !== filters[key]) {
                    add = false;
                    break;
                }
            }
            if(add) {
                return this._modelData[i];
            }
        }

        return null;
    }

    /**
     * Return a classic Array from the indexed objects in modelData
     *
     * @returns {Array}
     */
    getUnIndexedData() {
        let out = [];

        for (let i in this._modelData) {
            out.push(this._modelData[i]);
        }

        return out;
    }
}
<commit_msg>Fix unload on null filters<commit_after>import { EventEmitter } from 'events';
import AppDispatcher from '../dispatchers/AppDispatcher';

export default class BaseStore extends EventEmitter {

    constructor(modelName, fetchMethod) {
        super();

        // the fetched data
        this._modelData = [];
        // the model name
        this._modelName = modelName;
        // the method to fetch the data of this model
        this._fetchMethod = fetchMethod;

        // the data to fetch
        this._filters = {length: 0};

        // binding
        this._delete = this._delete.bind(this);
        this._set = this._set.bind(this);
    }

    subscribe(actionSubscribe) {
        this._dispatchToken = AppDispatcher.register(actionSubscribe());
    }

    get dispatchToken() {
        return this._dispatchToken;
    }

    emitChange() {
        this.emit('CHANGE');
    }

    addChangeListener(cb) {
        this.on('CHANGE', cb)
    }

    removeChangeListener(cb) {
        this.removeListener('CHANGE', cb);
    }

    /**
     * Use the fetchMethod to fetch the data needed of this model.
     *
     * @param {number} [componentToken]: the new component
     * @return {Promise}
     */
    fetchData(componentToken) {

        return new Promise((resolve, reject) => {
            let filters = this.getFiltersSet();

            // No need to ask the server if there is no filter
            if(Array.isArray(filters) && filters.length === 0) {
                this._setModelData([]);
            }
            else {
                // Check if the new filter already exist
                let fetch = true;
                if(componentToken !== null) {
                    for (let index in this._filters) {
                        if (index !== 'length' && index != componentToken &&
                        (this._filters[index] === null || Object.is(this._filters[index], this._filters[componentToken]))) {
                            console.log(this._filters, index, componentToken, '0', 0);
                            fetch = false;
                            break;
                        }
                    }
                }
                else {
                    // If there a filter has been deleted, then only refresh if there is no "null" filter
                    for (let index in this._filters) {
                        if (index !== 'length' && this._filters[index] === null) {
                            console.log(this._filters, index);
                            fetch = false;
                            break;
                        }
                    }
                }

                // Fetch from the server only if it use usefull
                if(fetch) {
                    console.log('fetch', this._modelName, this.getFiltersSet());
                    this._fetchMethod(this.getFiltersSet())
                        .then(result => {
                            this._setModelData(result);

                            // listen model changes
                            iosocket.on(this._modelName, this._handleModelEvents);

                            resolve({
                                result: this.find(this._filters[componentToken]),
                                token: componentToken
                            });
                        })
                        .catch(error => reject(error));
                }
                else {
                    resolve({
                        result: this.find(this._filters[componentToken]),
                        token: componentToken
                    });
                }
            }
        });
    }

    /**
     * Add new filters and fetch the data to get the new asked data
     *
     * @param {Array|null} filters: new the data to get
     * @returns {Promise}
     */
    loadData(filters) {
        const componentToken = this._filters.length;
        this._filters.length++;
        this._filters[componentToken] = filters;
        // refresh the store with the new filters
        return this.fetchData(componentToken);
    }

    /**
     * Remove the data used only for the component which has this token
     * This function can be called safely with a null token
     *
     * @param {number|null} token: the component's token
     */
    unloadData(token) {
        if(this._filters[token] !== undefined) {
            // Delete filter
            delete this._filters[token];
            // reload only the data needed
            this.fetchData();
        }
    }

    /**
     * From this._filters, return an array of unique filters
     * Or null if one filter is null
     *
     * @returns {Array|null}
     */
    getFiltersSet() {
        let filters = [];
        for (let filter in this._filters) {
            if (this._filters[filter] === null) {
                filters = null;
                break;
            }
            filters = [...new Set([...filters, ...this._filters[filter]])];
        }
        return filters;
    }

    /**
     * Delete an item in modelData by id
     * @param {string} id: the item id
     */
    _delete(id) {
        delete this._modelData[id];
        this.emitChange();
    }

    /**
     * Add or update an item
     * @param {string} id: the item id
     * @param {object} data: the item data
     */
    _set(id, data) {
        this._modelData[id] = data;
        this.emitChange();
    }

    /**
     * From an array of objects, create an array where the key is
     * the object id and the value is the object
     *
     * @param {Array} data: array of objects
     */
    _setModelData(data) {
        let newModelData = [];
        for (let item of data) {
            newModelData[item.id] = item;
        }
        this._modelData = newModelData;
        this.emitChange();
    }

    /**
     * Find a data in the store by his id
     *
     * @param {string} id: the requested data id
     * @returns {object|undefined}
     */
    findById(id) {
        return this._modelData[id];
    }

    /**
     * Find list of elements that match filters
     *
     * @param  {Object} filters: Object of filters
     * @return {Array} Array of elements
     */
    find(filters) {
        let out = [];

        for (let i in this._modelData) {
            let add = true;
            for (let key in filters) {
                if(this._modelData[i][key] !== filters[key]) {
                    add = false;
                    break;
                }
            }
            if(add) {
                out.push(this._modelData[i]);
            }
        }

        return out;
    }

    /**
     * Return the first element that matches the filters
     *
     * @param {Object} filters: Object of filters
     * @return {Object|null} the object found or null by default
     */
    findOne(filters) {
        for (let i in this._modelData) {
            let add = true;
            for (let key in filters) {
                if(this._modelData[i][key] !== filters[key]) {
                    add = false;
                    break;
                }
            }
            if(add) {
                return this._modelData[i];
            }
        }

        return null;
    }

    /**
     * Return a classic Array from the indexed objects in modelData
     *
     * @returns {Array}
     */
    getUnIndexedData() {
        let out = [];

        for (let i in this._modelData) {
            out.push(this._modelData[i]);
        }

        return out;
    }
}
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-6 01:00:02<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom'
import Header from './Header'
import Content from './Content'

class Index extends Component {
    render() {
        return (

                <Content />

        )
    }
}

ReactDOM.render(
    <Index />,
    document.getElementById('root')
);
<commit_msg>在context中设置store<commit_after>import React, {Component} from 'react'
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom'
import Header from './Header'
import Content from './Content'

// 生成 store
function createStore(reducer) {
    let state = null;
    const listeners = [];
    const subscribe = (listener) => listeners.push(listener);
    const getState = () => state;
    const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach((listener) => {
            listener();
        });
    };
    dispatch({});   // 初始化 state
    return {
        getState,
        dispatch,
        subscribe
    }
}

const themeReducer = (state, action) => {
    if (!state) {
        return {
            themeColor: 'red'
        }
    }
    switch (action.type) {
        case 'CHANGE_COLOR':
            return {
                ...state,
                themeColor: action.themeColor
            };
        default:
            return state;
    }
};

const store = createStore(themeReducer);

class Index extends Component {

    static childContextTypes = {
        store: PropTypes.object
    };

    getChildContext() {
        return {
            store
        }
    }

    render() {
        return (

                <Content />

        )
    }
}

ReactDOM.render(
    <Index />,
    document.getElementById('root')
);
<|endoftext|>


<commit_before>'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var react = require('react-tools');

module.exports = function (name) {
	return through.obj(function (file, enc, cb) {
		if (file.isNull()) {
			this.push(file);
			return cb();
		}

		if (file.isStream()) {
			this.emit('error', new gutil.PluginError('gulp-react', 'Streaming not supported'));
			return cb();
		}

		try {
			file.contents = new Buffer(react.transform(file.contents.toString()));
			file.path = gutil.replaceExtension(file.path, '.js');
		} catch (err) {
			this.emit('error', new gutil.PluginError('gulp-react', err));
		}

		this.push(file);
		cb();
	});
};
<commit_msg>Set file.path as the error object's .fileName<commit_after>'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var react = require('react-tools');

module.exports = function (name) {
	return through.obj(function (file, enc, cb) {
		if (file.isNull()) {
			this.push(file);
			return cb();
		}

		if (file.isStream()) {
			this.emit('error', new gutil.PluginError('gulp-react', 'Streaming not supported'));
			return cb();
		}

		try {
			file.contents = new Buffer(react.transform(file.contents.toString()));
			file.path = gutil.replaceExtension(file.path, '.js');
		} catch (err) {
			err.fileName = file.path;
			this.emit('error', new gutil.PluginError('gulp-react', err));
		}

		this.push(file);
		cb();
	});
};
<|endoftext|>


<commit_before>'use strict';

var File = require('vinyl');
var assert = require('assert');
var dest = require('./');

describe('dest()', function () {
  it('should not modify the destination path when nothing is defined:', function (cb) {
    var stream = dest();
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.md');
      cb();
    });
    stream.end();
  });

  it('should set the destination base to the given filepath:', function (cb) {
    var stream = dest('dist');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.md');
      cb();
    });
    stream.end();
  });

  it('should use options.base:', function (cb) {
    var stream = dest({base: 'foo/'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'foo/post.md');
      cb();
    });
    stream.end();
  });

  it('should set the destination extension with `ext`:', function (cb) {
    var stream = dest({ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.html');
      cb();
    });
    stream.end();
  });

  it('should set the destination extension with `extname`:', function (cb) {
    var stream = dest({extname: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.html');
      cb();
    });
    stream.end();
  });

  it('should use the properties defined in the options:', function (cb) {
    var stream = dest('dist', {basename: 'foo', ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.html');
      cb();
    });
    stream.end();
  });

  it('should work with double extensions:', function (cb) {
    var stream = dest('dist/');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.min.js'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.min.js');
      cb();
    });
    stream.end();
  });

  it('should work with double extensions:', function (cb) {
    var stream = dest('dist', {basename: 'foo', ext: '.min.js'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.min.js');
      cb();
    });
    stream.end();
  });

  it('should set the destination path and extension:', function (cb) {
    var stream = dest('dist', {ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.html');
      cb();
    });
    stream.end();
  });

  it('should substitute `:props` with file path parts:', function (cb) {
    var stream = dest('dist/:name.foo');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.foo');
      cb();
    });
    stream.end();
  });

  it('should substitute `:props` with options props:', function (cb) {
    var stream = dest(':dir/:name.:a:b:c', {dir: 'dist', a: 'A', b: 'B', c: 'C'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.ABC');
      cb();
    });
    stream.end();
  });

  it('should allow a function to be used:', function (cb) {
    var stream = dest('dist/:name', function (file, parsed) {
      file.name = 'foo.bar';
      return file;
    });

    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.bar');
      cb();
    });
    stream.end();
  });
});
<commit_msg>lint tests<commit_after>'use strict';

require('mocha');
var File = require('vinyl');
var assert = require('assert');
var dest = require('./');

describe('dest()', function () {
  it('should not modify the destination path when nothing is defined:', function (cb) {
    var stream = dest();
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.md');
      cb();
    });
    stream.end();
  });

  it('should set the destination base to the given filepath:', function (cb) {
    var stream = dest('dist');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.md');
      cb();
    });
    stream.end();
  });

  it('should use options.base:', function (cb) {
    var stream = dest({base: 'foo/'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'foo/post.md');
      cb();
    });
    stream.end();
  });

  it('should set the destination extension with `ext`:', function (cb) {
    var stream = dest({ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.html');
      cb();
    });
    stream.end();
  });

  it('should set the destination extension with `extname`:', function (cb) {
    var stream = dest({extname: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'post.html');
      cb();
    });
    stream.end();
  });

  it('should use the properties defined in the options:', function (cb) {
    var stream = dest('dist', {basename: 'foo', ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.html');
      cb();
    });
    stream.end();
  });

  it('should work with double extensions:', function (cb) {
    var stream = dest('dist/');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.min.js'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.min.js');
      cb();
    });
    stream.end();
  });

  it('should work with double extensions:', function (cb) {
    var stream = dest('dist', {basename: 'foo', ext: '.min.js'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.min.js');
      cb();
    });
    stream.end();
  });

  it('should set the destination path and extension:', function (cb) {
    var stream = dest('dist', {ext: '.html'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.html');
      cb();
    });
    stream.end();
  });

  it('should substitute `:props` with file path parts:', function (cb) {
    var stream = dest('dist/:name.foo');
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.foo');
      cb();
    });
    stream.end();
  });

  it('should substitute `:props` with options props:', function (cb) {
    var stream = dest(':dir/:name.:a:b:c', {dir: 'dist', a: 'A', b: 'B', c: 'C'});
    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/post.ABC');
      cb();
    });
    stream.end();
  });

  it('should allow a function to be used:', function (cb) {
    var stream = dest('dist/:name', function (file, parsed) {
      file.name = 'foo.bar';
      return file;
    });

    var buffer = [];

    stream.write(new File({
      base: __dirname,
      path: __dirname + '/post.md'
    }));

    stream.on('data', function (file) {
      buffer.push(file);
    });

    stream.on('end', function () {
      assert.equal(buffer.length, 1);
      assert.equal(buffer[0].relative, 'dist/foo.bar');
      cb();
    });
    stream.end();
  });
});
<|endoftext|>


<commit_before>import test from 'ava';
import pathExists from 'path-exists';
import fn from './';

test('meme', t => {
	await fn('Don\t forget to be awesome', {delay: 500, background: '#1d2628', filename: 'out.gif'});

	t.true(pathExists.sync('out.gif'));
});
<commit_msg>add support for :heart_eyes:<commit_after>import test from 'ava';
import pathExists from 'path-exists';
import fn from './';

test('meme', t => {
	await fn('Don\'t forget to be awesome', {delay: 500, background: '#1d2628', filename: 'out.gif'});

	t.true(pathExists.sync('out.gif'));
});
<|endoftext|>


<commit_before>require('dotenv').config();
var body_parser = require('body-parser');
var express = require('express');
var flip = require('flip');
var qs = require('qs');
var request = require('request');

if (!process.env.APP_CLIENT_ID || !process.env.APP_CLIENT_SECRET || !process.env.PORT) {
  console.log('Error: Specify APP_CLIENT_ID, APP_CLIENT_SECRET, and PORT in environment');
  process.exit(1);
}

var app = express();
app.use(body_parser.json());
app.use(body_parser.urlencoded({ extended: true }));

// Handle oauth flow
app.get('/oauth', function(req, res) {
  var url = 'https://slack.com/api/oauth.access?' + qs.stringify({
    client_id: process.env.APP_CLIENT_ID,
    client_secret: process.env.APP_CLIENT_SECRET,
    code: req.query.code,
  });

  request.post(url, function(err, http, body) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Success!');
    }
  });
});

// Respond to webhooks
app.post('/webhook', function(req, res) {
  if (!req.body.token === process.env.APP_COMMAND_TOKEN) return res.sendStatus(403);
  if (!req.body.command || !req.body.command.startsWith('/tableflip')) return res.sendStatus(200);

  var flipped_text = flip(req.body.text) || '┻━┻';
  var response_text =  '(╯°□°）╯︵ ' + flipped_text;

  // Send our actual response async
  request({
    body: {
      response_type: 'in_channel',
      text: response_text,
    },
    json: true,
    method: 'post',
    uri: req.body.response_url,
  });

  // Let Slack know we didn't timeout
  res.send();
});

app.listen(process.env.PORT, function() {
  console.log('Server up...', host, port);
});

app.get('health', function(req, res) {
  res.send('Ok');
});
<commit_msg>Fix server message<commit_after>require('dotenv').config();
var body_parser = require('body-parser');
var express = require('express');
var flip = require('flip');
var qs = require('qs');
var request = require('request');

if (!process.env.APP_CLIENT_ID || !process.env.APP_CLIENT_SECRET || !process.env.PORT) {
  console.log('Error: Specify APP_CLIENT_ID, APP_CLIENT_SECRET, and PORT in environment');
  process.exit(1);
}

var app = express();
app.use(body_parser.json());
app.use(body_parser.urlencoded({ extended: true }));

// Handle oauth flow
app.get('/oauth', function(req, res) {
  var url = 'https://slack.com/api/oauth.access?' + qs.stringify({
    client_id: process.env.APP_CLIENT_ID,
    client_secret: process.env.APP_CLIENT_SECRET,
    code: req.query.code,
  });

  request.post(url, function(err, http, body) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Success!');
    }
  });
});

// Respond to webhooks
app.post('/webhook', function(req, res) {
  if (!req.body.token === process.env.APP_COMMAND_TOKEN) return res.sendStatus(403);
  if (!req.body.command || !req.body.command.startsWith('/tableflip')) return res.sendStatus(200);

  var flipped_text = flip(req.body.text) || '┻━┻';
  var response_text =  '(╯°□°）╯︵ ' + flipped_text;

  // Send our actual response async
  request({
    body: {
      response_type: 'in_channel',
      text: response_text,
    },
    json: true,
    method: 'post',
    uri: req.body.response_url,
  });

  // Let Slack know we didn't timeout
  res.send();
});

app.listen(process.env.PORT, function() {
  console.log('Server listening on', process.env.PORT);
});

app.get('health', function(req, res) {
  res.send('Ok');
});
<|endoftext|>


<commit_before>module.exports = {
  Util              : require('./_models/Util.class.js')
, ConfSite          : require('./_models/ConfSite.class.js')
, ConfPage          : require('./_models/ConfPage.class.js')
, Conference        : require('./_models/Conference.class.js')
, SupporterLevel    : require('./_models/SupporterLevel.class.js')
, Supporter         : require('./_models/Supporter.class.js')
, Exhibitor         : require('./_models/Exhibitor.class.js')
, Person            : require('./_models/Person.class.js')
, Place             : require('./_models/Place.class.js')
, RegistrationPeriod: require('./_models/RegistrationPeriod.class.js')
, Pass              : require('./_models/Pass.class.js')
, Session           : require('./_models/Session.class.js')
, ImportantDate     : require('./_models/ImportantDate.class.js')
}
<commit_msg>change module.exports order<commit_after>module.exports = {
  Util              : require('./_models/Util.class.js'),
  ConfSite          : require('./_models/ConfSite.class.js'),
  ConfPage          : require('./_models/ConfPage.class.js'),
  Conference        : require('./_models/Conference.class.js'),
  RegistrationPeriod: require('./_models/RegistrationPeriod.class.js'),
  Pass              : require('./_models/Pass.class.js'),
  Session           : require('./_models/Session.class.js'),
  Place             : require('./_models/Place.class.js'),
  Person            : require('./_models/Person.class.js'),
  SupporterLevel    : require('./_models/SupporterLevel.class.js'),
  Supporter         : require('./_models/Supporter.class.js'),
  Exhibitor         : require('./_models/Exhibitor.class.js'),
  ImportantDate     : require('./_models/ImportantDate.class.js'),
}
<|endoftext|>


<commit_before>var fs = require("fs");
var path = require('path');
var brocWriter = require("broccoli-writer");
var helpers = require("broccoli-kitchen-sink-helpers");

var BroccoliManifest = function BroccoliManifest(inTree, options) {
  if (!(this instanceof BroccoliManifest)) {
    return new BroccoliManifest(inTree, options);
  }
  this.inTree = inTree;
  options = options || {};
  this.appcacheFile = options.appcacheFile || "/manifest.appcache";
};

module.exports = BroccoliManifest;
BroccoliManifest.prototype = Object.create(brocWriter.prototype);
BroccoliManifest.prototype.constructor = BroccoliManifest;
BroccoliManifest.prototype.description = "Creates an manifest.appcache file for your project";

BroccoliManifest.prototype.write = function(readTree, destDir) {
  var appcacheFile = this.appcacheFile;
  return readTree(this.inTree).then(function (srcDir) {
    var lines = ["CACHE MANIFEST", "# created " + (new Date()).toISOString(), "", "CACHE:"];

    getFilesRecursively(srcDir, [ "**/*" ]).forEach(function (file) {
      var srcFile = path.join(srcDir, file);
      var stat = fs.lstatSync(srcFile);

      if (!stat.isFile() && !stat.isSymbolicLink())
        return;

      lines.push(srcFile);
    });

    lines.push("","NETWORK:","*");

    fs.writeFileSync(path.join(destDir, appcacheFile), lines.join("\n"));
  });
};

function getFilesRecursively(dir, globPatterns) {
  return helpers.multiGlob(globPatterns, { cwd: dir });
}

<commit_msg>Fix file path<commit_after>var fs = require("fs");
var path = require('path');
var brocWriter = require("broccoli-writer");
var helpers = require("broccoli-kitchen-sink-helpers");

var BroccoliManifest = function BroccoliManifest(inTree, options) {
  if (!(this instanceof BroccoliManifest)) {
    return new BroccoliManifest(inTree, options);
  }
  this.inTree = inTree;
  options = options || {};
  this.appcacheFile = options.appcacheFile || "/manifest.appcache";
};

module.exports = BroccoliManifest;
BroccoliManifest.prototype = Object.create(brocWriter.prototype);
BroccoliManifest.prototype.constructor = BroccoliManifest;
BroccoliManifest.prototype.description = "Creates an manifest.appcache file for your project";

BroccoliManifest.prototype.write = function(readTree, destDir) {
  var appcacheFile = this.appcacheFile;
  return readTree(this.inTree).then(function (srcDir) {
    var lines = ["CACHE MANIFEST", "# created " + (new Date()).toISOString(), "", "CACHE:"];

    getFilesRecursively(srcDir, [ "**/*" ]).forEach(function (file) {
      var srcFile = path.join(srcDir, file);
      var stat = fs.lstatSync(srcFile);

      if (!stat.isFile() && !stat.isSymbolicLink())
        return;

      lines.push(file);
    });

    lines.push("","NETWORK:","*");

    fs.writeFileSync(path.join(destDir, appcacheFile), lines.join("\n"));
  });
};

function getFilesRecursively(dir, globPatterns) {
  return helpers.multiGlob(globPatterns, { cwd: dir });
}

<|endoftext|>


<commit_before>(function() {
  'use strict';

  var _ = require('lodash');
  var Promise = require('bluebird');
  var cleanup = require('./lib/cleanup');
  var opts = require('./lib/opts');

  var actions = {
    download: require('./lib/actions/download'),
    jsdoc: require('./lib/actions/jsdoc'),
    lint: require('./lib/actions/lint'),
    build: require('./lib/actions/build'),
    deploy: require('./lib/actions/deploy'),
    release: require('./lib/actions/release')
  };

  /**
   * GitHub Release Manager - Perform various actions related to tags & releases, using the GitHub API.
   *
   * @param {string} [op] - The operation to perform. possible values are defined by whatever "actions" are set up.
   * @param {object} [options] - All [options] specific to the action being performed, plus:
   * @param {boolean} [options.checkForOpts=true] - Whether or not to check for `grm.opts`; defaults to true.
   * @returns {bluebird Promise} - For valid actions, the promise is defined by each action.
   *                               For invalid actions, the promise is rejected with an Error.
   */
  function grm(op, options) {
    op = op || 'release';

    if (_.isFunction(actions[op])) {
      var prepareOptions;

      if (_.get(options, 'checkForOpts') === false) {
        prepareOptions = Promise.resolve;
      } else {
        prepareOptions = opts;
      }

      return prepareOptions(options)
          .then(actions[op])
          .then(_.partial(cleanup, options));
    }

    return Promise.reject(new Error('unknown op: \'' + op + '\''));
  }

  module.exports = grm;
})();
<commit_msg>expose the CLI adapter interface thru the export<commit_after>(function() {
  'use strict';

  var _ = require('lodash');
  var Promise = require('bluebird');
  var cleanup = require('./lib/cleanup');
  var opts = require('./lib/opts');

  var actions = {
    download: require('./lib/actions/download'),
    jsdoc: require('./lib/actions/jsdoc'),
    lint: require('./lib/actions/lint'),
    build: require('./lib/actions/build'),
    deploy: require('./lib/actions/deploy'),
    release: require('./lib/actions/release')
  };

  /**
   * GitHub Release Manager - Perform various actions related to tags & releases, using the GitHub API.
   *
   * @param {string} [op] - The operation to perform. possible values are defined by whatever "actions" are set up.
   * @param {object} [options] - All [options] specific to the action being performed, plus:
   * @param {boolean} [options.checkForOpts=true] - Whether or not to check for `grm.opts`; defaults to true.
   * @returns {bluebird Promise} - For valid actions, the promise is defined by each action.
   *                               For invalid actions, the promise is rejected with an Error.
   */
  function grm(op, options) {
    op = op || 'release';

    if (_.isFunction(actions[op])) {
      var prepareOptions;

      if (_.get(options, 'checkForOpts') === false) {
        prepareOptions = Promise.resolve;
      } else {
        prepareOptions = opts;
      }

      return prepareOptions(options)
          .then(actions[op])
          .then(_.partial(cleanup, options));
    }

    return Promise.reject(new Error('unknown op: \'' + op + '\''));
  }

  grm.cli = function() {
    require('./lib/cliAdapter').apply(null, arguments);
  };

  module.exports = grm;
})();
<|endoftext|>