removing build again

This commit is contained in:
Ali Abid 2020-12-01 11:46:23 -08:00
parent 70b50f37db
commit 01ebc24df9
124 changed files with 0 additions and 73380 deletions

View File

@ -1,5 +0,0 @@
from gradio.interface import * # This makes it possible to import `Interface` as `gradio.Interface`.
import pkg_resources
current_pkg_version = pkg_resources.require("gradio")[0].version
__version__ = current_pkg_version

View File

@ -1,34 +0,0 @@
class Component():
"""
A class for defining the methods that all gradio input and output components should have.
"""
def __init__(self, label):
self.label = label
def get_template_context(self):
"""
:return: a dictionary with context variables for the javascript file associated with the context
"""
return {"label": self.label}
@classmethod
def get_shortcut_implementations(cls):
"""
Return dictionary of shortcut implementations
"""
return {}
def rebuild(self, dir, data):
"""
All interfaces should define a method that rebuilds the flagged input when it's passed back (i.e. rebuilds image from base64)
"""
return data
@classmethod
def get_all_shortcut_implementations(cls):
shortcuts = {}
for sub_cls in cls.__subclasses__():
for shortcut, parameters in sub_cls.get_shortcut_implementations().items():
shortcuts[shortcut] = (sub_cls, parameters)
return shortcuts

View File

@ -1,28 +0,0 @@
import numpy as np
from sklearn.decomposition import PCA
SMALL_CONST = 1e-10
def calculate_similarity(embedding1, embedding2):
"""
Scores the similarity between two embeddings by taking the cosine similarity
"""
e1, e2 = np.array(embedding1), np.array(embedding2)
cosine_similarity = np.dot(e1, e2) / (np.linalg.norm(e1) * np.linalg.norm(e2) + SMALL_CONST)
return cosine_similarity
def fit_pca_to_embeddings(embeddings):
"""
Computes 2D tsne embeddings from a list of higher-dimensional embeddings
"""
pca_model = PCA(n_components=2, random_state=0)
embeddings = np.array(embeddings)
embeddings_2D = pca_model.fit_transform(embeddings)
return pca_model, [{'x': e[0], 'y': e[1]} for e in embeddings_2D.tolist()]
def transform_with_pca(pca_model, embeddings):
"""
Computes 2D tsne embeddings from a list of higher-dimensional embeddings
"""
embeddings_2D = pca_model.transform(embeddings)
return [{'x': e[0], 'y': e[1]} for e in embeddings_2D.tolist()]

File diff suppressed because one or more lines are too long

View File

@ -1,471 +0,0 @@
"""
This is the core file in the `gradio` package, and defines the Interface class, including methods for constructing the
interface using the input and output types.
"""
from gradio.inputs import InputComponent
from gradio.outputs import OutputComponent
from gradio import networking, strings, utils
from gradio.interpretation import quantify_difference_in_label
import requests
import random
import time
import webbrowser
import inspect
import sys
import weakref
import analytics
import numpy as np
import os
import copy
analytics.write_key = "uxIFddIEuuUcFLf9VgH2teTEtPlWdkNy"
analytics_url = 'https://api.gradio.app/'
ip_address = networking.get_local_ip_address()
class Interface:
"""
Interfaces are created with Gradio using the `gradio.Interface()` function.
"""
instances = weakref.WeakSet()
@classmethod
def get_instances(cls):
"""
:return: list of all current instances.
"""
return list(
Interface.instances)
def __init__(self, fn, inputs, outputs, verbose=False, examples=None,
examples_per_page=10, live=False,
layout="horizontal", show_input=True, show_output=True,
capture_session=False, interpretation=None,
title=None, description=None, thumbnail=None,
server_port=None, server_name=networking.LOCALHOST_NAME,
allow_screenshot=True, allow_flagging=True,
embedding="default", flagging_dir="flagged", analytics_enabled=True):
"""
Parameters:
fn (Callable): the function to wrap an interface around.
inputs (Union[str, List[Union[str, InputComponent]]]): a single Gradio input component, or list of Gradio input components. Components can either be passed as instantiated objects, or referred to by their string shortcuts. The number of input components should match the number of parameters in fn.
outputs (Union[str, List[Union[str, OutputComponent]]]): a single Gradio output component, or list of Gradio output components. Components can either be passed as instantiated objects, or referred to by their string shortcuts. The number of output components should match the number of values returned by fn.
verbose (bool): whether to print detailed information during launch.
examples (List[List[Any]]): sample inputs for the function; if provided, appears below the UI components and can be used to populate the interface. Should be nested list, in which the outer list consists of samples and each inner list consists of an input corresponding to each input component.
examples_per_page (int): If examples are provided, how many to display per page.
live (bool): whether the interface should automatically reload on change.
layout (str): Layout of input and output panels. "horizontal" arranges them as two columns of equal height, "unaligned" arranges them as two columns of unequal height, and "vertical" arranges them vertically.
capture_session (bool): if True, captures the default graph and session (needed for Tensorflow 1.x)
interpretation (Union[Callable, str]): function that provides interpretation explaining prediction output. Pass "default" to use built-in interpreter.
title (str): a title for the interface; if provided, appears above the input and output components.
description (str): a description for the interface; if provided, appears above the input and output components.
thumbnail (str): path to image or src to use as display picture for models listed in gradio.app/hub
server_name (str): to make app accessible on local network set to "0.0.0.0".
allow_screenshot (bool): if False, users will not see a button to take a screenshot of the interface.
allow_flagging (bool): if False, users will not see a button to flag an input and output.
flagging_dir (str): what to name the dir where flagged data is stored.
"""
def get_input_instance(iface):
if isinstance(iface, str):
shortcut = InputComponent.get_all_shortcut_implementations()[iface]
return shortcut[0](**shortcut[1])
elif isinstance(iface, InputComponent):
return iface
else:
raise ValueError("Input interface must be of type `str` or "
"`InputComponent`")
def get_output_instance(iface):
if isinstance(iface, str):
shortcut = OutputComponent.get_all_shortcut_implementations()[iface]
return shortcut[0](**shortcut[1])
elif isinstance(iface, OutputComponent):
return iface
else:
raise ValueError(
"Output interface must be of type `str` or "
"`OutputComponent`"
)
if isinstance(inputs, list):
self.input_interfaces = [get_input_instance(i) for i in inputs]
else:
self.input_interfaces = [get_input_instance(inputs)]
if isinstance(outputs, list):
self.output_interfaces = [get_output_instance(i) for i in outputs]
else:
self.output_interfaces = [get_output_instance(outputs)]
if not isinstance(fn, list):
fn = [fn]
self.output_interfaces *= len(fn)
self.predict = fn
self.verbose = verbose
self.status = "OFF"
self.live = live
self.layout = layout
self.show_input = show_input
self.show_output = show_output
self.flag_hash = random.getrandbits(32)
self.capture_session = capture_session
self.interpretation = interpretation
self.session = None
self.server_name = server_name
self.title = title
self.description = description
self.thumbnail = thumbnail
self.examples = examples
self.examples_per_page = examples_per_page
self.server_port = server_port
self.simple_server = None
self.allow_screenshot = allow_screenshot
self.allow_flagging = allow_flagging
self.flagging_dir = flagging_dir
Interface.instances.add(self)
self.analytics_enabled=analytics_enabled
self.save_to = None
self.share = None
self.embedding = embedding
data = {'fn': fn,
'inputs': inputs,
'outputs': outputs,
'live': live,
'capture_session': capture_session,
'ip_address': ip_address,
'interpretation': interpretation,
'embedding': embedding,
'allow_flagging': allow_flagging,
'allow_screenshot': allow_screenshot,
}
if self.capture_session:
try:
import tensorflow as tf
self.session = tf.get_default_graph(), \
tf.keras.backend.get_session()
except (ImportError, AttributeError):
# If they are using TF >= 2.0 or don't have TF,
# just ignore this.
pass
if self.allow_flagging:
if self.title is not None:
dir_name = "_".join(self.title.split(" "))
else:
dir_name = "_".join([fn.__name__ for fn in self.predict])
index = 1
while os.path.exists(self.flagging_dir + "/" + dir_name +
"_{}".format(index)):
index += 1
self.flagging_dir = self.flagging_dir + "/" + dir_name + \
"_{}".format(index)
if self.analytics_enabled:
try:
requests.post(analytics_url + 'gradio-initiated-analytics/',
data=data)
except requests.ConnectionError:
pass # do not push analytics if no network
def get_config_file(self):
config = {
"input_interfaces": [
(iface.__class__.__name__.lower(), iface.get_template_context())
for iface in self.input_interfaces],
"output_interfaces": [
(iface.__class__.__name__.lower(), iface.get_template_context())
for iface in self.output_interfaces],
"function_count": len(self.predict),
"live": self.live,
"examples_per_page": self.examples_per_page,
"layout": self.layout,
"show_input": self.show_input,
"show_output": self.show_output,
"title": self.title,
"description": self.description,
"thumbnail": self.thumbnail,
"allow_screenshot": self.allow_screenshot,
"allow_flagging": self.allow_flagging,
"allow_interpretation": self.interpretation is not None
}
try:
param_names = inspect.getfullargspec(self.predict[0])[0]
for iface, param in zip(config["input_interfaces"], param_names):
if not iface[1]["label"]:
iface[1]["label"] = param.replace("_", " ")
for i, iface in enumerate(config["output_interfaces"]):
ret_name = "Output " + str(i + 1) if len(config["output_interfaces"]) > 1 else "Output"
if not iface[1]["label"]:
iface[1]["label"] = ret_name
except ValueError:
pass
if self.examples is not None:
processed_examples = []
for example_set in self.examples:
processed_set = []
for iface, example in zip(self.input_interfaces, example_set):
processed_set.append(example)
processed_examples.append(processed_set)
config["examples"] = processed_examples
return config
def run_prediction(self, processed_input, return_duration=False):
predictions = []
durations = []
for predict_fn in self.predict:
start = time.time()
if self.capture_session and self.session is not None:
graph, sess = self.session
with graph.as_default(), sess.as_default():
prediction = predict_fn(*processed_input)
else:
try:
prediction = predict_fn(*processed_input)
except ValueError as exception:
if str(exception).endswith("is not an element of this graph."):
raise ValueError(strings.en["TF1_ERROR"])
else:
raise exception
duration = time.time() - start
if len(self.output_interfaces) == len(self.predict):
prediction = [prediction]
durations.append(duration)
predictions.extend(prediction)
if return_duration:
return predictions, durations
else:
return predictions
def process(self, raw_input):
"""
:param raw_input: a list of raw inputs to process and apply the prediction(s) on.
processed output: a list of processed outputs to return as the prediction(s).
duration: a list of time deltas measuring inference time for each prediction fn.
"""
processed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(self.input_interfaces)]
predictions, durations = self.run_prediction(processed_input, return_duration=True)
processed_output = [output_interface.postprocess(
predictions[i]) for i, output_interface in enumerate(self.output_interfaces)]
return processed_output, durations
def embed(self, processed_input):
if self.embedding == "default":
embeddings = np.concatenate([input_interface.embed(processed_input[i])
for i, input_interface in enumerate(self.input_interfaces)])
else:
embeddings = self.embedding(*processed_input)
return embeddings
def interpret(self, raw_input):
"""
Runs the interpretation command for the machine learning model. Handles both the "default" out-of-the-box
interpretation for a certain set of UI component types, as well as the custom interpretation case.
:param raw_input: a list of raw inputs to apply the interpretation(s) on.
"""
if self.interpretation == "default":
processed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(self.input_interfaces)]
original_output = self.run_prediction(processed_input)
scores, alternative_outputs = [], []
for i, x in enumerate(raw_input):
input_interface = self.input_interfaces[i]
neighbor_raw_input = list(raw_input)
neighbor_values, interpret_kwargs, interpret_by_removal = input_interface.get_interpretation_neighbors(x)
interface_scores = []
alternative_output = []
for neighbor_input in neighbor_values:
neighbor_raw_input[i] = neighbor_input
processed_neighbor_input = [input_interface.preprocess(neighbor_raw_input[i])
for i, input_interface in enumerate(self.input_interfaces)]
neighbor_output = self.run_prediction(processed_neighbor_input)
processed_neighbor_output = [output_interface.postprocess(
neighbor_output[i]) for i, output_interface in enumerate(self.output_interfaces)]
alternative_output.append(processed_neighbor_output)
interface_scores.append(quantify_difference_in_label(self, original_output, neighbor_output))
alternative_outputs.append(alternative_output)
if not interpret_by_removal:
interface_scores = [-score for score in interface_scores]
scores.append(
input_interface.get_interpretation_scores(
raw_input[i], neighbor_values, interface_scores, **interpret_kwargs))
return scores, alternative_outputs
else:
processed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(self.input_interfaces)]
interpreter = self.interpretation
if self.capture_session and self.session is not None:
graph, sess = self.session
with graph.as_default(), sess.as_default():
interpretation = interpreter(*processed_input)
else:
try:
interpretation = interpreter(*processed_input)
except ValueError as exception:
if str(exception).endswith("is not an element of this graph."):
raise ValueError(strings.en["TF1_ERROR"])
else:
raise exception
if len(raw_input) == 1:
interpretation = [interpretation]
return interpretation, []
def close(self):
if self.simple_server and not (self.simple_server.fileno() == -1): # checks to see if server is running
print("Closing Gradio server on port {}...".format(self.server_port))
networking.close_server(self.simple_server)
def run_until_interrupted(self, thread, path_to_local_server):
try:
while 1:
pass
except (KeyboardInterrupt, OSError):
print("Keyboard interruption in main thread... closing server.")
thread.keep_running = False
networking.url_ok(path_to_local_server) # Hit the server one more time to close it
def test_launch(self):
for predict_fn in self.predict:
print("Test launch: {}()...".format(predict_fn.__name__), end=' ')
raw_input = []
for input_interface in self.input_interfaces:
if input_interface.test_input is None: # If no test input is defined for that input interface
print("SKIPPED")
break
else: # If a test input is defined for each interface object
raw_input.append(input_interface.test_input)
else:
self.process(raw_input)
print("PASSED")
continue
def launch(self, inline=None, inbrowser=None, share=False, debug=False):
"""
Parameters:
inline (bool): whether to display in the interface inline on python notebooks.
inbrowser (bool): whether to automatically launch the interface in a new tab on the default browser.
share (bool): whether to create a publicly shareable link from your computer for the interface.
debug (bool): if True, and the interface was launched from Google Colab, prints the errors in the cell output.
Returns:
app (flask.Flask): Flask app object
path_to_local_server (str): Locally accessible link
share_url (str): Publicly accessible link (if share=True)
"""
config = self.get_config_file()
networking.set_config(config)
networking.set_meta_tags(self.title, self.description, self.thumbnail)
server_port, app, thread = networking.start_server(
self, self.server_name, self.server_port)
path_to_local_server = "http://{}:{}/".format(self.server_name, server_port)
self.server_port = server_port
self.status = "RUNNING"
self.server = app
utils.version_check()
is_colab = utils.colab_check()
if is_colab:
share = True
if not is_colab:
if not networking.url_ok(path_to_local_server):
share = True
else:
print(strings.en["RUNNING_LOCALLY"].format(path_to_local_server))
else:
if debug:
print("Colab notebook detected. This cell will run indefinitely so that you can see errors and logs. "
"To turn off, set debug=False in launch().")
else:
print("Colab notebook detected. To show errors in colab notebook, set debug=True in launch()")
self.share = share
if share:
print("This share link will expire in 24 hours. If you need a "
"permanent link, email support@gradio.app")
try:
share_url = networking.setup_tunnel(server_port)
print("Running on External URL:", share_url)
except RuntimeError:
data = {'error': 'RuntimeError in launch method'}
if self.analytics_enabled:
try:
requests.post(analytics_url + 'gradio-error-analytics/',
data=data)
except requests.ConnectionError:
pass # do not push analytics if no network
share_url = None
if self.verbose:
print(strings.en["NGROK_NO_INTERNET"])
else:
print("To get a public link for a hosted model, "
"set Share=True")
if self.verbose:
print(strings.en["PUBLIC_SHARE_TRUE"])
share_url = None
if inline is None:
inline = utils.ipython_check()
if inbrowser is None:
# if interface won't appear inline, open it in new tab,
# otherwise keep it inline
inbrowser = not inline
else:
if inbrowser is None:
inbrowser = False
if inbrowser and not is_colab:
webbrowser.open(path_to_local_server) # Open a browser tab
# with the interface.
if inline:
from IPython.display import IFrame, display
# Embed the remote interface page if on google colab;
# otherwise, embed the local page.
print("Interface loading below...")
if share:
while not networking.url_ok(share_url):
time.sleep(1)
display(IFrame(share_url, width=1000, height=500))
else:
display(IFrame(path_to_local_server, width=1000, height=500))
r = requests.get(path_to_local_server + "enable_sharing/" + (share_url or "None"))
if debug or int(os.getenv('GRADIO_DEBUG',0))==1:
while True:
sys.stdout.flush()
time.sleep(0.1)
launch_method = 'browser' if inbrowser else 'inline'
if self.analytics_enabled:
data = {
'launch_method': launch_method,
'is_google_colab': is_colab,
'is_sharing_on': share,
'share_url': share_url,
'ip_address': ip_address
}
try:
requests.post(analytics_url + 'gradio-launched-analytics/',
data=data)
except requests.ConnectionError:
pass # do not push analytics if no network
is_in_interactive_mode = bool(getattr(sys, 'ps1', sys.flags.interactive))
if not is_in_interactive_mode:
self.run_until_interrupted(thread, path_to_local_server)
return app, path_to_local_server, share_url
def reset_all():
for io in Interface.get_instances():
io.close()

View File

@ -1,30 +0,0 @@
from gradio.outputs import Label, Textbox
def diff(original, perturbed):
try: # try computing numerical difference
score = float(original) - float(perturbed)
except ValueError: # otherwise, look at strict difference in label
score = int(not(original == perturbed))
return score
def quantify_difference_in_label(interface, original_output, perturbed_output):
output_interface = interface.output_interfaces[0]
post_original_output = output_interface.postprocess(original_output[0])
post_perturbed_output = output_interface.postprocess(perturbed_output[0])
if type(output_interface) == Label:
original_label = post_original_output["label"]
perturbed_label = post_perturbed_output["label"]
# Handle different return types of Label interface
if "confidences" in post_original_output:
original_confidence = original_output[0][original_label]
perturbed_confidence = perturbed_output[0][original_label]
score = original_confidence - perturbed_confidence
else:
score = diff(original_label, perturbed_label)
return score
elif type(output_interface) == Textbox:
score = diff(post_original_output, post_perturbed_output)
return score

View File

@ -1,308 +0,0 @@
"""
Defines helper methods useful for setting up ports, launching servers, and handling `ngrok`
"""
import os
import socket
import threading
from flask import Flask, request, jsonify, abort, send_file, render_template
from flask_cachebuster import CacheBuster
from flask_cors import CORS
import threading
import pkg_resources
from distutils import dir_util
import time
import json
import urllib.request
from shutil import copyfile
import requests
import sys
import csv
import logging
import gradio as gr
from gradio.embeddings import calculate_similarity, fit_pca_to_embeddings, transform_with_pca
from gradio.tunneling import create_tunnel
INITIAL_PORT_VALUE = int(os.getenv(
'GRADIO_SERVER_PORT', "7860")) # The http server will try to open on port 7860. If not available, 7861, 7862, etc.
TRY_NUM_PORTS = int(os.getenv(
'GRADIO_NUM_PORTS', "100")) # Number of ports to try before giving up and throwing an exception.
LOCALHOST_NAME = os.getenv(
'GRADIO_SERVER_NAME', "127.0.0.1")
GRADIO_API_SERVER = "https://api.gradio.app/v1/tunnel-request"
GRADIO_FEATURE_ANALYTICS_URL = "https://api.gradio.app/gradio-feature-analytics/"
STATIC_TEMPLATE_LIB = pkg_resources.resource_filename("gradio", "templates/")
STATIC_PATH_LIB = pkg_resources.resource_filename("gradio", "static/")
GRADIO_STATIC_ROOT = "https://gradio.app"
app = Flask(__name__,
template_folder=STATIC_TEMPLATE_LIB,
static_folder=STATIC_PATH_LIB,
static_url_path="/static/")
CORS(app)
cache_buster = CacheBuster(config={'extensions': ['.js', '.css'], 'hash_size': 5})
cache_buster.init_app(app)
app.app_globals = {}
# Hide Flask default message
cli = sys.modules['flask.cli']
cli.show_server_banner = lambda *x: None
def set_meta_tags(title, description, thumbnail):
app.app_globals.update({
"title": title,
"description": description,
"thumbnail": thumbnail
})
def set_config(config):
app.app_globals["config"] = config
def get_local_ip_address():
try:
ip_address = requests.get('https://api.ipify.org').text
except requests.ConnectionError:
ip_address = "No internet connection"
return ip_address
IP_ADDRESS = get_local_ip_address()
def get_first_available_port(initial, final):
"""
Gets the first open port in a specified range of port numbers
:param initial: the initial value in the range of port numbers
:param final: final (exclusive) value in the range of port numbers, should be greater than `initial`
:return:
"""
for port in range(initial, final):
try:
s = socket.socket() # create a socket object
s.bind((LOCALHOST_NAME, port)) # Bind to the port
s.close()
return port
except OSError:
pass
raise OSError(
"All ports from {} to {} are in use. Please close a port.".format(
initial, final
)
)
@app.route("/", methods=["GET"])
def main():
return render_template("index.html",
title=app.app_globals["title"],
description=app.app_globals["description"],
thumbnail=app.app_globals["thumbnail"],
vendor_prefix=(GRADIO_STATIC_ROOT if app.interface.share else "")
)
@app.route("/config/", methods=["GET"])
def config():
return jsonify(app.app_globals["config"])
@app.route("/enable_sharing/<path:path>", methods=["GET"])
def enable_sharing(path):
if path == "None":
path = None
app.app_globals["config"]["share_url"] = path
return jsonify(success=True)
@app.route("/api/predict/", methods=["POST"])
def predict():
raw_input = request.json["data"]
prediction, durations = app.interface.process(raw_input)
output = {"data": prediction, "durations": durations}
return jsonify(output)
def log_feature_analytics(feature):
if app.interface.analytics_enabled:
try:
requests.post(GRADIO_FEATURE_ANALYTICS_URL,
data={
'ip_address': IP_ADDRESS,
'feature': feature})
except requests.ConnectionError:
pass # do not push analytics if no network
@app.route("/api/score_similarity/", methods=["POST"])
def score_similarity():
raw_input = request.json["data"]
preprocessed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(app.interface.input_interfaces)]
input_embedding = app.interface.embed(preprocessed_input)
scores = list()
for example in app.interface.examples:
preprocessed_example = [iface.preprocess(iface.preprocess_example(example))
for iface, example in zip(app.interface.input_interfaces, example)]
example_embedding = app.interface.embed(preprocessed_example)
scores.append(calculate_similarity(input_embedding, example_embedding))
log_feature_analytics('score_similarity')
return jsonify({"data": scores})
@app.route("/api/view_embeddings/", methods=["POST"])
def view_embeddings():
sample_embedding = []
if "data" in request.json:
raw_input = request.json["data"]
preprocessed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(app.interface.input_interfaces)]
sample_embedding.append(app.interface.embed(preprocessed_input))
example_embeddings = []
for example in app.interface.examples:
preprocessed_example = [iface.preprocess(iface.preprocess_example(example))
for iface, example in zip(app.interface.input_interfaces, example)]
example_embedding = app.interface.embed(preprocessed_example)
example_embeddings.append(example_embedding)
pca_model, embeddings_2d = fit_pca_to_embeddings(sample_embedding + example_embeddings)
sample_embedding_2d = embeddings_2d[:len(sample_embedding)]
example_embeddings_2d = embeddings_2d[len(sample_embedding):]
app.pca_model = pca_model
log_feature_analytics('view_embeddings')
return jsonify({"sample_embedding_2d": sample_embedding_2d, "example_embeddings_2d": example_embeddings_2d})
@app.route("/api/update_embeddings/", methods=["POST"])
def update_embeddings():
sample_embedding, sample_embedding_2d = [], []
if "data" in request.json:
raw_input = request.json["data"]
preprocessed_input = [input_interface.preprocess(raw_input[i])
for i, input_interface in enumerate(app.interface.input_interfaces)]
sample_embedding.append(app.interface.embed(preprocessed_input))
sample_embedding_2d = transform_with_pca(app.pca_model, sample_embedding)
return jsonify({"sample_embedding_2d": sample_embedding_2d})
@app.route("/api/predict_examples/", methods=["POST"])
def predict_examples():
example_ids = request.json["data"]
predictions_set = {}
for example_id in example_ids:
example_set = app.interface.examples[example_id]
processed_example_set = [iface.preprocess_example(example)
for iface, example in zip(app.interface.input_interfaces, example_set)]
try:
predictions, _ = app.interface.process(processed_example_set)
except:
continue
predictions_set[example_id] = predictions
output = {"data": predictions_set}
return jsonify(output)
@app.route("/api/flag/", methods=["POST"])
def flag():
log_feature_analytics('flag')
flag_path = os.path.join(app.cwd, app.interface.flagging_dir)
os.makedirs(flag_path,
exist_ok=True)
output = {'inputs': [app.interface.input_interfaces[
i].rebuild(
flag_path, request.json['data']['input_data'][i]) for i
in range(len(app.interface.input_interfaces))],
'outputs': [app.interface.output_interfaces[
i].rebuild(
flag_path, request.json['data']['output_data'][i])
for i
in range(len(app.interface.output_interfaces))]}
log_fp = "{}/log.csv".format(flag_path)
is_new = not os.path.exists(log_fp)
with open(log_fp, "a") as csvfile:
headers = ["input_{}".format(i) for i in range(len(
output["inputs"]))] + ["output_{}".format(i) for i in
range(len(output["outputs"]))]
writer = csv.DictWriter(csvfile, delimiter=',',
lineterminator='\n',
fieldnames=headers)
if is_new:
writer.writeheader()
writer.writerow(
dict(zip(headers, output["inputs"] +
output["outputs"]))
)
return jsonify(success=True)
@app.route("/api/interpret/", methods=["POST"])
def interpret():
log_feature_analytics('interpret')
raw_input = request.json["data"]
interpretation_scores, alternative_outputs = app.interface.interpret(raw_input)
return jsonify({
"interpretation_scores": interpretation_scores,
"alternative_outputs": alternative_outputs
})
@app.route("/file/<path:path>", methods=["GET"])
def file(path):
return send_file(os.path.join(app.cwd, path))
def start_server(interface, server_name, server_port=None):
if server_port is None:
server_port = INITIAL_PORT_VALUE
port = get_first_available_port(
server_port, server_port + TRY_NUM_PORTS
)
app.interface = interface
app.cwd = os.getcwd()
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
if interface.save_to is not None:
interface.save_to["port"] = port
thread = threading.Thread(target=app.run,
kwargs={"port": port, "host": server_name},
daemon=True)
thread.start()
return port, app, thread
def close_server(process):
process.terminate()
process.join()
def url_request(url):
try:
req = urllib.request.Request(
url=url, headers={"content-type": "application/json"}
)
res = urllib.request.urlopen(req, timeout=10)
return res
except Exception as e:
raise RuntimeError(str(e))
def setup_tunnel(local_server_port):
response = url_request(GRADIO_API_SERVER)
if response and response.code == 200:
try:
payload = json.loads(response.read().decode("utf-8"))[0]
return create_tunnel(payload, LOCALHOST_NAME, local_server_port)
except Exception as e:
raise RuntimeError(str(e))
def url_ok(url):
try:
r = requests.head(url)
return r.status_code == 200
except ConnectionError:
return False

View File

@ -1,423 +0,0 @@
"""
This module defines various classes that can serve as the `output` to an interface. Each class must inherit from
`OutputComponent`, and each class must define a path to its template. All of the subclasses of `OutputComponent` are
automatically added to a registry, which allows them to be easily referenced in other parts of the code.
"""
from gradio.component import Component
import numpy as np
import json
from gradio import processing_utils
import datetime
import operator
from numbers import Number
import warnings
import tempfile
import scipy
import os
import pandas as pd
import PIL
from types import ModuleType
class OutputComponent(Component):
"""
Output Component. All output components subclass this.
"""
def postprocess(self, y):
"""
Any postprocessing needed to be performed on function output.
"""
return y
class Textbox(OutputComponent):
'''
Component creates a textbox to render output text or number.
Output type: Union[str, float, int]
'''
def __init__(self, type="auto", label=None):
'''
Parameters:
type (str): Type of value to be passed to component. "str" expects a string, "number" expects a float value, "auto" detects return type.
label (str): component name in interface.
'''
self.type = type
super().__init__(label)
def get_template_context(self):
return {
**super().get_template_context()
}
@classmethod
def get_shortcut_implementations(cls):
return {
"text": {"type": "str"},
"textbox": {"type": "str"},
"number": {"type": "number"},
}
def postprocess(self, y):
if self.type == "str" or self.type == "auto":
return str(y)
elif self.type == "number":
return y
else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'str', 'number'")
class Label(OutputComponent):
'''
Component outputs a classification label, along with confidence scores of top categories if provided. Confidence scores are represented as a dictionary mapping labels to scores between 0 and 1.
Output type: Union[Dict[str, float], str, int, float]
'''
CONFIDENCES_KEY = "confidences"
def __init__(self, num_top_classes=None, type="auto", label=None):
'''
Parameters:
num_top_classes (int): number of most confident classes to show.
type (str): Type of value to be passed to component. "value" expects a single out label, "confidences" expects a dictionary mapping labels to confidence scores, "auto" detects return type.
label (str): component name in interface.
'''
self.num_top_classes = num_top_classes
self.type = type
super().__init__(label)
def postprocess(self, y):
if self.type == "label" or (self.type == "auto" and (isinstance(y, str) or isinstance(y, Number))):
return {"label": str(y)}
elif self.type == "confidences" or (self.type == "auto" and isinstance(y, dict)):
sorted_pred = sorted(
y.items(),
key=operator.itemgetter(1),
reverse=True
)
if self.num_top_classes is not None:
sorted_pred = sorted_pred[:self.num_top_classes]
return {
"label": sorted_pred[0][0],
"confidences": [
{
"label": pred[0],
"confidence": pred[1]
} for pred in sorted_pred
]
}
else:
raise ValueError("The `Label` output interface expects one of: a string label, or an int label, a "
"float label, or a dictionary whose keys are labels and values are confidences.")
@classmethod
def get_shortcut_implementations(cls):
return {
"label": {},
}
def rebuild(self, dir, data):
"""
Default rebuild method for label
"""
# return json.loads(data)
return data
class Image(OutputComponent):
'''
Component displays an output image.
Output type: Union[numpy.array, PIL.Image, str, matplotlib.pyplot, Tuple[Union[numpy.array, PIL.Image, str], List[Tuple[str, float, float, float, float]]]]
'''
def __init__(self, type="auto", labeled_segments=False, plot=False, label=None):
'''
Parameters:
type (str): Type of value to be passed to component. "numpy" expects a numpy array with shape (width, height, 3), "pil" expects a PIL image object, "file" expects a file path to the saved image, "plot" expects a matplotlib.pyplot object, "auto" detects return type.
labeled_segments (bool): If True, expects a two-element tuple to be returned. The first element of the tuple is the image of format specified by type. The second element is a list of tuples, where each tuple represents a labeled segment within the image. The first element of the tuple is the string label of the segment, followed by 4 floats that represent the left-x, top-y, right-x, and bottom-y coordinates of the bounding box.
plot (bool): DEPRECATED. Whether to expect a plot to be returned by the function.
label (str): component name in interface.
'''
self.labeled_segments = labeled_segments
if plot:
warnings.warn("The 'plot' parameter has been deprecated. Set parameter 'type' to 'plot' instead.", DeprecationWarning)
self.type = "plot"
else:
self.type = type
super().__init__(label)
@classmethod
def get_shortcut_implementations(cls):
return {
"image": {},
"segmented_image": {"labeled_segments": True},
"plot": {"type": "plot"},
"pil": {"type": "pil"}
}
def postprocess(self, y):
if self.labeled_segments:
y, coordinates = y
else:
coordinates = []
if self.type == "auto":
if isinstance(y, np.ndarray):
dtype = "numpy"
elif isinstance(y, PIL.Image.Image):
dtype = "pil"
elif isinstance(y, str):
dtype = "file"
elif isinstance(y, ModuleType):
dtype = "plot"
else:
dtype = self.type
if dtype in ["numpy", "pil"]:
if dtype == "pil":
y = np.array(y)
out_y = processing_utils.encode_array_to_base64(y)
elif dtype == "file":
out_y = processing_utils.encode_file_to_base64(y)
elif dtype == "plot":
out_y = processing_utils.encode_plot_to_base64(y)
else:
raise ValueError("Unknown type: " + dtype + ". Please choose from: 'numpy', 'pil', 'file', 'plot'.")
return out_y, coordinates
def rebuild(self, dir, data):
"""
Default rebuild method to decode a base64 image
"""
im = processing_utils.decode_base64_to_image(data)
timestamp = datetime.datetime.now()
filename = 'output_{}_{}.png'.format(self.label, timestamp.strftime("%Y-%m-%d-%H-%M-%S"))
im.save('{}/{}'.format(dir, filename), 'PNG')
return filename
class KeyValues(OutputComponent):
'''
Component displays a table representing values for multiple fields.
Output type: Union[Dict, List[Tuple[str, Union[str, int, float]]]]
'''
def __init__(self, label=None):
'''
Parameters:
label (str): component name in interface.
'''
super().__init__(label)
def postprocess(self, y):
if isinstance(y, dict):
return list(y.items())
elif isinstance(y, list):
return y
else:
raise ValueError("The `KeyValues` output interface expects an output that is a dictionary whose keys are "
"labels and values are corresponding values.")
@classmethod
def get_shortcut_implementations(cls):
return {
"key_values": {},
}
class HighlightedText(OutputComponent):
'''
Component creates text that contains spans that are highlighted by category or numerical value.
Output is represent as a list of Tuple pairs, where the first element represents the span of text represented by the tuple, and the second element represents the category or value of the text.
Output type: List[Tuple[str, Union[float, str]]]
'''
def __init__(self, color_map=None, label=None):
'''
Parameters:
color_map (Dict[str, str]): Map between category and respective colors
label (str): component name in interface.
'''
self.color_map = color_map
super().__init__(label)
def get_template_context(self):
return {
"color_map": self.color_map,
**super().get_template_context()
}
@classmethod
def get_shortcut_implementations(cls):
return {
"highlight": {},
}
def postprocess(self, y):
return y
class Audio(OutputComponent):
'''
Creates an audio player that plays the output audio.
Output type: Union[Tuple[int, numpy.array], str]
'''
def __init__(self, type="auto", label=None):
'''
Parameters:
type (str): Type of value to be passed to component. "numpy" returns a 2-set tuple with an integer sample_rate and the data numpy.array of shape (samples, 2), "file" returns a temporary file path to the saved wav audio file, "auto" detects return type.
label (str): component name in interface.
'''
self.type = type
super().__init__(label)
def get_template_context(self):
return {
**super().get_template_context()
}
@classmethod
def get_shortcut_implementations(cls):
return {
"audio": {},
}
def postprocess(self, y):
if self.type in ["numpy", "file", "auto"]:
if self.type == "numpy" or (self.type == "auto" and isinstance(y, tuple)):
file = tempfile.NamedTemporaryFile()
scipy.io.wavfile.write(file, y[0], y[1])
y = file.name
return processing_utils.encode_file_to_base64(y, type="audio", ext="wav")
else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'numpy', 'file'.")
class JSON(OutputComponent):
'''
Used for JSON output. Expects a JSON string or a Python object that is JSON serializable.
Output type: Union[str, Any]
'''
def __init__(self, label=None):
'''
Parameters:
label (str): component name in interface.
'''
super().__init__(label)
def postprocess(self, y):
if isinstance(y, str):
return json.dumps(y)
else:
return y
@classmethod
def get_shortcut_implementations(cls):
return {
"json": {},
}
class HTML(OutputComponent):
'''
Used for HTML output. Expects an HTML valid string.
Output type: str
'''
def __init__(self, label=None):
'''
Parameters:
label (str): component name in interface.
'''
super().__init__(label)
@classmethod
def get_shortcut_implementations(cls):
return {
"html": {},
}
class File(OutputComponent):
'''
Used for file output.
Output type: Union[file-like, str]
'''
def __init__(self, label=None):
'''
Parameters:
label (str): component name in interface.
'''
super().__init__(label)
@classmethod
def get_shortcut_implementations(cls):
return {
"file": {},
}
def postprocess(self, y):
return {
"name": os.path.basename(y),
"size": os.path.getsize(y),
"data": processing_utils.encode_file_to_base64(y, header=False)
}
class Dataframe(OutputComponent):
"""
Component displays 2D output through a spreadsheet interface.
Output type: Union[pandas.DataFrame, numpy.array, List[Union[str, float]], List[List[Union[str, float]]]]
"""
def __init__(self, headers=None, type="auto", label=None):
'''
Parameters:
headers (List[str]): Header names to dataframe.
type (str): Type of value to be passed to component. "pandas" for pandas dataframe, "numpy" for numpy array, or "array" for Python array, "auto" detects return type.
label (str): component name in interface.
'''
self.type = type
self.headers = headers
super().__init__(label)
def get_template_context(self):
return {
"headers": self.headers,
**super().get_template_context()
}
@classmethod
def get_shortcut_implementations(cls):
return {
"dataframe": {},
"numpy": {"type": "numpy"},
"matrix": {"type": "array"},
"list": {"type": "array"},
}
def postprocess(self, y):
if self.type == "auto":
if isinstance(y, pd.core.frame.DataFrame):
dtype = "pandas"
elif isinstance(y, np.ndarray):
dtype = "numpy"
elif isinstance(y, list):
dtype = "array"
else:
dtype = self.type
if dtype == "pandas":
return {"headers": list(y.columns), "data": y.values.tolist()}
elif dtype in ("numpy", "array"):
if dtype == "numpy":
y = y.tolist()
if len(y) == 0 or not isinstance(y[0], list):
y = [y]
return {"data": y}
else:
raise ValueError("Unknown type: " + self.type + ". Please choose from: 'pandas', 'numpy', 'array'.")

