Add optional toolbar item label

Add optional toolbar item label

--- addons/toolbars/src/components/MenuToolbar.tsx
+++ addons/toolbars/src/components/MenuToolbar.tsx
@@ -10,6 +10,7 @@
   name,
   description,
   toolbar: { icon, items },
+  showName,
 }) => {
   const [globals, updateGlobals] = useGlobals();
   const selectedValue = globals[id];
@@ -43,6 +44,7 @@
       {selectedIcon ? (
         <IconButton key={name} active={active} title={description}>
           <Icons icon={selectedIcon} />
+          {showName ? `\xa0${name}` : ``}
         </IconButton>
       ) : (
         <TabButton active={active}>{name}</TabButton>

<|original_code|>
import React, { FC } from 'react';
import { useGlobals } from '@storybook/api';
import { Icons, IconButton, WithTooltip, TooltipLinkList, TabButton } from '@storybook/components';
import { NormalizedToolbarArgType } from '../types';

export type MenuToolbarProps = NormalizedToolbarArgType & { id: string };

export const MenuToolbar: FC<MenuToolbarProps> = ({
  id,
  name,
  description,
  toolbar: { icon, items },
}) => {
  const [globals, updateGlobals] = useGlobals();
  const selectedValue = globals[id];
  const active = selectedValue != null;
  const selectedItem = active && items.find((item) => item.value === selectedValue);
  const selectedIcon = (selectedItem && selectedItem.icon) || icon;

  return (
    <WithTooltip
      placement="top"
      trigger="click"
      tooltip={({ onHide }) => {
        const links = items.map((item) => {
          const { value, left, title, right } = item;
          return {
            id: value,
            left,
            title,
            right,
            active: selectedValue === value,
            onClick: () => {
              updateGlobals({ [id]: value });
              onHide();
            },
          };
        });
        return <TooltipLinkList links={links} />;
      }}
      closeOnClick
    >
      {selectedIcon ? (
        <IconButton key={name} active={active} title={description}>
          <Icons icon={selectedIcon} />
        </IconButton>
      ) : (
        <TabButton active={active}>{name}</TabButton>
      )}
    </WithTooltip>
  );
};

<|edits_diff|>
--- addons/toolbars/src/components/MenuToolbar.tsx
+++ addons/toolbars/src/components/MenuToolbar.tsx
@@ -10,6 +10,7 @@
   name,
   description,
   toolbar: { icon, items },
+  showName,
 }) => {
   const [globals, updateGlobals] = useGlobals();
   const selectedValue = globals[id];
<|current_version|>
import React, { FC } from 'react';
import { useGlobals } from '@storybook/api';
import { Icons, IconButton, WithTooltip, TooltipLinkList, TabButton } from '@storybook/components';
import { NormalizedToolbarArgType } from '../types';

export type MenuToolbarProps = NormalizedToolbarArgType & { id: string };

export const MenuToolbar: FC<MenuToolbarProps> = ({
  id,
  name,
  description,
  toolbar: { icon, items },
  showName,
}) => {
  const [globals, updateGlobals] = useGlobals();
  const selectedValue = globals[id];
  const active = selectedValue != null;
  const selectedItem = active && items.find((item) => item.value === selectedValue);
  const selectedIcon = (selectedItem && selectedItem.icon) || icon;

  return (
    <WithTooltip
      placement="top"
      trigger="click"
      tooltip={({ onHide }) => {
        const links = items.map((item) => {
          const { value, left, title, right } = item;
          return {
            id: value,
            left,
            title,
            right,
            active: selectedValue === value,
            onClick: () => {
              updateGlobals({ [id]: value });
              onHide();
            },
          };
        });
        return <TooltipLinkList links={links} />;
      }}
      closeOnClick
    >
      {selectedIcon ? (
        <IconButton key={name} active={active} title={description}>
          <Icons icon={selectedIcon} />
        </IconButton>
      ) : (
        <TabButton active={active}>{name}</TabButton>
      )}
    </WithTooltip>
  );
};

<|next_version|>
import React, { FC } from 'react';
import { useGlobals } from '@storybook/api';
import { Icons, IconButton, WithTooltip, TooltipLinkList, TabButton } from '@storybook/components';
import { NormalizedToolbarArgType } from '../types';

export type MenuToolbarProps = NormalizedToolbarArgType & { id: string };

export const MenuToolbar: FC<MenuToolbarProps> = ({
  id,
  name,
  description,
  toolbar: { icon, items },
  showName,
}) => {
  const [globals, updateGlobals] = useGlobals();
  const selectedValue = globals[id];
  const active = selectedValue != null;
  const selectedItem = active && items.find((item) => item.value === selectedValue);
  const selectedIcon = (selectedItem && selectedItem.icon) || icon;

  return (
    <WithTooltip
      placement="top"
      trigger="click"
      tooltip={({ onHide }) => {
        const links = items.map((item) => {
          const { value, left, title, right } = item;
          return {
            id: value,
            left,
            title,
            right,
            active: selectedValue === value,
            onClick: () => {
              updateGlobals({ [id]: value });
              onHide();
            },
          };
        });
        return <TooltipLinkList links={links} />;
      }}
      closeOnClick
    >
      {selectedIcon ? (
        <IconButton key={name} active={active} title={description}>
          <Icons icon={selectedIcon} />
          {showName ? `\xa0${name}` : ``}
        </IconButton>
      ) : (
        <TabButton active={active}>{name}</TabButton>
      )}
    </WithTooltip>
  );
};


Fix al listar y editar tareas que estan paginadas.

--- frontend/src/app/app.routing.ts
+++ frontend/src/app/app.routing.ts
@@ -19,7 +19,9 @@
     {path: 'user-edit', component: UserEditComponent},
     {path: 'task-new', component: TaskNewComponent},
     {path: 'task/:id', component: TaskDetailComponent},
+    {path: 'index/:page/task/:id', component: TaskDetailComponent},
     {path: 'task-edit/:id', component: TaskEditComponent},
+    {path: 'index/:page/task-edit/:id', component: TaskEditComponent},
     {path: '**', component: LoginComponent}
 ];

<|original_code|>
import {ModuleWithProviders} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import {LoginComponent} from './components/login.component';
import {RegisterComponent} from './components/register.component';
import {DefaultComponent} from './components/default.component';
import {UserEditComponent} from './components/user.edit.component';
import {TaskNewComponent} from './components/task.new.component';
import {TaskDetailComponent} from './components/task.detail.component';
import {TaskEditComponent} from './components/task.edit.component';

const appRoutes: Routes = [
    {path: '', component: DefaultComponent},
    {path: 'index', component: DefaultComponent},
    {path: 'index/:page', component: DefaultComponent},
    {path: 'login', component: LoginComponent},
    {path: 'login/:id', component: LoginComponent},
    {path: 'register', component: RegisterComponent},
    {path: 'user-edit', component: UserEditComponent},
    {path: 'task-new', component: TaskNewComponent},
    {path: 'task/:id', component: TaskDetailComponent},
    {path: 'task-edit/:id', component: TaskEditComponent},
    {path: '**', component: LoginComponent}
];

export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

<|edits_diff|>
--- frontend/src/app/app.routing.ts
+++ frontend/src/app/app.routing.ts
@@ -19,6 +19,7 @@
     {path: 'user-edit', component: UserEditComponent},
     {path: 'task-new', component: TaskNewComponent},
     {path: 'task/:id', component: TaskDetailComponent},
+    {path: 'index/:page/task/:id', component: TaskDetailComponent},
     {path: 'task-edit/:id', component: TaskEditComponent},
     {path: '**', component: LoginComponent}
 ];
<|current_version|>
import {ModuleWithProviders} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import {LoginComponent} from './components/login.component';
import {RegisterComponent} from './components/register.component';
import {DefaultComponent} from './components/default.component';
import {UserEditComponent} from './components/user.edit.component';
import {TaskNewComponent} from './components/task.new.component';
import {TaskDetailComponent} from './components/task.detail.component';
import {TaskEditComponent} from './components/task.edit.component';

const appRoutes: Routes = [
    {path: '', component: DefaultComponent},
    {path: 'index', component: DefaultComponent},
    {path: 'index/:page', component: DefaultComponent},
    {path: 'login', component: LoginComponent},
    {path: 'login/:id', component: LoginComponent},
    {path: 'register', component: RegisterComponent},
    {path: 'user-edit', component: UserEditComponent},
    {path: 'task-new', component: TaskNewComponent},
    {path: 'task/:id', component: TaskDetailComponent},
    {path: 'index/:page/task/:id', component: TaskDetailComponent},
    {path: 'task-edit/:id', component: TaskEditComponent},
    {path: '**', component: LoginComponent}
];

export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

<|next_version|>
import {ModuleWithProviders} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import {LoginComponent} from './components/login.component';
import {RegisterComponent} from './components/register.component';
import {DefaultComponent} from './components/default.component';
import {UserEditComponent} from './components/user.edit.component';
import {TaskNewComponent} from './components/task.new.component';
import {TaskDetailComponent} from './components/task.detail.component';
import {TaskEditComponent} from './components/task.edit.component';

const appRoutes: Routes = [
    {path: '', component: DefaultComponent},
    {path: 'index', component: DefaultComponent},
    {path: 'index/:page', component: DefaultComponent},
    {path: 'login', component: LoginComponent},
    {path: 'login/:id', component: LoginComponent},
    {path: 'register', component: RegisterComponent},
    {path: 'user-edit', component: UserEditComponent},
    {path: 'task-new', component: TaskNewComponent},
    {path: 'task/:id', component: TaskDetailComponent},
    {path: 'index/:page/task/:id', component: TaskDetailComponent},
    {path: 'task-edit/:id', component: TaskEditComponent},
    {path: 'index/:page/task-edit/:id', component: TaskEditComponent},
    {path: '**', component: LoginComponent}
];

export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);


Use FontAwesomeModule for share icons

feat(ShareButtonModule): Use FontAwesomeModule for share icons

--- lib/button/src/share-button.module.ts
+++ lib/button/src/share-button.module.ts
@@ -3,6 +3,7 @@
 import { ShareModule, ShareButtons, ShareButtonsConfig, CONFIG } from '@ngx-share/core';

 import { ShareButtonComponent } from './share-button.component';
+import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

 export function ShareButtonsFactory(config: ShareButtonsConfig) {
   return new ShareButtons(config);
@@ -14,10 +15,12 @@
   ],
   imports: [
     ShareModule,
+    FontAwesomeModule,
     CommonModule
   ],
   exports: [
     ShareModule,
+    FontAwesomeModule,
     ShareButtonComponent
   ]
 })

<|original_code|>
import { NgModule, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ShareModule, ShareButtons, ShareButtonsConfig, CONFIG } from '@ngx-share/core';

import { ShareButtonComponent } from './share-button.component';

export function ShareButtonsFactory(config: ShareButtonsConfig) {
  return new ShareButtons(config);
}

@NgModule({
  declarations: [
    ShareButtonComponent
  ],
  imports: [
    ShareModule,
    CommonModule
  ],
  exports: [
    ShareModule,
    ShareButtonComponent
  ]
})
export class ShareButtonModule {
  static forRoot(config?: ShareButtonsConfig) {
    return {
      ngModule: ShareButtonModule,
      providers: [
        {provide: CONFIG, useValue: config},
        {
          provide: ShareButtons,
          useFactory: ShareButtonsFactory,
          deps: [CONFIG]
        }
      ]
    };
  }
}

