diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md
index b17c61ae73..d718b46117 100644
--- a/docs/en/UI/Angular/Component-Replacement.md
+++ b/docs/en/UI/Angular/Component-Replacement.md
@@ -1,10 +1,10 @@
-# Component Replacement
+## Component Replacement
You can replace some ABP components with your custom components.
The reason that you **can replace** but **cannot customize** default ABP components is disabling or changing a part of that component can cause problems. So we named those components as _Replaceable Components_.
-## How to Replace a Component
+### How to Replace a Component
Create a new component that you want to use instead of an ABP component. Add that component to `declarations` and `entryComponents` in the `AppModule`.
@@ -29,7 +29,54 @@ export class AppComponent {

-## Available Replaceable Components
+
+### How to Replace a Layout
+
+Each ABP theme module has 3 layouts named `ApplicationLayoutComponent`, `AccountLayoutComponent`, `EmptyLayoutComponent`. These layouts can be replaced with the same way.
+
+> A layout component template should contain `` element.
+
+The below example describes how to replace the `ApplicationLayoutComponent`:
+
+Run the following command to generate a layout in `angular` folder:
+
+```bash
+yarn ng generate component shared/my-application-layout --export --entryComponent
+
+# You don't need the --entryComponent option in Angular 9
+```
+
+Add the following code in your layout template (`my-layout.component.html`) where you want the page to be loaded.
+
+```html
+
+```
+
+Open the `app.component.ts` and add the below content:
+
+```js
+import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent
+import { MyApplicationLayoutComponent } from './shared/my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent
+import { Store } from '@ngxs/store'; // imported Store
+//...
+export class AppComponent {
+ constructor(..., private store: Store) {} // injected Store
+
+ ngOnInit() {
+ // added below content
+ this.store.dispatch(
+ new AddReplaceableComponent({
+ component: MyApplicationLayoutComponent,
+ key: 'Theme.ApplicationLayoutComponent',
+ }),
+ );
+
+ //...
+ }
+}
+```
+
+### Available Replaceable Components
| Component key | Description |
| -------------------------------------------------- | --------------------------------------------- |
diff --git a/docs/en/UI/Angular/Linked-List.md b/docs/en/UI/Angular/Linked-List.md
index c3fb307806..388c5963cd 100644
--- a/docs/en/UI/Angular/Linked-List.md
+++ b/docs/en/UI/Angular/Linked-List.md
@@ -26,7 +26,7 @@ The constructor does not get any parameters.
### How to Add New Nodes
-There are a few methods to create new nodes in a linked list and all of them are separately available as well as revealed from an `add` method.
+There are several methods to create new nodes in a linked list and all of them are separately available as well as revealed by `add` and `addMany` methods.
@@ -50,6 +50,22 @@ list.addHead('c');
+#### addManyHead(values: T\[\]): ListNode\\[\]
+
+Adds multiple nodes with given values as the first nodes in list:
+
+```js
+list.addManyHead(['a', 'b', 'c']);
+
+// "a" <-> "b" <-> "c"
+
+list.addManyHead(['x', 'y', 'z']);
+
+// "x" <-> "y" <-> "z" <-> "a" <-> "b" <-> "c"
+```
+
+
+
#### addTail(value: T): ListNode\
Adds a node with given value as the last node in list:
@@ -70,6 +86,22 @@ list.addTail('c');
+#### addManyTail(values: T\[\]): ListNode\\[\]
+
+Adds multiple nodes with given values as the last nodes in list:
+
+```js
+list.addManyTail(['a', 'b', 'c']);
+
+// "a" <-> "b" <-> "c"
+
+list.addManyTail(['x', 'y', 'z']);
+
+// "a" <-> "b" <-> "c" <-> "x" <-> "y" <-> "z"
+```
+
+
+
#### addAfter(value: T, previousValue: T, compareFn = compare): ListNode\
Adds a node with given value after the first node that has the previous value:
@@ -109,6 +141,40 @@ list.addAfter({ x: 0 }, { x: 2 }, (v1, v2) => v1.x === v2.x);
+#### addManyAfter(values: T\[\], previousValue: T, compareFn = compare): ListNode\\[\]
+
+Adds multiple nodes with given values after the first node that has the previous value:
+
+```js
+list.addManyTail(['a', 'b', 'b', 'c']);
+
+// "a" <-> "b" <-> "b" <-> "c"
+
+list.addManyAfter(['x', 'y'], 'b');
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "b" <-> "c"
+```
+
+
+
+You may pass a custom compare function to detect the searched value:
+
+```js
+list.addManyTail([{ x: 1 },{ x: 2 },{ x: 3 }]);
+
+// {"x":1} <-> {"x":2} <-> {"x":3}
+
+list.addManyAfter([{ x: 4 }, { x: 5 }], { x: 2 }, (v1, v2) => v1.x === v2.x);
+
+// {"x":1} <-> {"x":2} <-> {"x":4} <-> {"x":5} <-> {"x":3}
+```
+
+
+
+> The default compare function checks deep equality, so you will rarely need to pass that parameter.
+
+
+
#### addBefore(value: T, nextValue: T, compareFn = compare): ListNode\
Adds a node with given value before the first node that has the next value:
@@ -148,6 +214,40 @@ list.addBefore({ x: 0 }, { x: 2 }, (v1, v2) => v1.x === v2.x);
+#### addManyBefore(values: T\[\], nextValue: T, compareFn = compare): ListNode\\[\]
+
+Adds multiple nodes with given values before the first node that has the next value:
+
+```js
+list.addManyTail(['a', 'b', 'b', 'c']);
+
+// "a" <-> "b" <-> "b" <-> "c"
+
+list.addManyBefore(['x', 'y'], 'b');
+
+// "a" <-> "x" <-> "y" <-> "b" <-> "b" <-> "c"
+```
+
+
+
+You may pass a custom compare function to detect the searched value:
+
+```js
+list.addManyTail([{ x: 1 },{ x: 2 },{ x: 3 }]);
+
+// {"x":1} <-> {"x":2} <-> {"x":3}
+
+list.addManyBefore([{ x: 4 }, { x: 5 }], { x: 2 }, (v1, v2) => v1.x === v2.x);
+
+// {"x":1} <-> {"x":4} <-> {"x":5} <-> {"x":2} <-> {"x":3}
+```
+
+
+
+> The default compare function checks deep equality, so you will rarely need to pass that parameter.
+
+
+
#### addByIndex(value: T, position: number): ListNode\
Adds a node with given value at the specified position in the list:
@@ -166,6 +266,52 @@ list.addByIndex('x', 2);
+It works with negative index too:
+
+```js
+list.addTail('a');
+list.addTail('b');
+list.addTail('c');
+
+// "a" <-> "b" <-> "c"
+
+list.addByIndex('x', -1);
+
+// "a" <-> "b" <-> "x" <-> "c"
+```
+
+
+
+#### addManyByIndex(values: T\[\], position: number): ListNode\\[\]
+
+Adds multiple nodes with given values at the specified position in the list:
+
+```js
+list.addManyTail(['a', 'b', 'c']);
+
+// "a" <-> "b" <-> "c"
+
+list.addManyByIndex(['x', 'y'], 2);
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "c"
+```
+
+
+
+It works with negative index too:
+
+```js
+list.addManyTail(['a', 'b', 'c']);
+
+// "a" <-> "b" <-> "c"
+
+list.addManyByIndex(['x', 'y'], -1);
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "c"
+```
+
+
+
#### add(value: T).head(): ListNode\
Adds a node with given value as the first node in list:
@@ -314,10 +460,172 @@ list.add('x').byIndex(2);
+It works with negative index too:
+
+```js
+list.add('a').tail();
+list.add('b').tail();
+list.add('c').tail();
+
+// "a" <-> "b" <-> "c"
+
+list.add('x').byIndex(-1);
+
+// "a" <-> "b" <-> "x" <-> "c"
+```
+
+
+
> This is an alternative API for `addByIndex`.
+#### addMany(values: T\[\]).head(): ListNode\\[\]
+
+Adds multiple nodes with given values as the first nodes in list:
+
+```js
+list.addMany(['a', 'b', 'c']).head();
+
+// "a" <-> "b" <-> "c"
+
+list.addMany(['x', 'y', 'z']).head();
+
+// "x" <-> "y" <-> "z" <-> "a" <-> "b" <-> "c"
+```
+
+
+
+> This is an alternative API for `addManyHead`.
+
+
+
+#### addMany(values: T\[\]).tail(): ListNode\\[\]
+
+Adds multiple nodes with given values as the last nodes in list:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.addMany(['x', 'y', 'z']).tail();
+
+// "a" <-> "b" <-> "c" <-> "x" <-> "y" <-> "z"
+```
+
+
+
+> This is an alternative API for `addManyTail`.
+
+
+
+#### addMany(values: T\[\]).after(previousValue: T, compareFn = compare): ListNode\\[\]
+
+Adds multiple nodes with given values after the first node that has the previous value:
+
+```js
+list.addMany(['a', 'b', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "b" <-> "c"
+
+list.addMany(['x', 'y']).after('b');
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "b" <-> "c"
+```
+
+
+
+You may pass a custom compare function to detect the searched value:
+
+```js
+list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
+
+// {"x":1} <-> {"x":2} <-> {"x":3}
+
+list.addMany([{ x: 4 }, { x: 5 }]).after({ x: 2 }, (v1, v2) => v1.x === v2.x);
+
+// {"x":1} <-> {"x":2} <-> {"x":4} <-> {"x":5} <-> {"x":3}
+```
+
+
+
+> This is an alternative API for `addManyAfter`.
+>
+> The default compare function checks deep equality, so you will rarely need to pass that parameter.
+
+
+
+#### addMany(values: T\[\]).before(nextValue: T, compareFn = compare): ListNode\\[\]
+
+Adds multiple nodes with given values before the first node that has the next value:
+
+```js
+list.addMany(['a', 'b', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "b" <-> "c"
+
+list.addMany(['x', 'y']).before('b');
+
+// "a" <-> "x" <-> "y" <-> "b" <-> "b" <-> "c"
+```
+
+
+
+You may pass a custom compare function to detect the searched value:
+
+```js
+list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
+
+// {"x":1} <-> {"x":2} <-> {"x":3}
+
+list.addMany([{ x: 4 }, { x: 5 }]).before({ x: 2 }, (v1, v2) => v1.x === v2.x);
+
+// {"x":1} <-> {"x":4} <-> {"x":5} <-> {"x":2} <-> {"x":3}
+```
+
+
+
+> This is an alternative API for `addManyBefore`.
+>
+> The default compare function checks deep equality, so you will rarely need to pass that parameter.
+
+
+
+#### addMany(values: T\[\]).byIndex(position: number): ListNode\\[\]
+
+Adds multiple nodes with given values at the specified position in the list:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.addMany(['x', 'y']).byIndex(2);
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "c"
+```
+
+
+
+It works with negative index too:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.addMany(['x', 'y']).byIndex(-1);
+
+// "a" <-> "b" <-> "x" <-> "y" <-> "c"
+```
+
+
+
+> This is an alternative API for `addManyByIndex`.
+
+
+
### How to Remove Nodes
There are a few methods to remove nodes from a linked list and all of them are separately available as well as revealed from a `drop` method.
@@ -329,9 +637,7 @@ There are a few methods to remove nodes from a linked list and all of them are s
Removes the first node from the list:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -342,14 +648,28 @@ list.dropHead();
+#### dropManyHead(count: number): ListNode\\[\]
+
+Removes the first nodes from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.dropManyHead(2);
+
+// "c"
+```
+
+
+
#### dropTail(): ListNode\ | undefined
Removes the last node from the list:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -360,14 +680,28 @@ list.dropTail();
+#### dropManyTail(count: number): ListNode\\[\]
+
+Removes the last nodes from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.dropManyTail(2);
+
+// "a"
+```
+
+
+
#### dropByIndex(position: number): ListNode\ | undefined
Removes the node with the specified position from the list:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -378,16 +712,56 @@ list.dropByIndex(1);
+It works with negative index too:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.dropByIndex(-2);
+
+// "a" <-> "c"
+```
+
+
+
+#### dropManyByIndex(count: number, position: number): ListNode\\[\]
+
+Removes the nodes starting from the specified position from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c', 'd']).tail();
+
+// "a" <-> "b" <-> "c" <-> "d
+
+list.dropManyByIndex(2, 1);
+
+// "a" <-> "d"
+```
+
+
+
+It works with negative index too:
+
+```js
+list.addMany(['a', 'b', 'c', 'd']).tail();
+
+// "a" <-> "b" <-> "c" <-> "d
+
+list.dropManyByIndex(2, -2);
+
+// "a" <-> "d"
+```
+
+
+
#### dropByValue(value: T, compareFn = compare): ListNode\ | undefined
Removes the first node with given value from the list:
```js
-list.addTail('a');
-list.addTail('x');
-list.addTail('b');
-list.addTail('x');
-list.addTail('c');
+list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
@@ -401,11 +775,7 @@ list.dropByValue('x');
You may pass a custom compare function to detect the searched value:
```js
-list.addTail({ x: 1 });
-list.addTail({ x: 0 });
-list.addTail({ x: 2 });
-list.addTail({ x: 0 });
-list.addTail({ x: 3 });
+list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
@@ -425,11 +795,7 @@ list.dropByValue({ x: 0 }, (v1, v2) => v1.x === v2.x);
Removes all nodes with given value from the list:
```js
-list.addTail('a');
-list.addTail('x');
-list.addTail('b');
-list.addTail('x');
-list.addTail('c');
+list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
@@ -443,11 +809,7 @@ list.dropByValueAll('x');
You may pass a custom compare function to detect the searched value:
```js
-list.addTail({ x: 1 });
-list.addTail({ x: 0 });
-list.addTail({ x: 2 });
-list.addTail({ x: 0 });
-list.addTail({ x: 3 });
+list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
@@ -467,9 +829,7 @@ list.dropByValue({ x: 0 }, (v1, v2) => v1.x === v2.x);
Removes the first node in list:
```js
-list.add('a').tail();
-list.add('b').tail();
-list.add('c').tail();
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -489,9 +849,7 @@ list.drop().head();
Removes the last node in list:
```js
-list.add('a').tail();
-list.add('b').tail();
-list.add('c').tail();
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -511,9 +869,7 @@ list.drop().tail();
Removes the node with the specified position from the list:
```js
-list.add('a').tail();
-list.add('b').tail();
-list.add('c').tail();
+list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
@@ -524,6 +880,20 @@ list.drop().byIndex(1);
+It works with negative index too:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.drop().byIndex(-2);
+
+// "a" <-> "c"
+```
+
+
+
> This is an alternative API for `dropByIndex`.
@@ -533,11 +903,7 @@ list.drop().byIndex(1);
Removes the first node with given value from the list:
```js
-list.add('a').tail();
-list.add('x').tail();
-list.add('b').tail();
-list.add('x').tail();
-list.add('c').tail();
+list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
@@ -551,11 +917,7 @@ list.drop().byValue('x');
You may pass a custom compare function to detect the searched value:
```js
-list.add({ x: 1 }).tail();
-list.add({ x: 0 }).tail();
-list.add({ x: 2 }).tail();
-list.add({ x: 0 }).tail();
-list.add({ x: 3 }).tail();
+list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
@@ -577,11 +939,7 @@ list.drop().byValue({ x: 0 }, (v1, v2) => v1.x === v2.x);
Removes all nodes with given value from the list:
```js
-list.add('a').tail();
-list.add('x').tail();
-list.add('b').tail();
-list.add('x').tail();
-list.add('c').tail();
+list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
@@ -595,11 +953,7 @@ list.drop().byValueAll('x');
You may pass a custom compare function to detect the searched value:
```js
-list.add({ x: 1 }).tail();
-list.add({ x: 0 }).tail();
-list.add({ x: 2 }).tail();
-list.add({ x: 0 }).tail();
-list.add({ x: 3 }).tail();
+list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
@@ -616,6 +970,80 @@ list.drop().byValueAll({ x: 0 }, (v1, v2) => v1.x === v2.x);
+#### dropMany(count: number).head(): ListNode\\[\]
+
+Removes the first nodes from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.dropMany(2).head();
+
+// "c"
+```
+
+
+
+> This is an alternative API for `dropManyHead`.
+
+
+
+#### dropMany(count: number).tail(): ListNode\\[\]
+
+Removes the last nodes from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c']).tail();
+
+// "a" <-> "b" <-> "c"
+
+list.dropMany(2).tail();
+
+// "a"
+```
+
+
+
+> This is an alternative API for `dropManyTail`.
+
+
+
+#### dropMany(count: number).byIndex(position: number): ListNode\\[\]
+
+Removes the nodes starting from the specified position from the list based on given count:
+
+```js
+list.addMany(['a', 'b', 'c', 'd']).tail();
+
+// "a" <-> "b" <-> "c" <-> "d
+
+list.dropMany(2).byIndex(1);
+
+// "a" <-> "d"
+```
+
+
+
+It works with negative index too:
+
+```js
+list.addMany(['a', 'b', 'c', 'd']).tail();
+
+// "a" <-> "b" <-> "c" <-> "d
+
+list.dropMany(2).byIndex(-2);
+
+// "a" <-> "d"
+```
+
+
+
+> This is an alternative API for `dropManyByIndex`.
+
+
+
### How to Find Nodes
There are a few methods to find specific nodes in a linked list.
@@ -627,10 +1055,7 @@ There are a few methods to find specific nodes in a linked list.
Finds the first node from the list that matches the given predicate:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
@@ -650,10 +1075,7 @@ found.next.value === "b"
Finds the position of the first node from the list that matches the given predicate:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
@@ -677,9 +1099,7 @@ i3 === -1
Finds and returns the node with specific position in the list:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
@@ -699,10 +1119,7 @@ found.next.value === "c"
Finds the position of the first node from the list that has the given value:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
@@ -724,11 +1141,7 @@ i3 === -1
You may pass a custom compare function to detect the searched value:
```js
-list.addTail({ x: 1 });
-list.addTail({ x: 0 });
-list.addTail({ x: 2 });
-list.addTail({ x: 0 });
-list.addTail({ x: 3 });
+list.addTailMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]);
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
@@ -764,9 +1177,7 @@ There are a few ways to iterate over or display a linked list.
Runs a callback function on all nodes in a linked list from head to tail:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
@@ -784,9 +1195,7 @@ list.forEach((node, index) => console.log(node.value + index));
A linked list is iterable. In other words, you may use methods like `for...of` on it.
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
@@ -801,14 +1210,12 @@ for(const node of list) {
-#### toArray(): T[]
+#### toArray(): T\[\]
-Converts a linked list to an array:
+Converts a linked list to an array of values:
```js
-list.addTail('a');
-list.addTail('b');
-list.addTail('c');
+list.addTailMany(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
@@ -821,15 +1228,32 @@ arr === ['a', 'b', 'c']
+#### toNodeArray(): T\[\]
+
+Converts a linked list to an array of nodes:
+
+```js
+list.addTailMany(['a', 'b', 'c']);
+
+// "a" <-> "b" <-> "c"
+
+const arr = list.toNodeArray();
+
+/*
+arr[0].value === 'a'
+arr[1].value === 'a'
+arr[2].value === 'a'
+*/
+```
+
+
+
#### toString(): string
Converts a linked list to a string representation of nodes and their relations:
```js
-list.addTail('a');
-list.addTail(2);
-list.addTail('c');
-list.addTail({ k: 4, v: 'd' });
+list.addTailMany(['a', 2, 'c', { k: 4, v: 'd' }]);
// "a" <-> 2 <-> "c" <-> {"k":4,"v":"d"}
@@ -842,3 +1266,19 @@ str === '"a" <-> 2 <-> "c" <-> {"k":4,"v":"d"}'
+You may pass a custom mapper function to map values before stringifying them:
+
+```js
+list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }]).tail();
+
+// {"x":1} <-> {"x":2} <-> {"x":3} <-> {"x":4} <-> {"x":5}
+
+const str = list.toString(value => value.x);
+
+/*
+str === '1 <-> 2 <-> 3 <-> 4 <-> 5'
+*/
+```
+
+
+
diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md
index b1cd9ad500..6209350349 100644
--- a/docs/en/UI/Angular/Service-Proxies.md
+++ b/docs/en/UI/Angular/Service-Proxies.md
@@ -25,9 +25,9 @@ The files generated with the `--module all` option like below:
### Services
-Each generated service matches a back-end controller. The services methods call back-end APIs via [RestService](./HTTP-Requests.md#restservice).
+Each generated service matches a back-end controller. The services methods call back-end APIs via [RestService](./Http-Requests#restservice).
-A variable named `apiName` (available as of v2.4) is defined in each service. `apiName` matches the module's RemoteServiceName. This variable passes to the `RestService` as a parameter at each request. If there is no microservice API defined in the environment, `RestService` uses the default. See [getting a specific API endpoint from application config](HTTP-Requests#how-to-get-a-specific-api-endpoint-from-application-config)
+A variable named `apiName` (available as of v2.4) is defined in each service. `apiName` matches the module's RemoteServiceName. This variable passes to the `RestService` as a parameter at each request. If there is no microservice API defined in the environment, `RestService` uses the default. See [getting a specific API endpoint from application config](./Http-Requests#how-to-get-a-specific-api-endpoint-from-application-config)
The `providedIn` property of the services is defined as `'root'`. Therefore no need to add a service as a provider to a module. You can use a service by injecting it into a constructor as shown below:
@@ -64,4 +64,4 @@ Initial values can optionally be passed to each class constructor.
## What's Next?
-* [Http Requests](./Http-Requests.md)
\ No newline at end of file
+* [HTTP Requests](./Http-Requests)
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 46cd056d29..d5b24f4404 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -5,7 +5,7 @@
"items": [
{
"text": "From Startup Templates",
- "path": "Getting-Started-With-Startup-Templates.md"
+ "path": "Getting-Started-With-Startup-Templates.md",
"items": [
{
"text": "Application with MVC (Razor Pages) UI",
diff --git a/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md b/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md
index 4d98c6cbc5..c74945ec01 100644
--- a/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md
+++ b/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md
@@ -89,20 +89,23 @@ public static class IdentityDbContextModelBuilderExtensions
builder.Entity(b =>
{
- b.ToTable(options.TablePrefix + "Users", options.Schema);
+ b.ToTable(options.TablePrefix + "Users", options.Schema);
+ b.ConfigureByConvention();
//code omitted for brevity
});
builder.Entity(b =>
{
b.ToTable(options.TablePrefix + "UserClaims", options.Schema);
+ b.ConfigureByConvention();
//code omitted for brevity
- });
+ });
//code omitted for brevity
}
}
````
+* **推荐** 为每个Enttiy映射调用 `b.ConfigureByConvention();`(如上所示).
* **推荐** 通过继承 `ModelBuilderConfigurationOptions` 来创建 **configuration Options** 类. 例如:
````C#
diff --git a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md
index 745861e2c3..1ff03ae104 100644
--- a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md
+++ b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md
@@ -25,7 +25,35 @@ return user.GetProperty("Title");
参阅[实体文档](Entities.md)了解更多关于额外系统.
-> 可以基于额外的属性执行**业务逻辑**. 你可以**override**服务方法获取或设置值. 重写服务在下面进行讨论.
+> 可以基于额外的属性执行**业务逻辑**. 你可以[重写服务方法](Customizing-Application-Modules-Overriding-Services.md). 然后获取或设置如上所示的值.
+
+## 实体扩展 (EF Core)
+
+如上所述,实体所有的额外属性都作为单个JSON对象存储在数据库表中. 它不适用复杂的场景,特别是在你需要的时候.
+
+* 使用额外属性创建**索引**和**外键**.
+* 使用额外属性编写**SQL**或**LINQ**(例如根据属性值搜索).
+* 创建你**自己的实体**映射到相同的表,但在实体中定义一个额外属性做为 **常规属性**(参阅 [EF Core迁移文档](Entity-Framework-Core-Migrations.md)了解更多).
+
+为了解决上面的问题,用于EF Core的ABP框架实体扩展系统允许你使用上面定义相同的额外属性API,但将所需的属性存储在单独的数据库表字段中.
+
+假设你想要添加 `SocialSecurityNumber` 到[身份模块](Modules/Identity.md)的 `IdentityUser` 实体. 你可以使用 `EntityExtensionManager` 静态类:
+
+````csharp
+EntityExtensionManager.AddProperty(
+ "SocialSecurityNumber",
+ b => { b.HasMaxLength(32); }
+);
+````
+
+* 你提供了 `IdentityUser` 作为实体名(泛型参数), `string` 做为新属性的类型, `SocialSecurityNumber` 做为属性名(也是数据库表的字段名).
+* 你还需要提供一个使用[EF Core Fluent API](https://docs.microsoft.com/en-us/ef/core/modeling/entity-properties)定义数据库映射属性的操作.
+
+> 必须在使用相关的 `DbContext` 之前执行此代码. 应用程序启动模板定义了一个名为 `YourProjectNameEntityExtensions` 的静态类. 你可以在此类中定义扩展确保在正确的时间执行它. 否则你需要自己处理.
+
+定义实体扩展后你需要使用EF Core的[Add-Migration](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#add-migration)和[Update-Database](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#update-database)命令来创建code first迁移类并更新数据库.
+
+然后你可以使用上一部分中定义的相同额外属性系统来操纵实体上的属性.
## 创建新实体映射到同一个数据库表/Collection
diff --git a/docs/zh-Hans/Entities.md b/docs/zh-Hans/Entities.md
index e5cd3cf839..32dc4ceb53 100644
--- a/docs/zh-Hans/Entities.md
+++ b/docs/zh-Hans/Entities.md
@@ -365,14 +365,17 @@ public static class IdentityUserExtensions
存储字典的方式取决于你使用的数据库提供程序.
-* 对于 [Entity Framework Core](Entity-Framework-Core.md), 它以 `JSON` 字符串形式存储在 `ExtraProperties` 字段中. 序列化到 `JSON` 和反序列化到 `JSON` 由ABP使用EF Core的[值转换](https://docs.microsoft.com/zh-cn/ef/core/modeling/value-conversions)系统自动完成.
+* 对于 [Entity Framework Core](Entity-Framework-Core.md),这是两种类型的配置;
+ * 默认它以 `JSON` 字符串形式存储在 `ExtraProperties` 字段中. 序列化到 `JSON` 和反序列化到 `JSON` 由ABP使用EF Core的[值转换](https://docs.microsoft.com/zh-cn/ef/core/modeling/value-conversions)系统自动完成.
+ * 如果需要,你可以使用 `EntityExtensionManager` 为所需的额外属性定义一个单独的数据库字段. 那些使用 `EntityExtensionManager` 配置的属性继续使用单个 `JSON` 字段. 当你使用预构建的[应用模块](Modules/Index.md)并且想要[扩展模块的实体](Customizing-Application-Modules-Extending-Entities.md). 参阅[EF Core迁移文档](Entity-Framework-Core.md)了解如何使用 `EntityExtensionManager`.
* 对于 [MongoDB](MongoDB.md), 它以 **常规字段** 存储, 因为 MongoDB 天生支持这种 [额外](https://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#supporting-extra-elements) 系统.
### 讨论额外的属性
-如果你使用**可重复使用的模块**,其中定义了一个实体,你想使用简单的方式get/set此实体相关的一些数据,那么额外的属性系统是非常有用的. 通常 **不需要** 为自己的实体使用这个系统,是因为它有以下缺点:
+如果你使用**可重复使用的模块**,其中定义了一个实体,你想使用简单的方式get/set此实体相关的一些数据,那么额外的属性系统是非常有用的.
+你通常 **不需要** 为自己的实体使用这个系统,是因为它有以下缺点:
-* 它不是**完全类型安全的**.
+* 它不是**完全类型安全的**,因为它使用字符串用作属性名称.
* 这些属性**不容易[自动映射](Object-To-Object-Mapping.md)到其他对象**.
* 它**不会**为EF Core在数据库表中**创建字段**,因此在数据库中针对这个字段创建索引或搜索/排序并不容易.
diff --git a/docs/zh-Hans/Entity-Framework-Core-Migrations.md b/docs/zh-Hans/Entity-Framework-Core-Migrations.md
index bcb0ac864e..0b6b075fb6 100644
--- a/docs/zh-Hans/Entity-Framework-Core-Migrations.md
+++ b/docs/zh-Hans/Entity-Framework-Core-Migrations.md
@@ -95,7 +95,7 @@ Volo.Abp.IdentityServer.AbpIdentityServerDbProperties.DbTablePrefix = "Ids";
这个项目有应用程序的 `DbContext`类(本例中的 `BookStoreDbContex` ).
-**每个模块都使用自己的 `DbContext` 类**来访问数据库。同样你的应用程序有它自己的 `DbContext`. 通常在应用程序中使用这个 `DbContet`(如果你遵循最佳实践,应该在自定义[仓储](Repositories.md)中使用). 它几乎是一个空的 `DbContext`,因为你的应用程序在一开始没有任何实体,除了预定义的 `AppUser` 实体:
+**每个模块都使用自己的 `DbContext` 类**来访问数据库。同样你的应用程序有它自己的 `DbContext`. 通常在应用程序中使用这个 `DbContet`(如果你遵循最佳实践,应该在[仓储](Repositories.md)中使用). 它几乎是一个空的 `DbContext`,因为你的应用程序在一开始没有任何实体,除了预定义的 `AppUser` 实体:
````csharp
[ConnectionStringName("Default")]
@@ -119,15 +119,15 @@ public class BookStoreDbContext : AbpDbContext
builder.Entity(b =>
{
- //Sharing the same table "AbpUsers" with the IdentityUser
- b.ToTable("AbpUsers");
+ //Sharing the same Users table with the IdentityUser
+ b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users");
- //Configure base properties
b.ConfigureByConvention();
b.ConfigureAbpUser();
- //Moved customization of the "AbpUsers" table to an extension method
- b.ConfigureCustomUserProperties();
+ /* Configure mappings for your additional properties
+ * Also see the MyProjectNameEntityExtensions class
+ */
});
/* Configure your own tables/entities inside the ConfigureBookStore method */
@@ -190,12 +190,6 @@ public class BookStoreMigrationsDbContext : AbpDbContext(b =>
- {
- b.ConfigureCustomUserProperties();
- });
-
/* Configure your own tables/entities inside the ConfigureBookStore method */
builder.ConfigureBookStore();
}
@@ -276,7 +270,7 @@ public class BackgroundJobsDbContext
您可能想在应用程序中**重用依赖模块的表**. 在这种情况下你有两个选择:
-1. 你可以**直接使用模块定义的实体**.
+1. 你可以**直接使用模块定义的实体**(你仍然可以在某种程度上[扩展实体](Customizing-Application-Modules-Extending-Entities.md)).
2. 你可以**创建一个新的实体**映射到同一个数据库表。
###### 使用由模块定义的实体
@@ -379,10 +373,8 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity(b =>
{
b.ToTable("AbpRoles");
-
b.ConfigureByConvention();
-
- b.ConfigureCustomRoleProperties();
+ b.Property(x => x.Title).HasMaxLength(128);
});
...
@@ -399,68 +391,42 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity(b =>
{
b.ToTable("AbpRoles");
-
b.ConfigureByConvention();
-
- b.ConfigureCustomRoleProperties();
+ b.Property(x => x.Title).HasMaxLength(128);
});
````
* 它映射到 `AbpRoles` 表,与 `IdentityRole` 实体共享.
* `ConfigureByConvention()` 配置了标准/基本属性(像`TenantId`),建议总是调用它.
-`ConfigureCustomRoleProperties()` 还不存在. 在 `BookStoreDbContextModelCreatingExtensions` 类中定义它 (在 `.EntityFrameworkCore` 项目的 `DbContext` 附近):
+你已经为你的 `DbContext` 配置自定义属性,该属性在应用程序运行时使用.
+与其直接更改 `MigrationsDbContext`,我们应该使用ABP框架的实体扩展系统,在解决方案的 `.EntityFrameworkCore` 项目中找到 `YourProjectNameEntityExtensions` 类(本示例中是 `BookStoreEntityExtensions`)并且进行以下更改:
````csharp
-public static void ConfigureCustomRoleProperties(this EntityTypeBuilder b)
- where TRole : class, IEntity
+public static class MyProjectNameEntityExtensions
{
- b.Property(nameof(AppRole.Title)).HasMaxLength(128);
-}
-````
-
-* 这个方法只定义实体的**自定义属性**.
-* 遗憾的是,我们不能在这里充分的利用**类型安全**(通过引用`AppRole`实体). 我们能做的最好就是使用 `Title` 名称做为类型安全。
-
-你已经为运行应用程序使用的 `DbContext` 配置了自定义属性. 我们还需要配置 `MigrationsDbContext`.
-
-打开`MigrationsDbContext`(本例是 `BookStoreMigrationsDbContext`)进行以下更改:
-
-````csharp
-protected override void OnModelCreating(ModelBuilder builder)
-{
- base.OnModelCreating(builder);
-
- /* Include modules to your migration db context */
-
- ...
-
- /* Configure customizations for entities from the modules included */
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
- //CONFIGURE THE CUSTOM ROLE PROPERTIES
- builder.Entity(b =>
+ public static void Configure()
{
- b.ConfigureCustomRoleProperties();
- });
-
- ...
-
- /* Configure your own tables/entities inside the ConfigureBookStore method */
-
- builder.ConfigureBookStore();
+ OneTimeRunner.Run(() =>
+ {
+ EntityExtensionManager.AddProperty(
+ "Title",
+ b => { b.HasMaxLength(128); }
+ );
+ });
+ }
}
````
-只增加下面几行:
+> 我们建议使用 `nameof(AppRole.Title)` 而不是硬编码 "Title" 字符串
-````csharp
-builder.Entity(b =>
-{
- b.ConfigureCustomRoleProperties();
-});
-````
+`EntityExtensionManager` 用于添加属性到现有的实体. 由于 `EntityExtensionManager` 是静态的,因此应调用一次. `OneTimeRunner` 是ABP框架定义简单的工具类.
-通过这种方式,我们重用了用于为角色配置自定义属性映射的扩展方法. 但是对 `IdentityRole` 实体进行了相同的自定义.
+参阅[EF Core集成文档](Entity-Framework-Core.md)了解更多关于实体扩展系统.
+
+我们在两个类中都重复了类似的数据库映射代码,例如 `HasMaxLength(128)`.
现在你可以在包管理控制台(记得选择 `.EntityFrameworkCore.DbMigrations` 做为PMC的默认项目并将 `.Web` 项目设置为启动项目)使用标准的 `Add-Migration` 命令添加一个新的EF Core数据库迁移.
@@ -540,7 +506,7 @@ public class AppRoleAppService : ApplicationService, IAppRoleAppService
###### 使用ExtraProperties
-所有从 `AggregateRoot` 派生的实体都可以在 `ExtraProperties` 属性中存储键值对, 它是 `Dictionary` 类型在数据库中被序列化为JSON. 所以你可以在字典中添加值用于查询,无需更改实体.
+所有从 `AggregateRoot` 派生的实体都可以在 `ExtraProperties` 属性(因为它们都实现了 `IHasExtraProperties` 接口)中存储键值对, 它是 `Dictionary` 类型在数据库中被序列化为JSON. 所以你可以在字典中添加值用于查询,无需更改实体.
例如你可以将查询属性 `Title` 存储在 `IdentityRole` 中,而不是创建一个新的实体.
例:
@@ -558,16 +524,13 @@ public class IdentityRoleExtendingService : ITransientDependency
public async Task GetTitleAsync(Guid id)
{
var role = await _identityRoleRepository.GetAsync(id);
-
return role.GetProperty("Title");
}
public async Task SetTitleAsync(Guid id, string newTitle)
{
var role = await _identityRoleRepository.GetAsync(id);
-
role.SetProperty("Title", newTitle);
-
await _identityRoleRepository.UpdateAsync(role);
}
}
@@ -580,6 +543,12 @@ public class IdentityRoleExtendingService : ITransientDependency
* 所有的额外属性都存储在数据库中的一个**JSON对象**,它们不是作为表的字段存储,与简单的表字段相比创建索引和针对此属性使用SQL查询将更加困难.
* 属性名称是字符串,他们**不是类型安全的**. 建议这些类型的属性定义常量,以防止拼写错误.
+###### 使用实体扩展系统
+
+实体扩展系统解决了额外属性主要的问题: 它可以将额外属性做为**标准表字段**存储到数据库.
+
+你需要做的就是如上所诉使用 `EntityExtensionManager` 定义额外属性, 然后你就可以使得 `GetProperty` 和 `SetProperty` 方法对实体的属性进行get/set,但是这时它存储在数据库表的单独字段中.
+
###### 创建新表
你可以创建**自己的表**来存储属性,而不是创建新实体并映射到同一表. 你通常复制原始实体的一些值. 例如可以将 `Name` 字段添加到你自己的表中,它是原表中 `Name` 字段的副本.
diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md
index 0bec4d1ab9..8638b89b63 100644
--- a/docs/zh-Hans/Entity-Framework-Core.md
+++ b/docs/zh-Hans/Entity-Framework-Core.md
@@ -58,6 +58,53 @@ namespace MyCompany.MyProject
}
````
+### 关于EF Core Fluent Mapping
+
+[应用程序启动模板](Startup-Templates/Application.md)已配置使用[EF Core fluent configuration API](https://docs.microsoft.com/en-us/ef/core/modeling/)映射你的实体到数据库表.
+
+你依然为你的实体属性使用**data annotation attributes**(像`[Required]`),而ABP文档通常遵循**fluent mapping API** approach方法. 如何使用取决与你.
+
+ABP框架有一些**实体基类**和**约定**(参阅[实体文档](Entities.md))提供了一些有用的扩展方法来配置从基本实体类继承的属性.
+
+#### ConfigureByConvention 方法
+
+`ConfigureByConvention()` 是主要的扩展方法,它对你的实体**配置所有的基本属性**和约定. 所以在你的流利映射代码中为你所有的实体调用这个方法是 **最佳实践**,
+
+**示例**: 假设你有一个直接继承 `AggregateRoot` 基类的 `Book` 实体:
+
+````csharp
+public class Book : AuditedAggregateRoot
+{
+ public string Name { get; set; }
+}
+````
+
+你可以在你的 `DbContext` 重写 `OnModelCreating` 方法并且做以下配置:
+
+````csharp
+protected override void OnModelCreating(ModelBuilder builder)
+{
+ //Always call the base method
+ base.OnModelCreating(builder);
+
+ builder.Entity(b =>
+ {
+ b.ToTable("Books");
+
+ //Configure the base properties
+ b.ConfigureByConvention();
+
+ //Configure other properties (if you are using the fluent API)
+ b.Property(x => x.Name).IsRequired().HasMaxLength(128);
+ });
+}
+````
+
+* 这里调用了 `b.ConfigureByConvention()` 它对于**配置基本属性**非常重要.
+* 你可以在这里配置 `Name` 属性或者使用**data annotation attributes**(参阅[EF Core 文档](https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-properties)).
+
+> 尽管有许多扩展方法可以配置基本属性,但如果需要 `ConfigureByConvention()` 内部会调用它们. 因此仅调用它就足够了.
+
### 配置连接字符串选择
如果你的应用程序有多个数据库,你可以使用 `connectionStringName]` Attribute为你的DbContext配置连接字符串名称.
@@ -225,7 +272,7 @@ public override async Task DeleteAsync(
}
````
-### 访问 EF Core API
+## 访问 EF Core API
大多数情况下应该隐藏仓储后面的EF Core API(这也是仓储的设计目地). 但是如果想要通过仓储访问DbContext实现,则可以使用`GetDbContext()`或`GetDbSet()`扩展方法. 例:
@@ -251,9 +298,59 @@ public class BookService
> 要点: 你必须在使用`DbContext`的项目里引用`Volo.Abp.EntityFrameworkCore`包. 这会破坏封装,但在这种情况下,这就是你需要的.
-### 高级主题
+## Extra Properties & Entity Extension Manager
+
+额外属性系统允许你为实现了 `IHasExtraProperties` 的实体set/get动态属性. 当你想将自定义属性添加到[应用程序模块](Modules/Index.md)中定义的实体时,它特别有用.
+
+默认,实体的所有额外属性存储在数据库的一个 `JSON` 对象中. 实体扩展系统允许你存储额外属性在数据库的单独字段中.
-#### 设置默认仓储类
+有关额外属性和实体扩展系统的更多信息,请参阅下列文档:
+
+* [自定义应用模块: 扩展实体](Customizing-Application-Modules-Extending-Entities.md)
+* [实体](Entities.md)
+
+本节只解释了 `EntityExtensionManager` 及其用法.
+
+### AddProperty 方法
+
+`EntityExtensionManager` 的 `AddProperty` 方法允许你实体定义附加的属性.
+
+**示例**: 添加 `Title` 属性 (数据库字段)到 `IdentityRole` 实体:
+
+````csharp
+EntityExtensionManager.AddProperty(
+ "Title",
+ b => { b.HasMaxLength(128); }
+);
+````
+
+如果相关模块已实现此功能(通过使用下面说明的 `ConfigureExtensions`)则将新属性添加到模型中. 然后你需要运行标准的 `Add-Migration` 和 `Update-Database` 命令更新数据库以添加新字段.
+
+>`AddProperty` 方法必须在使用相关的 `DbContext` 之前调用,它是一个静态方法. 最好的方法是尽早的应用程序中使用它. 应用程序启动模板含有 `YourProjectNameEntityExtensions` 类,可以在放心的在此类中使用此方法.
+
+### ConfigureExtensions
+
+如果你正在开发一个可重用使用的模块,并允许应用程序开发人员将属性添加到你的实体,你可以在实体映射使用 `ConfigureExtensions` 扩展方法:
+
+````csharp
+builder.Entity(b =>
+{
+ b.ConfigureExtensions();
+ //...
+});
+````
+
+如果你调用 `ConfigureByConvention()` 扩展方法(在此示例中 `b.ConfigureByConvention`),ABP框架内部会调用 `ConfigureExtensions` 方法. 使用 `ConfigureByConvention` 方法是**最佳实践**,因为它还按照约定配置基本属性的数据库映射.
+
+参阅上面提到的 "*ConfigureByConvention 方法*" 了解更多信息.
+
+### GetPropertyNames
+
+`EntityExtensionManager.GetPropertyNames` 静态方法可以用作为此实体定义的扩展属性的名称. 应用程序代码通常不需要,但是ABP框架在内部使用它.
+
+## 高级主题
+
+### 设置默认仓储类
默认的通用仓储的默认实现是`EfCoreRepository`类,你可以创建自己的实现,并将其做为默认实现
@@ -343,3 +440,7 @@ context.Services.AddAbpDbContext(options =>
````
在这个例子中,`OtherDbContext`实现了`IBookStoreDbContext`. 此功能允许你在开发时使用多个DbContext(每个模块一个),但在运行时可以使用单个DbContext(实现所有DbContext的所有接口).
+
+## 另请参阅
+
+* [实体](Entities.md)
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs b/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs
deleted file mode 100644
index 5594306229..0000000000
--- a/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Volo.Abp.AspNetCore.Mvc;
-
-namespace VoloDocs.Web.Controllers
-{
- public class HomeController : AbpController
- {
- public void Index()
- {
-
- }
- }
-}
diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml
index 0d75012326..0a212f1499 100644
--- a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml
+++ b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml
@@ -3,3 +3,21 @@
@{
}
+@if (!Model.Projects.Any())
+{
+
+ No projects found!
+ See documentation to see how you can create a new one.
+
+}
+else
+{
+ Projects
+
+
+ @foreach (var project in Model.Projects)
+ {
+ @project.Name
+ }
+
+}
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs
index b127db4b3f..537d650f83 100644
--- a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs
+++ b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs
@@ -1,29 +1,59 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Options;
using Volo.Docs;
+using Volo.Docs.Projects;
namespace VoloDocs.Web.Pages
{
public class IndexModel : PageModel
{
+ public IReadOnlyList Projects { get; set; }
+
private readonly DocsUiOptions _urlUiOptions;
- public IndexModel(IOptions urlOptions)
+ private readonly IProjectAppService _projectAppService;
+
+ public IndexModel(IOptions urlOptions, IProjectAppService projectAppService)
{
+ _projectAppService = projectAppService;
_urlUiOptions = urlOptions.Value;
}
- public IActionResult OnGet()
+ public async Task OnGetAsync()
{
- //TODO: Create HomeController & Index instead of Page. Otherwise, we have an empty Index.cshtml file.
- if (!_urlUiOptions.RoutePrefix.IsNullOrWhiteSpace())
+ var projects = await _projectAppService.GetListAsync();
+
+ if (projects.Items.Count == 1)
{
- return Redirect("." + _urlUiOptions.RoutePrefix);
+ return await RedirectToProjectAsync(projects.Items.First());
+ }
+ else if (projects.Items.Count > 1)
+ {
+ Projects = projects.Items;
}
return Page();
}
+
+ private async Task RedirectToProjectAsync(ProjectDto project, string language = "en", string version = null)
+ {
+ var path = GetUrlForProject(project, language, version);
+ return await Task.FromResult(Redirect(path));
+ }
+
+ //Eg: "/en/abp/latest"
+ public string GetUrlForProject(ProjectDto project, string language = "en", string version = null)
+ {
+ return "." +
+ _urlUiOptions.RoutePrefix.EnsureStartsWith('/').EnsureEndsWith('/') +
+ language.EnsureEndsWith('/') +
+ project.ShortName.EnsureEndsWith('/') +
+ (version ?? DocsAppConsts.Latest);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/modules/docs/app/VoloDocs.Web/package-lock.json b/modules/docs/app/VoloDocs.Web/package-lock.json
index a666d3cc7c..e764349469 100644
--- a/modules/docs/app/VoloDocs.Web/package-lock.json
+++ b/modules/docs/app/VoloDocs.Web/package-lock.json
@@ -5,247 +5,256 @@
"requires": true,
"dependencies": {
"@abp/anchor-js": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/anchor-js/-/anchor-js-0.5.1.tgz",
- "integrity": "sha512-9N/iPP9tDdq9lKRNFQuqRL+QYSv5fq789KgHHGG1/MqExJ6KTPcqUDHvQ53kz96pUgJA+Fyn3dpwgPqLVYI3Yg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/anchor-js/-/anchor-js-1.1.1.tgz",
+ "integrity": "sha512-hHyYYJ09hhT5xeQJUsBN43yT+y49FKcigq4Wrx8448TrW7r2NJD5i3Xy3BGEstNSlfcQPTsmciQnbkcU2rX1HQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "anchor-js": "^4.1.1"
+ "@abp/core": "^1.1.1",
+ "anchor-js": "^4.2.2"
}
},
"@abp/aspnetcore.mvc.ui": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-0.4.9.tgz",
- "integrity": "sha512-AveMEi6WRQmD1tM9yVNLAe6ffcbtoL3ZGQKTPA95Q+dy5xBXVg4Y8jdhxawNPK64KYArhfrVkQDfa4mq3pW5Qw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-1.1.1.tgz",
+ "integrity": "sha512-wZbptVCSxZzEjkJx+/sWrH9Pikp9nOy7V8Htz+L+S7/qAzfXu5PRVV8ahddfAcDHRk30buRhdbJlCVdt6hkZ6g==",
"requires": {
- "ansi-colors": "^1.1.0",
+ "ansi-colors": "^4.1.1",
"extend-object": "^1.0.0",
- "gulp": "^3.9.1",
- "merge-stream": "^1.0.1",
+ "gulp": "^4.0.2",
+ "merge-stream": "^2.0.0",
"path": "^0.12.7",
- "rimraf": "^2.6.2"
+ "rimraf": "^3.0.0"
}
},
"@abp/aspnetcore.mvc.ui.theme.basic": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-0.4.9.tgz",
- "integrity": "sha512-g3Zby8x8+vWw3oTJsSPasjm4tv7BG4270PEf7jK9w925+lIyKYHn6UxOcFbSU2pi9mJTnaF+Fk/rScIcdxwZZw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-1.1.1.tgz",
+ "integrity": "sha512-ooXtCM3TWN69RU7xs6avnzOQBXzsiHY5BEIogzSBialZC4uG5H56qrIr4MbsFNae+PQM23Mw2tnJ/Z7dutURCQ==",
"requires": {
- "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.9"
+ "@abp/aspnetcore.mvc.ui.theme.shared": "^1.1.1"
}
},
"@abp/aspnetcore.mvc.ui.theme.shared": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-0.4.9.tgz",
- "integrity": "sha512-Fe4UfQ215Pz2V6D5HUYhDJFeJWjKLcv2gsZfOheWLlOBgYh274pdnUIwceoZ4Btpa9aPECLG+LAH4dTbs8vjRg==",
- "requires": {
- "@abp/aspnetcore.mvc.ui": "^0.4.9",
- "@abp/bootstrap": "^0.4.9",
- "@abp/datatables.net-bs4": "^0.4.9",
- "@abp/font-awesome": "^0.4.9",
- "@abp/jquery-form": "^0.4.9",
- "@abp/jquery-validation-unobtrusive": "^0.4.9",
- "@abp/lodash": "^0.4.9",
- "@abp/select2": "^0.4.9",
- "@abp/sweetalert": "^0.4.9",
- "@abp/timeago": "^0.4.9",
- "@abp/toastr": "^0.4.9"
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-1.1.1.tgz",
+ "integrity": "sha512-LilSyefzT1+rcTU7vbWxcO8TwBgGZIx6QbMUrDicSTH6LLJ9S5+yNaGNJbbZKDG6qx0BEoC1u8dE8KCUshwxoQ==",
+ "requires": {
+ "@abp/aspnetcore.mvc.ui": "^1.1.1",
+ "@abp/bootstrap": "^1.1.1",
+ "@abp/bootstrap-datepicker": "^1.1.1",
+ "@abp/datatables.net-bs4": "^1.1.1",
+ "@abp/font-awesome": "^1.1.1",
+ "@abp/jquery-form": "^1.1.1",
+ "@abp/jquery-validation-unobtrusive": "^1.1.1",
+ "@abp/lodash": "^1.1.1",
+ "@abp/luxon": "^1.1.1",
+ "@abp/malihu-custom-scrollbar-plugin": "^1.1.1",
+ "@abp/select2": "^1.1.1",
+ "@abp/sweetalert": "^1.1.1",
+ "@abp/timeago": "^1.1.1",
+ "@abp/toastr": "^1.1.1"
}
},
"@abp/bootstrap": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/bootstrap/-/bootstrap-0.4.9.tgz",
- "integrity": "sha512-A7lDHo43KnqjINo0xWECx/WzNQe3vqvE3GPv6uXq3KDi+gStQLAFBq3bVcVW/kSxiquDQ/tuCLRpE0qlhoobag==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/bootstrap/-/bootstrap-1.1.1.tgz",
+ "integrity": "sha512-OIaGJaizhI8UNfy4bnw2xT2Z0QG7BJJrjxOPGepfd4jn/AUi/vFdOpJFWvu2P9PwSzRmn/LuSlr2WONDOdPVWQ==",
+ "requires": {
+ "@abp/core": "^1.1.1",
+ "bootstrap": "^4.3.1"
+ }
+ },
+ "@abp/bootstrap-datepicker": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/bootstrap-datepicker/-/bootstrap-datepicker-1.1.1.tgz",
+ "integrity": "sha512-RIQLSrKBu/cTAU2lFenSAoKcMp7wgF4e3nP4/iOu5ZtCgti5vUjMEcqEvBxtlwKTHMXsTG4GtNKqjTwjXMjONQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "bootstrap": "^4.1.1"
+ "bootstrap-datepicker": "^1.9.0"
}
},
"@abp/clipboard": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/clipboard/-/clipboard-0.5.1.tgz",
- "integrity": "sha512-efOPloVL0moRqGpAMA7DU5o+vzzu7ipGOFcG9nOfDD6uGY9AsOztFc71GwIFrtwADvJSiJHD6OfEIfR++dCT0w==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/clipboard/-/clipboard-1.1.1.tgz",
+ "integrity": "sha512-O6b7VCAh2mxjkPhgUZYQBhXf0u+dWRECBOYN4KxYiKfk+2xL8X+34Ls7hVLbyuD+4xCcNirMZIG5CnS8auHC/A==",
"requires": {
- "@abp/core": "^0.4.9",
+ "@abp/core": "^1.1.1",
"clipboard": "^2.0.4"
}
},
"@abp/core": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/core/-/core-0.4.9.tgz",
- "integrity": "sha512-JbibIPDz0w/C9YhexNagMD763qbZCclcHLVlTpKEZUcxzp6rZXwPR6ekh/PnvzD0R7wmHOh+bHl0hs5JSdy3oA=="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/core/-/core-1.1.1.tgz",
+ "integrity": "sha512-OvUG7xRvk8nSqwC1s45YPnTuhC2OWe1AVa1nnC6FVHMH/g1Je7UJwnbu47K7uNS+lDRJUIktNbufYKiwutEjRg=="
},
"@abp/datatables.net": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/datatables.net/-/datatables.net-0.4.9.tgz",
- "integrity": "sha512-URimiGMFBusEMo9aAadLFCossbYyrN2R6+6YrQ+heqxdheCPmm2wupsXSFoUBHBhD0tzF4rY+OL//oOg3Wtg4g==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/datatables.net/-/datatables.net-1.1.1.tgz",
+ "integrity": "sha512-y76IDBlgc0n1YgQqJ+9cfzXpLwr2arhdIfSmqX+qRXz6GfVNY7e3JijkFSgDKUzKGYo1HZMzgJmDmeNIRwMZsQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "datatables.net": "^1.10.16"
+ "@abp/core": "^1.1.1",
+ "datatables.net": "^1.10.20"
}
},
"@abp/datatables.net-bs4": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/datatables.net-bs4/-/datatables.net-bs4-0.4.9.tgz",
- "integrity": "sha512-Dsz0fy2haBz3dl2MLXWjW2bhDBzp1cpWXSXj8TEEzYazjhyoqBy6AiFlEnRCqO49KZD6Ps1cONSRxx4c4On9Lg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/datatables.net-bs4/-/datatables.net-bs4-1.1.1.tgz",
+ "integrity": "sha512-t40xQIGBMLPZiSbcZHW3AwE8uk+xcl7OitBT1jym0XPKVtgJsHez3ynDE5v/PjHe+ColCG8lTRjRnNoXo5dzDw==",
"requires": {
- "@abp/datatables.net": "^0.4.9",
- "datatables.net-bs4": "^1.10.16"
+ "@abp/datatables.net": "^1.1.1",
+ "datatables.net-bs4": "^1.10.20"
}
},
"@abp/docs": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/docs/-/docs-0.5.1.tgz",
- "integrity": "sha512-3pGYnxZxm2kYPfu2EwDF0QinsNTym2cWlYAo7mVUBuReTPMhwHYtgrE7AX3nCVv1iAo6ltW+mebonGt1s5yXzA==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/docs/-/docs-1.1.1.tgz",
+ "integrity": "sha512-z2Dk7EOhBdFo6BYbgccD91PIg37L2ehkgRT4RWf61dRyjPAQgPwwwyVSqApFmKveWPCzreHoTPKbnrU7EzAssw==",
"requires": {
- "@abp/anchor-js": "^0.5.1",
- "@abp/clipboard": "^0.5.1",
- "@abp/malihu-custom-scrollbar-plugin": "^0.5.1",
- "@abp/popper.js": "^0.5.1",
- "@abp/prismjs": "^0.5.1"
+ "@abp/anchor-js": "^1.1.1",
+ "@abp/clipboard": "^1.1.1",
+ "@abp/malihu-custom-scrollbar-plugin": "^1.1.1",
+ "@abp/popper.js": "^1.1.1",
+ "@abp/prismjs": "^1.1.1"
}
},
"@abp/font-awesome": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/font-awesome/-/font-awesome-0.4.9.tgz",
- "integrity": "sha512-H4H/PJeSypoq++jP7eqS3y5jpbPIglUByPymHnho7U84gO06tZBUIoK00zyLACUVLzNztWANhmVqyA6OaHQ6xQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/font-awesome/-/font-awesome-1.1.1.tgz",
+ "integrity": "sha512-6RHbixi7IVWAb3JCHrUmEYD3HmAH4R75Nuo54LvFzATrh4G6gdBONIeDuTo79OTxe4Zhp+WLxeA49Y21kt77mg==",
"requires": {
- "@abp/core": "^0.4.9",
- "font-awesome": "^4.7.0"
+ "@abp/core": "^1.1.1",
+ "@fortawesome/fontawesome-free": "^5.11.2"
}
},
"@abp/jquery": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/jquery/-/jquery-0.4.9.tgz",
- "integrity": "sha512-Lte2rfDhcVXRA18mJMyPs0oFoiX/7x10F9cwMyX4+8e9QulA0dg+MjJZ4HIbxRoKvaYPz0AdE5VZ511folFeTg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/jquery/-/jquery-1.1.1.tgz",
+ "integrity": "sha512-kj4BTtXF0VbCzCqRXnRVEbGndR3F8NlbBhVQN6BQktOuZta3fvx7f2+pSok8vQv0ddmqUFY7FTT2Ei3l4363LQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "jquery": "^3.3.1"
+ "@abp/core": "^1.1.1",
+ "jquery": "^3.4.1"
}
},
"@abp/jquery-form": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/jquery-form/-/jquery-form-0.4.9.tgz",
- "integrity": "sha512-T1LzHNO+L/ATSfsaSu9H5rq9oUGjjBrwcJBVQhWRuGbB/Nsv1t4CdCPZHqbYBsn3ji/6T9C80FMdL+s4iOfy8A==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/jquery-form/-/jquery-form-1.1.1.tgz",
+ "integrity": "sha512-AIIdN36f8xwr4LgiNnBHohJ5tlxh/r+DuDtXcScpZN6GWBE+XgUotN0pZIIva82IxCyUNdDudzgluX9IjI+00w==",
"requires": {
- "@abp/jquery": "^0.4.9",
+ "@abp/jquery": "^1.1.1",
"jquery-form": "^4.2.2"
}
},
"@abp/jquery-validation": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/jquery-validation/-/jquery-validation-0.4.9.tgz",
- "integrity": "sha512-8C58G9BTYszW6E0EO6NYqXLEbABXt/yGlOqAFCkPiLVfUcoC6uARqkgIgNVnE99ZUeSmluNsYeCczP0Qb0yNzg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/jquery-validation/-/jquery-validation-1.1.1.tgz",
+ "integrity": "sha512-YvAjIW8epp+ddu01BTUkZWPfEADAvNPJeUrrZ6OpcPWM15Tf+ddr4ATgJ1LCg0Bh5F09iQC855osow3lt8sc7g==",
"requires": {
- "@abp/jquery": "^0.4.9",
- "jquery-validation": "^1.17.0"
+ "@abp/jquery": "^1.1.1",
+ "jquery-validation": "^1.19.1"
}
},
"@abp/jquery-validation-unobtrusive": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-0.4.9.tgz",
- "integrity": "sha512-GR62QEPexX4uLcqF3y72V39nlx/70C7ubeaIxS1ZEq+0wGklwAiyq1p19qpB5Cuj2GJL+vFrIig5w+B79P2iAw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-1.1.1.tgz",
+ "integrity": "sha512-q1b0KG8l3DXUiW8JXdq9l1jR/CwgzrZdxwdKGLB2J/oxHlywQIb7yrjR6WGCshjPpcx2SkOL0j/ZXMIMh533hQ==",
"requires": {
- "@abp/jquery-validation": "^0.4.9",
- "jquery-validation-unobtrusive": "^3.2.9"
+ "@abp/jquery-validation": "^1.1.1",
+ "jquery-validation-unobtrusive": "^3.2.11"
}
},
"@abp/lodash": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/lodash/-/lodash-0.4.9.tgz",
- "integrity": "sha512-/itYbXQL145WigKIGpnyWgARml7QGie7xqhC1WZG5iUkdqLx+4YBXesdzGFykthDewiQNz8mB2gPk64d376AAw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/lodash/-/lodash-1.1.1.tgz",
+ "integrity": "sha512-nH7bRS28Tf4hEXcpKHd1IM+MzYTqX8t3htGmsLX4UESQd52eODYOIldtX6gm3OW1O6ECwW6si/o0M2pTEpQqvg==",
"requires": {
- "@abp/core": "^0.4.9",
- "lodash": "^4.17.10"
- },
- "dependencies": {
- "lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
- }
+ "@abp/core": "^1.1.1",
+ "lodash": "^4.17.15"
+ }
+ },
+ "@abp/luxon": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/luxon/-/luxon-1.1.1.tgz",
+ "integrity": "sha512-WNu8JRSb5FDXfcDwjMYyeYeUN48uuDc/I2cdo3xd1rcY+lbmbzxoG9IYOlE8cRHdgX3z82qsZXFs2lcAy0Le2g==",
+ "requires": {
+ "luxon": "^1.21.3"
}
},
"@abp/malihu-custom-scrollbar-plugin": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-0.5.1.tgz",
- "integrity": "sha512-i9XorWsWcqb3tbbiwvE4OQCfXXJO38HlkQgvlwzxshB8xDcS9v/JL5fAAvM/Cr66fB2zybsrCseq9QcBXL+yCQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-1.1.1.tgz",
+ "integrity": "sha512-n4b4QK/L1Czdx0oOpUR/bWjK9VENexfUSV/aMjwzHhDmEFABAmEfhIpudCYDwewGswrd7C9agmBvakv2rwPQeA==",
"requires": {
- "@abp/core": "^0.4.9",
+ "@abp/core": "^1.1.1",
"malihu-custom-scrollbar-plugin": "^3.1.5"
}
},
"@abp/popper.js": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/popper.js/-/popper.js-0.5.1.tgz",
- "integrity": "sha512-qS97hQQtG78mVPRvmZZtBb7Vu905NpThl9PN3jPWWDiVbOV2/d+BXCTRhTRbfdup3C5cmGdntjaGxfcxlxHt1Q==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/popper.js/-/popper.js-1.1.1.tgz",
+ "integrity": "sha512-heR73cqmMsVPNgsPxBYbkvc842R3hEEuDAj4oaXZwVTeWXayU6TdDcGdIrfwMZwW2eWivYNnO0bMOVmuhZKTTQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "popper.js": "^1.14.6"
+ "@abp/core": "^1.1.1",
+ "popper.js": "^1.16.0"
}
},
"@abp/prismjs": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/@abp/prismjs/-/prismjs-0.5.1.tgz",
- "integrity": "sha512-DxoidAVV8LmtgFonbzGJEfszQDUaHEQc+/bcJtyQCuv5l+uflVnpAH+6W8IAErt5N96a0RJbeV9ZBXjIhqOzpA==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/prismjs/-/prismjs-1.1.1.tgz",
+ "integrity": "sha512-kZh2imqVTMDWmE2v+S4wMsigu/hSyVaz3VvZzGctFNctzC17LeD6z6ymfrtQ5BPJbCxGSpHwOt4/Y8bycPTEuQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "prismjs": "^1.15.0"
+ "@abp/core": "^1.1.1",
+ "prismjs": "^1.17.1"
}
},
"@abp/select2": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/select2/-/select2-0.4.9.tgz",
- "integrity": "sha512-AaJHWy9fkP/LqVkruZGfvzgdZXyT96/FpnflUpoNPXjuvVRptkJpd/BQiWjpyjS+qzuZ+m3X9dms0d0lAyFKYA==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/select2/-/select2-1.1.1.tgz",
+ "integrity": "sha512-t0qcJhD+uo2+XWr4nmMQLAx7MRGQUBdZ81YmGty045ReoSaEKQf4haLkzBcMzpBRusiyMQO/PbxjtwMw/xJQTQ==",
"requires": {
- "@abp/core": "^0.4.9",
- "select2": "^4.0.5"
+ "@abp/core": "^1.1.1",
+ "select2": "^4.0.12"
}
},
"@abp/sweetalert": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/sweetalert/-/sweetalert-0.4.9.tgz",
- "integrity": "sha512-FaxtELo7Um/uasasbOGi1j1XuBtZ819mUo7+6pMSWj2CSAkg2A/RyT9NhYcX8oyGpv188W5CjZfJ1DM0bRH+pQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/sweetalert/-/sweetalert-1.1.1.tgz",
+ "integrity": "sha512-V6K/qg7J/bdFmom2kaXYeiLvcmLHFl+MacPX4yYAK2biZdb2pWOkUdmcAzZdOT+UruKfLRhvraVC2uXDySi9NA==",
"requires": {
- "@abp/core": "^0.4.9",
- "sweetalert": "^2.1.0"
+ "@abp/core": "^1.1.1",
+ "sweetalert": "^2.1.2"
}
},
"@abp/timeago": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/timeago/-/timeago-0.4.9.tgz",
- "integrity": "sha512-RsAyJCl+rEWQL0q0Nx/ijy+iOBYm5IC5Re6y4SQ1jYF/B4n88GM2PFy6kLrE+HHGl5Z5hkWr5OGXmFem50Y3Wg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/timeago/-/timeago-1.1.1.tgz",
+ "integrity": "sha512-QYYih/4n6XhCqkRw7fBfyg58T5CHqJHyz7SAfq86RiKAJ4jVtjdSVxj3XKxz8eCb56wZGsO1xXXStI3vdLwwNw==",
"requires": {
- "@abp/jquery": "^0.4.9",
- "timeago": "^1.6.3"
+ "@abp/jquery": "^1.1.1",
+ "timeago": "^1.6.7"
}
},
"@abp/toastr": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/@abp/toastr/-/toastr-0.4.9.tgz",
- "integrity": "sha512-KjnETa1Og5EIMDw/pIxPoKLTABBcsxBN8BqwIG33ya2+BIRfAI7b0lEMoKK+qmwVwI5dkXZlKFGIUmPtb+zVCw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abp/toastr/-/toastr-1.1.1.tgz",
+ "integrity": "sha512-GDewBppm+0FO6kTTy0huczoH9P5q6lFicHFAoEawAMkuWJFW/Ihv/YnEvKGDQwGftuVSWexfqBMN/RZ5YSOiGQ==",
"requires": {
- "@abp/jquery": "^0.4.9",
+ "@abp/jquery": "^1.1.1",
"toastr": "^2.1.4"
}
},
- "almond": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz",
- "integrity": "sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA="
+ "@fortawesome/fontawesome-free": {
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz",
+ "integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg=="
},
"anchor-js": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/anchor-js/-/anchor-js-4.1.1.tgz",
- "integrity": "sha512-c2Wl9F1X0C4jkYKLla1SNE2uI6xJrSKsRC7HCCg4yLNQ5sL5D+tDEWrjRaoTuTlMTqBCnF6kOuR3dx59Erxpvw=="
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/anchor-js/-/anchor-js-4.2.2.tgz",
+ "integrity": "sha512-Rg1tGaG4K3avYqDh7rOYCE/odWxpUiHStnlKL/bGOt9cl6NjR06zhPGVQcCAjE5PT48oQeHVgqNmLzxh0Kuk4A=="
},
"ansi-colors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
- "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
- "requires": {
- "ansi-wrap": "^0.1.0"
- }
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
},
"ansi-gray": {
"version": "0.1.1",
@@ -260,16 +269,28 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
"ansi-wrap": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768="
},
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "append-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+ "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+ "requires": {
+ "buffer-equal": "^1.0.0"
+ }
+ },
"archy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
@@ -280,35 +301,89 @@
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
},
+ "arr-filter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+ "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
},
+ "arr-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+ "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
"arr-union": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
},
- "array-differ": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
- "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE="
- },
"array-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
"integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8="
},
+ "array-initial": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+ "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+ "requires": {
+ "array-slice": "^1.0.0",
+ "is-number": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+ }
+ }
+ },
+ "array-last": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "requires": {
+ "is-number": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+ }
+ }
+ },
"array-slice": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
"integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="
},
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
+ "array-sort": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+ "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+ "requires": {
+ "default-compare": "^1.0.0",
+ "get-value": "^2.0.6",
+ "kind-of": "^5.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
},
"array-unique": {
"version": "0.3.2",
@@ -320,11 +395,51 @@
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
},
+ "async-done": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
+ "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.2",
+ "process-nextick-args": "^2.0.0",
+ "stream-exhaust": "^1.0.1"
+ }
+ },
+ "async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
+ },
+ "async-settle": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+ "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+ "requires": {
+ "async-done": "^1.2.2"
+ }
+ },
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
+ "bach": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+ "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+ "requires": {
+ "arr-filter": "^1.1.1",
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "array-each": "^1.0.0",
+ "array-initial": "^1.0.0",
+ "array-last": "^1.1.1",
+ "async-done": "^1.2.2",
+ "async-settle": "^1.0.0",
+ "now-and-later": "^2.0.0"
+ }
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -380,15 +495,32 @@
}
}
},
- "beeper": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
- "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak="
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw=="
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
},
"bootstrap": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz",
- "integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w=="
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.4.1.tgz",
+ "integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA=="
+ },
+ "bootstrap-datepicker": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/bootstrap-datepicker/-/bootstrap-datepicker-1.9.0.tgz",
+ "integrity": "sha512-9rYYbaVOheGYxjOr/+bJCmRPihfy+LkLSg4fIFMT9Od8WwWB/MB50w0JO1eBgKUMbb7PFHQD5uAfI3ArAxZRXA==",
+ "requires": {
+ "jquery": ">=1.7.1 <4.0.0"
+ }
},
"brace-expansion": {
"version": "1.1.11",
@@ -426,6 +558,16 @@
}
}
},
+ "buffer-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+ "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74="
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ },
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -442,16 +584,35 @@
"unset-value": "^1.0.0"
}
},
- "chalk": {
- "version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+ },
+ "chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ }
}
},
"class-utils": {
@@ -476,24 +637,64 @@
}
},
"clipboard": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
- "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
+ "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
"clone": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
- "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
+ },
+ "clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg="
},
"clone-stats": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
- "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA="
+ },
+ "cloneable-readable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^2.0.0",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "collection-map": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+ "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+ "requires": {
+ "arr-map": "^2.0.2",
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
},
"collection-visit": {
"version": "1.0.0",
@@ -510,47 +711,79 @@
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
},
"component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
"copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
},
+ "copy-props": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
+ "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
+ "requires": {
+ "each-props": "^1.3.0",
+ "is-plain-object": "^2.0.1"
+ }
+ },
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
"datatables.net": {
- "version": "1.10.19",
- "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.19.tgz",
- "integrity": "sha512-+ljXcI6Pj3PTGy5pesp3E5Dr3x3AV45EZe0o1r0gKENN2gafBKXodVnk2ypKwl2tTmivjxbkiqoWnipTefyBTA==",
+ "version": "1.10.20",
+ "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.20.tgz",
+ "integrity": "sha512-4E4S7tTU607N3h0fZPkGmAtr9mwy462u+VJ6gxYZ8MxcRIjZqHy3Dv1GNry7i3zQCktTdWbULVKBbkAJkuHEnQ==",
"requires": {
"jquery": ">=1.7"
}
},
"datatables.net-bs4": {
- "version": "1.10.19",
- "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.19.tgz",
- "integrity": "sha512-pgeP17w4aPR7HIxIwuJghfqXULjdg1K6xMUUKDyCERJRSNNK4MRToFfELtIsluLNN555YBK4Kx8nihX5/ZT1Fw==",
+ "version": "1.10.20",
+ "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.20.tgz",
+ "integrity": "sha512-kQmMUMsHMOlAW96ztdoFqjSbLnlGZQ63iIM82kHbmldsfYdzuyhbb4hTx6YNBi481WCO3iPSvI6YodNec46ZAw==",
"requires": {
- "datatables.net": "1.10.19",
+ "datatables.net": "1.10.20",
"jquery": ">=1.7"
}
},
- "dateformat": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
- "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI="
- },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -559,17 +792,42 @@
"ms": "2.0.0"
}
},
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
- "defaults": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
- "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "default-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+ "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+ "requires": {
+ "kind-of": "^5.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "default-resolution": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+ "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ="
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"requires": {
- "clone": "^1.0.2"
+ "object-keys": "^1.0.12"
}
},
"define-property": {
@@ -614,30 +872,65 @@
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
},
- "deprecated": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz",
- "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk="
- },
"detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
},
- "duplexer2": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
- "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
+ "duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "each-props": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+ "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
"requires": {
- "readable-stream": "~1.1.9"
+ "is-plain-object": "^2.0.1",
+ "object.defaults": "^1.1.0"
}
},
"end-of-stream": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
- "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.53",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+ "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
"requires": {
- "once": "~1.3.0"
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
}
},
"es6-object-assign": {
@@ -645,10 +938,25 @@
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
},
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
},
"expand-brackets": {
"version": "2.1.4",
@@ -690,6 +998,21 @@
"homedir-polyfill": "^1.0.1"
}
},
+ "ext": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+ "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+ "requires": {
+ "type": "^2.0.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
+ "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow=="
+ }
+ }
+ },
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -779,15 +1102,22 @@
}
},
"fancy-log": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
- "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
"requires": {
"ansi-gray": "^0.1.1",
"color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
"time-stamp": "^1.0.0"
}
},
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true
+ },
"fill-range": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -809,26 +1139,30 @@
}
}
},
- "find-index": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
- "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ="
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
},
"findup-sync": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
- "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+ "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
"requires": {
"detect-file": "^1.0.0",
- "is-glob": "^3.1.0",
+ "is-glob": "^4.0.0",
"micromatch": "^3.0.4",
"resolve-dir": "^1.0.1"
}
},
"fined": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz",
- "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
"requires": {
"expand-tilde": "^2.0.2",
"is-plain-object": "^2.0.3",
@@ -837,20 +1171,19 @@
"parse-filepath": "^1.0.1"
}
},
- "first-chunk-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz",
- "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04="
- },
"flagged-respawn": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz",
- "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="
},
- "font-awesome": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
- "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
+ "flush-write-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
+ }
},
"for-in": {
"version": "1.0.2",
@@ -873,84 +1206,579 @@
"map-cache": "^0.2.2"
}
},
- "fs.realpath": {
+ "fs-mkdirp-stream": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "gaze": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz",
- "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+ "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
"requires": {
- "globule": "~0.1.0"
+ "graceful-fs": "^4.1.11",
+ "through2": "^2.0.3"
}
},
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
- "glob": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
- "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
+ "fsevents": {
+ "version": "1.2.12",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz",
+ "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==",
+ "optional": true,
"requires": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^2.0.1",
- "once": "^1.3.0"
- }
- },
- "glob-stream": {
- "version": "3.1.18",
- "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz",
- "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=",
- "requires": {
- "glob": "^4.3.1",
- "glob2base": "^0.0.12",
- "minimatch": "^2.0.1",
- "ordered-read-streams": "^0.1.0",
- "through2": "^0.6.1",
- "unique-stream": "^1.0.0"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1",
+ "node-pre-gyp": "*"
},
"dependencies": {
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "abbrev": {
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true,
+ "optional": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "bundled": true,
+ "optional": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "bundled": true,
+ "optional": true,
"requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
}
},
- "through2": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
- "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+ "balanced-match": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "optional": true,
"requires": {
- "readable-stream": ">=1.0.33-1 <1.1.0-0",
- "xtend": ">=4.0.0 <4.1.0-0"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
- }
+ },
+ "chownr": {
+ "version": "1.1.4",
+ "bundled": true,
+ "optional": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true,
+ "optional": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true,
+ "optional": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "debug": {
+ "version": "3.2.6",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "bundled": true,
+ "optional": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "bundled": true,
+ "optional": true
+ },
+ "fs-minipass": {
+ "version": "1.2.7",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.6",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "bundled": true,
+ "optional": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "bundled": true,
+ "optional": true
+ },
+ "minipass": {
+ "version": "2.9.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "1.3.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.9.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "bundled": true,
+ "optional": true
+ },
+ "needle": {
+ "version": "2.3.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.14.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4.4.2"
+ }
+ },
+ "nopt": {
+ "version": "4.0.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-normalize-package-bin": {
+ "version": "1.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "npm-packlist": {
+ "version": "1.4.8",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "rc": {
+ "version": "1.2.8",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "bundled": true,
+ "optional": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true,
+ "optional": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true,
+ "optional": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "bundled": true,
+ "optional": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "tar": {
+ "version": "4.4.13",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "bundled": true,
+ "optional": true
+ }
}
},
- "glob-watcher": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz",
- "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=",
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "glob-stream": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+ "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
"requires": {
- "gaze": "^0.5.1"
+ "extend": "^3.0.0",
+ "glob": "^7.1.1",
+ "glob-parent": "^3.1.0",
+ "is-negated-glob": "^1.0.0",
+ "ordered-read-streams": "^1.0.0",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.1.5",
+ "remove-trailing-separator": "^1.0.1",
+ "to-absolute-glob": "^2.0.0",
+ "unique-stream": "^2.0.2"
}
},
- "glob2base": {
- "version": "0.0.12",
- "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
- "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
+ "glob-watcher": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
+ "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==",
"requires": {
- "find-index": "^0.1.1"
+ "anymatch": "^2.0.0",
+ "async-done": "^1.2.0",
+ "chokidar": "^2.0.0",
+ "is-negated-glob": "^1.0.0",
+ "just-debounce": "^1.0.0",
+ "object.defaults": "^1.1.0"
}
},
"global-modules": {
@@ -975,51 +1803,10 @@
"which": "^1.2.14"
}
},
- "globule": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
- "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
- "requires": {
- "glob": "~3.1.21",
- "lodash": "~1.0.1",
- "minimatch": "~0.2.11"
- },
- "dependencies": {
- "glob": {
- "version": "3.1.21",
- "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
- "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
- "requires": {
- "graceful-fs": "~1.2.0",
- "inherits": "1",
- "minimatch": "~0.2.11"
- }
- },
- "graceful-fs": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
- "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q="
- },
- "inherits": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
- "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js="
- },
- "minimatch": {
- "version": "0.2.14",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
- "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
- "requires": {
- "lru-cache": "2",
- "sigmund": "~1.0.0"
- }
- }
- }
- },
"glogg": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz",
- "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+ "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
"requires": {
"sparkles": "^1.0.0"
}
@@ -1033,56 +1820,54 @@
}
},
"graceful-fs": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
- "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
- "requires": {
- "natives": "^1.1.0"
- }
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
},
"gulp": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz",
- "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=",
- "requires": {
- "archy": "^1.0.0",
- "chalk": "^1.0.0",
- "deprecated": "^0.0.1",
- "gulp-util": "^3.0.0",
- "interpret": "^1.0.0",
- "liftoff": "^2.1.0",
- "minimist": "^1.1.0",
- "orchestrator": "^0.3.0",
- "pretty-hrtime": "^1.0.0",
- "semver": "^4.1.0",
- "tildify": "^1.0.0",
- "v8flags": "^2.0.2",
- "vinyl-fs": "^0.3.0"
- }
- },
- "gulp-util": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
- "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=",
- "requires": {
- "array-differ": "^1.0.0",
- "array-uniq": "^1.0.2",
- "beeper": "^1.0.0",
- "chalk": "^1.0.0",
- "dateformat": "^2.0.0",
- "fancy-log": "^1.1.0",
- "gulplog": "^1.0.0",
- "has-gulplog": "^0.1.0",
- "lodash._reescape": "^3.0.0",
- "lodash._reevaluate": "^3.0.0",
- "lodash._reinterpolate": "^3.0.0",
- "lodash.template": "^3.0.0",
- "minimist": "^1.1.0",
- "multipipe": "^0.1.2",
- "object-assign": "^3.0.0",
- "replace-ext": "0.0.1",
- "through2": "^2.0.0",
- "vinyl": "^0.5.0"
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
+ "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "requires": {
+ "glob-watcher": "^5.0.3",
+ "gulp-cli": "^2.2.0",
+ "undertaker": "^1.2.1",
+ "vinyl-fs": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "requires": {
+ "ansi-wrap": "^0.1.0"
+ }
+ },
+ "gulp-cli": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz",
+ "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==",
+ "requires": {
+ "ansi-colors": "^1.0.1",
+ "archy": "^1.0.0",
+ "array-sort": "^1.0.0",
+ "color-support": "^1.1.3",
+ "concat-stream": "^1.6.0",
+ "copy-props": "^2.0.1",
+ "fancy-log": "^1.3.2",
+ "gulplog": "^1.0.0",
+ "interpret": "^1.1.0",
+ "isobject": "^3.0.1",
+ "liftoff": "^3.1.0",
+ "matchdep": "^2.0.0",
+ "mute-stdout": "^1.0.0",
+ "pretty-hrtime": "^1.0.0",
+ "replace-homedir": "^1.0.0",
+ "semver-greatest-satisfied-range": "^1.1.0",
+ "v8flags": "^3.0.1",
+ "yargs": "^7.1.0"
+ }
+ }
}
},
"gulplog": {
@@ -1093,21 +1878,10 @@
"glogg": "^1.0.0"
}
},
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "has-gulplog": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
- "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
- "requires": {
- "sparkles": "^1.0.0"
- }
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"has-value": {
"version": "1.0.0",
@@ -1139,13 +1913,18 @@
}
},
"homedir-polyfill": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
- "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
"requires": {
"parse-passwd": "^1.0.0"
}
},
+ "hosted-git-info": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
+ },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -1156,9 +1935,9 @@
}
},
"inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
@@ -1166,9 +1945,14 @@
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"interpret": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
- "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
+ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw=="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
},
"is-absolute": {
"version": "1.0.0",
@@ -1197,6 +1981,19 @@
}
}
},
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -1247,14 +2044,27 @@
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
"is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"requires": {
- "is-extglob": "^2.1.0"
+ "is-extglob": "^2.1.1"
}
},
+ "is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI="
+ },
"is-number": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
@@ -1302,15 +2112,20 @@
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
},
+ "is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao="
+ },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
},
"isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isexe": {
"version": "2.0.0",
@@ -1323,9 +2138,9 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
},
"jquery": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
- "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
+ "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
},
"jquery-form": {
"version": "4.2.2",
@@ -1341,154 +2156,103 @@
"integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU="
},
"jquery-validation": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.18.0.tgz",
- "integrity": "sha512-+MK0pvoegfLrJnwtCU6tx305Vgp9HWevpmdVwDf5TthmINkn0wqqLD0bpa75EERlHsBBjMmza//ppx5ZQPnW3Q==",
- "requires": {
- "jquery": "^1.7 || ^2.0 || ^3.1"
- }
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.19.1.tgz",
+ "integrity": "sha512-QNnrZBqSltWUEJx+shOY5WtfrIb0gWmDjFfQP8rZKqMMSfpRSwEkSqhfHPvDfkObD8Hnv5KHSYI8yg73sVFdqA=="
},
"jquery-validation-unobtrusive": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.10.tgz",
- "integrity": "sha512-z9ZBP/HslaGNKzFSpfLNJoFm2iqPJfE6CKM0H5e9LmKnYTFxErvCFQZomOLiTmLmZi8Wi/otW38cEXExVDha0w==",
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.11.tgz",
+ "integrity": "sha512-3FQPllaWdD+Aq55zJLGSW39+eXPDz1HhwAvrSwYi8zHQ8DVcu5IJ1HVeTiCl0BnCnrIBvfFU3zEB/DrGdcoRIQ==",
"requires": {
"jquery": ">=1.8",
"jquery-validation": ">=1.16"
}
},
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
+ },
+ "just-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
+ "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo="
+ },
"kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
},
- "liftoff": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
- "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=",
+ "last-run": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+ "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
"requires": {
- "extend": "^3.0.0",
- "findup-sync": "^2.0.0",
- "fined": "^1.0.1",
- "flagged-respawn": "^1.0.0",
- "is-plain-object": "^2.0.4",
- "object.map": "^1.0.0",
- "rechoir": "^0.6.2",
- "resolve": "^1.1.7"
+ "default-resolution": "^2.0.0",
+ "es6-weak-map": "^2.0.1"
}
},
- "lodash": {
- "version": "1.0.2",
- "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
- "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE="
- },
- "lodash._basecopy": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
- "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY="
- },
- "lodash._basetostring": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
- "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U="
- },
- "lodash._basevalues": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
- "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc="
- },
- "lodash._getnative": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
- "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
- },
- "lodash._isiterateecall": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
- "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw="
- },
- "lodash._reescape": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz",
- "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo="
- },
- "lodash._reevaluate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz",
- "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0="
- },
- "lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
- },
- "lodash._root": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
- "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI="
- },
- "lodash.escape": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
- "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=",
+ "lazystream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
"requires": {
- "lodash._root": "^3.0.0"
+ "readable-stream": "^2.0.5"
}
},
- "lodash.isarguments": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
- "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
- },
- "lodash.isarray": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
- "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
- },
- "lodash.keys": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
- "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
"requires": {
- "lodash._getnative": "^3.0.0",
- "lodash.isarguments": "^3.0.0",
- "lodash.isarray": "^3.0.0"
+ "invert-kv": "^1.0.0"
}
},
- "lodash.restparam": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
- "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU="
+ "lead": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+ "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+ "requires": {
+ "flush-write-stream": "^1.0.2"
+ }
},
- "lodash.template": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
- "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=",
+ "liftoff": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
+ "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
"requires": {
- "lodash._basecopy": "^3.0.0",
- "lodash._basetostring": "^3.0.0",
- "lodash._basevalues": "^3.0.0",
- "lodash._isiterateecall": "^3.0.0",
- "lodash._reinterpolate": "^3.0.0",
- "lodash.escape": "^3.0.0",
- "lodash.keys": "^3.0.0",
- "lodash.restparam": "^3.0.0",
- "lodash.templatesettings": "^3.0.0"
+ "extend": "^3.0.0",
+ "findup-sync": "^3.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
}
},
- "lodash.templatesettings": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz",
- "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=",
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"requires": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.escape": "^3.0.0"
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
}
},
- "lru-cache": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
- "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI="
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ },
+ "luxon": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.22.2.tgz",
+ "integrity": "sha512-vq6eSaOOw1fKob+JXwfu0e3/UFUT4G4HTFRJab7dch8J1OdOGW/vXqCiJsY7rm2In+5gKNYx0EtnYT0Tc5V4Qw=="
},
"make-iterator": {
"version": "1.0.1",
@@ -1519,43 +2283,43 @@
"object-visit": "^1.0.0"
}
},
- "merge-stream": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
- "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
+ "matchdep": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+ "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
"requires": {
- "readable-stream": "^2.0.1"
+ "findup-sync": "^2.0.0",
+ "micromatch": "^3.0.4",
+ "resolve": "^1.4.0",
+ "stack-trace": "0.0.10"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
"requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
}
},
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
"requires": {
- "safe-buffer": "~5.1.0"
+ "is-extglob": "^2.1.0"
}
}
}
},
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -1577,22 +2341,17 @@
}
},
"minimatch": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
- "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
- "brace-expansion": "^1.0.0"
+ "brace-expansion": "^1.1.7"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
"mixin-deep": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"requires": {
"for-in": "^1.0.2",
"is-extendable": "^1.0.1"
@@ -1608,33 +2367,21 @@
}
}
},
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "requires": {
- "minimist": "0.0.8"
- },
- "dependencies": {
- "minimist": {
- "version": "0.0.8",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
- }
- }
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
- "multipipe": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
- "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
- "requires": {
- "duplexer2": "0.0.2"
- }
+ "mute-stdout": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg=="
+ },
+ "nan": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+ "optional": true
},
"nanomatch": {
"version": "1.2.13",
@@ -1654,15 +2401,42 @@
"to-regex": "^3.0.1"
}
},
- "natives": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.5.tgz",
- "integrity": "sha512-1pJ+02gl2KJgCPFtpZGtuD4lGSJnIZvvFHCQTOeDRMSXjfu2GmYWuhI8NFMA4W2I5NNFRbfy/YCiVt4CgNpP8A=="
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
- "object-assign": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
- "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I="
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ },
+ "now-and-later": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "requires": {
+ "once": "^1.3.2"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"object-copy": {
"version": "0.1.0",
@@ -1692,12 +2466,28 @@
}
}
},
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
"integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
"requires": {
- "isobject": "^3.0.0"
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
}
},
"object.defaults": {
@@ -1728,33 +2518,38 @@
"isobject": "^3.0.1"
}
},
- "once": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
- "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
+ "object.reduce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+ "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
"requires": {
- "wrappy": "1"
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
}
},
- "orchestrator": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz",
- "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=",
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
- "end-of-stream": "~0.1.5",
- "sequencify": "~0.0.7",
- "stream-consume": "~0.1.0"
+ "wrappy": "1"
}
},
"ordered-read-streams": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz",
- "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+ "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+ "requires": {
+ "readable-stream": "^2.0.1"
+ }
},
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "requires": {
+ "lcid": "^1.0.0"
+ }
},
"parse-filepath": {
"version": "1.0.2",
@@ -1766,6 +2561,19 @@
"path-root": "^0.1.1"
}
},
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
+ },
"parse-passwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
@@ -1785,6 +2593,19 @@
"util": "^0.10.3"
}
},
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1808,10 +2629,38 @@
"resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
"integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0="
},
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
"popper.js": {
- "version": "1.14.6",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz",
- "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA=="
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"posix-character-classes": {
"version": "0.1.1",
@@ -1824,9 +2673,9 @@
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE="
},
"prismjs": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz",
- "integrity": "sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA==",
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz",
+ "integrity": "sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==",
"requires": {
"clipboard": "^2.0.0"
}
@@ -1837,24 +2686,75 @@
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
},
"process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"promise-polyfill": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
"integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc="
},
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
"readable-stream": {
- "version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
}
},
"rechoir": {
@@ -1874,6 +2774,30 @@
"safe-regex": "^1.1.0"
}
},
+ "remove-bom-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+ "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+ "requires": {
+ "is-buffer": "^1.1.5",
+ "is-utf8": "^0.2.1"
+ }
+ },
+ "remove-bom-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+ "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+ "requires": {
+ "remove-bom-buffer": "^3.0.0",
+ "safe-buffer": "^5.1.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ },
"repeat-element": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
@@ -1885,16 +2809,36 @@
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
"replace-ext": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
- "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs="
+ },
+ "replace-homedir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+ "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
+ "requires": {
+ "homedir-polyfill": "^1.0.1",
+ "is-absolute": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
},
"resolve": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
- "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
+ "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"requires": {
- "path-parse": "^1.0.5"
+ "path-parse": "^1.0.6"
}
},
"resolve-dir": {
@@ -1906,6 +2850,14 @@
"global-modules": "^1.0.0"
}
},
+ "resolve-options": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+ "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+ "requires": {
+ "value-or-function": "^3.0.0"
+ }
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -1917,34 +2869,11 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
"rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"requires": {
- "glob": "^7.0.5"
- },
- "dependencies": {
- "glob": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
- "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- }
+ "glob": "^7.1.3"
}
},
"safe-buffer": {
@@ -1966,28 +2895,32 @@
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
},
"select2": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.5.tgz",
- "integrity": "sha1-eqxQaSVhmFs007guxV4ib4lg1Ao=",
- "requires": {
- "almond": "~0.3.1",
- "jquery-mousewheel": "~3.1.13"
- }
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.13.tgz",
+ "integrity": "sha512-1JeB87s6oN/TDxQQYCvS5EFoQyvV6eYMZZ0AeA4tdFDYWN3BAGZ8npr17UBFddU0lgAt3H0yjX3X6/ekOj1yjw=="
},
"semver": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
- "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto="
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "semver-greatest-satisfied-range": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+ "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+ "requires": {
+ "sver-compat": "^1.5.0"
+ }
},
- "sequencify": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz",
- "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw="
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"set-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
- "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
"requires": {
"extend-shallow": "^2.0.1",
"is-extendable": "^0.1.1",
@@ -2005,11 +2938,6 @@
}
}
},
- "sigmund": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
- "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA="
- },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -2113,11 +3041,11 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
"requires": {
- "atob": "^2.1.1",
+ "atob": "^2.1.2",
"decode-uri-component": "^0.2.0",
"resolve-url": "^0.2.1",
"source-map-url": "^0.4.0",
@@ -2134,6 +3062,34 @@
"resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
"integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw=="
},
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
+ },
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -2142,6 +3098,11 @@
"extend-shallow": "^3.0.0"
}
},
+ "stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
+ },
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -2161,15 +3122,33 @@
}
}
},
- "stream-consume": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz",
- "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg=="
+ "stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw=="
+ },
+ "stream-shift": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
},
"string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
},
"strip-ansi": {
"version": "3.0.1",
@@ -2180,72 +3159,47 @@
}
},
"strip-bom": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz",
- "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"requires": {
- "first-chunk-stream": "^1.0.0",
"is-utf8": "^0.2.0"
}
},
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ "sver-compat": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+ "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+ "requires": {
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
+ }
},
"sweetalert": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz",
- "integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz",
+ "integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==",
"requires": {
"es6-object-assign": "^1.1.0",
"promise-polyfill": "^6.0.2"
}
},
"through2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
- "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"requires": {
- "readable-stream": "^2.1.5",
+ "readable-stream": "~2.3.6",
"xtend": "~4.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
- "tildify": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
- "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=",
+ "through2-filter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+ "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
"requires": {
- "os-homedir": "^1.0.0"
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
}
},
"time-stamp": {
@@ -2254,17 +3208,26 @@
"integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM="
},
"timeago": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/timeago/-/timeago-1.6.3.tgz",
- "integrity": "sha512-x97d1X1KsNapWJTgCOOAy/59XagYu2WsDTAH/yvPsWi5bqtGbLPaVZBv3HZ3jTpakHR+JGGyrI9qC0yuvIAvnQ==",
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/timeago/-/timeago-1.6.7.tgz",
+ "integrity": "sha512-FikcjN98+ij0siKH4VO4dZ358PR3oDDq4Vdl1+sN9gWz1/+JXGr3uZbUShYH/hL7bMhcTpPbplJU5Tej4b4jbQ==",
"requires": {
- "jquery": ">=1.2.3"
+ "jquery": ">=1.5.0 <4.0"
}
},
"tiny-emitter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
+ },
+ "to-absolute-glob": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
- "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow=="
+ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+ "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "is-negated-glob": "^1.0.0"
+ }
},
"to-object-path": {
"version": "0.3.0",
@@ -2304,6 +3267,14 @@
"repeat-string": "^1.6.1"
}
},
+ "to-through": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+ "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+ "requires": {
+ "through2": "^2.0.3"
+ }
+ },
"toastr": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz",
@@ -2312,47 +3283,61 @@
"jquery": ">=1.12.0"
}
},
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
"unc-path-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
},
+ "undertaker": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
+ "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+ "requires": {
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "bach": "^1.0.0",
+ "collection-map": "^1.0.0",
+ "es6-weak-map": "^2.0.1",
+ "last-run": "^1.1.0",
+ "object.defaults": "^1.0.0",
+ "object.reduce": "^1.0.0",
+ "undertaker-registry": "^1.0.0"
+ }
+ },
+ "undertaker-registry": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA="
+ },
"union-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
- "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
"requires": {
"arr-union": "^3.1.0",
"get-value": "^2.0.6",
"is-extendable": "^0.1.1",
- "set-value": "^0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
- "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.1",
- "to-object-path": "^0.3.0"
- }
- }
+ "set-value": "^2.0.1"
}
},
"unique-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz",
- "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+ "requires": {
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
+ }
},
"unset-value": {
"version": "1.0.0",
@@ -2387,14 +3372,14 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
}
}
},
+ "upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
+ },
"urix": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
@@ -2405,17 +3390,19 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
- "user-home": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
- "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA="
- },
"util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
"requires": {
"inherits": "2.0.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ }
}
},
"util-deprecate": {
@@ -2424,72 +3411,76 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"v8flags": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
- "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz",
+ "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==",
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"requires": {
- "user-home": "^1.1.1"
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
}
},
+ "value-or-function": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM="
+ },
"vinyl": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz",
- "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
"requires": {
- "clone": "^1.0.0",
- "clone-stats": "^0.0.1",
- "replace-ext": "0.0.1"
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
}
},
"vinyl-fs": {
- "version": "0.3.14",
- "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz",
- "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=",
- "requires": {
- "defaults": "^1.0.0",
- "glob-stream": "^3.1.5",
- "glob-watcher": "^0.0.6",
- "graceful-fs": "^3.0.0",
- "mkdirp": "^0.5.0",
- "strip-bom": "^1.0.0",
- "through2": "^0.6.1",
- "vinyl": "^0.4.0"
- },
- "dependencies": {
- "clone": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
- "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8="
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "through2": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
- "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
- "requires": {
- "readable-stream": ">=1.0.33-1 <1.1.0-0",
- "xtend": ">=4.0.0 <4.1.0-0"
- }
- },
- "vinyl": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
- "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
- "requires": {
- "clone": "^0.2.0",
- "clone-stats": "^0.0.1"
- }
- }
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+ "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+ "requires": {
+ "fs-mkdirp-stream": "^1.0.0",
+ "glob-stream": "^6.1.0",
+ "graceful-fs": "^4.0.0",
+ "is-valid-glob": "^1.0.0",
+ "lazystream": "^1.0.0",
+ "lead": "^1.0.0",
+ "object.assign": "^4.0.4",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.3.3",
+ "remove-bom-buffer": "^3.0.0",
+ "remove-bom-stream": "^1.2.0",
+ "resolve-options": "^1.1.0",
+ "through2": "^2.0.0",
+ "to-through": "^2.0.0",
+ "value-or-function": "^3.0.0",
+ "vinyl": "^2.0.0",
+ "vinyl-sourcemap": "^1.1.0"
+ }
+ },
+ "vinyl-sourcemap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+ "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+ "requires": {
+ "append-buffer": "^1.0.2",
+ "convert-source-map": "^1.5.0",
+ "graceful-fs": "^4.1.6",
+ "normalize-path": "^2.1.1",
+ "now-and-later": "^2.0.0",
+ "remove-bom-buffer": "^3.0.0",
+ "vinyl": "^2.0.0"
}
},
"which": {
@@ -2500,15 +3491,62 @@
"isexe": "^2.0.0"
}
},
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+ "requires": {
+ "camelcase": "^3.0.0"
+ }
}
}
}
diff --git a/modules/docs/app/VoloDocs.Web/package.json b/modules/docs/app/VoloDocs.Web/package.json
index fca480e355..b711db27ba 100644
--- a/modules/docs/app/VoloDocs.Web/package.json
+++ b/modules/docs/app/VoloDocs.Web/package.json
@@ -6,4 +6,4 @@
"@abp/aspnetcore.mvc.ui.theme.basic": "^1.0.2",
"@abp/docs": "^1.0.2"
}
-}
\ No newline at end of file
+}
diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
index 57ade1bb4b..1000091b65 100644
--- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
+++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
@@ -4,11 +4,13 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json;
+using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Projects;
+using Volo.Extensions;
namespace Volo.Docs.Admin.Documents
{
@@ -38,15 +40,19 @@ namespace Volo.Docs.Admin.Documents
{
var project = await _projectRepository.GetAsync(input.ProjectId);
- var navigationFile = await GetDocumentAsync(
+ var navigationDocument = await GetDocumentAsync(
project,
project.NavigationDocumentName,
input.LanguageCode,
input.Version
);
- var nav = JsonConvert.DeserializeObject(navigationFile.Content);
- var leafs = nav.Items.GetAllNodes(x => x.Items)
+ if (!JsonConvertExtensions.TryDeserializeObject(navigationDocument.Content, out var navigation))
+ {
+ throw new UserFriendlyException($"Cannot validate navigation file '{project.NavigationDocumentName}' for the project {project.Name}.");
+ }
+
+ var leafs = navigation.Items.GetAllNodes(x => x.Items)
.Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace())
.ToList();
diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
index 9863995d15..4e6138d260 100644
--- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
+++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
@@ -7,9 +7,11 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
+using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Projects;
+using Volo.Extensions;
namespace Volo.Docs.Documents
{
@@ -32,8 +34,8 @@ namespace Volo.Docs.Documents
IDistributedCache languageCache,
IDistributedCache resourceCache,
IDistributedCache documentUpdateCache,
- IHostEnvironment hostEnvironment,
- IDocumentFullSearch documentFullSearch,
+ IHostEnvironment hostEnvironment,
+ IDocumentFullSearch documentFullSearch,
IOptions docsElasticSearchOptions)
{
_projectRepository = projectRepository;
@@ -82,7 +84,10 @@ namespace Volo.Docs.Documents
input.Version
);
- var navigationNode = JsonConvert.DeserializeObject(navigationDocument.Content);
+ if (!JsonConvertExtensions.TryDeserializeObject(navigationDocument.Content, out var navigationNode))
+ {
+ throw new UserFriendlyException($"Cannot validate navigation file '{project.NavigationDocumentName}' for the project {project.Name}.");
+ }
var leafs = navigationNode.Items.GetAllNodes(x => x.Items)
.Where(x => !x.Path.IsNullOrWhiteSpace())
@@ -173,11 +178,16 @@ namespace Volo.Docs.Documents
input.Version
);
- return JsonConvert.DeserializeObject(document.Content);
+ if (!JsonConvertExtensions.TryDeserializeObject(document.Content, out var documentParameters))
+ {
+ throw new UserFriendlyException($"Cannot validate document parameters file '{project.ParametersDocumentName}' for the project {project.Name}.");
+ }
+
+ return documentParameters;
}
catch (DocumentNotFoundException)
{
- Logger.LogWarning($"Parameter file ({project.ParametersDocumentName}) not found.");
+ Logger.LogWarning($"Parameter file ({project.ParametersDocumentName}) not found!");
return new DocumentParametersDto();
}
}
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainConsts.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainConsts.cs
new file mode 100644
index 0000000000..ff6bd56ee4
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainConsts.cs
@@ -0,0 +1,7 @@
+namespace Volo.Docs
+{
+ public class DocsDomainConsts
+ {
+ public static string LanguageConfigFileName = "docs-langs.json";
+ }
+}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs
index 3fa341a848..cc0f03a60a 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs
@@ -4,11 +4,13 @@ using System.IO;
using System.Security;
using System.Threading.Tasks;
using Newtonsoft.Json;
+using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.IO;
using Volo.Docs.Documents;
using Volo.Docs.FileSystem.Projects;
using Volo.Docs.Projects;
+using Volo.Extensions;
namespace Volo.Docs.FileSystem.Documents
{
@@ -22,7 +24,7 @@ namespace Volo.Docs.FileSystem.Documents
var path = Path.Combine(projectFolder, languageCode, documentName);
CheckDirectorySecurity(projectFolder, path);
-
+
var content = await FileHelper.ReadAllTextAsync(path);
var localDirectory = "";
@@ -55,10 +57,15 @@ namespace Volo.Docs.FileSystem.Documents
public async Task GetLanguageListAsync(Project project, string version)
{
- var path = Path.Combine(project.GetFileSystemPath(), "docs-langs.json");
- var configAsJson = await FileHelper.ReadAllTextAsync(path);
+ var path = Path.Combine(project.GetFileSystemPath(), DocsDomainConsts.LanguageConfigFileName);
+ var configJsonContent = await FileHelper.ReadAllTextAsync(path);
+
+ if (!JsonConvertExtensions.TryDeserializeObject(configJsonContent, out var languageConfig))
+ {
+ throw new UserFriendlyException($"Cannot validate language config file '{DocsDomainConsts.LanguageConfigFileName}' for the project {project.Name}.");
+ }
- return JsonConvert.DeserializeObject(configAsJson);
+ return languageConfig;
}
public async Task GetResource(Project project, string resourceName, string languageCode, string version)
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs
index 3e287789e9..012fc7aed9 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs
@@ -10,6 +10,8 @@ using Volo.Docs.GitHub.Projects;
using Volo.Docs.Projects;
using Newtonsoft.Json.Linq;
using Octokit;
+using Volo.Abp;
+using Volo.Extensions;
using Project = Volo.Docs.Projects.Project;
namespace Volo.Docs.GitHub.Documents
@@ -55,11 +57,11 @@ namespace Volo.Docs.GitHub.Documents
var lastSignificantUpdateTime = !isNavigationDocument && !isParameterDocument && version == project.LatestVersionBranchName ?
await GetLastSignificantUpdateTime(
fileCommits,
- project,
+ project,
project.GetGitHubInnerUrl(languageCode, documentName),
lastKnownSignificantUpdateTime,
documentCreationTime
- ) ?? lastKnownSignificantUpdateTime
+ ) ?? lastKnownSignificantUpdateTime
: null;
var document = new Document(GuidGenerator.Create(),
@@ -179,11 +181,16 @@ namespace Volo.Docs.GitHub.Documents
var rootUrl = project.GetGitHubUrl(version);
var userAgent = project.GetGithubUserAgentOrNull();
- var url = CalculateRawRootUrl(rootUrl) + "docs-langs.json";
+ var url = CalculateRawRootUrl(rootUrl) + DocsDomainConsts.LanguageConfigFileName;
var configAsJson = await DownloadWebContentAsStringAsync(url, token, userAgent);
- return JsonConvert.DeserializeObject(configAsJson);
+ if (!JsonConvertExtensions.TryDeserializeObject(configAsJson, out var languageConfig))
+ {
+ throw new UserFriendlyException($"Cannot validate language config file '{DocsDomainConsts.LanguageConfigFileName}' for the project {project.Name} - v{version}.");
+ }
+
+ return languageConfig;
}
private async Task> GetReleasesAsync(Project project)
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
index 4627800832..ef21353236 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
@@ -23,54 +23,25 @@ namespace Volo.Docs.GitHub.Documents
public async Task GetFileRawStringContentAsync(string rawUrl, string token, string userAgent)
{
- var httpClient = _clientFactory.CreateClient(HttpClientName);
- if (!token.IsNullOrWhiteSpace())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", token);
- }
-
- if (!userAgent.IsNullOrWhiteSpace())
- {
- httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
- }
-
+ using var httpClient = CreateHttpClient(token, userAgent);
return await httpClient.GetStringAsync(new Uri(rawUrl));
}
public async Task GetFileRawByteArrayContentAsync(string rawUrl, string token, string userAgent)
{
- var httpClient = _clientFactory.CreateClient(HttpClientName);
- if (!token.IsNullOrWhiteSpace())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", token);
- }
-
- if (!userAgent.IsNullOrWhiteSpace())
- {
- httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
- }
-
+ using var httpClient = CreateHttpClient(token, userAgent);
return await httpClient.GetByteArrayAsync(new Uri(rawUrl));
}
-
+
public async Task> GetReleasesAsync(string name, string repositoryName, string token)
{
- var client = token.IsNullOrWhiteSpace()
- ? new GitHubClient(new ProductHeaderValue(name))
- : new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
-
- return (await client
- .Repository
- .Release
- .GetAll(name, repositoryName)).ToList();
+ var client = GetGitHubClient(name, token);
+ return await client.Repository.Release.GetAll(name, repositoryName);
}
public async Task> GetFileCommitsAsync(string name, string repositoryName, string version, string filename, string token)
{
- var client = token.IsNullOrWhiteSpace()
- ? new GitHubClient(new ProductHeaderValue(name))
- : new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
-
+ var client = GetGitHubClient(name, token);
var repo = await client.Repository.Get(name, repositoryName);
var request = new CommitRequest { Path = filename, Sha = version };
return await client.Repository.Commit.GetAll(repo.Id, request);
@@ -78,12 +49,32 @@ namespace Volo.Docs.GitHub.Documents
public async Task GetSingleCommitsAsync(string name, string repositoryName, string sha, string token)
{
- var client = token.IsNullOrWhiteSpace()
- ? new GitHubClient(new ProductHeaderValue(name))
- : new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
-
+ var client = GetGitHubClient(name, token);
var repo = await client.Repository.Get(name, repositoryName);
return await client.Repository.Commit.Get(repo.Id, sha);
}
+
+ private HttpClient CreateHttpClient(string token, string userAgent)
+ {
+ var httpClient = _clientFactory.CreateClient(HttpClientName);
+ if (!token.IsNullOrWhiteSpace())
+ {
+ httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", token);
+ }
+
+ if (!userAgent.IsNullOrWhiteSpace())
+ {
+ httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ }
+
+ return httpClient;
+ }
+
+ private static GitHubClient GetGitHubClient(string name, string token)
+ {
+ return token.IsNullOrWhiteSpace()
+ ? new GitHubClient(new ProductHeaderValue(name))
+ : new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
+ }
}
}
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Extensions/NewtonsoftJsonExtensions.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Extensions/NewtonsoftJsonExtensions.cs
new file mode 100644
index 0000000000..200baa9c2c
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Extensions/NewtonsoftJsonExtensions.cs
@@ -0,0 +1,22 @@
+using System;
+using Newtonsoft.Json;
+
+namespace Volo.Extensions
+{
+ public static class JsonConvertExtensions
+ {
+ public static bool TryDeserializeObject(string jsonContent, out T result)
+ {
+ try
+ {
+ result = JsonConvert.DeserializeObject(jsonContent);
+ return true;
+ }
+ catch
+ {
+ result = default;
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs
index 4a4f3b2142..990f2a0dec 100644
--- a/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs
+++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/ScribanDocumentSectionRenderer.cs
@@ -7,16 +7,17 @@ using Newtonsoft.Json;
using Scriban;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-using Volo.Docs.Documents;
+using Volo.Abp;
+using Volo.Extensions;
namespace Volo.Docs.HtmlConverting
{
public class ScribanDocumentSectionRenderer : IDocumentSectionRenderer
{
- private const string jsonOpener = "````json";
- private const string jsonCloser = "````";
- private const string docs_param = "//[doc-params]";
- private const string docs_templates = "//[doc-template]";
+ private const string JsonOpener = "````json";
+ private const string JsonCloser = "````";
+ private const string DocsParam = "//[doc-params]";
+ private const string DocsTemplates = "//[doc-template]";
public ILogger Logger { get; set; }
@@ -40,6 +41,7 @@ namespace Volo.Docs.HtmlConverting
}
var result = await scribanTemplate.RenderAsync(parameters);
+
return RemoveOptionsJson(result);
}
@@ -47,7 +49,7 @@ namespace Volo.Docs.HtmlConverting
{
try
{
- if (!document.Contains(jsonOpener) || !document.Contains(docs_param))
+ if (!document.Contains(JsonOpener) || !document.Contains(DocsParam))
{
return new Dictionary>();
}
@@ -59,9 +61,14 @@ namespace Volo.Docs.HtmlConverting
return new Dictionary>();
}
- var pureJson = insideJsonSection.Replace(docs_param, "").Trim();
+ var pureJson = insideJsonSection.Replace(DocsParam, "").Trim();
+
+ if (!JsonConvertExtensions.TryDeserializeObject>>(pureJson, out var availableParameters))
+ {
+ throw new UserFriendlyException("ERROR-20200327: Cannot validate JSON content for `AvailableParameters`!");
+ }
- return JsonConvert.DeserializeObject>>(pureJson);
+ return await Task.FromResult(availableParameters);
}
catch (Exception)
{
@@ -70,12 +77,13 @@ namespace Volo.Docs.HtmlConverting
}
}
- private string RemoveOptionsJson(string document)
+ private static string RemoveOptionsJson(string document)
{
var orgDocument = document;
+
try
{
- if (!document.Contains(jsonOpener) || !document.Contains(docs_param))
+ if (!document.Contains(JsonOpener) || !document.Contains(DocsParam))
{
return orgDocument;
}
@@ -88,8 +96,9 @@ namespace Volo.Docs.HtmlConverting
}
return document.Remove(
- jsonBeginningIndex - jsonOpener.Length, (jsonEndingIndex + jsonCloser.Length) - (jsonBeginningIndex - jsonOpener.Length)
- );
+ jsonBeginningIndex - JsonOpener.Length,
+ (jsonEndingIndex + JsonCloser.Length) - (jsonBeginningIndex - JsonOpener.Length)
+ );
}
catch (Exception)
{
@@ -97,25 +106,25 @@ namespace Volo.Docs.HtmlConverting
}
}
- private (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document)
+ private static (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document)
{
var searchedIndex = 0;
while (searchedIndex < document.Length)
{
- var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(jsonOpener, StringComparison.Ordinal) + jsonOpener.Length + searchedIndex;
+ var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length + searchedIndex;
if (jsonBeginningIndex < 0)
{
return (-1, -1, "");
}
- var jsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser, StringComparison.Ordinal) + jsonBeginningIndex;
+ var jsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(JsonCloser, StringComparison.Ordinal) + jsonBeginningIndex;
var insideJsonSection = document[jsonBeginningIndex..jsonEndingIndex];
- if (insideJsonSection.IndexOf(docs_param) < 0)
+ if (insideJsonSection.IndexOf(DocsParam, StringComparison.Ordinal) < 0)
{
- searchedIndex = jsonEndingIndex + jsonCloser.Length;
+ searchedIndex = jsonEndingIndex + JsonCloser.Length;
continue;
}
@@ -129,68 +138,84 @@ namespace Volo.Docs.HtmlConverting
{
var templates = new List();
- while (documentContent.Contains(jsonOpener))
+ while (documentContent.Contains(JsonOpener))
{
var afterJsonOpener = documentContent.Substring(
- documentContent.IndexOf(jsonOpener, StringComparison.Ordinal) + jsonOpener.Length);
+ documentContent.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
+ );
var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
- afterJsonOpener.IndexOf(jsonCloser, StringComparison.Ordinal));
+ afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal)
+ );
documentContent = afterJsonOpener.Substring(
- afterJsonOpener.IndexOf(jsonCloser, StringComparison.Ordinal) + jsonCloser.Length);
+ afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
+ );
- if (!betweenJsonOpenerAndCloser.Contains(docs_templates))
+ if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
{
continue;
}
- var json = betweenJsonOpenerAndCloser.Substring(betweenJsonOpenerAndCloser.IndexOf(docs_templates, StringComparison.Ordinal) + docs_templates.Length);
+ var json = betweenJsonOpenerAndCloser.Substring(betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) + DocsTemplates.Length);
- var template = JsonConvert.DeserializeObject(json);
+ if (!JsonConvertExtensions.TryDeserializeObject(json, out var template))
+ {
+ throw new UserFriendlyException($"ERROR-20200327: Cannot validate JSON content for `AvailableParameters`!");
+ }
templates.Add(template);
}
- return templates;
+ return await Task.FromResult(templates);
}
- private string SetPartialTemplates(string document, List templates)
+ private static string SetPartialTemplates(string document, IReadOnlyCollection templates)
{
var newDocument = new StringBuilder();
- while (document.Contains(jsonOpener))
+ while (document.Contains(JsonOpener))
{
var beforeJson = document.Substring(0,
- document.IndexOf(jsonOpener, StringComparison.Ordinal) + jsonOpener.Length);
+ document.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
+ );
var afterJsonOpener = document.Substring(
- document.IndexOf(jsonOpener, StringComparison.Ordinal) + jsonOpener.Length);
+ document.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
+ );
var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
- afterJsonOpener.IndexOf(jsonCloser, StringComparison.Ordinal));
+ afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal)
+ );
- if (!betweenJsonOpenerAndCloser.Contains(docs_templates))
+ if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
{
document = afterJsonOpener.Substring(
- afterJsonOpener.IndexOf(jsonCloser, StringComparison.Ordinal) + jsonCloser.Length);
- newDocument.Append(beforeJson + betweenJsonOpenerAndCloser + jsonCloser);
+ afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
+ );
+
+ newDocument.Append(beforeJson + betweenJsonOpenerAndCloser + JsonCloser);
continue;
}
- var json = betweenJsonOpenerAndCloser.Substring(betweenJsonOpenerAndCloser.IndexOf(docs_templates, StringComparison.Ordinal) + docs_templates.Length);
-
- var templatePath = JsonConvert.DeserializeObject(json)?.Path;
+ var json = betweenJsonOpenerAndCloser.Substring(
+ betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) + DocsTemplates.Length
+ );
- var template = templates.FirstOrDefault(t => t.Path == templatePath);
+ if (JsonConvertExtensions.TryDeserializeObject(json, out var documentPartialTemplateWithValuesDto))
+ {
+ var template = templates.FirstOrDefault(t => t.Path == documentPartialTemplateWithValuesDto.Path);
- var beforeTemplate = document.Substring(0,
- document.IndexOf(jsonOpener, StringComparison.Ordinal));
+ var beforeTemplate = document.Substring(0,
+ document.IndexOf(JsonOpener, StringComparison.Ordinal)
+ );
- newDocument.Append(beforeTemplate + template?.Content + jsonCloser);
+ newDocument.Append(beforeTemplate + template?.Content + JsonCloser);
- document = afterJsonOpener.Substring(
- afterJsonOpener.IndexOf(jsonCloser, StringComparison.Ordinal) + jsonCloser.Length);
+ document = afterJsonOpener.Substring(
+ afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
+ );
+ }
}
newDocument.Append(document);
diff --git a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj
index ed9cf98af8..afec611259 100644
--- a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj
+++ b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj
@@ -19,6 +19,7 @@
+
diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json
index d0289505fe..af185688b2 100644
--- a/npm/ng-packs/angular.json
+++ b/npm/ng-packs/angular.json
@@ -526,5 +526,5 @@
}
}
},
- "defaultProject": "core"
+ "defaultProject": "dev-app"
}
diff --git a/npm/ng-packs/apps/dev-app/src/app/app.module.ts b/npm/ng-packs/apps/dev-app/src/app/app.module.ts
index f1324c233a..64f8150f01 100644
--- a/npm/ng-packs/apps/dev-app/src/app/app.module.ts
+++ b/npm/ng-packs/apps/dev-app/src/app/app.module.ts
@@ -21,9 +21,6 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })];
imports: [
CoreModule.forRoot({
environment,
- requirements: {
- layouts: LAYOUTS,
- },
}),
ThemeSharedModule.forRoot(),
AccountConfigModule.forRoot({ redirectUrl: '/' }),
diff --git a/npm/ng-packs/packages/account/src/lib/services/account.service.ts b/npm/ng-packs/packages/account/src/lib/services/account.service.ts
index 6c2571a518..ae9fc19d21 100644
--- a/npm/ng-packs/packages/account/src/lib/services/account.service.ts
+++ b/npm/ng-packs/packages/account/src/lib/services/account.service.ts
@@ -7,6 +7,8 @@ import { RegisterResponse, RegisterRequest, TenantIdResponse } from '../models';
providedIn: 'root',
})
export class AccountService {
+ apiName = 'AbpAccount';
+
constructor(private rest: RestService) {}
findTenant(tenantName: string): Observable {
@@ -15,7 +17,7 @@ export class AccountService {
url: `/api/abp/multi-tenancy/tenants/by-name/${tenantName}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
register(body: RegisterRequest): Observable {
@@ -25,6 +27,9 @@ export class AccountService {
body,
};
- return this.rest.request(request, { skipHandleError: true });
+ return this.rest.request(request, {
+ skipHandleError: true,
+ apiName: this.apiName,
+ });
}
}
diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
index 7fc1826efe..c07f11580f 100644
--- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
+++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
@@ -1,12 +1,12 @@
-import { Component, Input, OnDestroy, Type, Injector } from '@angular/core';
+import { Component, OnDestroy, Type } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router';
-import { Select, Store } from '@ngxs/store';
-import { Observable } from 'rxjs';
+import { Store } from '@ngxs/store';
import snq from 'snq';
import { eLayoutType } from '../enums/common';
-import { Config } from '../models/config';
import { ABP } from '../models/common';
+import { ReplaceableComponents } from '../models/replaceable-components';
import { ConfigState } from '../states/config.state';
+import { ReplaceableComponentsState } from '../states/replaceable-components.state';
import { takeUntilDestroy } from '../utils/rxjs-utils';
@Component({
@@ -20,24 +20,10 @@ import { takeUntilDestroy } from '../utils/rxjs-utils';
`,
})
export class DynamicLayoutComponent implements OnDestroy {
- @Select(ConfigState.getOne('requirements')) requirements$: Observable;
-
layout: Type;
constructor(private router: Router, private route: ActivatedRoute, private store: Store) {
- const {
- requirements: { layouts },
- routes,
- } = this.store.selectSnapshot(ConfigState.getAll);
-
- if ((this.route.snapshot.data || {}).layout) {
- this.layout = layouts
- .filter(l => !!l)
- .find(
- (l: any) =>
- snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1,
- );
- }
+ const { routes } = this.store.selectSnapshot(ConfigState.getAll);
router.events.pipe(takeUntilDestroy(this)).subscribe(event => {
if (event instanceof NavigationEnd) {
@@ -45,15 +31,24 @@ export class DynamicLayoutComponent implements OnDestroy {
{ path: router.url.replace('/', '') },
] as any);
- const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes);
+ const layouts = {
+ application: this.getComponent('Theme.ApplicationLayoutComponent'),
+ account: this.getComponent('Theme.AccountLayoutComponent'),
+ empty: this.getComponent('Theme.EmptyLayoutComponent'),
+ };
- this.layout = layouts
- .filter(l => !!l)
- .find((l: any) => snq(() => l.type.toLowerCase().indexOf(layout), -1) > -1);
+ const expectedLayout =
+ (this.route.snapshot.data || {}).layout || findLayout(segments, routes);
+
+ this.layout = layouts[expectedLayout].component;
}
});
}
+ private getComponent(key: string): ReplaceableComponents.ReplaceableComponent {
+ return this.store.selectSnapshot(ReplaceableComponentsState.getComponent(key));
+ }
+
ngOnDestroy() {}
}
diff --git a/npm/ng-packs/packages/core/src/lib/models/common.ts b/npm/ng-packs/packages/core/src/lib/models/common.ts
index 8b4fb76cb0..79792a1b61 100644
--- a/npm/ng-packs/packages/core/src/lib/models/common.ts
+++ b/npm/ng-packs/packages/core/src/lib/models/common.ts
@@ -6,7 +6,11 @@ import { Subject } from 'rxjs';
export namespace ABP {
export interface Root {
environment: Partial;
- requirements: Config.Requirements;
+ /**
+ *
+ * @deprecated To be deleted in v3.0
+ */
+ requirements?: Config.Requirements;
}
export type PagedResponse = {
diff --git a/npm/ng-packs/packages/core/src/lib/services/application-configuration.service.ts b/npm/ng-packs/packages/core/src/lib/services/application-configuration.service.ts
index 5081f94068..39b893501c 100644
--- a/npm/ng-packs/packages/core/src/lib/services/application-configuration.service.ts
+++ b/npm/ng-packs/packages/core/src/lib/services/application-configuration.service.ts
@@ -3,12 +3,18 @@ import { Observable } from 'rxjs';
import { Rest } from '../models/rest';
import { ApplicationConfiguration } from '../models/application-configuration';
import { RestService } from './rest.service';
+import { Store } from '@ngxs/store';
+import { ConfigState } from '../states/config.state';
@Injectable({
providedIn: 'root',
})
export class ApplicationConfigurationService {
- constructor(private rest: RestService) {}
+ get apiName(): string {
+ return this.store.selectSnapshot(ConfigState.getDeep('environment.application.name'));
+ }
+
+ constructor(private rest: RestService, private store: Store) {}
getConfiguration(): Observable {
const request: Rest.Request = {
@@ -16,6 +22,8 @@ export class ApplicationConfigurationService {
url: '/api/abp/application-configuration',
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
}
diff --git a/npm/ng-packs/packages/core/src/lib/services/profile.service.ts b/npm/ng-packs/packages/core/src/lib/services/profile.service.ts
index 38d5fb3a7b..d80caf7e80 100644
--- a/npm/ng-packs/packages/core/src/lib/services/profile.service.ts
+++ b/npm/ng-packs/packages/core/src/lib/services/profile.service.ts
@@ -7,6 +7,8 @@ import { Profile, Rest } from '../models';
providedIn: 'root',
})
export class ProfileService {
+ apiName = 'AbpIdentity';
+
constructor(private rest: RestService) {}
get(): Observable {
@@ -15,7 +17,7 @@ export class ProfileService {
url: '/api/identity/my-profile',
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
update(body: Profile.Response): Observable {
@@ -25,16 +27,24 @@ export class ProfileService {
body,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
- changePassword(body: Profile.ChangePasswordRequest, skipHandleError: boolean = false): Observable {
+ changePassword(
+ body: Profile.ChangePasswordRequest,
+ skipHandleError: boolean = false,
+ ): Observable {
const request: Rest.Request = {
method: 'POST',
url: '/api/identity/my-profile/change-password',
body,
};
- return this.rest.request(request, { skipHandleError });
+ return this.rest.request(request, {
+ skipHandleError,
+ apiName: this.apiName,
+ });
}
}
diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts
index f8f4d069f6..01a181229f 100644
--- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts
+++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts
@@ -81,7 +81,7 @@ export class ConfigState {
static getApiUrl(key?: string) {
const selector = createSelector([ConfigState], (state: Config.State): string => {
- return state.environment.apis[key || 'default'].url;
+ return (state.environment.apis[key || 'default'] || state.environment.apis.default).url;
});
return selector;
@@ -301,7 +301,7 @@ export class ConfigState {
}
@Action(SetEnvironment)
- setEnvironment({ patchState }: StateContext, { environment }:SetEnvironment) {
+ setEnvironment({ patchState }: StateContext, { environment }: SetEnvironment) {
return patchState({
environment,
});
diff --git a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
index 54a602b84a..0a123b6a4f 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
@@ -1,36 +1,36 @@
import { Component, NgModule } from '@angular/core';
import { ActivatedRoute, RouterModule } from '@angular/router';
-import { createRoutingFactory, SpectatorRouting, SpyObject } from '@ngneat/spectator/jest';
-import { Store } from '@ngxs/store';
+import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest';
+import { NgxsModule, Store } from '@ngxs/store';
+import { DynamicLayoutComponent, RouterOutletComponent } from '../components';
import { eLayoutType } from '../enums';
import { ABP } from '../models';
-import { DynamicLayoutComponent, RouterOutletComponent } from '../components';
+import { ConfigState, ReplaceableComponentsState } from '../states';
+import { ApplicationConfigurationService } from '../services';
@Component({
selector: 'abp-layout-application',
template: '',
})
-class DummyApplicationLayoutComponent {
- static type = eLayoutType.application;
-}
+class DummyApplicationLayoutComponent {}
@Component({
selector: 'abp-layout-account',
template: '',
})
-class DummyAccountLayoutComponent {
- static type = eLayoutType.account;
-}
+class DummyAccountLayoutComponent {}
@Component({
selector: 'abp-layout-empty',
template: '',
})
-class DummyEmptyLayoutComponent {
- static type = eLayoutType.empty;
-}
+class DummyEmptyLayoutComponent {}
-const LAYOUTS = [DummyApplicationLayoutComponent, DummyAccountLayoutComponent, DummyEmptyLayoutComponent];
+const LAYOUTS = [
+ DummyApplicationLayoutComponent,
+ DummyAccountLayoutComponent,
+ DummyEmptyLayoutComponent,
+];
@NgModule({
imports: [RouterModule],
@@ -47,13 +47,57 @@ class DummyComponent {
constructor(public route: ActivatedRoute) {}
}
+const storeData = {
+ ConfigState: {
+ routes: [
+ {
+ path: '',
+ wrapper: true,
+ children: [
+ {
+ path: 'parentWithLayout',
+ layout: eLayoutType.application,
+ children: [
+ { path: 'childWithoutLayout' },
+ { path: 'childWithLayout', layout: eLayoutType.account },
+ ],
+ },
+ ],
+ },
+ { path: 'withData', layout: eLayoutType.application },
+ ,
+ ] as ABP.FullRoute[],
+ environment: { application: {} },
+ },
+ ReplaceableComponentsState: {
+ replaceableComponents: [
+ {
+ key: 'Theme.ApplicationLayoutComponent',
+ component: DummyApplicationLayoutComponent,
+ },
+ {
+ key: 'Theme.AccountLayoutComponent',
+ component: DummyAccountLayoutComponent,
+ },
+ {
+ key: 'Theme.EmptyLayoutComponent',
+ component: DummyEmptyLayoutComponent,
+ },
+ ],
+ },
+};
+
describe('DynamicLayoutComponent', () => {
const createComponent = createRoutingFactory({
component: RouterOutletComponent,
stubsEnabled: false,
- mocks: [Store],
declarations: [DummyComponent, DynamicLayoutComponent],
- imports: [RouterModule, DummyLayoutModule],
+ mocks: [ApplicationConfigurationService],
+ imports: [
+ RouterModule,
+ DummyLayoutModule,
+ NgxsModule.forRoot([ConfigState, ReplaceableComponentsState]),
+ ],
routes: [
{ path: '', component: RouterOutletComponent },
{
@@ -100,33 +144,13 @@ describe('DynamicLayoutComponent', () => {
});
let spectator: SpectatorRouting;
- let store: SpyObject;
- const mockStoreData = {
- requirements: { layouts: LAYOUTS },
- routes: [
- {
- path: '',
- wrapper: true,
- children: [
- {
- path: 'parentWithLayout',
- layout: eLayoutType.application,
- children: [{ path: 'childWithoutLayout' }, { path: 'childWithLayout', layout: eLayoutType.account }],
- },
- ],
- },
- { path: 'withData', layout: eLayoutType.application },
- ,
- ] as ABP.FullRoute[],
- environment: { application: {} },
- };
- let storeSpy: jest.SpyInstance;
+ let store: Store;
beforeEach(async () => {
spectator = createComponent();
store = spectator.get(Store);
- storeSpy = jest.spyOn(store, 'selectSnapshot');
- storeSpy.mockReturnValue(mockStoreData);
+
+ store.reset(storeData);
});
it('should handle application layout from parent abp route and display it', async () => {
@@ -159,7 +183,7 @@ describe('DynamicLayoutComponent', () => {
});
it('should not display any layout when layouts are empty', async () => {
- storeSpy.mockReturnValue({ ...mockStoreData, requirements: { layouts: [] } });
+ store.reset({ ...storeData, ReplaceableComponentsState: {} });
spectator.detectChanges();
diff --git a/npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts
index 518956deba..3ad9eeda63 100644
--- a/npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts
+++ b/npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts
@@ -1,4 +1,4 @@
-import { LinkedList } from '../utils/linked-list';
+import { LinkedList, ListNode } from '../utils/linked-list';
describe('Linked List (Doubly)', () => {
let list: LinkedList;
@@ -44,9 +44,11 @@ describe('Linked List (Doubly)', () => {
expect(list.length).toBe(3);
expect(list.head.value).toBe('c');
expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('a');
expect(list.head.previous).toBeUndefined();
expect(list.tail.value).toBe('a');
expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('c');
expect(list.tail.next).toBeUndefined();
});
});
@@ -72,34 +74,49 @@ describe('Linked List (Doubly)', () => {
expect(list.length).toBe(3);
expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
expect(list.head.previous).toBeUndefined();
expect(list.tail.value).toBe('c');
expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
expect(list.tail.next).toBeUndefined();
});
});
describe('#after', () => {
- it('should place a node after node with given value', () => {
+ it('should add a node after node with given value', () => {
list.add('a').tail();
- list.add('b').tail();
- list.add('c').tail();
- // "a" <-> "b" <-> "c"
+ // "a"
- list.add('x').after('b');
+ list.add('b').after('a');
+ list.add('c').after('b');
- // "a" <-> "b" <-> "x" <-> "c"
+ // "a" <-> "b" <-> "c"
- expect(list.length).toBe(4);
+ expect(list.length).toBe(3);
expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('b');
- expect(list.head.next.next.value).toBe('x');
- expect(list.head.next.next.next.value).toBe('c');
+ expect(list.head.next.next.value).toBe('c');
expect(list.tail.value).toBe('c');
- expect(list.tail.previous.value).toBe('x');
- expect(list.tail.previous.previous.value).toBe('b');
- expect(list.tail.previous.previous.previous.value).toBe('a');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ });
+
+ it('should add a node to tail if given value is not found', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.add('b').after('x');
+
+ // "a" <-> "b"
+
+ expect(list.length).toBe(2);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.tail.value).toBe('b');
+ expect(list.tail.previous.value).toBe('a');
});
it('should be able to receive a custom compareFn', () => {
@@ -126,79 +143,516 @@ describe('Linked List (Doubly)', () => {
});
describe('#before', () => {
- it('should place a node before node with given value', () => {
+ it('should add a node before node with given value', () => {
+ list.add('c').tail();
+
+ // "c"
+
+ list.add('b').before('c');
+ list.add('a').before('b');
+
+ // "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ });
+
+ it('should add a node to head if given value is not found', () => {
+ list.add('b').tail();
+
+ // "a"
+
+ list.add('a').before('x');
+
+ // "a" <-> "b"
+
+ expect(list.length).toBe(2);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.tail.value).toBe('b');
+ expect(list.tail.previous.value).toBe('a');
+ });
+
+ it('should be able to receive a custom compareFn', () => {
+ list.add({ x: 1 }).tail();
+ list.add({ x: 2 }).tail();
+ list.add({ x: 3 }).tail();
+
+ // {"x":1} <-> {"x":2} <-> {"x":3}
+
+ list.add({ x: 0 }).before({ x: 2 }, (v1: X, v2: X) => v1.x === v2.x);
+
+ // {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":3}
+
+ expect(list.length).toBe(4);
+ expect(list.head.value.x).toBe(1);
+ expect(list.head.next.value.x).toBe(0);
+ expect(list.head.next.next.value.x).toBe(2);
+ expect(list.head.next.next.next.value.x).toBe(3);
+ expect(list.tail.value.x).toBe(3);
+ expect(list.tail.previous.value.x).toBe(2);
+ expect(list.tail.previous.previous.value.x).toBe(0);
+ expect(list.tail.previous.previous.previous.value.x).toBe(1);
+ });
+ });
+
+ describe('#byIndex', () => {
+ it('should add a node at given index', () => {
list.add('a').tail();
list.add('b').tail();
list.add('c').tail();
// "a" <-> "b" <-> "c"
- list.add('x').before('b');
+ list.add('x').byIndex(1);
// "a" <-> "x" <-> "b" <-> "c"
- expect(list.length).toBe(4);
+ list.add('y').byIndex(3);
+
+ // "a" <-> "x" <-> "b" <-> "y" <-> "c"
+
+ expect(list.length).toBe(5);
expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('x');
expect(list.head.next.next.value).toBe('b');
+ expect(list.head.next.next.next.value).toBe('y');
+ expect(list.head.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('y');
+ expect(list.tail.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should add a node to head if given index is zero', () => {
+ list.add('a').tail();
+ list.add('b').tail();
+ list.add('c').tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.add('x').byIndex(0);
+
+ // "x" <-> "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('x');
+ expect(list.head.next.value).toBe('a');
+ expect(list.head.next.next.value).toBe('b');
expect(list.head.next.next.next.value).toBe('c');
expect(list.tail.value).toBe('c');
expect(list.tail.previous.value).toBe('b');
- expect(list.tail.previous.previous.value).toBe('x');
- expect(list.tail.previous.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.previous.value).toBe('x');
+ });
+
+ it('should add a node to tail if given index more than size', () => {
+ list.add('a').tail();
+ list.add('b').tail();
+ list.add('c').tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.add('x').byIndex(4);
+
+ // "a" <-> "b" <-> "c" <-> "x"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.head.next.next.next.value).toBe('x');
+ expect(list.tail.value).toBe('x');
+ expect(list.tail.previous.value).toBe('c');
+ expect(list.tail.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should be able to add a node at given index counting from right to left', () => {
+ list.add('a').tail();
+ list.add('b').tail();
+ list.add('c').tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.add('x').byIndex(-1);
+
+ // "a" <-> "b" <-> "x" <-> "c"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('x');
+ expect(list.head.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('x');
+ expect(list.tail.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should add a node to head if given index is less than minus size', () => {
+ list.add('a').tail();
+ list.add('b').tail();
+ list.add('c').tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.add('x').byIndex(-4);
+
+ // "x" <-> "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('x');
+ expect(list.head.next.value).toBe('a');
+ expect(list.head.next.next.value).toBe('b');
+ expect(list.head.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.previous.value).toBe('x');
+ });
+ });
+ });
+
+ describe('#addMany', () => {
+ describe('#head', () => {
+ it('should add multiple nodes to the head of the list', () => {
+ list.add('x').head();
+
+ // "x"
+
+ list.addMany(['a', 'b', 'c']).head();
+
+ // "a" <-> "b" <-> "c" <-> "x"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.head.next.next.next.value).toBe('x');
+ expect(list.head.previous).toBeUndefined();
+ expect(list.tail.value).toBe('x');
+ expect(list.tail.previous.value).toBe('c');
+ expect(list.tail.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.value).toBe('a');
+ expect(list.tail.next).toBeUndefined();
+ });
+ });
+
+ describe('#tail', () => {
+ it('should add multiple nodes to the tail of the list', () => {
+ list.add('x').tail();
+
+ // "x"
+
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "x" <-> "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('x');
+ expect(list.head.next.value).toBe('a');
+ expect(list.head.next.next.value).toBe('b');
+ expect(list.head.next.next.next.value).toBe('c');
+ expect(list.head.previous).toBeUndefined();
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.previous.value).toBe('x');
+ expect(list.tail.next).toBeUndefined();
+ });
+ });
+
+ describe('#after', () => {
+ it('should add multiple nodes after node with given value', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.addMany(['b', 'c']).after('a');
+
+ // "a" <-> "b" <-> "c"
+
+ list.addMany(['x', 'y', 'z']).after('b');
+
+ // "a" <-> "b" <-> "x" <-> "y" <-> "z" <-> "c"
+
+ expect(list.length).toBe(6);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('x');
+ expect(list.head.next.next.next.value).toBe('y');
+ expect(list.head.next.next.next.next.value).toBe('z');
+ expect(list.head.next.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('z');
+ expect(list.tail.previous.previous.value).toBe('y');
+ expect(list.tail.previous.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should add multiple nodes to tail if given value is not found', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.addMany(['b', 'c']).after('x');
+
+ // "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ });
+
+ it('should be able to receive a custom compareFn', () => {
+ list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
+
+ // {"x":1} <-> {"x":2} <-> {"x":3}
+
+ list.addMany([{ x: 4 }, { x: 5 }]).after({ x: 1 }, (v1: X, v2: X) => v1.x === v2.x);
+
+ // {"x":1} <-> {"x":4} <-> {"x":5} <-> {"x":2} <-> {"x":3}
+
+ expect(list.length).toBe(5);
+ expect(list.head.value.x).toBe(1);
+ expect(list.head.next.value.x).toBe(4);
+ expect(list.head.next.next.value.x).toBe(5);
+ expect(list.head.next.next.next.value.x).toBe(2);
+ expect(list.head.next.next.next.next.value.x).toBe(3);
+ expect(list.tail.value.x).toBe(3);
+ expect(list.tail.previous.value.x).toBe(2);
+ expect(list.tail.previous.previous.value.x).toBe(5);
+ expect(list.tail.previous.previous.previous.value.x).toBe(4);
+ expect(list.tail.previous.previous.previous.previous.value.x).toBe(1);
+ });
+
+ it('should not change the list when empty array given as value', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.addMany([]).after('a');
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+ });
+
+ describe('#before', () => {
+ it('should add multiple nodes before node with given value', () => {
+ list.add('c').tail();
+
+ // "c"
+
+ list.addMany(['a', 'b']).before('c');
+
+ // "a" <-> "b" <-> "c"
+
+ list.addMany(['x', 'y', 'z']).before('b');
+
+ // "a" <-> "x" <-> "y" <-> "z" <-> "b" <-> "c"
+
+ expect(list.length).toBe(6);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('x');
+ expect(list.head.next.next.value).toBe('y');
+ expect(list.head.next.next.next.value).toBe('z');
+ expect(list.head.next.next.next.next.value).toBe('b');
+ expect(list.head.next.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('z');
+ expect(list.tail.previous.previous.previous.value).toBe('y');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should add multiple nodes to head if given value is not found', () => {
+ list.add('c').tail();
+
+ // "c"
+
+ list.addMany(['a', 'b']).before('x');
+
+ // "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ });
+
+ it('should be able to receive a custom compareFn', () => {
+ list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
+
+ // {"x":1} <-> {"x":2} <-> {"x":3}
+
+ list.addMany([{ x: 4 }, { x: 5 }]).before({ x: 3 }, (v1: X, v2: X) => v1.x === v2.x);
+
+ // {"x":1} <-> {"x":2} <-> {"x":4} <-> {"x":5} <-> {"x":3}
+
+ expect(list.length).toBe(5);
+ expect(list.head.value.x).toBe(1);
+ expect(list.head.next.value.x).toBe(2);
+ expect(list.head.next.next.value.x).toBe(4);
+ expect(list.head.next.next.next.value.x).toBe(5);
+ expect(list.head.next.next.next.next.value.x).toBe(3);
+ expect(list.tail.value.x).toBe(3);
+ expect(list.tail.previous.value.x).toBe(5);
+ expect(list.tail.previous.previous.value.x).toBe(4);
+ expect(list.tail.previous.previous.previous.value.x).toBe(2);
+ expect(list.tail.previous.previous.previous.previous.value.x).toBe(1);
+ });
+
+ it('should not change the list when empty array given as value', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.addMany([]).before('a');
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+ });
+
+ describe('#byIndex', () => {
+ it('should add multiple nodes starting from given index', () => {
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.addMany(['x', 'y']).byIndex(1);
+
+ // "a" <-> "x" <-> "y" <-> "b" <-> "c"
+
+ list.addMany(['z']).byIndex(4);
+
+ // "a" <-> "x" <-> "y" <-> "b" <-> "z" <-> "c"
+
+ expect(list.length).toBe(6);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('x');
+ expect(list.head.next.next.value).toBe('y');
+ expect(list.head.next.next.next.value).toBe('b');
+ expect(list.head.next.next.next.next.value).toBe('z');
+ expect(list.head.next.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('z');
+ expect(list.tail.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.value).toBe('y');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.previous.previous.previous.value).toBe('a');
+ });
+
+ it('should add multiple nodes to head if given index is zero', () => {
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.addMany(['x', 'y']).byIndex(0);
+
+ // "x" <-> "y" <-> "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(5);
+ expect(list.head.value).toBe('x');
+ expect(list.head.next.value).toBe('y');
+ expect(list.head.next.next.value).toBe('a');
+ expect(list.head.next.next.next.value).toBe('b');
+ expect(list.head.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.previous.value).toBe('y');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('x');
});
- it('should be able to receive a custom compareFn', () => {
- list.add({ x: 1 }).tail();
- list.add({ x: 2 }).tail();
- list.add({ x: 3 }).tail();
+ it('should add multiple nodes to tail if given index more than size', () => {
+ list.addMany(['a', 'b', 'c']).tail();
- // {"x":1} <-> {"x":2} <-> {"x":3}
+ // "a" <-> "b" <-> "c"
- list.add({ x: 0 }).before({ x: 2 }, (v1: X, v2: X) => v1.x === v2.x);
+ list.addMany(['x', 'y']).byIndex(4);
- // {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":3}
+ // "a" <-> "b" <-> "c" <-> "x" <-> "y"
- expect(list.length).toBe(4);
- expect(list.head.value.x).toBe(1);
- expect(list.head.next.value.x).toBe(0);
- expect(list.head.next.next.value.x).toBe(2);
- expect(list.head.next.next.next.value.x).toBe(3);
- expect(list.tail.value.x).toBe(3);
- expect(list.tail.previous.value.x).toBe(2);
- expect(list.tail.previous.previous.value.x).toBe(0);
- expect(list.tail.previous.previous.previous.value.x).toBe(1);
+ expect(list.length).toBe(5);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.head.next.next.next.value).toBe('x');
+ expect(list.head.next.next.next.next.value).toBe('y');
+ expect(list.tail.value).toBe('y');
+ expect(list.tail.previous.value).toBe('x');
+ expect(list.tail.previous.previous.value).toBe('c');
+ expect(list.tail.previous.previous.previous.value).toBe('b');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('a');
});
- });
- describe('#byIndex', () => {
- it('should place a node at given index', () => {
- list.add('a').tail();
- list.add('b').tail();
- list.add('c').tail();
+ it('should be able to add multiple nodes at given index counting from right to left', () => {
+ list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
- list.add('x').byIndex(1);
-
- // "a" <-> "x" <-> "b" <-> "c"
-
- list.add('y').byIndex(3);
+ list.addMany(['x', 'y']).byIndex(-1);
- // "a" <-> "x" <-> "b" <-> "y" <-> "c"
+ // "a" <-> "b" <-> "x" <-> "y" <-> "c"
expect(list.length).toBe(5);
expect(list.head.value).toBe('a');
- expect(list.head.next.value).toBe('x');
- expect(list.head.next.next.value).toBe('b');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('x');
expect(list.head.next.next.next.value).toBe('y');
expect(list.head.next.next.next.next.value).toBe('c');
expect(list.tail.value).toBe('c');
expect(list.tail.previous.value).toBe('y');
- expect(list.tail.previous.previous.value).toBe('b');
- expect(list.tail.previous.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.value).toBe('x');
+ expect(list.tail.previous.previous.previous.value).toBe('b');
expect(list.tail.previous.previous.previous.previous.value).toBe('a');
});
+
+ it('should add a node to head if given index is less than minus size', () => {
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "a" <-> "b" <-> "c"
+
+ list.addMany(['x', 'y']).byIndex(-4);
+
+ // "x" <-> "y" <-> "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(5);
+ expect(list.head.value).toBe('x');
+ expect(list.head.next.value).toBe('y');
+ expect(list.head.next.next.value).toBe('a');
+ expect(list.head.next.next.next.value).toBe('b');
+ expect(list.head.next.next.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ expect(list.tail.previous.previous.previous.value).toBe('y');
+ expect(list.tail.previous.previous.previous.previous.value).toBe('x');
+ });
});
});
@@ -212,19 +666,19 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
- const node1 = list.find(node => node.previous && node.previous.value === 'a');
+ const found1 = list.find(node => node.previous && node.previous.value === 'a');
- expect(node1.value).toBe('x');
- expect(node1.previous.value).toBe('a');
- expect(node1.next.value).toBe('b');
+ expect(found1.value).toBe('x');
+ expect(found1.previous.value).toBe('a');
+ expect(found1.next.value).toBe('b');
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
- const node2 = list.find(node => node.next && node.next.value === 'c');
+ const found2 = list.find(node => node.next && node.next.value === 'c');
- expect(node2.value).toBe('x');
- expect(node2.previous.value).toBe('b');
- expect(node2.next.value).toBe('c');
+ expect(found2.value).toBe('x');
+ expect(found2.previous.value).toBe('b');
+ expect(found2.next.value).toBe('c');
});
it('should return undefined when list is empty', () => {
@@ -329,7 +783,8 @@ describe('Linked List (Doubly)', () => {
describe('#drop', () => {
describe('#head', () => {
it('should return undefined when there is no head', () => {
- expect(list.drop().head()).toBeUndefined();
+ const dropped = list.drop().head();
+ expect(dropped).toBeUndefined();
});
it('should remove the node from the head of the list', () => {
@@ -350,12 +805,22 @@ describe('Linked List (Doubly)', () => {
expect(list.tail.value).toBe('c');
expect(list.tail.previous.value).toBe('b');
expect(list.tail.next).toBeUndefined();
+
+ // "b" <-> "c"
+
+ list.drop().head();
+ list.drop().head();
+
+ expect(list.length).toBe(0);
+ expect(list.head).toBeUndefined();
+ expect(list.tail).toBeUndefined();
});
});
- describe('#head', () => {
+ describe('#tail', () => {
it('should return undefined when there is no tail', () => {
- expect(list.drop().tail()).toBeUndefined();
+ const dropped = list.drop().tail();
+ expect(dropped).toBeUndefined();
});
it('should remove the node from the tail of the list', () => {
@@ -376,6 +841,15 @@ describe('Linked List (Doubly)', () => {
expect(list.tail.value).toBe('b');
expect(list.tail.previous.value).toBe('a');
expect(list.tail.next).toBeUndefined();
+
+ // "a" <-> "b"
+
+ list.drop().tail();
+ list.drop().tail();
+
+ expect(list.length).toBe(0);
+ expect(list.head).toBeUndefined();
+ expect(list.tail).toBeUndefined();
});
});
@@ -393,7 +867,7 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "c" <-> "d" <-> "e"
- list.drop().byIndex(2);
+ list.drop().byIndex(-2);
// "a" <-> "c" <-> "e"
@@ -404,11 +878,21 @@ describe('Linked List (Doubly)', () => {
expect(list.tail.value).toBe('e');
expect(list.tail.previous.value).toBe('c');
expect(list.tail.previous.previous.value).toBe('a');
+
+ // "a" <-> "c" <-> "e"
+
+ list.drop().byIndex(2);
+ list.drop().byIndex(1);
+ list.drop().byIndex(0);
+
+ expect(list.length).toBe(0);
+ expect(list.head).toBeUndefined();
+ expect(list.tail).toBeUndefined();
});
it('should return undefined when list is empty', () => {
- const node = list.drop().byIndex(0);
- expect(node).toBeUndefined();
+ const dropped = list.drop().byIndex(0);
+ expect(dropped).toBeUndefined();
});
it('should return undefined when given index does not exist', () => {
@@ -418,11 +902,11 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "b" <-> "c"
- const node1 = list.drop().byIndex(4);
+ const dropped1 = list.drop().byIndex(4);
// "a" <-> "b" <-> "c"
- expect(node1).toBeUndefined();
+ expect(dropped1).toBeUndefined();
expect(list.length).toBe(3);
expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('b');
@@ -433,11 +917,11 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "b" <-> "c"
- const node2 = list.drop().byIndex(-1);
+ const dropped2 = list.drop().byIndex(-4);
// "a" <-> "b" <-> "c"
- expect(node2).toBeUndefined();
+ expect(dropped2).toBeUndefined();
expect(list.length).toBe(3);
expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('b');
@@ -506,8 +990,8 @@ describe('Linked List (Doubly)', () => {
});
it('should return undefined when list is empty', () => {
- const node = list.drop().byValue('x');
- expect(node).toBeUndefined();
+ const dropped = list.drop().byValue('x');
+ expect(dropped).toBeUndefined();
});
it('should return undefined when given value is not found', () => {
@@ -622,6 +1106,214 @@ describe('Linked List (Doubly)', () => {
});
});
+ describe('#dropMany', () => {
+ describe('#head', () => {
+ it('should return empty array when there is no head', () => {
+ const dropped = list.dropMany(1).head();
+ expect(dropped).toEqual([]);
+ });
+
+ it('should remove multiple nodes from the head of the list', () => {
+ list.addMany(['a', 'b', 'c', 'd', 'e']).tail();
+
+ // "a" <-> "b" <-> "c" <-> "d" <-> "e"
+
+ list.dropMany(3).head();
+
+ // "d" <-> "e"
+
+ expect(list.length).toBe(2);
+ expect(list.head.value).toBe('d');
+ expect(list.head.next.value).toBe('e');
+ expect(list.head.previous).toBeUndefined();
+ expect(list.tail.value).toBe('e');
+ expect(list.tail.previous.value).toBe('d');
+ expect(list.tail.next).toBeUndefined();
+ });
+
+ it('should not change the list when count is less than or equal to zero', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.dropMany(0).head();
+
+ // "a"
+
+ list.dropMany(-1).head();
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+ });
+
+ describe('#tail', () => {
+ it('should return empty array when there is no tail', () => {
+ const dropped = list.dropMany(1).tail();
+ expect(dropped).toEqual([]);
+ });
+
+ it('should remove multiple nodes from the tail of the list', () => {
+ list.addMany(['a', 'b', 'c', 'd', 'e']).tail();
+
+ // "a" <-> "b" <-> "c" <-> "d" <-> "e"
+
+ list.dropMany(3).tail();
+
+ // "a" <-> "b"
+
+ expect(list.length).toBe(2);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.previous).toBeUndefined();
+ expect(list.tail.value).toBe('b');
+ expect(list.tail.previous.value).toBe('a');
+ expect(list.tail.next).toBeUndefined();
+ });
+
+ it('should not change the list when count is less than or equal to zero', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.dropMany(0).tail();
+
+ // "a"
+
+ list.dropMany(-1).tail();
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+ });
+
+ describe('#byIndex', () => {
+ it('should remove multiple nodes starting from given index', () => {
+ list.addMany(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']).tail();
+
+ // "a" <-> "b" <-> "c" <-> "d" <-> "e" <-> "f" <-> "g" <-> "h"
+
+ list.dropMany(2).byIndex(1);
+
+ // "a" <-> "d" <-> "e" <-> "f" <-> "g" <-> "h"
+
+ list.dropMany(2).byIndex(-3);
+
+ // "a" <-> "d" <-> "e" <-> "h"
+
+ expect(list.length).toBe(4);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('d');
+ expect(list.head.next.next.value).toBe('e');
+ expect(list.head.next.next.next.value).toBe('h');
+ expect(list.tail.value).toBe('h');
+ expect(list.tail.previous.value).toBe('e');
+ expect(list.tail.previous.previous.value).toBe('d');
+ expect(list.tail.previous.previous.previous.value).toBe('a');
+
+ list.dropMany(4).byIndex(0);
+
+ expect(list.length).toBe(0);
+ expect(list.head).toBeUndefined();
+ expect(list.tail).toBeUndefined();
+ });
+
+ it('should return empty array when list is empty', () => {
+ const dropped = list.dropMany(1).byIndex(0);
+ expect(dropped).toEqual([]);
+ });
+
+ it('should return empty array when given index does not exist', () => {
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "a" <-> "b" <-> "c"
+
+ const dropped = list.dropMany(3).byIndex(4);
+
+ // "a" <-> "b" <-> "c"
+
+ expect(dropped).toEqual([]);
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+ });
+
+ it('should remove from start when given index is less than minus size', () => {
+ list.addMany(['a', 'b', 'c', 'd', 'e']).tail();
+
+ // "a" <-> "b" <-> "c" <-> "d" <-> "e"
+
+ list.dropMany(2).byIndex(-9);
+
+ // "c" <-> "d" <-> "e"
+
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('c');
+ expect(list.head.next.value).toBe('d');
+ expect(list.head.next.next.value).toBe('e');
+ expect(list.tail.value).toBe('e');
+ expect(list.tail.previous.value).toBe('d');
+ expect(list.tail.previous.previous.value).toBe('c');
+ });
+
+ it('should remove from end when given index + count is larger than or equal to size', () => {
+ list.addMany(['a', 'b', 'c', 'd', 'e']).tail();
+
+ // "a" <-> "b" <-> "c" <-> "d" <-> "e"
+
+ list.dropMany(2).byIndex(3);
+
+ // "a" <-> "b" <-> "c"
+
+ expect(list.length).toBe(3);
+ expect(list.head.value).toBe('a');
+ expect(list.head.next.value).toBe('b');
+ expect(list.head.next.next.value).toBe('c');
+ expect(list.tail.value).toBe('c');
+ expect(list.tail.previous.value).toBe('b');
+ expect(list.tail.previous.previous.value).toBe('a');
+
+ // "a" <-> "b" <-> "c"
+
+ list.dropMany(9).byIndex(1);
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+
+ it('should not change the list when count is less than or equal to zero', () => {
+ list.add('a').tail();
+
+ // "a"
+
+ list.dropMany(0).byIndex(0);
+
+ // "a"
+
+ list.dropMany(-1).byIndex(0);
+
+ // "a"
+
+ expect(list.length).toBe(1);
+ expect(list.head.value).toBe('a');
+ expect(list.tail.value).toBe('a');
+ });
+ });
+ });
+
describe('#get', () => {
it('should return node at given index', () => {
list.add('a').tail();
@@ -761,6 +1453,27 @@ describe('Linked List (Doubly)', () => {
});
});
+ describe('#toNodeArray', () => {
+ it('should return array of nodes', () => {
+ list.addTail('a');
+ list.addTail(2);
+ list.addTail('c');
+ list.addTail({ k: 4, v: 'd' });
+
+ // "a" <-> 2 <-> "c" <-> {"k":4,"v":"d"}
+
+ const arr = list.toNodeArray();
+
+ expect(arr.every(node => node instanceof ListNode)).toBe(true);
+ expect(arr.map(node => node.value)).toEqual(['a', 2, 'c', { k: 4, v: 'd' }]);
+ });
+
+ it('should return empty array when list is empty', () => {
+ const arr = list.toNodeArray();
+ expect(arr).toEqual([]);
+ });
+ });
+
describe('#toString', () => {
it('should return string representation', () => {
list.addTail('a');
@@ -778,6 +1491,23 @@ describe('Linked List (Doubly)', () => {
const str = list.toString();
expect(str).toBe('');
});
+
+ it('should be coercible', () => {
+ list.addMany(['a', 'b', 'c']).tail();
+
+ // "a" <-> "b" <-> "c"
+
+ expect('' + list).toBe('"a" <-> "b" <-> "c"');
+ });
+
+ it('should be able to receive a custom mapperFn', () => {
+ list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
+
+ // {"x":1} <-> {"x":2} <-> {"x":3}
+
+ const str = list.toString(value => value.x);
+ expect(str).toBe('1 <-> 2 <-> 3');
+ });
});
it('should be iterable', () => {
diff --git a/npm/ng-packs/packages/core/src/lib/utils/linked-list.ts b/npm/ng-packs/packages/core/src/lib/utils/linked-list.ts
index 42cc5bc941..9bd3e21941 100644
--- a/npm/ng-packs/packages/core/src/lib/utils/linked-list.ts
+++ b/npm/ng-packs/packages/core/src/lib/utils/linked-list.ts
@@ -27,65 +27,107 @@ export class LinkedList {
return this.size;
}
- private linkWith(
+ private attach(
value: T,
previousNode: ListNode | undefined,
nextNode: ListNode | undefined,
): ListNode {
- const node = new ListNode(value);
-
if (!previousNode) return this.addHead(value);
+
if (!nextNode) return this.addTail(value);
+ const node = new ListNode(value);
node.previous = previousNode;
previousNode.next = node;
node.next = nextNode;
nextNode.previous = node;
- this.size += 1;
+ this.size++;
+
+ return node;
+ }
+
+ private attachMany(
+ values: T[],
+ previousNode: ListNode | undefined,
+ nextNode: ListNode | undefined,
+ ): ListNode[] {
+ if (!values.length) return [];
+
+ if (!previousNode) return this.addManyHead(values);
+
+ if (!nextNode) return this.addManyTail(values);
+
+ const list = new LinkedList();
+ list.addManyTail(values);
+ list.first!.previous = previousNode;
+ previousNode.next = list.first;
+ list.last!.next = nextNode;
+ nextNode.previous = list.last;
+
+ this.size += values.length;
+
+ return list.toNodeArray();
+ }
+
+ private detach(node: ListNode) {
+ if (!node.previous) return this.dropHead();
+
+ if (!node.next) return this.dropTail();
+
+ node.previous.next = node.next;
+ node.next.previous = node.previous;
+
+ this.size--;
return node;
}
add(value: T) {
return {
- after: (previousValue: T, compareFn = compare) => {
- return this.addAfter(value, previousValue, compareFn);
- },
- before: (nextValue: T, compareFn = compare) => {
- return this.addBefore(value, nextValue, compareFn);
- },
- byIndex: (position: number): ListNode => {
- return this.addByIndex(value, position);
- },
- head: (): ListNode => {
- return this.addHead(value);
- },
- tail: (): ListNode => {
- return this.addTail(value);
- },
+ after: (previousValue: T, compareFn: ListComparisonFn = compare) =>
+ this.addAfter(value, previousValue, compareFn),
+ before: (nextValue: T, compareFn: ListComparisonFn = compare) =>
+ this.addBefore(value, nextValue, compareFn),
+ byIndex: (position: number) => this.addByIndex(value, position),
+ head: () => this.addHead(value),
+ tail: () => this.addTail(value),
+ };
+ }
+
+ addMany(values: T[]) {
+ return {
+ after: (previousValue: T, compareFn: ListComparisonFn = compare) =>
+ this.addManyAfter(values, previousValue, compareFn),
+ before: (nextValue: T, compareFn: ListComparisonFn = compare) =>
+ this.addManyBefore(values, nextValue, compareFn),
+ byIndex: (position: number) => this.addManyByIndex(values, position),
+ head: () => this.addManyHead(values),
+ tail: () => this.addManyTail(values),
};
}
- addAfter(value: T, previousValue: T, compareFn = compare): ListNode {
+ addAfter(value: T, previousValue: T, compareFn: ListComparisonFn = compare): ListNode {
const previous = this.find(node => compareFn(node.value, previousValue));
- return previous ? this.linkWith(value, previous, previous.next) : this.addTail(value);
+ return previous ? this.attach(value, previous, previous.next) : this.addTail(value);
}
- addBefore(value: T, nextValue: T, compareFn = compare): ListNode {
+ addBefore(value: T, nextValue: T, compareFn: ListComparisonFn = compare): ListNode {
const next = this.find(node => compareFn(node.value, nextValue));
- return next ? this.linkWith(value, next.previous, next) : this.addHead(value);
+ return next ? this.attach(value, next.previous, next) : this.addHead(value);
}
addByIndex(value: T, position: number): ListNode {
+ if (position < 0) position += this.size;
+ else if (position >= this.size) return this.addTail(value);
+
if (position <= 0) return this.addHead(value);
- if (position >= this.size) return this.addTail(value);
const next = this.get(position)!;
- return this.linkWith(value, next.previous, next);
+ return this.attach(value, next.previous, next);
}
addHead(value: T): ListNode {
@@ -97,7 +139,7 @@ export class LinkedList {
else this.last = node;
this.first = node;
- this.size += 1;
+ this.size++;
return node;
}
@@ -114,51 +156,92 @@ export class LinkedList {
this.last = node;
}
- this.size += 1;
+ this.size++;
return node;
}
+ addManyAfter(
+ values: T[],
+ previousValue: T,
+ compareFn: ListComparisonFn = compare,
+ ): ListNode[] {
+ const previous = this.find(node => compareFn(node.value, previousValue));
+
+ return previous ? this.attachMany(values, previous, previous.next) : this.addManyTail(values);
+ }
+
+ addManyBefore(
+ values: T[],
+ nextValue: T,
+ compareFn: ListComparisonFn = compare,
+ ): ListNode[] {
+ const next = this.find(node => compareFn(node.value, nextValue));
+
+ return next ? this.attachMany(values, next.previous, next) : this.addManyHead(values);
+ }
+
+ addManyByIndex(values: T[], position: number): ListNode[] {
+ if (position < 0) position += this.size;
+
+ if (position <= 0) return this.addManyHead(values);
+
+ if (position >= this.size) return this.addManyTail(values);
+
+ const next = this.get(position)!;
+
+ return this.attachMany(values, next.previous, next);
+ }
+
+ addManyHead(values: T[]): ListNode[] {
+ return values.reduceRight[]>((nodes, value) => {
+ nodes.unshift(this.addHead(value));
+ return nodes;
+ }, []);
+ }
+
+ addManyTail(values: T[]): ListNode[] {
+ return values.map(value => this.addTail(value));
+ }
+
drop() {
return {
byIndex: (position: number) => this.dropByIndex(position),
- byValue: (value: T, compareFn = compare) => this.dropByValue(value, compareFn),
- byValueAll: (value: T, compareFn = compare) => this.dropByValueAll(value, compareFn),
+ byValue: (value: T, compareFn: ListComparisonFn = compare) =>
+ this.dropByValue(value, compareFn),
+ byValueAll: (value: T, compareFn: ListComparisonFn = compare) =>
+ this.dropByValueAll(value, compareFn),
head: () => this.dropHead(),
tail: () => this.dropTail(),
};
}
+ dropMany(count: number) {
+ return {
+ byIndex: (position: number) => this.dropManyByIndex(count, position),
+ head: () => this.dropManyHead(count),
+ tail: () => this.dropManyTail(count),
+ };
+ }
+
dropByIndex(position: number): ListNode | undefined {
- if (position === 0) return this.dropHead();
- else if (position === this.size - 1) return this.dropTail();
+ if (position < 0) position += this.size;
const current = this.get(position);
- if (current) {
- current.previous!.next = current.next;
- current.next!.previous = current.previous;
-
- this.size -= 1;
-
- return current;
- }
-
- return undefined;
+ return current ? this.detach(current) : undefined;
}
- dropByValue(value: T, compareFn = compare): ListNode | undefined {
+ dropByValue(value: T, compareFn: ListComparisonFn = compare): ListNode | undefined {
const position = this.findIndex(node => compareFn(node.value, value));
- if (position < 0) return undefined;
-
- return this.dropByIndex(position);
+ return position < 0 ? undefined : this.dropByIndex(position);
}
- dropByValueAll(value: T, compareFn = compare): ListNode[] {
+ dropByValueAll(value: T, compareFn: ListComparisonFn = compare): ListNode[] {
const dropped: ListNode[] = [];
- for (let current = this.first, position = 0; current; position += 1, current = current.next) {
+ for (let current = this.first, position = 0; current; position++, current = current.next) {
if (compareFn(current.value, value)) {
dropped.push(this.dropByIndex(position - dropped.length)!);
}
@@ -176,7 +259,7 @@ export class LinkedList {
if (this.first) this.first.previous = undefined;
else this.last = undefined;
- this.size -= 1;
+ this.size--;
return head;
}
@@ -193,7 +276,7 @@ export class LinkedList {
if (this.last) this.last.next = undefined;
else this.first = undefined;
- this.size -= 1;
+ this.size--;
return tail;
}
@@ -201,24 +284,66 @@ export class LinkedList {
return undefined;
}
- find(predicate: ListIteratorFunction): ListNode | undefined {
- for (let current = this.first, position = 0; current; position += 1, current = current.next) {
+ dropManyByIndex(count: number, position: number): ListNode[] {
+ if (count <= 0) return [];
+
+ if (position < 0) position = Math.max(position + this.size, 0);
+ else if (position >= this.size) return [];
+
+ count = Math.min(count, this.size - position);
+
+ const dropped: ListNode[] = [];
+
+ while (count--) {
+ const current = this.get(position);
+ dropped.push(this.detach(current!)!);
+ }
+
+ return dropped;
+ }
+
+ dropManyHead(count: Exclude): ListNode[] {
+ if (count <= 0) return [];
+
+ count = Math.min(count, this.size);
+
+ const dropped: ListNode[] = [];
+
+ while (count--) dropped.unshift(this.dropHead()!);
+
+ return dropped;
+ }
+
+ dropManyTail(count: Exclude): ListNode[] {
+ if (count <= 0) return [];
+
+ count = Math.min(count, this.size);
+
+ const dropped: ListNode[] = [];
+
+ while (count--) dropped.push(this.dropTail()!);
+
+ return dropped;
+ }
+
+ find(predicate: ListIteratorFn): ListNode | undefined {
+ for (let current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this)) return current;
}
return undefined;
}
- findIndex(predicate: ListIteratorFunction): number {
- for (let current = this.first, position = 0; current; position += 1, current = current.next) {
+ findIndex(predicate: ListIteratorFn): number {
+ for (let current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this)) return position;
}
return -1;
}
- forEach(callback: ListIteratorFunction) {
- for (let node = this.first, position = 0; node; position += 1, node = node.next) {
+ forEach(callback: ListIteratorFn) {
+ for (let node = this.first, position = 0; node; position++, node = node.next) {
callback(node, position, this);
}
}
@@ -227,7 +352,7 @@ export class LinkedList {
return this.find((_, index) => position === index);
}
- indexOf(value: T, compareFn = compare): number {
+ indexOf(value: T, compareFn: ListComparisonFn = compare): number {
return this.findIndex(node => compareFn(node.value, value));
}
@@ -239,20 +364,32 @@ export class LinkedList {
return array;
}
- toString(): string {
+ toNodeArray(): ListNode[] {
+ const array = new Array(this.size);
+
+ this.forEach((node, index) => (array[index!] = node));
+
+ return array;
+ }
+
+ toString(mapperFn: ListMapperFn = JSON.stringify): string {
return this.toArray()
- .map(value => JSON.stringify(value))
+ .map(value => mapperFn(value))
.join(' <-> ');
}
*[Symbol.iterator]() {
- for (let node = this.first, position = 0; node; position += 1, node = node.next) {
+ for (let node = this.first, position = 0; node; position++, node = node.next) {
yield node.value;
}
}
}
-export type ListIteratorFunction = (
+export type ListMapperFn = (value: T) => any;
+
+export type ListComparisonFn = (value1: T, value2: T) => boolean;
+
+export type ListIteratorFn = (
node: ListNode,
index?: number,
list?: LinkedList,
diff --git a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts
index 5f6c0eed6e..1020e60d4e 100644
--- a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts
+++ b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts
@@ -8,6 +8,8 @@ import { FeatureManagement } from '../models';
providedIn: 'root',
})
export class FeatureManagementService {
+ apiName = 'FeatureManagement';
+
constructor(private rest: RestService, private store: Store) {}
getFeatures(params: FeatureManagement.Provider): Observable {
@@ -16,7 +18,9 @@ export class FeatureManagementService {
url: '/api/abp/features',
params,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
updateFeatures({
@@ -30,6 +34,6 @@ export class FeatureManagementService {
body: { features },
params: { providerKey, providerName },
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
}
diff --git a/npm/ng-packs/packages/identity/src/lib/services/identity.service.ts b/npm/ng-packs/packages/identity/src/lib/services/identity.service.ts
index ae9ca3a921..51e88557fe 100644
--- a/npm/ng-packs/packages/identity/src/lib/services/identity.service.ts
+++ b/npm/ng-packs/packages/identity/src/lib/services/identity.service.ts
@@ -7,6 +7,8 @@ import { Identity } from '../models/identity';
providedIn: 'root',
})
export class IdentityService {
+ apiName = 'AbpIdentity';
+
constructor(private rest: RestService) {}
getRoles(params = {} as ABP.PageQueryParams): Observable {
@@ -16,7 +18,7 @@ export class IdentityService {
params,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
getAllRoles(): Observable {
@@ -25,7 +27,7 @@ export class IdentityService {
url: '/api/identity/roles/all',
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
getRoleById(id: string): Observable {
@@ -34,7 +36,7 @@ export class IdentityService {
url: `/api/identity/roles/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
deleteRole(id: string): Observable {
@@ -43,7 +45,7 @@ export class IdentityService {
url: `/api/identity/roles/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
createRole(body: Identity.RoleSaveRequest): Observable {
@@ -53,7 +55,9 @@ export class IdentityService {
body,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
updateRole(body: Identity.RoleItem): Observable {
@@ -66,7 +70,9 @@ export class IdentityService {
body,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
getUsers(params = {} as ABP.PageQueryParams): Observable {
@@ -76,7 +82,7 @@ export class IdentityService {
params,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
getUserById(id: string): Observable {
@@ -85,7 +91,7 @@ export class IdentityService {
url: `/api/identity/users/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
getUserRoles(id: string): Observable {
@@ -94,7 +100,7 @@ export class IdentityService {
url: `/api/identity/users/${id}/roles`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
deleteUser(id: string): Observable {
@@ -103,7 +109,7 @@ export class IdentityService {
url: `/api/identity/users/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
createUser(body: Identity.UserSaveRequest): Observable {
@@ -113,7 +119,9 @@ export class IdentityService {
body,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
updateUser(body: Identity.UserItem): Observable {
@@ -126,6 +134,8 @@ export class IdentityService {
body,
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
}
diff --git a/npm/ng-packs/packages/permission-management/src/lib/services/permission-management.service.ts b/npm/ng-packs/packages/permission-management/src/lib/services/permission-management.service.ts
index e7fdd98ce3..fa6433e952 100644
--- a/npm/ng-packs/packages/permission-management/src/lib/services/permission-management.service.ts
+++ b/npm/ng-packs/packages/permission-management/src/lib/services/permission-management.service.ts
@@ -7,16 +7,23 @@ import { PermissionManagement } from '../models/permission-management';
providedIn: 'root',
})
export class PermissionManagementService {
+ apiName = 'AbpPermissionManagement';
+
constructor(private rest: RestService) {}
- getPermissions(params: PermissionManagement.GrantedProvider): Observable {
+ getPermissions(
+ params: PermissionManagement.GrantedProvider,
+ ): Observable {
const request: Rest.Request = {
method: 'GET',
url: '/api/abp/permissions',
params,
};
- return this.rest.request(request);
+ return this.rest.request(
+ request,
+ { apiName: this.apiName },
+ );
}
updatePermissions({
@@ -31,6 +38,8 @@ export class PermissionManagementService {
params: { providerKey, providerName },
};
- return this.rest.request(request);
+ return this.rest.request(request, {
+ apiName: this.apiName,
+ });
}
}
diff --git a/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts b/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts
index 27ee26b7ed..8678da1332 100644
--- a/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts
+++ b/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts
@@ -7,6 +7,8 @@ import { TenantManagement } from '../models/tenant-management';
providedIn: 'root',
})
export class TenantManagementService {
+ apiName = 'AbpTenantManagement';
+
constructor(private rest: RestService) {}
getTenant(params = {} as ABP.PageQueryParams): Observable {
@@ -16,7 +18,7 @@ export class TenantManagementService {
params,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
getTenantById(id: string): Observable {
@@ -25,7 +27,7 @@ export class TenantManagementService {
url: `/api/multi-tenancy/tenants/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
deleteTenant(id: string): Observable {
@@ -34,7 +36,7 @@ export class TenantManagementService {
url: `/api/multi-tenancy/tenants/${id}`,
};
- return this.rest.request(request);
+ return this.rest.request(request, { apiName: this.apiName });
}
createTenant(body: TenantManagement.AddRequest): Observable {
@@ -44,7 +46,9 @@ export class TenantManagementService {
body,
};
- return this.rest.request(request);
+ return this.rest.request