forked from gav/es-bot
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
b313b15686 | |||
aacb413176 | |||
efc711cd3b | |||
b77f1bc13d | |||
55f17606d6 | |||
e0c9aad35a | |||
8c558f7bc0 | |||
a66fde985f | |||
f97a8286b7 | |||
1dfd81de31 | |||
20eaea722f | |||
ee834376db | |||
ca6ac97e33 | |||
be430673f1 | |||
2dc6327fe1 | |||
221ff51d3d | |||
0fc4d0df82 | |||
fe897a596c | |||
2bc65d37dd | |||
98136d93a2 | |||
cc206ff358 | |||
9065115927 | |||
db629bb804 | |||
0649bb445c | |||
c5d18e56d5 | |||
08e7f4ee93 | |||
65ed6f9fa6 | |||
d9c9f8f131 | |||
80584dbaf9 | |||
56adc16b04 | |||
f2e6e27179 | |||
a54eeaf625 | |||
80b464baf5 | |||
e1bd7234ed |
10
.drone.yml
Normal file
10
.drone.yml
Normal file
@ -0,0 +1,10 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: greeting
|
||||
image: alpine
|
||||
commands:
|
||||
- echo hello
|
||||
- echo world
|
5
.env.sample
Normal file
5
.env.sample
Normal file
@ -0,0 +1,5 @@
|
||||
PG_USER=pg
|
||||
PG_PASS=<password>
|
||||
PG_OUTBOUND_PORT=5432
|
||||
GROUP_ID=<group id>
|
||||
TOKEN=<token>
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,6 @@
|
||||
*__pycache__*
|
||||
tmp
|
||||
.env
|
||||
docker-compose-dev.yml
|
||||
*.DS_Store*
|
||||
.idea/
|
||||
|
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
||||
FROM python:3.9
|
||||
|
||||
ENV DB_ADDR localhost:5432
|
||||
ENV GROUP_ID group_id
|
||||
ENV NFT_ADDR http://localhost:5001
|
||||
ENV PASS pg
|
||||
ENV REDIS_ADDR localhost
|
||||
ENV TMP_DIR ./tmp
|
||||
ENV TOKEN token
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN mkdir -p /app/tmp
|
||||
|
||||
COPY ./requirements.txt /app/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
|
||||
CMD ["python3", "main.py"]
|
12
README.md
12
README.md
@ -1,3 +1,13 @@
|
||||
# es-bot
|
||||
|
||||
todo (пока лень)
|
||||
[](https://droneci.gavt45.ru/gav/es-bot)
|
||||
|
||||
|
||||
## Deploy
|
||||
```shell
|
||||
$ cp .env.example .env
|
||||
```
|
||||
Change variables as you need and then:
|
||||
```shell
|
||||
$ docker-compose up -d
|
||||
```
|
||||
|
@ -1,2 +1,5 @@
|
||||
from .menu import menu_router
|
||||
from .test import test_router
|
||||
from .teacher import teacher_router
|
||||
from .student import student_router
|
||||
from .man import man_router
|
||||
|
19
blueprints/man.py
Normal file
19
blueprints/man.py
Normal file
@ -0,0 +1,19 @@
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler, PayloadContainsFilter, BotEvent, \
|
||||
EventTypeFilter
|
||||
from vkwave.types.bot_events import BotEventType
|
||||
|
||||
import locales
|
||||
|
||||
man_router = DefaultRouter()
|
||||
|
||||
|
||||
@man_router.registrar.with_decorator(
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value),
|
||||
PayloadContainsFilter("man"),
|
||||
)
|
||||
async def man_menu(event: BotEvent):
|
||||
sevent = SimpleBotEvent(event)
|
||||
return await sevent.answer(
|
||||
message=locales.MAN,
|
||||
keyboard=locales.MAN_KB.get_keyboard(),
|
||||
)
|
@ -1,12 +1,29 @@
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler, EventTypeFilter
|
||||
from vkwave.types.bot_events import BotEventType
|
||||
|
||||
import locales
|
||||
|
||||
menu_router = DefaultRouter()
|
||||
|
||||
|
||||
@simple_bot_message_handler(menu_router,)
|
||||
@menu_router.registrar.with_decorator(
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value),
|
||||
)
|
||||
async def menu(event: SimpleBotEvent):
|
||||
return await event.answer(
|
||||
sevent = SimpleBotEvent(event)
|
||||
return await sevent.answer(
|
||||
message=locales.MENU,
|
||||
keyboard=locales.MENU_KB.get_keyboard(),
|
||||
)
|
||||
|
||||
|
||||
@menu_router.registrar.with_decorator(
|
||||
EventTypeFilter(BotEventType.GROUP_JOIN.value),
|
||||
)
|
||||
async def menu(event: SimpleBotEvent):
|
||||
return await event.api_ctx.messages.send(
|
||||
keyboard=locales.MENU_KB.get_keyboard(),
|
||||
peer_id=event.object.object.user_id,
|
||||
message=locales.MENU,
|
||||
random_id=0
|
||||
)
|
||||
|
19
blueprints/student.py
Normal file
19
blueprints/student.py
Normal file
@ -0,0 +1,19 @@
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler, PayloadContainsFilter, BotEvent, \
|
||||
EventTypeFilter
|
||||
from vkwave.types.bot_events import BotEventType
|
||||
|
||||
import locales
|
||||
|
||||
student_router = DefaultRouter()
|
||||
|
||||
|
||||
@student_router.registrar.with_decorator(
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value),
|
||||
PayloadContainsFilter("student"),
|
||||
)
|
||||
async def student_menu(event: BotEvent):
|
||||
sevent = SimpleBotEvent(event)
|
||||
return await sevent.answer(
|
||||
message=locales.ST_MENU,
|
||||
keyboard=locales.ST_KB.get_keyboard(),
|
||||
)
|
19
blueprints/teacher.py
Normal file
19
blueprints/teacher.py
Normal file
@ -0,0 +1,19 @@
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler, PayloadContainsFilter, BotEvent, \
|
||||
EventTypeFilter
|
||||
from vkwave.types.bot_events import BotEventType
|
||||
|
||||
import locales
|
||||
|
||||
teacher_router = DefaultRouter()
|
||||
|
||||
|
||||
@teacher_router.registrar.with_decorator(
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value),
|
||||
PayloadContainsFilter("teacher"),
|
||||
)
|
||||
async def teacher_menu(event: BotEvent):
|
||||
sevent = SimpleBotEvent(event)
|
||||
return await sevent.answer(
|
||||
message=locales.TC_MENU,
|
||||
keyboard=locales.TC_KB.get_keyboard(),
|
||||
)
|
@ -1,46 +1,25 @@
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, simple_bot_message_handler, PayloadFilter, PayloadContainsFilter, \
|
||||
PhotoUploader
|
||||
from vkwave.bots import Keyboard, ButtonColor
|
||||
from vkwave.bots import DefaultRouter, SimpleBotEvent, PayloadContainsFilter
|
||||
from vkwave.bots import Keyboard
|
||||
from vkwave.bots import EventTypeFilter, BotEvent
|
||||
from vkwave.types.bot_events import BotEventType
|
||||
from vkwave.bots.fsm import FiniteStateMachine, StateFilter, ForWhat, State, ANY_STATE
|
||||
|
||||
import locales
|
||||
from config import Config
|
||||
from db import DB
|
||||
from db.db import TestResult
|
||||
from locales import INPUT_NAME_TEXT
|
||||
|
||||
|
||||
# MENU_KB.add_row()
|
||||
# MENU_KB.add_text_button(text="Профиль", payload={"command": "profile"}, color=ButtonColor.SECONDARY)
|
||||
# MENU_KB.add_row()
|
||||
# MENU_KB.add_text_button(text="Бонус", payload={"command": "bonus"}, color=ButtonColor.POSITIVE)
|
||||
# from nft_things.NftSender import NFTSender
|
||||
from util.redis_db import RedisDB
|
||||
from util.nft_util import get_image
|
||||
|
||||
test_router = DefaultRouter()
|
||||
|
||||
test_router.registrar.add_default_filter(
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value)) # we don't want to write it in all handlers.
|
||||
EMPTY_KB = '{"buttons": [], "inline": false, "one_time": false}'
|
||||
|
||||
|
||||
# # exiting from poll (works on any state)
|
||||
# @test_router.registrar.with_decorator(
|
||||
# lambda event: event.object.object.message.text == "exit",
|
||||
# StateFilter(fsm=fsm, state=ANY_STATE, for_what=ForWhat.FOR_USER)
|
||||
# )
|
||||
# async def simple_handler(event: BotEvent):
|
||||
# # Check if we have the user in database
|
||||
# if await fsm.get_data(event, for_what=ForWhat.FOR_USER) is not None:
|
||||
# await fsm.finish(event=event, for_what=ForWhat.FOR_USER)
|
||||
# return "You are quited!"
|
||||
|
||||
@test_router.registrar.with_decorator(
|
||||
PayloadContainsFilter("test"),# for state in States.questions[:-1]]
|
||||
EventTypeFilter(BotEventType.MESSAGE_NEW.value),
|
||||
PayloadContainsFilter("test"),
|
||||
)
|
||||
async def main_part_handle(event: BotEvent):
|
||||
user_id = event.object.object.message.from_id
|
||||
@ -50,8 +29,7 @@ async def main_part_handle(event: BotEvent):
|
||||
state_idx = int(payload["test"])
|
||||
logging.debug(f"State index: {state_idx}")
|
||||
|
||||
|
||||
q_res = payload['q'] if 'q' in payload else None
|
||||
q_res = payload['q'] if 'q' in payload else event.object.object.message.text
|
||||
logging.debug(f"Qres: {q_res}")
|
||||
|
||||
# extra_state_data works as fsm.add_data(..., state_data={"name": event.object.object.message.text})
|
||||
@ -61,17 +39,28 @@ async def main_part_handle(event: BotEvent):
|
||||
DB().update_test_result(user_id, question=state_idx, answer=q_res)
|
||||
|
||||
if state_idx + 1 < len(locales.questions):
|
||||
RedisDB().set_state(user_id, state_idx + 1)
|
||||
kb = locales.questions[state_idx + 1][1]
|
||||
if kb:
|
||||
return await botevent.answer(
|
||||
message=locales.questions[state_idx + 1][0],
|
||||
keyboard=locales.questions[state_idx + 1][1].get_keyboard(),
|
||||
keyboard=kb.get_keyboard(),
|
||||
)
|
||||
else:
|
||||
return await botevent.answer(
|
||||
message=locales.questions[state_idx + 1][0],
|
||||
payload=json.dumps({"test": state_idx + 1}),
|
||||
keyboard=EMPTY_KB, # try to remove keyboard
|
||||
)
|
||||
else:
|
||||
# todo add task to send user an image here
|
||||
# Config().nft_sender.add_task()
|
||||
RedisDB().del_state(user_id)
|
||||
logging.warn("Sending attach!")
|
||||
|
||||
big_attachment = await Config().uploader.get_attachments_from_paths(
|
||||
peer_id=user_id,
|
||||
file_paths=["img.jpg"],
|
||||
file_paths=[get_image(user_id)],
|
||||
)
|
||||
await Config().api_ctx.messages.send(
|
||||
user_id=user_id, attachment=big_attachment, random_id=0
|
||||
@ -80,21 +69,3 @@ async def main_part_handle(event: BotEvent):
|
||||
message=locales.LAST_MESSAGE,
|
||||
keyboard=locales.LAST_MESSAGE_KB.get_keyboard(),
|
||||
)
|
||||
|
||||
# @test_router.registrar.with_decorator(
|
||||
# StateFilter(fsm=fsm, state=MyState.age, for_what=ForWhat.FOR_USER),
|
||||
# )
|
||||
# async def simple_handler(event: BotEvent):
|
||||
# if not event.object.object.message.text.isdigit():
|
||||
# return f"Please, send only positive numbers!"
|
||||
# await fsm.add_data(
|
||||
# event=event,
|
||||
# for_what=ForWhat.FOR_USER,
|
||||
# state_data={"age": event.object.object.message.text},
|
||||
# )
|
||||
# user_data = await fsm.get_data(event=event, for_what=ForWhat.FOR_USER)
|
||||
#
|
||||
# # finish poll and delete the user
|
||||
# # `fsm.finish` will do it
|
||||
# await fsm.finish(event=event, for_what=ForWhat.FOR_USER)
|
||||
# return f"Your data - {user_data}"
|
||||
|
10
config.py
10
config.py
@ -1,4 +1,7 @@
|
||||
import os
|
||||
|
||||
from vkwave.bots import PhotoUploader
|
||||
|
||||
from util import Singleton
|
||||
|
||||
|
||||
@ -9,8 +12,13 @@ class Config(metaclass=Singleton):
|
||||
PG_USER = os.environ["USER"]
|
||||
PG_PASS = os.environ["PASS"]
|
||||
PG_ADDR = os.environ["DB_ADDR"]
|
||||
REDIS_ADDR = os.environ["REDIS_ADDR"]
|
||||
|
||||
NFT_SVC_ADDR = os.environ["NFT_ADDR"]
|
||||
|
||||
TMP_DIR = os.environ["TMP_DIR"]
|
||||
|
||||
def __init__(self):
|
||||
self.api_ctx = None
|
||||
self.uploader = None
|
||||
self.uploader: PhotoUploader = None
|
||||
|
||||
|
9
db/db.py
9
db/db.py
@ -64,10 +64,19 @@ class DB(metaclass=Singleton):
|
||||
|
||||
def update_test_result(self, user_id: int, question: int, answer: str):
|
||||
user = self._session.query(Candidate).filter(Candidate.id == user_id).first()
|
||||
for i, ans in enumerate(user.test_result[0].answers):
|
||||
if ans.question == question:
|
||||
logging.debug(f"Update test result: {question} {answer}")
|
||||
user.test_result[0].answers[i].answer = answer
|
||||
break
|
||||
else:
|
||||
logging.warn(f"New test result: {question} {answer}")
|
||||
user.test_result[0].answers.append(QuestionAnswer(question=question, answer=answer))
|
||||
self._session.commit()
|
||||
|
||||
def add_candidate(self, candidate: Candidate):
|
||||
if self._session.query(Candidate).filter(Candidate.id == candidate.id).first() is not None:
|
||||
return
|
||||
tres = TestResult(answers=[])
|
||||
candidate.test_result = [tres]
|
||||
self._session.add(candidate)
|
||||
|
@ -1,5 +1,30 @@
|
||||
version: "2"
|
||||
services:
|
||||
image_gen:
|
||||
build:
|
||||
context: ./nft_svc
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- 5001:5000
|
||||
|
||||
bot:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
environment:
|
||||
- DB_ADDR=pgdb:5432
|
||||
- GROUP_ID=${GROUP_ID}
|
||||
- NFT_ADDR=http://image_gen:5000
|
||||
- PASS=${PG_PASS}
|
||||
- REDIS_ADDR=redis
|
||||
- TMP_DIR=./tmp
|
||||
- TOKEN=${TOKEN}
|
||||
- USER=${PG_USER}
|
||||
depends_on:
|
||||
- pgdb
|
||||
- redis
|
||||
- image_gen
|
||||
|
||||
pgdb:
|
||||
image: 'postgres:12'
|
||||
restart: always
|
||||
@ -8,7 +33,18 @@ services:
|
||||
- POSTGRES_PASSWORD=${PG_PASS}
|
||||
- POSTGRES_DB=db
|
||||
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||
# volumes:
|
||||
# - ${PG_MNT}:/var/lib/postgresql/data
|
||||
ports:
|
||||
- ${PG_OUTBOUND_PORT}:5432
|
||||
volumes:
|
||||
- bot_pg_data:/var/lib/postgresql/data
|
||||
# ports:
|
||||
# - ${PG_OUTBOUND_PORT}:5432
|
||||
redis:
|
||||
image: "redis:alpine"
|
||||
command: redis-server --appendonly yes --appendfsync everysec
|
||||
# ports:
|
||||
# - 6379:6379
|
||||
volumes:
|
||||
- bot_redis_data:/data
|
||||
|
||||
volumes:
|
||||
bot_pg_data:
|
||||
bot_redis_data:
|
||||
|
BIN
img.jpg
BIN
img.jpg
Binary file not shown.
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 131 B |
145
locales.py
145
locales.py
@ -1,10 +1,72 @@
|
||||
from vkwave.bots import Keyboard, ButtonColor
|
||||
|
||||
# menu
|
||||
MENU = "Привет!"
|
||||
MENU = """С помощью бота вы можете:
|
||||
⚙ пройти тест и получить индивидуальный NFT-талисман, сгенерированный специально для вас нейросетью;
|
||||
⚙ вступить в чат абитуриентов, студентов и преподавателей;
|
||||
⚙ пообщаться со студентом (можно выбрать с кем);
|
||||
⚙ пообщаться с руководителем ИШ или преподавателем (можно выбрать с кем)."""
|
||||
MENU_KB = Keyboard()
|
||||
MENU_KB.add_text_button(text="Пройти тест!", payload={"test": "-1"}, color=ButtonColor.POSITIVE)
|
||||
MENU_KB.add_link_button(text="Общий чатик", link="https://vk.me/join/AJQ1dw97/SBEQYIyQdZfG69y")
|
||||
MENU_KB.add_text_button(text="Пройти тест", payload={"test": "-1"}, color=ButtonColor.POSITIVE)
|
||||
MENU_KB.add_link_button(text="Чат абитуриентов", link="https://vk.me/join/AJQ1dw97/SBEQYIyQdZfG69y")
|
||||
MENU_KB.add_row()
|
||||
MENU_KB.add_text_button(text="Пообщаться со студентом", payload={"student": "1"}, color=ButtonColor.PRIMARY)
|
||||
MENU_KB.add_row()
|
||||
MENU_KB.add_text_button(text="Пообщаться с преподавателем", payload={"teacher": "1"}, color=ButtonColor.PRIMARY)
|
||||
# MENU_KB.add_row()
|
||||
# MENU_KB.add_text_button(text="АЧе делать?", payload={"man": "1"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
# Student menu
|
||||
ST_MENU = """Если вы ходите узнать про жизнь студента Инженерной школы, то можете написать этим ребятам:
|
||||
*fossa_mar (Даша Пискеева), 2 курс;
|
||||
*shestakova__d (Даша Шестакова), 2 курс;
|
||||
*cleverbitch (Лиза Булгакова), 2 курс;
|
||||
*brainkiller78 (Данил Тищенко), 1 курс;
|
||||
*skazaniyk (Дмитрий Хамутский), 1 курс;
|
||||
*kirik229 (Анжела Шадрина), 2 курс;
|
||||
*dinazavrrrik (Назар Коновалов), 1 курс;
|
||||
*tenikeev (Тимур Еникеев), 1 курс.
|
||||
"""
|
||||
ST_KB = Keyboard()
|
||||
ST_KB.add_link_button(text="Даша Пискеева", link="https://vk.com/fossa_mar")
|
||||
ST_KB.add_link_button(text="Даша Шестакова", link="https://vk.com/shestakova__d")
|
||||
ST_KB.add_row()
|
||||
ST_KB.add_link_button(text="Лиза Булгакова", link="https://vk.com/cleverbitch")
|
||||
ST_KB.add_link_button(text="Данил Тищенко", link="https://vk.com/brainkiller78")
|
||||
ST_KB.add_row()
|
||||
ST_KB.add_link_button(text="Дмитрий Хамутский", link="https://vk.com/skazaniyk")
|
||||
ST_KB.add_link_button(text="Анжела Шадрина", link="https://vk.com/kirik229")
|
||||
ST_KB.add_row()
|
||||
ST_KB.add_link_button(text="Назар Коновалов", link="https://vk.com/dinazavrrrik")
|
||||
ST_KB.add_link_button(text="Тимур Еникеев", link="https://vk.com/tenikeev")
|
||||
ST_KB.add_row()
|
||||
ST_KB.add_text_button(text="Вернуться на главную", payload={}, color=ButtonColor.NEGATIVE)
|
||||
|
||||
# Teacher menu
|
||||
TC_MENU = """Вы можете написать преподавателям и руководителям Инженерной школы:
|
||||
*anastasia.v.karpenko (Анастасия Валерьевна Карпенко) — руководитель ИШ, преподаватель «Математической логики» и «Основ проектной деятельности»;
|
||||
*krkaushan (Кристина Андреевна Насыбуллова) — заместитель декана по 2 курсу;
|
||||
*id11073597 (Тимур Ринатович Насыбуллов) — преподаватель «Алгебры и геометрии» и «Теории функций комплексного переменного»;
|
||||
*yury_efremenko (Ефременко Юрий Даниилович) — заместитель декана по набору, преподаватель «Алгебры и геометрии»."""
|
||||
TC_KB = Keyboard()
|
||||
TC_KB.add_link_button(text="Анастасия Валерьевна", link="https://vk.com/anastasia.v.karpenko")
|
||||
TC_KB.add_link_button(text="Кристина Андреевна", link="https://vk.com/krkaushan")
|
||||
TC_KB.add_row()
|
||||
TC_KB.add_link_button(text="Тимур Ринатович", link="https://vk.com/id11073597")
|
||||
TC_KB.add_link_button(text="Юрий Даниилович", link="https://vk.com/yury_efremenko")
|
||||
TC_KB.add_row()
|
||||
TC_KB.add_text_button(text="Вернуться на главную", payload={}, color=ButtonColor.NEGATIVE)
|
||||
|
||||
# Manual
|
||||
MAN = """Если вы хотите пройти тест - нажми на соответствующую кнопку.
|
||||
Если вы абитуриент, и хотите узнать больше про инженерную школу, то вы можете пообщаться со студентами или преподавателями!
|
||||
Для этого нажмите на кнопку “Диалог со студентом” или “Диалог с преподавателем”.
|
||||
Также вы можете узнать про нас из соцсетей - для этого нажмите на кнопку “Таплинк”.
|
||||
Если вы хотите пообщаться с другими абитуриентами - нажми на кнопку “Неформальный чат”.
|
||||
Приятного пользования!"""
|
||||
|
||||
MAN_KB = Keyboard()
|
||||
MAN_KB.add_text_button(text="ХОЧУ ДОМОЙ!!!!!!!!!!!!!!!", payload={}, color=ButtonColor.NEGATIVE)
|
||||
|
||||
# TEST Questions
|
||||
INPUT_NAME_TEXT = "Пожалуйста, введите имя:"
|
||||
@ -12,54 +74,75 @@ INPUT_NAME_TEXT = "Пожалуйста, введите имя:"
|
||||
# 1
|
||||
WHAT_ENGINEER_ARE_YOU = "Кто ты из инженеров?"
|
||||
WHAT_ENGINEER_ARE_YOU_KB = Keyboard()
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Маск", payload={"q": "Маск", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Рогозин", payload={"q": "Рогозин", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Тесла", payload={"q": "Тесла", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Илон Маск", payload={"q": "Илон Маск"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Дмитрий Рогозин", payload={"q": "Дмитрий Рогозин"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_row()
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Кулибин", payload={"q": "Кулибин", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Калашников", payload={"q": "Калашников", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Кондратюк", payload={"q": "Кондратюк", "test": "0"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Никола Тесла", payload={"q": "Никола Тесла"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Иван Кулибин", payload={"q": "Иван Кулибин"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_row()
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Михаил Калашников", payload={"q": "Михаил Калашников"}, color=ButtonColor.PRIMARY)
|
||||
WHAT_ENGINEER_ARE_YOU_KB.add_text_button(text="Юрий Кондратюк", payload={"q": "Юрий Кондратюк"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
# 2
|
||||
PROG_LANG = "Какой ЯП нравится?"
|
||||
PROG_LANG = "Какой язык программирования вы чаще всего используете?"
|
||||
PROG_LANG_KB = Keyboard()
|
||||
PROG_LANG_KB.add_text_button(text="Python", payload={"q": "Python", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Pascal", payload={"q": "Pascal", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="C/C++", payload={"q": "ccpp", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Python", payload={"q": "Python"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Pascal", payload={"q": "Pascal"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_row()
|
||||
PROG_LANG_KB.add_text_button(text="JS", payload={"q": "JS", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="HTML+CSS", payload={"q": "HTMLCSS", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Haskel", payload={"q": "Haskel", "test": "1"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
PROG_LANG_KB.add_text_button(text="C/C++", payload={"q": "ccpp"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="JS", payload={"q": "JS"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_row()
|
||||
PROG_LANG_KB.add_text_button(text="HTML+CSS", payload={"q": "HTMLCSS"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Haskel", payload={"q": "Haskel"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_row()
|
||||
PROG_LANG_KB.add_text_button(text="Java", payload={"q": "Java"}, color=ButtonColor.PRIMARY)
|
||||
PROG_LANG_KB.add_text_button(text="Я не программирую", payload={"q": "Я не программирую"}, color=ButtonColor.PRIMARY)
|
||||
# 3
|
||||
FAV_THEME = "Какой предмет нравится?"
|
||||
FAV_THEME = "Какая школьная дисциплина нравится вам больше?"
|
||||
FAV_THEME_KB = Keyboard()
|
||||
FAV_THEME_KB.add_text_button(text="Матеша", payload={"q": "Матеша", "test": "2"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Русский/Литра", payload={"q": "русскийлитра", "test": "2"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Инфа", payload={"q": "Инфа", "test": "2"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Математика", payload={"q": "Математика"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Русский/Литература", payload={"q": "русскийлитра"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_row()
|
||||
FAV_THEME_KB.add_text_button(text="Физика", payload={"q": "Физика", "test": "2"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="другое", payload={"q": "other", "test": "2"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Информатика/программирование", payload={"q": "Инфа"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Физика", payload={"q": "Физика"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_row()
|
||||
FAV_THEME_KB.add_text_button(text="История/обществознание", payload={"q": "Инфа"}, color=ButtonColor.PRIMARY)
|
||||
FAV_THEME_KB.add_text_button(text="Другой", payload={"q": "other"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
# 4
|
||||
EGE = "Как готовился к ЕГЭ?"
|
||||
EGE = "Как вы готовитесь к ЕГЭ?"
|
||||
EGE_KB = Keyboard()
|
||||
EGE_KB.add_text_button(text="В школе", payload={"q": "школа", "test": "3"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="online", payload={"q": "online", "test": "3"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="репетитор", payload={"q": "репетитор", "test": "3"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="В школе", payload={"q": "школа"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="В онлайн-школе", payload={"q": "online"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="С репетитором", payload={"q": "репетитор"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_row()
|
||||
EGE_KB.add_text_button(text="Сам", payload={"q": "Сам", "test": "3"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="wtf?", payload={"q": "wtf", "test": "3"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="Самостоятельно", payload={"q": "Сам"}, color=ButtonColor.PRIMARY)
|
||||
EGE_KB.add_text_button(text="А? Какие экзамены?", payload={"q": "А? Какие экзамены?"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
# 5
|
||||
TRANS_ENGINEER_COUNT = "Сколько нужно инженеров, чтобы запустить трансляцию в Телемосте?"
|
||||
TRANS_ENGINEER_COUNT_KB = Keyboard()
|
||||
TRANS_ENGINEER_COUNT_KB.add_text_button(text="1", payload={"q": "1"}, color=ButtonColor.PRIMARY)
|
||||
TRANS_ENGINEER_COUNT_KB.add_text_button(text="2", payload={"q": "2"}, color=ButtonColor.PRIMARY)
|
||||
TRANS_ENGINEER_COUNT_KB.add_text_button(text="5", payload={"q": "5"}, color=ButtonColor.PRIMARY)
|
||||
|
||||
# 6
|
||||
ZODIAC = "Кто вы по знаку зодиака?"
|
||||
# ZODIAC_KB = Keyboard()
|
||||
# # 7
|
||||
# CONTACT = "Введите почту или ник в телеграмме, по которому мы сможем прислать вам результаты"
|
||||
|
||||
# last
|
||||
LAST_MESSAGE = "Спасибо, что прошел тест!"
|
||||
LAST_MESSAGE = "Теперь у вас есть ваш персональный NFT-талисман! Он поможет вам при сдаче экзаменов и поступлении в желаемый университет 🌟"
|
||||
LAST_MESSAGE_KB = Keyboard()
|
||||
LAST_MESSAGE_KB.add_text_button(text="Вернуться на главную", payload={}, color=ButtonColor.POSITIVE)
|
||||
|
||||
|
||||
questions = [
|
||||
(WHAT_ENGINEER_ARE_YOU, WHAT_ENGINEER_ARE_YOU_KB),
|
||||
(PROG_LANG, PROG_LANG_KB),
|
||||
(FAV_THEME, FAV_THEME_KB),
|
||||
(EGE, EGE_KB),
|
||||
(TRANS_ENGINEER_COUNT, TRANS_ENGINEER_COUNT_KB),
|
||||
(ZODIAC, None),
|
||||
# (CONTACT, None),
|
||||
]
|
||||
|
13
main.py
13
main.py
@ -3,29 +3,28 @@ import logging
|
||||
from vkwave.bots import SimpleLongPollBot, PhotoUploader
|
||||
|
||||
from blueprints import (
|
||||
menu_router, test_router,
|
||||
menu_router, test_router, student_router, teacher_router, man_router,
|
||||
)
|
||||
from config import Config
|
||||
from middlewares import UserMiddleware
|
||||
# from nft_things.NftSender import NFTSender
|
||||
from middlewares.test_state_middleware import TestStateMiddleware
|
||||
|
||||
logging.basicConfig(level="DEBUG")
|
||||
|
||||
bot = SimpleLongPollBot(Config.TOKEN, group_id=Config.GROUP_ID)
|
||||
|
||||
# nft_sender = NFTSender(bot.api_context)
|
||||
# nft_sender.start()
|
||||
uploader = PhotoUploader(bot.api_context)
|
||||
Config().api_ctx = bot.api_context
|
||||
Config().uploader = uploader
|
||||
|
||||
bot.middleware_manager.add_middleware(UserMiddleware())
|
||||
|
||||
bot.middleware_manager.add_middleware(TestStateMiddleware())
|
||||
|
||||
bot.dispatcher.add_router(test_router)
|
||||
# bot.dispatcher.add_router(games_router)
|
||||
# bot.dispatcher.add_router(coin_flip_router)
|
||||
# bot.dispatcher.add_router(bonus_router)
|
||||
bot.dispatcher.add_router(student_router)
|
||||
bot.dispatcher.add_router(teacher_router)
|
||||
bot.dispatcher.add_router(man_router)
|
||||
|
||||
# регаем последним чтобы сначала проверялись все остальные команды
|
||||
bot.dispatcher.add_router(menu_router)
|
||||
|
31
middlewares/test_state_middleware.py
Normal file
31
middlewares/test_state_middleware.py
Normal file
@ -0,0 +1,31 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from vkwave.bots import BaseMiddleware, BotEvent, MiddlewareResult, SimpleBotEvent, Storage
|
||||
from vkwave.bots.storage.types import Key
|
||||
from vkwave.types.bot_events import MessageNewObject
|
||||
|
||||
from db import DB, Candidate
|
||||
from util.redis_db import RedisDB
|
||||
|
||||
storage = Storage()
|
||||
|
||||
|
||||
class TestStateMiddleware(BaseMiddleware):
|
||||
async def pre_process_event(self, event: BotEvent) -> MiddlewareResult:
|
||||
if isinstance(event.object.object, MessageNewObject):
|
||||
user_id = event.object.object.message.from_id
|
||||
else:
|
||||
return MiddlewareResult(True)
|
||||
|
||||
redis_test_state = RedisDB().get_state(user_id)
|
||||
logging.debug(event.object.object.message.payload)
|
||||
payload_json = json.loads(event.object.object.message.payload) if event.object.object.message.payload else {}
|
||||
|
||||
if 'test' not in payload_json.keys() and (
|
||||
redis_test_state != None):
|
||||
logging.debug(f"User {user_id} is in state: {redis_test_state}")
|
||||
payload_json["test"] = int(redis_test_state)
|
||||
|
||||
event.object.object.message.payload = json.dumps(payload_json)
|
||||
return MiddlewareResult(True)
|
@ -1,19 +1,33 @@
|
||||
import logging
|
||||
|
||||
from vkwave.bots import BaseMiddleware, BotEvent, MiddlewareResult, SimpleBotEvent
|
||||
from vkwave.types.bot_events import GroupJoinObject, MessageNewObject
|
||||
from vkwave.types.objects import UsersUser
|
||||
|
||||
from db import DB, Candidate
|
||||
|
||||
|
||||
async def get_user(api_ctx, user_id):
|
||||
raw_user = (
|
||||
await api_ctx.api_request("users.get", {"user_ids": user_id})
|
||||
)["response"][0]
|
||||
return UsersUser(**raw_user)
|
||||
|
||||
|
||||
class UserMiddleware(BaseMiddleware):
|
||||
async def pre_process_event(self, event: BotEvent) -> MiddlewareResult:
|
||||
db = DB()
|
||||
botevent = SimpleBotEvent(event)
|
||||
|
||||
if isinstance(event.object.object, GroupJoinObject):
|
||||
user_id = event.object.object.user_id
|
||||
elif isinstance(event.object.object, MessageNewObject):
|
||||
user_id = event.object.object.message.from_id
|
||||
else:
|
||||
return MiddlewareResult(True)
|
||||
|
||||
user = db.get_user(user_id)
|
||||
if not user:
|
||||
user_info = await botevent.get_user()
|
||||
user_info = await get_user(event.api_ctx, user_id)
|
||||
logging.debug(f"Got user info: {user_info}")
|
||||
user = Candidate(id=user_id, sex=user_info.sex, name=user_info.first_name, last_name=user_info.last_name)
|
||||
db.add_candidate(user)
|
||||
|
14
nft_svc/Dockerfile
Normal file
14
nft_svc/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM python:3.9
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./requirements.txt /app/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
ENTRYPOINT [ "flask" ]
|
||||
CMD ["run", "--host=0.0.0.0", "--port=5000"]
|
46
nft_svc/app.py
Normal file
46
nft_svc/app.py
Normal file
@ -0,0 +1,46 @@
|
||||
import io
|
||||
import random
|
||||
import os
|
||||
|
||||
from PIL import Image
|
||||
from flask import Flask, request, jsonify
|
||||
import matplotlib.image as mpimg
|
||||
import base64
|
||||
|
||||
app = Flask(__name__)
|
||||
IMAGE_PATH = 'pics'
|
||||
|
||||
|
||||
def open_image_as_array(path):
|
||||
return mpimg.imread(path)
|
||||
|
||||
|
||||
def get_encoded_img(arr):
|
||||
img = Image.fromarray(arr)
|
||||
img_byte_arr = io.BytesIO()
|
||||
img.save(img_byte_arr, format='PNG')
|
||||
encoded_img = base64.encodebytes(img_byte_arr.getvalue()).decode('ascii')
|
||||
return str(encoded_img)
|
||||
|
||||
|
||||
@app.route('/getImage', methods=['GET'])
|
||||
def get_image():
|
||||
# print(random.choice(os.listdir(IMAGE_PATH)))
|
||||
file = os.path.join(IMAGE_PATH, random.choice(os.listdir(IMAGE_PATH)))
|
||||
# buffered = io.BytesIO()
|
||||
# image.save(buffered, format="JPEG")
|
||||
# img_str = base64.b64encode(buffered.getvalue())
|
||||
image = base64.encodebytes(open(file, 'rb').read()).decode('ascii')
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"image": image,
|
||||
"first_time": 1
|
||||
})
|
||||
|
||||
|
||||
def start_app():
|
||||
app.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
start_app()
|
10
nft_svc/gunicorn_config.py
Normal file
10
nft_svc/gunicorn_config.py
Normal file
@ -0,0 +1,10 @@
|
||||
# Gunicorn config variables
|
||||
loglevel = "info"
|
||||
errorlog = "-" # stderr
|
||||
accesslog = "-" # stdout
|
||||
worker_tmp_dir = "/dev/shm"
|
||||
graceful_timeout = 120
|
||||
timeout = 120
|
||||
keepalive = 5
|
||||
threads = 4
|
||||
workers = 4
|
BIN
nft_svc/pics/CVT_Qma1K5CgzcthqmeKj6SrYUwKd9Tho2dRimE3tKKDtJ5Jg1.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma1K5CgzcthqmeKj6SrYUwKd9Tho2dRimE3tKKDtJ5Jg1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma2BZS2XDo9qMLfNQJ5c5wA7nAhKBXF87ewi3BJB6KG6z.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma2BZS2XDo9qMLfNQJ5c5wA7nAhKBXF87ewi3BJB6KG6z.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma34ddY5rpprLa18iiCbNMpXSm75za6ASXebXjmFuxJda.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma34ddY5rpprLa18iiCbNMpXSm75za6ASXebXjmFuxJda.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma3NdGrDkHtk18UYrH397ucQEHcoDtKkzzHDbEobts9Ye.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma3NdGrDkHtk18UYrH397ucQEHcoDtKkzzHDbEobts9Ye.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma4aVQkgWrN9mJ15u9ERXfP7Tgw6KS3VuAAFkB7bT7ofc.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma4aVQkgWrN9mJ15u9ERXfP7Tgw6KS3VuAAFkB7bT7ofc.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma6Gmadq87bN871FwVZFakEj27m6NHvWdQCJ8nqsfHN6y.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma6Gmadq87bN871FwVZFakEj27m6NHvWdQCJ8nqsfHN6y.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma9B6buzf1bpbVehmPaRYhs9JnpEtqH3x1c1ChGpD4oSF.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma9B6buzf1bpbVehmPaRYhs9JnpEtqH3x1c1ChGpD4oSF.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qma9LH68TqyVLkSc3ML48m2Do2McTNbLdzCbDMcxtxTZYi.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qma9LH68TqyVLkSc3ML48m2Do2McTNbLdzCbDMcxtxTZYi.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaDRbLMfvknqBFBPfMV4T2L1nHvazcvyMeNrzHTmkBh2Q.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaDRbLMfvknqBFBPfMV4T2L1nHvazcvyMeNrzHTmkBh2Q.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaDxVYiftgzFpdPyvwPSmpmCaJQY6heXvhcqkd6A9c2Th.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaDxVYiftgzFpdPyvwPSmpmCaJQY6heXvhcqkd6A9c2Th.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaEi29fEJ6oCsmzVkzvbgkHaUgBLGbejz3wfPwn2gAKGB.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaEi29fEJ6oCsmzVkzvbgkHaUgBLGbejz3wfPwn2gAKGB.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaEmyNJkaGwPzt81Ckh6gfCjWkS8SU6rcGinitrgwoTC1.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaEmyNJkaGwPzt81Ckh6gfCjWkS8SU6rcGinitrgwoTC1.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaGZ5ZLWpcBDfVc1nk1Z9NKhRbosdpmRf5ou6LomjFyFt.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaGZ5ZLWpcBDfVc1nk1Z9NKhRbosdpmRf5ou6LomjFyFt.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaGbUgTouqsEms6YV549GTEgnGDU9tcKd7phjxdop9miq.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaGbUgTouqsEms6YV549GTEgnGDU9tcKd7phjxdop9miq.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaJCu36QXpZU8Yxb9ed4FaF1zdCH5jpyUVataa42N8ymE.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaJCu36QXpZU8Yxb9ed4FaF1zdCH5jpyUVataa42N8ymE.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaKgSXg6CuLcgTTEYmzi3Wf39iJCRvC8L7qzCFyurKjca.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaKgSXg6CuLcgTTEYmzi3Wf39iJCRvC8L7qzCFyurKjca.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaKrSzBM6Z2gDZoj3LzVYteeJTEH5nKuf1xH477P3pWZD.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaKrSzBM6Z2gDZoj3LzVYteeJTEH5nKuf1xH477P3pWZD.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaL58fifkbmp5ua5UdqHoDSFUXCbAZtdhYNDbEXepBbyY.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaL58fifkbmp5ua5UdqHoDSFUXCbAZtdhYNDbEXepBbyY.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaMAijN3sidd278axRth5VSM7QtYGmXmG5HToGRohzX3o.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaMAijN3sidd278axRth5VSM7QtYGmXmG5HToGRohzX3o.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaMEgoT2JUp4TbhrZyWN6AyEFpaVTPnZzUXxjBUGgKhqz.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaMEgoT2JUp4TbhrZyWN6AyEFpaVTPnZzUXxjBUGgKhqz.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaSyaW1BAjCiJ8yY73PN4FPm4xP93gjdZFGqdPu86ZSwH.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaSyaW1BAjCiJ8yY73PN4FPm4xP93gjdZFGqdPu86ZSwH.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaVotBMs8gz3SwSadgx9kyWXNmiCHWecEYEjui4AjiHYN.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaVotBMs8gz3SwSadgx9kyWXNmiCHWecEYEjui4AjiHYN.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaWvdqVZQeQXqSfR1HwPgWUUp1rfvDCQKvcc3gouhfbRm.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaWvdqVZQeQXqSfR1HwPgWUUp1rfvDCQKvcc3gouhfbRm.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmaZUBZqVyogW15Bs9dLepFDZAcCCAfXcGrpR91B9jTNRs.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmaZUBZqVyogW15Bs9dLepFDZAcCCAfXcGrpR91B9jTNRs.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmabbuMzAAmC6FoCB5CirX7wLqzRMaSGzNXo4ZydP4qQXS.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmabbuMzAAmC6FoCB5CirX7wLqzRMaSGzNXo4ZydP4qQXS.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmabmeKDLNuP3U1APbqTZBVteRcGtyz7HMhzWgdYRCZJrM.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmabmeKDLNuP3U1APbqTZBVteRcGtyz7HMhzWgdYRCZJrM.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmadeX35BEv7BSPD4iwZFVv75Bjko9zwUM4EScNyF2odwE.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmadeX35BEv7BSPD4iwZFVv75Bjko9zwUM4EScNyF2odwE.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmafTeagXdPKnAS8idcBCopmHXQYfqXgHxYbbbpnQ4NL6p.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmafTeagXdPKnAS8idcBCopmHXQYfqXgHxYbbbpnQ4NL6p.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmafjR3GJ9HDGxbgr5rnUHcYTo63aV4wKu1Fy88orezvRr.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmafjR3GJ9HDGxbgr5rnUHcYTo63aV4wKu1Fy88orezvRr.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmag6ZLzmBS8Yq5a7zTYEz29guMnVahzgC1ubNdTTp9Dwt.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmag6ZLzmBS8Yq5a7zTYEz29guMnVahzgC1ubNdTTp9Dwt.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmaj61UgqQ1GKaYKYXQa1kztVSRKojEF8CEyyudKbpWqJE.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmaj61UgqQ1GKaYKYXQa1kztVSRKojEF8CEyyudKbpWqJE.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmajN2HLraSryKk85yL8ziJkgfW8fdrLBTgbDHnuzSkeLD.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmajN2HLraSryKk85yL8ziJkgfW8fdrLBTgbDHnuzSkeLD.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmajjKGWrDdqsVwfFWvtEALX5zeg1Ju8B8CJ7xAEsx6aKy.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmajjKGWrDdqsVwfFWvtEALX5zeg1Ju8B8CJ7xAEsx6aKy.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmam7Fv62fax4JCzcWzpGwcfVD79CvVfEnvfx1fF4wHSgv.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmam7Fv62fax4JCzcWzpGwcfVD79CvVfEnvfx1fF4wHSgv.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmanJPfagsPv5rop4wFqXwCXYm2c4EwzCVozspz6FSPUAA.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmanJPfagsPv5rop4wFqXwCXYm2c4EwzCVozspz6FSPUAA.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmapDRkc9ftLKvfBEFutDq2r39ATczU7GMStMXmXfz6p4t.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmapDRkc9ftLKvfBEFutDq2r39ATczU7GMStMXmXfz6p4t.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmatP5oEnCHCdcH9ZvKnutVNDJdf9nj2ih3Empvnxuy4J2.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmatP5oEnCHCdcH9ZvKnutVNDJdf9nj2ih3Empvnxuy4J2.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmattVVN45mTHCvCmMNxi6GiZZHedP3ew3ENZbpCpHFC5f.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmattVVN45mTHCvCmMNxi6GiZZHedP3ew3ENZbpCpHFC5f.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmaw8pNjYTY1TsHiBmVQ9QdfMnt7xFphWzPY5iggXCwnrP.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmaw8pNjYTY1TsHiBmVQ9QdfMnt7xFphWzPY5iggXCwnrP.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmawx1RjED8arBaFoG8vWc9YDBPiQY4QVgCSAUqHrnWTzP.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmawx1RjED8arBaFoG8vWc9YDBPiQY4QVgCSAUqHrnWTzP.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmayRDxaK7xWnSE8oRJEAL3xsCNT6tQNNaWk1FhCCKLHHf.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmayRDxaK7xWnSE8oRJEAL3xsCNT6tQNNaWk1FhCCKLHHf.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmazun61wXRfPjHDwwE7pDtRSuekeHjHeu1LcvowW9VjJK.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmazun61wXRfPjHDwwE7pDtRSuekeHjHeu1LcvowW9VjJK.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb1k7w7Cef71qoz7nf2wVBQjNgfDSzoCvqQyNuZHA48xd.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb1k7w7Cef71qoz7nf2wVBQjNgfDSzoCvqQyNuZHA48xd.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb3b4TE8E6KozFw8PQdM4Z6V92coFQ8EA6CoWnVf2wJPA.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb3b4TE8E6KozFw8PQdM4Z6V92coFQ8EA6CoWnVf2wJPA.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb3hii9pPbiJmkrhRWJu2ehuf5WPhcvteubxYxMDJGBx1.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb3hii9pPbiJmkrhRWJu2ehuf5WPhcvteubxYxMDJGBx1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb4w4VqJWkWVGveh49cPixAfXNEASYTswVjso2HB7v4eU.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb4w4VqJWkWVGveh49cPixAfXNEASYTswVjso2HB7v4eU.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb6aDehMdQvLQ8mz8kQyKBb7JyMCXh2sHyfvjPdNaNeTN.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb6aDehMdQvLQ8mz8kQyKBb7JyMCXh2sHyfvjPdNaNeTN.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmb8z12AJm8kXDp6yc6qATgLpBT3tqqavoWmrRTVRAqAuW.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmb8z12AJm8kXDp6yc6qATgLpBT3tqqavoWmrRTVRAqAuW.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbD3xEVxvSkWXjj3c1xEGUwKuEuVau3mwGL4ghVorJbGX.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbD3xEVxvSkWXjj3c1xEGUwKuEuVau3mwGL4ghVorJbGX.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbNh3L2XUMnh3xMirGKQeLBfmwEvVkNEYVkqMVoPFqkJd.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbNh3L2XUMnh3xMirGKQeLBfmwEvVkNEYVkqMVoPFqkJd.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbT3GLeJrdyqfHYjsPpRfBTgNdqyEi3JnnCMkHktD3ush.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbT3GLeJrdyqfHYjsPpRfBTgNdqyEi3JnnCMkHktD3ush.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbTadqUAqYaUKCDEiXkRxAExZ4u4wF61BKzqDbKyeo79B.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbTadqUAqYaUKCDEiXkRxAExZ4u4wF61BKzqDbKyeo79B.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbUykVTfuyDjPKMB9ec58ZeCzobgk1Wj2j1YahLpdUNtq.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbUykVTfuyDjPKMB9ec58ZeCzobgk1Wj2j1YahLpdUNtq.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbYdArMsaDTkCykbrmmy2ZMu6cib4Xi8fxZUWmLEC5EKe.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbYdArMsaDTkCykbrmmy2ZMu6cib4Xi8fxZUWmLEC5EKe.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbfY4coP6E8WuZBAQTksBaED2CG8Er1CBgiPwg22kgftC.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbfY4coP6E8WuZBAQTksBaED2CG8Er1CBgiPwg22kgftC.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmbfk9P6YmqVdZjnLSWJKpH35TY2v7FACwSf7NBmiiNxaU.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmbfk9P6YmqVdZjnLSWJKpH35TY2v7FACwSf7NBmiiNxaU.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmbh85akVePYM5HpoDsXXnFAZArYfiUbj2oiL5XC7KNV6R.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmbh85akVePYM5HpoDsXXnFAZArYfiUbj2oiL5XC7KNV6R.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbhficXqS3857gzmLEqozznAcSsN3UBc4asmsDpsUMDac.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbhficXqS3857gzmLEqozznAcSsN3UBc4asmsDpsUMDac.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbpiEk2vGRhPUXeCcuHkchj7VKYcAk3FcsP84GC34psep.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbpiEk2vGRhPUXeCcuHkchj7VKYcAk3FcsP84GC34psep.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbqCf38McontHnRg4sA345N2P8njmt4uNsRhZW15fmBc1.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbqCf38McontHnRg4sA345N2P8njmt4uNsRhZW15fmBc1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbsBtJPp94znjxs2NGtYa5D32Rhx6k2w9vNhGeh44ps9v.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbsBtJPp94znjxs2NGtYa5D32Rhx6k2w9vNhGeh44ps9v.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbtEg8b7yHNnZjzs5jjCvBVFG3Nad3R6z7TYqbw2rWEaA.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbtEg8b7yHNnZjzs5jjCvBVFG3Nad3R6z7TYqbw2rWEaA.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbuGEbHofRxXipQRKNQbLCDr6h4z2orZLx9zwBB1i5kAv.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbuGEbHofRxXipQRKNQbLCDr6h4z2orZLx9zwBB1i5kAv.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbvYXRjmdxA64MtX9GBJZbJKuhK27rpTavasxqa28ZCCx.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbvYXRjmdxA64MtX9GBJZbJKuhK27rpTavasxqa28ZCCx.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmbxxsHUGX9w3JFrvsnDFbQLCSre1mTjgfy9hUjBYstzm6.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmbxxsHUGX9w3JFrvsnDFbQLCSre1mTjgfy9hUjBYstzm6.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmc2tNpvg9evTm3EYN6qeYCwTgvx38AWNsCwRmbByc27HU.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmc2tNpvg9evTm3EYN6qeYCwTgvx38AWNsCwRmbByc27HU.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmc2vAko2xbADEPNBri4tCLBiyQukViXPEQQ9FrSVmcGLp.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmc2vAko2xbADEPNBri4tCLBiyQukViXPEQQ9FrSVmcGLp.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmc4B7rijMBru7g88XntiiendhUwBAy7ASEXct2d1ExZxS.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmc4B7rijMBru7g88XntiiendhUwBAy7ASEXct2d1ExZxS.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_Qmc4sVnPar1Ew2Q54YPLxy7Yj6m7yJGo6ptzp6PUXmEMoN.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_Qmc4sVnPar1Ew2Q54YPLxy7Yj6m7yJGo6ptzp6PUXmEMoN.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcALPkMEZPunyk57CSBQWKArvx1K5SECNAGrPhnELo4xh.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcALPkMEZPunyk57CSBQWKArvx1K5SECNAGrPhnELo4xh.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcBPQg4L8rgzuPEnPiVWXES2Zu21zqLcFMxzm6Bo2AEBK.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcBPQg4L8rgzuPEnPiVWXES2Zu21zqLcFMxzm6Bo2AEBK.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcBpKKFCx8Vq9sjiEtR3opUfdXZqbMHyFwXuQqkrgHnW9.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcBpKKFCx8Vq9sjiEtR3opUfdXZqbMHyFwXuQqkrgHnW9.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcCApW7BTAtDrhJXRz58ZneBWLHueqPyWCKAfRE84F1Ng.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcCApW7BTAtDrhJXRz58ZneBWLHueqPyWCKAfRE84F1Ng.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcCyoX3fX7HSACrh89z1FHKCCfypxxSCrfBxkMUWXXwW7.jpg.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcCyoX3fX7HSACrh89z1FHKCCfypxxSCrfBxkMUWXXwW7.jpg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcDtbawGDgCLBs8fBahVwTiuqLDc4uJqyZkL7P6J2s3gF.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcDtbawGDgCLBs8fBahVwTiuqLDc4uJqyZkL7P6J2s3gF.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
nft_svc/pics/CVT_QmcFardKJdWsTZ8DVv2Nj16MHFzgnZmdcsWtbwuhCyLJ6P.png
(Stored with Git LFS)
Normal file
BIN
nft_svc/pics/CVT_QmcFardKJdWsTZ8DVv2Nj16MHFzgnZmdcsWtbwuhCyLJ6P.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user