diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-03-26 11:28:58 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-03-26 12:19:02 +0200 |
commit | 746bcd25e22e492cd45a92bc9addb04cf81d208b (patch) | |
tree | 3244166092e839b0c19539742ec9377bac6e3517 | |
download | rcc-746bcd25e22e492cd45a92bc9addb04cf81d208b.tar.xz |
Initial commit
-rw-r--r-- | .gitmodules | 6 | ||||
m--------- | 3rd-party/frozen | 0 | ||||
m--------- | 3rd-party/tabler-icons | 0 | ||||
-rw-r--r-- | lib/embed.cpp | 70 | ||||
-rw-r--r-- | lib/embed.h | 34 | ||||
-rw-r--r-- | meson.build | 37 | ||||
-rw-r--r-- | readme.md | 37 | ||||
-rwxr-xr-x | scripts/gen-resources.sh | 9 | ||||
-rwxr-xr-x | scripts/rcc | 101 | ||||
-rw-r--r-- | test/main.cpp | 17 | ||||
-rw-r--r-- | test/resources.xrc | 377 |
11 files changed, 688 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..36e8968 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "3rd-party/frozen"] + path = 3rd-party/frozen + url = https://github.com/serge-sans-paille/frozen +[submodule "3rd-party/tabler-icons"] + path = 3rd-party/tabler-icons + url = https://github.com/tabler/tabler-icons diff --git a/3rd-party/frozen b/3rd-party/frozen new file mode 160000 +Subproject 8357f86de5383dde8539734d3a1620ecc70e4a1 diff --git a/3rd-party/tabler-icons b/3rd-party/tabler-icons new file mode 160000 +Subproject ec114c0eb5bbfec35ce32ec7201be01cb01b24d diff --git a/lib/embed.cpp b/lib/embed.cpp new file mode 100644 index 0000000..c3b0286 --- /dev/null +++ b/lib/embed.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "embed.h" +#include <zstd.h> // presumes zstd library is installed +#include <cassert> + +using namespace embed; + +ZSTD_DDict* dictPtr = nullptr; + +Resources::Resources(const ResourceData &info) + : m_info(info) +{ + if(!info.dictionary.empty()) { + dictPtr = ZSTD_createDDict(info.dictionary.data(), info.dictionary.size()); + } +} + +Resources::~Resources() +{ + if(dictPtr != nullptr) { + ZSTD_freeDDict(dictPtr); + } +} + +[[nodiscard]] std::span<unsigned char> Resources::decompress(const std::span<const unsigned char> &entry) +{ + /* Read the content size from the frame header. For simplicity we require + * that it is always present. By default, zstd will write the content size + * in the header when it is known. If you can't guarantee that the frame + * content size is always written into the header, either use streaming + * decompression, or ZSTD_decompressBound(). + */ + unsigned long long const rSize = ZSTD_getFrameContentSize(entry.data(), entry.size()); + assert(rSize != ZSTD_CONTENTSIZE_ERROR); //, "%s: not compressed by zstd!", fname); + assert(rSize != ZSTD_CONTENTSIZE_UNKNOWN); //, "%s: original size unknown!", fname); + auto* rBuff = new unsigned char[(size_t) rSize]; + + /* Check that the dictionary ID matches. + * If a non-zstd dictionary is used, then both will be zero. + * By default zstd always writes the dictionary ID into the frame. + * Zstd will check if there is a dictionary ID mismatch as well. + */ + unsigned const expectedDictID = ZSTD_getDictID_fromDDict(dictPtr); + unsigned const actualDictID = ZSTD_getDictID_fromFrame(entry.data(), entry.size()); + assert(actualDictID == expectedDictID); //"DictID mismatch: expected %u got %u", + + /* Decompress using the dictionary. + * If you need to control the decompression parameters, then use the + * advanced API: ZSTD_DCtx_setParameter(), ZSTD_DCtx_refDDict(), and + * ZSTD_decompressDCtx(). + */ + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + assert(dctx != NULL); //, "ZSTD_createDCtx() failed!"); + size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, entry.data(), entry.size(), dictPtr); + /* When zstd knows the content size, it will error if it doesn't match. */ + assert(dSize == rSize); //, "Impossible because zstd will check this condition!"); + + ZSTD_freeDCtx(dctx); + return std::span(rBuff, rSize); +} + diff --git a/lib/embed.h b/lib/embed.h new file mode 100644 index 0000000..566b14c --- /dev/null +++ b/lib/embed.h @@ -0,0 +1,34 @@ +#pragma once + +#include <span> +#include <string> +#include <unordered_map> +#include <frozen/unordered_map.h> +#include <frozen/string.h> + +namespace embed { + +enum Compression { + None, + Zstd +}; + +struct ResourceData { + Compression compression = None; + std::span<const unsigned char> dictionary; +}; + +class Resources { +public: + explicit Resources(const ResourceData &info); + ~Resources(); + + [[nodiscard]] + std::span<unsigned char> decompress(const std::span<const unsigned char> &entry); + +private: + const ResourceData m_info; +}; // class + +} + diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..ffae406 --- /dev/null +++ b/meson.build @@ -0,0 +1,37 @@ +project('libembed', ['cpp'], + default_options: ['cpp_std=c++2a', 'warning_level=3'], +) + +# libstdc++ lacks std::span at the moment +add_project_arguments(['-stdlib=libc++'], language: 'cpp') +add_project_link_arguments(['-stdlib=libc++'], language : 'cpp') + +dep_zstd = dependency('libzstd') +dep_gtest = dependency('gtest') + +libembed = library('embed', + 'lib/embed.cpp', + dependencies: [ dep_zstd ], + include_directories: '3rd-party/frozen/include/' +) + +dep_libembed = declare_dependency( + link_with: libembed, + include_directories: include_directories('lib/', '3rd-party/frozen/include') +) + +prog_python = import('python').find_installation('python3') +resources_h = custom_target('resources.h', + output: 'resources.h', + input: 'scripts/rcc', + command: [prog_python, '@INPUT@', '--compress=Zstd', '--dict=dictionary', '--output=@OUTPUT@', meson.current_source_dir()/'3rd-party/tabler-icons/icons/chevron-up.svg'], +) + +test('libembed', + executable('embed', + sources: [ 'test/main.cpp', resources_h ], + dependencies: [ dep_gtest, dep_libembed ] + ), + env: environment({ 'CONFIGFILE' : meson.current_source_dir()/'test/defaultrc.ini' }), + workdir: meson.current_source_dir()/'test' +) diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..d75ac34 --- /dev/null +++ b/readme.md @@ -0,0 +1,37 @@ +## rcc + +This is a resource compiler for C++, similar to Qt's rcc. It will generate hexdumps of files, optionally compress them with zstd. + +### requirements +* rcc tool requires python +* zstd compression requires zstd + +libembed: +* c++20 +* frozen: https://github.com/serge-sans-paille/frozen (constexpr string and unordered_map) + +### license + +Copyright (c) 2020 aqua@iserlohn-fortress.net + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + diff --git a/scripts/gen-resources.sh b/scripts/gen-resources.sh new file mode 100755 index 0000000..a1db9fd --- /dev/null +++ b/scripts/gen-resources.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +echo '<RCC>' +echo ' <qresource prefix="/icons">' +for f in $@; do + echo ' <file alias="'$(basename $f)'">'$f'</file>'; +done +echo ' </qresource>' +echo '</RCC>' diff --git a/scripts/rcc b/scripts/rcc new file mode 100755 index 0000000..2ca587c --- /dev/null +++ b/scripts/rcc @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import os.path +import subprocess +import xml.etree.ElementTree as xml + +def train(files, output, zstd='zstd', maxdict=512): + cmd = [ zstd, '--train', '--stdout', '--maxdict=' + str(maxdict), '-o', output ] + + for f in files: + cmd.append(f.name) + + subprocess.run(cmd) + +def compress(file, zstd='zstd', level=19, dictionary=None): + cmd = [ zstd, '--compress', '--stdout', '-' + str(level) ] + + if dictionary is not None: + cmd.append('-D') + cmd.append(dictionary.name) + + cmd.append(file.name) + return subprocess.run(cmd, capture_output=True).stdout + +def hexdump(array_name, input_file, out_h): + array_len = 0 + + print("constexpr unsigned char {}[] = {{".format(array_name), file=out_h) + + for byte in input_file[0:len(input_file)]: + array_len+=1 + if array_len%16 == 0: + print(" 0x{:02X},".format(byte), file=out_h) + else: + print(" 0x{:02X},".format(byte), file=out_h, end='') + + + print("};", file=out_h) + print("constexpr size_t {}_len = {};\n".format(array_name, array_len), file=out_h) + +def name(path): + name = path.replace('/', '_') + if name.endswith('.zstd'): + name = name[:-5] + name = name.replace('-', '_') + name = name.replace('.', '_') + return name + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description='Resource Compiler for C++', + epilog='If using compression, make sure the required dependencies are provided.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + + parser.add_argument('input', type=argparse.FileType('rt'), help='input file (.xrc)') + parser.add_argument('-o', '--output', type=argparse.FileType('wt'), metavar='OUT', default=sys.stdout, help='output header file') + + parser.add_argument('--compress', choices=[ 'None', 'Zstd' ], help='compress input files using algorightm') + parser.add_argument('--dict', type=argparse.FileType('rb'), help='[zstd] use specified dictionary, recommended for many similar small files') + parser.add_argument('--train', action='store_true', help='[zstd] train dictionary') + + args=parser.parse_args() + + entries_list = "" + + if args.compress=='Zstd' and args.train: + train(args.input, args.dict.name) + + # write header + print("// Autogenerated binary file hexdump", file=args.output) + print("// This file may get overwritten by the build system\n", file=args.output) + print("#include <embed.h>\n", file=args.output) + + # write file data + for child in xml.parse(args.input).getroot(): + if child.tag == 'qresource': + prefix = child.attrib['prefix'] + for i in child: + vname = name(i.text) + with open(i.text) as f: + hexdump(vname, compress(f, dictionary=args.dict), args.output) + entries_list += " {{ \"{}/{}\", std::span({}, {}_len) }},\n".format(prefix, i.attrib['alias'], vname, vname) + + # write dictionary + if args.dict is not None: + hexdump('dictionary', args.dict.read(), args.output) + + # write entries + print("constexpr auto entries = frozen::make_unordered_map<frozen::string, std::span<const unsigned char>>({", file=args.output) + print(entries_list, file=args.output) + print("});\n", file=args.output) + + # write metadata struct + print("constexpr embed::ResourceData metadata = {", file=args.output) + print(" .compression = embed::{},".format(args.compress), file=args.output) + if args.dict is not None: + print(" .dictionary = std::span(dictionary, dictionary_len),", file=args.output) + print("};", file=args.output) diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 0000000..faf5a16 --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,17 @@ +#include <gtest/gtest.h> +#include "resources.h" +#include <cstdio> + +int main(int argc, char** argv) +{ +// testing::InitGoogleTest(&argc, argv); +// return RUN_ALL_TESTS(); + embed::Resources ctx(metadata); + constexpr auto raw = entries.at("/icons/chevron-up.svg"); + static_assert(!raw.empty()); + const auto x = ctx.decompress(raw); + for(const char c : x) + printf("%c", c); + delete[] x.data(); + return 0; +} diff --git a/test/resources.xrc b/test/resources.xrc new file mode 100644 index 0000000..deb35d9 --- /dev/null +++ b/test/resources.xrc @@ -0,0 +1,377 @@ +<RCC> + <qresource prefix="/icons"> + <file alias="activity.svg">../3rd-party/tabler-icons/icons/activity.svg</file> + <file alias="ad.svg">../3rd-party/tabler-icons/icons/ad.svg</file> + <file alias="adjustments.svg">../3rd-party/tabler-icons/icons/adjustments.svg</file> + <file alias="alarm.svg">../3rd-party/tabler-icons/icons/alarm.svg</file> + <file alias="alert-circle.svg">../3rd-party/tabler-icons/icons/alert-circle.svg</file> + <file alias="alert-triangle.svg">../3rd-party/tabler-icons/icons/alert-triangle.svg</file> + <file alias="align-center.svg">../3rd-party/tabler-icons/icons/align-center.svg</file> + <file alias="align-justified.svg">../3rd-party/tabler-icons/icons/align-justified.svg</file> + <file alias="align-left.svg">../3rd-party/tabler-icons/icons/align-left.svg</file> + <file alias="align-right.svg">../3rd-party/tabler-icons/icons/align-right.svg</file> + <file alias="aperture.svg">../3rd-party/tabler-icons/icons/aperture.svg</file> + <file alias="archive.svg">../3rd-party/tabler-icons/icons/archive.svg</file> + <file alias="arrow-back.svg">../3rd-party/tabler-icons/icons/arrow-back.svg</file> + <file alias="arrow-bar-down.svg">../3rd-party/tabler-icons/icons/arrow-bar-down.svg</file> + <file alias="arrow-bar-left.svg">../3rd-party/tabler-icons/icons/arrow-bar-left.svg</file> + <file alias="arrow-bar-right.svg">../3rd-party/tabler-icons/icons/arrow-bar-right.svg</file> + <file alias="arrow-bar-up.svg">../3rd-party/tabler-icons/icons/arrow-bar-up.svg</file> + <file alias="arrow-down-circle.svg">../3rd-party/tabler-icons/icons/arrow-down-circle.svg</file> + <file alias="arrow-down-left-circle.svg">../3rd-party/tabler-icons/icons/arrow-down-left-circle.svg</file> + <file alias="arrow-down-left.svg">../3rd-party/tabler-icons/icons/arrow-down-left.svg</file> + <file alias="arrow-down-right-circle.svg">../3rd-party/tabler-icons/icons/arrow-down-right-circle.svg</file> + <file alias="arrow-down-right.svg">../3rd-party/tabler-icons/icons/arrow-down-right.svg</file> + <file alias="arrow-down.svg">../3rd-party/tabler-icons/icons/arrow-down.svg</file> + <file alias="arrow-forward.svg">../3rd-party/tabler-icons/icons/arrow-forward.svg</file> + <file alias="arrow-left-circle.svg">../3rd-party/tabler-icons/icons/arrow-left-circle.svg</file> + <file alias="arrow-left.svg">../3rd-party/tabler-icons/icons/arrow-left.svg</file> + <file alias="arrow-narrow-down.svg">../3rd-party/tabler-icons/icons/arrow-narrow-down.svg</file> + <file alias="arrow-narrow-left.svg">../3rd-party/tabler-icons/icons/arrow-narrow-left.svg</file> + <file alias="arrow-narrow-right.svg">../3rd-party/tabler-icons/icons/arrow-narrow-right.svg</file> + <file alias="arrow-narrow-up.svg">../3rd-party/tabler-icons/icons/arrow-narrow-up.svg</file> + <file alias="arrow-right-circle.svg">../3rd-party/tabler-icons/icons/arrow-right-circle.svg</file> + <file alias="arrow-right.svg">../3rd-party/tabler-icons/icons/arrow-right.svg</file> + <file alias="arrow-up-circle.svg">../3rd-party/tabler-icons/icons/arrow-up-circle.svg</file> + <file alias="arrow-up-left-circle.svg">../3rd-party/tabler-icons/icons/arrow-up-left-circle.svg</file> + <file alias="arrow-up-left.svg">../3rd-party/tabler-icons/icons/arrow-up-left.svg</file> + <file alias="arrow-up-right-circle.svg">../3rd-party/tabler-icons/icons/arrow-up-right-circle.svg</file> + <file alias="arrow-up-right.svg">../3rd-party/tabler-icons/icons/arrow-up-right.svg</file> + <file alias="arrow-up.svg">../3rd-party/tabler-icons/icons/arrow-up.svg</file> + <file alias="arrows-diagonal-2.svg">../3rd-party/tabler-icons/icons/arrows-diagonal-2.svg</file> + <file alias="arrows-diagonal.svg">../3rd-party/tabler-icons/icons/arrows-diagonal.svg</file> + <file alias="arrows-horizontal.svg">../3rd-party/tabler-icons/icons/arrows-horizontal.svg</file> + <file alias="arrows-maximize.svg">../3rd-party/tabler-icons/icons/arrows-maximize.svg</file> + <file alias="arrows-minimize.svg">../3rd-party/tabler-icons/icons/arrows-minimize.svg</file> + <file alias="arrows-sort.svg">../3rd-party/tabler-icons/icons/arrows-sort.svg</file> + <file alias="arrows-vertical.svg">../3rd-party/tabler-icons/icons/arrows-vertical.svg</file> + <file alias="artboard.svg">../3rd-party/tabler-icons/icons/artboard.svg</file> + <file alias="at.svg">../3rd-party/tabler-icons/icons/at.svg</file> + <file alias="award.svg">../3rd-party/tabler-icons/icons/award.svg</file> + <file alias="backspace.svg">../3rd-party/tabler-icons/icons/backspace.svg</file> + <file alias="ban.svg">../3rd-party/tabler-icons/icons/ban.svg</file> + <file alias="battery-1.svg">../3rd-party/tabler-icons/icons/battery-1.svg</file> + <file alias="battery-2.svg">../3rd-party/tabler-icons/icons/battery-2.svg</file> + <file alias="battery-3.svg">../3rd-party/tabler-icons/icons/battery-3.svg</file> + <file alias="battery-4.svg">../3rd-party/tabler-icons/icons/battery-4.svg</file> + <file alias="battery-charging.svg">../3rd-party/tabler-icons/icons/battery-charging.svg</file> + <file alias="battery.svg">../3rd-party/tabler-icons/icons/battery.svg</file> + <file alias="bed.svg">../3rd-party/tabler-icons/icons/bed.svg</file> + <file alias="bell.svg">../3rd-party/tabler-icons/icons/bell.svg</file> + <file alias="bike.svg">../3rd-party/tabler-icons/icons/bike.svg</file> + <file alias="bluetooth.svg">../3rd-party/tabler-icons/icons/bluetooth.svg</file> + <file alias="bolt.svg">../3rd-party/tabler-icons/icons/bolt.svg</file> + <file alias="book.svg">../3rd-party/tabler-icons/icons/book.svg</file> + <file alias="bookmark.svg">../3rd-party/tabler-icons/icons/bookmark.svg</file> + <file alias="border-all.svg">../3rd-party/tabler-icons/icons/border-all.svg</file> + <file alias="border-bottom.svg">../3rd-party/tabler-icons/icons/border-bottom.svg</file> + <file alias="border-horizontal.svg">../3rd-party/tabler-icons/icons/border-horizontal.svg</file> + <file alias="border-inner.svg">../3rd-party/tabler-icons/icons/border-inner.svg</file> + <file alias="border-left.svg">../3rd-party/tabler-icons/icons/border-left.svg</file> + <file alias="border-none.svg">../3rd-party/tabler-icons/icons/border-none.svg</file> + <file alias="border-outer.svg">../3rd-party/tabler-icons/icons/border-outer.svg</file> + <file alias="border-right.svg">../3rd-party/tabler-icons/icons/border-right.svg</file> + <file alias="border-top.svg">../3rd-party/tabler-icons/icons/border-top.svg</file> + <file alias="border-vertical.svg">../3rd-party/tabler-icons/icons/border-vertical.svg</file> + <file alias="box.svg">../3rd-party/tabler-icons/icons/box.svg</file> + <file alias="briefcase.svg">../3rd-party/tabler-icons/icons/briefcase.svg</file> + <file alias="bucket.svg">../3rd-party/tabler-icons/icons/bucket.svg</file> + <file alias="bug.svg">../3rd-party/tabler-icons/icons/bug.svg</file> + <file alias="building-arch.svg">../3rd-party/tabler-icons/icons/building-arch.svg</file> + <file alias="building-bridge-2.svg">../3rd-party/tabler-icons/icons/building-bridge-2.svg</file> + <file alias="building-bridge.svg">../3rd-party/tabler-icons/icons/building-bridge.svg</file> + <file alias="building-church.svg">../3rd-party/tabler-icons/icons/building-church.svg</file> + <file alias="building-hospital.svg">../3rd-party/tabler-icons/icons/building-hospital.svg</file> + <file alias="building-store.svg">../3rd-party/tabler-icons/icons/building-store.svg</file> + <file alias="building.svg">../3rd-party/tabler-icons/icons/building.svg</file> + <file alias="bulb-off.svg">../3rd-party/tabler-icons/icons/bulb-off.svg</file> + <file alias="bulb.svg">../3rd-party/tabler-icons/icons/bulb.svg</file> + <file alias="calendar-event.svg">../3rd-party/tabler-icons/icons/calendar-event.svg</file> + <file alias="calendar.svg">../3rd-party/tabler-icons/icons/calendar.svg</file> + <file alias="camera.svg">../3rd-party/tabler-icons/icons/camera.svg</file> + <file alias="caret-down.svg">../3rd-party/tabler-icons/icons/caret-down.svg</file> + <file alias="caret-left.svg">../3rd-party/tabler-icons/icons/caret-left.svg</file> + <file alias="caret-right.svg">../3rd-party/tabler-icons/icons/caret-right.svg</file> + <file alias="caret-up.svg">../3rd-party/tabler-icons/icons/caret-up.svg</file> + <file alias="cash.svg">../3rd-party/tabler-icons/icons/cash.svg</file> + <file alias="cast.svg">../3rd-party/tabler-icons/icons/cast.svg</file> + <file alias="chart-area-line.svg">../3rd-party/tabler-icons/icons/chart-area-line.svg</file> + <file alias="chart-area.svg">../3rd-party/tabler-icons/icons/chart-area.svg</file> + <file alias="chart-bar.svg">../3rd-party/tabler-icons/icons/chart-bar.svg</file> + <file alias="chart-candle.svg">../3rd-party/tabler-icons/icons/chart-candle.svg</file> + <file alias="chart-donut.svg">../3rd-party/tabler-icons/icons/chart-donut.svg</file> + <file alias="chart-line.svg">../3rd-party/tabler-icons/icons/chart-line.svg</file> + <file alias="chart-pie.svg">../3rd-party/tabler-icons/icons/chart-pie.svg</file> + <file alias="check.svg">../3rd-party/tabler-icons/icons/check.svg</file> + <file alias="chevron-down.svg">../3rd-party/tabler-icons/icons/chevron-down.svg</file> + <file alias="chevron-left.svg">../3rd-party/tabler-icons/icons/chevron-left.svg</file> + <file alias="chevron-right.svg">../3rd-party/tabler-icons/icons/chevron-right.svg</file> + <file alias="chevron-up.svg">../3rd-party/tabler-icons/icons/chevron-up.svg</file> + <file alias="chevrons-down.svg">../3rd-party/tabler-icons/icons/chevrons-down.svg</file> + <file alias="chevrons-left.svg">../3rd-party/tabler-icons/icons/chevrons-left.svg</file> + <file alias="chevrons-right.svg">../3rd-party/tabler-icons/icons/chevrons-right.svg</file> + <file alias="chevrons-up.svg">../3rd-party/tabler-icons/icons/chevrons-up.svg</file> + <file alias="circle-check.svg">../3rd-party/tabler-icons/icons/circle-check.svg</file> + <file alias="circle-minus.svg">../3rd-party/tabler-icons/icons/circle-minus.svg</file> + <file alias="circle-plus.svg">../3rd-party/tabler-icons/icons/circle-plus.svg</file> + <file alias="circle-x.svg">../3rd-party/tabler-icons/icons/circle-x.svg</file> + <file alias="circle.svg">../3rd-party/tabler-icons/icons/circle.svg</file> + <file alias="clipboard-check.svg">../3rd-party/tabler-icons/icons/clipboard-check.svg</file> + <file alias="clipboard-list.svg">../3rd-party/tabler-icons/icons/clipboard-list.svg</file> + <file alias="clipboard-x.svg">../3rd-party/tabler-icons/icons/clipboard-x.svg</file> + <file alias="clipboard.svg">../3rd-party/tabler-icons/icons/clipboard.svg</file> + <file alias="clock.svg">../3rd-party/tabler-icons/icons/clock.svg</file> + <file alias="cloud-download.svg">../3rd-party/tabler-icons/icons/cloud-download.svg</file> + <file alias="cloud-rain.svg">../3rd-party/tabler-icons/icons/cloud-rain.svg</file> + <file alias="cloud-snow.svg">../3rd-party/tabler-icons/icons/cloud-snow.svg</file> + <file alias="cloud-storm.svg">../3rd-party/tabler-icons/icons/cloud-storm.svg</file> + <file alias="cloud-upload.svg">../3rd-party/tabler-icons/icons/cloud-upload.svg</file> + <file alias="cloud.svg">../3rd-party/tabler-icons/icons/cloud.svg</file> + <file alias="code.svg">../3rd-party/tabler-icons/icons/code.svg</file> + <file alias="color-swatch.svg">../3rd-party/tabler-icons/icons/color-swatch.svg</file> + <file alias="command.svg">../3rd-party/tabler-icons/icons/command.svg</file> + <file alias="compass.svg">../3rd-party/tabler-icons/icons/compass.svg</file> + <file alias="copy.svg">../3rd-party/tabler-icons/icons/copy.svg</file> + <file alias="copyright.svg">../3rd-party/tabler-icons/icons/copyright.svg</file> + <file alias="corner-down-left.svg">../3rd-party/tabler-icons/icons/corner-down-left.svg</file> + <file alias="corner-down-right.svg">../3rd-party/tabler-icons/icons/corner-down-right.svg</file> + <file alias="corner-left-down.svg">../3rd-party/tabler-icons/icons/corner-left-down.svg</file> + <file alias="corner-left-up.svg">../3rd-party/tabler-icons/icons/corner-left-up.svg</file> + <file alias="corner-right-down.svg">../3rd-party/tabler-icons/icons/corner-right-down.svg</file> + <file alias="corner-right-up.svg">../3rd-party/tabler-icons/icons/corner-right-up.svg</file> + <file alias="corner-up-left.svg">../3rd-party/tabler-icons/icons/corner-up-left.svg</file> + <file alias="corner-up-right.svg">../3rd-party/tabler-icons/icons/corner-up-right.svg</file> + <file alias="credit-card.svg">../3rd-party/tabler-icons/icons/credit-card.svg</file> + <file alias="crop.svg">../3rd-party/tabler-icons/icons/crop.svg</file> + <file alias="cut.svg">../3rd-party/tabler-icons/icons/cut.svg</file> + <file alias="dashboard.svg">../3rd-party/tabler-icons/icons/dashboard.svg</file> + <file alias="database.svg">../3rd-party/tabler-icons/icons/database.svg</file> + <file alias="device-desktop.svg">../3rd-party/tabler-icons/icons/device-desktop.svg</file> + <file alias="device-floppy.svg">../3rd-party/tabler-icons/icons/device-floppy.svg</file> + <file alias="device-gamepad.svg">../3rd-party/tabler-icons/icons/device-gamepad.svg</file> + <file alias="device-laptop.svg">../3rd-party/tabler-icons/icons/device-laptop.svg</file> + <file alias="device-mobile.svg">../3rd-party/tabler-icons/icons/device-mobile.svg</file> + <file alias="device-speaker.svg">../3rd-party/tabler-icons/icons/device-speaker.svg</file> + <file alias="device-tablet.svg">../3rd-party/tabler-icons/icons/device-tablet.svg</file> + <file alias="device-tv.svg">../3rd-party/tabler-icons/icons/device-tv.svg</file> + <file alias="diamond.svg">../3rd-party/tabler-icons/icons/diamond.svg</file> + <file alias="dice.svg">../3rd-party/tabler-icons/icons/dice.svg</file> + <file alias="directions.svg">../3rd-party/tabler-icons/icons/directions.svg</file> + <file alias="disabled.svg">../3rd-party/tabler-icons/icons/disabled.svg</file> + <file alias="disc.svg">../3rd-party/tabler-icons/icons/disc.svg</file> + <file alias="dots-circle-horizontal.svg">../3rd-party/tabler-icons/icons/dots-circle-horizontal.svg</file> + <file alias="dots-diagonal-2.svg">../3rd-party/tabler-icons/icons/dots-diagonal-2.svg</file> + <file alias="dots-diagonal.svg">../3rd-party/tabler-icons/icons/dots-diagonal.svg</file> + <file alias="dots-vertical.svg">../3rd-party/tabler-icons/icons/dots-vertical.svg</file> + <file alias="dots.svg">../3rd-party/tabler-icons/icons/dots.svg</file> + <file alias="download.svg">../3rd-party/tabler-icons/icons/download.svg</file> + <file alias="droplet.svg">../3rd-party/tabler-icons/icons/droplet.svg</file> + <file alias="edit.svg">../3rd-party/tabler-icons/icons/edit.svg</file> + <file alias="external-link.svg">../3rd-party/tabler-icons/icons/external-link.svg</file> + <file alias="eye.svg">../3rd-party/tabler-icons/icons/eye.svg</file> + <file alias="face-id.svg">../3rd-party/tabler-icons/icons/face-id.svg</file> + <file alias="file-check.svg">../3rd-party/tabler-icons/icons/file-check.svg</file> + <file alias="file-download.svg">../3rd-party/tabler-icons/icons/file-download.svg</file> + <file alias="file-invoice.svg">../3rd-party/tabler-icons/icons/file-invoice.svg</file> + <file alias="file-minus.svg">../3rd-party/tabler-icons/icons/file-minus.svg</file> + <file alias="file-music.svg">../3rd-party/tabler-icons/icons/file-music.svg</file> + <file alias="file-plus.svg">../3rd-party/tabler-icons/icons/file-plus.svg</file> + <file alias="file-shredder.svg">../3rd-party/tabler-icons/icons/file-shredder.svg</file> + <file alias="file-text.svg">../3rd-party/tabler-icons/icons/file-text.svg</file> + <file alias="file-x.svg">../3rd-party/tabler-icons/icons/file-x.svg</file> + <file alias="file.svg">../3rd-party/tabler-icons/icons/file.svg</file> + <file alias="filter.svg">../3rd-party/tabler-icons/icons/filter.svg</file> + <file alias="flag.svg">../3rd-party/tabler-icons/icons/flag.svg</file> + <file alias="flip-horizontal.svg">../3rd-party/tabler-icons/icons/flip-horizontal.svg</file> + <file alias="flip-vertical.svg">../3rd-party/tabler-icons/icons/flip-vertical.svg</file> + <file alias="floppy-disk.svg">../3rd-party/tabler-icons/icons/floppy-disk.svg</file> + <file alias="folder-minus.svg">../3rd-party/tabler-icons/icons/folder-minus.svg</file> + <file alias="folder-plus.svg">../3rd-party/tabler-icons/icons/folder-plus.svg</file> + <file alias="folder-x.svg">../3rd-party/tabler-icons/icons/folder-x.svg</file> + <file alias="folder.svg">../3rd-party/tabler-icons/icons/folder.svg</file> + <file alias="folders.svg">../3rd-party/tabler-icons/icons/folders.svg</file> + <file alias="frame.svg">../3rd-party/tabler-icons/icons/frame.svg</file> + <file alias="friends.svg">../3rd-party/tabler-icons/icons/friends.svg</file> + <file alias="gauge.svg">../3rd-party/tabler-icons/icons/gauge.svg</file> + <file alias="gift.svg">../3rd-party/tabler-icons/icons/gift.svg</file> + <file alias="git-branch.svg">../3rd-party/tabler-icons/icons/git-branch.svg</file> + <file alias="git-commit.svg">../3rd-party/tabler-icons/icons/git-commit.svg</file> + <file alias="git-compare.svg">../3rd-party/tabler-icons/icons/git-compare.svg</file> + <file alias="git-merge.svg">../3rd-party/tabler-icons/icons/git-merge.svg</file> + <file alias="git-pull-request.svg">../3rd-party/tabler-icons/icons/git-pull-request.svg</file> + <file alias="glass-full.svg">../3rd-party/tabler-icons/icons/glass-full.svg</file> + <file alias="glass.svg">../3rd-party/tabler-icons/icons/glass.svg</file> + <file alias="globe.svg">../3rd-party/tabler-icons/icons/globe.svg</file> + <file alias="grid-dots.svg">../3rd-party/tabler-icons/icons/grid-dots.svg</file> + <file alias="grid.svg">../3rd-party/tabler-icons/icons/grid.svg</file> + <file alias="hash.svg">../3rd-party/tabler-icons/icons/hash.svg</file> + <file alias="headphones.svg">../3rd-party/tabler-icons/icons/headphones.svg</file> + <file alias="heart.svg">../3rd-party/tabler-icons/icons/heart.svg</file> + <file alias="help.svg">../3rd-party/tabler-icons/icons/help.svg</file> + <file alias="home-2.svg">../3rd-party/tabler-icons/icons/home-2.svg</file> + <file alias="home.svg">../3rd-party/tabler-icons/icons/home.svg</file> + <file alias="ice-cream.svg">../3rd-party/tabler-icons/icons/ice-cream.svg</file> + <file alias="id.svg">../3rd-party/tabler-icons/icons/id.svg</file> + <file alias="inbox.svg">../3rd-party/tabler-icons/icons/inbox.svg</file> + <file alias="infinity.svg">../3rd-party/tabler-icons/icons/infinity.svg</file> + <file alias="info-circle.svg">../3rd-party/tabler-icons/icons/info-circle.svg</file> + <file alias="info-square.svg">../3rd-party/tabler-icons/icons/info-square.svg</file> + <file alias="key.svg">../3rd-party/tabler-icons/icons/key.svg</file> + <file alias="layers-difference.svg">../3rd-party/tabler-icons/icons/layers-difference.svg</file> + <file alias="layers-intersect.svg">../3rd-party/tabler-icons/icons/layers-intersect.svg</file> + <file alias="layers-subtract.svg">../3rd-party/tabler-icons/icons/layers-subtract.svg</file> + <file alias="layers-union.svg">../3rd-party/tabler-icons/icons/layers-union.svg</file> + <file alias="layout-2.svg">../3rd-party/tabler-icons/icons/layout-2.svg</file> + <file alias="layout-align-bottom.svg">../3rd-party/tabler-icons/icons/layout-align-bottom.svg</file> + <file alias="layout-align-center.svg">../3rd-party/tabler-icons/icons/layout-align-center.svg</file> + <file alias="layout-align-left.svg">../3rd-party/tabler-icons/icons/layout-align-left.svg</file> + <file alias="layout-align-middle.svg">../3rd-party/tabler-icons/icons/layout-align-middle.svg</file> + <file alias="layout-align-right.svg">../3rd-party/tabler-icons/icons/layout-align-right.svg</file> + <file alias="layout-align-top.svg">../3rd-party/tabler-icons/icons/layout-align-top.svg</file> + <file alias="layout-bottombar.svg">../3rd-party/tabler-icons/icons/layout-bottombar.svg</file> + <file alias="layout-columns.svg">../3rd-party/tabler-icons/icons/layout-columns.svg</file> + <file alias="layout-distribute-horizontal.svg">../3rd-party/tabler-icons/icons/layout-distribute-horizontal.svg</file> + <file alias="layout-distribute-vertical.svg">../3rd-party/tabler-icons/icons/layout-distribute-vertical.svg</file> + <file alias="layout-navbar.svg">../3rd-party/tabler-icons/icons/layout-navbar.svg</file> + <file alias="layout-rows.svg">../3rd-party/tabler-icons/icons/layout-rows.svg</file> + <file alias="layout-sidebar-right.svg">../3rd-party/tabler-icons/icons/layout-sidebar-right.svg</file> + <file alias="layout-sidebar.svg">../3rd-party/tabler-icons/icons/layout-sidebar.svg</file> + <file alias="layout.svg">../3rd-party/tabler-icons/icons/layout.svg</file> + <file alias="lego.svg">../3rd-party/tabler-icons/icons/lego.svg</file> + <file alias="lifebuoy.svg">../3rd-party/tabler-icons/icons/lifebuoy.svg</file> + <file alias="link.svg">../3rd-party/tabler-icons/icons/link.svg</file> + <file alias="list-check.svg">../3rd-party/tabler-icons/icons/list-check.svg</file> + <file alias="list.svg">../3rd-party/tabler-icons/icons/list.svg</file> + <file alias="live-photo.svg">../3rd-party/tabler-icons/icons/live-photo.svg</file> + <file alias="location.svg">../3rd-party/tabler-icons/icons/location.svg</file> + <file alias="lock-open.svg">../3rd-party/tabler-icons/icons/lock-open.svg</file> + <file alias="lock.svg">../3rd-party/tabler-icons/icons/lock.svg</file> + <file alias="magnet.svg">../3rd-party/tabler-icons/icons/magnet.svg</file> + <file alias="mail-opened.svg">../3rd-party/tabler-icons/icons/mail-opened.svg</file> + <file alias="mail.svg">../3rd-party/tabler-icons/icons/mail.svg</file> + <file alias="man.svg">../3rd-party/tabler-icons/icons/man.svg</file> + <file alias="map-2.svg">../3rd-party/tabler-icons/icons/map-2.svg</file> + <file alias="map-pin.svg">../3rd-party/tabler-icons/icons/map-pin.svg</file> + <file alias="map.svg">../3rd-party/tabler-icons/icons/map.svg</file> + <file alias="maximize.svg">../3rd-party/tabler-icons/icons/maximize.svg</file> + <file alias="menu.svg">../3rd-party/tabler-icons/icons/menu.svg</file> + <file alias="message-2.svg">../3rd-party/tabler-icons/icons/message-2.svg</file> + <file alias="message-circle.svg">../3rd-party/tabler-icons/icons/message-circle.svg</file> + <file alias="message-dots.svg">../3rd-party/tabler-icons/icons/message-dots.svg</file> + <file alias="message.svg">../3rd-party/tabler-icons/icons/message.svg</file> + <file alias="messages.svg">../3rd-party/tabler-icons/icons/messages.svg</file> + <file alias="microphone.svg">../3rd-party/tabler-icons/icons/microphone.svg</file> + <file alias="minimize.svg">../3rd-party/tabler-icons/icons/minimize.svg</file> + <file alias="minus.svg">../3rd-party/tabler-icons/icons/minus.svg</file> + <file alias="mood-confuzed.svg">../3rd-party/tabler-icons/icons/mood-confuzed.svg</file> + <file alias="mood-happy.svg">../3rd-party/tabler-icons/icons/mood-happy.svg</file> + <file alias="mood-neutral.svg">../3rd-party/tabler-icons/icons/mood-neutral.svg</file> + <file alias="mood-sad.svg">../3rd-party/tabler-icons/icons/mood-sad.svg</file> + <file alias="mood-smile.svg">../3rd-party/tabler-icons/icons/mood-smile.svg</file> + <file alias="moon.svg">../3rd-party/tabler-icons/icons/moon.svg</file> + <file alias="mouse.svg">../3rd-party/tabler-icons/icons/mouse.svg</file> + <file alias="movie.svg">../3rd-party/tabler-icons/icons/movie.svg</file> + <file alias="mug.svg">../3rd-party/tabler-icons/icons/mug.svg</file> + <file alias="music.svg">../3rd-party/tabler-icons/icons/music.svg</file> + <file alias="news.svg">../3rd-party/tabler-icons/icons/news.svg</file> + <file alias="note.svg">../3rd-party/tabler-icons/icons/note.svg</file> + <file alias="notes.svg">../3rd-party/tabler-icons/icons/notes.svg</file> + <file alias="notification.svg">../3rd-party/tabler-icons/icons/notification.svg</file> + <file alias="package.svg">../3rd-party/tabler-icons/icons/package.svg</file> + <file alias="paint.svg">../3rd-party/tabler-icons/icons/paint.svg</file> + <file alias="palette.svg">../3rd-party/tabler-icons/icons/palette.svg</file> + <file alias="paperclip.svg">../3rd-party/tabler-icons/icons/paperclip.svg</file> + <file alias="parking.svg">../3rd-party/tabler-icons/icons/parking.svg</file> + <file alias="pencil.svg">../3rd-party/tabler-icons/icons/pencil.svg</file> + <file alias="phone-call.svg">../3rd-party/tabler-icons/icons/phone-call.svg</file> + <file alias="phone-incoming.svg">../3rd-party/tabler-icons/icons/phone-incoming.svg</file> + <file alias="phone-outgoing.svg">../3rd-party/tabler-icons/icons/phone-outgoing.svg</file> + <file alias="phone-pause.svg">../3rd-party/tabler-icons/icons/phone-pause.svg</file> + <file alias="phone.svg">../3rd-party/tabler-icons/icons/phone.svg</file> + <file alias="photo.svg">../3rd-party/tabler-icons/icons/photo.svg</file> + <file alias="plane.svg">../3rd-party/tabler-icons/icons/plane.svg</file> + <file alias="plus.svg">../3rd-party/tabler-icons/icons/plus.svg</file> + <file alias="point.svg">../3rd-party/tabler-icons/icons/point.svg</file> + <file alias="power.svg">../3rd-party/tabler-icons/icons/power.svg</file> + <file alias="presentation.svg">../3rd-party/tabler-icons/icons/presentation.svg</file> + <file alias="printer.svg">../3rd-party/tabler-icons/icons/printer.svg</file> + <file alias="prompt.svg">../3rd-party/tabler-icons/icons/prompt.svg</file> + <file alias="puzzle.svg">../3rd-party/tabler-icons/icons/puzzle.svg</file> + <file alias="qrcode.svg">../3rd-party/tabler-icons/icons/qrcode.svg</file> + <file alias="record-mail.svg">../3rd-party/tabler-icons/icons/record-mail.svg</file> + <file alias="refresh.svg">../3rd-party/tabler-icons/icons/refresh.svg</file> + <file alias="registered.svg">../3rd-party/tabler-icons/icons/registered.svg</file> + <file alias="repeat-once.svg">../3rd-party/tabler-icons/icons/repeat-once.svg</file> + <file alias="repeat.svg">../3rd-party/tabler-icons/icons/repeat.svg</file> + <file alias="rotate-clockwise.svg">../3rd-party/tabler-icons/icons/rotate-clockwise.svg</file> + <file alias="rotate.svg">../3rd-party/tabler-icons/icons/rotate.svg</file> + <file alias="route.svg">../3rd-party/tabler-icons/icons/route.svg</file> + <file alias="router.svg">../3rd-party/tabler-icons/icons/router.svg</file> + <file alias="rss.svg">../3rd-party/tabler-icons/icons/rss.svg</file> + <file alias="ruler.svg">../3rd-party/tabler-icons/icons/ruler.svg</file> + <file alias="scissors.svg">../3rd-party/tabler-icons/icons/scissors.svg</file> + <file alias="search.svg">../3rd-party/tabler-icons/icons/search.svg</file> + <file alias="selector.svg">../3rd-party/tabler-icons/icons/selector.svg</file> + <file alias="send.svg">../3rd-party/tabler-icons/icons/send.svg</file> + <file alias="server.svg">../3rd-party/tabler-icons/icons/server.svg</file> + <file alias="settings.svg">../3rd-party/tabler-icons/icons/settings.svg</file> + <file alias="share.svg">../3rd-party/tabler-icons/icons/share.svg</file> + <file alias="shield-check.svg">../3rd-party/tabler-icons/icons/shield-check.svg</file> + <file alias="shield-x.svg">../3rd-party/tabler-icons/icons/shield-x.svg</file> + <file alias="shield.svg">../3rd-party/tabler-icons/icons/shield.svg</file> + <file alias="shopping-cart.svg">../3rd-party/tabler-icons/icons/shopping-cart.svg</file> + <file alias="sort-ascending.svg">../3rd-party/tabler-icons/icons/sort-ascending.svg</file> + <file alias="sort-descending.svg">../3rd-party/tabler-icons/icons/sort-descending.svg</file> + <file alias="square-check.svg">../3rd-party/tabler-icons/icons/square-check.svg</file> + <file alias="square-minus.svg">../3rd-party/tabler-icons/icons/square-minus.svg</file> + <file alias="square-plus.svg">../3rd-party/tabler-icons/icons/square-plus.svg</file> + <file alias="square-x.svg">../3rd-party/tabler-icons/icons/square-x.svg</file> + <file alias="square.svg">../3rd-party/tabler-icons/icons/square.svg</file> + <file alias="stack.svg">../3rd-party/tabler-icons/icons/stack.svg</file> + <file alias="star.svg">../3rd-party/tabler-icons/icons/star.svg</file> + <file alias="sticker.svg">../3rd-party/tabler-icons/icons/sticker.svg</file> + <file alias="sum.svg">../3rd-party/tabler-icons/icons/sum.svg</file> + <file alias="sun.svg">../3rd-party/tabler-icons/icons/sun.svg</file> + <file alias="switch-horizontal.svg">../3rd-party/tabler-icons/icons/switch-horizontal.svg</file> + <file alias="switch-vertical.svg">../3rd-party/tabler-icons/icons/switch-vertical.svg</file> + <file alias="switch.svg">../3rd-party/tabler-icons/icons/switch.svg</file> + <file alias="tag.svg">../3rd-party/tabler-icons/icons/tag.svg</file> + <file alias="target.svg">../3rd-party/tabler-icons/icons/target.svg</file> + <file alias="temperature-celsius.svg">../3rd-party/tabler-icons/icons/temperature-celsius.svg</file> + <file alias="temperature-fahrenheit.svg">../3rd-party/tabler-icons/icons/temperature-fahrenheit.svg</file> + <file alias="temperature.svg">../3rd-party/tabler-icons/icons/temperature.svg</file> + <file alias="template.svg">../3rd-party/tabler-icons/icons/template.svg</file> + <file alias="test-pipe.svg">../3rd-party/tabler-icons/icons/test-pipe.svg</file> + <file alias="thumb-down.svg">../3rd-party/tabler-icons/icons/thumb-down.svg</file> + <file alias="thumb-up.svg">../3rd-party/tabler-icons/icons/thumb-up.svg</file> + <file alias="ticket.svg">../3rd-party/tabler-icons/icons/ticket.svg</file> + <file alias="toggle-left.svg">../3rd-party/tabler-icons/icons/toggle-left.svg</file> + <file alias="toggle-right.svg">../3rd-party/tabler-icons/icons/toggle-right.svg</file> + <file alias="tool.svg">../3rd-party/tabler-icons/icons/tool.svg</file> + <file alias="trash.svg">../3rd-party/tabler-icons/icons/trash.svg</file> + <file alias="trending-down.svg">../3rd-party/tabler-icons/icons/trending-down.svg</file> + <file alias="trending-up.svg">../3rd-party/tabler-icons/icons/trending-up.svg</file> + <file alias="triangle.svg">../3rd-party/tabler-icons/icons/triangle.svg</file> + <file alias="trophy.svg">../3rd-party/tabler-icons/icons/trophy.svg</file> + <file alias="unlink.svg">../3rd-party/tabler-icons/icons/unlink.svg</file> + <file alias="upload.svg">../3rd-party/tabler-icons/icons/upload.svg</file> + <file alias="urgent.svg">../3rd-party/tabler-icons/icons/urgent.svg</file> + <file alias="user-check.svg">../3rd-party/tabler-icons/icons/user-check.svg</file> + <file alias="user-minus.svg">../3rd-party/tabler-icons/icons/user-minus.svg</file> + <file alias="user-plus.svg">../3rd-party/tabler-icons/icons/user-plus.svg</file> + <file alias="user-x.svg">../3rd-party/tabler-icons/icons/user-x.svg</file> + <file alias="user.svg">../3rd-party/tabler-icons/icons/user.svg</file> + <file alias="viewfinder.svg">../3rd-party/tabler-icons/icons/viewfinder.svg</file> + <file alias="virus.svg">../3rd-party/tabler-icons/icons/virus.svg</file> + <file alias="volume-2.svg">../3rd-party/tabler-icons/icons/volume-2.svg</file> + <file alias="volume-3.svg">../3rd-party/tabler-icons/icons/volume-3.svg</file> + <file alias="volume.svg">../3rd-party/tabler-icons/icons/volume.svg</file> + <file alias="wallet.svg">../3rd-party/tabler-icons/icons/wallet.svg</file> + <file alias="wifi.svg">../3rd-party/tabler-icons/icons/wifi.svg</file> + <file alias="woman.svg">../3rd-party/tabler-icons/icons/woman.svg</file> + <file alias="world.svg">../3rd-party/tabler-icons/icons/world.svg</file> + <file alias="x.svg">../3rd-party/tabler-icons/icons/x.svg</file> + <file alias="zoom-in.svg">../3rd-party/tabler-icons/icons/zoom-in.svg</file> + <file alias="zoom-out.svg">../3rd-party/tabler-icons/icons/zoom-out.svg</file> + </qresource> +</RCC> |