From df185b027a757604ac720858c2edffe2fb0c2155 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 14 Apr 2014 22:43:57 +0000 Subject: lt3graph (14apr14) git-svn-id: svn://tug.org/texlive/trunk@33439 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/lt3graph/lt3graph-dry.sty | 2 +- .../tex/latex/lt3graph/lt3graph-packagedoc.cls | 7 +- Master/texmf-dist/tex/latex/lt3graph/lt3graph.sty | 273 +++++++++++---------- 3 files changed, 141 insertions(+), 141 deletions(-) (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/latex/lt3graph/lt3graph-dry.sty b/Master/texmf-dist/tex/latex/lt3graph/lt3graph-dry.sty index d9b6cce119e..bcb21ea2e3d 100644 --- a/Master/texmf-dist/tex/latex/lt3graph/lt3graph-dry.sty +++ b/Master/texmf-dist/tex/latex/lt3graph/lt3graph-dry.sty @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \iffalse %%%% % % -% Copyright (c) 2013 - Michiel Helvensteijn (www.mhelvens.net) % +% Copyright (c) 2013 - Michiel Helvensteijn - www.mhelvens.net % % % % https://github.com/mhelvens/latex-lt3graph % % % diff --git a/Master/texmf-dist/tex/latex/lt3graph/lt3graph-packagedoc.cls b/Master/texmf-dist/tex/latex/lt3graph/lt3graph-packagedoc.cls index e792191b829..62b0ceeacdb 100644 --- a/Master/texmf-dist/tex/latex/lt3graph/lt3graph-packagedoc.cls +++ b/Master/texmf-dist/tex/latex/lt3graph/lt3graph-packagedoc.cls @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % -% Copyright (C) 2013 by Michiel Helvensteijn - www.mhelvens.net % +% Copyright (c) 2013 - Michiel Helvensteijn - www.mhelvens.net % % % % https://github.com/mhelvens/latex-lt3graph % % % @@ -29,15 +29,14 @@ % Importing The Main Package % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%\RequirePackage{\packagename} - -\RequirePackage[display]{\packagename} +\RequirePackage{\packagename} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Importing Other Packages % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{etoolbox} +\RequirePackage[table]{xcolor} \RequirePackage[xcolor]{mdframed} \RequirePackage{marginnote} \RequirePackage{listings} diff --git a/Master/texmf-dist/tex/latex/lt3graph/lt3graph.sty b/Master/texmf-dist/tex/latex/lt3graph/lt3graph.sty index 4c9b4fb6055..9306e0061bb 100644 --- a/Master/texmf-dist/tex/latex/lt3graph/lt3graph.sty +++ b/Master/texmf-dist/tex/latex/lt3graph/lt3graph.sty @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \iffalse %%%% % % -% Copyright (c) 2013 - Michiel Helvensteijn (www.mhelvens.net) % +% Copyright (c) 2013 - Michiel Helvensteijn - www.mhelvens.net % % % % https://github.com/mhelvens/latex-lt3graph % % % @@ -19,7 +19,7 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \fi %%%% -% \CheckSum{841} +% \CheckSum{845} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -48,7 +48,7 @@ % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\ProvidesExplPackage{lt3graph}{2013/12/05}{0.0.9-r1} +\ProvidesExplPackage{lt3graph}{2013/12/05}{0.0.9-r2} {a LaTeX3 datastructure for representing directed graphs with data} % \end{macrocode} % @@ -81,38 +81,6 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% We now test whether the |display| option was used: -% -% \begin{macrocode} -\bool_new:N \__graph_format_bool -\bool_set_false:N \__graph_format_bool - -\keys_define:nn {lt3graph} - { display .code:n = \bool_set_true:N \__graph_format_bool } - -\ProcessKeysPackageOptions {lt3graph} -% \end{macrocode} -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% If the |display| option was used, load additional packages: -% -% \begin{macrocode} -\bool_if:NT \__graph_format_bool { - \RequirePackage[table]{xcolor} -} -% \end{macrocode} -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Additions to \LaTeX3 Fundamentals} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -195,8 +163,8 @@ { \seq_map_inline:Nn \g__graph_prop_data_types_seq {#1} } \seq_new:N \g__graph_prop_data_types_seq \seq_set_from_clist:Nn \g__graph_prop_data_types_seq - {vertices, edge-values, edge-froms, edge-tos, edge-triples, - indegree, outdegree} + {vertices, edge-values, edge-froms, edge-tos, + edge-triples, indegree, outdegree} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,6 +198,13 @@ \tl_set:cn {##1} {#2} } } +\cs_new_protected:Nn \__graph_ptr_gnew:Nn { + \withargs [\uniquecsname] { + \tl_gset:Nn #1 {##1} + \tl_new:c {##1} + \tl_gset:cn {##1} {#2} + } +} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -368,7 +343,7 @@ { %%% create pointer to value % - \__graph_ptr_new:Nn \l__graph_vertex_data_tl {#3} + \use:c {__graph_ptr_#4new:Nn} \l__graph_vertex_data_tl {#3} %%% add the vertex % @@ -378,8 +353,8 @@ \graph_get_vertex:NnNT #1 {#2} \l_tmpa_tl { %%% initialize degree to 0 % - \use:c{prop_#4put:cnn} {\__graph_tl:nnn{graph}{#1}{indegree}} {#2}{0} - \use:c{prop_#4put:cnn} {\__graph_tl:nnn{graph}{#1}{outdegree}} {#2}{0} + \use:c{prop_#4put:cnn} {\__graph_tl:nnn{graph}{#1}{indegree}} {#2} {0} + \use:c{prop_#4put:cnn} {\__graph_tl:nnn{graph}{#1}{outdegree}} {#2} {0} } } \tl_new:N \l__graph_vertex_data_tl @@ -433,7 +408,7 @@ { \__graph_tl:nnn{graph}{#1}{edge-tos} } { \__graph_key:nn{#2}{#3} } { \tl_to_str:n{#3} } - \__graph_ptr_new:Nn \l__graph_edge_data_tl {#4} + \use:c{__graph_ptr_#5new:Nn} \l__graph_edge_data_tl {#4} \use:c{prop_#5put:coV} { \__graph_tl:nnn{graph}{#1}{edge-values} } { \__graph_key:nn{#2}{#3} } @@ -591,8 +566,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Test whether a vertex |#2| exists. If so, its value is -% stored in |#3| and |T| is left in the input stream. If it -% doesn't, |F| is left in the input stream. +% stored in |#3| and |T| is left in the input stream. If +% it doesn't, |F| is left in the input stream. % % \begin{macrocode} \prg_new_protected_conditional:Nnn \graph_get_vertex:NnN @@ -688,9 +663,9 @@ \cs_new:Npn \graph_if_vertex_can_reach_cycle:NnTF #1#2 { \__graph_if_vertex_can_reach_cycle:NnnTF #1 {#2} {\__graph_empty_set} } \cs_new:Npn \graph_if_vertex_can_reach_cycle:NnT #1#2 - { \__graph_if_vertex_can_reach_cycle:NnnT #1 {#2} {\__graph_empty_set} } + { \__graph_if_vertex_can_reach_cycle:NnnT #1 {#2} {\__graph_empty_set} } \cs_new:Npn \graph_if_vertex_can_reach_cycle:NnF #1#2 - { \__graph_if_vertex_can_reach_cycle:NnnF #1 {#2} {\__graph_empty_set} } + { \__graph_if_vertex_can_reach_cycle:NnnF #1 {#2} {\__graph_empty_set} } \prg_new_conditional:Nnn \__graph_if_vertex_can_reach_cycle:Nnn {p, T, F, TF} @@ -754,6 +729,41 @@ +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % Test whether graph |#1| contains any cycles: +% % +% % \begin{macrocode} +% \prg_new_protected_conditional:Nnn \graph_get_cycle:NN +% {T, F, TF} +% % #1: graph id +% % #2: l3seq variable to put the cycle description in +% { +% \seq_clear:N #2 +% \__graph_get_cycle:NNTF #1 #2 +% {\prg_return_true: } +% {\prg_return_false:} +% } +% +% \prg_new_protected_conditional:Nnn \__graph_get_cycle:NN +% {T, F, TF} +% % #1: graph id +% % #2: l3seq variable +% { +% \graph_map_successors_inline:Nnn #1 {} { +% \seq_if_in:NnTF #2 {##1} { +% % TODO +% }{ +% % TODO +% } +% } +% } +% % \end{macrocode} +% % +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Assume that graph |#1| is acyclic and test @@ -1302,22 +1312,25 @@ % % \begin{macrocode} \cs_new_protected:Nn \graph_map_topological_order_tokens:Nn { + %%% Fill \l__graph_source_vertices with source-nodes and count indegrees % \prop_clear:N \l__graph_source_vertices \graph_map_vertices_inline:Nn #1 { - \prop_put:Nnf \l__graph_tmp_indegrees_int {##1} - {\graph_get_indegree:Nn #1 {##1}} - \int_compare:nT {\graph_get_indegree:Nn #1 {##1} = 0} - { \prop_put:Nnn \l__graph_source_vertices {##1} {} } - } + \prop_put:Nnf \l__graph_tmp_indeg_int {##1} + { \graph_get_indegree:Nn #1 {##1} } + \int_compare:nT {\graph_get_indegree:Nn #1 {##1} = 0} { + \prop_put:Nnn \l__graph_source_vertices {##1} {} + } } %%% Main loop % \bool_until_do:nn {\prop_if_empty_p:N \l__graph_source_vertices} { %%% Choose any vertex (\l__graph_topo_key_tl, \l__graph_topo_value_tl) % - \__graph_prop_any_key_pop:NN \l__graph_source_vertices \l__graph_topo_key_tl + \__graph_prop_any_key_pop:NN + \l__graph_source_vertices + \l__graph_topo_key_tl \graph_get_vertex:NVNT #1 \l__graph_topo_key_tl \l__graph_topo_val_tl { %%% Run the mapping funtion on the key and value from that vertex % @@ -1328,29 +1341,25 @@ %%% and add all now-empty vertices to \l__graph_source_vertices % \graph_map_outgoing_edges_inline:NVn #1 \l__graph_topo_key_tl { - \prop_put:Nnf \l__graph_tmp_indegrees_int {##2} - {\int_eval:n {\prop_get:Nn \l__graph_tmp_indegrees_int {##2} - 1}} - \int_compare:nT {\prop_get:Nn \l__graph_tmp_indegrees_int {##2} = 0} { + \prop_put:Nnf \l__graph_tmp_indeg_int {##2} + {\int_eval:n {\prop_get:Nn \l__graph_tmp_indeg_int {##2} - 1}} + \int_compare:nT {\prop_get:Nn \l__graph_tmp_indeg_int {##2} = 0} { \prop_put:Nnn \l__graph_source_vertices {##2} {} - } - } - } - } -} +} } } } } \cs_new_protected:Nn \__graph_prop_any_key_pop:NN { \prop_map_inline:Nn #1 { \tl_set:Nn #2 {##1} \prop_remove:Nn #1 {##1} - \prop_map_break:n {\use_none:n} + \prop_map_break:n {\use_none:nnn} } - { \tl_set:Nn #2 {\q_no_value} } + \tl_set:Nn #2 {\q_no_value} % TODO: test } \cs_generate_variant:Nn \withargs:nnn {VVn} \cs_generate_variant:Nn \graph_map_outgoing_edges_inline:Nnn {NVn} \cs_generate_variant:Nn \prop_put:Nnn {Nnf} \cs_generate_variant:Nn \graph_get_vertex:NnNT {NVNT} \prop_new:N \l__graph_source_vertices -\prop_new:N \l__graph_tmp_indegrees_int +\prop_new:N \l__graph_tmp_indeg_int \tl_new:N \l__graph_topo_key_tl \tl_new:N \l__graph_topo_val_tl % \end{macrocode} @@ -1367,8 +1376,9 @@ % Assumes that the graph is acyclic (for now). % % \begin{macrocode} -\cs_new:Nn \graph_map_topological_order_function:NN - { \graph_map_topological_order_tokens:Nn #1 {#2} } +\cs_new:Nn \graph_map_topological_order_function:NN { + \graph_map_topological_order_tokens:Nn #1 {#2} +} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1387,8 +1397,7 @@ \withargs (c) [\uniquecsname] [#2] { \cs_set:Npn ##1 ####1####2 {##2} \graph_map_topological_order_function:NN #1 ##1 - } -} +} } % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1406,49 +1415,49 @@ % Set graph |#1| to the transitive closure of graph |#2|. % % \begin{macrocode} -\cs_new_protected:Nn \graph_set_transitive_closure:NN - { \__graph_set_transitive_closure:NNNnn #1 #2 \use_none:nnn {} { } } -\cs_new_protected:Nn \graph_gset_transitive_closure:NN - { \__graph_set_transitive_closure:NNNnn #1 #2 \use_none:nnn {} {g} } -\cs_new_protected:Nn \graph_set_transitive_closure:NNNn - { \__graph_set_transitive_closure:NNNnn #1 #2 #3 {#4} { } } -\cs_new_protected:Nn \graph_gset_transitive_closure:NNNn - { \__graph_set_transitive_closure:NNNnn #1 #2 #3 {#4} {g} } -\cs_new_protected:Nn \__graph_set_transitive_closure:NNNnn +\cs_new_protected:Nn \graph_set_transitive_closure:NN { + \__graph_set_transitive_closure:NNNnn #1 #2 \use_none:nnn {} { } +} +\cs_new_protected:Nn \graph_gset_transitive_closure:NN { + \__graph_set_transitive_closure:NNNnn #1 #2 \use_none:nnn {} {g} +} +\cs_new_protected:Nn \graph_set_transitive_closure:NNNn { + \__graph_set_transitive_closure:NNNnn #1 #2 #3 {#4} { } +} +\cs_new_protected:Nn \graph_gset_transitive_closure:NNNn { + \__graph_set_transitive_closure:NNNnn #1 #2 #3 {#4} {g} +} +\cs_new_protected:Nn \__graph_set_transitive_closure:NNNnn { % #1: target % #2: source % #3: combination function with argspec :nnn % #4: default 'old' value - { - \use:c{graph_#5set_eq:NN} #1 #2 - - \cs_set:Nn \__graph_edge_combinator:nnn - { \exp_not:n { #3 {##1} {##2} {##3} } } - \cs_generate_variant:Nn \__graph_edge_combinator:nnn {VVV} - + \use:c{graph_#5set_eq:NN} #1 #2 + + \cs_set:Nn \__graph_edge_combinator:nnn { + \exp_not:n { #3 {##1} {##2} {##3} } } + \cs_generate_variant:Nn \__graph_edge_combinator:nnn {VVV} + + \graph_map_vertices_inline:Nn #2 { \graph_map_vertices_inline:Nn #2 { - \graph_map_vertices_inline:Nn #2 { - \graph_get_edge:NnnNT #2 {##1} {####1} \l__graph_edge_value_i_tl { - \graph_map_vertices_inline:Nn #2 { - \graph_get_edge:NnnNT #2 {####1} {########1} - \l__graph_edge_value_ii_tl { - \graph_get_edge:NnnNF #1 {##1} {########1} - \l__graph_edge_value_old_tl - { \tl_set:Nn \l__graph_edge_value_old_tl {#4} } - \exp_args:NNx \tl_set:No \l__graph_edge_value_new_tl { - \__graph_edge_combinator:VVV - \l__graph_edge_value_i_tl - \l__graph_edge_value_ii_tl - \l__graph_edge_value_old_tl - } - \use:c{graph_#5put_edge:NnnV} #1 {##1} {########1} - \l__graph_edge_value_new_tl + \graph_get_edge:NnnNT #2 {##1} {####1} + \l__graph_edge_value_i_tl { + \graph_map_vertices_inline:Nn #2 { + \graph_get_edge:NnnNT #2 {####1} {########1} + \l__graph_edge_value_ii_tl { + \graph_get_edge:NnnNF #1 {##1} {########1} + \l__graph_edge_value_old_tl { + \tl_set:Nn \l__graph_edge_value_old_tl {#4} } - } - } - } - } - } + \exp_args:NNx \tl_set:No \l__graph_edge_value_new_tl { + \__graph_edge_combinator:VVV + \l__graph_edge_value_i_tl + \l__graph_edge_value_ii_tl + \l__graph_edge_value_old_tl + } + \use:c{graph_#5put_edge:NnnV} #1 {##1} {########1} + \l__graph_edge_value_new_tl +} } } } } } \cs_generate_variant:Nn \graph_put_edge:Nnnn {NnnV} \cs_generate_variant:Nn \graph_gput_edge:Nnnn {NnnV} \cs_generate_variant:Nn \tl_to_str:n {o} @@ -1464,30 +1473,26 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% Assume that graph |#2| contains no cycles, and set graph |#1| to its transitive reduction. +% Assume that graph |#2| contains no cycles, and +% set graph |#1| to its transitive reduction. % % \begin{macrocode} -\cs_new_protected:Nn \graph_set_transitive_reduction:NN - { \__graph_set_transitive_reduction:NNn #1 #2 { } } -\cs_new_protected:Nn \graph_gset_transitive_reduction:NN - { \__graph_set_transitive_reduction:NNn #1 #2 {g} } -\cs_new_protected:Nn \__graph_set_transitive_reduction:NNn +\cs_new_protected:Nn \graph_set_transitive_reduction:NN { + \__graph_set_transitive_reduction:NNn #1 #2 { } } +\cs_new_protected:Nn \graph_gset_transitive_reduction:NN { + \__graph_set_transitive_reduction:NNn #1 #2 {g} } +\cs_new_protected:Nn \__graph_set_transitive_reduction:NNn { % #1: target % #2: source - { - \use:c{graph_#3set_eq:NN} #1 #2 + \use:c{graph_#3set_eq:NN} #1 #2 + \graph_map_vertices_inline:Nn #2 { \graph_map_vertices_inline:Nn #2 { - \graph_map_vertices_inline:Nn #2 { - \graph_get_edge:NnnNT #2 {##1} {####1} \l_tmpa_tl { - \graph_map_vertices_inline:Nn #2 { - \graph_get_edge:NnnNT #2 {####1} {########1} \l_tmpa_tl { - \use:c{graph_#3remove_edge:Nnn} #1 {##1} {########1} - } - } - } - } - } - } + \graph_get_edge:NnnNT #2 {##1} {####1} \l_tmpa_tl { + \graph_map_vertices_inline:Nn #2 { + \graph_get_edge:NnnNT #2 {####1} {########1} \l_tmpa_tl { + \use:c{graph_#3remove_edge:Nnn} #1 {##1} {########1} + } } } } } +} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1502,23 +1507,21 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% If the |display| option was given, we define some additional +% We define some additional % functions that can display the graph in table-form. -% -% \begin{macrocode} -\bool_if:NT \__graph_format_bool { -% \end{macrocode} -% % This is the option-less version, which delegates -% to the full version of the function: +% to the full version: % % \begin{macrocode} -\cs_new_protected:Nn \graph_display_table:N - { \graph_display_table:Nn #1 {} } +\cs_new_protected:Nn \graph_display_table:N { + \graph_display_table:Nn #1 {} } % \end{macrocode} % % The full version has a second argument accepting options -% that determine table formatting. We first define those options: +% that determine table formatting. We first define those options. +% Please note that with the standard options, the |xcolor| package +% is required with the |table| option, because of our use of the +% |\cellcolor| command. % % \begin{macrocode} \keys_define:nn {lt3graph-display} { @@ -1667,7 +1670,8 @@ % We are finished with this row; go on to the next iteration: % % \begin{macrocode} - \tl_put_right:Nx \l__graph_table_content_tl { \seq_use:Nn \l__graph_row_seq {&} } + \tl_put_right:Nx \l__graph_table_content_tl + { \seq_use:Nn \l__graph_row_seq {&} } \tl_put_right:Nn \l__graph_table_content_tl {\\\hline} % \end{macrocode} % \uninteresting\begin{macrocode} @@ -1697,9 +1701,6 @@ \bool_new:N \l__graph_table_skipfirst_bool \seq_new:N \l__graph_row_seq % \end{macrocode} -% \uninteresting\begin{macrocode} -} -% \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3