@dxos/credentials 0.8.4-main.b97322e → 0.8.4-main.bc674ce
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/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
- package/dist/lib/browser/index.mjs +100 -58
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +100 -58
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/credentials/assertions.d.ts +1 -1
- package/dist/types/src/credentials/assertions.d.ts.map +1 -1
- package/dist/types/src/credentials/credential-factory.d.ts +4 -4
- package/dist/types/src/credentials/credential-factory.d.ts.map +1 -1
- package/dist/types/src/credentials/credential-generator.d.ts.map +1 -1
- package/dist/types/src/did.d.ts +1 -1
- package/dist/types/src/did.d.ts.map +1 -1
- package/dist/types/src/presentations/presentation.d.ts.map +1 -1
- package/dist/types/src/presentations/verifier.d.ts.map +1 -1
- package/dist/types/src/processor/device-state-machine.d.ts +2 -2
- package/dist/types/src/processor/device-state-machine.d.ts.map +1 -1
- package/dist/types/src/processor/profile-state-machine.d.ts +2 -2
- package/dist/types/src/processor/profile-state-machine.d.ts.map +1 -1
- package/dist/types/src/state-machine/member-state-machine.d.ts +1 -1
- package/dist/types/src/state-machine/member-state-machine.d.ts.map +1 -1
- package/dist/types/src/state-machine/space-state-machine.d.ts +1 -1
- package/dist/types/src/state-machine/space-state-machine.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -18
- package/src/credentials/assertions.ts +1 -1
- package/src/credentials/credential-factory.ts +5 -5
- package/src/credentials/credential-generator.ts +1 -1
- package/src/did.ts +2 -2
- package/src/presentations/json-encoding.test.ts +3 -1
- package/src/presentations/presentation.ts +2 -1
- package/src/presentations/verifier.test.ts +2 -1
- package/src/presentations/verifier.ts +2 -1
- package/src/processor/device-state-machine.ts +4 -3
- package/src/processor/profile-state-machine.ts +4 -3
- package/src/state-machine/invitation-state-machine.test.ts +3 -2
- package/src/state-machine/member-state-machine.test.ts +2 -1
- package/src/state-machine/member-state-machine.ts +1 -1
- package/src/state-machine/space-state-machine.test.ts +2 -1
- package/src/state-machine/space-state-machine.ts +14 -8
- package/vitest.config.ts +7 -6
- package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
|
Binary file
|
|
@@ -2,7 +2,7 @@ import "@dxos/node-std/globals";
|
|
|
2
2
|
|
|
3
3
|
// src/did.ts
|
|
4
4
|
import { subtleCrypto } from "@dxos/crypto";
|
|
5
|
-
import {
|
|
5
|
+
import { IdentityDid, PublicKey } from "@dxos/keys";
|
|
6
6
|
import { ComplexMap } from "@dxos/util";
|
|
7
7
|
var IDENTITY_DIDS_CACHE = new ComplexMap(PublicKey.hash);
|
|
8
8
|
var createDidFromIdentityKey = async (identityKey) => {
|
|
@@ -317,6 +317,9 @@ var createCredentialSignerWithChain = (signer, chain, signingKey) => ({
|
|
|
317
317
|
import { AdmittedFeed, SpaceMember } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
318
318
|
import { Timeframe as Timeframe2 } from "@dxos/timeframe";
|
|
319
319
|
var CredentialGenerator = class {
|
|
320
|
+
_signer;
|
|
321
|
+
_identityKey;
|
|
322
|
+
_deviceKey;
|
|
320
323
|
constructor(_signer, _identityKey, _deviceKey) {
|
|
321
324
|
this._signer = _signer;
|
|
322
325
|
this._identityKey = _identityKey;
|
|
@@ -637,10 +640,11 @@ import { PublicKey as PublicKey4 } from "@dxos/keys";
|
|
|
637
640
|
import { Callback, ComplexMap as ComplexMap2 } from "@dxos/util";
|
|
638
641
|
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/feed-state-machine.ts";
|
|
639
642
|
var FeedStateMachine = class {
|
|
643
|
+
_spaceKey;
|
|
644
|
+
_feeds = new ComplexMap2(PublicKey4.hash);
|
|
645
|
+
onFeedAdmitted = new Callback();
|
|
640
646
|
constructor(_spaceKey) {
|
|
641
647
|
this._spaceKey = _spaceKey;
|
|
642
|
-
this._feeds = new ComplexMap2(PublicKey4.hash);
|
|
643
|
-
this.onFeedAdmitted = new Callback();
|
|
644
648
|
}
|
|
645
649
|
get feeds() {
|
|
646
650
|
return this._feeds;
|
|
@@ -686,13 +690,11 @@ var FeedStateMachine = class {
|
|
|
686
690
|
import { PublicKey as PublicKey5 } from "@dxos/keys";
|
|
687
691
|
import { Callback as Callback2, ComplexMap as ComplexMap3, ComplexSet } from "@dxos/util";
|
|
688
692
|
var InvitationStateMachine = class {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
this.onDelegatedInvitationRemoved = new Callback2();
|
|
695
|
-
}
|
|
693
|
+
_invitations = new ComplexMap3(PublicKey5.hash);
|
|
694
|
+
_redeemedInvitationCredentialIds = new ComplexSet(PublicKey5.hash);
|
|
695
|
+
_cancelledInvitationCredentialIds = new ComplexSet(PublicKey5.hash);
|
|
696
|
+
onDelegatedInvitation = new Callback2();
|
|
697
|
+
onDelegatedInvitationRemoved = new Callback2();
|
|
696
698
|
get invitations() {
|
|
697
699
|
return this._invitations;
|
|
698
700
|
}
|
|
@@ -766,23 +768,40 @@ import { log } from "@dxos/log";
|
|
|
766
768
|
import { Callback as Callback3, ComplexMap as ComplexMap4, ComplexSet as ComplexSet2 } from "@dxos/util";
|
|
767
769
|
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/halo/credentials/src/graph/credential-graph.ts";
|
|
768
770
|
var CredentialGraph = class {
|
|
771
|
+
_stateHandler;
|
|
772
|
+
/**
|
|
773
|
+
* Local ids are used during traversals.
|
|
774
|
+
*/
|
|
775
|
+
_vertexIdGenerator = 1;
|
|
776
|
+
/**
|
|
777
|
+
* All credentials without parent references are connected to the root.
|
|
778
|
+
*/
|
|
779
|
+
_root = {
|
|
780
|
+
id: -1,
|
|
781
|
+
parents: [],
|
|
782
|
+
children: []
|
|
783
|
+
};
|
|
784
|
+
/**
|
|
785
|
+
* A credential which is not a parent of any other credential has the sentinel as a child.
|
|
786
|
+
* Sentinel is a virtual merge-point of all credentials.
|
|
787
|
+
*/
|
|
788
|
+
_sentinel = {
|
|
789
|
+
id: -2,
|
|
790
|
+
parents: [],
|
|
791
|
+
children: []
|
|
792
|
+
};
|
|
793
|
+
/**
|
|
794
|
+
* Vertex references are used for fast credential inserts into the graph.
|
|
795
|
+
*/
|
|
796
|
+
_vertexByCredentialId = new ComplexMap4(PublicKey6.hash);
|
|
797
|
+
/**
|
|
798
|
+
* The current state of the graph.
|
|
799
|
+
*/
|
|
800
|
+
_subjectToVertex = new ComplexMap4(PublicKey6.hash);
|
|
801
|
+
_subjectToState = new ComplexMap4(PublicKey6.hash);
|
|
802
|
+
onSubjectStateChanged = new Callback3();
|
|
769
803
|
constructor(_stateHandler) {
|
|
770
804
|
this._stateHandler = _stateHandler;
|
|
771
|
-
this._vertexIdGenerator = 1;
|
|
772
|
-
this._root = {
|
|
773
|
-
id: -1,
|
|
774
|
-
parents: [],
|
|
775
|
-
children: []
|
|
776
|
-
};
|
|
777
|
-
this._sentinel = {
|
|
778
|
-
id: -2,
|
|
779
|
-
parents: [],
|
|
780
|
-
children: []
|
|
781
|
-
};
|
|
782
|
-
this._vertexByCredentialId = new ComplexMap4(PublicKey6.hash);
|
|
783
|
-
this._subjectToVertex = new ComplexMap4(PublicKey6.hash);
|
|
784
|
-
this._subjectToState = new ComplexMap4(PublicKey6.hash);
|
|
785
|
-
this.onSubjectStateChanged = new Callback3();
|
|
786
805
|
}
|
|
787
806
|
getSubjectState(subjectId) {
|
|
788
807
|
return this._subjectToState.get(subjectId);
|
|
@@ -1317,11 +1336,13 @@ var toChosenPath = (path) => {
|
|
|
1317
1336
|
// src/state-machine/member-state-machine.ts
|
|
1318
1337
|
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/member-state-machine.ts";
|
|
1319
1338
|
var MemberStateMachine = class {
|
|
1339
|
+
_spaceKey;
|
|
1340
|
+
_ownerKey;
|
|
1341
|
+
_memberProfiles = new ComplexMap5(PublicKey7.hash);
|
|
1342
|
+
_hashgraph = new CredentialGraph(this);
|
|
1343
|
+
onMemberRoleChanged = this._hashgraph.onSubjectStateChanged;
|
|
1320
1344
|
constructor(_spaceKey) {
|
|
1321
1345
|
this._spaceKey = _spaceKey;
|
|
1322
|
-
this._memberProfiles = new ComplexMap5(PublicKey7.hash);
|
|
1323
|
-
this._hashgraph = new CredentialGraph(this);
|
|
1324
|
-
this.onMemberRoleChanged = this._hashgraph.onSubjectStateChanged;
|
|
1325
1346
|
}
|
|
1326
1347
|
get creator() {
|
|
1327
1348
|
return this._ownerKey && this._hashgraph.getSubjectState(this._ownerKey);
|
|
@@ -1469,20 +1490,26 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
1469
1490
|
}
|
|
1470
1491
|
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/space-state-machine.ts";
|
|
1471
1492
|
var SpaceStateMachine = class {
|
|
1493
|
+
_spaceKey;
|
|
1494
|
+
_members;
|
|
1495
|
+
_feeds;
|
|
1496
|
+
_invitations = new InvitationStateMachine();
|
|
1497
|
+
_credentials = [];
|
|
1498
|
+
_credentialsById = new ComplexMap6(PublicKey8.hash);
|
|
1499
|
+
_processedCredentials = new ComplexSet3(PublicKey8.hash);
|
|
1500
|
+
_genesisCredential;
|
|
1501
|
+
_credentialProcessors = [];
|
|
1502
|
+
onCredentialProcessed = new Callback4();
|
|
1503
|
+
onMemberRoleChanged;
|
|
1504
|
+
onFeedAdmitted;
|
|
1505
|
+
onDelegatedInvitation = this._invitations.onDelegatedInvitation;
|
|
1506
|
+
onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
|
|
1472
1507
|
constructor(_spaceKey) {
|
|
1473
1508
|
this._spaceKey = _spaceKey;
|
|
1474
1509
|
this._members = new MemberStateMachine(this._spaceKey);
|
|
1475
1510
|
this._feeds = new FeedStateMachine(this._spaceKey);
|
|
1476
|
-
this._invitations = new InvitationStateMachine();
|
|
1477
|
-
this._credentials = [];
|
|
1478
|
-
this._credentialsById = new ComplexMap6(PublicKey8.hash);
|
|
1479
|
-
this._processedCredentials = new ComplexSet3(PublicKey8.hash);
|
|
1480
|
-
this._credentialProcessors = [];
|
|
1481
|
-
this.onCredentialProcessed = new Callback4();
|
|
1482
1511
|
this.onMemberRoleChanged = this._members.onMemberRoleChanged;
|
|
1483
1512
|
this.onFeedAdmitted = this._feeds.onFeedAdmitted;
|
|
1484
|
-
this.onDelegatedInvitation = this._invitations.onDelegatedInvitation;
|
|
1485
|
-
this.onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
|
|
1486
1513
|
}
|
|
1487
1514
|
get creator() {
|
|
1488
1515
|
return this._members.creator;
|
|
@@ -1546,7 +1573,7 @@ var SpaceStateMachine = class {
|
|
|
1546
1573
|
if (result.kind !== "pass") {
|
|
1547
1574
|
log3.warn(`Invalid credential: ${result.errors.join(", ")}`, void 0, {
|
|
1548
1575
|
F: __dxlog_file6,
|
|
1549
|
-
L:
|
|
1576
|
+
L: 162,
|
|
1550
1577
|
S: this,
|
|
1551
1578
|
C: (f, a) => f(...a)
|
|
1552
1579
|
});
|
|
@@ -1559,7 +1586,7 @@ var SpaceStateMachine = class {
|
|
|
1559
1586
|
if (this._genesisCredential) {
|
|
1560
1587
|
log3.warn("Space already has a genesis credential.", void 0, {
|
|
1561
1588
|
F: __dxlog_file6,
|
|
1562
|
-
L:
|
|
1589
|
+
L: 171,
|
|
1563
1590
|
S: this,
|
|
1564
1591
|
C: (f, a) => f(...a)
|
|
1565
1592
|
});
|
|
@@ -1568,7 +1595,7 @@ var SpaceStateMachine = class {
|
|
|
1568
1595
|
if (!credential.issuer.equals(this._spaceKey)) {
|
|
1569
1596
|
log3.warn("Space genesis credential must be issued by space.", void 0, {
|
|
1570
1597
|
F: __dxlog_file6,
|
|
1571
|
-
L:
|
|
1598
|
+
L: 175,
|
|
1572
1599
|
S: this,
|
|
1573
1600
|
C: (f, a) => f(...a)
|
|
1574
1601
|
});
|
|
@@ -1577,7 +1604,7 @@ var SpaceStateMachine = class {
|
|
|
1577
1604
|
if (!credential.subject.id.equals(this._spaceKey)) {
|
|
1578
1605
|
log3.warn("Space genesis credential must be issued to space.", void 0, {
|
|
1579
1606
|
F: __dxlog_file6,
|
|
1580
|
-
L:
|
|
1607
|
+
L: 179,
|
|
1581
1608
|
S: this,
|
|
1582
1609
|
C: (f, a) => f(...a)
|
|
1583
1610
|
});
|
|
@@ -1593,7 +1620,7 @@ var SpaceStateMachine = class {
|
|
|
1593
1620
|
if (!this._genesisCredential) {
|
|
1594
1621
|
log3.warn("Space must have a genesis credential before adding members.", void 0, {
|
|
1595
1622
|
F: __dxlog_file6,
|
|
1596
|
-
L:
|
|
1623
|
+
L: 192,
|
|
1597
1624
|
S: this,
|
|
1598
1625
|
C: (f, a) => f(...a)
|
|
1599
1626
|
});
|
|
@@ -1602,7 +1629,7 @@ var SpaceStateMachine = class {
|
|
|
1602
1629
|
if (!this._canInviteNewMembers(credential.issuer)) {
|
|
1603
1630
|
log3.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
|
|
1604
1631
|
F: __dxlog_file6,
|
|
1605
|
-
L:
|
|
1632
|
+
L: 196,
|
|
1606
1633
|
S: this,
|
|
1607
1634
|
C: (f, a) => f(...a)
|
|
1608
1635
|
});
|
|
@@ -1616,7 +1643,7 @@ var SpaceStateMachine = class {
|
|
|
1616
1643
|
if (!this._genesisCredential) {
|
|
1617
1644
|
log3.warn("Space must have a genesis credential before adding members.", void 0, {
|
|
1618
1645
|
F: __dxlog_file6,
|
|
1619
|
-
L:
|
|
1646
|
+
L: 207,
|
|
1620
1647
|
S: this,
|
|
1621
1648
|
C: (f, a) => f(...a)
|
|
1622
1649
|
});
|
|
@@ -1629,7 +1656,7 @@ var SpaceStateMachine = class {
|
|
|
1629
1656
|
if (!this._genesisCredential) {
|
|
1630
1657
|
log3.warn("Space must have a genesis credential before admitting feeds.", void 0, {
|
|
1631
1658
|
F: __dxlog_file6,
|
|
1632
|
-
L:
|
|
1659
|
+
L: 217,
|
|
1633
1660
|
S: this,
|
|
1634
1661
|
C: (f, a) => f(...a)
|
|
1635
1662
|
});
|
|
@@ -1643,7 +1670,7 @@ var SpaceStateMachine = class {
|
|
|
1643
1670
|
if (!this._canInviteNewMembers(credential.issuer)) {
|
|
1644
1671
|
log3.warn(`Invalid invitation, space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
|
|
1645
1672
|
F: __dxlog_file6,
|
|
1646
|
-
L:
|
|
1673
|
+
L: 228,
|
|
1647
1674
|
S: this,
|
|
1648
1675
|
C: (f, a) => f(...a)
|
|
1649
1676
|
});
|
|
@@ -1684,15 +1711,24 @@ _ts_decorate([
|
|
|
1684
1711
|
synchronized
|
|
1685
1712
|
], SpaceStateMachine.prototype, "process", null);
|
|
1686
1713
|
var CredentialConsumer = class {
|
|
1714
|
+
processor;
|
|
1715
|
+
_onOpen;
|
|
1716
|
+
_onClose;
|
|
1717
|
+
_ctx = new Context(void 0, {
|
|
1718
|
+
F: __dxlog_file6,
|
|
1719
|
+
L: 273
|
|
1720
|
+
});
|
|
1721
|
+
/**
|
|
1722
|
+
* @internal
|
|
1723
|
+
* Processor is ready to process live credentials.
|
|
1724
|
+
* NOTE: Setting this flag before all existing credentials are processed will cause them to be processed out of order.
|
|
1725
|
+
* Set externally.
|
|
1726
|
+
*/
|
|
1727
|
+
_isReadyForLiveCredentials = false;
|
|
1687
1728
|
constructor(processor, _onOpen, _onClose) {
|
|
1688
1729
|
this.processor = processor;
|
|
1689
1730
|
this._onOpen = _onOpen;
|
|
1690
1731
|
this._onClose = _onClose;
|
|
1691
|
-
this._ctx = new Context(void 0, {
|
|
1692
|
-
F: __dxlog_file6,
|
|
1693
|
-
L: 267
|
|
1694
|
-
});
|
|
1695
|
-
this._isReadyForLiveCredentials = false;
|
|
1696
1732
|
}
|
|
1697
1733
|
/**
|
|
1698
1734
|
* @internal
|
|
@@ -1722,10 +1758,13 @@ import { log as log4 } from "@dxos/log";
|
|
|
1722
1758
|
import { ComplexMap as ComplexMap7 } from "@dxos/util";
|
|
1723
1759
|
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/halo/credentials/src/processor/device-state-machine.ts";
|
|
1724
1760
|
var DeviceStateMachine = class {
|
|
1761
|
+
_params;
|
|
1762
|
+
// TODO(burdon): Return values via getter.
|
|
1763
|
+
authorizedDeviceKeys = new ComplexMap7(PublicKey9.hash);
|
|
1764
|
+
deviceChainReady = new Trigger();
|
|
1765
|
+
deviceCredentialChain;
|
|
1725
1766
|
constructor(_params) {
|
|
1726
1767
|
this._params = _params;
|
|
1727
|
-
this.authorizedDeviceKeys = new ComplexMap7(PublicKey9.hash);
|
|
1728
|
-
this.deviceChainReady = new Trigger();
|
|
1729
1768
|
}
|
|
1730
1769
|
async processCredential(credential) {
|
|
1731
1770
|
log4("processing credential...", {
|
|
@@ -1734,7 +1773,7 @@ var DeviceStateMachine = class {
|
|
|
1734
1773
|
credential
|
|
1735
1774
|
}, {
|
|
1736
1775
|
F: __dxlog_file7,
|
|
1737
|
-
L:
|
|
1776
|
+
L: 36,
|
|
1738
1777
|
S: this,
|
|
1739
1778
|
C: (f, a) => f(...a)
|
|
1740
1779
|
});
|
|
@@ -1754,7 +1793,7 @@ var DeviceStateMachine = class {
|
|
|
1754
1793
|
size: this.authorizedDeviceKeys.size
|
|
1755
1794
|
}, {
|
|
1756
1795
|
F: __dxlog_file7,
|
|
1757
|
-
L:
|
|
1796
|
+
L: 56,
|
|
1758
1797
|
S: this,
|
|
1759
1798
|
C: (f, a) => f(...a)
|
|
1760
1799
|
});
|
|
@@ -1764,7 +1803,7 @@ var DeviceStateMachine = class {
|
|
|
1764
1803
|
case "dxos.halo.credentials.DeviceProfile": {
|
|
1765
1804
|
invariant6(this.authorizedDeviceKeys.has(credential.subject.id), "Device not found.", {
|
|
1766
1805
|
F: __dxlog_file7,
|
|
1767
|
-
L:
|
|
1806
|
+
L: 66,
|
|
1768
1807
|
S: this,
|
|
1769
1808
|
A: [
|
|
1770
1809
|
"this.authorizedDeviceKeys.has(credential.subject.id)",
|
|
@@ -1777,7 +1816,7 @@ var DeviceStateMachine = class {
|
|
|
1777
1816
|
profile: assertion.profile
|
|
1778
1817
|
}, {
|
|
1779
1818
|
F: __dxlog_file7,
|
|
1780
|
-
L:
|
|
1819
|
+
L: 69,
|
|
1781
1820
|
S: this,
|
|
1782
1821
|
C: (f, a) => f(...a)
|
|
1783
1822
|
});
|
|
@@ -1794,6 +1833,9 @@ var DeviceStateMachine = class {
|
|
|
1794
1833
|
import { log as log5 } from "@dxos/log";
|
|
1795
1834
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/halo/credentials/src/processor/profile-state-machine.ts";
|
|
1796
1835
|
var ProfileStateMachine = class {
|
|
1836
|
+
_params;
|
|
1837
|
+
// TODO(burdon): Return values via getter.
|
|
1838
|
+
profile;
|
|
1797
1839
|
constructor(_params) {
|
|
1798
1840
|
this._params = _params;
|
|
1799
1841
|
}
|
|
@@ -1807,7 +1849,7 @@ var ProfileStateMachine = class {
|
|
|
1807
1849
|
credential
|
|
1808
1850
|
}, {
|
|
1809
1851
|
F: __dxlog_file8,
|
|
1810
|
-
L:
|
|
1852
|
+
L: 35,
|
|
1811
1853
|
S: this,
|
|
1812
1854
|
C: (f, a) => f(...a)
|
|
1813
1855
|
});
|
|
@@ -1819,7 +1861,7 @@ var ProfileStateMachine = class {
|
|
|
1819
1861
|
profile: this.profile
|
|
1820
1862
|
}, {
|
|
1821
1863
|
F: __dxlog_file8,
|
|
1822
|
-
L:
|
|
1864
|
+
L: 41,
|
|
1823
1865
|
S: this,
|
|
1824
1866
|
C: (f, a) => f(...a)
|
|
1825
1867
|
});
|