From dc93296d6325c9d74b034cbb6472cde164ee2c32 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 23 Mar 2020 09:21:43 +0300 Subject: [PATCH 01/53] docs: add service-proxies document --- docs/en/UI/Angular/Config-State.md | 4 ++ docs/en/UI/Angular/Permission-Management.md | 2 +- docs/en/UI/Angular/Rest-Service.md | 3 + docs/en/UI/Angular/Service-Proxies.md | 67 ++++++++++++++++++ .../generated-files-via-generate-proxy.png | Bin 0 -> 240566 bytes docs/en/docs-nav.json | 4 ++ 6 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 docs/en/UI/Angular/Rest-Service.md create mode 100644 docs/en/UI/Angular/Service-Proxies.md create mode 100644 docs/en/UI/Angular/images/generated-files-via-generate-proxy.png diff --git a/docs/en/UI/Angular/Config-State.md b/docs/en/UI/Angular/Config-State.md index 72c8e6c6fd..7fc202982c 100644 --- a/docs/en/UI/Angular/Config-State.md +++ b/docs/en/UI/Angular/Config-State.md @@ -288,3 +288,7 @@ Note that **you do not have to call this method at application initiation**, bec #### Environment Properties Please refer to `Config.Environment` type for all the properties you can pass to `dispatchSetEnvironment` as parameter. It can be found in the [config.ts file](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L13). + +## What's Next? + +* [Component Replacement](./Component-Replacement.md) \ No newline at end of file diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md index 6e5c5d7155..ababd25e7f 100644 --- a/docs/en/UI/Angular/Permission-Management.md +++ b/docs/en/UI/Angular/Permission-Management.md @@ -76,4 +76,4 @@ Granted Policies are stored in the `auth` property of `ConfigState`. ## What's Next? -* [Component Replacement](./Component-Replacement.md) \ No newline at end of file +* [Config State](./Config-State.md) \ No newline at end of file diff --git a/docs/en/UI/Angular/Rest-Service.md b/docs/en/UI/Angular/Rest-Service.md new file mode 100644 index 0000000000..d817cab3c6 --- /dev/null +++ b/docs/en/UI/Angular/Rest-Service.md @@ -0,0 +1,3 @@ +## Rest Service + +TODO \ No newline at end of file diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md new file mode 100644 index 0000000000..56d640ec54 --- /dev/null +++ b/docs/en/UI/Angular/Service-Proxies.md @@ -0,0 +1,67 @@ +## Service Proxies + +It is common to call a REST endpoint in the server from our Angular applications. In this case, we generally create **services** (those have methods for each service method on the server side) and **model objects** (matches to [DTOs](../../Data-Transfer-Objects) in the server side). + +In addition to manually creating such server-interacting services, we could use tools like [NSWAG](https://github.com/RicoSuter/NSwag) to generate service proxies for us. But NSWAG has the following problems we've experienced: + +* It generates a **big, single** .ts file which has some problems; + * It get **too large** when your application grows. + * It doesn't fit into the **[modular](../../Module-Development-Basics) approach** of the ABP framework. +* It creates a bit **ugly code**. We want to have a clean code (just like if we write manually). +* It can not generate the same **method signature** declared in the server side (because swagger.json doesn't exactly reflect the method signature of the backend service). We've created an endpoint that exposes server side method contacts to allow clients generate a better aligned client proxies. + +ABP CLI `generate-proxies` command automatically generates the typescript client proxies by creating folders which separated by module names in the `src/app` folder. +Run the following command in the **root folder** of the angular application: + +```bash +abp generate-proxy +``` + +It only creates proxies only for your own application's services. It doesn't create proxies for the services of the application modules you're using (by default). There are several options. See the [CLI documentation](../../CLI). + +The files generated with the `--module all` option like below: + +![generated-files-via-generate-proxy](./images/generated-files-via-generate-proxy.png) + +### Services + +Each generated service matches a back-end controller. The services methods call back-end APIs via [RestService](./Rest-Service.md). + + + +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: + +```js +import { AbpApplicationConfigurationService } from '../app/shared/services'; + +//... +export class HomeComponent{ + constructor(private appConfigService: AbpApplicationConfigurationService) {} + + ngOnInit() { + this.appConfigService.get().subscribe() + } +} +``` + +The Angular compiler removes the services that have not been injected anywhere from the final output. See the [tree-shakable providers documentation](https://angular.io/guide/dependency-injection-providers#tree-shakable-providers). + +### Models + +The generated models match the DTOs in the back-end. Each model is generated as a class under the `src/app/*/shared/models` folder. + +There are a few [base classes](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/dtos.ts) in the `@abp/ng.core` package. Some models extend these classes. + +A class instance can be created as shown below: + +```js +import { IdentityRoleCreateDto } from '../identity/shared/models'; +//... +const instance = new IdentityRoleCreateDto({name: 'Role 1', isDefault: false, isPublic: true}) +``` + +Initial values ​​can optionally be passed to each class constructor. + +## What's Next? + +* [Localization](./Localization.md) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png b/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..77a120a35ddda488b21f575917e7e704ee58b83b GIT binary patch literal 240566 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%0A|x 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%0DB4diPpnh7Tg|E|$rrh!1Im5<36#++7o|kKq-W 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