<|edits_diff|>
--- lib/button/src/share-button.module.ts
+++ lib/button/src/share-button.module.ts
@@ -3,6 +3,7 @@
 import { ShareModule, ShareButtons, ShareButtonsConfig, CONFIG } from '@ngx-share/core';

 import { ShareButtonComponent } from './share-button.component';
+import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

 export function ShareButtonsFactory(config: ShareButtonsConfig) {
   return new ShareButtons(config);
@@ -14,6 +15,7 @@
   ],
   imports: [
     ShareModule,
+    FontAwesomeModule,
     CommonModule
   ],
   exports: [
<|current_version|>
import { NgModule, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ShareModule, ShareButtons, ShareButtonsConfig, CONFIG } from '@ngx-share/core';

import { ShareButtonComponent } from './share-button.component';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

export function ShareButtonsFactory(config: ShareButtonsConfig) {
  return new ShareButtons(config);
}

@NgModule({
  declarations: [
    ShareButtonComponent
  ],
  imports: [
    ShareModule,
    FontAwesomeModule,
    CommonModule
  ],
  exports: [
    ShareModule,
    ShareButtonComponent
  ]
})
export class ShareButtonModule {
  static forRoot(config?: ShareButtonsConfig) {
    return {
      ngModule: ShareButtonModule,
      providers: [
        {provide: CONFIG, useValue: config},
        {
          provide: ShareButtons,
          useFactory: ShareButtonsFactory,
          deps: [CONFIG]
        }
      ]
    };
  }
}

<|next_version|>
import { NgModule, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ShareModule, ShareButtons, ShareButtonsConfig, CONFIG } from '@ngx-share/core';

import { ShareButtonComponent } from './share-button.component';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

export function ShareButtonsFactory(config: ShareButtonsConfig) {
  return new ShareButtons(config);
}

@NgModule({
  declarations: [
    ShareButtonComponent
  ],
  imports: [
    ShareModule,
    FontAwesomeModule,
    CommonModule
  ],
  exports: [
    ShareModule,
    FontAwesomeModule,
    ShareButtonComponent
  ]
})
export class ShareButtonModule {
  static forRoot(config?: ShareButtonsConfig) {
    return {
      ngModule: ShareButtonModule,
      providers: [
        {provide: CONFIG, useValue: config},
        {
          provide: ShareButtons,
          useFactory: ShareButtonsFactory,
          deps: [CONFIG]
        }
      ]
    };
  }
}


Add count down button (not work)

Add count down button (not work)

--- src/ts/view/counter.ts
+++ src/ts/view/counter.ts
@@ -20,8 +20,13 @@
             countUpButton.innerHTML = "Up";
             countUpButton.classList.add("countUp");

+            var countDownButton:HTMLButtonElement = document.createElement("button");
+            countDownButton.innerHTML = "Down";
+            countDownButton.classList.add("countDown");
+
             counter.appendChild(countView);
             counter.appendChild(countUpButton);
+            counter.appendChild(countDownButton);
             return counter;
         }
         update() {

<|original_code|>
namespace YJMCNT {
    /**
     * CounterView
     */
    export class CounterView extends Core.View {
        counter:Counter;

        constructor() {
            super();
            this.counter = new Counter();
            this.counter.addObserver(this);
        }
        render() {
            var counter = document.createElement("div");
            var countView = document.createElement("span");
            countView.classList.add("count");
            countView.innerText = "count: "+this.counter.show().toString();

            var countUpButton:HTMLButtonElement = document.createElement("button");
            countUpButton.innerHTML = "Up";
            countUpButton.classList.add("countUp");

            counter.appendChild(countView);
            counter.appendChild(countUpButton);
            return counter;
        }
        update() {
            this.notifyObservers();
        }
    }
}

<|edits_diff|>
--- src/ts/view/counter.ts
+++ src/ts/view/counter.ts
@@ -20,6 +20,10 @@
             countUpButton.innerHTML = "Up";
             countUpButton.classList.add("countUp");

+            var countDownButton:HTMLButtonElement = document.createElement("button");
+            countDownButton.innerHTML = "Down";
+            countDownButton.classList.add("countDown");
+
             counter.appendChild(countView);
             counter.appendChild(countUpButton);
             return counter;
<|current_version|>
namespace YJMCNT {
    /**
     * CounterView
     */
    export class CounterView extends Core.View {
        counter:Counter;

        constructor() {
            super();
            this.counter = new Counter();
            this.counter.addObserver(this);
        }
        render() {
            var counter = document.createElement("div");
            var countView = document.createElement("span");
            countView.classList.add("count");
            countView.innerText = "count: "+this.counter.show().toString();

            var countUpButton:HTMLButtonElement = document.createElement("button");
            countUpButton.innerHTML = "Up";
            countUpButton.classList.add("countUp");

            var countDownButton:HTMLButtonElement = document.createElement("button");
            countDownButton.innerHTML = "Down";
            countDownButton.classList.add("countDown");

            counter.appendChild(countView);
            counter.appendChild(countUpButton);
            return counter;
        }
        update() {
            this.notifyObservers();
        }
    }
}

<|next_version|>
namespace YJMCNT {
    /**
     * CounterView
     */
    export class CounterView extends Core.View {
        counter:Counter;

        constructor() {
            super();
            this.counter = new Counter();
            this.counter.addObserver(this);
        }
        render() {
            var counter = document.createElement("div");
            var countView = document.createElement("span");
            countView.classList.add("count");
            countView.innerText = "count: "+this.counter.show().toString();

            var countUpButton:HTMLButtonElement = document.createElement("button");
            countUpButton.innerHTML = "Up";
            countUpButton.classList.add("countUp");

            var countDownButton:HTMLButtonElement = document.createElement("button");
            countDownButton.innerHTML = "Down";
            countDownButton.classList.add("countDown");

            counter.appendChild(countView);
            counter.appendChild(countUpButton);
            counter.appendChild(countDownButton);
            return counter;
        }
        update() {
            this.notifyObservers();
        }
    }
}


Add toggle animation to menu

Add toggle animation to menu

--- src/renderer/app/components/Menu/styles.ts
+++ src/renderer/app/components/Menu/styles.ts
@@ -1,6 +1,7 @@
 import styled, { css } from 'styled-components';

 import { shadows } from '@mixins';
+import { EASE_FUNCTION } from '~/constants';

 export const Container = styled.div`
   width: 300px;
@@ -14,11 +15,16 @@
   border-radius: 4px;
   transform-origin: top right;
   -webkit-app-region: no-drag;
+  will-change: opacity;
   box-sizing: border-box;
   box-shadow: ${shadows(6)};

   ${({ visible }: { visible: boolean }) => css`
     opacity: ${visible ? 1 : 0};
     pointer-events: ${visible ? 'all' : 'none'};
+    transform: ${visible ? 'scale(1)' : 'scale(0)'};
+    transition: ${`0.3s ${EASE_FUNCTION} transform, ${
+      visible ? 0.1 : 0.2
+    }s opacity`};
   `};
 `;

<|original_code|>
import styled, { css } from 'styled-components';

import { shadows } from '@mixins';

export const Container = styled.div`
  width: 300px;
  padding-top: 4px;
  padding-bottom: 4px;
  position: absolute;
  top: 56px;
  right: 0;
  background-color: #fff;
  z-index: 9999;
  border-radius: 4px;
  transform-origin: top right;
  -webkit-app-region: no-drag;
  box-sizing: border-box;
  box-shadow: ${shadows(6)};

  ${({ visible }: { visible: boolean }) => css`
    opacity: ${visible ? 1 : 0};
    pointer-events: ${visible ? 'all' : 'none'};
  `};
`;

<|edits_diff|>
--- src/renderer/app/components/Menu/styles.ts
+++ src/renderer/app/components/Menu/styles.ts
@@ -1,6 +1,7 @@
 import styled, { css } from 'styled-components';

 import { shadows } from '@mixins';
+import { EASE_FUNCTION } from '~/constants';

 export const Container = styled.div`
   width: 300px;
@@ -14,6 +15,7 @@
   border-radius: 4px;
   transform-origin: top right;
   -webkit-app-region: no-drag;
+  will-change: opacity;
   box-sizing: border-box;
   box-shadow: ${shadows(6)};

<|current_version|>
import styled, { css } from 'styled-components';

import { shadows } from '@mixins';
import { EASE_FUNCTION } from '~/constants';

export const Container = styled.div`
  width: 300px;
  padding-top: 4px;
  padding-bottom: 4px;
  position: absolute;
  top: 56px;
  right: 0;
  background-color: #fff;
  z-index: 9999;
  border-radius: 4px;
  transform-origin: top right;
  -webkit-app-region: no-drag;
  will-change: opacity;
  box-sizing: border-box;
  box-shadow: ${shadows(6)};

  ${({ visible }: { visible: boolean }) => css`
    opacity: ${visible ? 1 : 0};
    pointer-events: ${visible ? 'all' : 'none'};
  `};
`;

<|next_version|>
import styled, { css } from 'styled-components';

import { shadows } from '@mixins';
import { EASE_FUNCTION } from '~/constants';

export const Container = styled.div`
  width: 300px;
  padding-top: 4px;
  padding-bottom: 4px;
  position: absolute;
  top: 56px;
  right: 0;
  background-color: #fff;
  z-index: 9999;
  border-radius: 4px;
  transform-origin: top right;
  -webkit-app-region: no-drag;
  will-change: opacity;
  box-sizing: border-box;
  box-shadow: ${shadows(6)};

  ${({ visible }: { visible: boolean }) => css`
    opacity: ${visible ? 1 : 0};
    pointer-events: ${visible ? 'all' : 'none'};
    transform: ${visible ? 'scale(1)' : 'scale(0)'};
    transition: ${`0.3s ${EASE_FUNCTION} transform, ${
      visible ? 0.1 : 0.2
    }s opacity`};
  `};
`;


Add failing test for function calls that have at least one non-spread argument, a spread argument, and overall potentially too few arguments

--- tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts
+++ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts
@@ -4,6 +4,7 @@
 declare function rest(s: string, a?: number, b?: number,  ...rest: number[]): void;
 declare function normal(s: string): void;
 declare function thunk(): string;
+declare function prefix2(s: string, n: number, a?: number, b?: number): void;

 declare var ns: number[];
 declare var mixed: (number | string)[];
@@ -32,3 +33,4 @@
 prefix(...ns) // required parameters are required
 prefix(...mixed)
 prefix(...tuple)
+prefix2("g", ...ns);

<|original_code|>
declare function all(a?: number, b?: number): void;
declare function weird(a?: number | string, b?: number | string): void;
declare function prefix(s: string, a?: number, b?: number): void;
declare function rest(s: string, a?: number, b?: number,  ...rest: number[]): void;
declare function normal(s: string): void;
declare function thunk(): string;

declare var ns: number[];
declare var mixed: (number | string)[];
declare var tuple: [number, string];

// good
all(...ns)
weird(...ns)
weird(...mixed)
weird(...tuple)
prefix("a", ...ns)
rest("d", ...ns)

// extra arguments
normal("g", ...ns)
thunk(...ns)

// bad
all(...mixed)
all(...tuple)
prefix("b", ...mixed)
prefix("c", ...tuple)
rest("e", ...mixed)
rest("f", ...tuple)
prefix(...ns) // required parameters are required
prefix(...mixed)
prefix(...tuple)

<|edits_diff|>
--- tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts
+++ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts
@@ -4,6 +4,7 @@
 declare function rest(s: string, a?: number, b?: number,  ...rest: number[]): void;
 declare function normal(s: string): void;
 declare function thunk(): string;
+declare function prefix2(s: string, n: number, a?: number, b?: number): void;

 declare var ns: number[];
 declare var mixed: (number | string)[];
<|current_version|>
declare function all(a?: number, b?: number): void;
declare function weird(a?: number | string, b?: number | string): void;
declare function prefix(s: string, a?: number, b?: number): void;
declare function rest(s: string, a?: number, b?: number,  ...rest: number[]): void;
declare function normal(s: string): void;
declare function thunk(): string;
declare function prefix2(s: string, n: number, a?: number, b?: number): void;

declare var ns: number[];
declare var mixed: (number | string)[];
declare var tuple: [number, string];

// good
all(...ns)
weird(...ns)
weird(...mixed)
weird(...tuple)
prefix("a", ...ns)
rest("d", ...ns)

// extra arguments
normal("g", ...ns)
thunk(...ns)

// bad
all(...mixed)
all(...tuple)
prefix("b", ...mixed)
prefix("c", ...tuple)
rest("e", ...mixed)
rest("f", ...tuple)
prefix(...ns) // required parameters are required
prefix(...mixed)
prefix(...tuple)

<|next_version|>
declare function all(a?: number, b?: number): void;
declare function weird(a?: number | string, b?: number | string): void;
declare function prefix(s: string, a?: number, b?: number): void;
declare function rest(s: string, a?: number, b?: number,  ...rest: number[]): void;
declare function normal(s: string): void;
declare function thunk(): string;
declare function prefix2(s: string, n: number, a?: number, b?: number): void;

declare var ns: number[];
declare var mixed: (number | string)[];
declare var tuple: [number, string];

// good
all(...ns)
weird(...ns)
weird(...mixed)
weird(...tuple)
prefix("a", ...ns)
rest("d", ...ns)

// extra arguments
normal("g", ...ns)
thunk(...ns)

// bad
all(...mixed)
all(...tuple)
prefix("b", ...mixed)
prefix("c", ...tuple)
rest("e", ...mixed)
rest("f", ...tuple)
prefix(...ns) // required parameters are required
prefix(...mixed)
prefix(...tuple)
prefix2("g", ...ns);


Add GetProcessHeaps(), HeapFree() of kernel32

--- src/lib/kernel32/api.ts
+++ src/lib/kernel32/api.ts
@@ -8,6 +8,10 @@
     GetModuleHandleW: [D.HMODULE, [D.LPCTSTR]],    // retrive value from buf by ret.ref().readUInt32()

     GetModuleHandleExW: [D.BOOL, [D.DWORD, D.LPCTSTR, D.HMODULE]],     // flags, optional LPCTSTR name, ref hModule
+
+    GetProcessHeaps: [D.DWORD, [D.DWORD, D.PHANDLE]],
+
+    HeapFree: [D.BOOL, [D.HANDLE, D.DWORD, D.LPVOID]],
 };

 export interface Win32Fn {
@@ -16,4 +20,8 @@
     GetModuleHandleW(lpModuleName: GT.LPCTSTR): GT.HMODULE;

     GetModuleHandleExW(dwFlags: GT.DWORD, lpModuleName: GT.LPCTSTR | null, phModule: GT.HMODULE): GT.BOOL;
+
+    GetProcessHeaps(NumberOfHeaps: GT.DWORD, ProcessHeaps: GT.PHANDLE): GT.DWORD;
+
+    HeapFree( hHeap: GT.HANDLE, dwFlags: GT.DWORD, lpMem: GT.LPVOID | null): GT.BOOL;
 }

<|original_code|>
import * as D from '../windef';
import * as GT from '../types';

export const fnDef: GT.Win32FnDef = {
    GetLastError: [D.DWORD, []], // err code: https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681381(v=vs.85).aspx

    GetModuleHandleW: [D.HMODULE, [D.LPCTSTR]],    // retrive value from buf by ret.ref().readUInt32()

    GetModuleHandleExW: [D.BOOL, [D.DWORD, D.LPCTSTR, D.HMODULE]],     // flags, optional LPCTSTR name, ref hModule
};

export interface Win32Fn {
    GetLastError(): GT.DWORD;

    GetModuleHandleW(lpModuleName: GT.LPCTSTR): GT.HMODULE;

    GetModuleHandleExW(dwFlags: GT.DWORD, lpModuleName: GT.LPCTSTR | null, phModule: GT.HMODULE): GT.BOOL;
}

<|edits_diff|>
--- src/lib/kernel32/api.ts
+++ src/lib/kernel32/api.ts
@@ -8,6 +8,10 @@
     GetModuleHandleW: [D.HMODULE, [D.LPCTSTR]],    // retrive value from buf by ret.ref().readUInt32()

     GetModuleHandleExW: [D.BOOL, [D.DWORD, D.LPCTSTR, D.HMODULE]],     // flags, optional LPCTSTR name, ref hModule
+
+    GetProcessHeaps: [D.DWORD, [D.DWORD, D.PHANDLE]],
+
+    HeapFree: [D.BOOL, [D.HANDLE, D.DWORD, D.LPVOID]],
 };

 export interface Win32Fn {
<|current_version|>
import * as D from '../windef';
import * as GT from '../types';

export const fnDef: GT.Win32FnDef = {
    GetLastError: [D.DWORD, []], // err code: https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681381(v=vs.85).aspx

    GetModuleHandleW: [D.HMODULE, [D.LPCTSTR]],    // retrive value from buf by ret.ref().readUInt32()

    GetModuleHandleExW: [D.BOOL, [D.DWORD, D.LPCTSTR, D.HMODULE]],     // flags, optional LPCTSTR name, ref hModule

    GetProcessHeaps: [D.DWORD, [D.DWORD, D.PHANDLE]],

    HeapFree: [D.BOOL, [D.HANDLE, D.DWORD, D.LPVOID]],
};

export interface Win32Fn {
    GetLastError(): GT.DWORD;

    GetModuleHandleW(lpModuleName: GT.LPCTSTR): GT.HMODULE;

    GetModuleHandleExW(dwFlags: GT.DWORD, lpModuleName: GT.LPCTSTR | null, phModule: GT.HMODULE): GT.BOOL;
}

<|next_version|>
import * as D from '../windef';
import * as GT from '../types';

export const fnDef: GT.Win32FnDef = {
    GetLastError: [D.DWORD, []], // err code: https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681381(v=vs.85).aspx

    GetModuleHandleW: [D.HMODULE, [D.LPCTSTR]],    // retrive value from buf by ret.ref().readUInt32()

    GetModuleHandleExW: [D.BOOL, [D.DWORD, D.LPCTSTR, D.HMODULE]],     // flags, optional LPCTSTR name, ref hModule

    GetProcessHeaps: [D.DWORD, [D.DWORD, D.PHANDLE]],

    HeapFree: [D.BOOL, [D.HANDLE, D.DWORD, D.LPVOID]],
};

export interface Win32Fn {
    GetLastError(): GT.DWORD;

    GetModuleHandleW(lpModuleName: GT.LPCTSTR): GT.HMODULE;

    GetModuleHandleExW(dwFlags: GT.DWORD, lpModuleName: GT.LPCTSTR | null, phModule: GT.HMODULE): GT.BOOL;

    GetProcessHeaps(NumberOfHeaps: GT.DWORD, ProcessHeaps: GT.PHANDLE): GT.DWORD;

    HeapFree( hHeap: GT.HANDLE, dwFlags: GT.DWORD, lpMem: GT.LPVOID | null): GT.BOOL;
}


Mark FS helpers as deprecated

Mark FS helpers as deprecated

--- helpers/fs.ts
+++ helpers/fs.ts
@@ -3,6 +3,7 @@

 export default class HelperFS {
     /**
+     * DEPRECATED: use `fs-extra`.pathExists()
      * Provides functionality of deprecated fs.exists()
      * See https://github.com/nodejs/node/issues/1592
      */
@@ -16,6 +17,7 @@
     }

     /**
+     * DEPRECATED: use `fs-extra`.pathExistsSync()
      * Provides functionality of deprecated fs.existsSync()
      * See https://github.com/nodejs/node/issues/1592
      */

<|original_code|>
import * as fs from "fs-extra";
import * as recursiveReaddir from "recursive-readdir";

export default class HelperFS {
    /**
     * Provides functionality of deprecated fs.exists()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static async exists(filename: string): Promise<boolean> {
        try {
            await fs.access(filename);
            return true;
        } catch (err) {
            return false;
        }
    }

    /**
     * Provides functionality of deprecated fs.existsSync()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static existsSync(filename: string): boolean {
        try {
            fs.accessSync(filename);
            return true;
        } catch (ex) {
            return false;
        }
    }

    /**
     * Maps the recursive-readdir module to a Promise interface.
     */
    public static recursiveReaddir(path: string): Promise<string[]> {
        return new Promise<string[]>((resolve, reject) => {
            recursiveReaddir(path, (err: Error, files: string[]) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(files);
                }
            });
        });
    }
}

<|edits_diff|>
--- helpers/fs.ts
+++ helpers/fs.ts
@@ -3,6 +3,7 @@

 export default class HelperFS {
     /**
+     * DEPRECATED: use `fs-extra`.pathExists()
      * Provides functionality of deprecated fs.exists()
      * See https://github.com/nodejs/node/issues/1592
      */
<|current_version|>
import * as fs from "fs-extra";
import * as recursiveReaddir from "recursive-readdir";

export default class HelperFS {
    /**
     * DEPRECATED: use `fs-extra`.pathExists()
     * Provides functionality of deprecated fs.exists()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static async exists(filename: string): Promise<boolean> {
        try {
            await fs.access(filename);
            return true;
        } catch (err) {
            return false;
        }
    }

    /**
     * Provides functionality of deprecated fs.existsSync()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static existsSync(filename: string): boolean {
        try {
            fs.accessSync(filename);
            return true;
        } catch (ex) {
            return false;
        }
    }

    /**
     * Maps the recursive-readdir module to a Promise interface.
     */
    public static recursiveReaddir(path: string): Promise<string[]> {
        return new Promise<string[]>((resolve, reject) => {
            recursiveReaddir(path, (err: Error, files: string[]) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(files);
                }
            });
        });
    }
}

<|next_version|>
import * as fs from "fs-extra";
import * as recursiveReaddir from "recursive-readdir";

export default class HelperFS {
    /**
     * DEPRECATED: use `fs-extra`.pathExists()
     * Provides functionality of deprecated fs.exists()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static async exists(filename: string): Promise<boolean> {
        try {
            await fs.access(filename);
            return true;
        } catch (err) {
            return false;
        }
    }

    /**
     * DEPRECATED: use `fs-extra`.pathExistsSync()
     * Provides functionality of deprecated fs.existsSync()
     * See https://github.com/nodejs/node/issues/1592
     */
    public static existsSync(filename: string): boolean {
        try {
            fs.accessSync(filename);
            return true;
        } catch (ex) {
            return false;
        }
    }

    /**
     * Maps the recursive-readdir module to a Promise interface.
     */
    public static recursiveReaddir(path: string): Promise<string[]> {
        return new Promise<string[]>((resolve, reject) => {
            recursiveReaddir(path, (err: Error, files: string[]) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(files);
                }
            });
        });
    }
}


Implement `get form` for UbuntuConfigComponent

--- src/app/catalog/plugins/ubuntu/ubuntu.component.ts
+++ src/app/catalog/plugins/ubuntu/ubuntu.component.ts
@@ -1,6 +1,7 @@
 import { Component, Input } from '@angular/core';
 import {
     FormBuilder,
+    FormGroup,
     FormGroupDirective } from '@angular/forms';
 import { BasePluginComponent } from '../base-plugin.component';

@@ -11,9 +12,15 @@
     inputs: ['cloud', 'initialConfig']
 })
 export class UbuntuConfigComponent extends BasePluginComponent {
+    ubuntuLaunchForm: FormGroup;

     constructor(fb: FormBuilder, parentContainer: FormGroupDirective) {
         super(fb, parentContainer);
+        this.ubuntuLaunchForm = fb.group({});
+    }
+
+    get form(): FormGroup {
+        return this.ubuntuLaunchForm;
     }

     get configName(): string {

<|original_code|>
import { Component, Input } from '@angular/core';
import {
    FormBuilder,
    FormGroupDirective } from '@angular/forms';
import { BasePluginComponent } from '../base-plugin.component';

@Component({
    selector: 'ubuntu-config',
    template: ``,
    inputs: ['cloud', 'initialConfig']
})
export class UbuntuConfigComponent extends BasePluginComponent {

    constructor(fb: FormBuilder, parentContainer: FormGroupDirective) {
        super(fb, parentContainer);
    }

    get configName(): string {
        return "config_ubuntu";
    }
}

<|edits_diff|>
--- src/app/catalog/plugins/ubuntu/ubuntu.component.ts
+++ src/app/catalog/plugins/ubuntu/ubuntu.component.ts
@@ -1,6 +1,7 @@
 import { Component, Input } from '@angular/core';
 import {
     FormBuilder,
+    FormGroup,
     FormGroupDirective } from '@angular/forms';
 import { BasePluginComponent } from '../base-plugin.component';

@@ -11,6 +12,7 @@
     inputs: ['cloud', 'initialConfig']
 })
 export class UbuntuConfigComponent extends BasePluginComponent {
+    ubuntuLaunchForm: FormGroup;

     constructor(fb: FormBuilder, parentContainer: FormGroupDirective) {
         super(fb, parentContainer);
<|current_version|>
import { Component, Input } from '@angular/core';
import {
    FormBuilder,
    FormGroup,
    FormGroupDirective } from '@angular/forms';
import { BasePluginComponent } from '../base-plugin.component';

@Component({
    selector: 'ubuntu-config',
    template: ``,
    inputs: ['cloud', 'initialConfig']
})
export class UbuntuConfigComponent extends BasePluginComponent {
    ubuntuLaunchForm: FormGroup;

    constructor(fb: FormBuilder, parentContainer: FormGroupDirective) {
        super(fb, parentContainer);
    }

    get configName(): string {
        return "config_ubuntu";
    }
}

<|next_version|>
import { Component, Input } from '@angular/core';
import {
    FormBuilder,
    FormGroup,
    FormGroupDirective } from '@angular/forms';
import { BasePluginComponent } from '../base-plugin.component';

@Component({
    selector: 'ubuntu-config',
    template: ``,
    inputs: ['cloud', 'initialConfig']
})
export class UbuntuConfigComponent extends BasePluginComponent {
    ubuntuLaunchForm: FormGroup;

    constructor(fb: FormBuilder, parentContainer: FormGroupDirective) {
        super(fb, parentContainer);
        this.ubuntuLaunchForm = fb.group({});
    }

    get form(): FormGroup {
        return this.ubuntuLaunchForm;
    }

    get configName(): string {
        return "config_ubuntu";
    }
}


Allow text wrapping for mobile

Allow text wrapping for mobile

--- src/v2/Apps/Partner/Components/PartnerHeader/PartnerHeaderAddress.tsx
+++ src/v2/Apps/Partner/Components/PartnerHeader/PartnerHeaderAddress.tsx
@@ -1,10 +1,15 @@
 import React from "react"
 import styled from "styled-components"
 import { uniq } from "lodash"
+import { media } from "@artsy/palette"
 import { PartnerHeader_partner } from "v2/__generated__/PartnerHeader_partner.graphql"

 export const TextWithNoWrap = styled.span`
   white-space: nowrap;
+
+  ${media.sm`
+    white-space: normal;
+  `};
 `
 export const PartnerHeaderAddress: React.FC<
   PartnerHeader_partner["locations"]

<|original_code|>
import React from "react"
import styled from "styled-components"
import { uniq } from "lodash"
import { PartnerHeader_partner } from "v2/__generated__/PartnerHeader_partner.graphql"

export const TextWithNoWrap = styled.span`
  white-space: nowrap;
`
export const PartnerHeaderAddress: React.FC<
  PartnerHeader_partner["locations"]
> = ({ edges }) => {
  return (
    <>
      {uniq(edges.map(edge => edge.node.city?.trim()))
        .filter(city => !!city)
        .map<React.ReactNode>((city, index) => (
          <TextWithNoWrap key={`${city}${index}`}>{city}</TextWithNoWrap>
        ))
        .reduce((prev, curr, index) => [
          prev,
          // The last space character is used instead of a non-breaking character
          // for better text wrapping behavior.
          <React.Fragment key={index}>  •  </React.Fragment>,
          curr,
        ])}
    </>
  )
}

<|edits_diff|>
--- src/v2/Apps/Partner/Components/PartnerHeader/PartnerHeaderAddress.tsx
+++ src/v2/Apps/Partner/Components/PartnerHeader/PartnerHeaderAddress.tsx
@@ -1,6 +1,7 @@
 import React from "react"
 import styled from "styled-components"
 import { uniq } from "lodash"
+import { media } from "@artsy/palette"
 import { PartnerHeader_partner } from "v2/__generated__/PartnerHeader_partner.graphql"

 export const TextWithNoWrap = styled.span`
<|current_version|>
import React from "react"
import styled from "styled-components"
import { uniq } from "lodash"
import { media } from "@artsy/palette"
import { PartnerHeader_partner } from "v2/__generated__/PartnerHeader_partner.graphql"

export const TextWithNoWrap = styled.span`
  white-space: nowrap;
`
export const PartnerHeaderAddress: React.FC<
  PartnerHeader_partner["locations"]
> = ({ edges }) => {
  return (
    <>
      {uniq(edges.map(edge => edge.node.city?.trim()))
        .filter(city => !!city)
        .map<React.ReactNode>((city, index) => (
          <TextWithNoWrap key={`${city}${index}`}>{city}</TextWithNoWrap>
        ))
        .reduce((prev, curr, index) => [
          prev,
          // The last space character is used instead of a non-breaking character
          // for better text wrapping behavior.
          <React.Fragment key={index}>  •  </React.Fragment>,
          curr,
        ])}
    </>
  )
}

<|next_version|>
import React from "react"
import styled from "styled-components"
import { uniq } from "lodash"
import { media } from "@artsy/palette"
import { PartnerHeader_partner } from "v2/__generated__/PartnerHeader_partner.graphql"

export const TextWithNoWrap = styled.span`
  white-space: nowrap;

  ${media.sm`
    white-space: normal;
  `};
`
export const PartnerHeaderAddress: React.FC<
  PartnerHeader_partner["locations"]
> = ({ edges }) => {
  return (
    <>
      {uniq(edges.map(edge => edge.node.city?.trim()))
        .filter(city => !!city)
        .map<React.ReactNode>((city, index) => (
          <TextWithNoWrap key={`${city}${index}`}>{city}</TextWithNoWrap>
        ))
        .reduce((prev, curr, index) => [
          prev,
          // The last space character is used instead of a non-breaking character
          // for better text wrapping behavior.
          <React.Fragment key={index}>  •  </React.Fragment>,
          curr,
        ])}
    </>
  )
}


Fix demo shell runtime issue with Search

--- demo-shell-ng2/app/main.ts
+++ demo-shell-ng2/app/main.ts
@@ -18,6 +18,7 @@
 import { bootstrap } from '@angular/platform-browser-dynamic';
 import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
 import { HTTP_PROVIDERS } from '@angular/http';
+import { ALFRESCO_SEARCH_PROVIDERS } from 'ng2-alfresco-search';
 import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core';
 import { UploadService } from 'ng2-alfresco-upload';
 import { AppComponent } from './app.component';
@@ -26,5 +27,6 @@
     ROUTER_PROVIDERS,
     HTTP_PROVIDERS,
     ALFRESCO_CORE_PROVIDERS,
+    ALFRESCO_SEARCH_PROVIDERS,
     UploadService
 ]);

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

