1) Port query tool to React. Fixes #6131

2) Added status bar to the Query Tool. Fixes #3253
3) Ensure that row numbers should be visible in view when scrolling horizontally. Fixes #3989
4) Allow removing a single query history. Refs #4113
5) Partially fixed Macros usability issues. Ref #6969
6) Fixed an issue where the Query tool opens on minimum size if the user opens multiple query tool Window quickly. Fixes #6725
7) Relocate GIS Viewer Button to the Left Side of the Results Table. Fixes #6830
8) Fixed an issue where the connection bar is not visible. Fixes #7188
9) Fixed an issue where an Empty message popup after running a query. Fixes #7260
10) Ensure that Autocomplete should work after changing the connection. Fixes #7262
11) Fixed an issue where the copy and paste row does not work if the first column contains no data. Fixes #7294
pull/83/head
Aditya Toshniwal 2022-04-07 17:36:56 +05:30 committed by Akshay Joshi
parent bf8e569bde
commit b5b9ee46a1
213 changed files with 11134 additions and 18830 deletions

View File

@ -9,12 +9,22 @@ This release contains a number of bug fixes and new features since the release o
New features
************
| `Issue #3253 <https://redmine.postgresql.org/issues/3253>`_ - Added status bar to the Query Tool.
| `Issue #3989 <https://redmine.postgresql.org/issues/3989>`_ - Ensure that row numbers should be visible in view when scrolling horizontally.
| `Issue #6830 <https://redmine.postgresql.org/issues/6830>`_ - Relocate GIS Viewer Button to the Left Side of the Results Table.
Housekeeping
************
| `Issue #6131 <https://redmine.postgresql.org/issues/6131>`_ - Port query tool to React.
Bug fixes
*********
| `Issue #6725 <https://redmine.postgresql.org/issues/6725>`_ - Fixed an issue where the Query tool opens on minimum size if the user opens multiple query tool Window quickly.
| `Issue #7187 <https://redmine.postgresql.org/issues/7187>`_ - Fixed an issue where the downloaded ERD diagram was 0 bytes.
| `Issue #7188 <https://redmine.postgresql.org/issues/7188>`_ - Fixed an issue where the connection bar is not visible.
| `Issue #7260 <https://redmine.postgresql.org/issues/7260>`_ - Fixed an issue where an Empty message popup after running a query.
| `Issue #7262 <https://redmine.postgresql.org/issues/7262>`_ - Ensure that Autocomplete should work after changing the connection.
| `Issue #7294 <https://redmine.postgresql.org/issues/7294>`_ - Fixed an issue where the copy and paste row does not work if the first column contains no data.

View File

@ -116,7 +116,6 @@
"closest": "^0.0.1",
"codemirror": "^5.59.2",
"context-menu": "^2.0.0",
"copy-to-clipboard": "^3.3.1",
"css-loader": "^5.0.1",
"cssnano": "^5.0.2",
"dagre": "^0.8.4",
@ -153,8 +152,10 @@
"react": "^17.0.1",
"react-aspen": "^1.1.0",
"react-checkbox-tree": "^1.7.2",
"react-data-grid": "^7.0.0-beta.11",
"react-dom": "^17.0.1",
"react-draggable": "^4.4.4",
"react-leaflet": "^3.2.2",
"react-rnd": "^10.3.5",
"react-router-dom": "^6.2.2",
"react-select": "^4.2.1",

View File

@ -54,7 +54,8 @@ from pgadmin.utils.master_password import validate_master_password, \
set_crypt_key, process_masterpass_disabled
from pgadmin.model import User
from pgadmin.utils.constants import MIMETYPE_APP_JS, PGADMIN_NODE,\
INTERNAL, KERBEROS, LDAP, QT_DEFAULT_PLACEHOLDER, OAUTH2, WEBSERVER
INTERNAL, KERBEROS, LDAP, QT_DEFAULT_PLACEHOLDER, OAUTH2, WEBSERVER,\
VW_EDT_DEFAULT_PLACEHOLDER
from pgadmin.authenticate import AuthSourceManager
try:
@ -854,6 +855,7 @@ def utils():
logout_url=get_logout_url(),
platform=sys.platform,
qt_default_placeholder=QT_DEFAULT_PLACEHOLDER,
vw_edt_default_placeholder=VW_EDT_DEFAULT_PLACEHOLDER,
enable_psql=config.ENABLE_PSQL
),
200, {'Content-Type': MIMETYPE_APP_JS})

View File

