Initial commit
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Which OS are you using?**
|
||||
- OS: [e.g. Linux or Windows]
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Any feature you want
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe feature you want**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
## Related issues / PRs.
|
||||
- #
|
||||
|
||||
## Summarize Changes
|
||||
1.
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Publish to Comfy registry
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# Uncomment the lines below to enable the workflow
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
# - master
|
||||
# paths:
|
||||
# - "pyproject.toml"
|
||||
|
||||
jobs:
|
||||
publish-node:
|
||||
name: Publish Custom Node to registry
|
||||
runs-on: ubuntu-latest
|
||||
# if this is a forked repository. Skipping the workflow.
|
||||
if: github.event.repository.fork == false
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Publish Custom Node
|
||||
uses: Comfy-Org/publish-node-action@main
|
||||
with:
|
||||
## Add your own personal access token to your Github Repository secrets and reference it here.
|
||||
## Get your personal access token from https://docs.comfy.org/registry/publishing#create-an-api-key-for-publishing
|
||||
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
||||
@@ -0,0 +1,3 @@
|
||||
/.idea/
|
||||
/venv/
|
||||
/__pycache__/
|
||||
@@ -0,0 +1,89 @@
|
||||
# ComfyUI CustomNode Template
|
||||
|
||||
This is the [ComfyUI](https://github.com/comfyanonymous/ComfyUI) custom node template repository that anyone can use to create their own custom nodes.
|
||||
|
||||
## Directory Structure
|
||||
```
|
||||
Project-Name/
|
||||
├── .github/ # GA workflow for publishing the ComfyUI registry
|
||||
├── workflows/ # Example workflows for your custom node
|
||||
├── modules/ # Your own modules for the custom node
|
||||
├── .gitignore # gitignore file
|
||||
├── __init__.py # Map your custom node display names here
|
||||
├── nodes.py # Your custom node classes
|
||||
├── README.md # README file
|
||||
├── pyproject.toml # Metadata file for the ComfyUI registry
|
||||
└── requirements.txt # Project dependencies
|
||||
```
|
||||
|
||||
## Custom Node Files
|
||||
|
||||
### [nodes.py](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/nodes.py)
|
||||
This file is where your actual custom node classes are defined. The class has specific methods that are called by the ComfyUI engine.
|
||||
There're some basic custom nodes for the example with some comments, you can modify them as you need.
|
||||
For detailed information on how to create custom nodes, please refer to the ComfyUI official documentation:
|
||||
- https://docs.comfy.org/essentials/custom_node_walkthrough.
|
||||
|
||||
### [__init__.py](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/__init__.py)
|
||||
You can map your custom node display names here. It will be used when users search for your custom node in the ComfyUI.
|
||||
|
||||
### [pyproject.toml](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/pyproject.toml)
|
||||
This file is used to publish your custom node to the ComfyUI registry. If you want to publish your custom node to the ComfyUI registry, you need to modify this file.
|
||||
|
||||
If you wonder what ComfyUI registry is, please read:
|
||||
|
||||
- https://docs.comfy.org/registry/overview#why-use-the-registry
|
||||
|
||||
### [requirements.txt](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/requirements.txt)
|
||||
This file contains the dependencies needed for your custom node. `torch` is already installed in the ComfyUI, so you only need to add "extra" dependencies here.
|
||||
|
||||
### [workflows/example-1.json](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/workflows)
|
||||
This is optional, but it is recommended to put your ComfyUI workflow json file inside your project so users can easily understand how to use your custom node.
|
||||
|
||||
## Github Actions
|
||||
|
||||
### [publish-comfyui-registry.yml](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/.github/workflows/publish-comfyui-registry.yml)
|
||||
When you push into the `master` branch, this workflow will be triggered and publish your custom node to the ComfyUI registry, using your [pyproject.toml](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/tree/master/pyproject.toml).
|
||||
You have to register your "REGISTRY_ACCESS_TOKEN" in the Github Action Secrets which you can get from:
|
||||
- https://docs.comfy.org/registry/publishing#create-an-api-key-for-publishing
|
||||
|
||||
After generating the repository from this template, uncomment the push to enable the workflow with auto trigger:
|
||||
|
||||
https://github.com/jhj0517/ComfyUI-CustomNodes-Template/blob/6ae10a1d161933c5e3cff432e1c8bbc9396be954/.github/workflows/publish-comfyui-registry.yml#L4-L10
|
||||
|
||||
## Github Issue & PR templates
|
||||
|
||||
There are some basic templates for the Github issues & PR. You can edit them or add more to fit your project's needs.
|
||||
|
||||
- Issue Templates:
|
||||
1. [bug_report.md](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) : Basic bug report template
|
||||
2. [feature_request.md](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) : Feature request template
|
||||
|
||||
- PR Template: [pull_request_template.md](https://github.com/jhj0517/ComfyUI-CustomNodes-Template/blob/master/.github/pull_request_template.md)
|
||||
|
||||
|
||||
## How to Strat Using Template
|
||||
|
||||
Click "Use this template" -> "Create a new repository", then you can create your own custom node from there.
|
||||
|
||||

|
||||
|
||||
The custom node installation guide below can usually be used for any custom node, you can use it in your README by modifying the repository name and URL.
|
||||
## Installation
|
||||
|
||||
1. git clone repository into `ComfyUI\custom_nodes\`
|
||||
```
|
||||
git clone https://github.com/replace-this-with-your-github-repository-url.git
|
||||
```
|
||||
|
||||
2. Go to `ComfyUI\custom_nodes\ComfyUI-Your-CustomNode-Name` and run
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
If you are using the portable version of ComfyUI, do this:
|
||||
```
|
||||
python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\ComfyUI-Your-CustomNode-Name\requirements.txt
|
||||
```
|
||||
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
from .nodes import *
|
||||
|
||||
|
||||
# Map all your custom nodes classes with the names that will be displayed in the UI.
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"(Down)Load My Model": MyModelLoader,
|
||||
"Calculate Plus": CalculatePlus,
|
||||
"Calculate Minus": CalculateMinus,
|
||||
"Example Output Node": ExampleOutputNode,
|
||||
}
|
||||
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS']
|
||||
@@ -0,0 +1,21 @@
|
||||
from typing import Optional
|
||||
|
||||
class CalculatorModel:
|
||||
def __init__(self):
|
||||
self.model = None
|
||||
|
||||
def load_model(self,
|
||||
model_path: str,
|
||||
device: str,
|
||||
compute_type: Optional[str] = None,
|
||||
):
|
||||
self.model = 1
|
||||
print("Calculator model loaded")
|
||||
|
||||
@staticmethod
|
||||
def plus(a, b):
|
||||
return a+b
|
||||
|
||||
@staticmethod
|
||||
def minus(a, b):
|
||||
return a-b
|
||||
@@ -0,0 +1,152 @@
|
||||
# Package Modules
|
||||
import os
|
||||
from typing import Union, BinaryIO, Dict, List, Tuple, Optional
|
||||
import time
|
||||
|
||||
# ComfyUI Modules
|
||||
import folder_paths
|
||||
from comfy.utils import ProgressBar
|
||||
|
||||
# Your Modules
|
||||
from .modules.calculator import CalculatorModel
|
||||
|
||||
|
||||
# Basic practice to get paths from ComfyUI
|
||||
custom_nodes_script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
custom_nodes_model_dir = os.path.join(folder_paths.models_dir, "my-custom-nodes")
|
||||
custom_nodes_output_dir = os.path.join(folder_paths.get_output_directory(), "my-custom-nodes")
|
||||
|
||||
|
||||
# These are example nodes that only contains basic functionalities with some comments.
|
||||
# If you need detailed explanation, please refer to : https://docs.comfy.org/essentials/custom_node_walkthrough
|
||||
# First Node:
|
||||
class MyModelLoader:
|
||||
# Define the input parameters of the node here.
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
my_models = ["Model A", "Model B", "Model C"]
|
||||
|
||||
return {
|
||||
# If the key is "required", the value must be filled.
|
||||
"required": {
|
||||
# `my_models` is the list, so it will be shown as a dropdown menu in the node. ( So that user can select one of them. )
|
||||
# You must provide the value in the tuple format. e.g. ("value",) or (3,) or ([1, 2],) etc.
|
||||
"model": (my_models,),
|
||||
"device": (['cuda', 'cpu', 'auto'],),
|
||||
},
|
||||
# If the key is "optional", the value is optional.
|
||||
"optional": {
|
||||
"compute_type": (['float32', 'float16'],),
|
||||
}
|
||||
}
|
||||
|
||||
# Define these constants inside the node.
|
||||
# `RETURN_TYPES` is important, as it limits the parameter types that can be passed to the next node, in `INPUT_TYPES()` above.
|
||||
RETURN_TYPES = ("MY_MODEL",)
|
||||
RETURN_NAMES = ("my_model",)
|
||||
# `FUNCTION` is the function name that will be called in the node.
|
||||
FUNCTION = "load_model"
|
||||
# `CATEGORY` is the category name that will be used when user searches the node.
|
||||
CATEGORY = "CustomNodesTemplate"
|
||||
|
||||
# In the function, use same parameter names as you specified in `INPUT_TYPES()`
|
||||
def load_model(self,
|
||||
model: str,
|
||||
device: str,
|
||||
compute_type: Optional[str] = None,
|
||||
) -> Tuple[CalculatorModel]:
|
||||
calculator_model = CalculatorModel()
|
||||
calculator_model.load_model(model, device, compute_type)
|
||||
|
||||
# You can use `comfy.utils.ProgressBar` to show the progress of the process.
|
||||
# First, initialize the total amount of the process.
|
||||
total_steps = 5
|
||||
comfy_pbar = ProgressBar(total_steps)
|
||||
# Then, update the progress.
|
||||
for i in range(1, total_steps):
|
||||
time.sleep(1)
|
||||
comfy_pbar.update(i) # Alternatively, you can use `comfy_pbar.update_absolute(value)` to update the progress with absolute value.
|
||||
|
||||
# Return the model as a tuple.
|
||||
return (calculator_model, )
|
||||
|
||||
|
||||
# Second Node
|
||||
class CalculatePlus:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MY_MODEL", ),
|
||||
},
|
||||
# Specify the parameters with type and default value.
|
||||
"optional": {
|
||||
"a": ("INT", {"default": 5}),
|
||||
"b": ("INT", {"default": 10}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("plus_value",)
|
||||
FUNCTION = "plus"
|
||||
CATEGORY = "CustomNodesTemplate"
|
||||
|
||||
def plus(self,
|
||||
model: CalculatorModel,
|
||||
a: Optional[int],
|
||||
b: Optional[int],
|
||||
) -> Tuple[int]:
|
||||
result = model.plus(a, b)
|
||||
return (result, )
|
||||
|
||||
|
||||
|
||||
# Third Node
|
||||
class CalculateMinus:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MY_MODEL", ),
|
||||
"a": ("INT", ),
|
||||
},
|
||||
"optional": {
|
||||
"b": ("INT", {"default": 10}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("minus_value",)
|
||||
FUNCTION = "minus"
|
||||
CATEGORY = "CustomNodesTemplate"
|
||||
|
||||
def minus(self,
|
||||
model: CalculatorModel,
|
||||
a: Optional[int],
|
||||
b: Optional[int],
|
||||
) -> Tuple[int]:
|
||||
result = model.minus(a, b)
|
||||
return (result, )
|
||||
|
||||
|
||||
|
||||
# Output Node
|
||||
class ExampleOutputNode:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("INT", ),
|
||||
},
|
||||
}
|
||||
|
||||
# If the node is output node, set this to True.
|
||||
OUTPUT_NODE = True
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("int",)
|
||||
FUNCTION = "result"
|
||||
CATEGORY = "CustomNodesTemplate"
|
||||
|
||||
def result(self,
|
||||
value: int,) -> Tuple[int]:
|
||||
return (value, )
|
||||
@@ -0,0 +1,17 @@
|
||||
# Edit the following fields to match your project
|
||||
|
||||
[project]
|
||||
name = "comfyui-customnodes-template"
|
||||
description = "Template repository for custom nodes from [ComfyUI-CustomNodes-Template](https://github.com/jhj0517/ComfyUI-CustomNodes-Template)."
|
||||
version = "1.0.0"
|
||||
license = {file = "LICENSE"}
|
||||
dependencies = ["",] # e.g.) ["numpy==1.18.1", ]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/jhj0517/ComfyUI-CustomNodes-Template"
|
||||
# Used by Comfy Registry https://comfyregistry.org
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "jhj0517"
|
||||
DisplayName = "ComfyUI-CustomNodes-Template"
|
||||
Icon = ""
|
||||
@@ -0,0 +1,3 @@
|
||||
# Update your requirements.
|
||||
# numpy==1.18.1
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
{
|
||||
"last_node_id": 23,
|
||||
"last_link_id": 16,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 10,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
904.8049926757812,
|
||||
-1030.0733642578125
|
||||
],
|
||||
"size": [
|
||||
244.79127502441406,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"This will a+b and output `plus_value` as `INT` type."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": "Example Output Node",
|
||||
"pos": [
|
||||
1633.39697265625,
|
||||
-909.4421997070312
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 8,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "INT",
|
||||
"link": 15,
|
||||
"widget": {
|
||||
"name": "value"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "int",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
16
|
||||
],
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Example Output Node"
|
||||
},
|
||||
"widgets_values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
1280.2978515625,
|
||||
-1024.9307861328125
|
||||
],
|
||||
"size": [
|
||||
268.57818603515625,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"This will a-b and output `minus_value` as `INT` type."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
529.62744140625,
|
||||
-1029.177734375
|
||||
],
|
||||
"size": [
|
||||
332.0714111328125,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"This is just a mocking node, it doesn't actually do anything.\nThis will return `my_model` as `MY_MODEL` type."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"type": "Calculate Plus",
|
||||
"pos": [
|
||||
898.446533203125,
|
||||
-802.1386108398438
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
82
|
||||
],
|
||||
"flags": {},
|
||||
"order": 6,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "model",
|
||||
"type": "MY_MODEL",
|
||||
"link": 8
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "plus_value",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
14
|
||||
],
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Calculate Plus"
|
||||
},
|
||||
"widgets_values": [
|
||||
1,
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"type": "(Down)Load My Model",
|
||||
"pos": [
|
||||
527.8483276367188,
|
||||
-907.7310791015625
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
106
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "my_model",
|
||||
"type": "MY_MODEL",
|
||||
"links": [
|
||||
8,
|
||||
9
|
||||
],
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "(Down)Load My Model"
|
||||
},
|
||||
"widgets_values": [
|
||||
"Model A",
|
||||
"cuda",
|
||||
"float32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"type": "Calculate Minus",
|
||||
"pos": [
|
||||
1281.708984375,
|
||||
-909.4426879882812
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
82
|
||||
],
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "model",
|
||||
"type": "MY_MODEL",
|
||||
"link": 9
|
||||
},
|
||||
{
|
||||
"name": "a",
|
||||
"type": "INT",
|
||||
"link": 14,
|
||||
"widget": {
|
||||
"name": "a"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "minus_value",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
15
|
||||
],
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Calculate Minus"
|
||||
},
|
||||
"widgets_values": [
|
||||
0,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
1635.964111328125,
|
||||
-1024.9598388671875
|
||||
],
|
||||
"size": [
|
||||
268.57818603515625,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"This is an example of an `OUTPUT_NODE`. Without an output node, the workflow cannot be queued."
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"type": "Display Any (rgthree)",
|
||||
"pos": [
|
||||
2046.694580078125,
|
||||
-934.2572631835938
|
||||
],
|
||||
"size": [
|
||||
264.5999755859375,
|
||||
76
|
||||
],
|
||||
"flags": {},
|
||||
"order": 9,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "source",
|
||||
"type": "*",
|
||||
"link": 16,
|
||||
"dir": 3
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"properties": {
|
||||
"Node name for S&R": "Display Any (rgthree)"
|
||||
},
|
||||
"widgets_values": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
2046.1151123046875,
|
||||
-1021.53759765625
|
||||
],
|
||||
"size": [
|
||||
313.9296875,
|
||||
59.71138000488281
|
||||
],
|
||||
"flags": {},
|
||||
"order": 5,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"This is \"Display Any\" node from rgthree-comfy:\nhttps://github.com/rgthree/rgthree-comfy"
|
||||
],
|
||||
"color": "#432",
|
||||
"bgcolor": "#653"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
8,
|
||||
14,
|
||||
0,
|
||||
15,
|
||||
0,
|
||||
"MY_MODEL"
|
||||
],
|
||||
[
|
||||
9,
|
||||
14,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
"MY_MODEL"
|
||||
],
|
||||
[
|
||||
14,
|
||||
15,
|
||||
0,
|
||||
16,
|
||||
1,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
15,
|
||||
16,
|
||||
0,
|
||||
22,
|
||||
0,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
16,
|
||||
22,
|
||||
0,
|
||||
18,
|
||||
0,
|
||||
"*"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"scale": 1.0731406124180385,
|
||||
"offset": [
|
||||
-59.30322993213241,
|
||||
1287.2851300794632
|
||||
]
|
||||
},
|
||||
"VHS_latentpreview": false,
|
||||
"VHS_latentpreviewrate": 0
|
||||
},
|
||||
"version": 0.4
|
||||
}
|
||||
Reference in New Issue
Block a user