deepline 0.1.66 → 0.1.69

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/dist/index.d.mts CHANGED
@@ -990,6 +990,56 @@ interface DeletePlayResult {
990
990
  deletedBindingCount: number;
991
991
  deletedRunCount: number;
992
992
  }
993
+ /** Owner-facing view of a play's public share page. */
994
+ interface SharePageOwnerView {
995
+ shareSlug: string;
996
+ publishedRevisionId: string;
997
+ publishedVersion: number;
998
+ visibility: string;
999
+ seoIndexing: 'index' | 'noindex';
1000
+ showAverageDeeplineCost: boolean;
1001
+ showAverageLatency: boolean;
1002
+ /** Stable public path, e.g. `/p/{shareSlug}`. */
1003
+ publicPath: string;
1004
+ /** Version-pinned canonical path, e.g. `/p/{shareSlug}/v/{version}`. */
1005
+ canonicalPath: string;
1006
+ createdAt: number;
1007
+ updatedAt: number;
1008
+ }
1009
+ /** One row in the owner-facing revision picker for sharing. */
1010
+ interface SharePageRevisionOption {
1011
+ revisionId: string;
1012
+ version: number;
1013
+ isLive: boolean;
1014
+ isWorking: boolean;
1015
+ isPublished: boolean;
1016
+ hasMap: boolean;
1017
+ hasCard: boolean;
1018
+ createdAt: number;
1019
+ }
1020
+ /** Status payload from `GET/POST/PATCH /api/v2/plays/:name/share`. */
1021
+ interface SharePageStatus {
1022
+ playName: string;
1023
+ share: SharePageOwnerView | null;
1024
+ publishedCopy: unknown | null;
1025
+ revisions: SharePageRevisionOption[];
1026
+ /** Present on publish responses when share-card generation was non-strict. */
1027
+ warning?: string | null;
1028
+ }
1029
+ interface PublishSharePageRequest {
1030
+ /** The revision to publish/repoint the public page to. */
1031
+ revisionId: string;
1032
+ /** Must be true — acknowledges the page is publicly viewable. */
1033
+ acknowledgedUnlisted: true;
1034
+ showAverageDeeplineCost?: boolean;
1035
+ showAverageLatency?: boolean;
1036
+ seoIndexing?: 'index' | 'noindex';
1037
+ }
1038
+ interface UpdateSharePageRequest {
1039
+ showAverageDeeplineCost?: boolean;
1040
+ showAverageLatency?: boolean;
1041
+ seoIndexing?: 'index' | 'noindex';
1042
+ }
993
1043
 
