@maxzima/wa-communicator 0.0.2 → 0.0.5
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 +10 -16
- package/dist/engine/CommunicatorReceiver.d.ts +14 -0
- package/dist/engine/CommunicatorReceiver.js +35 -0
- package/dist/engine/CommunicatorSender.d.ts +11 -0
- package/dist/engine/CommunicatorSender.js +20 -0
- package/dist/enums/BaseEnum.d.ts +8 -0
- package/dist/enums/BaseEnum.js +31 -0
- package/dist/enums/CommunicatorActionEnum.d.ts +7 -0
- package/dist/enums/CommunicatorActionEnum.js +10 -0
- package/dist/enums/CommunicatorTargetEnum.d.ts +5 -0
- package/dist/enums/CommunicatorTargetEnum.js +8 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +12 -0
- package/package.json +2 -1
- package/src/engine/CommunicatorReceiver.ts +5 -9
- package/src/engine/CommunicatorSender.ts +6 -2
- package/src/enums/CommunicatorActionEnum.ts +8 -7
- package/src/enums/CommunicatorTargetEnum.ts +6 -5
- package/src/types.ts +11 -19
- package/src/enums/BaseEnum.ts +0 -36
package/README.md
CHANGED
|
@@ -7,16 +7,14 @@ const communicator = new CommunicatorSender({
|
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
communicator.sendMessage({
|
|
10
|
-
target:
|
|
11
|
-
action:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
]
|
|
10
|
+
target: CommunicatorTargetEnum.SIGN_UP,
|
|
11
|
+
action: {
|
|
12
|
+
[CommunicatorActionEnum.CLOSE]: true,
|
|
13
|
+
[CommunicatorActionEnum.GOTO]: {
|
|
14
|
+
url: 'clients.google.com',
|
|
15
|
+
isTargetBlank: true
|
|
16
|
+
},
|
|
17
|
+
}
|
|
20
18
|
});
|
|
21
19
|
```
|
|
22
20
|
|
|
@@ -25,12 +23,8 @@ communicator.sendMessage({
|
|
|
25
23
|
```javascript
|
|
26
24
|
const communicator = new CommunicatorReceiver({
|
|
27
25
|
callback: (message) => {
|
|
28
|
-
if (message.target ===
|
|
29
|
-
message.action.
|
|
30
|
-
if (action.key === CommunicatorActionEnum.GOTO) {
|
|
31
|
-
window.location = action.params['url'];
|
|
32
|
-
}
|
|
33
|
-
})
|
|
26
|
+
if (message.target === CommunicatorTargetEnum.SIGN_UP && message.action[CommunicatorActionEnum.GOTO]) {
|
|
27
|
+
window.location.href = message.action[CommunicatorActionEnum.GOTO].url;
|
|
34
28
|
}
|
|
35
29
|
}
|
|
36
30
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TReceiverProps } from '../types';
|
|
2
|
+
export declare class CommunicatorReceiver {
|
|
3
|
+
private readonly callback;
|
|
4
|
+
constructor(props: TReceiverProps);
|
|
5
|
+
/**
|
|
6
|
+
* Watch Messages
|
|
7
|
+
*/
|
|
8
|
+
watch(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Message Receive Callback
|
|
11
|
+
* @param event
|
|
12
|
+
*/
|
|
13
|
+
private onMessage;
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class CommunicatorReceiver {
|
|
2
|
+
constructor(props) {
|
|
3
|
+
/**
|
|
4
|
+
* Message Receive Callback
|
|
5
|
+
* @param event
|
|
6
|
+
*/
|
|
7
|
+
this.onMessage = (event) => {
|
|
8
|
+
if (!event || !event.origin || !event.data) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let message;
|
|
12
|
+
try {
|
|
13
|
+
message = JSON.parse(event.data);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.log('PostMessage read error');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (window.origin !== event.origin) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (typeof this.callback !== 'function') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.callback(message);
|
|
26
|
+
};
|
|
27
|
+
this.callback = props.callback;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Watch Messages
|
|
31
|
+
*/
|
|
32
|
+
watch() {
|
|
33
|
+
window.addEventListener('message', this.onMessage, false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TCommunicatorMessage, TSenderProps } from '../types';
|
|
2
|
+
export declare class CommunicatorSender {
|
|
3
|
+
private readonly otherWindow;
|
|
4
|
+
private readonly targetOrigin;
|
|
5
|
+
constructor(props: TSenderProps);
|
|
6
|
+
/**
|
|
7
|
+
* Send PostMessage
|
|
8
|
+
* @param message
|
|
9
|
+
*/
|
|
10
|
+
sendMessage(message: TCommunicatorMessage): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { modifyUrl } from '../utils';
|
|
2
|
+
import { CommunicatorTargetEnum_isCorrect } from '../enums/CommunicatorTargetEnum';
|
|
3
|
+
export class CommunicatorSender {
|
|
4
|
+
constructor(props) {
|
|
5
|
+
this.otherWindow = props.otherWindow;
|
|
6
|
+
this.targetOrigin = modifyUrl(props.targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Send PostMessage
|
|
10
|
+
* @param message
|
|
11
|
+
*/
|
|
12
|
+
sendMessage(message) {
|
|
13
|
+
if (!this.targetOrigin ||
|
|
14
|
+
!CommunicatorTargetEnum_isCorrect(message.target)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const jsonMessage = JSON.stringify(message);
|
|
18
|
+
this.otherWindow.postMessage(jsonMessage, this.targetOrigin);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export default class BaseEnum {
|
|
2
|
+
static isCorrect(value) {
|
|
3
|
+
return value && value.trim() && this.getAsArray().indexOf(value) !== -1;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Gets array of all possible values
|
|
7
|
+
*/
|
|
8
|
+
static getAsArray() {
|
|
9
|
+
if (!this.array) {
|
|
10
|
+
let props = Object.getOwnPropertyNames(this);
|
|
11
|
+
let obj = Object.getPrototypeOf(this);
|
|
12
|
+
this.array = [];
|
|
13
|
+
while (Object.prototype.isPrototypeOf.call(BaseEnum, obj)) {
|
|
14
|
+
props = [...props, ...Object.getOwnPropertyNames(obj)];
|
|
15
|
+
obj = Object.getPrototypeOf(obj);
|
|
16
|
+
}
|
|
17
|
+
for (const prop of props) {
|
|
18
|
+
if (['caller', 'arguments', 'name', 'length', 'prototype'].indexOf(prop) !== -1) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const self = this;
|
|
22
|
+
const propValue = self[prop];
|
|
23
|
+
if (typeof propValue === 'string' && prop.indexOf('CONTEXT') === -1) {
|
|
24
|
+
this.array.push(propValue);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return this.array;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
BaseEnum.array = null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export var CommunicatorActionEnum;
|
|
2
|
+
(function (CommunicatorActionEnum) {
|
|
3
|
+
CommunicatorActionEnum["CLOSE"] = "close";
|
|
4
|
+
CommunicatorActionEnum["OPEN"] = "open";
|
|
5
|
+
CommunicatorActionEnum["GOTO"] = "goto";
|
|
6
|
+
CommunicatorActionEnum["RESIZE"] = "resize";
|
|
7
|
+
})(CommunicatorActionEnum || (CommunicatorActionEnum = {}));
|
|
8
|
+
export function CommunicatorActionEnum_isCorrect(item) {
|
|
9
|
+
return Object.values(CommunicatorActionEnum).includes(item);
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var CommunicatorTargetEnum;
|
|
2
|
+
(function (CommunicatorTargetEnum) {
|
|
3
|
+
CommunicatorTargetEnum["SIGN_UP"] = "sign_up";
|
|
4
|
+
CommunicatorTargetEnum["SIGN_IN"] = "sign_in";
|
|
5
|
+
})(CommunicatorTargetEnum || (CommunicatorTargetEnum = {}));
|
|
6
|
+
export function CommunicatorTargetEnum_isCorrect(item) {
|
|
7
|
+
return Object.values(CommunicatorTargetEnum).includes(item);
|
|
8
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommunicatorReceiver } from "./engine/CommunicatorReceiver";
|
|
2
|
+
import { CommunicatorSender } from "./engine/CommunicatorSender";
|
|
3
|
+
import { CommunicatorTargetEnum } from "./enums/CommunicatorTargetEnum";
|
|
4
|
+
import { CommunicatorActionEnum } from "./enums/CommunicatorActionEnum";
|
|
5
|
+
import * as types from "./types";
|
|
6
|
+
export { CommunicatorReceiver, CommunicatorSender, CommunicatorTargetEnum, CommunicatorActionEnum, types, };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommunicatorReceiver } from "./engine/CommunicatorReceiver";
|
|
2
|
+
import { CommunicatorSender } from "./engine/CommunicatorSender";
|
|
3
|
+
import { CommunicatorTargetEnum } from "./enums/CommunicatorTargetEnum";
|
|
4
|
+
import { CommunicatorActionEnum } from "./enums/CommunicatorActionEnum";
|
|
5
|
+
import * as types from "./types";
|
|
6
|
+
export { CommunicatorReceiver, CommunicatorSender, CommunicatorTargetEnum, CommunicatorActionEnum, types, };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CommunicatorActionEnum } from "./enums/CommunicatorActionEnum";
|
|
2
|
+
import { CommunicatorTargetEnum } from "./enums/CommunicatorTargetEnum";
|
|
3
|
+
export declare type TSenderProps = {
|
|
4
|
+
targetOrigin: string;
|
|
5
|
+
otherWindow: Window;
|
|
6
|
+
};
|
|
7
|
+
export declare type TReceiverProps = {
|
|
8
|
+
callback: TReceiverCallback;
|
|
9
|
+
};
|
|
10
|
+
export declare type TReceiverCallback = (message: TCommunicatorMessage) => void;
|
|
11
|
+
export declare type TCommunicatorActionResizeParams = {
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare type TCommunicatorActionGotoParams = {
|
|
16
|
+
url: string;
|
|
17
|
+
isTargetBlank?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare type TCommunicatorSenderActionMap = {
|
|
20
|
+
[CommunicatorActionEnum.RESIZE]?: TCommunicatorActionResizeParams;
|
|
21
|
+
[CommunicatorActionEnum.GOTO]?: TCommunicatorActionGotoParams;
|
|
22
|
+
[CommunicatorActionEnum.CLOSE]?: true;
|
|
23
|
+
[CommunicatorActionEnum.OPEN]?: CommunicatorTargetEnum;
|
|
24
|
+
};
|
|
25
|
+
export declare type TCommunicatorMessage = {
|
|
26
|
+
target: CommunicatorTargetEnum;
|
|
27
|
+
action: TCommunicatorSenderActionMap;
|
|
28
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { CommunicatorActionEnum } from "./enums/CommunicatorActionEnum";
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function modifyUrl(address: string): string;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function modifyUrl(address) {
|
|
2
|
+
let url;
|
|
3
|
+
try {
|
|
4
|
+
let targetOrigin = address.trim();
|
|
5
|
+
targetOrigin = (targetOrigin.indexOf('://') === -1) ? 'https://' + targetOrigin : targetOrigin;
|
|
6
|
+
url = new URL(targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
catch (_) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return url.toString();
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.
|
|
2
|
+
"version": "0.0.5",
|
|
3
3
|
"name": "@maxzima/wa-communicator",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Noname",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"node": ">=14"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"prepublish": "rm -rf dist",
|
|
13
14
|
"postinstall": "npm run build",
|
|
14
15
|
"build": "tsc --project tsconfig.json"
|
|
15
16
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {TCommunicatorMessage, TReceiverProps} from '../types';
|
|
1
|
+
import {TCommunicatorMessage, TReceiverCallback, TReceiverProps} from '../types';
|
|
2
2
|
|
|
3
3
|
export class CommunicatorReceiver {
|
|
4
|
-
private readonly callback:
|
|
4
|
+
private readonly callback: TReceiverCallback;
|
|
5
5
|
|
|
6
6
|
constructor(props: TReceiverProps) {
|
|
7
7
|
this.callback = props.callback;
|
|
@@ -11,14 +11,14 @@ export class CommunicatorReceiver {
|
|
|
11
11
|
* Watch Messages
|
|
12
12
|
*/
|
|
13
13
|
public watch() {
|
|
14
|
-
window.addEventListener('message', this.
|
|
14
|
+
window.addEventListener('message', this.onMessage, false);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Message Receive Callback
|
|
19
19
|
* @param event
|
|
20
20
|
*/
|
|
21
|
-
private
|
|
21
|
+
private onMessage = (event: MessageEvent) => {
|
|
22
22
|
if (!event || !event.origin || !event.data) {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
@@ -36,10 +36,6 @@ export class CommunicatorReceiver {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
if (!Array.isArray(message.action)) {
|
|
40
|
-
message.action = [message.action];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
39
|
if (typeof this.callback !== 'function') {
|
|
44
40
|
return;
|
|
45
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {TCommunicatorMessage, TSenderProps} from '../types';
|
|
2
2
|
import {modifyUrl} from '../utils';
|
|
3
|
-
import {
|
|
3
|
+
import {CommunicatorTargetEnum_isCorrect} from '../enums/CommunicatorTargetEnum';
|
|
4
4
|
|
|
5
5
|
export class CommunicatorSender {
|
|
6
6
|
private readonly otherWindow: Window;
|
|
@@ -11,10 +11,14 @@ export class CommunicatorSender {
|
|
|
11
11
|
this.targetOrigin = modifyUrl(props.targetOrigin);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Send PostMessage
|
|
16
|
+
* @param message
|
|
17
|
+
*/
|
|
14
18
|
public sendMessage(message: TCommunicatorMessage) {
|
|
15
19
|
if (
|
|
16
20
|
!this.targetOrigin ||
|
|
17
|
-
!
|
|
21
|
+
!CommunicatorTargetEnum_isCorrect(message.target)
|
|
18
22
|
) {
|
|
19
23
|
return;
|
|
20
24
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export enum CommunicatorActionEnum {
|
|
2
|
+
CLOSE = 'close',
|
|
3
|
+
OPEN = 'open',
|
|
4
|
+
GOTO = 'goto',
|
|
5
|
+
RESIZE = 'resize',
|
|
6
|
+
}
|
|
3
7
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
public static OPEN: TCommunicatorActionKey = 'open';
|
|
7
|
-
public static GOTO: TCommunicatorActionKey = 'goto';
|
|
8
|
-
public static RESIZE: TCommunicatorActionKey = 'resize';
|
|
8
|
+
export function CommunicatorActionEnum_isCorrect(item: string): boolean {
|
|
9
|
+
return Object.values(CommunicatorActionEnum).includes(item as CommunicatorActionEnum);
|
|
9
10
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export enum CommunicatorTargetEnum {
|
|
2
|
+
SIGN_UP = 'sign_up',
|
|
3
|
+
SIGN_IN = 'sign_in',
|
|
4
|
+
}
|
|
3
5
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
public static SIGN_IN: TCommunicatorTargetKey = 'sign_in';
|
|
6
|
+
export function CommunicatorTargetEnum_isCorrect(item: string): boolean {
|
|
7
|
+
return Object.values(CommunicatorTargetEnum).includes(item as CommunicatorTargetEnum);
|
|
7
8
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import {CommunicatorActionEnum} from "./enums/CommunicatorActionEnum";
|
|
2
|
+
import {CommunicatorTargetEnum} from "./enums/CommunicatorTargetEnum";
|
|
3
|
+
|
|
1
4
|
export type TSenderProps = {
|
|
2
5
|
targetOrigin: string,
|
|
3
6
|
otherWindow: Window,
|
|
4
7
|
}
|
|
5
8
|
|
|
6
9
|
export type TReceiverProps = {
|
|
7
|
-
callback:
|
|
10
|
+
callback: TReceiverCallback,
|
|
8
11
|
}
|
|
9
12
|
|
|
10
|
-
export type
|
|
11
|
-
export type TCommunicatorActionKey = keyof TCommunicatorSenderActionMap;
|
|
13
|
+
export type TReceiverCallback = (message: TCommunicatorMessage) => void;
|
|
12
14
|
|
|
13
15
|
export type TCommunicatorActionResizeParams = {
|
|
14
16
|
width?: number,
|
|
@@ -21,23 +23,13 @@ export type TCommunicatorActionGotoParams = {
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export type TCommunicatorSenderActionMap = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
[CommunicatorActionEnum.RESIZE]?: TCommunicatorActionResizeParams,
|
|
27
|
+
[CommunicatorActionEnum.GOTO]?: TCommunicatorActionGotoParams,
|
|
28
|
+
[CommunicatorActionEnum.CLOSE]?: true,
|
|
29
|
+
[CommunicatorActionEnum.OPEN]?: CommunicatorTargetEnum,
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export type TCommunicatorMessage = {
|
|
31
|
-
target:
|
|
32
|
-
action:
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type TCommunicatorMessageReceiver = {
|
|
36
|
-
target: TCommunicatorTargetKey,
|
|
37
|
-
action: TCommunicatorActionItem[]
|
|
33
|
+
target: CommunicatorTargetEnum,
|
|
34
|
+
action: TCommunicatorSenderActionMap
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
export type TCommunicatorActionItem = {
|
|
41
|
-
key: TCommunicatorActionKey,
|
|
42
|
-
params?: TCommunicatorSenderActionMap[TCommunicatorActionKey]
|
|
43
|
-
};
|
package/src/enums/BaseEnum.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export default abstract class BaseEnum {
|
|
2
|
-
public static array: string[] = null;
|
|
3
|
-
|
|
4
|
-
public static isCorrect(value: string): boolean {
|
|
5
|
-
return value && value.trim() && this.getAsArray().indexOf(value) !== -1;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Gets array of all possible values
|
|
10
|
-
*/
|
|
11
|
-
public static getAsArray(): string[] {
|
|
12
|
-
if (!this.array) {
|
|
13
|
-
let props = Object.getOwnPropertyNames(this);
|
|
14
|
-
let obj = Object.getPrototypeOf(this);
|
|
15
|
-
|
|
16
|
-
this.array = [];
|
|
17
|
-
|
|
18
|
-
while (Object.prototype.isPrototypeOf.call(BaseEnum, obj)) {
|
|
19
|
-
props = [...props, ...Object.getOwnPropertyNames(obj)];
|
|
20
|
-
obj = Object.getPrototypeOf(obj);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
for (const prop of props) {
|
|
24
|
-
if (['caller', 'arguments', 'name', 'length', 'prototype'].indexOf(prop) !== -1) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
const self = this as {[index: string]: any};
|
|
28
|
-
const propValue = self[prop];
|
|
29
|
-
if (typeof propValue === 'string' && prop.indexOf('CONTEXT') === -1) {
|
|
30
|
-
this.array.push(propValue);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return this.array;
|
|
35
|
-
}
|
|
36
|
-
}
|