Skip to content

Instantly share code, notes, and snippets.

@adahl5
Created May 14, 2023 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adahl5/c74c7833d52e059713842890774d706b to your computer and use it in GitHub Desktop.
Save adahl5/c74c7833d52e059713842890774d706b to your computer and use it in GitHub Desktop.
JSON schema generated by huma with app.DisableSchemaProperty() and schema.GenerateInline = false
{
"components": {
"schemas": {
"Book": {
"type": "object",
"properties": {
"author": {
"type": "string",
"description": "Author"
},
"id": {
"type": "string",
"description": "Book ID"
},
"published": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time"
},
"title": {
"type": "string",
"description": "Title"
}
},
"additionalProperties": false,
"required": [
"id",
"title",
"author",
"published"
]
},
"BookList": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Book"
}
},
"BookPutRequest": {
"type": "object",
"properties": {
"author": {
"type": "string",
"description": "Author"
},
"published": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time"
},
"title": {
"type": "string",
"description": "Title"
}
},
"additionalProperties": false,
"required": [
"title",
"author",
"published"
]
},
"ErrorDetail": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Where the error occured, e.g. 'body.items[3].tags' or 'path.thing-id'"
},
"message": {
"type": "string",
"description": "Error message text"
},
"value": {
"description": "The value at the given location"
}
},
"additionalProperties": false
},
"ErrorModel": {
"type": "object",
"properties": {
"detail": {
"type": "string",
"description": "A human-readable explanation specific to this occurrence of the problem.",
"example": "Property foo is required but is missing."
},
"errors": {
"type": "array",
"description": "Optional list of individual error details",
"items": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Where the error occured, e.g. 'body.items[3].tags' or 'path.thing-id'"
},
"message": {
"type": "string",
"description": "Error message text"
},
"value": {
"description": "The value at the given location"
}
},
"additionalProperties": false
}
},
"instance": {
"type": "string",
"description": "A URI reference that identifies the specific occurence of the problem.",
"format": "uri",
"example": "https://example.com/error-log/abc123"
},
"status": {
"type": "integer",
"description": "HTTP status code",
"format": "int32",
"example": 400
},
"title": {
"type": "string",
"description": "A short, human-readable summary of the problem type. This value should not change between occurances of the error.",
"example": "Bad Request"
},
"type": {
"type": "string",
"description": "A URI reference to human-readable documentation for the error.",
"format": "uri",
"default": "about:blank",
"example": "https://example.com/errors/example"
}
},
"additionalProperties": false
},
"Genre": {
"type": "object",
"properties": {
"books": {
"type": "array",
"description": "Books",
"items": {
"type": "object",
"properties": {
"author": {
"type": "string",
"description": "Author"
},
"id": {
"type": "string",
"description": "Book ID"
},
"published": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time"
},
"title": {
"type": "string",
"description": "Title"
}
},
"additionalProperties": false,
"required": [
"id",
"title",
"author",
"published"
]
}
},
"created": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time",
"readOnly": true
},
"description": {
"type": "string",
"description": "Description"
},
"id": {
"type": "string",
"description": "Genre ID"
}
},
"additionalProperties": false,
"required": [
"id",
"books",
"description",
"created"
]
},
"GenrePutRequest": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "Description"
}
},
"additionalProperties": false,
"required": [
"description"
]
},
"GenreSummary": {
"type": "object",
"properties": {
"created": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time"
},
"description": {
"type": "string",
"description": "Description"
},
"id": {
"type": "string",
"description": "Genre ID"
}
},
"additionalProperties": false,
"required": [
"id",
"description",
"created"
]
},
"GenreSummaryList": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GenreSummary"
}
},
"patch-book-request": {
"type": "object",
"properties": {
"author": {
"type": "string",
"description": "Author"
},
"published": {
"type": "string",
"description": "Created date/time as ISO8601",
"format": "date-time"
},
"title": {
"type": "string",
"description": "Title"
}
},
"additionalProperties": false
},
"patch-book-request2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {
"type": "string",
"description": "JSON Pointer for the source of a move or copy"
},
"op": {
"type": "string",
"description": "Operation name",
"enum": [
"add",
"remove",
"replace",
"move",
"copy",
"test"
]
},
"path": {
"type": "string",
"description": "JSON Pointer to the field being operated on, or the destination of a move/copy operation"
},
"value": {
"description": "The value to set"
}
},
"additionalProperties": false,
"required": [
"op",
"path"
]
}
},
"patch-genre-request": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "Description"
}
},
"additionalProperties": false
},
"patch-genre-request2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {
"type": "string",
"description": "JSON Pointer for the source of a move or copy"
},
"op": {
"type": "string",
"description": "Operation name",
"enum": [
"add",
"remove",
"replace",
"move",
"copy",
"test"
]
},
"path": {
"type": "string",
"description": "JSON Pointer to the field being operated on, or the destination of a move/copy operation"
},
"value": {
"description": "The value to set"
}
},
"additionalProperties": false,
"required": [
"op",
"path"
]
}
}
}
},
"info": {
"title": "BookStore API",
"version": "1.0.0"
},
"openapi": "3.0.3",
"paths": {
"/v1/genres": {
"get": {
"operationId": "list-genres",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenreSummaryList"
}
}
},
"description": "OK",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Returns a list of all genres"
}
},
"/v1/genres/{genre-id}": {
"delete": {
"operationId": "delete-genre",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Found",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Delete a genre by its ID"
},
"get": {
"operationId": "get-genre",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Genre"
}
}
},
"description": "OK",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Found",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Get a genre by its ID"
},
"patch": {
"description": "Partial update operation supporting both JSON Merge Patch \\u0026 JSON Patch updates.",
"operationId": "patch-genre",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/patch-genre-request2"
}
},
"application/merge-patch+json": {
"schema": {
"$ref": "#/components/schemas/patch-genre-request"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"304": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Modified",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"408": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Timeout",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"413": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Entity Too Large",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"415": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unsupported Media Type",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Patch genre"
},
"put": {
"operationId": "put-genre",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenrePutRequest"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"408": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Timeout",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"413": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Entity Too Large",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Create or update a genre"
}
},
"/v1/genres/{genre-id}/books": {
"get": {
"operationId": "list-books",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BookList"
}
}
},
"description": "OK",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Found",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Returns a list of all books for a genre",
"tags": [
"Books by Genre"
]
}
},
"/v1/genres/{genre-id}/books/{book-id}": {
"delete": {
"operationId": "delete-book",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
},
{
"name": "book-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Found",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Delete a book by its ID",
"tags": [
"Books by Genre"
]
},
"get": {
"operationId": "get-book",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
},
{
"name": "book-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Book"
}
}
},
"description": "OK",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Found",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Get a book by its ID",
"tags": [
"Books by Genre"
]
},
"patch": {
"description": "Partial update operation supporting both JSON Merge Patch \\u0026 JSON Patch updates.",
"operationId": "patch-book",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
},
{
"name": "book-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/patch-book-request2"
}
},
"application/merge-patch+json": {
"schema": {
"$ref": "#/components/schemas/patch-book-request"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"304": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Not Modified",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"408": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Timeout",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"413": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Entity Too Large",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"415": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unsupported Media Type",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Patch book",
"tags": [
"Books by Genre"
]
},
"put": {
"operationId": "put-book",
"parameters": [
{
"name": "genre-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
},
{
"name": "book-id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-zA-Z0-9._-]{1,32}$"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BookPutRequest"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Bad Request",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"408": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Timeout",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"413": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Request Entity Too Large",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Unprocessable Entity",
"headers": {
"Content-Type": {
"description": "Content-Type",
"schema": {
"type": "string"
}
},
"Link": {
"description": "Link",
"schema": {
"type": "string"
}
}
}
}
},
"summary": "Create or update a book",
"tags": [
"Books by Genre"
]
}
}
},
"servers": [
{
"url": "http://localhost:8888",
"description": "Development server"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment