Compare commits

..

28 Commits

Author SHA1 Message Date
takatost
1ade70aa1e feat: bump version to 0.3.20 (#1135) 2023-09-09 23:47:14 +08:00
takatost
2658c4d57b fix: answer returned null when response_mode was blocking (#1133) 2023-09-09 23:22:21 +08:00
zxhlyh
84c76bc04a Feat/chat add origin (#1130) 2023-09-09 19:17:12 +08:00
takatost
6effcd3755 feat: optimize celery start cmd (#1129) 2023-09-09 13:48:29 +08:00
李锐东
d9866489f0 feat: add health check and depend condition in docker compose (#1113) 2023-09-09 13:47:08 +08:00
takatost
c4d8bdc3db fix: hf hosted inference check (#1128) 2023-09-09 00:29:48 +08:00
Joel
681eb1cfcc fix: click inner link no jump (#1118) 2023-09-08 10:21:42 +08:00
Matri
a5d21f3b09 fix: shortening invite url (#1100)
Co-authored-by: MatriQi <matri@aifi.io>
2023-09-07 17:15:57 +08:00
Joel
7ba068c3e4 fix: self host embedding missing base url config (#1116) 2023-09-07 14:56:38 +08:00
bowen
b201eeedbd fix: optimize styles (#1112) 2023-09-07 14:24:09 +08:00
Rhon Joe
f28cb84977 fix(web): fix AppCard Menu popover open bug (#1107) 2023-09-07 09:47:31 +08:00
Joel
714872cd58 chore: enchancment frontend readme (#1110) 2023-09-07 09:43:24 +08:00
Joel
0708bd60ee fix: try to fix chunk load error (#1109) 2023-09-06 15:47:53 +08:00
Joel
23a6c85b80 chore: handle workspace apps scrollbar (#1101) 2023-09-05 15:56:21 +08:00
bowen
4a28599fbd fix: optimize feedback and app icon (#1099) 2023-09-05 09:13:59 +08:00
seewhy
7c66d3c793 feat: Optimize the description for Azure deployment name (#1091) 2023-09-04 14:26:22 +08:00
Joel
cc9edfffd8 fix: markdown code lang capitalization and line number color (#1098) 2023-09-04 11:31:25 +08:00
Joel
6fa2454c9a fix: change frontend start script (#1096) 2023-09-04 11:10:32 +08:00
crazywoola
487e699021 fix: ui in chat openning statement (#1094) 2023-09-04 10:26:46 +08:00
takatost
a7cdb745c1 feat: support spark v2 validate (#1086) 2023-09-01 20:53:32 +08:00
takatost
73c86ee6a0 fix: prompt of title generation (#1084) 2023-09-01 14:55:58 +08:00
takatost
48eb590065 feat: optimize last_active_at update (#1083) 2023-09-01 13:58:26 +08:00
takatost
33562a9d8d feat: optimize prompt (#1080) 2023-09-01 11:46:06 +08:00
Rhon Joe
c9194ba382 chore(api): api image multistage build (#1069) 2023-09-01 11:13:22 +08:00
takatost
a199fa6388 feat: optimize high load sql query of document segment (#1078) 2023-09-01 10:52:39 +08:00
takatost
4c8608dc61 feat: optimize conversation title generation output must be a valid JSON (#1077) 2023-09-01 10:31:42 +08:00
Garfield Dai
a6b0f788e7 feat: add visual studio code debug config. (#1068)
Co-authored-by: Keruberosu <631677014@qq.com>
2023-09-01 09:15:06 +08:00
takatost
df6604a734 feat: optimize generation of conversation title (#1075) 2023-09-01 02:28:37 +08:00
120 changed files with 2991 additions and 244 deletions

View File

@@ -20,7 +20,8 @@ def check_file_for_chinese_comments(file_path):
def main():
has_chinese = False
excluded_files = ["model_template.py", 'stopwords.py', 'commands.py',
'indexing_runner.py', 'web_reader_tool.py', 'spark_provider.py']
'indexing_runner.py', 'web_reader_tool.py', 'spark_provider.py',
'prompts.py']
for root, _, files in os.walk("."):
for file in files:

3
.gitignore vendored
View File

@@ -149,4 +149,5 @@ sdks/python-client/build
sdks/python-client/dist
sdks/python-client/dify_client.egg-info
.vscode/
.vscode/*
!.vscode/launch.json

27
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "api/app.py",
"FLASK_DEBUG": "1",
"GEVENT_SUPPORT": "True"
},
"args": [
"run",
"--host=0.0.0.0",
"--port=5001",
"--debug"
],
"jinja": true,
"justMyCode": true
}
]
}

View File

@@ -1,7 +1,18 @@
FROM python:3.10-slim
# packages install stage
FROM python:3.10-slim AS base
LABEL maintainer="takatost@gmail.com"
RUN apt-get update \
&& apt-get install -y --no-install-recommends gcc g++ python3-dev libc-dev libffi-dev
COPY requirements.txt /requirements.txt
RUN pip install --prefix=/pkg -r requirements.txt
# build stage
FROM python:3.10-slim AS builder
ENV FLASK_APP app.py
ENV EDITION SELF_HOSTED
ENV DEPLOY_ENV PRODUCTION
@@ -15,13 +26,12 @@ EXPOSE 5001
WORKDIR /app/api
RUN apt-get update && \
apt-get install -y bash curl wget vim gcc g++ python3-dev libc-dev libffi-dev nodejs
COPY requirements.txt /app/api/requirements.txt
RUN pip install -r requirements.txt
RUN apt-get update \
&& apt-get install -y --no-install-recommends bash curl wget vim nodejs \
&& apt-get autoremove \
&& rm -rf /var/lib/apt/lists/*
COPY --from=base /pkg /usr/local
COPY . /app/api/
COPY docker/entrypoint.sh /entrypoint.sh

View File

@@ -52,7 +52,7 @@
flask run --host 0.0.0.0 --port=5001 --debug
```
7. Setup your application by visiting http://localhost:5001/console/api/setup or other apis...
8. If you need to debug local async processing, you can run `celery -A app.celery worker -Q dataset,generation,mail`, celery can do dataset importing and other async tasks.
8. If you need to debug local async processing, you can run `celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail`, celery can do dataset importing and other async tasks.
8. Start frontend

View File

@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
import os
from datetime import datetime
from datetime import datetime, timedelta
from werkzeug.exceptions import Forbidden
@@ -145,8 +145,12 @@ def load_user(user_id):
_create_tenant_for_account(account)
session['workspace_id'] = account.current_tenant_id
account.last_active_at = datetime.utcnow()
db.session.commit()
current_time = datetime.utcnow()
# update last_active_at when last_active_at is more than 10 minutes ago
if current_time - account.last_active_at > timedelta(minutes=10):
account.last_active_at = current_time
db.session.commit()
# Log in the user with the updated user_id
flask_login.login_user(account, remember=True)

View File

@@ -100,7 +100,7 @@ class Config:
self.CONSOLE_URL = get_env('CONSOLE_URL')
self.API_URL = get_env('API_URL')
self.APP_URL = get_env('APP_URL')
self.CURRENT_VERSION = "0.3.19"
self.CURRENT_VERSION = "0.3.20"
self.COMMIT_SHA = get_env('COMMIT_SHA')
self.EDITION = "SELF_HOSTED"
self.DEPLOY_ENV = get_env('DEPLOY_ENV')

View File

@@ -16,26 +16,25 @@ from services.account_service import RegisterService
class ActivateCheckApi(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('workspace_id', type=str, required=True, nullable=False, location='args')
parser.add_argument('email', type=email, required=True, nullable=False, location='args')
parser.add_argument('workspace_id', type=str, required=False, nullable=True, location='args')
parser.add_argument('email', type=email, required=False, nullable=True, location='args')
parser.add_argument('token', type=str, required=True, nullable=False, location='args')
args = parser.parse_args()
account = RegisterService.get_account_if_token_valid(args['workspace_id'], args['email'], args['token'])
workspaceId = args['workspace_id']
reg_email = args['email']
token = args['token']
tenant = db.session.query(Tenant).filter(
Tenant.id == args['workspace_id'],
Tenant.status == 'normal'
).first()
invitation = RegisterService.get_invitation_if_token_valid(workspaceId, reg_email, token)
return {'is_valid': account is not None, 'workspace_name': tenant.name}
return {'is_valid': invitation is not None, 'workspace_name': invitation['tenant'].name if invitation else None}
class ActivateApi(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('workspace_id', type=str, required=True, nullable=False, location='json')
parser.add_argument('email', type=email, required=True, nullable=False, location='json')
parser.add_argument('workspace_id', type=str, required=False, nullable=True, location='json')
parser.add_argument('email', type=email, required=False, nullable=True, location='json')
parser.add_argument('token', type=str, required=True, nullable=False, location='json')
parser.add_argument('name', type=str_len(30), required=True, nullable=False, location='json')
parser.add_argument('password', type=valid_password, required=True, nullable=False, location='json')
@@ -44,12 +43,13 @@ class ActivateApi(Resource):
parser.add_argument('timezone', type=timezone, required=True, nullable=False, location='json')
args = parser.parse_args()
account = RegisterService.get_account_if_token_valid(args['workspace_id'], args['email'], args['token'])
if account is None:
invitation = RegisterService.get_invitation_if_token_valid(args['workspace_id'], args['email'], args['token'])
if invitation is None:
raise AlreadyActivateError()
RegisterService.revoke_token(args['workspace_id'], args['email'], args['token'])
account = invitation['account']
account.name = args['name']
# generate password salt

View File

@@ -72,7 +72,7 @@ class MemberInviteEmailApi(Resource):
invitation_results.append({
'status': 'success',
'email': invitee_email,
'url': f'{console_web_url}/activate?workspace_id={current_user.current_tenant_id}&email={invitee_email}&token={token}'
'url': f'{console_web_url}/activate?email={invitee_email}&token={token}'
})
account = marshal(account, account_fields)
account['role'] = role

View File

@@ -1,3 +1,4 @@
import json
import logging
from langchain.schema import OutputParserException
@@ -22,18 +23,25 @@ class LLMGenerator:
if len(query) > 2000:
query = query[:300] + "...[TRUNCATED]..." + query[-300:]
prompt = prompt.format(query=query)
query = query.replace("\n", " ")
prompt += query + "\n"
model_instance = ModelFactory.get_text_generation_model(
tenant_id=tenant_id,
model_kwargs=ModelKwargs(
max_tokens=50
temperature=1,
max_tokens=100
)
)
prompts = [PromptMessage(content=prompt)]
response = model_instance.run(prompts)
answer = response.content
result_dict = json.loads(answer)
answer = result_dict['Your Output']
return answer.strip()
@classmethod

View File

@@ -25,7 +25,7 @@ class KeywordTableIndex(BaseIndex):
keyword_table = {}
for text in texts:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(text.metadata['doc_id'], list(keywords))
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
dataset_keyword_table = DatasetKeywordTable(
@@ -52,7 +52,7 @@ class KeywordTableIndex(BaseIndex):
keyword_table = self._get_dataset_keyword_table()
for text in texts:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(text.metadata['doc_id'], list(keywords))
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
self._save_dataset_keyword_table(keyword_table)
@@ -199,15 +199,18 @@ class KeywordTableIndex(BaseIndex):
return sorted_chunk_indices[: k]
def _update_segment_keywords(self, node_id: str, keywords: List[str]):
document_segment = db.session.query(DocumentSegment).filter(DocumentSegment.index_node_id == node_id).first()
def _update_segment_keywords(self, dataset_id: str, node_id: str, keywords: List[str]):
document_segment = db.session.query(DocumentSegment).filter(
DocumentSegment.dataset_id == dataset_id,
DocumentSegment.index_node_id == node_id
).first()
if document_segment:
document_segment.keywords = keywords
db.session.commit()
def create_segment_keywords(self, node_id: str, keywords: List[str]):
keyword_table = self._get_dataset_keyword_table()
self._update_segment_keywords(node_id, keywords)
self._update_segment_keywords(self.dataset.id, node_id, keywords)
keyword_table = self._add_text_to_keyword_table(keyword_table, node_id, keywords)
self._save_dataset_keyword_table(keyword_table)

View File

@@ -1,6 +1,5 @@
from typing import List, Optional, Any
from langchain import HuggingFaceHub
from langchain.callbacks.manager import Callbacks
from langchain.schema import LLMResult
@@ -9,6 +8,7 @@ from core.model_providers.models.llm.base import BaseLLM
from core.model_providers.models.entity.message import PromptMessage
from core.model_providers.models.entity.model_params import ModelMode, ModelKwargs
from core.third_party.langchain.llms.huggingface_endpoint_llm import HuggingFaceEndpointLLM
from core.third_party.langchain.llms.huggingface_hub_llm import HuggingFaceHubLLM
class HuggingfaceHubModel(BaseLLM):
@@ -31,7 +31,7 @@ class HuggingfaceHubModel(BaseLLM):
streaming=streaming
)
else:
client = HuggingFaceHub(
client = HuggingFaceHubLLM(
repo_id=self.name,
task=self.credentials['task_type'],
model_kwargs=provider_model_kwargs,
@@ -88,4 +88,6 @@ class HuggingfaceHubModel(BaseLLM):
if 'baichuan' in self.name.lower():
return False
return True
return True
else:
return False

View File

@@ -89,7 +89,8 @@ class HuggingfaceHubProvider(BaseModelProvider):
raise CredentialsValidateFailedError('Task Type must be provided.')
if credentials['task_type'] not in ("text2text-generation", "text-generation", "summarization"):
raise CredentialsValidateFailedError('Task Type must be one of text2text-generation, text-generation, summarization.')
raise CredentialsValidateFailedError('Task Type must be one of text2text-generation, '
'text-generation, summarization.')
try:
llm = HuggingFaceEndpointLLM(

View File

@@ -83,14 +83,15 @@ class SparkProvider(BaseModelProvider):
if 'api_secret' not in credentials:
raise CredentialsValidateFailedError('Spark api_secret must be provided.')
try:
credential_kwargs = {
'app_id': credentials['app_id'],
'api_key': credentials['api_key'],
'api_secret': credentials['api_secret'],
}
credential_kwargs = {
'app_id': credentials['app_id'],
'api_key': credentials['api_key'],
'api_secret': credentials['api_secret'],
}
try:
chat_llm = ChatSpark(
model_name='spark-v2',
max_tokens=10,
temperature=0.01,
**credential_kwargs
@@ -104,7 +105,27 @@ class SparkProvider(BaseModelProvider):
chat_llm(messages)
except SparkError as ex:
raise CredentialsValidateFailedError(str(ex))
# try spark v1.5 if v2.1 failed
try:
chat_llm = ChatSpark(
model_name='spark',
max_tokens=10,
temperature=0.01,
**credential_kwargs
)
messages = [
HumanMessage(
content="ping"
)
]
chat_llm(messages)
except SparkError as ex:
raise CredentialsValidateFailedError(str(ex))
except Exception as ex:
logging.exception('Spark config validation failed')
raise ex
except Exception as ex:
logging.exception('Spark config validation failed')
raise ex

View File

@@ -1,10 +1,65 @@
CONVERSATION_TITLE_PROMPT = (
"Human:{query}\n-----\n"
"Help me summarize the intent of what the human said and provide a title, the title should not exceed 20 words.\n"
"If what the human said is conducted in English, you should only return an English title.\n"
"If what the human said is conducted in Chinese, you should only return a Chinese title.\n"
"title:"
)
# Written by YORKI MINAKO🤡
CONVERSATION_TITLE_PROMPT = """You need to decompose the user's input into "subject" and "intention" in order to accurately figure out what the user's input language actually is.
Notice: the language type user use could be diverse, which can be English, Chinese, Español, Arabic, Japanese, French, and etc.
MAKE SURE your output is the SAME language as the user's input!
Your output is restricted only to: (Input language) Intention + Subject(short as possible)
Your output MUST be a valid JSON.
Tip: When the user's question is directed at you (the language model), you can add an emoji to make it more fun.
example 1:
User Input: hi, yesterday i had some burgers.
{
"Language Type": "The user's input is pure English",
"Your Reasoning": "The language of my output must be pure English.",
"Your Output": "sharing yesterday's food"
}
example 2:
User Input: hello
{
"Language Type": "The user's input is written in pure English",
"Your Reasoning": "The language of my output must be pure English.",
"Your Output": "Greeting myself☺"
}
example 3:
User Input: why mmap file: oom
{
"Language Type": "The user's input is written in pure English",
"Your Reasoning": "The language of my output must be pure English.",
"Your Output": "Asking about the reason for mmap file: oom"
}
example 4:
User Input: www.convinceme.yesterday-you-ate-seafood.tv讲了什么
{
"Language Type": "The user's input English-Chinese mixed",
"Your Reasoning": "The English-part is an URL, the main intention is still written in Chinese, so the language of my output must be using Chinese.",
"Your Output": "询问网站www.convinceme.yesterday-you-ate-seafood.tv"
}
example 5:
User Input: why小红的年龄is老than小明
{
"Language Type": "The user's input is English-Chinese mixed",
"Your Reasoning": "The English parts are subjective particles, the main intention is written in Chinese, besides, Chinese occupies a greater \"actual meaning\" than English, so the language of my output must be using Chinese.",
"Your Output": "询问小红和小明的年龄"
}
example 6:
User Input: yo, 你今天咋样?
{
"Language Type": "The user's input is English-Chinese mixed",
"Your Reasoning": "The English-part is a subjective particle, the main intention is written in Chinese, so the language of my output must be using Chinese.",
"Your Output": "查询今日我的状态☺️"
}
User Input:
"""
CONVERSATION_SUMMARY_PROMPT = (
"Please generate a short summary of the following conversation.\n"

View File

@@ -0,0 +1,62 @@
from typing import Dict, Optional, List, Any
from huggingface_hub import HfApi, InferenceApi
from langchain import HuggingFaceHub
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.llms.huggingface_hub import VALID_TASKS
from pydantic import root_validator
from langchain.utils import get_from_dict_or_env
class HuggingFaceHubLLM(HuggingFaceHub):
"""HuggingFaceHub models.
To use, you should have the ``huggingface_hub`` python package installed, and the
environment variable ``HUGGINGFACEHUB_API_TOKEN`` set with your API token, or pass
it as a named parameter to the constructor.
Only supports `text-generation`, `text2text-generation` and `summarization` for now.
Example:
.. code-block:: python
from langchain.llms import HuggingFaceHub
hf = HuggingFaceHub(repo_id="gpt2", huggingfacehub_api_token="my-api-key")
"""
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that api key and python package exists in environment."""
huggingfacehub_api_token = get_from_dict_or_env(
values, "huggingfacehub_api_token", "HUGGINGFACEHUB_API_TOKEN"
)
client = InferenceApi(
repo_id=values["repo_id"],
token=huggingfacehub_api_token,
task=values.get("task"),
)
client.options = {"wait_for_model": False, "use_gpu": False}
values["client"] = client
return values
def _call(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> str:
hfapi = HfApi(token=self.huggingfacehub_api_token)
model_info = hfapi.model_info(repo_id=self.repo_id)
if not model_info:
raise ValueError(f"Model {self.repo_id} not found.")
if 'inference' in model_info.cardData and not model_info.cardData['inference']:
raise ValueError(f"Inference API has been turned off for this model {self.repo_id}.")
if model_info.pipeline_tag not in VALID_TASKS:
raise ValueError(f"Model {self.repo_id} is not a valid task, "
f"must be one of {VALID_TASKS}.")
return super()._call(prompt, stop, run_manager, **kwargs)

View File

@@ -26,7 +26,7 @@ def handle(sender, **kwargs):
conversation.name = name
except:
conversation.name = 'New Chat'
conversation.name = 'New conversation'
db.session.add(conversation)
db.session.commit()

View File

@@ -1,5 +1,6 @@
# -*- coding:utf-8 -*-
import base64
import json
import logging
import secrets
import uuid
@@ -346,6 +347,10 @@ class TenantService:
class RegisterService:
@classmethod
def _get_invitation_token_key(cls, token: str) -> str:
return f'member_invite:token:{token}'
@classmethod
def register(cls, email, name, password: str = None, open_id: str = None, provider: str = None) -> Account:
db.session.begin_nested()
@@ -401,7 +406,7 @@ class RegisterService:
# send email
send_invite_member_mail_task.delay(
to=email,
token=cls.generate_invite_token(tenant, account),
token=token,
inviter_name=inviter.name if inviter else 'Dify',
workspace_id=tenant.id,
workspace_name=tenant.name,
@@ -412,21 +417,35 @@ class RegisterService:
@classmethod
def generate_invite_token(cls, tenant: Tenant, account: Account) -> str:
token = str(uuid.uuid4())
email_hash = sha256(account.email.encode()).hexdigest()
cache_key = 'member_invite_token:{}, {}:{}'.format(str(tenant.id), email_hash, token)
redis_client.setex(cache_key, 3600, str(account.id))
invitation_data = {
'account_id': account.id,
'email': account.email,
'workspace_id': tenant.id,
}
redis_client.setex(
cls._get_invitation_token_key(token),
3600,
json.dumps(invitation_data)
)
return token
@classmethod
def revoke_token(cls, workspace_id: str, email: str, token: str):
email_hash = sha256(email.encode()).hexdigest()
cache_key = 'member_invite_token:{}, {}:{}'.format(workspace_id, email_hash, token)
redis_client.delete(cache_key)
if workspace_id and email:
email_hash = sha256(email.encode()).hexdigest()
cache_key = 'member_invite_token:{}, {}:{}'.format(workspace_id, email_hash, token)
redis_client.delete(cache_key)
else:
redis_client.delete(cls._get_invitation_token_key(token))
@classmethod
def get_account_if_token_valid(cls, workspace_id: str, email: str, token: str) -> Optional[Account]:
def get_invitation_if_token_valid(cls, workspace_id: str, email: str, token: str) -> Optional[Account]:
invitation_data = cls._get_invitation_by_token(token, workspace_id, email)
if not invitation_data:
return None
tenant = db.session.query(Tenant).filter(
Tenant.id == workspace_id,
Tenant.id == invitation_data['workspace_id'],
Tenant.status == 'normal'
).first()
@@ -435,30 +454,43 @@ class RegisterService:
tenant_account = db.session.query(Account, TenantAccountJoin.role).join(
TenantAccountJoin, Account.id == TenantAccountJoin.account_id
).filter(Account.email == email, TenantAccountJoin.tenant_id == tenant.id).first()
).filter(Account.email == invitation_data['email'], TenantAccountJoin.tenant_id == tenant.id).first()
if not tenant_account:
return None
account_id = cls._get_account_id_by_invite_token(workspace_id, email, token)
if not account_id:
return None
account = tenant_account[0]
if not account:
return None
if account_id != str(account.id):
if invitation_data['account_id'] != str(account.id):
return None
return account
return {
'account': account,
'data': invitation_data,
'tenant': tenant,
}
@classmethod
def _get_account_id_by_invite_token(cls, workspace_id: str, email: str, token: str) -> Optional[str]:
email_hash = sha256(email.encode()).hexdigest()
cache_key = 'member_invite_token:{}, {}:{}'.format(workspace_id, email_hash, token)
account_id = redis_client.get(cache_key)
if not account_id:
return None
def _get_invitation_by_token(cls, token: str, workspace_id: str, email: str) -> Optional[str]:
if workspace_id is not None and email is not None:
email_hash = sha256(email.encode()).hexdigest()
cache_key = f'member_invite_token:{workspace_id}, {email_hash}:{token}'
account_id = redis_client.get(cache_key)
return account_id.decode('utf-8')
if not account_id:
return None
return {
'account_id': account_id.decode('utf-8'),
'email': email,
'workspace_id': workspace_id,
}
else:
data = redis_client.get(cls._get_invitation_token_key(token))
if not data:
return None
invitation = json.loads(data)
return invitation

View File

@@ -367,7 +367,7 @@ class CompletionService:
result = json.loads(result)
if result.get('error'):
cls.handle_error(result)
if 'data' in result:
if result['event'] == 'message' and 'data' in result:
return cls.get_message_response_data(result.get('data'))
except ValueError as e:
if e.args[0] != "I/O operation on closed file.": # ignore this error

View File

@@ -2,7 +2,7 @@ version: '3.1'
services:
# API service
api:
image: langgenius/dify-api:0.3.19
image: langgenius/dify-api:0.3.20
restart: always
environment:
# Startup mode, 'api' starts the API server.
@@ -114,9 +114,12 @@ services:
# The sample rate for Sentry profiles. Default: `1.0`
SENTRY_PROFILES_SAMPLE_RATE: 1.0
depends_on:
- db
- redis
- weaviate
db:
condition: service_healthy
redis:
condition: service_healthy
weaviate:
condition: service_started
volumes:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
@@ -124,7 +127,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
image: langgenius/dify-api:0.3.19
image: langgenius/dify-api:0.3.20
restart: always
environment:
# Startup mode, 'worker' starts the Celery worker for processing the queue.
@@ -167,16 +170,19 @@ services:
# the api-key for resend (https://resend.com)
RESEND_API_KEY: ''
depends_on:
- db
- redis
- weaviate
db:
condition: service_healthy
redis:
condition: service_healthy
weaviate:
condition: service_started
volumes:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
# Frontend web application.
web:
image: langgenius/dify-web:0.3.19
image: langgenius/dify-web:0.3.20
restart: always
environment:
EDITION: SELF_HOSTED
@@ -206,6 +212,11 @@ services:
- ./volumes/db/data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD", "pg_isready"]
interval: 1s
timeout: 3s
retries: 30
# The redis cache.
redis:
@@ -216,6 +227,8 @@ services:
- ./volumes/redis/data:/data
# Set the redis password when startup redis server.
command: redis-server --requirepass difyai123456
healthcheck:
test: ["CMD", "redis-cli","ping"]
# The Weaviate vector store.
weaviate:

View File

@@ -2,41 +2,91 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
### Run by source code
To start the web frontend service, you will need [Node.js v18.x (LTS)](https://nodejs.org/en) and [NPM version 8.x.x](https://www.npmjs.com/) or [Yarn](https://yarnpkg.com/).
First, run the development server:
First, install the dependencies:
```bash
npm install
# or
yarn
```
Then, configure the environment variables. Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Modify the values of these environment variables according to your requirements:
```
# For production release, change this to PRODUCTION
NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
# The deployment edition, SELF_HOSTED or CLOUD
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# SENTRY
NEXT_PUBLIC_SENTRY_DSN=
```
Finally, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
You can start editing the file under folder `app`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
### Run by Docker
First, Build the frontend image
```bash
docker build . -t dify-web
```
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
Then, configure the environment variables.Use the same method mentioned in run by source code.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
Finally, run the frontend service:
```bash
docker run -it -p 3000:3000 -e EDITION=SELF_HOSTED -e CONSOLE_URL=http://127.0.0.1:3000 -e APP_URL=http://127.0.0.1:3000 dify-web
```
When the console api domain and web app api domain are different, you can set the CONSOLE_URL and APP_URL separately.
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
## Deploy
### Deploy on server
First, build the app for production:
```bash
npm run build
```
Then, move the static files to standalone folder:
```bash
mv .next/static .next/standalone/.next
cp -r ./public .next/standalone/.next/
```
Finally, start the app:
```bash
node .next/standalone/server.js
```
If your project needs alternative port or hostname for listening, you can define PORT and HOSTNAME environment variables, before running server.js. For example, `PORT=3000 HOSTNAME=localhost node .next/standalone/server.js`.
## Lint Code
If your ide is VSCode, rename `web/.vscode/settings.example.json` to `web/.vscode/settings.json` for lint code setting.
If your IDE is VSCode, rename `web/.vscode/settings.example.json` to `web/.vscode/settings.json` for lint code setting.
## Learn More
## Documentation
Visit https://docs.dify.ai/getting-started/readme to view the full documentation.
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
## Community
The Dify community can be found on [Discord community](https://discord.com/invite/FngNHpbcY7), where you can ask questions, voice ideas, and share your projects.

View File

@@ -33,20 +33,18 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
if (!response)
return <Loading />
const handleError = (err: Error | null) => {
if (!err) {
notify({
type: 'success',
message: t('common.actionMsg.modifiedSuccessfully'),
})
const handleCallbackResult = (err: Error | null, message?: string) => {
const type = err ? 'error' : 'success'
message ||= (type === 'success' ? 'modifiedSuccessfully' : 'modifiedUnsuccessfully')
if (type === 'success') {
mutate(detailParams)
}
else {
notify({
type: 'error',
message: t('common.actionMsg.modificationFailed'),
})
}
notify({
type,
message: t(`common.actionMsg.${message}`),
})
}
const onChangeSiteStatus = async (value: boolean) => {
@@ -56,7 +54,8 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
body: { enable_site: value },
}) as Promise<App>,
)
handleError(err)
handleCallbackResult(err)
}
const onChangeApiStatus = async (value: boolean) => {
@@ -66,7 +65,8 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
body: { enable_api: value },
}) as Promise<App>,
)
handleError(err)
handleCallbackResult(err)
}
const onSaveSiteConfig: IAppCardProps['onSaveSiteConfig'] = async (params) => {
@@ -79,7 +79,7 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
if (!err)
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
handleError(err)
handleCallbackResult(err)
}
const onGenerateCode = async () => {
@@ -88,7 +88,8 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
url: `/apps/${appId}/site/access-token-reset`,
}) as Promise<UpdateAppSiteCodeResponse>,
)
handleError(err)
handleCallbackResult(err, err ? 'generatedUnsuccessfully' : 'generatedSuccessfully')
}
return (

View File

@@ -16,6 +16,7 @@ import { ToastContext } from '@/app/components/base/toast'
import { deleteApp, fetchAppDetail, updateAppSiteConfig } from '@/service/apps'
import AppIcon from '@/app/components/base/app-icon'
import AppsContext, { useAppContext } from '@/context/app-context'
import type { HtmlContentProps } from '@/app/components/base/popover'
import CustomPopover from '@/app/components/base/popover'
import Divider from '@/app/components/base/divider'
import { asyncRunSafe } from '@/utils'
@@ -93,21 +94,21 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
else {
notify({
type: 'error',
message: t('common.actionMsg.modificationFailed'),
message: t('common.actionMsg.modifiedUnsuccessfully'),
})
}
},
[app.id],
)
const Operations = (props: any) => {
const Operations = (props: HtmlContentProps) => {
const onClickSettings = async (e: React.MouseEvent<HTMLButtonElement>) => {
props?.onClose()
props.onClick?.()
e.preventDefault()
await getAppDetail()
}
const onClickDelete = async (e: React.MouseEvent<HTMLDivElement>) => {
props?.onClose()
props.onClick?.()
e.preventDefault()
setShowConfirmDelete(true)
}
@@ -157,6 +158,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
)
}
className={'!w-[128px] h-fit !z-20'}
manualClose
/>}
</div>
<div className={style.listItemDescription}>

View File

@@ -31,8 +31,8 @@ const ActivateForm = () => {
const checkParams = {
url: '/activate/check',
params: {
workspace_id: workspaceID,
email,
...workspaceID && { workspace_id: workspaceID },
...email && { email },
token,
},
}

View File

@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { UserCircleIcon } from '@heroicons/react/24/solid'
import cn from 'classnames'
import type { DisplayScene, FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc, ThoughtItem } from '../type'
import type { CitationItem, DisplayScene, FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc, ThoughtItem } from '../type'
import OperationBtn from '../operation'
import LoadingAnim from '../loading-anim'
import { EditIcon, EditIconSolid, OpeningStatementIcon, RatingIcon } from '../icon-component'
@@ -13,6 +13,7 @@ import s from '../style.module.css'
import MoreInfo from '../more-info'
import CopyBtn from '../copy-btn'
import Thought from '../thought'
import Citation from '../citation'
import { randomString } from '@/utils'
import type { Annotation, MessageRating } from '@/models/log'
import AppContext from '@/context/app-context'
@@ -45,11 +46,14 @@ export type IAnswerProps = {
isResponsing?: boolean
answerIconClassName?: string
thoughts?: ThoughtItem[]
citation?: CitationItem[]
isThinking?: boolean
dataSets?: DataSet[]
isShowCitation?: boolean
isShowCitationHitInfo?: boolean
}
// The component needs to maintain its own state to control whether to display input component
const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedbackEdit = false, onFeedback, onSubmitAnnotation, displayScene = 'web', isResponsing, answerIconClassName, thoughts, isThinking, dataSets }) => {
const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedbackEdit = false, onFeedback, onSubmitAnnotation, displayScene = 'web', isResponsing, answerIconClassName, thoughts, citation, isThinking, dataSets, isShowCitation, isShowCitationHitInfo = false }) => {
const { id, content, more, feedback, adminFeedback, annotation: initAnnotation } = item
const [showEdit, setShowEdit] = useState(false)
const [loading, setLoading] = useState(false)
@@ -171,7 +175,7 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
</div>
}
</div>
<div className={s.answerWrapWrap}>
<div className={cn(s.answerWrapWrap, 'chat-answer-container')}>
<div className={`${s.answerWrap} ${showEdit ? 'w-full' : ''}`}>
<div className={`${s.answer} relative text-sm text-gray-900`}>
<div className={'ml-2 py-3 px-4 bg-gray-100 rounded-tr-2xl rounded-b-2xl'}>
@@ -237,6 +241,11 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
</div>
</>
}
{
!!citation?.length && !isThinking && isShowCitation && !isResponsing && (
<Citation data={citation} showHitInfo={isShowCitationHitInfo} />
)
}
</div>
<div className='absolute top-[-14px] right-[-14px] flex flex-row justify-end gap-1'>
{!item.isOpeningStatement && (

View File

@@ -0,0 +1,123 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import type { CitationItem } from '../type'
import Popup from './popup'
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
export type Resources = {
documentId: string
documentName: string
dataSourceType: string
sources: CitationItem[]
}
type CitationProps = {
data: CitationItem[]
showHitInfo?: boolean
}
const Citation: FC<CitationProps> = ({
data,
showHitInfo,
}) => {
const { t } = useTranslation()
const elesRef = useRef<HTMLDivElement[]>([])
const [limitNumberInOneLine, setlimitNumberInOneLine] = useState(0)
const [showMore, setShowMore] = useState(false)
const resources = useMemo(() => data.reduce((prev: Resources[], next) => {
const documentId = next.document_id
const documentName = next.document_name
const dataSourceType = next.data_source_type
const documentIndex = prev.findIndex(i => i.documentId === documentId)
if (documentIndex > -1) {
prev[documentIndex].sources.push(next)
}
else {
prev.push({
documentId,
documentName,
dataSourceType,
sources: [next],
})
}
return prev
}, []), [data])
const handleAdjustResourcesLayout = () => {
const containerWidth = document.querySelector('.chat-answer-container')!.clientWidth - 40
let totalWidth = 0
for (let i = 0; i < resources.length; i++) {
totalWidth += elesRef.current[i].clientWidth
if (totalWidth + i * 4 > containerWidth!) {
totalWidth -= elesRef.current[i].clientWidth
if (totalWidth + 34 > containerWidth!)
setlimitNumberInOneLine(i - 1)
else
setlimitNumberInOneLine(i)
break
}
else {
setlimitNumberInOneLine(i + 1)
}
}
}
useEffect(() => {
handleAdjustResourcesLayout()
}, [])
const resourcesLength = resources.length
return (
<div className='mt-3 -mb-1'>
<div className='flex items-center mb-2 text-xs font-medium text-gray-500'>
{t('common.chat.citation.title')}
<div className='grow ml-2 h-[1px] bg-black/5' />
</div>
<div className='relative flex flex-wrap'>
{
resources.map((res, index) => (
<div
key={index}
className='absolute top-0 left-0 w-auto mr-1 mb-1 pl-7 pr-2 max-w-[240px] h-7 text-xs whitespace-nowrap opacity-0 -z-10'
ref={ele => (elesRef.current[index] = ele!)}
>
{res.documentName}
</div>
))
}
{
resources.slice(0, showMore ? resourcesLength : limitNumberInOneLine).map((res, index) => (
<div key={index} className='mr-1 mb-1 cursor-pointer'>
<Popup
data={res}
showHitInfo={showHitInfo}
/>
</div>
))
}
{
limitNumberInOneLine < resourcesLength && (
<div
className='flex items-center px-2 h-7 bg-white rounded-lg text-xs font-medium text-gray-500 cursor-pointer'
onClick={() => setShowMore(v => !v)}
>
{
!showMore
? `+ ${resourcesLength - limitNumberInOneLine}`
: <ChevronDown className='w-4 h-4 text-gray-600 rotate-180' />
}
</div>
)
}
</div>
</div>
)
}
export default Citation

View File

@@ -0,0 +1,123 @@
import { Fragment, useState } from 'react'
import type { FC } from 'react'
import Link from 'next/link'
import { useTranslation } from 'react-i18next'
import Tooltip from './tooltip'
import ProgressTooltip from './progress-tooltip'
import type { Resources } from './index'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import FileIcon from '@/app/components/base/file-icon'
import {
Hash02,
Target04,
} from '@/app/components/base/icons/src/vender/line/general'
import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows'
import {
BezierCurve03,
TypeSquare,
} from '@/app/components/base/icons/src/vender/line/editor'
type PopupProps = {
data: Resources
showHitInfo?: boolean
}
const Popup: FC<PopupProps> = ({
data,
showHitInfo = false,
}) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const fileType = data.dataSourceType === 'upload_file'
? (/\.([^.]*)$/g.exec(data.documentName)?.[1] || '')
: 'notion'
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
offset={{
mainAxis: 8,
crossAxis: -2,
}}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<div className='flex items-center px-2 max-w-[240px] h-7 bg-white rounded-lg'>
<FileIcon type={fileType} className='mr-1 w-4 h-4' />
<div className='text-xs text-gray-600 truncate'>{data.documentName}</div>
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1000 }}>
<div className='w-[360px] bg-gray-50 rounded-xl shadow-lg'>
<div className='px-4 pt-3 pb-2'>
<div className='flex items-center h-[18px]'>
<FileIcon type={fileType} className='mr-1 w-4 h-4' />
<div className='text-xs font-medium text-gray-600 truncate'>{data.documentName}</div>
</div>
</div>
<div className='px-4 py-0.5 max-h-[450px] bg-white rounded-lg overflow-auto'>
{
data.sources.map((source, index) => (
<Fragment key={index}>
<div className='group py-3'>
{
showHitInfo && (
<div className='flex items-center justify-between mb-2'>
<div className='flex items-center px-1.5 h-5 border border-gray-200 rounded-md'>
<Hash02 className='mr-0.5 w-3 h-3 text-gray-400' />
<div className='text-[11px] font-medium text-gray-500'>{source.segment_position}</div>
</div>
<Link
href={`/datasets/${source.dataset_id}/documents/${source.document_id}`}
className='hidden items-center h-[18px] text-xs text-primary-600 group-hover:flex'>
Link to dataset
<ArrowUpRight className='ml-1 w-3 h-3' />
</Link>
</div>
)
}
<div className='text-[13px] text-gray-800'>{source.content}</div>
{
showHitInfo && (
<div className='flex items-center mt-2 text-xs font-medium text-gray-500'>
<Tooltip
text={t('common.chat.citation.characters')}
data={source.word_count}
icon={<TypeSquare className='mr-1 w-3 h-3' />}
/>
<Tooltip
text={t('common.chat.citation.hitCount')}
data={source.hit_count}
icon={<Target04 className='mr-1 w-3 h-3' />}
/>
<Tooltip
text={t('common.chat.citation.vectorHash')}
data={source.index_node_hash.substring(0, 7)}
icon={<BezierCurve03 className='mr-1 w-3 h-3' />}
/>
<ProgressTooltip data={Number(source.score.toFixed(2))} />
</div>
)
}
</div>
{
index !== data.sources.length - 1 && (
<div className='my-1 h-[1px] bg-black/5' />
)
}
</Fragment>
))
}
</div>
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default Popup

View File

@@ -0,0 +1,46 @@
import { useState } from 'react'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type ProgressTooltipProps = {
data: number
}
const ProgressTooltip: FC<ProgressTooltipProps> = ({
data,
}) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
>
<PortalToFollowElemTrigger
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<div className='grow flex items-center'>
<div className='mr-1 w-16 h-1.5 rounded-[3px] border border-gray-400 overflow-hidden'>
<div className='bg-gray-400 h-full' style={{ width: `${data * 100}%` }}></div>
</div>
{data}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1001 }}>
<div className='p-3 bg-white text-xs font-medium text-gray-500 rounded-lg shadow-lg'>
{t('common.chat.citation.hitScore')} {data}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default ProgressTooltip

View File

@@ -0,0 +1,46 @@
import React, { useState } from 'react'
import type { FC } from 'react'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type TooltipProps = {
data: number | string
text: string
icon: React.ReactNode
}
const Tooltip: FC<TooltipProps> = ({
data,
text,
icon,
}) => {
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
>
<PortalToFollowElemTrigger
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<div className='flex items-center mr-6'>
{icon}
{data}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1001 }}>
<div className='p-3 bg-white text-xs font-medium text-gray-500 rounded-lg shadow-lg'>
{text} {data}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default Tooltip

View File

@@ -48,15 +48,17 @@ export type IChatProps = {
isShowSuggestion?: boolean
suggestionList?: string[]
isShowSpeechToText?: boolean
isShowCitation?: boolean
answerIconClassName?: string
isShowConfigElem?: boolean
dataSets?: DataSet[]
isShowCitationHitInfo?: boolean
}
const Chat: FC<IChatProps> = ({
configElem,
chatList,
controlChatUpdateAllConversation,
feedbackDisabled = false,
isHideFeedbackEdit = false,
isHideSendInput = false,
@@ -74,9 +76,11 @@ const Chat: FC<IChatProps> = ({
isShowSuggestion,
suggestionList,
isShowSpeechToText,
isShowCitation,
answerIconClassName,
isShowConfigElem,
dataSets,
isShowCitationHitInfo,
}) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
@@ -162,6 +166,7 @@ const Chat: FC<IChatProps> = ({
if (item.isAnswer) {
const isLast = item.id === chatList[chatList.length - 1].id
const thoughts = item.agent_thoughts?.filter(item => item.thought !== '[DONE]')
const citation = item.citation
const isThinking = !item.content && item.agent_thoughts && item.agent_thoughts?.length > 0 && !item.agent_thoughts.some(item => item.thought === '[DONE]')
return <Answer
key={item.id}
@@ -174,8 +179,11 @@ const Chat: FC<IChatProps> = ({
isResponsing={isResponsing && isLast}
answerIconClassName={answerIconClassName}
thoughts={thoughts}
citation={citation}
isThinking={isThinking}
dataSets={dataSets}
isShowCitation={isShowCitation}
isShowCitationHitInfo={isShowCitationHitInfo}
/>
}
return <Question key={item.id} id={item.id} content={item.content} more={item.more} useCurrentUserAvatar={useCurrentUserAvatar} />

View File

@@ -23,10 +23,26 @@ export type ThoughtItem = {
tool_input: string
message_id: string
}
export type CitationItem = {
content: string
data_source_type: string
dataset_name: string
dataset_id: string
document_id: string
document_name: string
hit_count: number
index_node_hash: string
segment_id: string
segment_position: number
score: number
word_count: number
}
export type IChatItem = {
id: string
content: string
agent_thoughts?: ThoughtItem[]
citation?: CitationItem[]
/**
* Specific message type
*/
@@ -51,3 +67,8 @@ export type IChatItem = {
useCurrentUserAvatar?: boolean
isOpeningStatement?: boolean
}
export type MessageEnd = {
id: string
retriever_resources?: CitationItem[]
}

View File

@@ -1,18 +1,18 @@
'use client'
import React, { FC, useState } from 'react'
import React, { useState } from 'react'
import cn from 'classnames'
export interface IRemoveIconProps {
type IRemoveIconProps = {
className?: string
isHoverStatus?: boolean
onClick: () => void
}
const RemoveIcon: FC<IRemoveIconProps> = ({
const RemoveIcon = ({
className,
isHoverStatus,
onClick
}) => {
onClick,
}: IRemoveIconProps) => {
const [isHovered, setIsHovered] = useState(false)
const computedIsHovered = isHoverStatus || isHovered
return (
@@ -23,7 +23,7 @@ const RemoveIcon: FC<IRemoveIconProps> = ({
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke={computedIsHovered ? "#D92D20" : "#667085"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
<path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke={computedIsHovered ? '#D92D20' : '#667085'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</div>
)

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 175 KiB

View File

@@ -26,4 +26,8 @@
.speechToTextPreview {
background-image: url(./preview-imgs/speech-to-text.svg);
}
.citationPreview {
background-image: url(./preview-imgs/citation.svg);
}

View File

@@ -8,11 +8,13 @@ import FeatureItem from './feature-item'
import Modal from '@/app/components/base/modal'
import SuggestedQuestionsAfterAnswerIcon from '@/app/components/app/configuration/base/icons/suggested-questions-after-answer-icon'
import { Microphone01 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import { Citations } from '@/app/components/base/icons/src/vender/solid/editor'
type IConfig = {
openingStatement: boolean
moreLikeThis: boolean
suggestedQuestionsAfterAnswer: boolean
speechToText: boolean
citation: boolean
}
export type IChooseFeatureProps = {
@@ -85,6 +87,14 @@ const ChooseFeature: FC<IChooseFeatureProps> = ({
/>
)
}
<FeatureItem
icon={<Citations className='w-4 h-4 text-[#FD853A]' />}
previewImgClassName='citationPreview'
title={t('appDebug.feature.citation.title')}
description={t('appDebug.feature.citation.description')}
value={config.citation}
onChange={value => onChange('citation', value)}
/>
</>
</FeatureGroup>
)}

View File

@@ -9,6 +9,8 @@ function useFeature({
setSuggestedQuestionsAfterAnswer,
speechToText,
setSpeechToText,
citation,
setCitation,
}: {
introduction: string
setIntroduction: (introduction: string) => void
@@ -18,6 +20,8 @@ function useFeature({
setSuggestedQuestionsAfterAnswer: (suggestedQuestionsAfterAnswer: boolean) => void
speechToText: boolean
setSpeechToText: (speechToText: boolean) => void
citation: boolean
setCitation: (citation: boolean) => void
}) {
const [tempshowOpeningStatement, setTempShowOpeningStatement] = React.useState(!!introduction)
useEffect(() => {
@@ -36,6 +40,7 @@ function useFeature({
moreLikeThis,
suggestedQuestionsAfterAnswer,
speechToText,
citation,
}
const handleFeatureChange = (key: string, value: boolean) => {
switch (key) {
@@ -53,6 +58,9 @@ function useFeature({
break
case 'speechToText':
setSpeechToText(value)
break
case 'citation':
setCitation(value)
}
}
return {

View File

@@ -36,6 +36,8 @@ const Config: FC = () => {
setSuggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
setSpeechToTextConfig,
citationConfig,
setCitationConfig,
} = useContext(ConfigContext)
const isChatApp = mode === AppType.chat
const { speech2textDefaultModel } = useProviderContext()
@@ -88,9 +90,15 @@ const Config: FC = () => {
draft.enabled = value
}))
},
citation: citationConfig.enabled,
setCitation: (value) => {
setCitationConfig(produce(citationConfig, (draft) => {
draft.enabled = value
}))
},
})
const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && !!speech2textDefaultModel))
const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && !!speech2textDefaultModel) || featureConfig.citation)
const hasToolbox = false
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
@@ -161,6 +169,7 @@ const Config: FC = () => {
}
isShowSuggestedQuestionsAfterAnswer={featureConfig.suggestedQuestionsAfterAnswer}
isShowSpeechText={featureConfig.speechToText && !!speech2textDefaultModel}
isShowCitation={featureConfig.citation}
/>
)
}

View File

@@ -29,9 +29,9 @@ const CardItem: FC<ICardItemProps> = ({
<div
className={
cn(className, s.card,
'flex items-center justify-between rounded-xl px-3 py-2.5 bg-white border border-gray-200 cursor-pointer')
'relative flex items-center rounded-xl px-3 py-2.5 bg-white border border-gray-200 cursor-pointer')
}>
<div className='shrink-0 flex items-center space-x-2'>
<div className='flex items-center space-x-2'>
<div className={cn(!config.embedding_available && 'opacity-50')}>
<TypeIcon type="upload_file" />
</div>
@@ -47,13 +47,13 @@ const CardItem: FC<ICardItemProps> = ({
</Tooltip>
)}
</div>
<div className={cn('flex text-xs text-gray-500', !config.embedding_available && 'opacity-50')}>
<div className={cn('max-w-[150px] flex text-xs text-gray-500', !config.embedding_available && 'opacity-50')}>
{formatNumber(config.word_count)} {t('appDebug.feature.dataSet.words')} · {formatNumber(config.document_count)} {t('appDebug.feature.dataSet.textBlocks')}
</div>
</div>
</div>
{!readonly && <RemoveIcon className={`${s.deleteBtn} shrink-0`} onClick={() => onRemove(config.id)} />}
{!readonly && <RemoveIcon className={`${s.deleteBtn} absolute right-1 top-1/2 translate-y-[-50%]`} onClick={() => onRemove(config.id)} />}
</div>
)
}

View File

@@ -8,9 +8,9 @@
}
.deleteBtn {
display: none;
visibility: hidden;
}
.card:hover .deleteBtn {
display: block;
visibility: visible;
}

View File

@@ -40,6 +40,7 @@ const Debug: FC<IDebug> = ({
introduction,
suggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
citationConfig,
moreLikeThisConfig,
inputs,
// setInputs,
@@ -162,6 +163,7 @@ const Debug: FC<IDebug> = ({
},
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
agent_mode: {
enabled: true,
tools: [...postDatasets],
@@ -199,7 +201,7 @@ const Debug: FC<IDebug> = ({
setChatList(newList)
// answer
const responseItem = {
const responseItem: IChatItem = {
id: `${Date.now()}`,
content: '',
isAnswer: true,
@@ -266,6 +268,19 @@ const Debug: FC<IDebug> = ({
setIsShowSuggestion(true)
}
},
onMessageEnd: (messageEnd) => {
responseItem.citation = messageEnd.retriever_resources
const newListWithAnswer = produce(
getChatList().filter(item => item.id !== responseItem.id && item.id !== placeholderAnswerId),
(draft) => {
if (!draft.find(item => item.id === questionId))
draft.push({ ...questionItem })
draft.push({ ...responseItem })
})
setChatList(newListWithAnswer)
},
onError() {
setResponsingFalse()
// role back placeholder answer
@@ -312,6 +327,7 @@ const Debug: FC<IDebug> = ({
opening_statement: introduction,
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
more_like_this: moreLikeThisConfig,
agent_mode: {
enabled: true,
@@ -391,6 +407,8 @@ const Debug: FC<IDebug> = ({
isShowSuggestion={doShowSuggestion}
suggestionList={suggestQuestions}
isShowSpeechToText={speechToTextConfig.enabled && !!speech2textDefaultModel}
isShowCitation={citationConfig.enabled}
isShowCitationHitInfo
/>
</div>
</div>

View File

@@ -0,0 +1,25 @@
'use client'
import React, { type FC } from 'react'
import { useTranslation } from 'react-i18next'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import { Citations } from '@/app/components/base/icons/src/vender/solid/editor'
const Citation: FC = () => {
const { t } = useTranslation()
return (
<Panel
title={
<div className='flex items-center gap-2'>
<div>{t('appDebug.feature.citation.title')}</div>
</div>
}
headerIcon={<Citations className='w-4 h-4 text-[#FD853A]' />}
headerRight={
<div className='text-xs text-gray-500'>{t('appDebug.feature.citation.resDes')}</div>
}
noBodySpacing
/>
)
}
export default React.memo(Citation)

View File

@@ -7,6 +7,7 @@ import type { IOpeningStatementProps } from './opening-statement'
import OpeningStatement from './opening-statement'
import SuggestedQuestionsAfterAnswer from './suggested-questions-after-answer'
import SpeechToText from './speech-to-text'
import Citation from './citation'
/*
* Include
@@ -19,12 +20,14 @@ type ChatGroupProps = {
openingStatementConfig: IOpeningStatementProps
isShowSuggestedQuestionsAfterAnswer: boolean
isShowSpeechText: boolean
isShowCitation: boolean
}
const ChatGroup: FC<ChatGroupProps> = ({
isShowOpeningStatement,
openingStatementConfig,
isShowSuggestedQuestionsAfterAnswer,
isShowSpeechText,
isShowCitation,
}) => {
const { t } = useTranslation()
@@ -43,6 +46,11 @@ const ChatGroup: FC<ChatGroupProps> = ({
<SpeechToText />
)
}
{
isShowCitation && (
<Citation />
)
}
</div>
</div>
)

View File

@@ -56,6 +56,9 @@ const Configuration: FC = () => {
const [speechToTextConfig, setSpeechToTextConfig] = useState<MoreLikeThisConfig>({
enabled: false,
})
const [citationConfig, setCitationConfig] = useState<MoreLikeThisConfig>({
enabled: false,
})
const [formattingChanged, setFormattingChanged] = useState(false)
const [inputs, setInputs] = useState<Inputs>({})
const [query, setQuery] = useState('')
@@ -77,6 +80,7 @@ const Configuration: FC = () => {
more_like_this: null,
suggested_questions_after_answer: null,
speech_to_text: null,
retriever_resource: null,
dataSets: [],
})
@@ -110,6 +114,9 @@ const Configuration: FC = () => {
setSpeechToTextConfig(modelConfig.speech_to_text || {
enabled: false,
})
setCitationConfig(modelConfig.retriever_resource || {
enabled: false,
})
}
const { textGenerationModelList } = useProviderContext()
@@ -159,6 +166,9 @@ const Configuration: FC = () => {
if (modelConfig.speech_to_text)
setSpeechToTextConfig(modelConfig.speech_to_text)
if (modelConfig.retriever_resource)
setCitationConfig(modelConfig.retriever_resource)
const config = {
modelConfig: {
provider: model.provider,
@@ -171,6 +181,7 @@ const Configuration: FC = () => {
more_like_this: modelConfig.more_like_this,
suggested_questions_after_answer: modelConfig.suggested_questions_after_answer,
speech_to_text: modelConfig.speech_to_text,
retriever_resource: modelConfig.retriever_resource,
dataSets: datasets || [],
},
completionParams: model.completion_params,
@@ -202,6 +213,7 @@ const Configuration: FC = () => {
more_like_this: moreLikeThisConfig,
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
agent_mode: {
enabled: true,
tools: [...postDatasets],
@@ -219,6 +231,7 @@ const Configuration: FC = () => {
draft.more_like_this = moreLikeThisConfig
draft.suggested_questions_after_answer = suggestedQuestionsAfterAnswerConfig
draft.speech_to_text = speechToTextConfig
draft.retriever_resource = citationConfig
draft.dataSets = dataSets
})
setPublishedConfig({
@@ -263,6 +276,8 @@ const Configuration: FC = () => {
setSuggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
setSpeechToTextConfig,
citationConfig,
setCitationConfig,
formattingChanged,
setFormattingChanged,
inputs,

View File

@@ -134,7 +134,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
<div className="space-y-3 ">
{promptVariables.map(({ key, name, type, options, max_length, required }) => (
<div key={key} className="flex items-center justify-between">
<div className="mr-1 shrink-0 w-[120px] text-sm text-gray-900">{name || key}</div>
<div className="mr-1 shrink-0 w-[120px] text-sm text-gray-900 break-all">{name || key}</div>
{type === 'select'
? (
<Select

View File

@@ -288,7 +288,7 @@ const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: st
return true
}
catch (err) {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
}
@@ -301,7 +301,7 @@ const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: st
return true
}
catch (err) {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
}
@@ -332,7 +332,7 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }
return true
}
catch (err) {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
}
@@ -344,7 +344,7 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }
return true
}
catch (err) {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
}

View File

@@ -119,9 +119,11 @@ function AppCard({
}
const onGenCode = async () => {
setGenLoading(true)
await asyncRunSafe(onGenerateCode?.() as any)
setGenLoading(false)
if (onGenerateCode) {
setGenLoading(true)
await asyncRunSafe(onGenerateCode())
setGenLoading(false)
}
}
return (

View File

@@ -7,6 +7,7 @@ import Modal from '@/app/components/base/modal'
import copyStyle from '@/app/components/app/chat/copy-btn/style.module.css'
import Tooltip from '@/app/components/base/tooltip'
import { useAppContext } from '@/context/app-context'
import { IS_CE_EDITION } from '@/config'
// const isDevelopment = process.env.NODE_ENV === 'development'
@@ -30,7 +31,15 @@ const OPTION_MAP = {
scripts: {
getContent: (url: string, token: string, isTestEnv?: boolean) =>
`<script>
window.difyChatbotConfig = { token: '${token}'${isTestEnv ? ', isDev: true' : ''} }
window.difyChatbotConfig = {
token: '${token}'${isTestEnv
? `,
isDev: true`
: ''}${IS_CE_EDITION
? `,
baseUrl: '${url}'`
: ''}
}
</script>
<script
src="${url}/embed.min.js"

View File

@@ -46,7 +46,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
onSave,
}) => {
const [isShowMore, setIsShowMore] = useState(false)
const { title, description, copyright, privacy_policy, default_language, icon, icon_background } = appInfo.site
const { icon, icon_background } = appInfo
const { title, description, copyright, privacy_policy, default_language } = appInfo.site
const [inputInfo, setInputInfo] = useState({ title, desc: description, copyright, privacyPolicy: privacy_policy })
const [language, setLanguage] = useState(default_language)
const [saveLoading, setSaveLoading] = useState(false)

View File

@@ -41,8 +41,8 @@ const ConfirmUI: FC<IConfirmUIProps> = ({
</div>
<div className='flex gap-3 mt-4 ml-12'>
<div onClick={onConfirm} className='w-20 leading-[34px] text-center text-white border rounded-lg cursor-pointer h-9 border-color-primary-700 bg-primary-700'>{confirmText || t('common.operation.confirm')}</div>
<div onClick={onCancel} className='w-20 leading-[34px] text-center text-gray-500 border rounded-lg cursor-pointer h-9 border-color-gray-200'>{cancelText || t('common.operation.cancel')}</div>
<div onClick={onConfirm} className='w-20 leading-9 text-center text-white border rounded-lg cursor-pointer h-9 border-color-primary-700 bg-primary-700'>{confirmText || t('common.operation.confirm')}</div>
<div onClick={onCancel} className='w-20 leading-9 text-center text-gray-500 border rounded-lg cursor-pointer h-9 border-color-gray-200'>{cancelText || t('common.operation.cancel')}</div>
</div>
</div>

View File

@@ -0,0 +1,48 @@
import type { FC } from 'react'
import {
Csv,
Html,
Json,
Md,
Pdf,
Txt,
Unknow,
Xlsx,
} from '@/app/components/base/icons/src/public/files'
import { Notion } from '@/app/components/base/icons/src/public/common'
type FileIconProps = {
type: string
className?: string
}
const FileIcon: FC<FileIconProps> = ({
type,
className,
}) => {
switch (type) {
case 'csv':
return <Csv className={className} />
case 'htm':
case 'html':
return <Html className={className} />
case 'json':
return <Json className={className} />
case 'md':
case 'markdown':
return <Md className={className} />
case 'pdf':
return <Pdf className={className} />
case 'txt':
return <Txt className={className} />
case 'xls':
case 'xlsx':
return <Xlsx className={className} />
case 'notion':
return <Notion className={className} />
default:
return <Unknow className={className} />
}
}
export default FileIcon

View File

@@ -0,0 +1,12 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5364_42310)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5725 18.2611L1.4229 15.5832C0.905706 14.9389 0.625 14.1466 0.625 13.3312V3.63437C0.625 2.4129 1.60224 1.39936 2.86295 1.31328L12.8326 0.632614C13.5569 0.583164 14.2768 0.775682 14.8717 1.17794L18.3745 3.5462C19.0015 3.97012 19.375 4.66312 19.375 5.40266V16.427C19.375 17.6223 18.4141 18.6121 17.1798 18.688L6.11458 19.3692C5.12958 19.4298 4.17749 19.0148 3.5725 18.2611Z" fill="white"/>
<path d="M7.03006 8.48663V8.35968C7.03006 8.03787 7.28779 7.77098 7.61997 7.7488L10.0396 7.58726L13.3857 12.5146V8.19003L12.5244 8.07522V8.01492C12.5244 7.68933 12.788 7.42068 13.1244 7.40344L15.326 7.29066V7.60749C15.326 7.75622 15.2154 7.88343 15.0638 7.90907L14.534 7.99868V15.0022L13.8691 15.2309C13.3136 15.4219 12.6952 15.2174 12.3772 14.7376L9.12879 9.83568V14.5143L10.1287 14.7056L10.1147 14.7984C10.0711 15.0889 9.82028 15.3086 9.51687 15.3221L7.03006 15.4328C6.99718 15.1204 7.23132 14.8409 7.55431 14.807L7.88143 14.7726V8.53447L7.03006 8.48663Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9218 1.85418L2.95217 2.53485C2.35499 2.57562 1.89209 3.05572 1.89209 3.63431V13.3311C1.89209 13.8748 2.07923 14.4029 2.42402 14.8325L4.57362 17.5104C4.92117 17.9433 5.46812 18.1817 6.03397 18.1469L17.0991 17.4658C17.6663 17.4309 18.1078 16.9761 18.1078 16.4269V5.4026C18.1078 5.06281 17.9362 4.74441 17.6481 4.54963L14.1453 2.18137C13.7883 1.94002 13.3564 1.82451 12.9218 1.85418ZM3.44654 3.78556C3.30788 3.6829 3.37387 3.46903 3.54806 3.45654L12.9889 2.77938C13.2897 2.75781 13.5886 2.84064 13.8318 3.01299L15.7261 4.35502C15.798 4.40597 15.7642 4.51596 15.6752 4.5208L5.67742 5.06454C5.37485 5.081 5.0762 4.99211 4.83563 4.814L3.44654 3.78556ZM5.20848 6.76913C5.20848 6.44433 5.47088 6.17604 5.80642 6.15777L16.3769 5.5821C16.7039 5.56429 16.9792 5.81577 16.9792 6.13232V15.6782C16.9792 16.0024 16.7177 16.2705 16.3829 16.2895L5.8793 16.8871C5.51537 16.9079 5.20848 16.6282 5.20848 16.2759V6.76913Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_5364_42310">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14424)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#EC5B27"/>
</g>
<g opacity="0.96">
<path d="M10.2704 24.0002V18.3042H8.87042V20.4962H7.38242V18.3042H5.98242V24.0002H7.38242V21.7442H8.87042V24.0002H10.2704Z" fill="white"/>
<path d="M15.2839 19.5522V18.3042H11.0839V19.5522H12.4839V24.0002H13.8839V19.5522H15.2839Z" fill="white"/>
<path d="M21.4116 24.0002V18.3042H20.0356L18.7556 20.8162L17.4756 18.3042H16.0996V24.0002H17.4996V21.2722L18.3076 22.6802H19.2036L20.0116 21.2722V24.0002H21.4116Z" fill="white"/>
<path d="M26.3525 24.0002V22.7522H23.9605V18.3042H22.5605V24.0002H26.3525Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14424" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14424"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14424" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14428)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#2D2D2E"/>
</g>
<g opacity="0.96">
<path d="M9.83907 22.0479V18.3039H8.43907V22.0159C8.43907 22.5599 8.12707 22.7999 7.69507 22.7999C7.38307 22.7999 7.23907 22.6879 7.06307 22.5119L6.14307 23.4239C6.60707 23.8879 7.03107 24.0479 7.69507 24.0479C8.76707 24.0479 9.83907 23.3999 9.83907 22.0479Z" fill="white"/>
<path d="M14.7321 22.2559C14.7321 21.7279 14.6121 21.3039 14.3081 21.0079C14.0681 20.7679 13.7001 20.6079 13.1881 20.5359L12.5001 20.4399C12.3001 20.4159 12.1801 20.3439 12.1081 20.2719C12.0201 20.1839 11.9961 20.0799 11.9961 20.0079C11.9961 19.7599 12.1961 19.4799 12.6841 19.4799C12.9321 19.4799 13.4041 19.4559 13.7641 19.8159L14.6441 18.9359C14.1561 18.4479 13.5401 18.2559 12.7241 18.2559C11.4281 18.2559 10.6441 19.0159 10.6441 20.0559C10.6441 20.5439 10.7721 20.9279 11.0361 21.1999C11.2921 21.4639 11.6761 21.6319 12.1801 21.7039L12.8681 21.7999C13.0521 21.8239 13.1721 21.8799 13.2441 21.9519C13.3241 22.0399 13.3561 22.1519 13.3561 22.2879C13.3561 22.6159 13.0921 22.7999 12.5401 22.7999C12.0841 22.7999 11.5641 22.6959 11.2681 22.3999L10.3721 23.2959C10.9481 23.8879 11.6601 24.0479 12.5321 24.0479C13.7321 24.0479 14.7321 23.4159 14.7321 22.2559Z" fill="white"/>
<path d="M19.8023 21.1519C19.8023 20.2959 19.8263 19.4959 19.2263 18.8959C18.8103 18.4799 18.3303 18.2559 17.6343 18.2559C16.9383 18.2559 16.4583 18.4799 16.0423 18.8959C15.4423 19.4959 15.4663 20.2959 15.4663 21.1519C15.4663 22.0079 15.4423 22.8079 16.0423 23.4079C16.4583 23.8239 16.9383 24.0479 17.6343 24.0479C18.3303 24.0479 18.8103 23.8239 19.2263 23.4079C19.8263 22.8079 19.8023 22.0079 19.8023 21.1519ZM18.4023 21.1519C18.4023 22.1919 18.3223 22.3759 18.1943 22.5439C18.0903 22.6799 17.8903 22.7999 17.6343 22.7999C17.3783 22.7999 17.1783 22.6799 17.0743 22.5439C16.9463 22.3759 16.8663 22.1919 16.8663 21.1519C16.8663 20.1119 16.9463 19.9199 17.0743 19.7519C17.1783 19.6159 17.3783 19.5039 17.6343 19.5039C17.8903 19.5039 18.0903 19.6159 18.1943 19.7519C18.3223 19.9199 18.4023 20.1119 18.4023 21.1519Z" fill="white"/>
<path d="M25.2154 23.9999V18.3039H23.8154V21.1679L21.9914 18.3039H20.7674V23.9999H22.1674V21.1359L23.9914 23.9999H25.2154Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14428" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14428"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14428" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,22 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14420)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#DD3633"/>
</g>
<g opacity="0.96">
<path d="M13.2801 20.1362C13.2801 19.2002 12.6001 18.3042 11.3361 18.3042H9.08008V24.0002H10.4801V21.9682H11.3361C12.6001 21.9682 13.2801 21.0722 13.2801 20.1362ZM11.8801 20.1362C11.8801 20.4322 11.6561 20.7122 11.2721 20.7122H10.4801V19.5602H11.2721C11.6561 19.5602 11.8801 19.8402 11.8801 20.1362Z" fill="white"/>
<path d="M18.3357 21.1522C18.3357 20.2562 18.4077 19.5282 17.7437 18.8642C17.3517 18.4722 16.7997 18.3042 16.2077 18.3042H14.0957V24.0002H16.2077C16.7997 24.0002 17.3517 23.8322 17.7437 23.4402C18.4077 22.7762 18.3357 22.0482 18.3357 21.1522ZM16.9357 21.1522C16.9357 22.1202 16.8957 22.2722 16.7837 22.4322C16.6557 22.6242 16.4637 22.7522 16.1117 22.7522H15.4957V19.5522H16.1117C16.4637 19.5522 16.6557 19.6802 16.7837 19.8722C16.8957 20.0322 16.9357 20.1922 16.9357 21.1522Z" fill="white"/>
<path d="M23.1786 19.5522V18.3042H19.3066V24.0002H20.7066V21.8002H22.8186V20.5522H20.7066V19.5522H23.1786Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14420" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14420"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14420" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14432)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#E3E5E8"/>
<path d="M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z" stroke="black" stroke-opacity="0.03" stroke-width="0.5"/>
</g>
<g opacity="0.96">
<path d="M13.2254 19.5522V18.3042H9.02539V19.5522H10.4254V24.0002H11.8254V19.5522H13.2254Z" fill="#667085"/>
<path d="M18.5371 24.0002L16.7611 21.0802L18.4251 18.3042H16.8331L16.0011 19.9122L15.1691 18.3042H13.5771L15.2411 21.0802L13.4651 24.0002H15.0651L16.0011 22.2482L16.9371 24.0002H18.5371Z" fill="#667085"/>
<path d="M22.9754 19.5522V18.3042H18.7754V19.5522H20.1754V24.0002H21.5754V19.5522H22.9754Z" fill="#667085"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14432" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14432"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14432" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14436)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#E3E5E8"/>
<path d="M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z" stroke="black" stroke-opacity="0.03" stroke-width="0.5"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9998 23.1992C15.8014 23.1992 15.6039 23.1968 15.4077 23.1924V24.0549C15.4077 24.3819 15.6728 24.647 15.9998 24.647C16.3268 24.647 16.592 24.3819 16.592 24.0549V23.1924C16.3957 23.1968 16.1983 23.1992 15.9998 23.1992Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0984 22.8838L11.757 23.8593C11.649 24.168 11.8117 24.5058 12.1203 24.6138C12.185 24.6364 12.251 24.6472 12.3159 24.6472C12.5605 24.6472 12.7894 24.4944 12.8747 24.2505L13.2936 23.0534C12.8807 23.0073 12.481 22.9506 12.0984 22.8838Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.2431 23.8593L19.9018 22.8838C19.5192 22.9506 19.1195 23.0073 18.7065 23.0534L19.1254 24.2505C19.2108 24.4944 19.4396 24.6472 19.6843 24.6472C19.7491 24.6472 19.8151 24.6364 19.8798 24.6138C20.1885 24.5058 20.3511 24.168 20.2431 23.8593Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1624 17.2634C20.2697 17.6416 20.3254 18.0369 20.3254 18.4409C20.3254 18.9087 20.05 19.3327 19.6226 19.5228C19.5564 19.5522 17.9801 20.2436 16.0359 20.2436C14.0917 20.2436 12.5153 19.5522 12.4492 19.5228C12.0218 19.3327 11.7464 18.9086 11.7464 18.4409C11.7464 18.0312 11.8037 17.6305 11.914 17.2476C10.3343 17.5645 8.5 18.2009 8.5 19.4464C8.5 20.2859 9.32512 20.9477 10.9525 21.4134C11.4194 21.547 11.9381 21.66 12.4949 21.7506C12.8783 21.813 13.28 21.8648 13.6953 21.9056C14.2455 21.9597 14.8197 21.9942 15.4079 22.0082C15.6039 22.0128 15.8013 22.0153 16 22.0153C16.1987 22.0153 16.3962 22.0128 16.5921 22.0082C17.1803 21.9943 17.7545 21.9596 18.3047 21.9056C18.72 21.8648 19.1217 21.8131 19.5051 21.7506C20.062 21.66 20.5807 21.547 21.0476 21.4134C22.6749 20.9477 23.5 20.2859 23.5 19.4464C23.5 18.2187 21.7108 17.5833 20.1624 17.2634Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.8441 17.1144C18.7585 16.9335 18.6559 16.7622 18.5384 16.6025C18.4174 16.4382 18.2809 16.286 18.1307 16.1486C17.5784 15.6437 16.8433 15.3354 16.036 15.3354C15.2318 15.3354 14.499 15.6411 13.9476 16.1426C13.7974 16.2791 13.6609 16.4303 13.5399 16.5937C13.4217 16.753 13.3185 16.924 13.2322 17.1048C13.039 17.5095 12.9307 17.9624 12.9307 18.4407C12.9307 18.4407 14.321 19.0592 16.036 19.0592C17.751 19.0592 19.1412 18.4407 19.1412 18.4407C19.1412 17.9662 19.0344 17.5167 18.8441 17.1144Z" fill="#98A2B3"/>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14436" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14436"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14436" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,18 @@
<svg width="24" height="26" viewBox="0 0 24 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_5938_927)">
<path d="M3 5.8C3 4.11984 3 3.27976 3.32698 2.63803C3.6146 2.07354 4.07354 1.6146 4.63803 1.32698C5.27976 1 6.11984 1 7.8 1H14L21 8V18.2C21 19.8802 21 20.7202 20.673 21.362C20.3854 21.9265 19.9265 22.3854 19.362 22.673C18.7202 23 17.8802 23 16.2 23H7.8C6.11984 23 5.27976 23 4.63803 22.673C4.07354 22.3854 3.6146 21.9265 3.32698 21.362C3 20.7202 3 19.8802 3 18.2V5.8Z" fill="#169951"/>
</g>
<path opacity="0.5" d="M14 1L21 8H16C14.8954 8 14 7.10457 14 6V1Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 12C17.5523 12 18 12.4477 18 13V18C18 18.5523 17.5523 19 17 19H7C6.44772 19 6 18.5523 6 18V13C6 12.4477 6.44772 12 7 12H17ZM11.5 13H7L7 15H11.5V13ZM12.5 18H17V16H12.5V18ZM11.5 16V18H7L7 16H11.5ZM12.5 15H17V13H12.5V15Z" fill="white" fill-opacity="0.96"/>
<defs>
<filter id="filter0_d_5938_927" x="1" y="0" width="22" height="26" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5938_927"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5938_927" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,5 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="bezier-curve-03">
<path id="Icon" d="M5.42857 3.5L2.57143 8.5M3 9.5H8.9999M9.42857 8.5L6.57143 3.5M1.8 10.5H2.2C2.48003 10.5 2.62004 10.5 2.727 10.4455C2.82108 10.3976 2.89757 10.3211 2.9455 10.227C3 10.12 3 9.98003 3 9.7V9.3C3 9.01997 3 8.87996 2.9455 8.773C2.89757 8.67892 2.82108 8.60243 2.727 8.5545C2.62004 8.5 2.48003 8.5 2.2 8.5H1.8C1.51997 8.5 1.37996 8.5 1.273 8.5545C1.17892 8.60243 1.10243 8.67892 1.0545 8.773C1 8.87996 1 9.01997 1 9.3V9.7C1 9.98003 1 10.12 1.0545 10.227C1.10243 10.3211 1.17892 10.3976 1.273 10.4455C1.37996 10.5 1.51997 10.5 1.8 10.5ZM9.8 10.5H10.2C10.48 10.5 10.62 10.5 10.727 10.4455C10.8211 10.3976 10.8976 10.3211 10.9455 10.227C11 10.12 11 9.98003 11 9.7V9.3C11 9.01997 11 8.87996 10.9455 8.773C10.8976 8.67892 10.8211 8.60243 10.727 8.5545C10.62 8.5 10.48 8.5 10.2 8.5H9.8C9.51997 8.5 9.37996 8.5 9.273 8.5545C9.17892 8.60243 9.10243 8.67892 9.0545 8.773C9 8.87996 9 9.01997 9 9.3V9.7C9 9.98003 9 10.12 9.0545 10.227C9.10243 10.3211 9.17892 10.3976 9.273 10.4455C9.37996 10.5 9.51997 10.5 9.8 10.5ZM5.8 3.5H6.2C6.48003 3.5 6.62004 3.5 6.727 3.4455C6.82108 3.39757 6.89757 3.32108 6.9455 3.227C7 3.12004 7 2.98003 7 2.7V2.3C7 2.01997 7 1.87996 6.9455 1.773C6.89757 1.67892 6.82108 1.60243 6.727 1.5545C6.62004 1.5 6.48003 1.5 6.2 1.5H5.8C5.51997 1.5 5.37996 1.5 5.273 1.5545C5.17892 1.60243 5.10243 1.67892 5.0545 1.773C5 1.87996 5 2.01997 5 2.3V2.7C5 2.98003 5 3.12004 5.0545 3.227C5.10243 3.32108 5.17892 3.39757 5.273 3.4455C5.37996 3.5 5.51997 3.5 5.8 3.5Z" stroke="#667085" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,5 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="type-square">
<path id="Icon" d="M4 3.5H8M6 3.5V8.5M3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V3.9C10.5 3.05992 10.5 2.63988 10.3365 2.31901C10.1927 2.03677 9.96323 1.8073 9.68099 1.66349C9.36012 1.5 8.94008 1.5 8.1 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5Z" stroke="#667085" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 746 B

View File

@@ -0,0 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Left Icon" clip-path="url(#clip0_10386_42171)">
<path id="Icon" d="M7.99998 4V2.5L9.49998 1L9.99998 2L11 2.5L9.49998 4H7.99998ZM7.99998 4L5.99999 5.99997M11 6C11 8.76142 8.76142 11 6 11C3.23858 11 1 8.76142 1 6C1 3.23858 3.23858 1 6 1M8.5 6C8.5 7.38071 7.38071 8.5 6 8.5C4.61929 8.5 3.5 7.38071 3.5 6C3.5 4.61929 4.61929 3.5 6 3.5" stroke="#667085" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_10386_42171">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 618 B

View File

@@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="citations">
<path id="Subtract" d="M0.666992 7.99996C0.666992 3.94987 3.95024 0.666626 8.00033 0.666626C12.0504 0.666626 15.3337 3.94987 15.3337 7.99996C15.3337 12.05 12.0504 15.3333 8.00033 15.3333C3.95024 15.3333 0.666992 12.05 0.666992 7.99996ZM4.66699 7.9801V9.97196H7.35742V7.48922H5.87533C5.85644 7.21231 5.90365 6.94484 6.01693 6.68681C6.2372 6.19592 6.66829 5.84979 7.31022 5.6484V4.66663C6.44803 4.83655 5.79036 5.19527 5.33724 5.7428C4.89041 6.29032 4.66699 7.03609 4.66699 7.9801ZM10.0264 6.70569C10.2466 6.19592 10.6746 5.84349 11.3102 5.6484V4.66663C10.4732 4.83655 9.82183 5.19212 9.35612 5.73336C8.8967 6.27459 8.66699 7.02351 8.66699 7.9801V9.97196H11.3574V7.48922H9.87533C9.85015 7.23748 9.9005 6.9763 10.0264 6.70569Z" fill="#FD853A"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 869 B

View File

@@ -0,0 +1,83 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "20",
"height": "20",
"viewBox": "0 0 20 20",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_5364_42310)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M3.5725 18.2611L1.4229 15.5832C0.905706 14.9389 0.625 14.1466 0.625 13.3312V3.63437C0.625 2.4129 1.60224 1.39936 2.86295 1.31328L12.8326 0.632614C13.5569 0.583164 14.2768 0.775682 14.8717 1.17794L18.3745 3.5462C19.0015 3.97012 19.375 4.66312 19.375 5.40266V16.427C19.375 17.6223 18.4141 18.6121 17.1798 18.688L6.11458 19.3692C5.12958 19.4298 4.17749 19.0148 3.5725 18.2611Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M7.03006 8.48663V8.35968C7.03006 8.03787 7.28779 7.77098 7.61997 7.7488L10.0396 7.58726L13.3857 12.5146V8.19003L12.5244 8.07522V8.01492C12.5244 7.68933 12.788 7.42068 13.1244 7.40344L15.326 7.29066V7.60749C15.326 7.75622 15.2154 7.88343 15.0638 7.90907L14.534 7.99868V15.0022L13.8691 15.2309C13.3136 15.4219 12.6952 15.2174 12.3772 14.7376L9.12879 9.83568V14.5143L10.1287 14.7056L10.1147 14.7984C10.0711 15.0889 9.82028 15.3086 9.51687 15.3221L7.03006 15.4328C6.99718 15.1204 7.23132 14.8409 7.55431 14.807L7.88143 14.7726V8.53447L7.03006 8.48663Z",
"fill": "black"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M12.9218 1.85418L2.95217 2.53485C2.35499 2.57562 1.89209 3.05572 1.89209 3.63431V13.3311C1.89209 13.8748 2.07923 14.4029 2.42402 14.8325L4.57362 17.5104C4.92117 17.9433 5.46812 18.1817 6.03397 18.1469L17.0991 17.4658C17.6663 17.4309 18.1078 16.9761 18.1078 16.4269V5.4026C18.1078 5.06281 17.9362 4.74441 17.6481 4.54963L14.1453 2.18137C13.7883 1.94002 13.3564 1.82451 12.9218 1.85418ZM3.44654 3.78556C3.30788 3.6829 3.37387 3.46903 3.54806 3.45654L12.9889 2.77938C13.2897 2.75781 13.5886 2.84064 13.8318 3.01299L15.7261 4.35502C15.798 4.40597 15.7642 4.51596 15.6752 4.5208L5.67742 5.06454C5.37485 5.081 5.0762 4.99211 4.83563 4.814L3.44654 3.78556ZM5.20848 6.76913C5.20848 6.44433 5.47088 6.17604 5.80642 6.15777L16.3769 5.5821C16.7039 5.56429 16.9792 5.81577 16.9792 6.13232V15.6782C16.9792 16.0024 16.7177 16.2705 16.3829 16.2895L5.8793 16.8871C5.51537 16.9079 5.20848 16.6282 5.20848 16.2759V6.76913Z",
"fill": "black"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_5364_42310"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "20",
"height": "20",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "Notion"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Notion.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Notion'
export default Icon

View File

@@ -1,3 +1,4 @@
export { default as Dify } from './Dify'
export { default as Github } from './Github'
export { default as MessageChatSquare } from './MessageChatSquare'
export { default as Notion } from './Notion'

View File

@@ -0,0 +1,178 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "32",
"height": "34",
"viewBox": "0 0 32 34",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_3055_14424)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z",
"fill": "#EC5B27"
},
"children": []
}
]
},
{
"type": "element",
"name": "g",
"attributes": {
"opacity": "0.96"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M10.2704 24.0002V18.3042H8.87042V20.4962H7.38242V18.3042H5.98242V24.0002H7.38242V21.7442H8.87042V24.0002H10.2704Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M15.2839 19.5522V18.3042H11.0839V19.5522H12.4839V24.0002H13.8839V19.5522H15.2839Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M21.4116 24.0002V18.3042H20.0356L18.7556 20.8162L17.4756 18.3042H16.0996V24.0002H17.4996V21.2722L18.3076 22.6802H19.2036L20.0116 21.2722V24.0002H21.4116Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M26.3525 24.0002V22.7522H23.9605V18.3042H22.5605V24.0002H26.3525Z",
"fill": "white"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_3055_14424",
"x": "2",
"y": "0.333496",
"width": "28",
"height": "33.3335",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_3055_14424"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_3055_14424",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Html"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Html.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Html'
export default Icon

View File

@@ -0,0 +1,178 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "32",
"height": "34",
"viewBox": "0 0 32 34",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_3055_14428)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z",
"fill": "#2D2D2E"
},
"children": []
}
]
},
{
"type": "element",
"name": "g",
"attributes": {
"opacity": "0.96"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M9.83907 22.0479V18.3039H8.43907V22.0159C8.43907 22.5599 8.12707 22.7999 7.69507 22.7999C7.38307 22.7999 7.23907 22.6879 7.06307 22.5119L6.14307 23.4239C6.60707 23.8879 7.03107 24.0479 7.69507 24.0479C8.76707 24.0479 9.83907 23.3999 9.83907 22.0479Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M14.7321 22.2559C14.7321 21.7279 14.6121 21.3039 14.3081 21.0079C14.0681 20.7679 13.7001 20.6079 13.1881 20.5359L12.5001 20.4399C12.3001 20.4159 12.1801 20.3439 12.1081 20.2719C12.0201 20.1839 11.9961 20.0799 11.9961 20.0079C11.9961 19.7599 12.1961 19.4799 12.6841 19.4799C12.9321 19.4799 13.4041 19.4559 13.7641 19.8159L14.6441 18.9359C14.1561 18.4479 13.5401 18.2559 12.7241 18.2559C11.4281 18.2559 10.6441 19.0159 10.6441 20.0559C10.6441 20.5439 10.7721 20.9279 11.0361 21.1999C11.2921 21.4639 11.6761 21.6319 12.1801 21.7039L12.8681 21.7999C13.0521 21.8239 13.1721 21.8799 13.2441 21.9519C13.3241 22.0399 13.3561 22.1519 13.3561 22.2879C13.3561 22.6159 13.0921 22.7999 12.5401 22.7999C12.0841 22.7999 11.5641 22.6959 11.2681 22.3999L10.3721 23.2959C10.9481 23.8879 11.6601 24.0479 12.5321 24.0479C13.7321 24.0479 14.7321 23.4159 14.7321 22.2559Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M19.8023 21.1519C19.8023 20.2959 19.8263 19.4959 19.2263 18.8959C18.8103 18.4799 18.3303 18.2559 17.6343 18.2559C16.9383 18.2559 16.4583 18.4799 16.0423 18.8959C15.4423 19.4959 15.4663 20.2959 15.4663 21.1519C15.4663 22.0079 15.4423 22.8079 16.0423 23.4079C16.4583 23.8239 16.9383 24.0479 17.6343 24.0479C18.3303 24.0479 18.8103 23.8239 19.2263 23.4079C19.8263 22.8079 19.8023 22.0079 19.8023 21.1519ZM18.4023 21.1519C18.4023 22.1919 18.3223 22.3759 18.1943 22.5439C18.0903 22.6799 17.8903 22.7999 17.6343 22.7999C17.3783 22.7999 17.1783 22.6799 17.0743 22.5439C16.9463 22.3759 16.8663 22.1919 16.8663 21.1519C16.8663 20.1119 16.9463 19.9199 17.0743 19.7519C17.1783 19.6159 17.3783 19.5039 17.6343 19.5039C17.8903 19.5039 18.0903 19.6159 18.1943 19.7519C18.3223 19.9199 18.4023 20.1119 18.4023 21.1519Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M25.2154 23.9999V18.3039H23.8154V21.1679L21.9914 18.3039H20.7674V23.9999H22.1674V21.1359L23.9914 23.9999H25.2154Z",
"fill": "white"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_3055_14428",
"x": "2",
"y": "0.333496",
"width": "28",
"height": "33.3335",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_3055_14428"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_3055_14428",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Json"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Json.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Json'
export default Icon

View File

@@ -0,0 +1,169 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "32",
"height": "34",
"viewBox": "0 0 32 34",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_3055_14420)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z",
"fill": "#DD3633"
},
"children": []
}
]
},
{
"type": "element",
"name": "g",
"attributes": {
"opacity": "0.96"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M13.2801 20.1362C13.2801 19.2002 12.6001 18.3042 11.3361 18.3042H9.08008V24.0002H10.4801V21.9682H11.3361C12.6001 21.9682 13.2801 21.0722 13.2801 20.1362ZM11.8801 20.1362C11.8801 20.4322 11.6561 20.7122 11.2721 20.7122H10.4801V19.5602H11.2721C11.6561 19.5602 11.8801 19.8402 11.8801 20.1362Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M18.3357 21.1522C18.3357 20.2562 18.4077 19.5282 17.7437 18.8642C17.3517 18.4722 16.7997 18.3042 16.2077 18.3042H14.0957V24.0002H16.2077C16.7997 24.0002 17.3517 23.8322 17.7437 23.4402C18.4077 22.7762 18.3357 22.0482 18.3357 21.1522ZM16.9357 21.1522C16.9357 22.1202 16.8957 22.2722 16.7837 22.4322C16.6557 22.6242 16.4637 22.7522 16.1117 22.7522H15.4957V19.5522H16.1117C16.4637 19.5522 16.6557 19.6802 16.7837 19.8722C16.8957 20.0322 16.9357 20.1922 16.9357 21.1522Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M23.1786 19.5522V18.3042H19.3066V24.0002H20.7066V21.8002H22.8186V20.5522H20.7066V19.5522H23.1786Z",
"fill": "white"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_3055_14420",
"x": "2",
"y": "0.333496",
"width": "28",
"height": "33.3335",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_3055_14420"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_3055_14420",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Pdf"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Pdf.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Pdf'
export default Icon

View File

@@ -0,0 +1,180 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "32",
"height": "34",
"viewBox": "0 0 32 34",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_3055_14432)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z",
"fill": "#E3E5E8"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z",
"stroke": "black",
"stroke-opacity": "0.03",
"stroke-width": "0.5"
},
"children": []
}
]
},
{
"type": "element",
"name": "g",
"attributes": {
"opacity": "0.96"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M13.2254 19.5522V18.3042H9.02539V19.5522H10.4254V24.0002H11.8254V19.5522H13.2254Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M18.5371 24.0002L16.7611 21.0802L18.4251 18.3042H16.8331L16.0011 19.9122L15.1691 18.3042H13.5771L15.2411 21.0802L13.4651 24.0002H15.0651L16.0011 22.2482L16.9371 24.0002H18.5371Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M22.9754 19.5522V18.3042H18.7754V19.5522H20.1754V24.0002H21.5754V19.5522H22.9754Z",
"fill": "#667085"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_3055_14432",
"x": "2",
"y": "0.333496",
"width": "28",
"height": "33.3335",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_3055_14432"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_3055_14432",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Txt"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Txt.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Txt'
export default Icon

View File

@@ -0,0 +1,199 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "32",
"height": "34",
"viewBox": "0 0 32 34",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_3055_14436)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z",
"fill": "#E3E5E8"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z",
"stroke": "black",
"stroke-opacity": "0.03",
"stroke-width": "0.5"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M15.9998 23.1992C15.8014 23.1992 15.6039 23.1968 15.4077 23.1924V24.0549C15.4077 24.3819 15.6728 24.647 15.9998 24.647C16.3268 24.647 16.592 24.3819 16.592 24.0549V23.1924C16.3957 23.1968 16.1983 23.1992 15.9998 23.1992Z",
"fill": "#98A2B3"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M12.0984 22.8838L11.757 23.8593C11.649 24.168 11.8117 24.5058 12.1203 24.6138C12.185 24.6364 12.251 24.6472 12.3159 24.6472C12.5605 24.6472 12.7894 24.4944 12.8747 24.2505L13.2936 23.0534C12.8807 23.0073 12.481 22.9506 12.0984 22.8838Z",
"fill": "#98A2B3"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M20.2431 23.8593L19.9018 22.8838C19.5192 22.9506 19.1195 23.0073 18.7065 23.0534L19.1254 24.2505C19.2108 24.4944 19.4396 24.6472 19.6843 24.6472C19.7491 24.6472 19.8151 24.6364 19.8798 24.6138C20.1885 24.5058 20.3511 24.168 20.2431 23.8593Z",
"fill": "#98A2B3"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M20.1624 17.2634C20.2697 17.6416 20.3254 18.0369 20.3254 18.4409C20.3254 18.9087 20.05 19.3327 19.6226 19.5228C19.5564 19.5522 17.9801 20.2436 16.0359 20.2436C14.0917 20.2436 12.5153 19.5522 12.4492 19.5228C12.0218 19.3327 11.7464 18.9086 11.7464 18.4409C11.7464 18.0312 11.8037 17.6305 11.914 17.2476C10.3343 17.5645 8.5 18.2009 8.5 19.4464C8.5 20.2859 9.32512 20.9477 10.9525 21.4134C11.4194 21.547 11.9381 21.66 12.4949 21.7506C12.8783 21.813 13.28 21.8648 13.6953 21.9056C14.2455 21.9597 14.8197 21.9942 15.4079 22.0082C15.6039 22.0128 15.8013 22.0153 16 22.0153C16.1987 22.0153 16.3962 22.0128 16.5921 22.0082C17.1803 21.9943 17.7545 21.9596 18.3047 21.9056C18.72 21.8648 19.1217 21.8131 19.5051 21.7506C20.062 21.66 20.5807 21.547 21.0476 21.4134C22.6749 20.9477 23.5 20.2859 23.5 19.4464C23.5 18.2187 21.7108 17.5833 20.1624 17.2634Z",
"fill": "#98A2B3"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M18.8441 17.1144C18.7585 16.9335 18.6559 16.7622 18.5384 16.6025C18.4174 16.4382 18.2809 16.286 18.1307 16.1486C17.5784 15.6437 16.8433 15.3354 16.036 15.3354C15.2318 15.3354 14.499 15.6411 13.9476 16.1426C13.7974 16.2791 13.6609 16.4303 13.5399 16.5937C13.4217 16.753 13.3185 16.924 13.2322 17.1048C13.039 17.5095 12.9307 17.9624 12.9307 18.4407C12.9307 18.4407 14.321 19.0592 16.036 19.0592C17.751 19.0592 19.1412 18.4407 19.1412 18.4407C19.1412 17.9662 19.0344 17.5167 18.8441 17.1144Z",
"fill": "#98A2B3"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_3055_14436",
"x": "2",
"y": "0.333496",
"width": "28",
"height": "33.3335",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_3055_14436"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_3055_14436",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Unknow"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Unknow.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Unknow'
export default Icon

View File

@@ -0,0 +1,145 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "26",
"viewBox": "0 0 24 26",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"filter": "url(#filter0_d_5938_927)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M3 5.8C3 4.11984 3 3.27976 3.32698 2.63803C3.6146 2.07354 4.07354 1.6146 4.63803 1.32698C5.27976 1 6.11984 1 7.8 1H14L21 8V18.2C21 19.8802 21 20.7202 20.673 21.362C20.3854 21.9265 19.9265 22.3854 19.362 22.673C18.7202 23 17.8802 23 16.2 23H7.8C6.11984 23 5.27976 23 4.63803 22.673C4.07354 22.3854 3.6146 21.9265 3.32698 21.362C3 20.7202 3 19.8802 3 18.2V5.8Z",
"fill": "#169951"
},
"children": []
}
]
},
{
"type": "element",
"name": "path",
"attributes": {
"opacity": "0.5",
"d": "M14 1L21 8H16C14.8954 8 14 7.10457 14 6V1Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M17 12C17.5523 12 18 12.4477 18 13V18C18 18.5523 17.5523 19 17 19H7C6.44772 19 6 18.5523 6 18V13C6 12.4477 6.44772 12 7 12H17ZM11.5 13H7L7 15H11.5V13ZM12.5 18H17V16H12.5V18ZM11.5 16V18H7L7 16H11.5ZM12.5 15H17V13H12.5V15Z",
"fill": "white",
"fill-opacity": "0.96"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "filter",
"attributes": {
"id": "filter0_d_5938_927",
"x": "1",
"y": "0",
"width": "22",
"height": "26",
"filterUnits": "userSpaceOnUse",
"color-interpolation-filters": "sRGB"
},
"children": [
{
"type": "element",
"name": "feFlood",
"attributes": {
"flood-opacity": "0",
"result": "BackgroundImageFix"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"in": "SourceAlpha",
"type": "matrix",
"values": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",
"result": "hardAlpha"
},
"children": []
},
{
"type": "element",
"name": "feOffset",
"attributes": {
"dy": "1"
},
"children": []
},
{
"type": "element",
"name": "feGaussianBlur",
"attributes": {
"stdDeviation": "1"
},
"children": []
},
{
"type": "element",
"name": "feColorMatrix",
"attributes": {
"type": "matrix",
"values": "0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in2": "BackgroundImageFix",
"result": "effect1_dropShadow_5938_927"
},
"children": []
},
{
"type": "element",
"name": "feBlend",
"attributes": {
"mode": "normal",
"in": "SourceGraphic",
"in2": "effect1_dropShadow_5938_927",
"result": "shape"
},
"children": []
}
]
}
]
}
]
},
"name": "Xlsx"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Xlsx.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Xlsx'
export default Icon

View File

@@ -1,2 +1,8 @@
export { default as Csv } from './Csv'
export { default as Html } from './Html'
export { default as Json } from './Json'
export { default as Md } from './Md'
export { default as Pdf } from './Pdf'
export { default as Txt } from './Txt'
export { default as Unknow } from './Unknow'
export { default as Xlsx } from './Xlsx'

View File

@@ -11,4 +11,6 @@ const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseP
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Localai'
export default Icon

View File

@@ -11,4 +11,6 @@ const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseP
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'LocalaiText'
export default Icon

View File

@@ -0,0 +1,38 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "bezier-curve-03"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M5.42857 3.5L2.57143 8.5M3 9.5H8.9999M9.42857 8.5L6.57143 3.5M1.8 10.5H2.2C2.48003 10.5 2.62004 10.5 2.727 10.4455C2.82108 10.3976 2.89757 10.3211 2.9455 10.227C3 10.12 3 9.98003 3 9.7V9.3C3 9.01997 3 8.87996 2.9455 8.773C2.89757 8.67892 2.82108 8.60243 2.727 8.5545C2.62004 8.5 2.48003 8.5 2.2 8.5H1.8C1.51997 8.5 1.37996 8.5 1.273 8.5545C1.17892 8.60243 1.10243 8.67892 1.0545 8.773C1 8.87996 1 9.01997 1 9.3V9.7C1 9.98003 1 10.12 1.0545 10.227C1.10243 10.3211 1.17892 10.3976 1.273 10.4455C1.37996 10.5 1.51997 10.5 1.8 10.5ZM9.8 10.5H10.2C10.48 10.5 10.62 10.5 10.727 10.4455C10.8211 10.3976 10.8976 10.3211 10.9455 10.227C11 10.12 11 9.98003 11 9.7V9.3C11 9.01997 11 8.87996 10.9455 8.773C10.8976 8.67892 10.8211 8.60243 10.727 8.5545C10.62 8.5 10.48 8.5 10.2 8.5H9.8C9.51997 8.5 9.37996 8.5 9.273 8.5545C9.17892 8.60243 9.10243 8.67892 9.0545 8.773C9 8.87996 9 9.01997 9 9.3V9.7C9 9.98003 9 10.12 9.0545 10.227C9.10243 10.3211 9.17892 10.3976 9.273 10.4455C9.37996 10.5 9.51997 10.5 9.8 10.5ZM5.8 3.5H6.2C6.48003 3.5 6.62004 3.5 6.727 3.4455C6.82108 3.39757 6.89757 3.32108 6.9455 3.227C7 3.12004 7 2.98003 7 2.7V2.3C7 2.01997 7 1.87996 6.9455 1.773C6.89757 1.67892 6.82108 1.60243 6.727 1.5545C6.62004 1.5 6.48003 1.5 6.2 1.5H5.8C5.51997 1.5 5.37996 1.5 5.273 1.5545C5.17892 1.60243 5.10243 1.67892 5.0545 1.773C5 1.87996 5 2.01997 5 2.3V2.7C5 2.98003 5 3.12004 5.0545 3.227C5.10243 3.32108 5.17892 3.39757 5.273 3.4455C5.37996 3.5 5.51997 3.5 5.8 3.5Z",
"stroke": "currentColor",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "BezierCurve03"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './BezierCurve03.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'BezierCurve03'
export default Icon

View File

@@ -0,0 +1,38 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "type-square"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M4 3.5H8M6 3.5V8.5M3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V3.9C10.5 3.05992 10.5 2.63988 10.3365 2.31901C10.1927 2.03677 9.96323 1.8073 9.68099 1.66349C9.36012 1.5 8.94008 1.5 8.1 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5Z",
"stroke": "currentColor",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "TypeSquare"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './TypeSquare.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'TypeSquare'
export default Icon

View File

@@ -0,0 +1,2 @@
export { default as BezierCurve03 } from './BezierCurve03'
export { default as TypeSquare } from './TypeSquare'

View File

@@ -0,0 +1,65 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "Left Icon",
"clip-path": "url(#clip0_10386_42171)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M7.99998 4V2.5L9.49998 1L9.99998 2L11 2.5L9.49998 4H7.99998ZM7.99998 4L5.99999 5.99997M11 6C11 8.76142 8.76142 11 6 11C3.23858 11 1 8.76142 1 6C1 3.23858 3.23858 1 6 1M8.5 6C8.5 7.38071 7.38071 8.5 6 8.5C4.61929 8.5 3.5 7.38071 3.5 6C3.5 4.61929 4.61929 3.5 6 3.5",
"stroke": "currentColor",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_10386_42171"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "12",
"height": "12",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "Target04"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Target04.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Target04'
export default Icon

View File

@@ -12,6 +12,7 @@ export { default as LogOut01 } from './LogOut01'
export { default as Pin02 } from './Pin02'
export { default as Plus } from './Plus'
export { default as SearchLg } from './SearchLg'
export { default as Target04 } from './Target04'
export { default as Trash03 } from './Trash03'
export { default as XClose } from './XClose'
export { default as X } from './X'

View File

@@ -0,0 +1,36 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "citations"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Subtract",
"d": "M0.666992 7.99996C0.666992 3.94987 3.95024 0.666626 8.00033 0.666626C12.0504 0.666626 15.3337 3.94987 15.3337 7.99996C15.3337 12.05 12.0504 15.3333 8.00033 15.3333C3.95024 15.3333 0.666992 12.05 0.666992 7.99996ZM4.66699 7.9801V9.97196H7.35742V7.48922H5.87533C5.85644 7.21231 5.90365 6.94484 6.01693 6.68681C6.2372 6.19592 6.66829 5.84979 7.31022 5.6484V4.66663C6.44803 4.83655 5.79036 5.19527 5.33724 5.7428C4.89041 6.29032 4.66699 7.03609 4.66699 7.9801ZM10.0264 6.70569C10.2466 6.19592 10.6746 5.84349 11.3102 5.6484V4.66663C10.4732 4.83655 9.82183 5.19212 9.35612 5.73336C8.8967 6.27459 8.66699 7.02351 8.66699 7.9801V9.97196H11.3574V7.48922H9.87533C9.85015 7.23748 9.9005 6.9763 10.0264 6.70569Z",
"fill": "currentColor"
},
"children": []
}
]
}
]
},
"name": "Citations"
}

View File

@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Citations.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Citations'
export default Icon

View File

@@ -1 +1,2 @@
export { default as Brush01 } from './Brush01'
export { default as Citations } from './Citations'

View File

@@ -10,17 +10,26 @@ import type { RefObject } from 'react'
import { useEffect, useRef, useState } from 'react'
import CopyBtn from '@/app/components/app/chat/copy-btn'
// import { copyToClipboard } from "../utils";
// https://txtfiddle.com/~hlshwya/extract-urls-from-text
// const urlRegex = /\b((https?|ftp|file):\/\/|(www|ftp)\.)[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/ig
// Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD
const capitalizationLanguageNameMap: Record<string, string> = {
sql: 'SQL',
javascript: 'JavaScript',
typescript: 'TypeScript',
vbscript: 'VBScript',
css: 'CSS',
html: 'HTML',
xml: 'XML',
php: 'PHP',
}
const getCorrectCapitalizationLanguageName = (language: string) => {
if (!language)
return 'Plain'
// function highlightURL(content: string) {
// return content.replace(urlRegex, (url) => {
// // fix http:// in [] will be parsed to link agin
// const res = `[${url.replace('://', ':&#47;&#47;')}](${url})`
// return res
// })
// }
if (language in capitalizationLanguageNameMap)
return capitalizationLanguageNameMap[language]
return language.charAt(0).toUpperCase() + language.substring(1)
}
export function PreCode(props: { children: any }) {
const ref = useRef<HTMLPreElement>(null)
@@ -75,12 +84,7 @@ export function Markdown(props: { content: string }) {
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
const language = match?.[1]
const languageShowName = (() => {
if (language)
return language.charAt(0).toUpperCase() + language.substring(1)
return 'Plain'
})()
const languageShowName = getCorrectCapitalizationLanguageName(language || '')
return (!inline && match)
? (
<div>

View File

@@ -2,9 +2,14 @@ import { Popover, Transition } from '@headlessui/react'
import { Fragment, cloneElement, useRef } from 'react'
import s from './style.module.css'
export type HtmlContentProps = {
onClose?: () => void
onClick?: () => void
}
type IPopover = {
className?: string
htmlContent: React.ReactNode
htmlContent: React.ReactElement<HtmlContentProps>
trigger?: 'click' | 'hover'
position?: 'bottom' | 'br'
btnElement?: string | React.ReactNode
@@ -84,7 +89,7 @@ export default function CustomPopover({
})
}
>
{cloneElement(htmlContent as React.ReactElement, {
{cloneElement(htmlContent as React.ReactElement<HtmlContentProps>, {
onClose: () => onMouseLeave(open),
...(manualClose
? {

View File

@@ -15,7 +15,7 @@ import {
useRole,
} from '@floating-ui/react'
import type { Placement } from '@floating-ui/react'
import type { OffsetOptions, Placement } from '@floating-ui/react'
type PortalToFollowElemOptions = {
/*
@@ -25,7 +25,7 @@ type PortalToFollowElemOptions = {
*/
placement?: Placement
open?: boolean
offset?: number
offset?: number | OffsetOptions
onOpenChange?: (open: boolean) => void
}

View File

@@ -304,7 +304,7 @@ const Completed: FC<ICompletedProps> = ({
setAllSegments([...allSegments])
}
else {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}
@@ -315,7 +315,7 @@ const Completed: FC<ICompletedProps> = ({
resetList()
}
else {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}

View File

@@ -206,7 +206,7 @@ const EmbeddingDetail: FC<Props> = ({ detail, stopPosition = 'top', datasetId: d
setIndexingStatusDetail(null)
}
else {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}

View File

@@ -292,7 +292,7 @@ const Metadata: FC<IMetadataProps> = ({ docDetail, loading, onUpdate }) => {
if (!e)
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
else
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
onUpdate?.()
setEditStatus(false)
setSaveLoading(false)

View File

@@ -150,7 +150,7 @@ export const OperationAction: FC<{
if (!e)
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
else
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
onUpdate(operationName)
}

View File

@@ -70,7 +70,7 @@ const Form = ({
await mutateDatasets()
}
catch (e) {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
finally {
setLoading(false)

View File

@@ -11,7 +11,7 @@ import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigge
export type IItemOperationProps = {
className?: string
isItemHovering: boolean
isItemHovering?: boolean
isPinned: boolean
isShowRenameConversation?: boolean
onRenameConversation?: () => void

Some files were not shown because too many files have changed in this diff Show More