View File

@ -1,172 +0,0 @@
from PIL import Image, ImageOps
from io import BytesIO
import base64
import tempfile
import scipy.io.wavfile
from scipy.fftpack import dct
import numpy as np
import skimage
#########################
# IMAGE PRE-PROCESSING
#########################
def decode_base64_to_image(encoding):
content = encoding.split(';')[1]
image_encoded = content.split(',')[1]
return Image.open(BytesIO(base64.b64decode(image_encoded)))
def encode_file_to_base64(f, type="image", ext=None, header=True):
with open(f, "rb") as file:
encoded_string = base64.b64encode(file.read())
base64_str = str(encoded_string, 'utf-8')
if not header:
return base64_str
if ext is None:
ext = f.split(".")[-1]
return "data:" + type + "/" + ext + ";base64," + base64_str
def encode_plot_to_base64(plt):
with BytesIO() as output_bytes:
plt.savefig(output_bytes, format="png")
bytes_data = output_bytes.getvalue()
base64_str = str(base64.b64encode(bytes_data), 'utf-8')
return "data:image/png;base64," + base64_str
def encode_array_to_base64(image_array):
with BytesIO() as output_bytes:
PIL_image = Image.fromarray(skimage.img_as_ubyte(image_array))
PIL_image.save(output_bytes, 'PNG')
bytes_data = output_bytes.getvalue()
base64_str = str(base64.b64encode(bytes_data), 'utf-8')
return "data:image/png;base64," + base64_str
def resize_and_crop(img, size, crop_type='center'):
"""
Resize and crop an image to fit the specified size.
args:
size: `(width, height)` tuple.
crop_type: can be 'top', 'middle' or 'bottom', depending on this
value, the image will cropped getting the 'top/left', 'middle' or
'bottom/right' of the image to fit the size.
raises:
ValueError: if an invalid `crop_type` is provided.
"""
if crop_type == "top":
center = (0, 0)
elif crop_type == "center":
center = (0.5, 0.5)
else:
raise ValueError
return ImageOps.fit(img, size, centering=center)
##################
# OUTPUT
##################
def decode_base64_to_binary(encoding):
inp = encoding.split(';')[1].split(',')[1]
return base64.b64decode(inp)
def decode_base64_to_file(encoding):
file_obj = tempfile.NamedTemporaryFile()
file_obj.write(decode_base64_to_binary(encoding))
file_obj.flush()
return file_obj
##################
# AUDIO FILES
##################
def generate_mfcc_features_from_audio_file(wav_filename=None,
pre_emphasis=0.95,
frame_size= 0.025,
frame_stride=0.01,
NFFT=512,
nfilt=40,
num_ceps=12,
cep_lifter=22,
sample_rate=None,
signal=None,
downsample_to=None):
"""
Loads and preprocesses a .wav audio file (or alternatively, a sample rate & signal) into mfcc coefficients, the typical inputs to models.
Adapted from: https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html
:param wav_filename: string name of audio file to process.
:param pre_emphasis: a float factor, typically 0.95 or 0.97, which amplifies high frequencies.
:param frame_size: a float that is the length, in seconds, of time frame over which to take the fft.
:param frame_stride: a float that is the offset, in seconds, between consecutive time frames.
:param NFFT: The number of points in the short-time fft for each time frame.
:param nfilt: The number of filters on the Mel-scale to extract frequency bands.
:param num_ceps: the number of cepstral coefficients to retrain.
:param cep_lifter: the int factor, by which to de-emphasize higher-frequency.
:param sample_rate: optional param represnting sample rate that is used if `wav_filename` is not provided
:param signal: optional param representing sample data that is used if `wav_filename` is not provided
:param downsample_to: optional param. If provided, audio file is downsampled to this many frames.
:return: a 3D numpy array of mfcc coefficients, of the shape 1 x num_frames x num_coeffs.
"""
if (wav_filename is None) and (sample_rate is None or signal is None):
raise ValueError("Either a wav_filename must be provdied or a sample_rate and signal")
elif wav_filename is None:
pass
else:
sample_rate, signal = scipy.io.wavfile.read(wav_filename)
if not(downsample_to is None):
signal = scipy.signal.resample(signal, downsample_to)
emphasized_signal = np.append(signal[0], signal[1:] - pre_emphasis * signal[:-1])
frame_length, frame_step = frame_size * sample_rate, frame_stride * sample_rate # Convert from seconds to samples
signal_length = len(emphasized_signal)
frame_length = int(round(frame_length))
frame_step = int(round(frame_step))
num_frames = int(np.ceil(float(np.abs(signal_length - frame_length)) / frame_step)) # Make sure that we have at least 1 frame
pad_signal_length = num_frames * frame_step + frame_length
z = np.zeros((pad_signal_length - signal_length))
pad_signal = np.append(emphasized_signal, z) # Pad Signal to make sure that all frames have equal number of samples without truncating any samples from the original signal
indices = np.tile(np.arange(0, frame_length), (num_frames, 1)) + np.tile(np.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T
frames = pad_signal[indices.astype(np.int32, copy=False)]
frames *= np.hamming(frame_length)
mag_frames = np.absolute(np.fft.rfft(frames, NFFT)) # Magnitude of the FFT
pow_frames = ((1.0 / NFFT) * ((mag_frames) ** 2)) # Power Spectrum
low_freq_mel = 0
high_freq_mel = (2595 * np.log10(1 + (sample_rate / 2) / 700)) # Convert Hz to Mel
mel_points = np.linspace(low_freq_mel, high_freq_mel, nfilt + 2) # Equally spaced in Mel scale
hz_points = (700 * (10**(mel_points / 2595) - 1)) # Convert Mel to Hz
bin = np.floor((NFFT + 1) * hz_points / sample_rate)
fbank = np.zeros((nfilt, int(np.floor(NFFT / 2 + 1))))
for m in range(1, nfilt + 1):
f_m_minus = int(bin[m - 1]) # left
f_m = int(bin[m]) # center
f_m_plus = int(bin[m + 1]) # right
for k in range(f_m_minus, f_m):
fbank[m - 1, k] = (k - bin[m - 1]) / (bin[m] - bin[m - 1])
for k in range(f_m, f_m_plus):
fbank[m - 1, k] = (bin[m + 1] - k) / (bin[m + 1] - bin[m])
filter_banks = np.dot(pow_frames, fbank.T)
filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks) # Numerical Stability
filter_banks = 20 * np.log10(filter_banks) # dB
mfcc = dct(filter_banks, type=2, axis=1, norm='ortho')[:, 0: (num_ceps + 1)] # Keep filters 1-13 by default.
(nframes, ncoeff) = mfcc.shape
n = np.arange(ncoeff)
lift = 1 + (cep_lifter / 2) * np.sin(np.pi * n / cep_lifter)
mfcc *= lift
filter_banks -= (np.mean(filter_banks, axis=0) + 1e-8)
mfcc -= (np.mean(mfcc, axis=0) + 1e-8)
return mfcc[np.newaxis, :, :] # Create a batch dimension.

View File

@ -1,11 +0,0 @@
{
"applinks": {
"apps": [],
"details": [
{
"appID": "RHW8FBGSTX.app.gradio.Gradio",
"paths": ["*"]
}
]
}
}

View File

@ -1,146 +0,0 @@
.panels {
margin-top: -24px;
margin-left: -16px;
}
.panel {
margin-top: 24px;
margin-left: 16px;
min-width: 300px;
flex: 1 1 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.panel_header {
text-transform: uppercase;
color: black;
font-size: 14px;
font-weight: bold;
display: flex;
margin-bottom: 8px;
}
.input_interfaces, .output_interfaces {
margin-bottom: 16px;
background-color: whitesmoke;
border-radius: 4px;
padding: 12px;
flex-grow: 1;
}
.interface {
display: flex;
flex-flow: column;
}
.interface_box {
height: 360px;
}
.interface_mini_box {
height: 180px;
}
.interface_max_box {
overflow: auto;
max-height: 360px;
}
.interface:not(*:last-child) {
margin-bottom: 16px;
}
.output_panel {
position: relative;
}
.loading {
position: absolute;
top: 3px;
right: 3px;
margin-left: auto;
z-index: 1;
}
.loading img {
height: 20px;
display: none;
}
.panel_buttons {
display: flex;
margin-left: -16px;
}
input.submit {
display: none;
}
input.panel_button {
background-color: whitesmoke;
padding: 12px;
box-sizing: border-box;
font-weight: bold;
border: 0 none;
border-radius: 4px;
margin-left: 16px;
flex-grow: 1;
}
.panel_button.left_panel_button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
flex-grow: 0.6;
}
.panel_button.right_panel_button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
flex-grow: 0.6;
margin-left: 0px;
background-color: #EEE;
}
.record_stop {
display: inline-flex;
align-items: center;
justify-content: center;
width: 60px;
border-radius: 4px;
}
.record_square {
width: 20px;
height: 20px;
background-color: #c90a0a;
box-shadow: inset 0 0 4px darkred;
}
input.submit {
background-color: #e67e22;
color: white;
}
.panel_button:hover {
background-color: lightgray;
}
input.submit:hover {
background-color: #f39c12;
}
.flagged {
background-color: pink !important;
}
/* label:hover {
background-color: lightgray;
} */
.overlay {
position: absolute;
height: 100vh;
width: 100vw;
position: fixed;
z-index: 1;
background-color: rgba(0, 0, 0, 0.7);
top: 0;
left: 0;
}
.loading {
justify-content: center;
align-items: center;
}
.invisible {
display: none !important;
}
.screenshot_logo {
display: flex;
justify-content: center;
flex-grow: 1;
padding: 4px;
box-sizing: border-box;
margin-left: 16px;
}
.screenshot_logo img {
height: 38px;
}

View File

@ -1,39 +0,0 @@
.checkbox_group {
display: flex;
flex-wrap: wrap;
align-items: center;
font-size: 18px;
margin-top: -12px;
margin-left: -16px;
}
.checkbox_group input, .checkbox {
margin: 0px;
}
.checkbox_group label {
margin-top: 12px;
margin-left: 16px;
}
.checkbox_solo label {
width: 27px !important;
padding-left: 11px;
padding-right: 3px;
}
.interpret_sub {
margin-top: 12px;
}
.interpret_sub:empty {
margin-top: 0;
}
.interpret_check {
display: inline-block;
padding: 4px 8px;
font-family: monospace;
font-weight: bold;
color: black;
font-size: 16px;
}
.interpret_select {
background-color: white;
border: solid 2px black;
box-sizing: border-box;
}

View File

@ -1,13 +0,0 @@
select.dropdown {
padding: 4px;
font-size: 18px;
border: solid 1px lightgray;
border-radius: 2px;
outline: none;
}
.select_interpretation > div {
font-weight: bold;
padding: 4px;
font-size: 12px;
box-sizing: border-box;
}

View File

@ -1,15 +0,0 @@
.file_display {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.file_name {
font-size: 24px;
font-weight: bold;
margin-bottom: 18px;
}
.file_size {
font-size: 18px;
}

View File

@ -1,100 +0,0 @@
.hide {
display: none !important;
}
.image_display {
height: 100%;
}
.view_holders {
flex-grow: 1;
background-color: #CCCCCC;
position: relative;
}
.image_preview_holder, .saliency_holder {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.saliency_holder {
position: absolute;
top: 0;
}
.saliency {
display: flex;
flex-direction: column;
border: none;
opacity: 1;
transition: opacity 0.2s ease;
}
.saliency:hover {
opacity: 0.4;
}
.image_preview {
width: 100%;
height: 100%;
object-fit: contain;
}
.hidden_upload {
display: none;
}
.image_editor_overlay {
display: flex;
justify-content: center;
align-items: center;
}
.image_editor_holder {
height: 85%;
width: 85%;
}
.image_editor {
background-color: black;
}
#tie-btn-reset, #tie-btn-delete, #tie-btn-delete-all {
display: none !important;
}
.tui-image-editor-icpartition {
background-color: transparent !important;
}
.tui_close {
border-radius: 0 !important;
border: none !important;
margin-left: 10px !important;
font-family: 'Open Sans', sans-serif !important;
}
.upload_zone {
font-weight: bold;
font-size: 24px;
color: #BBB;
cursor: pointer;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
line-height: 1.5em;
flex-flow: column;
}
.upload_zone img {
height: 120px;
}
.drop_zone {
border: dashed 8px #DDD;
}
.edit_holder {
display: flex;
justify-content: flex-end;
position: relative;
}
.edit_image {
position: absolute;
z-index: 1;
}
.interface_button {
padding: 6px;
text-transform: uppercase;
font-weight: bold;
font-size: 14px;
}

View File

@ -1,52 +0,0 @@
.hidden {
display: none !important;
}
.recording.input_caption {
color: #C00000;
}
.volume_display {
width: 100%;
display: flex;
}
.volume {
flex-grow: 1;
display: flex;
align-items: center;
}
.volume_left {
justify-content: flex-end;
}
.volume_bar {
height: 12px;
background-color: #C00000;
transition: width 0.1s;
}
.volume_left .volume_bar {
border-radius: 4px 0 0 4px;
}
.volume_right .volume_bar {
border-radius: 0 4px 4px 0;
}
.player {
display: flex;
width: 100%;
height: 100%;
flex-flow: column;
align-items: center;
justify-content: center;
}
.waveform {
width: 100%;
}
.waveform > wave {
overflow: visible !important;
}
.waveform canvas {
border: none !important;
}
.playpause {
margin-top: 26px;
font-size: 20px;
padding: 4px;
border-radius: 2px;
}

View File

@ -1,15 +0,0 @@
.radio_group {
display: flex;
flex-wrap: wrap;
align-items: center;
font-size: 18px;
margin-top: -12px;
margin-left: -16px;
}
.radio_group input {
margin: 0px;
}
.radio_group label {
margin-top: 12px;
margin-left: 16px;
}

View File

@ -1,58 +0,0 @@
.hide {
display: none !important;
}
.sketchpad {
display: flex;
flex-direction: column;
height: 100%;
}
.sketch_tools {
flex: 0 1 auto;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
}
.brush {
border-radius: 50%;
background-color: #AAA;
margin: 0px 20px;
cursor: pointer;
}
.brush.selected, .brush:hover {
background-color: black;
}
#brush_1 {
height: 8px;
width: 8px;
}
#brush_2 {
height: 16px;
width: 16px;
}
#brush_3 {
height: 24px;
width: 24px;
}
.view_holders {
flex-grow: 1;
background-color: #CCCCCC;
position: relative;
}
.canvas_holder canvas {
background-color: white;
}
.canvas_holder {
text-align: center;
width: 100%;
height: calc(100% - 36px);
}
.saliency_holder {
position: absolute;
top: 0;
opacity: 0.9;
}
.view_holders canvas {
background-color: white;
border: solid 1px white;
}

View File

@ -1,34 +0,0 @@
.slider_container .slider {
margin: 0 24px;
}
.slider_container .ui-slider-handle {
width: 3em !important;
height: 1.6em !important;
top: 50% !important;
margin-top: -.8em;
margin-left: -1.5em !important;
text-align: center;
line-height: 1.6em;
cursor: pointer !important;
font-weight: bold;
outline: none !important;
}
.interpret_range {
width: 100%;
display: flex;
margin-top: 12px;
}
.interpret_range:empty {
margin-top: 0px;
}
.interpret_range > div {
min-height: 24px;
flex-grow: 1;
text-align: center;
font-weight: bold;
padding: 4px;
font-size: 12px;
display: flex;
align-items: center;
box-sizing: border-box;
}

View File

@ -1,13 +0,0 @@
textarea.input_text, input.input_text {
resize: none;
width: 100%;
font-size: 18px;
outline: none;
height: 100%;
background-color: white;
border: solid 1px lightgray;
border-radius: 2px;
box-sizing: border-box;
padding: 4px;
font-family: monospace;
}

View File

@ -1,20 +0,0 @@
.webcam_box {
width: 100% !important;
flex-grow: 1;
background-color: #BBBBBB;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.webcam_box canvas {
border: none;
}
.take_photo {
font-weight: bold;
font-size: 14px;
padding: 10px 0;
}
.snapped {
display: none;
}

View File

@ -1,15 +0,0 @@
.output_text {
width: 100%;
font-size: 18px;
outline: none;
background-color: white;
border: solid 1px lightgray;
border-radius: 2px;
box-sizing: border-box;
padding: 4px;
min-height: 30px;
font-family: monospace;
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
word-wrap: break-word; /* IE */
}

View File

@ -1,22 +0,0 @@
.highlight_legend {
margin-bottom: 4px;
}
.color_legend {
font-family: monospace;
padding: 4px;
border-radius: 2px;
display: flex;
justify-content: space-between;
background: linear-gradient(90deg, rgba(58,241,255,1) 0%, rgba(58,241,255,0) 49%, rgba(230,126,34,0) 50%, rgba(230,126,34,1) 100%);
margin-bottom: 4px;
}
.category-label {
display: inline-flex;
margin-right: 8px;
margin-bottom: 4px;
}
.category-label div {
width: 24px;
margin-right: 4px;
}

View File

@ -1,15 +0,0 @@
.output_text {
width: 100%;
font-size: 18px;
outline: none;
background-color: white;
border: solid 1px lightgray;
border-radius: 2px;
box-sizing: border-box;
padding: 4px;
min-height: 30px;
font-family: monospace;
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
word-wrap: break-word; /* IE */
}

View File

@ -1,12 +0,0 @@
.output_image_holder {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.output_image {
width: 100%;
height: 100%;
object-fit: contain;
}

View File

@ -1,13 +0,0 @@
.key_values th {
text-align: left;
}
.key_values tr {
padding: 4px;
}
.key_values {
font-family: monospace;
font-size: 16px;
}
.key_values tbody tr:nth-child(odd) {
background-color: white;
}

View File

@ -1,48 +0,0 @@
.confidence_intervals {
display: flex;
font-size: 20px;
}
.confidences {
flex-grow: 1;
display: flex;
flex-flow: column;
align-items: baseline;
font-family: monospace;
}
.confidence {
background-color: #888888;
color: white;
text-align: right;
display: flex;
align-items: center;
justify-content: flex-end;
}
.labels {
max-width: 120px;
margin-right: 4px;
}
.label, .confidence {
overflow: hidden;
white-space: nowrap;
height: 27px;
margin-bottom: 4px;
padding: 2px;
}
.label {
text-overflow: ellipsis;
text-align: right;
}
.confidence {
text-overflow: clip;
padding-left: 6px;
padding-right: 6px;
}
.output_class {
font-weight: bold;
font-size: 36px;
padding: 32px 16px;;
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
}

View File

@ -1,15 +0,0 @@
.output_text {
width: 100%;
font-size: 18px;
outline: none;
background-color: white;
border: solid 1px lightgray;
border-radius: 2px;
box-sizing: border-box;
padding: 4px;
min-height: 30px;
font-family: monospace;
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
word-wrap: break-word; /* IE */
}

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
body#lib {
font-family: 'Open Sans', sans-serif;
margin: 20px 0 0;
position: relative;
padding-bottom: 60px;
}
button, input[type="submit"], input[type="reset"], input[type="text"], input[type="button"], select[type="submit"] {
border: none;
font: inherit;
outline: inherit;
-webkit-appearance: none;
}
select {
font: inherit;
}
label, input[type=radio], input[type=checkbox], select, input[type=range], button, input[type="submit"], input[type="reset"], input[type="button"], select[type="submit"] {
cursor: pointer;
}
.loading_time {
color: #e67e22;
text-align: right;
font-family: monospace;
}
.share {
text-align: center;
margin-bottom: 10px;
font-size: 14px;
}
.share-copy {
background-color: whitesmoke;
padding: 4px;
border-radius: 2px;
}
.title {
text-align: center;
}
.container {
max-width: 1028px;
width: 100%;
margin: 0 auto;
padding-left: 24px;
padding-right: 24px;
box-sizing: border-box;
}
.panels {
display: flex;
flex-flow: row;
flex-wrap: wrap;
justify-content: center;
}
button.primary {
color: white;
background-color: #e67e22;
}
button.secondary {
color: black;
background-color: #F6F6F6;
}
h4 {
margin-bottom: 0.5em;
}
.interpretation_legend {
display: flex;
padding: 8px;
border: solid 2px black;
justify-content: space-between;
font-family: monospace;
background-image: linear-gradient(to right, #3498db ,white,#e74c3c);
}
.interpretation_explained ul {
font-size: 14px;
}
.close_explain {
cursor: pointer;
}
.examples > button {
padding: 8px 16px;
border-radius: 2px;
margin-right: 4px;
background-color: whitesmoke;
}
.examples > table {
border-collapse: collapse;
font-family: monospace;
padding: 8px;
background-color: whitesmoke;
border-right: solid 4px whitesmoke;
border-left: solid 4px whitesmoke;
border-bottom: solid 4px whitesmoke;
margin-top: 8px;
}
.examples > table th {
padding: 8px 16px;
text-align: left;
font-size: 18px;
text-transform: uppercase;
}
.examples_body > tr > td {
padding: 8px;
cursor: pointer;
}
.pages {
display: flex;
align-items: center;
margin-top: 8px;
flex-wrap: wrap;
}
.page {
padding: 8px;
margin: 4px;
border-radius: 4px;
}
.examples_body > tr:nth-child(odd) {
background-color: white;
}
.examples_body > tr:hover {
background-color: lightgray;
}
.examples_body > tr.current_example {
background-color: #ffb573;
}
#credit {
text-align: center;
position: absolute;
left: 0;
right: 0;
bottom: 18px;
height: 24px;
}
#credit img {
height: 24px;
}

View File

@ -1,9 +0,0 @@
/*!
* Cropper.js v1.5.7
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2020-05-23T05:22:57.283Z
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="11" height="22"><defs><linearGradient id="a"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><radialGradient xlink:href="#a" cx="9.739" cy="9.716" fx="9.739" fy="9.716" r="3.709" gradientUnits="userSpaceOnUse"/></defs><g stroke="#000" fill="none"><g transform="translate(-129.5 -333.862) translate(0 .188)"><rect transform="matrix(.962 0 0 .971 4.943 11.548)" ry="2" rx="2" y="332.362" x="130" height="10.337" width="10.432" opacity=".5"/><g><path d="M132 339.175h6" opacity=".5"/><path d="M135 336.175v6" opacity=".5"/></g></g><g transform="translate(-129.5 -333.862)"><rect width="10.432" height="10.337" x="130" y="332.362" rx="2" ry="2" transform="matrix(.962 0 0 .971 4.943 22.736)" opacity=".5"/><path d="M132 350.362h6" opacity=".5"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,115 +0,0 @@
/*
* JSON Tree Viewer
* http://github.com/summerstyle/jsonTreeViewer
*
* Copyright 2017 Vera Lobacheva (http://iamvera.com)
* Released under the MIT license (LICENSE.txt)
*/
/* Background for the tree. May use for <body> element */
.jsontree_bg {
background: #FFF;
}
/* Styles for the container of the tree (e.g. fonts, margins etc.) */
.jsontree_tree {
font-family: 'PT Mono', monospace;
font-size: 14px;
padding-left: 0;
}
.jsontree_tree ul {
padding-left: 20px;
}
.jsontree_tree li {
list-style: none;
}
/* Styles for a list of child nodes */
.jsontree_child-nodes {
display: none;
margin-bottom: 5px;
line-height: 2;
}
.jsontree_node_expanded > .jsontree_value-wrapper > .jsontree_value > .jsontree_child-nodes {
display: block;
}
/* Styles for labels */
.jsontree_label-wrapper {
float: left;
margin-right: 8px;
}
.jsontree_label {
font-weight: normal;
vertical-align: top;
color: #000;
position: relative;
padding: 1px;
border-radius: 4px;
cursor: default;
}
.jsontree_node_marked > .jsontree_label-wrapper > .jsontree_label {
background: #fff2aa;
}
/* Styles for values */
.jsontree_value-wrapper {
display: block;
overflow: hidden;
}
.jsontree_node_complex > .jsontree_value-wrapper {
overflow: inherit;
}
.jsontree_value {
vertical-align: top;
display: inline;
}
.jsontree_value_null {
color: #777;
font-weight: bold;
}
.jsontree_value_string {
color: #025900;
font-weight: bold;
}
.jsontree_value_number {
color: #000E59;
font-weight: bold;
}
.jsontree_value_boolean {
color: #600100;
font-weight: bold;
}
/* Styles for active elements */
.jsontree_expand-button {
position: absolute;
top: 3px;
left: -15px;
display: block;
width: 11px;
height: 11px;
background-image: url('icons.svg');
}
.jsontree_node_expanded > .jsontree_label-wrapper > .jsontree_label > .jsontree_expand-button {
background-position: 0 -11px;
}
.jsontree_show-more {
cursor: pointer;
}
.jsontree_node_expanded > .jsontree_value-wrapper > .jsontree_value > .jsontree_show-more {
display: none;
}
.jsontree_node_empty > .jsontree_label-wrapper > .jsontree_label > .jsontree_expand-button,
.jsontree_node_empty > .jsontree_value-wrapper > .jsontree_value > .jsontree_show-more {
display: none !important;
}
.jsontree_node_complex > .jsontree_label-wrapper > .jsontree_label {
cursor: pointer;
}
.jsontree_node_empty > .jsontree_label-wrapper > .jsontree_label {
cursor: default !important;
}

File diff suppressed because one or more lines are too long

View File

@ -1,153 +0,0 @@
/*!
* Toast UI Colorpicker
* @version 2.2.0
* @author NHNEnt FE Development Team <dl_javascript@nhnent.com>
* @license MIT
*/
.tui-colorpicker-clearfix {
zoom: 1;
}
.tui-colorpicker-clearfix:after {
content: '';
display: block;
clear: both;
}
.tui-colorpicker-vml {
behavior: url("#default#VML");
display: block;
}
.tui-colorpicker-container {
width: 152px;
}
.tui-colorpicker-palette-container {
width: 152px;
}
.tui-colorpicker-palette-container ul {
width: 152px;
margin: 0px;
padding: 0px;
}
.tui-colorpicker-palette-container li {
float: left;
margin: 0;
padding: 0 3px 3px 0;
list-style: none;
}
.tui-colorpicker-palette-button {
display: block;
border: none;
overflow: hidden;
outline: none;
margin: 0px;
padding: 0px;
width: 16px;
height: 16px;
border: 1px solid #ccc;
cursor: pointer;
}
.tui-colorpicker-palette-button.tui-colorpicker-selected {
border: 2px solid #000;
}
.tui-colorpicker-palette-button.tui-colorpicker-color-transparent {
barckground-repeat: repeat;
background-repeat: no-repeat;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRgxSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4BZIsUAR0IZN8BsdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPDRcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLoMjiWpFaUgBQ65xdUFmWmZ5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBLmsbAsH0PA4PEKYSYyjwGBn5rBoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAGbaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjEzPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CghrN1AAAABzSURBVCgVldKxEYAgDAXQD5VOpLuwgi4jlrTMqF00oOd5Aia/CcV/F4oYOgNlrLjvVyCEVJchBjEC25538PeaWTzRMBLxvIL7UZwFwL06qoA6aoAy+gFfJABvJAQPUoCMlICRRd8BzgHzJL4ok9aJ67l4AK9AxVKhHryUAAAAAElFTkSuQmCC");
}
.tui-colorpicker-palette-hex {
font-family: monospace;
display: inline-block;
*display: inline;
zoom: 1;
width: 60px;
vertical-align: middle;
}
.tui-colorpicker-palette-preview {
display: inline-block;
*display: inline;
zoom: 1;
width: 12px;
height: 12px;
border: 1px solid #ccc;
border: 1px solid #ccc;
vertical-align: middle;
overflow: hidden;
}
.tui-colorpicker-palette-toggle-slider {
display: inline-block;
*display: inline;
zoom: 1;
vertical-align: middle;
float: right;
}
.tui-colorpicker-slider-container {
margin: 5px 0 0 0;
height: 122px;
zoom: 1;
}
.tui-colorpicker-slider-container:after {
content: '';
display: block;
clear: both;
}
.tui-colorpicker-slider-left {
float: left;
width: 120px;
height: 120px;
}
.tui-colorpicker-slider-right {
float: right;
width: 32px;
height: 120px;
}
.tui-colorpicker-svg {
display: block;
}
.tui-colorpicker-slider-handle {
position: absolute;
overflow: visible;
top: 0;
left: 0;
width: 1px;
height: 1px;
z-index: 2;
opacity: 0.9;
}
.tui-colorpicker-svg-slider {
width: 120px;
height: 120px;
border: 1px solid #ccc;
overflow: hidden;
}
.tui-colorpicker-vml-slider {
position: relative;
width: 120px;
height: 120px;
border: 1px solid #ccc;
overflow: hidden;
}
.tui-colorpicker-vml-slider-bg {
position: absolute;
margin: -1px 0 0 -1px;
top: 0;
left: 0;
width: 122px;
height: 122px;
}
.tui-colorpicker-svg-huebar {
float: right;
width: 18px;
height: 120px;
border: 1px solid #ccc;
overflow: visible;
}
.tui-colorpicker-vml-huebar {
width: 32px;
position: relative;
}
.tui-colorpicker-vml-huebar-bg {
position: absolute;
top: 0;
right: 0;
width: 18px;
height: 121px;
}

View File

@ -1,940 +0,0 @@
/*!
* tui-image-editor.js
* @version 3.5.2
* @author NHNEnt FE Development Lab <dl_javascript@nhnent.com>
* @license MIT
*/
body > textarea {
position: fixed !important;
}
.tui-image-editor-container {
marign: 0;
padding: 0;
box-sizing: border-box;
min-height: 300px;
height: 100%;
position: relative;
background-color: #282828;
overflow: hidden;
letter-spacing: 0.3px;
}
.tui-image-editor-container div,
.tui-image-editor-container ul,
.tui-image-editor-container label,
.tui-image-editor-container input,
.tui-image-editor-container li {
box-sizing: border-box;
margin: 0;
padding: 0;
-ms-user-select: none;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.tui-image-editor-container .tui-image-editor-header {
/* BUTTON AND LOGO */
min-width: 533px;
position: absolute;
background-color: #151515;
top: 0;
width: 100%;
}
.tui-image-editor-container .tui-image-editor-header-buttons,
.tui-image-editor-container .tui-image-editor-controls-buttons {
float: right;
margin: 8px;
}
.tui-image-editor-container .tui-image-editor-header-logo,
.tui-image-editor-container .tui-image-editor-controls-logo {
float: left;
width: 30%;
padding: 17px;
}
.tui-image-editor-container .tui-image-editor-controls-logo,
.tui-image-editor-container .tui-image-editor-controls-buttons {
width: 270px;
height: 100%;
display: none;
}
.tui-image-editor-container .tui-image-editor-header-buttons button,
.tui-image-editor-container .tui-image-editor-header-buttons div,
.tui-image-editor-container .tui-image-editor-controls-buttons button {
display: inline-block;
position: relative;
width: 120px;
height: 40px;
padding: 0;
line-height: 40px;
outline: none;
border-radius: 20px;
border: 1px solid #ddd;
font-family: 'Noto Sans', sans-serif;
font-size: 12px;
font-weight: bold;
cursor: pointer;
vertical-align: middle;
letter-spacing: 0.3px;
text-align: center;
}
.tui-image-editor-container .tui-image-editor-download-btn {
background-color: #fdba3b;
border-color: #fdba3b;
color: #fff;
}
.tui-image-editor-container .tui-image-editor-load-btn {
position: absolute;
left: 0;
right: 0;
display: inline-block;
top: 0;
bottom: 0;
width: 100%;
cursor: pointer;
opacity: 0;
}
.tui-image-editor-container .tui-image-editor-main-container {
position: absolute;
width: 100%;
top: 0;
bottom: 64px;
}
.tui-image-editor-container .tui-image-editor-main {
position: absolute;
text-align: center;
top: 64px;
bottom: 0;
right: 0;
left: 0;
}
.tui-image-editor-container .tui-image-editor-wrap {
position: absolute;
bottom: 0;
width: 100%;
overflow: auto;
}
.tui-image-editor-container .tui-image-editor-wrap .tui-image-editor-size-wrap {
display: table;
width: 100%;
height: 100%;
}
.tui-image-editor-container .tui-image-editor-wrap .tui-image-editor-size-wrap .tui-image-editor-align-wrap {
display: table-cell;
vertical-align: middle;
}
.tui-image-editor-container .tui-image-editor {
position: relative;
display: inline-block;
}
.tui-image-editor-container .tui-image-editor-menu {
width: auto;
list-style: none;
padding: 0;
margin: 0 auto;
display: table-cell;
text-align: center;
vertical-align: middle;
white-space: nowrap;
}
.tui-image-editor-container .tui-image-editor-menu > .tui-image-editor-item {
position: relative;
display: inline-block;
border-radius: 2px;
padding: 7px 8px 3px 8px;
cursor: pointer;
margin: 0 4px;
}
.tui-image-editor-container .tui-image-editor-menu > .tui-image-editor-item[title]:hover:before {
content: '';
position: absolute;
display: inline-block;
margin: 0 auto 0;
width: 0;
height: 0;
border-right: 7px solid transparent;
border-top: 7px solid #2f2f2f;
border-left: 7px solid transparent;
position: absolute;
left: 13px;
top: -2px;
}
.tui-image-editor-container .tui-image-editor-menu > .tui-image-editor-item[title]:hover:after {
content: attr(title);
position: absolute;
display: inline-block;
background-color: #2f2f2f;
color: #fff;
padding: 5px 8px;
font-size: 11px;
font-weight: lighter;
border-radius: 3px;
max-height: 23px;
top: -22px;
left: 0;
min-width: 24px;
}
.tui-image-editor-container .tui-image-editor-menu > .tui-image-editor-item.active {
background-color: #fff;
transition: all 0.3s ease;
}
.tui-image-editor-container .tui-image-editor-wrap {
position: absolute;
}
.tui-image-editor-container .tui-image-editor-grid-visual {
display: none;
position: absolute;
width: 100%;
height: 100%;
border: 1px solid rgba(255,255,255,0.7);
}
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-flip .tui-image-editor,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-rotate .tui-image-editor {
transition: none;
}
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-flip .tui-image-editor-grid-visual,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-rotate .tui-image-editor-grid-visual {
display: block;
}
.tui-image-editor-container .tui-image-editor-grid-visual table {
width: 100%;
height: 100%;
border-collapse: collapse;
}
.tui-image-editor-container .tui-image-editor-grid-visual table td {
border: 1px solid rgba(255,255,255,0.3);
}
.tui-image-editor-container .tui-image-editor-grid-visual table td.dot:before {
content: '';
position: absolute;
box-sizing: border-box;
width: 10px;
height: 10px;
border: 0;
box-shadow: 0 0 1px 0 rgba(0,0,0,0.3);
border-radius: 100%;
background-color: #fff;
}
.tui-image-editor-container .tui-image-editor-grid-visual table td.dot.left-top:before {
top: -5px;
left: -5px;
}
.tui-image-editor-container .tui-image-editor-grid-visual table td.dot.right-top:before {
top: -5px;
right: -5px;
}
.tui-image-editor-container .tui-image-editor-grid-visual table td.dot.left-bottom:before {
bottom: -5px;
left: -5px;
}
.tui-image-editor-container .tui-image-editor-grid-visual table td.dot.right-bottom:before {
bottom: -5px;
right: -5px;
}
.tui-image-editor-container .tui-image-editor-submenu {
display: none;
position: absolute;
bottom: 0;
width: 100%;
height: 150px;
white-space: nowrap;
z-index: 2;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-button:hover svg > use.active {
display: block;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item li {
display: inline-block;
vertical-align: top;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-image-editor-newline {
display: block;
margin-top: 0;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-image-editor-button {
position: relative;
cursor: pointer;
display: inline-block;
font-weight: normal;
font-size: 11px;
margin: 0 9px 0 9px;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-image-editor-button.preset {
margin: 0 9px 20px 5px;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item label {
display: inline-block;
cursor: pointer;
padding-top: 5px;
font-family: "Noto Sans", sans-serif;
font-size: 11px;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-image-editor-button.apply label,
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-image-editor-button.cancel label {
vertical-align: 7px;
}
.tui-image-editor-container .tui-image-editor-submenu > div {
display: none;
vertical-align: bottom;
}
.tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-submenu-style {
opacity: 0.95;
z-index: -1;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: block;
}
.tui-image-editor-container .tui-image-editor-partition > div {
width: 1px;
height: 52px;
border-left: 1px solid #3c3c3c;
margin: 0 8px 0 8px;
}
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-filter .tui-image-editor-partition > div {
height: 108px;
margin: 0 29px 0 0px;
}
.tui-image-editor-container .tui-image-editor-submenu-align {
text-align: left;
margin-right: 30px;
}
.tui-image-editor-container .tui-image-editor-submenu-align label {
width: 55px;
white-space: nowrap;
}
.tui-image-editor-container .tui-image-editor-submenu-align:first-child {
margin-right: 0;
}
.tui-image-editor-container .tui-image-editor-submenu-align:first-child label {
width: 70px;
}
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-crop .tui-image-editor-submenu > div.tui-image-editor-menu-crop,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-flip .tui-image-editor-submenu > div.tui-image-editor-menu-flip,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-rotate .tui-image-editor-submenu > div.tui-image-editor-menu-rotate,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-shape .tui-image-editor-submenu > div.tui-image-editor-menu-shape,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-text .tui-image-editor-submenu > div.tui-image-editor-menu-text,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-mask .tui-image-editor-submenu > div.tui-image-editor-menu-mask,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-icon .tui-image-editor-submenu > div.tui-image-editor-menu-icon,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-draw .tui-image-editor-submenu > div.tui-image-editor-menu-draw,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-filter .tui-image-editor-submenu > div.tui-image-editor-menu-filter {
display: table-cell;
}
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-crop .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-flip .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-rotate .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-shape .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-text .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-mask .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-icon .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-draw .tui-image-editor-submenu,
.tui-image-editor-container .tui-image-editor-main.tui-image-editor-menu-filter .tui-image-editor-submenu {
display: table;
}
.tui-image-editor-container .filter-color-item {
display: inline-block;
}
.tui-image-editor-container .filter-color-item .tui-image-editor-checkbox {
display: block;
}
.tui-image-editor-container .tui-image-editor-checkbox-wrap {
display: inline-block !important;
text-align: left;
}
.tui-image-editor-container .tui-image-editor-checkbox-wrap.fixed-width {
width: 187px;
white-space: normal;
}
.tui-image-editor-container .tui-image-editor-checkbox {
display: inline-block;
margin: 1px 0 1px 0;
}
.tui-image-editor-container .tui-image-editor-checkbox input {
width: 14px;
height: 14px;
opacity: 0;
}
.tui-image-editor-container .tui-image-editor-checkbox input + label {
color: #fff;
height: 14px;
position: relative;
}
.tui-image-editor-container .tui-image-editor-checkbox input + label:before {
content: '';
position: absolute;
width: 14px;
height: 14px;
background-color: #fff;
top: 6px;
left: -19px;
display: inline-block;
margin: 0;
text-align: center;
font-size: 11px;
border: 0;
border-radius: 2px;
padding-top: 1px;
box-sizing: border-box;
}
.tui-image-editor-container .tui-image-editor-checkbox input[type='checkbox']:checked + label:before {
background-size: cover;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAMBJREFUKBWVkjEOwjAMRe2WgZW7IIHEDdhghhuwcQ42rlJugAQS54Cxa5cq1QM5TUpByZfS2j9+dlJVt/tX5ZxbS4ZU9VLkQvSHKTIGRaVJYFmKrBbTCJxE2UgCdDzMZDkHrOV6b95V0US6UmgKodujEZbJg0B0ZgEModO5lrY1TMQf1TpyJGBEjD+E2NPN7ukIUDiF/BfEXgRiGEw8NgkffYGYwCi808fpn/6OvfUfsDr/Vc1IfRf8sKnFVqeiVQfDu0tf/nWH9gAAAABJRU5ErkJggg==");
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap {
position: relative;
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap select {
width: 100%;
height: 28px;
margin-top: 4px;
border: 0;
outline: 0;
border-radius: 0;
border: 1px solid #cbdbdb;
background-color: #fff;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0 7px 0 10px;
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap .tui-image-editor-selectlist {
display: none;
position: relative;
top: -1px;
border: 1px solid #ccc;
background-color: #fff;
border-top: 0px;
padding: 4px 0;
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap .tui-image-editor-selectlist li {
display: block;
text-align: left;
padding: 7px 10px;
font-family: 'Noto Sans', sans-serif;
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap .tui-image-editor-selectlist li:hover {
background-color: rgba(81,92,230,0.05);
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap:before {
content: '';
position: absolute;
display: inline-block;
width: 14px;
height: 14px;
right: 5px;
top: 10px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAHlJREFUKBVjYBgFOEOAEVkmPDxc89+/f6eAYjzI4kD2FyYmJrOVK1deh4kzwRggGiQBVJCELAZig8SQNYHEmEEEMrh69eo1HR0dfqCYJUickZGxf9WqVf3IakBsFBthklpaWmVA9mEQhrJhUoTp0NBQCRAmrHL4qgAAuu4cWZOZIGsAAAAASUVORK5CYII=");
background-size: cover;
}
.tui-image-editor-container .tui-image-editor-selectlist-wrap select::-ms-expand {
display: none;
}
.tui-image-editor-container .tui-image-editor-virtual-range-bar .tui-image-editor-disabled,
.tui-image-editor-container .tui-image-editor-virtual-range-subbar .tui-image-editor-disabled,
.tui-image-editor-container .tui-image-editor-virtual-range-pointer .tui-image-editor-disabled {
backbround-color: #f00;
}
.tui-image-editor-container .tui-image-editor-range {
position: relative;
top: 5px;
width: 166px;
height: 17px;
display: inline-block;
}
.tui-image-editor-container .tui-image-editor-virtual-range-bar {
top: 7px;
position: absolute;
width: 100%;
height: 2px;
background-color: #666;
}
.tui-image-editor-container .tui-image-editor-virtual-range-subbar {
position: absolute;
height: 100%;
left: 0;
right: 0;
background-color: #d1d1d1;
}
.tui-image-editor-container .tui-image-editor-virtual-range-pointer {
position: absolute;
cursor: pointer;
top: -5px;
left: 0;
width: 12px;
height: 12px;
background-color: #fff;
border-radius: 100%;
}
.tui-image-editor-container .tui-image-editor-range-wrap {
display: inline-block;
margin-left: 4px;
}
.tui-image-editor-container .tui-image-editor-range-wrap.short .tui-image-editor-range {
width: 100px;
}
.tui-image-editor-container .color-picker-control .tui-image-editor-range {
width: 108px;
margin-left: 10px;
}
.tui-image-editor-container .color-picker-control .tui-image-editor-virtual-range-pointer {
background-color: #333;
}
.tui-image-editor-container .color-picker-control .tui-image-editor-virtual-range-bar {
background-color: #ccc;
}
.tui-image-editor-container .color-picker-control .tui-image-editor-virtual-range-subbar {
background-color: #606060;
}
.tui-image-editor-container .tui-image-editor-range-wrap.tui-image-editor-newline.short {
margin-top: -2px;
margin-left: 19px;
}
.tui-image-editor-container .tui-image-editor-range-wrap.tui-image-editor-newline.short label {
color: #8e8e8e;
font-weight: normal;
}
.tui-image-editor-container .tui-image-editor-range-wrap label {
vertical-align: baseline;
font-size: 11px;
margin-right: 7px;
color: #fff;
}
.tui-image-editor-container .tui-image-editor-range-value {
cursor: default;
width: 40px;
height: 24px;
outline: none;
border-radius: 2px;
box-shadow: none;
border: 1px solid #d5d5d5;
text-align: center;
background-color: #1c1c1c;
color: #fff;
font-weight: lighter;
vertical-align: baseline;
font-family: 'Noto Sans', sans-serif;
margin-top: 21px;
margin-left: 4px;
}
.tui-image-editor-container .tui-image-editor-controls {
position: absolute;
background-color: #151515;
width: 100%;
height: 64px;
display: table;
bottom: 0;
z-index: 2;
}
.tui-image-editor-container .tui-image-editor-icpartition {
display: inline-block;
background-color: #282828;
width: 1px;
height: 24px;
}
.tui-image-editor-container.left .tui-image-editor-menu > .tui-image-editor-item[title]:before {
left: 28px;
top: 11px;
border-right: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
}
.tui-image-editor-container.left .tui-image-editor-menu > .tui-image-editor-item[title]:after {
top: 7px;
left: 39px;
white-space: nowrap;
}
.tui-image-editor-container.left .tui-image-editor-submenu {
left: 0;
height: 100%;
width: 248px;
}
.tui-image-editor-container.left .tui-image-editor-main-container {
left: 64px;
width: calc(100% - 64px);
height: 100%;
}
.tui-image-editor-container.left .tui-image-editor-controls {
width: 64px;
height: 100%;
display: table;
}
.tui-image-editor-container.left .tui-image-editor-menu,
.tui-image-editor-container.right .tui-image-editor-menu {
white-space: inherit;
}
.tui-image-editor-container.left .tui-image-editor-submenu,
.tui-image-editor-container.right .tui-image-editor-submenu {
white-space: normal;
}
.tui-image-editor-container.left .tui-image-editor-submenu > div,
.tui-image-editor-container.right .tui-image-editor-submenu > div {
vertical-align: middle;
}
.tui-image-editor-container.left .tui-image-editor-controls li,
.tui-image-editor-container.right .tui-image-editor-controls li {
display: inline-block;
margin: 4px auto;
}
.tui-image-editor-container.left .tui-image-editor-icpartition,
.tui-image-editor-container.right .tui-image-editor-icpartition {
position: relative;
top: -7px;
width: 24px;
height: 1px;
}
.tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-partition,
.tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-partition {
display: block;
width: 75%;
margin: auto;
}
.tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-partition > div,
.tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-partition > div {
border-left: 0;
height: 10px;
border-bottom: 1px solid #3c3c3c;
width: 100%;
margin: 0;
}
.tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-submenu-align,
.tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-submenu-align {
margin-right: 0;
}
.tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-submenu-item li,
.tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-submenu-item li {
margin-top: 15px;
}
.tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-colorpicker-clearfix li,
.tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-submenu-item .tui-colorpicker-clearfix li {
margin-top: 0;
}
.tui-image-editor-container.left .tui-image-editor-checkbox-wrap.fixed-width,
.tui-image-editor-container.right .tui-image-editor-checkbox-wrap.fixed-width {
width: 182px;
white-space: normal;
}
.tui-image-editor-container.left .tui-image-editor-range-wrap.tui-image-editor-newline label.range,
.tui-image-editor-container.right .tui-image-editor-range-wrap.tui-image-editor-newline label.range {
display: block;
text-align: left;
width: 75%;
margin: auto;
}
.tui-image-editor-container.left .tui-image-editor-range,
.tui-image-editor-container.right .tui-image-editor-range {
width: 136px;
}
.tui-image-editor-container.right .tui-image-editor-menu > .tui-image-editor-item[title]:before {
left: -3px;
top: 11px;
border-left: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
}
.tui-image-editor-container.right .tui-image-editor-menu > .tui-image-editor-item[title]:after {
top: 7px;
left: -44px;
white-space: nowrap;
}
.tui-image-editor-container.right .tui-image-editor-submenu {
right: 0;
height: 100%;
width: 248px;
}
.tui-image-editor-container.right .tui-image-editor-main-container {
right: 64px;
width: calc(100% - 64px);
height: 100%;
}
.tui-image-editor-container.right .tui-image-editor-controls {
right: 0;
width: 64px;
height: 100%;
display: table;
}
.tui-image-editor-container.top .tui-image-editor-submenu .tui-image-editor-partition.only-left-right,
.tui-image-editor-container.bottom .tui-image-editor-submenu .tui-image-editor-partition.only-left-right {
display: none;
}
.tui-image-editor-container.bottom .tui-image-editor-submenu > div {
padding-bottom: 24px;
}
.tui-image-editor-container.top .color-picker-control .triangle {
top: -8px;
border-right: 7px solid transparent;
border-top: 0px;
border-left: 7px solid transparent;
border-bottom: 8px solid #fff;
}
.tui-image-editor-container.top .tui-image-editor-size-wrap {
height: 100%;
}
.tui-image-editor-container.top .tui-image-editor-main-container {
bottom: 0;
}
.tui-image-editor-container.top .tui-image-editor-menu > .tui-image-editor-item[title]:before {
left: 13px;
border-top: 0;
border-bottom: 7px solid #2f2f2f;
top: 33px;
}
.tui-image-editor-container.top .tui-image-editor-menu > .tui-image-editor-item[title]:after {
top: 38px;
}
.tui-image-editor-container.top .tui-image-editor-submenu {
top: 0;
bottom: inherit;
}
.tui-image-editor-container.top .tui-image-editor-submenu > div {
padding-top: 24px;
vertical-align: top;
}
.tui-image-editor-container.top .tui-image-editor-controls-logo {
display: table-cell;
}
.tui-image-editor-container.top .tui-image-editor-controls-buttons {
display: table-cell;
}
.tui-image-editor-container.top .tui-image-editor-main {
top: 64px;
height: calc(100% - 64px);
}
.tui-image-editor-container.top .tui-image-editor-controls {
top: 0;
bottom: inherit;
}
.tui-image-editor-container #tie-icon-add-button .tui-image-editor-button {
min-width: 42px;
}
.tui-image-editor-container .svg_ic-menu {
width: 24px;
height: 24px;
}
.tui-image-editor-container .svg_ic-submenu {
width: 32px;
height: 32px;
}
.tui-image-editor-container .svg_img-bi {
width: 257px;
height: 26px;
}
.tui-image-editor-container .tui-image-editor-controls svg > use {
display: none;
}
.tui-image-editor-container .tui-image-editor-controls .enabled svg:hover > use.hover,
.tui-image-editor-container .tui-image-editor-controls .normal svg:hover > use.hover {
display: block;
}
.tui-image-editor-container .tui-image-editor-controls .active svg:hover > use.hover {
display: none;
}
.tui-image-editor-container .tui-image-editor-controls svg > use.normal {
display: block;
}
.tui-image-editor-container .tui-image-editor-controls .active svg > use.active {
display: block;
}
.tui-image-editor-container .tui-image-editor-controls .enabled svg > use.enabled {
display: block;
}
.tui-image-editor-container .tui-image-editor-controls .active svg > use.normal,
.tui-image-editor-container .tui-image-editor-controls .enabled svg > use.normal {
display: none;
}
.tui-image-editor-container .tui-image-editor-controls:hover {
z-index: 3;
}
.tui-image-editor-container div.tui-colorpicker-clearfix {
width: 159px;
height: 28px;
border: 1px solid #d5d5d5;
border-radius: 2px;
background-color: #f5f5f5;
margin-top: 6px;
padding: 4px 7px 4px 7px;
}
.tui-image-editor-container .tui-colorpicker-palette-hex {
width: 114px;
background-color: #f5f5f5;
border: 0;
font-size: 11px;
margin-top: 2px;
font-family: 'Noto Sans', sans-serif;
}
.tui-image-editor-container .tui-colorpicker-palette-hex[value='#ffffff'] + .tui-colorpicker-palette-preview,
.tui-image-editor-container .tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview {
border: 1px solid #ccc;
}
.tui-image-editor-container .tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview {
background-size: cover;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAdBJREFUWAnFl0FuwjAQRZ0ukiugHqFSOQNdseuKW3ALzkA4BateICvUGyCxrtRFd4WuunH/TzykaYJrnLEYaTJJsP2+x8GZZCbQrLU5mj7Bn+EP8HvnCObd+R7xBV5lWfaNON4AnsA38E94qLEt+0yiFaBzAV/Bv+Cxxr4co7hKCDpw1q9wLeNYYdlAwyn8TYt8Hme3+8D5ozcTaMCZ68PXa2tnM2sbEcOZAJhrrpl2DAcTOGNjZPSfCdzkw6JrfbiMv+osBe4y9WOedhm4jZfhbENWuxS44H9Wz/xw4WzqLOAqh1+zycgAwzEMzr5k5gaHOa9ULBwuuDkFlHI1Kl4PJ66kgIpnoywOTmRFAYcbwYk9UMApWkD8zAV5ihcwHk4Rx7gl0IFTQL0EFc+CTQ9OZHWH3YhlVJiVpTHbrTGLhTHLZVgff6s9lyBsI9KduSS83oj+34rTwJutmBmCnMsvozRwZqB5GTkBw6/jdPDu69iJ6BYk6eCcfbcgcQIK/MByaaiMqm8rHcjol2TnpWDhyAKSGdA3FrxtJUToX0ODqatetfGE+8tyEUOV8GY5dGRwLP/MBS4RHQr4bT7NRAQjlcOTfZxmv2G+c4hI8nn+Ax5PG/zhI393AAAAAElFTkSuQmCC");
}
.tui-image-editor-container .tui-colorpicker-palette-preview {
border-radius: 100%;
float: left;
width: 17px;
height: 17px;
border: 0;
}
.tui-image-editor-container .color-picker-control {
position: absolute;
display: none;
z-index: 99;
width: 192px;
background-color: #fff;
box-shadow: 0 3px 22px 6px rgba(0,0,0,0.15);
padding: 16px;
border-radius: 2px;
}
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-toggle-slider {
display: none;
}
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-button {
border: 0;
border-radius: 100%;
margin: 2px;
background-size: cover;
font-size: 1px;
}
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-button[title='#ffffff'] {
border: 1px solid #ccc;
}
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-button[title=''] {
border: 1px solid #ccc;
}
.tui-image-editor-container .color-picker-control .triangle {
width: 0;
height: 0;
border-right: 7px solid transparent;
border-top: 8px solid #fff;
border-left: 7px solid transparent;
position: absolute;
bottom: -8px;
left: 84px;
}
.tui-image-editor-container .color-picker-control .tui-colorpicker-container,
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-container ul,
.tui-image-editor-container .color-picker-control .tui-colorpicker-palette-container {
width: 100%;
height: auto;
}
.tui-image-editor-container .filter-color-item .color-picker-control label {
font-color: #333;
font-weight: normal;
margin-right: 7pxleft;
}
.tui-image-editor-container .filter-color-item .tui-image-editor-checkbox {
margin-top: 0;
}
.tui-image-editor-container .filter-color-item .tui-image-editor-checkbox input + label:before {
left: -16px;
}
.tui-image-editor-container .color-picker {
width: 100%;
height: auto;
}
.tui-image-editor-container .color-picker-value {
width: 32px;
height: 32px;
border: 0px;
border-radius: 100%;
margin: auto;
margin-bottom: 1px;
}
.tui-image-editor-container .color-picker-value.transparent {
border: 1px solid #cbcbcb;
background-size: cover;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAdBJREFUWAnFl0FuwjAQRZ0ukiugHqFSOQNdseuKW3ALzkA4BateICvUGyCxrtRFd4WuunH/TzykaYJrnLEYaTJJsP2+x8GZZCbQrLU5mj7Bn+EP8HvnCObd+R7xBV5lWfaNON4AnsA38E94qLEt+0yiFaBzAV/Bv+Cxxr4co7hKCDpw1q9wLeNYYdlAwyn8TYt8Hme3+8D5ozcTaMCZ68PXa2tnM2sbEcOZAJhrrpl2DAcTOGNjZPSfCdzkw6JrfbiMv+osBe4y9WOedhm4jZfhbENWuxS44H9Wz/xw4WzqLOAqh1+zycgAwzEMzr5k5gaHOa9ULBwuuDkFlHI1Kl4PJ66kgIpnoywOTmRFAYcbwYk9UMApWkD8zAV5ihcwHk4Rx7gl0IFTQL0EFc+CTQ9OZHWH3YhlVJiVpTHbrTGLhTHLZVgff6s9lyBsI9KduSS83oj+34rTwJutmBmCnMsvozRwZqB5GTkBw6/jdPDu69iJ6BYk6eCcfbcgcQIK/MByaaiMqm8rHcjol2TnpWDhyAKSGdA3FrxtJUToX0ODqatetfGE+8tyEUOV8GY5dGRwLP/MBS4RHQr4bT7NRAQjlcOTfZxmv2G+c4hI8nn+Ax5PG/zhI393AAAAAElFTkSuQmCC");
}
.tui-image-editor-container .color-picker-value + label {
color: #fff;
}
.tui-image-editor-container .tui-image-editor-submenu svg > use {
display: none;
}
.tui-image-editor-container .tui-image-editor-submenu svg > use.normal {
display: block;
}
#tie-icon-add-button.icon-bubble .tui-image-editor-button[data-icontype="icon-bubble"] svg > use.active,
#tie-icon-add-button.icon-heart .tui-image-editor-button[data-icontype="icon-heart"] svg > use.active,
#tie-icon-add-button.icon-location .tui-image-editor-button[data-icontype="icon-location"] svg > use.active,
#tie-icon-add-button.icon-polygon .tui-image-editor-button[data-icontype="icon-polygon"] svg > use.active,
#tie-icon-add-button.icon-star .tui-image-editor-button[data-icontype="icon-star"] svg > use.active,
#tie-icon-add-button.icon-star-2 .tui-image-editor-button[data-icontype="icon-star-2"] svg > use.active,
#tie-icon-add-button.icon-arrow-3 .tui-image-editor-button[data-icontype="icon-arrow-3"] svg > use.active,
#tie-icon-add-button.icon-arrow-2 .tui-image-editor-button[data-icontype="icon-arrow-2"] svg > use.active,
#tie-icon-add-button.icon-arrow .tui-image-editor-button[data-icontype="icon-arrow"] svg > use.active {
display: block;
}
#tie-draw-line-select-button.line .tui-image-editor-button.line svg > use.normal,
#tie-draw-line-select-button.free .tui-image-editor-button.free svg > use.normal {
display: none;
}
#tie-draw-line-select-button.line .tui-image-editor-button.line svg > use.active,
#tie-draw-line-select-button.free .tui-image-editor-button.free svg > use.active {
display: block;
}
#tie-flip-button.resetFlip .tui-image-editor-button.resetFlip svg > use.normal,
#tie-flip-button.flipX .tui-image-editor-button.flipX svg > use.normal,
#tie-flip-button.flipY .tui-image-editor-button.flipY svg > use.normal {
display: none;
}
#tie-flip-button.resetFlip .tui-image-editor-button.resetFlip svg > use.active,
#tie-flip-button.flipX .tui-image-editor-button.flipX svg > use.active,
#tie-flip-button.flipY .tui-image-editor-button.flipY svg > use.active {
display: block;
}
#tie-mask-apply.apply.active .tui-image-editor-button.apply label {
color: #fff;
}
#tie-mask-apply.apply.active .tui-image-editor-button.apply svg > use.active {
display: block;
}
#tie-crop-button .tui-image-editor-button.apply,
#tie-crop-preset-button .tui-image-editor-button.apply {
margin-right: 24px;
}
#tie-crop-button .tui-image-editor-button.preset.active svg > use.active,
#tie-crop-preset-button .tui-image-editor-button.preset.active svg > use.active {
display: block;
}
#tie-crop-button .tui-image-editor-button.apply.active svg > use.active,
#tie-crop-preset-button .tui-image-editor-button.apply.active svg > use.active {
display: block;
}
#tie-shape-button.rect .tui-image-editor-button.rect svg > use.normal,
#tie-shape-button.circle .tui-image-editor-button.circle svg > use.normal,
#tie-shape-button.triangle .tui-image-editor-button.triangle svg > use.normal {
display: none;
}
#tie-shape-button.rect .tui-image-editor-button.rect svg > use.active,
#tie-shape-button.circle .tui-image-editor-button.circle svg > use.active,
#tie-shape-button.triangle .tui-image-editor-button.triangle svg > use.active {
display: block;
}
#tie-text-effect-button .tui-image-editor-button.active svg > use.active {
display: block;
}
#tie-text-align-button.left .tui-image-editor-button.left svg > use.active,
#tie-text-align-button.center .tui-image-editor-button.center svg > use.active,
#tie-text-align-button.right .tui-image-editor-button.right svg > use.active {
display: block;
}
#tie-mask-image-file,
#tie-icon-image-file {
opacity: 0;
position: absolute;
width: 100%;
height: 100%;
border: 1px solid #008000;
cursor: inherit;
left: 0;
top: 0;
}
.tui-image-editor-container.top.tui-image-editor-top-optimization .tui-image-editor-controls ul {
text-align: right;
}
.tui-image-editor-container.top.tui-image-editor-top-optimization .tui-image-editor-controls-logo {
display: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,235 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs>
<circle id="a" cx="16" cy="16" r="16"/>
</defs><symbol id="icon-a-ic-apply" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#434343" d="M4 12.011l5 5L20.011 6"/>
</g>
</symbol><symbol id="icon-a-ic-cancel" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#434343" d="M6 6l12 12M18 6L6 18"/>
</g>
</symbol><symbol id="icon-a-ic-color-transparent-w" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<g>
<use fill="#FFF" xlink:href="#a"/>
<circle cx="16" cy="16" r="15.5" stroke="#D5D5D5"/>
</g>
<path stroke="#FF4040" stroke-width="1.5" d="M27 5L5 27"/>
</g>
</symbol><symbol id="icon-a-ic-crop" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#434343" d="M4 0h1v20a1 1 0 0 1-1-1V0zM20 17h-1V5h1v12zm0 2v5h-1v-5h1z"/>
<path fill="#434343" d="M5 19h19v1H5zM4.762 4v1H0V4h4.762zM7 4h12a1 1 0 0 1 1 1H7V4z"/>
</g>
</symbol><symbol id="icon-a-ic-delete-all" viewBox="0 0 24 24">
<g fill="#434343" fill-rule="evenodd">
<path d="M5 23H3a1 1 0 0 1-1-1V6h1v16h2v1zm16-10h-1V6h1v7zM9 13H8v-3h1v3zm3 0h-1v-3h1v3zm3 0h-1v-3h1v3zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM11.286 21H8.714L8 23H7l1-2.8V20h.071L9.5 16h1l1.429 4H12v.2l1 2.8h-1l-.714-2zm-.357-1L10 17.4 9.071 20h1.858zM20 22h3v1h-4v-7h1v6zm-5 0h3v1h-4v-7h1v6z"/>
</g>
</symbol><symbol id="icon-a-ic-delete" viewBox="0 0 24 24">
<g fill="#434343" fill-rule="evenodd">
<path d="M3 6v16h17V6h1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h1zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM8 10h1v6H8v-6zm3 0h1v6h-1v-6zm3 0h1v6h-1v-6z"/>
</g>
</symbol><symbol id="icon-a-ic-draw-free" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M2.5 20.929C2.594 10.976 4.323 6 7.686 6c5.872 0 2.524 19 7.697 19s1.89-14.929 6.414-14.929 1.357 10.858 5.13 10.858c1.802 0 2.657-2.262 2.566-6.786"/>
</g>
</symbol><symbol id="icon-a-ic-draw-line" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M2 15.5h28"/>
</g>
</symbol><symbol id="icon-a-ic-draw" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#434343" d="M2.5 21.5H5c.245 0 .48-.058.691-.168l.124-.065.14.01c.429.028.85-.127 1.16-.437L22.55 5.405a.5.5 0 0 0 0-.707l-3.246-3.245a.5.5 0 0 0-.707 0L3.162 16.888a1.495 1.495 0 0 0-.437 1.155l.01.14-.065.123c-.111.212-.17.448-.17.694v2.5z"/>
<path fill="#434343" d="M16.414 3.707l3.89 3.89-.708.706-3.889-3.889z"/>
</g>
</symbol><symbol id="icon-a-ic-filter" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#434343" d="M12 7v1H2V7h10zm6 0h4v1h-4V7zM12 16v1h10v-1H12zm-6 0H2v1h4v-1z"/>
<path fill="#434343" d="M8.5 20a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM15.5 11a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</g>
</symbol><symbol id="icon-a-ic-flip-reset" viewBox="0 0 31 32">
<g fill="none" fill-rule="evenodd">
<path d="M31 0H0v32h31z"/>
<path fill="#434343" d="M28 16a8 8 0 0 1-8 8H3v-1h1v-7H3a8 8 0 0 1 8-8h17v1h-1v7h1zM11 9a7 7 0 0 0-7 7v7h16a7 7 0 0 0 7-7V9H11z"/>
<path stroke="#434343" stroke-linecap="square" d="M24 5l3.5 3.5L24 12M7 20l-3.5 3.5L7 27"/>
</g>
</symbol><symbol id="icon-a-ic-flip-x" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M32 32H0V0h32z"/>
<path fill="#434343" d="M17 32h-1V0h1zM27.167 11l.5 3h-1.03l-.546-3h1.076zm-.5-3h-1.122L25 5h-5V4h5.153a1 1 0 0 1 .986.836L26.667 8zm1.5 9l.5 3h-.94l-.545-3h.985zm1 6l.639 3.836A1 1 0 0 1 28.819 28H26v-1h3l-.726-4h.894zM23 28h-3v-1h3v1zM13 4v1H7L3 27h10v1H3.18a1 1 0 0 1-.986-1.164l3.666-22A1 1 0 0 1 6.847 4H13z"/>
</g>
</symbol><symbol id="icon-a-ic-flip-y" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0v32h32V0z"/>
<path fill="#434343" d="M0 16v1h32v-1zM11 27.167l3 .5v-1.03l-3-.546v1.076zm-3-.5v-1.122L5 25v-5H4v5.153a1 1 0 0 0 .836.986L8 26.667zm9 1.5l3 .5v-.94l-3-.545v.985zm6 1l3.836.639A1 1 0 0 0 28 28.82V26h-1v3l-4-.727v.894zM28 23v-3h-1v3h1zM4 13h1V7l22-4v10h1V3.18a1 1 0 0 0-1.164-.986l-22 3.667A1 1 0 0 0 4 6.847V13z"/>
</g>
</symbol><symbol id="icon-a-ic-flip" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#434343" d="M11 0h1v24h-1zM19 21v-1h2v-2h1v2a1 1 0 0 1-1 1h-2zm-2 0h-3v-1h3v1zm5-5h-1v-3h1v3zm0-5h-1V8h1v3zm0-5h-1V4h-2V3h2a1 1 0 0 1 1 1v2zm-5-3v1h-3V3h3zM9 3v1H2v16h7v1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-arrow-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M21.793 18.5H2.5v-5h18.935l-7.6-8h5.872l10.5 10.5-10.5 10.5h-5.914l8-8z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-arrow-3" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M25.288 16.42L14.208 27.5H6.792l11.291-11.291L6.826 4.5h7.381l11.661 11.661-.58.258z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-arrow" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M2.5 11.5v9h18v5.293L30.293 16 20.5 6.207V11.5h-18z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-bubble" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M22.207 24.5L16.5 30.207V24.5H8A6.5 6.5 0 0 1 1.5 18V9A6.5 6.5 0 0 1 8 2.5h16A6.5 6.5 0 0 1 30.5 9v9a6.5 6.5 0 0 1-6.5 6.5h-1.793z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-heart" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill-rule="nonzero" stroke="#434343" d="M15.996 30.675l1.981-1.79c7.898-7.177 10.365-9.718 12.135-13.012.922-1.716 1.377-3.37 1.377-5.076 0-4.65-3.647-8.297-8.297-8.297-2.33 0-4.86 1.527-6.817 3.824l-.38.447-.381-.447C13.658 4.027 11.126 2.5 8.797 2.5 4.147 2.5.5 6.147.5 10.797c0 1.714.46 3.375 1.389 5.098 1.775 3.288 4.26 5.843 12.123 12.974l1.984 1.806z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M17.314 18.867l1.951-2.53 4 5.184h-17l6.5-8.84 4.549 6.186z"/>
<path fill="#434343" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01z"/>
<path fill="#434343" d="M25 3h1v9h-1z"/>
<path stroke="#434343" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-a-ic-icon-location" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<g stroke="#434343">
<path d="M16 31.28C23.675 23.302 27.5 17.181 27.5 13c0-6.351-5.149-11.5-11.5-11.5S4.5 6.649 4.5 13c0 4.181 3.825 10.302 11.5 18.28z"/>
<circle cx="16" cy="13" r="4.5"/>
</g>
</g>
</symbol><symbol id="icon-a-ic-icon-polygon" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M.576 16L8.29 29.5h15.42L31.424 16 23.71 2.5H8.29L.576 16z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-star-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M19.446 31.592l2.265-3.272 3.946.25.636-3.94 3.665-1.505-1.12-3.832 2.655-2.962-2.656-2.962 1.12-3.832-3.664-1.505-.636-3.941-3.946.25-2.265-3.271L16 3.024 12.554 1.07 10.289 4.34l-3.946-.25-.636 3.941-3.665 1.505 1.12 3.832L.508 16.33l2.656 2.962-1.12 3.832 3.664 1.504.636 3.942 3.946-.25 2.265 3.27L16 29.638l3.446 1.955z"/>
</g>
</symbol><symbol id="icon-a-ic-icon-star" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" d="M25.292 29.878l-1.775-10.346 7.517-7.327-10.388-1.51L16 1.282l-4.646 9.413-10.388 1.51 7.517 7.327-1.775 10.346L16 24.993l9.292 4.885z"/>
</g>
</symbol><symbol id="icon-a-ic-icon" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M11.923 19.136L5.424 22l.715-7.065-4.731-5.296 6.94-1.503L11.923 2l3.574 6.136 6.94 1.503-4.731 5.296L18.42 22z"/>
</g>
</symbol><symbol id="icon-a-ic-mask-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01zM15 23a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-1a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
<path fill="#434343" d="M25 3h1v9h-1z"/>
<path stroke="#434343" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-a-ic-mask" viewBox="0 0 24 24">
<g fill="none">
<circle cx="12" cy="12" r="4.5" stroke="#434343"/>
<path fill="#434343" d="M2 1h20a1 1 0 0 1 1 1v20a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm0 1v20h20V2H2z"/>
</g>
</symbol><symbol id="icon-a-ic-redo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#434343" d="M21 6H9a6 6 0 1 0 0 12h12v1H9A7 7 0 0 1 9 5h12v1z"/>
<path stroke="#434343" stroke-linecap="square" d="M19 3l2.5 2.5L19 8"/>
</g>
</symbol><symbol id="icon-a-ic-reset" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#434343" d="M2 13v-1a7 7 0 0 1 7-7h13v1h-1v5h1v1a7 7 0 0 1-7 7H2v-1h1v-5H2zm7-7a6 6 0 0 0-6 6v6h12a6 6 0 0 0 6-6V6H9z"/>
<path stroke="#434343" stroke-linecap="square" d="M19 3l2.5 2.5L19 8M5 16l-2.5 2.5L5 21"/>
</g>
</symbol><symbol id="icon-a-ic-rotate-clockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#434343" d="M29 17h-.924c0 6.627-5.373 12-12 12-6.628 0-12-5.373-12-12C4.076 10.398 9.407 5.041 16 5V4C8.82 4 3 9.82 3 17s5.82 13 13 13 13-5.82 13-13z"/>
<path stroke="#434343" stroke-linecap="square" d="M16 1.5l4 3-4 3"/>
<path fill="#434343" fill-rule="nonzero" d="M16 4h4v1h-4z"/>
</g>
</symbol><symbol id="icon-a-ic-rotate-counterclockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#434343" d="M3 17h.924c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.602-5.331-11.96-11.924-12V4c7.18 0 13 5.82 13 13s-5.82 13-13 13S3 24.18 3 17z"/>
<path fill="#434343" fill-rule="nonzero" d="M12 4h4v1h-4z"/>
<path stroke="#434343" stroke-linecap="square" d="M16 1.5l-4 3 4 3"/>
</g>
</symbol><symbol id="icon-a-ic-rotate" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#434343" d="M8.349 22.254a10.002 10.002 0 0 1-2.778-1.719l.65-.76a9.002 9.002 0 0 0 2.495 1.548l-.367.931zm2.873.704l.078-.997a9 9 0 1 0-.557-17.852l-.14-.99A10.076 10.076 0 0 1 12.145 3c5.523 0 10 4.477 10 10s-4.477 10-10 10c-.312 0-.62-.014-.924-.042zm-7.556-4.655a9.942 9.942 0 0 1-1.253-2.996l.973-.234a8.948 8.948 0 0 0 1.124 2.693l-.844.537zm-1.502-5.91A9.949 9.949 0 0 1 2.88 9.23l.925.382a8.954 8.954 0 0 0-.644 2.844l-.998-.062zm2.21-5.686c.687-.848 1.51-1.58 2.436-2.166l.523.852a9.048 9.048 0 0 0-2.188 1.95l-.771-.636z"/>
<path stroke="#434343" stroke-linecap="square" d="M13 1l-2.5 2.5L13 6"/>
</g>
</symbol><symbol id="icon-a-ic-shape-circle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<circle cx="16" cy="16" r="14.5" stroke="#434343"/>
</g>
</symbol><symbol id="icon-a-ic-shape-rectangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<rect width="27" height="27" x="2.5" y="2.5" stroke="#434343" rx="1"/>
</g>
</symbol><symbol id="icon-a-ic-shape-triangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M16 2.5l15.5 27H.5z"/>
</g>
</symbol><symbol id="icon-a-ic-shape" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#434343" d="M14.706 8H21a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-4h1v4h12V9h-5.706l-.588-1z"/>
<path stroke="#434343" stroke-linecap="round" stroke-linejoin="round" d="M8.5 1.5l7.5 13H1z"/>
</g>
</symbol><symbol id="icon-a-ic-text-align-center" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M2 5h28v1H2zM8 12h16v1H8zM2 19h28v1H2zM8 26h16v1H8z"/>
</g>
</symbol><symbol id="icon-a-ic-text-align-left" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M2 5h28v1H2zM2 12h16v1H2zM2 19h28v1H2zM2 26h16v1H2z"/>
</g>
</symbol><symbol id="icon-a-ic-text-align-right" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M2 5h28v1H2zM14 12h16v1H14zM2 19h28v1H2zM14 26h16v1H14z"/>
</g>
</symbol><symbol id="icon-a-ic-text-bold" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M7 2h2v2H7zM7 28h2v2H7z"/>
<path stroke="#434343" stroke-width="2" d="M9 3v12h9a6 6 0 1 0 0-12H9zM9 15v14h10a7 7 0 0 0 0-14H9z"/>
</g>
</symbol><symbol id="icon-a-ic-text-italic" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M15 2h5v1h-5zM11 29h5v1h-5zM17 3h1l-4 26h-1z"/>
</g>
</symbol><symbol id="icon-a-ic-text-underline" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#434343" d="M8 2v14a8 8 0 1 0 16 0V2h1v14a9 9 0 0 1-18 0V2h1zM3 29h26v1H3z"/>
<path fill="#434343" d="M5 2h5v1H5zM22 2h5v1h-5z"/>
</g>
</symbol><symbol id="icon-a-ic-text" viewBox="0 0 24 24">
<g fill="#434343" fill-rule="evenodd">
<path d="M4 3h15a1 1 0 0 1 1 1H3a1 1 0 0 1 1-1zM3 4h1v1H3zM19 4h1v1h-1z"/>
<path d="M11 3h1v18h-1z"/>
<path d="M10 20h3v1h-3z"/>
</g>
</symbol><symbol id="icon-a-ic-undo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M24 0H0v24h24z" opacity=".5"/>
<path fill="#434343" d="M3 6h12a6 6 0 1 1 0 12H3v1h12a7 7 0 0 0 0-14H3v1z"/>
<path stroke="#434343" stroke-linecap="square" d="M5 3L2.5 5.5 5 8"/>
</g>
</symbol><symbol id="icon-a-img-bi" viewBox="0 0 257 26">
<g fill="#FDBA3B">
<path d="M26 5a8.001 8.001 0 0 0 0 16 8.001 8.001 0 0 0 0-16M51.893 19.812L43.676 5.396A.78.78 0 0 0 43 5a.78.78 0 0 0-.677.396l-8.218 14.418a.787.787 0 0 0 0 .792c.14.244.396.394.676.394h16.436c.28 0 .539-.15.678-.396a.796.796 0 0 0-.002-.792M15.767 5.231A.79.79 0 0 0 15.21 5H.791A.791.791 0 0 0 0 5.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M85.767 5.231A.79.79 0 0 0 85.21 5H70.791a.791.791 0 0 0-.791.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M65.942 9.948l2.17-3.76a.78.78 0 0 0 0-.792.791.791 0 0 0-.684-.396h-8.54A5.889 5.889 0 0 0 53 10.86a5.887 5.887 0 0 0 3.07 5.17l-2.184 3.782A.792.792 0 0 0 54.571 21h8.54a5.89 5.89 0 0 0 2.831-11.052M105.7 21h2.3V5h-2.3zM91 5h2.4v10.286c0 1.893 1.612 3.429 3.6 3.429s3.6-1.536 3.6-3.429V5h2.4v10.286c0 3.156-2.686 5.714-6 5.714-3.313 0-6-2.558-6-5.714V5zM252.148 21.128h-2.377V9.659h2.27v1.64c.69-1.299 1.792-1.938 3.304-1.938.497 0 .95.065 1.382.192l-.215 2.277a3.734 3.734 0 0 0-1.275-.213c-1.814 0-3.089 1.234-3.089 3.638v5.873zm-7.095-5.744a3.734 3.734 0 0 0-1.101-2.703c-.714-.766-1.6-1.149-2.658-1.149-1.058 0-1.944.383-2.679 1.149a3.803 3.803 0 0 0-1.08 2.703c0 1.063.368 1.978 1.08 2.722.735.746 1.62 1.128 2.68 1.128 1.058 0 1.943-.382 2.657-1.128.734-.744 1.101-1.659 1.101-2.722zm-9.916 0c0-1.682.583-3.086 1.729-4.256 1.166-1.17 2.635-1.767 4.428-1.767 1.793 0 3.262.597 4.407 1.767 1.167 1.17 1.75 2.574 1.75 4.256 0 1.7-.583 3.127-1.75 4.297-1.145 1.17-2.614 1.745-4.407 1.745-1.793 0-3.262-.575-4.428-1.745-1.146-1.17-1.729-2.596-1.729-4.297zm-1.5 3.233l.821 1.83c-.864.638-1.944.958-3.22.958-2.526 0-3.822-1.554-3.822-4.383V11.66h-2.01v-2h2.031V5.595h2.355v4.063h4.018v2h-4.018v5.405c0 1.469.605 2.191 1.793 2.191.626 0 1.318-.212 2.052-.638zm-12.43 2.51h2.375V9.66h-2.376v11.469zm1.23-12.977c-.929 0-1.642-.682-1.642-1.596 0-.873.713-1.554 1.643-1.554.885 0 1.576.681 1.576 1.554 0 .914-.69 1.596-1.576 1.596zm-6.49 7.234c0-1.086-.346-1.98-1.037-2.724-.692-.745-1.599-1.128-2.7-1.128-1.102 0-2.01.383-2.7 1.128-.692.744-1.037 1.638-1.037 2.724 0 1.084.345 2.02 1.036 2.766.691.744 1.6 1.105 2.7 1.105 1.102 0 2.01-.361 2.7-1.105.692-.746 1.038-1.682 1.038-2.766zm-.173-4.129V5h2.397v16.128h-2.354v-1.596c-1.015 1.255-2.333 1.873-3.91 1.873-1.663 0-3.068-.575-4.169-1.724-1.102-1.17-1.663-2.596-1.663-4.297 0-1.682.561-3.107 1.663-4.256 1.101-1.17 2.485-1.745 4.148-1.745 1.534 0 2.83.617 3.888 1.872zm-11.48 9.873h-10.218V5.405h10.195v2.318h-7.711V12h7.15v2.32h-7.15v4.489h7.733v2.319zm-23.891-9.724c-1.793 0-3.132 1.192-3.478 2.979h6.783c-.194-1.808-1.555-2.979-3.305-2.979zm5.703 3.766c0 .32-.021.703-.086 1.128h-9.095c.346 1.787 1.62 3 3.867 3 1.318 0 2.916-.49 3.953-1.234l.994 1.724c-1.189.872-3.067 1.595-5.033 1.595-4.364 0-6.243-3-6.243-6.021 0-1.724.54-3.15 1.642-4.277 1.101-1.127 2.548-1.702 4.298-1.702 1.664 0 3.046.511 4.105 1.553 1.058 1.043 1.598 2.447 1.598 4.234zm-19.949 3.894c1.08 0 1.966-.362 2.68-1.085.712-.724 1.058-1.617 1.058-2.703 0-1.084-.346-2-1.059-2.701-.713-.702-1.599-1.064-2.679-1.064-1.058 0-1.944.362-2.656 1.085-.714.702-1.059 1.596-1.059 2.68 0 1.086.345 2 1.059 2.724.712.702 1.598 1.064 2.656 1.064zm3.673-7.936V9.66h2.29v10.299c0 1.85-.584 3.32-1.728 4.404-1.146 1.085-2.68 1.638-4.58 1.638-1.945 0-3.672-.553-5.206-1.638l1.037-1.808c1.296.915 2.679 1.36 4.126 1.36 2.484 0 3.996-1.51 3.996-3.637v-.83c-1.015 1.127-2.311 1.702-3.91 1.702-1.684 0-3.089-.554-4.19-1.68-1.102-1.128-1.642-2.532-1.642-4.214 0-1.68.561-3.085 1.706-4.191 1.145-1.128 2.571-1.681 4.234-1.681 1.534 0 2.83.575 3.867 1.745zm-18.07 8.127c1.102 0 1.988-.382 2.7-1.128.714-.744 1.06-1.659 1.06-2.743 0-1.065-.346-1.98-1.06-2.724-.712-.745-1.598-1.128-2.7-1.128-1.101 0-2.008.383-2.7 1.128-.691.744-1.036 1.66-1.036 2.745 0 1.084.345 2 1.037 2.745.691.744 1.598 1.105 2.7 1.105zm3.652-8V9.66h2.29v11.469h-2.29v-1.575c-1.059 1.234-2.399 1.852-3.976 1.852-1.663 0-3.067-.575-4.168-1.745-1.102-1.17-1.642-2.617-1.642-4.34 0-1.724.54-3.128 1.642-4.256 1.1-1.128 2.505-1.681 4.168-1.681 1.577 0 2.917.617 3.976 1.872zM138.79 9.34c1.404 0 2.527.448 3.37 1.34.863.873 1.295 2.086 1.295 3.596v6.852h-2.376V14.66c0-2.021-1.036-3.128-2.657-3.128-1.727 0-2.915 1.255-2.915 3.192v6.404h-2.377v-6.426c0-1.978-1.037-3.17-2.679-3.17-1.728 0-2.937 1.277-2.937 3.234v6.362h-2.377V9.659h2.333v1.66c.692-1.212 1.988-1.979 3.522-1.979 1.533.021 2.958.767 3.586 2.107.798-1.277 2.419-2.107 4.212-2.107zm-19.517 11.788h2.484V5.405h-2.484v15.723z"/>
</g>
</symbol></svg>

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,224 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs/><symbol id="icon-b-ic-apply" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#555555" d="M4 12.011l5 5L20.011 6"/>
</g>
</symbol><symbol id="icon-b-ic-cancel" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#555555" d="M6 6l12 12M18 6L6 18"/>
</g>
</symbol><symbol id="icon-b-ic-crop" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#555555" d="M4 0h1v20a1 1 0 0 1-1-1V0zM20 17h-1V5h1v12zm0 2v5h-1v-5h1z"/>
<path fill="#555555" d="M5 19h19v1H5zM4.762 4v1H0V4h4.762zM7 4h12a1 1 0 0 1 1 1H7V4z"/>
</g>
</symbol><symbol id="icon-b-ic-delete-all" viewBox="0 0 24 24">
<g fill="#555555" fill-rule="evenodd">
<path d="M5 23H3a1 1 0 0 1-1-1V6h1v16h2v1zm16-10h-1V6h1v7zM9 13H8v-3h1v3zm3 0h-1v-3h1v3zm3 0h-1v-3h1v3zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM11.286 21H8.714L8 23H7l1-2.8V20h.071L9.5 16h1l1.429 4H12v.2l1 2.8h-1l-.714-2zm-.357-1L10 17.4 9.071 20h1.858zM20 22h3v1h-4v-7h1v6zm-5 0h3v1h-4v-7h1v6z"/>
</g>
</symbol><symbol id="icon-b-ic-delete" viewBox="0 0 24 24">
<g fill="#555555" fill-rule="evenodd">
<path d="M3 6v16h17V6h1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h1zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM8 10h1v6H8v-6zm3 0h1v6h-1v-6zm3 0h1v6h-1v-6z"/>
</g>
</symbol><symbol id="icon-b-ic-draw-free" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M2.5 20.929C2.594 10.976 4.323 6 7.686 6c5.872 0 2.524 19 7.697 19s1.89-14.929 6.414-14.929 1.357 10.858 5.13 10.858c1.802 0 2.657-2.262 2.566-6.786"/>
</g>
</symbol><symbol id="icon-b-ic-draw-line" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M2 15.5h28"/>
</g>
</symbol><symbol id="icon-b-ic-draw" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#555555" d="M2.5 21.5H5c.245 0 .48-.058.691-.168l.124-.065.14.01c.429.028.85-.127 1.16-.437L22.55 5.405a.5.5 0 0 0 0-.707l-3.246-3.245a.5.5 0 0 0-.707 0L3.162 16.888a1.495 1.495 0 0 0-.437 1.155l.01.14-.065.123c-.111.212-.17.448-.17.694v2.5z"/>
<path fill="#555555" d="M16.414 3.707l3.89 3.89-.708.706-3.889-3.889z"/>
</g>
</symbol><symbol id="icon-b-ic-filter" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#555555" d="M12 7v1H2V7h10zm6 0h4v1h-4V7zM12 16v1h10v-1H12zm-6 0H2v1h4v-1z"/>
<path fill="#555555" d="M8.5 20a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM15.5 11a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</g>
</symbol><symbol id="icon-b-ic-flip-reset" viewBox="0 0 31 32">
<g fill="none" fill-rule="evenodd">
<path d="M31 0H0v32h31z"/>
<path fill="#555555" d="M28 16a8 8 0 0 1-8 8H3v-1h1v-7H3a8 8 0 0 1 8-8h17v1h-1v7h1zM11 9a7 7 0 0 0-7 7v7h16a7 7 0 0 0 7-7V9H11z"/>
<path stroke="#555555" stroke-linecap="square" d="M24 5l3.5 3.5L24 12M7 20l-3.5 3.5L7 27"/>
</g>
</symbol><symbol id="icon-b-ic-flip-x" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M32 32H0V0h32z"/>
<path fill="#555555" d="M17 32h-1V0h1zM27.167 11l.5 3h-1.03l-.546-3h1.076zm-.5-3h-1.122L25 5h-5V4h5.153a1 1 0 0 1 .986.836L26.667 8zm1.5 9l.5 3h-.94l-.545-3h.985zm1 6l.639 3.836A1 1 0 0 1 28.819 28H26v-1h3l-.726-4h.894zM23 28h-3v-1h3v1zM13 4v1H7L3 27h10v1H3.18a1 1 0 0 1-.986-1.164l3.666-22A1 1 0 0 1 6.847 4H13z"/>
</g>
</symbol><symbol id="icon-b-ic-flip-y" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0v32h32V0z"/>
<path fill="#555555" d="M0 16v1h32v-1zM11 27.167l3 .5v-1.03l-3-.546v1.076zm-3-.5v-1.122L5 25v-5H4v5.153a1 1 0 0 0 .836.986L8 26.667zm9 1.5l3 .5v-.94l-3-.545v.985zm6 1l3.836.639A1 1 0 0 0 28 28.82V26h-1v3l-4-.727v.894zM28 23v-3h-1v3h1zM4 13h1V7l22-4v10h1V3.18a1 1 0 0 0-1.164-.986l-22 3.667A1 1 0 0 0 4 6.847V13z"/>
</g>
</symbol><symbol id="icon-b-ic-flip" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#555555" d="M11 0h1v24h-1zM19 21v-1h2v-2h1v2a1 1 0 0 1-1 1h-2zm-2 0h-3v-1h3v1zm5-5h-1v-3h1v3zm0-5h-1V8h1v3zm0-5h-1V4h-2V3h2a1 1 0 0 1 1 1v2zm-5-3v1h-3V3h3zM9 3v1H2v16h7v1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-arrow-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M21.793 18.5H2.5v-5h18.935l-7.6-8h5.872l10.5 10.5-10.5 10.5h-5.914l8-8z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-arrow-3" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M25.288 16.42L14.208 27.5H6.792l11.291-11.291L6.826 4.5h7.381l11.661 11.661-.58.258z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-arrow" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M2.5 11.5v9h18v5.293L30.293 16 20.5 6.207V11.5h-18z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-bubble" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M22.207 24.5L16.5 30.207V24.5H8A6.5 6.5 0 0 1 1.5 18V9A6.5 6.5 0 0 1 8 2.5h16A6.5 6.5 0 0 1 30.5 9v9a6.5 6.5 0 0 1-6.5 6.5h-1.793z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-heart" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill-rule="nonzero" stroke="#555555" d="M15.996 30.675l1.981-1.79c7.898-7.177 10.365-9.718 12.135-13.012.922-1.716 1.377-3.37 1.377-5.076 0-4.65-3.647-8.297-8.297-8.297-2.33 0-4.86 1.527-6.817 3.824l-.38.447-.381-.447C13.658 4.027 11.126 2.5 8.797 2.5 4.147 2.5.5 6.147.5 10.797c0 1.714.46 3.375 1.389 5.098 1.775 3.288 4.26 5.843 12.123 12.974l1.984 1.806z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M17.314 18.867l1.951-2.53 4 5.184h-17l6.5-8.84 4.549 6.186z"/>
<path fill="#555555" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01z"/>
<path fill="#555555" d="M25 3h1v9h-1z"/>
<path stroke="#555555" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-b-ic-icon-location" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<g stroke="#555555">
<path d="M16 31.28C23.675 23.302 27.5 17.181 27.5 13c0-6.351-5.149-11.5-11.5-11.5S4.5 6.649 4.5 13c0 4.181 3.825 10.302 11.5 18.28z"/>
<circle cx="16" cy="13" r="4.5"/>
</g>
</g>
</symbol><symbol id="icon-b-ic-icon-polygon" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M.576 16L8.29 29.5h15.42L31.424 16 23.71 2.5H8.29L.576 16z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-star-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M19.446 31.592l2.265-3.272 3.946.25.636-3.94 3.665-1.505-1.12-3.832 2.655-2.962-2.656-2.962 1.12-3.832-3.664-1.505-.636-3.941-3.946.25-2.265-3.271L16 3.024 12.554 1.07 10.289 4.34l-3.946-.25-.636 3.941-3.665 1.505 1.12 3.832L.508 16.33l2.656 2.962-1.12 3.832 3.664 1.504.636 3.942 3.946-.25 2.265 3.27L16 29.638l3.446 1.955z"/>
</g>
</symbol><symbol id="icon-b-ic-icon-star" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" d="M25.292 29.878l-1.775-10.346 7.517-7.327-10.388-1.51L16 1.282l-4.646 9.413-10.388 1.51 7.517 7.327-1.775 10.346L16 24.993l9.292 4.885z"/>
</g>
</symbol><symbol id="icon-b-ic-icon" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M11.923 19.136L5.424 22l.715-7.065-4.731-5.296 6.94-1.503L11.923 2l3.574 6.136 6.94 1.503-4.731 5.296L18.42 22z"/>
</g>
</symbol><symbol id="icon-b-ic-mask-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01zM15 23a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-1a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
<path fill="#555555" d="M25 3h1v9h-1z"/>
<path stroke="#555555" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-b-ic-mask" viewBox="0 0 24 24">
<g fill="none">
<circle cx="12" cy="12" r="4.5" stroke="#555555"/>
<path fill="#555555" d="M2 1h20a1 1 0 0 1 1 1v20a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm0 1v20h20V2H2z"/>
</g>
</symbol><symbol id="icon-b-ic-redo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#555555" d="M21 6H9a6 6 0 1 0 0 12h12v1H9A7 7 0 0 1 9 5h12v1z"/>
<path stroke="#555555" stroke-linecap="square" d="M19 3l2.5 2.5L19 8"/>
</g>
</symbol><symbol id="icon-b-ic-reset" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#555555" d="M2 13v-1a7 7 0 0 1 7-7h13v1h-1v5h1v1a7 7 0 0 1-7 7H2v-1h1v-5H2zm7-7a6 6 0 0 0-6 6v6h12a6 6 0 0 0 6-6V6H9z"/>
<path stroke="#555555" stroke-linecap="square" d="M19 3l2.5 2.5L19 8M5 16l-2.5 2.5L5 21"/>
</g>
</symbol><symbol id="icon-b-ic-rotate-clockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#555555" d="M29 17h-.924c0 6.627-5.373 12-12 12-6.628 0-12-5.373-12-12C4.076 10.398 9.407 5.041 16 5V4C8.82 4 3 9.82 3 17s5.82 13 13 13 13-5.82 13-13z"/>
<path stroke="#555555" stroke-linecap="square" d="M16 1.5l4 3-4 3"/>
<path fill="#555555" fill-rule="nonzero" d="M16 4h4v1h-4z"/>
</g>
</symbol><symbol id="icon-b-ic-rotate-counterclockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#555555" d="M3 17h.924c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.602-5.331-11.96-11.924-12V4c7.18 0 13 5.82 13 13s-5.82 13-13 13S3 24.18 3 17z"/>
<path fill="#555555" fill-rule="nonzero" d="M12 4h4v1h-4z"/>
<path stroke="#555555" stroke-linecap="square" d="M16 1.5l-4 3 4 3"/>
</g>
</symbol><symbol id="icon-b-ic-rotate" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#555555" d="M8.349 22.254a10.002 10.002 0 0 1-2.778-1.719l.65-.76a9.002 9.002 0 0 0 2.495 1.548l-.367.931zm2.873.704l.078-.997a9 9 0 1 0-.557-17.852l-.14-.99A10.076 10.076 0 0 1 12.145 3c5.523 0 10 4.477 10 10s-4.477 10-10 10c-.312 0-.62-.014-.924-.042zm-7.556-4.655a9.942 9.942 0 0 1-1.253-2.996l.973-.234a8.948 8.948 0 0 0 1.124 2.693l-.844.537zm-1.502-5.91A9.949 9.949 0 0 1 2.88 9.23l.925.382a8.954 8.954 0 0 0-.644 2.844l-.998-.062zm2.21-5.686c.687-.848 1.51-1.58 2.436-2.166l.523.852a9.048 9.048 0 0 0-2.188 1.95l-.771-.636z"/>
<path stroke="#555555" stroke-linecap="square" d="M13 1l-2.5 2.5L13 6"/>
</g>
</symbol><symbol id="icon-b-ic-shape-circle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<circle cx="16" cy="16" r="14.5" stroke="#555555"/>
</g>
</symbol><symbol id="icon-b-ic-shape-rectangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<rect width="27" height="27" x="2.5" y="2.5" stroke="#555555" rx="1"/>
</g>
</symbol><symbol id="icon-b-ic-shape-triangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M16 2.5l15.5 27H.5z"/>
</g>
</symbol><symbol id="icon-b-ic-shape" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#555555" d="M14.706 8H21a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-4h1v4h12V9h-5.706l-.588-1z"/>
<path stroke="#555555" stroke-linecap="round" stroke-linejoin="round" d="M8.5 1.5l7.5 13H1z"/>
</g>
</symbol><symbol id="icon-b-ic-text-align-center" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M2 5h28v1H2zM8 12h16v1H8zM2 19h28v1H2zM8 26h16v1H8z"/>
</g>
</symbol><symbol id="icon-b-ic-text-align-left" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M2 5h28v1H2zM2 12h16v1H2zM2 19h28v1H2zM2 26h16v1H2z"/>
</g>
</symbol><symbol id="icon-b-ic-text-align-right" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M2 5h28v1H2zM14 12h16v1H14zM2 19h28v1H2zM14 26h16v1H14z"/>
</g>
</symbol><symbol id="icon-b-ic-text-bold" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M7 2h2v2H7zM7 28h2v2H7z"/>
<path stroke="#555555" stroke-width="2" d="M9 3v12h9a6 6 0 1 0 0-12H9zM9 15v14h10a7 7 0 0 0 0-14H9z"/>
</g>
</symbol><symbol id="icon-b-ic-text-italic" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M15 2h5v1h-5zM11 29h5v1h-5zM17 3h1l-4 26h-1z"/>
</g>
</symbol><symbol id="icon-b-ic-text-underline" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#555555" d="M8 2v14a8 8 0 1 0 16 0V2h1v14a9 9 0 0 1-18 0V2h1zM3 29h26v1H3z"/>
<path fill="#555555" d="M5 2h5v1H5zM22 2h5v1h-5z"/>
</g>
</symbol><symbol id="icon-b-ic-text" viewBox="0 0 24 24">
<g fill="#555555" fill-rule="evenodd">
<path d="M4 3h15a1 1 0 0 1 1 1H3a1 1 0 0 1 1-1zM3 4h1v1H3zM19 4h1v1h-1z"/>
<path d="M11 3h1v18h-1z"/>
<path d="M10 20h3v1h-3z"/>
</g>
</symbol><symbol id="icon-b-ic-undo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M24 0H0v24h24z" opacity=".5"/>
<path fill="#555555" d="M3 6h12a6 6 0 1 1 0 12H3v1h12a7 7 0 0 0 0-14H3v1z"/>
<path stroke="#555555" stroke-linecap="square" d="M5 3L2.5 5.5 5 8"/>
</g>
</symbol><symbol id="icon-b-img-bi" viewBox="0 0 257 26">
<g fill="#FDBA3B">
<path d="M26 5a8.001 8.001 0 0 0 0 16 8.001 8.001 0 0 0 0-16M51.893 19.812L43.676 5.396A.78.78 0 0 0 43 5a.78.78 0 0 0-.677.396l-8.218 14.418a.787.787 0 0 0 0 .792c.14.244.396.394.676.394h16.436c.28 0 .539-.15.678-.396a.796.796 0 0 0-.002-.792M15.767 5.231A.79.79 0 0 0 15.21 5H.791A.791.791 0 0 0 0 5.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M85.767 5.231A.79.79 0 0 0 85.21 5H70.791a.791.791 0 0 0-.791.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M65.942 9.948l2.17-3.76a.78.78 0 0 0 0-.792.791.791 0 0 0-.684-.396h-8.54A5.889 5.889 0 0 0 53 10.86a5.887 5.887 0 0 0 3.07 5.17l-2.184 3.782A.792.792 0 0 0 54.571 21h8.54a5.89 5.89 0 0 0 2.831-11.052M105.7 21h2.3V5h-2.3zM91 5h2.4v10.286c0 1.893 1.612 3.429 3.6 3.429s3.6-1.536 3.6-3.429V5h2.4v10.286c0 3.156-2.686 5.714-6 5.714-3.313 0-6-2.558-6-5.714V5zM252.148 21.128h-2.377V9.659h2.27v1.64c.69-1.299 1.792-1.938 3.304-1.938.497 0 .95.065 1.382.192l-.215 2.277a3.734 3.734 0 0 0-1.275-.213c-1.814 0-3.089 1.234-3.089 3.638v5.873zm-7.095-5.744a3.734 3.734 0 0 0-1.101-2.703c-.714-.766-1.6-1.149-2.658-1.149-1.058 0-1.944.383-2.679 1.149a3.803 3.803 0 0 0-1.08 2.703c0 1.063.368 1.978 1.08 2.722.735.746 1.62 1.128 2.68 1.128 1.058 0 1.943-.382 2.657-1.128.734-.744 1.101-1.659 1.101-2.722zm-9.916 0c0-1.682.583-3.086 1.729-4.256 1.166-1.17 2.635-1.767 4.428-1.767 1.793 0 3.262.597 4.407 1.767 1.167 1.17 1.75 2.574 1.75 4.256 0 1.7-.583 3.127-1.75 4.297-1.145 1.17-2.614 1.745-4.407 1.745-1.793 0-3.262-.575-4.428-1.745-1.146-1.17-1.729-2.596-1.729-4.297zm-1.5 3.233l.821 1.83c-.864.638-1.944.958-3.22.958-2.526 0-3.822-1.554-3.822-4.383V11.66h-2.01v-2h2.031V5.595h2.355v4.063h4.018v2h-4.018v5.405c0 1.469.605 2.191 1.793 2.191.626 0 1.318-.212 2.052-.638zm-12.43 2.51h2.375V9.66h-2.376v11.469zm1.23-12.977c-.929 0-1.642-.682-1.642-1.596 0-.873.713-1.554 1.643-1.554.885 0 1.576.681 1.576 1.554 0 .914-.69 1.596-1.576 1.596zm-6.49 7.234c0-1.086-.346-1.98-1.037-2.724-.692-.745-1.599-1.128-2.7-1.128-1.102 0-2.01.383-2.7 1.128-.692.744-1.037 1.638-1.037 2.724 0 1.084.345 2.02 1.036 2.766.691.744 1.6 1.105 2.7 1.105 1.102 0 2.01-.361 2.7-1.105.692-.746 1.038-1.682 1.038-2.766zm-.173-4.129V5h2.397v16.128h-2.354v-1.596c-1.015 1.255-2.333 1.873-3.91 1.873-1.663 0-3.068-.575-4.169-1.724-1.102-1.17-1.663-2.596-1.663-4.297 0-1.682.561-3.107 1.663-4.256 1.101-1.17 2.485-1.745 4.148-1.745 1.534 0 2.83.617 3.888 1.872zm-11.48 9.873h-10.218V5.405h10.195v2.318h-7.711V12h7.15v2.32h-7.15v4.489h7.733v2.319zm-23.891-9.724c-1.793 0-3.132 1.192-3.478 2.979h6.783c-.194-1.808-1.555-2.979-3.305-2.979zm5.703 3.766c0 .32-.021.703-.086 1.128h-9.095c.346 1.787 1.62 3 3.867 3 1.318 0 2.916-.49 3.953-1.234l.994 1.724c-1.189.872-3.067 1.595-5.033 1.595-4.364 0-6.243-3-6.243-6.021 0-1.724.54-3.15 1.642-4.277 1.101-1.127 2.548-1.702 4.298-1.702 1.664 0 3.046.511 4.105 1.553 1.058 1.043 1.598 2.447 1.598 4.234zm-19.949 3.894c1.08 0 1.966-.362 2.68-1.085.712-.724 1.058-1.617 1.058-2.703 0-1.084-.346-2-1.059-2.701-.713-.702-1.599-1.064-2.679-1.064-1.058 0-1.944.362-2.656 1.085-.714.702-1.059 1.596-1.059 2.68 0 1.086.345 2 1.059 2.724.712.702 1.598 1.064 2.656 1.064zm3.673-7.936V9.66h2.29v10.299c0 1.85-.584 3.32-1.728 4.404-1.146 1.085-2.68 1.638-4.58 1.638-1.945 0-3.672-.553-5.206-1.638l1.037-1.808c1.296.915 2.679 1.36 4.126 1.36 2.484 0 3.996-1.51 3.996-3.637v-.83c-1.015 1.127-2.311 1.702-3.91 1.702-1.684 0-3.089-.554-4.19-1.68-1.102-1.128-1.642-2.532-1.642-4.214 0-1.68.561-3.085 1.706-4.191 1.145-1.128 2.571-1.681 4.234-1.681 1.534 0 2.83.575 3.867 1.745zm-18.07 8.127c1.102 0 1.988-.382 2.7-1.128.714-.744 1.06-1.659 1.06-2.743 0-1.065-.346-1.98-1.06-2.724-.712-.745-1.598-1.128-2.7-1.128-1.101 0-2.008.383-2.7 1.128-.691.744-1.036 1.66-1.036 2.745 0 1.084.345 2 1.037 2.745.691.744 1.598 1.105 2.7 1.105zm3.652-8V9.66h2.29v11.469h-2.29v-1.575c-1.059 1.234-2.399 1.852-3.976 1.852-1.663 0-3.067-.575-4.168-1.745-1.102-1.17-1.642-2.617-1.642-4.34 0-1.724.54-3.128 1.642-4.256 1.1-1.128 2.505-1.681 4.168-1.681 1.577 0 2.917.617 3.976 1.872zM138.79 9.34c1.404 0 2.527.448 3.37 1.34.863.873 1.295 2.086 1.295 3.596v6.852h-2.376V14.66c0-2.021-1.036-3.128-2.657-3.128-1.727 0-2.915 1.255-2.915 3.192v6.404h-2.377v-6.426c0-1.978-1.037-3.17-2.679-3.17-1.728 0-2.937 1.277-2.937 3.234v6.362h-2.377V9.659h2.333v1.66c.692-1.212 1.988-1.979 3.522-1.979 1.533.021 2.958.767 3.586 2.107.798-1.277 2.419-2.107 4.212-2.107zm-19.517 11.788h2.484V5.405h-2.484v15.723z"/>
</g>
</symbol></svg>

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,224 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs/><symbol id="icon-c-ic-apply" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#e9e9e9" d="M4 12.011l5 5L20.011 6"/>
</g>
</symbol><symbol id="icon-c-ic-cancel" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#e9e9e9" d="M6 6l12 12M18 6L6 18"/>
</g>
</symbol><symbol id="icon-c-ic-crop" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#e9e9e9" d="M4 0h1v20a1 1 0 0 1-1-1V0zM20 17h-1V5h1v12zm0 2v5h-1v-5h1z"/>
<path fill="#e9e9e9" d="M5 19h19v1H5zM4.762 4v1H0V4h4.762zM7 4h12a1 1 0 0 1 1 1H7V4z"/>
</g>
</symbol><symbol id="icon-c-ic-delete-all" viewBox="0 0 24 24">
<g fill="#e9e9e9" fill-rule="evenodd">
<path d="M5 23H3a1 1 0 0 1-1-1V6h1v16h2v1zm16-10h-1V6h1v7zM9 13H8v-3h1v3zm3 0h-1v-3h1v3zm3 0h-1v-3h1v3zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM11.286 21H8.714L8 23H7l1-2.8V20h.071L9.5 16h1l1.429 4H12v.2l1 2.8h-1l-.714-2zm-.357-1L10 17.4 9.071 20h1.858zM20 22h3v1h-4v-7h1v6zm-5 0h3v1h-4v-7h1v6z"/>
</g>
</symbol><symbol id="icon-c-ic-delete" viewBox="0 0 24 24">
<g fill="#e9e9e9" fill-rule="evenodd">
<path d="M3 6v16h17V6h1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h1zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM8 10h1v6H8v-6zm3 0h1v6h-1v-6zm3 0h1v6h-1v-6z"/>
</g>
</symbol><symbol id="icon-c-ic-draw-free" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M2.5 20.929C2.594 10.976 4.323 6 7.686 6c5.872 0 2.524 19 7.697 19s1.89-14.929 6.414-14.929 1.357 10.858 5.13 10.858c1.802 0 2.657-2.262 2.566-6.786"/>
</g>
</symbol><symbol id="icon-c-ic-draw-line" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M2 15.5h28"/>
</g>
</symbol><symbol id="icon-c-ic-draw" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#e9e9e9" d="M2.5 21.5H5c.245 0 .48-.058.691-.168l.124-.065.14.01c.429.028.85-.127 1.16-.437L22.55 5.405a.5.5 0 0 0 0-.707l-3.246-3.245a.5.5 0 0 0-.707 0L3.162 16.888a1.495 1.495 0 0 0-.437 1.155l.01.14-.065.123c-.111.212-.17.448-.17.694v2.5z"/>
<path fill="#e9e9e9" d="M16.414 3.707l3.89 3.89-.708.706-3.889-3.889z"/>
</g>
</symbol><symbol id="icon-c-ic-filter" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#e9e9e9" d="M12 7v1H2V7h10zm6 0h4v1h-4V7zM12 16v1h10v-1H12zm-6 0H2v1h4v-1z"/>
<path fill="#e9e9e9" d="M8.5 20a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM15.5 11a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</g>
</symbol><symbol id="icon-c-ic-flip-reset" viewBox="0 0 31 32">
<g fill="none" fill-rule="evenodd">
<path d="M31 0H0v32h31z"/>
<path fill="#e9e9e9" d="M28 16a8 8 0 0 1-8 8H3v-1h1v-7H3a8 8 0 0 1 8-8h17v1h-1v7h1zM11 9a7 7 0 0 0-7 7v7h16a7 7 0 0 0 7-7V9H11z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M24 5l3.5 3.5L24 12M7 20l-3.5 3.5L7 27"/>
</g>
</symbol><symbol id="icon-c-ic-flip-x" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M32 32H0V0h32z"/>
<path fill="#e9e9e9" d="M17 32h-1V0h1zM27.167 11l.5 3h-1.03l-.546-3h1.076zm-.5-3h-1.122L25 5h-5V4h5.153a1 1 0 0 1 .986.836L26.667 8zm1.5 9l.5 3h-.94l-.545-3h.985zm1 6l.639 3.836A1 1 0 0 1 28.819 28H26v-1h3l-.726-4h.894zM23 28h-3v-1h3v1zM13 4v1H7L3 27h10v1H3.18a1 1 0 0 1-.986-1.164l3.666-22A1 1 0 0 1 6.847 4H13z"/>
</g>
</symbol><symbol id="icon-c-ic-flip-y" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0v32h32V0z"/>
<path fill="#e9e9e9" d="M0 16v1h32v-1zM11 27.167l3 .5v-1.03l-3-.546v1.076zm-3-.5v-1.122L5 25v-5H4v5.153a1 1 0 0 0 .836.986L8 26.667zm9 1.5l3 .5v-.94l-3-.545v.985zm6 1l3.836.639A1 1 0 0 0 28 28.82V26h-1v3l-4-.727v.894zM28 23v-3h-1v3h1zM4 13h1V7l22-4v10h1V3.18a1 1 0 0 0-1.164-.986l-22 3.667A1 1 0 0 0 4 6.847V13z"/>
</g>
</symbol><symbol id="icon-c-ic-flip" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#e9e9e9" d="M11 0h1v24h-1zM19 21v-1h2v-2h1v2a1 1 0 0 1-1 1h-2zm-2 0h-3v-1h3v1zm5-5h-1v-3h1v3zm0-5h-1V8h1v3zm0-5h-1V4h-2V3h2a1 1 0 0 1 1 1v2zm-5-3v1h-3V3h3zM9 3v1H2v16h7v1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-arrow-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M21.793 18.5H2.5v-5h18.935l-7.6-8h5.872l10.5 10.5-10.5 10.5h-5.914l8-8z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-arrow-3" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M25.288 16.42L14.208 27.5H6.792l11.291-11.291L6.826 4.5h7.381l11.661 11.661-.58.258z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-arrow" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M2.5 11.5v9h18v5.293L30.293 16 20.5 6.207V11.5h-18z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-bubble" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M22.207 24.5L16.5 30.207V24.5H8A6.5 6.5 0 0 1 1.5 18V9A6.5 6.5 0 0 1 8 2.5h16A6.5 6.5 0 0 1 30.5 9v9a6.5 6.5 0 0 1-6.5 6.5h-1.793z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-heart" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill-rule="nonzero" stroke="#e9e9e9" d="M15.996 30.675l1.981-1.79c7.898-7.177 10.365-9.718 12.135-13.012.922-1.716 1.377-3.37 1.377-5.076 0-4.65-3.647-8.297-8.297-8.297-2.33 0-4.86 1.527-6.817 3.824l-.38.447-.381-.447C13.658 4.027 11.126 2.5 8.797 2.5 4.147 2.5.5 6.147.5 10.797c0 1.714.46 3.375 1.389 5.098 1.775 3.288 4.26 5.843 12.123 12.974l1.984 1.806z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M17.314 18.867l1.951-2.53 4 5.184h-17l6.5-8.84 4.549 6.186z"/>
<path fill="#e9e9e9" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01z"/>
<path fill="#e9e9e9" d="M25 3h1v9h-1z"/>
<path stroke="#e9e9e9" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-c-ic-icon-location" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<g stroke="#e9e9e9">
<path d="M16 31.28C23.675 23.302 27.5 17.181 27.5 13c0-6.351-5.149-11.5-11.5-11.5S4.5 6.649 4.5 13c0 4.181 3.825 10.302 11.5 18.28z"/>
<circle cx="16" cy="13" r="4.5"/>
</g>
</g>
</symbol><symbol id="icon-c-ic-icon-polygon" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M.576 16L8.29 29.5h15.42L31.424 16 23.71 2.5H8.29L.576 16z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-star-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M19.446 31.592l2.265-3.272 3.946.25.636-3.94 3.665-1.505-1.12-3.832 2.655-2.962-2.656-2.962 1.12-3.832-3.664-1.505-.636-3.941-3.946.25-2.265-3.271L16 3.024 12.554 1.07 10.289 4.34l-3.946-.25-.636 3.941-3.665 1.505 1.12 3.832L.508 16.33l2.656 2.962-1.12 3.832 3.664 1.504.636 3.942 3.946-.25 2.265 3.27L16 29.638l3.446 1.955z"/>
</g>
</symbol><symbol id="icon-c-ic-icon-star" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" d="M25.292 29.878l-1.775-10.346 7.517-7.327-10.388-1.51L16 1.282l-4.646 9.413-10.388 1.51 7.517 7.327-1.775 10.346L16 24.993l9.292 4.885z"/>
</g>
</symbol><symbol id="icon-c-ic-icon" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M11.923 19.136L5.424 22l.715-7.065-4.731-5.296 6.94-1.503L11.923 2l3.574 6.136 6.94 1.503-4.731 5.296L18.42 22z"/>
</g>
</symbol><symbol id="icon-c-ic-mask-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01zM15 23a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-1a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
<path fill="#e9e9e9" d="M25 3h1v9h-1z"/>
<path stroke="#e9e9e9" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-c-ic-mask" viewBox="0 0 24 24">
<g fill="none">
<circle cx="12" cy="12" r="4.5" stroke="#e9e9e9"/>
<path fill="#e9e9e9" d="M2 1h20a1 1 0 0 1 1 1v20a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm0 1v20h20V2H2z"/>
</g>
</symbol><symbol id="icon-c-ic-redo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#e9e9e9" d="M21 6H9a6 6 0 1 0 0 12h12v1H9A7 7 0 0 1 9 5h12v1z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M19 3l2.5 2.5L19 8"/>
</g>
</symbol><symbol id="icon-c-ic-reset" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#e9e9e9" d="M2 13v-1a7 7 0 0 1 7-7h13v1h-1v5h1v1a7 7 0 0 1-7 7H2v-1h1v-5H2zm7-7a6 6 0 0 0-6 6v6h12a6 6 0 0 0 6-6V6H9z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M19 3l2.5 2.5L19 8M5 16l-2.5 2.5L5 21"/>
</g>
</symbol><symbol id="icon-c-ic-rotate-clockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#e9e9e9" d="M29 17h-.924c0 6.627-5.373 12-12 12-6.628 0-12-5.373-12-12C4.076 10.398 9.407 5.041 16 5V4C8.82 4 3 9.82 3 17s5.82 13 13 13 13-5.82 13-13z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M16 1.5l4 3-4 3"/>
<path fill="#e9e9e9" fill-rule="nonzero" d="M16 4h4v1h-4z"/>
</g>
</symbol><symbol id="icon-c-ic-rotate-counterclockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#e9e9e9" d="M3 17h.924c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.602-5.331-11.96-11.924-12V4c7.18 0 13 5.82 13 13s-5.82 13-13 13S3 24.18 3 17z"/>
<path fill="#e9e9e9" fill-rule="nonzero" d="M12 4h4v1h-4z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M16 1.5l-4 3 4 3"/>
</g>
</symbol><symbol id="icon-c-ic-rotate" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#e9e9e9" d="M8.349 22.254a10.002 10.002 0 0 1-2.778-1.719l.65-.76a9.002 9.002 0 0 0 2.495 1.548l-.367.931zm2.873.704l.078-.997a9 9 0 1 0-.557-17.852l-.14-.99A10.076 10.076 0 0 1 12.145 3c5.523 0 10 4.477 10 10s-4.477 10-10 10c-.312 0-.62-.014-.924-.042zm-7.556-4.655a9.942 9.942 0 0 1-1.253-2.996l.973-.234a8.948 8.948 0 0 0 1.124 2.693l-.844.537zm-1.502-5.91A9.949 9.949 0 0 1 2.88 9.23l.925.382a8.954 8.954 0 0 0-.644 2.844l-.998-.062zm2.21-5.686c.687-.848 1.51-1.58 2.436-2.166l.523.852a9.048 9.048 0 0 0-2.188 1.95l-.771-.636z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M13 1l-2.5 2.5L13 6"/>
</g>
</symbol><symbol id="icon-c-ic-shape-circle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<circle cx="16" cy="16" r="14.5" stroke="#e9e9e9"/>
</g>
</symbol><symbol id="icon-c-ic-shape-rectangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<rect width="27" height="27" x="2.5" y="2.5" stroke="#e9e9e9" rx="1"/>
</g>
</symbol><symbol id="icon-c-ic-shape-triangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M16 2.5l15.5 27H.5z"/>
</g>
</symbol><symbol id="icon-c-ic-shape" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#e9e9e9" d="M14.706 8H21a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-4h1v4h12V9h-5.706l-.588-1z"/>
<path stroke="#e9e9e9" stroke-linecap="round" stroke-linejoin="round" d="M8.5 1.5l7.5 13H1z"/>
</g>
</symbol><symbol id="icon-c-ic-text-align-center" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M2 5h28v1H2zM8 12h16v1H8zM2 19h28v1H2zM8 26h16v1H8z"/>
</g>
</symbol><symbol id="icon-c-ic-text-align-left" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M2 5h28v1H2zM2 12h16v1H2zM2 19h28v1H2zM2 26h16v1H2z"/>
</g>
</symbol><symbol id="icon-c-ic-text-align-right" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M2 5h28v1H2zM14 12h16v1H14zM2 19h28v1H2zM14 26h16v1H14z"/>
</g>
</symbol><symbol id="icon-c-ic-text-bold" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M7 2h2v2H7zM7 28h2v2H7z"/>
<path stroke="#e9e9e9" stroke-width="2" d="M9 3v12h9a6 6 0 1 0 0-12H9zM9 15v14h10a7 7 0 0 0 0-14H9z"/>
</g>
</symbol><symbol id="icon-c-ic-text-italic" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M15 2h5v1h-5zM11 29h5v1h-5zM17 3h1l-4 26h-1z"/>
</g>
</symbol><symbol id="icon-c-ic-text-underline" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#e9e9e9" d="M8 2v14a8 8 0 1 0 16 0V2h1v14a9 9 0 0 1-18 0V2h1zM3 29h26v1H3z"/>
<path fill="#e9e9e9" d="M5 2h5v1H5zM22 2h5v1h-5z"/>
</g>
</symbol><symbol id="icon-c-ic-text" viewBox="0 0 24 24">
<g fill="#e9e9e9" fill-rule="evenodd">
<path d="M4 3h15a1 1 0 0 1 1 1H3a1 1 0 0 1 1-1zM3 4h1v1H3zM19 4h1v1h-1z"/>
<path d="M11 3h1v18h-1z"/>
<path d="M10 20h3v1h-3z"/>
</g>
</symbol><symbol id="icon-c-ic-undo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M24 0H0v24h24z" opacity=".5"/>
<path fill="#e9e9e9" d="M3 6h12a6 6 0 1 1 0 12H3v1h12a7 7 0 0 0 0-14H3v1z"/>
<path stroke="#e9e9e9" stroke-linecap="square" d="M5 3L2.5 5.5 5 8"/>
</g>
</symbol><symbol id="icon-c-img-bi" viewBox="0 0 257 26">
<g fill="#FDBA3B">
<path d="M26 5a8.001 8.001 0 0 0 0 16 8.001 8.001 0 0 0 0-16M51.893 19.812L43.676 5.396A.78.78 0 0 0 43 5a.78.78 0 0 0-.677.396l-8.218 14.418a.787.787 0 0 0 0 .792c.14.244.396.394.676.394h16.436c.28 0 .539-.15.678-.396a.796.796 0 0 0-.002-.792M15.767 5.231A.79.79 0 0 0 15.21 5H.791A.791.791 0 0 0 0 5.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M85.767 5.231A.79.79 0 0 0 85.21 5H70.791a.791.791 0 0 0-.791.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M65.942 9.948l2.17-3.76a.78.78 0 0 0 0-.792.791.791 0 0 0-.684-.396h-8.54A5.889 5.889 0 0 0 53 10.86a5.887 5.887 0 0 0 3.07 5.17l-2.184 3.782A.792.792 0 0 0 54.571 21h8.54a5.89 5.89 0 0 0 2.831-11.052M105.7 21h2.3V5h-2.3zM91 5h2.4v10.286c0 1.893 1.612 3.429 3.6 3.429s3.6-1.536 3.6-3.429V5h2.4v10.286c0 3.156-2.686 5.714-6 5.714-3.313 0-6-2.558-6-5.714V5zM252.148 21.128h-2.377V9.659h2.27v1.64c.69-1.299 1.792-1.938 3.304-1.938.497 0 .95.065 1.382.192l-.215 2.277a3.734 3.734 0 0 0-1.275-.213c-1.814 0-3.089 1.234-3.089 3.638v5.873zm-7.095-5.744a3.734 3.734 0 0 0-1.101-2.703c-.714-.766-1.6-1.149-2.658-1.149-1.058 0-1.944.383-2.679 1.149a3.803 3.803 0 0 0-1.08 2.703c0 1.063.368 1.978 1.08 2.722.735.746 1.62 1.128 2.68 1.128 1.058 0 1.943-.382 2.657-1.128.734-.744 1.101-1.659 1.101-2.722zm-9.916 0c0-1.682.583-3.086 1.729-4.256 1.166-1.17 2.635-1.767 4.428-1.767 1.793 0 3.262.597 4.407 1.767 1.167 1.17 1.75 2.574 1.75 4.256 0 1.7-.583 3.127-1.75 4.297-1.145 1.17-2.614 1.745-4.407 1.745-1.793 0-3.262-.575-4.428-1.745-1.146-1.17-1.729-2.596-1.729-4.297zm-1.5 3.233l.821 1.83c-.864.638-1.944.958-3.22.958-2.526 0-3.822-1.554-3.822-4.383V11.66h-2.01v-2h2.031V5.595h2.355v4.063h4.018v2h-4.018v5.405c0 1.469.605 2.191 1.793 2.191.626 0 1.318-.212 2.052-.638zm-12.43 2.51h2.375V9.66h-2.376v11.469zm1.23-12.977c-.929 0-1.642-.682-1.642-1.596 0-.873.713-1.554 1.643-1.554.885 0 1.576.681 1.576 1.554 0 .914-.69 1.596-1.576 1.596zm-6.49 7.234c0-1.086-.346-1.98-1.037-2.724-.692-.745-1.599-1.128-2.7-1.128-1.102 0-2.01.383-2.7 1.128-.692.744-1.037 1.638-1.037 2.724 0 1.084.345 2.02 1.036 2.766.691.744 1.6 1.105 2.7 1.105 1.102 0 2.01-.361 2.7-1.105.692-.746 1.038-1.682 1.038-2.766zm-.173-4.129V5h2.397v16.128h-2.354v-1.596c-1.015 1.255-2.333 1.873-3.91 1.873-1.663 0-3.068-.575-4.169-1.724-1.102-1.17-1.663-2.596-1.663-4.297 0-1.682.561-3.107 1.663-4.256 1.101-1.17 2.485-1.745 4.148-1.745 1.534 0 2.83.617 3.888 1.872zm-11.48 9.873h-10.218V5.405h10.195v2.318h-7.711V12h7.15v2.32h-7.15v4.489h7.733v2.319zm-23.891-9.724c-1.793 0-3.132 1.192-3.478 2.979h6.783c-.194-1.808-1.555-2.979-3.305-2.979zm5.703 3.766c0 .32-.021.703-.086 1.128h-9.095c.346 1.787 1.62 3 3.867 3 1.318 0 2.916-.49 3.953-1.234l.994 1.724c-1.189.872-3.067 1.595-5.033 1.595-4.364 0-6.243-3-6.243-6.021 0-1.724.54-3.15 1.642-4.277 1.101-1.127 2.548-1.702 4.298-1.702 1.664 0 3.046.511 4.105 1.553 1.058 1.043 1.598 2.447 1.598 4.234zm-19.949 3.894c1.08 0 1.966-.362 2.68-1.085.712-.724 1.058-1.617 1.058-2.703 0-1.084-.346-2-1.059-2.701-.713-.702-1.599-1.064-2.679-1.064-1.058 0-1.944.362-2.656 1.085-.714.702-1.059 1.596-1.059 2.68 0 1.086.345 2 1.059 2.724.712.702 1.598 1.064 2.656 1.064zm3.673-7.936V9.66h2.29v10.299c0 1.85-.584 3.32-1.728 4.404-1.146 1.085-2.68 1.638-4.58 1.638-1.945 0-3.672-.553-5.206-1.638l1.037-1.808c1.296.915 2.679 1.36 4.126 1.36 2.484 0 3.996-1.51 3.996-3.637v-.83c-1.015 1.127-2.311 1.702-3.91 1.702-1.684 0-3.089-.554-4.19-1.68-1.102-1.128-1.642-2.532-1.642-4.214 0-1.68.561-3.085 1.706-4.191 1.145-1.128 2.571-1.681 4.234-1.681 1.534 0 2.83.575 3.867 1.745zm-18.07 8.127c1.102 0 1.988-.382 2.7-1.128.714-.744 1.06-1.659 1.06-2.743 0-1.065-.346-1.98-1.06-2.724-.712-.745-1.598-1.128-2.7-1.128-1.101 0-2.008.383-2.7 1.128-.691.744-1.036 1.66-1.036 2.745 0 1.084.345 2 1.037 2.745.691.744 1.598 1.105 2.7 1.105zm3.652-8V9.66h2.29v11.469h-2.29v-1.575c-1.059 1.234-2.399 1.852-3.976 1.852-1.663 0-3.067-.575-4.168-1.745-1.102-1.17-1.642-2.617-1.642-4.34 0-1.724.54-3.128 1.642-4.256 1.1-1.128 2.505-1.681 4.168-1.681 1.577 0 2.917.617 3.976 1.872zM138.79 9.34c1.404 0 2.527.448 3.37 1.34.863.873 1.295 2.086 1.295 3.596v6.852h-2.376V14.66c0-2.021-1.036-3.128-2.657-3.128-1.727 0-2.915 1.255-2.915 3.192v6.404h-2.377v-6.426c0-1.978-1.037-3.17-2.679-3.17-1.728 0-2.937 1.277-2.937 3.234v6.362h-2.377V9.659h2.333v1.66c.692-1.212 1.988-1.979 3.522-1.979 1.533.021 2.958.767 3.586 2.107.798-1.277 2.419-2.107 4.212-2.107zm-19.517 11.788h2.484V5.405h-2.484v15.723z"/>
</g>
</symbol></svg>

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,224 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs/><symbol id="icon-d-ic-apply" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#8a8a8a" d="M4 12.011l5 5L20.011 6"/>
</g>
</symbol><symbol id="icon-d-ic-cancel" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path stroke="#8a8a8a" d="M6 6l12 12M18 6L6 18"/>
</g>
</symbol><symbol id="icon-d-ic-crop" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#8a8a8a" d="M4 0h1v20a1 1 0 0 1-1-1V0zM20 17h-1V5h1v12zm0 2v5h-1v-5h1z"/>
<path fill="#8a8a8a" d="M5 19h19v1H5zM4.762 4v1H0V4h4.762zM7 4h12a1 1 0 0 1 1 1H7V4z"/>
</g>
</symbol><symbol id="icon-d-ic-delete-all" viewBox="0 0 24 24">
<g fill="#8a8a8a" fill-rule="evenodd">
<path d="M5 23H3a1 1 0 0 1-1-1V6h1v16h2v1zm16-10h-1V6h1v7zM9 13H8v-3h1v3zm3 0h-1v-3h1v3zm3 0h-1v-3h1v3zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM11.286 21H8.714L8 23H7l1-2.8V20h.071L9.5 16h1l1.429 4H12v.2l1 2.8h-1l-.714-2zm-.357-1L10 17.4 9.071 20h1.858zM20 22h3v1h-4v-7h1v6zm-5 0h3v1h-4v-7h1v6z"/>
</g>
</symbol><symbol id="icon-d-ic-delete" viewBox="0 0 24 24">
<g fill="#8a8a8a" fill-rule="evenodd">
<path d="M3 6v16h17V6h1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h1zM14.794 3.794L13 2h-3L8.206 3.794A.963.963 0 0 1 8 2.5l.703-1.055A1 1 0 0 1 9.535 1h3.93a1 1 0 0 1 .832.445L15 2.5a.965.965 0 0 1-.206 1.294zM14.197 4H8.803h5.394z"/>
<path d="M0 3h23v1H0zM8 10h1v6H8v-6zm3 0h1v6h-1v-6zm3 0h1v6h-1v-6z"/>
</g>
</symbol><symbol id="icon-d-ic-draw-free" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M2.5 20.929C2.594 10.976 4.323 6 7.686 6c5.872 0 2.524 19 7.697 19s1.89-14.929 6.414-14.929 1.357 10.858 5.13 10.858c1.802 0 2.657-2.262 2.566-6.786"/>
</g>
</symbol><symbol id="icon-d-ic-draw-line" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M2 15.5h28"/>
</g>
</symbol><symbol id="icon-d-ic-draw" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#8a8a8a" d="M2.5 21.5H5c.245 0 .48-.058.691-.168l.124-.065.14.01c.429.028.85-.127 1.16-.437L22.55 5.405a.5.5 0 0 0 0-.707l-3.246-3.245a.5.5 0 0 0-.707 0L3.162 16.888a1.495 1.495 0 0 0-.437 1.155l.01.14-.065.123c-.111.212-.17.448-.17.694v2.5z"/>
<path fill="#8a8a8a" d="M16.414 3.707l3.89 3.89-.708.706-3.889-3.889z"/>
</g>
</symbol><symbol id="icon-d-ic-filter" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#8a8a8a" d="M12 7v1H2V7h10zm6 0h4v1h-4V7zM12 16v1h10v-1H12zm-6 0H2v1h4v-1z"/>
<path fill="#8a8a8a" d="M8.5 20a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM15.5 11a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</g>
</symbol><symbol id="icon-d-ic-flip-reset" viewBox="0 0 31 32">
<g fill="none" fill-rule="evenodd">
<path d="M31 0H0v32h31z"/>
<path fill="#8a8a8a" d="M28 16a8 8 0 0 1-8 8H3v-1h1v-7H3a8 8 0 0 1 8-8h17v1h-1v7h1zM11 9a7 7 0 0 0-7 7v7h16a7 7 0 0 0 7-7V9H11z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M24 5l3.5 3.5L24 12M7 20l-3.5 3.5L7 27"/>
</g>
</symbol><symbol id="icon-d-ic-flip-x" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M32 32H0V0h32z"/>
<path fill="#8a8a8a" d="M17 32h-1V0h1zM27.167 11l.5 3h-1.03l-.546-3h1.076zm-.5-3h-1.122L25 5h-5V4h5.153a1 1 0 0 1 .986.836L26.667 8zm1.5 9l.5 3h-.94l-.545-3h.985zm1 6l.639 3.836A1 1 0 0 1 28.819 28H26v-1h3l-.726-4h.894zM23 28h-3v-1h3v1zM13 4v1H7L3 27h10v1H3.18a1 1 0 0 1-.986-1.164l3.666-22A1 1 0 0 1 6.847 4H13z"/>
</g>
</symbol><symbol id="icon-d-ic-flip-y" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0v32h32V0z"/>
<path fill="#8a8a8a" d="M0 16v1h32v-1zM11 27.167l3 .5v-1.03l-3-.546v1.076zm-3-.5v-1.122L5 25v-5H4v5.153a1 1 0 0 0 .836.986L8 26.667zm9 1.5l3 .5v-.94l-3-.545v.985zm6 1l3.836.639A1 1 0 0 0 28 28.82V26h-1v3l-4-.727v.894zM28 23v-3h-1v3h1zM4 13h1V7l22-4v10h1V3.18a1 1 0 0 0-1.164-.986l-22 3.667A1 1 0 0 0 4 6.847V13z"/>
</g>
</symbol><symbol id="icon-d-ic-flip" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#8a8a8a" d="M11 0h1v24h-1zM19 21v-1h2v-2h1v2a1 1 0 0 1-1 1h-2zm-2 0h-3v-1h3v1zm5-5h-1v-3h1v3zm0-5h-1V8h1v3zm0-5h-1V4h-2V3h2a1 1 0 0 1 1 1v2zm-5-3v1h-3V3h3zM9 3v1H2v16h7v1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-arrow-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M21.793 18.5H2.5v-5h18.935l-7.6-8h5.872l10.5 10.5-10.5 10.5h-5.914l8-8z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-arrow-3" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M25.288 16.42L14.208 27.5H6.792l11.291-11.291L6.826 4.5h7.381l11.661 11.661-.58.258z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-arrow" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M2.5 11.5v9h18v5.293L30.293 16 20.5 6.207V11.5h-18z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-bubble" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M22.207 24.5L16.5 30.207V24.5H8A6.5 6.5 0 0 1 1.5 18V9A6.5 6.5 0 0 1 8 2.5h16A6.5 6.5 0 0 1 30.5 9v9a6.5 6.5 0 0 1-6.5 6.5h-1.793z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-heart" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill-rule="nonzero" stroke="#8a8a8a" d="M15.996 30.675l1.981-1.79c7.898-7.177 10.365-9.718 12.135-13.012.922-1.716 1.377-3.37 1.377-5.076 0-4.65-3.647-8.297-8.297-8.297-2.33 0-4.86 1.527-6.817 3.824l-.38.447-.381-.447C13.658 4.027 11.126 2.5 8.797 2.5 4.147 2.5.5 6.147.5 10.797c0 1.714.46 3.375 1.389 5.098 1.775 3.288 4.26 5.843 12.123 12.974l1.984 1.806z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M17.314 18.867l1.951-2.53 4 5.184h-17l6.5-8.84 4.549 6.186z"/>
<path fill="#8a8a8a" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01z"/>
<path fill="#8a8a8a" d="M25 3h1v9h-1z"/>
<path stroke="#8a8a8a" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-d-ic-icon-location" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<g stroke="#8a8a8a">
<path d="M16 31.28C23.675 23.302 27.5 17.181 27.5 13c0-6.351-5.149-11.5-11.5-11.5S4.5 6.649 4.5 13c0 4.181 3.825 10.302 11.5 18.28z"/>
<circle cx="16" cy="13" r="4.5"/>
</g>
</g>
</symbol><symbol id="icon-d-ic-icon-polygon" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M.576 16L8.29 29.5h15.42L31.424 16 23.71 2.5H8.29L.576 16z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-star-2" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M19.446 31.592l2.265-3.272 3.946.25.636-3.94 3.665-1.505-1.12-3.832 2.655-2.962-2.656-2.962 1.12-3.832-3.664-1.505-.636-3.941-3.946.25-2.265-3.271L16 3.024 12.554 1.07 10.289 4.34l-3.946-.25-.636 3.941-3.665 1.505 1.12 3.832L.508 16.33l2.656 2.962-1.12 3.832 3.664 1.504.636 3.942 3.946-.25 2.265 3.27L16 29.638l3.446 1.955z"/>
</g>
</symbol><symbol id="icon-d-ic-icon-star" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" d="M25.292 29.878l-1.775-10.346 7.517-7.327-10.388-1.51L16 1.282l-4.646 9.413-10.388 1.51 7.517 7.327-1.775 10.346L16 24.993l9.292 4.885z"/>
</g>
</symbol><symbol id="icon-d-ic-icon" viewBox="0 0 24 24">
<g fill="none">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M11.923 19.136L5.424 22l.715-7.065-4.731-5.296 6.94-1.503L11.923 2l3.574 6.136 6.94 1.503-4.731 5.296L18.42 22z"/>
</g>
</symbol><symbol id="icon-d-ic-mask-load" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M18.01 4a11.798 11.798 0 0 0 0 1H3v24h24V14.986a8.738 8.738 0 0 0 1 0V29a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h15.01zM15 23a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-1a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
<path fill="#8a8a8a" d="M25 3h1v9h-1z"/>
<path stroke="#8a8a8a" d="M22 6l3.5-3.5L29 6"/>
</g>
</symbol><symbol id="icon-d-ic-mask" viewBox="0 0 24 24">
<g fill="none">
<circle cx="12" cy="12" r="4.5" stroke="#8a8a8a"/>
<path fill="#8a8a8a" d="M2 1h20a1 1 0 0 1 1 1v20a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm0 1v20h20V2H2z"/>
</g>
</symbol><symbol id="icon-d-ic-redo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#8a8a8a" d="M21 6H9a6 6 0 1 0 0 12h12v1H9A7 7 0 0 1 9 5h12v1z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M19 3l2.5 2.5L19 8"/>
</g>
</symbol><symbol id="icon-d-ic-reset" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z" opacity=".5"/>
<path fill="#8a8a8a" d="M2 13v-1a7 7 0 0 1 7-7h13v1h-1v5h1v1a7 7 0 0 1-7 7H2v-1h1v-5H2zm7-7a6 6 0 0 0-6 6v6h12a6 6 0 0 0 6-6V6H9z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M19 3l2.5 2.5L19 8M5 16l-2.5 2.5L5 21"/>
</g>
</symbol><symbol id="icon-d-ic-rotate-clockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#8a8a8a" d="M29 17h-.924c0 6.627-5.373 12-12 12-6.628 0-12-5.373-12-12C4.076 10.398 9.407 5.041 16 5V4C8.82 4 3 9.82 3 17s5.82 13 13 13 13-5.82 13-13z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M16 1.5l4 3-4 3"/>
<path fill="#8a8a8a" fill-rule="nonzero" d="M16 4h4v1h-4z"/>
</g>
</symbol><symbol id="icon-d-ic-rotate-counterclockwise" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path fill="#8a8a8a" d="M3 17h.924c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.602-5.331-11.96-11.924-12V4c7.18 0 13 5.82 13 13s-5.82 13-13 13S3 24.18 3 17z"/>
<path fill="#8a8a8a" fill-rule="nonzero" d="M12 4h4v1h-4z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M16 1.5l-4 3 4 3"/>
</g>
</symbol><symbol id="icon-d-ic-rotate" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h24v24H0z"/>
<path fill="#8a8a8a" d="M8.349 22.254a10.002 10.002 0 0 1-2.778-1.719l.65-.76a9.002 9.002 0 0 0 2.495 1.548l-.367.931zm2.873.704l.078-.997a9 9 0 1 0-.557-17.852l-.14-.99A10.076 10.076 0 0 1 12.145 3c5.523 0 10 4.477 10 10s-4.477 10-10 10c-.312 0-.62-.014-.924-.042zm-7.556-4.655a9.942 9.942 0 0 1-1.253-2.996l.973-.234a8.948 8.948 0 0 0 1.124 2.693l-.844.537zm-1.502-5.91A9.949 9.949 0 0 1 2.88 9.23l.925.382a8.954 8.954 0 0 0-.644 2.844l-.998-.062zm2.21-5.686c.687-.848 1.51-1.58 2.436-2.166l.523.852a9.048 9.048 0 0 0-2.188 1.95l-.771-.636z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M13 1l-2.5 2.5L13 6"/>
</g>
</symbol><symbol id="icon-d-ic-shape-circle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<circle cx="16" cy="16" r="14.5" stroke="#8a8a8a"/>
</g>
</symbol><symbol id="icon-d-ic-shape-rectangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<rect width="27" height="27" x="2.5" y="2.5" stroke="#8a8a8a" rx="1"/>
</g>
</symbol><symbol id="icon-d-ic-shape-triangle" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M16 2.5l15.5 27H.5z"/>
</g>
</symbol><symbol id="icon-d-ic-shape" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#8a8a8a" d="M14.706 8H21a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-4h1v4h12V9h-5.706l-.588-1z"/>
<path stroke="#8a8a8a" stroke-linecap="round" stroke-linejoin="round" d="M8.5 1.5l7.5 13H1z"/>
</g>
</symbol><symbol id="icon-d-ic-text-align-center" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M2 5h28v1H2zM8 12h16v1H8zM2 19h28v1H2zM8 26h16v1H8z"/>
</g>
</symbol><symbol id="icon-d-ic-text-align-left" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M2 5h28v1H2zM2 12h16v1H2zM2 19h28v1H2zM2 26h16v1H2z"/>
</g>
</symbol><symbol id="icon-d-ic-text-align-right" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M2 5h28v1H2zM14 12h16v1H14zM2 19h28v1H2zM14 26h16v1H14z"/>
</g>
</symbol><symbol id="icon-d-ic-text-bold" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M7 2h2v2H7zM7 28h2v2H7z"/>
<path stroke="#8a8a8a" stroke-width="2" d="M9 3v12h9a6 6 0 1 0 0-12H9zM9 15v14h10a7 7 0 0 0 0-14H9z"/>
</g>
</symbol><symbol id="icon-d-ic-text-italic" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M15 2h5v1h-5zM11 29h5v1h-5zM17 3h1l-4 26h-1z"/>
</g>
</symbol><symbol id="icon-d-ic-text-underline" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>
<path fill="#8a8a8a" d="M8 2v14a8 8 0 1 0 16 0V2h1v14a9 9 0 0 1-18 0V2h1zM3 29h26v1H3z"/>
<path fill="#8a8a8a" d="M5 2h5v1H5zM22 2h5v1h-5z"/>
</g>
</symbol><symbol id="icon-d-ic-text" viewBox="0 0 24 24">
<g fill="#8a8a8a" fill-rule="evenodd">
<path d="M4 3h15a1 1 0 0 1 1 1H3a1 1 0 0 1 1-1zM3 4h1v1H3zM19 4h1v1h-1z"/>
<path d="M11 3h1v18h-1z"/>
<path d="M10 20h3v1h-3z"/>
</g>
</symbol><symbol id="icon-d-ic-undo" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="M24 0H0v24h24z" opacity=".5"/>
<path fill="#8a8a8a" d="M3 6h12a6 6 0 1 1 0 12H3v1h12a7 7 0 0 0 0-14H3v1z"/>
<path stroke="#8a8a8a" stroke-linecap="square" d="M5 3L2.5 5.5 5 8"/>
</g>
</symbol><symbol id="icon-d-img-bi" viewBox="0 0 257 26">
<g fill="#FDBA3B">
<path d="M26 5a8.001 8.001 0 0 0 0 16 8.001 8.001 0 0 0 0-16M51.893 19.812L43.676 5.396A.78.78 0 0 0 43 5a.78.78 0 0 0-.677.396l-8.218 14.418a.787.787 0 0 0 0 .792c.14.244.396.394.676.394h16.436c.28 0 .539-.15.678-.396a.796.796 0 0 0-.002-.792M15.767 5.231A.79.79 0 0 0 15.21 5H.791A.791.791 0 0 0 0 5.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M85.767 5.231A.79.79 0 0 0 85.21 5H70.791a.791.791 0 0 0-.791.79v6.42a.793.793 0 0 0 .791.79h3.21v7.21c.001.21.082.408.234.56.147.148.347.23.558.23h6.416a.788.788 0 0 0 .792-.79V13h3.006c.413 0 .611-.082.762-.232.15-.149.23-.35.231-.559V5.791a.787.787 0 0 0-.233-.56M65.942 9.948l2.17-3.76a.78.78 0 0 0 0-.792.791.791 0 0 0-.684-.396h-8.54A5.889 5.889 0 0 0 53 10.86a5.887 5.887 0 0 0 3.07 5.17l-2.184 3.782A.792.792 0 0 0 54.571 21h8.54a5.89 5.89 0 0 0 2.831-11.052M105.7 21h2.3V5h-2.3zM91 5h2.4v10.286c0 1.893 1.612 3.429 3.6 3.429s3.6-1.536 3.6-3.429V5h2.4v10.286c0 3.156-2.686 5.714-6 5.714-3.313 0-6-2.558-6-5.714V5zM252.148 21.128h-2.377V9.659h2.27v1.64c.69-1.299 1.792-1.938 3.304-1.938.497 0 .95.065 1.382.192l-.215 2.277a3.734 3.734 0 0 0-1.275-.213c-1.814 0-3.089 1.234-3.089 3.638v5.873zm-7.095-5.744a3.734 3.734 0 0 0-1.101-2.703c-.714-.766-1.6-1.149-2.658-1.149-1.058 0-1.944.383-2.679 1.149a3.803 3.803 0 0 0-1.08 2.703c0 1.063.368 1.978 1.08 2.722.735.746 1.62 1.128 2.68 1.128 1.058 0 1.943-.382 2.657-1.128.734-.744 1.101-1.659 1.101-2.722zm-9.916 0c0-1.682.583-3.086 1.729-4.256 1.166-1.17 2.635-1.767 4.428-1.767 1.793 0 3.262.597 4.407 1.767 1.167 1.17 1.75 2.574 1.75 4.256 0 1.7-.583 3.127-1.75 4.297-1.145 1.17-2.614 1.745-4.407 1.745-1.793 0-3.262-.575-4.428-1.745-1.146-1.17-1.729-2.596-1.729-4.297zm-1.5 3.233l.821 1.83c-.864.638-1.944.958-3.22.958-2.526 0-3.822-1.554-3.822-4.383V11.66h-2.01v-2h2.031V5.595h2.355v4.063h4.018v2h-4.018v5.405c0 1.469.605 2.191 1.793 2.191.626 0 1.318-.212 2.052-.638zm-12.43 2.51h2.375V9.66h-2.376v11.469zm1.23-12.977c-.929 0-1.642-.682-1.642-1.596 0-.873.713-1.554 1.643-1.554.885 0 1.576.681 1.576 1.554 0 .914-.69 1.596-1.576 1.596zm-6.49 7.234c0-1.086-.346-1.98-1.037-2.724-.692-.745-1.599-1.128-2.7-1.128-1.102 0-2.01.383-2.7 1.128-.692.744-1.037 1.638-1.037 2.724 0 1.084.345 2.02 1.036 2.766.691.744 1.6 1.105 2.7 1.105 1.102 0 2.01-.361 2.7-1.105.692-.746 1.038-1.682 1.038-2.766zm-.173-4.129V5h2.397v16.128h-2.354v-1.596c-1.015 1.255-2.333 1.873-3.91 1.873-1.663 0-3.068-.575-4.169-1.724-1.102-1.17-1.663-2.596-1.663-4.297 0-1.682.561-3.107 1.663-4.256 1.101-1.17 2.485-1.745 4.148-1.745 1.534 0 2.83.617 3.888 1.872zm-11.48 9.873h-10.218V5.405h10.195v2.318h-7.711V12h7.15v2.32h-7.15v4.489h7.733v2.319zm-23.891-9.724c-1.793 0-3.132 1.192-3.478 2.979h6.783c-.194-1.808-1.555-2.979-3.305-2.979zm5.703 3.766c0 .32-.021.703-.086 1.128h-9.095c.346 1.787 1.62 3 3.867 3 1.318 0 2.916-.49 3.953-1.234l.994 1.724c-1.189.872-3.067 1.595-5.033 1.595-4.364 0-6.243-3-6.243-6.021 0-1.724.54-3.15 1.642-4.277 1.101-1.127 2.548-1.702 4.298-1.702 1.664 0 3.046.511 4.105 1.553 1.058 1.043 1.598 2.447 1.598 4.234zm-19.949 3.894c1.08 0 1.966-.362 2.68-1.085.712-.724 1.058-1.617 1.058-2.703 0-1.084-.346-2-1.059-2.701-.713-.702-1.599-1.064-2.679-1.064-1.058 0-1.944.362-2.656 1.085-.714.702-1.059 1.596-1.059 2.68 0 1.086.345 2 1.059 2.724.712.702 1.598 1.064 2.656 1.064zm3.673-7.936V9.66h2.29v10.299c0 1.85-.584 3.32-1.728 4.404-1.146 1.085-2.68 1.638-4.58 1.638-1.945 0-3.672-.553-5.206-1.638l1.037-1.808c1.296.915 2.679 1.36 4.126 1.36 2.484 0 3.996-1.51 3.996-3.637v-.83c-1.015 1.127-2.311 1.702-3.91 1.702-1.684 0-3.089-.554-4.19-1.68-1.102-1.128-1.642-2.532-1.642-4.214 0-1.68.561-3.085 1.706-4.191 1.145-1.128 2.571-1.681 4.234-1.681 1.534 0 2.83.575 3.867 1.745zm-18.07 8.127c1.102 0 1.988-.382 2.7-1.128.714-.744 1.06-1.659 1.06-2.743 0-1.065-.346-1.98-1.06-2.724-.712-.745-1.598-1.128-2.7-1.128-1.101 0-2.008.383-2.7 1.128-.691.744-1.036 1.66-1.036 2.745 0 1.084.345 2 1.037 2.745.691.744 1.598 1.105 2.7 1.105zm3.652-8V9.66h2.29v11.469h-2.29v-1.575c-1.059 1.234-2.399 1.852-3.976 1.852-1.663 0-3.067-.575-4.168-1.745-1.102-1.17-1.642-2.617-1.642-4.34 0-1.724.54-3.128 1.642-4.256 1.1-1.128 2.505-1.681 4.168-1.681 1.577 0 2.917.617 3.976 1.872zM138.79 9.34c1.404 0 2.527.448 3.37 1.34.863.873 1.295 2.086 1.295 3.596v6.852h-2.376V14.66c0-2.021-1.036-3.128-2.657-3.128-1.727 0-2.915 1.255-2.915 3.192v6.404h-2.377v-6.426c0-1.978-1.037-3.17-2.679-3.17-1.728 0-2.937 1.277-2.937 3.234v6.362h-2.377V9.659h2.333v1.66c.692-1.212 1.988-1.979 3.522-1.979 1.533.021 2.958.767 3.586 2.107.798-1.277 2.419-2.107 4.212-2.107zm-19.517 11.788h2.484V5.405h-2.484v15.723z"/>
</g>
</symbol></svg>

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -1,180 +0,0 @@
var io_master_template = {
gather: function() {
this.clear();
this.gathering = true;
for (let iface of this.input_interfaces) {
iface.submit();
}
},
clear: function() {
this.last_input = new Array(this.input_interfaces.length);
this.input_count = 0;
if (this.gather_timeout) {
window.clearTimeout(this.gather_timeout);
}
},
input: function(interface_id, data) {
this.last_input[interface_id] = data;
this.input_count += 1;
if (this.input_count == this.input_interfaces.length) {
this.submit();
this.gathering = false;
}
},
submit: function() {
let io = this;
if (!this.config.live) {
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
this.target.find(".loading_failed").hide();
this.target.find(".output_interfaces").css("opacity", 0.5);
}
this.fn(this.last_input, "predict").then((output) => {
io.output(output);
}).catch((error) => {
console.error(error);
this.target.find(".loading_in_progress").hide();
this.target.find(".loading_failed").show();
});
},
score_similarity: function(callback) {
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
this.target.find(".loading_failed").hide();
this.target.find(".output_interfaces").css("opacity", 0.5);
this.fn(this.last_input, "score_similarity").then((output) => {
output = output["data"];
this.target.find(".loading").addClass("invisible");
this.target.find(".output_interfaces").css("opacity", 1);
this.order_mapping = sortWithIndices(output).reverse();
callback();
})
},
view_embeddings: function(callback) {
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
this.target.find(".loading_failed").hide();
this.target.find(".output_interfaces").css("opacity", 0.5);
this.fn(this.last_input, "view_embeddings").then((output) => {
this.target.find(".loading").addClass("invisible");
this.target.find(".output_interfaces").css("opacity", 1);
callback(output)
})
},
update_embeddings: function(callback) {
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
this.target.find(".loading_failed").hide();
this.target.find(".output_interfaces").css("opacity", 0.5);
this.fn(this.last_input, "update_embeddings").then((output) => {
this.target.find(".loading").addClass("invisible");
this.target.find(".output_interfaces").css("opacity", 1);
callback(output)
})
},
submit_examples: function(callback) {
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
this.target.find(".loading_failed").hide();
this.target.find(".output_interfaces").css("opacity", 0.5);
let example_ids = [];
if (this.loaded_examples == null) {
this.loaded_examples = {};
}
for (let i = 0; i < this.config.examples.length; i++) {
if (!(i in this.loaded_examples)) {
example_ids.push(i);
}
}
this.fn(example_ids, "predict_examples").then((output) => {
this.target.find(".loading").addClass("invisible");
this.target.find(".output_interfaces").css("opacity", 1);
output = output["data"];
for (let [example_id, output_values] of Object.entries(output)) {
this.loaded_examples[example_id] = output_values;
}
callback();
}).catch((error) => {
console.error(error);
this.target.find(".loading_in_progress").hide();
this.target.find(".loading_failed").show();
});
},
output: function(data, do_not_cache) {
if (!do_not_cache) {
this.last_output = data["data"];
}
for (let i = 0; i < this.output_interfaces.length; i++) {
this.output_interfaces[i].output(data["data"][i]);
}
if (data["durations"]) {
let ratio = this.output_interfaces.length / data["durations"].length;
for (let i = 0; i < this.output_interfaces.length; i = i + ratio) {
this.output_interfaces[i].target.parent().find(`.loading_time[interface="${i + ratio - 1}"]`).text("Latency: " + ((data["durations"][i / ratio])).toFixed(2) + "s");
}
}
if (this.config.live) {
var io = this;
var refresh_lag = this.config.refresh_lag || 0;
this.gather_timeout = window.setTimeout(function() {
io.gather();
}, refresh_lag);
} else {
this.target.find(".loading").addClass("invisible");
this.target.find(".output_interfaces").css("opacity", 1);
}
},
no_input: function() {
if (this.gathering && this.config.live) {
var io = this;
this.gather_timeout = window.setTimeout(function() {
io.gather();
}, 200);
}
this.gathering = false;
},
flag: function() {
var post_data = {
'input_data' : this.last_input ,
'output_data' : this.last_output
}
this.fn(post_data, "flag")
},
interpret: function() {
var io = this;
this.target.find(".loading").removeClass("invisible");
this.target.find(".loading_in_progress").show();
var post_data = this.last_input;
this.fn(post_data, "interpret").then((data) => {
for (let [idx, interpretation] of data["interpretation_scores"].entries()) {
io.input_interfaces[idx].show_interpretation(interpretation);
}
io.alternative_outputs = data["alternative_outputs"]
io.target.find(".loading_in_progress").hide();
}).catch((error) => {
console.error(error);
this.target.find(".loading_in_progress").hide();
this.target.find(".loading_failed").show();
})
},
alternative_interpret: function(interface_index, alternate_index) {
if (interface_index === false) {
this.output({"data": this.last_output});
} else if (io.alternative_outputs) {
this.output(
{"data": io.alternative_outputs[interface_index][alternate_index]},
/*do_not_cache=*/true
)
}
}
};

View File

@ -1,564 +0,0 @@
function gradio(config, fn, target, example_file_path) {
target = $(target);
target.html(`
<div class="share invisible">
Live at <a class="share-link" target="_blank"></a>.
<button class="share-copy">Copy Link</button>
</div>
<h1 class="title"></h1>
<p class="description"></p>
<div class="panels">
<div class="panel input_panel">
<div class="input_interfaces">
</div>
<div class="panel_buttons">
<input class="clear panel_button" type="reset" value="CLEAR">
<input class="submit panel_button" type="submit" value="SUBMIT"/>
</div>
</div>
<div class="panel output_panel">
<div class="loading invisible">
<img class="loading_in_progress" src="/static/img/logo_loading.gif">
<img class="loading_failed" src="/static/img/logo_error.png">
</div>
<div class="output_interfaces">
</div>
<div class="panel_buttons">
<input class="interpret panel_button" type="button" value="INTERPRET"/>
<input class="screenshot panel_button left_panel_button" type="button" value="SCREENSHOT"/>
<input class="record panel_button right_panel_button" type="button" value="GIF"/>
<div class="screenshot_logo invisible">
<img src="/static/img/logo_inline.png">
<button class='record_stop'>
<div class='record_square' style=''></div>
</button>
</div>
<input class="flag panel_button" type="button" value="FLAG"/>
</div>
</div>
</div>
<div class="interpretation_explained invisible">
<h4>Interpretation Legend <span class='close_explain'>&#10006;</span></h4>
<div class='interpretation_legend'>
<div>&larr; Decreased output score / confidence</div>
<div>Increased output score / confidence &rarr;</div>
</div>
<p>When you click Interpret, you can see how different parts of the input contributed to the final output. The legend above will highlight each of the input components as follows:</p>
<ul></ul>
</div>
<div class="examples invisible">
<h4>Examples</small></h4>
<button class="run_examples examples-content">Run All</button>
<button class="load_prev examples-content">Load Previous <em>(CTRL + &larr;)</em></button>
<button class="load_next examples-content">Load Next <em>(CTRL + &rarr;)</em></button>
<button class="order_similar examples-content">Order by Similarity</button>
<button class="view_embeddings examples-content">View Embeddings</button>
<button class="update_embeddings embeddings-content invisible">Update Embeddings</button>
<button class="view_examples embeddings-content invisible">View Examples</button>
<div class="pages invisible">Page:</div>
<table class="examples-content">
</table>
<div class="plot embeddings-content invisible"><canvas id="canvas" width="400px" height="300px"></canvas></div>
</div>`);
let io_master = Object.create(io_master_template);
io_master.fn = fn
io_master.target = target;
io_master.config = config;
io_master.example_file_path = example_file_path;
let input_to_object_map = {
"csv" : {},
"image" : image_input,
"sketchpad" : sketchpad_input,
"textbox" : textbox_input,
"number" : number_input,
"webcam" : webcam,
"microphone" : microphone,
"radio" : radio,
"checkbox" : checkbox,
"checkboxgroup" : checkbox_group,
"slider" : slider,
"dropdown" : dropdown,
"audio" : audio_input,
"file" : file_input,
"dataframe" : dataframe_input,
}
let output_to_object_map = {
"csv" : {},
"image" : image_output,
"label" : label_output,
"keyvalues" : key_values,
"textbox" : textbox_output,
"highlightedtext": highlighted_text,
"audio": audio_output,
"json": json_output,
"html": html_output,
"file" : file_output,
"dataframe" : dataframe_output,
}
let id_to_interface_map = {}
let embedding_chart;
function set_interface_id(interface, id) {
interface.id = id;
id_to_interface_map[id] = interface;
}
if (config["title"]) {
target.find(".title").text(config["title"]);
}
if (config["description"]) {
target.find(".description").text(config["description"]);
}
if (config["share_url"]) {
let share_url = config["share_url"];
target.find(".share").removeClass("invisible");
target.find(".share-link").text(share_url).attr("href", share_url);
target.find(".share-copy").click(function() {
copyToClipboard(share_url);
target.find(".share-copy").text("Copied!");
})
};
_id = 0;
let input_interfaces = [];
let output_interfaces = [];
for (let i = 0; i < config["input_interfaces"].length; i++) {
input_interface_data = config["input_interfaces"][i];
input_interface = Object.create(input_to_object_map[input_interface_data[0]]);
if (input_interface_data[1]["label"]) {
target.find(".input_interfaces").append(`
<div class="panel_header">${input_interface_data[1]["label"]}</strong>
`);
}
target.find(".input_interfaces").append(`
<div class="input_interface interface" interface_id=${_id}>
${input_interface.html}
</div>
`);
input_interface.target = target.find(`.input_interface[interface_id=${_id}]`);
set_interface_id(input_interface, _id);
input_interface.io_master = io_master;
input_interface.init(input_interface_data[1]);
input_interfaces.push(input_interface);
_id++;
}
for (let i = 0; i < config["output_interfaces"].length; i++) {
if (i != 0 && i % (config["output_interfaces"].length / config.function_count) == 0) {
target.find(".output_interfaces").append("<hr>");
}
output_interface_data = config["output_interfaces"][i];
output_interface = Object.create(output_to_object_map[
output_interface_data[0]]);
if (output_interface_data[1]["label"]) {
target.find(".output_interfaces").append(`
<div class="panel_header">${output_interface_data[1]["label"]}</strong>
`);
}
target.find(".output_interfaces").append(`
<div class="output_interface interface" interface_id=${_id}>
${output_interface.html}
</div>
`);
target.find(".output_interfaces").append(`
<div class="loading_time" interface="${i}"> </div>
`);
output_interface.target = target.find(`.output_interface[interface_id=${_id}]`);
set_interface_id(output_interface, _id);
output_interface.io_master = io_master;
output_interface.init(output_interface_data[1]);
output_interfaces.push(output_interface);
_id++;
}
io_master.input_interfaces = input_interfaces;
io_master.output_interfaces = output_interfaces;
if (config.layout == "unaligned") {
target.find(".panels").css("align-items", "flex-start");
} else if (config.layout == "vertical") {
target.find(".panels").css("flex-direction", "column");
}
function clear_all() {
for (let input_interface of input_interfaces) {
input_interface.clear();
}
for (let output_interface of output_interfaces) {
output_interface.clear();
}
target.find(".flag").removeClass("flagged");
target.find(".flag").val("FLAG");
target.find(".flag_message").empty();
target.find(".loading").addClass("invisible");
target.find(".loading_time").text("");
target.find(".output_interfaces").css("opacity", 1);
io_master.last_input = null;
io_master.last_output = null;
}
target.find(".clear").click(clear_all);
if (!config["allow_screenshot"] && !config["allow_flagging"] && !config["allow_interpretation"]) {
target.find(".screenshot, .record, .flag, .interpret").css("visibility", "hidden");
} else {
if (!config["allow_screenshot"]) {
target.find(".screenshot, .record").hide();
}
if (!config["allow_flagging"]) {
target.find(".flag").hide();
}
if (!config["allow_interpretation"]) {
target.find(".interpret").hide();
} else {
let interpret_html = "";
for (let [i, interface] of io_master.input_interfaces.entries()) {
let label = config.input_interfaces[i][1]["label"];;
interpret_html += "<li><strong>" + label + "</strong> - " + interface.interpretation_logic + "</li>";
}
target.find(".interpretation_explained ul").html(interpret_html);
target.find(".interpretation_explained .close_explain").click(function() {
target.find(".interpretation_explained").remove();
});
if (config["examples"]) {
target.find(".examples").removeClass("invisible");
let html = "<thead>"
for (let i = 0; i < config["input_interfaces"].length; i++) {
label = config["input_interfaces"][i][1]["label"];
html += "<th>" + label + "</th>";
}
}
}
}
function load_example(example_id) {
clear_all();
for (let [i, value] of config["examples"][example_id].entries()) {
input_interfaces[i].load_example(value);
};
if (io_master.loaded_examples && example_id in io_master.loaded_examples) {
io_master.output({"data": io_master.loaded_examples[example_id]});
}
let example_order = io_master.order_mapping.indexOf(example_id);
let current_page = Math.floor(example_order / config["examples_per_page"]);
if (current_page != io_master.current_page) {
io_master.current_page = current_page;
load_page();
}
$(".examples_body > tr").removeClass("current_example");
$(".examples_body > tr[row='" + example_id + "'").addClass("current_example");
io_master.current_example = example_id;
}
function next_example() {
current_example = io_master.current_example;
if (current_example == null) {
new_index = 0;
} else {
new_index = (io_master.order_mapping.indexOf(current_example) + 1 + config.examples.length) % config.examples.length;
}
load_example(io_master.order_mapping[new_index]);
}
function prev_example() {
current_example = io_master.current_example;
if (current_example == null) {
new_index = 0;
} else {
new_index = (io_master.order_mapping.indexOf(current_example) - 1 + config.examples.length) % config.examples.length;
}
load_example(io_master.order_mapping[new_index]);
}
function load_page() {
page_num = io_master.current_page;
target.find(".page").removeClass("primary");
target.find(`.page[page=${page_num}]`).addClass("primary");
let page_start = page_num * config["examples_per_page"]
let html = "";
for (let i = page_start; i < page_start + config["examples_per_page"] && i < config.examples.length; i++) {
let example_id = io_master.order_mapping[i];
let example = config["examples"][example_id];
html += "<tr row=" + example_id + ">";
for (let [j, col] of example.entries()) {
let new_col = JSON.parse(JSON.stringify(col))
if (input_interfaces[j].load_example_preview) {
new_col = input_interfaces[j].load_example_preview(new_col);
}
html += "<td>" + new_col + "</td>";
}
if (io_master.loaded_examples && example_id in io_master.loaded_examples) {
output_values = io_master.loaded_examples[example_id]
for (let j = 0; j < output_values.length; j++) {
let output_interface = io_master.output_interfaces[j];
let example_preview = output_values[j];
if (output_interface.load_example_preview) {
example_preview = output_interface.load_example_preview(example_preview)
}
html += "<td>" + example_preview + "</td>";
}
}
html += "</tr>";
}
target.find(".examples > table > tbody").html(html);
}
if (config["examples"]) {
target.find(".examples").removeClass("invisible");
let html = "<thead>"
for (let i = 0; i < config["input_interfaces"].length; i++) {
label = config["input_interfaces"][i][1]["label"];
html += "<th>" + label + "</th>";
}
html += "</thead>";
html += "<tbody class='examples_body'></tbody>";
target.find(".examples table").html(html);
io_master.current_page = 0;
io_master.order_mapping = [...Array(config.examples.length).keys()];
let page_count = Math.ceil(config.examples.length / config.examples_per_page)
if (page_count > 1) {
target.find(".pages").removeClass("invisible");
let html = "";
for (let i = 0; i < page_count; i++) {
html += `<button class='page' page='${i}'>${i+1}</button>`
}
target.find(".pages").append(html);
}
load_page();
target.on("click", ".examples_body > tr", function() {
let example_id = parseInt($(this).attr("row"));
load_example(example_id);
})
target.on("click", ".page", function() {
let page_num = parseInt($(this).attr("page"));
io_master.current_page = page_num;
load_page();
})
target.find(".load_prev").click(prev_example);
target.find(".load_next").click(next_example);
target.find(".order_similar").click(function() {
io_master.score_similarity(function() {
io_master.current_page = 0
io_master.current_example = null;
load_page();
})
});
target.find(".view_examples").click(function() {
target.find(".examples-content").removeClass("invisible");
target.find(".embeddings-content").addClass("invisible");
});
target.find(".update_embeddings").click(function() {
io_master.update_embeddings(function(output) {
embedding_chart.data.datasets[0].data.push(output["sample_embedding_2d"][0]);
console.log(output["sample_embedding_2d"][0])
embedding_chart.update();
})
});
target.find(".view_embeddings").click(function() {
io_master.view_embeddings(function(output) {
let ctx = $('#canvas')[0].getContext('2d');
let backgroundColors = getBackgroundColors(io_master);
embedding_chart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [{
label: 'Sample Embedding',
data: output["sample_embedding_2d"],
backgroundColor: 'rgb(0, 0, 0)',
borderColor: 'rgb(0, 0, 0)',
pointRadius: 13,
pointHoverRadius: 13,
pointStyle: 'rectRot',
showLine: true,
fill: false,
}, {
label: 'Dataset Embeddings',
data: output["example_embeddings_2d"],
backgroundColor: backgroundColors,
borderColor: backgroundColors,
pointRadius: 7,
pointHoverRadius: 7
}]
},
options: {
legend: {display: false}
}
});
$("#canvas")[0].onclick = function(evt){
var activePoints = embedding_chart.getElementsAtEvent(evt);
var firstPoint = activePoints[0];
if (firstPoint._datasetIndex==1) { // if it's from the sample embeddings dataset
load_example(firstPoint._index)
}
};
target.find(".examples-content").addClass("invisible");
target.find(".embeddings-content").removeClass("invisible");
})
});
$("body").keydown(function(e) {
if ($(document.activeElement).attr("type") == "text" || $(document.activeElement).attr("type") == "textarea") {
return;
}
e = e || window.event;
var keyCode = e.keyCode || e.which,
arrow = {left: 37, up: 38, right: 39, down: 40 };
if (e.ctrlKey) {
if (keyCode == arrow.left) {
prev_example();
} else if (keyCode == arrow.right) {
next_example();
}
}
});
};
target.find(".screenshot").click(function() {
$(".screenshot, .record").hide();
$(".screenshot_logo").removeClass("invisible");
$(".record_stop").hide();
html2canvas(target[0], {
scrollX: 0,
scrollY: -window.scrollY
}).then(function(canvas) {
saveAs(canvas.toDataURL(), 'screenshot.png');
$(".screenshot, .record").show();
$(".screenshot_logo").addClass("invisible");
});
});
target.find(".record").click(function() {
$(".screenshot, .record").hide();
$(".screenshot_logo").removeClass("invisible");
$(".record_stop").show();
target.append("<canvas class='recording_draw invisible' width=640 height=480></canvas>");
target.append("<video class='recording invisible' autoplay playsinline></video>");
navigator.mediaDevices.getDisplayMedia(
{ video: { width: 9999, height: 9999 } }
).then(stream => {
video = target.find("video.recording")[0];
canvas = target.find("canvas.recording_draw")[0];
io_master.recording = {frames: [], stream: stream};
video.srcObject = stream;
const ctx = canvas.getContext('2d');
io_master.recording.interval = window.setInterval(() => {
let first = (io_master.recording.width === undefined);
if (first) {
io_master.recording.width = video.videoWidth;
io_master.recording.height = video.videoHeight;
io_master.recording.start = Date.now();
canvas.width = `${video.videoWidth}`;
canvas.height = `${video.videoHeight}`;
}
ctx.drawImage(video, 0, 0);
const imageData = ctx.getImageData(0, 0, io_master.recording.width, io_master.recording.height);
io_master.recording.frames.push({
imageData,
timestamp: first ? 0 : Date.now() - this.startTime
});
}, 100);
});
});
target.find(".record_stop").click(function() {
window.clearInterval(io_master.recording.interval);
io_master.recording.stream.getTracks().forEach(track => track.stop());
const gif = new GifEncoder({
width: io_master.recording.width,
height: io_master.recording.height,
});
gif.once('finished', blob => {
saveAs(URL.createObjectURL(blob), 'recording.gif');
});
const start = 0;
const end = io_master.recording.frames.length - 1;
const processFrame = index => {
if (index > end) {
gif.render();
return;
}
let { imageData, timestamp } = io_master.recording.frames[index];
const delay = index < end ? io_master.recording.frames[index + 1].timestamp - timestamp : 100;
gif.addFrame(imageData, delay);
setTimeout(() => processFrame(index + 1), 0);
};
processFrame(start);
$(".screenshot, .record").show();
$(".screenshot_logo").addClass("invisible");
target.find("canvas.recording_draw").remove();
target.find("video.recording").remove();
})
if (config.live) {
io_master.gather();
} else {
target.find(".submit").show();
target.find(".submit").click(function() {
io_master.gather();
target.find(".flag").removeClass("flagged");
target.find(".flag").val("FLAG");
})
}
if (!config.show_input) {
target.find(".input_panel").hide();
}
target.find(".flag").click(function() {
if (io_master.last_output) {
target.find(".flag").addClass("flagged");
target.find(".flag").val("FLAGGED");
io_master.flag();
}
})
target.find(".interpret").click(function() {
target.find(".interpretation_explained").removeClass("invisible");
if (io_master.last_output) {
io_master.interpret();
}
});
target.find(".run_examples").click(function() {
if (!io_master.has_loaded_examples) {
this.has_loaded_examples = true;
let html = ""
for (let i = 0; i < io_master.output_interfaces.length; i++) {
html += "<th>" + config.output_interfaces[i][1]["label"] + "</th>";
}
target.find(".examples > table > thead > tr").append(html);
}
io_master.has_loaded_examples = true;
io_master.submit_examples(load_page);
})
$(".input_panel").on("mouseover", ".alternate", function() {
let interface_index = $(this).closest(".interface").attr("interface_id");
let alternate_index = $(this).attr("alternate_index");
io_master.alternative_interpret(interface_index, alternate_index);
})
$(".input_panel").on("mouseout", ".alternate", function() {
io_master.alternative_interpret(false);
})
return io_master;
}
function gradio_url(config, url, target, example_file_path) {
return gradio(config, function(data, action) {
return new Promise((resolve, reject) => {
$.ajax({type: "POST",
url: url + action + "/",
data: JSON.stringify({"data": data}),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: resolve,
error: reject,
});
});
}, target, example_file_path);
}
function saveAs(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
//Firefox requires the link to be in the body
document.body.appendChild(link);
//simulate click
link.click();
//remove the link when done
document.body.removeChild(link);
} else {
window.open(uri);
}
}