s%n+a76Wa=Pzhl>ePyT5UAtf=yk2bVSo2A|b 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 i0fT@+z#uRK5cvP!R=^hNR7^?$0000 Date: Tue, 24 Mar 2020 09:53:44 +0300 Subject: [PATCH 02/53] docs: remove rest-service.md and updated the service proxies documentation --- docs/en/UI/Angular/Rest-Service.md | 3 --- docs/en/UI/Angular/Service-Proxies.md | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 docs/en/UI/Angular/Rest-Service.md diff --git a/docs/en/UI/Angular/Rest-Service.md b/docs/en/UI/Angular/Rest-Service.md deleted file mode 100644 index d817cab3c6..0000000000 --- a/docs/en/UI/Angular/Rest-Service.md +++ /dev/null @@ -1,3 +0,0 @@ -## Rest Service - -TODO \ No newline at end of file diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md index 56d640ec54..b1cd9ad500 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](./Rest-Service.md). +Each generated service matches a back-end controller. The services methods call back-end APIs via [RestService](./HTTP-Requests.md#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) 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? -* [Localization](./Localization.md) \ No newline at end of file +* [Http Requests](./Http-Requests.md) \ No newline at end of file From 6b07a3a8375da22ceb03c889a65c415762ee5882 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 26 Mar 2020 11:52:43 +0300 Subject: [PATCH 03/53] refactor(core): add fallback api to getApiUrl selector --- npm/ng-packs/packages/core/src/lib/states/config.state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8ce206dd76..91bcc5d914 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; From 191d2baa52be49af60b5515618225cd49a9bbfc3 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 26 Mar 2020 11:53:39 +0300 Subject: [PATCH 04/53] feat: add apiName variables to some services --- .../src/lib/services/account.service.ts | 9 +++-- .../application-configuration.service.ts | 12 +++++-- .../core/src/lib/services/profile.service.ts | 18 +++++++--- .../services/feature-management.service.ts | 8 +++-- .../src/lib/services/identity.service.ts | 34 ++++++++++++------- .../services/permission-management.service.ts | 15 ++++++-- .../lib/services/tenant-management.service.ts | 28 ++++++++++----- 7 files changed, 91 insertions(+), 33 deletions(-) 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/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/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(request, { + apiName: this.apiName, + }); } updateTenant(body: TenantManagement.UpdateRequest): Observable { @@ -57,7 +61,9 @@ export class TenantManagementService { body, }; - return this.rest.request(request); + return this.rest.request(request, { + apiName: this.apiName, + }); } getDefaultConnectionString(id: string): Observable { @@ -68,7 +74,9 @@ export class TenantManagementService { responseType: Rest.ResponseType.Text, url, }; - return this.rest.request(request); + return this.rest.request(request, { + apiName: this.apiName, + }); } updateDefaultConnectionString( @@ -81,7 +89,9 @@ export class TenantManagementService { url, params: { defaultConnectionString: payload.defaultConnectionString }, }; - return this.rest.request(request); + return this.rest.request(request, { + apiName: this.apiName, + }); } deleteDefaultConnectionString(id: string): Observable { @@ -91,6 +101,8 @@ export class TenantManagementService { method: 'DELETE', url, }; - return this.rest.request(request); + return this.rest.request(request, { + apiName: this.apiName, + }); } } From d0956a0a241e01520f01115b464620877ae834cc Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Thu, 26 Mar 2020 18:25:16 +0300 Subject: [PATCH 05/53] Update en.json --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index cb79af1665..2a27cce735 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -86,6 +86,11 @@ "AreYouSureYouWantToDeleteAllComputers": "Are you sure you want to delete all computers?", "DeleteAll": "Delete all", "DoYouWantToCreateNewUser": "Do you want to create new user?", - "MasterModules": "Master Modules" + "MasterModules": "Master Modules", + "OrganizationName": "Organization name", + "OrganizationNamePlaceholder": "Organization name...", + "UsernameOrEmail": "Username or email", + "UsernameOrEmailPlaceholder": "Username or email...", + "Member": "Member" } } \ No newline at end of file From 4d93244f06b3f54c3c700b7439ce1ddadf3b4dc9 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 26 Mar 2020 19:06:27 +0300 Subject: [PATCH 06/53] feat(core): add methods to LinkedList for adding and dropping multiple nodes --- .../core/src/lib/tests/linked-list.spec.ts | 870 ++++++++++++++++-- .../core/src/lib/utils/linked-list.ts | 257 ++++-- 2 files changed, 997 insertions(+), 130 deletions(-) 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, From 7a22f1a4f24bf1f098723c3c896d177e0d4e4cf9 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 26 Mar 2020 20:08:54 +0300 Subject: [PATCH 07/53] docs(core): add how to add and drop multiple values in LinkedList --- docs/en/UI/Angular/Linked-List.md | 628 +++++++++++++++++++++++++----- 1 file changed, 534 insertions(+), 94 deletions(-) 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' +*/ +``` + + + From 73911d7854647d096a5f9a2d1b708038c96ca7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 26 Mar 2020 22:15:25 +0300 Subject: [PATCH 08/53] Added Getting-Started-With-Startup-Templates.md updated links. --- docs/en/Getting-Started-With-Startup-Templates.md | 6 ++++++ docs/en/Startup-Templates/Application.md | 15 +++++++++------ docs/en/docs-nav.json | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 docs/en/Getting-Started-With-Startup-Templates.md diff --git a/docs/en/Getting-Started-With-Startup-Templates.md b/docs/en/Getting-Started-With-Startup-Templates.md new file mode 100644 index 0000000000..19442ec81e --- /dev/null +++ b/docs/en/Getting-Started-With-Startup-Templates.md @@ -0,0 +1,6 @@ +# Getting Started with the Startup Templates + +See the following tutorials to learn how to get started with the ABP Framework using the pre-built application startup templates: + +* [Getting Started With the ASP.NET Core MVC / Razor Pages UI](Getting-Started-AspNetCore-MVC-Template.md) +* [Getting Started with the Angular UI](Getting-Started-Angular-Template.md) \ No newline at end of file diff --git a/docs/en/Startup-Templates/Application.md b/docs/en/Startup-Templates/Application.md index 3a5c6c3bb2..8298c01f1b 100644 --- a/docs/en/Startup-Templates/Application.md +++ b/docs/en/Startup-Templates/Application.md @@ -2,11 +2,12 @@ ## Introduction -This template provides a layered application structure based on the [Domain Driven Design](../Domain-Driven-Design.md) (DDD) practices. This document explains the solution structure and projects in details. If you want to start quickly, follow the guides below: +This template provides a layered application structure based on the [Domain Driven Design](../Domain-Driven-Design.md) (DDD) practices. -* See [Getting Started With the ASP.NET Core MVC Template](../Getting-Started-AspNetCore-MVC-Template.md) to create a new solution and run it for this template (uses MVC as the UI framework and Entity Framework Core as the database provider). -* See the [ASP.NET Core MVC Application Development Tutorial](../Tutorials/Part-1.md?UI=MVC) to learn how to develop applications using this template (uses MVC as the UI framework and Entity Framework Core as the database provider). -* See the [Angular Application Development Tutorial](../Tutorials/Part-1.md?UI=NG) to learn how to develop applications using this template (uses Angular as the UI framework and MongoDB as the database provider). +This document explains **the solution structure** and projects in details. If you want to start quickly, follow the guides below: + +* [The getting started document](../Getting-Started-With-Startup-Templates.md) explains how to create a new application in a few minutes. +* [The application development tutorial](../Tutorials/Part-1) explains step by step application development. ## How to Start With? @@ -123,6 +124,8 @@ Notice that the migration `DbContext` is only used for database migrations and * * Depends on the `.EntityFrameworkCore` project since it re-uses the configuration defined for the `DbContext` of the application. > This project is available only if you are using EF Core as the database provider. +> +> See the [Entity Framework Core Migrations Guide](../Entity-Framework-Core-Migrations.md) to understand this project in details. #### .DbMigrator Project @@ -269,5 +272,5 @@ The files under the `angular/src/environments` folder has the essential configur ## What's Next? -- See [Getting Started With the ASP.NET Core MVC Template](../Getting-Started-AspNetCore-MVC-Template.md) to create a new solution and run it for this template. -- See the [ASP.NET Core MVC Tutorial](../Tutorials/Part-1.md) to learn how to develop applications using this template. +- [The getting started document](../Getting-Started-With-Startup-Templates.md) explains how to create a new application in a few minutes. +- [The application development tutorial](../Tutorials/Part-1) explains step by step application development. diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index c273e59346..71641bf2a8 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -5,6 +5,7 @@ "items": [ { "text": "From Startup Templates", + "path": "Getting-Started-With-Startup-Templates.md" "items": [ { "text": "Application with MVC (Razor Pages) UI", From c4c4cfadccc27dadac817b9d0e96a0df4f6c0cc6 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 07:29:52 +0300 Subject: [PATCH 09/53] fix: fix lint error --- npm/ng-packs/packages/core/src/lib/states/config.state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..74e9ee8cd0 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 @@ -301,7 +301,7 @@ export class ConfigState { } @Action(SetEnvironment) - setEnvironment({ patchState }: StateContext, { environment }:SetEnvironment) { + setEnvironment({ patchState }: StateContext, { environment }: SetEnvironment) { return patchState({ environment, }); From 0a17d721b96d39e8f37819afa4a343459cf1c37d Mon Sep 17 00:00:00 2001 From: Mehmet Erim <34455572+mehmet-erim@users.noreply.github.com> Date: Fri, 27 Mar 2020 07:53:39 +0300 Subject: [PATCH 10/53] Update Service-Proxies.md --- docs/en/UI/Angular/Service-Proxies.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md index b1cd9ad500..97b43b7513 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.md#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.md#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.md) From aab32ad8c5dc6c968f42f4e6ee57953f68eec5a8 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 09:10:45 +0300 Subject: [PATCH 11/53] chore: set dev-app as default project --- npm/ng-packs/angular.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" } From 83645730b9bc38eae238861c9432acb05518189f Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 09:16:45 +0300 Subject: [PATCH 12/53] refactor: deprecate the requirements obj --- .../apps/dev-app/src/app/app.module.ts | 3 -- .../packages/core/src/lib/models/common.ts | 6 ++- templates/app/angular/src/app/app.module.ts | 6 +-- .../module/angular/src/app/app.module.ts | 46 +++++++++---------- 4 files changed, 27 insertions(+), 34 deletions(-) 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/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/templates/app/angular/src/app/app.module.ts b/templates/app/angular/src/app/app.module.ts index 5df354fb38..928dff5172 100644 --- a/templates/app/angular/src/app/app.module.ts +++ b/templates/app/angular/src/app/app.module.ts @@ -3,7 +3,6 @@ import { CoreModule } from '@abp/ng.core'; import { IdentityConfigModule } from '@abp/ng.identity.config'; import { SettingManagementConfigModule } from '@abp/ng.setting-management.config'; import { TenantManagementConfigModule } from '@abp/ng.tenant-management.config'; -import { LAYOUTS } from '@abp/ng.theme.basic'; import { ThemeSharedModule } from '@abp/ng.theme.shared'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -20,10 +19,7 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; @NgModule({ imports: [ CoreModule.forRoot({ - environment, - requirements: { - layouts: LAYOUTS - } + environment }), ThemeSharedModule.forRoot(), AccountConfigModule.forRoot({ redirectUrl: '/' }), diff --git a/templates/module/angular/src/app/app.module.ts b/templates/module/angular/src/app/app.module.ts index c0fef36c9a..2705a3318b 100644 --- a/templates/module/angular/src/app/app.module.ts +++ b/templates/module/angular/src/app/app.module.ts @@ -1,21 +1,20 @@ -import { AccountConfigModule } from '@abp/ng.account.config'; -import { CoreModule } from '@abp/ng.core'; -import { IdentityConfigModule } from '@abp/ng.identity.config'; -import { SettingManagementConfigModule } from '@abp/ng.setting-management.config'; -import { TenantManagementConfigModule } from '@abp/ng.tenant-management.config'; -import { LAYOUTS } from '@abp/ng.theme.basic'; -import { ThemeSharedModule } from '@abp/ng.theme.shared'; -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin'; -import { NgxsModule } from '@ngxs/store'; -import { OAuthModule } from 'angular-oauth2-oidc'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { SharedModule } from './shared/shared.module'; -import { MyProjectNameConfigModule } from '../../projects/my-project-name-config/src/public-api'; +import { AccountConfigModule } from "@abp/ng.account.config"; +import { CoreModule } from "@abp/ng.core"; +import { IdentityConfigModule } from "@abp/ng.identity.config"; +import { SettingManagementConfigModule } from "@abp/ng.setting-management.config"; +import { TenantManagementConfigModule } from "@abp/ng.tenant-management.config"; +import { ThemeSharedModule } from "@abp/ng.theme.shared"; +import { NgModule } from "@angular/core"; +import { BrowserModule } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { NgxsLoggerPluginModule } from "@ngxs/logger-plugin"; +import { NgxsModule } from "@ngxs/store"; +import { OAuthModule } from "angular-oauth2-oidc"; +import { environment } from "../environments/environment"; +import { AppRoutingModule } from "./app-routing.module"; +import { AppComponent } from "./app.component"; +import { SharedModule } from "./shared/shared.module"; +import { MyProjectNameConfigModule } from "../../projects/my-project-name-config/src/public-api"; const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; @@ -24,14 +23,11 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; imports: [ ThemeSharedModule.forRoot(), CoreModule.forRoot({ - environment, - requirements: { - layouts: LAYOUTS, - }, + environment }), OAuthModule.forRoot(), NgxsModule.forRoot([]), - AccountConfigModule.forRoot({ redirectUrl: '/' }), + AccountConfigModule.forRoot({ redirectUrl: "/" }), IdentityConfigModule, TenantManagementConfigModule, SettingManagementConfigModule, @@ -41,8 +37,8 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; AppRoutingModule, SharedModule, - ...(environment.production ? [] : LOGGERS), + ...(environment.production ? [] : LOGGERS) ], - bootstrap: [AppComponent], + bootstrap: [AppComponent] }) export class AppModule {} From 97c3a6fce04210fdadfb526ce83c4e7ab7e1a59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20=C3=87A=C4=9EDA=C5=9E?= Date: Fri, 27 Mar 2020 10:02:49 +0300 Subject: [PATCH 13/53] added missing comma to docs-nav.json --- docs/en/docs-nav.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 71641bf2a8..d46e16bfe5 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", From 4ad19ebf84a7af0d68dcd9968bf13e510c6b77ee Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 10:21:56 +0300 Subject: [PATCH 14/53] feat(theme-basic): add layouts to replaceable components state --- .../src/lib/services/initial.service.ts | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts b/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts index 33c7c18770..21fb1756bc 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts @@ -1,12 +1,29 @@ +import { LazyLoadService, AddReplaceableComponent } from '@abp/ng.core'; import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; -import { LazyLoadService } from '@abp/ng.core'; +import { Store } from '@ngxs/store'; import styles from '../constants/styles'; +import { ApplicationLayoutComponent } from '../components/application-layout/application-layout.component'; +import { AccountLayoutComponent } from '../components/account-layout/account-layout.component'; +import { EmptyLayoutComponent } from '../components/empty-layout/empty-layout.component'; @Injectable({ providedIn: 'root' }) export class InitialService { - constructor(private lazyLoadService: LazyLoadService) { + constructor(private lazyLoadService: LazyLoadService, private store: Store) { this.appendStyle().subscribe(); + this.store.dispatch([ + new AddReplaceableComponent({ + key: 'Theme.ApplicationLayoutComponent', + component: ApplicationLayoutComponent, + }), + new AddReplaceableComponent({ + key: 'Theme.AccountLayoutComponent', + component: AccountLayoutComponent, + }), + new AddReplaceableComponent({ + key: 'Theme.EmptyLayoutComponent', + component: EmptyLayoutComponent, + }), + ]); } appendStyle() { From 857ee6b9ef82376c42229c613764feaee7896a95 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 10:22:45 +0300 Subject: [PATCH 15/53] feat(core): get layouts from store in dynamic-layout.component --- .../components/dynamic-layout.component.ts | 49 +++++---- .../tests/dynamic-layout.component.spec.ts | 102 +++++++++++------- 2 files changed, 93 insertions(+), 58 deletions(-) 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..fc3926a1ea 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,13 +1,15 @@ import { Component, Input, OnDestroy, Type, Injector } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router'; import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; +import { Observable, combineLatest } from 'rxjs'; import snq from 'snq'; import { eLayoutType } from '../enums/common'; import { Config } from '../models/config'; import { ABP } from '../models/common'; import { ConfigState } from '../states/config.state'; import { takeUntilDestroy } from '../utils/rxjs-utils'; +import { ReplaceableComponentsState } from '../states/replaceable-components.state'; +import { ReplaceableComponents } from '../models/replaceable-components'; @Component({ selector: 'abp-dynamic-layout', @@ -20,24 +22,24 @@ import { takeUntilDestroy } from '../utils/rxjs-utils'; `, }) export class DynamicLayoutComponent implements OnDestroy { - @Select(ConfigState.getOne('requirements')) requirements$: Observable; + @Select(ReplaceableComponentsState.getComponent('Theme.ApplicationLayoutComponent')) + applicationLayout$: Observable; + + @Select(ReplaceableComponentsState.getComponent('Theme.AccountLayoutComponent')) + accountLayout$: Observable; + + @Select(ReplaceableComponentsState.getComponent('Theme.EmptyLayoutComponent')) + emptyLayout$: Observable; layout: Type; + layouts = {} as { [key in eLayoutType]: Type }; + + expectedLayout: eLayoutType = eLayoutType.empty; + 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, - ); - } + this.listenToLayouts(); + const { routes } = this.store.selectSnapshot(ConfigState.getAll); router.events.pipe(takeUntilDestroy(this)).subscribe(event => { if (event instanceof NavigationEnd) { @@ -45,16 +47,25 @@ export class DynamicLayoutComponent implements OnDestroy { { path: router.url.replace('/', '') }, ] as any); - const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes); + this.expectedLayout = + (this.route.snapshot.data || {}).layout || findLayout(segments, routes); - this.layout = layouts - .filter(l => !!l) - .find((l: any) => snq(() => l.type.toLowerCase().indexOf(layout), -1) > -1); + this.layout = this.layouts[this.expectedLayout]; } }); } ngOnDestroy() {} + + listenToLayouts() { + combineLatest(this.applicationLayout$, this.accountLayout$, this.emptyLayout$) + .pipe(takeUntilDestroy(this)) + .subscribe(([application, account, empty]) => { + this.layouts.application = application.component; + this.layouts.account = account.component; + this.layouts.empty = empty.component; + }); + } } function findLayout(segments: UrlSegment[], routes: ABP.FullRoute[]): eLayoutType { 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(); From 84890bb91958cc4666a23ef559c62757cb8c9442 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 27 Mar 2020 11:58:12 +0300 Subject: [PATCH 16/53] #closes 3381 --- .../Controllers/HomeController.cs | 7 + .../docs/app/VoloDocs.Web/Pages/Index.cshtml | 5 - .../app/VoloDocs.Web/Pages/Index.cshtml.cs | 29 - .../docs/app/VoloDocs.Web/package-lock.json | 2796 +++++++++++------ modules/docs/app/VoloDocs.Web/package.json | 2 +- .../Documents/DocumentAdminAppService.cs | 12 +- .../Volo/Docs/Documents/DocumentAppService.cs | 20 +- .../Volo/Docs/DocsDomainConsts.cs | 7 + .../Documents/FileSystemDocumentSource.cs | 15 +- .../GitHub/Documents/GithubDocumentSource.cs | 15 +- .../Extensions/NewtonsoftJsonExtensions.cs | 22 + .../ScribanDocumentSectionRenderer.cs | 109 +- .../src/Volo.Docs.Web/Volo.Docs.Web.csproj | 1 + 13 files changed, 2068 insertions(+), 972 deletions(-) delete mode 100644 modules/docs/app/VoloDocs.Web/Pages/Index.cshtml delete mode 100644 modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs create mode 100644 modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainConsts.cs create mode 100644 modules/docs/src/Volo.Docs.Domain/Volo/Extensions/NewtonsoftJsonExtensions.cs diff --git a/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs b/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs index 5594306229..17c6550502 100644 --- a/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs +++ b/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs @@ -6,7 +6,14 @@ namespace VoloDocs.Web.Controllers { public void Index() { + //if (!_urlUiOptions.RoutePrefix.IsNullOrWhiteSpace()) + //{ + // return Redirect("." + _urlUiOptions.RoutePrefix); + //} + //return Page(); + + //return Redirect("/en/abp/latest"); } } } diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml deleted file mode 100644 index 0d75012326..0000000000 --- a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml +++ /dev/null @@ -1,5 +0,0 @@ -@page -@model VoloDocs.Web.Pages.IndexModel -@{ -} - diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs deleted file mode 100644 index b127db4b3f..0000000000 --- a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Options; -using Volo.Docs; - -namespace VoloDocs.Web.Pages -{ - public class IndexModel : PageModel - { - private readonly DocsUiOptions _urlUiOptions; - - public IndexModel(IOptions urlOptions) - { - _urlUiOptions = urlOptions.Value; - } - - public IActionResult OnGet() - { - //TODO: Create HomeController & Index instead of Page. Otherwise, we have an empty Index.cshtml file. - if (!_urlUiOptions.RoutePrefix.IsNullOrWhiteSpace()) - { - return Redirect("." + _urlUiOptions.RoutePrefix); - } - - return Page(); - } - } -} \ 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/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 @@ + From 5c541897808bd96f08a21beac8247b2dbfe61587 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 27 Mar 2020 12:34:18 +0300 Subject: [PATCH 17/53] add home page #3381 --- .../Controllers/HomeController.cs | 19 ------ .../docs/app/VoloDocs.Web/Pages/Index.cshtml | 23 ++++++++ .../app/VoloDocs.Web/Pages/Index.cshtml.cs | 59 +++++++++++++++++++ 3 files changed, 82 insertions(+), 19 deletions(-) delete mode 100644 modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs create mode 100644 modules/docs/app/VoloDocs.Web/Pages/Index.cshtml create mode 100644 modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs 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 17c6550502..0000000000 --- a/modules/docs/app/VoloDocs.Web/Controllers/HomeController.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Volo.Abp.AspNetCore.Mvc; - -namespace VoloDocs.Web.Controllers -{ - public class HomeController : AbpController - { - public void Index() - { - //if (!_urlUiOptions.RoutePrefix.IsNullOrWhiteSpace()) - //{ - // return Redirect("." + _urlUiOptions.RoutePrefix); - //} - - //return Page(); - - //return Redirect("/en/abp/latest"); - } - } -} diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml new file mode 100644 index 0000000000..0a212f1499 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml @@ -0,0 +1,23 @@ +@page +@model VoloDocs.Web.Pages.IndexModel +@{ +} + +@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 new file mode 100644 index 0000000000..537d650f83 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs @@ -0,0 +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; + + private readonly IProjectAppService _projectAppService; + + public IndexModel(IOptions urlOptions, IProjectAppService projectAppService) + { + _projectAppService = projectAppService; + _urlUiOptions = urlOptions.Value; + } + + public async Task OnGetAsync() + { + var projects = await _projectAppService.GetListAsync(); + + if (projects.Items.Count == 1) + { + 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); + } + } +} From e08290b1c5ac4456c21c6cb6760427d50579a0a3 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 13:52:01 +0300 Subject: [PATCH 18/53] docs: add how to replace a layout section to component-replacement.md --- docs/en/UI/Angular/Component-Replacement.md | 53 +++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) 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 { ![Example Usage](./images/component-replacement.gif) -## 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 | | -------------------------------------------------- | --------------------------------------------- | From 0ccce0bbf999b95ff224e8c8ca78046c937bf0c5 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 13:52:17 +0300 Subject: [PATCH 19/53] docs: fix the links --- docs/en/UI/Angular/Service-Proxies.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md index 97b43b7513..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.md#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) +* [HTTP Requests](./Http-Requests) From 8d71b74281dd6fac4279970d14c47806c86e50ba Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 27 Mar 2020 14:31:09 +0300 Subject: [PATCH 20/53] style: add prettierrc and rules matching other angular projects --- templates/module/angular/.prettierrc | 5 +++ .../module/angular/src/app/app.module.ts | 42 +++++++++---------- 2 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 templates/module/angular/.prettierrc diff --git a/templates/module/angular/.prettierrc b/templates/module/angular/.prettierrc new file mode 100644 index 0000000000..5e2863a11f --- /dev/null +++ b/templates/module/angular/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/templates/module/angular/src/app/app.module.ts b/templates/module/angular/src/app/app.module.ts index 2705a3318b..93e09321ec 100644 --- a/templates/module/angular/src/app/app.module.ts +++ b/templates/module/angular/src/app/app.module.ts @@ -1,20 +1,20 @@ -import { AccountConfigModule } from "@abp/ng.account.config"; -import { CoreModule } from "@abp/ng.core"; -import { IdentityConfigModule } from "@abp/ng.identity.config"; -import { SettingManagementConfigModule } from "@abp/ng.setting-management.config"; -import { TenantManagementConfigModule } from "@abp/ng.tenant-management.config"; -import { ThemeSharedModule } from "@abp/ng.theme.shared"; -import { NgModule } from "@angular/core"; -import { BrowserModule } from "@angular/platform-browser"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { NgxsLoggerPluginModule } from "@ngxs/logger-plugin"; -import { NgxsModule } from "@ngxs/store"; -import { OAuthModule } from "angular-oauth2-oidc"; -import { environment } from "../environments/environment"; -import { AppRoutingModule } from "./app-routing.module"; -import { AppComponent } from "./app.component"; -import { SharedModule } from "./shared/shared.module"; -import { MyProjectNameConfigModule } from "../../projects/my-project-name-config/src/public-api"; +import { AccountConfigModule } from '@abp/ng.account.config'; +import { CoreModule } from '@abp/ng.core'; +import { IdentityConfigModule } from '@abp/ng.identity.config'; +import { SettingManagementConfigModule } from '@abp/ng.setting-management.config'; +import { TenantManagementConfigModule } from '@abp/ng.tenant-management.config'; +import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin'; +import { NgxsModule } from '@ngxs/store'; +import { OAuthModule } from 'angular-oauth2-oidc'; +import { MyProjectNameConfigModule } from '../../projects/my-project-name-config/src/public-api'; +import { environment } from '../environments/environment'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { SharedModule } from './shared/shared.module'; const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; @@ -23,11 +23,11 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; imports: [ ThemeSharedModule.forRoot(), CoreModule.forRoot({ - environment + environment, }), OAuthModule.forRoot(), NgxsModule.forRoot([]), - AccountConfigModule.forRoot({ redirectUrl: "/" }), + AccountConfigModule.forRoot({ redirectUrl: '/' }), IdentityConfigModule, TenantManagementConfigModule, SettingManagementConfigModule, @@ -37,8 +37,8 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; AppRoutingModule, SharedModule, - ...(environment.production ? [] : LOGGERS) + ...(environment.production ? [] : LOGGERS), ], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) export class AppModule {} From d72aada3b5bcfe05e9c33f60e1658d83c740bf9f Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 27 Mar 2020 15:02:18 +0300 Subject: [PATCH 21/53] refactor GithubRepositoryManager #3381 --- .../Documents/GithubRepositoryManager.cs | 68 +++++++++---------- 1 file changed, 32 insertions(+), 36 deletions(-) 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..754263989f 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,30 @@ 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))); + var client = GetGitHubClient(name, token); + + var releases = await client.Repository.Release.GetAll(name, repositoryName); - return (await client - .Repository - .Release - .GetAll(name, repositoryName)).ToList(); + return releases.ToList(); } 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 +54,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))); + } } } From bb226783c5bda77bb08af71e65de49f73b77f466 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 27 Mar 2020 15:03:22 +0300 Subject: [PATCH 22/53] #3381 --- .../Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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 754263989f..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 @@ -24,24 +24,19 @@ namespace Volo.Docs.GitHub.Documents public async Task GetFileRawStringContentAsync(string rawUrl, string token, string userAgent) { using var httpClient = CreateHttpClient(token, userAgent); - return await httpClient.GetStringAsync(new Uri(rawUrl)); } public async Task GetFileRawByteArrayContentAsync(string rawUrl, string token, string 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 = GetGitHubClient(name, token); - - var releases = await client.Repository.Release.GetAll(name, repositoryName); - - return releases.ToList(); + return await client.Repository.Release.GetAll(name, repositoryName); } public async Task> GetFileCommitsAsync(string name, string repositoryName, string version, string filename, string token) From 2f7e69e1a27f2dc1732e4a55ef98d752b6f86f20 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 15:06:07 +0300 Subject: [PATCH 23/53] refactor: reduce codes and increase readability --- .../components/dynamic-layout.component.ts | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) 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 fc3926a1ea..e835dd777d 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,15 +1,13 @@ -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, combineLatest } 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 { takeUntilDestroy } from '../utils/rxjs-utils'; import { ReplaceableComponentsState } from '../states/replaceable-components.state'; -import { ReplaceableComponents } from '../models/replaceable-components'; +import { takeUntilDestroy } from '../utils/rxjs-utils'; @Component({ selector: 'abp-dynamic-layout', @@ -22,23 +20,9 @@ import { ReplaceableComponents } from '../models/replaceable-components'; `, }) export class DynamicLayoutComponent implements OnDestroy { - @Select(ReplaceableComponentsState.getComponent('Theme.ApplicationLayoutComponent')) - applicationLayout$: Observable; - - @Select(ReplaceableComponentsState.getComponent('Theme.AccountLayoutComponent')) - accountLayout$: Observable; - - @Select(ReplaceableComponentsState.getComponent('Theme.EmptyLayoutComponent')) - emptyLayout$: Observable; - layout: Type; - layouts = {} as { [key in eLayoutType]: Type }; - - expectedLayout: eLayoutType = eLayoutType.empty; - constructor(private router: Router, private route: ActivatedRoute, private store: Store) { - this.listenToLayouts(); const { routes } = this.store.selectSnapshot(ConfigState.getAll); router.events.pipe(takeUntilDestroy(this)).subscribe(event => { @@ -47,25 +31,25 @@ export class DynamicLayoutComponent implements OnDestroy { { path: router.url.replace('/', '') }, ] as any); - this.expectedLayout = + const layouts = { + application: this.getComponent('Theme.ApplicationLayoutComponent'), + account: this.getComponent('Theme.AccountLayoutComponent'), + empty: this.getComponent('Theme.EmptyApplicationLayoutComponent'), + }; + + const expectedLayout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes); - this.layout = this.layouts[this.expectedLayout]; + this.layout = layouts[expectedLayout].component; } }); } - ngOnDestroy() {} - - listenToLayouts() { - combineLatest(this.applicationLayout$, this.accountLayout$, this.emptyLayout$) - .pipe(takeUntilDestroy(this)) - .subscribe(([application, account, empty]) => { - this.layouts.application = application.component; - this.layouts.account = account.component; - this.layouts.empty = empty.component; - }); + getComponent(key: string): ReplaceableComponents.ReplaceableComponent { + return this.store.selectSnapshot(ReplaceableComponentsState.getComponent(key)); } + + ngOnDestroy() {} } function findLayout(segments: UrlSegment[], routes: ABP.FullRoute[]): eLayoutType { From 91668b35f423dcca63be06f972e23a8a9e6bfb22 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 15:14:00 +0300 Subject: [PATCH 24/53] =?UTF-8?q?refactor(core):=20make=20getComponent=20m?= =?UTF-8?q?ethod=20in=20DynamicCompo=C4=B1nent=20private?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/src/lib/components/dynamic-layout.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e835dd777d..71dd0f3fdf 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 @@ -45,7 +45,7 @@ export class DynamicLayoutComponent implements OnDestroy { }); } - getComponent(key: string): ReplaceableComponents.ReplaceableComponent { + private getComponent(key: string): ReplaceableComponents.ReplaceableComponent { return this.store.selectSnapshot(ReplaceableComponentsState.getComponent(key)); } From 1f2418b8721e0d991f2289bc4c57ca666de14c60 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 27 Mar 2020 15:48:37 +0300 Subject: [PATCH 25/53] fix(core): fix component key in dynamic layout --- .../core/src/lib/components/dynamic-layout.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 71dd0f3fdf..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 @@ -34,7 +34,7 @@ export class DynamicLayoutComponent implements OnDestroy { const layouts = { application: this.getComponent('Theme.ApplicationLayoutComponent'), account: this.getComponent('Theme.AccountLayoutComponent'), - empty: this.getComponent('Theme.EmptyApplicationLayoutComponent'), + empty: this.getComponent('Theme.EmptyLayoutComponent'), }; const expectedLayout = From 6239fcd585958de01da89725d3d3cbc9b244ef5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arma=C4=9Fan=20=C3=9Cnl=C3=BC?= <36102404+armgnunlu@users.noreply.github.com> Date: Fri, 27 Mar 2020 17:40:04 +0300 Subject: [PATCH 26/53] Resolved #3238 --- .../Pages/Documents/Project/Index.cshtml | 31 +- .../Pages/Documents/Search.cshtml | 88 +++-- .../Pages/Documents/Shared/Styles/vs.css | 240 ++++++------ .../Pages/Documents/Shared/Styles/vs.min.css | 2 +- .../Pages/Documents/Shared/Styles/vs.scss | 349 ++++++++++-------- 5 files changed, 384 insertions(+), 326 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 67e5352e22..6fcf402d70 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -68,7 +68,7 @@ }
-