public-com-cli 0.1.0
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/LICENSE.md +21 -0
- package/README.md +273 -0
- package/dist/api/accounts.d.ts +12 -0
- package/dist/api/accounts.js +5 -0
- package/dist/api/accounts.js.map +1 -0
- package/dist/api/history.d.ts +31 -0
- package/dist/api/history.js +29 -0
- package/dist/api/history.js.map +1 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.js +9 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/instruments.d.ts +22 -0
- package/dist/api/instruments.js +46 -0
- package/dist/api/instruments.js.map +1 -0
- package/dist/api/market-data.d.ts +48 -0
- package/dist/api/market-data.js +20 -0
- package/dist/api/market-data.js.map +1 -0
- package/dist/api/option-details.d.ts +17 -0
- package/dist/api/option-details.js +9 -0
- package/dist/api/option-details.js.map +1 -0
- package/dist/api/orders.d.ts +125 -0
- package/dist/api/orders.js +43 -0
- package/dist/api/orders.js.map +1 -0
- package/dist/api/portfolio.d.ts +81 -0
- package/dist/api/portfolio.js +19 -0
- package/dist/api/portfolio.js.map +1 -0
- package/dist/api/types.d.ts +12 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/authentication/keychain.d.ts +5 -0
- package/dist/authentication/keychain.js +17 -0
- package/dist/authentication/keychain.js.map +1 -0
- package/dist/authentication/token.d.ts +9 -0
- package/dist/authentication/token.js +35 -0
- package/dist/authentication/token.js.map +1 -0
- package/dist/commands/accounts.d.ts +3 -0
- package/dist/commands/accounts.js +42 -0
- package/dist/commands/accounts.js.map +1 -0
- package/dist/commands/authenticate.d.ts +3 -0
- package/dist/commands/authenticate.js +103 -0
- package/dist/commands/authenticate.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.js +234 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +67 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/history.d.ts +3 -0
- package/dist/commands/history.js +91 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/instrument.d.ts +3 -0
- package/dist/commands/instrument.js +85 -0
- package/dist/commands/instrument.js.map +1 -0
- package/dist/commands/instruments.d.ts +3 -0
- package/dist/commands/instruments.js +118 -0
- package/dist/commands/instruments.js.map +1 -0
- package/dist/commands/option-greeks.d.ts +3 -0
- package/dist/commands/option-greeks.js +66 -0
- package/dist/commands/option-greeks.js.map +1 -0
- package/dist/commands/options-chain.d.ts +3 -0
- package/dist/commands/options-chain.js +110 -0
- package/dist/commands/options-chain.js.map +1 -0
- package/dist/commands/options-expirations.d.ts +3 -0
- package/dist/commands/options-expirations.js +54 -0
- package/dist/commands/options-expirations.js.map +1 -0
- package/dist/commands/order-cancel.d.ts +3 -0
- package/dist/commands/order-cancel.js +37 -0
- package/dist/commands/order-cancel.js.map +1 -0
- package/dist/commands/order-place.d.ts +3 -0
- package/dist/commands/order-place.js +104 -0
- package/dist/commands/order-place.js.map +1 -0
- package/dist/commands/order-preflight.d.ts +3 -0
- package/dist/commands/order-preflight.js +138 -0
- package/dist/commands/order-preflight.js.map +1 -0
- package/dist/commands/order.d.ts +3 -0
- package/dist/commands/order.js +108 -0
- package/dist/commands/order.js.map +1 -0
- package/dist/commands/portfolio.d.ts +3 -0
- package/dist/commands/portfolio.js +107 -0
- package/dist/commands/portfolio.js.map +1 -0
- package/dist/commands/quotes.d.ts +3 -0
- package/dist/commands/quotes.js +86 -0
- package/dist/commands/quotes.js.map +1 -0
- package/dist/helpers/api.d.ts +3 -0
- package/dist/helpers/api.js +5 -0
- package/dist/helpers/api.js.map +1 -0
- package/dist/helpers/config.d.ts +5 -0
- package/dist/helpers/config.js +40 -0
- package/dist/helpers/config.js.map +1 -0
- package/dist/helpers/fetch.d.ts +24 -0
- package/dist/helpers/fetch.js +202 -0
- package/dist/helpers/fetch.js.map +1 -0
- package/dist/helpers/output.d.ts +5 -0
- package/dist/helpers/output.js +13 -0
- package/dist/helpers/output.js.map +1 -0
- package/dist/helpers/validation.d.ts +2 -0
- package/dist/helpers/validation.js +14 -0
- package/dist/helpers/validation.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { InstrumentInfo } from './types.js';
|
|
2
|
+
export type OrderSide = 'BUY' | 'SELL';
|
|
3
|
+
export type OrderType = 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_LIMIT';
|
|
4
|
+
export type TimeInForce = 'DAY' | 'GTD';
|
|
5
|
+
export type MarketSession = 'CORE' | 'EXTENDED';
|
|
6
|
+
export type OpenCloseIndicator = 'OPEN' | 'CLOSE';
|
|
7
|
+
export interface OrderExpiration {
|
|
8
|
+
timeInForce: TimeInForce;
|
|
9
|
+
expirationTime?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface OrderInstrument {
|
|
12
|
+
symbol: string;
|
|
13
|
+
type: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PreflightSingleLegRequest {
|
|
16
|
+
instrument: OrderInstrument;
|
|
17
|
+
orderSide: OrderSide;
|
|
18
|
+
orderType: OrderType;
|
|
19
|
+
expiration: OrderExpiration;
|
|
20
|
+
quantity?: string;
|
|
21
|
+
amount?: string;
|
|
22
|
+
limitPrice?: string;
|
|
23
|
+
stopPrice?: string;
|
|
24
|
+
equityMarketSession?: MarketSession;
|
|
25
|
+
openCloseIndicator?: OpenCloseIndicator;
|
|
26
|
+
}
|
|
27
|
+
export interface RegulatoryFees {
|
|
28
|
+
secFee?: string;
|
|
29
|
+
tafFee?: string;
|
|
30
|
+
orfFee?: string;
|
|
31
|
+
occFee?: string;
|
|
32
|
+
catFee?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface MarginRequirement {
|
|
35
|
+
maintenanceRequirement?: string;
|
|
36
|
+
initialRequirement?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface OptionDetails {
|
|
39
|
+
strikePrice?: string;
|
|
40
|
+
expirationDate?: string;
|
|
41
|
+
optionType?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface PreflightResponse {
|
|
44
|
+
estimatedCommission?: string;
|
|
45
|
+
regulatoryFees?: RegulatoryFees;
|
|
46
|
+
orderValue?: string;
|
|
47
|
+
estimatedCost?: string;
|
|
48
|
+
buyingPowerRequirement?: string;
|
|
49
|
+
estimatedProceeds?: string;
|
|
50
|
+
marginRequirement?: MarginRequirement;
|
|
51
|
+
optionDetails?: OptionDetails;
|
|
52
|
+
}
|
|
53
|
+
export declare function preflightSingleLeg(accountId: string, request: PreflightSingleLegRequest): Promise<PreflightResponse>;
|
|
54
|
+
export interface OrderLegRequest {
|
|
55
|
+
instrument: OrderInstrument;
|
|
56
|
+
orderSide: OrderSide;
|
|
57
|
+
openCloseIndicator?: OpenCloseIndicator;
|
|
58
|
+
ratioQuantity?: number;
|
|
59
|
+
}
|
|
60
|
+
export interface PreflightMultiLegRequest {
|
|
61
|
+
orderType: OrderType;
|
|
62
|
+
expiration: OrderExpiration;
|
|
63
|
+
limitPrice?: string;
|
|
64
|
+
quantity?: string;
|
|
65
|
+
legs: OrderLegRequest[];
|
|
66
|
+
}
|
|
67
|
+
export interface PreflightMultiLegResponse extends PreflightResponse {
|
|
68
|
+
baseSymbol?: string;
|
|
69
|
+
strategyName?: string;
|
|
70
|
+
legs?: Array<{
|
|
71
|
+
instrument: InstrumentInfo;
|
|
72
|
+
side: OrderSide;
|
|
73
|
+
optionDetails?: OptionDetails;
|
|
74
|
+
}>;
|
|
75
|
+
priceIncrement?: {
|
|
76
|
+
increment?: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export declare function preflightMultiLeg(accountId: string, request: PreflightMultiLegRequest): Promise<PreflightMultiLegResponse>;
|
|
80
|
+
export interface PlaceOrderRequest {
|
|
81
|
+
orderId: string;
|
|
82
|
+
instrument: OrderInstrument;
|
|
83
|
+
orderSide: OrderSide;
|
|
84
|
+
orderType: OrderType;
|
|
85
|
+
expiration: OrderExpiration;
|
|
86
|
+
quantity?: string;
|
|
87
|
+
amount?: string;
|
|
88
|
+
limitPrice?: string;
|
|
89
|
+
stopPrice?: string;
|
|
90
|
+
equityMarketSession?: MarketSession;
|
|
91
|
+
openCloseIndicator?: OpenCloseIndicator;
|
|
92
|
+
legs?: OrderLegRequest[];
|
|
93
|
+
}
|
|
94
|
+
export interface PlaceOrderResponse {
|
|
95
|
+
orderId: string;
|
|
96
|
+
}
|
|
97
|
+
export declare function placeOrder(accountId: string, request: PlaceOrderRequest): Promise<PlaceOrderResponse>;
|
|
98
|
+
export type OrderStatus = 'NEW' | 'PENDING' | 'OPEN' | 'FILLED' | 'PARTIALLY_FILLED' | 'CANCELLED' | 'REJECTED' | 'EXPIRED';
|
|
99
|
+
export interface OrderDetails {
|
|
100
|
+
orderId: string;
|
|
101
|
+
instrument: InstrumentInfo;
|
|
102
|
+
createdAt: string;
|
|
103
|
+
type: OrderType;
|
|
104
|
+
side: OrderSide;
|
|
105
|
+
status: OrderStatus;
|
|
106
|
+
quantity?: string;
|
|
107
|
+
notionalValue?: string;
|
|
108
|
+
expiration: OrderExpiration;
|
|
109
|
+
limitPrice?: string;
|
|
110
|
+
stopPrice?: string;
|
|
111
|
+
closedAt?: string;
|
|
112
|
+
openCloseIndicator?: OpenCloseIndicator;
|
|
113
|
+
filledQuantity?: string;
|
|
114
|
+
averagePrice?: string;
|
|
115
|
+
legs?: Array<{
|
|
116
|
+
instrument: InstrumentInfo;
|
|
117
|
+
side: OrderSide;
|
|
118
|
+
openCloseIndicator?: OpenCloseIndicator;
|
|
119
|
+
ratioQuantity?: number;
|
|
120
|
+
}>;
|
|
121
|
+
rejectReason?: string;
|
|
122
|
+
}
|
|
123
|
+
export declare function getOrder(accountId: string, orderId: string): Promise<OrderDetails>;
|
|
124
|
+
export declare function cancelOrder(accountId: string, orderId: string): Promise<void>;
|
|
125
|
+
//# sourceMappingURL=orders.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { authenticatedFetch, ApiError } from '../helpers/fetch.js';
|
|
2
|
+
import { NotFoundError } from './portfolio.js';
|
|
3
|
+
export async function preflightSingleLeg(accountId, request) {
|
|
4
|
+
return authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/preflight/single-leg`, {
|
|
5
|
+
method: 'POST',
|
|
6
|
+
body: request,
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export async function preflightMultiLeg(accountId, request) {
|
|
10
|
+
return authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/preflight/multi-leg`, {
|
|
11
|
+
method: 'POST',
|
|
12
|
+
body: request,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function placeOrder(accountId, request) {
|
|
16
|
+
return authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/order`, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
body: request,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export async function getOrder(accountId, orderId) {
|
|
22
|
+
try {
|
|
23
|
+
return await authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/order/${encodeURIComponent(orderId)}`);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err instanceof ApiError && err.statusCode === 404) {
|
|
27
|
+
throw new NotFoundError(`Order '${orderId}' not found. It may not be indexed yet.`);
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function cancelOrder(accountId, orderId) {
|
|
33
|
+
try {
|
|
34
|
+
await authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/order/${encodeURIComponent(orderId)}`, { method: 'DELETE' });
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof ApiError && err.statusCode === 404) {
|
|
38
|
+
throw new NotFoundError(`Order '${orderId}' not found`);
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../../src/api/orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA8D/C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,OAAkC;IAElC,OAAO,kBAAkB,CACvB,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,uBAAuB,EAC9E;QACE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,OAAO;KACd,CACF,CAAC;AACJ,CAAC;AA8BD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,OAAiC;IAEjC,OAAO,kBAAkB,CACvB,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,sBAAsB,EAC7E;QACE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,OAAO;KACd,CACF,CAAC;AACJ,CAAC;AAqBD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,OAA0B;IAE1B,OAAO,kBAAkB,CACvB,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,QAAQ,EAC/D;QACE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,OAAO;KACd,CACF,CAAC;AACJ,CAAC;AAqCD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,SAAiB,EACjB,OAAe;IAEf,IAAI,CAAC;QACH,OAAO,MAAM,kBAAkB,CAC7B,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,UAAU,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAC/F,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YACtD,MAAM,IAAI,aAAa,CACrB,UAAU,OAAO,yCAAyC,CAC3D,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,kBAAkB,CACtB,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,UAAU,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAC9F,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YACtD,MAAM,IAAI,aAAa,CAAC,UAAU,OAAO,aAAa,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ApiError } from '../helpers/fetch.js';
|
|
2
|
+
import { Instrument } from './types.js';
|
|
3
|
+
export interface BuyingPower {
|
|
4
|
+
cashOnlyBuyingPower: string;
|
|
5
|
+
buyingPower: string;
|
|
6
|
+
optionsBuyingPower: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Equity {
|
|
9
|
+
type: string;
|
|
10
|
+
value: string;
|
|
11
|
+
percentageOfPortfolio: string;
|
|
12
|
+
}
|
|
13
|
+
export interface LastPrice {
|
|
14
|
+
lastPrice: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
}
|
|
17
|
+
export interface Gain {
|
|
18
|
+
gainValue: string;
|
|
19
|
+
gainPercentage: string;
|
|
20
|
+
timestamp?: string;
|
|
21
|
+
lastUpdate?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CostBasis {
|
|
24
|
+
totalCost: string;
|
|
25
|
+
unitCost: string;
|
|
26
|
+
gainValue: string;
|
|
27
|
+
gainPercentage: string;
|
|
28
|
+
lastUpdate: string;
|
|
29
|
+
}
|
|
30
|
+
export interface Position {
|
|
31
|
+
instrument: Instrument;
|
|
32
|
+
quantity: string;
|
|
33
|
+
openedAt: string;
|
|
34
|
+
currentValue: string;
|
|
35
|
+
percentOfPortfolio: string;
|
|
36
|
+
lastPrice: LastPrice;
|
|
37
|
+
instrumentGain: Gain;
|
|
38
|
+
positionDailyGain: Gain;
|
|
39
|
+
costBasis: CostBasis;
|
|
40
|
+
}
|
|
41
|
+
export interface OrderLeg {
|
|
42
|
+
instrument: Instrument;
|
|
43
|
+
side: string;
|
|
44
|
+
openCloseIndicator: string;
|
|
45
|
+
ratioQuantity: number;
|
|
46
|
+
}
|
|
47
|
+
export interface Order {
|
|
48
|
+
orderId: string;
|
|
49
|
+
instrument: Instrument;
|
|
50
|
+
createdAt: string;
|
|
51
|
+
type: string;
|
|
52
|
+
side: string;
|
|
53
|
+
status: string;
|
|
54
|
+
quantity: string;
|
|
55
|
+
notionalValue: string;
|
|
56
|
+
expiration: {
|
|
57
|
+
timeInForce: string;
|
|
58
|
+
expirationTime: string;
|
|
59
|
+
};
|
|
60
|
+
limitPrice?: string;
|
|
61
|
+
stopPrice?: string;
|
|
62
|
+
closedAt?: string;
|
|
63
|
+
openCloseIndicator: string;
|
|
64
|
+
filledQuantity: string;
|
|
65
|
+
averagePrice: string;
|
|
66
|
+
legs?: OrderLeg[];
|
|
67
|
+
rejectReason?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface Portfolio {
|
|
70
|
+
accountId: string;
|
|
71
|
+
accountType: string;
|
|
72
|
+
buyingPower: BuyingPower;
|
|
73
|
+
equity: Equity[];
|
|
74
|
+
positions: Position[];
|
|
75
|
+
orders: Order[];
|
|
76
|
+
}
|
|
77
|
+
export declare class NotFoundError extends ApiError {
|
|
78
|
+
constructor(message: string);
|
|
79
|
+
}
|
|
80
|
+
export declare function getPortfolio(accountId: string): Promise<Portfolio>;
|
|
81
|
+
//# sourceMappingURL=portfolio.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { authenticatedFetch, ApiError } from '../helpers/fetch.js';
|
|
2
|
+
export class NotFoundError extends ApiError {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message, 404, false);
|
|
5
|
+
this.name = 'NotFoundError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export async function getPortfolio(accountId) {
|
|
9
|
+
try {
|
|
10
|
+
return await authenticatedFetch(`userapigateway/trading/${encodeURIComponent(accountId)}/portfolio/v2`);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
if (err instanceof ApiError && err.statusCode === 404) {
|
|
14
|
+
throw new NotFoundError(`Account '${accountId}' not found`);
|
|
15
|
+
}
|
|
16
|
+
throw err;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=portfolio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio.js","sourceRoot":"","sources":["../../src/api/portfolio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAsFnE,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,IAAI,CAAC;QACH,OAAO,MAAM,kBAAkB,CAC7B,0BAA0B,kBAAkB,CAAC,SAAS,CAAC,eAAe,CACvE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YACtD,MAAM,IAAI,aAAa,CAAC,YAAY,SAAS,aAAa,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SecurityType = 'EQUITY' | 'ETF' | 'ADR' | 'CRYPTO' | 'OPTION' | 'MULTI_LEG_INSTRUMENT' | 'ALT' | 'TREASURY' | 'BOND' | 'INDEX' | 'UNDERLYING_SECURITY_FOR_INDEX_OPTION';
|
|
2
|
+
export type TradingStatus = 'BUY_AND_SELL' | 'BUY_ONLY' | 'SELL_ONLY' | 'LIQUIDATION_ONLY' | 'DISABLED' | 'NONE';
|
|
3
|
+
export interface Instrument {
|
|
4
|
+
symbol: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
type: string;
|
|
7
|
+
}
|
|
8
|
+
export interface InstrumentInfo {
|
|
9
|
+
symbol: string;
|
|
10
|
+
type: SecurityType;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function storeApiKey(apiKey: string): Promise<void>;
|
|
2
|
+
export declare function getApiKey(): Promise<string | null>;
|
|
3
|
+
export declare function deleteApiKey(): Promise<boolean>;
|
|
4
|
+
export declare function hasApiKey(): Promise<boolean>;
|
|
5
|
+
//# sourceMappingURL=keychain.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import keytar from 'keytar';
|
|
2
|
+
const SERVICE_NAME = 'public-com-cli';
|
|
3
|
+
const ACCOUNT_NAME = 'api-key';
|
|
4
|
+
export async function storeApiKey(apiKey) {
|
|
5
|
+
await keytar.setPassword(SERVICE_NAME, ACCOUNT_NAME, apiKey);
|
|
6
|
+
}
|
|
7
|
+
export async function getApiKey() {
|
|
8
|
+
return keytar.getPassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
9
|
+
}
|
|
10
|
+
export async function deleteApiKey() {
|
|
11
|
+
return keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
12
|
+
}
|
|
13
|
+
export async function hasApiKey() {
|
|
14
|
+
const key = await getApiKey();
|
|
15
|
+
return key !== null;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=keychain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/authentication/keychain.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,YAAY,GAAG,gBAAgB,CAAC;AACtC,MAAM,YAAY,GAAG,SAAS,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,OAAO,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;IAC9B,OAAO,GAAG,KAAK,IAAI,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface TokenData {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function storeToken(accessToken: string, validityInMinutes: number): Promise<void>;
|
|
6
|
+
export declare function getToken(): Promise<TokenData | null>;
|
|
7
|
+
export declare function deleteToken(): Promise<void>;
|
|
8
|
+
export declare function isTokenExpired(expiresAt: number): boolean;
|
|
9
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import keytar from 'keytar';
|
|
2
|
+
const SERVICE_NAME = 'public-com-cli';
|
|
3
|
+
const ACCESS_TOKEN_ACCOUNT = 'access-token';
|
|
4
|
+
const EXPIRES_AT_ACCOUNT = 'expires-at';
|
|
5
|
+
export async function storeToken(accessToken, validityInMinutes) {
|
|
6
|
+
const expiresAt = Date.now() + validityInMinutes * 60 * 1000;
|
|
7
|
+
await Promise.all([
|
|
8
|
+
keytar.setPassword(SERVICE_NAME, ACCESS_TOKEN_ACCOUNT, accessToken),
|
|
9
|
+
keytar.setPassword(SERVICE_NAME, EXPIRES_AT_ACCOUNT, expiresAt.toString()),
|
|
10
|
+
]);
|
|
11
|
+
}
|
|
12
|
+
export async function getToken() {
|
|
13
|
+
const [accessToken, expiresAtStr] = await Promise.all([
|
|
14
|
+
keytar.getPassword(SERVICE_NAME, ACCESS_TOKEN_ACCOUNT),
|
|
15
|
+
keytar.getPassword(SERVICE_NAME, EXPIRES_AT_ACCOUNT),
|
|
16
|
+
]);
|
|
17
|
+
if (!accessToken || !expiresAtStr) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
accessToken,
|
|
22
|
+
expiresAt: parseInt(expiresAtStr, 10),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export async function deleteToken() {
|
|
26
|
+
await Promise.all([
|
|
27
|
+
keytar.deletePassword(SERVICE_NAME, ACCESS_TOKEN_ACCOUNT),
|
|
28
|
+
keytar.deletePassword(SERVICE_NAME, EXPIRES_AT_ACCOUNT),
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
31
|
+
export function isTokenExpired(expiresAt) {
|
|
32
|
+
const bufferMs = 60 * 1000;
|
|
33
|
+
return Date.now() >= expiresAt - bufferMs;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/authentication/token.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,YAAY,GAAG,gBAAgB,CAAC;AACtC,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAC5C,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAOxC,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,WAAmB,EACnB,iBAAyB;IAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;IAE7D,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,oBAAoB,EAAE,WAAW,CAAC;QACnE,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC;KAC3E,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,oBAAoB,CAAC;QACtD,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,kBAAkB,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,WAAW;QACX,SAAS,EAAE,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,oBAAoB,CAAC;QACzD,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC;KACxD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,GAAG,QAAQ,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getAccounts, ApiError, AuthenticationError, RateLimitError, } from '../helpers/api.js';
|
|
3
|
+
import { success, error, info } from '../helpers/output.js';
|
|
4
|
+
export function createAccountsCommand() {
|
|
5
|
+
const accounts = new Command('accounts')
|
|
6
|
+
.description('List your trading accounts')
|
|
7
|
+
.action(async () => {
|
|
8
|
+
try {
|
|
9
|
+
const { accounts } = await getAccounts();
|
|
10
|
+
if (accounts.length === 0) {
|
|
11
|
+
info('No accounts found.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
success(`Found ${accounts.length} account${accounts.length > 1 ? 's' : ''}:\n`);
|
|
15
|
+
for (const account of accounts) {
|
|
16
|
+
console.log(` Account ID: ${account.accountId}`);
|
|
17
|
+
console.log(` Account Type: ${account.accountType}`);
|
|
18
|
+
console.log(` Brokerage Type: ${account.brokerageAccountType}`);
|
|
19
|
+
console.log(` Options Level: ${account.optionsLevel}`);
|
|
20
|
+
console.log(` Trade Permissions: ${account.tradePermissions}`);
|
|
21
|
+
console.log();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (err instanceof AuthenticationError) {
|
|
26
|
+
error(err.message);
|
|
27
|
+
}
|
|
28
|
+
else if (err instanceof RateLimitError) {
|
|
29
|
+
error('Too many requests. Please try again later.');
|
|
30
|
+
}
|
|
31
|
+
else if (err instanceof ApiError) {
|
|
32
|
+
error(`Failed to fetch accounts: ${err.message}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
error(`Failed to fetch accounts: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
36
|
+
}
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return accounts;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/commands/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SACrC,WAAW,CAAC,4BAA4B,CAAC;SACzC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;YAEzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YAED,OAAO,CACL,SAAS,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CACvE,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;gBACzD,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC3D,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;gBACpE,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC5D,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;gBAChE,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;gBACvC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;iBAAM,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;gBACzC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YACtD,CAAC;iBAAM,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBACnC,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,KAAK,CACH,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACpF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { storeApiKey, deleteApiKey, hasApiKey, } from '../authentication/keychain.js';
|
|
3
|
+
import { success, error, info } from '../helpers/output.js';
|
|
4
|
+
import { isValidApiKey } from '../helpers/validation.js';
|
|
5
|
+
import { validateApiKey, clearTokens, getAccounts, ApiError, AuthenticationError, RateLimitError, } from '../helpers/api.js';
|
|
6
|
+
export function createAuthenticateCommand() {
|
|
7
|
+
const auth = new Command('auth').description('Manage authentication with Public.com API');
|
|
8
|
+
auth
|
|
9
|
+
.command('login')
|
|
10
|
+
.description('Authenticate with your Public.com API key')
|
|
11
|
+
.requiredOption('-k, --key <apiKey>', 'Your Public.com API key')
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
try {
|
|
14
|
+
const apiKey = options.key.trim();
|
|
15
|
+
if (!isValidApiKey(apiKey)) {
|
|
16
|
+
error('Invalid API key format. API key must be at least 16 characters.');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
info('Validating API key...');
|
|
20
|
+
await validateApiKey(apiKey);
|
|
21
|
+
await storeApiKey(apiKey);
|
|
22
|
+
success('Authenticated successfully. API key stored securely.');
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (err instanceof AuthenticationError) {
|
|
26
|
+
error(`Authentication failed: ${err.message}`);
|
|
27
|
+
}
|
|
28
|
+
else if (err instanceof RateLimitError) {
|
|
29
|
+
error('Too many requests. Please try again later.');
|
|
30
|
+
}
|
|
31
|
+
else if (err instanceof ApiError) {
|
|
32
|
+
error(`API error: ${err.message}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
error(`Failed to authenticate: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
36
|
+
}
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
auth
|
|
41
|
+
.command('logout')
|
|
42
|
+
.description('Remove stored credentials from system keychain')
|
|
43
|
+
.action(async () => {
|
|
44
|
+
try {
|
|
45
|
+
const hadKey = await hasApiKey();
|
|
46
|
+
await Promise.all([deleteApiKey(), clearTokens()]);
|
|
47
|
+
if (hadKey) {
|
|
48
|
+
success('Logged out successfully. Credentials removed.');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
info('No credentials were stored.');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
error(`Failed to logout: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
auth
|
|
60
|
+
.command('status')
|
|
61
|
+
.description('Check authentication status and display account info')
|
|
62
|
+
.action(async () => {
|
|
63
|
+
try {
|
|
64
|
+
const hasKey = await hasApiKey();
|
|
65
|
+
if (!hasKey) {
|
|
66
|
+
info('Not authenticated. Run "public-cli auth login -k <key>" to authenticate.');
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
info('Fetching account information...');
|
|
70
|
+
const { accounts } = await getAccounts();
|
|
71
|
+
success('Authenticated\n');
|
|
72
|
+
if (accounts.length === 0) {
|
|
73
|
+
info('No accounts found.');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
console.log('Accounts:');
|
|
77
|
+
for (const account of accounts) {
|
|
78
|
+
console.log(`\n Account ID: ${account.accountId}`);
|
|
79
|
+
console.log(` Account Type: ${account.accountType}`);
|
|
80
|
+
console.log(` Brokerage Type: ${account.brokerageAccountType}`);
|
|
81
|
+
console.log(` Options Level: ${account.optionsLevel}`);
|
|
82
|
+
console.log(` Trade Permissions: ${account.tradePermissions}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
if (err instanceof AuthenticationError) {
|
|
87
|
+
error(`Authentication failed: ${err.message}`);
|
|
88
|
+
}
|
|
89
|
+
else if (err instanceof RateLimitError) {
|
|
90
|
+
error('Too many requests. Please try again later.');
|
|
91
|
+
}
|
|
92
|
+
else if (err instanceof ApiError) {
|
|
93
|
+
error(`Failed to fetch account info: ${err.message}`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
error(`Failed to check status: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
97
|
+
}
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return auth;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=authenticate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/commands/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,SAAS,GACV,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,MAAM,UAAU,yBAAyB;IACvC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAC1C,2CAA2C,CAC5C,CAAC;IAEF,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,2CAA2C,CAAC;SACxD,cAAc,CAAC,oBAAoB,EAAE,yBAAyB,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,OAAwB,EAAE,EAAE;QACzC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAElC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,KAAK,CACH,iEAAiE,CAClE,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAE9B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;YAE1B,OAAO,CAAC,sDAAsD,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;gBACvC,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACjD,CAAC;iBAAM,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;gBACzC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YACtD,CAAC;iBAAM,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBACnC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,KAAK,CACH,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAClF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YAEjC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;YAEnD,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,+CAA+C,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CACH,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAC5E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,CACF,0EAA0E,CAC3E,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAExC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;YAEzC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAE3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,yBAAyB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;gBACnE,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC3D,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;gBACvC,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACjD,CAAC;iBAAM,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;gBACzC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YACtD,CAAC;iBAAM,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBACnC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,KAAK,CACH,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAClF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,IAAI,CAAC;AACd,CAAC"}
|