View File

@ -1,174 +0,0 @@
const audio_input = {
html: `
<div class="interface_box">
<div class="file_zone hidden">
<div class="upload_zone drop_zone">
<div class="input_caption">Drop Audio Here<br>- or -<br>Click to Upload</div>
</div>
<div class="file_display hide">
<div class="file_name"></div>
<div class="file_size"></div>
</div>
<input class="hidden_upload" type="file" accept="audio/*" />
</div>
<div class="upload_zone mic_zone hidden">
<img class="not_recording" src="/static/img/mic.png" />
<div class="recording hidden volume_display">
<div class="volume volume_left">
<div class="volume_bar"></div>
</div>
<img src="/static/img/mic_recording.png" />
<div class="volume volume_right">
<div class="volume_bar"></div>
</div>
</div>
<div class="not_recording input_caption">Click to Record from Microphone</div>
<div class="recording hidden input_caption">Click to Stop Recording</div>
</div>
<div class="player hidden">
<div class="waveform"></div>
<div class="interpret_range"></div>
<button class="playpause primary">Play / Pause</button>
</div>
</div>
`,
state: "NO_AUDIO",
init: function(opts) {
var io = this;
this.source = opts.source;
this.wavesurfer = WaveSurfer.create({
container: io.target.find('.waveform')[0],
waveColor: '#888888',
progressColor: '#e67e22',
barWidth: 3,
hideScrollbar: true
});
if (this.source == "microphone") {
this.target.find(".mic_zone").removeClass("hidden");
this.target.find(".mic_zone").click(function() {
if (io.state == "NO_AUDIO") {
if (!has_audio_loaded) {
loadAudio();
io.mic = new p5.AudioIn();
}
io.recorder = new p5.SoundRecorder();
io.soundFile = new p5.SoundFile();
io.recorder.setInput(io.mic);
io.target.find(".recording").removeClass("hidden");
io.target.find(".not_recording").hide();
io.state = "RECORDING";
io.mic.start();
io.recorder.record(io.soundFile);
io.interval_id = window.setInterval(function () {
var volume = Math.floor(100 * io.mic.getLevel());
io.target.find(".volume_bar").width(`${(volume > 0 ? 10 : 0) + Math.round(2 * Math.sqrt(10 * volume))}px`)
}, 100)
}
});
this.target.find(".mic_zone").mousedown(function() {
if (io.state == "RECORDING" || io.state == "STOP_RECORDING") {
io.recorder.stop();
var blob = io.soundFile.getBlob();
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
io.load_preview_from_audio(reader.result);
}
if (io.interval_id) {
window.clearInterval(io.interval_id);
}
}
})
} else if (this.source == "upload") {
this.target.find(".file_zone").removeClass("hidden");
this.target.find(".upload_zone").click(function (e) {
io.target.find(".hidden_upload").click();
});
this.target.on('drag dragstart dragend dragover dragenter dragleave drop',
".drop_zone", function(e) {
e.preventDefault();
e.stopPropagation();
})
this.target.on('drop', '.drop_zone', function(e) {
files = e.originalEvent.dataTransfer.files;
io.load_preview_from_files(files)
});
this.target.find('.hidden_upload').on('change', function (e) {
if (this.files) {
io.load_preview_from_files(this.files);
}
})
}
this.target.find(".playpause").click(function () {
io.wavesurfer.playPause();
})
},
load_preview_from_audio: function(audio) {
var io = this;
io.audio_data = audio;
io.target.find(".upload_zone").hide();
io.target.find(".player").removeClass("hidden");
io.wavesurfer.load(io.audio_data);
if (io.state == "STOP_RECORDING") {
io.state = "RECORDED";
io.submit();
}
io.state = "RECORDED";
},
load_preview_from_files: function(files) {
if (!files.length || !window.FileReader) {
return
}
var ReaderObj = new FileReader()
ReaderObj.readAsDataURL(files[0])
io = this;
this.state = "AUDIO_LOADING"
ReaderObj.onloadend = function() {
io.load_preview_from_audio(this.result);
}
},
submit: function() {
if (this.state == "RECORDED") {
this.io_master.input(this.id, this.audio_data);
} else if (this.state == "RECORDING") {
this.state = "STOP_RECORDING";
this.target.find(".upload_zone").mousedown();
}
},
load_example: function(example_data) {
example_data = this.io_master.example_file_path + example_data;
let io = this;
if (io.state == "NO_AUDIO" || io.state == "RECORDED") {
io.clear();
toDataURL(example_data, function(data) {
io.load_preview_from_audio(data);
})
}
},
show_interpretation: function(data) {
let html = ""
for (let [i, value] of data.entries()) {
html += `
<div class='alternate' alternate_index='${i}'
style='background-color: ${getSaliencyColor(value)}'>
</div> `
}
this.target.find(".interpret_range").html(html);
},
interpretation_logic: "Highlights the output contribution of subsections of the audio input split by time.",
clear: function() {
this.audio_data = null;
this.state = "NO_AUDIO";
this.target.find(".interpret_range").empty();
this.target.find(".not_recording").show();
this.target.find(".recording").addClass("hidden");
this.target.find(".player").addClass("hidden");
this.target.find(".upload_zone").show();
this.target.find(".hidden_upload").prop("value", "")
if (this.wavesurfer) {
this.wavesurfer.stop();
}
}
}