@ -10,7 +10,7 @@ import sys
from flask_babel import gettext
from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\
PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \
PREF_LABEL_OPTIONS, QT_DEFAULT_PLACEHOLDER
PREF_LABEL_OPTIONS, QT_DEFAULT_PLACEHOLDER, VW_EDT_DEFAULT_PLACEHOLDER
from flask_security import current_user
import config
@ -483,7 +483,7 @@ def register_browser_preferences(self):
self.ve_edt_tab_title = self.preference.register(
'tab_settings', 'vw_edt_tab_title_placeholder',
gettext("View/Edit data tab title"),
'text', '%SCHEMA%.%TABLE%/%DATABASE%/%USERNAME%@%SERVER%',
'text', VW_EDT_DEFAULT_PLACEHOLDER,
category_label=PREF_LABEL_DISPLAY,
help_str=gettext(
'Supported placeholders are %SCHEMA%, %TABLE%, %DATABASE%, '

View File

@ -1284,7 +1284,7 @@ class ServerNode(PGChildNodeView):
}
)
def connect(self, gid, sid, user_name=None):
def connect(self, gid, sid, user_name=None, resp_json=False):
"""
Connect the Server and return the connection object.
Verification Process before Connection:
@ -1331,12 +1331,15 @@ class ServerNode(PGChildNodeView):
else:
return unauthorized(gettext(UNAUTH_REQ))
data = {}
data = None
if request.form:
data = request.form
elif request.data:
data = json.loads(request.data, encoding='utf-8')
if data is None:
data = {}
password = None
passfile = None
tunnel_password = None
@ -1406,9 +1409,10 @@ class ServerNode(PGChildNodeView):
# password or both. Return the password template in case password is
# not provided, or password has not been saved earlier.
if prompt_password or prompt_tunnel_password:
return self.get_response_for_password(server, 428, prompt_password,
prompt_tunnel_password,
user=user_name)
return self.get_response_for_password(
server, 428, prompt_password, prompt_tunnel_password,
user=user_name, resp_json=resp_json
)
status = True
try:
@ -1423,7 +1427,8 @@ class ServerNode(PGChildNodeView):
except Exception as e:
current_app.logger.exception(e)
return self.get_response_for_password(
server, 401, True, True, getattr(e, 'message', str(e)))
server, 401, True, True, getattr(e, 'message', str(e)),
resp_json=resp_json)
if not status:
@ -1434,8 +1439,9 @@ class ServerNode(PGChildNodeView):
if errmsg.find('Ticket expired') != -1:
return internal_server_error(errmsg)
return self.get_response_for_password(server, 401, True,
True, errmsg)
return self.get_response_for_password(
server, 401, True, True, errmsg, resp_json=resp_json
)
else:
if save_password and config.ALLOW_SAVE_PASSWORD:
try:
@ -1859,47 +1865,54 @@ class ServerNode(PGChildNodeView):
def get_response_for_password(self, server, status, prompt_password=False,
prompt_tunnel_password=False, errmsg=None,
user=None):
user=None, resp_json=False):
if server.use_ssh_tunnel:
data = {
"server_label": server.name,
"username": server.username,
"tunnel_username": server.tunnel_username,
"tunnel_host": server.tunnel_host,
"tunnel_identity_file": server.tunnel_identity_file,
"errmsg": errmsg,
"service": server.service,
"prompt_tunnel_password": prompt_tunnel_password,
"prompt_password": prompt_password,
"allow_save_password":
True if config.ALLOW_SAVE_PASSWORD and
session['allow_save_password'] else False,
"allow_save_tunnel_password":
True if config.ALLOW_SAVE_TUNNEL_PASSWORD and
session['allow_save_password'] else False
}
return make_json_response(
success=0,
status=status,
result=render_template(
'servers/tunnel_password.html',
server_label=server.name,
username=server.username,
tunnel_username=server.tunnel_username,
tunnel_host=server.tunnel_host,
tunnel_identity_file=server.tunnel_identity_file,
errmsg=errmsg,
_=gettext,
service=server.service,
prompt_tunnel_password=prompt_tunnel_password,
prompt_password=prompt_password,
allow_save_password=True if
config.ALLOW_SAVE_PASSWORD and
session['allow_save_password'] else False,
allow_save_tunnel_password=True if
config.ALLOW_SAVE_TUNNEL_PASSWORD and
session['allow_save_password'] else False
)
**data,
) if not resp_json else data
)
else:
data = {
"server_label": server.name,
"username": server.username,
"errmsg": errmsg,
"service": server.service,
"prompt_password": True,
"allow_save_password":
True if config.ALLOW_SAVE_PASSWORD and
session['allow_save_password'] else False,
}
return make_json_response(
success=0,
status=status,
result=render_template(
'servers/password.html',
server_label=server.name,
username=user if user else server.username,
errmsg=errmsg,
service=server.service,
_=gettext,
allow_save_password=True if
config.ALLOW_SAVE_PASSWORD and
session['allow_save_password'] else False,
)
**data
) if not resp_json else data
)
def clear_saved_password(self, gid, sid):

View File

@ -0,0 +1,103 @@
import React, { useState } from 'react';
import gettext from 'sources/gettext';
import { Box } from '@material-ui/core';
import { DefaultButton, PrimaryButton } from '../../../static/js/components/Buttons';
import CloseIcon from '@material-ui/icons/CloseRounded';
import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
import PropTypes from 'prop-types';
import { useModalStyles } from '../../../static/js/helpers/ModalProvider';
import { FormFooterMessage, InputCheckbox, InputText, MESSAGE_TYPE } from '../../../static/js/components/FormComponents';
export default function ConnectServerContent({closeModal, data, onOK}) {
const classes = useModalStyles();
const [formData, setFormData] = useState({
tunnel_password: '',
save_tunnel_password: false,
password: '',
save_password: false,
});
const onTextChange = (e, id) => {
let val = e;
if(e && e.target) {
val = e.target.value;
}
setFormData((prev)=>({...prev, [id]: val}));
};
if(!data) {
return <>No data</>;
}
return (
<Box display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2}>
{data.prompt_tunnel_password && <>
<Box>
<span style={{fontWeight: 'bold'}}>
{data.tunnel_identity_file ?
gettext('Please enter the SSH Tunnel password for the identity file \'%s\' to connect the server "%s"', data.tunnel_identity_file, data.tunnel_host)
: gettext('Please enter the SSH Tunnel password for the user \'%s\' to connect the server "%s"', data.tunnel_username, data.tunnel_host)
}
</span>
</Box>
<Box marginTop='12px'>
<InputText type="password" value={formData['tunnel_password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'tunnel_password')} autoFocus />
</Box>
<Box marginTop='12px'>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_tunnel_password']}
onChange={(e)=>onTextChange(e.target.checked, 'save_tunnel_password')} disabled={!data.allow_save_tunnel_password} />
</Box>
</>}
{data.prompt_password && <>
<Box>
<span style={{fontWeight: 'bold'}}>
{data.username ?
gettext('Please enter the password for the user \'%s\' to connect the server - "%s"', data.username, data.server_label)
: gettext('Please enter the password for the user to connect the server - "%s"', data.server_label)
}
</span>
</Box>
<Box marginTop='12px'>
<InputText type="password" value={formData['password']} maxLength={null}
onChange={(e)=>onTextChange(e, 'password')} autoFocus />
</Box>
<Box marginTop='12px'>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_password']}
onChange={(e)=>onTextChange(e.target.checked, 'save_password')} disabled={!data.allow_save_password} />
</Box>
</>}
<FormFooterMessage type={MESSAGE_TYPE.ERROR} message={data.errmsg} closable={false} style={{
position: 'unset', padding: '12px 0px 0px'
}}/>
</Box>
<Box className={classes.footer}>
<DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={()=>{
closeModal();
}} >{gettext('Cancel')}</DefaultButton>
<PrimaryButton data-test="save" className={classes.margin} startIcon={<CheckRoundedIcon />} onClick={()=>{
let postFormData = new FormData();
if(data.prompt_tunnel_password) {
postFormData.append('tunnel_password', formData.tunnel_password);
formData.save_tunnel_password &&
postFormData.append('save_tunnel_password', formData.save_tunnel_password);
}
if(data.prompt_password) {
postFormData.append('password', formData.password);
formData.save_password &&
postFormData.append('save_password', formData.save_password);
}
onOK?.(postFormData);
closeModal();
}} >{gettext('OK')}</PrimaryButton>
</Box>
</Box>
);
}
ConnectServerContent.propTypes = {
closeModal: PropTypes.func,
data: PropTypes.object,
onOK: PropTypes.func
};

View File

@ -119,8 +119,8 @@ define([
);
},
show_query_tool: function() {
if(pgAdmin.DataGrid) {
pgAdmin.DataGrid.show_query_tool('', pgAdmin.Browser.tree.selected());
if(pgAdmin.Tools.SQLEditor) {
pgAdmin.Tools.SQLEditor.showQueryTool('', pgAdmin.Browser.tree.selected());
}
},
show_search_objects: function() {

View File

@ -253,7 +253,7 @@ _.extend(pgBrowser.keyboardNavigation, {
return;
// Call data grid method to render query tool
pgAdmin.DataGrid.show_query_tool('', tree.i);
pgAdmin.Tools.SQLEditor.showQueryTool('', tree.i);
},
bindSubMenuViewData: function() {
const tree = this.getTreeDetails();
@ -262,7 +262,7 @@ _.extend(pgBrowser.keyboardNavigation, {
return;
// Call data grid method to render view data
pgAdmin.DataGrid.show_data_grid({'mnuid': 1}, tree.i);
pgAdmin.Tools.SQLEditor.showViewData({'mnuid': 1}, tree.i);
},
bindSubMenuSearchObjects: function() {
const tree = this.getTreeDetails();

View File

@ -975,7 +975,7 @@ define('pgadmin.browser.node', [
sql_url = 'sql';
}
// Open data grid & pass the URL for fetching
pgAdmin.DataGrid.show_query_tool(
pgAdmin.Tools.SQLEditor.showQueryTool(
obj.generate_url(i, sql_url, d, true),
i, scriptType
);
@ -1001,7 +1001,7 @@ define('pgadmin.browser.node', [
};
pgBrowser.Node.callbacks.show_script(data);
}else{
pgAdmin.DataGrid.show_query_tool('', i);
pgAdmin.Tools.SQLEditor.showQueryTool('', i);
}
},

View File

@ -112,6 +112,10 @@ _.extend(pgBrowser, {
}, 500);
},
triggerPreferencesChange: function(moduleChanged) {
$.event.trigger('prefchange:'+moduleChanged);
},
reflectPreferences: function(module) {
let obj = this;
@ -130,7 +134,13 @@ _.extend(pgBrowser, {
},
onPreferencesChange: function(module, eventHandler) {
$(pgWindow).on('prefchange:'+module, function(event) {
let eventWindow = pgWindow;
if (window.location === window.parent?.location ) {
// The page is in a new tab
eventWindow = window;
}
$(eventWindow).on('prefchange:'+module, function(event) {
eventHandler(event);
});
},

View File

@ -112,11 +112,11 @@ export function initializeToolbar(panel, wcDocker) {
// Listen on button click event.
panel.on(wcDocker.EVENT.BUTTON, function(data) {
if ('name' in data && data.name === gettext('Query Tool'))
pgAdmin.DataGrid.show_query_tool('', pgAdmin.Browser.tree.selected());
pgAdmin.Tools.SQLEditor.showQueryTool('', pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === gettext('View Data'))
pgAdmin.DataGrid.show_data_grid({mnuid: 3}, pgAdmin.Browser.tree.selected());
pgAdmin.Tools.SQLEditor.showViewData({mnuid: 3}, pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === gettext('Filtered Rows'))
pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected());
pgAdmin.Tools.SQLEditor.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === gettext('Search objects'))
pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected());
else if ('name' in data && data.name === gettext('PSQL Tool')){

View File

@ -56,6 +56,7 @@ define('pgadmin.browser.utils',
pgAdmin['enable_psql'] = '{{enable_psql}}' == 'True';
pgAdmin['platform'] = '{{platform}}';
pgAdmin['qt_default_placeholder'] = '{{qt_default_placeholder}}'
pgAdmin['vw_edt_default_placeholder'] = '{{vw_edt_default_placeholder}}'
/* GET Binary Path Browse config */
pgAdmin['enable_binary_path_browsing'] = '{{ current_app.config.get('ENABLE_BINARY_PATH_BROWSING') }}' == 'True';

View File

@ -14,7 +14,7 @@ let svgDownloader = {
},
downloadSVG: function(content, fileName) {
// Safari xlink NS issue fix
// Safari xlink NS issue fixblobURL
content = content.replace(/NS\d+:href/gi, 'xlink:href');
var svgURL = this.blobURL(content, 'image/svg+xml');

View File

@ -26,7 +26,7 @@ import pgAdmin from 'sources/pgadmin';
import { DefaultButton, PgIconButton, PrimaryButton } from '../../../../static/js/components/Buttons';
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
import { getBinaryPathSchema } from '../../../../browser/server_groups/servers/static/js/binary_path.ui';
import { _set_dynamic_tab } from '../../../../tools/datagrid/static/js/show_query_tool';
import { _set_dynamic_tab } from '../../../../tools/sqleditor/static/js/show_query_tool';
class PreferencesSchema extends BaseUISchema {
constructor(initValues = {}, schemaFields = []) {
@ -289,7 +289,7 @@ export default function PreferencesComponent({ ...props }) {
if(_el.name == 'column_data_auto_resize') {
size_control_id = _el.id;
}
});
element.disabled = (state) => {
return state[size_control_id] != 'by_data';
@ -343,7 +343,7 @@ export default function PreferencesComponent({ ...props }) {
}
if (note && note.length > 0) {
//Add Note for Nodes
//Add Note for Nodes
preferencesData.push(
{
id: _.uniqueId('note') + subNode.id,

View File

@ -122,7 +122,7 @@ def store(setting=None, value=None):
store_setting(setting, value)
except Exception as e:
success = 0
errormsg = e.message
errormsg = str(e)
try:
info = traceback.format_exc()
@ -141,12 +141,21 @@ def reset_layout():
"""Reset configuration setting"""
try:
db.session.query(Setting) \
.filter(Setting.user_id == current_user.id)\
.filter((Setting.setting == 'Browser/Layout') |
(Setting.setting == 'SQLEditor/Layout') |
(Setting.setting == 'Debugger/Layout'))\
.delete()
if request.params['setting'] in [
'Browser/Layout', 'SQLEditor/Layout', 'Debugger/Layout']:
db.session.query(Setting) \
.filter(Setting.user_id == current_user.id) \
.filter((Setting.setting == 'Browser/Layout') |
(Setting.setting == 'SQLEditor/Layout') |
(Setting.setting == 'Debugger/Layout')) \
.delete()
else:
db.session.query(Setting) \
.filter(Setting.user_id == current_user.id)\
.filter((Setting.setting == 'Browser/Layout') |
(Setting.setting == 'SQLEditor/Layout') |
(Setting.setting == 'Debugger/Layout'))\
.delete()
db.session.commit()
except Exception as e:

View File

@ -8,7 +8,7 @@
//////////////////////////////////////////////////////////////
define('app', [
'sources/pgadmin', 'bundled_browser', 'pgadmin.datagrid',
'sources/pgadmin', 'bundled_browser',
], function(pgAdmin) {
var initializeModules = function(Object) {
for (var key in Object) {

View File

@ -0,0 +1,215 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import { makeStyles } from '@material-ui/styles';
import React from 'react';
import clsx from 'clsx';
import _ from 'lodash';
import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
import HTMLReactParse from 'html-react-parser';
import { commonTableStyles } from '../Theme';
import PropTypes from 'prop-types';
const useStyles = makeStyles((theme)=>({
collapsible: {
cursor: 'pointer',
},
collapseParent: {
borderBottom: '2px dashed '+theme.palette.primary.main,
},
level2: {
backgroundColor: '#fff',
color: '#000',
},
level3: {
backgroundColor: '#fff',
color: '#000',
},
level4: {
backgroundColor: '#fff',
color: '#000',
},
}));
function getRowClassname(data, collapseParent) {
const classes = useStyles();
let className = [];
if(data['Plans']?.length > 0) {
className.push(classes.collapsible);
}
if(!_.isEmpty(data['exclusive_flag'])) {
className.push(classes['level'+data['exclusive_flag']]);
}
if(!_.isEmpty(data['inclusive_flag'])) {
className.push(classes['level'+data['inclusive_flag']]);
}
if(!_.isEmpty(data['rowsx_flag'])) {
className.push(classes['level'+data['rowsx_flag']]);
}
if(collapseParent) {
className.push(classes.collapseParent);
}
return className;
}
function NodeText({displayText, extraInfo}) {
return (
<>
<ArrowRightAltIcon fontSize="small" /> {displayText}
{extraInfo?.length > 0 && <ul>
{extraInfo.map((item, i)=>{
return <li key={i}>{HTMLReactParse(item)}</li>;
})}
</ul>}
</>);
}
NodeText.propTypes = {
displayText: PropTypes.string,
extraInfo: PropTypes.array,
};
function ExplainRow({row, show, activeExId, setActiveExId, collapsedExId, toggleCollapseExId}) {
let data = row['data'];
const exId = `pga_ex_${data['level'].join('_')}`;
const parentExId = `pga_ex_${data['parent_node']}`;
const collapsed = collapsedExId.findIndex((v)=>parentExId.startsWith(v)) > -1;
const className = getRowClassname(data, collapsedExId.indexOf(exId) > -1);
let onRowClick = (e)=>{
toggleCollapseExId(e.currentTarget.getAttribute('data-ex-id'), data['Plans']?.length);
};
return (
<tr onMouseEnter={(e)=>{setActiveExId(e.currentTarget.getAttribute('data-ex-id'));}}
onMouseLeave={()=>{setActiveExId(null);}}
className={clsx(className)} data-parent={parentExId}
data-ex-id={`pga_ex_${data['level'].join('_')}`}
style={collapsed ? {display: 'none'} : {}}
onClick={onRowClick}>
<td>
<FiberManualRecordIcon fontSize="small" style={{visibility: activeExId==parentExId ? 'visible' : 'hidden'}} />
</td>
<td>{data['_serial']}.</td>
<td style={{paddingLeft: data['level'].length*30+'px'}} title={row['tooltip_text']}>
<NodeText displayText={row['display_text']} extraInfo={row['node_extra_info']} />
</td>
<td style={show.show_timings ? {} : {display: 'none'}}>
{data['exclusive'] && (data['exclusive']+' ms')}
</td>
<td style={show.show_timings ? {} : {display: 'none'}}>
{data['inclusive'] && (data['inclusive']+' ms')}
</td>
<td style={{display: 'none'}}>{!_.isUndefined(data['rowsx_flag'])
&& (data['rowsx_direction'] == 'positive' ? '&uarr;' : '&darr;')
}</td>
<td style={show.show_rowsx ? {} : {display: 'none'}}>
{data['rowsx']}
</td>
<td style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
{data['Actual Rows']}
</td>
<td style={(show.show_rowsx || show.show_plan_rows) ? {} : {display: 'none'}}>
{data['Plan Rows']}
</td>
<td style={(show.show_rowsx || show.show_rows) ? {} : {display: 'none'}}>
{data['Actual Loops']}
</td>
</tr>
);
}
ExplainRow.propTypes = {
row: PropTypes.shape({
data: PropTypes.shape({
Plans: PropTypes.array,
level: PropTypes.number,
_serial: PropTypes.number,
parent_node: PropTypes.number,
exclusive: PropTypes.number,
inclusive: PropTypes.number,
rowsx_direction: PropTypes.string,
rowsx: PropTypes.number,
rowsx_flag: PropTypes.number,
'Actual Rows': PropTypes.number,
'Plan Rows': PropTypes.number,
'Actual Loops': PropTypes.number,
}),
node_extra_info: PropTypes.array,
display_text: PropTypes.string,
tooltip_text: PropTypes.string,
}),
show: PropTypes.shape({
show_timings: PropTypes.bool,
show_rowsx: PropTypes.bool,
show_rows: PropTypes.bool,
show_plan_rows: PropTypes.bool,
}),
activeExId: PropTypes.string,
setActiveExId: PropTypes.string,
collapsedExId: PropTypes.string,
toggleCollapseExId: PropTypes.func,
};
export default function Analysis({explainTable}) {
const tableClasses = commonTableStyles();
const [activeExId, setActiveExId] = React.useState();
const [collapsedExId, setCollapsedExId] = React.useState([]);
const toggleCollapseExId = (exId, hasPlans=true)=>{
if(hasPlans) {
setCollapsedExId((prev)=>{
if(prev.indexOf(exId) > -1) {
return prev.filter((v)=>v!=exId);
}
return [...prev, exId];
});
}
};
return <table className={clsx(tableClasses.table, tableClasses.noBorder, tableClasses.borderBottom)}>
<thead>
<tr>
<th rowSpan="2" style={{width: '30px'}}></th>
<th rowSpan="2"><button disabled="">#</button></th>
<th rowSpan="2"><button disabled="">Node</button></th>
<th colSpan="2" style={explainTable.show_timings ? {} : {display: 'none'}}>
<button disabled="">Timings</button>
</th>
<th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}} colSpan="3">
<button disabled="">Rows</button>
</th>
<th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}} rowSpan="2">
<button disabled="">Loops</button>
</th>
</tr>
<tr>
<th style={explainTable.show_timings ? {} : {display: 'none'}}>
<button disabled="">Exclusive</button>
</th>
<th style={explainTable.show_timings ? {} : {display: 'none'}}>
<button disabled="">Inclusive</button>
</th>
<th style={explainTable.show_rowsx ? {} : {display: 'none'}}><button disabled="">Rows X</button></th>
<th style={(explainTable.show_rowsx || explainTable.show_rows) ? {} : {display: 'none'}}><button disabled="">Actual</button></th>
<th style={(explainTable.show_rowsx || explainTable.plan_rows) ? {} : {display: 'none'}}><button disabled="">Plan</button></th>
</tr>
</thead>
<tbody>
{_.sortBy(explainTable.rows,(r)=>r['data']['_serial']).map((row, i)=>{
return <ExplainRow key={i} row={row} show={{
show_timings: explainTable.show_timings,
show_rowsx: explainTable.show_rowsx,
show_rows: explainTable.show_rows,
show_plan_rows: explainTable.show_plan_rows,
}} activeExId={activeExId} setActiveExId={setActiveExId} collapsedExId={collapsedExId} toggleCollapseExId={toggleCollapseExId} />;
})}
</tbody>
</table>;
}
Analysis.propTypes = {
explainTable: PropTypes.object,
};

View File

@ -0,0 +1,143 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React from 'react';
import { Box, Grid, makeStyles } from '@material-ui/core';
import gettext from 'sources/gettext';
import { commonTableStyles } from '../Theme';
import clsx from 'clsx';
import _ from 'lodash';
import PropTypes from 'prop-types';
const useStyles = makeStyles((theme)=>({
title: {
fontWeight: 'bold',
padding: '4px',
backgroundColor: theme.otherVars.cardHeaderBg,
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
},
tableRow: {
backgroundColor: theme.palette.grey[200]
},
tableName:{
fontWeight: 'bold',
},
nodeName: {
paddingLeft: '30px',
},
}));
export default function ExplainStatistics({explainTable}) {
// _renderStatisticsTable
const classes = useStyles();
const tableClasses = commonTableStyles();
return (
<Box p={1}>
<Grid container spacing={1}>
<Grid item lg={6} md={12}>
<div className={classes.title}>{gettext('Statistics per Node Type')}</div>
<table className={clsx(tableClasses.table)}>
<thead>
<tr>
<th>{gettext('Node type')}</th>
<th>{gettext('Count')}</th>
{explainTable.show_timings && <>
<th>{gettext('Time spent')}</th>
<th>{'% '+gettext('of query')}</th>
</>}
</tr>
</thead>
<tbody>
{_.sortBy(Object.keys(explainTable.statistics.nodes)).map((key, i)=>{
let node = explainTable.statistics.nodes[key];
return <tr key={i}>
<td>{node.name}</td>
<td>{node.count}</td>
{explainTable.show_timings && <>
<td>{Math.ceil10(node.sum_of_times, -3) + ' ms'}</td>
<td>{Math.ceil10(((node.sum_of_times||0)/(explainTable.total_time||1)) * 100, -2)+ '%'}</td>
</>}
</tr>;
})}
</tbody>
</table>
</Grid>
<Grid item lg={6} md={12}>
<div className={classes.title}>{gettext('Statistics per Relation')}</div>
<table className={clsx(tableClasses.table)}>
<thead>
<tr>
<th>{gettext('Relation name')}</th>
<th>{gettext('Scan count')}</th>
{explainTable.show_timings && <>
<th>{gettext('Total time')}</th>
<th>{'% '+gettext('of query')}</th>
</>}
</tr>
<tr>
<th>{gettext('Node type')}</th>
<th>{gettext('Count')}</th>
{explainTable.show_timings && <>
<th>{gettext('Sum of times')}</th>
<th>{'% '+gettext('of relation')}</th>
</>}
</tr>
</thead>
<tbody>
{_.sortBy(Object.keys(explainTable.statistics.tables)).map((key, i)=>{
let table = explainTable.statistics.tables[key];
table.sum_of_times = _.sumBy(table.nodes, 'sum_of_times');
return <React.Fragment key={i}>
<tr className={classes.tableRow}>
<td className={classes.tableName}>{table.name}</td>
<td>{table.count}</td>
{explainTable.show_timings && <>
<td>{Math.ceil10(table.sum_of_times, -3) + ' ms'}</td>
<td>{Math.ceil10(((table.sum_of_times||0)/(explainTable.total_time||1)) * 100, -2)+ '%'}</td>
</>}
</tr>
{_.sortBy(Object.keys(table.nodes)).map((nodeKey, j)=>{
let node = table.nodes[nodeKey];
return <tr key={j}>
<td><div className={classes.nodeName}>{node.name}</div></td>
<td>{node.count}</td>
{explainTable.show_timings && <>
<td>{Math.ceil10(node.sum_of_times, -3) + ' ms'}</td>
<td>{Math.ceil10(((node.sum_of_times||0)/(table.sum_of_times||1)) * 100, -2)+ '%'}</td>
</>}
</tr>;
})}
</React.Fragment>;
})}
</tbody>
</table>
</Grid>
</Grid>
</Box>
);
}
const NodeType = {
name: PropTypes.string,
count: PropTypes.number,
sum_of_times: PropTypes.number,
};
ExplainStatistics.propTypes = {
explainTable: PropTypes.shape({
show_timings: PropTypes.bool,
statistics: PropTypes.shape({
nodes: PropTypes.arrayOf(NodeType),
tables: PropTypes.arrayOf({
...NodeType,
nodes: PropTypes.arrayOf(NodeType),
}),
}),
total_time: PropTypes.number,
}),
};

View File

@ -0,0 +1,435 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import { Box, Card, CardContent, CardHeader, makeStyles, useTheme } from '@material-ui/core';
import React, {useEffect} from 'react';
import _ from 'lodash';
import { PgButtonGroup, PgIconButton } from '../components/Buttons';
import ZoomInIcon from '@material-ui/icons/ZoomIn';
import ZoomOutIcon from '@material-ui/icons/ZoomOut';
import ZoomOutMapIcon from '@material-ui/icons/ZoomOutMap';
import SaveAltIcon from '@material-ui/icons/SaveAlt';
import gettext from 'sources/gettext';
import ReactDOMServer from 'react-dom/server';
import url_for from 'sources/url_for';
import { downloadSvg } from './svg_download';
import CloseIcon from '@material-ui/icons/CloseRounded';
import { commonTableStyles } from '../Theme';
import clsx from 'clsx';
import PropTypes from 'prop-types';
// Some predefined constants used to calculate image location and its border
var pWIDTH = 100.;
var pHEIGHT = 100.;
var IMAGE_WIDTH = 50;
var IMAGE_HEIGHT = 50;
var ARROW_WIDTH = 10,
ARROW_HEIGHT = 10;
var TXT_ALIGN = 5,
TXT_SIZE = '15px';
var xMargin = 25,
yMargin = 25;
var MIN_ZOOM_FACTOR = 0.3,
MAX_ZOOM_FACTOR = 2,
INIT_ZOOM_FACTOR = 1;
var ZOOM_RATIO = 0.05;
const AUXILIARY_KEYS = ['image', 'Plans', 'level', 'image_text', 'xpos', 'ypos', 'width', 'height', 'total_time', 'parent_node', '_serial', 'arr_id'];
function PolyLine({startx, starty, endx, endy, opts, arrowOpts}) {
// Calculate end point of first starting straight line (startx1, starty1)
// Calculate start point of 2nd straight line (endx1, endy1)
let midX1 = startx + ((endx - startx) / 3),
midX2 = startx + (2 * ((endx - startx) / 3));
return (
<>
<line x1={startx} x2={midX1} y1={starty} y2={starty} {...opts}></line>
<line x1={midX1-1} x2={midX2} y1={starty} y2={endy} {...opts}></line>
<line x1={midX2} x2={endx} y1={endy} y2={endy} {...opts} {...arrowOpts}></line>
</>
);
}
PolyLine.propTypes = {
startx: PropTypes.number,
starty: PropTypes.number,
endx: PropTypes.number,
endy: PropTypes.number,
opts: PropTypes.object,
arrowOpts: PropTypes.object,
};
function Multitext({currentXpos, currentYpos, label, maxWidth}) {
const theme = useTheme();
let abc = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var xmlns = 'http://www.w3.org/2000/svg';
var svgElem = document.createElementNS(xmlns, 'svg');
svgElem.setAttributeNS(xmlns, 'height', '100%');
svgElem.setAttributeNS(xmlns, 'width', '100%');
var text = document.createElementNS(xmlns, 'text');
text.innerHTML = abc;
text.setAttributeNS(xmlns, 'x', 0);
text.setAttributeNS(xmlns, 'y', 0);
let attributes={
'font-size': TXT_SIZE,
'text-anchor': 'middle',
'fill': theme.palette.text.primary,
};
Object.keys(attributes).forEach((key)=>{
text.setAttributeNS(xmlns, key, attributes[key]);
});
svgElem.appendChild(text);
document.body.appendChild(svgElem);
/*
* Find letter width in pixels and
* index from where the text should be broken
*/
var letterWidth = text.getBBox().width / abc.length,
wordBreakIndex = Math.round((maxWidth / letterWidth)) - 1;
svgElem.remove();
var words = label.split(' '),
widthSoFar = 0,
lines = [],
currLine = '',
/*
* Function to divide string into multiple lines
* and store them in an array if it size crosses
* the max-width boundary.
*/
splitTextInMultiLine = function(leading, so_far, line) {
var l = line.length,
res = [];
if (l == 0)
return res;
if (so_far && (so_far + (l * letterWidth) > maxWidth)) {
res.push(leading);
res = res.concat(splitTextInMultiLine('', 0, line));
} else if (so_far) {
res.push(leading + ' ' + line);
} else {
if (leading)
res.push(leading);
if (line.length > wordBreakIndex + 1)
res.push(line.slice(0, wordBreakIndex) + '-');
else
res.push(line);
res = res.concat(splitTextInMultiLine('', 0, line.slice(wordBreakIndex)));
}
return res;
};
for (var i = 0; i < words.length; i++) {
var tmpArr = splitTextInMultiLine(
currLine, widthSoFar, words[i]
);
if (currLine) {
lines = lines.slice(0, lines.length - 1);
}
lines = lines.concat(tmpArr);
currLine = lines[lines.length - 1];
widthSoFar = (currLine.length * letterWidth);
}
return (
<text x={currentXpos} y={currentYpos} fill={theme.palette.text.primary} style={{fontSize: TXT_SIZE, textAnchor: 'middle'}}>
{lines.map((line, i)=>{
if(i > 0) {
return <tspan key={i} dy="1.2em" x={currentXpos}>{line}</tspan>;
}
return <tspan key={i}>{line}</tspan>;
})}
</text>
);
}
Multitext.propTypes = {
currentXpos: PropTypes.number,
currentYpos: PropTypes.number,
label: PropTypes.string,
maxWidth: PropTypes.number,
};
function Image({plan, label, currentXpos, currentYpos, content, download, onNodeClick}) {
return (
<>
<image href={content}
preserveAspectRatio="none"
x={currentXpos + (pWIDTH - IMAGE_WIDTH) / 2}
y={currentYpos + (pHEIGHT - IMAGE_HEIGHT) / 2}
width={IMAGE_WIDTH} height={IMAGE_HEIGHT}
style={{cursor: 'pointer'}} onClick={onNodeClick}>
{download &&
<title>
<NodeDetails plan={plan} download={true} />
</title>
}
</image>
<Multitext currentXpos={currentXpos + (pWIDTH / 2) + TXT_ALIGN} currentYpos={currentYpos + pHEIGHT - TXT_ALIGN} label={label} maxWidth={150} />
</>
);
}
Image.propTypes = {
plan: PropTypes.object,
label: PropTypes.string,
currentXpos: PropTypes.number,
currentYpos: PropTypes.number,
content: PropTypes.string,
download: PropTypes.bool,
onNodeClick: PropTypes.func,
};
function NodeDetails({plan, download=false}) {
return <>
{Object.keys(plan).map((key)=>{
if(AUXILIARY_KEYS.indexOf(key) != -1) {
return <></>;
}
if(download) {
return `${key}: ${plan[key]}\n`;
} else {
return (<tr key={key}>
<td>{_.escape(key)}</td>
<td>{_.escape(plan[key])}</td>
</tr>);
}
})}
</>;
}
NodeDetails.propTypes = {
plan: PropTypes.object,
download: PropTypes.bool,
};
function PlanContent({plan, pXpos, pYpos, ...props}) {
const theme = useTheme();
let currentXpos = props.xpos + plan.xpos,
currentYpos = props.ypos + plan.ypos,
isSubPlan = (plan['Parent Relationship'] === 'SubPlan');
const nodeLabel = plan.Schema == undefined ?
plan.image_text : plan.Schema + '.' + plan.image_text;
let polylineProps = null;
if(!_.isUndefined(pYpos)) {
let arrowSize = props.ctx.arrows[plan['arr_id']];
polylineProps = {
startx: currentXpos + pWIDTH,
starty: currentYpos + (pHEIGHT / 2),
endx: pXpos - ARROW_WIDTH,
endy: pYpos + (pHEIGHT / 2),
arr_id: plan['arr_id'],
};
polylineProps.opts = {
stroke: theme.palette.text.primary,
strokeWidth: arrowSize + 2,
};
polylineProps.arrowOpts = {
style: {
markerEnd: `url("#${plan['arr_id']}")`,
}
};
}
return (
<>
<g>
{isSubPlan &&
<>
<rect x={currentXpos - plan.width + pWIDTH + xMargin}
y={currentYpos - plan.height + pHEIGHT + yMargin - TXT_ALIGN}
width={plan.width - xMargin}
height={plan.height + (currentYpos - yMargin)}
rx={5}
stroke="#444444"
strokeWidth={1.2}
fill="gray"
fillOpacity={0.2}
/>
<tspan x={currentXpos + pWIDTH - (plan.width / 2) - xMargin}
y={currentYpos + pHEIGHT - (plan.height / 2) - yMargin}
fontSize={TXT_SIZE}
textAnchor="start"
fill="red"
>{plan['Subplan Name']}</tspan>
</>}
<Image
label={nodeLabel}
content={url_for('misc.index') + 'static/explain/img/' + plan.image}
currentXpos={currentXpos}
currentYpos={currentYpos}
plan={plan}
download={props.download}
onNodeClick={()=>props.onNodeClick(nodeLabel, plan)}
/>
{polylineProps && <PolyLine {...polylineProps} />}
</g>
{plan['Plans'].map((p, i)=>(
<PlanContent key={i} plan={p} pXpos={currentXpos} pYpos={currentYpos} {...props}/>
))}
</>
);
}
PlanContent.propTypes = {
plan: PropTypes.object,
pXpos: PropTypes.number,
pYpos: PropTypes.number,
xpos: PropTypes.number,
ypos: PropTypes.number,
ctx: PropTypes.object,
download: PropTypes.bool,
onNodeClick: PropTypes.func,
};
function PlanSVG({planData, zoomFactor, fitZoomFactor, ...props}) {
const theme = useTheme();
useEffect(()=>{
fitZoomFactor && fitZoomFactor(planData.width);
}, [planData.width]);
return (
<svg height={planData.height*zoomFactor} width={planData.width*zoomFactor} version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
{Object.keys(props.ctx.arrows).map((arr_id, i)=>{
let arrowPoints = [
0, 0,
0, (ARROW_WIDTH / 2),
ARROW_HEIGHT, (ARROW_WIDTH / 4),
0, 0
].join(',');
let viewBox = [0, 0, 2 * ARROW_WIDTH, 2 * ARROW_HEIGHT].join(' ');
return(
<marker key={i} viewBox={viewBox} markerWidth={ARROW_WIDTH} markerHeight={ARROW_HEIGHT} orient="auto" refX="0" refY={ARROW_WIDTH / 4} id={arr_id} fill={theme.palette.text.primary}>
<polygon points={arrowPoints}></polygon>
</marker>
);
})}
</defs>
<g transform={`matrix(${zoomFactor},0,0,${zoomFactor},0,0)`}>
<rect x="0" y="0" width={planData.width} height={planData.height} rx="5" ry="5" fill={theme.palette.background.default}></rect>
<PlanContent plan={planData['Plan']} xpos={planData.width - xMargin} ypos={yMargin} {...props}/>
</g>
</svg>
);
}
PlanSVG.propTypes = {
planData: PropTypes.object,
zoomFactor: PropTypes.number,
fitZoomFactor: PropTypes.number,
ctx: PropTypes.object,
};
const useStyles = makeStyles((theme)=>({
explainDetails: {
minWidth: '200px',
maxWidth: '300px',
position: 'absolute',
top: '0.25rem',
bottom: '0.25rem',
right: '0.25rem',
borderColor: theme.otherVars.borderColor,
// box-shadow: 0 0.125rem 0.5rem rgb(132 142 160 / 28%);
wordBreak: 'break-all',
display: 'flex',
flexDirection: 'column',
zIndex: 99,
},
explainContent: {
height: '100%',
overflow: 'auto',
}
}));
export default function Graphical({planData, ctx}) {
const tableStyles = commonTableStyles();
const classes = useStyles();
const graphContainerRef = React.useRef();
const [zoomFactor, setZoomFactor] = React.useState(INIT_ZOOM_FACTOR);
const [[explainPlanTitle, explainPlanDetails], setExplainPlanDetails] = React.useState([null, null]);
const onCmdClick = (cmd)=>{
if(cmd == 'in') {
setZoomFactor((prev)=>{
if(prev >= MAX_ZOOM_FACTOR) return prev;
return prev+ZOOM_RATIO;
});
} else if(cmd == 'out') {
setZoomFactor((prev)=>{
if(prev <= MIN_ZOOM_FACTOR) return prev;
return prev-ZOOM_RATIO;
});
} else {
setZoomFactor(INIT_ZOOM_FACTOR);
}
};
const fitZoomFactor = React.useCallback((svgWidth)=>{
/*
* Scale graph in case its width is bigger than panel width
* in which the graph is displayed
*/
if(graphContainerRef.current.offsetWidth && svgWidth) {
let zoomFactor = graphContainerRef.current.offsetWidth/svgWidth;
zoomFactor = zoomFactor < MIN_ZOOM_FACTOR ? MIN_ZOOM_FACTOR : zoomFactor;
zoomFactor = zoomFactor > INIT_ZOOM_FACTOR ? INIT_ZOOM_FACTOR : zoomFactor;
setZoomFactor(zoomFactor);
}
}, []);
const onDownloadClick = ()=>{
downloadSvg(ReactDOMServer.renderToStaticMarkup(
<PlanSVG planData={planData} download={true} ctx={ctx} zoomFactor={INIT_ZOOM_FACTOR} onNodeClick={()=>{}}/>
), 'explain_plan_' + (new Date()).getTime() + '.svg');
};
const onNodeClick = React.useCallback((title, details)=>{
setExplainPlanDetails([title, details]);
}, []);
return (
<Box ref={graphContainerRef} height="100%" width="100%" overflow="auto">
<Box position="absolute" top="4px" left="4px" gridGap="4px" display="flex">
<PgButtonGroup size="small">
<PgIconButton title={gettext('Zoom in')} icon={<ZoomInIcon />} onClick={()=>onCmdClick('in')}/>
<PgIconButton title={gettext('Zoom to original')} icon={<ZoomOutMapIcon />} onClick={()=>onCmdClick()}/>
<PgIconButton title={gettext('Zoom out')} icon={<ZoomOutIcon />} onClick={()=>onCmdClick('out')}/>
</PgButtonGroup>
<PgButtonGroup size="small">
<PgIconButton title={gettext('Download')} icon={<SaveAltIcon />} onClick={onDownloadClick}/>
</PgButtonGroup>
</Box>
<PlanSVG planData={planData} ctx={ctx} zoomFactor={zoomFactor} fitZoomFactor={fitZoomFactor}
onNodeClick={onNodeClick}
/>
{Boolean(explainPlanDetails) &&
<Card className={classes.explainDetails}>
<CardHeader title={<Box display="flex">
{explainPlanTitle}
<Box marginLeft="auto">
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>setExplainPlanDetails([null, null])}/>
</Box>
</Box>} />
<CardContent className={classes.explainContent}>
<table className={clsx(tableStyles.table, tableStyles.borderBottom)}>
<tbody>
<NodeDetails download={false} plan={explainPlanDetails} />
</tbody>
</table>
</CardContent>
</Card>}
</Box>
);
}
Graphical.propTypes = {
planData: PropTypes.object,
ctx: PropTypes.object,
};

View File

@ -0,0 +1,300 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
/*
* A map which is used to fetch the image to be drawn and
* text which will appear below it
*/
const ImageMapper = {
'Aggregate': {
'image': 'ex_aggregate.svg',
'image_text': 'Aggregate',
},
'Append': {
'image': 'ex_append.svg',
'image_text': 'Append',
},
'Bitmap Index Scan': function(data) {
return {
'image': 'ex_bmp_index.svg',
'image_text': data['Index Name'],
};
},
'Bitmap Heap Scan': function(data) {
return {
'image': 'ex_bmp_heap.svg',
'image_text': data['Relation Name'],
};
},
'BitmapAnd': {
'image': 'ex_bmp_and.svg',
'image_text': 'Bitmap AND',
},
'BitmapOr': {
'image': 'ex_bmp_or.svg',
'image_text': 'Bitmap OR',
},
'CTE Scan': {
'image': 'ex_cte_scan.svg',
'image_text': 'CTE Scan',
},
'Function Scan': {
'image': 'ex_result.svg',
'image_text': 'Function Scan',
},
'Foreign Scan': {
'image': 'ex_foreign_scan.svg',
'image_text': 'Foreign Scan',
},
'Gather': {
'image': 'ex_gather_motion.svg',
'image_text': 'Gather',
},
'Gather Merge': {
'image': 'ex_gather_merge.svg',
'image_text': 'Gather Merge',
},
'Group': {
'image': 'ex_group.svg',
'image_text': 'Group',
},
'GroupAggregate': {
'image': 'ex_aggregate.svg',
'image_text': 'Group Aggregate',
},
'Hash': {
'image': 'ex_hash.svg',
'image_text': 'Hash',
},
'Hash Join': function(data) {
if (!data['Join Type']) return {
'image': 'ex_join.svg',
'image_text': 'Join',
};
switch (data['Join Type']) {
case 'Anti':
return {
'image': 'ex_hash_anti_join.svg',
'image_text': 'Hash Anti Join',
};
case 'Semi':
return {
'image': 'ex_hash_semi_join.svg',
'image_text': 'Hash Semi Join',
};
default:
return {
'image': 'ex_hash.svg',
'image_text': String('Hash ' + data['Join Type'] + ' Join'),
};
}
},
'HashAggregate': {
'image': 'ex_aggregate.svg',
'image_text': 'Hash Aggregate',
},
'Index Only Scan': function(data) {
return {
'image': 'ex_index_only_scan.svg',
'image_text': data['Index Name'],
};
},
'Index Scan': function(data) {
return {
'image': 'ex_index_scan.svg',
'image_text': data['Index Name'],
};
},
'Index Scan Backword': {
'image': 'ex_index_scan.svg',
'image_text': 'Index Backward Scan',
},
'Limit': {
'image': 'ex_limit.svg',
'image_text': 'Limit',
},
'LockRows': {
'image': 'ex_lock_rows.svg',
'image_text': 'Lock Rows',
},
'Materialize': {
'image': 'ex_materialize.svg',
'image_text': 'Materialize',
},
'Merge Append': {
'image': 'ex_merge_append.svg',
'image_text': 'Merge Append',
},
'Merge Join': function(data) {
switch (data['Join Type']) {
case 'Anti':
return {
'image': 'ex_merge_anti_join.svg',
'image_text': 'Merge Anti Join',
};
case 'Semi':
return {
'image': 'ex_merge_semi_join.svg',
'image_text': 'Merge Semi Join',
};
default:
return {
'image': 'ex_merge.svg',
'image_text': String('Merge ' + data['Join Type'] + ' Join'),
};
}
},
'ModifyTable': function(data) {
switch (data['Operation']) {
case 'Insert':
return {
'image': 'ex_insert.svg',
'image_text': 'Insert',
};
case 'Update':
return {
'image': 'ex_update.svg',
'image_text': 'Update',
};
case 'Delete':
return {
'image': 'ex_delete.svg',
'image_text': 'Delete',
};
}
},
'Named Tuplestore Scan': {
'image': 'ex_named_tuplestore_scan.svg',
'image_text': 'Named Tuplestore Scan',
},
'Nested Loop': function(data) {
switch (data['Join Type']) {
case 'Anti':
return {
'image': 'ex_nested_loop_anti_join.svg',
'image_text': 'Nested Loop Anti Join',
};
case 'Semi':
return {
'image': 'ex_nested_loop_semi_join.svg',
'image_text': 'Nested Loop Semi Join',
};
default:
return {
'image': 'ex_nested.svg',
'image_text': 'Nested Loop ' + data['Join Type'] + ' Join',
};
}
},
'ProjectSet': {
'image': 'ex_projectset.svg',
'image_text': 'ProjectSet',
},
'Recursive Union': {
'image': 'ex_recursive_union.svg',
'image_text': 'Recursive Union',
},
'Result': {
'image': 'ex_result.svg',
'image_text': 'Result',
},
'Sample Scan': {
'image': 'ex_scan.svg',
'image_text': 'Sample Scan',
},
'Scan': {
'image': 'ex_scan.svg',
'image_text': 'Scan',
},
'Seek': {
'image': 'ex_seek.svg',
'image_text': 'Seek',
},
'SetOp': function(data) {
let strategy = data['Strategy'],
command = data['Command'];
if (strategy == 'Hashed') {
if (command.startsWith('Intersect')) {
if (command == 'Intersect All')
return {
'image': 'ex_hash_setop_intersect_all.svg',
'image_text': 'Hashed Intersect All',
};
return {
'image': 'ex_hash_setop_intersect.svg',
'image_text': 'Hashed Intersect',
};
} else if (command.startsWith('Except')) {
if (command == 'Except All')
return {
'image': 'ex_hash_setop_except_all.svg',
'image_text': 'Hashed Except All',
};
return {
'image': 'ex_hash_setop_except.svg',
'image_text': 'Hash Except',
};
}
return {
'image': 'ex_hash_setop_unknown.svg',
'image_text': 'Hashed SetOp Unknown',
};
}
return {
'image': 'ex_setop.svg',
'image_text': 'SetOp',
};
},
'Seq Scan': function(data) {
return {
'image': 'ex_scan.svg',
'image_text': data['Relation Name'],
};
},
'Subquery Scan': {
'image': 'ex_subplan.svg',
'image_text': 'SubQuery Scan',
},
'Sort': {
'image': 'ex_sort.svg',
'image_text': 'Sort',
},
'Tid Scan': {
'image': 'ex_tid_scan.svg',
'image_text': 'Tid Scan',
},
'Table Function Scan': {
'image': 'ex_table_func_scan.svg',
'image_text': 'Table Function Scan',
},
'Unique': {
'image': 'ex_unique.svg',
'image_text': 'Unique',
},
'Values Scan': {
'image': 'ex_values_scan.svg',
'image_text': 'Values Scan',
},
'WindowAgg': {
'image': 'ex_window_aggregate.svg',
'image_text': 'Window Aggregate',
},
'WorkTable Scan': {
'image': 'ex_worktable_scan.svg',
'image_text': 'WorkTable Scan',
},
'Undefined': {
'image': 'ex_unknown.svg',
'image_text': 'Undefined',
},
};
export default ImageMapper;

View File

@ -0,0 +1,23 @@
.explain-tooltip {
display: table-cell;
text-align: left;
white-space: nowrap;
padding: 2px !important;
font-size: small;
}
td.explain-tooltip-val {
display: table-cell;
text-align: left;
white-space: pre-wrap;
padding: 2px !important;
font-size: small;
font-weight: normal;
}
.pgadmin-tooltip-table {
border-collapse: collapse;
border-spacing: 1px;
top: auto;
left: auto;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3,.cls-8{fill:#c8ffac;}.cls-4{fill:#48d601;}.cls-5{fill:#d3d4f3;}.cls-6{fill:#666bd1;}.cls-11,.cls-7,.cls-9{fill:none;}.cls-7{stroke:#666bd1;}.cls-10,.cls-11,.cls-7,.cls-9{stroke-linejoin:round;}.cls-7,.cls-9{opacity:0.8;}.cls-8{stroke:#48d601;stroke-miterlimit:10;opacity:0.7;}.cls-9{stroke:#c18f35;}.cls-10{fill:#34495e;}.cls-10,.cls-11{stroke:#34495e;}.cls-11{stroke-linecap:round;}</style></defs><title>ex_aggregate</title><g id="ex_broadcast_motion"><rect class="cls-1" x="38.42" y="27.25" width="8.28" height="9"/><path class="cls-2" d="M46.2,27.75v8H38.92v-8H46.2m1-1H37.92v10H47.2v-10Z"/><rect class="cls-1" x="46.72" y="27.25" width="8.28" height="9"/><path class="cls-2" d="M54.5,27.75v8H47.22v-8H54.5m1-1H46.22v10H55.5v-10Z"/><path class="cls-3" d="M39.92,45.23c-1.37,0-1.5-.13-1.5-1.5v-7.5H46.7v9Z"/><path class="cls-4" d="M46.2,36.73v8H39.92a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-7H46.2m1-1H37.92v8c0,1.65.35,2,2,2H47.2v-10Z"/><path class="cls-3" d="M46.72,45.23v-9H55v7.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M54.5,36.73v7a3.29,3.29,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.22v-8H54.5m1-1H46.22v10H53.5c1.65,0,2-.35,2-2v-8Z"/><path class="cls-5" d="M38.42,27.27v-7.5c0-1.37.13-1.5,1.5-1.5H46.7v9Z"/><path class="cls-6" d="M46.2,18.77v8H38.92v-7a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H46.2m1-1H39.92c-1.65,0-2,.35-2,2v8H47.2v-10Z"/><path class="cls-5" d="M46.72,27.27v-9H53.5c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-6" d="M53.5,18.77a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H47.22v-8H53.5m0-1H46.22v10H55.5v-8c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M9,25.43V13.93c0-1.37.13-1.5,1.5-1.5h5.78v13Z"/><path class="cls-6" d="M15.81,12.93v12H9.53v-11a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H10.53c-1.65,0-2,.35-2,2v12h8.28v-14Z"/><path class="cls-5" d="M16.32,25.43v-13H22.1c1.37,0,1.5.13,1.5,1.5v11.5Z"/><path class="cls-6" d="M22.1,12.93A3.25,3.25,0,0,1,23,13h0a2.18,2.18,0,0,1,.1.92v11H16.82v-12H22.1m0-1H15.82v14H24.1v-12c0-1.65-.35-2-2-2Z"/><line class="cls-7" x1="9.06" y1="18.77" x2="15.8" y2="18.77"/><line class="cls-7" x1="16.08" y1="18.77" x2="23.57" y2="18.77"/><path class="cls-3" d="M10.53,51.45C9.16,51.45,9,51.33,9,50V38.45h7.28v13Z"/><path class="cls-4" d="M15.81,39V51H10.53a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V39h6.28m1-1H8.53V50c0,1.65.35,2,2,2h6.28V38Z"/><path class="cls-3" d="M16.32,51.45v-13H23.6V50c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M23.1,39V50a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H16.82V39H23.1m1-1H15.82V52H22.1c1.65,0,2-.35,2-2V38Z"/><line class="cls-8" x1="16.08" y1="44.8" x2="23.57" y2="44.8"/><line class="cls-8" x1="9.06" y1="44.8" x2="15.8" y2="44.8"/><rect class="cls-1" x="16.32" y="25.43" width="7.28" height="13"/><path class="cls-2" d="M23.1,25.93v12H16.82v-12H23.1m1-1H15.82v14H24.1v-14Z"/><line class="cls-9" x1="16.08" y1="31.78" x2="23.57" y2="31.78"/><rect class="cls-1" x="9.03" y="25.43" width="7.28" height="13"/><path class="cls-2" d="M15.81,25.93v12H9.53v-12h6.28m1-1H8.53v14h8.28v-14Z"/><line class="cls-9" x1="9.06" y1="31.78" x2="15.8" y2="31.78"/><polygon class="cls-10" points="37.01 23.11 33.87 24.12 35.16 20.39 37.01 23.11"/><line class="cls-11" x1="34.91" y1="22.57" x2="25" y2="19.04"/><polygon class="cls-10" points="37.01 40.87 33.87 39.87 35.16 43.6 37.01 40.87"/><line class="cls-11" x1="34.91" y1="41.42" x2="25" y2="44.95"/><polygon class="cls-10" points="37.07 31.78 34.43 33.76 34.43 29.8 37.07 31.78"/><line class="cls-11" x1="34.89" y1="31.88" x2="25" y2="31.92"/></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#528d19;}.cls-1,.cls-2{stroke:#528d19;}.cls-1,.cls-11,.cls-2,.cls-8{stroke-linejoin:round;}.cls-11,.cls-2,.cls-8{fill:none;}.cls-2{stroke-linecap:round;stroke-width:2px;}.cls-3{fill:#f0ecb6;}.cls-4{fill:#3588c1;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7{opacity:0.7;}.cls-8{stroke:#c18f35;}.cls-9{fill:#d3d4f3;}.cls-10{fill:#666bd1;}.cls-11{stroke:#666bd1;}</style></defs><title>ex_append</title><g id="ex_append"><polygon class="cls-1" points="23.04 38.11 25.57 41.49 20.51 41.49 23.04 38.11"/><line class="cls-2" x1="23.04" y1="41.49" x2="23.04" y2="44.47"/><polygon class="cls-1" points="40.98 38.11 43.5 41.49 38.45 41.49 40.98 38.11"/><line class="cls-2" x1="40.97" y1="41.49" x2="40.97" y2="44.47"/><path class="cls-3" d="M8,34.5c-1.37,0-1.5-.13-1.5-1.5V12.5h51V33c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M57,13V33a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,34H8a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,7,33V13H57m1-1H6V33c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V12Z"/><path class="cls-5" d="M46.38,12.5v-6H56c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M56,7a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,8v4H46.88V7H56m0-1H45.88v7H58V8c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M6.52,12.5V8c0-1.37.13-1.5,1.5-1.5H17.6v6Z"/><path class="cls-6" d="M17.1,7v5H7V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,8,7H17.1m1-1H8C6.37,6,6,6.35,6,8v5H18.1V6Z"/><rect class="cls-5" x="36.82" y="6.5" width="9.56" height="6"/><path class="cls-6" d="M45.88,7v5H37.31V7h8.56m1-1H36.32v7H46.88V6Z"/><rect class="cls-5" x="27.25" y="6.5" width="9.56" height="6"/><path class="cls-6" d="M36.32,7v5H27.75V7h8.56m1-1H26.76v7H37.32V6Z"/><rect class="cls-5" x="17.62" y="6.5" width="9.62" height="6"/><path class="cls-6" d="M26.74,7v5H18.12V7h8.61m1-1H17.13v7H27.74V6Z"/><g class="cls-7"><line class="cls-8" x1="17.61" y1="34" x2="17.61" y2="13"/><line class="cls-8" x1="36.8" y1="34" x2="36.8" y2="13"/><line class="cls-8" x1="27.21" y1="34" x2="27.21" y2="13"/><line class="cls-8" x1="46.39" y1="34" x2="46.39" y2="13"/><line class="cls-8" x1="7" y1="19.85" x2="57.25" y2="19.85"/><line class="cls-8" x1="7" y1="27.23" x2="57.25" y2="27.23"/></g><rect class="cls-9" x="6.52" y="48.5" width="50.98" height="9" rx="1.5" ry="1.5"/><path class="cls-10" d="M56,49a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,50v6a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,57H8a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,7,56V50a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,8,49H56m0-1H8c-1.65,0-2,.35-2,2v6c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V50c0-1.65-.35-2-2-2Z"/><g class="cls-7"><line class="cls-11" x1="17.6" y1="57.06" x2="17.6" y2="48.83"/><line class="cls-11" x1="27.2" y1="57.06" x2="27.2" y2="48.83"/><line class="cls-11" x1="36.8" y1="57.06" x2="36.8" y2="48.83"/><line class="cls-11" x1="46.4" y1="57.06" x2="46.4" y2="48.83"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-8{fill:#34495e;}.cls-2{fill:#d3d4f3;}.cls-3{fill:#666bd1;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{opacity:0.7;}.cls-11,.cls-7{fill:none;stroke-linejoin:round;}.cls-7{stroke:#666bd1;}.cls-8{font-size:6px;font-family:Helvetica-Bold, Helvetica;font-weight:700;}.cls-9{fill:#f0ecb6;}.cls-10{fill:#c18f35;}.cls-11{stroke:#c18f35;}</style></defs><title>ex_bmp_and</title><g id="ex_bmp_and"><path class="cls-1" d="M26,28.89a5.2,5.2,0,0,1-.46-2.07,4.62,4.62,0,0,1,1.4-3.45A5.14,5.14,0,0,1,30.69,22a4.68,4.68,0,0,1,3.49,1.27,4.19,4.19,0,0,1,1.26,3,5.47,5.47,0,0,1-1.3,3.62A12.24,12.24,0,0,1,31.6,32l3.91,4.69Q35.9,35.56,36,35t.31-1.62h2.5a16,16,0,0,1-1,4q-.74,1.9-.74,1.53l3.81,4.65H37.55l-2-2.46a10.55,10.55,0,0,1-2.19,1.9,7.55,7.55,0,0,1-4,1.05Q26,44,24.49,42.19A6.18,6.18,0,0,1,23,38.11,5.89,5.89,0,0,1,24.45,34a16.16,16.16,0,0,1,3.37-2.49A11.06,11.06,0,0,1,26,28.89Zm6.33,12a6.09,6.09,0,0,0,1.79-1.67l-4.85-5.93a14.74,14.74,0,0,0-2.68,2.11,3.93,3.93,0,0,0-1,2.68,3.08,3.08,0,0,0,1.25,2.64,4.39,4.39,0,0,0,2.66.92A5.05,5.05,0,0,0,32.33,40.93Zm-.21-12.2A3.31,3.31,0,0,0,33,26.53a2.35,2.35,0,0,0-.63-1.64,2.17,2.17,0,0,0-1.69-.69,2.26,2.26,0,0,0-2.56,2.3,3.27,3.27,0,0,0,.49,1.71,15.83,15.83,0,0,0,1.64,2.12A11.08,11.08,0,0,0,32.12,28.74Z"/><rect class="cls-2" x="6.54" y="7.5" width="11.98" height="49" rx="1.5" ry="1.5"/><path class="cls-3" d="M17,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,18,9V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,17,56H8a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,7,55V9a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,8,8h9m0-1H8C6.39,7,6,7.35,6,9V55c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V9c0-1.65-.35-2-2-2Z"/><path class="cls-4" d="M6.54,15.5V9c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-5" d="M17,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,18,9v6H7V9a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,8,8h9m0-1H8C6.39,7,6,7.35,6,9v7H19V9c0-1.65-.35-2-2-2Z"/><g class="cls-6"><line class="cls-7" x1="7.05" y1="23.74" x2="18.02" y2="23.74"/><line class="cls-7" x1="7.05" y1="31.49" x2="18.02" y2="31.49"/><line class="cls-7" x1="7.05" y1="39.23" x2="18.02" y2="39.23"/><line class="cls-7" x1="7.05" y1="46.97" x2="18.02" y2="46.97"/></g><text class="cls-8" transform="translate(10.87 21.83)">1</text><text class="cls-8" transform="translate(10.87 29.76)">0</text><text class="cls-8" transform="translate(10.87 45.24)">1</text><text class="cls-8" transform="translate(10.87 37.62)">0</text><text class="cls-8" transform="translate(10.87 53.33)">0</text><rect class="cls-9" x="45.47" y="7.5" width="11.98" height="49" rx="1.5" ry="1.5"/><path class="cls-10" d="M56,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,9V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,56H47a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,46,55V9A3.28,3.28,0,0,1,46,8.1,2.18,2.18,0,0,1,47,8h9m0-1H47c-1.65,0-2,.35-2,2V55c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V9c0-1.65-.35-2-2-2Z"/><g class="cls-6"><line class="cls-11" x1="45.98" y1="23.74" x2="56.95" y2="23.74"/><line class="cls-11" x1="45.98" y1="31.49" x2="56.95" y2="31.49"/><line class="cls-11" x1="45.98" y1="39.23" x2="56.95" y2="39.23"/><line class="cls-11" x1="45.98" y1="46.97" x2="56.95" y2="46.97"/></g><text class="cls-8" transform="translate(49.8 21.83)">0</text><text class="cls-8" transform="translate(49.8 29.76)">0</text><text class="cls-8" transform="translate(49.8 45.24)">1</text><text class="cls-8" transform="translate(49.8 37.62)">1</text><text class="cls-8" transform="translate(49.8 53.33)">1</text><path class="cls-4" d="M45.47,15.5V9c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-5" d="M56,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,9v6H46V9A3.28,3.28,0,0,1,46,8.1,2.18,2.18,0,0,1,47,8h9m0-1H47c-1.65,0-2,.35-2,2v7H58V9c0-1.65-.35-2-2-2Z"/></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{opacity:0.7;}.cls-10,.cls-13,.cls-15,.cls-4{fill:none;}.cls-4{stroke:#c18f35;}.cls-10,.cls-12,.cls-13,.cls-14,.cls-15,.cls-4{stroke-linejoin:round;}.cls-5{fill:#addff3;}.cls-14,.cls-6{fill:#2980b9;}.cls-11,.cls-7{fill:#34495e;}.cls-8{fill:#d3d4f3;}.cls-9{fill:#666bd1;}.cls-10{stroke:#666bd1;}.cls-11{font-size:6px;font-family:Helvetica-Bold, Helvetica;font-weight:700;}.cls-12{fill:#528d19;}.cls-12,.cls-13{stroke:#528d19;}.cls-13,.cls-15{stroke-linecap:round;stroke-width:2px;}.cls-14,.cls-15{stroke:#2980b9;}</style></defs><title>ex_bmp_heap</title><g id="ex_bmp_heap"><path class="cls-1" d="M37,56.5c-1.37,0-1.5-.13-1.5-1.5V9c0-.9.43-1.5,2.5-1.5H55c2.07,0,2.5.6,2.5,1.5V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M55,8c2,0,2,.55,2,1V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,56H37a3.25,3.25,0,0,1-.9-.08h0A2.17,2.17,0,0,1,36,55V9c0-.45,0-1,2-1H55m0-1H38c-1.65,0-3,.35-3,2V55c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V9c0-1.65-1.35-2-3-2Z"/><g class="cls-3"><line class="cls-4" x1="35.98" y1="23.74" x2="56.94" y2="23.74"/><line class="cls-4" x1="35.98" y1="31.49" x2="56.94" y2="31.49"/><line class="cls-4" x1="35.98" y1="39.23" x2="56.94" y2="39.23"/><line class="cls-4" x1="35.98" y1="46.97" x2="56.94" y2="46.97"/></g><g class="cls-3"><line class="cls-4" x1="50.04" y1="16" x2="50.04" y2="56.11"/><line class="cls-4" x1="43.07" y1="16" x2="43.07" y2="56.11"/></g><path class="cls-5" d="M35.47,15.5V9c0-1.37.13-1.5,1.5-1.5H56c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-6" d="M56,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,9v6H36V9A3.28,3.28,0,0,1,36,8.1,2.18,2.18,0,0,1,37,8H56m0-1H37c-1.65,0-2,.35-2,2v7H58V9c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M36.71,25l5.12.08v5.39l-5.12-.08Z"/><path class="cls-7" d="M51.07,40.48l5.12.08V46l-5.12-.08Z"/><path class="cls-8" d="M8,56.5c-1.37,0-1.5-.13-1.5-1.5V10c0-2.07.6-2.5,1.5-2.5h9c.9,0,1.5.43,1.5,2.5V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-9" d="M17,8c.45,0,1,0,1,2V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,17,56H8a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,7,55V10c0-2,.55-2,1-2h9m0-1H8C6.35,7,6,8.35,6,10V55c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V10c0-1.65-.35-3-2-3Z"/><path class="cls-5" d="M6.5,15.5V9c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-6" d="M17,8a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,18,9v6H7V9a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,8,8h9m0-1H8C6.35,7,6,7.35,6,9v7H19V9c0-1.65-.35-2-2-2Z"/><g class="cls-3"><line class="cls-10" x1="7.01" y1="23.74" x2="17.97" y2="23.74"/><line class="cls-10" x1="7.01" y1="31.49" x2="17.97" y2="31.49"/><line class="cls-10" x1="7.01" y1="39.23" x2="17.97" y2="39.23"/><line class="cls-10" x1="7.01" y1="46.97" x2="17.97" y2="46.97"/></g><text class="cls-11" transform="translate(10.82 21.83)">1</text><text class="cls-11" transform="translate(10.82 29.76)">0</text><text class="cls-11" transform="translate(10.82 45.24)">1</text><text class="cls-11" transform="translate(10.82 37.62)">0</text><text class="cls-11" transform="translate(10.82 53.33)">0</text><polygon class="cls-12" points="17.81 27.49 21.19 24.96 21.19 30.02 17.81 27.49"/><line class="cls-13" x1="21.19" y1="27.49" x2="36.16" y2="27.49"/><polygon class="cls-12" points="17.81 43.01 21.19 40.48 21.19 45.54 17.81 43.01"/><line class="cls-13" x1="21.19" y1="43.01" x2="50.04" y2="43.01"/><polygon class="cls-14" points="30.47 51.68 27.94 48.3 33 48.3 30.47 51.68"/><line class="cls-15" x1="30.47" y1="48.3" x2="30.47" y2="17.32"/></g></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{opacity:0.7;}.cls-14,.cls-4,.cls-9{fill:none;}.cls-4{stroke:#c18f35;}.cls-13,.cls-14,.cls-4,.cls-8,.cls-9{stroke-linejoin:round;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-15,.cls-7,.cls-8{fill:#34495e;}.cls-8,.cls-9{stroke:#34495e;}.cls-14,.cls-9{stroke-linecap:round;stroke-width:2px;}.cls-10,.cls-12{fill:#d3d4f3;}.cls-11{fill:#666bd1;}.cls-12{stroke:#666bd1;stroke-miterlimit:10;}.cls-13{fill:#528d19;}.cls-13,.cls-14{stroke:#528d19;}.cls-15{font-size:6px;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>ex_bmp_index</title><g id="ex_bmp_index"><path class="cls-1" d="M37,54.5c-1.37,0-1.5-.13-1.5-1.5V16.5h22V53c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M57,17V53a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,54H37a3.25,3.25,0,0,1-.9-.08h0A2.17,2.17,0,0,1,36,53V17H57m1-1H35V53c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V16Z"/><g class="cls-3"><line class="cls-4" x1="36.03" y1="23.74" x2="56.99" y2="23.74"/><line class="cls-4" x1="36.03" y1="31.49" x2="56.99" y2="31.49"/><line class="cls-4" x1="36.03" y1="39.23" x2="56.99" y2="39.23"/><line class="cls-4" x1="36.03" y1="46.97" x2="56.99" y2="46.97"/></g><g class="cls-3"><line class="cls-4" x1="50.08" y1="17" x2="50.08" y2="54.11"/><line class="cls-4" x1="43.12" y1="17" x2="43.12" y2="54.11"/></g><path class="cls-5" d="M35.52,16.5V10c0-.9.43-1.5,2.5-1.5H56c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-6" d="M56,9a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,10v6H36V10c0-.45,0-1,2-1H56m0-1H38c-1.65,0-3,.35-3,2v7H58V10c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M36.76,25l5.12.08v5.39l-5.12-.08Z"/><path class="cls-7" d="M36.76,40.48l5.12.08V46l-5.12-.08Z"/><polygon class="cls-8" points="30.2 51.68 27.68 48.3 32.73 48.3 30.2 51.68"/><line class="cls-9" x1="30.2" y1="48.3" x2="30.2" y2="17.32"/><path class="cls-10" d="M10,54.5c-1.37,0-1.5-.13-1.5-1.5V16.5h12V53c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-11" d="M20,17V53a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,19,54H10a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,9,53V17H20m1-1H8V53c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V16Z"/><path class="cls-5" d="M8.5,16.5V10c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-6" d="M19,9a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,20,10v6H9V10a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,10,9h9m0-1H10c-1.65,0-2,.35-2,2v7H21V10c0-1.65-.35-2-2-2Z"/><line class="cls-12" x1="9" y1="23.74" x2="19.99" y2="23.74"/><line class="cls-12" x1="9" y1="31.49" x2="19.99" y2="31.49"/><line class="cls-12" x1="9" y1="39.23" x2="19.99" y2="39.23"/><line class="cls-12" x1="9" y1="46.98" x2="19.99" y2="46.98"/><polygon class="cls-13" points="17.81 27.49 21.19 24.96 21.19 30.02 17.81 27.49"/><line class="cls-14" x1="21.19" y1="27.49" x2="36.16" y2="27.49"/><polygon class="cls-13" points="17.81 43.22 21.19 40.69 21.19 45.75 17.81 43.22"/><line class="cls-14" x1="21.19" y1="43.22" x2="36.16" y2="43.22"/><text class="cls-15" transform="translate(12.82 22.45)">0</text><text class="cls-15" transform="translate(12.82 30.02)">1</text><text class="cls-15" transform="translate(12.82 45.24)">1</text><text class="cls-15" transform="translate(12.82 37.33)">0</text><text class="cls-15" transform="translate(12.82 52.73)">0</text></g></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-11{fill:none;stroke-linejoin:round;}.cls-1{stroke:#34495e;stroke-linecap:round;stroke-width:4px;}.cls-2,.cls-4{fill:#d3d4f3;}.cls-3{fill:#666bd1;}.cls-4{stroke:#666bd1;stroke-miterlimit:10;}.cls-5{font-size:6px;fill:#34495e;font-family:Helvetica-Bold, Helvetica;font-weight:700;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}.cls-8{fill:#f0ecb6;}.cls-9{fill:#c18f35;}.cls-10{opacity:0.7;}.cls-11{stroke:#c18f35;}</style></defs><title>ex_bmp_or</title><g id="ex_bmp_or"><line class="cls-1" x1="32" y1="15.84" x2="32" y2="48.16"/><path class="cls-2" d="M10,56.5c-1.37,0-1.5-.13-1.5-1.5V15.46h12V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M20,16V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,19,56H10a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,9,55V16H20m1-1H8V55c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V15Z"/><line class="cls-4" x1="9.01" y1="23.74" x2="19.97" y2="23.74"/><line class="cls-4" x1="9.01" y1="31.49" x2="19.97" y2="31.49"/><line class="cls-4" x1="9.01" y1="39.23" x2="19.97" y2="39.23"/><line class="cls-4" x1="9.01" y1="46.97" x2="19.97" y2="46.97"/><text class="cls-5" transform="translate(12.82 21.83)">1</text><text class="cls-5" transform="translate(12.82 29.76)">0</text><text class="cls-5" transform="translate(12.82 45.24)">1</text><text class="cls-5" transform="translate(12.82 37.62)">0</text><text class="cls-5" transform="translate(12.82 53.33)">0</text><path class="cls-6" d="M8.5,15.5V9c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-7" d="M19,8a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,20,9v6H9V9a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,10,8h9m0-1H10C8.35,7,8,7.35,8,9v7H21V9c0-1.65-.35-2-2-2Z"/><path class="cls-8" d="M45,56.5c-1.37,0-1.5-.13-1.5-1.5V15.46h12V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-9" d="M55,16V55a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,54,56H45a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,44,55V16H55m1-1H43V55c0,1.65.35,2,2,2h9c1.65,0,2-.35,2-2V15Z"/><g class="cls-10"><line class="cls-11" x1="44.03" y1="23.74" x2="54.99" y2="23.74"/><line class="cls-11" x1="44.03" y1="31.49" x2="54.99" y2="31.49"/><line class="cls-11" x1="44.03" y1="39.23" x2="54.99" y2="39.23"/><line class="cls-11" x1="44.03" y1="46.97" x2="54.99" y2="46.97"/></g><text class="cls-5" transform="translate(47.84 21.83)">0</text><text class="cls-5" transform="translate(47.84 29.76)">0</text><text class="cls-5" transform="translate(47.84 45.24)">1</text><text class="cls-5" transform="translate(47.84 37.62)">1</text><text class="cls-5" transform="translate(47.84 53.33)">1</text><path class="cls-6" d="M43.52,15.5V9c0-1.37.13-1.5,1.5-1.5h9c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-7" d="M54,8a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,55,9v6H44V9a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,45,8h9m0-1H45c-1.65,0-2,.35-2,2v7H56V9c0-1.65-.35-2-2-2Z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{opacity:0.7;}.cls-4,.cls-6{fill:none;}.cls-4{stroke:#c18f35;}.cls-4,.cls-5,.cls-6{stroke-linejoin:round;}.cls-5{fill:#34495e;}.cls-5,.cls-6{stroke:#34495e;}.cls-6{stroke-linecap:round;}</style></defs><title>ex_broadcast_motion</title><g id="ex_broadcast_motion"><path class="cls-1" d="M21.56,51.69c-1.34,0-1.49-.13-1.5-1.41V14.15c0-1.28.15-1.41,1.5-1.41h9c1.34,0,1.48.13,1.5,1.41V50.28c0,1.28-.15,1.41-1.5,1.41Z"/><path class="cls-2" d="M21.56,13.24h9a3.09,3.09,0,0,1,.9.08h0a2,2,0,0,1,.1.84V50.27a3,3,0,0,1-.08.81,2.15,2.15,0,0,1-.92.1h-9a3.09,3.09,0,0,1-.9-.08h0a2,2,0,0,1-.1-.84V14.16a3,3,0,0,1,.08-.81,2.15,2.15,0,0,1,.92-.1m0-1c-1.61,0-2,.34-2,1.9h0V50.28h0c0,1.56.38,1.9,2,1.9h9c1.61,0,2-.34,2-1.9h0V14.15h0c0-1.56-.38-1.9-2-1.9Z"/><g class="cls-3"><line class="cls-4" x1="20.57" y1="19.93" x2="31.54" y2="19.93"/><line class="cls-4" x1="20.57" y1="27.67" x2="31.54" y2="27.67"/><line class="cls-4" x1="20.57" y1="35.42" x2="31.54" y2="35.42"/><line class="cls-4" x1="20.57" y1="43.16" x2="31.54" y2="43.16"/></g><polygon class="cls-5" points="43.3 54.68 42.27 51.55 40.01 54.79 43.3 54.68"/><line class="cls-6" x1="41.57" y1="53.35" x2="33.5" y2="47.64"/><polygon class="cls-5" points="43.3 9.32 42.27 12.45 40.01 9.21 43.3 9.32"/><line class="cls-6" x1="41.57" y1="10.65" x2="33.5" y2="16.36"/><polygon class="cls-5" points="45.44 31.63 42.8 29.65 42.8 33.6 45.44 31.63"/><line class="cls-6" x1="43.25" y1="31.53" x2="33.36" y2="31.48"/><polygon class="cls-5" points="45.04 18.95 41.88 18 43.23 21.71 45.04 18.95"/><line class="cls-6" x1="42.95" y1="19.61" x2="33.64" y2="22.95"/><polygon class="cls-5" points="45.04 43.48 41.88 44.44 43.23 40.72 45.04 43.48"/><line class="cls-6" x1="42.95" y1="42.83" x2="33.64" y2="39.49"/></g></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-9{fill:#2980b9;}.cls-1,.cls-2{stroke:#2980b9;}.cls-1,.cls-2,.cls-6,.cls-7{stroke-linejoin:round;}.cls-2{fill:#6c6c6c;stroke-linecap:round;stroke-width:2px;}.cls-3{fill:#caf0b7;}.cls-4{fill:#36c13d;}.cls-5,.cls-6{opacity:0.7;}.cls-6,.cls-7{fill:none;stroke:#36c13d;}.cls-8{fill:#addff3;}.cls-10{font-size:12px;fill:#34495e;font-family:HelveticaNeue-Bold, Helvetica Neue;font-weight:700;letter-spacing:0.1em;}</style></defs><title>ex_cte_scan</title><g id="ex_cte_scan"><polygon class="cls-1" points="9.97 50.75 6.49 46.1 13.45 46.1 9.97 50.75"/><line class="cls-2" x1="9.97" y1="46.74" x2="9.97" y2="15.76"/><path class="cls-3" d="M18,57.44c-1.37,0-1.5-.13-1.5-1.5V15.5h41V55.94c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M57,16V55.94a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H18a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16H57m1-1H16V55.94c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V15Z"/><g class="cls-5"><line class="cls-6" x1="24.7" y1="56.94" x2="24.7" y2="15.94"/><line class="cls-6" x1="41.1" y1="56.94" x2="41.1" y2="15.94"/><line class="cls-6" x1="32.9" y1="56.94" x2="32.9" y2="15.94"/><line class="cls-6" x1="49.3" y1="56.94" x2="49.3" y2="15.94"/><g class="cls-5"><line class="cls-7" x1="17" y1="23.94" x2="56.97" y2="23.94"/><line class="cls-7" x1="17" y1="32.31" x2="56.97" y2="32.31"/><line class="cls-7" x1="17" y1="40.68" x2="56.97" y2="40.68"/><line class="cls-7" x1="17" y1="49.05" x2="56.97" y2="49.05"/></g></g><path class="cls-8" d="M49.31,15.49v-9H56c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-9" d="M56,7a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,57,8v7H49.81V7H56m0-1H48.81V16H58V8c0-1.65-.35-2-2-2Z"/><path class="cls-8" d="M16.51,15.49V8c0-1.37.13-1.5,1.5-1.5H24.7v9Z"/><path class="cls-9" d="M24.2,7v8H17V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,18,7H24.2m1-1H18c-1.65,0-2,.35-2,2v8H25.2V6Z"/><rect class="cls-8" x="41.1" y="6.49" width="8.19" height="9"/><path class="cls-9" d="M48.79,7v8H41.6V7h7.18m1-1H40.61V16h9.19V6Z"/><rect class="cls-8" x="32.91" y="6.49" width="8.19" height="9"/><path class="cls-9" d="M40.6,7v8H33.41V7H40.6m1-1H32.42V16H41.6V6Z"/><rect class="cls-8" x="24.72" y="6.49" width="8.17" height="9"/><path class="cls-9" d="M32.4,7v8H25.22V7H32.4m1-1H24.22V16H33.4V6Z"/><text class="cls-10" transform="translate(23.35 38.4)">CTE</text></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3,.cls-4{opacity:0.7;}.cls-4,.cls-5{fill:none;stroke:#c18f36;stroke-linejoin:round;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}.cls-8{fill:#f64d12;}</style></defs><title>ex_delete</title><g id="ex_delete"><path class="cls-1" d="M18,57.44c-1.37,0-1.5-.13-1.5-1.5V15.5h41V55.94c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M57,16V55.94a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H18a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16H57m1-1H16V55.94c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V15Z"/><g class="cls-3"><line class="cls-4" x1="24.7" y1="56.94" x2="24.7" y2="15.94"/><line class="cls-4" x1="41.1" y1="56.94" x2="41.1" y2="15.94"/><line class="cls-4" x1="32.9" y1="56.94" x2="32.9" y2="15.94"/><line class="cls-4" x1="49.3" y1="56.94" x2="49.3" y2="15.94"/><g class="cls-3"><line class="cls-5" x1="17" y1="23.94" x2="56.97" y2="23.94"/><line class="cls-5" x1="17" y1="32.31" x2="56.97" y2="32.31"/><line class="cls-5" x1="17" y1="40.68" x2="56.97" y2="40.68"/><line class="cls-5" x1="17" y1="49.05" x2="56.97" y2="49.05"/></g></g><path class="cls-6" d="M49.31,15.49v-9H56c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-7" d="M56,7a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,57,8v7H49.81V7H56m0-1H48.81V16H58V8c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M16.51,15.49V8c0-1.37.13-1.5,1.5-1.5H24.7v9Z"/><path class="cls-7" d="M24.2,7v8H17V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,18,7H24.2m1-1H18c-1.65,0-2,.35-2,2v8H25.2V6Z"/><rect class="cls-6" x="41.1" y="6.49" width="8.19" height="9"/><path class="cls-7" d="M48.79,7v8H41.6V7h7.18m1-1H40.61V16h9.19V6Z"/><rect class="cls-6" x="32.91" y="6.49" width="8.19" height="9"/><path class="cls-7" d="M40.6,7v8H33.41V7H40.6m1-1H32.42V16H41.6V6Z"/><rect class="cls-6" x="24.72" y="6.49" width="8.17" height="9"/><path class="cls-7" d="M32.4,7v8H25.22V7H32.4m1-1H24.22V16H33.4V6Z"/><path class="cls-8" d="M17.5,24.94h6.2v6.37H17.5Z"/><path class="cls-8" d="M25.71,41.72h6.2v6.37h-6.2Z"/><path class="cls-8" d="M33.94,41.72h6.2v6.37h-6.2Z"/><path class="cls-2" d="M6,29.22a3.37,3.37,0,0,1,5.71-2.43h0l.13.13.05.05L23.45,38.52a.4.4,0,0,1,.18.2l1.63,5.82v.06h0a.46.46,0,0,1,0,.12.41.41,0,0,1,0,.12s0,0,0,0h0a.4.4,0,0,1-.06.1l0,0,0,0-.1.06h0l-.12,0-.12,0h-.07l-5.82-1.63a.4.4,0,0,1-.2-.18L6.95,31.58a.4.4,0,0,1-.08-.12A3.35,3.35,0,0,1,6,29.22ZM18.9,42.38l1-2h0L10,30.41,8.46,31.93Zm5,.55-.84.84,1.17.33Zm-1-3.48-2.26,1.09L19.6,42.8l2.57.72L23.66,42Zm-.42-.7L12.08,28.31l-1.52,1.52,9.93,9.93h0ZM6.83,29.25a2.55,2.55,0,0,0,.83,1.88h0l.22.22,3.62-3.62-.22-.22h0a2.56,2.56,0,0,0-4.45,1.73Z"/><polygon class="cls-1" points="18.9 42.38 19.9 40.36 19.9 40.35 9.97 30.42 8.45 31.94 18.9 42.38"/><polygon class="cls-1" points="12.07 28.32 10.55 29.84 20.48 39.77 20.49 39.76 22.52 38.76 12.07 28.32"/><path class="cls-1" d="M6.85,29.21a2.55,2.55,0,0,0,.83,1.88h0l.22.22,3.62-3.62-.22-.22h0a2.56,2.56,0,0,0-4.45,1.73Z"/><polygon class="cls-1" points="22.94 39.45 20.69 40.54 19.6 42.8 22.17 43.52 23.66 42.03 22.94 39.45"/></g></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-9{fill:#34495e;}.cls-1,.cls-2{stroke:#34495e;}.cls-1,.cls-2,.cls-6{stroke-linejoin:round;}.cls-2,.cls-6{fill:none;}.cls-2{stroke-linecap:round;stroke-width:2px;}.cls-3{fill:#dae7e7;}.cls-4{fill:#83b8bd;}.cls-5{opacity:0.8;}.cls-6{stroke:#83b8bd;}.cls-7{fill:#addff3;}.cls-8{fill:#2980b9;}.cls-9{font-size:12px;font-family:HelveticaNeue-Bold, Helvetica Neue;font-weight:700;letter-spacing:0.1em;}</style></defs><title>ex_foreign_scan</title><polygon class="cls-1" points="9.97 50.75 6.49 46.1 13.45 46.1 9.97 50.75"/><line class="cls-2" x1="9.97" y1="46.74" x2="9.97" y2="15.76"/><path class="cls-3" d="M18,57.44c-1.37,0-1.5-.13-1.5-1.5V15.5h41V55.94c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M57,16V55.94a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H18a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16H57m1-1H16V55.94c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V15Z"/><g class="cls-5"><line class="cls-6" x1="24.7" y1="56.94" x2="24.7" y2="15.94"/><line class="cls-6" x1="41.1" y1="56.94" x2="41.1" y2="15.94"/><line class="cls-6" x1="32.9" y1="56.94" x2="32.9" y2="15.94"/><line class="cls-6" x1="49.3" y1="56.94" x2="49.3" y2="15.94"/><line class="cls-6" x1="17" y1="23.94" x2="56.97" y2="23.94"/><line class="cls-6" x1="17" y1="32.31" x2="56.97" y2="32.31"/><line class="cls-6" x1="17" y1="40.68" x2="56.97" y2="40.68"/><line class="cls-6" x1="17" y1="49.05" x2="56.97" y2="49.05"/></g><path class="cls-7" d="M49.31,15.49v-9H56c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-8" d="M56,7a3.25,3.25,0,0,1,.9.08h0A2.17,2.17,0,0,1,57,8v7H49.81V7H56m0-1H48.81V16H58V8c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M16.51,15.49V8c0-1.37.13-1.5,1.5-1.5H24.7v9Z"/><path class="cls-8" d="M24.2,7v8H17V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,18,7H24.2m1-1H18c-1.65,0-2,.35-2,2v8H25.2V6Z"/><rect class="cls-7" x="41.1" y="6.49" width="8.19" height="9"/><path class="cls-8" d="M48.79,7v8H41.6V7h7.18m1-1H40.61V16h9.19V6Z"/><rect class="cls-7" x="32.91" y="6.49" width="8.19" height="9"/><path class="cls-8" d="M40.6,7v8H33.41V7H40.6m1-1H32.42V16H41.6V6Z"/><rect class="cls-7" x="24.72" y="6.49" width="8.17" height="9"/><path class="cls-8" d="M32.4,7v8H25.22V7H32.4m1-1H24.22V16H33.4V6Z"/><text class="cls-9" transform="translate(23.35 38.4)">CTE</text></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64.03 64"><defs><style>.cls-1{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3,.cls-6{fill:#f0ecb6;}.cls-4{fill:#c18f36;}.cls-5{opacity:0.8;}.cls-6{stroke:#c18f36;stroke-miterlimit:10;}.cls-7{fill:#addff3;}.cls-8{fill:#2980b9;}.cls-10,.cls-9{fill:#528d19;stroke:#528d19;stroke-linejoin:round;}.cls-10{stroke-linecap:round;stroke-width:2px;}</style></defs><title>gather_merge</title><g id="ex_append"><path class="cls-1" d="M12.82,14.3c-1.37,0-1.5-.12-1.5-1.5v-4c0-1.38.13-1.5,1.5-1.5h4.5v7Z"/><path class="cls-2" d="M16.82,7.82v6h-4a3.54,3.54,0,0,1-.9-.07h0a2.16,2.16,0,0,1-.1-.93v-4a2.7,2.7,0,0,1,.08-.9s.19-.1.92-.1h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5v-8Z"/><path class="cls-1" d="M17.32,14.3v-7H22.1c1.38,0,1.5.12,1.5,1.5v4c0,1.38-.12,1.5-1.5,1.5Z"/><path class="cls-2" d="M22.1,7.82a3.44,3.44,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v4a3.71,3.71,0,0,1-.07.9,2.16,2.16,0,0,1-.93.1H17.82v-6H22.1m0-1H16.82v8H22.1c1.65,0,2-.35,2-2v-4c0-1.65-.35-2-2-2Z"/><path class="cls-1" d="M27.87,14.3c-1.37,0-1.5-.12-1.5-1.5v-4c0-1.38.13-1.5,1.5-1.5h4.5v7Z"/><path class="cls-2" d="M31.87,7.82v6h-4a3.64,3.64,0,0,1-.9-.07h0a2.4,2.4,0,0,1-.1-.93v-4a3.18,3.18,0,0,1,.08-.9,2.08,2.08,0,0,1,.92-.1h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5v-8Z"/><path class="cls-1" d="M32.38,14.3v-7h4.78c1.37,0,1.5.12,1.5,1.5v4c0,1.38-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M37.16,7.82a3.39,3.39,0,0,1,.89.07h0a2.4,2.4,0,0,1,.1.93v4a3.18,3.18,0,0,1-.08.9,2.08,2.08,0,0,1-.92.1H32.88v-6h4.28m0-1H31.88v8h5.28c1.65,0,2-.35,2-2v-4c0-1.65-.35-2-2-2Z"/><path class="cls-1" d="M42.93,14.3c-1.38,0-1.5-.12-1.5-1.5v-4c0-1.38.12-1.5,1.5-1.5h4.5v7Z"/><path class="cls-2" d="M46.93,7.82v6h-4a3.44,3.44,0,0,1-.9-.07h0a2.16,2.16,0,0,1-.1-.93v-4a3.71,3.71,0,0,1,.07-.9,2.16,2.16,0,0,1,.93-.1h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5v-8Z"/><path class="cls-1" d="M47.43,14.3v-7h4.78c1.37,0,1.5.12,1.5,1.5v4c0,1.38-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M52.21,7.82a3.54,3.54,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v4a2.7,2.7,0,0,1-.08.9s-.19.1-.92.1H47.93v-6h4.28m0-1H46.93v8h5.28c1.65,0,2-.35,2-2v-4c0-1.65-.35-2-2-2Z"/><path class="cls-3" d="M21.21,57.44c-1.38,0-1.5-.13-1.5-1.5V44.49h24.6V55.94c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M43.81,45V55.94a4,4,0,0,1-.07.9,2.4,2.4,0,0,1-.93.1H21.21a3.11,3.11,0,0,1-.9-.08h0a2.13,2.13,0,0,1-.1-.92V45h23.6m1-1H19.21V55.94c0,1.65.35,2,2,2h21.6c1.65,0,2-.35,2-2V44Z"/><g class="cls-5"><line class="cls-6" x1="27.91" y1="56.93" x2="27.91" y2="44.93"/><line class="cls-6" x1="36.12" y1="56.93" x2="36.12" y2="44.93"/><line class="cls-6" x1="20.2" y1="50.93" x2="43.79" y2="50.93"/></g><path class="cls-7" d="M36.13,44.49v-6h6.69c1.37,0,1.5.12,1.5,1.5v4.5Z"/><path class="cls-8" d="M42.82,39a3.54,3.54,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v4H36.63V39h6.19m0-1H35.63v7h9.19V40c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M19.71,44.49V40c0-1.38.12-1.5,1.5-1.5H27.9v6Z"/><path class="cls-8" d="M27.4,39v5H20.21V40a3.71,3.71,0,0,1,.07-.9,2.16,2.16,0,0,1,.93-.1H27.4m1-1H21.21c-1.65,0-2,.35-2,2v5H28.4V38Z"/><rect class="cls-7" x="27.92" y="38.49" width="8.19" height="6"/><path class="cls-8" d="M35.61,39v5H28.42V39h7.18m1-1H27.43v7h9.19V38Z"/><polygon class="cls-9" points="27.1 36.38 27.96 32.25 23.38 34.39 27.1 36.38"/><line class="cls-10" x1="25.55" y1="33.06" x2="18.96" y2="18.94"/><polygon class="cls-9" points="32.4 36.2 34.92 32.82 29.86 32.82 32.4 36.2"/><line class="cls-10" x1="32.39" y1="32.54" x2="32.39" y2="18.02"/><polygon class="cls-9" points="38.52 36.38 37.65 32.25 42.24 34.39 38.52 36.38"/><line class="cls-10" x1="40.06" y1="33.06" x2="46.65" y2="18.94"/></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#addff3;}.cls-2{fill:#2980b9;}.cls-3{fill:none;stroke:#d04465;stroke-linecap:round;stroke-linejoin:round;}.cls-4{fill:#d04465;}.cls-5{fill:#f3c7d7;}</style></defs><title>ex_gather_motion</title><g id="ex_delete"><rect class="cls-1" x="47.19" y="45.43" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M55.69,45.93v8h-8v-8h8m0-1h-8a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><rect class="cls-1" x="7.81" y="45.43" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M16.31,45.93v8h-8v-8h8m0-1h-8a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><rect class="cls-1" x="27.51" y="9.57" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M36,10.07v8H28v-8h8m0-1H28a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><line class="cls-3" x1="18.14" y1="44.2" x2="21.92" y2="42.02"/><path class="cls-4" d="M24,40.82a12.09,12.09,0,0,0-2,3.36l-.35-2-1.55-1.3A12.08,12.08,0,0,0,24,40.82Z"/><line class="cls-3" x1="42.06" y1="42.22" x2="45.84" y2="44.4"/><path class="cls-4" d="M40,41a12.09,12.09,0,0,1,2,3.36l.35-2,1.55-1.3A12.08,12.08,0,0,1,40,41Z"/><line class="cls-3" x1="32.09" y1="20.07" x2="32.08" y2="24.43"/><path class="cls-4" d="M32.08,26.85a12.09,12.09,0,0,0-1.9-3.42l1.9.69,1.9-.69A12.08,12.08,0,0,0,32.08,26.85Z"/><circle class="cls-5" cx="32.08" cy="35.93" r="7.5"/><path class="cls-4" d="M32.08,28.93a7,7,0,1,1-7,7,7,7,0,0,1,7-7m0-1a8,8,0,1,0,8,8,8,8,0,0,0-8-8Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-10,.cls-3{fill:#d3d4f3;}.cls-4{fill:#666bd1;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7{opacity:0.7;}.cls-8,.cls-9{fill:none;stroke-linejoin:round;}.cls-11,.cls-8{stroke:#c18f35;}.cls-10,.cls-12,.cls-9{stroke:#666bd1;}.cls-10,.cls-11,.cls-12{stroke-miterlimit:10;}.cls-11{fill:#34495e;}.cls-12{fill:#528d19;}</style></defs><title>ex_group</title><rect class="cls-1" x="19.03" y="16" width="35.98" height="24.96"/><path class="cls-2" d="M54.52,16.5v24h-35v-24h35m1-1h-37v26h37v-26Z"/><path class="cls-3" d="M20.53,56c-1.37,0-1.5-.13-1.5-1.5V41H55V54.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M54.52,41.5v13a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-33a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-13h35m1-1h-37v14c0,1.65.35,2,2,2h33c1.65,0,2-.35,2-2v-14Z"/><path class="cls-5" d="M46.87,16V8h6.63c1.37,0,1.5.13,1.5,1.5V16Z"/><path class="cls-6" d="M53.49,8.5a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v6H47.37v-7h6.13m0-1H46.37v9h9.13v-7c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M19,16V9.5c0-1.37.13-1.5,1.5-1.5h6.59v8Z"/><path class="cls-6" d="M26.59,8.5v7H19.51v-6a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.09m1-1H20.51c-1.65,0-2,.35-2,2v7h9.09v-9Z"/><rect class="cls-5" x="40.31" y="8" width="7.05" height="8"/><path class="cls-6" d="M46.86,8.5v7H40.8v-7h6m1-1h-8v9h8.05v-9Z"/><rect class="cls-5" x="33.74" y="8" width="6.57" height="8"/><path class="cls-6" d="M39.81,8.5v7H34.24v-7h5.56m1-1H33.25v9h7.57v-9Z"/><rect class="cls-5" x="26.62" y="8" width="7.1" height="8"/><path class="cls-6" d="M33.23,8.5v7H27.12v-7h6.1m1-1h-8.1v9h8.11v-9Z"/><g class="cls-7"><line class="cls-8" x1="26.61" y1="40.5" x2="26.61" y2="16.5"/><line class="cls-8" x1="40.29" y1="40.5" x2="40.29" y2="16.5"/><line class="cls-8" x1="33.7" y1="40.5" x2="33.7" y2="16.5"/><line class="cls-8" x1="47.37" y1="40.5" x2="47.37" y2="16.5"/><line class="cls-9" x1="26.61" y1="55.62" x2="26.61" y2="40.5"/><line class="cls-9" x1="40.29" y1="55.62" x2="40.29" y2="40.5"/><line class="cls-9" x1="33.7" y1="55.62" x2="33.7" y2="40.5"/><line class="cls-9" x1="47.37" y1="55.62" x2="47.37" y2="40.5"/><line class="cls-8" x1="19.49" y1="24.35" x2="54.46" y2="24.35"/><line class="cls-10" x1="19.52" y1="48.5" x2="54.49" y2="48.5"/><line class="cls-8" x1="19.49" y1="32.73" x2="54.46" y2="32.73"/></g><path class="cls-11" d="M14.88,38.29l-.53,0a4.34,4.34,0,0,1-.67-.11A5.39,5.39,0,0,1,13,37.9a2.9,2.9,0,0,1-.7-.41,3.31,3.31,0,0,1-.83-.9A3.65,3.65,0,0,1,11,35.52c-.09-.39-.22-5.25-.3-5.66a2.39,2.39,0,0,0-.47-1.06,2.66,2.66,0,0,0-1-.73.69.69,0,0,1,0-1.17,2.65,2.65,0,0,0,1-.73,2.37,2.37,0,0,0,.47-1.06c.08-.41.13-2.91.14-3.38A7,7,0,0,1,11,20.45a3.66,3.66,0,0,1,.43-1.07,3.34,3.34,0,0,1,.83-.9,2.89,2.89,0,0,1,.7-.41,5.12,5.12,0,0,1,.72-.23,4.11,4.11,0,0,1,.67-.11l.53,0v.44a4.47,4.47,0,0,0-2.05.51,2.82,2.82,0,0,0-1.06,1.08,3.58,3.58,0,0,0-.4,1.4c0,.5-.14,3.7-.2,4a2.77,2.77,0,0,1-.26.83,2.41,2.41,0,0,1-.44.6,2.52,2.52,0,0,1-.62.46,3.65,3.65,0,0,1-.64.27,3.52,3.52,0,0,1-.6.13c-.19,0-.19.1,0,.12a3.5,3.5,0,0,1,.6.13,4,4,0,0,1,.64.27,2.53,2.53,0,0,1,.62.46,2.37,2.37,0,0,1,.44.6,2.76,2.76,0,0,1,.26.83,2.56,2.56,0,0,1,.13.93s0,3.6.06,4.1a3.59,3.59,0,0,0,.4,1.4,2.81,2.81,0,0,0,1.06,1.08,4.42,4.42,0,0,0,2.05.51Z"/><path class="cls-12" d="M14.88,55.3l-.53,0a4.34,4.34,0,0,1-.67-.11,5.39,5.39,0,0,1-.72-.23,2.9,2.9,0,0,1-.7-.41,3.31,3.31,0,0,1-.83-.9A3.65,3.65,0,0,1,11,52.53c-.09-.39-.22-1.25-.3-1.66a2.39,2.39,0,0,0-.47-1.06,2.66,2.66,0,0,0-1-.73.69.69,0,0,1,0-1.17,2.65,2.65,0,0,0,1-.73,2.37,2.37,0,0,0,.47-1.06c.08-.41.21-1.28.3-1.66a3.66,3.66,0,0,1,.43-1.07,3.34,3.34,0,0,1,.83-.9,2.89,2.89,0,0,1,.7-.41,5.12,5.12,0,0,1,.72-.23,4.11,4.11,0,0,1,.67-.11l.53,0v.44a4.47,4.47,0,0,0-2.05.51,2.82,2.82,0,0,0-1.06,1.08,3.58,3.58,0,0,0-.4,1.4,7.66,7.66,0,0,1-.2,1,2.77,2.77,0,0,1-.26.83,2.41,2.41,0,0,1-.44.6,2.52,2.52,0,0,1-.62.46,3.65,3.65,0,0,1-.64.27,3.52,3.52,0,0,1-.6.13c-.19,0-.19.1,0,.12a3.5,3.5,0,0,1,.6.13,4,4,0,0,1,.64.27,2.53,2.53,0,0,1,.62.46,2.37,2.37,0,0,1,.44.6,2.76,2.76,0,0,1,.26.83,7.66,7.66,0,0,1,.2,1,3.59,3.59,0,0,0,.4,1.4,2.81,2.81,0,0,0,1.06,1.08,4.42,4.42,0,0,0,2.05.51Z"/></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-10,.cls-11{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3{fill:#addff3;}.cls-4{fill:#2980b9;}.cls-5{opacity:0.7;}.cls-12,.cls-6{fill:none;}.cls-10,.cls-11,.cls-6{stroke:#666bd1;}.cls-12,.cls-14,.cls-15,.cls-6{stroke-linejoin:round;}.cls-7{fill:#f0ecb6;}.cls-8{fill:#c18f35;}.cls-9{fill:#72ceee;stroke:#2980b9;}.cls-15,.cls-9{stroke-linecap:round;}.cls-10,.cls-11,.cls-9{stroke-miterlimit:10;}.cls-11,.cls-12{opacity:0.8;}.cls-12{stroke:#c18f35;}.cls-13{fill:#c00;}.cls-14,.cls-15{fill:#528d19;stroke:#528d19;}.cls-15{stroke-width:2px;}</style></defs><title>ex_hash</title><path class="cls-1" d="M10.38,56.5c-1.37,0-1.5-.13-1.5-1.5V15.5h9V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M17.36,16V55a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-6a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V16h8m1-1h-10V55c0,1.65.35,2,2,2h6c1.65,0,2-.35,2-2V15Z"/><path class="cls-3" d="M8.88,15.5V9c0-1.37.13-1.5,1.5-1.5h6c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-4" d="M16.36,8a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v6h-8V9a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6m0-1h-6c-1.65,0-2,.35-2,2v7h10V9c0-1.65-.35-2-2-2Z"/><g class="cls-5"><line class="cls-6" x1="9.39" y1="23.74" x2="17.35" y2="23.74"/><line class="cls-6" x1="9.39" y1="31.49" x2="17.35" y2="31.49"/><line class="cls-6" x1="9.39" y1="39.23" x2="17.35" y2="39.23"/><line class="cls-6" x1="9.39" y1="46.97" x2="17.35" y2="46.97"/></g><path class="cls-1" d="M47.4,46.22v-28h6.22c1.37,0,1.5.13,1.5,1.5v25c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M53.62,18.72a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v25a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.9v-27h5.72m0-1H46.9v29h6.72c1.65,0,2-.35,2-2v-25c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M26.64,46.22c-1.37,0-1.5-.13-1.5-1.5V24.22H47.42v22Z"/><path class="cls-8" d="M46.92,24.72v21H26.64a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-20H46.92m1-1H24.64v21c0,1.65.35,2,2,2H47.92v-23Z"/><path class="cls-3" d="M25.14,24.22v-4.5c0-1.37.13-1.5,1.5-1.5H47.42v6Z"/><path class="cls-4" d="M46.92,18.72v5H25.64v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H46.92m1-1H26.64c-1.65,0-2,.35-2,2v5H47.92v-7Z"/><line class="cls-9" x1="32.6" y1="24.05" x2="32.6" y2="18.24"/><line class="cls-10" x1="55" y1="24.22" x2="47.92" y2="24.22"/><line class="cls-11" x1="55" y1="31.49" x2="47.92" y2="31.49"/><line class="cls-11" x1="55" y1="38.96" x2="47.92" y2="38.96"/><line class="cls-9" x1="40.35" y1="24.05" x2="40.35" y2="18.24"/><line class="cls-12" x1="32.6" y1="46.05" x2="32.6" y2="24.72"/><line class="cls-12" x1="40.35" y1="46.05" x2="40.35" y2="24.72"/><line class="cls-12" x1="25.17" y1="31.57" x2="47.42" y2="31.57"/><line class="cls-12" x1="25.17" y1="38.96" x2="47.42" y2="38.96"/><path class="cls-13" d="M10.27,32.86h6.38V38H10.27Z"/><path class="cls-13" d="M33.81,32.71h5.4v5.23h-5.4Z"/><polygon class="cls-14" points="33.43 35.53 30.05 33 30.05 38.06 33.43 35.53"/><line class="cls-15" x1="29.77" y1="35.53" x2="19.33" y2="35.53"/><polygon class="cls-14" points="36.84 7.67 34.31 11.05 39.37 11.05 36.84 7.67"/><line class="cls-15" x1="36.84" y1="11.33" x2="36.84" y2="30.77"/></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-10{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3{fill:#addff3;}.cls-4{fill:#2980b9;}.cls-5{opacity:0.7;}.cls-11,.cls-16,.cls-6{fill:none;}.cls-10,.cls-6{stroke:#666bd1;}.cls-11,.cls-13,.cls-14,.cls-6{stroke-linejoin:round;}.cls-7{fill:#f0ecb6;}.cls-8{fill:#c18f35;}.cls-9{fill:#72ceee;stroke:#2980b9;}.cls-14,.cls-9{stroke-linecap:round;}.cls-10,.cls-16,.cls-9{stroke-miterlimit:10;}.cls-11{stroke:#c18f35;}.cls-12{fill:#c00;}.cls-13,.cls-14{fill:#528d19;stroke:#528d19;}.cls-14{stroke-width:2px;}.cls-15{fill:#def4fd;}.cls-16{stroke:#c00;stroke-width:1.5px;}</style></defs><title>ex_hash_anti_join</title><rect class="cls-1" x="8.66" y="7.5" width="8.98" height="49" rx="1.5" ry="1.5"/><path class="cls-2" d="M16.14,8a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92V55a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-6a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V9a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6m0-1h-6c-1.65,0-2,.35-2,2V55c0,1.65.35,2,2,2h6c1.65,0,2-.35,2-2V9c0-1.65-.35-2-2-2Z"/><path class="cls-3" d="M8.66,15.5V9c0-1.37.13-1.5,1.5-1.5h6c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-4" d="M16.14,8a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v6h-8V9a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6m0-1h-6c-1.65,0-2,.35-2,2v7h10V9c0-1.65-.35-2-2-2Z"/><g class="cls-5"><line class="cls-6" x1="9.17" y1="23.74" x2="17.13" y2="23.74"/><line class="cls-6" x1="9.17" y1="31.49" x2="17.13" y2="31.49"/><line class="cls-6" x1="9.17" y1="39.23" x2="17.13" y2="39.23"/><line class="cls-6" x1="9.17" y1="46.97" x2="17.13" y2="46.97"/></g><path class="cls-1" d="M47.18,46.22v-28H53.4c1.37,0,1.5.13,1.5,1.5v25c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M53.4,18.72a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v25a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.68v-27H53.4m0-1H46.68v29H53.4c1.65,0,2-.35,2-2v-25c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M26.42,46.22c-1.37,0-1.5-.13-1.5-1.5V24.22H47.2v22Z"/><path class="cls-8" d="M46.7,24.72v21H26.42a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-20H46.7m1-1H24.42v21c0,1.65.35,2,2,2H47.7v-23Z"/><path class="cls-3" d="M24.92,24.22v-4.5c0-1.37.13-1.5,1.5-1.5H47.2v6Z"/><path class="cls-4" d="M46.7,18.72v5H25.42v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H46.7m1-1H26.42c-1.65,0-2,.35-2,2v5H47.7v-7Z"/><line class="cls-9" x1="32.38" y1="24.05" x2="32.38" y2="18.24"/><line class="cls-10" x1="54.78" y1="24.22" x2="47.7" y2="24.22"/><line class="cls-9" x1="40.13" y1="24.05" x2="40.13" y2="18.24"/><line class="cls-11" x1="32.38" y1="46.05" x2="32.38" y2="24.72"/><line class="cls-11" x1="40.13" y1="46.05" x2="40.13" y2="24.72"/><line class="cls-11" x1="24.95" y1="31.57" x2="47.2" y2="31.57"/><line class="cls-11" x1="24.95" y1="38.96" x2="47.2" y2="38.96"/><path class="cls-12" d="M10.05,32.86h6.37V38H10.05Z"/><path class="cls-12" d="M33.59,32.71H39v5.23h-5.4Z"/><polygon class="cls-13" points="33.21 35.53 29.83 33 29.83 38.06 33.21 35.53"/><line class="cls-14" x1="29.55" y1="35.53" x2="19.11" y2="35.53"/><polygon class="cls-13" points="36.62 7.67 34.09 11.05 39.15 11.05 36.62 7.67"/><line class="cls-14" x1="36.62" y1="11.33" x2="36.62" y2="30.77"/><circle class="cls-15" cx="50.8" cy="34.37" r="4.29"/><path class="cls-12" d="M50.8,30.83a3.54,3.54,0,1,1-3.54,3.54,3.55,3.55,0,0,1,3.54-3.54m0-1.5a5,5,0,1,0,5,5,5,5,0,0,0-5-5Z"/><line class="cls-16" x1="47.52" y1="36.64" x2="54.03" y2="31.91"/></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-10,.cls-11{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3{fill:#addff3;}.cls-4{fill:#2980b9;}.cls-5{opacity:0.7;}.cls-12,.cls-6{fill:none;}.cls-10,.cls-11,.cls-6{stroke:#666bd1;}.cls-12,.cls-14,.cls-15,.cls-6{stroke-linejoin:round;}.cls-7{fill:#f0ecb6;}.cls-8{fill:#c18f35;}.cls-9{fill:#72ceee;stroke:#2980b9;}.cls-15,.cls-9{stroke-linecap:round;}.cls-10,.cls-11,.cls-9{stroke-miterlimit:10;}.cls-11{opacity:0.8;}.cls-12{stroke:#c18f35;}.cls-13{fill:#c00;}.cls-14,.cls-15{fill:#528d19;stroke:#528d19;}.cls-15{stroke-width:2px;}</style></defs><title>ex_hash_semi_join</title><path class="cls-1" d="M10.16,56.5c-1.37,0-1.5-.13-1.5-1.5V15.5h9V55c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M17.14,16V55a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-6a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16h8m1-1h-10V55c0,1.65.35,2,2,2h6c1.65,0,2-.35,2-2V15Z"/><path class="cls-3" d="M8.66,15.5V9c0-1.37.13-1.5,1.5-1.5h6c1.37,0,1.5.13,1.5,1.5v6.5Z"/><path class="cls-4" d="M16.14,8a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v6h-8V9a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6m0-1h-6c-1.65,0-2,.35-2,2v7h10V9c0-1.65-.35-2-2-2Z"/><g class="cls-5"><line class="cls-6" x1="9.17" y1="23.74" x2="17.13" y2="23.74"/><line class="cls-6" x1="9.17" y1="31.49" x2="17.13" y2="31.49"/><line class="cls-6" x1="9.17" y1="39.23" x2="17.13" y2="39.23"/><line class="cls-6" x1="9.17" y1="46.97" x2="17.13" y2="46.97"/></g><path class="cls-1" d="M47.18,46.22v-28H53.4c1.37,0,1.5.13,1.5,1.5v25c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M53.4,18.72a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v25a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.68v-27H53.4m0-1H46.68v29H53.4c1.65,0,2-.35,2-2v-25c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M26.42,46.22c-1.37,0-1.5-.13-1.5-1.5V24.22H47.2v22Z"/><path class="cls-8" d="M46.7,24.72v21H26.42a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-20H46.7m1-1H24.42v21c0,1.65.35,2,2,2H47.7v-23Z"/><path class="cls-3" d="M24.92,24.22v-4.5c0-1.37.13-1.5,1.5-1.5H47.2v6Z"/><path class="cls-4" d="M46.7,18.72v5H25.42v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H46.7m1-1H26.42c-1.65,0-2,.35-2,2v5H47.7v-7Z"/><line class="cls-9" x1="32.38" y1="24.05" x2="32.38" y2="18.24"/><line class="cls-10" x1="54.78" y1="24.22" x2="47.7" y2="24.22"/><line class="cls-11" x1="54.78" y1="31.49" x2="47.7" y2="31.49"/><line class="cls-11" x1="54.78" y1="38.96" x2="47.7" y2="38.96"/><line class="cls-9" x1="40.13" y1="24.05" x2="40.13" y2="18.24"/><line class="cls-12" x1="32.38" y1="46.05" x2="32.38" y2="24.72"/><line class="cls-12" x1="40.13" y1="46.05" x2="40.13" y2="24.72"/><line class="cls-12" x1="24.95" y1="31.57" x2="47.2" y2="31.57"/><line class="cls-12" x1="24.95" y1="38.96" x2="47.2" y2="38.96"/><path class="cls-13" d="M10.05,32.86h6.37V38H10.05Z"/><path class="cls-13" d="M33.59,32.71H39v5.23h-5.4Z"/><polygon class="cls-14" points="33.21 35.53 29.83 33 29.83 38.06 33.21 35.53"/><line class="cls-15" x1="29.55" y1="35.53" x2="19.11" y2="35.53"/><polygon class="cls-14" points="36.62 7.67 34.09 11.05 39.15 11.05 36.62 7.67"/><line class="cls-15" x1="36.62" y1="11.33" x2="36.62" y2="30.77"/></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-3{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-10,.cls-3{stroke:#c18f35;}.cls-3,.cls-9{stroke-miterlimit:10;}.cls-10,.cls-3,.cls-8{opacity:0.8;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{fill:#d3d4f3;}.cls-7{fill:#666bd1;}.cls-10,.cls-8{fill:none;stroke-linejoin:round;}.cls-8{stroke:#666bd1;}.cls-9{fill:#34495e;stroke:#528d19;}.cls-11{fill:#88f625;}</style></defs><title>ex_hash_setop_except</title><path class="cls-1" d="M13.16,58.21c-1.37,0-1.5-.13-1.5-1.5V39.52h7V56.71c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M18.15,40V56.71a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V40h6m1-1h-8V56.71c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39Z"/><line class="cls-3" x1="12.05" y1="45.87" x2="18.29" y2="45.87"/><line class="cls-3" x1="12.05" y1="51.79" x2="18.29" y2="51.79"/><path class="cls-4" d="M11.66,11.67V7.17c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,6.17a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M13.16,30.36c-1.37,0-1.5-.13-1.5-1.5V11.67h7V28.86c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M18.15,12.17V28.86a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V12.17h6m1-1h-8V28.86c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V11.17Z"/><line class="cls-8" x1="12.05" y1="18.02" x2="18.29" y2="18.02"/><line class="cls-8" x1="12.05" y1="23.94" x2="18.29" y2="23.94"/><path class="cls-4" d="M11.66,39.52V35c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,34a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6V35a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8V35c0-1.65-.35-2-2-2Z"/><path class="cls-9" d="M22.25,41.12a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46V37c0-.68,0-1.25,0-1.72A9.28,9.28,0,0,1,26,34.1a2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,24.3,22.9a4.47,4.47,0,0,0-2.05-.51V22l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07A7,7,0,0,1,26.28,26c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-1" d="M35.18,37.79c-1.37,0-1.5-.13-1.5-1.5V24.79H41v13Z"/><path class="cls-2" d="M40.46,25.29v12H35.18a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-11h6.28m1-1H33.18v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-6" d="M40.95,37.79v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M47.73,25.29v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H41.45v-12h6.28m1-1H40.45v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-4" d="M33.68,24.79v-4.5c0-1.37.13-1.5,1.5-1.5H41v6Z"/><path class="cls-5" d="M40.46,19.29v5H34.18v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H35.18c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-4" d="M40.95,24.79v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M46.73,19.29a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H41.45v-5h5.28m0-1H40.45v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="40.71" y1="31.14" x2="48.2" y2="31.14"/><line class="cls-10" x1="33.71" y1="31.14" x2="40.45" y2="31.14"/><path class="cls-11" d="M36,50.42a8.4,8.4,0,0,1,5-7.66,8.4,8.4,0,1,0,0,15.33A8.4,8.4,0,0,1,36,50.42Z"/><path class="cls-2" d="M37.56,43.4a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><path class="cls-7" d="M44.43,43.4a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-3{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-10,.cls-3{stroke:#c18f35;}.cls-3,.cls-9{stroke-miterlimit:10;}.cls-10,.cls-3,.cls-8{opacity:0.8;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{fill:#d3d4f3;}.cls-7{fill:#666bd1;}.cls-10,.cls-8{fill:none;stroke-linejoin:round;}.cls-8{stroke:#666bd1;}.cls-12,.cls-9{fill:#34495e;}.cls-9{stroke:#528d19;}.cls-11{fill:#88f625;}.cls-12{font-size:9px;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>ex_hash_setop_except_all</title><path class="cls-1" d="M13.16,58.21c-1.37,0-1.5-.13-1.5-1.5V39.52h7V56.71c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M18.15,40V56.71a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V40h6m1-1h-8V56.71c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39Z"/><line class="cls-3" x1="12.05" y1="45.87" x2="18.29" y2="45.87"/><line class="cls-3" x1="12.05" y1="51.79" x2="18.29" y2="51.79"/><path class="cls-4" d="M11.66,11.67V7.17c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,6.17a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M13.16,30.36c-1.37,0-1.5-.13-1.5-1.5V11.67h7V28.86c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M18.15,12.17V28.86a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V12.17h6m1-1h-8V28.86c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V11.17Z"/><line class="cls-8" x1="12.05" y1="18.02" x2="18.29" y2="18.02"/><line class="cls-8" x1="12.05" y1="23.94" x2="18.29" y2="23.94"/><path class="cls-4" d="M11.66,39.52V35c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,34a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6V35a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8V35c0-1.65-.35-2-2-2Z"/><path class="cls-9" d="M22.25,41.12a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46V37c0-.68,0-1.25,0-1.72A9.28,9.28,0,0,1,26,34.1a2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,24.3,22.9a4.47,4.47,0,0,0-2.05-.51V22l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07A7,7,0,0,1,26.28,26c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-1" d="M35.18,37.79c-1.37,0-1.5-.13-1.5-1.5V24.79H41v13Z"/><path class="cls-2" d="M40.46,25.29v12H35.18a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-11h6.28m1-1H33.18v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-6" d="M40.95,37.79v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M47.73,25.29v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H41.45v-12h6.28m1-1H40.45v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-4" d="M33.68,24.79v-4.5c0-1.37.13-1.5,1.5-1.5H41v6Z"/><path class="cls-5" d="M40.46,19.29v5H34.18v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H35.18c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-4" d="M40.95,24.79v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M46.73,19.29a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4H41.45v-5h5.28m0-1H40.45v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="40.71" y1="31.14" x2="48.2" y2="31.14"/><line class="cls-10" x1="33.71" y1="31.14" x2="40.45" y2="31.14"/><path class="cls-11" d="M36,50.42a8.4,8.4,0,0,1,5-7.66,8.4,8.4,0,1,0,0,15.33A8.4,8.4,0,0,1,36,50.42Z"/><path class="cls-2" d="M37.56,43.4a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><path class="cls-7" d="M44.43,43.4a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><text class="cls-12" transform="translate(20.35 18.02)">All</text></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#88f625;}.cls-2,.cls-4{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-11,.cls-4{stroke:#c18f35;}.cls-10,.cls-4{stroke-miterlimit:10;}.cls-11,.cls-4,.cls-9{opacity:0.8;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7{fill:#d3d4f3;}.cls-8{fill:#666bd1;}.cls-11,.cls-9{fill:none;stroke-linejoin:round;}.cls-9{stroke:#666bd1;}.cls-10{fill:#34495e;stroke:#528d19;}</style></defs><title>ex_hash_setop_intersect</title><path class="cls-1" d="M41,42.7A8.4,8.4,0,0,0,41,58,8.4,8.4,0,0,0,41,42.7Z"/><path class="cls-2" d="M13.16,58.27c-1.37,0-1.5-.13-1.5-1.5V39.58h7V56.77c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M18.15,40.08V56.77a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V40.08h6m1-1h-8V56.77c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39.08Z"/><line class="cls-4" x1="12.05" y1="45.93" x2="18.29" y2="45.93"/><line class="cls-4" x1="12.05" y1="51.85" x2="18.29" y2="51.85"/><path class="cls-5" d="M11.66,11.73V7.23c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M17.15,6.23a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M13.16,30.42c-1.37,0-1.5-.13-1.5-1.5V11.73h7V28.92c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-8" d="M18.15,12.23V28.92a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V12.23h6m1-1h-8V28.92c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V11.23Z"/><line class="cls-9" x1="12.05" y1="18.08" x2="18.29" y2="18.08"/><line class="cls-9" x1="12.05" y1="24" x2="18.29" y2="24"/><path class="cls-5" d="M11.66,39.58v-4.5c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M17.15,34.08a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-10" d="M22.25,41.18a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46v.35c0-.68,0-1.25,0-1.72a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,24.3,23a4.47,4.47,0,0,0-2.05-.51V22l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07,7,7,0,0,1,.16,1.29c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-2" d="M35.18,37.85c-1.37,0-1.5-.13-1.5-1.5V24.85H41v13Z"/><path class="cls-3" d="M40.46,25.35v12H35.18a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-11h6.28m1-1H33.18v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-7" d="M40.95,37.85v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-8" d="M47.73,25.35v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H41.45v-12h6.28m1-1H40.45v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-5" d="M33.68,24.85v-4.5c0-1.37.13-1.5,1.5-1.5H41v6Z"/><path class="cls-6" d="M40.46,19.35v5H34.18v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H35.18c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-5" d="M40.95,24.85v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M46.73,19.35a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H41.45v-5h5.28m0-1H40.45v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-9" x1="40.71" y1="31.2" x2="48.2" y2="31.2"/><line class="cls-11" x1="33.71" y1="31.2" x2="40.45" y2="31.2"/><path class="cls-3" d="M37.56,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><path class="cls-8" d="M44.43,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#88f625;}.cls-2,.cls-4{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-11,.cls-4{stroke:#c18f35;}.cls-10,.cls-4{stroke-miterlimit:10;}.cls-11,.cls-4,.cls-9{opacity:0.8;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7{fill:#d3d4f3;}.cls-8{fill:#666bd1;}.cls-11,.cls-9{fill:none;stroke-linejoin:round;}.cls-9{stroke:#666bd1;}.cls-10,.cls-12{fill:#34495e;}.cls-10{stroke:#528d19;}.cls-12{font-size:9px;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>ex_hash_setop_intersect_all</title><path class="cls-1" d="M41,42.7A8.4,8.4,0,0,0,41,58,8.4,8.4,0,0,0,41,42.7Z"/><path class="cls-2" d="M13.16,58.27c-1.37,0-1.5-.13-1.5-1.5V39.58h7V56.77c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M18.15,40.08V56.77a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V40.08h6m1-1h-8V56.77c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39.08Z"/><line class="cls-4" x1="12.05" y1="45.93" x2="18.29" y2="45.93"/><line class="cls-4" x1="12.05" y1="51.85" x2="18.29" y2="51.85"/><path class="cls-5" d="M11.66,11.73V7.23c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M17.15,6.23a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M13.16,30.42c-1.37,0-1.5-.13-1.5-1.5V11.73h7V28.92c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-8" d="M18.15,12.23V28.92a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V12.23h6m1-1h-8V28.92c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V11.23Z"/><line class="cls-9" x1="12.05" y1="18.08" x2="18.29" y2="18.08"/><line class="cls-9" x1="12.05" y1="24" x2="18.29" y2="24"/><path class="cls-5" d="M11.66,39.58v-4.5c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M17.15,34.08a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-10" d="M22.25,41.18a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46v.35c0-.68,0-1.25,0-1.72a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,24.3,23a4.47,4.47,0,0,0-2.05-.51V22l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07,7,7,0,0,1,.16,1.29c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-2" d="M35.18,37.85c-1.37,0-1.5-.13-1.5-1.5V24.85H41v13Z"/><path class="cls-3" d="M40.46,25.35v12H35.18a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-11h6.28m1-1H33.18v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-7" d="M40.95,37.85v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-8" d="M47.73,25.35v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H41.45v-12h6.28m1-1H40.45v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-5" d="M33.68,24.85v-4.5c0-1.37.13-1.5,1.5-1.5H41v6Z"/><path class="cls-6" d="M40.46,19.35v5H34.18v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H35.18c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-5" d="M40.95,24.85v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-6" d="M46.73,19.35a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4H41.45v-5h5.28m0-1H40.45v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-9" x1="40.71" y1="31.2" x2="48.2" y2="31.2"/><line class="cls-11" x1="33.71" y1="31.2" x2="40.45" y2="31.2"/><path class="cls-3" d="M37.56,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><path class="cls-8" d="M44.43,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><text class="cls-12" transform="translate(20.98 18.36)">All</text></svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-3{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-10,.cls-3{stroke:#c18f35;}.cls-3,.cls-9{stroke-miterlimit:10;}.cls-10,.cls-3,.cls-8{opacity:0.8;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{fill:#d3d4f3;}.cls-7{fill:#666bd1;}.cls-10,.cls-8{fill:none;stroke-linejoin:round;}.cls-8{stroke:#666bd1;}.cls-9{fill:#34495e;stroke:#528d19;}.cls-11{font-size:9px;fill:#c00;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>ex_hash_setop_unknown</title><path class="cls-1" d="M13.16,58.27c-1.37,0-1.5-.13-1.5-1.5V39.58h7V56.77c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M18.15,40.08V56.77a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V40.08h6m1-1h-8V56.77c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39.08Z"/><line class="cls-3" x1="12.05" y1="45.93" x2="18.29" y2="45.93"/><line class="cls-3" x1="12.05" y1="51.85" x2="18.29" y2="51.85"/><path class="cls-4" d="M11.66,11.73V7.23c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,6.23a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M13.16,30.42c-1.37,0-1.5-.13-1.5-1.5V11.73h7V28.92c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M18.15,12.23V28.92a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V12.23h6m1-1h-8V28.92c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V11.23Z"/><line class="cls-8" x1="12.05" y1="18.08" x2="18.29" y2="18.08"/><line class="cls-8" x1="12.05" y1="24" x2="18.29" y2="24"/><path class="cls-4" d="M11.66,39.58v-4.5c0-1.37.13-1.5,1.5-1.5h4c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M17.15,34.08a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4h-6v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1h-4c-1.65,0-2,.35-2,2v5h8v-5c0-1.65-.35-2-2-2Z"/><path class="cls-9" d="M22.25,41.18a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46v.35c0-.68,0-1.25,0-1.72a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,24.3,23a4.47,4.47,0,0,0-2.05-.51V22l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07,7,7,0,0,1,.16,1.29c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-1" d="M35.18,37.85c-1.37,0-1.5-.13-1.5-1.5V24.85H41v13Z"/><path class="cls-2" d="M40.46,25.35v12H35.18a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-11h6.28m1-1H33.18v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-6" d="M40.95,37.85v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-7" d="M47.73,25.35v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H41.45v-12h6.28m1-1H40.45v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-4" d="M33.68,24.85v-4.5c0-1.37.13-1.5,1.5-1.5H41v6Z"/><path class="cls-5" d="M40.46,19.35v5H34.18v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H35.18c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-4" d="M40.95,24.85v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M46.73,19.35a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H41.45v-5h5.28m0-1H40.45v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="40.71" y1="31.2" x2="48.2" y2="31.2"/><line class="cls-10" x1="33.71" y1="31.2" x2="40.45" y2="31.2"/><path class="cls-2" d="M37.56,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><path class="cls-7" d="M44.43,43.46a6.9,6.9,0,1,1-6.9,6.9,6.91,6.91,0,0,1,6.9-6.9m0-1.5a8.4,8.4,0,1,0,8.4,8.4,8.4,8.4,0,0,0-8.4-8.4Z"/><text class="cls-11" transform="translate(38.29 53.85)">?</text></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:none;stroke:#747474;stroke-width:0.75px;}.cls-1,.cls-7{stroke-linecap:round;}.cls-1,.cls-6,.cls-7{stroke-linejoin:round;}.cls-2{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-4{fill:#addff3;}.cls-5,.cls-6,.cls-7{fill:#2980b9;}.cls-6,.cls-7{stroke:#2980b9;}.cls-7{stroke-width:2px;}</style></defs><title>ex_index_only_scan</title><line class="cls-1" x1="36.89" y1="24.41" x2="24.9" y2="31.3"/><line class="cls-1" x1="36.89" y1="24.41" x2="48.87" y2="31.3"/><line class="cls-1" x1="24.9" y1="37.22" x2="18.92" y2="43.22"/><line class="cls-1" x1="24.9" y1="37.22" x2="30.89" y2="43.22"/><line class="cls-1" x1="48.87" y1="37.22" x2="42.55" y2="43.22"/><line class="cls-1" x1="48.87" y1="37.22" x2="54.85" y2="43.22"/><path class="cls-2" d="M33.39,23.91c-1.37,0-1.5-.13-1.5-1.5V18.22h10v4.19c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M41.38,18.72v3.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-7a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V18.72h9m1-1h-11v4.69c0,1.65.35,2,2,2h7c1.65,0,2-.35,2-2V17.72Z"/><rect class="cls-2" x="20.91" y="31.03" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M27.39,31.53a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V32.53a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V32.53c0-1.65-.35-2-2-2Z"/><rect class="cls-2" x="14.92" y="43.72" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M21.41,44.22a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V45.22a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V45.22c0-1.65-.35-2-2-2Z"/><rect class="cls-2" x="26.89" y="43.72" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M33.38,44.22a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V45.22a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V45.22c0-1.65-.35-2-2-2Z"/><rect class="cls-2" x="38.89" y="43.72" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M45.38,44.22a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V45.22a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V45.22c0-1.65-.35-2-2-2Z"/><rect class="cls-2" x="50.86" y="43.72" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M57.35,44.22a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V45.22a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V45.22c0-1.65-.35-2-2-2Z"/><rect class="cls-2" x="44.88" y="30.97" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M51.36,31.47a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-5a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V32.47a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V32.47c0-1.65-.35-2-2-2Z"/><path class="cls-4" d="M31.89,18.28V16.09c0-1.37.13-1.5,1.5-1.5h7c1.37,0,1.5.13,1.5,1.5v2.19Z"/><path class="cls-5" d="M40.38,15.09a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v1.69h-9V16.09a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h7m0-1h-7c-1.65,0-2,.35-2,2v2.69h11V16.09c0-1.65-.35-2-2-2Z"/><polygon class="cls-6" points="8.13 49.45 4.65 44.8 11.61 44.8 8.13 49.45"/><line class="cls-7" x1="8.13" y1="45.43" x2="8.13" y2="18.46"/></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:none;stroke:#747474;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75px;}.cls-2,.cls-8{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{fill:#c18f36;}.cls-7{opacity:0.8;}.cls-8{stroke:#c18f36;stroke-miterlimit:10;}</style></defs><title>ex_index_scan</title><line class="cls-1" x1="13.85" y1="36.23" x2="19.12" y2="44.7"/><line class="cls-1" x1="13.85" y1="36.23" x2="19.09" y2="27.92"/><line class="cls-1" x1="27.64" y1="44.33" x2="35.64" y2="50.23"/><line class="cls-1" x1="27.64" y1="44.33" x2="35.64" y2="38.92"/><rect class="cls-2" x="19.26" y="41.65" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M25.75,42.15a3.54,3.54,0,0,1,.9.07h0a2.4,2.4,0,0,1,.1.93v2.69a3.18,3.18,0,0,1-.08.9s-.19.1-.92.1h-5a3.11,3.11,0,0,1-.9-.08h0a2.25,2.25,0,0,1-.1-.92V43.15a3.18,3.18,0,0,1,.08-.9s.19-.1.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V43.15c0-1.65-.35-2-2-2Z"/><line class="cls-1" x1="27.64" y1="27.83" x2="35.64" y2="33.73"/><line class="cls-1" x1="27.64" y1="27.83" x2="35.64" y2="22.42"/><rect class="cls-2" x="19.26" y="25.15" width="7.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-3" d="M25.75,25.65a3.54,3.54,0,0,1,.9.07h0a2.4,2.4,0,0,1,.1.93v2.69a3.18,3.18,0,0,1-.08.9s-.19.1-.92.1h-5a3.11,3.11,0,0,1-.9-.08h0a2.25,2.25,0,0,1-.1-.92V26.65a3.18,3.18,0,0,1,.08-.9s.19-.1.92-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V26.65c0-1.65-.35-2-2-2Z"/><path class="cls-2" d="M6.61,40.89c-1.38,0-1.5-.13-1.5-1.5V35.2h8v4.19c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M12.59,35.7v3.69a2.7,2.7,0,0,1-.08.9s-.19.1-.92.1h-5a3,3,0,0,1-.9-.08h0a2.45,2.45,0,0,1-.09-.92V35.7h7m1-1h-9v4.69c0,1.65.35,2,2,2h5c1.65,0,2-.35,2-2V34.7Z"/><path class="cls-4" d="M5.11,35.26V33.07c0-1.38.12-1.5,1.5-1.5h5c1.37,0,1.5.12,1.5,1.5v2.19Z"/><path class="cls-5" d="M11.59,32.07a3.54,3.54,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v1.69h-7V33.07a3.71,3.71,0,0,1,.07-.9,2.16,2.16,0,0,1,.93-.1h5m0-1h-5c-1.65,0-2,.35-2,2v2.69h9V33.07c0-1.65-.35-2-2-2Z"/><path class="cls-2" d="M35.74,53.47c-1.38,0-1.5-.12-1.5-1.5V19.53H58.89V52c0,1.38-.13,1.5-1.5,1.5Z"/><path class="cls-6" d="M58.39,20V52a2.7,2.7,0,0,1-.08.9s-.19.1-.92.1H35.74a3.54,3.54,0,0,1-.9-.07h0a2.16,2.16,0,0,1-.1-.93V20H58.39m1-1H33.74V52c0,1.65.35,2,2,2H57.39c1.65,0,2-.35,2-2V19Z"/><g class="cls-7"><line class="cls-8" x1="42.44" y1="52.97" x2="42.44" y2="19.97"/><line class="cls-8" x1="50.63" y1="52.97" x2="50.63" y2="19.97"/><line class="cls-8" x1="34.73" y1="27.97" x2="58.37" y2="27.97"/><line class="cls-8" x1="34.73" y1="36.34" x2="58.37" y2="36.34"/><line class="cls-8" x1="34.73" y1="44.71" x2="58.37" y2="44.71"/></g><path class="cls-4" d="M50.7,19.53v-9h6.69c1.38,0,1.5.12,1.5,1.5v7.5Z"/><path class="cls-5" d="M57.39,11a3.44,3.44,0,0,1,.9.07h0a2.62,2.62,0,0,1,.09.93v7H51.2V11h6.19m0-1H50.2V20h9.19V12c0-1.65-.35-2-2-2Z"/><path class="cls-4" d="M34.23,19.53V12c0-1.38.13-1.5,1.5-1.5h6.7v9Z"/><path class="cls-5" d="M41.93,11v8h-7.2V12a3.18,3.18,0,0,1,.08-.9,2.08,2.08,0,0,1,.92-.1h6.2m1-1h-7.2c-1.65,0-2,.35-2,2v8h9.2V10Z"/><rect class="cls-4" x="42.45" y="10.53" width="8.17" height="9"/><path class="cls-5" d="M50.12,11v8H43V11h7.17m1-1H42V20h9.17V10Z"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-5{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{fill:#88f625;}.cls-4{opacity:0.8;}.cls-5{stroke:#c18f36;stroke-miterlimit:10;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}</style></defs><title>ex_insert</title><path class="cls-1" d="M16.73,57.47c-1.37,0-1.5-.13-1.5-1.5V15.53h41V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M55.72,16V56a3.29,3.29,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-38a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16h40m1-1h-42V56c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V15Z"/><rect class="cls-3" x="48.52" y="49.53" width="7.22" height="7.44"/><rect class="cls-3" x="40.32" y="49.53" width="7.22" height="7.44"/><rect class="cls-3" x="32.12" y="49.53" width="7.22" height="7.44"/><g class="cls-4"><line class="cls-5" x1="23.43" y1="56.97" x2="23.43" y2="15.97"/><line class="cls-5" x1="39.83" y1="56.97" x2="39.83" y2="15.97"/><line class="cls-5" x1="31.63" y1="56.97" x2="31.63" y2="15.97"/><line class="cls-5" x1="48.03" y1="56.97" x2="48.03" y2="15.97"/><line class="cls-5" x1="15.73" y1="23.97" x2="55.7" y2="23.97"/><line class="cls-5" x1="15.73" y1="32.34" x2="55.7" y2="32.34"/><line class="cls-5" x1="15.73" y1="40.71" x2="55.7" y2="40.71"/><line class="cls-5" x1="15.73" y1="49.08" x2="55.7" y2="49.08"/></g><path class="cls-6" d="M48,15.53v-9h6.69c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-7" d="M54.73,7a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H48.53V7h6.19m0-1H47.53V16h9.19V8c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M15.23,15.53V8c0-1.37.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-7" d="M22.93,7v8H15.73V8a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.19m1-1H16.73c-1.65,0-2,.35-2,2v8h9.19V6Z"/><rect class="cls-6" x="39.83" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M47.52,7v8H40.33V7h7.18m1-1H39.33V16h9.19V6Z"/><rect class="cls-6" x="31.64" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M39.33,7v8H32.14V7h7.18m1-1H31.14V16h9.19V6Z"/><rect class="cls-6" x="23.45" y="6.53" width="8.17" height="9"/><path class="cls-7" d="M31.12,7v8H23.95V7h7.17m1-1H23V16h9.18V6Z"/><path class="cls-2" d="M7.27,28.28A3.37,3.37,0,0,1,13,25.85h0l.13.13.05.05L24.72,37.58a.4.4,0,0,1,.18.2l1.63,5.82v.06h0a.46.46,0,0,1,0,.12.41.41,0,0,1,0,.12s0,0,0,0h0a.4.4,0,0,1-.06.1l0,0,0,0-.1.06h0l-.12,0-.12,0H26l-5.82-1.63a.4.4,0,0,1-.2-.18L8.22,30.64a.4.4,0,0,1-.08-.12A3.35,3.35,0,0,1,7.27,28.28Zm12.9,13.15,1-2h0l-9.93-9.93L9.73,31Zm5,.55-.84.84,1.17.33Zm-1-3.48L22,39.6l-1.09,2.26,2.57.72,1.49-1.49Zm-.42-.7L13.35,27.37l-1.52,1.52,9.93,9.93h0ZM8.1,28.31a2.55,2.55,0,0,0,.83,1.88h0l.22.22,3.62-3.62-.22-.22h0A2.56,2.56,0,0,0,8.1,28.31Z"/><polygon class="cls-1" points="20.17 41.45 21.17 39.42 21.18 39.41 11.25 29.48 9.73 31 20.17 41.45"/><polygon class="cls-1" points="13.35 27.38 11.83 28.9 21.76 38.83 21.77 38.82 23.79 37.83 13.35 27.38"/><path class="cls-1" d="M8.12,28.27A2.55,2.55,0,0,0,9,30.15H9l.22.22,3.62-3.62-.22-.22h0a2.56,2.56,0,0,0-4.45,1.73Z"/><polygon class="cls-1" points="24.22 38.52 21.96 39.6 20.87 41.86 23.44 42.58 24.94 41.09 24.22 38.52"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#34495e;stroke:#528d19;stroke-miterlimit:10;}.cls-2{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-4{fill:#d3d4f3;}.cls-5{fill:#666bd1;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}.cls-8,.cls-9{fill:none;stroke-linejoin:round;opacity:0.8;}.cls-8{stroke:#666bd1;}.cls-9{stroke:#c18f35;}</style></defs><title>ex_join</title><path class="cls-1" d="M30.27,41.36a4.42,4.42,0,0,0,2.05-.51,2.81,2.81,0,0,0,1.06-1.08,3.59,3.59,0,0,0,.4-1.4q.06-.75.06-1.46v.35c0-.68,0-1.25,0-1.72a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2q0-.71,0-1.73v.36c0-.47,0-1-.06-1.46a3.58,3.58,0,0,0-.4-1.4,2.82,2.82,0,0,0-1.06-1.08,4.47,4.47,0,0,0-2.05-.51V22.2l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9A3.66,3.66,0,0,1,34.15,25a7,7,0,0,1,.16,1.29c0,.47,0,1.88,0,1.88a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06,7.9,7.9,0,0,0-.12,1.5s-.09,2.78-.18,3.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><path class="cls-2" d="M41.14,49.88c-1.37,0-1.5-.13-1.5-1.5V19.88h7.28v30Z"/><path class="cls-3" d="M46.42,20.38v29H41.14a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-28h6.28m1-1H39.14v29c0,1.65.35,2,2,2h6.28v-31Z"/><path class="cls-4" d="M46.9,49.88v-30h7.28v28.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-5" d="M53.69,20.38v28a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.4v-29h6.28m1-1H46.4v31h6.28c1.65,0,2-.35,2-2v-29Z"/><path class="cls-6" d="M39.64,19.88v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-7" d="M46.42,14.38v5H40.14v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H41.14c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-6" d="M46.91,19.88v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-7" d="M52.69,14.38a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H47.41v-5h5.28m0-1H46.41v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="46.67" y1="26.23" x2="54.16" y2="26.23"/><line class="cls-9" x1="39.67" y1="26.23" x2="46.4" y2="26.23"/><line class="cls-8" x1="46.67" y1="32.23" x2="54.16" y2="32.23"/><line class="cls-9" x1="39.67" y1="32.23" x2="46.4" y2="32.23"/><line class="cls-8" x1="46.67" y1="38.23" x2="54.16" y2="38.23"/><line class="cls-9" x1="39.67" y1="38.23" x2="46.4" y2="38.23"/><line class="cls-8" x1="46.67" y1="44.23" x2="54.16" y2="44.23"/><line class="cls-9" x1="39.67" y1="44.23" x2="46.4" y2="44.23"/><path class="cls-4" d="M11.34,29.31c-1.37,0-1.5-.13-1.5-1.5V16.31h7.28v13Z"/><path class="cls-5" d="M16.62,16.81v12H11.34a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-11h6.28m1-1H9.34v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-4" d="M17.11,29.31v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-5" d="M23.89,16.81v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H17.61v-12h6.28m1-1H16.61v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-6" d="M9.84,16.31v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-7" d="M16.62,10.81v5H10.34v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H11.34c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-6" d="M17.11,16.31v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-7" d="M22.89,10.81a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H17.61v-5h5.28m0-1H16.61v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="16.87" y1="22.66" x2="24.37" y2="22.66"/><line class="cls-8" x1="9.87" y1="22.66" x2="16.61" y2="22.66"/><path class="cls-2" d="M11.34,53.46c-1.37,0-1.5-.13-1.5-1.5V40.46h7.28v13Z"/><path class="cls-3" d="M16.62,41V53H11.34a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V41h6.28m1-1H9.34V52c0,1.65.35,2,2,2h6.28V40Z"/><path class="cls-2" d="M17.11,53.46v-13h7.28V52c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M23.89,41V52a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H17.61V41h6.28m1-1H16.61V54h6.28c1.65,0,2-.35,2-2V40Z"/><path class="cls-6" d="M9.84,40.46V36c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-7" d="M16.62,35v5H10.34V36a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H11.34c-1.65,0-2,.35-2,2v5h8.28V34Z"/><path class="cls-6" d="M17.11,40.46v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-7" d="M22.89,35a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H17.61V35h5.28m0-1H16.61v7h8.28V36c0-1.65-.35-2-2-2Z"/><line class="cls-9" x1="16.87" y1="46.81" x2="24.37" y2="46.81"/><line class="cls-9" x1="9.87" y1="46.81" x2="16.61" y2="46.81"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-4{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{opacity:0.8;}.cls-4{stroke:#c18f36;}.cls-4,.cls-7{stroke-miterlimit:10;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7{fill:#d3d4f3;stroke:#c00;}.cls-7,.cls-9{stroke-linecap:round;stroke-width:1.5px;}.cls-8,.cls-9{fill:#528d19;}.cls-9{stroke:#528d19;stroke-linejoin:round;}</style></defs><title>ex_limit</title><path class="cls-1" d="M12.79,53.47c-1.37,0-1.5-.13-1.5-1.5V19.53h41V52c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M51.77,20V52a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-38a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V20h40m1-1h-42V52c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V19Z"/><g class="cls-3"><line class="cls-4" x1="19.48" y1="52.97" x2="19.48" y2="19.97"/><line class="cls-4" x1="35.88" y1="52.97" x2="35.88" y2="19.97"/><line class="cls-4" x1="27.68" y1="52.97" x2="27.68" y2="19.97"/><line class="cls-4" x1="44.08" y1="52.97" x2="44.08" y2="19.97"/><line class="cls-4" x1="11.78" y1="27.97" x2="51.75" y2="27.97"/><line class="cls-4" x1="11.78" y1="36.34" x2="51.75" y2="36.34"/><line class="cls-4" x1="11.78" y1="44.71" x2="51.75" y2="44.71"/></g><path class="cls-5" d="M44.09,19.53v-9h6.69c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-6" d="M50.78,11a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H44.59V11h6.19m0-1H43.59V20h9.19V12c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M11.29,19.53V12c0-1.37.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-6" d="M19,11v8H11.79V12a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H19m1-1H12.79c-1.65,0-2,.35-2,2v8H20V10Z"/><rect class="cls-5" x="35.88" y="10.53" width="8.18" height="9"/><path class="cls-6" d="M43.57,11v8H36.38V11h7.18m1-1H35.39V20h9.19V10Z"/><rect class="cls-5" x="27.69" y="10.53" width="8.19" height="9"/><path class="cls-6" d="M35.38,11v8H28.19V11h7.18m1-1H27.2V20h9.19V10Z"/><rect class="cls-5" x="19.5" y="10.53" width="8.17" height="9"/><path class="cls-6" d="M27.18,11v8H20V11h7.17m1-1H19V20h9.18V10Z"/><line class="cls-7" x1="6.31" y1="19.76" x2="57.77" y2="19.77"/><line class="cls-7" x1="6.31" y1="36.33" x2="57.77" y2="36.34"/><polygon class="cls-8" points="56.25 34.71 58.78 31.33 53.72 31.33 56.25 34.71"/><line class="cls-9" x1="56.25" y1="32.18" x2="56.25" y2="21.94"/><polygon class="cls-8" points="7.75 34.71 10.28 31.33 5.22 31.33 7.75 34.71"/><line class="cls-9" x1="7.75" y1="32.18" x2="7.75" y2="21.94"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-5{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{fill:#ffbd30;}.cls-4{opacity:0.8;}.cls-5{stroke:#c18f36;stroke-miterlimit:10;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}.cls-8{fill:url(#linear-gradient);}.cls-9{fill:#757272;}.cls-10{fill:#fbf1c3;}</style><linearGradient id="linear-gradient" x1="5.03" y1="27.25" x2="14.71" y2="36.93" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ceba59"/><stop offset="1" stop-color="#b76451"/></linearGradient></defs><title>ex_lock_rows</title><path class="cls-1" d="M19.74,57.47c-1.37,0-1.5-.13-1.5-1.5V15.53h41V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M58.72,16V56a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-38a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16h40m1-1h-42V56c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V15Z"/><rect class="cls-3" x="18.72" y="24.56" width="7.22" height="7.44"/><rect class="cls-3" x="35.13" y="41.11" width="7.22" height="7.44"/><rect class="cls-3" x="26.92" y="41.11" width="7.22" height="7.44"/><g class="cls-4"><line class="cls-5" x1="26.43" y1="56.97" x2="26.43" y2="15.97"/><line class="cls-5" x1="42.83" y1="56.97" x2="42.83" y2="15.97"/><line class="cls-5" x1="34.63" y1="56.97" x2="34.63" y2="15.97"/><line class="cls-5" x1="51.03" y1="56.97" x2="51.03" y2="15.97"/><line class="cls-5" x1="18.73" y1="23.97" x2="58.7" y2="23.97"/><line class="cls-5" x1="18.73" y1="32.34" x2="58.7" y2="32.34"/><line class="cls-5" x1="18.73" y1="40.71" x2="58.7" y2="40.71"/><line class="cls-5" x1="18.73" y1="49.08" x2="58.7" y2="49.08"/></g><path class="cls-6" d="M51,15.53v-9h6.69c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-7" d="M57.73,7a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H51.54V7h6.19m0-1H50.54V16h9.19V8c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M18.24,15.53V8c0-1.37.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-7" d="M25.93,7v8H18.74V8a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.19m1-1H19.74c-1.65,0-2,.35-2,2v8h9.19V6Z"/><rect class="cls-6" x="42.83" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M50.52,7v8H43.33V7h7.18m1-1H42.34V16h9.19V6Z"/><rect class="cls-6" x="34.64" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M42.33,7v8H35.14V7h7.18m1-1H34.15V16h9.19V6Z"/><rect class="cls-6" x="26.45" y="6.53" width="8.17" height="9"/><path class="cls-7" d="M34.13,7v8H26.95V7h7.17m1-1H26V16h9.18V6Z"/><path id="Shape" class="cls-8" d="M14.07,27.19H5.67a1.4,1.4,0,0,0-1.4,1.4v7A1.4,1.4,0,0,0,5.67,37h8.4a1.4,1.4,0,0,0,1.4-1.4v-7a1.4,1.4,0,0,0-1.4-1.4Zm0,8.4H5.67v-7h8.4Z"/><path id="Shape-2" data-name="Shape" class="cls-9" d="M13.37,27.19v-1.4a3.5,3.5,0,0,0-7,0s0,1.42,0,1.42H7.7s0-1.41,0-1.42a2.17,2.17,0,0,1,4.34,0v1.4Z"/><rect class="cls-10" x="5.67" y="28.59" width="8.4" height="7"/></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{opacity:0.6;}.cls-2{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-6{fill:none;stroke:#c18f35;opacity:0.8;}.cls-6,.cls-7,.cls-8{stroke-linejoin:round;}.cls-7,.cls-8{fill:#528d19;stroke:#528d19;}.cls-8{stroke-linecap:round;stroke-width:2px;}</style></defs><title>ex_materialize</title><g class="cls-1"><path class="cls-2" d="M10.17,49.88c-1.37,0-1.5-.13-1.5-1.5V19.88H16v30Z"/><path class="cls-3" d="M15.45,20.38v29H10.17a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-28h6.28m1-1H8.17v29c0,1.65.35,2,2,2h6.28v-31Z"/><path class="cls-2" d="M15.94,49.88v-30h7.28v28.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M22.72,20.38v28a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H16.44v-29h6.28m1-1H15.44v31h6.28c1.65,0,2-.35,2-2v-29Z"/><path class="cls-4" d="M8.67,19.88v-4.5c0-1.37.13-1.5,1.5-1.5H16v6Z"/><path class="cls-5" d="M15.45,14.38v5H9.17v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H10.17c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-4" d="M15.94,19.88v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M21.72,14.38a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H16.44v-5h5.28m0-1H15.44v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-6" x1="15.7" y1="26.23" x2="23.19" y2="26.23"/><line class="cls-6" x1="8.7" y1="26.23" x2="15.44" y2="26.23"/><line class="cls-6" x1="15.7" y1="32.23" x2="23.19" y2="32.23"/><line class="cls-6" x1="8.7" y1="32.23" x2="15.44" y2="32.23"/><line class="cls-6" x1="15.7" y1="38.23" x2="23.19" y2="38.23"/><line class="cls-6" x1="8.7" y1="38.23" x2="15.44" y2="38.23"/><line class="cls-6" x1="15.7" y1="44.23" x2="23.19" y2="44.23"/><line class="cls-6" x1="8.7" y1="44.23" x2="15.44" y2="44.23"/></g><path class="cls-2" d="M42.45,49.88c-1.37,0-1.5-.13-1.5-1.5V19.88h7.28v30Z"/><path class="cls-3" d="M47.73,20.38v29H42.45a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-28h6.28m1-1H40.45v29c0,1.65.35,2,2,2h6.28v-31Z"/><path class="cls-2" d="M48.22,49.88v-30H55.5v28.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M55,20.38v28a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H48.72v-29H55m1-1H47.72v31H54c1.65,0,2-.35,2-2v-29Z"/><path class="cls-4" d="M41,19.88v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-5" d="M47.73,14.38v5H41.45v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H42.45c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-4" d="M48.22,19.88v-6H54c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M54,14.38a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H48.72v-5H54m0-1H47.72v7H56v-5c0-1.65-.35-2-2-2Z"/><line class="cls-6" x1="47.98" y1="26.23" x2="55.47" y2="26.23"/><line class="cls-6" x1="40.98" y1="26.23" x2="47.72" y2="26.23"/><line class="cls-6" x1="47.98" y1="32.23" x2="55.47" y2="32.23"/><line class="cls-6" x1="40.98" y1="32.23" x2="47.72" y2="32.23"/><line class="cls-6" x1="47.98" y1="38.23" x2="55.47" y2="38.23"/><line class="cls-6" x1="40.98" y1="38.23" x2="47.72" y2="38.23"/><line class="cls-6" x1="47.98" y1="44.23" x2="55.47" y2="44.23"/><line class="cls-6" x1="40.98" y1="44.23" x2="47.72" y2="44.23"/><polygon class="cls-7" points="37.55 32 34.17 29.47 34.17 34.53 37.55 32"/><line class="cls-8" x1="33.89" y1="32" x2="26.45" y2="32"/></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3{fill:none;stroke:#666bd1;}.cls-10,.cls-11,.cls-3{stroke-linejoin:round;}.cls-3,.cls-6{opacity:0.8;}.cls-4,.cls-7{fill:#f0ecb6;}.cls-5{fill:#c18f36;}.cls-7{stroke:#c18f36;stroke-miterlimit:10;}.cls-8{fill:#addff3;}.cls-9{fill:#2980b9;}.cls-10,.cls-11{fill:#528d19;stroke:#528d19;}.cls-11{stroke-linecap:round;stroke-width:2px;}</style></defs><title>ex_merge</title><path class="cls-1" d="M9.5,17.48C8.13,17.48,8,17.36,8,16V12c0-1.37.13-1.5,1.5-1.5H14v7Z"/><path class="cls-2" d="M13.5,11v6h-4a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,8.5,16V12a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,9.5,11h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5V10Z"/><path class="cls-1" d="M14,17.48v-7H25.19c1.37,0,1.5.13,1.5,1.5v4c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M25.19,11a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H14.5V11H25.19m0-1H13.5v8H25.19c1.65,0,2-.35,2-2V12c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="20.27" y1="17.1" x2="20.27" y2="10.86"/><path class="cls-4" d="M32.89,53.5c-1.37,0-1.5-.13-1.5-1.5V27.56H56V52c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-5" d="M55.49,28.06V52a3.29,3.29,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H32.89a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V28.06h23.6m1-1H30.89V52c0,1.65.35,2,2,2h21.6c1.65,0,2-.35,2-2V27.06Z"/><g class="cls-6"><line class="cls-7" x1="39.58" y1="52.99" x2="39.58" y2="28"/><line class="cls-7" x1="47.8" y1="52.99" x2="47.8" y2="28"/><line class="cls-7" x1="31.88" y1="33.99" x2="55.47" y2="33.99"/><line class="cls-7" x1="31.88" y1="40.36" x2="55.47" y2="40.36"/><line class="cls-7" x1="31.88" y1="46.73" x2="55.47" y2="46.73"/></g><path class="cls-8" d="M47.81,27.55v-6H54.5c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-9" d="M54.5,22.05a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H48.31v-5H54.5m0-1H47.31v7H56.5v-5c0-1.65-.35-2-2-2Z"/><path class="cls-8" d="M31.39,27.55v-4.5c0-1.37.13-1.5,1.5-1.5h6.69v6Z"/><path class="cls-9" d="M39.08,22.05v5H31.89v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.19m1-1H32.89c-1.65,0-2,.35-2,2v5h9.19v-7Z"/><rect class="cls-8" x="39.6" y="21.55" width="8.19" height="6"/><path class="cls-9" d="M47.29,22.05v5H40.1v-5h7.18m1-1H39.11v7h9.19v-7Z"/><polygon class="cls-10" points="27.87 44 24.49 41.47 24.49 46.53 27.87 44"/><line class="cls-11" x1="24.21" y1="44" x2="17.1" y2="44"/><line class="cls-11" x1="16.96" y1="21.56" x2="16.96" y2="44"/></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-10,.cls-13,.cls-3{fill:none;}.cls-3{stroke:#666bd1;}.cls-10,.cls-3,.cls-4,.cls-5{stroke-linejoin:round;}.cls-10,.cls-3{opacity:0.8;}.cls-4,.cls-5{fill:#528d19;stroke:#528d19;}.cls-5{stroke-linecap:round;stroke-width:2px;}.cls-6{fill:#f0ecb6;}.cls-7{fill:#c18f35;}.cls-8{fill:#addff3;}.cls-9{fill:#2980b9;}.cls-10{stroke:#c18f35;}.cls-11{fill:#def4fd;}.cls-12{fill:#c00;}.cls-13{stroke:#c00;stroke-miterlimit:10;stroke-width:1.5px;}</style></defs><title>ex_merge_anti_join</title><path class="cls-1" d="M10.12,18.59c-1.37,0-1.5-.13-1.5-1.5v-4c0-1.37.13-1.5,1.5-1.5h4.5v7Z"/><path class="cls-2" d="M14.12,12.11v6h-4a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-4a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5v-8Z"/><path class="cls-1" d="M14.63,18.59v-7H25.81c1.37,0,1.5.13,1.5,1.5v4c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M25.81,12.11a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H15.13v-6H25.81m0-1H14.13v8H25.81c1.65,0,2-.35,2-2v-4c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="20.9" y1="18.21" x2="20.9" y2="11.97"/><polygon class="cls-4" points="28.49 38.11 25.11 35.58 25.11 40.64 28.49 38.11"/><line class="cls-5" x1="24.83" y1="38.11" x2="17.73" y2="38.11"/><line class="cls-5" x1="17.58" y1="22.67" x2="17.58" y2="38.11"/><path class="cls-6" d="M34.26,52.16c-1.37,0-1.5-.13-1.5-1.5V28.16H40v24Z"/><path class="cls-7" d="M39.54,28.66v23H34.26a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-22h6.28m1-1H32.26v23c0,1.65.35,2,2,2h6.28v-25Z"/><path class="cls-8" d="M32.76,28.16v-4.5c0-1.37.13-1.5,1.5-1.5H40v6Z"/><path class="cls-9" d="M39.54,22.66v5H33.26v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H34.26c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><line class="cls-10" x1="32.79" y1="34.51" x2="39.53" y2="34.51"/><line class="cls-10" x1="32.79" y1="40.51" x2="39.53" y2="40.51"/><line class="cls-10" x1="32.79" y1="46.51" x2="39.53" y2="46.51"/><rect class="cls-6" x="40.06" y="28.16" width="7.28" height="24"/><path class="cls-7" d="M46.84,28.66v23H40.56v-23h6.28m1-1H39.56v25h8.28v-25Z"/><path class="cls-1" d="M47.32,52.16v-24h7.28v22.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M54.11,28.66v22a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H47.82v-23h6.28m1-1H46.82v25h6.28c1.65,0,2-.35,2-2v-23Z"/><rect class="cls-8" x="40.06" y="22.16" width="7.28" height="6"/><path class="cls-9" d="M46.84,22.66v5H40.56v-5h6.28m1-1H39.56v7h8.28v-7Z"/><path class="cls-8" d="M47.32,28.16v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-9" d="M53.11,22.66a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4H47.82v-5h5.28m0-1H46.83v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="47.09" y1="34.51" x2="54.58" y2="34.51"/><line class="cls-10" x1="40.09" y1="34.51" x2="46.82" y2="34.51"/><line class="cls-3" x1="47.09" y1="40.51" x2="54.58" y2="40.51"/><line class="cls-10" x1="40.09" y1="40.51" x2="46.82" y2="40.51"/><line class="cls-3" x1="47.09" y1="46.51" x2="54.58" y2="46.51"/><line class="cls-10" x1="40.09" y1="46.51" x2="46.82" y2="46.51"/><circle class="cls-11" cx="50.83" cy="40.46" r="4.29"/><path class="cls-12" d="M50.83,36.92a3.54,3.54,0,1,1-3.54,3.54,3.55,3.55,0,0,1,3.54-3.54m0-1.5a5,5,0,1,0,5,5,5,5,0,0,0-5-5Z"/><line class="cls-13" x1="47.55" y1="42.73" x2="54.06" y2="38"/></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-10,.cls-3{fill:none;opacity:0.8;}.cls-3{stroke:#666bd1;}.cls-10,.cls-3,.cls-4,.cls-5{stroke-linejoin:round;}.cls-4,.cls-5{fill:#528d19;stroke:#528d19;}.cls-5{stroke-linecap:round;stroke-width:2px;}.cls-6{fill:#f0ecb6;}.cls-7{fill:#c18f35;}.cls-8{fill:#addff3;}.cls-9{fill:#2980b9;}.cls-10{stroke:#c18f35;}.cls-11{opacity:0.6;}</style></defs><title>ex_merge_semi_join</title><path class="cls-1" d="M10.51,18.18c-1.37,0-1.5-.13-1.5-1.5v-4c0-1.37.13-1.5,1.5-1.5H15v7Z"/><path class="cls-2" d="M14.51,11.69v6h-4a3.26,3.26,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m1-1h-5c-1.65,0-2,.35-2,2v4c0,1.65.35,2,2,2h5v-8Z"/><path class="cls-1" d="M15,18.18v-7H26.2c1.37,0,1.5.13,1.5,1.5v4c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M26.2,11.69a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4a3.29,3.29,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H15.51v-6H26.2m0-1H14.51v8H26.2c1.65,0,2-.35,2-2v-4c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="21.28" y1="17.79" x2="21.28" y2="11.55"/><polygon class="cls-4" points="28.88 37.69 25.5 35.16 25.5 40.22 28.88 37.69"/><line class="cls-5" x1="25.21" y1="37.69" x2="18.11" y2="37.69"/><line class="cls-5" x1="17.97" y1="22.25" x2="17.97" y2="37.69"/><path class="cls-6" d="M34.64,52.57c-1.37,0-1.5-.13-1.5-1.5V28.57h7.28v24Z"/><path class="cls-7" d="M39.92,29.07v23H34.64a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-22h6.28m1-1H32.64v23c0,1.65.35,2,2,2h6.28v-25Z"/><path class="cls-8" d="M33.14,28.57v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-9" d="M39.92,23.07v5H33.64v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H34.64c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><line class="cls-10" x1="33.17" y1="34.92" x2="39.91" y2="34.92"/><line class="cls-10" x1="33.17" y1="40.92" x2="39.91" y2="40.92"/><line class="cls-10" x1="33.17" y1="46.92" x2="39.91" y2="46.92"/><g class="cls-11"><rect class="cls-6" x="40.44" y="28.57" width="7.28" height="24"/><path class="cls-7" d="M47.22,29.07v23H40.94v-23h6.28m1-1H39.94v25h8.28v-25Z"/><path class="cls-1" d="M47.71,52.57v-24H55v22.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M54.49,29.07v22a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H48.21v-23h6.28m1-1H47.21v25h6.28c1.65,0,2-.35,2-2v-23Z"/><rect class="cls-8" x="40.44" y="22.57" width="7.28" height="6"/><path class="cls-9" d="M47.22,23.07v5H40.94v-5h6.28m1-1H39.94v7h8.28v-7Z"/><path class="cls-8" d="M47.71,28.57v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-9" d="M53.49,23.07a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H48.21v-5h5.28m0-1H47.21v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="47.47" y1="34.92" x2="54.96" y2="34.92"/><line class="cls-10" x1="40.47" y1="34.92" x2="47.21" y2="34.92"/><line class="cls-3" x1="47.47" y1="40.92" x2="54.96" y2="40.92"/><line class="cls-10" x1="40.47" y1="40.92" x2="47.21" y2="40.92"/><line class="cls-3" x1="47.47" y1="46.92" x2="54.96" y2="46.92"/><line class="cls-10" x1="40.47" y1="46.92" x2="47.21" y2="46.92"/></g></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-2,.cls-4,.cls-6,.cls-8{fill:#f3c7d7;}.cls-1,.cls-2{stroke:#d04465;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-8{stroke-miterlimit:10;}.cls-2,.cls-4,.cls-6,.cls-8{opacity:0.5;}.cls-3{fill:#addff3;}.cls-3,.cls-4{stroke:#2980b9;}.cls-5{fill:#f0ecb6;}.cls-5,.cls-6{stroke:#c18f36;}.cls-7{fill:#d3d4f3;}.cls-7,.cls-8{stroke:#666bd1;}.cls-10,.cls-9{fill:#646464;stroke:#646464;stroke-linejoin:round;}.cls-10{stroke-linecap:round;stroke-width:2px;}</style></defs><title>named_tuplestore_scan</title><rect class="cls-1" x="22.81" y="22.32" width="31.05" height="7.04" rx="1"/><line class="cls-2" x1="34.89" y1="29.08" x2="34.89" y2="22.84"/><line class="cls-2" x1="28.83" y1="29.08" x2="28.83" y2="22.84"/><line class="cls-2" x1="41.27" y1="29.08" x2="41.27" y2="22.84"/><line class="cls-2" x1="47.4" y1="29.08" x2="47.4" y2="22.84"/><rect class="cls-3" x="22.81" y="34.68" width="31.05" height="7.04" rx="1"/><line class="cls-4" x1="34.89" y1="41.44" x2="34.89" y2="35.2"/><line class="cls-4" x1="28.83" y1="41.44" x2="28.83" y2="35.2"/><line class="cls-4" x1="41.27" y1="41.44" x2="41.27" y2="35.2"/><line class="cls-4" x1="47.4" y1="41.44" x2="47.4" y2="35.2"/><rect class="cls-5" x="22.81" y="47.24" width="31.05" height="7.04" rx="1"/><line class="cls-6" x1="34.89" y1="54" x2="34.89" y2="47.76"/><line class="cls-6" x1="28.83" y1="54" x2="28.83" y2="47.76"/><line class="cls-6" x1="41.27" y1="54" x2="41.27" y2="47.76"/><line class="cls-6" x1="47.4" y1="54" x2="47.4" y2="47.76"/><rect class="cls-7" x="22.81" y="9.72" width="31.05" height="7.04" rx="1"/><line class="cls-8" x1="34.89" y1="16.47" x2="34.89" y2="10.23"/><line class="cls-8" x1="28.83" y1="16.47" x2="28.83" y2="10.23"/><line class="cls-8" x1="41.27" y1="16.47" x2="41.27" y2="10.23"/><line class="cls-8" x1="47.4" y1="16.47" x2="47.4" y2="10.23"/><polygon class="cls-9" points="13.62 53.99 10.14 49.35 17.09 49.35 13.62 53.99"/><line class="cls-10" x1="13.62" y1="49.98" x2="13.62" y2="10.01"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-3{fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}.cls-1{stroke:#666bd1;}.cls-2{fill:#666bd1;}.cls-3{stroke:#8d8119;}.cls-4{fill:#8d8119;}</style></defs><title>ex_nested</title><path class="cls-1" d="M17.23,20a6,6,0,0,1,6-6h22a6,6,0,0,1,6,6V44a6,6,0,0,1-6,6h-22a6,6,0,0,1-6-6V32.27"/><polygon class="cls-2" points="17.23 27.31 12.77 33.26 21.68 33.26 17.23 27.31"/><path class="cls-3" d="M24.23,25c0-3.3.7-4,4-4h12c3.3,0,4,.7,4,4V39c0,3.3-.7,4-4,4H28.72c-3.3,0-4-.7-4-4V33.72"/><polygon class="cls-4" points="24.67 31.34 20.71 36.1 28.23 36.1 24.67 31.34"/></svg>

After

Width:  |  Height:  |  Size: 693 B

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-11,.cls-15,.cls-3,.cls-8{fill:none;}.cls-1,.cls-8{stroke:#666bd1;}.cls-1,.cls-3{stroke-linecap:round;}.cls-1,.cls-11,.cls-3,.cls-8{stroke-linejoin:round;}.cls-1,.cls-15,.cls-3{stroke-width:1.5px;}.cls-2{fill:#666bd1;}.cls-3{stroke:#8d8119;}.cls-4{fill:#8d8119;}.cls-5{fill:#d3d4f3;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}.cls-11,.cls-8{opacity:0.8;}.cls-9{fill:#f0ecb6;}.cls-10{fill:#c18f35;}.cls-11{stroke:#c18f35;}.cls-12{fill:#34495e;stroke:#528d19;}.cls-12,.cls-15{stroke-miterlimit:10;}.cls-13{fill:#def4fd;}.cls-14{fill:#c00;}.cls-15{stroke:#c00;}</style></defs><title>ex_nested_loop_anti_join</title><path class="cls-1" d="M8.68,22.32c0-.35.06-3.69.17-4a3,3,0,0,1,2.83-2h14a3,3,0,0,1,3,3v24a3,3,0,0,1-3,3h-14a3,3,0,0,1-3-3V28.46"/><polygon class="cls-2" points="8.68 25.98 6.45 28.95 10.9 28.95 8.68 25.98"/><path class="cls-3" d="M12.18,24.82c0-.26,0-3.48,0-3.68.11-1.07.58-1.32,2-1.32h9c1.65,0,2,.35,2,2v19c0,1.65-.35,2-2,2H14.42c-1.65,0-2-.35-2-2V29.18"/><polygon class="cls-4" points="12.4 27.99 10.42 30.37 14.18 30.37 12.4 27.99"/><path class="cls-5" d="M48.87,46.94v-24h7.28v22.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M55.65,23.44v22a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H49.37v-23h6.28m1-1H48.37v25h6.28c1.65,0,2-.35,2-2v-23Z"/><path class="cls-6" d="M48.87,22.94v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-7" d="M54.65,17.44a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v4H49.37v-5h5.28m0-1H48.37v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-8" x1="48.63" y1="29.29" x2="56.12" y2="29.29"/><line class="cls-8" x1="48.63" y1="35.29" x2="56.12" y2="35.29"/><line class="cls-8" x1="48.63" y1="41.29" x2="56.12" y2="41.29"/><path class="cls-9" d="M43.1,46.94c-1.37,0-1.5-.13-1.5-1.5V22.94h7.28v24Z"/><path class="cls-10" d="M48.38,23.44v23H43.1a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-22h6.28m1-1H41.1v23c0,1.65.35,2,2,2h6.28v-25Z"/><path class="cls-6" d="M41.6,22.94v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-7" d="M48.38,17.44v5H42.1v-4a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H43.1c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><line class="cls-11" x1="41.63" y1="29.29" x2="48.37" y2="29.29"/><line class="cls-11" x1="41.63" y1="35.29" x2="48.37" y2="35.29"/><line class="cls-11" x1="41.63" y1="41.29" x2="48.37" y2="41.29"/><path class="cls-12" d="M33.87,35.61A9.28,9.28,0,0,1,34,34.4a2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2c0-.47.5.77.58,1.18a2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73,2.39,2.39,0,0,0-.47,1.06C34.37,34.84,33.85,36.08,33.87,35.61Z"/><circle class="cls-13" cx="52.51" cy="35.29" r="4.29"/><path class="cls-14" d="M52.51,31.75A3.54,3.54,0,1,1,49,35.29a3.55,3.55,0,0,1,3.54-3.54m0-1.5a5,5,0,1,0,5,5,5,5,0,0,0-5-5Z"/><line class="cls-15" x1="49.22" y1="37.57" x2="55.73" y2="32.83"/></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{opacity:0.6;}.cls-2{fill:#d3d4f3;}.cls-3{fill:#666bd1;}.cls-4{fill:#addff3;}.cls-5{fill:#2980b9;}.cls-11,.cls-12,.cls-6,.cls-9{fill:none;stroke-linejoin:round;}.cls-11,.cls-6{stroke:#666bd1;}.cls-6,.cls-9{opacity:0.8;}.cls-7{fill:#f0ecb6;}.cls-8{fill:#c18f35;}.cls-9{stroke:#c18f35;}.cls-10{fill:#34495e;stroke:#528d19;stroke-miterlimit:10;}.cls-11,.cls-12{stroke-linecap:round;stroke-width:1.5px;}.cls-12{stroke:#8d8119;}.cls-13{fill:#8d8119;}</style></defs><title>ex_nested_loop_semi_join</title><g class="cls-1"><path class="cls-2" d="M49.45,46.88v-24h7.28v22.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-3" d="M56.23,23.38v22a3.29,3.29,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H49.95v-23h6.28m1-1H48.95v25h6.28c1.65,0,2-.35,2-2v-23Z"/><path class="cls-4" d="M49.45,22.88v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-5" d="M55.23,17.38a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H49.95v-5h5.28m0-1H49v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-6" x1="49.21" y1="29.23" x2="56.71" y2="29.23"/><line class="cls-6" x1="49.21" y1="35.23" x2="56.71" y2="35.23"/><line class="cls-6" x1="49.21" y1="41.23" x2="56.71" y2="41.23"/></g><path class="cls-7" d="M43.68,46.88c-1.37,0-1.5-.13-1.5-1.5V22.88h7.28v24Z"/><path class="cls-8" d="M49,23.38v23H43.68a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-22H49m1-1H41.68v23c0,1.65.35,2,2,2H50v-25Z"/><path class="cls-4" d="M42.18,22.88v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-5" d="M49,17.38v5H42.68v-4a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H49m1-1H43.68c-1.65,0-2,.35-2,2v5H50v-7Z"/><line class="cls-9" x1="42.21" y1="29.23" x2="48.95" y2="29.23"/><line class="cls-9" x1="42.21" y1="35.23" x2="48.95" y2="35.23"/><line class="cls-9" x1="42.21" y1="41.23" x2="48.95" y2="41.23"/><path class="cls-10" d="M34.45,35.55a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2c0-.47.5.77.58,1.18a2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73A2.39,2.39,0,0,0,35,34.37C35,34.78,34.44,36,34.45,35.55Z"/><path class="cls-11" d="M9,23.05c0-.35.06-3.69.17-4a3,3,0,0,1,2.83-2H26a3,3,0,0,1,3,3v24a3,3,0,0,1-3,3H12a3,3,0,0,1-3-3V29.19"/><polygon class="cls-3" points="8.99 26.71 6.77 29.68 11.22 29.68 8.99 26.71"/><path class="cls-12" d="M12.49,25.55c0-.26,0-3.48,0-3.68.11-1.07.58-1.32,2-1.32h9c1.65,0,2,.35,2,2v19c0,1.65-.35,2-2,2H14.74c-1.65,0-2-.35-2-2V29.91"/><polygon class="cls-13" points="12.71 28.72 10.74 31.1 14.49 31.1 12.71 28.72"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64.03 64"><defs><style>.cls-1{fill:none;stroke:#d04465;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}.cls-2,.cls-4{fill:#e6e6e6;}.cls-3{fill:#818181;}.cls-4{stroke:#818181;}.cls-4,.cls-5{stroke-miterlimit:10;}.cls-5{fill:#d3d4f3;stroke:#666bd1;}</style></defs><title>projectset</title><g id="_1" data-name="1"><line class="cls-1" x1="53.64" y1="20.63" x2="54.58" y2="18.35"/><line class="cls-1" x1="51.36" y1="26.18" x2="52.52" y2="23.36"/><line class="cls-1" x1="41.33" y1="50.52" x2="50.31" y2="28.73"/><line class="cls-1" x1="10.38" y1="20.63" x2="9.45" y2="18.35"/><line class="cls-1" x1="12.67" y1="26.18" x2="11.51" y2="23.36"/><line class="cls-1" x1="22.7" y1="50.52" x2="13.72" y2="28.73"/><line class="cls-1" x1="20.61" y1="32.38" x2="19.44" y2="29.56"/><line class="cls-1" x1="28.13" y1="50.52" x2="21.66" y2="34.93"/><line class="cls-1" x1="21.34" y1="9.61" x2="20.84" y2="8.73"/><line class="cls-1" x1="24.27" y1="16.64" x2="22.39" y2="12.16"/><line class="cls-1" x1="43.58" y1="32.38" x2="44.74" y2="29.56"/><line class="cls-1" x1="36.05" y1="50.52" x2="42.53" y2="34.93"/><line class="cls-1" x1="43.56" y1="10.89" x2="44.11" y2="9.64"/><line class="cls-1" x1="41.07" y1="16.85" x2="42.51" y2="13.44"/><path class="cls-2" d="M14.41,63.53v-4a3.5,3.5,0,0,1,3.5-3.5h28.5a3.5,3.5,0,0,1,3.5,3.5v4Z"/><path class="cls-3" d="M46.41,56.49a3,3,0,0,1,3,3V63H14.91V59.49a3,3,0,0,1,3-3h28.5m0-1H17.91a4,4,0,0,0-4,4V64h36.5V59.49a4,4,0,0,0-4-4Z"/><path class="cls-2" d="M22.27,55.9l-1.85-5.48a.11.11,0,0,1,.09-.05h23.3a.11.11,0,0,1,.09.05L42.05,55.9Z"/><path class="cls-3" d="M43.22,50.87,41.69,55.4H22.63L21.1,50.87H43.22m.59-1H20.51a.6.6,0,0,0-.6.6l2,5.93h20.5l2-5.93a.6.6,0,0,0-.6-.6Z"/><path class="cls-2" d="M32.08,61.06a1.39,1.39,0,1,1,1.38-1.38A1.38,1.38,0,0,1,32.08,61.06Z"/><path class="cls-3" d="M32.08,58.79a.89.89,0,1,1-.89.89.89.89,0,0,1,.89-.89m0-1A1.89,1.89,0,1,0,34,59.68a1.89,1.89,0,0,0-1.88-1.89Z"/><line class="cls-4" x1="21.17" y1="52.28" x2="28.29" y2="52.28"/><line class="cls-4" x1="21.83" y1="54.08" x2="34.69" y2="54.08"/></g><g id="ex_append"><path class="cls-5" d="M22.06,23.87H42a0,0,0,0,1,0,0v3a1,1,0,0,1-1,1H23.06a1,1,0,0,1-1-1v-3A0,0,0,0,1,22.06,23.87Z"/><rect class="cls-5" x="27.07" y="23.87" width="5" height="4"/><rect class="cls-5" x="32.03" y="23.87" width="5" height="4"/><path class="cls-5" d="M23.06,20.13H41a1,1,0,0,1,1,1v3a0,0,0,0,1,0,0H22.06a0,0,0,0,1,0,0v-3A1,1,0,0,1,23.06,20.13Z"/><rect class="cls-5" x="27.07" y="20.13" width="5" height="4"/><rect class="cls-5" x="32.03" y="20.13" width="5" height="4"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f3c7d7;}.cls-2{fill:#d04465;}.cls-3{fill:none;stroke:#2980b9;stroke-linecap:round;stroke-linejoin:round;}.cls-4{fill:#2980b9;}.cls-5{fill:#addff3;}</style></defs><title>ex_redistribute_motion</title><g id="ex_delete"><rect class="cls-1" x="47.19" y="45.43" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M55.69,45.93v8h-8v-8h8m0-1h-8a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><rect class="cls-1" x="7.81" y="45.43" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M16.31,45.93v8h-8v-8h8m0-1h-8a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><rect class="cls-1" x="27.51" y="9.57" width="9" height="9" rx="0.5" ry="0.5"/><path class="cls-2" d="M36,10.07v8H28v-8h8m0-1H28a1,1,0,0,0-1,1v8a1,1,0,0,0,1,1h8a1,1,0,0,0,1-1v-8a1,1,0,0,0-1-1Z"/><line class="cls-3" x1="20.23" y1="43" x2="24.01" y2="40.82"/><path class="cls-4" d="M18.14,44.2a12.09,12.09,0,0,1,3.91-.06l-1.55-1.3-.35-2A12.08,12.08,0,0,1,18.14,44.2Z"/><line class="cls-3" x1="39.96" y1="41.02" x2="43.75" y2="43.2"/><path class="cls-4" d="M45.84,44.4a12.09,12.09,0,0,0-3.91-.06L43.47,43l.35-2A12.08,12.08,0,0,0,45.84,44.4Z"/><line class="cls-3" x1="32.08" y1="22.48" x2="32.08" y2="26.85"/><path class="cls-4" d="M32.09,20.07a12.09,12.09,0,0,1-1.91,3.42l1.9-.69,1.9.69A12.08,12.08,0,0,1,32.09,20.07Z"/><circle class="cls-5" cx="32.08" cy="35.93" r="7.5"/><path class="cls-4" d="M32.08,28.93a7,7,0,1,1-7,7,7,7,0,0,1,7-7m0-1a8,8,0,1,0,8,8,8,8,0,0,0-8-8Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-6{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{fill:#addff3;}.cls-4{fill:#2980b9;}.cls-5{opacity:0.8;}.cls-6{stroke:#34495e;stroke-miterlimit:10;}</style></defs><title>ex_result</title><path class="cls-1" d="M10,57.47c-1.37,0-1.5-.13-1.5-1.5V15.53h47V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M55,16V56a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,54,57H10a3.25,3.25,0,0,1-.9-.08h0A2.17,2.17,0,0,1,9,56V16H55m1-1H8V56c0,1.65.35,2,2,2H54c1.65,0,2-.35,2-2V15Z"/><path class="cls-3" d="M8.5,15.53V8c0-1.37.13-1.5,1.5-1.5H54c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-4" d="M54,7a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,55,8v7H9V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,10,7H54m0-1H10C8.35,6,8,6.38,8,8v8H56V8c0-1.65-.35-2-2-2Z"/><g class="cls-5"><line class="cls-6" x1="14" y1="25.97" x2="23.97" y2="25.97"/><line class="cls-6" x1="14" y1="34.34" x2="23.97" y2="34.34"/><line class="cls-6" x1="14" y1="42.71" x2="23.97" y2="42.71"/><line class="cls-6" x1="14" y1="51.08" x2="23.97" y2="51.08"/></g><g class="cls-5"><line class="cls-6" x1="14" y1="21.97" x2="23.97" y2="21.97"/><line class="cls-6" x1="14" y1="30.34" x2="23.97" y2="30.34"/><line class="cls-6" x1="14" y1="38.71" x2="23.97" y2="38.71"/><line class="cls-6" x1="14" y1="47.08" x2="23.97" y2="47.08"/></g><g class="cls-5"><line class="cls-6" x1="14" y1="11.03" x2="23.97" y2="11.03"/></g><g class="cls-5"><line class="cls-6" x1="27" y1="11.03" x2="36.97" y2="11.03"/></g><g class="cls-5"><line class="cls-6" x1="40" y1="11.03" x2="49.97" y2="11.03"/></g><g class="cls-5"><line class="cls-6" x1="27" y1="25.97" x2="36.97" y2="25.97"/><line class="cls-6" x1="27" y1="34.34" x2="36.97" y2="34.34"/><line class="cls-6" x1="27" y1="42.71" x2="36.97" y2="42.71"/><line class="cls-6" x1="27" y1="51.08" x2="36.97" y2="51.08"/></g><g class="cls-5"><line class="cls-6" x1="27" y1="21.97" x2="36.97" y2="21.97"/><line class="cls-6" x1="27" y1="30.34" x2="36.97" y2="30.34"/><line class="cls-6" x1="27" y1="38.71" x2="36.97" y2="38.71"/><line class="cls-6" x1="27" y1="47.08" x2="36.97" y2="47.08"/></g><g class="cls-5"><line class="cls-6" x1="40" y1="25.97" x2="49.97" y2="25.97"/><line class="cls-6" x1="40" y1="34.34" x2="49.97" y2="34.34"/><line class="cls-6" x1="40" y1="42.71" x2="49.97" y2="42.71"/><line class="cls-6" x1="40" y1="51.08" x2="49.97" y2="51.08"/></g><g class="cls-5"><line class="cls-6" x1="40" y1="21.97" x2="49.97" y2="21.97"/><line class="cls-6" x1="40" y1="30.34" x2="49.97" y2="30.34"/><line class="cls-6" x1="40" y1="38.71" x2="49.97" y2="38.71"/><line class="cls-6" x1="40" y1="47.08" x2="49.97" y2="47.08"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-2,.cls-8{fill:#2980b9;}.cls-1,.cls-2{stroke:#2980b9;stroke-linejoin:round;}.cls-2{stroke-linecap:round;stroke-width:2px;}.cls-3,.cls-6{fill:#f0ecb6;}.cls-4{fill:#c18f36;}.cls-5{opacity:0.8;}.cls-6{stroke:#c18f36;stroke-miterlimit:10;}.cls-7{fill:#addff3;}</style></defs><title>ex_scan</title><polygon class="cls-1" points="9.06 50.78 5.58 46.14 12.54 46.14 9.06 50.78"/><line class="cls-2" x1="9.06" y1="46.77" x2="9.06" y2="15.8"/><path class="cls-3" d="M18.43,57.47c-1.38,0-1.5-.12-1.5-1.5V15.53h41V56c0,1.38-.12,1.5-1.5,1.5Z"/><path class="cls-4" d="M57.41,16V56a3.71,3.71,0,0,1-.07.9,2.16,2.16,0,0,1-.93.1h-38a3.54,3.54,0,0,1-.9-.07h0a2.16,2.16,0,0,1-.1-.93V16h40m1-1h-42V56c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V15Z"/><g class="cls-5"><line class="cls-6" x1="25.13" y1="56.97" x2="25.13" y2="15.97"/><line class="cls-6" x1="41.52" y1="56.97" x2="41.52" y2="15.97"/><line class="cls-6" x1="33.32" y1="56.97" x2="33.32" y2="15.97"/><line class="cls-6" x1="49.72" y1="56.97" x2="49.72" y2="15.97"/><line class="cls-6" x1="17.42" y1="23.97" x2="57.4" y2="23.97"/><line class="cls-6" x1="17.42" y1="32.34" x2="57.4" y2="32.34"/><line class="cls-6" x1="17.42" y1="40.71" x2="57.4" y2="40.71"/><line class="cls-6" x1="17.42" y1="49.08" x2="57.4" y2="49.08"/></g><path class="cls-7" d="M49.73,15.53v-9h6.69c1.37,0,1.5.12,1.5,1.5v7.5Z"/><path class="cls-8" d="M56.42,7a3.54,3.54,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v7H50.23V7h6.19m0-1H49.23V16h9.19V8c0-1.65-.35-2-2-2Z"/><path class="cls-7" d="M16.92,15.53V8c0-1.38.13-1.5,1.5-1.5h6.7v9Z"/><path class="cls-8" d="M24.62,7v8h-7.2V8a3.18,3.18,0,0,1,.08-.9,2.08,2.08,0,0,1,.92-.1h6.2m1-1h-7.2c-1.65,0-2,.35-2,2v8h9.2V6Z"/><rect class="cls-7" x="41.52" y="6.53" width="8.19" height="9"/><path class="cls-8" d="M49.21,7v8H42V7h7.19m1-1H41V16h9.19V6Z"/><rect class="cls-7" x="33.33" y="6.53" width="8.19" height="9"/><path class="cls-8" d="M41,7v8H33.83V7H41m1-1H32.83V16H42V6Z"/><rect class="cls-7" x="25.14" y="6.53" width="8.17" height="9"/><path class="cls-8" d="M32.81,7v8H25.64V7h7.17m1-1H24.64V16h9.17V6Z"/></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-4{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{opacity:0.8;}.cls-4{stroke:#c18f36;stroke-miterlimit:10;}.cls-5{fill:#addff3;}.cls-6{fill:#2980b9;}.cls-7,.cls-8{fill:#528d19;stroke:#528d19;stroke-linejoin:round;}.cls-8{stroke-linecap:round;stroke-width:2px;}.cls-9{fill:#34495e;}</style></defs><title>ex_seek</title><path class="cls-1" d="M18,57.46c-1.37,0-1.5-.13-1.5-1.5V15.52h41V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M57,16V56a3.28,3.28,0,0,1-.08.9A2.18,2.18,0,0,1,56,57H18a3.25,3.25,0,0,1-.9-.08h0A2.18,2.18,0,0,1,17,56V16H57m1-1H16V56c0,1.65.35,2,2,2H56c1.65,0,2-.35,2-2V15Z"/><g class="cls-3"><line class="cls-4" x1="24.7" y1="56.95" x2="24.7" y2="15.96"/><line class="cls-4" x1="41.1" y1="56.95" x2="41.1" y2="15.96"/><line class="cls-4" x1="32.9" y1="56.95" x2="32.9" y2="15.96"/><line class="cls-4" x1="49.3" y1="56.95" x2="49.3" y2="15.96"/><line class="cls-4" x1="17" y1="23.95" x2="56.97" y2="23.95"/><line class="cls-4" x1="17" y1="32.32" x2="56.97" y2="32.32"/><line class="cls-4" x1="17" y1="40.69" x2="56.97" y2="40.69"/><line class="cls-4" x1="17" y1="49.06" x2="56.97" y2="49.06"/></g><path class="cls-5" d="M49.31,15.51v-9H56c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-6" d="M56,7a3.25,3.25,0,0,1,.9.08h0A2.18,2.18,0,0,1,57,8v7H49.81V7H56m0-1H48.81V16H58V8c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M16.51,15.51V8c0-1.37.13-1.5,1.5-1.5H24.7v9Z"/><path class="cls-6" d="M24.2,7v8H17V8a3.28,3.28,0,0,1,.08-.9A2.18,2.18,0,0,1,18,7H24.2m1-1H18c-1.65,0-2,.35-2,2v8H25.2V6Z"/><rect class="cls-5" x="41.1" y="6.51" width="8.19" height="9"/><path class="cls-6" d="M48.79,7v8H41.6V7h7.18m1-1H40.61V16h9.19V6Z"/><rect class="cls-5" x="32.91" y="6.51" width="8.19" height="9"/><path class="cls-6" d="M40.6,7v8H33.41V7H40.6m1-1H32.42V16H41.6V6Z"/><rect class="cls-5" x="24.72" y="6.51" width="8.17" height="9"/><path class="cls-6" d="M32.4,7v8H25.22V7H32.4m1-1H24.22V16H33.4V6Z"/><polygon class="cls-7" points="14.91 53.1 11.53 50.57 11.53 55.63 14.91 53.1"/><line class="cls-8" x1="11.25" y1="53.1" x2="4.14" y2="53.1"/><polygon class="cls-7" points="14.91 36.29 11.53 33.76 11.53 38.82 14.91 36.29"/><line class="cls-8" x1="11.25" y1="36.29" x2="4.14" y2="36.29"/><line class="cls-8" x1="4" y1="15.66" x2="4" y2="53.1"/><rect class="cls-9" x="17.99" y="33.77" width="5.22" height="5.44"/><rect class="cls-9" x="17.99" y="50.57" width="5.22" height="5.44"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{opacity:0.7;}.cls-2{fill:#f0ecb6;}.cls-3{fill:#c18f35;}.cls-4{fill:#d3d4f3;}.cls-5{fill:#666bd1;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}</style></defs><title>ex_setop</title><g class="cls-1"><rect class="cls-2" x="46.01" y="35.58" width="7" height="7"/><path class="cls-3" d="M52.51,36.08v6h-6v-6h6m1-1h-8v8h8v-8Z"/><path class="cls-2" d="M19.51,49.56a1.5,1.5,0,0,1-1.5-1.5v-5.5h7v7Z"/><path class="cls-3" d="M24.51,43.06v6h-5a1,1,0,0,1-1-1v-5h6m1-1h-8v6a2,2,0,0,0,2,2h6v-8Z"/><rect class="cls-2" x="25.04" y="42.56" width="7" height="7"/><path class="cls-3" d="M31.54,43.06v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-2" x="32.01" y="42.56" width="7" height="7"/><path class="cls-3" d="M38.51,43.06v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-2" x="39.04" y="42.56" width="7" height="7"/><path class="cls-3" d="M45.54,43.06v6h-6v-6h6m1-1h-8v8h8v-8Z"/><path class="cls-2" d="M46,49.56v-7h7v5.5a1.5,1.5,0,0,1-1.5,1.5Z"/><path class="cls-3" d="M52.51,43.06v5a1,1,0,0,1-1,1h-5v-6h6m1-1h-8v8h6a2,2,0,0,0,2-2v-6Z"/><path class="cls-2" d="M46,28.43v-7h5.5a1.5,1.5,0,0,1,1.5,1.5v5.5Z"/><path class="cls-3" d="M51.51,21.93a1,1,0,0,1,1,1v5h-6v-6h5m0-1h-6v8h8v-6a2,2,0,0,0-2-2Z"/><rect class="cls-2" x="46.01" y="28.5" width="7" height="7"/><path class="cls-3" d="M52.51,29v6h-6V29h6m1-1h-8v8h8V28Z"/></g><g class="cls-1"><rect class="cls-4" x="10.99" y="28.36" width="7" height="7"/><path class="cls-5" d="M17.49,28.86v6h-6v-6h6m1-1h-8v8h8v-8Z"/><path class="cls-4" d="M12.49,42.36a1.5,1.5,0,0,1-1.5-1.5v-5.5h7v7Z"/><path class="cls-5" d="M17.49,35.86v6h-5a1,1,0,0,1-1-1v-5h6m1-1h-8v6a2,2,0,0,0,2,2h6v-8Z"/><rect class="cls-4" x="10.99" y="21.28" width="7" height="7"/><path class="cls-5" d="M17.49,21.78v6h-6v-6h6m1-1h-8v8h8v-8Z"/><path class="cls-4" d="M11,21.44v-5.5a1.5,1.5,0,0,1,1.5-1.5H18v7Z"/><path class="cls-5" d="M17.49,14.94v6h-6v-5a1,1,0,0,1,1-1h5m1-1h-6a2,2,0,0,0-2,2v6h8v-8Z"/><rect class="cls-4" x="17.96" y="14.44" width="7" height="7"/><path class="cls-5" d="M24.46,14.94v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-4" x="24.99" y="14.44" width="7" height="7"/><path class="cls-5" d="M31.49,14.94v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-4" x="32.01" y="14.44" width="7" height="7"/><path class="cls-5" d="M38.51,14.94v6h-6v-6h6m1-1h-8v8h8v-8Z"/><path class="cls-4" d="M39,21.44v-7h5.5a1.5,1.5,0,0,1,1.5,1.5v5.5Z"/><path class="cls-5" d="M44.49,14.94a1,1,0,0,1,1,1v5h-6v-6h5m0-1h-6v8h8v-6a2,2,0,0,0-2-2Z"/></g><rect class="cls-6" x="18.01" y="21.43" width="7" height="7"/><path class="cls-7" d="M24.51,21.93v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="25.04" y="21.43" width="7" height="7"/><path class="cls-7" d="M31.54,21.93v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="39.04" y="21.43" width="7" height="7"/><path class="cls-7" d="M45.54,21.93v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="39.04" y="28.5" width="7" height="7"/><path class="cls-7" d="M45.54,29v6h-6V29h6m1-1h-8v8h8V28Z"/><rect class="cls-6" x="18.01" y="35.58" width="7" height="7"/><path class="cls-7" d="M24.51,36.08v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="25.04" y="35.58" width="7" height="7"/><path class="cls-7" d="M31.54,36.08v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="32.01" y="35.58" width="7" height="7"/><path class="cls-7" d="M38.51,36.08v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="39.04" y="35.58" width="7" height="7"/><path class="cls-7" d="M45.54,36.08v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="32.01" y="21.43" width="7" height="7"/><path class="cls-7" d="M38.51,21.93v6h-6v-6h6m1-1h-8v8h8v-8Z"/><rect class="cls-6" x="18.01" y="28.5" width="7" height="7"/><path class="cls-7" d="M24.51,29v6h-6V29h6m1-1h-8v8h8V28Z"/><rect class="cls-6" x="25.04" y="28.5" width="7" height="7"/><path class="cls-7" d="M31.54,29v6h-6V29h6m1-1h-8v8h8V28Z"/><rect class="cls-6" x="32.01" y="28.5" width="7" height="7"/><path class="cls-7" d="M38.51,29v6h-6V29h6m1-1h-8v8h8V28Z"/></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#d3d4f3;}.cls-2{fill:#666bd1;}.cls-3{fill:#b6eeff;}.cls-4{fill:#0cc5ff;}.cls-5{fill:#c8ffac;}.cls-6{fill:#48d601;}.cls-7{fill:#f0ecb6;}.cls-8{fill:#c18f35;}.cls-9{fill:#ffe7e7;}.cls-10{fill:#ff3d3d;}.cls-11{fill:#addff3;}.cls-12{fill:#2980b9;}.cls-13{fill:#34495e;}.cls-14,.cls-15{fill:#528d19;stroke:#528d19;stroke-linejoin:round;}.cls-15{stroke-linecap:round;stroke-width:2px;}</style></defs><title>ex_sort</title><path class="cls-1" d="M13.19,50.94c-1.37,0-1.5-.13-1.5-1.5v-4.8H23v6.3Z"/><path class="cls-2" d="M22.47,45.14v5.3H13.19a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-4.3H22.47m1-1H11.19v5.3c0,1.65.35,2,2,2H23.47v-7.3Z"/><rect class="cls-3" x="11.69" y="38.31" width="11.28" height="6.3"/><path class="cls-4" d="M22.47,38.81v5.3H12.19v-5.3H22.47m1-1H11.19v7.3H23.47v-7.3Z"/><rect class="cls-5" x="11.69" y="31.97" width="11.28" height="6.31"/><path class="cls-6" d="M22.47,32.47v5.3H12.19v-5.3H22.47m1-1H11.19v7.3H23.47v-7.3Z"/><rect class="cls-7" x="11.69" y="25.68" width="11.28" height="6.3"/><path class="cls-8" d="M22.47,26.18v5.3H12.19v-5.3H22.47m1-1H11.19v7.3H23.47v-7.3Z"/><rect class="cls-9" x="11.69" y="19.38" width="11.28" height="6.3"/><path class="cls-10" d="M22.47,19.88v5.3H12.19v-5.3H22.47m1-1H11.19v7.3H23.47v-7.3Z"/><path class="cls-11" d="M11.69,19.36v-4.8c0-1.37.22-1.44,1.07-1.49H21.9c.85,0,1.07.12,1.07,1.49v4.8Z"/><path class="cls-12" d="M21.87,13.56h0a2.24,2.24,0,0,1,.5.07h0a2.23,2.23,0,0,1,.1.92v4.3H12.19v-4.3a3.07,3.07,0,0,1,.08-.9,1.3,1.3,0,0,1,.52-.09h9.08m1.6-1h0Zm0,0H12.74c-1.25.07-1.54.5-1.54,2v5.3H23.47v-5.3c0-1.48-.29-1.91-1.54-2Z"/><path class="cls-13" d="M17.51,20.93v3.36h-.77V20.93Z"/><path class="cls-13" d="M19.32,20.93v3.36h-.77V20.93Z"/><path class="cls-13" d="M15.67,20.93v3.36H14.9V20.93Z"/><path class="cls-13" d="M17.51,27.22v3.36h-.77V27.22Z"/><path class="cls-13" d="M19.32,27.22v3.36h-.77V27.22Z"/><path class="cls-13" d="M21.07,27.22v3.36H20.3V27.22Z"/><path class="cls-13" d="M14,27.22v3.36h-.77V27.22Z"/><path class="cls-13" d="M15.67,27.22v3.36H14.9V27.22Z"/><path class="cls-13" d="M18.65,39.78v3.36h-.77V39.78Z"/><path class="cls-13" d="M20.4,39.78v3.36h-.77V39.78Z"/><path class="cls-13" d="M15.23,39.78v3.36h-.77V39.78Z"/><path class="cls-13" d="M16.87,39.78v3.36H16.1V39.78Z"/><path class="cls-13" d="M17.51,33.59v3.36h-.77V33.59Z"/><path class="cls-13" d="M18.65,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M16.87,46.11v3.36H16.1V46.11Z"/><path class="cls-7" d="M42.53,50.94c-1.37,0-1.5-.13-1.5-1.5v-4.8H52.31v6.3Z"/><path class="cls-8" d="M51.81,45.14v5.3H42.53a3.26,3.26,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-4.3H51.81m1-1H40.53v5.3c0,1.65.35,2,2,2H52.81v-7.3Z"/><rect class="cls-3" x="41.03" y="38.31" width="11.28" height="6.3"/><path class="cls-4" d="M51.81,38.81v5.3H41.53v-5.3H51.81m1-1H40.53v7.3H52.81v-7.3Z"/><rect class="cls-9" x="41.03" y="31.97" width="11.28" height="6.31"/><path class="cls-10" d="M51.81,32.47v5.3H41.53v-5.3H51.81m1-1H40.53v7.3H52.81v-7.3Z"/><rect class="cls-1" x="41.03" y="25.68" width="11.28" height="6.3"/><path class="cls-2" d="M51.81,26.18v5.3H41.53v-5.3H51.81m1-1H40.53v7.3H52.81v-7.3Z"/><rect class="cls-5" x="41.03" y="19.38" width="11.28" height="6.3"/><path class="cls-6" d="M51.81,19.88v5.3H41.53v-5.3H51.81m1-1H40.53v7.3H52.81v-7.3Z"/><path class="cls-11" d="M41,19.36v-4.8c0-1.37.22-1.44,1.07-1.49h9.14c.85,0,1.07.12,1.07,1.49v4.8Z"/><path class="cls-12" d="M51.21,13.56h0a2.24,2.24,0,0,1,.5.07h0a2.23,2.23,0,0,1,.1.92v4.3H41.53v-4.3a3.07,3.07,0,0,1,.08-.9,1.3,1.3,0,0,1,.52-.09h9.08m1.6-1h0Zm0,0H42.07c-1.25.07-1.54.5-1.54,2v5.3H52.81v-5.3c0-1.48-.29-1.91-1.54-2Z"/><path class="cls-13" d="M46.84,33.44V36.8h-.77V33.44Z"/><path class="cls-13" d="M48.66,33.44V36.8h-.77V33.44Z"/><path class="cls-13" d="M45,33.44V36.8h-.77V33.44Z"/><path class="cls-13" d="M46.84,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M48.66,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M50.41,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M43.36,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M45,46.11v3.36h-.77V46.11Z"/><path class="cls-13" d="M48,39.78v3.36h-.77V39.78Z"/><path class="cls-13" d="M49.73,39.78v3.36H49V39.78Z"/><path class="cls-13" d="M44.57,39.78v3.36H43.8V39.78Z"/><path class="cls-13" d="M46.2,39.78v3.36h-.77V39.78Z"/><path class="cls-13" d="M46.84,20.85v3.36h-.77V20.85Z"/><path class="cls-13" d="M47.73,27.22v3.36H47V27.22Z"/><path class="cls-13" d="M46,27.22v3.36h-.77V27.22Z"/><polygon class="cls-14" points="37.38 32 34 29.47 34 34.53 37.38 32"/><line class="cls-15" x1="33.72" y1="32" x2="26.62" y2="32"/></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{fill:#addff3;}.cls-4{fill:#2980b9;}.cls-5,.cls-6,.cls-8{fill:none;}.cls-5{stroke:#c18f35;opacity:0.8;}.cls-10,.cls-11,.cls-5,.cls-6,.cls-8{stroke-linejoin:round;}.cls-6{stroke:#666bd1;}.cls-11,.cls-6,.cls-8{stroke-linecap:round;}.cls-6,.cls-8{stroke-width:1.5px;}.cls-7{fill:#666bd1;}.cls-8{stroke:#8d8119;}.cls-9{fill:#8d8119;}.cls-10,.cls-11{fill:#528d19;stroke:#528d19;}.cls-11{stroke-width:2px;}</style></defs><title>ex_subplan</title><path class="cls-1" d="M9,53.38c-1.37,0-1.5-.13-1.5-1.5V40.38h7.28v13Z"/><path class="cls-2" d="M14.23,40.88v12H9a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-11h6.28m1-1H7v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-1" d="M14.72,53.38v-13H22v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M21.5,40.88v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H15.22v-12H21.5m1-1H14.22v14H20.5c1.65,0,2-.35,2-2v-12Z"/><path class="cls-3" d="M7.45,40.38v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-4" d="M14.23,34.88v5H8v-4A3.28,3.28,0,0,1,8,35a2.18,2.18,0,0,1,.92-.1h5.28m1-1H9c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-3" d="M14.72,40.38v-6H20.5c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-4" d="M20.5,34.88a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v4H15.22v-5H20.5m0-1H14.22v7H22.5v-5c0-1.65-.35-2-2-2Z"/><line class="cls-5" x1="14.48" y1="46.73" x2="21.97" y2="46.73"/><line class="cls-5" x1="7.48" y1="46.73" x2="14.22" y2="46.73"/><path class="cls-1" d="M43.53,53.38c-1.37,0-1.5-.13-1.5-1.5V40.38h7.28v13Z"/><path class="cls-2" d="M48.81,40.88v12H43.53a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92v-11h6.28m1-1H41.53v12c0,1.65.35,2,2,2h6.28v-14Z"/><path class="cls-1" d="M49.3,53.38v-13h7.28v11.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M56.08,40.88v11a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H49.8v-12h6.28m1-1H48.8v14h6.28c1.65,0,2-.35,2-2v-12Z"/><path class="cls-3" d="M42,40.38v-4.5c0-1.37.13-1.5,1.5-1.5h5.78v6Z"/><path class="cls-4" d="M48.81,34.88v5H42.53v-4a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H43.53c-1.65,0-2,.35-2,2v5h8.28v-7Z"/><path class="cls-3" d="M49.3,40.38v-6h5.78c1.37,0,1.5.13,1.5,1.5v4.5Z"/><path class="cls-4" d="M55.08,34.88A3.25,3.25,0,0,1,56,35h0a2.17,2.17,0,0,1,.1.92v4H49.8v-5h5.28m0-1H48.8v7h8.28v-5c0-1.65-.35-2-2-2Z"/><line class="cls-5" x1="49.06" y1="46.73" x2="56.55" y2="46.73"/><line class="cls-5" x1="42.06" y1="46.73" x2="48.8" y2="46.73"/><path class="cls-6" d="M23.5,12.88a3,3,0,0,1,3-3h11a3,3,0,0,1,3,3v12a3,3,0,0,1-3,3h-11a3,3,0,0,1-3-3V19"/><polygon class="cls-7" points="23.5 16.54 21.27 19.51 25.73 19.51 23.5 16.54"/><path class="cls-8" d="M27,15.38c0-1.65.35-2,2-2h6c1.65,0,2,.35,2,2v7c0,1.65-.35,2-2,2H29.25c-1.65,0-2-.35-2-2V19.74"/><polygon class="cls-9" points="27.22 18.55 25.24 20.93 29 20.93 27.22 18.55"/><polygon class="cls-10" points="40.91 44.2 37.53 41.67 37.53 46.73 40.91 44.2"/><line class="cls-11" x1="39.25" y1="44.2" x2="32.14" y2="44.2"/><polygon class="cls-10" points="23.23 44.2 26.61 41.67 26.61 46.73 23.23 44.2"/><line class="cls-11" x1="24.9" y1="44.2" x2="32" y2="44.2"/><line class="cls-11" x1="32" y1="29.77" x2="32" y2="44.2"/></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f3c7d7;}.cls-2{fill:#d04465;}.cls-3{opacity:0.5;}.cls-4{fill:none;stroke:#d04465;}.cls-4,.cls-7,.cls-8{stroke-linejoin:round;}.cls-5{fill:#addff3;}.cls-6,.cls-7,.cls-8{fill:#2980b9;}.cls-7,.cls-8{stroke:#2980b9;}.cls-8{stroke-linecap:round;stroke-width:2px;}</style></defs><title>table_fun_scan</title><path class="cls-1" d="M22.85,49c-1.37,0-1.5-.12-1.5-1.5V24H54.14V47.47c0,1.38-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M53.64,24.53V47.47a3.18,3.18,0,0,1-.08.9s-.19.1-.92.1H22.85A3.39,3.39,0,0,1,22,48.4h0a2.4,2.4,0,0,1-.1-.93V24.53H53.64m1-1H20.85V47.47c0,1.65.35,2,2,2H52.64c1.65,0,2-.35,2-2V23.53Z"/><g class="cls-3"><line class="cls-4" x1="37.75" y1="48.47" x2="37.75" y2="24.47"/><line class="cls-4" x1="29.55" y1="48.47" x2="29.55" y2="24.47"/><line class="cls-4" x1="45.95" y1="48.47" x2="45.95" y2="24.47"/><line class="cls-4" x1="21.85" y1="32.47" x2="53.62" y2="32.47"/><line class="cls-4" x1="21.85" y1="40.84" x2="53.62" y2="40.84"/></g><path class="cls-5" d="M46,24V15h6.69c1.38,0,1.5.12,1.5,1.5V24Z"/><path class="cls-6" d="M52.64,15.53a3.44,3.44,0,0,1,.9.07h0a2.16,2.16,0,0,1,.1.93v7H46.45v-8h6.19m0-1H45.45v10h9.19v-8c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M21.35,24v-7.5c0-1.38.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-6" d="M29,15.53v8H21.85v-7a2.7,2.7,0,0,1,.08-.9s.19-.1.92-.1H29m1-1H22.85c-1.65,0-2,.35-2,2v8H30v-10Z"/><rect class="cls-5" x="37.75" y="15.03" width="8.19" height="9"/><path class="cls-6" d="M45.43,15.53v8H38.24v-8h7.18m1-1H37.25v10h9.19v-10Z"/><rect class="cls-5" x="29.56" y="15.03" width="8.19" height="9"/><path class="cls-6" d="M37.24,15.53v8H30.05v-8h7.18m1-1H29.06v10h9.19v-10Z"/><polygon class="cls-7" points="12.83 47.38 9.36 42.73 16.31 42.73 12.83 47.38"/><line class="cls-8" x1="12.83" y1="43.36" x2="12.83" y2="16.39"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#e6e6e6;}.cls-2{fill:#818181;}.cls-3{fill:#fbe65a;}.cls-4{fill:#c4953b;}.cls-5{fill:none;stroke:#2980b9;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}.cls-6{fill:#2980b9;}</style></defs><title>ex_tid_scan</title><path class="cls-1" d="M35.47,50.69c-9.57,0-16-2.84-16-5.5s6.43-5.5,16-5.5,16,2.84,16,5.5S45,50.69,35.47,50.69Z"/><path class="cls-2" d="M35.47,40.19c8.87,0,15.5,2.64,15.5,5s-6.63,5-15.5,5S20,47.55,20,45.19s6.63-5,15.5-5m0-1c-9.11,0-16.5,2.69-16.5,6s7.39,6,16.5,6S52,48.5,52,45.19s-7.39-6-16.5-6Z"/><path class="cls-1" d="M35.47,46.28c-9.57,0-16-2.84-16-5.5s6.43-5.5,16-5.5,16,2.84,16,5.5S45,46.28,35.47,46.28Z"/><path class="cls-2" d="M35.47,35.78c8.87,0,15.5,2.64,15.5,5s-6.63,5-15.5,5S20,43.14,20,40.78s6.63-5,15.5-5m0-1c-9.11,0-16.5,2.69-16.5,6s7.39,6,16.5,6,16.5-2.69,16.5-6-7.39-6-16.5-6Z"/><path class="cls-1" d="M35.47,42c-9.57,0-16-2.84-16-5.5s6.43-5.5,16-5.5,16,2.84,16,5.5S45,42,35.47,42Z"/><path class="cls-2" d="M35.47,31.46c8.87,0,15.5,2.64,15.5,5s-6.63,5-15.5,5S20,38.83,20,36.46s6.63-5,15.5-5m0-1c-9.11,0-16.5,2.69-16.5,6s7.39,6,16.5,6,16.5-2.69,16.5-6-7.39-6-16.5-6Z"/><path class="cls-1" d="M35.47,37.52c-9.57,0-16-2.84-16-5.5s6.43-5.5,16-5.5,16,2.84,16,5.5S45,37.52,35.47,37.52Z"/><path class="cls-2" d="M35.47,27C44.34,27,51,29.66,51,32s-6.63,5-15.5,5S20,34.38,20,32s6.63-5,15.5-5m0-1C26.36,26,19,28.7,19,32s7.39,6,16.5,6S52,35.33,52,32s-7.39-6-16.5-6Z"/><path class="cls-1" d="M35.47,32.69c-9.57,0-16-2.84-16-5.5s6.43-5.5,16-5.5,16,2.84,16,5.5S45,32.69,35.47,32.69Z"/><path class="cls-2" d="M35.47,22.19c8.87,0,15.5,2.64,15.5,5s-6.63,5-15.5,5S20,29.55,20,27.19s6.63-5,15.5-5m0-1c-9.11,0-16.5,2.69-16.5,6s7.39,6,16.5,6S52,30.5,52,27.19s-7.39-6-16.5-6Z"/><path class="cls-3" d="M19.55,26.69c.73-2.45,6.72-4.91,15.43-5v5Z"/><path class="cls-4" d="M34.47,22.2v4H20.35c1.46-2,7-3.83,14.12-4m1-1c-9.11,0-16.5,2.69-16.5,6h16.5v-6Z"/><path class="cls-5" d="M12,26c2.38-8.37,12.92-13.21,22-13.21"/><path class="cls-6" d="M40.4,12.81a31.73,31.73,0,0,0-9,5l1.81-5-1.81-5A31.7,31.7,0,0,0,40.4,12.81Z"/></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-3{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{stroke:#c18f35;}.cls-3,.cls-4,.cls-7,.cls-8{stroke-miterlimit:10;}.cls-3,.cls-7{opacity:0.8;}.cls-4{fill:#34495e;stroke:#528d19;}.cls-5,.cls-7,.cls-8{fill:#d3d4f3;}.cls-6{fill:#666bd1;}.cls-7{stroke:#666bd1;}.cls-8{stroke:#c00;stroke-linecap:round;stroke-width:1.5px;opacity:0.5;}</style></defs><title>ex_unique</title><rect class="cls-1" x="40.3" y="17.26" width="9.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M48.79,17.76a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-7a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V18.76a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h7m0-1h-7c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h7c1.65,0,2-.35,2-2V18.76c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="13.71" y="10.76" width="9.98" height="18.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M22.2,11.26a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92V27.95a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-7a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V12.26a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h7m0-1h-7c-1.65,0-2,.35-2,2V27.95c0,1.65.35,2,2,2h7c1.65,0,2-.35,2-2V12.26c0-1.65-.35-2-2-2Z"/><line class="cls-3" x1="14.1" y1="17.17" x2="23.34" y2="17.17"/><line class="cls-3" x1="14.1" y1="23.4" x2="23.34" y2="23.4"/><path class="cls-4" d="M28.87,27.47A4.42,4.42,0,0,0,30.92,27,2.81,2.81,0,0,0,32,25.88a3.59,3.59,0,0,0,.4-1.4c0-.5.07-.36.09-.83a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2c0-.47,0-.33-.09-.83a3.58,3.58,0,0,0-.4-1.4,2.82,2.82,0,0,0-1.06-1.08,4.47,4.47,0,0,0-2.05-.51V12.3l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07,7,7,0,0,1,.16,1.29c0,.47,0-.12,0-.12a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73A2.39,2.39,0,0,0,33,22.47a7.9,7.9,0,0,0-.12,1.5s-.09.78-.18,1.17a3.65,3.65,0,0,1-.43,1.07,3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><rect class="cls-5" x="40.3" y="41.05" width="9.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-6" d="M48.79,41.55a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-7a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V42.55a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h7m0-1h-7c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h7c1.65,0,2-.35,2-2V42.55c0-1.65-.35-2-2-2Z"/><rect class="cls-5" x="13.79" y="34.55" width="9.98" height="18.69" rx="1.5" ry="1.5"/><path class="cls-6" d="M22.28,35.05a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92V51.74a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-7a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V36.05a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h7m0-1h-7c-1.65,0-2,.35-2,2V51.74c0,1.65.35,2,2,2h7c1.65,0,2-.35,2-2V36.05c0-1.65-.35-2-2-2Z"/><line class="cls-7" x1="14.18" y1="40.97" x2="23.42" y2="40.97"/><line class="cls-7" x1="14.18" y1="47.2" x2="23.42" y2="47.2"/><path class="cls-4" d="M28.87,51.26a4.42,4.42,0,0,0,2.05-.51A2.81,2.81,0,0,0,32,49.67a3.59,3.59,0,0,0,.4-1.4c0-.5.07-.36.09-.83a9.28,9.28,0,0,1,.11-1.2,2.76,2.76,0,0,1,.26-.83,2.37,2.37,0,0,1,.44-.6,2.53,2.53,0,0,1,.62-.46,4,4,0,0,1,.64-.27,3.5,3.5,0,0,1,.6-.13c.19,0,.19-.1,0-.12a3.52,3.52,0,0,1-.6-.13,3.65,3.65,0,0,1-.64-.27,2.52,2.52,0,0,1-.62-.46,2.41,2.41,0,0,1-.44-.6,2.77,2.77,0,0,1-.26-.83,9.31,9.31,0,0,1-.11-1.2c0-.47,0-.33-.09-.83a3.58,3.58,0,0,0-.4-1.4A2.82,2.82,0,0,0,30.92,37a4.47,4.47,0,0,0-2.05-.51V36.1l.53,0a4.11,4.11,0,0,1,.67.11,5.12,5.12,0,0,1,.72.23,2.89,2.89,0,0,1,.7.41,3.34,3.34,0,0,1,.83.9,3.66,3.66,0,0,1,.43,1.07,7,7,0,0,1,.16,1.29c0,.47,0-.12,0-.12a7.9,7.9,0,0,0,.12,1.5,2.37,2.37,0,0,0,.47,1.06,2.65,2.65,0,0,0,1,.73.69.69,0,0,1,0,1.17,2.66,2.66,0,0,0-1,.73A2.39,2.39,0,0,0,33,46.27a7.9,7.9,0,0,0-.12,1.5s-.09.78-.18,1.17A3.65,3.65,0,0,1,32.32,50a3.31,3.31,0,0,1-.83.9,2.9,2.9,0,0,1-.7.41,5.39,5.39,0,0,1-.72.23,4.34,4.34,0,0,1-.67.11l-.53,0Z"/><line class="cls-8" x1="14.1" y1="29.05" x2="23.34" y2="10.99"/><line class="cls-8" x1="14.18" y1="52.92" x2="23.42" y2="34.87"/></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#1cafe4;}</style></defs><title>ex_unknown</title><path class="cls-1" d="M23.34,13.2a14.76,14.76,0,0,1,8.16-2.14,17.57,17.57,0,0,1,10.56,3q4.2,3,4.2,9a10.18,10.18,0,0,1-1.82,6.16,21,21,0,0,1-4.09,3.88l-2,1.55a6,6,0,0,0-2.16,3A12.5,12.5,0,0,0,35.83,41H28.2a22.11,22.11,0,0,1,.9-6.57,11.57,11.57,0,0,1,3.76-4.18l2-1.6A7.17,7.17,0,0,0,36.53,27a5.67,5.67,0,0,0,1.12-3.4,6.58,6.58,0,0,0-1.25-3.9q-1.25-1.76-4.56-1.76t-4.62,2.17a8.34,8.34,0,0,0-1.36,4.5H17.74Q18.08,16.55,23.34,13.2ZM28,44.81h8.41v8.13H28Z"/></svg>

After

Width:  |  Height:  |  Size: 615 B

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-5{fill:#f0ecb6;}.cls-2{fill:#c18f36;}.cls-3{fill:#ffbd30;}.cls-4{opacity:0.8;}.cls-5{stroke:#c18f36;stroke-miterlimit:10;}.cls-6{fill:#addff3;}.cls-7{fill:#2980b9;}</style></defs><title>ex_update</title><path class="cls-1" d="M16.73,57.47c-1.37,0-1.5-.13-1.5-1.5V15.53h41V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-2" d="M55.72,16V56a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-38a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V16h40m1-1h-42V56c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V15Z"/><rect class="cls-3" x="32.12" y="41.2" width="7.22" height="7.44"/><rect class="cls-3" x="23.92" y="41.2" width="7.22" height="7.44"/><rect class="cls-3" x="15.72" y="24.48" width="7.22" height="7.44"/><g class="cls-4"><line class="cls-5" x1="23.43" y1="56.97" x2="23.43" y2="15.97"/><line class="cls-5" x1="39.83" y1="56.97" x2="39.83" y2="15.97"/><line class="cls-5" x1="31.63" y1="56.97" x2="31.63" y2="15.97"/><line class="cls-5" x1="48.03" y1="56.97" x2="48.03" y2="15.97"/><line class="cls-5" x1="15.73" y1="23.97" x2="55.7" y2="23.97"/><line class="cls-5" x1="15.73" y1="32.34" x2="55.7" y2="32.34"/><line class="cls-5" x1="15.73" y1="40.71" x2="55.7" y2="40.71"/><line class="cls-5" x1="15.73" y1="49.08" x2="55.7" y2="49.08"/></g><path class="cls-6" d="M48,15.53v-9h6.69c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-7" d="M54.73,7a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H48.53V7h6.19m0-1H47.53V16h9.19V8c0-1.65-.35-2-2-2Z"/><path class="cls-6" d="M15.23,15.53V8c0-1.37.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-7" d="M22.93,7v8H15.73V8a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.19m1-1H16.73c-1.65,0-2,.35-2,2v8h9.19V6Z"/><rect class="cls-6" x="39.83" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M47.52,7v8H40.33V7h7.18m1-1H39.33V16h9.19V6Z"/><rect class="cls-6" x="31.64" y="6.53" width="8.19" height="9"/><path class="cls-7" d="M39.33,7v8H32.14V7h7.18m1-1H31.14V16h9.19V6Z"/><rect class="cls-6" x="23.45" y="6.53" width="8.17" height="9"/><path class="cls-7" d="M31.12,7v8H23.95V7h7.17m1-1H23V16h9.18V6Z"/><path class="cls-2" d="M7.27,28.28A3.37,3.37,0,0,1,13,25.85h0l.13.13.05.05L24.72,37.58a.4.4,0,0,1,.18.2l1.63,5.82v.06h0a.46.46,0,0,1,0,.12.41.41,0,0,1,0,.12s0,0,0,0h0a.4.4,0,0,1-.06.1l0,0,0,0-.1.06h0l-.12,0-.12,0H26l-5.82-1.63a.4.4,0,0,1-.2-.18L8.22,30.64a.4.4,0,0,1-.08-.12A3.35,3.35,0,0,1,7.27,28.28Zm12.9,13.15,1-2h0l-9.93-9.93L9.73,31Zm5,.55-.84.84,1.17.33Zm-1-3.48L22,39.6l-1.09,2.26,2.57.72,1.49-1.49Zm-.42-.7L13.35,27.37l-1.52,1.52,9.93,9.93h0ZM8.1,28.31a2.55,2.55,0,0,0,.83,1.88h0l.22.22,3.62-3.62-.22-.22h0A2.56,2.56,0,0,0,8.1,28.31Z"/><polygon class="cls-1" points="20.17 41.45 21.17 39.42 21.18 39.41 11.25 29.48 9.73 31 20.17 41.45"/><polygon class="cls-1" points="13.35 27.38 11.83 28.9 21.76 38.83 21.77 38.82 23.79 37.83 13.35 27.38"/><path class="cls-1" d="M8.12,28.27A2.55,2.55,0,0,0,9,30.15H9l.22.22,3.62-3.62-.22-.22h0a2.56,2.56,0,0,0-4.45,1.73Z"/><polygon class="cls-1" points="24.22 38.52 21.96 39.6 20.87 41.86 23.44 42.58 24.94 41.09 24.22 38.52"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3{fill:#2980b9;stroke:#2980b9;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style></defs><title>ex_values_scan</title><rect class="cls-1" x="20.5" y="14.17" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M26,14.67a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H22a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V15.67a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H22c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V15.67c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="33.5" y="17.17" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M39,17.67a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H35a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V18.67a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H35c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V18.67c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="46.5" y="20.14" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M52,20.64a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H48a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V21.64a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H48c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V21.64c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="20.5" y="26.25" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M26,26.75a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H22a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V27.75a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H22c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V27.75c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="33.5" y="29.25" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M39,29.75a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H35a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V30.75a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H35c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V30.75c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="46.5" y="32.22" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M52,32.72a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H48a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V33.72a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H48c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V33.72c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="20.5" y="38.17" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M26,38.67a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H22a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V39.67a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H22c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V39.67c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="33.5" y="41.17" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M39,41.67a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H35a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V42.67a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H35c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V42.67c0-1.65-.35-2-2-2Z"/><rect class="cls-1" x="46.5" y="44.14" width="6.98" height="5.69" rx="1.5" ry="1.5"/><path class="cls-2" d="M52,44.64a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v2.69a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H48a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V45.64a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h4m0-1H48c-1.65,0-2,.35-2,2v2.69c0,1.65.35,2,2,2h4c1.65,0,2-.35,2-2V45.64c0-1.65-.35-2-2-2Z"/><polygon class="cls-3" points="13.49 49.49 10.01 44.85 16.97 44.85 13.49 49.49"/><line class="cls-3" x1="13.49" y1="45.48" x2="13.49" y2="14.51"/></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#f0ecb6;}.cls-2{fill:#c18f35;}.cls-3,.cls-8{fill:#c8ffac;}.cls-4{fill:#48d601;}.cls-5{fill:#d3d4f3;}.cls-6{fill:#666bd1;}.cls-10,.cls-7,.cls-9{fill:none;}.cls-7{stroke:#666bd1;}.cls-10,.cls-11,.cls-7,.cls-9{stroke-linejoin:round;}.cls-7,.cls-9{opacity:0.8;}.cls-8{stroke:#48d601;stroke-miterlimit:10;opacity:0.7;}.cls-9{stroke:#c18f35;}.cls-10,.cls-11{stroke:#34495e;}.cls-10{stroke-linecap:round;}.cls-11{fill:#34495e;}</style></defs><title>ex_window_aggregate</title><g id="ex_broadcast_motion"><rect class="cls-1" x="40.67" y="27.31" width="8.28" height="9"/><path class="cls-2" d="M48.45,27.81v8H41.17v-8h7.28m1-1H40.17v10h9.28v-10Z"/><rect class="cls-1" x="48.97" y="27.31" width="8.28" height="9"/><path class="cls-2" d="M56.75,27.81v8H49.47v-8h7.28m1-1H48.47v10h9.28v-10Z"/><path class="cls-3" d="M42.17,45.29c-1.37,0-1.5-.13-1.5-1.5v-7.5h8.28v9Z"/><path class="cls-4" d="M48.45,36.79v8H42.17a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92v-7h7.28m1-1H40.17v8c0,1.65.35,2,2,2h7.28v-10Z"/><path class="cls-3" d="M49,45.29v-9h8.28v7.5c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M56.75,36.79v7a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H49.47v-8h7.28m1-1H48.47v10h7.28c1.65,0,2-.35,2-2v-8Z"/><path class="cls-5" d="M40.67,27.33v-7.5c0-1.37.13-1.5,1.5-1.5h6.78v9Z"/><path class="cls-6" d="M48.45,18.83v8H41.17v-7a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h6.28m1-1H42.17c-1.65,0-2,.35-2,2v8h9.28v-10Z"/><path class="cls-5" d="M49,27.33v-9h6.78c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-6" d="M55.75,18.83a3.25,3.25,0,0,1,.9.08h0a2.17,2.17,0,0,1,.1.92v7H49.47v-8h6.28m0-1H48.47v10h9.28v-8c0-1.65-.35-2-2-2Z"/><path class="cls-5" d="M11.28,25.49V14c0-1.37.13-1.5,1.5-1.5h5.78v13Z"/><path class="cls-6" d="M18.06,13V25H11.78V14a3.28,3.28,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1h5.28m1-1H12.78c-1.65,0-2,.35-2,2V26h8.28V12Z"/><path class="cls-5" d="M18.57,25.49v-13h5.78c1.37,0,1.5.13,1.5,1.5v11.5Z"/><path class="cls-6" d="M24.35,13a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92V25H19.07V13h5.28m0-1H18.07V26h8.28V14c0-1.65-.35-2-2-2Z"/><line class="cls-7" x1="11.31" y1="18.83" x2="18.05" y2="18.83"/><line class="cls-7" x1="18.33" y1="18.83" x2="25.82" y2="18.83"/><path class="cls-3" d="M12.78,51.51c-1.37,0-1.5-.13-1.5-1.5V38.51h7.28v13Z"/><path class="cls-4" d="M18.06,39V51H12.78a3.25,3.25,0,0,1-.9-.08h0a2.18,2.18,0,0,1-.1-.92V39h6.28m1-1H10.78V50c0,1.65.35,2,2,2h6.28V38Z"/><path class="cls-3" d="M18.57,51.51v-13h7.28V50c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M25.35,39V50a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1H19.07V39h6.28m1-1H18.07V52h6.28c1.65,0,2-.35,2-2V38Z"/><line class="cls-8" x1="18.33" y1="44.86" x2="25.82" y2="44.86"/><line class="cls-8" x1="11.31" y1="44.86" x2="18.05" y2="44.86"/><rect class="cls-1" x="18.57" y="25.49" width="7.28" height="13"/><path class="cls-2" d="M25.35,26V38H19.07V26h6.28m1-1H18.07V39h8.28V25Z"/><line class="cls-9" x1="18.33" y1="31.84" x2="25.82" y2="31.84"/><rect class="cls-1" x="11.28" y="25.49" width="7.28" height="13"/><path class="cls-2" d="M18.06,26V38H11.78V26h6.28m1-1H10.78V39h8.28V25Z"/><line class="cls-9" x1="11.31" y1="31.84" x2="18.05" y2="31.84"/><rect class="cls-10" x="6.25" y="18.84" width="25" height="25.99" rx="2" ry="2"/><polygon class="cls-11" points="39.32 22.95 36.68 24.93 36.68 20.98 39.32 22.95"/><line class="cls-10" x1="37.14" y1="23.05" x2="31.25" y2="23.09"/><polygon class="cls-11" points="39.32 31.84 36.68 33.82 36.68 29.86 39.32 31.84"/><line class="cls-10" x1="37.14" y1="31.94" x2="31.25" y2="31.98"/><polygon class="cls-11" points="39.32 40.6 36.68 42.58 36.68 38.63 39.32 40.6"/><line class="cls-10" x1="37.14" y1="40.7" x2="31.25" y2="40.75"/></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1 @@
<svg id="_1" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1,.cls-9{fill:#2980b9;}.cls-1,.cls-2{stroke:#2980b9;}.cls-1,.cls-2,.cls-6,.cls-7{stroke-linejoin:round;}.cls-2,.cls-6,.cls-7{fill:none;}.cls-2{stroke-linecap:round;stroke-width:2px;}.cls-3{fill:#f3c7d7;}.cls-4{fill:#d04465;}.cls-5{opacity:0.5;}.cls-6,.cls-7{stroke:#d04465;}.cls-7{opacity:0.8;}.cls-8{fill:#addff3;}.cls-10{font-size:10px;fill:#34495e;font-family:HelveticaNeue-Bold, Helvetica Neue;font-weight:700;}.cls-10,.cls-12{letter-spacing:0.1em;}.cls-11{letter-spacing:0.01em;}</style></defs><title>ex_worktable_scan</title><polygon class="cls-1" points="9.72 50.78 6.25 46.14 13.2 46.14 9.72 50.78"/><line class="cls-2" x1="9.72" y1="46.77" x2="9.72" y2="15.8"/><path class="cls-3" d="M17.76,57.47c-1.37,0-1.5-.13-1.5-1.5V15.53h41V56c0,1.37-.13,1.5-1.5,1.5Z"/><path class="cls-4" d="M56.75,16V56a3.28,3.28,0,0,1-.08.9,2.18,2.18,0,0,1-.92.1h-38a3.25,3.25,0,0,1-.9-.08h0a2.17,2.17,0,0,1-.1-.92V16h40m1-1h-42V56c0,1.65.35,2,2,2h38c1.65,0,2-.35,2-2V15Z"/><g class="cls-5"><line class="cls-6" x1="24.46" y1="56.97" x2="24.46" y2="15.97"/><line class="cls-6" x1="40.86" y1="56.97" x2="40.86" y2="15.97"/><line class="cls-6" x1="32.66" y1="56.97" x2="32.66" y2="15.97"/><line class="cls-6" x1="49.06" y1="56.97" x2="49.06" y2="15.97"/><line class="cls-6" x1="16.76" y1="23.97" x2="56.73" y2="23.97"/><line class="cls-7" x1="16.76" y1="32.34" x2="56.73" y2="32.34"/><line class="cls-6" x1="16.76" y1="40.71" x2="56.73" y2="40.71"/><line class="cls-6" x1="16.76" y1="49.08" x2="56.73" y2="49.08"/></g><path class="cls-8" d="M49.06,15.53v-9h6.69c1.37,0,1.5.13,1.5,1.5v7.5Z"/><path class="cls-9" d="M55.76,7a3.25,3.25,0,0,1,.9.08h0a2.18,2.18,0,0,1,.1.92v7H49.56V7h6.19m0-1H48.56V16h9.19V8c0-1.65-.35-2-2-2Z"/><path class="cls-8" d="M16.26,15.53V8c0-1.37.13-1.5,1.5-1.5h6.69v9Z"/><path class="cls-9" d="M24,7v8H16.76V8a3.29,3.29,0,0,1,.08-.9,2.18,2.18,0,0,1,.92-.1H24m1-1H17.76c-1.65,0-2,.35-2,2v8H25V6Z"/><rect class="cls-8" x="40.86" y="6.53" width="8.19" height="9"/><path class="cls-9" d="M48.54,7v8H41.36V7h7.18m1-1H40.36V16h9.19V6Z"/><rect class="cls-8" x="32.67" y="6.53" width="8.19" height="9"/><path class="cls-9" d="M40.36,7v8H33.17V7h7.18m1-1H32.17V16h9.19V6Z"/><rect class="cls-8" x="24.48" y="6.53" width="8.17" height="9"/><path class="cls-9" d="M32.15,7v8H25V7h7.17m1-1H24V16h9.18V6Z"/><text class="cls-10" transform="translate(18.98 33.55)">WORK<tspan class="cls-11"><tspan x="-0.42" y="12">T</tspan><tspan class="cls-12" x="5.78" y="12">ABLE</tspan></tspan></text></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,487 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import { Box, Tab, Tabs } from '@material-ui/core';
import React from 'react';
import _ from 'lodash';
import Graphical from './Graphical';
import TabPanel from '../components/TabPanel';
import gettext from 'sources/gettext';
import ImageMapper from './ImageMapper';
import { makeStyles } from '@material-ui/styles';
import Analysis from './Analysis';
import ExplainStatistics from './ExplainStatistics';
import PropTypes from 'prop-types';
import EmptyPanelMessage from '../components/EmptyPanelMessage';
const useStyles = makeStyles((theme)=>({
tabPanel: {
padding: 0,
backgroundColor: theme.palette.background.default,
}
}));
// Some predefined constants used to calculate image location and its border
var pWIDTH = 100.;
var pHEIGHT = 100.;
var offsetX = 200,
offsetY = 60;
var xMargin = 25,
yMargin = 25;
const DEFAULT_ARROW_SIZE = 2;
function nodeExplainTableData(_planData, _ctx) {
let node_info,
display_text = [],
tooltip = [],
node_extra_info = [],
info = _ctx.explainTable;
// Display: <NODE>[ using <Index> ] [ on <Schema>.<Table>[ as <Alias>]]
if (/Scan/.test(_planData['Node Type'])) {
display_text.push(_planData['Node Type']);
tooltip.push(_planData['Node Type']);
} else {
display_text.push(_planData['image_text']);
tooltip.push(_planData['image_text']);
}
node_info = tooltip.join('');
if (typeof(_planData['Index Name']) !== 'undefined') {
display_text.push(' using ');
tooltip.push(' using ');
display_text.push(_.escape(_planData['Index Name']));
tooltip.push(_planData['Index Name']);
}
if (typeof(_planData['Relation Name']) !== 'undefined') {
display_text.push(' on ');
tooltip.push(' on ');
if (typeof(_planData['Schema']) !== 'undefined') {
display_text.push(_.escape(_planData['Schema']));
tooltip.push(_planData['Schema']);
display_text.push('.');
tooltip.push('.');
}
display_text.push(_.escape(_planData['Relation Name']));
tooltip.push(_planData['Relation Name']);
if (typeof(_planData['Alias']) !== 'undefined') {
display_text.push(' as ');
tooltip.push(' as ');
display_text.push(_.escape(_planData['Alias']));
tooltip.push(_.escape(_planData['Alias']));
}
}
if (
typeof(_planData['Plan Rows']) !== 'undefined' &&
typeof(_planData['Plan Width']) !== 'undefined'
) {
let cost = [
' (cost=',
(typeof(_planData['Startup Cost']) !== 'undefined' ?
_planData['Startup Cost'] : ''),
'..',
(typeof(_planData['Total Cost']) !== 'undefined' ?
_planData['Total Cost'] : ''),
' rows=',
_planData['Plan Rows'],
' width=',
_planData['Plan Width'],
')',
].join('');
display_text.push(cost);
tooltip.push(cost);
}
if (
typeof(_planData['Actual Startup Time']) !== 'undefined' ||
typeof(_planData['Actual Total Time']) !== 'undefined' ||
typeof(_planData['Actual Rows']) !== 'undefined'
) {
let actual = [
' (',
(typeof(_planData['Actual Startup Time']) !== 'undefined' ?
('actual=' + _planData['Actual Startup Time']) + '..' : ''
),
(typeof(_planData['Actual Total Time']) !== 'undefined' ?
_planData['Actual Total Time'] + ' ' : ''
),
(typeof(_planData['Actual Rows']) !== 'undefined' ?
('rows=' + _planData['Actual Rows']) : ''
),
(typeof(_planData['Actual Loops']) !== 'undefined' ?
(' loops=' + _planData['Actual Loops']) : ''
),
')',
].join('');
display_text.push(actual);
tooltip.push(actual);
}
if ('Join Filter' in _planData) {
node_extra_info.push(
'<strong>' + gettext('Join Filter') + '</strong>: ' + _.escape(_planData['Join Filter'])
);
}
if ('Filter' in _planData) {
node_extra_info.push('<strong>' + gettext('Filter') + '</strong>: ' + _.escape(_planData['Filter']));
}
if ('Index Cond' in _planData) {
node_extra_info.push('<strong>' + gettext('Index Cond') + '</strong>: ' + _.escape(_planData['Index Cond']));
}
if ('Hash Cond' in _planData) {
node_extra_info.push('<strong>' + gettext('Hash Cond') + '</strong>: ' + _.escape(_planData['Hash Cond']));
}
if ('Rows Removed by Filter' in _planData) {
node_extra_info.push(
'<strong>' + gettext('Rows Removed by Filter') + '</strong>: ' +
_.escape(_planData['Rows Removed by Filter'])
);
}
if ('Peak Memory Usage' in _planData) {
var buffer = [
'<strong>' + gettext('Buckets') + '</strong>:', _.escape(_planData['Hash Buckets']),
'<strong>' + gettext('Batches') + '</strong>:', _.escape(_planData['Hash Batches']),
'<strong>' + gettext('Memory Usage') + '</strong>:', _.escape(_planData['Peak Memory Usage']), 'kB',
].join(' ');
node_extra_info.push(buffer);
}
if ('Recheck Cond' in _planData) {
node_extra_info.push('<strong>' + gettext('Recheck Cond') + '</strong>: ' + _planData['Recheck Cond']);
}
if ('Exact Heap Blocks' in _planData) {
node_extra_info.push('<strong>' + gettext('Heap Blocks') + '</strong>: exact=' + _planData['Exact Heap Blocks']);
}
info.rows.push({
data: _planData,
display_text: display_text.join(''),
tooltip_text: tooltip.join(''),
node_extra_info: node_extra_info,
});
if (typeof(_planData['exclusive_flag']) !== 'undefined') {
info.show_timings = true;
}
if (typeof(_planData['rowsx_flag']) !== 'undefined') {
info.show_rowsx = true;
}
if (typeof(_planData['Actual Loops']) !== 'undefined') {
info.show_rows = true;
}
if (typeof(_planData['Plan Rows']) !== 'undefined') {
info.show_plan_rows = true;
}
if (typeof(_planData['total_time']) !== 'undefined') {
info.total_time = _planData['total_time'];
}
let node;
if (typeof(_planData['Relation Name']) !== 'undefined') {
let relationName = (
typeof(_planData['Schema']) !== 'undefined' ?
(_planData['Schema'] + '.') : ''
) + _planData['Relation Name'],
table = info.statistics.tables[relationName] || {
name: relationName,
count: 0,
sum_of_times: 0,
nodes: {},
};
node = table.nodes[node_info] || {
name: node_info,
count: 0,
sum_of_times: 0,
};
table.count++;
table.sum_of_times += _planData['exclusive'];
node.count++;
node.sum_of_times += _planData['exclusive'];
table.nodes[node_info] = node;
info.statistics.tables[relationName] = table;
}
node = info.statistics.nodes[node_info] || {
name: node_info,
count: 0,
sum_of_times: 0,
};
node.count++;
node.sum_of_times += _planData['exclusive'];
info.statistics.nodes[node_info] = node;
}
function parsePlan(data, ctx) {
var idx = 1,
lvl = data.level = data.level || [idx],
plans = [],
nodeType = data['Node Type'],
// Calculating relative xpos of current node from top node
xpos = data.xpos = data.xpos - pWIDTH,
// Calculating relative ypos of current node from top node
ypos = data.ypos,
maxChildWidth = 0;
ctx.totalNodes++;
ctx.explainTable.total_time = data['total_time'] || data['Actual Total Time'];
data['_serial'] = ctx.totalNodes;
data['width'] = pWIDTH;
data['height'] = pHEIGHT;
// Calculate arrow width according to cost of a particular plan
let arrowSize = DEFAULT_ARROW_SIZE;
let startCost = data['Startup Cost'],
totalCost = data['Total Cost'];
if (startCost != undefined && totalCost != undefined) {
arrowSize = Math.round(Math.log((startCost + totalCost) / 2 + startCost));
arrowSize = arrowSize < 1 ? 1 : arrowSize > 10 ? 10 : arrowSize;
}
data['arr_id'] = _.uniqueId('arr');
ctx.arrows[data['arr_id']] = arrowSize;
/*
* calculating xpos, ypos, width and height if current node is a subplan
*/
if (data['Parent Relationship'] === 'SubPlan') {
data['width'] += (xMargin * 2) + (xMargin / 2);
data['height'] += (yMargin * 2);
data['ypos'] += yMargin;
xpos -= xMargin;
ypos += yMargin;
}
if (nodeType.startsWith('(slice'))
nodeType = nodeType.substring(0, 7);
// Get the image information for current node
var mappedImage = (_.isFunction(ImageMapper[nodeType]) &&
ImageMapper[nodeType].apply(undefined, [data])) ||
ImageMapper[nodeType] || {
'image': 'ex_unknown.svg',
'image_text': nodeType,
};
data['image'] = mappedImage['image'];
data['image_text'] = mappedImage['image_text'];
if ('Actual Total Time' in data && 'Actual Loops' in data) {
data['inclusive'] = Math.ceil10(
data['Actual Total Time'] * data['Actual Loops'], -3
);
data['exclusive'] = data['inclusive'];
data['inclusive_factor'] = data['inclusive'] / (
data['total_time'] || data['Actual Total Time']
);
data['inclusive_flag'] = data['inclusive_factor'] <= 0.1 ? '1' :
data['inclusive_factor'] < 0.5 ? '2' :
data['inclusive_factor'] <= 0.9 ? '3' : '4';
}
if ('Actual Rows' in data && 'Plan Rows' in data) {
if (
data['Actual Rows'] === 0 || data['Actual Rows'] > data['Plan Rows']
) {
data['rowsx'] = data['Plan Rows'] === 0 ? 0 :
(data['Actual Rows'] / data['Plan Rows']);
data['rowsx_direction'] = 'negative';
} else {
data['rowsx'] = data['Actual Rows'] === 0 ? 0 : (
data['Plan Rows'] / data['Actual Rows']
);
data['rowsx_direction'] = 'positive';
}
data['rowsx_flag'] = data['rowsx'] <= 10 ? '1' : (
data['rowsx'] <= 100 ? '2' : (data['rowsx'] <= 1000 ? '3' : '4')
);
data['rowsx'] = Math.ceil10(data['rowsx'], -2);
}
// Start calculating xpos, ypos, width and height for child plans if any
if ('Plans' in data) {
data['width'] += offsetX;
data['Plans'].forEach(function(p) {
let level = _.clone(lvl);
level.push(idx);
let plan = parsePlan({
...p,
'level': level,
xpos: xpos - offsetX,
ypos: ypos,
total_time: data['total_time'] || data['Actual Total Time'],
parent_node: lvl.join('_'),
}, ctx);
if (maxChildWidth < plan.width) {
maxChildWidth = plan.width;
}
if ('exclusive' in data) {
if (plan.inclusive) {
data['exclusive'] -= plan.inclusive;
}
}
var childHeight = plan.height;
if (idx !== 1) {
data['height'] = data['height'] + childHeight + offsetY;
} else if (childHeight > data['height']) {
data['height'] = childHeight;
}
ypos += childHeight + offsetY;
plans.push(plan);
idx++;
});
}
if ('exclusive' in data) {
data['exclusive'] = Math.ceil10(data['exclusive'], -3);
data['exclusive_factor'] = (
data['exclusive'] / (data['total_time'] || data['Actual Total Time'])
);
data['exclusive_flag'] = data['exclusive_factor'] <= 0.1 ? '1' :
data['exclusive_factor'] < 0.5 ? '2' :
data['exclusive_factor'] <= 0.9 ? '3' : '4';
}
// Final Width and Height of current node
data['width'] += maxChildWidth;
data['Plans'] = plans;
nodeExplainTableData(data, ctx);
return data;
}
function parsePlanData(data, ctx) {
let retPlan = {};
if(data) {
if ('Plan' in data) {
let plan = parsePlan({
...data['Plan'],
xpos: 0,
ypos: 0,
}, ctx);
retPlan['Plan'] = plan;
retPlan['xpos'] = 0;
retPlan['ypos'] = 0;
retPlan['width'] = plan.width + (xMargin * 2);
retPlan['height'] = plan.height + (yMargin * 4);
}
retPlan['Statistics'] = {
'JIT': [],
'Triggers': [],
'Summary': {},
};
if (data && 'JIT' in data) {
retPlan['Statistics']['JIT'] = retPlan['JIT'];
}
if (data && 'Triggers' in data) {
retPlan['Statistics']['Triggers'] = retPlan['JITriggersT'];
}
if(data) {
let summKeys = ['Planning Time', 'Execution Time'],
summary = {};
summKeys.forEach((key)=>{
if (key in data) {
summary[key] = data[key];
}
});
retPlan['Statistics']['Summary'] = summary;
}
if (data && 'Settings' in data) {
retPlan['Statistics']['Settings'] = data['Settings'];
}
}
return retPlan;
}
export default function Explain({plans=[]}) {
const classes = useStyles();
const [tabValue, setTabValue] = React.useState(0);
let ctx = React.useRef({
totalNodes: 0,
totalDownloadedNodes: 0,
isDownloaded: 0,
explainTable: {
rows: [],
statistics: {
tables: {},
nodes: {},
},
},
arrows: {},
});
let planData = React.useMemo(()=>(plans && parsePlanData(plans[0], ctx.current)), [plans]);
if(_.isEmpty(plans)) {
return <Box height="100%" display="flex" flexDirection="column">
<EmptyPanelMessage text={gettext('Use Explain/Explain analyze button to generate the plan for a query. Alternatively, you can also execute "EXPLAIN (FORMAT JSON) [QUERY]".')} />
</Box>;
}
return (
<Box height="100%" display="flex" flexDirection="column">
<Box>
<Tabs
value={tabValue}
onChange={(_e, selTabValue) => {
setTabValue(selTabValue);
}}
// indicatorColor="primary"
variant="scrollable"
scrollButtons="auto"
action={(ref)=>ref && ref.updateIndicator()}
>
<Tab label="Graphical" />
<Tab label="Analysis" />
<Tab label="Statistics" />
</Tabs>
</Box>
<TabPanel value={tabValue} index={0} classNameRoot={classes.tabPanel}>
<Graphical planData={planData} ctx={ctx.current}/>
</TabPanel>
<TabPanel value={tabValue} index={1} classNameRoot={classes.tabPanel}>
<Analysis explainTable={ctx.current.explainTable} />
</TabPanel>
<TabPanel value={tabValue} index={2} classNameRoot={classes.tabPanel}>
<ExplainStatistics explainTable={ctx.current.explainTable} />
</TabPanel>
</Box>
);
}
Explain.propTypes = {
plans: PropTypes.array,
};

View File

@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import getApiInstance from '../api_instance';
function convertImageURLtoDataURI(api, image) {
return new Promise(function(resolve, reject) {
let href = image.getAttribute('href') || image.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
api.get(href).then(({data})=>{
image.setAttribute('href', 'data:image/svg+xml;base64,'+window.btoa(data));
resolve();
}).catch(()=>{
reject();
});
});
}
export function downloadSvg(svg, svgName) {
let svgDiv = document.createElement('div');
svgDiv.innerHTML = svg;
svgDiv.style.visibility = 'hidden';
svgDiv.style.display = 'table';
svgDiv.style.position = 'absolute';
let svgElement = svgDiv.firstChild;
let api = getApiInstance();
if (!svgElement) { return; }
let images = svgElement.getElementsByTagName('image');
let image_promises = [];
if (images){
for (let image of images) {
if ((image.getAttribute('href') && image.getAttribute('href').indexOf('data:') === -1)
|| (image.getAttribute('xlink:href') && image.getAttribute('xlink:href').indexOf('data:') === -1)) {
image_promises.push(convertImageURLtoDataURI(api, image));
}
}
}
Promise.all(image_promises).then(function() {
let blob = new Blob([svgElement.outerHTML], {type: 'image/svg+xml'});
let svgURL = (window.URL || window.webkitURL).createObjectURL(blob);
let newElement = document.createElement('a');
newElement.href = svgURL;
newElement.setAttribute('download', svgName);
document.body.appendChild(newElement);
newElement.click();
document.body.removeChild(newElement);
});
}

View File

@ -187,8 +187,8 @@ export default function FormView({
if(_.isArray(dep)) {
source = dep;
}
if(field.depChange) {
depListener.addDepListener(source, accessPath.concat(field.id), field.depChange);
if(field.depChange || field.deferredDepChange) {
depListener.addDepListener(source, accessPath.concat(field.id), field.depChange, field.deferredDepChange);
}
if(field.depChange || field.deferredDepChange) {
depListener.addDepListener(source, accessPath.concat(field.id), field.depChange, field.deferredDepChange);

View File

@ -429,7 +429,7 @@ function prepareData(val, createMode=false) {
/* If its the dialog */
function SchemaDialogView({
getInitData, viewHelperProps, schema={}, showFooter=true, isTabView=true, ...props}) {
getInitData, viewHelperProps, loadingText, schema={}, showFooter=true, isTabView=true, ...props}) {
const classes = useDialogStyles();
/* Some useful states */
const [dirty, setDirty] = useState(false);
@ -704,7 +704,7 @@ function SchemaDialogView({
<DepListenerContext.Provider value={depListenerObj.current}>
<Box className={classes.root}>
<Box className={classes.form}>
<Loader message={loaderText}/>
<Loader message={loaderText || loadingText}/>
<FormView value={sessData} viewHelperProps={viewHelperProps}
schema={schema} accessPath={[]} dataDispatch={sessDispatchWithListener}
hasSQLTab={props.hasSQL} getSQLValue={getSQLValue} firstEleRef={firstEleRef} isTabView={isTabView} className={props.formClassName} />
@ -746,6 +746,7 @@ SchemaDialogView.propTypes = {
}),
inCatalog: PropTypes.bool,
}).isRequired,
loadingText: PropTypes.string,
schema: CustomPropTypes.schemaUI,
onSave: PropTypes.func,
onClose: PropTypes.func,

View File

@ -22,7 +22,7 @@ export default function(basicSettings) {
disabledContrastText: '#fff',
hoverMain: '#303030',
hoverContrastText: '#fff',
hoverBorderColor: '#2e2e2e',
hoverBorderColor: '#151515',
},
primary: {
main: '#234d6e',
@ -73,7 +73,7 @@ export default function(basicSettings) {
icon: {
main: '#6b6b6b',
contrastText: '#fff',
borderColor: '#2e2e2e',
borderColor: darken('#2e2e2e', 0.6),
disabledMain: '#6b6b6b',
disabledContrastText: '#fff',
disabledBorderColor: '#2e2e2e',
@ -86,6 +86,7 @@ export default function(basicSettings) {
inputBorderColor: '#6b6b6b',
inputDisabledBg: 'inherit',
headerBg: '#424242',
activeBorder: '#d4d4d4',
activeColor: '#d4d4d4',
tableBg: '#424242',
activeStepBg: '#234d6e',
@ -93,6 +94,11 @@ export default function(basicSettings) {
stepBg: '#FFFFFF',
stepFg: '#000',
toggleBtnBg: '#000',
editorToolbarBg: '#303030',
qtDatagridBg: '#2e2e2e',
qtDatagridSelectFg: '#d4d4d4',
cardHeaderBg: '#424242',
colorFg: '#FFFFFF',
emptySpaceBg: '#212121',
}
});

View File

@ -80,17 +80,23 @@ export default function(basicSettings) {
}
},
otherVars: {
borderColor: '#4a4a4a',
borderColor: '#A6B7C8',
inputBorderColor: '#6b6b6b',
inputDisabledBg: '#1F2932',
headerBg: '#010B15',
activeColor: '#d4d4d4',
activeBorder: '#fff',
activeColor: '#fff',
tableBg: '#010B15',
activeStepBg: '#84D6FF',
activeStepFg: '#010b15',
stepBg: '#FFFFFF',
stepFg: '#000',
toggleBtnBg: '#6B6B6B',
editorToolbarBg: '#010B15',
qtDatagridBg: '#010B15',
qtDatagridSelectFg: '#010B15',
cardHeaderBg: '#062F57',
colorFg: '#FFFFFF',
emptySpaceBg: '#010B15',
}
});

View File

@ -81,7 +81,7 @@ basicSettings = createMuiTheme(basicSettings, {
height: '28px',
fontSize: '0.875rem',
'& .MuiSvgIcon-root': {
height: '0.8em',
height: '1.2rem',
}
},
},
@ -167,13 +167,17 @@ basicSettings = createMuiTheme(basicSettings, {
MuiDialog: {
paper: {
margin: 0,
},
scrollPaper: {
alignItems: 'flex-start',
margin: '5% auto',
}
},
MuiTooltip: {
popper: {
top: 0,
zIndex: 9999,
}
},
},
MuiMenu: {
list: {
@ -231,6 +235,9 @@ basicSettings = createMuiTheme(basicSettings, {
MuiListItem: {
disableGutters: true,
},
MuiTooltip: {
arrow: true,
}
},
});
@ -460,6 +467,7 @@ function getFinalTheme(baseTheme) {
MuiCardHeader: {
root: {
padding: '4px 8px',
backgroundColor: baseTheme.otherVars.cardHeaderBg,
...mixins.panelBorder.bottom,
}
},
@ -487,11 +495,22 @@ function getFinalTheme(baseTheme) {
'&$selected': {
backgroundColor: baseTheme.palette.primary.light,
borderColor: baseTheme.palette.primary.main,
color: basicSettings.palette.getContrastText(baseTheme.palette.primary.light),
'&:hover': {
backgroundColor: baseTheme.palette.primary.light,
}
},
}
},
MuiTooltip: {
tooltip: {
fontSize: '0.7rem',
color: baseTheme.palette.background.default,
backgroundColor: baseTheme.palette.text.primary,
},
arrow: {
color: baseTheme.palette.text.primary,
}
}
}
}, baseTheme);

View File

@ -101,7 +101,9 @@ export default function(basicSettings) {
stepFg: '#000',
toggleBtnBg: '#000',
editorToolbarBg: '#ebeef3',
datagridBg: '#fff',
qtDatagridBg: '#fff',
qtDatagridSelectFg: '#222',
cardHeaderBg: '#fff',
emptySpaceBg: '#ebeef3',
}
});

View File

@ -29,7 +29,7 @@ export function parseApiError(error) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
if(error.response.headers['content-type'] == 'application/json') {
return `INTERNAL SERVER ERROR: ${error.response.data.errormsg}`;
return error.response.data.errormsg;
} else {
return error.response.statusText;
}

View File

@ -0,0 +1,13 @@
export function copyToClipboard(text) {
try {
navigator.clipboard.writeText(text);
} catch {
/* Suppress error */
console.error('Does not have clipboard acccess');
}
localStorage.setItem('clipboard', text);
}
export function getFromClipboard() {
return localStorage.getItem('clipboard');
}

View File

@ -42,6 +42,7 @@ const useStyles = makeStyles((theme)=>({
}
},
iconButton: {
minWidth: 0,
padding: '3px 6px',
'&.MuiButton-sizeSmall, &.MuiButton-outlinedSizeSmall, &.MuiButton-containedSizeSmall': {
padding: '1px 4px',
@ -59,6 +60,7 @@ const useStyles = makeStyles((theme)=>({
'&:hover': {
backgroundColor: theme.custom.icon.hoverMain,
color: theme.custom.icon.hoverContrastText,
borderColor: theme.custom.icon.borderColor,
},
},
splitButton: {
@ -72,6 +74,7 @@ const useStyles = makeStyles((theme)=>({
xsButton: {
padding: '2px 1px',
height: '24px',
minWidth: '24px',
'& .MuiSvgIcon-root': {
height: '0.8em',
}
@ -127,27 +130,29 @@ DefaultButton.propTypes = {
/* pgAdmin Icon button, takes Icon component as input */
export const PgIconButton = forwardRef(({icon, title, shortcut, accessKey, className, splitButton, style, color, ...props}, ref)=>{
export const PgIconButton = forwardRef(({icon, title, shortcut, className, splitButton, style, color, accesskey, ...props}, ref)=>{
const classes = useStyles();
let shortcutTitle = null;
if(accessKey || shortcut) {
shortcutTitle = <ShortcutTitle title={title} accessKey={accessKey} shortcut={shortcut}/>;
if(accesskey || shortcut) {
shortcutTitle = <ShortcutTitle title={title} accesskey={accesskey} shortcut={shortcut}/>;
}
/* Tooltip does not work for disabled items */
if(props.disabled) {
if(color == 'primary') {
return (
<PrimaryButton ref={ref} style={{minWidth: 0, ...style}}
className={clsx(classes.iconButton, (splitButton ? classes.splitButton : ''), className)} {...props}>
<PrimaryButton ref={ref} style={style}
className={clsx(classes.iconButton, (splitButton ? classes.splitButton : ''), className)}
accessKey={accesskey} {...props}>
{icon}
</PrimaryButton>
);
} else {
return (
<DefaultButton ref={ref} style={{minWidth: 0, ...style}}
className={clsx(classes.iconButton, classes.iconButtonDefault, (splitButton ? classes.splitButton : ''), className)} {...props}>
<DefaultButton ref={ref} style={style}
className={clsx(classes.iconButton, classes.iconButtonDefault, (splitButton ? classes.splitButton : ''), className)}
accessKey={accesskey} {...props}>
{icon}
</DefaultButton>
);
@ -156,8 +161,9 @@ export const PgIconButton = forwardRef(({icon, title, shortcut, accessKey, class
if(color == 'primary') {
return (
<Tooltip title={shortcutTitle || title || ''} aria-label={title || ''}>
<PrimaryButton ref={ref} style={{minWidth: 0, ...style}}
className={clsx(classes.iconButton, (splitButton ? classes.splitButton : ''), className)} {...props}>
<PrimaryButton ref={ref} style={style}
className={clsx(classes.iconButton, (splitButton ? classes.splitButton : ''), className)}
accessKey={accesskey} {...props}>
{icon}
</PrimaryButton>
</Tooltip>
@ -165,8 +171,9 @@ export const PgIconButton = forwardRef(({icon, title, shortcut, accessKey, class
} else {
return (
<Tooltip title={shortcutTitle || title || ''} aria-label={title || ''}>
<DefaultButton ref={ref} style={{minWidth: 0, ...style}}
className={clsx(classes.iconButton, classes.iconButtonDefault, (splitButton ? classes.splitButton : ''), className)} {...props}>
<DefaultButton ref={ref} style={style}
className={clsx(classes.iconButton, classes.iconButtonDefault, (splitButton ? classes.splitButton : ''), className)}
accessKey={accesskey} {...props}>
{icon}
</DefaultButton>
</Tooltip>
@ -179,7 +186,7 @@ PgIconButton.propTypes = {
icon: CustomPropTypes.children,
title: PropTypes.string.isRequired,
shortcut: CustomPropTypes.shortcut,
accessKey: PropTypes.string,
accesskey: PropTypes.string,
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
style: PropTypes.object,
color: PropTypes.oneOf(['primary', 'default', undefined]),

View File

@ -8,11 +8,11 @@
//////////////////////////////////////////////////////////////
import React, { useEffect, useMemo, useRef, useState } from 'react';
import {default as OrigCodeMirror} from 'bundled_codemirror';
import OrigCodeMirror from 'bundled_codemirror';
import {useOnScreen} from 'sources/custom_hooks';
import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
import pgAdmin from 'sources/pgadmin';
import pgWindow from 'sources/window';
import gettext from 'sources/gettext';
import { Box, InputAdornment, makeStyles } from '@material-ui/core';
import clsx from 'clsx';
@ -31,6 +31,11 @@ const useStyles = makeStyles((theme)=>({
root: {
position: 'relative',
},
hideCursor: {
'& .CodeMirror-cursors': {
display: 'none'
}
},
findDialog: {
position: 'absolute',
zIndex: 99,
@ -70,31 +75,40 @@ function parseQuery(query, useRegex=false, matchCase=false) {
return query;
}
function getRegexFinder(query) {
return (stream) => {
query.lastIndex = stream.pos;
var match = query.exec(stream.string);
if (match && match.index == stream.pos) {
stream.pos += match[0].length || 1;
return 'searching';
} else if (match) {
stream.pos = match.index;
} else {
stream.skipToEnd();
}
};
}
function getPlainStringFinder(query, matchCase) {
return (stream) => {
var matchIndex = (matchCase ? stream.string : stream.string.toLowerCase()).indexOf(query, stream.pos);
if(matchIndex == -1) {
stream.skipToEnd();
} else if(matchIndex == stream.pos) {
stream.pos += query.length;
return 'searching';
} else {
stream.pos = matchIndex;
}
};
}
function searchOverlay(query, matchCase) {
return {
token: typeof query == 'string' ?
(stream) =>{
var matchIndex = (matchCase ? stream.string : stream.string.toLowerCase()).indexOf(query, stream.pos);
if(matchIndex == -1) {
stream.skipToEnd();
} else if(matchIndex == stream.pos) {
stream.pos += query.length;
return 'searching';
} else {
stream.pos = matchIndex;
}
} : (stream) => {
query.lastIndex = stream.pos;
var match = query.exec(stream.string);
if (match && match.index == stream.pos) {
stream.pos += match[0].length || 1;
return 'searching';
} else if (match) {
stream.pos = match.index;
} else {
stream.skipToEnd();
}
}
getPlainStringFinder(query, matchCase) : getRegexFinder(query)
};
}
@ -260,28 +274,96 @@ FindDialog.propTypes = {
onClose: PropTypes.func,
};
function handleDrop(editor, e) {
var dropDetails = null;
try {
dropDetails = JSON.parse(e.dataTransfer.getData('text'));
/* Stop firefox from redirecting */
if(e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
} catch(error) {
/* if parsing fails, it must be the drag internal of codemirror text */
return;
}
var cursor = editor.coordsChar({
left: e.x,
top: e.y,
});
editor.replaceRange(dropDetails.text, cursor);
editor.focus();
editor.setSelection({
...cursor,
ch: cursor.ch + dropDetails.cur.from,
},{
...cursor,
ch: cursor.ch +dropDetails.cur.to,
});
}
function calcFontSize(fontSize) {
if(fontSize) {
fontSize = parseFloat((Math.round(parseFloat(fontSize + 'e+2')) + 'e-2'));
let rounded = Number(fontSize);
if(rounded > 0) {
return rounded + 'em';
}
}
return '1em';
}
/* React wrapper for CodeMirror */
export default function CodeMirror({currEditor, name, value, options, events, readonly, disabled, className}) {
export default function CodeMirror({currEditor, name, value, options, events, readonly, disabled, className, autocomplete=false}) {
const taRef = useRef();
const editor = useRef();
const cmWrapper = useRef();
const isVisibleTrack = useRef();
const classes = useStyles();
const [[showFind, isReplace], setShowFind] = useState([false, false]);
const defaultOptions = {
tabindex: '0',
lineNumbers: true,
styleSelectedText: true,
mode: 'text/x-pgsql',
foldOptions: {
widget: '\u2026',
},
foldGutter: true,
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
extraKeys: pgAdmin.Browser.editor_shortcut_keys,
dragDrop: false,
screenReaderLabel: gettext('SQL editor'),
};
const defaultOptions = useMemo(()=>{
let goLeftKey = 'Ctrl-Alt-Left',
goRightKey = 'Ctrl-Alt-Right',
commentKey = 'Ctrl-/';
if(isMac()) {
goLeftKey = 'Cmd-Alt-Left';
goRightKey = 'Cmd-Alt-Right';
commentKey = 'Cmd-/';
}
return {
tabindex: '0',
lineNumbers: true,
styleSelectedText: true,
mode: 'text/x-pgsql',
foldOptions: {
widget: '\u2026',
},
foldGutter: true,
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
extraKeys: {
// Autocomplete sql command
...(autocomplete ? {
'Ctrl-Space': 'autocomplete',
}: {}),
'Alt-Up': 'goLineUp',
'Alt-Down': 'goLineDown',
// Move word by word left/right
[goLeftKey]: 'goGroupLeft',
[goRightKey]: 'goGroupRight',
// Allow user to delete Tab(s)
'Shift-Tab': 'indentLess',
//comment
[commentKey]: 'toggleComment',
},
dragDrop: true,
screenReaderLabel: gettext('SQL editor'),
};
});
useEffect(()=>{
const finalOptions = {...defaultOptions, ...options};
@ -317,29 +399,61 @@ export default function CodeMirror({currEditor, name, value, options, events, re
setShowFind([false, false]);
setShowFind([true, true]);
}
}
},
'Cmd-G': false,
});
}
Object.keys(events||{}).forEach((eventName)=>{
editor.current.on(eventName, events[eventName]);
});
editor.current.on('drop', handleDrop);
initPreferences();
return ()=>{
editor.current?.toTextArea();
};
}, []);
const initPreferences = ()=>{
reflectPreferences();
pgWindow?.pgAdmin?.Browser?.onPreferencesChange('sqleditor', function() {
reflectPreferences();
});
};
const reflectPreferences = ()=>{
let pref = pgWindow?.pgAdmin?.Browser?.get_preferences_for_module('sqleditor') || {};
let wrapEle = editor?.current.getWrapperElement();
wrapEle && (wrapEle.style.fontSize = calcFontSize(pref.sql_font_size));
if(pref.plain_editor_mode) {
editor?.current.setOption('mode', 'text/plain');
/* Although not required, setting explicitly as codemirror will remove code folding only on next edit */
editor?.current.setOption('foldGutter', false);
} else {
editor?.current.setOption('mode', 'text/x-pgsql');
editor?.current.setOption('foldGutter', pref.code_folding);
}
editor?.current.setOption('indentWithTabs', pref.indent_with_tabs);
editor?.current.setOption('indentUnit', pref.tab_size);
editor?.current.setOption('tabSize', pref.tab_size);
editor?.current.setOption('lineWrapping', pref.wrap_code);
editor?.current.setOption('autoCloseBrackets', pref.insert_pair_brackets);
editor?.current.setOption('matchBrackets', pref.brace_matching);
editor?.current.refresh();
};
useEffect(()=>{
if(editor.current) {
if(disabled) {
cmWrapper.current.classList.add('cm_disabled');
editor.current.setOption('readOnly', 'nocursor');
editor.current.setOption('readOnly', true);
cmWrapper.current.classList.add(classes.hideCursor);
} else if(readonly) {
cmWrapper.current.classList.add('cm_disabled');
editor.current.setOption('readOnly', true);
editor.current.addKeyMap({'Tab': false});
editor.current.addKeyMap({'Shift-Tab': false});
cmWrapper.current.classList.add(classes.hideCursor);
} else {
cmWrapper.current.classList.remove('cm_disabled');
editor.current.setOption('readOnly', false);
@ -392,4 +506,5 @@ CodeMirror.propTypes = {
readonly: PropTypes.bool,
disabled: PropTypes.bool,
className: CustomPropTypes.className,
autocomplete: PropTypes.bool,
};

View File

@ -22,17 +22,16 @@ ExternalIcon.propTypes = {
Icon: PropTypes.elementType.isRequired,
};
export const QueryToolIcon = ()=><ExternalIcon Icon={QueryToolSvg} style={{height: '0.7em'}} />;
export const SaveDataIcon = ()=><ExternalIcon Icon={SaveDataSvg} style={{height: '0.7em'}} />;
export const QueryToolIcon = ()=><ExternalIcon Icon={QueryToolSvg} style={{height: '1rem'}} />;
export const SaveDataIcon = ()=><ExternalIcon Icon={SaveDataSvg} style={{height: '1rem'}} />;
export const PasteIcon = ()=><ExternalIcon Icon={PasteSvg} />;
export const FilterIcon = ()=><ExternalIcon Icon={FilterSvg} />;
export const CommitIcon = ()=><ExternalIcon Icon={CommitSvg} />;
export const RollbackIcon = ()=><ExternalIcon Icon={RollbackSvg} />;
export const ClearIcon = ()=><ExternalIcon Icon={ClearSvg} />;
export const ConnectedIcon = ()=><ExternalIcon Icon={ConnectedSvg} style={{height: '0.7em'}} />;
export const DisonnectedIcon = ()=><ExternalIcon Icon={DisconnectedSvg} style={{height: '0.7em'}} />;
export const ConnectedIcon = ()=><ExternalIcon Icon={ConnectedSvg} style={{height: '1rem'}} />;
export const DisonnectedIcon = ()=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem'}} />;
export const RegexIcon = ()=><ExternalIcon Icon={RegexSvg} />;
export const FormatCaseIcon = ()=><ExternalIcon Icon={FormatCaseSvg} />;
export const ExpandDialogIcon = ()=><ExternalIcon Icon={Expand} style={{height: '1.2em'}} />;
export const MinimizeDialogIcon = ()=><ExternalIcon Icon={Collapse} style={{height: '1.4em'}} />;
export const ExpandDialogIcon = ()=><ExternalIcon Icon={Expand} style={{height: '1.2rem'}} />;
export const MinimizeDialogIcon = ()=><ExternalIcon Icon={Collapse} style={{height: '1.4rem'}} />;

View File

@ -207,6 +207,7 @@ FormInputSQL.propTypes = {
helpMessage: PropTypes.string,
testcid: PropTypes.string,
value: PropTypes.string,
controlProps: PropTypes.object,
noLabel: PropTypes.bool,
change: PropTypes.func,
};
@ -570,7 +571,7 @@ export function InputRadio({ helpid, value, onChange, controlProps, readonly, ..
disableRipple
{...props}
/>
}
label={controlProps.label}
className={(readonly || props.disabled) ? classes.readOnlySwitch : null}
@ -821,6 +822,7 @@ export const InputSelect = forwardRef(({
const [[finalOptions, isLoading], setFinalOptions] = useState([[], true]);
const theme = useTheme();
/* React will always take options var as changed parameter. So,
We cannot run the below effect with options dependency as it will keep on
loading the options. optionsReloadBasis is helpful to avoid repeated
@ -1174,20 +1176,21 @@ const useStylesFormFooter = makeStyles((theme) => ({
}));
/* The form footer used mostly for showing error */
export function FormFooterMessage(props) {
export function FormFooterMessage({style, ...props}) {
const classes = useStylesFormFooter();
if (!props.message) {
return <></>;
}
return (
<Box className={classes.root}>
<Box className={classes.root} style={style}>
<NotifierMessage {...props}></NotifierMessage>
</Box>
);
}
FormFooterMessage.propTypes = {
style: PropTypes.object,
message: PropTypes.string,
};

View File

@ -13,7 +13,7 @@ import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
/* React wrapper for JsonEditor */
export default function JsonEditor({currEditor, value, options, className}) {
export default function JsonEditor({getEditor, value, options, className}) {
const eleRef = useRef();
const editor = useRef();
const defaultOptions = {
@ -34,9 +34,10 @@ export default function JsonEditor({currEditor, value, options, className}) {
}
});
editor.current.setText(value);
currEditor && currEditor(editor.current);
getEditor?.(editor.current);
editor.current.focus();
return ()=>editor.current?.destroy();
/* Required by json editor */
eleRef.current.style.height = eleRef.current.offsetHeight + 'px';
}, []);
useMemo(() => {
@ -53,7 +54,7 @@ export default function JsonEditor({currEditor, value, options, className}) {
}
JsonEditor.propTypes = {
currEditor: PropTypes.func,
getEditor: PropTypes.func,
value: PropTypes.string,
options: PropTypes.object,
className: CustomPropTypes.className,

View File

@ -18,6 +18,9 @@ const useStyles = makeStyles((theme)=>({
'& .szh-menu': {
padding: '4px 0px',
zIndex: 1000,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
border: `1px solid ${theme.otherVars.borderColor}`
},
'& .szh-menu__divider': {
margin: 0,

View File

@ -4,8 +4,13 @@ import PropTypes from 'prop-types';
import { isMac } from '../keyboard_shortcuts';
import _ from 'lodash';
import CustomPropTypes from '../custom_prop_types';
import gettext from 'sources/gettext';
const useStyles = makeStyles((theme)=>({
shortcutTitle: {
width: '100%',
textAlign: 'center',
},
shortcut: {
justifyContent: 'center',
marginTop: '0.125rem',
@ -19,10 +24,43 @@ const useStyles = makeStyles((theme)=>({
},
}));
export function getBrowserAccesskey() {
/* Ref: https://github.com/tillsanders/access-key-label-polyfill/ */
let ua = window.navigator.userAgent;
// macOS
if (ua.match(/macintosh/i)) {
// Firefox
if (ua.match(/firefox/i)) {
const firefoxVersion = ua.match(/firefox[\s/](\d+)/i);
// Firefox < v14
if (firefoxVersion[1] && parseInt(firefoxVersion[1], 10) < 14) {
return ['Ctrl'];
}
}
return ['Option', 'Ctrl'];
}
// Internet Explorer / Edge
if (ua.match(/msie|trident/i) || ua.match(/\sedg/i)) {
return ['Alt'];
}
// iOS / iPadOS
if (ua.match(/(ipod|iphone|ipad)/i)) {
// accesskeyLabel is supported > v14, but we're not checking for versions here, since we use
// feature support detection
return ['Option', 'Ctrl'];
}
// Fallback
// Note: Apparently, Chrome for Android is not even supporting accesskey, so be prepared.
return [gettext('Accesskey')];
}
export function shortcutToString(shortcut, accesskey=null, asArray=false) {
let keys = [];
if(accesskey) {
keys.push('Accesskey');
keys = getBrowserAccesskey();
keys.push(_.capitalize(accesskey?.toUpperCase()));
} else if(shortcut) {
shortcut.alt && keys.push((isMac() ? 'Option' : 'Alt'));
@ -41,12 +79,12 @@ export function shortcutToString(shortcut, accesskey=null, asArray=false) {
}
/* The tooltip content to show shortcut details */
export default function ShortcutTitle({title, shortcut, accessKey}) {
export default function ShortcutTitle({title, shortcut, accesskey}) {
const classes = useStyles();
let keys = shortcutToString(shortcut, accessKey, true);
let keys = shortcutToString(shortcut, accesskey, true);
return (
<>
<div>{title}</div>
<div className={classes.shortcutTitle}>{title}</div>
<div className={classes.shortcut}>
{keys.map((key, i)=>{
return <div key={i} className={classes.key}>{key}</div>;
@ -59,5 +97,5 @@ export default function ShortcutTitle({title, shortcut, accessKey}) {
ShortcutTitle.propTypes = {
title: PropTypes.string,
shortcut: CustomPropTypes.shortcut,
accessKey: PropTypes.string,
accesskey: PropTypes.string,
};

View File

@ -1,5 +1,6 @@
import {useRef, useEffect, useState, useCallback} from 'react';
export { useStopwatch } from 'react-timer-hook';
import moment from 'moment';
// export { useStopwatch } from 'react-timer-hook';
/* React hook for setInterval */
export function useInterval(callback, delay) {
@ -78,6 +79,50 @@ export function useIsMounted() {
return useCallback(() => ref.current, []);
}
export function useStopwatch() {
const prevTime = useRef(new Date());
const [totalMsec, setTotalMsec] = useState(0);
const [isRunning, setIsRunning] = useState(false);
useInterval(() => {
setTotalMsec(moment(new Date()).diff(prevTime.current));
}, isRunning ? 100 : -1);
function start(startTime) {
prevTime.current = startTime || new Date();
setIsRunning(true);
}
const pause = (endTime)=>{
setIsRunning(false);
setTotalMsec(moment(endTime || new Date()).diff(prevTime.current));
};
function reset() {
setTotalMsec(0);
}
let msec = totalMsec;
/* Extract seconds from millisecs */
let seconds = parseInt(msec/1000);
msec = msec%1000;
/* Extract mins from seconds */
let minutes = parseInt(seconds/60);
seconds = seconds%60;
/* Extract hrs from mins */
let hours = parseInt(minutes/60);
minutes = minutes%60;
return {
hours: hours,
minutes: minutes,
seconds: seconds,
msec: msec,
start, pause, reset, isRunning,
};
}
/*
shortcuts = [
@ -105,27 +150,30 @@ export function useKeyboardShortcuts(shortcuts, eleRef) {
const matchFound = (shortcut, e)=>{
if(!shortcut) return false;
let keyCode = e.which || e.keyCode;
return shortcut.alt == e.altKey &&
shortcut.shift == e.shiftKey &&
shortcut.control == e.ctrlKey &&
return Boolean(shortcut.alt) == e.altKey &&
Boolean(shortcut.shift) == e.shiftKey &&
Boolean(shortcut.control) == e.ctrlKey &&
shortcut.key.key_code == keyCode;
};
useEffect(()=>{
let ele = eleRef.current ?? document;
const keyupCallback = (e)=>{
for(let i=0; i<(shortcutsRef.current??[]).length; i++){
let {shortcut, options} = shortcutsRef.current[i];
if(matchFound(shortcut, e)) {
if(options.callback && (options.enabled ?? true)) {
options.callback(e);
}
break;
const keydownCallback = (e)=>{
Promise.resolve(0).then(()=>{
let allListeners = _.filter(shortcutsRef.current, (s)=>matchFound(s.shortcut, e));
for(const {options} of allListeners) {
Promise.resolve(0).then(()=>{
if(options.callback && (options.enabled ?? true)) {
e.preventDefault();
e.stopPropagation();
options.callback(e);
}
});
}
}
});
};
ele.addEventListener('keyup', keyupCallback);
ele.addEventListener('keydown', keydownCallback);
return ()=>{
ele.removeEventListener('keyup', keyupCallback);
ele.removeEventListener('keydown', keydownCallback);
};
}, [eleRef.current]);

View File

@ -31,9 +31,9 @@ const CustomPropTypes = {
]),
shortcut: PropTypes.shape({
alt: PropTypes.bool,
control: PropTypes.bool,
shift: PropTypes.bool,
alt: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
control: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
shift: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
key: PropTypes.shape({
char: PropTypes.string,
}),

View File

@ -1,4 +1,3 @@
import React from 'react';
import _ from 'lodash';
export default class EventBus {
@ -6,11 +5,12 @@ export default class EventBus {
this._eventListeners = [];
}
registerListener(event, callback) {
registerListener(event, callback, once=false) {
this._eventListeners = this._eventListeners || [];
this._eventListeners.push({
event: event,
callback: callback,
fired: once ? 'pending' : 'ignore',
});
}
@ -28,17 +28,19 @@ export default class EventBus {
}
fireEvent(event, ...args) {
let self = this;
Promise.resolve(0).then(()=>{
let allListeners = _.filter(this._eventListeners, (e)=>e.event==event);
if(allListeners) {
for(const listener of allListeners) {
Promise.resolve(0).then(()=>{
listener.callback(...args);
if(listener.fired == 'pending') {
self.deregisterListener(event, listener.callback);
}
});
}
}
});
}
}
export const EventBusContext = React.createContext(new EventBus());

View File

@ -1,8 +1,14 @@
import React from 'react';
import React, { useRef, useMemo } from 'react';
import DockLayout from 'rc-dock';
import { makeStyles } from '@material-ui/styles';
import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
import EventBus from './EventBus';
import getApiInstance from '../api_instance';
import url_for from 'sources/url_for';
import { PgIconButton } from '../components/Buttons';
import CloseIcon from '@material-ui/icons/CloseRounded';
import gettext from 'sources/gettext';
import {ExpandDialogIcon, MinimizeDialogIcon } from '../components/ExternalIcon';
const useStyles = makeStyles((theme)=>({
@ -26,10 +32,21 @@ const useStyles = makeStyles((theme)=>({
paddingLeft: 0,
backgroundColor: theme.palette.background.default,
...theme.mixins.panelBorder.bottom,
'& .dock-nav-wrap': {
cursor: 'move',
}
},
'& .dock-panel': {
border: 'none',
'&.dragging': {
opacity: 0.6,
pointerEvents: 'visible',
},
'& .dock': {
borderRadius: 'inherit',
},
'&.dock-style-dialogs': {
borderRadius: theme.shape.borderRadius,
'&.dock-panel.dragging': {
opacity: 1,
},
@ -46,6 +63,10 @@ const useStyles = makeStyles((theme)=>({
color: theme.palette.text.primary,
}
},
},
'& .dock-tabpane': {
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}
},
'& .dock-tab': {
@ -54,10 +75,33 @@ const useStyles = makeStyles((theme)=>({
marginRight: 0,
background: 'unset',
fontWeight: 'unset',
color: theme.palette.text.primary,
'&::hover': {
color: 'unset',
},
'& > div': {
padding: '4px 10px',
},
'& .drag-initiator': {
display: 'flex',
'& .dock-tab-close-btn': {
color: theme.palette.text.primary,
position: 'unset',
marginLeft: '8px',
fontSize: '18px',
transition: 'none',
'&::before': {
content: '"\\00d7"',
position: 'relative',
top: '-5px',
}
}
}
},
'& .dock-extra-content': {
alignItems: 'center',
paddingRight: '10px',
},
'& .dock-vbox, & .dock-hbox .dock-vbox': {
'& .dock-divider': {
flexBasis: '1px',
@ -91,25 +135,33 @@ const useStyles = makeStyles((theme)=>({
},
'& .dock-fbox': {
zIndex: 1060,
},
'& .dock-mbox': {
zIndex: 1080,
},
'& .drag-accept-reject::after': {
content: '',
}
}
}));
export const LayoutEventsContext = React.createContext();
export class LayoutHelper {
static getPanel(attrs) {
return {
cached: true,
group: 'default',
...attrs,
};
}
static close(docker, panelId) {
docker.dockMove(docker.find(panelId), 'remove');
docker?.dockMove(docker.find(panelId), 'remove');
}
static focus(docker, panelId) {
docker.updateTab(panelId, null, true);
docker?.updateTab(panelId, null, true);
}
static openDialog(docker, panelData, width=500, height=300) {
@ -128,12 +180,16 @@ export class LayoutHelper {
tabs: [LayoutHelper.getPanel({
...panelData,
group: 'dialogs',
closable: true,
closable: false,
})],
}, null, 'float');
}
}
static isTabOpen(docker, panelId) {
return Boolean(docker.find(panelId));
}
static openTab(docker, panelData, refTabId, direction, forceRerender=false) {
let panel = docker.find(panelData.id);
if(panel) {
@ -149,31 +205,110 @@ export class LayoutHelper {
}
}
export default function Layout({groups, layoutInstance, ...props}) {
function saveLayout(layoutObj, layoutId) {
let api = getApiInstance();
if(!layoutId || !layoutObj) {
return;
}
const formData = new FormData();
formData.append('setting', layoutId);
formData.append('value', JSON.stringify(layoutObj.saveLayout()));
api.post(url_for('settings.store_bulk'), formData)
.catch(()=>{/* No need to throw error */});
}
function getDialogsGroup() {
return {
disableDock: true,
tabLocked: true,
floatable: 'singleTab',
panelExtra: (panelData, context) => (
<div>
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>{
context.dockMove(panelData, null, 'remove');
}} />
</div>
)
};
}
function getDefaultGroup() {
return {
maximizable: false,
panelExtra: (panelData, context) => {
let icon = <ExpandDialogIcon style={{width: '0.7em'}}/>;
let title = gettext('Maximise');
if(panelData?.parent?.mode == 'maximize') {
icon = <MinimizeDialogIcon />;
title = gettext('Restore');
}
return <div>
<PgIconButton title={title} icon={icon} size="xs" noBorder onClick={()=>{
context.dockMove(panelData, null, 'maximize');
}} />
</div>;
}
};
}
export default function Layout({groups, getLayoutInstance, layoutId, savedLayout, ...props}) {
const classes = useStyles();
const layoutObj = useRef();
const defaultGroups = React.useMemo(()=>({
'dialogs': {
disableDock: true,
tabLocked: true,
floatable: 'singleTab',
},
'dialogs': getDialogsGroup(),
'default': getDefaultGroup(),
...groups,
}), [groups]);
return (
const layoutEventBus = React.useRef(new EventBus());
return useMemo(()=>(
<div className={classes.docklayout}>
<DockLayout
style={{
height: '100%',
}}
ref={layoutInstance}
groups={defaultGroups}
{...props}
/>
<LayoutEventsContext.Provider value={layoutEventBus.current}>
<DockLayout
style={{
height: '100%',
}}
ref={(obj)=>{
layoutObj.current = obj;
if(layoutObj.current) {
layoutObj.current.resetLayout = ()=>{
layoutObj.current.loadLayout(props.defaultLayout);
saveLayout(layoutObj.current, layoutId);
};
}
getLayoutInstance?.(layoutObj.current);
try {
layoutObj.current?.loadLayout(JSON.parse(savedLayout));
} catch {
/* Fallback to default */
layoutObj.current?.loadLayout(props.defaultLayout);
}
}}
groups={defaultGroups}
onLayoutChange={(_l, currentTabId, direction)=>{
saveLayout(layoutObj.current, layoutId);
if(Object.values(LAYOUT_EVENTS).indexOf(direction) > -1) {
layoutEventBus.current.fireEvent(LAYOUT_EVENTS[direction.toUpperCase()], currentTabId);
}
}}
{...props}
/>
</LayoutEventsContext.Provider>
</div>
);
), []);
}
Layout.propTypes = {
groups: PropTypes.object,
layoutInstance: CustomPropTypes.ref,
getLayoutInstance: PropTypes.func,
};
export const LAYOUT_EVENTS = {
ACTIVE: 'active',
REMOVE: 'remove',
FLOAT: 'float',
FRONT: 'front',
MAXIMIZE: 'maximize',
MOVE: 'move',
};

View File

@ -209,7 +209,7 @@ PaperComponent.propTypes = {
height: PropTypes.number,
};
const useModalStyles = makeStyles(() => ({
export const useModalStyles = makeStyles((theme) => ({
titleBar: {
display: 'flex',
flexGrow: 1
@ -227,9 +227,18 @@ const useModalStyles = makeStyles(() => ({
flexShrink: 0,
userSelect: 'none',
},
footer: {
display: 'flex',
justifyContent: 'flex-end',
padding: '0.5rem',
...theme.mixins.panelBorder?.top,
},
margin: {
marginLeft: '0.25rem',
},
iconButtonStyle: {
marginLeft: 'auto',
marginRight: '0.3em'
marginRight: '4px'
}
}));

View File

@ -1,35 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import moment from 'moment';
import gettext from 'sources/gettext';
export function calculateQueryRunTime(startTime, endTime) {
let total_ms = moment(endTime).diff(startTime);
let result = '';
let secs, mins, hrs;
/* Extract seconds from millisecs */
secs = parseInt(total_ms/1000);
total_ms = total_ms%1000;
/* Extract mins from seconds */
mins = parseInt(secs/60);
secs = secs%60;
/* Extract hrs from mins */
hrs = parseInt(mins/60);
mins = mins%60;
result = (hrs>0 ? hrs + ' ' + gettext('hr') + ' ': '')
+ (mins>0 ? mins + ' ' + gettext('min') + ' ': '')
+ (hrs<=0 && secs>0 ? secs + ' ' + gettext('secs') + ' ': '')
+ (hrs<=0 && mins<=0 ? total_ms + ' ' + gettext('msec') + ' ':'');
return result.trim();
}

View File

@ -1,57 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import {calculateQueryRunTime} from './calculate_query_run_time';
import gettext from '../gettext';
function hasResultsToDisplay(res) {
return res.colinfo != null;
}
function isQueryTool(sqlEditor) {
return sqlEditor.is_query_tool;
}
function isNotificationEnabled(sqlEditor) {
return sqlEditor.info_notifier_timeout >= 0;
}
export function callRenderAfterPoll(sqlEditor, Notify, res) {
sqlEditor.query_end_time = new Date();
sqlEditor.rows_affected = res.rows_affected;
sqlEditor.has_more_rows = res.has_more_rows;
if (hasResultsToDisplay(res)) {
sqlEditor._render(res);
} else {
sqlEditor.total_time = calculateQueryRunTime(
sqlEditor.query_start_time,
sqlEditor.query_end_time);
const msg = gettext('Query returned successfully in %s.', sqlEditor.total_time);
if (res.result)
res.result += '\n\n' + msg;
else
res.result = msg;
sqlEditor.update_msg_history(true, res.result, false);
sqlEditor.reset_data_store();
if (isNotificationEnabled(sqlEditor)) {
Notify.success(msg, sqlEditor.info_notifier_timeout);
}
sqlEditor.enable_disable_download_btn(true);
}
if (isQueryTool(sqlEditor)) {
sqlEditor.disable_tool_buttons(false);
}
sqlEditor.trigger('pgadmin-sqleditor:check_synchronous_db_name_change', res);
sqlEditor.setIsQueryRunning(false);
sqlEditor.trigger('pgadmin-sqleditor:loading-icon:hide');
}

View File

@ -1,370 +0,0 @@
//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////////////////
import gettext from '../gettext';
import $ from 'jquery';
import url_for from '../url_for';
import axios from 'axios';
import * as httpErrorHandler from './query_tool_http_error_handler';
import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
import * as SqlEditorUtils from 'sources/sqleditor_utils';
class LoadingScreen {
constructor(sqlEditor) {
this.sqlEditor = sqlEditor;
}
setMessage(message) {
this.sqlEditor.trigger(
'pgadmin-sqleditor:loading-icon:message',
gettext(message)
);
}
show(withMessage) {
this.sqlEditor.trigger(
'pgadmin-sqleditor:loading-icon:show',
withMessage
);
}
hide() {
this.sqlEditor.trigger('pgadmin-sqleditor:loading-icon:hide');
}
}
class ExecuteQuery {
constructor(sqlEditor, userManagement) {
this.sqlServerObject = sqlEditor;
this.loadingScreen = new LoadingScreen(sqlEditor);
this.userManagement = userManagement;
}
delayedPoll() {
const self = this;
setTimeout(
() => {
self.poll();
}, self.sqlServerObject.POLL_FALLBACK_TIME());
}
execute(sqlStatement, explainPlan, connect) {
// If it is an empty query, do nothing.
if (sqlStatement.length <= 0) {
// Enable query execution button if user execute empty query.
$('#btn-flash').prop('disabled', false);
return;
}
const self = this;
self.explainPlan = explainPlan;
const sqlStatementWithAnalyze = ExecuteQuery.prepareAnalyzeSql(sqlStatement, explainPlan);
self.initializeExecutionOnSqlEditor(sqlStatementWithAnalyze);
axios.post(
this.generateURLReconnectionFlag(connect),
JSON.stringify(sqlStatementWithAnalyze),
{headers: {'Content-Type': 'application/json'}})
.then(function (result) {
let httpMessageData = result.data;
self.removeGridViewMarker();
self.updateSqlEditorLastTransactionStatus(httpMessageData.data.transaction_status);
if (ExecuteQuery.isSqlCorrect(httpMessageData)) {
self.loadingScreen.setMessage('Waiting for the query to complete...');
// Disable drop down arrow to change connections
SqlEditorUtils.disable_connection_dropdown(true);
self.updateSqlEditorStateWithInformationFromServer(httpMessageData.data);
// If status is True then poll the result.
self.delayedPoll();
} else {
self.loadingScreen.hide();
self.enableSQLEditorButtons();
self.disableDownloadButton();
// Enable/Disable commit and rollback button.
if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
|| result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
self.enableTransactionButtons();
} else {
self.disableTransactionButtons();
}
self.sqlServerObject.update_msg_history(false, httpMessageData.data.result);
if ('notifies' in httpMessageData.data)
self.sqlServerObject.update_notifications(httpMessageData.data.notifies);
// Highlight the error in the sql panel
self.sqlServerObject._highlight_error(httpMessageData.data.result);
}
}).catch(function (error) {
self.onExecuteHTTPError(error);
}
);
}
generateURLReconnectionFlag(shouldReconnect) {
let url = url_for('sqleditor.query_tool_start', {
'trans_id': this.sqlServerObject.transId,
});
if (shouldReconnect) {
url += '?connect=1';
}
return url;
}
poll() {
const self = this;
axios.get(
url_for('sqleditor.poll', {
'trans_id': self.sqlServerObject.transId,
})
).then(
(httpMessage) => {
self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
// Enable/Disable commit and rollback button.
if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
|| httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
self.enableTransactionButtons();
} else {
self.disableTransactionButtons();
}
if (ExecuteQuery.isQueryFinished(httpMessage)) {
if (this.sqlServerObject.close_on_idle_transaction &&
httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
this.sqlServerObject.check_needed_confirmations_before_closing_panel();
self.loadingScreen.setMessage('Loading data from the database server and rendering...');
self.sqlServerObject.call_render_after_poll(httpMessage.data.data);
if ('notifies' in httpMessage.data.data)
self.sqlServerObject.update_notifications(httpMessage.data.data.notifies);
} else if (ExecuteQuery.isQueryStillRunning(httpMessage)) {
// If status is Busy then poll the result by recursive call to the poll function
this.delayedPoll();
self.sqlServerObject.setIsQueryRunning(true);
if (httpMessage.data.data.result) {
self.sqlServerObject.update_msg_history(httpMessage.data.data.status, httpMessage.data.data.result, false);
}
} else if (ExecuteQuery.isConnectionToServerLostWhilePolling(httpMessage)) {
self.loadingScreen.hide();
// Enable/Disable query tool button only if is_query_tool is true.
if (self.sqlServerObject.is_query_tool) {
self.enableSQLEditorButtons();
}
self.sqlServerObject.update_msg_history(false, httpMessage.data.data.result, true);
} else if (ExecuteQuery.isQueryCancelled(httpMessage)) {
self.loadingScreen.hide();
self.sqlServerObject.update_msg_history(false, 'Execution Cancelled!', true);
}
// Enable connection list drop down again for query tool only
if(self.sqlServerObject.is_query_tool && !ExecuteQuery.isQueryStillRunning(httpMessage)){
SqlEditorUtils.disable_connection_dropdown(false);
}
}
).catch(
error => {
// Enable/Disable query tool button only if is_query_tool is true.
self.sqlServerObject.resetQueryHistoryObject(self.sqlServerObject);
self.loadingScreen.hide();
self.sqlServerObject.setIsQueryRunning(false);
if (self.sqlServerObject.is_query_tool) {
self.enableSQLEditorButtons();
SqlEditorUtils.disable_connection_dropdown(false);
}
if(error.response) {
if(ExecuteQuery.wasConnectionLostToPythonServer(error.response)) {
self.handleConnectionToServerLost();
return;
}
const errorData = error.response.data;
if (self.userManagement.isPgaLoginRequired(errorData)) {
return self.userManagement.pgaLogin();
}
let msg = ExecuteQuery.extractErrorMessage(errorData);
self.sqlServerObject.update_msg_history(false, msg);
// Highlight the error in the sql panel
self.sqlServerObject._highlight_error(msg);
} else if(error.request) {
self.handleConnectionToServerLost();
return;
} else {
console.error(error);
}
});
}
initializeExecutionOnSqlEditor(sqlStatement) {
this.loadingScreen.show(gettext('Running query...'));
$('#btn-flash').prop('disabled', true);
this.disableDownloadButton();
this.sqlServerObject.query_start_time = new Date();
if (typeof sqlStatement === 'object') {
this.sqlServerObject.query = sqlStatement['sql'];
} else {
this.sqlServerObject.query = sqlStatement;
}
this.sqlServerObject.rows_affected = 0;
this.sqlServerObject._init_polling_flags();
this.disableSQLEditorButtons();
this.disableTransactionButtons();
}
static prepareAnalyzeSql(sqlStatement, analyzeSql) {
return {
sql: sqlStatement,
explain_plan: analyzeSql,
};
}
onExecuteHTTPError(httpMessage) {
this.loadingScreen.hide();
this.enableSQLEditorButtons();
if (ExecuteQuery.wasConnectionLostToPythonServer(httpMessage.response)) {
this.handleConnectionToServerLost();
return;
}
if (this.userManagement.isPgaLoginRequired(httpMessage.response)) {
this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
this.userManagement.pgaLogin();
}
if (httpErrorHandler.httpResponseRequiresNewTransaction(httpMessage.response)) {
this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
this.sqlServerObject.initTransaction();
}
if (this.wasDatabaseConnectionLost(httpMessage)) {
this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
this.sqlServerObject.handle_connection_lost(false, httpMessage);
}
if(this.isCryptKeyMissing(httpMessage)) {
this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
this.sqlServerObject.handle_cryptkey_missing();
return;
}
let msg = httpMessage.response.data.errormsg;
this.sqlServerObject.update_msg_history(false, msg);
}
wasDatabaseConnectionLost(httpMessage) {
return httpMessage.response.status === 503 &&
httpMessage.response.data.info !== undefined &&
httpMessage.response.data.info === 'CONNECTION_LOST';
}
isCryptKeyMissing(httpMessage) {
return httpMessage.response.status === 503 &&
httpMessage.response.data.info !== undefined &&
httpMessage.response.data.info === 'CRYPTKEY_MISSING';
}
removeGridViewMarker() {
if (this.sqlServerObject.gridView.marker) {
this.sqlServerObject.gridView.marker.clear();
delete this.sqlServerObject.gridView.marker;
this.sqlServerObject.gridView.marker = null;
// Remove already existing marker
this.sqlServerObject.gridView.query_tool_obj.removeLineClass(this.sqlServerObject.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
}
}
disableDownloadButton() {
this.sqlServerObject.enable_disable_download_btn(true);
}
enableSQLEditorButtons() {
this.sqlServerObject.disable_tool_buttons(false);
}
disableSQLEditorButtons() {
this.sqlServerObject.disable_tool_buttons(true);
}
enableTransactionButtons() {
this.sqlServerObject.disable_transaction_buttons(false);
}
disableTransactionButtons() {
this.sqlServerObject.special_sql = undefined;
this.sqlServerObject.disable_transaction_buttons(true);
}
static wasConnectionLostToPythonServer(httpResponse) {
return _.isUndefined(httpResponse) || _.isUndefined(httpResponse.data);
}
handleConnectionToServerLost() {
this.sqlServerObject.update_msg_history(false,
gettext('Not connected to the server or the connection to the server has been closed.')
);
}
updateSqlEditorStateWithInformationFromServer(messageData) {
this.sqlServerObject.can_edit = messageData.can_edit;
this.sqlServerObject.can_filter = messageData.can_filter;
this.sqlServerObject.info_notifier_timeout = messageData.info_notifier_timeout;
}
updateSqlEditorLastTransactionStatus(transactionStatus) {
this.sqlServerObject.last_transaction_status = transactionStatus;
}
static isSqlCorrect(httpMessageData) {
return httpMessageData.data.status;
}
static extractErrorMessage(httpMessage) {
let msg = httpMessage.errormsg;
if (httpMessage.responseJSON !== undefined &&
httpMessage.responseJSON.errormsg !== undefined)
msg = httpMessage.responseJSON.errormsg;
return msg;
}
static isQueryFinished(httpMessage) {
return httpMessage.data.data.status === 'Success';
}
static isQueryStillRunning(httpMessage) {
return httpMessage.data.data.status === 'Busy';
}
static isQueryCancelled(httpMessage) {
return httpMessage.data.data.status === 'Cancel';
}
static isConnectionToServerLostWhilePolling(httpMessage) {
return httpMessage.data.data.status === 'NotConnected';
}
}
module.exports = {
ExecuteQuery: ExecuteQuery,
};

View File

@ -1,278 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
import $ from 'jquery';
import Alertify from 'pgadmin.alertifyjs';
import pgAdmin from 'sources/pgadmin';
import Backform from 'pgadmin.backform';
import axios from 'axios';
var queryToolActions = require('sources/sqleditor/query_tool_actions');
import filterDialogModel from 'sources/sqleditor/filter_dialog_model';
import {handleQueryToolAjaxError} from 'sources/sqleditor/query_tool_http_error_handler';
import Notify from '../../../static/js/helpers/Notifier';
let FilterDialog = {
geturl: function(transId, reconnect) {
let url = url_for('sqleditor.get_filter_data', {
'trans_id': transId,
});
if(reconnect) {
url += '?connect=1';
}
return url;
},
'dialog': function(handler, reconnect) {
let title = gettext('Sort/Filter options');
$.ajax({
url: this.geturl(handler.transId, reconnect),
headers: {
'Cache-Control' : 'no-cache',
},
})
.done(function (res) {
let response = res.data.result;
// Check the alertify dialog already loaded then delete it to clear
// the cache
if (Alertify.filterDialog) {
delete Alertify.filterDialog;
}
// Create Dialog
Alertify.dialog('filterDialog', function factory() {
let $container = $('<div class=\'data_sorting_dialog\'></div>');
return {
main: function() {
this.set('title', gettext('Sort/Filter options'));
},
build: function() {
this.elements.content.appendChild($container.get(0));
Alertify.pgDialogBuild.apply(this);
},
setup: function() {
return {
buttons: [{
text: '',
key: 112,
className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
attrs: {
name: 'dialog_help',
type: 'button',
label: gettext('Help'),
'aria-label': gettext('Help'),
url: url_for('help.static', {
'filename': 'editgrid.html',
}),
},
}, {
text: gettext('Cancel'),
key: 27,
className: 'btn btn-secondary fa fa-times pg-alertify-button',
'data-btn-name': 'cancel',
}, {
text: gettext('OK'),
className: 'btn btn-primary fa fa-check pg-alertify-button',
'data-btn-name': 'ok',
}],
// Set options for dialog
options: {
title: title,
//disable both padding and overflow control.
padding: !1,
overflow: !1,
model: 0,
resizable: true,
maximizable: true,
pinnable: false,
closableByDimmer: false,
modal: false,
autoReset: false,
},
};
},
hooks: {
// triggered when the dialog is closed
onclose: function() {
if (this.view) {
this.filterCollectionModel.stopSession();
this.view.model.stopSession();
this.view.remove({
data: true,
internal: true,
silent: true,
});
}
},
},
prepare: function() {
let self = this;
$container.html('');
// Disable Ok button
this.__internal.buttons[2].element.disabled = true;
// Status bar
this.statusBar = $(
'<div class=\'pg-prop-status-bar pg-el-xs-12 d-none\'>' +
' <div class="error-in-footer"> ' +
' <div class="d-flex px-2 py-1"> ' +
' <div class="pr-2"> ' +
' <i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i> ' +
' </div> ' +
' <div class="alert-text" role="alert"></div> ' +
' </div> ' +
' </div> ' +
'</div>').appendTo($container);
// To show progress on filter Saving/Updating on AJAX
this.showFilterProgress = $(
`<div id="show_filter_progress" class="pg-sp-container sql-editor-busy-fetching d-none">
<div class="pg-sp-content">
<div class="row"><div class="col-12 pg-sp-icon sql-editor-busy-icon"></div></div>
<div class="row"><div class="col-12 pg-sp-text sql-editor-busy-text">` + gettext('Loading data...') + `</div></div>
</div>
</div>`
).appendTo($container);
$(
self.showFilterProgress[0]
).removeClass('d-none');
self.filterCollectionModel = filterDialogModel(response);
let fields = Backform.generateViewSchema(
null, self.filterCollectionModel, 'create', null, null, true
);
let view = this.view = new Backform.Dialog({
el: '<div></div>',
model: self.filterCollectionModel,
schema: fields,
});
$(this.elements.body.childNodes[0]).addClass(
'alertify_tools_dialog_properties obj_properties'
);
$container.append(view.render().$el);
// Enable/disable save button and show/hide statusbar based on session
view.listenTo(view.model, 'pgadmin-session:start', function() {
view.listenTo(view.model, 'pgadmin-session:invalid', function(msg) {
self.statusBar.removeClass('d-none');
$(self.statusBar.find('.alert-text')).html(msg);
// Disable Okay button
self.__internal.buttons[2].element.disabled = true;
});
view.listenTo(view.model, 'pgadmin-session:valid', function() {
self.statusBar.addClass('d-none');
$(self.statusBar.find('.alert-text')).html('');
// Enable Okay button
self.__internal.buttons[2].element.disabled = false;
});
});
view.listenTo(view.model, 'pgadmin-session:stop', function() {
view.stopListening(view.model, 'pgadmin-session:invalid');
view.stopListening(view.model, 'pgadmin-session:valid');
});
// Starts monitoring changes to model
view.model.startNewSession();
// Set data in collection
let viewDataSortingModel = view.model.get('data_sorting');
viewDataSortingModel.add(response['data_sorting']);
// Hide Progress ...
$(
self.showFilterProgress[0]
).addClass('d-none');
},
// Callback functions when click on the buttons of the Alertify dialogs
callback: function(e) {
let self = this;
if (e.button.element.name == 'dialog_help') {
e.cancel = true;
pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
null, null);
} else if (e.button['data-btn-name'] === 'ok') {
e.cancel = true; // Do not close dialog
let filterCollectionModel = this.filterCollectionModel.toJSON();
// Show Progress ...
$(
self.showFilterProgress[0]
).removeClass('d-none');
axios.put(
url_for('sqleditor.set_filter_data', {
'trans_id': handler.transId,
}),
filterCollectionModel
).then(function (result) {
// Hide Progress ...
$(
self.showFilterProgress[0]
).addClass('d-none');
let filterResponse = result.data.data;
if (filterResponse.status) {
setTimeout(
function() {
self.close(); // Close the dialog now
Notify.success(gettext('Filter updated successfully'));
queryToolActions.executeQuery(handler);
}, 10
);
} else {
Notify.alert(
gettext('Validation Error'),
filterResponse.result
);
}
}).catch(function (error) {
// Hide Progress ...
$(
self.showFilterProgress[0]
).addClass('d-none');
handler.onExecuteHTTPError(error);
setTimeout(
function() {
Notify.error(error);
}, 10
);
});
} else {
self.close();
}
},
};
});
Alertify.filterDialog(title).resizeTo(pgAdmin.Browser.stdW.md,pgAdmin.Browser.stdH.md);
})
.fail(function(e) {
handleQueryToolAjaxError(pgAdmin, handler, e, '_show_filter', [], true);
});
},
};
module.exports = FilterDialog;

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