994
1044
  interface PlayStagedFileRef {
995
1045
  storageKind: 'r2';
@@ -1060,6 +1110,18 @@ type PlaySheetRowsResult = {
1060
1110
  customerDbUrl?: string;
1061
1111
  deltaCursor?: number;
1062
1112
  };
1113
+ type PlaySecretMetadata = {
1114
+ _id: string;
1115
+ orgId: string;
1116
+ scope: 'org' | 'play';
1117
+ playName?: string;
1118
+ name: string;
1119
+ status: string;
1120
+ hasValue: boolean;
1121
+ createdAt: number;
1122
+ updatedAt: number;
1123
+ lastUsedAt?: number;
1124
+ };
1063
1125
  type RunsNamespace = {
1064
1126
  get: (runId: string, options?: {
1065
1127
  full?: boolean;
@@ -1116,6 +1178,8 @@ declare class DeeplineClient {
1116
1178
  private playCloneEditStarter;
1117
1179
  private summarizePlayListItem;
1118
1180
  private summarizePlayDetail;
1181
+ listSecrets(): Promise<PlaySecretMetadata[]>;
1182
+ checkSecret(name: string): Promise<PlaySecretMetadata | null>;
1119
1183
  /**
1120
1184
  * List all available tools.
1121
1185
  *
@@ -1568,6 +1632,34 @@ declare class DeeplineClient {
1568
1632
  * bindings, and local run records. Deepline prebuilt plays are read-only.
1569
1633
  */
1570
1634
  deletePlay(name: string): Promise<DeletePlayResult>;
1635
+ /**
1636
+ * Current share status for a play: the public page (if any), the published
1637
+ * copy, and the revision picker. Read-only.
1638
+ */
1639
+ getSharePage(name: string): Promise<SharePageStatus>;
1640
+ /**
1641
+ * Publish (or repoint) the play's public share page to a revision. Requires
1642
+ * `acknowledgedUnlisted: true` — the page is publicly viewable. Org-admin only.
1643
+ */
1644
+ publishSharePage(name: string, request: PublishSharePageRequest): Promise<SharePageStatus>;
1645
+ /**
1646
+ * Update share-page settings (SEO indexing, credit-cost / latency display)
1647
+ * without moving the published pointer. Org-admin only.
1648
+ */
1649
+ updateSharePage(name: string, request: UpdateSharePageRequest): Promise<SharePageStatus>;
1650
+ /**
1651
+ * Unshare: hard-delete the play's public page and its cards. Returns the
1652
+ * fresh status (now `share: null`). Org-admin only. Idempotent — a no-op when
1653
+ * the play was never published.
1654
+ */
1655
+ unpublishSharePage(name: string): Promise<SharePageStatus>;
1656
+ /**
1657
+ * Regenerate the LLM landing-page copy for a revision (defaults to the
1658
+ * published one). Org-admin only.
1659
+ */
1660
+ regenerateSharePage(name: string, request?: {
1661
+ revisionId?: string;
1662
+ }): Promise<SharePageStatus>;
1571
1663
  /**
1572
1664
  * Run a play end-to-end: submit, stream until terminal, return result.
1573
1665
  *
@@ -1998,6 +2090,29 @@ type PlayBindings = {
1998
2090
  /** IANA timezone (e.g. `'America/New_York'`). Defaults to UTC. */
1999
2091
  timezone?: string;
2000
2092
  };
2093
+ /**
2094
+ * Customer-authored play secrets this play is allowed to use at runtime.
2095
+ * Values are never bundled or exposed by the SDK; access them with
2096
+ * `ctx.secrets.get("NAME")` and approved helpers such as
2097
+ * `ctx.secrets.bearer(handle)`.
2098
+ */
2099
+ secrets?: readonly string[];
2100
+ };
2101
+ declare const SECRET_HANDLE_BRAND: unique symbol;
2102
+ type SecretHandle = {
2103
+ readonly [SECRET_HANDLE_BRAND]: never;
2104
+ readonly name: string;
2105
+ toString(): string;
2106
+ toJSON(): never;
2107
+ };
2108
+ type SecretAuth = {
2109
+ readonly kind: 'bearer' | 'header';
2110
+ readonly secret: SecretHandle;
2111
+ readonly header?: string;
2112
+ };
2113
+ type SecretAwareRequestInit = Omit<RequestInit, 'headers'> & {
2114
+ headers?: HeadersInit;
2115
+ auth?: SecretAuth;
2001
2116
  };
2002
2117
  type LoosePlayObject = {
2003
2118
  [key: string]: LoosePlayObject;
@@ -2299,7 +2414,7 @@ interface DeeplinePlayRuntimeContext {
2299
2414
  * @param init - Fetch options.
2300
2415
  * @returns Recorded response.
2301
2416
  */
2302
- fetch(key: string, url: string | URL, init?: RequestInit, options?: {
2417
+ fetch(key: string, url: string | URL, init?: SecretAwareRequestInit, options?: {
2303
2418
  staleAfterSeconds?: number;
2304
2419
  }): Promise<{
2305
2420
  ok: boolean;
@@ -2310,6 +2425,11 @@ interface DeeplinePlayRuntimeContext {
2310
2425
  bodyText: string;
2311
2426
  json: unknown | null;
2312
2427
  }>;
2428
+ secrets: {
2429
+ get(name: string): SecretHandle;
2430
+ bearer(secret: SecretHandle): SecretAuth;
2431
+ header(header: string, secret: SecretHandle): SecretAuth;
2432
+ };
2313
2433
  runPlay<TOutput = unknown>(key: string, playRef: string | PlayReferenceLike, input: Record<string, unknown>, options: {
2314
2434
  description?: string;
2315
2435
  staleAfterSeconds?: number;
package/dist/index.d.ts CHANGED
@@ -990,6 +990,56 @@ interface DeletePlayResult {
990
990
  deletedBindingCount: number;
991
991
  deletedRunCount: number;
992
992
  }
993
+ /** Owner-facing view of a play's public share page. */
994
+ interface SharePageOwnerView {
995
+ shareSlug: string;
996
+ publishedRevisionId: string;
997
+ publishedVersion: number;
998
+ visibility: string;
999
+ seoIndexing: 'index' | 'noindex';
1000
+ showAverageDeeplineCost: boolean;
1001
+ showAverageLatency: boolean;
1002
+ /** Stable public path, e.g. `/p/{shareSlug}`. */
1003
+ publicPath: string;
1004
+ /** Version-pinned canonical path, e.g. `/p/{shareSlug}/v/{version}`. */
1005
+ canonicalPath: string;
1006
+ createdAt: number;
1007
+ updatedAt: number;
1008
+ }
1009
+ /** One row in the owner-facing revision picker for sharing. */
1010
+ interface SharePageRevisionOption {
1011
+ revisionId: string;
1012
+ version: number;
1013
+ isLive: boolean;
1014
+ isWorking: boolean;
1015
+ isPublished: boolean;
1016
+ hasMap: boolean;
1017
+ hasCard: boolean;
1018
+ createdAt: number;
1019
+ }
1020
+ /** Status payload from `GET/POST/PATCH /api/v2/plays/:name/share`. */
1021
+ interface SharePageStatus {
1022
+ playName: string;
1023
+ share: SharePageOwnerView | null;
1024
+ publishedCopy: unknown | null;
1025
+ revisions: SharePageRevisionOption[];
1026
+ /** Present on publish responses when share-card generation was non-strict. */
1027
+ warning?: string | null;
1028
+ }
1029
+ interface PublishSharePageRequest {
1030
+ /** The revision to publish/repoint the public page to. */
1031
+ revisionId: string;
1032
+ /** Must be true — acknowledges the page is publicly viewable. */
1033
+ acknowledgedUnlisted: true;
1034
+ showAverageDeeplineCost?: boolean;
1035
+ showAverageLatency?: boolean;
1036
+ seoIndexing?: 'index' | 'noindex';
1037
+ }
1038
+ interface UpdateSharePageRequest {
1039
+ showAverageDeeplineCost?: boolean;
1040
+ showAverageLatency?: boolean;
1041
+ seoIndexing?: 'index' | 'noindex';
1042
+ }
993
1043
 
994
1044
  interface PlayStagedFileRef {
995
1045
  storageKind: 'r2';
@@ -1060,6 +1110,18 @@ type PlaySheetRowsResult = {
1060
1110
  customerDbUrl?: string;
1061
1111
  deltaCursor?: number;
1062
1112
  };
1113
+ type PlaySecretMetadata = {
1114
+ _id: string;
1115
+ orgId: string;
1116
+ scope: 'org' | 'play';
1117
+ playName?: string;
1118
+ name: string;
1119
+ status: string;
1120
+ hasValue: boolean;
1121
+ createdAt: number;
1122
+ updatedAt: number;
1123
+ lastUsedAt?: number;
1124
+ };
1063
1125
  type RunsNamespace = {
1064
1126
  get: (runId: string, options?: {
1065
1127
  full?: boolean;
@@ -1116,6 +1178,8 @@ declare class DeeplineClient {
1116
1178
  private playCloneEditStarter;
1117
1179
  private summarizePlayListItem;
1118
1180
  private summarizePlayDetail;
1181
+ listSecrets(): Promise<PlaySecretMetadata[]>;
1182
+ checkSecret(name: string): Promise<PlaySecretMetadata | null>;
1119
1183
  /**
1120
1184
  * List all available tools.
1121
1185
  *
@@ -1568,6 +1632,34 @@ declare class DeeplineClient {
1568
1632
  * bindings, and local run records. Deepline prebuilt plays are read-only.
1569
1633
  */
1570
1634
  deletePlay(name: string): Promise<DeletePlayResult>;
1635
+ /**
1636
+ * Current share status for a play: the public page (if any), the published
1637
+ * copy, and the revision picker. Read-only.
1638
+ */
1639
+ getSharePage(name: string): Promise<SharePageStatus>;
1640
+ /**
1641
+ * Publish (or repoint) the play's public share page to a revision. Requires
1642
+ * `acknowledgedUnlisted: true` — the page is publicly viewable. Org-admin only.
1643
+ */
1644
+ publishSharePage(name: string, request: PublishSharePageRequest): Promise<SharePageStatus>;
1645
+ /**
1646
+ * Update share-page settings (SEO indexing, credit-cost / latency display)
1647
+ * without moving the published pointer. Org-admin only.
1648
+ */
1649
+ updateSharePage(name: string, request: UpdateSharePageRequest): Promise<SharePageStatus>;
1650
+ /**
1651
+ * Unshare: hard-delete the play's public page and its cards. Returns the
1652
+ * fresh status (now `share: null`). Org-admin only. Idempotent — a no-op when
1653
+ * the play was never published.
1654
+ */
1655
+ unpublishSharePage(name: string): Promise<SharePageStatus>;
1656
+ /**
1657
+ * Regenerate the LLM landing-page copy for a revision (defaults to the
1658
+ * published one). Org-admin only.
1659
+ */
1660
+ regenerateSharePage(name: string, request?: {
1661
+ revisionId?: string;
1662
+ }): Promise<SharePageStatus>;
1571
1663
  /**
1572
1664
  * Run a play end-to-end: submit, stream until terminal, return result.
1573
1665
  *
@@ -1998,6 +2090,29 @@ type PlayBindings = {
1998
2090
  /** IANA timezone (e.g. `'America/New_York'`). Defaults to UTC. */
1999
2091
  timezone?: string;
2000
2092
  };
2093
+ /**
2094
+ * Customer-authored play secrets this play is allowed to use at runtime.
2095
+ * Values are never bundled or exposed by the SDK; access them with
2096
+ * `ctx.secrets.get("NAME")` and approved helpers such as
2097
+ * `ctx.secrets.bearer(handle)`.
2098
+ */
2099
+ secrets?: readonly string[];
2100
+ };
2101
+ declare const SECRET_HANDLE_BRAND: unique symbol;
2102
+ type SecretHandle = {
2103
+ readonly [SECRET_HANDLE_BRAND]: never;
2104
+ readonly name: string;
2105
+ toString(): string;
2106
+ toJSON(): never;
2107
+ };
2108
+ type SecretAuth = {
2109
+ readonly kind: 'bearer' | 'header';
2110
+ readonly secret: SecretHandle;
2111
+ readonly header?: string;
2112
+ };
2113
+ type SecretAwareRequestInit = Omit<RequestInit, 'headers'> & {
2114
+ headers?: HeadersInit;
2115
+ auth?: SecretAuth;
2001
2116
  };
2002
2117
  type LoosePlayObject = {
2003
2118
  [key: string]: LoosePlayObject;
@@ -2299,7 +2414,7 @@ interface DeeplinePlayRuntimeContext {
2299
2414
  * @param init - Fetch options.
2300
2415
  * @returns Recorded response.
2301
2416
  */
2302
- fetch(key: string, url: string | URL, init?: RequestInit, options?: {
2417
+ fetch(key: string, url: string | URL, init?: SecretAwareRequestInit, options?: {
2303
2418
  staleAfterSeconds?: number;
2304
2419
  }): Promise<{
2305
2420
  ok: boolean;
@@ -2310,6 +2425,11 @@ interface DeeplinePlayRuntimeContext {
2310
2425
  bodyText: string;
2311
2426
  json: unknown | null;
2312
2427
  }>;
2428
+ secrets: {
2429
+ get(name: string): SecretHandle;
2430
+ bearer(secret: SecretHandle): SecretAuth;
2431
+ header(header: string, secret: SecretHandle): SecretAuth;
2432
+ };
2313
2433
  runPlay<TOutput = unknown>(key: string, playRef: string | PlayReferenceLike, input: Record<string, unknown>, options: {
2314
2434
  description?: string;
2315
2435
  staleAfterSeconds?: number;
package/dist/index.js CHANGED
@@ -241,10 +241,10 @@ var import_node_path2 = require("path");
241
241
 
242
242
  // src/release.ts
243
243
  var SDK_RELEASE = {
244
- version: "0.1.66",
244
+ version: "0.1.69",
245
245
  apiContract: "2026-05-play-bootstrap-dataset-summary",
246
246
  supportPolicy: {
247
- latest: "0.1.66",
247
+ latest: "0.1.69",
248
248
  minimumSupported: "0.1.53",
249
249
  deprecatedBelow: "0.1.53"
250
250
  }
@@ -495,6 +495,9 @@ var HttpClient = class {
495
495
  headers
496
496
  });
497
497
  }
498
+ async patch(path, body, headers) {
499
+ return this.request(path, { method: "PATCH", body, headers });
500
+ }
498
501
  /**
499
502
  * Send a DELETE request.
500
503
  *
@@ -835,6 +838,22 @@ var DeeplineClient = class {
835
838
  };
836
839
  }
837
840
  // ——————————————————————————————————————————————————————————
841
+ // Secrets
842
+ // ——————————————————————————————————————————————————————————
843
+ async listSecrets() {
844
+ const response = await this.http.get(
845
+ "/api/v2/secrets"
846
+ );
847
+ return Array.isArray(response.secrets) ? response.secrets : [];
848
+ }
849
+ async checkSecret(name) {
850
+ const normalized = name.trim().toUpperCase();
851
+ const secrets = await this.listSecrets();
852
+ return secrets.find(
853
+ (secret) => secret.name === normalized && secret.status === "active" && secret.hasValue
854
+ ) ?? null;
855
+ }
856
+ // ——————————————————————————————————————————————————————————
838
857
  // Tools
839
858
  // ——————————————————————————————————————————————————————————
840
859
  /**
@@ -1618,6 +1637,61 @@ var DeeplineClient = class {
1618
1637
  return this.http.delete(`/api/v2/plays/${encodedName}`);
1619
1638
  }
1620
1639
  // ——————————————————————————————————————————————————————————
1640
+ // Plays — public share pages
1641
+ // ——————————————————————————————————————————————————————————
1642
+ /**
1643
+ * Current share status for a play: the public page (if any), the published
1644
+ * copy, and the revision picker. Read-only.
1645
+ */
1646
+ async getSharePage(name) {
1647
+ const encodedName = encodeURIComponent(name);
1648
+ return this.http.get(`/api/v2/plays/${encodedName}/share`);
1649
+ }
1650
+ /**
1651
+ * Publish (or repoint) the play's public share page to a revision. Requires
1652
+ * `acknowledgedUnlisted: true` — the page is publicly viewable. Org-admin only.
1653
+ */
1654
+ async publishSharePage(name, request) {
1655
+ const encodedName = encodeURIComponent(name);
1656
+ return this.http.post(
1657
+ `/api/v2/plays/${encodedName}/share`,
1658
+ request
1659
+ );
1660
+ }
1661
+ /**
1662
+ * Update share-page settings (SEO indexing, credit-cost / latency display)
1663
+ * without moving the published pointer. Org-admin only.
1664
+ */
1665
+ async updateSharePage(name, request) {
1666
+ const encodedName = encodeURIComponent(name);
1667
+ return this.http.patch(
1668
+ `/api/v2/plays/${encodedName}/share`,
1669
+ request
1670
+ );
1671
+ }
1672
+ /**
1673
+ * Unshare: hard-delete the play's public page and its cards. Returns the
1674
+ * fresh status (now `share: null`). Org-admin only. Idempotent — a no-op when
1675
+ * the play was never published.
1676
+ */
1677
+ async unpublishSharePage(name) {
1678
+ const encodedName = encodeURIComponent(name);
1679
+ return this.http.delete(
1680
+ `/api/v2/plays/${encodedName}/share`
1681
+ );
1682
+ }
1683
+ /**
1684
+ * Regenerate the LLM landing-page copy for a revision (defaults to the
1685
+ * published one). Org-admin only.
1686
+ */
1687
+ async regenerateSharePage(name, request = {}) {
1688
+ const encodedName = encodeURIComponent(name);
1689
+ return this.http.post(
1690
+ `/api/v2/plays/${encodedName}/share/regenerate`,
1691
+ request
1692
+ );
1693
+ }
1694
+ // ——————————————————————————————————————————————————————————
1621
1695
  // Plays — high-level orchestration
1622
1696
  // ——————————————————————————————————————————————————————————
1623
1697
  /**
package/dist/index.mjs CHANGED
@@ -179,10 +179,10 @@ import { join as join2 } from "path";
179
179
 
180
180
  // src/release.ts
181
181
  var SDK_RELEASE = {
182
- version: "0.1.66",
182
+ version: "0.1.69",
183
183
  apiContract: "2026-05-play-bootstrap-dataset-summary",
184
184
  supportPolicy: {
185
- latest: "0.1.66",
185
+ latest: "0.1.69",
186
186
  minimumSupported: "0.1.53",
187
187
  deprecatedBelow: "0.1.53"
188
188
  }
@@ -433,6 +433,9 @@ var HttpClient = class {
433
433
  headers
434
434
  });
435
435
  }
436
+ async patch(path, body, headers) {
437
+ return this.request(path, { method: "PATCH", body, headers });
438
+ }
436
439
  /**
437
440
  * Send a DELETE request.
438
441
  *
@@ -773,6 +776,22 @@ var DeeplineClient = class {
773
776
  };
774
777
  }
775
778
  // ——————————————————————————————————————————————————————————
779
+ // Secrets
780
+ // ——————————————————————————————————————————————————————————
781
+ async listSecrets() {
782
+ const response = await this.http.get(
783
+ "/api/v2/secrets"
784
+ );
785
+ return Array.isArray(response.secrets) ? response.secrets : [];
786
+ }
787
+ async checkSecret(name) {
788
+ const normalized = name.trim().toUpperCase();
789
+ const secrets = await this.listSecrets();
790
+ return secrets.find(
791
+ (secret) => secret.name === normalized && secret.status === "active" && secret.hasValue
792
+ ) ?? null;
793
+ }
794
+ // ——————————————————————————————————————————————————————————
776
795
  // Tools
777
796
  // ——————————————————————————————————————————————————————————
778
797
  /**
@@ -1556,6 +1575,61 @@ var DeeplineClient = class {
1556
1575
  return this.http.delete(`/api/v2/plays/${encodedName}`);
1557
1576
  }
1558
1577
  // ——————————————————————————————————————————————————————————
1578
+ // Plays — public share pages
1579
+ // ——————————————————————————————————————————————————————————
1580
+ /**
1581
+ * Current share status for a play: the public page (if any), the published
1582
+ * copy, and the revision picker. Read-only.
1583
+ */
1584
+ async getSharePage(name) {
1585
+ const encodedName = encodeURIComponent(name);
1586
+ return this.http.get(`/api/v2/plays/${encodedName}/share`);
1587
+ }
1588
+ /**
1589
+ * Publish (or repoint) the play's public share page to a revision. Requires
1590
+ * `acknowledgedUnlisted: true` — the page is publicly viewable. Org-admin only.
1591
+ */
1592
+ async publishSharePage(name, request) {
1593
+ const encodedName = encodeURIComponent(name);
1594
+ return this.http.post(
1595
+ `/api/v2/plays/${encodedName}/share`,
1596
+ request
1597
+ );
1598
+ }
1599
+ /**
1600
+ * Update share-page settings (SEO indexing, credit-cost / latency display)
1601
+ * without moving the published pointer. Org-admin only.
1602
+ */
1603
+ async updateSharePage(name, request) {
1604
+ const encodedName = encodeURIComponent(name);
1605
+ return this.http.patch(
1606
+ `/api/v2/plays/${encodedName}/share`,
1607
+ request
1608
+ );
1609
+ }
1610
+ /**
1611
+ * Unshare: hard-delete the play's public page and its cards. Returns the
1612
+ * fresh status (now `share: null`). Org-admin only. Idempotent — a no-op when
1613
+ * the play was never published.
1614
+ */
1615
+ async unpublishSharePage(name) {
1616
+ const encodedName = encodeURIComponent(name);
1617
+ return this.http.delete(
1618
+ `/api/v2/plays/${encodedName}/share`
1619
+ );
1620
+ }
1621
+ /**
1622
+ * Regenerate the LLM landing-page copy for a revision (defaults to the
1623
+ * published one). Org-admin only.
1624
+ */
1625
+ async regenerateSharePage(name, request = {}) {
1626
+ const encodedName = encodeURIComponent(name);
1627
+ return this.http.post(
1628
+ `/api/v2/plays/${encodedName}/share/regenerate`,
1629
+ request
1630
+ );
1631
+ }
1632
+ // ——————————————————————————————————————————————————————————
1559
1633
  // Plays — high-level orchestration
1560
1634
  // ——————————————————————————————————————————————————————————
1561
1635
  /**