Compare commits
37 Commits
ed4f1d6f2c
...
main
Author | SHA1 | Date | |
---|---|---|---|
cb3d6a98b9 | |||
ada67a13d3 | |||
f4c928f26e | |||
91fd515d39 | |||
be6e841d3d | |||
af6afa6903 | |||
6ab5d2a28d | |||
4be033f288 | |||
c550f92003 | |||
ed836b3ee0 | |||
ac7a43abf4 | |||
49f19fce91 | |||
b2197eb8e9 | |||
5fbc2cae1c | |||
730abb49ce | |||
edccab054a | |||
e8210c6fdd | |||
55d69d7c13 | |||
50fb18d4ff | |||
77b1ea1fc8 | |||
61501a9b64 | |||
c1507adac5 | |||
45fb9eda1c | |||
982a61f4bf | |||
18e5b41663 | |||
910c39cbd0 | |||
9952dfd49d | |||
00f75d5382 | |||
d78828554b | |||
b84b561109 | |||
a618815500 | |||
e1f3dc6ae4 | |||
f378db6c6f | |||
7cec0f7d61 | |||
f902d0374c | |||
b5f0a0c4f7 | |||
00623cea09 |
357
Doxyfile
357
Doxyfile
@@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.9.8
|
# Doxyfile 1.9.4
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project.
|
# doxygen (www.doxygen.org) for a project.
|
||||||
@@ -19,8 +19,7 @@
|
|||||||
# configuration file:
|
# configuration file:
|
||||||
# doxygen -x [configFile]
|
# doxygen -x [configFile]
|
||||||
# Use doxygen to compare the used configuration file with the template
|
# Use doxygen to compare the used configuration file with the template
|
||||||
# configuration file without replacing the environment variables or CMake type
|
# configuration file without replacing the environment variables:
|
||||||
# replacement variables:
|
|
||||||
# doxygen -x_noenv [configFile]
|
# doxygen -x_noenv [configFile]
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -86,7 +85,7 @@ CREATE_SUBDIRS = NO
|
|||||||
# level increment doubles the number of directories, resulting in 4096
|
# level increment doubles the number of directories, resulting in 4096
|
||||||
# directories at level 8 which is the default and also the maximum value. The
|
# directories at level 8 which is the default and also the maximum value. The
|
||||||
# sub-directories are organized in 2 levels, the first level always has a fixed
|
# sub-directories are organized in 2 levels, the first level always has a fixed
|
||||||
# number of 16 directories.
|
# numer of 16 directories.
|
||||||
# Minimum value: 0, maximum value: 8, default value: 8.
|
# Minimum value: 0, maximum value: 8, default value: 8.
|
||||||
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
|
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
|
||||||
|
|
||||||
@@ -363,17 +362,6 @@ MARKDOWN_SUPPORT = YES
|
|||||||
|
|
||||||
TOC_INCLUDE_HEADINGS = 5
|
TOC_INCLUDE_HEADINGS = 5
|
||||||
|
|
||||||
# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to
|
|
||||||
# generate identifiers for the Markdown headings. Note: Every identifier is
|
|
||||||
# unique.
|
|
||||||
# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a
|
|
||||||
# sequence number starting at 0 and GITHUB use the lower case version of title
|
|
||||||
# with any whitespace replaced by '-' and punctuation characters removed.
|
|
||||||
# The default value is: DOXYGEN.
|
|
||||||
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
|
||||||
|
|
||||||
MARKDOWN_ID_STYLE = DOXYGEN
|
|
||||||
|
|
||||||
# When enabled doxygen tries to link words that correspond to documented
|
# When enabled doxygen tries to link words that correspond to documented
|
||||||
# classes, or namespaces to their corresponding documentation. Such a link can
|
# classes, or namespaces to their corresponding documentation. Such a link can
|
||||||
# be prevented in individual cases by putting a % sign in front of the word or
|
# be prevented in individual cases by putting a % sign in front of the word or
|
||||||
@@ -498,14 +486,6 @@ LOOKUP_CACHE_SIZE = 0
|
|||||||
|
|
||||||
NUM_PROC_THREADS = 1
|
NUM_PROC_THREADS = 1
|
||||||
|
|
||||||
# If the TIMESTAMP tag is set different from NO then each generated page will
|
|
||||||
# contain the date or date and time when the page was generated. Setting this to
|
|
||||||
# NO can help when comparing the output of multiple runs.
|
|
||||||
# Possible values are: YES, NO, DATETIME and DATE.
|
|
||||||
# The default value is: NO.
|
|
||||||
|
|
||||||
TIMESTAMP = NO
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Build related configuration options
|
# Build related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -587,8 +567,7 @@ HIDE_UNDOC_MEMBERS = NO
|
|||||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
|
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
|
||||||
# undocumented classes that are normally visible in the class hierarchy. If set
|
# undocumented classes that are normally visible in the class hierarchy. If set
|
||||||
# to NO, these classes will be included in the various overviews. This option
|
# to NO, these classes will be included in the various overviews. This option
|
||||||
# will also hide undocumented C++ concepts if enabled. This option has no effect
|
# has no effect if EXTRACT_ALL is enabled.
|
||||||
# if EXTRACT_ALL is enabled.
|
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_UNDOC_CLASSES = NO
|
HIDE_UNDOC_CLASSES = NO
|
||||||
@@ -626,8 +605,7 @@ INTERNAL_DOCS = NO
|
|||||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||||
# YES.
|
# YES.
|
||||||
# Possible values are: SYSTEM, NO and YES.
|
# The default value is: system dependent.
|
||||||
# The default value is: SYSTEM.
|
|
||||||
|
|
||||||
CASE_SENSE_NAMES = YES
|
CASE_SENSE_NAMES = YES
|
||||||
|
|
||||||
@@ -879,26 +857,11 @@ WARN_IF_INCOMPLETE_DOC = YES
|
|||||||
|
|
||||||
WARN_NO_PARAMDOC = NO
|
WARN_NO_PARAMDOC = NO
|
||||||
|
|
||||||
# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about
|
|
||||||
# undocumented enumeration values. If set to NO, doxygen will accept
|
|
||||||
# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
|
|
||||||
# will automatically be disabled.
|
|
||||||
# The default value is: NO.
|
|
||||||
|
|
||||||
WARN_IF_UNDOC_ENUM_VAL = NO
|
|
||||||
|
|
||||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||||
# at the end of the doxygen process doxygen will return with a non-zero status.
|
# at the end of the doxygen process doxygen will return with a non-zero status.
|
||||||
# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves
|
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
|
||||||
# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not
|
|
||||||
# write the warning messages in between other messages but write them at the end
|
|
||||||
# of a run, in case a WARN_LOGFILE is defined the warning messages will be
|
|
||||||
# besides being in the defined file also be shown at the end of a run, unless
|
|
||||||
# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case
|
|
||||||
# the behavior will remain as with the setting FAIL_ON_WARNINGS.
|
|
||||||
# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT.
|
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
WARN_AS_ERROR = NO
|
WARN_AS_ERROR = NO
|
||||||
@@ -957,21 +920,10 @@ INPUT = README.md \
|
|||||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||||
# documentation (see:
|
# documentation (see:
|
||||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||||
# See also: INPUT_FILE_ENCODING
|
|
||||||
# The default value is: UTF-8.
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
|
||||||
# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify
|
|
||||||
# character encoding on a per file pattern basis. Doxygen will compare the file
|
|
||||||
# name with each pattern and apply the encoding instead of the default
|
|
||||||
# INPUT_ENCODING) if there is a match. The character encodings are a list of the
|
|
||||||
# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding
|
|
||||||
# "INPUT_ENCODING" for further information on supported encodings.
|
|
||||||
|
|
||||||
INPUT_FILE_ENCODING =
|
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
||||||
# *.h) to filter out the source-files in the directories.
|
# *.h) to filter out the source-files in the directories.
|
||||||
@@ -983,12 +935,12 @@ INPUT_FILE_ENCODING =
|
|||||||
# Note the list of default checked file patterns might differ from the list of
|
# Note the list of default checked file patterns might differ from the list of
|
||||||
# default file extension mappings.
|
# default file extension mappings.
|
||||||
#
|
#
|
||||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm,
|
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||||
# *.cpp, *.cppm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl,
|
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||||
# *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, *.php,
|
# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
|
||||||
# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be
|
# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
|
||||||
# provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
|
||||||
# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
|
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||||
|
|
||||||
FILE_PATTERNS = *.h \
|
FILE_PATTERNS = *.h \
|
||||||
*.js \
|
*.js \
|
||||||
@@ -1030,6 +982,9 @@ EXCLUDE_PATTERNS =
|
|||||||
# output. The symbol name can be a fully qualified name, a word, or if the
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
# ANamespace::AClass, ANamespace::*Test
|
# ANamespace::AClass, ANamespace::*Test
|
||||||
|
#
|
||||||
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
|
# exclude all test directories use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
|
|
||||||
@@ -1074,11 +1029,6 @@ IMAGE_PATH = docs/images/
|
|||||||
# code is scanned, but not when the output code is generated. If lines are added
|
# code is scanned, but not when the output code is generated. If lines are added
|
||||||
# or removed, the anchors will not be placed correctly.
|
# or removed, the anchors will not be placed correctly.
|
||||||
#
|
#
|
||||||
# Note that doxygen will use the data processed and written to standard output
|
|
||||||
# for further processing, therefore nothing else, like debug statements or used
|
|
||||||
# commands (so in case of a Windows batch file always use @echo OFF), should be
|
|
||||||
# written to standard output.
|
|
||||||
#
|
|
||||||
# Note that for custom extensions or not directly supported extensions you also
|
# Note that for custom extensions or not directly supported extensions you also
|
||||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
# properly processed by doxygen.
|
# properly processed by doxygen.
|
||||||
@@ -1120,15 +1070,6 @@ FILTER_SOURCE_PATTERNS =
|
|||||||
|
|
||||||
USE_MDFILE_AS_MAINPAGE = README.md
|
USE_MDFILE_AS_MAINPAGE = README.md
|
||||||
|
|
||||||
# The Fortran standard specifies that for fixed formatted Fortran code all
|
|
||||||
# characters from position 72 are to be considered as comment. A common
|
|
||||||
# extension is to allow longer lines before the automatic comment starts. The
|
|
||||||
# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
|
|
||||||
# be processed before the automatic comment starts.
|
|
||||||
# Minimum value: 7, maximum value: 10000, default value: 72.
|
|
||||||
|
|
||||||
FORTRAN_COMMENT_AFTER = 72
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -1266,11 +1207,10 @@ CLANG_DATABASE_PATH =
|
|||||||
|
|
||||||
ALPHABETICAL_INDEX = YES
|
ALPHABETICAL_INDEX = YES
|
||||||
|
|
||||||
# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
|
# In case all classes in a project start with a common prefix, all classes will
|
||||||
# that should be ignored while generating the index headers. The IGNORE_PREFIX
|
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||||
# tag works for classes, function and member names. The entity will be placed in
|
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||||
# the alphabetical list under the first letter of the entity name that remains
|
# while generating the index headers.
|
||||||
# after removing the prefix.
|
|
||||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
IGNORE_PREFIX =
|
IGNORE_PREFIX =
|
||||||
@@ -1349,12 +1289,7 @@ HTML_STYLESHEET =
|
|||||||
# Doxygen will copy the style sheet files to the output directory.
|
# Doxygen will copy the style sheet files to the output directory.
|
||||||
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
||||||
# style sheet in the list overrules the setting of the previous ones in the
|
# style sheet in the list overrules the setting of the previous ones in the
|
||||||
# list).
|
# list). For an example see the documentation.
|
||||||
# Note: Since the styling of scrollbars can currently not be overruled in
|
|
||||||
# Webkit/Chromium, the styling will be left out of the default doxygen.css if
|
|
||||||
# one or more extra stylesheets have been specified. So if scrollbar
|
|
||||||
# customization is desired it has to be added explicitly. For an example see the
|
|
||||||
# documentation.
|
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_STYLESHEET =
|
HTML_EXTRA_STYLESHEET =
|
||||||
@@ -1369,19 +1304,6 @@ HTML_EXTRA_STYLESHEET =
|
|||||||
|
|
||||||
HTML_EXTRA_FILES =
|
HTML_EXTRA_FILES =
|
||||||
|
|
||||||
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
|
|
||||||
# should be rendered with a dark or light theme.
|
|
||||||
# Possible values are: LIGHT always generate light mode output, DARK always
|
|
||||||
# generate dark mode output, AUTO_LIGHT automatically set the mode according to
|
|
||||||
# the user preference, use light mode if no preference is set (the default),
|
|
||||||
# AUTO_DARK automatically set the mode according to the user preference, use
|
|
||||||
# dark mode if no preference is set and TOGGLE allow to user to switch between
|
|
||||||
# light and dark mode via a button.
|
|
||||||
# The default value is: AUTO_LIGHT.
|
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
||||||
|
|
||||||
HTML_COLORSTYLE = AUTO_LIGHT
|
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||||
# will adjust the colors in the style sheet and background images according to
|
# will adjust the colors in the style sheet and background images according to
|
||||||
# this color. Hue is specified as an angle on a color-wheel, see
|
# this color. Hue is specified as an angle on a color-wheel, see
|
||||||
@@ -1412,6 +1334,15 @@ HTML_COLORSTYLE_SAT = 100
|
|||||||
|
|
||||||
HTML_COLORSTYLE_GAMMA = 80
|
HTML_COLORSTYLE_GAMMA = 80
|
||||||
|
|
||||||
|
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||||
|
# page will contain the date and time when the page was generated. Setting this
|
||||||
|
# to YES can help to show when doxygen was last run and thus if the
|
||||||
|
# documentation is up to date.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
#HTML_TIMESTAMP = NO
|
||||||
|
|
||||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||||
# documentation will contain a main index with vertical navigation menus that
|
# documentation will contain a main index with vertical navigation menus that
|
||||||
# are dynamically created via JavaScript. If disabled, the navigation index will
|
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||||
@@ -1431,13 +1362,6 @@ HTML_DYNAMIC_MENUS = YES
|
|||||||
|
|
||||||
HTML_DYNAMIC_SECTIONS = NO
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
|
||||||
# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be
|
|
||||||
# dynamically folded and expanded in the generated HTML source code.
|
|
||||||
# The default value is: YES.
|
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
||||||
|
|
||||||
HTML_CODE_FOLDING = YES
|
|
||||||
|
|
||||||
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
|
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
|
||||||
# shown in the various tree structured indices initially; the user can expand
|
# shown in the various tree structured indices initially; the user can expand
|
||||||
# and collapse entries dynamically later on. Doxygen will expand the tree to
|
# and collapse entries dynamically later on. Doxygen will expand the tree to
|
||||||
@@ -1568,16 +1492,6 @@ BINARY_TOC = NO
|
|||||||
|
|
||||||
TOC_EXPAND = NO
|
TOC_EXPAND = NO
|
||||||
|
|
||||||
# The SITEMAP_URL tag is used to specify the full URL of the place where the
|
|
||||||
# generated documentation will be placed on the server by the user during the
|
|
||||||
# deployment of the documentation. The generated sitemap is called sitemap.xml
|
|
||||||
# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL
|
|
||||||
# is specified no sitemap is generated. For information about the sitemap
|
|
||||||
# protocol see https://www.sitemaps.org
|
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
||||||
|
|
||||||
SITEMAP_URL =
|
|
||||||
|
|
||||||
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
|
||||||
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
|
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
|
||||||
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
|
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
|
||||||
@@ -1753,6 +1667,17 @@ HTML_FORMULA_FORMAT = png
|
|||||||
|
|
||||||
FORMULA_FONTSIZE = 10
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
|
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
|
||||||
|
# generated for formulas are transparent PNGs. Transparent PNGs are not
|
||||||
|
# supported properly for IE 6.0, but are supported on all modern browsers.
|
||||||
|
#
|
||||||
|
# Note that when changing this option you need to delete any form_*.png files in
|
||||||
|
# the HTML output directory before the changes have effect.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
#FORMULA_TRANSPARENT = YES
|
||||||
|
|
||||||
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||||
# to create new LaTeX commands to be used in formulas as building blocks. See
|
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||||
# the section "Including formulas" for details.
|
# the section "Including formulas" for details.
|
||||||
@@ -1814,8 +1739,8 @@ MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
|
|||||||
|
|
||||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
# extension names that should be enabled during MathJax rendering. For example
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
# for MathJax version 2 (see
|
# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html
|
||||||
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
|
# #tex-and-latex-extensions):
|
||||||
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||||
# For example for MathJax version 3 (see
|
# For example for MathJax version 3 (see
|
||||||
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
|
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
|
||||||
@@ -2066,16 +1991,9 @@ PDF_HYPERLINKS = YES
|
|||||||
|
|
||||||
USE_PDFLATEX = YES
|
USE_PDFLATEX = YES
|
||||||
|
|
||||||
# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error.
|
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
|
||||||
# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch
|
# command to the generated LaTeX files. This will instruct LaTeX to keep running
|
||||||
# mode nothing is printed on the terminal, errors are scrolled as if <return> is
|
# if errors occur, instead of asking the user for help.
|
||||||
# hit at every error; missing files that TeX tries to input or request from
|
|
||||||
# keyboard input (\read on a not open input stream) cause the job to abort,
|
|
||||||
# NON_STOP In nonstop mode the diagnostic message will appear on the terminal,
|
|
||||||
# but there is no possibility of user interaction just like in batch mode,
|
|
||||||
# SCROLL In scroll mode, TeX will stop only for missing files to input or if
|
|
||||||
# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at
|
|
||||||
# each error, asking for user intervention.
|
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
@@ -2096,6 +2014,14 @@ LATEX_HIDE_INDICES = NO
|
|||||||
|
|
||||||
LATEX_BIB_STYLE = plain
|
LATEX_BIB_STYLE = plain
|
||||||
|
|
||||||
|
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
|
||||||
|
# page will contain the date and time when the page was generated. Setting this
|
||||||
|
# to NO can help when comparing the output of multiple runs.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
#LATEX_TIMESTAMP = NO
|
||||||
|
|
||||||
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# path from which the emoji images will be read. If a relative path is entered,
|
# path from which the emoji images will be read. If a relative path is entered,
|
||||||
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||||
@@ -2261,39 +2187,13 @@ DOCBOOK_OUTPUT = docbook
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
|
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
|
||||||
# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures
|
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
|
||||||
# the structure of the code including all documentation. Note that this feature
|
# the structure of the code including all documentation. Note that this feature
|
||||||
# is still experimental and incomplete at the moment.
|
# is still experimental and incomplete at the moment.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_AUTOGEN_DEF = NO
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration options related to Sqlite3 output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3
|
|
||||||
# database with symbols found by doxygen stored in tables.
|
|
||||||
# The default value is: NO.
|
|
||||||
|
|
||||||
#GENERATE_SQLITE3 = NO
|
|
||||||
|
|
||||||
# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be
|
|
||||||
# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put
|
|
||||||
# in front of it.
|
|
||||||
# The default directory is: sqlite3.
|
|
||||||
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
|
||||||
|
|
||||||
#SQLITE3_OUTPUT = sqlite3
|
|
||||||
|
|
||||||
# The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db
|
|
||||||
# database file will be recreated with each doxygen run. If set to NO, doxygen
|
|
||||||
# will warn if an a database file is already found and not modify it.
|
|
||||||
# The default value is: YES.
|
|
||||||
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
|
||||||
|
|
||||||
#SQLITE3_RECREATE_DB = YES
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the Perl module output
|
# Configuration options related to the Perl module output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -2436,15 +2336,15 @@ TAGFILES =
|
|||||||
|
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE =
|
||||||
|
|
||||||
# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces
|
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
|
||||||
# will be listed in the class and namespace index. If set to NO, only the
|
# the class index. If set to NO, only the inherited external classes will be
|
||||||
# inherited external classes will be listed.
|
# listed.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
ALLEXTERNALS = NO
|
ALLEXTERNALS = NO
|
||||||
|
|
||||||
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
|
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
|
||||||
# in the topic index. If set to NO, only the current project's groups will be
|
# in the modules index. If set to NO, only the current project's groups will be
|
||||||
# listed.
|
# listed.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
|
|
||||||
@@ -2458,9 +2358,16 @@ EXTERNAL_GROUPS = YES
|
|||||||
EXTERNAL_PAGES = YES
|
EXTERNAL_PAGES = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to diagram generator tools
|
# Configuration options related to the dot tool
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||||
|
# then run dia to produce the diagram and insert it in the documentation. The
|
||||||
|
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||||
|
# If left empty dia is assumed to be found in the default search path.
|
||||||
|
|
||||||
|
DIA_PATH =
|
||||||
|
|
||||||
# If set to YES the inheritance and collaboration graphs will hide inheritance
|
# If set to YES the inheritance and collaboration graphs will hide inheritance
|
||||||
# and usage relations if the target is undocumented or is not a class.
|
# and usage relations if the target is undocumented or is not a class.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
@@ -2469,10 +2376,10 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
|
|
||||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||||
# available from the path. This tool is part of Graphviz (see:
|
# available from the path. This tool is part of Graphviz (see:
|
||||||
# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||||
# Bell Labs. The other options in this section have no effect if this option is
|
# Bell Labs. The other options in this section have no effect if this option is
|
||||||
# set to NO
|
# set to NO
|
||||||
# The default value is: YES.
|
# The default value is: NO.
|
||||||
|
|
||||||
HAVE_DOT = YES
|
HAVE_DOT = YES
|
||||||
|
|
||||||
@@ -2486,51 +2393,37 @@ HAVE_DOT = YES
|
|||||||
|
|
||||||
DOT_NUM_THREADS = 0
|
DOT_NUM_THREADS = 0
|
||||||
|
|
||||||
# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
|
# When you want a differently looking font in the dot files that doxygen
|
||||||
# subgraphs. When you want a differently looking font in the dot files that
|
# generates you can specify the font name using DOT_FONTNAME. You need to make
|
||||||
# doxygen generates you can specify fontname, fontcolor and fontsize attributes.
|
# sure dot is able to find the font, which can be done by putting it in a
|
||||||
# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
|
# standard location or by setting the DOTFONTPATH environment variable or by
|
||||||
# Edge and Graph Attributes specification</a> You need to make sure dot is able
|
# setting DOT_FONTPATH to the directory containing the font.
|
||||||
# to find the font, which can be done by putting it in a standard location or by
|
# The default value is: Helvetica.
|
||||||
# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
|
|
||||||
# directory containing the font. Default graphviz fontsize is 14.
|
|
||||||
# The default value is: fontname=Helvetica,fontsize=10.
|
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
|
#DOT_FONTNAME = Helvetica
|
||||||
|
|
||||||
# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
|
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
|
||||||
# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
|
# dot graphs.
|
||||||
# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
|
# Minimum value: 4, maximum value: 24, default value: 10.
|
||||||
# arrows shapes.</a>
|
|
||||||
# The default value is: labelfontname=Helvetica,labelfontsize=10.
|
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
|
#DOT_FONTSIZE = 10
|
||||||
|
|
||||||
# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
|
# By default doxygen will tell dot to use the default font as specified with
|
||||||
# around nodes set 'shape=plain' or 'shape=plaintext' <a
|
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
|
||||||
# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
|
# the path where dot can find it using this tag.
|
||||||
# The default value is: shape=box,height=0.2,width=0.4.
|
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
#DOT_FONTPATH =
|
||||||
|
|
||||||
# You can set the path where dot can find font specified with fontname in
|
# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
|
||||||
# DOT_COMMON_ATTR and others dot attributes.
|
# graph for each documented class showing the direct and indirect inheritance
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
|
||||||
|
# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
|
||||||
DOT_FONTPATH =
|
# to TEXT the direct and indirect inheritance relations will be shown as texts /
|
||||||
|
# links.
|
||||||
# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will
|
# Possible values are: NO, YES, TEXT and GRAPH.
|
||||||
# generate a graph for each documented class showing the direct and indirect
|
|
||||||
# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and
|
|
||||||
# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case
|
|
||||||
# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the
|
|
||||||
# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used.
|
|
||||||
# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance
|
|
||||||
# relations will be shown as texts / links.
|
|
||||||
# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
|
|
||||||
CLASS_GRAPH = YES
|
CLASS_GRAPH = YES
|
||||||
@@ -2538,21 +2431,15 @@ CLASS_GRAPH = YES
|
|||||||
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
|
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
|
||||||
# graph for each documented class showing the direct and indirect implementation
|
# graph for each documented class showing the direct and indirect implementation
|
||||||
# dependencies (inheritance, containment, and class references variables) of the
|
# dependencies (inheritance, containment, and class references variables) of the
|
||||||
# class with other documented classes. Explicit enabling a collaboration graph,
|
# class with other documented classes.
|
||||||
# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the
|
|
||||||
# command \collaborationgraph. Disabling a collaboration graph can be
|
|
||||||
# accomplished by means of the command \hidecollaborationgraph.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
COLLABORATION_GRAPH = YES
|
COLLABORATION_GRAPH = YES
|
||||||
|
|
||||||
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
|
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
|
||||||
# groups, showing the direct groups dependencies. Explicit enabling a group
|
# groups, showing the direct groups dependencies. See also the chapter Grouping
|
||||||
# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means
|
# in the manual.
|
||||||
# of the command \groupgraph. Disabling a directory graph can be accomplished by
|
|
||||||
# means of the command \hidegroupgraph. See also the chapter Grouping in the
|
|
||||||
# manual.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
@@ -2612,9 +2499,7 @@ TEMPLATE_RELATIONS = NO
|
|||||||
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
|
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
|
||||||
# YES then doxygen will generate a graph for each documented file showing the
|
# YES then doxygen will generate a graph for each documented file showing the
|
||||||
# direct and indirect include dependencies of the file with other documented
|
# direct and indirect include dependencies of the file with other documented
|
||||||
# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO,
|
# files.
|
||||||
# can be accomplished by means of the command \includegraph. Disabling an
|
|
||||||
# include graph can be accomplished by means of the command \hideincludegraph.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
@@ -2623,10 +2508,7 @@ INCLUDE_GRAPH = YES
|
|||||||
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
|
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
|
||||||
# set to YES then doxygen will generate a graph for each documented file showing
|
# set to YES then doxygen will generate a graph for each documented file showing
|
||||||
# the direct and indirect include dependencies of the file with other documented
|
# the direct and indirect include dependencies of the file with other documented
|
||||||
# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set
|
# files.
|
||||||
# to NO, can be accomplished by means of the command \includedbygraph. Disabling
|
|
||||||
# an included by graph can be accomplished by means of the command
|
|
||||||
# \hideincludedbygraph.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
@@ -2666,10 +2548,7 @@ GRAPHICAL_HIERARCHY = YES
|
|||||||
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
|
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
|
||||||
# dependencies a directory has on other directories in a graphical way. The
|
# dependencies a directory has on other directories in a graphical way. The
|
||||||
# dependency relations are determined by the #include relations between the
|
# dependency relations are determined by the #include relations between the
|
||||||
# files in the directories. Explicit enabling a directory graph, when
|
# files in the directories.
|
||||||
# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command
|
|
||||||
# \directorygraph. Disabling a directory graph can be accomplished by means of
|
|
||||||
# the command \hidedirectorygraph.
|
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
@@ -2685,13 +2564,12 @@ DIR_GRAPH_MAX_DEPTH = 1
|
|||||||
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
||||||
# generated by dot. For an explanation of the image formats see the section
|
# generated by dot. For an explanation of the image formats see the section
|
||||||
# output formats in the documentation of the dot tool (Graphviz (see:
|
# output formats in the documentation of the dot tool (Graphviz (see:
|
||||||
# https://www.graphviz.org/)).
|
# http://www.graphviz.org/)).
|
||||||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||||
# requirement).
|
# requirement).
|
||||||
# Possible values are: png, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd,
|
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
|
||||||
# gif, gif:cairo, gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd,
|
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
||||||
# png:cairo, png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
|
||||||
# png:gdiplus:gdiplus.
|
# png:gdiplus:gdiplus.
|
||||||
# The default value is: png.
|
# The default value is: png.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
@@ -2723,12 +2601,11 @@ DOT_PATH =
|
|||||||
|
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# then run dia to produce the diagram and insert it in the documentation. The
|
# contain msc files that are included in the documentation (see the \mscfile
|
||||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
# command).
|
||||||
# If left empty dia is assumed to be found in the default search path.
|
|
||||||
|
|
||||||
DIA_PATH =
|
MSCFILE_DIRS =
|
||||||
|
|
||||||
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dia files that are included in the documentation (see the \diafile
|
# contain dia files that are included in the documentation (see the \diafile
|
||||||
@@ -2778,6 +2655,18 @@ DOT_GRAPH_MAX_NODES = 50
|
|||||||
|
|
||||||
MAX_DOT_GRAPH_DEPTH = 0
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|
||||||
|
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
||||||
|
# background. This is disabled by default, because dot on Windows does not seem
|
||||||
|
# to support this out of the box.
|
||||||
|
#
|
||||||
|
# Warning: Depending on the platform used, enabling this option may lead to
|
||||||
|
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
|
||||||
|
# read).
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
#DOT_TRANSPARENT = NO
|
||||||
|
|
||||||
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
|
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
|
||||||
# files in one run (i.e. multiple -o and -T options on the command line). This
|
# files in one run (i.e. multiple -o and -T options on the command line). This
|
||||||
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
||||||
@@ -2805,19 +2694,3 @@ GENERATE_LEGEND = YES
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
|
|
||||||
DOT_CLEANUP = YES
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
|
||||||
# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will
|
|
||||||
# use a built-in version of mscgen tool to produce the charts. Alternatively,
|
|
||||||
# the MSCGEN_TOOL tag can also specify the name an external tool. For instance,
|
|
||||||
# specifying prog as the value, doxygen will call the tool as prog -T
|
|
||||||
# <outfile_format> -o <outputfile> <inputfile>. The external tool should support
|
|
||||||
# output file formats "png", "eps", "svg", and "ismap".
|
|
||||||
|
|
||||||
MSCGEN_TOOL =
|
|
||||||
|
|
||||||
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
|
||||||
# contain msc files that are included in the documentation (see the \mscfile
|
|
||||||
# command).
|
|
||||||
|
|
||||||
MSCFILE_DIRS =
|
|
||||||
|
2823
Doxyfile.bak
Normal file
2823
Doxyfile.bak
Normal file
File diff suppressed because it is too large
Load Diff
11
GNUmakefile
11
GNUmakefile
@@ -16,9 +16,9 @@ MAKEFLAGS += --no-builtin-rules
|
|||||||
## LD := Linker.
|
## LD := Linker.
|
||||||
## ANDROID_SDK := Path to the Android SDK.
|
## ANDROID_SDK := Path to the Android SDK.
|
||||||
|
|
||||||
VERSION_CODE := 41
|
VERSION_CODE := 43
|
||||||
VERSION_CODE_IOS := 16
|
VERSION_CODE_IOS := 17
|
||||||
VERSION_NUMBER := 0.2025.8-wip
|
VERSION_NUMBER := 0.2025.9-wip
|
||||||
VERSION_NAME := This program kills fascists.
|
VERSION_NAME := This program kills fascists.
|
||||||
|
|
||||||
IPHONEOS_VERSION_MIN=14.0
|
IPHONEOS_VERSION_MIN=14.0
|
||||||
@@ -253,7 +253,10 @@ $(ANDROID_TARGETS): CFLAGS += \
|
|||||||
-fno-asynchronous-unwind-tables \
|
-fno-asynchronous-unwind-tables \
|
||||||
-funwind-tables \
|
-funwind-tables \
|
||||||
-Wno-unknown-warning-option
|
-Wno-unknown-warning-option
|
||||||
$(ANDROID_TARGETS): LDFLAGS += --sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC
|
$(ANDROID_TARGETS): LDFLAGS += \
|
||||||
|
--sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot \
|
||||||
|
-Wl,-z,max-page-size=16384 \
|
||||||
|
-fPIC
|
||||||
$(DEBUG_TARGETS): CFLAGS += -DDEBUG -Og
|
$(DEBUG_TARGETS): CFLAGS += -DDEBUG -Og
|
||||||
$(DEBUG_TARGETS): LDFLAGS += -Og
|
$(DEBUG_TARGETS): LDFLAGS += -Og
|
||||||
$(RELEASE_TARGETS): CFLAGS += \
|
$(RELEASE_TARGETS): CFLAGS += \
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "🦀",
|
"emoji": "🦀",
|
||||||
"previous": "&TTGzyovmfKozjELCGPBFLLEXQcpfaArOMmqzemvz9J8=.sha256"
|
"previous": "&Hd6CuhhnZIf13PdFJYZBUYLYZO84WdaKvWXLC29M7Ac=.sha256"
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,9 @@ class TfElement extends LitElement {
|
|||||||
channels_latest: {type: Object},
|
channels_latest: {type: Object},
|
||||||
guest: {type: Boolean},
|
guest: {type: Boolean},
|
||||||
url: {type: String},
|
url: {type: String},
|
||||||
|
private_closed: {type: Object},
|
||||||
private_messages: {type: Array},
|
private_messages: {type: Array},
|
||||||
|
grouped_private_messages: {type: Object},
|
||||||
recent_reactions: {type: Array},
|
recent_reactions: {type: Array},
|
||||||
is_administrator: {type: Boolean},
|
is_administrator: {type: Boolean},
|
||||||
stay_connected: {type: Boolean},
|
stay_connected: {type: Boolean},
|
||||||
@@ -48,6 +50,7 @@ class TfElement extends LitElement {
|
|||||||
this.loading_latest = 0;
|
this.loading_latest = 0;
|
||||||
this.loading_latest_scheduled = 0;
|
this.loading_latest_scheduled = 0;
|
||||||
this.recent_reactions = [];
|
this.recent_reactions = [];
|
||||||
|
this.private_closed = {};
|
||||||
tfrpc.rpc.getBroadcasts().then((b) => {
|
tfrpc.rpc.getBroadcasts().then((b) => {
|
||||||
self.broadcasts = b || [];
|
self.broadcasts = b || [];
|
||||||
});
|
});
|
||||||
@@ -85,9 +88,22 @@ class TfElement extends LitElement {
|
|||||||
this.whoami = whoami ?? (ids.length ? ids[0] : undefined);
|
this.whoami = whoami ?? (ids.length ? ids[0] : undefined);
|
||||||
this.guest = !this.whoami?.length;
|
this.guest = !this.whoami?.length;
|
||||||
this.ids = ids;
|
this.ids = ids;
|
||||||
|
let private_closed =
|
||||||
|
(await tfrpc.rpc.databaseGet('private_closed')) ?? '{}';
|
||||||
|
this.private_closed = JSON.parse(private_closed);
|
||||||
await this.load_channels();
|
await this.load_channels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async close_private_chat(event) {
|
||||||
|
let update = {};
|
||||||
|
update[event.detail.key] = true;
|
||||||
|
this.private_closed = Object.assign(update, this.private_closed);
|
||||||
|
await tfrpc.rpc.databaseSet(
|
||||||
|
'private_closed',
|
||||||
|
JSON.stringify(this.private_closed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async load_channels() {
|
async load_channels() {
|
||||||
let channels = await tfrpc.rpc.query(
|
let channels = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
@@ -135,12 +151,32 @@ class TfElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visible_private() {
|
||||||
|
if (!this.grouped_private_messages || !this.private_closed) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
let self = this;
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(this.grouped_private_messages).filter(([key, value]) => {
|
||||||
|
let channel = '🔐' + [...new Set(JSON.parse(key))].sort().join(',');
|
||||||
|
let grouped_latest = Math.max(...value.map((x) => x.rowid));
|
||||||
|
return (
|
||||||
|
!self.private_closed[key] ||
|
||||||
|
self.channels_unread[channel] === undefined ||
|
||||||
|
grouped_latest > self.channels_unread[channel]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
next_channel(delta) {
|
next_channel(delta) {
|
||||||
let channel_names = [
|
let channel_names = [
|
||||||
'',
|
'',
|
||||||
'@',
|
'@',
|
||||||
'👍',
|
'👍',
|
||||||
'🔐',
|
...Object.keys(this.visible_private())
|
||||||
|
.sort()
|
||||||
|
.map((x) => '🔐' + JSON.parse(x).join(',')),
|
||||||
...this.channels.map((x) => '#' + x),
|
...this.channels.map((x) => '#' + x),
|
||||||
];
|
];
|
||||||
let index = channel_names.indexOf(this.hash.substring(1));
|
let index = channel_names.indexOf(this.hash.substring(1));
|
||||||
@@ -366,6 +402,36 @@ class TfElement extends LitElement {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async group_private_messages(messages) {
|
||||||
|
let groups = {};
|
||||||
|
let result = await this.decrypt(
|
||||||
|
await tfrpc.rpc.query(
|
||||||
|
`
|
||||||
|
SELECT messages.rowid, messages.id, author, timestamp, json(content) AS content
|
||||||
|
FROM messages
|
||||||
|
JOIN json_each(?) AS ids
|
||||||
|
WHERE messages.id = ids.value
|
||||||
|
ORDER BY timestamp DESC
|
||||||
|
`,
|
||||||
|
[JSON.stringify(messages)]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
for (let message of result) {
|
||||||
|
let key = JSON.stringify(
|
||||||
|
[
|
||||||
|
...new Set(
|
||||||
|
message?.decrypted?.recps?.filter((x) => x != this.whoami)
|
||||||
|
),
|
||||||
|
].sort() ?? []
|
||||||
|
);
|
||||||
|
if (!groups[key]) {
|
||||||
|
groups[key] = [];
|
||||||
|
}
|
||||||
|
groups[key].push(message);
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
async load_channels_latest(following) {
|
async load_channels_latest(following) {
|
||||||
let start_time = new Date();
|
let start_time = new Date();
|
||||||
let latest_private = this.get_latest_private(following);
|
let latest_private = this.get_latest_private(following);
|
||||||
@@ -438,12 +504,15 @@ class TfElement extends LitElement {
|
|||||||
console.log('channels took', (new Date() - start_time) / 1000.0);
|
console.log('channels took', (new Date() - start_time) / 1000.0);
|
||||||
let self = this;
|
let self = this;
|
||||||
start_time = new Date();
|
start_time = new Date();
|
||||||
latest_private.then(function (latest) {
|
latest_private.then(async function (latest) {
|
||||||
self.channels_latest = Object.assign({}, self.channels_latest, {
|
self.channels_latest = Object.assign({}, self.channels_latest, {
|
||||||
'🔐': latest[0],
|
'🔐': latest[0],
|
||||||
});
|
});
|
||||||
console.log('private took', (new Date() - start_time) / 1000.0);
|
console.log('private took', (new Date() - start_time) / 1000.0);
|
||||||
self.private_messages = latest[1];
|
self.private_messages = latest[1];
|
||||||
|
self.grouped_private_messages = await self.group_private_messages(
|
||||||
|
latest[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,8 +697,10 @@ class TfElement extends LitElement {
|
|||||||
@refresh=${this.refresh}
|
@refresh=${this.refresh}
|
||||||
@toggle_stay_connected=${this.toggle_stay_connected}
|
@toggle_stay_connected=${this.toggle_stay_connected}
|
||||||
@loadmessages=${this.reset_progress}
|
@loadmessages=${this.reset_progress}
|
||||||
|
@closeprivatechat=${this.close_private_chat}
|
||||||
.connections=${this.connections}
|
.connections=${this.connections}
|
||||||
.private_messages=${this.private_messages}
|
.private_messages=${this.private_messages}
|
||||||
|
.grouped_private_messages=${this.visible_private()}
|
||||||
.recent_reactions=${this.recent_reactions}
|
.recent_reactions=${this.recent_reactions}
|
||||||
?is_administrator=${this.is_administrator}
|
?is_administrator=${this.is_administrator}
|
||||||
?stay_connected=${this.stay_connected}
|
?stay_connected=${this.stay_connected}
|
||||||
|
@@ -16,6 +16,7 @@ class TfComposeElement extends LitElement {
|
|||||||
author: {type: String},
|
author: {type: String},
|
||||||
channel: {type: String},
|
channel: {type: String},
|
||||||
new_thread: {type: Boolean},
|
new_thread: {type: Boolean},
|
||||||
|
recipients: {type: Array},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +92,9 @@ class TfComposeElement extends LitElement {
|
|||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true,
|
composed: true,
|
||||||
detail: {
|
detail: {
|
||||||
id: this.branch,
|
id:
|
||||||
|
this.branch ??
|
||||||
|
(this.recipients ? this.recipients.join(',') : undefined),
|
||||||
draft: draft,
|
draft: draft,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -291,7 +294,7 @@ class TfComposeElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
get_values() {
|
||||||
let values = Object.entries(this.users).map((x) => ({
|
let values = Object.entries(this.users).map((x) => ({
|
||||||
key: x[1].name ?? x[0],
|
key: x[1].name ?? x[0],
|
||||||
value: x[0],
|
value: x[0],
|
||||||
@@ -307,11 +310,15 @@ class TfComposeElement extends LitElement {
|
|||||||
values
|
values
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
let tribute = new Tribute({
|
let tribute = new Tribute({
|
||||||
iframe: this.shadowRoot,
|
iframe: this.shadowRoot,
|
||||||
collection: [
|
collection: [
|
||||||
{
|
{
|
||||||
values: values,
|
values: this.get_values(),
|
||||||
selectTemplate: function (item) {
|
selectTemplate: function (item) {
|
||||||
return item
|
return item
|
||||||
? `[@${item.original.key}](${item.original.value})`
|
? `[@${item.original.key}](${item.original.value})`
|
||||||
@@ -330,6 +337,7 @@ class TfComposeElement extends LitElement {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
tribute.attach(this.renderRoot.getElementById('edit'));
|
tribute.attach(this.renderRoot.getElementById('edit'));
|
||||||
|
this._tribute = tribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
updated() {
|
updated() {
|
||||||
@@ -340,6 +348,7 @@ class TfComposeElement extends LitElement {
|
|||||||
preview.innerHTML = this.process_text(edit.innerText);
|
preview.innerHTML = this.process_text(edit.innerText);
|
||||||
this.last_updated_text = edit.innerText;
|
this.last_updated_text = edit.innerText;
|
||||||
}
|
}
|
||||||
|
this._tribute.collection[0].values = this.get_values();
|
||||||
let encrypt = this.renderRoot.getElementById('encrypt_to');
|
let encrypt = this.renderRoot.getElementById('encrypt_to');
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
let tribute = new Tribute({
|
let tribute = new Tribute({
|
||||||
@@ -496,7 +505,17 @@ class TfComposeElement extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_draft() {
|
get_draft() {
|
||||||
return this.drafts[this.branch || ''] || {};
|
let key =
|
||||||
|
this.branch ||
|
||||||
|
(this.recipients ? this.recipients.join(',') : undefined) ||
|
||||||
|
'';
|
||||||
|
let draft = this.drafts[key] || {};
|
||||||
|
if (this.recipients && !draft.encrypt_to?.length) {
|
||||||
|
draft.encrypt_to = [
|
||||||
|
...new Set(this.recipients).union(new Set(draft.encrypt_to ?? [])),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_encrypt(event) {
|
update_encrypt(event) {
|
||||||
|
@@ -349,6 +349,9 @@ class TfProfileElement extends LitElement {
|
|||||||
${until(this.load_follows(), html`<p>Loading accounts followed...</p>`)}
|
${until(this.load_follows(), html`<p>Loading accounts followed...</p>`)}
|
||||||
<footer class="w3-container">
|
<footer class="w3-container">
|
||||||
<p>
|
<p>
|
||||||
|
<a class="w3-button w3-theme-d1" href=${'#🔐' + (this.id != this.whoami ? this.id : '')}>
|
||||||
|
Open Private Chat
|
||||||
|
</a>
|
||||||
${edit}
|
${edit}
|
||||||
${follow}
|
${follow}
|
||||||
${block}
|
${block}
|
||||||
|
@@ -43,6 +43,8 @@ const tf = css`
|
|||||||
border-left: 4px solid #fff;
|
border-left: 4px solid #fff;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
time_range: {type: Array},
|
time_range: {type: Array},
|
||||||
time_loading: {type: Array},
|
time_loading: {type: Array},
|
||||||
private_messages: {type: Array},
|
private_messages: {type: Array},
|
||||||
|
grouped_private_messages: {type: Object},
|
||||||
recent_reactions: {type: Array},
|
recent_reactions: {type: Array},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -208,7 +209,9 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
console.log(
|
console.log(
|
||||||
`load of ${result.length} rows took ${(t2 - t0) / 1000} (${(t1 - t0) / 1000} to find ${initial_messages.length} initial messages, ${(t2 - t1) / 1000} to find ${result.length} total messages) following=${this.following.length} st=${start_time} et=${end_time}`
|
`load of ${result.length} rows took ${(t2 - t0) / 1000} (${(t1 - t0) / 1000} to find ${initial_messages.length} initial messages, ${(t2 - t1) / 1000} to find ${result.length} total messages) following=${this.following.length} st=${start_time} et=${end_time}`
|
||||||
);
|
);
|
||||||
} else if (this.hash == '#🔐') {
|
} else if (this.hash.startsWith('#🔐')) {
|
||||||
|
let ids =
|
||||||
|
this.hash == '#🔐' ? [] : this.hash.substring('#🔐'.length).split(',');
|
||||||
result = await tfrpc.rpc.query(
|
result = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
SELECT TRUE AS is_primary, messages.rowid, messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
SELECT TRUE AS is_primary, messages.rowid, messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
@@ -220,7 +223,11 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
ORDER BY messages.rowid DESC LIMIT ?4
|
ORDER BY messages.rowid DESC LIMIT ?4
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
JSON.stringify(this.private_messages),
|
JSON.stringify(
|
||||||
|
this.grouped_private_messages?.[JSON.stringify(ids)]?.map(
|
||||||
|
(x) => x.id
|
||||||
|
) ?? []
|
||||||
|
),
|
||||||
start_time,
|
start_time,
|
||||||
end_time,
|
end_time,
|
||||||
k_max_results,
|
k_max_results,
|
||||||
@@ -379,13 +386,16 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
this.loading++;
|
this.loading++;
|
||||||
let messages = [];
|
let messages = [];
|
||||||
|
let original_hash = this.hash;
|
||||||
try {
|
try {
|
||||||
if (this._messages_hash !== this.hash) {
|
if (this._messages_hash !== this.hash) {
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
this._messages_hash = this.hash;
|
this._messages_hash = this.hash;
|
||||||
}
|
}
|
||||||
this._messages_following = JSON.stringify(this.following);
|
this._messages_following = JSON.stringify(this.following);
|
||||||
this._private_messages = JSON.stringify(this.private_messages);
|
this._private_messages =
|
||||||
|
JSON.stringify(this.private_messages) +
|
||||||
|
JSON.stringify(this.grouped_private_messages);
|
||||||
let now = new Date().valueOf();
|
let now = new Date().valueOf();
|
||||||
let start_time = now - 24 * 60 * 60 * 1000;
|
let start_time = now - 24 * 60 * 60 * 1000;
|
||||||
this.start_time = start_time;
|
this.start_time = start_time;
|
||||||
@@ -398,7 +408,9 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
} finally {
|
} finally {
|
||||||
this.loading--;
|
this.loading--;
|
||||||
}
|
}
|
||||||
this.messages = this.merge_messages(this.messages, messages);
|
if (this.hash == original_hash) {
|
||||||
|
this.messages = this.merge_messages(this.messages, messages);
|
||||||
|
}
|
||||||
this.time_loading = undefined;
|
this.time_loading = undefined;
|
||||||
console.log(
|
console.log(
|
||||||
`loading ${messages.length} messages done for ${self.whoami} in ${(new Date() - start_time) / 1000}s`
|
`loading ${messages.length} messages done for ${self.whoami} in ${(new Date() - start_time) / 1000}s`
|
||||||
@@ -424,12 +436,42 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close_private_chat() {
|
||||||
|
this.mark_all_read();
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('closeprivatechat', {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
detail: {
|
||||||
|
key: JSON.stringify(
|
||||||
|
this.hash == '#🔐'
|
||||||
|
? []
|
||||||
|
: this.hash.substring('#🔐'.length).split(',')
|
||||||
|
),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
tfrpc.rpc.setHash('#');
|
||||||
|
}
|
||||||
|
|
||||||
|
render_close_chat_button() {
|
||||||
|
if (this.hash.startsWith('#🔐')) {
|
||||||
|
return html`
|
||||||
|
<button class="w3-button w3-theme-d1" @click=${this.close_private_chat}>
|
||||||
|
Close Chat
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (
|
if (
|
||||||
!this.messages ||
|
!this.messages ||
|
||||||
this._messages_hash !== this.hash ||
|
this._messages_hash !== this.hash ||
|
||||||
this._messages_following !== JSON.stringify(this.following) ||
|
this._messages_following !== JSON.stringify(this.following) ||
|
||||||
this._private_messages !== JSON.stringify(this.private_messages)
|
this._private_messages !==
|
||||||
|
JSON.stringify(this.private_messages) +
|
||||||
|
JSON.stringify(this.grouped_private_messages)
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
`loading messages for ${this.whoami} (following ${this.following.length})`
|
`loading messages for ${this.whoami} (following ${this.following.length})`
|
||||||
@@ -489,6 +531,7 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
Mark All Read
|
Mark All Read
|
||||||
</button>`
|
</button>`
|
||||||
: undefined}
|
: undefined}
|
||||||
|
${this.render_close_chat_button()}
|
||||||
<tf-news
|
<tf-news
|
||||||
id="news"
|
id="news"
|
||||||
whoami=${this.whoami}
|
whoami=${this.whoami}
|
||||||
|
@@ -24,6 +24,7 @@ class TfTabNewsElement extends LitElement {
|
|||||||
channels_latest: {type: Object},
|
channels_latest: {type: Object},
|
||||||
connections: {type: Array},
|
connections: {type: Array},
|
||||||
private_messages: {type: Array},
|
private_messages: {type: Array},
|
||||||
|
grouped_private_messages: {type: Object},
|
||||||
recent_reactions: {type: Array},
|
recent_reactions: {type: Array},
|
||||||
peer_exchange: {type: Boolean},
|
peer_exchange: {type: Boolean},
|
||||||
is_administrator: {type: Boolean},
|
is_administrator: {type: Boolean},
|
||||||
@@ -115,6 +116,19 @@ class TfTabNewsElement extends LitElement {
|
|||||||
) {
|
) {
|
||||||
return '✉️ ';
|
return '✉️ ';
|
||||||
}
|
}
|
||||||
|
} else if (channel?.startsWith('🔐')) {
|
||||||
|
let key = JSON.stringify(channel.substring('🔐'.length).split(','));
|
||||||
|
if (this.grouped_private_messages?.[key]) {
|
||||||
|
let grouped_latest = Math.max(
|
||||||
|
...this.grouped_private_messages?.[key]?.map((x) => x.rowid)
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
this.channels_unread[channel] === undefined ||
|
||||||
|
grouped_latest > this.channels_unread[channel]
|
||||||
|
) {
|
||||||
|
return '✉️ ';
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (
|
} else if (
|
||||||
this.channels_latest[channel] &&
|
this.channels_latest[channel] &&
|
||||||
this.channels_latest[channel] > 0 &&
|
this.channels_latest[channel] > 0 &&
|
||||||
@@ -257,12 +271,29 @@ class TfTabNewsElement extends LitElement {
|
|||||||
style=${this.hash == '#👍' ? 'font-weight: bold' : undefined}
|
style=${this.hash == '#👍' ? 'font-weight: bold' : undefined}
|
||||||
>${this.unread_status('👍')}👍votes</a
|
>${this.unread_status('👍')}👍votes</a
|
||||||
>
|
>
|
||||||
<a
|
${Object.keys(this?.grouped_private_messages ?? [])
|
||||||
href="#🔐"
|
?.sort()
|
||||||
class="w3-bar-item w3-button"
|
?.map(
|
||||||
style=${this.hash == '#🔐' ? 'font-weight: bold' : undefined}
|
(key) => html`
|
||||||
>${this.unread_status('🔐')}🔐private</a
|
<a
|
||||||
>
|
href=${'#🔐' + JSON.parse(key).join(',')}
|
||||||
|
class="w3-bar-item w3-button"
|
||||||
|
style=${this.hash == '#🔐' + JSON.parse(key).join(',')
|
||||||
|
? 'font-weight: bold'
|
||||||
|
: undefined}
|
||||||
|
>${this.unread_status('🔐' + JSON.parse(key).join(','))}
|
||||||
|
${(key != '[]' ? JSON.parse(key) : [this.whoami]).map(
|
||||||
|
(id) => html`
|
||||||
|
<tf-user
|
||||||
|
id=${id}
|
||||||
|
nolink="true"
|
||||||
|
.users=${this.users}
|
||||||
|
></tf-user>
|
||||||
|
`
|
||||||
|
)}</a
|
||||||
|
>
|
||||||
|
`
|
||||||
|
)}
|
||||||
${Object.keys(this.drafts)
|
${Object.keys(this.drafts)
|
||||||
.sort()
|
.sort()
|
||||||
.map(
|
.map(
|
||||||
@@ -418,6 +449,9 @@ class TfTabNewsElement extends LitElement {
|
|||||||
.drafts=${this.drafts}
|
.drafts=${this.drafts}
|
||||||
@tf-draft=${this.draft}
|
@tf-draft=${this.draft}
|
||||||
.channel=${this.channel()}
|
.channel=${this.channel()}
|
||||||
|
.recipients=${this.hash.startsWith('#🔐')
|
||||||
|
? this.hash.substring('#🔐'.length).split(',')
|
||||||
|
: undefined}
|
||||||
></tf-compose>
|
></tf-compose>
|
||||||
</div>
|
</div>
|
||||||
${profile}
|
${profile}
|
||||||
@@ -434,6 +468,7 @@ class TfTabNewsElement extends LitElement {
|
|||||||
.channels_unread=${this.channels_unread}
|
.channels_unread=${this.channels_unread}
|
||||||
.channels_latest=${this.channels_latest}
|
.channels_latest=${this.channels_latest}
|
||||||
.private_messages=${this.private_messages}
|
.private_messages=${this.private_messages}
|
||||||
|
.grouped_private_messages=${this.grouped_private_messages}
|
||||||
.recent_reactions=${this.recent_reactions}
|
.recent_reactions=${this.recent_reactions}
|
||||||
></tf-tab-news-feed>
|
></tf-tab-news-feed>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -9,6 +9,7 @@ class TfUserElement extends LitElement {
|
|||||||
fallback_name: {type: String},
|
fallback_name: {type: String},
|
||||||
icon_only: {type: Boolean},
|
icon_only: {type: Boolean},
|
||||||
users: {type: Object},
|
users: {type: Object},
|
||||||
|
nolink: {type: Boolean},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +38,9 @@ class TfUserElement extends LitElement {
|
|||||||
let name_string = name ?? this.fallback_name ?? this.id;
|
let name_string = name ?? this.fallback_name ?? this.id;
|
||||||
name = this.icon_only
|
name = this.icon_only
|
||||||
? undefined
|
? undefined
|
||||||
: html`<a target="_top" href=${'#' + this.id}>${name_string}</a>`;
|
: !this.nolink
|
||||||
|
? html`<a target="_top" href=${'#' + this.id}>${name_string}</a>`
|
||||||
|
: html`<span>${name_string}</span>`;
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
let image_link = user.image;
|
let image_link = user.image;
|
||||||
@@ -56,7 +59,8 @@ class TfUserElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return html` <div
|
return html` <div
|
||||||
style="display: inline-block; vertical-align: middle; font-weight: bold; text-wrap: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis"
|
style=${'display: inline-block; vertical-align: middle; text-wrap: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis' +
|
||||||
|
(this.nolink ? '' : '; font-weight: bold')}
|
||||||
>
|
>
|
||||||
${image} ${name}
|
${image} ${name}
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@@ -438,6 +438,9 @@ class TfNavigationElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a tf-navigation element.
|
||||||
|
*/
|
||||||
customElements.define('tf-navigation', TfNavigationElement);
|
customElements.define('tf-navigation', TfNavigationElement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -703,6 +703,9 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSB message added callback.
|
||||||
|
*/
|
||||||
ssb.addEventListener('message', function () {
|
ssb.addEventListener('message', function () {
|
||||||
broadcastEvent('onMessage', [...arguments]);
|
broadcastEvent('onMessage', [...arguments]);
|
||||||
});
|
});
|
||||||
|
@@ -25,14 +25,14 @@
|
|||||||
}:
|
}:
|
||||||
pkgs.stdenv.mkDerivation rec {
|
pkgs.stdenv.mkDerivation rec {
|
||||||
pname = "tildefriends";
|
pname = "tildefriends";
|
||||||
version = "0.0.33";
|
version = "0.2025.8";
|
||||||
|
|
||||||
src = pkgs.fetchFromGitea {
|
src = pkgs.fetchFromGitea {
|
||||||
domain = "dev.tildefriends.net";
|
domain = "dev.tildefriends.net";
|
||||||
owner = "cory";
|
owner = "cory";
|
||||||
repo = "tildefriends";
|
repo = "tildefriends";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-9D28gmaBTRVyXhY3zZd/W9PsXA1YZt/K69hz41aVP04=";
|
hash = "sha256-N/5lp8RL19B6Z43kRxx7c01WVJkK44a/wwNgRJPk5uI=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2
deps/codemirror/cm6.js
vendored
2
deps/codemirror/cm6.js
vendored
File diff suppressed because one or more lines are too long
230
deps/codemirror_src/package-lock.json
generated
vendored
230
deps/codemirror_src/package-lock.json
generated
vendored
@@ -19,9 +19,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/autocomplete": {
|
"node_modules/@codemirror/autocomplete": {
|
||||||
"version": "6.18.6",
|
"version": "6.18.7",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.7.tgz",
|
||||||
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
|
"integrity": "sha512-8EzdeIoWPJDsMBwz3zdzwXnUpCzMiCyz5/A3FIPpriaclFCGDkAzK13sMcnsu5rowqiyeQN2Vs2TsOcoDPZirQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
@@ -98,9 +98,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/language": {
|
"node_modules/@codemirror/language": {
|
||||||
"version": "6.11.2",
|
"version": "6.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.2.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.3.tgz",
|
||||||
"integrity": "sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==",
|
"integrity": "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
@@ -155,9 +155,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/view": {
|
"node_modules/@codemirror/view": {
|
||||||
"version": "6.38.1",
|
"version": "6.38.2",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.2.tgz",
|
||||||
"integrity": "sha512-RmTOkE7hRU3OVREqFVITWHz6ocgBjv08GoePscAakgVQfciA3SGCEk7mb9IzwW61cKKmlTpHXG6DUE5Ubx+MGQ==",
|
"integrity": "sha512-bTWAJxL6EOFLPzTx+O5P5xAO3gTqpatQ2b/ARQ8itfU/v2LlpS3pH2fkL0A3E/Fx8Y2St2KES7ZEV0sHTsSW/A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.5.0",
|
"@codemirror/state": "^6.5.0",
|
||||||
@@ -167,9 +167,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.12",
|
"version": "0.3.13",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
"integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
|
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -188,9 +188,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/source-map": {
|
"node_modules/@jridgewell/source-map": {
|
||||||
"version": "0.3.10",
|
"version": "0.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
|
||||||
"integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==",
|
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -199,16 +199,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.5.4",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||||
"integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
|
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.29",
|
"version": "0.3.30",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
|
||||||
"integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
|
"integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -360,9 +360,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz",
|
||||||
"integrity": "sha512-9f3nSTFI2ivfxc7/tHBHcJ8pRnp8ROrELvsVprlQPVvcZ+j5zztYd+PTJGpyIOAdTvNwNrpCXswKSeoQcyGjMQ==",
|
"integrity": "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -373,9 +373,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-tFZSEhqJ8Yrpe50TzOdeoYi72gi/jsnT7y8Qrozf3cNu28WX+s6I3XzEPUAqoaT9SAS8Xz9AzGTFlxxCH/w20w==",
|
"integrity": "sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -386,9 +386,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-+DikIIs+p6yU2hF51UaWG8BnHbq90X0QIOt5zqSKSZxY+G3qqdLih214e9InJal21af2PuuxkDectetGfbVPJw==",
|
"integrity": "sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -399,9 +399,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.0.tgz",
|
||||||
"integrity": "sha512-5a+NofhdEB/WimSlFMskbFQn1vqz1FWryYpA99trmZGO6qEmiS0IsX6w4B3d91U878Q2ZQdiaFF1gxX4P147og==",
|
"integrity": "sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -412,9 +412,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-igr/RlKPS3OCy4jD3XBmAmo3UAcNZkJSubRsw1JeM8bAbwf15k/3eMZXD91bnjheijJiOJcga3kfCLKjV8IXNg==",
|
"integrity": "sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -425,9 +425,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.0.tgz",
|
||||||
"integrity": "sha512-MdigWzPSHlQzB1xZ+MdFDWTAH+kcn7UxjEBoOKuaso7z1DRlnAnrknB1mTtNOQ+GdPI8xgExAGwHeqQjntR0Cg==",
|
"integrity": "sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -438,9 +438,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.0.tgz",
|
||||||
"integrity": "sha512-dmZseE0ZwA/4yy1+BwFrDqFTjjNg24GO9xSrb1weVbt6AFkhp5pz1gVS7IMtfIvoWy8yp6q/zN0bKnefRUImvQ==",
|
"integrity": "sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -451,9 +451,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.0.tgz",
|
||||||
"integrity": "sha512-fzhfn6p9Cfm3W8UrWKIa4l7Wfjs/KGdgaswMBBE3KY3Ta43jg2XsPrAtfezHpsRk0Nx+TFuS3hZk/To2N5kFPQ==",
|
"integrity": "sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -464,9 +464,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-vVDD+iPDPmJQ5nAQ5Tifq3ywdv60FartglFI8VOCK+hcU9aoG0qlQTsDJP97O5yiTaTqlneZWoARMcVC5nyUoQ==",
|
"integrity": "sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -477,9 +477,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-0d0jx08fzDHCzXqrtCMEEyxKU0SvJrWmUjUDE2/KDQ2UDJql0tfiwYvEx1oHELClKO8CNdE+AGJj+RqXscZpdQ==",
|
"integrity": "sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -490,9 +490,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-XBYu9oW9eKJadWn8M7hkTZsD4yG+RrsTrVEgyKwb4L72cpJjRbRboTG9Lg9fec8MxJp/cfTHAocg4mnismQR8A==",
|
"integrity": "sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@@ -503,9 +503,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-wJaRvcT17PoOK6Ggcfo3nouFlybHvARBS4jzT0PC/lg17fIJHcDS2fZz3sD+iA4nRlho2zE6OGbU0HvwATdokQ==",
|
"integrity": "sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -516,9 +516,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-GZ5bkMFteAGkcmh8x0Ok4LSa+L62Ez0tMsHPX6JtR0wl4Xc3bQcrFHDiR5DGLEDFtGrXih4Nd/UDaFqs968/wA==",
|
"integrity": "sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -529,9 +529,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-7CjPw6FflFsVOUfWOrVrREiV3IYXG4RzZ1ZQUaT3BtSK8YXN6x286o+sruPZJESIaPebYuFowmg54ZdrkVBYog==",
|
"integrity": "sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -542,9 +542,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-nmvnl0ZiuysltcB/cKjUh40Rx4FbSyueERDsl2FLvLYr6pCgSsvGr3SocUT84svSpmloS7f1DRWqtRha74Gi1w==",
|
"integrity": "sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -555,9 +555,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-Cv+moII5C8RM6gZbR3cb21o6rquVDZrN2o81maROg1LFzBz2dZUwIQSxFA8GtGZ/F2KtsqQ2z3eFPBb6akvQNg==",
|
"integrity": "sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -568,9 +568,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-PHcMG8DZTM9RCIjp8QIfN0VYtX0TtBPnWOTRurFhoCDoi9zptUZL2k7pCs+5rgut7JAiUsYy+huyhVKPcmxoog==",
|
"integrity": "sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -580,10 +580,23 @@
|
|||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||||
|
"version": "4.50.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.0.tgz",
|
||||||
|
"integrity": "sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-1SI/Rd47e8aQJeFWMDg16ET+fjvCcD/CzeaRmIEPmb05hx+3cCcwIF4ebUag4yTt/D1peE+Mgp0+Po3M358cAA==",
|
"integrity": "sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -594,9 +607,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-JwOCYxmumFDfDhx4kNyz6kTVK3gWzBIvVdMNzQMRDubcoGRDniOOmo6DDNP42qwZx3Bp9/6vWJ+kNzNqXoHmeA==",
|
"integrity": "sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -607,9 +620,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-IPMIfrfkG1GaEXi+JSsQEx8x9b4b+hRZXO7KYc2pKio3zO2/VDXDs6B9Ts/nnO+25Fk1tdAVtUn60HKKPPzDig==",
|
"integrity": "sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -799,9 +812,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.46.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.0.tgz",
|
||||||
"integrity": "sha512-ONmkT3Ud3IfW15nl7l4qAZko5/2iZ5ALVBDh02ZSZ5IGVLJSYkRcRa3iB58VyEIyoofs9m2xdVrm+lTi97+3pw==",
|
"integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.8"
|
"@types/estree": "1.0.8"
|
||||||
@@ -814,26 +827,27 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.46.0",
|
"@rollup/rollup-android-arm-eabi": "4.50.0",
|
||||||
"@rollup/rollup-android-arm64": "4.46.0",
|
"@rollup/rollup-android-arm64": "4.50.0",
|
||||||
"@rollup/rollup-darwin-arm64": "4.46.0",
|
"@rollup/rollup-darwin-arm64": "4.50.0",
|
||||||
"@rollup/rollup-darwin-x64": "4.46.0",
|
"@rollup/rollup-darwin-x64": "4.50.0",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.46.0",
|
"@rollup/rollup-freebsd-arm64": "4.50.0",
|
||||||
"@rollup/rollup-freebsd-x64": "4.46.0",
|
"@rollup/rollup-freebsd-x64": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.46.0",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.46.0",
|
"@rollup/rollup-linux-arm-musleabihf": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.46.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.46.0",
|
"@rollup/rollup-linux-arm64-musl": "4.50.0",
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": "4.46.0",
|
"@rollup/rollup-linux-loongarch64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-ppc64-gnu": "4.46.0",
|
"@rollup/rollup-linux-ppc64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.46.0",
|
"@rollup/rollup-linux-riscv64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.46.0",
|
"@rollup/rollup-linux-riscv64-musl": "4.50.0",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.46.0",
|
"@rollup/rollup-linux-s390x-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.46.0",
|
"@rollup/rollup-linux-x64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.46.0",
|
"@rollup/rollup-linux-x64-musl": "4.50.0",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.46.0",
|
"@rollup/rollup-openharmony-arm64": "4.50.0",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.46.0",
|
"@rollup/rollup-win32-arm64-msvc": "4.50.0",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.46.0",
|
"@rollup/rollup-win32-ia32-msvc": "4.50.0",
|
||||||
|
"@rollup/rollup-win32-x64-msvc": "4.50.0",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -915,14 +929,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.43.1",
|
"version": "5.44.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz",
|
||||||
"integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
|
"integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.14.0",
|
"acorn": "^8.15.0",
|
||||||
"commander": "^2.20.0",
|
"commander": "^2.20.0",
|
||||||
"source-map-support": "~0.5.20"
|
"source-map-support": "~0.5.20"
|
||||||
},
|
},
|
||||||
|
6
flake.lock
generated
6
flake.lock
generated
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1753749649,
|
"lastModified": 1756217674,
|
||||||
"narHash": "sha256-+jkEZxs7bfOKfBIk430K+tK9IvXlwzqQQnppC2ZKFj4=",
|
"narHash": "sha256-TH1SfSP523QI7kcPiNtMAEuwZR3Jdz0MCDXPs7TS8uo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1f08a4df998e21f4e8be8fb6fbf61d11a1a5076a",
|
"rev": "4e7667a90c167f7a81d906e5a75cba4ad8bee620",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
9
metadata/en-US/changelogs/42.txt
Normal file
9
metadata/en-US/changelogs/42.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
* Private messages interface overhaul in progress.
|
||||||
|
* Added a loading indicator.
|
||||||
|
* Documented the core JavaScript.
|
||||||
|
* Fixed @-completion.
|
||||||
|
* Covered up launch on Android with the splash screen.
|
||||||
|
* Update:
|
||||||
|
* CodeMirror
|
||||||
|
* OpenSSL 3.5.2
|
||||||
|
* speedscope 1.23.1
|
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.unprompted.tildefriends"
|
package="com.unprompted.tildefriends"
|
||||||
android:versionCode="41"
|
android:versionCode="43"
|
||||||
android:versionName="0.2025.8-wip">
|
android:versionName="0.2025.9-wip">
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<application
|
<application
|
||||||
|
@@ -19,12 +19,12 @@ import android.os.RemoteException;
|
|||||||
import android.os.StrictMode;
|
import android.os.StrictMode;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.DownloadListener;
|
import android.webkit.DownloadListener;
|
||||||
import android.webkit.JsPromptResult;
|
import android.webkit.JsPromptResult;
|
||||||
@@ -43,6 +43,7 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class TildeFriendsActivity extends Activity {
|
public class TildeFriendsActivity extends Activity {
|
||||||
@@ -52,28 +53,42 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
String port_file_path;
|
String port_file_path;
|
||||||
Thread create_thread;
|
Thread create_thread;
|
||||||
Thread server_thread;
|
Thread server_thread;
|
||||||
|
Thread log_thread;
|
||||||
ServiceConnection service_connection;
|
ServiceConnection service_connection;
|
||||||
FileObserver observer;
|
FileObserver observer;
|
||||||
|
LinkedBlockingQueue<String> log_queue = new LinkedBlockingQueue<String>();
|
||||||
|
|
||||||
private ValueCallback<Uri[]> upload_message;
|
private ValueCallback<Uri[]> upload_message;
|
||||||
private final static int FILECHOOSER_RESULT = 1;
|
private final static int FILECHOOSER_RESULT = 1;
|
||||||
private float touch_down_y;
|
private float touch_down_y;
|
||||||
|
private boolean ready = false;
|
||||||
|
private boolean loaded = false;
|
||||||
|
private boolean shutting_down = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Log.w("tildefriends", "Calling system.loadLibrary().");
|
log("Calling system.loadLibrary().");
|
||||||
System.loadLibrary("tildefriends");
|
System.loadLibrary("tildefriends");
|
||||||
Log.w("tildefriends", "system.loadLibrary() completed.");
|
log("system.loadLibrary() completed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native int tf_server_main(String files_dir, String apk_path, String out_port_file_path, ConnectivityManager connectivity_manager);
|
public static native int tf_server_main(String files_dir, String apk_path, String out_port_file_path, ConnectivityManager connectivity_manager);
|
||||||
public static native int tf_sandbox_main(int pipe_fd);
|
public static native int tf_sandbox_main(int pipe_fd);
|
||||||
|
|
||||||
|
public static void log(String message) {
|
||||||
|
if (s_activity != null && s_activity.log_queue != null && message != null) {
|
||||||
|
try {
|
||||||
|
s_activity.log_queue.put(message);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
android.util.Log.w("tildefriends", message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createThread() {
|
private void createThread() {
|
||||||
web_view = (TildeFriendsWebView)findViewById(R.id.web);
|
web_view = (TildeFriendsWebView)findViewById(R.id.web);
|
||||||
set_status("Extracting executable...");
|
log(String.format("getFilesDir() is %s", getFilesDir().toString()));
|
||||||
Log.w("tildefriends", String.format("getFilesDir() is %s", getFilesDir().toString()));
|
log(String.format("getPackageResourcePath() is %s", getPackageResourcePath().toString()));
|
||||||
Log.w("tildefriends", String.format("getPackageResourcePath() is %s", getPackageResourcePath().toString()));
|
log(String.format("nativeLibraryDir is %s", getApplicationInfo().nativeLibraryDir));
|
||||||
Log.w("tildefriends", String.format("nativeLibraryDir is %s", getApplicationInfo().nativeLibraryDir));
|
|
||||||
|
|
||||||
port_file_path = getFilesDir().toString() + "/port.txt";
|
port_file_path = getFilesDir().toString() + "/port.txt";
|
||||||
new File(port_file_path).delete();
|
new File(port_file_path).delete();
|
||||||
@@ -81,21 +96,20 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
|
|
||||||
TildeFriendsActivity activity = this;
|
TildeFriendsActivity activity = this;
|
||||||
|
|
||||||
set_status("Starting server...");
|
|
||||||
server_thread = new Thread(new Runnable() {
|
server_thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Log.w("tildefriends", "Watching for changes in: " + getFilesDir().toString());
|
log("Watching for changes in: " + getFilesDir().toString());
|
||||||
observer = make_file_observer(getFilesDir().toString(), port_file_path);
|
observer = make_file_observer(getFilesDir().toString(), port_file_path);
|
||||||
observer.startWatching();
|
observer.startWatching();
|
||||||
|
|
||||||
Log.w("tildefriends", "Calling tf_server_main.");
|
log("Calling tf_server_main.");
|
||||||
int result = tf_server_main(
|
int result = tf_server_main(
|
||||||
getFilesDir().toString(),
|
getFilesDir().toString(),
|
||||||
getPackageResourcePath().toString(),
|
getPackageResourcePath().toString(),
|
||||||
port_file_path,
|
port_file_path,
|
||||||
(ConnectivityManager)getApplicationContext().getSystemService(CONNECTIVITY_SERVICE));
|
(ConnectivityManager)getApplicationContext().getSystemService(CONNECTIVITY_SERVICE));
|
||||||
Log.w("tildefriends", "tf_server_main returned " + result + ".");
|
log("tf_server_main returned " + result + ".");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
server_thread.start();
|
server_thread.start();
|
||||||
@@ -109,17 +123,17 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
|
|
||||||
web_view.setDownloadListener(new DownloadListener() {
|
web_view.setDownloadListener(new DownloadListener() {
|
||||||
public void onDownloadStart(String url, String userAgent, String content_disposition, String mime_type, long content_length) {
|
public void onDownloadStart(String url, String userAgent, String content_disposition, String mime_type, long content_length) {
|
||||||
Log.w("tildefriends", "Let's download: " + url + " (" + content_disposition + ")");
|
log("Let's download: " + url + " (" + content_disposition + ")");
|
||||||
String file_name = URLUtil.guessFileName(url, content_disposition, mime_type);
|
String file_name = URLUtil.guessFileName(url, content_disposition, mime_type);
|
||||||
if (url.startsWith("data:") && url.indexOf(',') != -1) {
|
if (url.startsWith("data:") && url.indexOf(',') != -1) {
|
||||||
String b64 = url.substring(url.indexOf(',') + 1);
|
String b64 = url.substring(url.indexOf(',') + 1);
|
||||||
byte[] data = Base64.decode(b64, Base64.DEFAULT);
|
byte[] data = Base64.decode(b64, Base64.DEFAULT);
|
||||||
Log.w("tildefriends", "Downloaded " + data.length + " bytes.");
|
log("Downloaded " + data.length + " bytes.");
|
||||||
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
try (OutputStream stream = new FileOutputStream(new File(path, file_name))) {
|
try (OutputStream stream = new FileOutputStream(new File(path, file_name))) {
|
||||||
stream.write(data);
|
stream.write(data);
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
Log.w("tildefriends", "IOException: " + e.toString());
|
log("IOException: " + e.toString());
|
||||||
}
|
}
|
||||||
Toast.makeText(getApplicationContext(), "Downloaded File", Toast.LENGTH_LONG).show();
|
Toast.makeText(getApplicationContext(), "Downloaded File", Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
@@ -227,12 +241,13 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onConsoleMessage(android.webkit.ConsoleMessage consoleMessage) {
|
public boolean onConsoleMessage(android.webkit.ConsoleMessage consoleMessage) {
|
||||||
Log.d("tildefriends", consoleMessage.message() + " -- From line " + consoleMessage.lineNumber() + " of " + consoleMessage.sourceId());
|
log(consoleMessage.message() + " -- From line " + consoleMessage.lineNumber() + " of " + consoleMessage.sourceId());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
web_view.setWebViewClient(new WebViewClient() {
|
web_view.setWebViewClient(new WebViewClient() {
|
||||||
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
|
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
|
||||||
{
|
{
|
||||||
if (request.getUrl() != null && request.getUrl().toString().startsWith(base_url)) {
|
if (request.getUrl() != null && request.getUrl().toString().startsWith(base_url)) {
|
||||||
@@ -242,6 +257,11 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
s_activity.loaded = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -252,6 +272,23 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
s_activity = this;
|
s_activity = this;
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
log_thread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!s_activity.shutting_down) {
|
||||||
|
try {
|
||||||
|
String message = log_queue.take();
|
||||||
|
if (message != null) {
|
||||||
|
android.util.Log.w("tildefriends", message);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log_thread.start();
|
||||||
StrictMode.setThreadPolicy(
|
StrictMode.setThreadPolicy(
|
||||||
new StrictMode.ThreadPolicy.Builder()
|
new StrictMode.ThreadPolicy.Builder()
|
||||||
.detectAll()
|
.detectAll()
|
||||||
@@ -271,6 +308,21 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
refresh.setVisibility(View.GONE);
|
refresh.setVisibility(View.GONE);
|
||||||
refresh.setText("REFRESH");
|
refresh.setText("REFRESH");
|
||||||
|
|
||||||
|
final View content = findViewById(android.R.id.content);
|
||||||
|
content.getViewTreeObserver().addOnPreDrawListener(
|
||||||
|
new ViewTreeObserver.OnPreDrawListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreDraw() {
|
||||||
|
if (s_activity.ready && s_activity.loaded) {
|
||||||
|
content.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
create_thread = new Thread(new Runnable() {
|
create_thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -283,8 +335,17 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy()
|
protected void onDestroy()
|
||||||
{
|
{
|
||||||
super.onDestroy();
|
try {
|
||||||
|
shutting_down = true;
|
||||||
|
if (log_queue != null) {
|
||||||
|
log_queue.put("Goodbye.");
|
||||||
|
}
|
||||||
|
log_thread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
log_thread = null;
|
||||||
s_activity = null;
|
s_activity = null;
|
||||||
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -376,46 +437,33 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void set_status(String text) {
|
|
||||||
TextView text_view = (TextView)findViewById(R.id.text);
|
|
||||||
web_view.setVisibility(View.GONE);
|
|
||||||
text_view.setVisibility(View.VISIBLE);
|
|
||||||
text_view.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hide_status() {
|
|
||||||
TextView text_view = (TextView)findViewById(R.id.text);
|
|
||||||
web_view.setVisibility(View.VISIBLE);
|
|
||||||
text_view.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void start_sandbox(int pipe_fd) {
|
public static void start_sandbox(int pipe_fd) {
|
||||||
Log.w("tildefriends", "starting service with fd: " + pipe_fd);
|
log("starting service with fd: " + pipe_fd);
|
||||||
Intent intent = new Intent(s_activity, TildeFriendsSandboxService.class);
|
Intent intent = new Intent(s_activity, TildeFriendsSandboxService.class);
|
||||||
s_activity.service_connection = new ServiceConnection() {
|
s_activity.service_connection = new ServiceConnection() {
|
||||||
@Override
|
@Override
|
||||||
public void onBindingDied(ComponentName name) {
|
public void onBindingDied(ComponentName name) {
|
||||||
Log.w("tildefriends", "onBindingDied");
|
log("onBindingDied");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNullBinding(ComponentName name) {
|
public void onNullBinding(ComponentName name) {
|
||||||
Log.w("tildefriends", "onNullBinding");
|
log("onNullBinding");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder binder) {
|
public void onServiceConnected(ComponentName name, IBinder binder) {
|
||||||
Log.w("tildefriends", "onServiceConnected");
|
log("onServiceConnected");
|
||||||
Parcel data = Parcel.obtain();
|
Parcel data = Parcel.obtain();
|
||||||
try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(pipe_fd)) {
|
try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(pipe_fd)) {
|
||||||
data.writeParcelable(pfd, 0);
|
data.writeParcelable(pfd, 0);
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
Log.w("tildefriends", "IOException: " + e);
|
log("IOException: " + e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
binder.transact(TildeFriendsSandboxService.START_CALL, data, null, IBinder.FLAG_ONEWAY);
|
binder.transact(TildeFriendsSandboxService.START_CALL, data, null, IBinder.FLAG_ONEWAY);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w("tildefriends", "RemoteException");
|
log("RemoteException");
|
||||||
} finally {
|
} finally {
|
||||||
data.recycle();
|
data.recycle();
|
||||||
}
|
}
|
||||||
@@ -423,14 +471,14 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
Log.w("tildefriends", "onServiceDisconnected");
|
log("onServiceDisconnected");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
s_activity.bindService(intent, s_activity.service_connection, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND);
|
s_activity.bindService(intent, s_activity.service_connection, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void stop_sandbox() {
|
public static void stop_sandbox() {
|
||||||
Log.w("tildefriends", "stop_sandbox");
|
log("stop_sandbox");
|
||||||
if (s_activity.service_connection != null) {
|
if (s_activity.service_connection != null) {
|
||||||
s_activity.unbindService(s_activity.service_connection);
|
s_activity.unbindService(s_activity.service_connection);
|
||||||
s_activity.service_connection = null;
|
s_activity.service_connection = null;
|
||||||
@@ -442,15 +490,11 @@ public class TildeFriendsActivity extends Activity {
|
|||||||
if (port >= 0) {
|
if (port >= 0) {
|
||||||
base_url = "http://127.0.0.1:" + String.valueOf(port) + "/";
|
base_url = "http://127.0.0.1:" + String.valueOf(port) + "/";
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
hide_status();
|
ready = true;
|
||||||
web_view.loadUrl(base_url + "login/auto");
|
web_view.loadUrl(base_url + "login/auto");
|
||||||
});
|
});
|
||||||
observer.stopWatching();
|
observer.stopWatching();
|
||||||
observer = null;
|
observer = null;
|
||||||
} else {
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
set_status("Waiting to connect...");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ import android.os.Binder;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class TildeFriendsSandboxService extends Service {
|
public class TildeFriendsSandboxService extends Service {
|
||||||
public static final int START_CALL = IBinder.FIRST_CALL_TRANSACTION;
|
public static final int START_CALL = IBinder.FIRST_CALL_TRANSACTION;
|
||||||
@@ -14,12 +13,12 @@ public class TildeFriendsSandboxService extends Service {
|
|||||||
Thread thread;
|
Thread thread;
|
||||||
|
|
||||||
public int onStartCommand(Intent intent, int flags, int start_id) {
|
public int onStartCommand(Intent intent, int flags, int start_id) {
|
||||||
Log.w("tildefriends", "TildeFriendsSandboxService: onStartCommand");
|
TildeFriendsActivity.log("TildeFriendsSandboxService: onStartCommand");
|
||||||
return super.onStartCommand(intent, flags, start_id);
|
return super.onStartCommand(intent, flags, start_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.w("tildefriends", "TildeFriendsSandboxService: onDestroy");
|
TildeFriendsActivity.log("TildeFriendsSandboxService: onDestroy");
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,9 +26,9 @@ public class TildeFriendsSandboxService extends Service {
|
|||||||
thread = new Thread(new Runnable() {
|
thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Log.w("tildefriends", "Calling tf_sandbox_main.");
|
TildeFriendsActivity.log("Calling tf_sandbox_main.");
|
||||||
int result = TildeFriendsActivity.tf_sandbox_main(pipe_fd);
|
int result = TildeFriendsActivity.tf_sandbox_main(pipe_fd);
|
||||||
Log.w("tildefriends", "tf_sandbox_main returned " + result + ".");
|
TildeFriendsActivity.log("tf_sandbox_main returned " + result + ".");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
@@ -43,7 +42,7 @@ public class TildeFriendsSandboxService extends Service {
|
|||||||
if (code == START_CALL) {
|
if (code == START_CALL) {
|
||||||
ParcelFileDescriptor pfd = read_pfd(data);
|
ParcelFileDescriptor pfd = read_pfd(data);
|
||||||
if (pfd != null) {
|
if (pfd != null) {
|
||||||
Log.w("tildefriends", "fd is " + pfd.getFd());
|
TildeFriendsActivity.log("fd is " + pfd.getFd());
|
||||||
start_thread(pfd.detachFd());
|
start_thread(pfd.detachFd());
|
||||||
try {
|
try {
|
||||||
pfd.close();
|
pfd.close();
|
||||||
|
@@ -10,11 +10,6 @@
|
|||||||
android:id="@+id/web"
|
android:id="@+id/web"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
<TextView
|
|
||||||
android:id="@+id/text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_horizontal|center_vertical"/>
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/refresh"
|
android:id="@+id/refresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@@ -13,13 +13,13 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.2025.8</string>
|
<string>0.2025.9</string>
|
||||||
<key>CFBundleSupportedPlatforms</key>
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
<array>
|
<array>
|
||||||
<string>iPhoneOS</string>
|
<string>iPhoneOS</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>16</string>
|
<string>17</string>
|
||||||
<key>DTPlatformName</key>
|
<key>DTPlatformName</key>
|
||||||
<string>iphoneos</string>
|
<string>iphoneos</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
87
src/ssb.c
87
src/ssb.c
@@ -133,6 +133,15 @@ typedef struct _tf_ssb_message_added_callback_node_t
|
|||||||
tf_ssb_message_added_callback_node_t* next;
|
tf_ssb_message_added_callback_node_t* next;
|
||||||
} tf_ssb_message_added_callback_node_t;
|
} tf_ssb_message_added_callback_node_t;
|
||||||
|
|
||||||
|
typedef struct _tf_ssb_blob_stored_callback_node_t tf_ssb_blob_stored_callback_node_t;
|
||||||
|
typedef struct _tf_ssb_blob_stored_callback_node_t
|
||||||
|
{
|
||||||
|
tf_ssb_blob_stored_callback_t* callback;
|
||||||
|
tf_ssb_callback_cleanup_t* cleanup;
|
||||||
|
void* user_data;
|
||||||
|
tf_ssb_blob_stored_callback_node_t* next;
|
||||||
|
} tf_ssb_blob_stored_callback_node_t;
|
||||||
|
|
||||||
typedef struct _tf_ssb_blob_want_added_callback_node_t tf_ssb_blob_want_added_callback_node_t;
|
typedef struct _tf_ssb_blob_want_added_callback_node_t tf_ssb_blob_want_added_callback_node_t;
|
||||||
typedef struct _tf_ssb_blob_want_added_callback_node_t
|
typedef struct _tf_ssb_blob_want_added_callback_node_t
|
||||||
{
|
{
|
||||||
@@ -235,6 +244,9 @@ typedef struct _tf_ssb_t
|
|||||||
tf_ssb_message_added_callback_node_t* message_added;
|
tf_ssb_message_added_callback_node_t* message_added;
|
||||||
int message_added_count;
|
int message_added_count;
|
||||||
|
|
||||||
|
tf_ssb_blob_stored_callback_node_t* blob_stored;
|
||||||
|
int blob_stored_count;
|
||||||
|
|
||||||
tf_ssb_blob_want_added_callback_node_t* blob_want_added;
|
tf_ssb_blob_want_added_callback_node_t* blob_want_added;
|
||||||
int blob_want_added_count;
|
int blob_want_added_count;
|
||||||
|
|
||||||
@@ -2741,6 +2753,17 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
}
|
}
|
||||||
tf_free(node);
|
tf_free(node);
|
||||||
}
|
}
|
||||||
|
while (ssb->blob_stored)
|
||||||
|
{
|
||||||
|
tf_ssb_blob_stored_callback_node_t* node = ssb->blob_stored;
|
||||||
|
ssb->blob_stored = node->next;
|
||||||
|
ssb->blob_stored_count--;
|
||||||
|
if (node->cleanup)
|
||||||
|
{
|
||||||
|
node->cleanup(ssb, node->user_data);
|
||||||
|
}
|
||||||
|
tf_free(node);
|
||||||
|
}
|
||||||
while (ssb->blob_want_added)
|
while (ssb->blob_want_added)
|
||||||
{
|
{
|
||||||
tf_ssb_blob_want_added_callback_node_t* node = ssb->blob_want_added;
|
tf_ssb_blob_want_added_callback_node_t* node = ssb->blob_want_added;
|
||||||
@@ -2783,6 +2806,16 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
|
|
||||||
uv_run(ssb->loop, UV_RUN_NOWAIT);
|
uv_run(ssb->loop, UV_RUN_NOWAIT);
|
||||||
|
|
||||||
|
if (ssb->own_context)
|
||||||
|
{
|
||||||
|
if (!ssb->quiet)
|
||||||
|
{
|
||||||
|
tf_printf("closing ssb context\n");
|
||||||
|
}
|
||||||
|
JS_FreeContext(ssb->context);
|
||||||
|
JS_FreeRuntime(ssb->runtime);
|
||||||
|
ssb->own_context = false;
|
||||||
|
}
|
||||||
if (ssb->loop == &ssb->own_loop)
|
if (ssb->loop == &ssb->own_loop)
|
||||||
{
|
{
|
||||||
if (!ssb->quiet)
|
if (!ssb->quiet)
|
||||||
@@ -2799,16 +2832,6 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
{
|
{
|
||||||
tf_printf("uv loop closed.\n");
|
tf_printf("uv loop closed.\n");
|
||||||
}
|
}
|
||||||
if (ssb->own_context)
|
|
||||||
{
|
|
||||||
if (!ssb->quiet)
|
|
||||||
{
|
|
||||||
tf_printf("closing ssb context\n");
|
|
||||||
}
|
|
||||||
JS_FreeContext(ssb->context);
|
|
||||||
JS_FreeRuntime(ssb->runtime);
|
|
||||||
ssb->own_context = false;
|
|
||||||
}
|
|
||||||
while (ssb->broadcasts)
|
while (ssb->broadcasts)
|
||||||
{
|
{
|
||||||
tf_ssb_broadcast_t* broadcast = ssb->broadcasts;
|
tf_ssb_broadcast_t* broadcast = ssb->broadcasts;
|
||||||
@@ -3960,9 +3983,53 @@ void tf_ssb_remove_message_added_callback(tf_ssb_t* ssb, tf_ssb_message_added_ca
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tf_ssb_add_blob_stored_callback(tf_ssb_t* ssb, tf_ssb_blob_stored_callback_t* callback, void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||||
|
{
|
||||||
|
tf_ssb_blob_stored_callback_node_t* node = tf_malloc(sizeof(tf_ssb_blob_stored_callback_node_t));
|
||||||
|
*node = (tf_ssb_blob_stored_callback_node_t) {
|
||||||
|
.callback = callback,
|
||||||
|
.cleanup = cleanup,
|
||||||
|
.user_data = user_data,
|
||||||
|
.next = ssb->blob_stored,
|
||||||
|
};
|
||||||
|
ssb->blob_stored = node;
|
||||||
|
ssb->blob_stored_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_ssb_remove_blob_stored_callback(tf_ssb_t* ssb, tf_ssb_blob_stored_callback_t* callback, void* user_data)
|
||||||
|
{
|
||||||
|
tf_ssb_blob_stored_callback_node_t** it = &ssb->blob_stored;
|
||||||
|
while (*it)
|
||||||
|
{
|
||||||
|
if ((*it)->callback == callback && (*it)->user_data == user_data)
|
||||||
|
{
|
||||||
|
tf_ssb_blob_stored_callback_node_t* node = *it;
|
||||||
|
*it = node->next;
|
||||||
|
ssb->blob_stored_count--;
|
||||||
|
if (node->cleanup)
|
||||||
|
{
|
||||||
|
node->cleanup(ssb, node->user_data);
|
||||||
|
}
|
||||||
|
tf_free(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it = &(*it)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tf_ssb_notify_blob_stored(tf_ssb_t* ssb, const char* id)
|
void tf_ssb_notify_blob_stored(tf_ssb_t* ssb, const char* id)
|
||||||
{
|
{
|
||||||
|
tf_ssb_blob_stored_callback_node_t* next = NULL;
|
||||||
ssb->blobs_stored++;
|
ssb->blobs_stored++;
|
||||||
|
for (tf_ssb_blob_stored_callback_node_t* node = ssb->blob_stored; node; node = next)
|
||||||
|
{
|
||||||
|
next = node->next;
|
||||||
|
tf_trace_begin(ssb->trace, "blob stored callback");
|
||||||
|
node->callback(ssb, id, node->user_data);
|
||||||
|
tf_trace_end(ssb->trace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* author, int32_t sequence, const char* id, JSValue message_keys)
|
void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* author, int32_t sequence, const char* id, JSValue message_keys)
|
||||||
|
@@ -903,10 +903,6 @@ void tf_ssb_db_add_blob_wants(sqlite3* db, const char* id)
|
|||||||
{
|
{
|
||||||
tf_printf("blob wants cache update failed: %s.\n", sqlite3_errmsg(db));
|
tf_printf("blob wants cache update failed: %s.\n", sqlite3_errmsg(db));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
tf_printf("want: %s\n", id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sqlite3_finalize(statement);
|
sqlite3_finalize(statement);
|
||||||
}
|
}
|
||||||
|
25
src/ssb.h
25
src/ssb.h
@@ -680,6 +680,31 @@ void tf_ssb_remove_message_added_callback(tf_ssb_t* ssb, tf_ssb_message_added_ca
|
|||||||
*/
|
*/
|
||||||
void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* author, int32_t sequence, const char* id, JSValue message_with_keys);
|
void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* author, int32_t sequence, const char* id, JSValue message_with_keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** A callback called when a blob is added to the database.
|
||||||
|
** @param ssb The SSB instance.
|
||||||
|
** @param id The blob identifier.
|
||||||
|
** @param user_data The user data.
|
||||||
|
*/
|
||||||
|
typedef void(tf_ssb_blob_stored_callback_t)(tf_ssb_t* ssb, const char* id, void* user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Register a callback called when a blob is added to the database.
|
||||||
|
** @param ssb The SSB instance.
|
||||||
|
** @param callback The callback function.
|
||||||
|
** @param cleanup A function to call when the callback is removed.
|
||||||
|
** @param user_data User data to pass to the callback.
|
||||||
|
*/
|
||||||
|
void tf_ssb_add_blob_stored_callback(tf_ssb_t* ssb, tf_ssb_blob_stored_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Remove a callback registered for when a blob is added to the database.
|
||||||
|
** @param ssb The SSB instance.
|
||||||
|
** @param callback The callback function.
|
||||||
|
** @param user_data User data registered with the callback.
|
||||||
|
*/
|
||||||
|
void tf_ssb_remove_blob_stored_callback(tf_ssb_t* ssb, tf_ssb_blob_stored_callback_t* callback, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Record that a new blob was stored.
|
** Record that a new blob was stored.
|
||||||
** @param ssb The SSB instance.
|
** @param ssb The SSB instance.
|
||||||
|
24
src/ssb.js.c
24
src/ssb.js.c
@@ -1627,6 +1627,20 @@ static void _tf_ssb_on_message_added_callback(tf_ssb_t* ssb, const char* author,
|
|||||||
JS_FreeValue(context, string);
|
JS_FreeValue(context, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _tf_ssb_on_blob_stored_callback(tf_ssb_t* ssb, const char* id, void* user_data)
|
||||||
|
{
|
||||||
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
|
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
|
||||||
|
JSValue string = JS_NewString(context, id);
|
||||||
|
JSValue response = JS_Call(context, callback, JS_UNDEFINED, 1, &string);
|
||||||
|
if (tf_util_report_error(context, response))
|
||||||
|
{
|
||||||
|
tf_ssb_remove_blob_stored_callback(ssb, _tf_ssb_on_blob_stored_callback, user_data);
|
||||||
|
}
|
||||||
|
JS_FreeValue(context, response);
|
||||||
|
JS_FreeValue(context, string);
|
||||||
|
}
|
||||||
|
|
||||||
static void _tf_ssb_on_blob_want_added_callback(tf_ssb_t* ssb, const char* id, void* user_data)
|
static void _tf_ssb_on_blob_want_added_callback(tf_ssb_t* ssb, const char* id, void* user_data)
|
||||||
{
|
{
|
||||||
JSContext* context = tf_ssb_get_context(ssb);
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
@@ -1747,6 +1761,11 @@ static JSValue _tf_ssb_add_event_listener(JSContext* context, JSValueConst this_
|
|||||||
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
tf_ssb_add_message_added_callback(ssb, _tf_ssb_on_message_added_callback, _tf_ssb_cleanup_value, ptr);
|
tf_ssb_add_message_added_callback(ssb, _tf_ssb_on_message_added_callback, _tf_ssb_cleanup_value, ptr);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(event_name, "blob") == 0)
|
||||||
|
{
|
||||||
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
|
tf_ssb_add_blob_stored_callback(ssb, _tf_ssb_on_blob_stored_callback, _tf_ssb_cleanup_value, ptr);
|
||||||
|
}
|
||||||
else if (strcmp(event_name, "blob_want_added") == 0)
|
else if (strcmp(event_name, "blob_want_added") == 0)
|
||||||
{
|
{
|
||||||
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
@@ -1790,6 +1809,11 @@ static JSValue _tf_ssb_remove_event_listener(JSContext* context, JSValueConst th
|
|||||||
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
tf_ssb_remove_message_added_callback(ssb, _tf_ssb_on_message_added_callback, ptr);
|
tf_ssb_remove_message_added_callback(ssb, _tf_ssb_on_message_added_callback, ptr);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(event_name, "blob") == 0)
|
||||||
|
{
|
||||||
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
|
tf_ssb_remove_blob_stored_callback(ssb, _tf_ssb_on_blob_stored_callback, ptr);
|
||||||
|
}
|
||||||
else if (strcmp(event_name, "blob_want_added") == 0)
|
else if (strcmp(event_name, "blob_want_added") == 0)
|
||||||
{
|
{
|
||||||
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
void* ptr = JS_VALUE_GET_PTR(JS_DupValue(context, callback));
|
||||||
|
@@ -152,6 +152,12 @@ static void _wait_stored(tf_ssb_t* ssb, bool* stored)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _blob_stored(tf_ssb_t* ssb, const char* id, void* user_data)
|
||||||
|
{
|
||||||
|
tf_printf("blob stored %s\n", id);
|
||||||
|
*(bool*)user_data = true;
|
||||||
|
}
|
||||||
|
|
||||||
void tf_ssb_test_ssb(const tf_test_options_t* options)
|
void tf_ssb_test_ssb(const tf_test_options_t* options)
|
||||||
{
|
{
|
||||||
tf_printf("Testing SSB.\n");
|
tf_printf("Testing SSB.\n");
|
||||||
@@ -224,8 +230,13 @@ void tf_ssb_test_ssb(const tf_test_options_t* options)
|
|||||||
|
|
||||||
char blob_id[k_id_base64_len] = { 0 };
|
char blob_id[k_id_base64_len] = { 0 };
|
||||||
const char* k_blob = "Hello, blob!";
|
const char* k_blob = "Hello, blob!";
|
||||||
|
bool blob_stored = false;
|
||||||
|
tf_ssb_add_blob_stored_callback(ssb0, _blob_stored, NULL, &blob_stored);
|
||||||
b = tf_ssb_db_blob_store(ssb0, (const uint8_t*)k_blob, strlen(k_blob), blob_id, sizeof(blob_id), NULL);
|
b = tf_ssb_db_blob_store(ssb0, (const uint8_t*)k_blob, strlen(k_blob), blob_id, sizeof(blob_id), NULL);
|
||||||
|
tf_ssb_notify_blob_stored(ssb0, blob_id);
|
||||||
|
tf_ssb_remove_blob_stored_callback(ssb0, _blob_stored, &blob_stored);
|
||||||
assert(b);
|
assert(b);
|
||||||
|
assert(blob_stored);
|
||||||
|
|
||||||
JSContext* context0 = tf_ssb_get_context(ssb0);
|
JSContext* context0 = tf_ssb_get_context(ssb0);
|
||||||
JSValue obj = JS_NewObject(context0);
|
JSValue obj = JS_NewObject(context0);
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
#define VERSION_NUMBER "0.2025.8-wip"
|
#define VERSION_NUMBER "0.2025.9-wip"
|
||||||
#define VERSION_NAME "This program kills fascists."
|
#define VERSION_NAME "This program kills fascists."
|
||||||
|
@@ -93,7 +93,7 @@ try:
|
|||||||
select(driver, ['#document', 'frame', '#gs_room_name'], ('send_keys', 'test room'))
|
select(driver, ['#document', 'frame', '#gs_room_name'], ('send_keys', 'test room'))
|
||||||
select(driver, ['#document', 'frame', '//*[@id="gs_room_name"]/following-sibling::button'], ('click',))
|
select(driver, ['#document', 'frame', '//*[@id="gs_room_name"]/following-sibling::button'], ('click',))
|
||||||
select(driver, ['//button[text()="✅ Allow"]'], ('click',))
|
select(driver, ['//button[text()="✅ Allow"]'], ('click',))
|
||||||
driver.switch_to.alert.accept()
|
wait.until(expected_conditions.alert_is_present()).accept()
|
||||||
|
|
||||||
select(driver, ['tf-navigation', 'shadow_root', '#identity'], ('click',))
|
select(driver, ['tf-navigation', 'shadow_root', '#identity'], ('click',))
|
||||||
select(driver, ['tf-navigation', 'shadow_root', '#logout'], ('click',))
|
select(driver, ['tf-navigation', 'shadow_root', '#logout'], ('click',))
|
||||||
|
Reference in New Issue
Block a user