@mdbase-dev/connect 0.1.0-beta.31 → 0.1.0-beta.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -34
- package/dist/advanced.d.ts +9 -0
- package/dist/advanced.js +6 -0
- package/dist/application-session.d.ts +39 -14
- package/dist/application-session.js +201 -70
- package/dist/async.js +11 -5
- package/dist/authority-proof.d.ts +3 -0
- package/dist/authority-proof.js +24 -0
- package/dist/browser/integrity.json +1 -1
- package/dist/browser/mdbase-connect.min.js +3 -3
- package/dist/browser/mdbase-connect.min.js.sha384 +1 -1
- package/dist/browser.d.ts +3 -0
- package/dist/browser.js +5 -0
- package/dist/capabilities.js +2 -1
- package/dist/collection-client.d.ts +36 -33
- package/dist/collection-client.js +549 -104
- package/dist/connect-authorization-helpers.d.ts +3 -0
- package/dist/connect-authorization-helpers.js +13 -0
- package/dist/connect-options.d.ts +12 -4
- package/dist/connect.d.ts +12 -4
- package/dist/connect.js +102 -103
- package/dist/connection-file-transport.d.ts +2 -2
- package/dist/connection-file-transport.js +4 -4
- package/dist/connection-notifications.d.ts +10 -4
- package/dist/connection-notifications.js +41 -23
- package/dist/connection-transport.d.ts +19 -15
- package/dist/connection-transport.js +202 -202
- package/dist/connection-types.d.ts +5 -4
- package/dist/connection.d.ts +47 -46
- package/dist/connection.js +320 -162
- package/dist/crypto-entry.d.ts +7 -0
- package/dist/crypto-entry.js +4 -0
- package/dist/crypto.js +4 -4
- package/dist/external-store.d.ts +10 -0
- package/dist/external-store.js +10 -0
- package/dist/file-transfer-internals.d.ts +23 -0
- package/dist/file-transfer-internals.js +224 -0
- package/dist/files.d.ts +36 -14
- package/dist/files.js +92 -222
- package/dist/hosted-file-request.js +3 -3
- package/dist/index.d.ts +24 -19
- package/dist/index.js +10 -18
- package/dist/internal-types.d.ts +9 -1
- package/dist/local-file-transport.d.ts +2 -2
- package/dist/local-file-transport.js +13 -13
- package/dist/mdbase-connect.d.ts +6 -4
- package/dist/mdbase-connect.js +9 -8
- package/dist/notifications.d.ts +3 -2
- package/dist/operation-helpers.d.ts +3 -3
- package/dist/operation-helpers.js +17 -34
- package/dist/operation-types.d.ts +435 -45
- package/dist/outcomes.d.ts +15 -15
- package/dist/outcomes.js +13 -1
- package/dist/pending-mutation-store.d.ts +13 -0
- package/dist/pending-mutation-store.js +64 -0
- package/dist/request-budget.d.ts +27 -0
- package/dist/request-budget.js +95 -0
- package/dist/runtime-utils.d.ts +2 -0
- package/dist/runtime-utils.js +19 -0
- package/dist/session.d.ts +5 -4
- package/dist/session.js +6 -5
- package/dist/stored-token.d.ts +10 -0
- package/dist/stored-token.js +60 -0
- package/dist/token-response.d.ts +11 -0
- package/dist/token-response.js +77 -0
- package/dist/watch-policy.d.ts +8 -0
- package/dist/watch-policy.js +12 -0
- package/package.json +12 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CollectionOperation, FileCapability, GrantScope, JsonObject, SyncChangesPage, SyncMutation, SyncMutationReceipt, SyncSession, SyncSnapshotPage } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { ConnectRequestOptions } from "./operation-types.js";
|
|
2
3
|
export type MdbaseConnectionRoute = "remote" | "direct" | "relay";
|
|
3
4
|
export type DirectAccessStatus = "disabled" | "permission_required" | "checking" | "available" | "unavailable" | "denied";
|
|
4
5
|
export interface MdbaseConnectionInfo {
|
|
@@ -25,10 +26,10 @@ export interface MdbaseAuthorizationCapabilities {
|
|
|
25
26
|
missingOperations: CollectionOperation[];
|
|
26
27
|
}
|
|
27
28
|
export interface MdbaseSyncTransport<Frontmatter extends JsonObject = JsonObject> {
|
|
28
|
-
openSession(): Promise<SyncSession>;
|
|
29
|
-
snapshot(snapshotId: string, page?: string): Promise<SyncSnapshotPage<Frontmatter>>;
|
|
30
|
-
changes(after: number, limit?: number): Promise<SyncChangesPage<Frontmatter>>;
|
|
31
|
-
mutate(mutation: SyncMutation): Promise<SyncMutationReceipt<Frontmatter>>;
|
|
29
|
+
openSession(options?: ConnectRequestOptions): Promise<SyncSession>;
|
|
30
|
+
snapshot(snapshotId: string, page?: string, options?: ConnectRequestOptions): Promise<SyncSnapshotPage<Frontmatter>>;
|
|
31
|
+
changes(after: number, limit?: number, options?: ConnectRequestOptions): Promise<SyncChangesPage<Frontmatter>>;
|
|
32
|
+
mutate(mutation: SyncMutation, options?: ConnectRequestOptions): Promise<SyncMutationReceipt<Frontmatter>>;
|
|
32
33
|
}
|
|
33
34
|
export interface MdbaseSyncConnection<Frontmatter extends JsonObject = JsonObject> {
|
|
34
35
|
collectionId: string;
|
package/dist/connection.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CollectionOperation, CollectionTypeDocument, FileCapability, GrantScope, JsonObject } from "@mdbase-dev/connect-protocol";
|
|
2
2
|
import { type ConnectionTransportInternals } from "./connection-transport.js";
|
|
3
3
|
import type { DirectAccessStatus, MdbaseAuthorizationCapabilities, MdbaseConnectionInfo, MdbaseConnectionRoute, MdbaseSyncConnection } from "./connection-types.js";
|
|
4
4
|
import type { GrantKeyStore } from "./crypto.js";
|
|
5
5
|
import { MdbaseFileClient } from "./files.js";
|
|
6
6
|
import { type Application } from "./internal-types.js";
|
|
7
7
|
import type { MdbaseNativeNotificationRegistration, MdbaseNativeNotificationRegistrationOptions, MdbaseNotificationRegistration, MdbaseNotificationRegistrationOptions } from "./notifications.js";
|
|
8
|
-
import type { ChangesInput, CreateInput, CreateTypeInput, DeleteInput, DeletePreflightResult, DeleteProgressOptions, DeleteResult, MdbaseDesiredTimer, MdbaseTimer, MdbaseTimerList, MdbaseTimerReconciliation,
|
|
8
|
+
import type { ChangesInput, CollectionChangesPage, CollectionDescription, CollectionSetupApplyResult, CollectionSetupAssessment, ApplyCollectionSetupInput, ApplyTypePackInput, AssessCollectionSetupInput, AssessTypePackInput, CreateInput, CreateTypeInput, CreateViewSourceInput, DeleteInput, DeletePreflightResult, DeleteProgressOptions, DeleteResult, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, MdbaseDesiredTimer, MdbaseTimer, MdbaseTimerList, MdbaseTimerReconciliation, ConnectRequestOptions, PendingMutation, QueryAllOptions, QueryInput, QueryPage, QueryPagesOptions, QueryResult, ReadInput, ReadTypeInput, ReadViewSourceInput, RenameInput, RenamePreflightResult, RenameProgressOptions, RenameResult, RecordDocument, SavedViewExecution, SavedViewList, SavedViewSourceDocument, TypePackApplyResult, TypePackAssessment, UpdateInput, UpdateTypeInput, UpdateViewSourceInput, MdbaseWatchSubscription, WatchInput } from "./operation-types.js";
|
|
9
9
|
import { type AuthorizationProblemCode, type CollectionChangesProblemCode, type CollectionDescriptionProblemCode, type CollectionMutationProblemCode, type CollectionQueryProblemCode, type CollectionReadProblemCode, type CollectionTypeProblemCode, type ConnectOutcome, type DirectAccessProblemCode, type NotificationProblemCode, type RegistrationProblemCode } from "./outcomes.js";
|
|
10
10
|
import type { MdbaseDeviceAuthorization } from "./authorization-types.js";
|
|
11
|
+
import { type ResolvedConnectTimeouts } from "./request-budget.js";
|
|
11
12
|
export type MdbaseAuthorizationTarget = {
|
|
12
13
|
kind: "choose";
|
|
13
14
|
} | {
|
|
14
15
|
kind: "collection";
|
|
15
16
|
collectionId: string;
|
|
16
17
|
};
|
|
17
|
-
export interface MdbaseAuthorizeOptions {
|
|
18
|
+
export interface MdbaseAuthorizeOptions extends ConnectRequestOptions {
|
|
18
19
|
operations?: CollectionOperation[];
|
|
19
20
|
/** Choose any compatible collection, or require one exact collection. */
|
|
20
21
|
target?: MdbaseAuthorizationTarget;
|
|
@@ -24,15 +25,12 @@ export interface MdbaseAuthorizeOptions {
|
|
|
24
25
|
onDeviceCode?: (authorization: MdbaseDeviceAuthorization) => void;
|
|
25
26
|
/** Replace the default popup for a downloaded application's approval page. */
|
|
26
27
|
openVerification?: (authorization: MdbaseDeviceAuthorization) => void | Promise<void>;
|
|
27
|
-
/** Stop polling and discard the unapproved, in-memory key. */
|
|
28
|
-
signal?: AbortSignal;
|
|
29
28
|
}
|
|
30
|
-
export interface MdbaseConnectionAuthorizeOptions {
|
|
29
|
+
export interface MdbaseConnectionAuthorizeOptions extends ConnectRequestOptions {
|
|
31
30
|
operations?: CollectionOperation[];
|
|
32
31
|
returnTo?: string;
|
|
33
32
|
onDeviceCode?: (authorization: MdbaseDeviceAuthorization) => void;
|
|
34
33
|
openVerification?: (authorization: MdbaseDeviceAuthorization) => void | Promise<void>;
|
|
35
|
-
signal?: AbortSignal;
|
|
36
34
|
}
|
|
37
35
|
export interface MdbaseConnectEnvironment {
|
|
38
36
|
distribution: "web" | "portable";
|
|
@@ -54,7 +52,8 @@ export interface MdbaseConnectionInternals<Frontmatter extends JsonObject> exten
|
|
|
54
52
|
readonly keyStore: GrantKeyStore;
|
|
55
53
|
readonly directAccessMode: "auto" | "disabled";
|
|
56
54
|
readonly loopbackUrl: string;
|
|
57
|
-
|
|
55
|
+
readonly timeouts: ResolvedConnectTimeouts;
|
|
56
|
+
register(options?: ConnectRequestOptions): Promise<Application>;
|
|
58
57
|
authorize(options?: MdbaseAuthorizeOptions): Promise<MdbaseAuthorizationOutcome<Frontmatter>>;
|
|
59
58
|
notificationKey(collectionId: string, transport?: "web_push" | "fcm"): string;
|
|
60
59
|
}
|
|
@@ -73,7 +72,7 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
73
72
|
get fileCapability(): FileCapability | null;
|
|
74
73
|
get directAccess(): DirectAccessStatus;
|
|
75
74
|
get route(): MdbaseConnectionRoute;
|
|
76
|
-
register(): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
|
|
75
|
+
register(options?: ConnectRequestOptions): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
|
|
77
76
|
info(): MdbaseConnectionInfo | null;
|
|
78
77
|
authorizationCapabilities(requiredOperations?: CollectionOperation[]): MdbaseAuthorizationCapabilities;
|
|
79
78
|
hasOperations(requiredOperations: CollectionOperation[]): boolean;
|
|
@@ -84,9 +83,9 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
84
83
|
}, AuthorizationProblemCode>>;
|
|
85
84
|
onConnectionChange(listener: (connection: MdbaseConnectionInfo | null) => void): () => void;
|
|
86
85
|
notifyStorageChanged(): void;
|
|
87
|
-
checkDirectAccess(): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
86
|
+
checkDirectAccess(options?: ConnectRequestOptions): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
88
87
|
/** Call from a user gesture to request browser permission for direct local access. */
|
|
89
|
-
requestDirectAccess(): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
88
|
+
requestDirectAccess(options?: ConnectRequestOptions): Promise<ConnectOutcome<DirectAccessStatus, DirectAccessProblemCode>>;
|
|
90
89
|
disableDirectAccess(): void;
|
|
91
90
|
/**
|
|
92
91
|
* Return one offline-replication transport regardless of whether the
|
|
@@ -102,58 +101,60 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
102
101
|
*/
|
|
103
102
|
registerNotifications(options: MdbaseNotificationRegistrationOptions): Promise<ConnectOutcome<MdbaseNotificationRegistration, NotificationProblemCode>>;
|
|
104
103
|
registerNativeNotifications(options: MdbaseNativeNotificationRegistrationOptions): Promise<ConnectOutcome<MdbaseNativeNotificationRegistration, NotificationProblemCode>>;
|
|
105
|
-
unregisterNativeNotifications(): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
106
|
-
unregisterNotifications(serviceWorker?: ServiceWorkerRegistration): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
104
|
+
unregisterNativeNotifications(options?: ConnectRequestOptions): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
105
|
+
unregisterNotifications(serviceWorker?: ServiceWorkerRegistration, options?: ConnectRequestOptions): Promise<ConnectOutcome<void, NotificationProblemCode>>;
|
|
107
106
|
forget(): void;
|
|
108
|
-
describe(): Promise<ConnectOutcome<CollectionDescription, CollectionDescriptionProblemCode>>;
|
|
109
|
-
changes(input?: ChangesInput, options?:
|
|
110
|
-
read(input: ReadInput): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionReadProblemCode>>;
|
|
111
|
-
query(input?: QueryInput, options?:
|
|
107
|
+
describe(options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionDescription, CollectionDescriptionProblemCode>>;
|
|
108
|
+
changes(input?: ChangesInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionChangesPage, CollectionChangesProblemCode>>;
|
|
109
|
+
read(input: ReadInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionReadProblemCode>>;
|
|
110
|
+
query(input?: QueryInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
112
111
|
queryPages(input?: QueryInput, options?: QueryPagesOptions<Frontmatter>): AsyncGenerator<ConnectOutcome<QueryPage<Frontmatter>, CollectionQueryProblemCode>>;
|
|
113
|
-
queryAll(input?: QueryInput, options?:
|
|
114
|
-
listViews(): Promise<ConnectOutcome<SavedViewList, CollectionReadProblemCode>>;
|
|
115
|
-
executeView(input: ExecuteViewInput): Promise<ConnectOutcome<SavedViewExecution<Frontmatter>, CollectionReadProblemCode>>;
|
|
116
|
-
readViewSource(input: ReadViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionReadProblemCode>>;
|
|
117
|
-
createViewSource(input: CreateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
118
|
-
updateViewSource(input: UpdateViewSourceInput): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
119
|
-
deleteViewSource(input: DeleteViewSourceInput): Promise<ConnectOutcome<DeleteViewSourceResult, CollectionMutationProblemCode>>;
|
|
120
|
-
create(input: CreateInput<Frontmatter
|
|
121
|
-
update(input: UpdateInput<Frontmatter
|
|
122
|
-
delete(input: DeleteInput, options?:
|
|
123
|
-
preflightDelete(input: DeleteInput, options?:
|
|
124
|
-
rename(input: RenameInput, options?:
|
|
125
|
-
preflightRename(input: RenameInput, options?:
|
|
112
|
+
queryAll(input?: QueryInput, options?: QueryAllOptions<Frontmatter>): Promise<ConnectOutcome<QueryResult<Frontmatter>, CollectionQueryProblemCode>>;
|
|
113
|
+
listViews(options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewList, CollectionReadProblemCode>>;
|
|
114
|
+
executeView(input: ExecuteViewInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewExecution<Frontmatter>, CollectionReadProblemCode>>;
|
|
115
|
+
readViewSource(input: ReadViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionReadProblemCode>>;
|
|
116
|
+
createViewSource(input: CreateViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
117
|
+
updateViewSource(input: UpdateViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<SavedViewSourceDocument, CollectionMutationProblemCode>>;
|
|
118
|
+
deleteViewSource(input: DeleteViewSourceInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeleteViewSourceResult, CollectionMutationProblemCode>>;
|
|
119
|
+
create(input: CreateInput<Frontmatter>, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
120
|
+
update(input: UpdateInput<Frontmatter>, options?: ConnectRequestOptions): Promise<ConnectOutcome<RecordDocument<Frontmatter>, CollectionMutationProblemCode>>;
|
|
121
|
+
delete(input: DeleteInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeleteResult, CollectionMutationProblemCode>>;
|
|
122
|
+
preflightDelete(input: DeleteInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<DeletePreflightResult, CollectionMutationProblemCode>>;
|
|
123
|
+
rename(input: RenameInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RenameResult, CollectionMutationProblemCode>>;
|
|
124
|
+
preflightRename(input: RenameInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<RenamePreflightResult, CollectionMutationProblemCode>>;
|
|
126
125
|
renameWithProgress(input: RenameInput, options?: RenameProgressOptions): Promise<ConnectOutcome<RenameResult, CollectionMutationProblemCode>>;
|
|
127
126
|
deleteWithProgress(input: DeleteInput, options?: DeleteProgressOptions): Promise<ConnectOutcome<DeleteResult, CollectionMutationProblemCode>>;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
127
|
+
pendingMutations<Result = unknown>(): readonly PendingMutation<Result>[];
|
|
128
|
+
pendingMutation<Result = unknown>(requestId: string): PendingMutation<Result> | null;
|
|
129
|
+
private recoverPendingMutation;
|
|
130
|
+
validate(input?: JsonObject, options?: ConnectRequestOptions): Promise<ConnectOutcome<JsonObject, CollectionReadProblemCode>>;
|
|
131
|
+
readType(input: ReadTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
132
|
+
createType(input: CreateTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
133
|
+
updateType(input: UpdateTypeInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionTypeDocument, CollectionTypeProblemCode>>;
|
|
134
|
+
assessTypePack(input: AssessTypePackInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<TypePackAssessment, CollectionTypeProblemCode>>;
|
|
135
|
+
applyTypePack(input: ApplyTypePackInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<TypePackApplyResult, CollectionTypeProblemCode>>;
|
|
136
|
+
assessCollectionSetup(input: AssessCollectionSetupInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionSetupAssessment, CollectionTypeProblemCode>>;
|
|
137
|
+
applyCollectionSetup(input: ApplyCollectionSetupInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<CollectionSetupApplyResult, CollectionTypeProblemCode>>;
|
|
138
|
+
listTimers(namespace: string, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimerList, CollectionReadProblemCode>>;
|
|
137
139
|
putTimer(input: {
|
|
138
140
|
namespace: string;
|
|
139
|
-
|
|
141
|
+
criterionId: string;
|
|
140
142
|
timer: MdbaseDesiredTimer;
|
|
141
|
-
}): Promise<ConnectOutcome<MdbaseTimer, CollectionMutationProblemCode>>;
|
|
143
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimer, CollectionMutationProblemCode>>;
|
|
142
144
|
cancelTimer(input: {
|
|
143
145
|
namespace: string;
|
|
144
146
|
id: string;
|
|
145
147
|
generation?: number;
|
|
146
|
-
}): Promise<ConnectOutcome<{
|
|
148
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<{
|
|
147
149
|
namespace: string;
|
|
148
150
|
id: string;
|
|
149
151
|
cancelled: boolean;
|
|
150
152
|
}, CollectionMutationProblemCode>>;
|
|
151
153
|
reconcileTimers(input: {
|
|
152
154
|
namespace: string;
|
|
153
|
-
|
|
155
|
+
criterionId: string;
|
|
154
156
|
timers: MdbaseDesiredTimer[];
|
|
155
|
-
}): Promise<ConnectOutcome<MdbaseTimerReconciliation, CollectionMutationProblemCode>>;
|
|
156
|
-
watch(options?:
|
|
157
|
-
operation<Result>(operation: CollectionOperation, input: unknown, options?: OperationRequestOptions): Promise<ConnectOutcome<Result>>;
|
|
157
|
+
}, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseTimerReconciliation, CollectionMutationProblemCode>>;
|
|
158
|
+
watch(input?: WatchInput, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseWatchSubscription, CollectionChangesProblemCode>>;
|
|
158
159
|
private emitConnection;
|
|
159
160
|
}
|