@twin.org/dataspace-control-plane-service 0.0.3-next.42 → 0.0.3-next.43

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.
@@ -44,7 +44,7 @@ export class DataspaceControlPlanePolicyRequester {
44
44
  * @param callback Optional callback interface for state change notifications.
45
45
  */
46
46
  constructor(loggingComponentType, callback) {
47
- this._loggingComponent = ComponentFactory.getIfExists(loggingComponentType ?? "logging");
47
+ this._loggingComponent = ComponentFactory.getIfExists(loggingComponentType);
48
48
  this._callback = callback;
49
49
  this._negotiations = new Map();
50
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dataspaceControlPlanePolicyRequester.js","sourceRoot":"","sources":["../../src/dataspaceControlPlanePolicyRequester.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ComponentFactory } from \"@twin.org/core\";\nimport type { INegotiationCallback } from \"@twin.org/dataspace-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { OdrlPolicyHelper, type IPolicyRequester } from \"@twin.org/rights-management-models\";\nimport {\n\tDataspaceProtocolContractNegotiationStateType,\n\ttype IDataspaceProtocolAgreement,\n\ttype IDataspaceProtocolOffer\n} from \"@twin.org/standards-dataspace-protocol\";\nimport type { INegotiationState } from \"./models/INegotiationState.js\";\n\n/**\n * Policy Requester for Dataspace Control Plane.\n *\n * Handles contract negotiation callbacks from PNP and forwards state changes\n * to the control plane service via the INegotiationCallback interface.\n *\n * Callback Flow:\n * 1. Control Plane initiates negotiation via PNP.sendRequestToProvider()\n * 2. PNP calls offer() → auto-accept, notify control plane\n * 3. PNP calls agreement() → store agreement, notify control plane\n * 4. PNP calls finalised() → notify control plane with agreementId\n * 5. Control plane notifies upstream caller (e.g. supply-chain)\n */\nexport class DataspaceControlPlanePolicyRequester implements IPolicyRequester {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<DataspaceControlPlanePolicyRequester>();\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponent?: ILoggingComponent;\n\n\t/**\n\t * Callback interface for notifying the control plane of negotiation state changes.\n\t * @internal\n\t */\n\tprivate readonly _callback?: INegotiationCallback;\n\n\t/**\n\t * Active negotiations tracked in memory.\n\t * Key: negotiationId\n\t * Value: Negotiation state\n\t * @internal\n\t */\n\tprivate readonly _negotiations: Map<string, INegotiationState>;\n\n\t/**\n\t * Create a new instance of DataspaceControlPlanePolicyRequester.\n\t * @param loggingComponentType Optional logging component type.\n\t * @param callback Optional callback interface for state change notifications.\n\t */\n\tconstructor(loggingComponentType?: string, callback?: INegotiationCallback) {\n\t\tthis._loggingComponent = ComponentFactory.getIfExists<ILoggingComponent>(\n\t\t\tloggingComponentType ?? \"logging\"\n\t\t);\n\t\tthis._callback = callback;\n\t\tthis._negotiations = new Map();\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn DataspaceControlPlanePolicyRequester.CLASS_NAME;\n\t}\n\n\t/**\n\t * Register a negotiation for tracking.\n\t * Called by the control plane service after initiating a negotiation via PNP.\n\t * @param negotiationId The negotiation ID returned by PNP.sendRequestToProvider().\n\t */\n\tpublic trackNegotiation(negotiationId: string): void {\n\t\tconst now = Date.now();\n\t\tthis._negotiations.set(negotiationId, {\n\t\t\tnegotiationId,\n\t\t\tstate: DataspaceProtocolContractNegotiationStateType.REQUESTED,\n\t\t\tstartedAt: now,\n\t\t\tupdatedAt: now\n\t\t});\n\t}\n\n\t/**\n\t * Get all active negotiations (for stalled cleanup).\n\t * @returns Map of negotiationId to negotiation state.\n\t */\n\tpublic getActiveNegotiations(): Map<string, INegotiationState> {\n\t\treturn this._negotiations;\n\t}\n\n\t/**\n\t * Remove a negotiation from tracking (for cleanup).\n\t * @param negotiationId The negotiation ID to remove.\n\t */\n\tpublic removeNegotiation(negotiationId: string): void {\n\t\tthis._negotiations.delete(negotiationId);\n\t}\n\n\t/**\n\t * A policy has been offered by a provider.\n\t * Called by PNP when provider sends an OfferMessage.\n\t * @param negotiationId The id of the negotiation.\n\t * @param offer The offer sent by the provider.\n\t * @returns True if the offer was accepted, false otherwise.\n\t */\n\tpublic async offer(negotiationId: string, offer: IDataspaceProtocolOffer): Promise<boolean> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"offerReceived\",\n\t\t\tdata: {\n\t\t\t\tnegotiationId,\n\t\t\t\tofferId: offer[\"@id\"]\n\t\t\t}\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.OFFERED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\t\t}\n\n\t\tawait this._callback?.onStateChanged(\n\t\t\tnegotiationId,\n\t\t\tDataspaceProtocolContractNegotiationStateType.OFFERED,\n\t\t\t{ offer }\n\t\t);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * A policy agreement has been sent by a provider.\n\t * Called by PNP when provider sends an AgreementMessage.\n\t * @param negotiationId The id of the negotiation.\n\t * @param agreement The agreement sent by the provider.\n\t * @returns True if the agreement was accepted, false otherwise.\n\t */\n\tpublic async agreement(\n\t\tnegotiationId: string,\n\t\tagreement: IDataspaceProtocolAgreement\n\t): Promise<boolean> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"agreementReceived\",\n\t\t\tdata: {\n\t\t\t\tnegotiationId,\n\t\t\t\tagreementId: OdrlPolicyHelper.getUid(agreement) ?? \"\"\n\t\t\t}\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.AGREED;\n\t\t\tnegotiation.agreement = agreement;\n\t\t\tnegotiation.updatedAt = Date.now();\n\t\t}\n\n\t\tawait this._callback?.onStateChanged(\n\t\t\tnegotiationId,\n\t\t\tDataspaceProtocolContractNegotiationStateType.AGREED,\n\t\t\t{ agreement }\n\t\t);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * A policy finalisation has been sent by a provider.\n\t * Called by PNP when provider sends a FinalizedEvent.\n\t * @param negotiationId The id of the negotiation.\n\t * @returns Nothing.\n\t */\n\tpublic async finalised(negotiationId: string): Promise<void> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"negotiationFinalized\",\n\t\t\tdata: { negotiationId }\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.FINALIZED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\n\t\t\tconst agreementId = OdrlPolicyHelper.getUid(negotiation.agreement);\n\t\t\tthis._negotiations.delete(negotiationId);\n\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"negotiationCompleted\",\n\t\t\t\tdata: {\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tagreementId,\n\t\t\t\t\tdurationMs: Date.now() - negotiation.startedAt\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (agreementId) {\n\t\t\t\tawait this._callback?.onStateChanged(\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tDataspaceProtocolContractNegotiationStateType.FINALIZED,\n\t\t\t\t\t{ agreement: negotiation.agreement }\n\t\t\t\t);\n\n\t\t\t\tawait this._callback?.onFinalized(negotiationId, agreementId);\n\t\t\t} else {\n\t\t\t\tawait this._callback?.onFailed(negotiationId, \"negotiationFinalizedNoAgreement\");\n\t\t\t}\n\t\t} else {\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"warn\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"unknownNegotiationFinalized\",\n\t\t\t\tdata: { negotiationId }\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * A policy termination has been sent by a provider.\n\t * Called by PNP when provider sends a TerminatedMessage or negotiation fails.\n\t * @param negotiationId The id of the negotiation.\n\t * @returns Nothing.\n\t */\n\tpublic async terminated(negotiationId: string): Promise<void> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"warn\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"negotiationTerminated\",\n\t\t\tdata: { negotiationId }\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.TERMINATED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\n\t\t\tthis._negotiations.delete(negotiationId);\n\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"negotiationRejected\",\n\t\t\t\tdata: {\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tdurationMs: Date.now() - negotiation.startedAt\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tawait this._callback?.onFailed(negotiationId, \"negotiationTerminatedByProvider\");\n\t\t} else {\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"warn\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"unknownNegotiationTerminated\",\n\t\t\t\tdata: { negotiationId }\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"dataspaceControlPlanePolicyRequester.js","sourceRoot":"","sources":["../../src/dataspaceControlPlanePolicyRequester.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ComponentFactory } from \"@twin.org/core\";\nimport type { INegotiationCallback } from \"@twin.org/dataspace-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { OdrlPolicyHelper, type IPolicyRequester } from \"@twin.org/rights-management-models\";\nimport {\n\tDataspaceProtocolContractNegotiationStateType,\n\ttype IDataspaceProtocolAgreement,\n\ttype IDataspaceProtocolOffer\n} from \"@twin.org/standards-dataspace-protocol\";\nimport type { INegotiationState } from \"./models/INegotiationState.js\";\n\n/**\n * Policy Requester for Dataspace Control Plane.\n *\n * Handles contract negotiation callbacks from PNP and forwards state changes\n * to the control plane service via the INegotiationCallback interface.\n *\n * Callback Flow:\n * 1. Control Plane initiates negotiation via PNP.sendRequestToProvider()\n * 2. PNP calls offer() → auto-accept, notify control plane\n * 3. PNP calls agreement() → store agreement, notify control plane\n * 4. PNP calls finalised() → notify control plane with agreementId\n * 5. Control plane notifies upstream caller (e.g. supply-chain)\n */\nexport class DataspaceControlPlanePolicyRequester implements IPolicyRequester {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<DataspaceControlPlanePolicyRequester>();\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponent?: ILoggingComponent;\n\n\t/**\n\t * Callback interface for notifying the control plane of negotiation state changes.\n\t * @internal\n\t */\n\tprivate readonly _callback?: INegotiationCallback;\n\n\t/**\n\t * Active negotiations tracked in memory.\n\t * Key: negotiationId\n\t * Value: Negotiation state\n\t * @internal\n\t */\n\tprivate readonly _negotiations: Map<string, INegotiationState>;\n\n\t/**\n\t * Create a new instance of DataspaceControlPlanePolicyRequester.\n\t * @param loggingComponentType Optional logging component type.\n\t * @param callback Optional callback interface for state change notifications.\n\t */\n\tconstructor(loggingComponentType?: string, callback?: INegotiationCallback) {\n\t\tthis._loggingComponent = ComponentFactory.getIfExists<ILoggingComponent>(loggingComponentType);\n\t\tthis._callback = callback;\n\t\tthis._negotiations = new Map();\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn DataspaceControlPlanePolicyRequester.CLASS_NAME;\n\t}\n\n\t/**\n\t * Register a negotiation for tracking.\n\t * Called by the control plane service after initiating a negotiation via PNP.\n\t * @param negotiationId The negotiation ID returned by PNP.sendRequestToProvider().\n\t */\n\tpublic trackNegotiation(negotiationId: string): void {\n\t\tconst now = Date.now();\n\t\tthis._negotiations.set(negotiationId, {\n\t\t\tnegotiationId,\n\t\t\tstate: DataspaceProtocolContractNegotiationStateType.REQUESTED,\n\t\t\tstartedAt: now,\n\t\t\tupdatedAt: now\n\t\t});\n\t}\n\n\t/**\n\t * Get all active negotiations (for stalled cleanup).\n\t * @returns Map of negotiationId to negotiation state.\n\t */\n\tpublic getActiveNegotiations(): Map<string, INegotiationState> {\n\t\treturn this._negotiations;\n\t}\n\n\t/**\n\t * Remove a negotiation from tracking (for cleanup).\n\t * @param negotiationId The negotiation ID to remove.\n\t */\n\tpublic removeNegotiation(negotiationId: string): void {\n\t\tthis._negotiations.delete(negotiationId);\n\t}\n\n\t/**\n\t * A policy has been offered by a provider.\n\t * Called by PNP when provider sends an OfferMessage.\n\t * @param negotiationId The id of the negotiation.\n\t * @param offer The offer sent by the provider.\n\t * @returns True if the offer was accepted, false otherwise.\n\t */\n\tpublic async offer(negotiationId: string, offer: IDataspaceProtocolOffer): Promise<boolean> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"offerReceived\",\n\t\t\tdata: {\n\t\t\t\tnegotiationId,\n\t\t\t\tofferId: offer[\"@id\"]\n\t\t\t}\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.OFFERED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\t\t}\n\n\t\tawait this._callback?.onStateChanged(\n\t\t\tnegotiationId,\n\t\t\tDataspaceProtocolContractNegotiationStateType.OFFERED,\n\t\t\t{ offer }\n\t\t);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * A policy agreement has been sent by a provider.\n\t * Called by PNP when provider sends an AgreementMessage.\n\t * @param negotiationId The id of the negotiation.\n\t * @param agreement The agreement sent by the provider.\n\t * @returns True if the agreement was accepted, false otherwise.\n\t */\n\tpublic async agreement(\n\t\tnegotiationId: string,\n\t\tagreement: IDataspaceProtocolAgreement\n\t): Promise<boolean> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"agreementReceived\",\n\t\t\tdata: {\n\t\t\t\tnegotiationId,\n\t\t\t\tagreementId: OdrlPolicyHelper.getUid(agreement) ?? \"\"\n\t\t\t}\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.AGREED;\n\t\t\tnegotiation.agreement = agreement;\n\t\t\tnegotiation.updatedAt = Date.now();\n\t\t}\n\n\t\tawait this._callback?.onStateChanged(\n\t\t\tnegotiationId,\n\t\t\tDataspaceProtocolContractNegotiationStateType.AGREED,\n\t\t\t{ agreement }\n\t\t);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * A policy finalisation has been sent by a provider.\n\t * Called by PNP when provider sends a FinalizedEvent.\n\t * @param negotiationId The id of the negotiation.\n\t * @returns Nothing.\n\t */\n\tpublic async finalised(negotiationId: string): Promise<void> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"negotiationFinalized\",\n\t\t\tdata: { negotiationId }\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.FINALIZED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\n\t\t\tconst agreementId = OdrlPolicyHelper.getUid(negotiation.agreement);\n\t\t\tthis._negotiations.delete(negotiationId);\n\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"negotiationCompleted\",\n\t\t\t\tdata: {\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tagreementId,\n\t\t\t\t\tdurationMs: Date.now() - negotiation.startedAt\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (agreementId) {\n\t\t\t\tawait this._callback?.onStateChanged(\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tDataspaceProtocolContractNegotiationStateType.FINALIZED,\n\t\t\t\t\t{ agreement: negotiation.agreement }\n\t\t\t\t);\n\n\t\t\t\tawait this._callback?.onFinalized(negotiationId, agreementId);\n\t\t\t} else {\n\t\t\t\tawait this._callback?.onFailed(negotiationId, \"negotiationFinalizedNoAgreement\");\n\t\t\t}\n\t\t} else {\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"warn\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"unknownNegotiationFinalized\",\n\t\t\t\tdata: { negotiationId }\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * A policy termination has been sent by a provider.\n\t * Called by PNP when provider sends a TerminatedMessage or negotiation fails.\n\t * @param negotiationId The id of the negotiation.\n\t * @returns Nothing.\n\t */\n\tpublic async terminated(negotiationId: string): Promise<void> {\n\t\tawait this._loggingComponent?.log({\n\t\t\tlevel: \"warn\",\n\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"negotiationTerminated\",\n\t\t\tdata: { negotiationId }\n\t\t});\n\n\t\tconst negotiation = this._negotiations.get(negotiationId);\n\t\tif (negotiation) {\n\t\t\tnegotiation.state = DataspaceProtocolContractNegotiationStateType.TERMINATED;\n\t\t\tnegotiation.updatedAt = Date.now();\n\n\t\t\tthis._negotiations.delete(negotiationId);\n\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"negotiationRejected\",\n\t\t\t\tdata: {\n\t\t\t\t\tnegotiationId,\n\t\t\t\t\tdurationMs: Date.now() - negotiation.startedAt\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tawait this._callback?.onFailed(negotiationId, \"negotiationTerminatedByProvider\");\n\t\t} else {\n\t\t\tawait this._loggingComponent?.log({\n\t\t\t\tlevel: \"warn\",\n\t\t\t\tsource: DataspaceControlPlanePolicyRequester.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"unknownNegotiationTerminated\",\n\t\t\t\tdata: { negotiationId }\n\t\t\t});\n\t\t}\n\t}\n}\n"]}