headscale/gen/openapiv2/headscale/v1/headscale.swagger.json

1449 lines
33 KiB
JSON

{
"swagger": "2.0",
"info": {
"title": "headscale/v1/headscale.proto",
"version": "version not set"
},
"tags": [
{
"name": "HeadscaleService"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/api/v1/apikey": {
"get": {
"operationId": "HeadscaleService_ListApiKeys",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListApiKeysResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"HeadscaleService"
]
},
"post": {
"summary": "--- ApiKeys start ---",
"operationId": "HeadscaleService_CreateApiKey",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1CreateApiKeyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1CreateApiKeyRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/apikey/expire": {
"post": {
"operationId": "HeadscaleService_ExpireApiKey",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ExpireApiKeyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1ExpireApiKeyRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/apikey/{prefix}": {
"delete": {
"operationId": "HeadscaleService_DeleteApiKey",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DeleteApiKeyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "prefix",
"in": "path",
"required": true,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/debug/node": {
"post": {
"summary": "--- Node start ---",
"operationId": "HeadscaleService_DebugCreateNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DebugCreateNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1DebugCreateNodeRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node": {
"get": {
"operationId": "HeadscaleService_ListNodes",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListNodesResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "user",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/backfillips": {
"post": {
"operationId": "HeadscaleService_BackfillNodeIPs",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1BackfillNodeIPsResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "confirmed",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/register": {
"post": {
"operationId": "HeadscaleService_RegisterNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1RegisterNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "user",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "key",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}": {
"get": {
"operationId": "HeadscaleService_GetNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
},
"delete": {
"operationId": "HeadscaleService_DeleteNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DeleteNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}/expire": {
"post": {
"operationId": "HeadscaleService_ExpireNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ExpireNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}/rename/{newName}": {
"post": {
"operationId": "HeadscaleService_RenameNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1RenameNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
},
{
"name": "newName",
"in": "path",
"required": true,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}/routes": {
"get": {
"operationId": "HeadscaleService_GetNodeRoutes",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetNodeRoutesResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}/tags": {
"post": {
"operationId": "HeadscaleService_SetTags",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1SetTagsResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/node/{nodeId}/user": {
"post": {
"operationId": "HeadscaleService_MoveNode",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1MoveNodeResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "nodeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
},
{
"name": "user",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/policy": {
"get": {
"summary": "--- Policy start ---",
"operationId": "HeadscaleService_GetPolicy",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetPolicyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"HeadscaleService"
]
},
"put": {
"operationId": "HeadscaleService_SetPolicy",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1SetPolicyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1SetPolicyRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/preauthkey": {
"get": {
"operationId": "HeadscaleService_ListPreAuthKeys",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListPreAuthKeysResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "user",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
},
"post": {
"summary": "--- PreAuthKeys start ---",
"operationId": "HeadscaleService_CreatePreAuthKey",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1CreatePreAuthKeyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1CreatePreAuthKeyRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/preauthkey/expire": {
"post": {
"operationId": "HeadscaleService_ExpirePreAuthKey",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ExpirePreAuthKeyResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1ExpirePreAuthKeyRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/routes": {
"get": {
"summary": "--- Route start ---",
"operationId": "HeadscaleService_GetRoutes",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetRoutesResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/routes/{routeId}": {
"delete": {
"operationId": "HeadscaleService_DeleteRoute",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DeleteRouteResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "routeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/routes/{routeId}/disable": {
"post": {
"operationId": "HeadscaleService_DisableRoute",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DisableRouteResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "routeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/routes/{routeId}/enable": {
"post": {
"operationId": "HeadscaleService_EnableRoute",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1EnableRouteResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "routeId",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/user": {
"get": {
"operationId": "HeadscaleService_ListUsers",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListUsersResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"tags": [
"HeadscaleService"
]
},
"post": {
"operationId": "HeadscaleService_CreateUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1CreateUserResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1CreateUserRequest"
}
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/user/{name}": {
"get": {
"summary": "--- User start ---",
"operationId": "HeadscaleService_GetUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetUserResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
},
"delete": {
"operationId": "HeadscaleService_DeleteUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DeleteUserResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
},
"/api/v1/user/{oldName}/rename/{newName}": {
"post": {
"operationId": "HeadscaleService_RenameUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1RenameUserResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "oldName",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "newName",
"in": "path",
"required": true,
"type": "string"
}
],
"tags": [
"HeadscaleService"
]
}
}
},
"definitions": {
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"v1ApiKey": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uint64"
},
"prefix": {
"type": "string"
},
"expiration": {
"type": "string",
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"lastSeen": {
"type": "string",
"format": "date-time"
}
}
},
"v1BackfillNodeIPsResponse": {
"type": "object",
"properties": {
"changes": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"v1CreateApiKeyRequest": {
"type": "object",
"properties": {
"expiration": {
"type": "string",
"format": "date-time"
}
}
},
"v1CreateApiKeyResponse": {
"type": "object",
"properties": {
"apiKey": {
"type": "string"
}
}
},
"v1CreatePreAuthKeyRequest": {
"type": "object",
"properties": {
"user": {
"type": "string"
},
"reusable": {
"type": "boolean"
},
"ephemeral": {
"type": "boolean"
},
"expiration": {
"type": "string",
"format": "date-time"
},
"aclTags": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"v1CreatePreAuthKeyResponse": {
"type": "object",
"properties": {
"preAuthKey": {
"$ref": "#/definitions/v1PreAuthKey"
}
}
},
"v1CreateUserRequest": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"v1CreateUserResponse": {
"type": "object",
"properties": {
"user": {
"$ref": "#/definitions/v1User"
}
}
},
"v1DebugCreateNodeRequest": {
"type": "object",
"properties": {
"user": {
"type": "string"
},
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"routes": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"v1DebugCreateNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1DeleteApiKeyResponse": {
"type": "object"
},
"v1DeleteNodeResponse": {
"type": "object"
},
"v1DeleteRouteResponse": {
"type": "object"
},
"v1DeleteUserResponse": {
"type": "object"
},
"v1DisableRouteResponse": {
"type": "object"
},
"v1EnableRouteResponse": {
"type": "object"
},
"v1ExpireApiKeyRequest": {
"type": "object",
"properties": {
"prefix": {
"type": "string"
}
}
},
"v1ExpireApiKeyResponse": {
"type": "object"
},
"v1ExpireNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1ExpirePreAuthKeyRequest": {
"type": "object",
"properties": {
"user": {
"type": "string"
},
"key": {
"type": "string"
}
}
},
"v1ExpirePreAuthKeyResponse": {
"type": "object"
},
"v1GetNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1GetNodeRoutesResponse": {
"type": "object",
"properties": {
"routes": {
"type": "array",
"items": {
"$ref": "#/definitions/v1Route"
}
}
}
},
"v1GetPolicyResponse": {
"type": "object",
"properties": {
"policy": {
"type": "string"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
}
},
"v1GetRoutesResponse": {
"type": "object",
"properties": {
"routes": {
"type": "array",
"items": {
"$ref": "#/definitions/v1Route"
}
}
}
},
"v1GetUserResponse": {
"type": "object",
"properties": {
"user": {
"$ref": "#/definitions/v1User"
}
}
},
"v1ListApiKeysResponse": {
"type": "object",
"properties": {
"apiKeys": {
"type": "array",
"items": {
"$ref": "#/definitions/v1ApiKey"
}
}
}
},
"v1ListNodesResponse": {
"type": "object",
"properties": {
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/v1Node"
}
}
}
},
"v1ListPreAuthKeysResponse": {
"type": "object",
"properties": {
"preAuthKeys": {
"type": "array",
"items": {
"$ref": "#/definitions/v1PreAuthKey"
}
}
}
},
"v1ListUsersResponse": {
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"$ref": "#/definitions/v1User"
}
}
}
},
"v1MoveNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1Node": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uint64"
},
"machineKey": {
"type": "string"
},
"nodeKey": {
"type": "string"
},
"discoKey": {
"type": "string"
},
"ipAddresses": {
"type": "array",
"items": {
"type": "string"
}
},
"name": {
"type": "string"
},
"user": {
"$ref": "#/definitions/v1User"
},
"lastSeen": {
"type": "string",
"format": "date-time"
},
"expiry": {
"type": "string",
"format": "date-time"
},
"preAuthKey": {
"$ref": "#/definitions/v1PreAuthKey"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"registerMethod": {
"$ref": "#/definitions/v1RegisterMethod"
},
"forcedTags": {
"type": "array",
"items": {
"type": "string"
}
},
"invalidTags": {
"type": "array",
"items": {
"type": "string"
}
},
"validTags": {
"type": "array",
"items": {
"type": "string"
}
},
"givenName": {
"type": "string"
},
"online": {
"type": "boolean"
}
}
},
"v1PreAuthKey": {
"type": "object",
"properties": {
"user": {
"type": "string"
},
"id": {
"type": "string"
},
"key": {
"type": "string"
},
"reusable": {
"type": "boolean"
},
"ephemeral": {
"type": "boolean"
},
"used": {
"type": "boolean"
},
"expiration": {
"type": "string",
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"aclTags": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"v1RegisterMethod": {
"type": "string",
"enum": [
"REGISTER_METHOD_UNSPECIFIED",
"REGISTER_METHOD_AUTH_KEY",
"REGISTER_METHOD_CLI",
"REGISTER_METHOD_OIDC"
],
"default": "REGISTER_METHOD_UNSPECIFIED"
},
"v1RegisterNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1RenameNodeResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1RenameUserResponse": {
"type": "object",
"properties": {
"user": {
"$ref": "#/definitions/v1User"
}
}
},
"v1Route": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uint64"
},
"node": {
"$ref": "#/definitions/v1Node"
},
"prefix": {
"type": "string"
},
"advertised": {
"type": "boolean"
},
"enabled": {
"type": "boolean"
},
"isPrimary": {
"type": "boolean"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time"
},
"deletedAt": {
"type": "string",
"format": "date-time"
}
}
},
"v1SetPolicyRequest": {
"type": "object",
"properties": {
"policy": {
"type": "string"
}
}
},
"v1SetPolicyResponse": {
"type": "object",
"properties": {
"policy": {
"type": "string"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
}
},
"v1SetTagsResponse": {
"type": "object",
"properties": {
"node": {
"$ref": "#/definitions/v1Node"
}
}
},
"v1User": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
}
}