import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { HTTP_PROVIDERS } from '@angular/http';
import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core';
import { UploadService } from 'ng2-alfresco-upload';
import { AppComponent } from './app.component';

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    ALFRESCO_CORE_PROVIDERS,
    UploadService
]);

<|edits_diff|>
--- demo-shell-ng2/app/main.ts
+++ demo-shell-ng2/app/main.ts
@@ -18,6 +18,7 @@
 import { bootstrap } from '@angular/platform-browser-dynamic';
 import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
 import { HTTP_PROVIDERS } from '@angular/http';
+import { ALFRESCO_SEARCH_PROVIDERS } from 'ng2-alfresco-search';
 import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core';
 import { UploadService } from 'ng2-alfresco-upload';
 import { AppComponent } from './app.component';
<|current_version|>
/*!
 * @license
 * Copyright 2016 Alfresco Software, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { HTTP_PROVIDERS } from '@angular/http';
import { ALFRESCO_SEARCH_PROVIDERS } from 'ng2-alfresco-search';
import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core';
import { UploadService } from 'ng2-alfresco-upload';
import { AppComponent } from './app.component';

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    ALFRESCO_CORE_PROVIDERS,
    UploadService
]);

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

import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { HTTP_PROVIDERS } from '@angular/http';
import { ALFRESCO_SEARCH_PROVIDERS } from 'ng2-alfresco-search';
import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core';
import { UploadService } from 'ng2-alfresco-upload';
import { AppComponent } from './app.component';

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    ALFRESCO_CORE_PROVIDERS,
    ALFRESCO_SEARCH_PROVIDERS,
    UploadService
]);


Clear reported lines if new report is received and it is less than report threshold

--- src/util/statusBarTextUtils.ts
+++ src/util/statusBarTextUtils.ts
@@ -22,6 +22,8 @@
       vimState.isRecordingMacro,
       true
     );
+  } else {
+    ReportClear(vimState);
   }
 }

@@ -41,6 +43,8 @@
         vimState.isRecordingMacro,
         true
       );
+    } else{
+      ReportClear(vimState);
     }
   }
 }

<|original_code|>
import { ModeName } from '../mode/mode';
import { StatusBar } from '../statusBar';
import { VimState } from '../state/vimState';
import { configuration } from '../configuration/configuration';

export function ReportClear(vimState: VimState) {
  StatusBar.Set('', vimState.currentMode, vimState.isRecordingMacro, true);
}

export function ReportLinesChanged(numLinesChanged: number, vimState: VimState) {
  if (numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' more lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  } else if (-numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' fewer lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  }
}

export function ReportLinesYanked(numLinesYanked: number, vimState: VimState) {
  if (numLinesYanked > configuration.report) {
    if (vimState.currentMode === ModeName.VisualBlock) {
      StatusBar.Set(
        'block of ' + numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    } else {
      StatusBar.Set(
        numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    }
  }
}

<|edits_diff|>
--- src/util/statusBarTextUtils.ts
+++ src/util/statusBarTextUtils.ts
@@ -22,6 +22,8 @@
       vimState.isRecordingMacro,
       true
     );
+  } else {
+    ReportClear(vimState);
   }
 }

<|current_version|>
import { ModeName } from '../mode/mode';
import { StatusBar } from '../statusBar';
import { VimState } from '../state/vimState';
import { configuration } from '../configuration/configuration';

export function ReportClear(vimState: VimState) {
  StatusBar.Set('', vimState.currentMode, vimState.isRecordingMacro, true);
}

export function ReportLinesChanged(numLinesChanged: number, vimState: VimState) {
  if (numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' more lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  } else if (-numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' fewer lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  } else {
    ReportClear(vimState);
  }
}

export function ReportLinesYanked(numLinesYanked: number, vimState: VimState) {
  if (numLinesYanked > configuration.report) {
    if (vimState.currentMode === ModeName.VisualBlock) {
      StatusBar.Set(
        'block of ' + numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    } else {
      StatusBar.Set(
        numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    }
  }
}

<|next_version|>
import { ModeName } from '../mode/mode';
import { StatusBar } from '../statusBar';
import { VimState } from '../state/vimState';
import { configuration } from '../configuration/configuration';

export function ReportClear(vimState: VimState) {
  StatusBar.Set('', vimState.currentMode, vimState.isRecordingMacro, true);
}

export function ReportLinesChanged(numLinesChanged: number, vimState: VimState) {
  if (numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' more lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  } else if (-numLinesChanged > configuration.report) {
    StatusBar.Set(
      numLinesChanged + ' fewer lines',
      vimState.currentMode,
      vimState.isRecordingMacro,
      true
    );
  } else {
    ReportClear(vimState);
  }
}

export function ReportLinesYanked(numLinesYanked: number, vimState: VimState) {
  if (numLinesYanked > configuration.report) {
    if (vimState.currentMode === ModeName.VisualBlock) {
      StatusBar.Set(
        'block of ' + numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    } else {
      StatusBar.Set(
        numLinesYanked + ' lines yanked',
        vimState.currentMode,
        vimState.isRecordingMacro,
        true
      );
    } else{
      ReportClear(vimState);
    }
  }
}


Add debug setting to `Orbit` global

Add debug setting to `Orbit` global

`Orbit.debug` is `true` by default to improve awareness of deprecations and other debugging safeguards.

--- packages/@orbit/core/src/main.ts
+++ packages/@orbit/core/src/main.ts
@@ -10,6 +10,7 @@
   assert: (description: string, test: boolean) => void | never;
   deprecate: (message: string, test?: boolean | (() => boolean)) => void;
   uuid: () => string;
+  debug: boolean;
 }

 // Establish the root object, `window` (`self`) in the browser, `global`
@@ -29,6 +30,7 @@
 export const Orbit: OrbitGlobal = {
   globals,
   assert,
+  debug: true,
   deprecate,
   uuid
 };

<|original_code|>
import { assert } from './assert';
import { deprecate } from './deprecate';
import { uuid } from '@orbit/utils';

declare const self: any;
declare const global: any;

export interface OrbitGlobal {
  globals: any;
  assert: (description: string, test: boolean) => void | never;
  deprecate: (message: string, test?: boolean | (() => boolean)) => void;
  uuid: () => string;
}

// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
//
// Source: https://github.com/jashkenas/underscore/blob/master/underscore.js#L11-L17
//     Underscore.js 1.8.3
//     http://underscorejs.org
//     (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
//     Underscore may be freely distributed under the MIT license.
const globals =
  (typeof self == 'object' && self.self === self && self) ||
  (typeof global == 'object' && global) ||
  {};

export const Orbit: OrbitGlobal = {
  globals,
  assert,
  deprecate,
  uuid
};

<|edits_diff|>
--- packages/@orbit/core/src/main.ts
+++ packages/@orbit/core/src/main.ts
@@ -10,6 +10,7 @@
   assert: (description: string, test: boolean) => void | never;
   deprecate: (message: string, test?: boolean | (() => boolean)) => void;
   uuid: () => string;
+  debug: boolean;
 }

 // Establish the root object, `window` (`self`) in the browser, `global`
<|current_version|>
import { assert } from './assert';
import { deprecate } from './deprecate';
import { uuid } from '@orbit/utils';

declare const self: any;
declare const global: any;

export interface OrbitGlobal {
  globals: any;
  assert: (description: string, test: boolean) => void | never;
  deprecate: (message: string, test?: boolean | (() => boolean)) => void;
  uuid: () => string;
  debug: boolean;
}

// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
//
// Source: https://github.com/jashkenas/underscore/blob/master/underscore.js#L11-L17
//     Underscore.js 1.8.3
//     http://underscorejs.org
//     (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
//     Underscore may be freely distributed under the MIT license.
const globals =
  (typeof self == 'object' && self.self === self && self) ||
  (typeof global == 'object' && global) ||
  {};

export const Orbit: OrbitGlobal = {
  globals,
  assert,
  deprecate,
  uuid
};

<|next_version|>
import { assert } from './assert';
import { deprecate } from './deprecate';
import { uuid } from '@orbit/utils';

declare const self: any;
declare const global: any;

export interface OrbitGlobal {
  globals: any;
  assert: (description: string, test: boolean) => void | never;
  deprecate: (message: string, test?: boolean | (() => boolean)) => void;
  uuid: () => string;
  debug: boolean;
}

// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
//
// Source: https://github.com/jashkenas/underscore/blob/master/underscore.js#L11-L17
//     Underscore.js 1.8.3
//     http://underscorejs.org
//     (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
//     Underscore may be freely distributed under the MIT license.
const globals =
  (typeof self == 'object' && self.self === self && self) ||
  (typeof global == 'object' && global) ||
  {};

export const Orbit: OrbitGlobal = {
  globals,
  assert,
  debug: true,
  deprecate,
  uuid
};


import ReactInputMask from 'react-input-mask';
import * as React from 'react';

<div>
    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />
</div>;

import ReactInputMask from 'react-input-mask';
import * as React from 'react';

let ref: HTMLInputElement | null = null;

<div>
    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="+7 (999) 999-99-99" inputRef={(node) => ref = node} />
</div>;

Add test for inputRef prop

Add test for inputRef prop

--- types/react-input-mask/react-input-mask-tests.tsx
+++ types/react-input-mask/react-input-mask-tests.tsx
@@ -1,5 +1,7 @@
 import ReactInputMask from 'react-input-mask';
 import * as React from 'react';
+
+let ref: HTMLInputElement | null = null;

 <div>
     <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
@@ -7,4 +9,5 @@
     <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
     <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
     <ReactInputMask mask="+7 (999) 999-99-99" />
+    <ReactInputMask mask="+7 (999) 999-99-99" inputRef={(node) => ref = node} />
 </div>;

import ReactInputMask from 'react-input-mask';
import * as React from 'react';

let ref: HTMLInputElement | null = null;

<div>
    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />
</div>;

<|original_code|>
import ReactInputMask from 'react-input-mask';
import * as React from 'react';

    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />

;

<|edits_diff|>
--- types/react-input-mask/react-input-mask-tests.tsx
+++ types/react-input-mask/react-input-mask-tests.tsx
@@ -1,5 +1,7 @@
 import ReactInputMask from 'react-input-mask';
 import * as React from 'react';
+
+let ref: HTMLInputElement | null = null;

     <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
<|current_version|>
import ReactInputMask from 'react-input-mask';
import * as React from 'react';

let ref: HTMLInputElement | null = null;

    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />

;

<|next_version|>
import ReactInputMask from 'react-input-mask';
import * as React from 'react';

let ref: HTMLInputElement | null = null;

    <ReactInputMask mask="+4\9 99 999 99" maskChar={null} />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="99-99-9999" defaultValue= "13-00-2017" />
    <ReactInputMask mask="99/99/9999" placeholder= "Enter birthdate" />
    <ReactInputMask mask="+7 (999) 999-99-99" />
    <ReactInputMask mask="+7 (999) 999-99-99" inputRef={(node) => ref = node} />

;


Fix dragStart, dragEnd mouse actions

Fix dragStart, dragEnd mouse actions

dragStart is called with (tree, node, $event)
dragEnd is called with (tree, node)
drag and dragOver is not implemented.

--- lib/directives/tree-drag.directive.ts
+++ lib/directives/tree-drag.directive.ts
@@ -22,10 +22,15 @@
   @HostListener('dragstart', ['$event']) onDragStart(ev) {
     // setting the data is required by firefox
     ev.dataTransfer.setData('text', ev.target.id);
+
+    this.draggedElement.mouseAction('dragStart', ev);
+
     setTimeout(() => this.treeDraggedElement.set(this.draggedElement), 30);
   }

   @HostListener('dragend') onDragEnd() {
+    this.draggedElement.mouseAction('dragEnd');
+
     this.treeDraggedElement.set(null);
   }
 }

<|original_code|>
import { Directive, Input, HostListener, Renderer, ElementRef, DoCheck } from '@angular/core';
import { TreeDraggedElement } from '../models/tree-dragged-element.model';

const DRAG_OVER_CLASS = 'is-dragging-over';

@Directive({
  selector: '[treeDrag]'
})
export class TreeDragDirective implements DoCheck {
  @Input('treeDrag') draggedElement;
  @Input() treeDragEnabled;

  private _allowDrag = (node) => true;

  constructor(private el: ElementRef, private renderer: Renderer, private treeDraggedElement: TreeDraggedElement) {
  }

  ngDoCheck() {
    this.renderer.setElementAttribute(this.el.nativeElement, 'draggable', this.treeDragEnabled ? 'true' : 'false');
  }

  @HostListener('dragstart', ['$event']) onDragStart(ev) {
    // setting the data is required by firefox
    ev.dataTransfer.setData('text', ev.target.id);
    setTimeout(() => this.treeDraggedElement.set(this.draggedElement), 30);
  }

  @HostListener('dragend') onDragEnd() {
    this.treeDraggedElement.set(null);
  }
}

<|edits_diff|>
--- lib/directives/tree-drag.directive.ts
+++ lib/directives/tree-drag.directive.ts
@@ -22,6 +22,9 @@
   @HostListener('dragstart', ['$event']) onDragStart(ev) {
     // setting the data is required by firefox
     ev.dataTransfer.setData('text', ev.target.id);
+
+    this.draggedElement.mouseAction('dragStart', ev);
+
     setTimeout(() => this.treeDraggedElement.set(this.draggedElement), 30);
   }

<|current_version|>
import { Directive, Input, HostListener, Renderer, ElementRef, DoCheck } from '@angular/core';
import { TreeDraggedElement } from '../models/tree-dragged-element.model';

const DRAG_OVER_CLASS = 'is-dragging-over';

@Directive({
  selector: '[treeDrag]'
})
export class TreeDragDirective implements DoCheck {
  @Input('treeDrag') draggedElement;
  @Input() treeDragEnabled;

  private _allowDrag = (node) => true;

  constructor(private el: ElementRef, private renderer: Renderer, private treeDraggedElement: TreeDraggedElement) {
  }

  ngDoCheck() {
    this.renderer.setElementAttribute(this.el.nativeElement, 'draggable', this.treeDragEnabled ? 'true' : 'false');
  }

  @HostListener('dragstart', ['$event']) onDragStart(ev) {
    // setting the data is required by firefox
    ev.dataTransfer.setData('text', ev.target.id);

    this.draggedElement.mouseAction('dragStart', ev);

    setTimeout(() => this.treeDraggedElement.set(this.draggedElement), 30);
  }

  @HostListener('dragend') onDragEnd() {
    this.treeDraggedElement.set(null);
  }
}

<|next_version|>
import { Directive, Input, HostListener, Renderer, ElementRef, DoCheck } from '@angular/core';
import { TreeDraggedElement } from '../models/tree-dragged-element.model';

const DRAG_OVER_CLASS = 'is-dragging-over';

@Directive({
  selector: '[treeDrag]'
})
export class TreeDragDirective implements DoCheck {
  @Input('treeDrag') draggedElement;
  @Input() treeDragEnabled;

  private _allowDrag = (node) => true;

  constructor(private el: ElementRef, private renderer: Renderer, private treeDraggedElement: TreeDraggedElement) {
  }

  ngDoCheck() {
    this.renderer.setElementAttribute(this.el.nativeElement, 'draggable', this.treeDragEnabled ? 'true' : 'false');
  }

  @HostListener('dragstart', ['$event']) onDragStart(ev) {
    // setting the data is required by firefox
    ev.dataTransfer.setData('text', ev.target.id);

    this.draggedElement.mouseAction('dragStart', ev);

    setTimeout(() => this.treeDraggedElement.set(this.draggedElement), 30);
  }

  @HostListener('dragend') onDragEnd() {
    this.draggedElement.mouseAction('dragEnd');

    this.treeDraggedElement.set(null);
  }
}


Fix Blank Space Component Background

Fix Blank Space Component Background

For some reason the background of the Blank Space Component was never rendered.

--- src/layout/BlankSpace.tsx
+++ src/layout/BlankSpace.tsx
@@ -1,5 +1,6 @@
 import * as React from "react";
 import * as LiveSplit from "../livesplit";
+import { gradientToCss } from "../util/ColorUtil";

 export interface Props { state: LiveSplit.BlankSpaceComponentStateJson }

@@ -10,6 +11,7 @@
                 className="blank-space"
                 style={{
                     height: this.props.state.height,
+                    background: gradientToCss(this.props.state.background),
                 }}
             />
         );

<|original_code|>
import * as React from "react";
import * as LiveSplit from "../livesplit";

export interface Props { state: LiveSplit.BlankSpaceComponentStateJson }

export default class BlankSpace extends React.Component<Props> {
    public render() {
        return (
            <div
                className="blank-space"
                style={{
                    height: this.props.state.height,
                }}
            />
        );
    }
}

<|edits_diff|>
--- src/layout/BlankSpace.tsx
+++ src/layout/BlankSpace.tsx
@@ -1,5 +1,6 @@
 import * as React from "react";
 import * as LiveSplit from "../livesplit";
+import { gradientToCss } from "../util/ColorUtil";

 export interface Props { state: LiveSplit.BlankSpaceComponentStateJson }

<|current_version|>
import * as React from "react";
import * as LiveSplit from "../livesplit";
import { gradientToCss } from "../util/ColorUtil";

export interface Props { state: LiveSplit.BlankSpaceComponentStateJson }

export default class BlankSpace extends React.Component<Props> {
    public render() {
        return (
            <div
                className="blank-space"
                style={{
                    height: this.props.state.height,
                }}
            />
        );
    }
}

<|next_version|>
import * as React from "react";
import * as LiveSplit from "../livesplit";
import { gradientToCss } from "../util/ColorUtil";

export interface Props { state: LiveSplit.BlankSpaceComponentStateJson }

export default class BlankSpace extends React.Component<Props> {
    public render() {
        return (
            <div
                className="blank-space"
                style={{
                    height: this.props.state.height,
                    background: gradientToCss(this.props.state.background),
                }}
            />
        );
    }
}


Include the pgsql Ace editor mode

[editor] Include the pgsql Ace editor mode

--- desktop/core/src/desktop/js/ext/aceHelper.ts
+++ desktop/core/src/desktop/js/ext/aceHelper.ts
@@ -11,6 +11,7 @@
 import 'ext/ace/mode-ksql';
 import 'ext/ace/mode-phoenix';
 import 'ext/ace/mode-presto';
+import 'ext/ace/mode-pgsql'
 import 'ext/ace/mode-sql';
 import 'ext/ace/mode-text';
 import 'ext/ace/snippets/bigquery';
@@ -22,6 +23,7 @@
 import 'ext/ace/snippets/ksql';
 import 'ext/ace/snippets/phoenix';
 import 'ext/ace/snippets/presto';
+import 'ext/ace/snippets/pgsql';
 import 'ext/ace/snippets/sql';
 import 'ext/ace/snippets/text';
 import 'ext/ace/theme-hue';

<|original_code|>
import 'ext/ace/ace'
import 'ext/ace/ext-language_tools';
import 'ext/ace/ext-searchbox';
import 'ext/ace/ext-settings_menu';
import 'ext/ace/mode-bigquery';
import 'ext/ace/mode-druid';
import 'ext/ace/mode-elasticsearch';
import 'ext/ace/mode-flink';
import 'ext/ace/mode-hive';
import 'ext/ace/mode-impala';
import 'ext/ace/mode-ksql';
import 'ext/ace/mode-phoenix';
import 'ext/ace/mode-presto';
import 'ext/ace/mode-sql';
import 'ext/ace/mode-text';
import 'ext/ace/snippets/bigquery';
import 'ext/ace/snippets/druid';
import 'ext/ace/snippets/elasticsearch';
import 'ext/ace/snippets/flink';
import 'ext/ace/snippets/hive';
import 'ext/ace/snippets/impala';
import 'ext/ace/snippets/ksql';
import 'ext/ace/snippets/phoenix';
import 'ext/ace/snippets/presto';
import 'ext/ace/snippets/sql';
import 'ext/ace/snippets/text';
import 'ext/ace/theme-hue';
import 'ext/ace/theme-hue_dark';
import './aceExtensions';

export default (window as any).ace;

<|edits_diff|>
--- desktop/core/src/desktop/js/ext/aceHelper.ts
+++ desktop/core/src/desktop/js/ext/aceHelper.ts
@@ -11,6 +11,7 @@
 import 'ext/ace/mode-ksql';
 import 'ext/ace/mode-phoenix';
 import 'ext/ace/mode-presto';
+import 'ext/ace/mode-pgsql'
 import 'ext/ace/mode-sql';
 import 'ext/ace/mode-text';
 import 'ext/ace/snippets/bigquery';
<|current_version|>
import 'ext/ace/ace'
import 'ext/ace/ext-language_tools';
import 'ext/ace/ext-searchbox';
import 'ext/ace/ext-settings_menu';
import 'ext/ace/mode-bigquery';
import 'ext/ace/mode-druid';
import 'ext/ace/mode-elasticsearch';
import 'ext/ace/mode-flink';
import 'ext/ace/mode-hive';
import 'ext/ace/mode-impala';
import 'ext/ace/mode-ksql';
import 'ext/ace/mode-phoenix';
import 'ext/ace/mode-presto';
import 'ext/ace/mode-pgsql'
import 'ext/ace/mode-sql';
import 'ext/ace/mode-text';
import 'ext/ace/snippets/bigquery';
import 'ext/ace/snippets/druid';
import 'ext/ace/snippets/elasticsearch';
import 'ext/ace/snippets/flink';
import 'ext/ace/snippets/hive';
import 'ext/ace/snippets/impala';
import 'ext/ace/snippets/ksql';
import 'ext/ace/snippets/phoenix';
import 'ext/ace/snippets/presto';
import 'ext/ace/snippets/sql';
import 'ext/ace/snippets/text';
import 'ext/ace/theme-hue';
import 'ext/ace/theme-hue_dark';
import './aceExtensions';

export default (window as any).ace;

<|next_version|>
import 'ext/ace/ace'
import 'ext/ace/ext-language_tools';
import 'ext/ace/ext-searchbox';
import 'ext/ace/ext-settings_menu';
import 'ext/ace/mode-bigquery';
import 'ext/ace/mode-druid';
import 'ext/ace/mode-elasticsearch';
import 'ext/ace/mode-flink';
import 'ext/ace/mode-hive';
import 'ext/ace/mode-impala';
import 'ext/ace/mode-ksql';
import 'ext/ace/mode-phoenix';
import 'ext/ace/mode-presto';
import 'ext/ace/mode-pgsql'
import 'ext/ace/mode-sql';
import 'ext/ace/mode-text';
import 'ext/ace/snippets/bigquery';
import 'ext/ace/snippets/druid';
import 'ext/ace/snippets/elasticsearch';
import 'ext/ace/snippets/flink';
import 'ext/ace/snippets/hive';
import 'ext/ace/snippets/impala';
import 'ext/ace/snippets/ksql';
import 'ext/ace/snippets/phoenix';
import 'ext/ace/snippets/presto';
import 'ext/ace/snippets/pgsql';
import 'ext/ace/snippets/sql';
import 'ext/ace/snippets/text';
import 'ext/ace/theme-hue';
import 'ext/ace/theme-hue_dark';
import './aceExtensions';

export default (window as any).ace;


Add foreground settings to playlist model.

--- Models/ModernPlaylist.ts
+++ Models/ModernPlaylist.ts
@@ -20,6 +20,8 @@
         isPlaylistOpen: boolean;
         playlist: Array<IModernPlaylistItem>;
         compactMode: boolean;
+        backgroundColor: string;
+        foregroundColor: string;
     }

     interface IModernPlaylistItem
@@ -32,5 +34,6 @@
         isExplicit: boolean;
         navigationUrl: string;
         coverImageUrl: string;
+        lrcFileOffset: number;
     }
 }

<|original_code|>
/**
 * @license
 *
 * ModernPlaylist.ts: Data structure for modern SoundManager2 playlist
 * -----------------------------------------------
 * Copyright (c) 2016 - 2017, The Little Moe New LLC. All rights reserved.
 *
 * This file is part of the project 'Sm2Shim'.
 * Code released under BSD-2-Clause license.
 *
 */