View File

@ -1,50 +0,0 @@
const checkbox = {
html: `
<div class="checkbox_solo">
<label class='holder'><input class="checkbox" type="checkbox">&nbsp;</label>
<div class="interpretation interpret_sub"></div>
</div>`,
init: function(opts) {
this.target.find("input").checkboxradio();
},
show_interpretation: function(data) {
let html = ""
let alternate_index = 0;
for (let i = 0; i < data.length; i++) {
let score = data[i];
let mark = ["&#x2717;", "&#x2713;"][i];
if (score == null) {
html += `<div class='interpret_check interpret_select'>
${mark}
</div>`
} else {
html += `<div class='interpret_check alternate'
alternate_index='${alternate_index}'
style='background-color: ${getSaliencyColor(score)}'>
${mark}
</div>`
alternate_index++;
}
}
this.target.find(".interpretation").html(html);
},
interpretation_logic: "Highlights the result of the alternative selection to checkbox. Hover to see alternative output.",
submit: function() {
let io = this;
let is_checked = this.target.find("input").prop("checked")
this.io_master.input(this.id, is_checked);
},
clear: function() {
this.target.find(".interpretation").empty();
this.target.find("input").prop("checked", false);
this.target.find("input").button("refresh");
},
load_example: function(data) {
if (data) {
this.target.find("input").prop("checked", true);
} else {
this.target.find("input").prop("checked", false);
}
this.target.find("input").button("refresh");
}
}

