mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-31 12:20:26 +08:00
[Integration Tests] Update a demo's config.json as part of integration test (#2005)
* add script to create configs for test demos * no message * fixes * fixes * fix * test fix * test fix * format * fix
This commit is contained in:
parent
b1dfc9a172
commit
13915f9c11
1
.github/workflows/ui.yml
vendored
1
.github/workflows/ui.yml
vendored
@ -53,6 +53,7 @@ jobs:
|
||||
node-version: 16
|
||||
cache: pnpm
|
||||
cache-dependency-path: ui/pnpm-lock.yaml
|
||||
- run: pip install -r ../requirements.txt
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm exec playwright install chromium
|
||||
- run: pnpm build
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.0.6",
|
||||
"version": "3.1.4",
|
||||
"mode": "blocks",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
@ -7,7 +7,7 @@
|
||||
"id": 1,
|
||||
"type": "textbox",
|
||||
"props": {
|
||||
"lines": 5,
|
||||
"lines": 2,
|
||||
"max_lines": 20,
|
||||
"value": "",
|
||||
"label": "Input",
|
||||
@ -24,7 +24,7 @@
|
||||
"lines": 1,
|
||||
"max_lines": 20,
|
||||
"value": "",
|
||||
"label": "Output-Interactive",
|
||||
"label": "Input 2",
|
||||
"show_label": true,
|
||||
"name": "textbox",
|
||||
"visible": true,
|
||||
@ -37,10 +37,9 @@
|
||||
"props": {
|
||||
"lines": 1,
|
||||
"max_lines": 20,
|
||||
"value": "Hello friends\nhello friends\n\nHello friends\n\n",
|
||||
"value": "",
|
||||
"label": "Output",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
"name": "textbox",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
@ -56,10 +55,128 @@
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type": "row",
|
||||
"props": {
|
||||
"type": "row",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "image",
|
||||
"props": {
|
||||
"image_mode": "RGB",
|
||||
"source": "upload",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"type": "image",
|
||||
"props": {
|
||||
"image_mode": "RGB",
|
||||
"source": "upload",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Mirror Image",
|
||||
"variant": "secondary",
|
||||
"name": "button",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "markdown",
|
||||
"props": {
|
||||
"value": "<h2>Text Examples</h2>\n",
|
||||
"name": "markdown",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": "dataset",
|
||||
"props": {
|
||||
"components": [
|
||||
"textbox",
|
||||
"textbox"
|
||||
],
|
||||
"headers": [
|
||||
"Input",
|
||||
"Input 2"
|
||||
],
|
||||
"samples": [
|
||||
[
|
||||
"hi",
|
||||
"Adam"
|
||||
],
|
||||
[
|
||||
"hello",
|
||||
"Eve"
|
||||
]
|
||||
],
|
||||
"type": "index",
|
||||
"name": "dataset",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"type": "markdown",
|
||||
"props": {
|
||||
"value": "<h2>Image Examples</h2>\n",
|
||||
"name": "markdown",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"type": "dataset",
|
||||
"props": {
|
||||
"components": [
|
||||
"image"
|
||||
],
|
||||
"headers": [],
|
||||
"samples": [
|
||||
[
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/blocks_inputs/lion.jpg"
|
||||
]
|
||||
],
|
||||
"type": "index",
|
||||
"name": "dataset",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"theme": "default",
|
||||
"css": null,
|
||||
"title": "Gradio",
|
||||
"enable_queue": false,
|
||||
"layout": {
|
||||
"id": 0,
|
||||
@ -75,6 +192,32 @@
|
||||
},
|
||||
{
|
||||
"id": 4
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"children": [
|
||||
{
|
||||
"id": 6
|
||||
},
|
||||
{
|
||||
"id": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8
|
||||
},
|
||||
{
|
||||
"id": 9
|
||||
},
|
||||
{
|
||||
"id": 10
|
||||
},
|
||||
{
|
||||
"id": 11
|
||||
},
|
||||
{
|
||||
"id": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -85,15 +228,79 @@
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
1
|
||||
1,
|
||||
2
|
||||
],
|
||||
"outputs": [
|
||||
2
|
||||
3
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": null
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
8
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
6
|
||||
],
|
||||
"outputs": [
|
||||
7
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
10
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
10
|
||||
],
|
||||
"outputs": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": false,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
12
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
12
|
||||
],
|
||||
"outputs": [
|
||||
6,
|
||||
7
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": false,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.0.6",
|
||||
"version": "3.1.4",
|
||||
"mode": "blocks",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
@ -76,6 +76,7 @@
|
||||
],
|
||||
"theme": "default",
|
||||
"css": null,
|
||||
"title": "Gradio",
|
||||
"enable_queue": false,
|
||||
"layout": {
|
||||
"id": 0,
|
||||
@ -118,7 +119,10 @@
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": null
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
{
|
||||
"version": "3.1.4",
|
||||
"mode": "blocks",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
{
|
||||
"id": 1,
|
||||
@ -7,11 +9,12 @@
|
||||
"props": {
|
||||
"lines": 1,
|
||||
"max_lines": 20,
|
||||
"default_value": "Frank",
|
||||
"value": "Frank",
|
||||
"label": "Name",
|
||||
"show_label": true,
|
||||
"name": "textbox",
|
||||
"css": {}
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -20,15 +23,18 @@
|
||||
"props": {
|
||||
"lines": 1,
|
||||
"max_lines": 20,
|
||||
"default_value": "",
|
||||
"value": "",
|
||||
"label": "Output",
|
||||
"show_label": true,
|
||||
"name": "textbox",
|
||||
"css": {}
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"theme": "default",
|
||||
"css": null,
|
||||
"title": "Gradio",
|
||||
"enable_queue": false,
|
||||
"layout": {
|
||||
"id": 0,
|
||||
@ -51,8 +57,13 @@
|
||||
"outputs": [
|
||||
2
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": false,
|
||||
"status_tracker": null,
|
||||
"queue": null
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.1.1\n",
|
||||
"version": "3.1.4",
|
||||
"mode": "blocks",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
@ -280,11 +280,20 @@
|
||||
"show_progress": true,
|
||||
"documentation": [
|
||||
[
|
||||
null,
|
||||
null
|
||||
[
|
||||
"list of selected choices",
|
||||
"List[str]"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
]
|
||||
],
|
||||
[
|
||||
null
|
||||
[
|
||||
"JSON output",
|
||||
"Dict | List | None"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -309,11 +318,20 @@
|
||||
"show_progress": true,
|
||||
"documentation": [
|
||||
[
|
||||
null,
|
||||
null
|
||||
[
|
||||
"list of selected choices",
|
||||
"List[str]"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
]
|
||||
],
|
||||
[
|
||||
null
|
||||
[
|
||||
"JSON output",
|
||||
"Dict | List | None"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
|
@ -1,50 +0,0 @@
|
||||
{
|
||||
"mode": "blocks",
|
||||
"components": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "textbox",
|
||||
"props": {
|
||||
"lines": 1,
|
||||
"placeholder": null,
|
||||
"value": "",
|
||||
"name": "textbox",
|
||||
"label": "Input-Output",
|
||||
"css": {},
|
||||
"interactive": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Run",
|
||||
"name": "button",
|
||||
"label": null,
|
||||
"css": {},
|
||||
"interactive": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"theme": "default",
|
||||
"layout": {
|
||||
"id": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"targets": [2],
|
||||
"trigger": "click",
|
||||
"inputs": [1],
|
||||
"outputs": [1],
|
||||
"queue": false
|
||||
}
|
||||
]
|
||||
}
|
68
demo/input_output/config.json
Normal file
68
demo/input_output/config.json
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"version": "3.1.4",
|
||||
"mode": "blocks",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "textbox",
|
||||
"props": {
|
||||
"lines": 1,
|
||||
"max_lines": 20,
|
||||
"value": "",
|
||||
"label": "Input-Output",
|
||||
"show_label": true,
|
||||
"name": "textbox",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Run",
|
||||
"variant": "secondary",
|
||||
"name": "button",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"theme": "default",
|
||||
"css": null,
|
||||
"title": "Gradio",
|
||||
"enable_queue": false,
|
||||
"layout": {
|
||||
"id": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"targets": [
|
||||
2
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
1
|
||||
],
|
||||
"outputs": [
|
||||
1
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": null,
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
"scroll_to_output": false,
|
||||
"show_progress": true
|
||||
}
|
||||
]
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"version": "3.0.16\n",
|
||||
"mode": "blocks",
|
||||
"version": "3.1.4",
|
||||
"mode": "interface",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
{
|
||||
"id": 26,
|
||||
"id": 33,
|
||||
"type": "markdown",
|
||||
"props": {
|
||||
"value": "<h1 style='text-align: center; margin-bottom: 1rem'>Kitchen Sink</h1>",
|
||||
@ -14,7 +14,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"id": 34,
|
||||
"type": "markdown",
|
||||
"props": {
|
||||
"value": "<p>Try out all the components!</p>",
|
||||
@ -24,7 +24,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"id": 35,
|
||||
"type": "row",
|
||||
"props": {
|
||||
"type": "row",
|
||||
@ -36,7 +36,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"id": 36,
|
||||
"type": "column",
|
||||
"props": {
|
||||
"type": "column",
|
||||
@ -46,7 +46,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"id": 37,
|
||||
"type": "column",
|
||||
"props": {
|
||||
"type": "column",
|
||||
@ -184,7 +184,6 @@
|
||||
"bar",
|
||||
"baz"
|
||||
],
|
||||
"value": "foo",
|
||||
"label": "Dropdown",
|
||||
"show_label": true,
|
||||
"name": "dropdown",
|
||||
@ -200,6 +199,7 @@
|
||||
"source": "upload",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"label": "Image",
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
@ -215,6 +215,7 @@
|
||||
"source": "upload",
|
||||
"tool": "select",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"label": "Image w/ Cropper",
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
@ -230,6 +231,7 @@
|
||||
"source": "canvas",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"label": "Sketchpad",
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
@ -245,6 +247,7 @@
|
||||
"source": "webcam",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"label": "Webcam",
|
||||
"show_label": true,
|
||||
"name": "image",
|
||||
@ -257,6 +260,7 @@
|
||||
"type": "video",
|
||||
"props": {
|
||||
"source": "upload",
|
||||
"mirror_webcam": true,
|
||||
"label": "Video",
|
||||
"show_label": true,
|
||||
"name": "video",
|
||||
@ -291,7 +295,85 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"id": 16,
|
||||
"type": "file",
|
||||
"props": {
|
||||
"file_count": "single",
|
||||
"label": "File",
|
||||
"show_label": true,
|
||||
"name": "file",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"type": "dataframe",
|
||||
"props": {
|
||||
"headers": [
|
||||
"Name",
|
||||
"Age",
|
||||
"Gender"
|
||||
],
|
||||
"datatype": [
|
||||
"str",
|
||||
"str",
|
||||
"str"
|
||||
],
|
||||
"row_count": [
|
||||
1,
|
||||
"dynamic"
|
||||
],
|
||||
"col_count": [
|
||||
3,
|
||||
"dynamic"
|
||||
],
|
||||
"value": {
|
||||
"headers": [
|
||||
"Name",
|
||||
"Age",
|
||||
"Gender"
|
||||
],
|
||||
"data": [
|
||||
[
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
]
|
||||
},
|
||||
"max_rows": 20,
|
||||
"overflow_row_behaviour": "paginate",
|
||||
"wrap": false,
|
||||
"label": "Dataframe",
|
||||
"show_label": true,
|
||||
"name": "dataframe",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"type": "timeseries",
|
||||
"props": {
|
||||
"x": "time",
|
||||
"y": [
|
||||
"price",
|
||||
"value"
|
||||
],
|
||||
"colors": [
|
||||
"pink",
|
||||
"purple"
|
||||
],
|
||||
"label": "df2",
|
||||
"show_label": true,
|
||||
"name": "timeseries",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"type": "row",
|
||||
"props": {
|
||||
"type": "row",
|
||||
@ -302,7 +384,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"id": 39,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Clear",
|
||||
@ -313,7 +395,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"id": 40,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Submit",
|
||||
@ -324,7 +406,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"id": 41,
|
||||
"type": "column",
|
||||
"props": {
|
||||
"type": "column",
|
||||
@ -334,7 +416,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"id": 42,
|
||||
"type": "statustracker",
|
||||
"props": {
|
||||
"cover_container": true,
|
||||
@ -344,7 +426,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 19,
|
||||
"type": "textbox",
|
||||
"props": {
|
||||
"lines": 1,
|
||||
@ -359,7 +441,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 20,
|
||||
"type": "label",
|
||||
"props": {
|
||||
"label": "Label",
|
||||
@ -371,7 +453,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 21,
|
||||
"type": "audio",
|
||||
"props": {
|
||||
"source": "upload",
|
||||
@ -385,13 +467,14 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"id": 22,
|
||||
"type": "image",
|
||||
"props": {
|
||||
"image_mode": "RGB",
|
||||
"source": "upload",
|
||||
"tool": "editor",
|
||||
"streaming": false,
|
||||
"mirror_webcam": true,
|
||||
"label": "Image",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
@ -401,10 +484,11 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"id": 23,
|
||||
"type": "video",
|
||||
"props": {
|
||||
"source": "upload",
|
||||
"mirror_webcam": true,
|
||||
"label": "Video",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
@ -414,7 +498,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"id": 24,
|
||||
"type": "highlightedtext",
|
||||
"props": {
|
||||
"color_map": {
|
||||
@ -431,7 +515,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"id": 25,
|
||||
"type": "highlightedtext",
|
||||
"props": {
|
||||
"show_legend": true,
|
||||
@ -444,7 +528,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"id": 26,
|
||||
"type": "json",
|
||||
"props": {
|
||||
"label": "JSON",
|
||||
@ -456,7 +540,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"id": 27,
|
||||
"type": "html",
|
||||
"props": {
|
||||
"value": "",
|
||||
@ -469,7 +553,131 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"id": 28,
|
||||
"type": "file",
|
||||
"props": {
|
||||
"file_count": "single",
|
||||
"label": "File",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
"name": "file",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"type": "dataframe",
|
||||
"props": {
|
||||
"headers": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"datatype": [
|
||||
"str",
|
||||
"str",
|
||||
"str"
|
||||
],
|
||||
"row_count": [
|
||||
1,
|
||||
"dynamic"
|
||||
],
|
||||
"col_count": [
|
||||
3,
|
||||
"dynamic"
|
||||
],
|
||||
"value": {
|
||||
"headers": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"data": [
|
||||
[
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
]
|
||||
},
|
||||
"max_rows": 20,
|
||||
"overflow_row_behaviour": "paginate",
|
||||
"wrap": false,
|
||||
"label": "Dataframe",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
"name": "dataframe",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"type": "dataframe",
|
||||
"props": {
|
||||
"headers": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"datatype": [
|
||||
"str",
|
||||
"str",
|
||||
"str"
|
||||
],
|
||||
"row_count": [
|
||||
1,
|
||||
"dynamic"
|
||||
],
|
||||
"col_count": [
|
||||
3,
|
||||
"dynamic"
|
||||
],
|
||||
"value": {
|
||||
"headers": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"data": [
|
||||
[
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
]
|
||||
},
|
||||
"max_rows": 20,
|
||||
"overflow_row_behaviour": "paginate",
|
||||
"wrap": false,
|
||||
"label": "Numpy",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
"name": "dataframe",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"type": "timeseries",
|
||||
"props": {
|
||||
"x": "time",
|
||||
"y": [
|
||||
"price",
|
||||
"value"
|
||||
],
|
||||
"label": "Timeseries",
|
||||
"show_label": true,
|
||||
"interactive": false,
|
||||
"name": "timeseries",
|
||||
"visible": true,
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"type": "row",
|
||||
"props": {
|
||||
"type": "row",
|
||||
@ -480,7 +688,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"id": 44,
|
||||
"type": "button",
|
||||
"props": {
|
||||
"value": "Flag",
|
||||
@ -491,7 +699,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"id": 45,
|
||||
"type": "dataset",
|
||||
"props": {
|
||||
"components": [
|
||||
@ -510,7 +718,10 @@
|
||||
"image",
|
||||
"video",
|
||||
"audio",
|
||||
"audio"
|
||||
"audio",
|
||||
"file",
|
||||
"dataframe",
|
||||
"timeseries"
|
||||
],
|
||||
"headers": [
|
||||
"Textbox",
|
||||
@ -528,7 +739,10 @@
|
||||
"Webcam",
|
||||
"Video",
|
||||
"Audio",
|
||||
"Microphone"
|
||||
"Microphone",
|
||||
"File",
|
||||
"Dataframe",
|
||||
"df2"
|
||||
],
|
||||
"samples": [
|
||||
[
|
||||
@ -549,7 +763,22 @@
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
|
||||
[
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
3,
|
||||
4,
|
||||
5
|
||||
]
|
||||
],
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
|
||||
],
|
||||
[
|
||||
"the quick brown fox",
|
||||
@ -569,7 +798,22 @@
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
|
||||
[
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
3,
|
||||
4,
|
||||
5
|
||||
]
|
||||
],
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
|
||||
],
|
||||
[
|
||||
"the quick brown fox",
|
||||
@ -589,7 +833,22 @@
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
|
||||
[
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
3,
|
||||
4,
|
||||
5
|
||||
]
|
||||
],
|
||||
"/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
|
||||
]
|
||||
],
|
||||
"type": "index",
|
||||
@ -599,7 +858,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 39,
|
||||
"id": 46,
|
||||
"type": "markdown",
|
||||
"props": {
|
||||
"value": "<p>Learn more about <a href=\"http://gradio.app\">Gradio</a></p>",
|
||||
@ -611,24 +870,25 @@
|
||||
],
|
||||
"theme": "default",
|
||||
"css": null,
|
||||
"title": "Kitchen Sink",
|
||||
"enable_queue": false,
|
||||
"layout": {
|
||||
"id": 25,
|
||||
"id": 32,
|
||||
"children": [
|
||||
{
|
||||
"id": 26
|
||||
"id": 33
|
||||
},
|
||||
{
|
||||
"id": 27
|
||||
"id": 34
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"id": 35,
|
||||
"children": [
|
||||
{
|
||||
"id": 29,
|
||||
"id": 36,
|
||||
"children": [
|
||||
{
|
||||
"id": 30,
|
||||
"id": 37,
|
||||
"children": [
|
||||
{
|
||||
"id": 0
|
||||
@ -677,36 +937,36 @@
|
||||
},
|
||||
{
|
||||
"id": 15
|
||||
},
|
||||
{
|
||||
"id": 16
|
||||
},
|
||||
{
|
||||
"id": 17
|
||||
},
|
||||
{
|
||||
"id": 18
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"id": 38,
|
||||
"children": [
|
||||
{
|
||||
"id": 32
|
||||
"id": 39
|
||||
},
|
||||
{
|
||||
"id": 33
|
||||
"id": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"id": 41,
|
||||
"children": [
|
||||
{
|
||||
"id": 35
|
||||
},
|
||||
{
|
||||
"id": 16
|
||||
},
|
||||
{
|
||||
"id": 17
|
||||
},
|
||||
{
|
||||
"id": 18
|
||||
"id": 42
|
||||
},
|
||||
{
|
||||
"id": 19
|
||||
@ -727,10 +987,31 @@
|
||||
"id": 24
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"id": 25
|
||||
},
|
||||
{
|
||||
"id": 26
|
||||
},
|
||||
{
|
||||
"id": 27
|
||||
},
|
||||
{
|
||||
"id": 28
|
||||
},
|
||||
{
|
||||
"id": 29
|
||||
},
|
||||
{
|
||||
"id": 30
|
||||
},
|
||||
{
|
||||
"id": 31
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"children": [
|
||||
{
|
||||
"id": 37
|
||||
"id": 44
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -739,17 +1020,17 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 38
|
||||
"id": 45
|
||||
},
|
||||
{
|
||||
"id": 39
|
||||
"id": 46
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"targets": [
|
||||
33
|
||||
40
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
@ -768,61 +1049,171 @@
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15
|
||||
],
|
||||
"outputs": [
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
18
|
||||
],
|
||||
"outputs": [
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
"status_tracker": 35,
|
||||
"status_tracker": 42,
|
||||
"queue": null,
|
||||
"api_name": "predict",
|
||||
"scroll_to_output": true,
|
||||
"show_progress": true,
|
||||
"documentation": [
|
||||
[
|
||||
"(str): text",
|
||||
"(str): text",
|
||||
"(float | None): numeric input",
|
||||
"(number): numeric input",
|
||||
"(number): numeric input",
|
||||
"(bool): boolean input",
|
||||
"(List[str]): list of selected choices",
|
||||
"(str): selected choice",
|
||||
"(str): selected choice",
|
||||
"(str): base64 url data",
|
||||
"(str): base64 url data",
|
||||
"(str): base64 url data",
|
||||
"(str): base64 url data",
|
||||
"(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property",
|
||||
"(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property",
|
||||
"(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property"
|
||||
[
|
||||
"text",
|
||||
"str | None"
|
||||
],
|
||||
[
|
||||
"text",
|
||||
"str | None"
|
||||
],
|
||||
[
|
||||
"numeric input",
|
||||
"float | None"
|
||||
],
|
||||
[
|
||||
"numeric input",
|
||||
"float"
|
||||
],
|
||||
[
|
||||
"numeric input",
|
||||
"float"
|
||||
],
|
||||
[
|
||||
"boolean input",
|
||||
"bool"
|
||||
],
|
||||
[
|
||||
"list of selected choices",
|
||||
"List[str]"
|
||||
],
|
||||
[
|
||||
"selected choice",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"selected choice",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
],
|
||||
[
|
||||
"base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
|
||||
"str | Dict"
|
||||
],
|
||||
[
|
||||
"JSON object with filename as 'name' property and base64 data as 'data' property",
|
||||
"Dict[str, str] | None"
|
||||
],
|
||||
[
|
||||
"JSON object with filename as 'name' property and base64 data as 'data' property",
|
||||
"Dict[str, str] | None"
|
||||
],
|
||||
[
|
||||
"JSON object with filename as 'name' property and base64 data as 'data' property",
|
||||
"Dict[str, str] | None"
|
||||
],
|
||||
[
|
||||
"List of JSON objects with filename as 'name' property and base64 data as 'data' property",
|
||||
"List[Dict[str, str]] | None"
|
||||
],
|
||||
[
|
||||
"2D array of str, numeric, or bool data",
|
||||
"DataframeData"
|
||||
],
|
||||
[
|
||||
"Dict with keys 'data': 2D array of str, numeric, or bool data, 'headers': list of strings for header names, 'range': optional two element list designating start of end of subrange.",
|
||||
"Dict | None"
|
||||
]
|
||||
],
|
||||
[
|
||||
"(str | None): text",
|
||||
"(Dict[label: str, confidences: List[Dict[label: str, confidence: number]]]): Object with key 'label' representing primary label, and key 'confidences' representing a list of label-confidence pairs",
|
||||
"(str): base64 url data",
|
||||
"(str): base64 url data",
|
||||
"(str): base64 url data",
|
||||
"(List[Tuple[str, str | number | None]]): List of (word, category) tuples",
|
||||
"(List[Tuple[str, str | number | None]]): List of (word, category) tuples",
|
||||
"(Dict | List): JSON output",
|
||||
null
|
||||
[
|
||||
"text",
|
||||
"str | None"
|
||||
],
|
||||
[
|
||||
"Object with key 'label' representing primary label, and key 'confidences' representing a list of label-confidence pairs",
|
||||
"Dict | None"
|
||||
],
|
||||
[
|
||||
"base64 url data",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"base64 url data",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"base64 url data",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"List of (word, category) tuples",
|
||||
"Optional[List[Tuple[str, str | float | None]]]"
|
||||
],
|
||||
[
|
||||
"List of (word, category) tuples",
|
||||
"Optional[List[Tuple[str, str | float | None]]]"
|
||||
],
|
||||
[
|
||||
"JSON output",
|
||||
"Dict | List | None"
|
||||
],
|
||||
[
|
||||
null,
|
||||
"None"
|
||||
],
|
||||
[
|
||||
"JSON object with key 'name' for filename, 'data' for base64 url, and 'size' for filesize in bytes",
|
||||
"Dict"
|
||||
],
|
||||
[
|
||||
"JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
|
||||
"Dict"
|
||||
],
|
||||
[
|
||||
"JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
|
||||
"Dict"
|
||||
],
|
||||
[
|
||||
"JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
|
||||
"Dict"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
32
|
||||
39
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [],
|
||||
@ -852,10 +1243,17 @@
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
30
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
37
|
||||
],
|
||||
"backend_fn": false,
|
||||
"js": "() => [\"\", \"\", null, 15, 0, null, [], \"baz\", \"foo\", null, null, null, null, null, null, null, \"\", null, null, null, null, null, null, null, null, {\"variant\": null, \"visible\": true, \"__type__\": \"update\"}]\n ",
|
||||
"js": "() => [\"\", \"\", null, 15, 0, null, [], \"baz\", null, null, null, null, null, null, null, null, null, null, null, \"\", null, null, null, null, null, null, null, null, null, null, null, null, {\"variant\": null, \"visible\": true, \"__type__\": \"update\"}]\n ",
|
||||
"status_tracker": null,
|
||||
"queue": null,
|
||||
"api_name": null,
|
||||
@ -864,7 +1262,7 @@
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
37
|
||||
44
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
@ -892,7 +1290,14 @@
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31
|
||||
],
|
||||
"outputs": [],
|
||||
"backend_fn": true,
|
||||
@ -905,11 +1310,11 @@
|
||||
},
|
||||
{
|
||||
"targets": [
|
||||
38
|
||||
45
|
||||
],
|
||||
"trigger": "click",
|
||||
"inputs": [
|
||||
38
|
||||
45
|
||||
],
|
||||
"outputs": [
|
||||
0,
|
||||
@ -927,7 +1332,10 @@
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"backend_fn": true,
|
||||
"js": null,
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.1.1\n",
|
||||
"version": "3.1.4",
|
||||
"mode": "interface",
|
||||
"dev_mode": true,
|
||||
"components": [
|
||||
@ -358,14 +358,32 @@
|
||||
"show_progress": true,
|
||||
"documentation": [
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
[
|
||||
"selected choice",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"numeric input",
|
||||
"float"
|
||||
],
|
||||
[
|
||||
"selected choice",
|
||||
"str"
|
||||
],
|
||||
[
|
||||
"list of selected choices",
|
||||
"List[str]"
|
||||
],
|
||||
[
|
||||
"boolean input",
|
||||
"bool"
|
||||
]
|
||||
],
|
||||
[
|
||||
null
|
||||
[
|
||||
"plot type mapped to plot base64 data",
|
||||
"Dict[str, str] | None"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"build:website": "vite build --mode production:website --emptyOutDir",
|
||||
"build:local": "vite build --mode production:local --emptyOutDir",
|
||||
"preview": "vite preview",
|
||||
"test:browser": "pnpm exec playwright test test/ --config=../../playwright.config.js",
|
||||
"test:browser": "pnpm exec python test/create_demo_configs.py && pnpm exec playwright test test/ --config=../../playwright.config.js",
|
||||
"test:browser:debug": "pnpm exec playwright test test/ --debug --config=../../playwright.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -27,18 +27,17 @@ function mock_api(page: Page, body: Array<unknown>) {
|
||||
|
||||
test("renders the correct elements", async ({ page }) => {
|
||||
await mock_demo(page, "blocks_inputs");
|
||||
await mock_api(page, [["hello world"]]);
|
||||
await mock_api(page, [["hi dawood"]]);
|
||||
await page.goto("http://localhost:3000");
|
||||
|
||||
const textbox = await page.locator("label:has-text('Input')");
|
||||
const button = await page.locator("button");
|
||||
const textboxOne = await page.locator("label:has-text('Input')").first();
|
||||
const textboxTwo = await page.locator("label:has-text('Input')").last();
|
||||
const submit = await page.locator("text=Submit");
|
||||
|
||||
await textbox.fill("hello world");
|
||||
await Promise.all([button.click(), page.waitForResponse("**/api/predict/")]);
|
||||
await expect(
|
||||
await page.inputValue("label:has-text('Output-Interactive')")
|
||||
).toEqual("hello world");
|
||||
await expect(await page.inputValue("label:has-text('Input')")).toEqual(
|
||||
"hello world"
|
||||
await textboxOne.fill("hi");
|
||||
await textboxTwo.fill("dawood");
|
||||
await Promise.all([submit.click(), page.waitForResponse("**/api/predict/")]);
|
||||
await expect(await page.inputValue("label:has-text('Output')")).toEqual(
|
||||
"hi dawood"
|
||||
);
|
||||
});
|
10
ui/packages/app/test/create_demo_configs.py
Normal file
10
ui/packages/app/test/create_demo_configs.py
Normal file
@ -0,0 +1,10 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
for f in os.listdir(os.path.dirname(__file__)):
|
||||
if ".spec.ts" in f:
|
||||
split_tup = f.split(".")
|
||||
command = f'python ../../../../demo/write_config.py {split_tup[0]} ../../../../demo/{split_tup[0]}/config.json'
|
||||
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, cwd=os.path.dirname(__file__))
|
||||
output, error = process.communicate()
|
||||
|
@ -26,7 +26,7 @@ function mock_api(page: Page, body: Array<unknown>) {
|
||||
}
|
||||
|
||||
test("a component acts as both input and output", async ({ page }) => {
|
||||
await mock_demo(page, "input-output");
|
||||
await mock_demo(page, "input_output");
|
||||
await mock_api(page, [["tset"]]);
|
||||
await page.goto("http://localhost:3000");
|
||||
|
Loading…
x
Reference in New Issue
Block a user