namespace Sm2Shim.Player.Models
{
    export interface IModernPlaylist
    {
        schemaVersion: number;
        loop: boolean;
        autoPlay: boolean;
        isPlaylistOpen: boolean;
        playlist: Array<IModernPlaylistItem>;
        compactMode: boolean;
    }

    interface IModernPlaylistItem
    {
        audioFileUrl: string;
        lrcFileUrl: string;
        title: string;
        album: string;
        artist: string;
        isExplicit: boolean;
        navigationUrl: string;
        coverImageUrl: string;
    }
}
<|edits_diff|>
--- Models/ModernPlaylist.ts
+++ Models/ModernPlaylist.ts
@@ -20,6 +20,8 @@
         isPlaylistOpen: boolean;
         playlist: Array<IModernPlaylistItem>;
         compactMode: boolean;
+        backgroundColor: string;
+        foregroundColor: string;
     }

     interface IModernPlaylistItem
<|current_version|>
/**
 * @license
 *
 * ModernPlaylist.ts: Data structure for modern SoundManager2 playlist
 * -----------------------------------------------
 * Copyright (c) 2016 - 2017, The Little Moe New LLC. All rights reserved.
 *
 * This file is part of the project 'Sm2Shim'.
 * Code released under BSD-2-Clause license.
 *
 */