View File

@ -1,70 +0,0 @@
const checkbox_group = {
html: ``,
init: function(opts) {
this.choices = opts.choices;
html = "<div class='checkbox_group'>"
for ([index, choice] of opts.choices.entries()) {
html += `
<label for="${this.id}_${index}">
<input id="${this.id}_${index}" type="checkbox" name="${this.id}" value="${index}">
<span>${choice}<span>
</label>
`;
}
html += "</div>"
this.target.html(html);
this.target.find("input").checkboxradio();
},
submit: function() {
let io = this;
let val_names = [];
this.target.find("input:checked").each(function(_, item) {
val_names.push(io.choices[$(item).val()])
})
this.io_master.input(this.id, val_names);
},
show_interpretation: function(data) {
this.target.find(".interpret_check").remove();
let alternate_index = 0;
for (let i = 0; i < data.length; i++) {
let html = "<div class='interpret_sub'>"
for (let j = 0; j < data[i].length; j++) {
let score = data[i][j];
let mark = ["&#x2717;", "&#x2713;"][j];
if (score == null) {
html += `<div class='interpret_check interpret_select'>
${mark}
</div>`
} else {
html += `<div class='interpret_check alternate'
alternate_index='${alternate_index}'
style='background-color: ${getSaliencyColor(score)}'>
${mark}
</div>`
alternate_index++;
}
}
html += "</div>"
this.target.find("label").eq(i).append(html);
}
},
interpretation_logic: "Highlights the result of alternative selections to the checkboxes. Hover to see alternative output.",
clear: function() {
this.target.find(".interpretation").empty();
this.target.find("input").prop("checked", false);
this.target.find("input").button("refresh");
},
load_example: function(data) {
for (let [i, choice] of this.choices.entries()) {
let child = i + 1;
let checkbox = this.target.find("label:nth-child("+child+") input");
console.log(data, choice, child)
if (data.includes(choice)) {
checkbox.prop("checked", true);
} else {
checkbox.prop("checked", false);
}
}
this.target.find("input").button("refresh");
}
}

