@yuants/vendor-turboflow 1.2.0 → 1.2.2
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/.rush/temp/chunked-rush-logs/vendor-turboflow.build.chunks.jsonl +7 -7
- package/.rush/temp/operation/build/all.log +7 -7
- package/.rush/temp/operation/build/log-chunks.jsonl +7 -7
- package/.rush/temp/operation/build/state.json +1 -1
- package/.rush/temp/shrinkwrap-deps.json +1 -1
- package/CHANGELOG.json +54 -0
- package/CHANGELOG.md +15 -1
- package/lib/api/private-api.d.ts +1 -1
- package/lib/api/private-api.d.ts.map +1 -1
- package/lib/api/private-api.js +5 -4
- package/lib/api/private-api.js.map +1 -1
- package/lib/api/public-api.d.ts +31 -0
- package/lib/api/public-api.d.ts.map +1 -0
- package/lib/api/public-api.js +29 -0
- package/lib/api/public-api.js.map +1 -0
- package/lib/index.d.ts +1 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/lib/services/exchange.d.ts +2 -0
- package/lib/services/exchange.d.ts.map +1 -0
- package/lib/services/exchange.js +96 -0
- package/lib/services/exchange.js.map +1 -0
- package/lib/services/orders/cancelOrder.d.ts.map +1 -1
- package/lib/services/orders/cancelOrder.js +21 -28
- package/lib/services/orders/cancelOrder.js.map +1 -1
- package/lib/services/orders/listOrders.d.ts +2 -2
- package/lib/services/orders/listOrders.d.ts.map +1 -1
- package/lib/services/orders/listOrders.js +9 -23
- package/lib/services/orders/listOrders.js.map +1 -1
- package/lib/services/orders/submitOrder.d.ts.map +1 -1
- package/lib/services/orders/submitOrder.js +7 -5
- package/lib/services/orders/submitOrder.js.map +1 -1
- package/package.json +7 -5
- package/rush-logs/vendor-turboflow.build.log +7 -7
- package/src/api/private-api.ts +14 -6
- package/src/api/public-api.ts +65 -0
- package/src/index.ts +1 -3
- package/src/services/exchange.ts +107 -0
- package/src/services/orders/cancelOrder.ts +22 -29
- package/src/services/orders/listOrders.ts +11 -28
- package/src/services/orders/submitOrder.ts +6 -5
- package/temp/package-deps.json +17 -14
- package/lib/services/account-actions-with-credential.d.ts +0 -2
- package/lib/services/account-actions-with-credential.d.ts.map +0 -1
- package/lib/services/account-actions-with-credential.js +0 -60
- package/lib/services/account-actions-with-credential.js.map +0 -1
- package/src/services/account-actions-with-credential.ts +0 -76
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { IOrder } from '@yuants/data-order';
|
|
2
|
-
import { formatTime } from '@yuants/utils';
|
|
2
|
+
import { decodePath, formatTime, newError } from '@yuants/utils';
|
|
3
3
|
import { ICredential, submitOrder as submitOrderApi } from '../../api/private-api';
|
|
4
4
|
|
|
5
5
|
export const submitOrder = async (credential: ICredential, order: IOrder): Promise<{ order_id: string }> => {
|
|
6
6
|
// Parse product_id to get pair_id
|
|
7
|
-
const
|
|
8
|
-
const pair_id = productParts[productParts.length - 1];
|
|
7
|
+
const [, _SWAP, _NAME, pair_id] = decodePath(order.product_id);
|
|
9
8
|
|
|
10
9
|
// Determine order_way based on order_direction
|
|
11
10
|
// 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)
|
|
@@ -50,8 +49,8 @@ export const submitOrder = async (credential: ICredential, order: IOrder): Promi
|
|
|
50
49
|
order_type,
|
|
51
50
|
order_way,
|
|
52
51
|
margin_type: 2, // Default to cross margin
|
|
53
|
-
leverage:
|
|
54
|
-
|
|
52
|
+
leverage: 1,
|
|
53
|
+
vol: order.volume, // usdc value
|
|
55
54
|
position_mode: 1, // Default to one-way
|
|
56
55
|
time_in_force: 'GTC' as const,
|
|
57
56
|
fee_mode: 1,
|
|
@@ -59,5 +58,7 @@ export const submitOrder = async (credential: ICredential, order: IOrder): Promi
|
|
|
59
58
|
price: order.price?.toString(),
|
|
60
59
|
});
|
|
61
60
|
|
|
61
|
+
if (!response.data?.order) throw newError('TURBOFLOW_SUBMIT_ORDER_FAILED', { response });
|
|
62
|
+
|
|
62
63
|
return { order_id: response.data.order.id };
|
|
63
64
|
};
|
package/temp/package-deps.json
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apps/vendor-turboflow/CHANGELOG.json": "
|
|
3
|
-
"apps/vendor-turboflow/CHANGELOG.md": "
|
|
2
|
+
"apps/vendor-turboflow/CHANGELOG.json": "0922dab8ef3112f0f508204d050839f53a2b8951",
|
|
3
|
+
"apps/vendor-turboflow/CHANGELOG.md": "92bf91e3bd2f18504a0e11c3cdd01bf72f1c8588",
|
|
4
4
|
"apps/vendor-turboflow/README.md": "084c5960ccac11196467867e63c790f6b14ca3a5",
|
|
5
|
-
"apps/vendor-turboflow/package.json": "
|
|
6
|
-
"apps/vendor-turboflow/src/api/private-api.ts": "
|
|
7
|
-
"apps/vendor-turboflow/src/
|
|
8
|
-
"apps/vendor-turboflow/src/
|
|
5
|
+
"apps/vendor-turboflow/package.json": "b7118e598204cc94df99b9dbeac6b2f0a9e34c0a",
|
|
6
|
+
"apps/vendor-turboflow/src/api/private-api.ts": "51ee681353f0a95470b5e250b1f68a3d461799e1",
|
|
7
|
+
"apps/vendor-turboflow/src/api/public-api.ts": "e5a8e21bf4797e56fdd6b1948b761ede54aa34eb",
|
|
8
|
+
"apps/vendor-turboflow/src/index.ts": "44b85b7532783f7734eaab6f90e426cb84da16eb",
|
|
9
|
+
"apps/vendor-turboflow/src/services/exchange.ts": "cd87240a3e66be141308cffab150e6d600315e95",
|
|
9
10
|
"apps/vendor-turboflow/src/services/order-actions-with-credential.ts": "65a026635484aca00a22ad1e3a37fdcc87955311",
|
|
10
|
-
"apps/vendor-turboflow/src/services/orders/cancelOrder.ts": "
|
|
11
|
-
"apps/vendor-turboflow/src/services/orders/listOrders.ts": "
|
|
11
|
+
"apps/vendor-turboflow/src/services/orders/cancelOrder.ts": "722b2cecb9d103df9e68ea54e7e0556d597d0da7",
|
|
12
|
+
"apps/vendor-turboflow/src/services/orders/listOrders.ts": "8e23af975d3395004b2479332a7d9e57dc4514b4",
|
|
12
13
|
"apps/vendor-turboflow/src/services/orders/modifyOrder.ts": "b833093cf61948efe6007cfc95583ef525201cd1",
|
|
13
|
-
"apps/vendor-turboflow/src/services/orders/submitOrder.ts": "
|
|
14
|
+
"apps/vendor-turboflow/src/services/orders/submitOrder.ts": "c95aa70551f8ce8e6d7ff696082d26145dfc89ac",
|
|
14
15
|
"apps/vendor-turboflow/tsconfig.json": "5d15ec8bd54da210724db6ed27c0f925f86ee153",
|
|
15
|
-
"apps/vendor-turboflow/.rush/temp/shrinkwrap-deps.json": "
|
|
16
|
-
"libraries/protocol/temp/package-deps.json": "
|
|
17
|
-
"libraries/utils/temp/package-deps.json": "
|
|
18
|
-
"libraries/
|
|
19
|
-
"libraries/data-
|
|
16
|
+
"apps/vendor-turboflow/.rush/temp/shrinkwrap-deps.json": "4db58413c55e23c69bcd2319c8fd3f010f5487e4",
|
|
17
|
+
"libraries/protocol/temp/package-deps.json": "14095036ed251977cb3fb362a7e23d8786aaa4c9",
|
|
18
|
+
"libraries/utils/temp/package-deps.json": "6d58e9b325e8d16de8a878c32010f626b12a01da",
|
|
19
|
+
"libraries/exchange/temp/package-deps.json": "68091305dec4ea0dc245f4314f1d474a2c3247d8",
|
|
20
|
+
"libraries/data-product/temp/package-deps.json": "60b8abf6f95edc29268f10f0d64331e2f034a3e5",
|
|
21
|
+
"libraries/data-account/temp/package-deps.json": "eb3d9ccad211a998fef9e0230e164407bf1b95fc",
|
|
22
|
+
"libraries/data-order/temp/package-deps.json": "cf5b85fc4c5160f51023f7fbdc68a7ed9db5573a",
|
|
20
23
|
"tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
|
|
21
24
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"account-actions-with-credential.d.ts","sourceRoot":"","sources":["../../src/services/account-actions-with-credential.ts"],"names":[],"mappings":""}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const data_account_1 = require("@yuants/data-account");
|
|
4
|
-
const protocol_1 = require("@yuants/protocol");
|
|
5
|
-
const utils_1 = require("@yuants/utils");
|
|
6
|
-
const private_api_1 = require("../api/private-api");
|
|
7
|
-
(0, data_account_1.provideAccountActionsWithCredential)(protocol_1.Terminal.fromNodeEnv(), 'TURBOFLOW', {
|
|
8
|
-
type: 'object',
|
|
9
|
-
required: ['private_key'],
|
|
10
|
-
properties: {
|
|
11
|
-
private_key: {
|
|
12
|
-
type: 'string',
|
|
13
|
-
description: 'ED25519 Private Key (base58 encoded)',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
}, {
|
|
17
|
-
listAccounts: async (credential) => {
|
|
18
|
-
const accountInfo = await (0, private_api_1.getAccountInfo)(credential, undefined);
|
|
19
|
-
return (0, utils_1.scopeError)('ListAccountsError::TurboFlow', { error: accountInfo.errno, message: accountInfo.msg }, () => [
|
|
20
|
-
{
|
|
21
|
-
account_id: `turboflow/${accountInfo.data.account_id}`,
|
|
22
|
-
},
|
|
23
|
-
]);
|
|
24
|
-
},
|
|
25
|
-
getAccountInfo: async (credential, account_id) => {
|
|
26
|
-
const assetsResponse = await (0, private_api_1.getAccountAssets)(credential, {
|
|
27
|
-
fill_coin_sub_info: '1',
|
|
28
|
-
});
|
|
29
|
-
const assetPositions = assetsResponse.data.list.map((x) => (0, data_account_1.makeSpotPosition)({
|
|
30
|
-
position_id: x.coin_code,
|
|
31
|
-
product_id: (0, utils_1.encodePath)('SPOT', x.coin_name),
|
|
32
|
-
volume: parseFloat(x.available_balance),
|
|
33
|
-
free_volume: parseFloat(x.available_balance),
|
|
34
|
-
closable_price: 1,
|
|
35
|
-
}));
|
|
36
|
-
const positionsResponse = await (0, private_api_1.getPositionList)(credential, { status: 'Holding' });
|
|
37
|
-
const positions = (positionsResponse.data.data || []).map((position) => {
|
|
38
|
-
const side = position.side === 1 ? 'LONG' : 'SHORT';
|
|
39
|
-
const holdSize = parseFloat(position.hold_size);
|
|
40
|
-
const holdAv = parseFloat(position.hold_av);
|
|
41
|
-
const unpnl = parseFloat(position.unpnl);
|
|
42
|
-
const im = parseFloat(position.im);
|
|
43
|
-
return {
|
|
44
|
-
position_id: position.id,
|
|
45
|
-
datasource_id: 'TURBOFLOW',
|
|
46
|
-
product_id: (0, utils_1.encodePath)('PERP', position.symbol),
|
|
47
|
-
direction: side,
|
|
48
|
-
volume: holdSize,
|
|
49
|
-
free_volume: holdSize,
|
|
50
|
-
position_price: holdAv,
|
|
51
|
-
closable_price: holdAv,
|
|
52
|
-
floating_profit: unpnl,
|
|
53
|
-
valuation: holdSize * holdAv,
|
|
54
|
-
margin: im,
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
return [...assetPositions, ...positions];
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
//# sourceMappingURL=account-actions-with-credential.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"account-actions-with-credential.js","sourceRoot":"","sources":["../../src/services/account-actions-with-credential.ts"],"names":[],"mappings":";;AAAA,uDAAwG;AACxG,+CAA4C;AAC5C,yCAAuD;AACvD,oDAAoG;AAEpG,IAAA,kDAAmC,EACjC,mBAAQ,CAAC,WAAW,EAAE,EACtB,WAAW,EACX;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,aAAa,CAAC;IACzB,UAAU,EAAE;QACV,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,sCAAsC;SACpD;KACF;CACF,EACD;IACE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,MAAM,IAAA,4BAAc,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAEhE,OAAO,IAAA,kBAAU,EACf,8BAA8B,EAC9B,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,EACtD,GAAG,EAAE,CAAC;YACJ;gBACE,UAAU,EAAE,aAAa,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE;aACvD;SACF,CACF,CAAC;IACJ,CAAC;IAED,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE;QAC/C,MAAM,cAAc,GAAG,MAAM,IAAA,8BAAgB,EAAC,UAAU,EAAE;YACxD,kBAAkB,EAAE,GAAG;SACxB,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxD,IAAA,+BAAgB,EAAC;YACf,WAAW,EAAE,CAAC,CAAC,SAAS;YACxB,UAAU,EAAE,IAAA,kBAAU,EAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;YAC3C,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC;YACvC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC;YAC5C,cAAc,EAAE,CAAC;SAClB,CAAC,CACH,CAAC;QAEF,MAAM,iBAAiB,GAAG,MAAM,IAAA,6BAAe,EAAC,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAEnF,MAAM,SAAS,GAAgB,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAEnC,OAAO;gBACL,WAAW,EAAE,QAAQ,CAAC,EAAE;gBACxB,aAAa,EAAE,WAAW;gBAC1B,UAAU,EAAE,IAAA,kBAAU,EAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;gBAC/C,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,QAAQ;gBACrB,cAAc,EAAE,MAAM;gBACtB,cAAc,EAAE,MAAM;gBACtB,eAAe,EAAE,KAAK;gBACtB,SAAS,EAAE,QAAQ,GAAG,MAAM;gBAC5B,MAAM,EAAE,EAAE;aACX,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,cAAc,EAAE,GAAG,SAAS,CAAC,CAAC;IAC3C,CAAC;CACF,CACF,CAAC","sourcesContent":["import { IPosition, makeSpotPosition, provideAccountActionsWithCredential } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath, scopeError } from '@yuants/utils';\nimport { getAccountAssets, getAccountInfo, getPositionList, ICredential } from '../api/private-api';\n\nprovideAccountActionsWithCredential<ICredential>(\n Terminal.fromNodeEnv(),\n 'TURBOFLOW',\n {\n type: 'object',\n required: ['private_key'],\n properties: {\n private_key: {\n type: 'string',\n description: 'ED25519 Private Key (base58 encoded)',\n },\n },\n },\n {\n listAccounts: async (credential) => {\n const accountInfo = await getAccountInfo(credential, undefined);\n\n return scopeError(\n 'ListAccountsError::TurboFlow',\n { error: accountInfo.errno, message: accountInfo.msg },\n () => [\n {\n account_id: `turboflow/${accountInfo.data.account_id}`,\n },\n ],\n );\n },\n\n getAccountInfo: async (credential, account_id) => {\n const assetsResponse = await getAccountAssets(credential, {\n fill_coin_sub_info: '1',\n });\n\n const assetPositions = assetsResponse.data.list.map((x) =>\n makeSpotPosition({\n position_id: x.coin_code,\n product_id: encodePath('SPOT', x.coin_name),\n volume: parseFloat(x.available_balance),\n free_volume: parseFloat(x.available_balance),\n closable_price: 1,\n }),\n );\n\n const positionsResponse = await getPositionList(credential, { status: 'Holding' });\n\n const positions: IPosition[] = (positionsResponse.data.data || []).map((position) => {\n const side = position.side === 1 ? 'LONG' : 'SHORT';\n const holdSize = parseFloat(position.hold_size);\n const holdAv = parseFloat(position.hold_av);\n const unpnl = parseFloat(position.unpnl);\n const im = parseFloat(position.im);\n\n return {\n position_id: position.id,\n datasource_id: 'TURBOFLOW',\n product_id: encodePath('PERP', position.symbol),\n direction: side,\n volume: holdSize,\n free_volume: holdSize, // Assuming all volume is free\n position_price: holdAv,\n closable_price: holdAv,\n floating_profit: unpnl,\n valuation: holdSize * holdAv,\n margin: im,\n };\n });\n\n return [...assetPositions, ...positions];\n },\n },\n);\n"]}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { IPosition, makeSpotPosition, provideAccountActionsWithCredential } from '@yuants/data-account';
|
|
2
|
-
import { Terminal } from '@yuants/protocol';
|
|
3
|
-
import { encodePath, scopeError } from '@yuants/utils';
|
|
4
|
-
import { getAccountAssets, getAccountInfo, getPositionList, ICredential } from '../api/private-api';
|
|
5
|
-
|
|
6
|
-
provideAccountActionsWithCredential<ICredential>(
|
|
7
|
-
Terminal.fromNodeEnv(),
|
|
8
|
-
'TURBOFLOW',
|
|
9
|
-
{
|
|
10
|
-
type: 'object',
|
|
11
|
-
required: ['private_key'],
|
|
12
|
-
properties: {
|
|
13
|
-
private_key: {
|
|
14
|
-
type: 'string',
|
|
15
|
-
description: 'ED25519 Private Key (base58 encoded)',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
listAccounts: async (credential) => {
|
|
21
|
-
const accountInfo = await getAccountInfo(credential, undefined);
|
|
22
|
-
|
|
23
|
-
return scopeError(
|
|
24
|
-
'ListAccountsError::TurboFlow',
|
|
25
|
-
{ error: accountInfo.errno, message: accountInfo.msg },
|
|
26
|
-
() => [
|
|
27
|
-
{
|
|
28
|
-
account_id: `turboflow/${accountInfo.data.account_id}`,
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
);
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
getAccountInfo: async (credential, account_id) => {
|
|
35
|
-
const assetsResponse = await getAccountAssets(credential, {
|
|
36
|
-
fill_coin_sub_info: '1',
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const assetPositions = assetsResponse.data.list.map((x) =>
|
|
40
|
-
makeSpotPosition({
|
|
41
|
-
position_id: x.coin_code,
|
|
42
|
-
product_id: encodePath('SPOT', x.coin_name),
|
|
43
|
-
volume: parseFloat(x.available_balance),
|
|
44
|
-
free_volume: parseFloat(x.available_balance),
|
|
45
|
-
closable_price: 1,
|
|
46
|
-
}),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const positionsResponse = await getPositionList(credential, { status: 'Holding' });
|
|
50
|
-
|
|
51
|
-
const positions: IPosition[] = (positionsResponse.data.data || []).map((position) => {
|
|
52
|
-
const side = position.side === 1 ? 'LONG' : 'SHORT';
|
|
53
|
-
const holdSize = parseFloat(position.hold_size);
|
|
54
|
-
const holdAv = parseFloat(position.hold_av);
|
|
55
|
-
const unpnl = parseFloat(position.unpnl);
|
|
56
|
-
const im = parseFloat(position.im);
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
position_id: position.id,
|
|
60
|
-
datasource_id: 'TURBOFLOW',
|
|
61
|
-
product_id: encodePath('PERP', position.symbol),
|
|
62
|
-
direction: side,
|
|
63
|
-
volume: holdSize,
|
|
64
|
-
free_volume: holdSize, // Assuming all volume is free
|
|
65
|
-
position_price: holdAv,
|
|
66
|
-
closable_price: holdAv,
|
|
67
|
-
floating_profit: unpnl,
|
|
68
|
-
valuation: holdSize * holdAv,
|
|
69
|
-
margin: im,
|
|
70
|
-
};
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
return [...assetPositions, ...positions];
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
);
|