namespace Sm2Shim.Player.Models
{
    export interface IModernPlaylist
    {
        schemaVersion: number;
        loop: boolean;
        autoPlay: boolean;
        isPlaylistOpen: boolean;
        playlist: Array<IModernPlaylistItem>;
        compactMode: boolean;
        backgroundColor: string;
        foregroundColor: string;
    }

    interface IModernPlaylistItem
    {
        audioFileUrl: string;
        lrcFileUrl: string;
        title: string;
        album: string;
        artist: string;
        isExplicit: boolean;
        navigationUrl: string;
        coverImageUrl: string;
    }
}
<|next_version|>
/**
 * @license
 *
 * ModernPlaylist.ts: Data structure for modern SoundManager2 playlist
 * -----------------------------------------------
 * Copyright (c) 2016 - 2017, The Little Moe New LLC. All rights reserved.
 *
 * This file is part of the project 'Sm2Shim'.
 * Code released under BSD-2-Clause license.
 *
 */

namespace Sm2Shim.Player.Models
{
    export interface IModernPlaylist
    {
        schemaVersion: number;
        loop: boolean;
        autoPlay: boolean;
        isPlaylistOpen: boolean;
        playlist: Array<IModernPlaylistItem>;
        compactMode: boolean;
        backgroundColor: string;
        foregroundColor: string;
    }