View File

@ -1,113 +0,0 @@
const dataframe_input = {
html: `
<div class="interface_max_box">
<div class="dataframe">
</div>
</div>
`,
init: function(opts) {
let row_count = opts.row_count;
let col_count = opts.col_count;
this.datatype = opts.datatype;
let data = [];
for (let i = 0; i < row_count; i++) {
let row = []
for (let j = 0; j < col_count; j++) {
row.push(null);
}
data.push(row);
}
this.default_data = data;
this.opts = opts;
this.reset(this.default_data);
},
reset: function(data) {
if (this.table) {
this.table.destroy();
}
row_count = data.length;
col_count = data[0].length;
config = {};
if (this.opts.headers || this.opts.datatype) {
let column_config = [];
for (let i = 0; i < col_count; i++) {
let column = {};
if (this.opts.datatype) {
let datatype = typeof this.opts.datatype === "string" ? this.opts.datatype : this.opts.datatype[i];
let datatype_map = {"str": "text", "bool": "checkbox", "number": "numeric", "date": "calendar"}
column.type = datatype_map[datatype];
}
if (this.opts.headers) {
column.title = this.opts.headers[i];
}
column_config.push(column);
}
config.columns = column_config;
}
config.data = data;
this.table = this.target.find(".dataframe").jexcel(config);
},
submit: function() {
let data = this.table.getData();
if (this.datatype) {
for (let i = 0; i < data[0].length; i++) {
if (this.datatype == "number" || (i < this.datatype.length && this.datatype[i] == "number")) {
for (let j = 0; j < data.length; j++) {
let val = data[j][i];
data[j][i] = val == "" ? 0 : parseFloat(val);
}
}
}
}
this.io_master.input(this.id, data);
},
show_interpretation: function(data) {
this.target.find("td").css("background-color", "white")
let cell_name = (i, j) => {
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let column_name = letters[i % 26];
if (i >= 26) {
column_name = letters[Math.floor(i / 26) - 1] + column_name;
}
return column_name + (j + 1);
}
for (let [j, row] of data.entries()) {
for (let [i, value] of row.entries()) {
console.log(cell_name(i, j), value);
this.table.setStyle(cell_name(i, j), 'background-color', getSaliencyColor(value));
}
}
},
interpretation_logic: "Highlights the output contribution of each cell in dataframe.",
load_example_preview: function(data) {
let data_copy = [];
for (let row of data.splice(0,3)) {
new_row = row.splice(0,3)
if (row.length > 3) {
new_row.push("...");
}
data_copy.push(new_row);
}
if (data.length > 3) {
new_row = Array(data_copy[0].length).fill("...");
data_copy.push(new_row);
}
let html = "<table><tbody>"
for (let row of data_copy) {
html += "<tr>";
for (let cell of row) {
html += "<td>" + cell + "</td>";
}
html += "</tr>";
}
html += "</tbody></table>";
return html;
},
load_example: function(data) {
this.reset(data);
},
clear: function() {
this.reset(this.default_data);
this.target.find("td").css("background-color", "white");
}
}

View File

@ -1,54 +0,0 @@
const dropdown = {
html: `
<div class="select_holder"></div>
<div class="select_interpretation interpret_sub"></div>
`,
init: function(opts) {
this.choices = opts.choices;
html = "<select class='dropdown'>"
for ([index, choice] of opts.choices.entries()) {
html += `<option value="${index}">${choice}</option>`
}
html += "</select>"
this.target.find(".select_holder").html(html);
this.target.find(".dropdown").selectmenu();
},
show_interpretation: function(data) {
let html = ""
let alternate_index = 0;
for (let i = 0; i < this.choices.length; i++) {
if (data[i] == null) {
html += `
<div class='interpret_select'>
${this.choices[i]}
</div>`
} else {
html += `
<div class='alternate'
alternate_index=${alternate_index}
style='background-color: ${getSaliencyColor(data[i])}'>
${this.choices[i]}
</div>`;
alternate_index++;
}
}
this.target.find(".select_interpretation").html(html);
},
interpretation_logic: "Highlights the result of the alternative selection to dropdown. Hover to see alternative output.",
submit: function() {
checked_val = this.target.find("option:selected").val();
if (checked_val) {
this.io_master.input(this.id, this.choices[checked_val]);
}
},
clear: function() {
this.target.find("option").prop("selected", false);
this.target.find(".dropdown").selectmenu("refresh");
this.target.find(".select_interpretation").empty();
},
load_example: function(data) {
let child = this.choices.indexOf(data) + 1;
this.target.find("option:nth-child(" + child + ")").prop("selected", true);
this.target.find(".dropdown").selectmenu("refresh");
}
}

View File

@ -1,82 +0,0 @@
const file_input = {
html: `
<div class="interface_mini_box">
<div class="upload_zone drop_zone">
<div class="input_caption">Drop File Here<br>- or -<br>Click to Upload</div>
</div>
<div class="file_display hide">
<div class="file_name"></div>
<div class="file_size"></div>
</div>
<input class="hidden_upload" type="file">
</div>`
,
init: function(opts) {
var io = this;
this.target.find(".upload_zone").click(function (e) {
io.target.find(".hidden_upload").click();
});
this.target.on('drag dragstart dragend dragover dragenter dragleave drop',
".drop_zone", function(e) {
e.preventDefault();
e.stopPropagation();
})
this.target.on('drop', '.drop_zone', function(e) {
files = e.originalEvent.dataTransfer.files;
io.load_preview_from_files(files)
});
this.target.find('.hidden_upload').on('change', function (e) {
if (this.files) {
io.load_preview_from_files(this.files);
}
})
},
submit: function() {
if (this.file_data) {
this.io_master.input(this.id, this.file_data);
}
},
load_preview: function() {
var io = this;
io.target.find(".upload_zone").hide();
io.target.find(".file_display").removeClass("hide");
io.target.find(".file_name").text(io.file_data.name);
if (io.file_data.size !== null) {
io.target.find(".file_size").text(prettyBytes(io.file_data.size));
}
},
load_preview_from_files: function(files) {
if (!files.length || !window.FileReader) {
return
}
var ReaderObj = new FileReader()
ReaderObj.readAsDataURL(files[0])
var io = this;
ReaderObj.onloadend = function() {
io.file_data = {
"name": files[0].name,
"size": files[0].size,
"data": this.result,
"is_local_example": false
}
io.load_preview()
};
},
load_example: function(example_data) {
var io = this;
io.file_data = {
"name": example_data,
"data": null,
"size": null,
"is_local_example": true
};
io.load_preview();
},
clear: function() {
this.target.find(".upload_zone").show();
this.target.find(".file_display").addClass("hide");
this.target.find(".hidden_upload").prop("value", "")
this.file_data = null;
},
file_data: null,
}

View File

@ -1,275 +0,0 @@
const image_input = {
html: `
<div class="interface_box">
<div class="upload_zone drop_zone hide">
<div class="input_caption">Drop Image Here<br>- or -<br>Click to Upload</div>
</div>
<div class="webcam upload_zone hide">
<div class="webcam_box">
</div>
<span>Click to Snap!</span>
</div>
<div class="sketchpad hide">
<div class="sketch_tools">
<div id="brush_1" size="8" class="brush"></div>
<div id="brush_2" size="16" class="brush selected"></div>
<div id="brush_3" size="24" class="brush"></div>
</div>
<div class="view_holders">
<div class="canvas_holder">
<canvas class="sketch"></canvas>
</div>
</div>
</div>
<div class="image_display hide">
<div class="edit_holder">
<button class="edit_image interface_button primary">Edit</button>
</div>
<div class="view_holders">
<div class="image_preview_holder">
<img class="image_preview" />
</div>
<div class="saliency_holder hide">
<canvas class="saliency"></canvas>
</div>
</div>
</div>
<input class="hidden_upload" type="file" accept="image/x-png,image/gif,image/jpeg" />
</div>
`
,
overlay_html: `
<div class="overlay interface_extension image_editor_overlay hide" interface_id="{0}">
<div class="image_editor_holder">
<div class="image_editor"></div>
</div>
</div>
`,
init: function(opts) {
var io = this;
this.shape = opts.shape;
this.source = opts.source;
this.tool = opts.tool;
if (this.tool == "select") {
this.target.find('.edit_holder').hide();
}
$('body').append(this.overlay_html.format(this.id));
this.overlay_target = $(`.overlay[interface_id=${this.id}]`);
if (this.source == "upload") {
io.target.find(".drop_zone").removeClass("hide");
this.target.find(".drop_zone").click(function (e) {
io.target.find(".hidden_upload").click();
});
this.target.on('drag dragstart dragend dragover dragenter dragleave drop',
".drop_zone", function(e) {
e.preventDefault();
e.stopPropagation();
})
this.target.on('drop', '.drop_zone', function(e) {
files = e.originalEvent.dataTransfer.files;
io.load_preview_from_files(files)
});
this.target.find('.hidden_upload').on('change', function (e) {
if (this.files) {
io.load_preview_from_files(this.files);
}
})
} else if (this.source == "webcam") {
io.target.find(".webcam").removeClass("hide");
let w = this.target.find(".webcam_box").width();
let h = this.target.find(".webcam_box").height();
let RATIO = 4/3;
let dim = Math.min(h, w / RATIO);
Webcam.set({
image_format: 'jpeg',
width: dim * RATIO,
height: dim,
dest_width: dim * RATIO,
dest_height: dim,
})
Webcam.attach(this.target.find(".webcam_box")[0]);
if (io.io_master.config.live) {
io.target.find(".webcam span").hide();
} else {
io.target.find(".webcam").click(function() {
Webcam.snap(function(image_data) {
io.target.find(".webcam").hide();
io.target.find(".image_display").removeClass("hide");
io.set_image_data(image_data, /*update_editor=*/true);
io.state = "IMAGE_LOADED";
});
})
}
} else if (this.source == "canvas") {
io.target.find(".sketchpad").removeClass("hide");
var dimension = Math.min(this.target.find(".canvas_holder").width(),
this.target.find(".canvas_holder").height()) - 2 // dimension - border
var id = this.id;
this.sketchpad = new Sketchpad({
element: '.interface[interface_id=' + id + '] .sketch',
width: dimension,
height: dimension
});
this.sketchpad.penSize = this.target.find(".brush.selected").attr("size");
this.canvas = this.target.find('.canvas_holder canvas')[0];
this.context = this.canvas.getContext("2d");
this.target.find(".brush").click(function (e) {
io.target.find(".brush").removeClass("selected");
$(this).addClass("selected");
io.sketchpad.penSize = $(this).attr("size");
})
this.clear();
}
this.target.find('.edit_image').click(function (e) {
io.overlay_target.removeClass("hide");
})
this.tui_editor = new tui.ImageEditor(this.overlay_target.
find(".image_editor")[0], {
includeUI: {
menuBarPosition: 'left',
menu: ['crop', 'flip', 'rotate', 'draw', 'filter', 'text']
},
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70
}
})
this.overlay_target.find(".tui-image-editor-header-buttons").html(`
<button class="tui_save tui_close interface_button primary">Save</button>
<button class="tui_cancel tui_close interface_button secondary">Cancel</button>
`)
this.overlay_target.find('.tui_close').click(function (e) {
io.overlay_target.addClass("hide");
if ($(e.target).hasClass('tui_save')) {
io.set_image_data(io.tui_editor.toDataURL(), /*update_editor=*/false);
}
});
},
submit: function() {
var io = this;
if (this.source == "canvas") {
var dataURL = this.canvas.toDataURL("image/png");
this.io_master.input(this.id, dataURL);
} else if (this.state == "IMAGE_LOADED") {
if (io.tool == "select") {
let canvas = io.cropper.getCroppedCanvas();
var dataURL = canvas.toDataURL("image/png");
this.io_master.input(this.id, dataURL);
} else {
io.io_master.input(io.id, this.image_data);
}
} else if (this.source == "webcam") {
if (!Webcam.loaded) {
io.io_master.no_input();
return;
}
Webcam.snap(function(image_data) {
if (io.io_master.config.live) {
io.io_master.input(io.id, image_data);
} else {
io.target.find(".webcam").hide();
io.target.find(".image_display").removeClass("hide");
io.set_image_data(image_data, /*update_editor=*/true);
io.state = "IMAGE_LOADED";
io.io_master.input(io.id, image_data);
}
});
} else {
io.io_master.no_input();
}
},
clear: function() {
if (this.source == "canvas") {
this.context.fillStyle = "#FFFFFF";
this.context.fillRect(0, 0, this.context.canvas.width, this.context.
canvas.height);
} else {
this.target.find(".upload_zone").show();
this.target.find(".image_preview").attr('src', '');
this.target.find(".image_display").addClass("hide");
this.target.find(".hidden_upload").prop("value", "")
this.state = "NO_IMAGE";
this.image_data = null;
if (this.cropper) {
this.cropper.destroy();
}
}
this.target.find(".saliency_holder").addClass("hide");
},
show_interpretation: function(data) {
if (this.target.find(".image_preview").attr("src")) {
var img = this.target.find(".image_preview")[0];
var size = getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight);
if (this.shape) {
size = getObjectFitSize(true, size.width, size.height, this.shape[0], this.shape[1])
}
var width = size.width;
var height = size.height;
this.target.find(".saliency_holder").removeClass("hide").html(`
<canvas class="saliency" width=${width} height=${height}></canvas>`);
var ctx = this.target.find(".saliency")[0].getContext('2d');
paintSaliency(data, ctx, width, height);
}
},
interpretation_logic: "Highlights the output contribution of subregions of image.",
state: "NO_IMAGE",
image_data: null,
set_image_data: function(image_data, update_editor) {
let io = this;
io.image_data = image_data
io.target.find(".image_preview").attr('src', image_data);
if (update_editor) {
io.tui_editor.loadImageFromURL(io.image_data, 'input').then(function (sizeValue) {
io.tui_editor.clearUndoStack();
io.tui_editor.ui.activeMenuEvent();
io.tui_editor.ui.resizeEditor({ imageSize: sizeValue });
});
}
if (io.tool == "select") {
io.cropper = new Cropper(io.target.find(".image_preview")[0]);
}
},
load_preview_from_files: function(files) {
if (!files.length || !window.FileReader || !/^image/.test(files[0].type)) {
return
}
var ReaderObj = new FileReader()
ReaderObj.readAsDataURL(files[0])
ReaderObj.io = this;
this.state = "IMAGE_LOADING"
ReaderObj.onloadend = function() {
let io = this.io;
io.target.find(".upload_zone").hide();
io.target.find(".image_display").removeClass("hide");
io.set_image_data(this.result, /*update_editor=*/true);
io.state = "IMAGE_LOADED"
}
},
load_example_preview: function(data) {
return "<img src='"+this.io_master.example_file_path+data+"' height=100>"
},
load_example: function(example_data) {
example_data = this.io_master.example_file_path + example_data;
let io = this;
toDataURL(example_data, function(data) {
if (io.source == "canvas") {
io.clear();
let ctx = this.context;
var img = new Image;
let dimension = io.target.find(".canvas_holder canvas").width();
img.onload = function(){
ctx.clearRect(0,0,dimension,dimension);
ctx.drawImage(img,0,0,dimension,dimension);
};
img.src = data;
} else {
io.target.find(".upload_zone").hide();
io.target.find(".image_display").removeClass("hide");
io.set_image_data(data, /*update_editor=*/true);
io.state = "IMAGE_LOADED";
}
})
}
}

View File

@ -1,98 +0,0 @@
const microphone = {
html: `
<div class="interface_box">
<div class="upload_zone">
<img class="not_recording" src="/static/img/mic.png" />
<div class="recording hidden volume_display">
<div class="volume volume_left">
<div class="volume_bar"></div>
</div>
<img src="/static/img/mic_recording.png" />
<div class="volume volume_right">
<div class="volume_bar"></div>
</div>
</div>
<div class="not_recording input_caption">Click to Record from Microphone</div>
<div class="recording hidden input_caption">Click to Stop Recording</div>
</div>
<div class="player hidden">
<div class="waveform"></div>
<button class="playpause primary">Play / Pause</button>
</div>
</div>
`,
state: "NO_AUDIO",
init: function(opts) {
var io = this;
this.wavesurfer = WaveSurfer.create({
container: '.waveform',
waveColor: '#888888',
progressColor: '#e67e22',
barWidth: 3,
hideScrollbar: true
});
this.target.find(".upload_zone").click(function() {
if (io.state == "NO_AUDIO") {
if (!has_audio_loaded) {
loadAudio();
io.mic = new p5.AudioIn();
}
io.recorder = new p5.SoundRecorder();
io.soundFile = new p5.SoundFile();
io.recorder.setInput(io.mic);
io.target.find(".recording").removeClass("hidden");
io.target.find(".not_recording").hide();
io.state = "RECORDING";
io.mic.start();
io.recorder.record(io.soundFile);
var interval_id = window.setInterval(function () {
var volume = Math.floor(100 * io.mic.getLevel());
io.target.find(".volume_bar").width(`${(volume > 0 ? 10 : 0) + Math.round(2 * Math.sqrt(10 * volume))}px`)
}, 100)
}
});
this.target.find(".upload_zone").mousedown(function() {
if (io.state == "RECORDING" || io.state == "STOP_RECORDING") {
io.target.find(".upload_zone").hide();
io.recorder.stop();
var blob = io.soundFile.getBlob();
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
io.audio_data = reader.result;
io.target.find(".player").removeClass("hidden");
io.wavesurfer.load(io.audio_data);
if (io.state == "STOP_RECORDING") {
io.state = "RECORDED";
io.submit();
}
io.state = "RECORDED";
}
window.clearInterval(interval_id);
}
})
this.target.find(".playpause").click(function () {
io.wavesurfer.playPause();
})
},
submit: function() {
if (this.state == "RECORDED") {
this.io_master.input(this.id, this.audio_data);
} else if (this.state == "RECORDING") {
this.state = "STOP_RECORDING";
this.target.find(".upload_zone").mousedown();
}
},
clear: function() {
this.audio_data = null;
this.state = "NO_AUDIO";
this.target.find(".not_recording").show();
this.target.find(".recording").addClass("hidden");
this.target.find(".player").addClass("hidden");
this.target.find(".upload_zone").show();
if (this.wavesurfer) {
this.wavesurfer.stop();
}
}
}

View File

@ -1,50 +0,0 @@
const number_input = {
html: `
<input type="text" class="input_text">
<div class="interpret_range"></div>
`,
init: function(opts) {
if (opts.default) {
this.target.find(".input_text").val(opts.default)
}
},
submit: function() {
text = this.target.find(".input_text").val();
if (!isNaN(parseFloat(text))) {
this.io_master.input(this.id, parseFloat(text));
} else {
this.io_master.no_input();
}
},
clear: function() {
this.target.find(".interpret_range").empty();
this.target.find(".input_text").val("");
this.target.find(".input_text").show();
},
show_interpretation: function(data) {
let html = ""
let alternate_index = 0;
for (let value_set of data) {
[value, score] = value_set;
if (score == null) {
html += `
<div class='interpret_select'>
${value}
</div>`
} else {
html += `
<div class='alternate'
alternate_index=${alternate_index}
style='background-color: ${getSaliencyColor(score)}'>
${value}
</div>`;
alternate_index++;
}
}
this.target.find(".interpret_range").html(html);
},
interpretation_logic: "Highlights the result of the alternative, neighboring values to input. Hover to see alternative output.",
load_example: function(data) {
this.target.find(".input_text").val(data);
}
}

View File

@ -1,56 +0,0 @@
const radio = {
html: ``,
init: function(opts) {
this.choices = opts.choices;
html = "<div class='radio_group'>"
for ([index, choice] of opts.choices.entries()) {
html += `
<label for="${this.id}_${index}">
<input id="${this.id}_${index}" type="radio" name="${this.id}" value="${index}">
${choice}
</label>
`;
}
html += "</div>"
this.target.html(html);
this.target.find("input").checkboxradio();
this.target.find("label:first-child input").prop("checked", true);
this.target.find("input").button("refresh");
},
submit: function() {
checked_val = this.target.find("input:checked").val();
this.io_master.input(this.id, this.choices[checked_val]);
},
show_interpretation: function(data) {
this.target.find(".interpret_check").remove();
let alternate_index = 0;
for (let i = 0; i < data.length; i++) {
let score = data[i];
if (score == null) {
var html = `<div class='interpret_check interpret_select'>
&#x2713;
</div>`
} else {
var html = `<div class='interpret_check alternate'
alternate_index=${alternate_index}
style='background-color: ${getSaliencyColor(data[i])}'>
&#x2713;
</div>`;
alternate_index++;
}
this.target.find("label").eq(i).append(html);
}
},
interpretation_logic: "Highlights the result of the alternative selection to radio. Hover to see alternative output.",
clear: function() {
this.target.find(".interpretation").empty();
this.target.find("input").prop("checked", false);
this.target.find("label:first-child input").prop("checked", true);
this.target.find("input").button("refresh");
},
load_example: function(data) {
let child = this.choices.indexOf(data) + 1;
this.target.find("label:nth-child("+child+") input").prop("checked", true);
this.target.find("input").button("refresh");
}
}

View File