    interface IModernPlaylistItem
    {
        audioFileUrl: string;
        lrcFileUrl: string;
        title: string;
        album: string;
        artist: string;
        isExplicit: boolean;
        navigationUrl: string;
        coverImageUrl: string;
        lrcFileOffset: number;
    }
}


Add router testing module to Error Component tests

Router links have been added to the error component and thuus the testing module is required.

--- src/app/error/error.component.spec.ts
+++ src/app/error/error.component.spec.ts
@@ -1,4 +1,5 @@
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';

 import { TitleService } from '../shared/title.service';
 import { MockTitleService } from '../shared/mocks/mock-title.service';
@@ -14,6 +15,7 @@

   beforeEach(async(() => {
     TestBed.configureTestingModule({
+      imports: [ RouterTestingModule ],
       declarations: [
         PageHeroComponent,
         ErrorComponent

<|original_code|>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TitleService } from '../shared/title.service';
import { MockTitleService } from '../shared/mocks/mock-title.service';

import { PageHeroComponent } from '../shared/page-hero/page-hero.component';

import { ErrorComponent } from './error.component';

describe('ErrorComponent', () => {
  const mockTitleService = new MockTitleService();
  let component: ErrorComponent;
  let fixture: ComponentFixture<ErrorComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        PageHeroComponent,
        ErrorComponent
      ],
      providers: [
        { provide: TitleService, useValue: mockTitleService }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ErrorComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create and show 404 text', () => {
    expect(component).toBeTruthy();

    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('.basic-card > h2').textContent)
      .toContain('You’re looking a little lost there.');
  });

  it('should reset title', () => {
    expect(mockTitleService.mockTitle).toBe('');
  });
});

<|edits_diff|>
--- src/app/error/error.component.spec.ts
+++ src/app/error/error.component.spec.ts
@@ -1,4 +1,5 @@
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';

 import { TitleService } from '../shared/title.service';
 import { MockTitleService } from '../shared/mocks/mock-title.service';
<|current_version|>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { TitleService } from '../shared/title.service';
import { MockTitleService } from '../shared/mocks/mock-title.service';

import { PageHeroComponent } from '../shared/page-hero/page-hero.component';

import { ErrorComponent } from './error.component';

describe('ErrorComponent', () => {
  const mockTitleService = new MockTitleService();
  let component: ErrorComponent;
  let fixture: ComponentFixture<ErrorComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        PageHeroComponent,
        ErrorComponent
      ],
      providers: [
        { provide: TitleService, useValue: mockTitleService }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ErrorComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create and show 404 text', () => {
    expect(component).toBeTruthy();

    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('.basic-card > h2').textContent)
      .toContain('You’re looking a little lost there.');
  });

  it('should reset title', () => {
    expect(mockTitleService.mockTitle).toBe('');
  });
});

<|next_version|>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { TitleService } from '../shared/title.service';
import { MockTitleService } from '../shared/mocks/mock-title.service';

import { PageHeroComponent } from '../shared/page-hero/page-hero.component';

import { ErrorComponent } from './error.component';

describe('ErrorComponent', () => {
  const mockTitleService = new MockTitleService();
  let component: ErrorComponent;
  let fixture: ComponentFixture<ErrorComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ RouterTestingModule ],
      declarations: [
        PageHeroComponent,
        ErrorComponent
      ],
      providers: [
        { provide: TitleService, useValue: mockTitleService }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ErrorComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create and show 404 text', () => {
    expect(component).toBeTruthy();

    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('.basic-card > h2').textContent)
      .toContain('You’re looking a little lost there.');
  });

  it('should reset title', () => {
    expect(mockTitleService.mockTitle).toBe('');
  });
});


Fix item numbers on pages >1

Fix item numbers on pages >1

--- src/pages/story-list.ts
+++ src/pages/story-list.ts
@@ -11,6 +11,7 @@

 export abstract class StoryList implements RoutableComponentActivate, RoutableComponentDetermineActivationStrategy {
     stories: Item[];
+    offset: number;
     currentPage: number;
     totalPages: number;
     readonly route: string;
@@ -39,5 +40,7 @@
         } else {
             this.stories = await this.api.fetchItemsOnPage(this.allStories, this.currentPage);
         }
+
+        this.offset = STORIES_PER_PAGE * (this.currentPage - 1);
     }
 }

<|original_code|>
import {
    RoutableComponentActivate,
    RoutableComponentDetermineActivationStrategy,
    Router
} from 'aurelia-router';
import { Item } from '../models/item';
import {
    HackerNewsApi,
    STORIES_PER_PAGE
} from '../services/api';

export abstract class StoryList implements RoutableComponentActivate, RoutableComponentDetermineActivationStrategy {
    stories: Item[];
    currentPage: number;
    totalPages: number;
    readonly route: string;

    protected readonly api: HackerNewsApi;
    protected readonly router: Router;
    private allStories: number[] = [];

    constructor(api: HackerNewsApi, router: Router, route: string) {
        this.api = api;
        this.router = router;
        this.route = route;
    }

    determineActivationStrategy(): 'no-change' | 'invoke-lifecycle' | 'replace' {
        return 'invoke-lifecycle';
    }

    async activate(params: any): Promise<void> {
        this.allStories = await this.api.fetch(this.route);
        this.currentPage = params.page ? Number(params.page) : 1;
        this.totalPages = Math.ceil(this.allStories.length / STORIES_PER_PAGE);

        if (this.currentPage > this.totalPages) {
            this.router.navigateToRoute(this.route, { page: this.totalPages });
        } else {
            this.stories = await this.api.fetchItemsOnPage(this.allStories, this.currentPage);
        }
    }
}