@ -1,57 +0,0 @@
const sketchpad_input = {
html: `
<div class="interface_box">
<div class="sketch_tools">
<div id="brush_1" size="8" class="brush"></div>
<div id="brush_2" size="16" class="brush selected"></div>
<div id="brush_3" size="24" class="brush"></div>
</div>
<div class="view_holders">
<div class="canvas_holder">
<canvas class="sketch"></canvas>
</div>
</div>
</div>
`,
init: function() {
var io = this;
var dimension = Math.min(this.target.find(".canvas_holder").width(),
this.target.find(".canvas_holder").height()) - 2 // dimension - border
var id = this.id;
this.sketchpad = new Sketchpad({
element: '.interface[interface_id=' + id + '] .sketch',
width: dimension,
height: dimension
});
this.sketchpad.penSize = this.target.find(".brush.selected").attr("size");
this.canvas = this.target.find('.canvas_holder canvas')[0];
this.context = this.canvas.getContext("2d");
this.target.find(".brush").click(function (e) {
io.target.find(".brush").removeClass("selected");
$(this).addClass("selected");
io.sketchpad.penSize = $(this).attr("size");
})
},
submit: function() {
var dataURL = this.canvas.toDataURL("image/png");
this.io_master.input(this.id, dataURL);
},
clear: function() {
this.context.clearRect(0, 0, this.context.canvas.width, this.context.
canvas.height);
},
load_example_preview: function(data) {
return "<img src="+data+" height=100>"
},
load_example: function(data) {
this.clear();
let ctx = this.context;
var img = new Image;
let dimension = this.target.find(".canvas_holder canvas").width();
img.onload = function(){
ctx.clearRect(0,0,dimension,dimension);
ctx.drawImage(img,0,0,dimension,dimension);
};
img.src = data;
}
}

View File

@ -1,50 +0,0 @@
const slider = {
html: `
<div class="slider_container">
<div class="slider">
<div class="ui-slider-handle"></div>
</div>
<div class="interpret_range"></div>
</div>
`,
init: function(opts) {
let io = this;
this.minimum = opts.minimum;
var handle = this.target.find(".ui-slider-handle");
this.slider = this.target.find(".slider").slider({
create: function() {
handle.text( $( this ).slider( "value" ) );
},
slide: function( event, ui ) {
handle.text( ui.value );
},
min: opts.minimum,
max: opts.maximum,
step: opts.step
});
},
submit: function() {
let value = this.slider.slider("value");
this.io_master.input(this.id, parseFloat(value));
},
show_interpretation: function(data) {
let html = ""
for (let [i, value] of data.entries()) {
html += `
<div class='alternate'
alternate_index=${i}
style='background-color: ${getSaliencyColor(value)}'>
</div> `
}
this.target.find(".interpret_range").html(html);
},
interpretation_logic: "Highlights the result of the alternative values along slider. Hover to see alternative output.",
clear: function() {
this.load_example(this.minimum)
this.target.find(".interpret_range").empty();
},
load_example: function(data) {
this.target.find(".slider").slider("option", "value", data)
this.target.find(".ui-slider-handle").text(data);
}
}

View File

@ -1,55 +0,0 @@
const textbox_input = {
html: `
<textarea class="input_text"></textarea>
<div class="output_text"></div>
`,
one_line_html: `<input type="text" class="input_text">`,
init: function(opts) {
if (opts.lines > 1) {
this.target.find(".input_text").attr("rows", opts.lines).css("height", "auto");
} else {
this.target.find("textarea").remove();
this.target.prepend(this.one_line_html);
}
if (opts.placeholder) {
this.target.find(".input_text").attr("placeholder", opts.placeholder)
}
if (opts.default) {
this.target.find(".input_text").val(opts.default)
}
this.target.find(".output_text").hide();
},
submit: function() {
text = this.target.find(".input_text").val();
this.io_master.input(this.id, text);
},
clear: function() {
this.target.find(".input_text").val("");
this.target.find(".output_text").empty();
this.target.find(".input_text").show();
this.target.find(".output_text").hide();
},
show_interpretation: function(data) {
this.target.find(".input_text").hide();
this.target.find(".output_text").show();
let html = "";
for (let [i, char_set] of data.entries()) {
[char, score] = char_set;
let color = getSaliencyColor(score);
html += `<span class='alternate'
alternate_index=${i}
style="background-color: ${color}">${char}</span>`
}
this.target.find(".output_text").html(html);
},
interpretation_logic: "Highlights the output contribution of substrings of input.",
load_example_preview: function(data) {
if (data.length > 20) {
return data.substring(0,20) + "...";
}
return data;
},
load_example: function(data) {
this.target.find(".input_text").val(data);
}
}

View File

@ -1,46 +0,0 @@
const webcam = {
html: `
<div class="interface_box">
<div class="webcam_box"></div>
</div>
`,
init: function(opts) {
var io = this;
let w = this.target.find(".webcam_box").width();
let h = this.target.find(".webcam_box").height();
let RATIO = 4/3;
let dim = Math.min(h, w / RATIO);
Webcam.set({
image_format: 'jpeg',
width: dim * RATIO,
height: dim,
dest_width: dim * RATIO,
dest_height: dim,
})
Webcam.attach(this.target.find(".webcam_box")[0]);
},
submit: function() {
var io = this;
Webcam.snap(function(image_data) {
io.io_master.input(io.id, image_data);
});
Webcam.freeze();
this.target.find("video").hide();
this.state = "SNAPPED";
},
clear: function() {
if (this.state == "SNAPPED") {
this.state = "CAMERA_ON";
Webcam.unfreeze();
this.target.find("video").show();
}
},
state: "NOT_STARTED",
image_data: null,
renderFeatured: function(data) {
return `<img src=${data}>`;
},
loadFeatured: function(data) {
return `<img src=${data}>`;
}
}

View File

@ -1,37 +0,0 @@
const audio_output = {
html: `
<div class="interface_box">
<div class="player hidden">
<div class="waveform"></div>
<button class="playpause primary">Play / Pause</button>
</div>
</div
`,
state: "NO_AUDIO",
init: function(opts) {
var io = this;
this.wavesurfer = WaveSurfer.create({
container: io.target.find('.waveform')[0],
waveColor: '#888888',
progressColor: '#e67e22',
barWidth: 3,
hideScrollbar: true
});
this.target.find(".playpause").click(function () {
io.wavesurfer.playPause();
})
},
output: function(data) {
io.target.find(".player").removeClass("hidden");
this.wavesurfer.load(data);
},
clear: function() {
this.target.find(".player").addClass("hidden");
if (this.wavesurfer) {
this.wavesurfer.stop();
}
},
load_example_preview: function(data) {
return "[audio]";
},
}

View File

@ -1,52 +0,0 @@
const dataframe_output = {
html: `
<div class="interface_max_box">
<div class="dataframe"></div>
</div>
`,
init: function(opts) {
},
output: function(data) {
let config = {data: data.data};
if (data.headers) {
let column_config = [];
for (let header of data.headers) {
column_config.push({title: header});
}
config.columns = column_config;
}
if (this.table) {
this.clear();
}
this.table = this.target.find(".dataframe").jexcel(config);
},
clear: function() {
jexcel.destroy(this.target.find(".dataframe")[0]);
this.table = null;
},
load_example_preview: function(data) {
data = JSON.parse(JSON.stringify(data["data"]))
let data_copy = [];
for (let row of data.splice(0,3)) {
new_row = row.splice(0,3)
if (row.length > 3) {
new_row.push("...");
}
data_copy.push(new_row);
}
if (data.length > 3) {
new_row = Array(data_copy[0].length).fill("...");
data_copy.push(new_row);
}
let html = "<table><tbody>"
for (let row of data_copy) {
html += "<tr>";
for (let cell of row) {
html += "<td>" + cell + "</td>";
}
html += "</tr>";
}
html += "</tbody></table>";
return html;
},
}

View File

@ -1,31 +0,0 @@
const file_output = {
html: `
<a class="interface_mini_box">
<div class="file_display file_download">
<div class="file_name"></div>
<div class="file_size"></div>
</div>
</div>
`,
init: function(opts) {
},
output: function(data) {
this.target.find(".file_name").text(data.name);
this.target.find(".file_size").text(prettyBytes(data.size));
this.target.find(".interface_mini_box")
.attr("href", "data:;base64," + data.data)
.attr("download", data.name);
},
submit: function() {
},
clear: function() {
this.target.find(".file_name").empty();
this.target.find(".file_size").empty();
this.target.find(".interface_mini_box")
.removeAttr("href")
.removeAttr("download");
},
load_example_preview: function(data) {
return data.name;
},
}

View File

@ -1,100 +0,0 @@
const highlighted_text = {
html: `
<div class="highlight_legend">
<div class="color_legend invisible">
<span>-1</span>
<span>0</span>
<span>+1</span>
</div>
<div class="category_legend invisible"></div>
</div>
<div class="output_text"></div>
`,
init: function(opts) {
this.color_map = {};
if (opts.color_map) {
this.generate_category_legend(opts.color_map);
}
},
new_category_index: 0,
generate_category_legend: function(map) {
let default_colors = ["pink", "lightblue", "gold", "plum", "lightskyblue", "greenyellow", "khaki", "cyan", "moccasin", "lightgray"]
for (let category in map) {
if (category in this.color_map) {
continue;
}
let color = map[category];
if (!color) {
if (this.new_category_index < default_colors.length) {
color = default_colors[this.new_category_index];
this.new_category_index++;
} else {
function randInt(min, max) {
return Math.floor(Math.random() * (max- min) + min);
}
color = "rgb(" + randInt(128, 240) + ", " + randInt(128, 240) + ", " + randInt(128, 240) + ")"
}
}
this.color_map[category] = color;
this.target.find(".category_legend").append(`
<div class="category-label">
<div style="background-color:${color}">&nbsp;</div>
${category}
</div>
`)
}
},
output: function(data) {
if (data.length == 0) {
return;
} else if (typeof(data[0][1]) == "string") {
this.target.find(".category_legend").removeClass("invisible");
let new_color_map = {};
for (let span of data) {
let category = span[1];
if (category != null) {
new_color_map[category] = null;
}
}
this.generate_category_legend(new_color_map);
let html = "";
for (let span of data) {
let category = span[1];
let color = category == null ? "white" : this.color_map[category];
html += `<span title="${category}" style="background-color: ${color}">${span[0]}</span>`
}
this.target.find(".output_text").html(html);
} else {
this.target.find(".color_legend").removeClass("invisible");
let html = "";
for (let span of data) {
let value = span[1];
let color = "";
if (value < 0) {
color = "8,241,255," + (-value);
} else {
color = "230,126,34," + value;
}
html += `<span title="${value}" style="background-color: rgba(${color})">${span[0]}</span>`
}
this.target.find(".output_text").html(html);
}
},
submit: function() {
},
clear: function() {
this.target.find(".output_text").empty();
this.target.find(".highlight_legend div").addClass("invisible");
},
load_example_preview: function(data) {
let output_string = "";
for (const [text, type] of data) {
output_string += text;
}
if (output_string.length > 20) {
return output_string.substring(0,20) + "...";
}
return data;
},
}

View File

@ -1,14 +0,0 @@
const html_output = {
html: ``,
init: function(opts) {
},
output: function(data) {
this.target.html(data);
},
clear: function() {
this.target.empty();
},
load_example_preview: function(data) {
return "[html]";
},
}

View File

@ -1,50 +0,0 @@
const image_output = {
html: `
<div class="interface_box">
<div class="view_holders">
<div class="saliency_holder hide">
<canvas class="saliency"></canvas>
</div>
<div class="output_image_holder hide">
<img class="output_image">
</div>
</div>
</div>
`,
init: function(opts) {},
output: function(data) {
let io = this;
let [img_data, coord] = data;
this.target.find(".output_image_holder").removeClass("hide");
img = this.target.find(".output_image").attr('src', img_data);
if (coord.length) {
img = img[0];
img.onload = function() {
var size = getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight);
var width = size.width;
var height = size.height;
io.target.find(".saliency_holder").removeClass("hide").html(`
<canvas class="saliency" width=${width} height=${height}></canvas>`);
var ctx = io.target.find(".saliency")[0].getContext('2d');
ctx.lineWidth = 2;
ctx.strokeStyle = 'red';
ctx.font = '16px monospace';
ctx.textBaseline = 'top';
for (let [label, left_x, top_y, right_x, bottom_y] of coord) {
ctx.rect(left_x, top_y, right_x - left_x, bottom_y - top_y);
ctx.fillText(label, left_x + 2, top_y + 2)
}
ctx.stroke();
}
}
},
clear: function() {
this.target.find(".output_image_holder").addClass("hide");
this.target.find(".saliency_holder").addClass("hide");
this.target.find(".output_image").attr('src', "")
},
load_example_preview: function(data) {
return "<img src='"+data+"' height=100>"
},
}

View File

@ -1,21 +0,0 @@
const json_output = {
html: `
`,
init: function(opts) {
},
output: function(data) {
this.clear();
jsonTree.create(data, this.target[0]);
},
clear: function() {
this.target.empty();
},
load_example_preview: function(data) {
json_string = JSON.stringify(data);
if (json_string.length > 20) {
return json_string.substring(0, 20) + "...";
} else {
return json_string;
}
},
}

View File

@ -1,35 +0,0 @@
const key_values = {
html: `
<table class="key_values">
<thead>
<th>Property</th>
<th>Value</th>
</thead>
<tbody></tbody>
</table>
`,
init: function(opts) {},
output: function(data) {
let html = ""
for (const [key, value] of data) {
html += `<tr>
<td>${key}</td>
<td>${value}</td>
</tr>`;
}
this.target.find("tbody").html(html);
},
clear: function() {
this.target.find("tbody").empty();
},
load_example_preview: function(data) {
let html_preview = "";
for (const [key, value] of data.slice(0,3)) {
html_preview += key + ": " + value + "<br>"
}
if (data.length > 3) {
html_preview += "..."
}
return html_preview;
},
}

View File

@ -1,39 +0,0 @@
const label_output = {
html: `
<div class="output_class"></div>
<div class="confidence_intervals">
<div class="labels"></div>
<div class="confidences"></div>
</div>
`,
init: function(opts) {},
output: function(data) {
this.target.find(".output_class").html(data["label"])
this.target.find(".confidence_intervals > div").empty()
if ("confidences" in data) {
for (var i = 0; i < data.confidences.length; i++)
{
let c = data.confidences[i]
let label = c["label"]
let confidence = Math.round(c["confidence"] * 100) + "%";
this.target.find(".labels").append(`<div class="label" title="${label}">${label}</div>`);
this.target.find(".confidences").append(`
<div class="confidence" style="min-width: calc(${confidence} - 12px);" title="${confidence}">${confidence}</div>`);
}
}
},
load_example_preview: function(data) {
if ("confidences" in data) {
for (let confidence_set of data["confidences"]) {
if (confidence_set["label"] == data["label"]) {
return data["label"] + " (" + (100*confidence_set["confidence"]).toFixed(1) + "%)";
}
}
}
return data["label"];
},
clear: function() {
this.target.find(".output_class").empty();
this.target.find(".confidence_intervals > div").empty();
}
}

View File

@ -1,19 +0,0 @@
const textbox_output = {
html: `<div class="output_text"></div>`,
init: function(opts) {
},
output: function(data) {
this.target.find(".output_text").text(data);
},
submit: function() {
},
clear: function() {
this.target.find(".output_text").empty();
},
load_example_preview: function(data) {
if (data.length > 20) {
return data.substring(0,20) + "...";
}
return data;
},
}

View File

@ -1,208 +0,0 @@
String.prototype.format = function() {
a = this;
for (k in arguments) {
a = a.replace("{" + k + "}", arguments[k])
}
return a
}
function sortWithIndices(toSort) {
for (var i = 0; i < toSort.length; i++) {
toSort[i] = [toSort[i], i];
}
toSort.sort(function(left, right) {
return left[0] < right[0] ? -1 : 1;
});
toSort.sortIndices = [];
for (var j = 0; j < toSort.length; j++) {
toSort.sortIndices.push(toSort[j][1]);
toSort[j] = toSort[j][0];
}
return toSort.sortIndices;
}
function toDataURL(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
function resizeImage(base64Str, max_width, max_height, callback) {
var img = new Image();
img.src = base64Str;
var canvas = document.createElement('canvas');
img.onload = () => {
var width = img.width;
var height = img.height;
if (width > height) {
if (width > max_width) {
height *= max_width / width;
width = max_width;
}
} else {
if (height > max_height) {
width *= max_height / height;
height = max_height;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
callback.call(null, canvas.toDataURL());
}
}
function toStringIfObject(input) {
if (input instanceof Object) {
return JSON.stringify(input);
}
return input;
}
function paintSaliency(data, ctx, width, height) {
var cell_width = width / data[0].length
var cell_height = height / data.length
var r = 0
data.forEach(function(row) {
var c = 0
row.forEach(function(cell) {
ctx.fillStyle = getSaliencyColor(cell);
ctx.fillRect(c * cell_width, r * cell_height, cell_width, cell_height);
c++;
})
r++;
})
}
function getBackgroundColors(io_master){
//Gets the background colors for the embedding plot
// If labels aren't loaded, or it's not a label output interface:
if (!io_master.loaded_examples || io_master["config"]["output_interfaces"][0][0]!="label") {
return 'rgb(54, 162, 235)'
}
// If it is a label interface, get the labels
let labels = []
let isConfidencesPresent = false;
for (let i=0; i<Object.keys(io_master.loaded_examples).length; i++) {
let label = io_master.loaded_examples[i][0]["label"];
if ("confidences" in io_master.loaded_examples[i][0]){
isConfidencesPresent = true;
}
labels.push(label);
}
// If they are all numbers, and there are no confidences, then it's a regression
const isNumeric = (currentValue) => !isNaN(currentValue);
let isNumericArray = labels.every(isNumeric);
if (isNumericArray && !isConfidencesPresent) {
let backgroundColors = [];
labels = labels.map(Number);
let max = Math.max(...labels);
let min = Math.min(...labels);
let rgb_max = [255, 178, 102]
let rgb_min = [204, 255, 255]
for (let i=0; i<labels.length; i++) {
let frac = (Number(labels[i])-min)/(max-min)
let color = [rgb_min[0]+frac*(rgb_max[0]-rgb_min[0]),
rgb_min[1]+frac*(rgb_max[1]-rgb_min[1]),
rgb_min[2]+frac*(rgb_max[2]-rgb_min[2])]
backgroundColors.push(color);
}
}
// Otherwise, it's a classification
let colorArray = ['#FF6633', '#FFB399', '#FF33FF', '#00B3E6',
'#E6B333', '#3366E6', '#999966', '#99FF99', '#B34D4D',
'#80B300', '#809900', '#E6B3B3', '#6680B3', '#66991A',
'#FF99E6', '#CCFF1A', '#FF1A66', '#E6331A', '#33FFCC',
'#66994D', '#B366CC', '#4D8000', '#B33300', '#CC80CC',
'#66664D', '#991AFF', '#E666FF', '#4DB3FF', '#1AB399',
'#E666B3', '#33991A', '#CC9999', '#B3B31A', '#00E680',
'#4D8066', '#809980', '#E6FF80', '#1AFF33', '#999933',
'#FF3380', '#CCCC00', '#66E64D', '#4D80CC', '#9900B3',
'#E64D66', '#4DB380', '#FF4D4D', '#99E6E6', '#6666FF'];
let backgroundColors = [];
let label_list = [];
for (let i=0; i<labels.length; i++) {
if (!(label_list.includes(labels[i]))){
label_list.push(labels[i]);
}
backgroundColors.push(colorArray[label_list.indexOf(labels[i]) % colorArray.length]);
}
return backgroundColors
}
function getSaliencyColor(value) {
if (value < 0) {
var color = [52, 152, 219];
} else {
var color = [231, 76, 60];
}
return colorToString(interpolate(Math.abs(value), [255,255,255], color));
}
function getObjectFitSize(contains /* true = contain, false = cover */, containerWidth, containerHeight, width, height){
var doRatio = width / height;
var cRatio = containerWidth / containerHeight;
var targetWidth = 0;
var targetHeight = 0;
var test = contains ? (doRatio > cRatio) : (doRatio < cRatio);
if (test) {
targetWidth = containerWidth;
targetHeight = targetWidth / doRatio;
} else {
targetHeight = containerHeight;
targetWidth = targetHeight * doRatio;
}
return {
width: targetWidth,
height: targetHeight,
x: (containerWidth - targetWidth) / 2,
y: (containerHeight - targetHeight) / 2
};
}
// val should be in the range [0.0, 1.0]
// rgb1 and rgb2 should be an array of 3 values each in the range [0, 255]
function interpolate(val, rgb1, rgb2) {
if (val > 1) {
val = 1;
}
val = Math.sqrt(val);
var rgb = [0,0,0];
var i;
for (i = 0; i < 3; i++) {
rgb[i] = Math.round(rgb1[i] * (1.0 - val) + rgb2[i] * val);
}
return rgb;
}
function colorToString(rgb) {
return "rgb(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ")";
}
function prettyBytes(bytes) {
let units = ["B", "KB", "MB", "GB", "PB"];
let i = 0;
while (bytes > 1024) {
bytes /= 1024;
i++;
}
let unit = units[i];
return bytes.toFixed(1) + " " + unit;
}

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}

View File

@ -1,82 +0,0 @@
var blackTheme = {
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': 'none',
'common.backgroundColor': '#1e1e1e',
'common.border': '0px',
// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',
// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': '\'Noto Sans\', sans-serif',
'loadButton.fontSize': '12px',
// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': '\'Noto Sans\', sans-serif',
'downloadButton.fontSize': '12px',
// main icons
'menu.normalIcon.path': '../dist/svg/icon-d.svg',
'menu.normalIcon.name': 'icon-d',
'menu.activeIcon.path': '../dist/svg/icon-b.svg',
'menu.activeIcon.name': 'icon-b',
'menu.disabledIcon.path': '../dist/svg/icon-a.svg',
'menu.disabledIcon.name': 'icon-a',
'menu.hoverIcon.path': '../dist/svg/icon-c.svg',
'menu.hoverIcon.name': 'icon-c',
'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
// submenu primary color
'submenu.backgroundColor': '#1e1e1e',
'submenu.partition.color': '#3c3c3c',
// submenu icons
'submenu.normalIcon.path': '../dist/svg/icon-d.svg',
'submenu.normalIcon.name': 'icon-d',
'submenu.activeIcon.path': '../dist/svg/icon-c.svg',
'submenu.activeIcon.name': 'icon-c',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',
// submenu labels
'submenu.normalLabel.color': '#8a8a8a',
'submenu.normalLabel.fontWeight': 'lighter',
'submenu.activeLabel.color': '#fff',
'submenu.activeLabel.fontWeight': 'lighter',
// checkbox style
'checkbox.border': '0px',
'checkbox.backgroundColor': '#fff',
// range style
'range.pointer.color': '#fff',
'range.bar.color': '#666',
'range.subbar.color': '#d1d1d1',
'range.disabledPointer.color': '#414141',
'range.disabledBar.color': '#282828',
'range.disabledSubbar.color': '#414141',
'range.value.color': '#fff',
'range.value.fontWeight': 'lighter',
'range.value.fontSize': '11px',
'range.value.border': '1px solid #353535',
'range.value.backgroundColor': '#151515',
'range.title.color': '#fff',
'range.title.fontWeight': 'lighter',
// colorpicker style
'colorpicker.button.border': '1px solid #1e1e1e',
'colorpicker.title.color': '#fff'
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
CC=emcc
CFLAGS=-O2 \
-s ALLOW_MEMORY_GROWTH=1 \
-s RESERVED_FUNCTION_POINTERS=20 \
-s ALLOW_TABLE_GROWTH=1 \
-Ivendor/libimagequant \
-Ivendor/gifsicle/src \
-Ivendor/gifsicle/include
LIBS=vendor/libimagequant/*.o \
vendor/gifsicle/src/giffunc.o \
vendor/gifsicle/src/fmalloc.o \
vendor/gifsicle/src/support.o \
vendor/gifsicle/src/gifwrite.o \
vendor/gifsicle/src/gifread.o
encoder.js: encoder.c vendor/libimagequant/libimagequant.o vendor/gifsicle/gifsicle.o
$(CC) $(CFLAGS) -o $@ encoder.c $(LIBS)
vendor/libimagequant/libimagequant.o:
cd vendor/libimagequant && make static
vendor/gifsicle/gifsicle.o:
cd vendor/gifsicle && make
.PHONY: clean
clean:
cd vendor/libimagequant && make clean
cd vendor/gifsicle && make clean
rm -f encoder.js encoder.wasm

View File

@ -1,3 +0,0 @@
#!/bin/sh
(cd vendor/libimagequant && ./configure --disable-sse CC=emcc)
(cd vendor/gifsicle && autoreconf -i && ./configure --disable-gifview --disable-gifdiff --disable-simd --disable-threads CC=emcc && rm -f a.out a.out.js a.out.wasm)

View File

@ -1,103 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <libimagequant.h>
#include <lcdfgif/gif.h>
#include <gifsicle.h>
#include <emscripten.h>
// #include <time.h>
// clock_t c;
// #define TIMESTAMP(name) \
// printf(" %s %f\n", name, ((double)(clock() - c) / CLOCKS_PER_SEC * 1000)); \
// c = clock();
Gt_OutputData active_output_data;
int mode = 0;
int nested_mode = 0;
Clp_Parser *clp = 0;
Gif_CompressInfo gif_write_info = {.flags = 0, .loss = 20};
typedef Gif_Stream Encoder;
inline Gif_Colormap *create_colormap_from_palette(const liq_palette *palette)
{
Gif_Colormap *colormap = Gif_NewFullColormap(palette->count, palette->count);
for (int i = 0; i < palette->count; i++)
{
liq_color color = palette->entries[i];
colormap->col[i].pixel = 256;
colormap->col[i].gfc_red = color.r;
colormap->col[i].gfc_green = color.g;
colormap->col[i].gfc_blue = color.b;
colormap->col[i].haspixel = 1;
}
return colormap;
}
EMSCRIPTEN_KEEPALIVE
void quantize_image(int width, int height, void *rgba, void (*cb)(void *, int, void *))
{
liq_attr *attr = liq_attr_create();
liq_image *raw_image = liq_image_create_rgba(attr, rgba, width, height, 0);
liq_result *res = liq_quantize_image(attr, raw_image);
liq_attr_destroy(attr);
const liq_palette *palette = liq_get_palette(res);
size_t size = width * height;
unsigned char *img = malloc(size);
liq_write_remapped_image(res, raw_image, img, size);
cb((void *)palette, sizeof(liq_palette), img);
liq_result_destroy(res);
liq_image_destroy(raw_image);
}
EMSCRIPTEN_KEEPALIVE
Encoder *encoder_new(int width, int height)
{
Gif_Stream *stream = Gif_NewStream();
stream->screen_width = width;
stream->screen_height = height;
stream->loopcount = 0;
return stream;
}
EMSCRIPTEN_KEEPALIVE
void encoder_add_frame(Encoder *encoder, int top, int left, int width, int height, void *data, int delay)
{
liq_palette *palette = data;
unsigned char *img = data + sizeof(liq_palette);
Gif_Image *image = Gif_NewImage();
image->top = top;
image->left = left;
image->width = width;
image->height = height;
image->delay = delay;
image->disposal = GIF_DISPOSAL_NONE;
image->local = create_colormap_from_palette(palette);
Gif_SetUncompressedImage(image, img, 0, 0);
Gif_FullCompressImage(encoder, image, &gif_write_info);
Gif_DeleteArray(image->img);
image->img = 0;
image->image_data = 0;
Gif_AddImage(encoder, image);
}
EMSCRIPTEN_KEEPALIVE
void encoder_finish(Encoder *encoder, void (*cb)(void *, int))
{
Gif_Writer *writer = Gif_NewMemoryWriter(&gif_write_info);
Gif_WriteGif(writer, encoder);
cb(writer->v, writer->pos);
Gif_DeleteMemoryWriter(writer);
Gif_DeleteStream(encoder);
}

File diff suppressed because one or more lines are too long

View File

@ -1,216 +0,0 @@
src = document.currentScript.src;
parent_dir = src.substring(0, src.lastIndexOf("/"));
function computeDiff(a, b, width) {
const ua = new Uint32Array(a);
const ub = new Uint32Array(b);
let top = undefined;
let bottom = undefined;
let left = width + 1;
let right = -1;
for (let i = 0; i < ua.length; i++) {
if ((ua[i] !== ub[i])) {
const y = Math.floor(i / width);
const x = i % width;
if (top === undefined) top = y;
bottom = y;
left = Math.min(left, x);
right = Math.max(right, x);
}
}
if (top !== undefined) {
return { top, left, width: right - left + 1, height: bottom - top + 1 };
}
return undefined;
}
function cropBuffer(_from, box, width) {
const result = new ArrayBuffer(4 * box.width * box.height);
const arr = new Uint32Array(result);
const from = new Uint32Array(_from);
for (let y = 0; y < box.height; y++) {
for (let x = 0; x < box.width; x++) {
arr[x + y * box.width] = from[box.left + x + (box.top + y) * width];
}
}
return result;
}
class GifEncoder {
constructor(opts) {
this.opts = opts;
this.listeners = new Map();
this.previousBuffer = undefined;
this.frames = [];
this.quantizers = [];
this.framesSentToQuantize = 0;
this.framesQuantized = 0;
this.framesSentToEncode = 0;
this.totalFrames = undefined;
this.busyQuantizers = 0;
this.writer = new Worker(parent_dir + '/writer.js');
this.writer.postMessage(opts);
const onMessage = msg => this._onWriterMessage(msg);
this.writer.addEventListener('message', onMessage);
this.disposeWriter = () => this.writer.removeEventListener('message', onMessage);
const numberOfWorkers = navigator.hardwareConcurrency ? Math.floor(navigator.hardwareConcurrency * 0.8) : 4;
for (let i = 0; i < numberOfWorkers; i++) {
const worker = new Worker(parent_dir + '/quantizer.js');
const onMessage = msg => this._onQuantizerMessage(i, msg);
worker.addEventListener('message', onMessage);
const dispose = () => worker.removeEventListener('message', onMessage);
this.quantizers.push({ worker, busy: false, frameIndex: undefined, dispose });
}
}
addFrame(imageData, delay) {
if (!this.quantizers || this.totalFrames !== undefined) {
return;
}
const buffer = imageData.data.buffer;
if (!this.previousBuffer) {
this.frames.push({ buffer, top: 0, left: 0, width: this.opts.width, height: this.opts.height, paletteLength: undefined, delay, quantized: false });
} else {
const box = computeDiff(buffer, this.previousBuffer, this.opts.width);
if (!box) {
this.frames[this.frames.length - 1].delay += delay; // no changes, let's drop the frame
} else {
const crop = cropBuffer(buffer, box, this.opts.width);
this.frames.push({ buffer: crop, ...box, paletteLength: undefined, delay, quantized: false });
}
}
this.previousBuffer = buffer;
this._work();
}
_work() {
if (!this.quantizers) {
return;
}
while (this.framesSentToQuantize < (this.totalFrames === undefined ? this.frames.length - 1 : this.totalFrames) && this.busyQuantizers < this.quantizers.length) {
const frameIndex = this.framesSentToQuantize++;
const frame = this.frames[frameIndex];
const worker = this.quantizers[this.quantizers.findIndex(x => !x.busy)];
worker.busy = true;
worker.frameIndex = frameIndex;
worker.worker.postMessage(frame, { transfer: [frame.buffer] });
this.busyQuantizers++;
}
}
_onQuantizerMessage(workerIndex, msg) {
if (!this.quantizers) {
return;
}
const worker = this.quantizers[workerIndex];
worker.busy = false;
this.busyQuantizers--;
this.framesQuantized++;
const frame = this.frames[worker.frameIndex];
frame.buffer = msg.data.buffer;
frame.paletteLength = msg.data.paletteLength;
frame.quantized = true;
while ((this.totalFrames === undefined || this.framesSentToEncode < this.totalFrames) && this.frames[this.framesSentToEncode].quantized) {
const frameIndex = this.framesSentToEncode++;
const frame = this.frames[frameIndex];
this.writer.postMessage(frame, { transfer: [frame.buffer] });
this.frames[frameIndex] = undefined; // gc
}
if (this.framesSentToEncode === this.totalFrames) {
this.writer.postMessage('finish', { transfer: [] });
}
if (this.totalFrames !== undefined) {
this._emit('progress', this.framesQuantized / this.totalFrames);
}
this._work();
}
_onWriterMessage(msg) {
const blob = new Blob([msg.data], { type: 'image/gif' });
this._emit('finished', blob);
this.dispose();
}
render() {
if (!this.quantizers) {
return;
}
this.totalFrames = this.frames.length;
this._work();
}
abort() {
this.dispose();
}
dispose() {
if (!this.quantizers) {
return;
}
this.writer.terminate();
this.disposeWriter();
for (const { worker, dispose } of this.quantizers) {
worker.terminate();
dispose();
}
this.quantizers = undefined;
this.frames = undefined;
}
// event listener
on(event, fn) {
let listeners = this.listeners.get(event);
if (!listeners) {
listeners = [];
this.listeners.set(event, listeners);
}
listeners.push(fn);
return () => listeners.splice(listeners.indexOf(fn), 1);
}
once(event, fn) {
const remove = this.on(event, data => {
fn(data);
remove();
});
}
_emit(event, data) {
const listeners = this.listeners.get(event) || [];
for (const listener of listeners) {
listener(data);
}
}
}

View File

@ -1,35 +0,0 @@
importScripts('encoder.js');
let initialized = false;
const frames = [];
function process(frame) {
if (frame) {
frames.push(frame);
}
while (initialized && (frame = frames.pop())) {
const ptr = Module._malloc(frame.buffer.byteLength);
const input = new Uint8Array(Module.HEAPU8.buffer, ptr, frame.buffer.byteLength);
input.set(new Uint8Array(frame.buffer));
const imageLength = frame.width * frame.height;
const cb = addFunctionWasm((palettePtr, paletteLength, imagePtr) => {
const buffer = new ArrayBuffer(paletteLength + imageLength);
const result = new Uint8Array(buffer);
result.set(new Uint8Array(Module.HEAPU8.buffer, palettePtr, paletteLength));
result.set(new Uint8Array(Module.HEAPU8.buffer, imagePtr, imageLength), paletteLength);
self.postMessage({ paletteLength, buffer }, { transfer: [buffer] });
}, 'viii');
Module['_quantize_image'](frame.width, frame.height, ptr, cb);
Module._free(ptr);
}
}
self.onmessage = msg => process(msg.data);
Module['onRuntimeInitialized'] = () => {
initialized = true;
process();
};

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