<|edits_diff|>
--- src/pages/story-list.ts
+++ src/pages/story-list.ts
@@ -11,6 +11,7 @@

 export abstract class StoryList implements RoutableComponentActivate, RoutableComponentDetermineActivationStrategy {
     stories: Item[];
+    offset: number;
     currentPage: number;
     totalPages: number;
     readonly route: string;
<|current_version|>
import {
    RoutableComponentActivate,
    RoutableComponentDetermineActivationStrategy,
    Router
} from 'aurelia-router';
import { Item } from '../models/item';
import {
    HackerNewsApi,
    STORIES_PER_PAGE
} from '../services/api';

export abstract class StoryList implements RoutableComponentActivate, RoutableComponentDetermineActivationStrategy {
    stories: Item[];
    offset: number;
    currentPage: number;
    totalPages: number;
    readonly route: string;

    protected readonly api: HackerNewsApi;
    protected readonly router: Router;
    private allStories: number[] = [];

    constructor(api: HackerNewsApi, router: Router, route: string) {
        this.api = api;
        this.router = router;
        this.route = route;
    }

    determineActivationStrategy(): 'no-change' | 'invoke-lifecycle' | 'replace' {
        return 'invoke-lifecycle';
    }

    async activate(params: any): Promise<void> {
        this.allStories = await this.api.fetch(this.route);
        this.currentPage = params.page ? Number(params.page) : 1;
        this.totalPages = Math.ceil(this.allStories.length / STORIES_PER_PAGE);

        if (this.currentPage > this.totalPages) {
            this.router.navigateToRoute(this.route, { page: this.totalPages });
        } else {
            this.stories = await this.api.fetchItemsOnPage(this.allStories, this.currentPage);
        }
    }
}

<|next_version|>
import {
    RoutableComponentActivate,
    RoutableComponentDetermineActivationStrategy,
    Router
} from 'aurelia-router';
import { Item } from '../models/item';
import {
    HackerNewsApi,
    STORIES_PER_PAGE
} from '../services/api';

export abstract class StoryList implements RoutableComponentActivate, RoutableComponentDetermineActivationStrategy {
    stories: Item[];
    offset: number;
    currentPage: number;
    totalPages: number;
    readonly route: string;

    protected readonly api: HackerNewsApi;
    protected readonly router: Router;
    private allStories: number[] = [];

    constructor(api: HackerNewsApi, router: Router, route: string) {
        this.api = api;
        this.router = router;
        this.route = route;
    }

    determineActivationStrategy(): 'no-change' | 'invoke-lifecycle' | 'replace' {
        return 'invoke-lifecycle';
    }

    async activate(params: any): Promise<void> {
        this.allStories = await this.api.fetch(this.route);
        this.currentPage = params.page ? Number(params.page) : 1;
        this.totalPages = Math.ceil(this.allStories.length / STORIES_PER_PAGE);

        if (this.currentPage > this.totalPages) {
            this.router.navigateToRoute(this.route, { page: this.totalPages });
        } else {
            this.stories = await this.api.fetchItemsOnPage(this.allStories, this.currentPage);
        }

        this.offset = STORIES_PER_PAGE * (this.currentPage - 1);
    }
}


Fix bug with not exporting model in Firefox

--- src/firefox/data/scripts/background.ts
+++ src/firefox/data/scripts/background.ts
@@ -6,6 +6,7 @@
 export var ui   :user_interface.UserInterface;
 export var core :CoreConnector;
 export var browserConnector: FirefoxCoreConnector;
+export var model :user_interface.Model;
 function initUI() {
     browserConnector = new FirefoxCoreConnector();
     core = new CoreConnector(browserConnector);
@@ -16,6 +17,7 @@

 if (undefined === ui) {
     ui = initUI();
+    model = ui.model;
 }

 ui.browser = 'firefox';

<|original_code|>
import user_interface = require('../../../generic_ui/scripts/ui');
import CoreConnector = require('../../../generic_ui/scripts/core_connector');
import FirefoxCoreConnector = require('./firefox_connector');
import FirefoxBrowserApi = require('./firefox_browser_api');

export var ui   :user_interface.UserInterface;
export var core :CoreConnector;
export var browserConnector: FirefoxCoreConnector;
function initUI() {
    browserConnector = new FirefoxCoreConnector();
    core = new CoreConnector(browserConnector);
    var firefoxBrowserApi = new FirefoxBrowserApi();

    return new user_interface.UserInterface(core, firefoxBrowserApi);
}

if (undefined === ui) {
    ui = initUI();
}

ui.browser = 'firefox';

<|edits_diff|>
--- src/firefox/data/scripts/background.ts
+++ src/firefox/data/scripts/background.ts
@@ -6,6 +6,7 @@
 export var ui   :user_interface.UserInterface;
 export var core :CoreConnector;
 export var browserConnector: FirefoxCoreConnector;
+export var model :user_interface.Model;
 function initUI() {
     browserConnector = new FirefoxCoreConnector();
     core = new CoreConnector(browserConnector);
<|current_version|>
import user_interface = require('../../../generic_ui/scripts/ui');
import CoreConnector = require('../../../generic_ui/scripts/core_connector');
import FirefoxCoreConnector = require('./firefox_connector');
import FirefoxBrowserApi = require('./firefox_browser_api');

export var ui   :user_interface.UserInterface;
export var core :CoreConnector;
export var browserConnector: FirefoxCoreConnector;
export var model :user_interface.Model;
function initUI() {
    browserConnector = new FirefoxCoreConnector();
    core = new CoreConnector(browserConnector);
    var firefoxBrowserApi = new FirefoxBrowserApi();

    return new user_interface.UserInterface(core, firefoxBrowserApi);
}

if (undefined === ui) {
    ui = initUI();
}

ui.browser = 'firefox';

<|next_version|>
import user_interface = require('../../../generic_ui/scripts/ui');
import CoreConnector = require('../../../generic_ui/scripts/core_connector');
import FirefoxCoreConnector = require('./firefox_connector');
import FirefoxBrowserApi = require('./firefox_browser_api');

export var ui   :user_interface.UserInterface;
export var core :CoreConnector;
export var browserConnector: FirefoxCoreConnector;
export var model :user_interface.Model;
function initUI() {
    browserConnector = new FirefoxCoreConnector();
    core = new CoreConnector(browserConnector);
    var firefoxBrowserApi = new FirefoxBrowserApi();

    return new user_interface.UserInterface(core, firefoxBrowserApi);
}

if (undefined === ui) {
    ui = initUI();
    model = ui.model;
}

ui.browser = 'firefox';


Increase the coverage to 100%.

Increase the coverage to 100%.

Just to have a green badge! These tests for 'retax' are not really revelant. All sub retax modules are already tested.

--- src/__tests__/server-test.ts
+++ src/__tests__/server-test.ts
@@ -3,7 +3,12 @@
 import middleware from '../server';

 describe('retax server', () => {
+  const serverConfig = {
+    serverRendering: true,
+  };
+
   it('exposes the middleware', () => {
     expect(middleware instanceof Function).toBeTruthy();
+    expect(middleware(serverConfig) instanceof Function);
   });
 });

<|original_code|>
(jest as any).disableAutomock();

import middleware from '../server';

describe('retax server', () => {
  it('exposes the middleware', () => {
    expect(middleware instanceof Function).toBeTruthy();
  });
});

<|edits_diff|>
--- src/__tests__/server-test.ts
+++ src/__tests__/server-test.ts
@@ -3,6 +3,10 @@
 import middleware from '../server';

 describe('retax server', () => {
+  const serverConfig = {
+    serverRendering: true,
+  };
+
   it('exposes the middleware', () => {
     expect(middleware instanceof Function).toBeTruthy();
   });
<|current_version|>
(jest as any).disableAutomock();

import middleware from '../server';

describe('retax server', () => {
  const serverConfig = {
    serverRendering: true,
  };

  it('exposes the middleware', () => {
    expect(middleware instanceof Function).toBeTruthy();
  });
});

<|next_version|>
(jest as any).disableAutomock();

import middleware from '../server';

describe('retax server', () => {
  const serverConfig = {
    serverRendering: true,
  };

  it('exposes the middleware', () => {
    expect(middleware instanceof Function).toBeTruthy();
    expect(middleware(serverConfig) instanceof Function);
  });
});


Throw error if run command is executed and more than one device found

--- commands/device/run-application.ts
+++ commands/device/run-application.ts
@@ -7,6 +7,7 @@
 export class RunApplicationOnDeviceCommand implements ICommand {

 	constructor(private $devicesServices: Mobile.IDevicesServices,
+		private $errors: IErrors,
 		private $stringParameter: ICommandParameter) { }

 	allowedParameters: ICommandParameter[] = [this.$stringParameter];
@@ -15,6 +16,10 @@
 		return (() => {
 			this.$devicesServices.initialize({ deviceId: options.device, skipInferPlatform: true }).wait();

+			if (this.$devicesServices.deviceCount > 1) {
+				this.$errors.fail("More than one device found. Specify device explicitly with --device option.To discover device ID, use $appbuilder device command.");
+			}
+
 			var action = (device: Mobile.IDevice) =>  { return (() => device.runApplication(args[0]).wait()).future<void>()(); };
 			this.$devicesServices.execute(action).wait();
 		}).future<void>()();

<|original_code|>
///<reference path="../../../.d.ts"/>
"use strict";

import options = require("./../../options");
import helpers = require("./../../helpers");

export class RunApplicationOnDeviceCommand implements ICommand {

	constructor(private $devicesServices: Mobile.IDevicesServices,
		private $stringParameter: ICommandParameter) { }

	allowedParameters: ICommandParameter[] = [this.$stringParameter];

	public execute(args: string[]): IFuture<void> {
		return (() => {
			this.$devicesServices.initialize({ deviceId: options.device, skipInferPlatform: true }).wait();

			var action = (device: Mobile.IDevice) =>  { return (() => device.runApplication(args[0]).wait()).future<void>()(); };
			this.$devicesServices.execute(action).wait();
		}).future<void>()();
	}
}
$injector.registerCommand("device|run", RunApplicationOnDeviceCommand);
<|edits_diff|>
--- commands/device/run-application.ts
+++ commands/device/run-application.ts
@@ -7,6 +7,7 @@
 export class RunApplicationOnDeviceCommand implements ICommand {

 	constructor(private $devicesServices: Mobile.IDevicesServices,
+		private $errors: IErrors,
 		private $stringParameter: ICommandParameter) { }

 	allowedParameters: ICommandParameter[] = [this.$stringParameter];
<|current_version|>
///<reference path="../../../.d.ts"/>
"use strict";

import options = require("./../../options");
import helpers = require("./../../helpers");

export class RunApplicationOnDeviceCommand implements ICommand {

	constructor(private $devicesServices: Mobile.IDevicesServices,
		private $errors: IErrors,
		private $stringParameter: ICommandParameter) { }

	allowedParameters: ICommandParameter[] = [this.$stringParameter];

	public execute(args: string[]): IFuture<void> {
		return (() => {
			this.$devicesServices.initialize({ deviceId: options.device, skipInferPlatform: true }).wait();

			var action = (device: Mobile.IDevice) =>  { return (() => device.runApplication(args[0]).wait()).future<void>()(); };
			this.$devicesServices.execute(action).wait();
		}).future<void>()();
	}
}
$injector.registerCommand("device|run", RunApplicationOnDeviceCommand);
<|next_version|>
///<reference path="../../../.d.ts"/>
"use strict";

import options = require("./../../options");
import helpers = require("./../../helpers");

export class RunApplicationOnDeviceCommand implements ICommand {

	constructor(private $devicesServices: Mobile.IDevicesServices,
		private $errors: IErrors,
		private $stringParameter: ICommandParameter) { }

	allowedParameters: ICommandParameter[] = [this.$stringParameter];

	public execute(args: string[]): IFuture<void> {
		return (() => {
			this.$devicesServices.initialize({ deviceId: options.device, skipInferPlatform: true }).wait();

			if (this.$devicesServices.deviceCount > 1) {
				this.$errors.fail("More than one device found. Specify device explicitly with --device option.To discover device ID, use $appbuilder device command.");
			}

			var action = (device: Mobile.IDevice) =>  { return (() => device.runApplication(args[0]).wait()).future<void>()(); };
			this.$devicesServices.execute(action).wait();
		}).future<void>()();
	}
}
$injector.registerCommand("device|run", RunApplicationOnDeviceCommand);


Fix scrolling on list browser hover tooltips

--- src/picturepark-sdk-v1-angular/projects/picturepark-sdk-v1-angular-ui/src/lib/features-module/list-browser/list-browser.module.ts
+++ src/picturepark-sdk-v1-angular/projects/picturepark-sdk-v1-angular-ui/src/lib/features-module/list-browser/list-browser.module.ts
@@ -7,10 +7,14 @@
 // COMPONENTS
 import { ListBrowserComponent } from './list-browser.component';
 import { BrowserToolbarModule } from '../browser-toolbar/browser-toolbar.module';
+import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip';

 @NgModule({
   declarations: [ListBrowserComponent],
   imports: [CommonModule, SharedModule, BrowserToolbarModule],
   exports: [ListBrowserComponent],
+  providers: [
+    { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: { showDelay: 250, hideDelay: 0, touchGestures: 'off' } }
+  ]
 })
 export class ListBrowserModule {}

<|original_code|>
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// MODULES
import { SharedModule } from '../../shared-module/shared-module.module';

// COMPONENTS
import { ListBrowserComponent } from './list-browser.component';
import { BrowserToolbarModule } from '../browser-toolbar/browser-toolbar.module';

@NgModule({
  declarations: [ListBrowserComponent],
  imports: [CommonModule, SharedModule, BrowserToolbarModule],
  exports: [ListBrowserComponent],
})
export class ListBrowserModule {}

<|edits_diff|>
--- src/picturepark-sdk-v1-angular/projects/picturepark-sdk-v1-angular-ui/src/lib/features-module/list-browser/list-browser.module.ts
+++ src/picturepark-sdk-v1-angular/projects/picturepark-sdk-v1-angular-ui/src/lib/features-module/list-browser/list-browser.module.ts
@@ -7,6 +7,7 @@
 // COMPONENTS
 import { ListBrowserComponent } from './list-browser.component';
 import { BrowserToolbarModule } from '../browser-toolbar/browser-toolbar.module';
+import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip';

 @NgModule({
   declarations: [ListBrowserComponent],
<|current_version|>
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// MODULES
import { SharedModule } from '../../shared-module/shared-module.module';

// COMPONENTS
import { ListBrowserComponent } from './list-browser.component';
import { BrowserToolbarModule } from '../browser-toolbar/browser-toolbar.module';
import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip';

@NgModule({
  declarations: [ListBrowserComponent],
  imports: [CommonModule, SharedModule, BrowserToolbarModule],
  exports: [ListBrowserComponent],
})
export class ListBrowserModule {}

<|next_version|>
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// MODULES
import { SharedModule } from '../../shared-module/shared-module.module';

// COMPONENTS
import { ListBrowserComponent } from './list-browser.component';
import { BrowserToolbarModule } from '../browser-toolbar/browser-toolbar.module';
import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip';

@NgModule({
  declarations: [ListBrowserComponent],
  imports: [CommonModule, SharedModule, BrowserToolbarModule],
  exports: [ListBrowserComponent],
  providers: [
    { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: { showDelay: 250, hideDelay: 0, touchGestures: 'off' } }
  ]
})
export class ListBrowserModule {}