fix different meta glitches
This commit is contained in:
parent
0ee5c2c526
commit
35b05b785e
@ -1,13 +1,46 @@
|
||||
#!/bin/bash
|
||||
echo "Validating inx files with xmllint. Only errors are printed to console"
|
||||
for folder in */ ; do xmllint --noout --relaxng ./inkscape.extension.rng $folder*.inx > /dev/null 2>> 000_xmllint.out; done; grep -v "validates\|warning: failed to load external entity" 000_xmllint.out; rm 000_xmllint.out
|
||||
clear
|
||||
|
||||
echo "--> Validating inx files with xmllint. Only errors are printed to console"
|
||||
for folder in */ ; do
|
||||
xmllint --noout --relaxng ./inkscape.extension.rng ${folder}*.inx > /dev/null 2>> 000_xmllint.out
|
||||
done
|
||||
grep -v "validates\|warning: failed to load external entity" 000_xmllint.out; rm 000_xmllint.out
|
||||
|
||||
echo "Count of inx files:"
|
||||
#complete set of meta information
|
||||
AGGLOMERATED_JSON=""
|
||||
for folder in */ ; do
|
||||
if [[ ! -f "${folder}/meta.json" ]]; then
|
||||
echo "meta.json missing for ${folder}"
|
||||
else
|
||||
echo ${AGGLOMERATED_JSON} > /tmp/prevJson
|
||||
AGGLOMERATED_JSON=$(jq -s ".[0] + .[1]" /tmp/prevJson ${folder}/meta.json)
|
||||
|
||||
#DEBUG
|
||||
#cat ${folder}/meta.json | jq
|
||||
fi
|
||||
done
|
||||
#print overall json
|
||||
#echo $AGGLOMERATED_JSON | jq
|
||||
|
||||
echo "--> Show unique license kinds used:"
|
||||
echo $AGGLOMERATED_JSON | jq -r '.[]|{license}|.[]' | sort | uniq -c
|
||||
|
||||
echo "--> show unique list of involved contributors (thanks/credits):"
|
||||
#echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq -c
|
||||
echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq
|
||||
|
||||
#show extensions which are in gallery
|
||||
GALLERY_EXTENSIONS=$(echo $AGGLOMERATED_JSON | jq -r '.[]|{inkscape_gallery_url}|.[]' | sort | grep -v "null")
|
||||
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
||||
EXTENSION=$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{name}|.[]')
|
||||
done
|
||||
|
||||
echo "--> Count of inx files:"
|
||||
INX=$(find ./ -type f -name "*.inx" | wc -l)
|
||||
echo INX: $INX
|
||||
|
||||
echo "Count of extension folders:"
|
||||
echo "--> Count of extension folders:"
|
||||
FOLDERS=$(ls -d */ | wc -l)
|
||||
echo FOLDERS: $FOLDERS
|
||||
|
||||
@ -24,40 +57,21 @@ echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Building Inkscape gallery extension zip files"
|
||||
TARGETDIR="../000_Inkscape_Gallery"
|
||||
mkdir -p $TARGETDIR > /dev/null
|
||||
|
||||
#list of extensions which are uploaded at Inkscape gallery by us at the moment
|
||||
for EXTENSION in \
|
||||
"animate_order" \
|
||||
"cleanup_styles" \
|
||||
"contour_scanner_and_trimmer" \
|
||||
"convert_to_polylines" \
|
||||
"create_links" \
|
||||
"dxf2papercraft" \
|
||||
"dxf_dwg_importer" \
|
||||
"imagetracerjs" \
|
||||
"inventory_sticker" \
|
||||
"move_path_node" \
|
||||
"remove_empty_groups" \
|
||||
"offset_paths" \
|
||||
"papercraft_unfold" \
|
||||
"paperfold" \
|
||||
"primitive" \
|
||||
"slic3r_stl_input" \
|
||||
"split_and_break_bezier_at_t" \
|
||||
"styles_to_layers" \
|
||||
"ungrouper_and_element_migrator_filter" \
|
||||
"unwind_paths" \
|
||||
"vpypetools"
|
||||
do
|
||||
mkdir -p $TARGETDIR > /dev/null 2>&1
|
||||
|
||||
#show extensions which are in gallery
|
||||
GALLERY_EXTENSIONS=$(echo $AGGLOMERATED_JSON | jq -r '.[]|{inkscape_gallery_url}|.[]' | sort | grep -v "null")
|
||||
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
||||
EXTENSION="$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{path}|.[]')"
|
||||
EXTRA=""
|
||||
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||
EXTRA="${EXTRA} apply_transformations/"
|
||||
elif [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||
EXTRA="${EXTRA} remove_empty_groups/"
|
||||
fi
|
||||
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
||||
rm $ZIPFILE > /dev/null
|
||||
elif [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||
EXTRA="${EXTRA} remove_empty_groups/"
|
||||
fi
|
||||
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
||||
rm $ZIPFILE > /dev/null 2>&1
|
||||
echo "--> creating $ZIPFILE"
|
||||
zip -r $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
20
extensions/fablabchemnitz/ellipse_by_five_points/meta.json
Normal file
20
extensions/fablabchemnitz/ellipse_by_five_points/meta.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "Ellipse By Five Points",
|
||||
"id": "fablabchemnitz.de.ellipse_by_five_points",
|
||||
"path": "ellipse_by_five_points",
|
||||
"original_name": "Ellipse by 5 Points",
|
||||
"original_id": "org.pernsteiner.inkscape.ellipse_5pts",
|
||||
"license": "BSD-2-Clause License",
|
||||
"license_url": "http://www.pernsteiner.org/inkscape/ellipse_5pts/inkscape-ellipse_5pts-0.1.1.zip",
|
||||
"comment": "bugfixed and ported to Inkscape v1 manually by Mario Voigt",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/ellipse_by_five_points",
|
||||
"fork_url": "http://www.pernsteiner.org/inkscape/ellipse_5pts/",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Ellipse+by+Five+Points",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"pernsteiner.org/Stuart Pernsteiner",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
20
extensions/fablabchemnitz/hex_tiles/meta.json
Normal file
20
extensions/fablabchemnitz/hex_tiles/meta.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "Hex Tiles",
|
||||
"id": "fablabchemnitz.de.hex_tiles",
|
||||
"path": "hex_tiles",
|
||||
"original_name": "Hex tiles",
|
||||
"original_id": "phillips.effect.hexlayoutguides",
|
||||
"license": "GNU GPL v2",
|
||||
"license_url": "https://sourceforge.net/p/razorfoss/svn/HEAD/tree/trunk/Inkscape/LayoutGuides/HexLayoutGuides.py",
|
||||
"comment": "",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/hex_tiles",
|
||||
"fork_url": "https://sourceforge.net/p/razorfoss/svn/HEAD/tree/trunk/Inkscape/LayoutGuides/",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Hex+Tiles",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"Luke Phillips:lukerazor@hotmail.com",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
@ -2,31 +2,40 @@
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Ids To Text</name>
|
||||
<id>fablabchemnitz.de.ids_to_text</id>
|
||||
<param name="path_attribute" appearance="combo" gui-text="Path attribute to show:" type="optiongroup">
|
||||
<option value="id">Id</option>
|
||||
<option value="label">Label</option>
|
||||
<option value="fill">Fill color</option>
|
||||
<option value="stroke">Stroke color</option>
|
||||
<option value="width">Width</option>
|
||||
<option value="height">Height</option>
|
||||
</param>
|
||||
<param name="fontsize" type="int" min="1" max="1000" gui-text="Font size (px):">10</param>
|
||||
<param name="color" type="color" appearance="colorbutton" gui-text="Color (in hex)">255</param>
|
||||
<param name="font" type="string" gui-text="Font">Roboto</param>
|
||||
<param name="fontweight" appearance="combo" gui-text="Font Weight" type="optiongroup">
|
||||
<param name="color" type="color" appearance="colorbutton" gui-text="Text color:">255</param>
|
||||
<param name="font" type="string" gui-text="Font:">Roboto</param>
|
||||
<param name="fontweight" appearance="combo" gui-text="Font weight:" type="optiongroup">
|
||||
<option value="light">Light</option>
|
||||
<option value="normal">Normal</option>
|
||||
<option value="italic">Italic</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="bold">Bold</option>
|
||||
</param>
|
||||
<param name="replaced" type="string" gui-text="Text to replace:"/>
|
||||
<param name="replacewith" type="string" gui-text="Replace with:"/>
|
||||
<param name="replaced" type="string" gui-text="Text to replace:" />
|
||||
<param name="replacewith" type="string" gui-text="Replace with:" />
|
||||
<param name="matchre" type="string" gui-text="Match regular expression:" />
|
||||
<param name="angle" type="float" min="-360" max="360" gui-text="Angle (°):">0</param>
|
||||
<param name="capitals" type="bool" gui-text="Capitalize all text">false</param>
|
||||
<param name="group" type="bool" gui-text="Group paths with the generated text elements">false</param>
|
||||
<label appearance="header">Help</label>
|
||||
<label>A simple Inkscape extension that lets you extract the ids from all selected paths and show them as elements inside the paths.
|
||||
Useful for when you want to have all paths' ids shown on the SVG document as text nodes.
|
||||
<label>Lets you extract the ids (or other attributes) from all selected paths and show them as text elements inside the paths.
|
||||
Examples and more info:</label>
|
||||
<label appearance="url">https://github.com/whiplashoo/ids_to_text_inkscape</label>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Various"/>
|
||||
</submenu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Various"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
|
@ -16,36 +16,87 @@ class IdsToText(inkex.EffectExtension):
|
||||
pars.add_argument('--replacewith', default = '', help = 'Replace with this text')
|
||||
pars.add_argument('--angle', type = float, dest = 'angle', default = 0, help = 'Rotation angle')
|
||||
pars.add_argument('--capitals', type = inkex.Boolean, default = False, help = 'Capitalize')
|
||||
pars.add_argument('--path_attribute', default='id', help='Path attribute to show')
|
||||
pars.add_argument('--matchre', default='', help='Match regular expression')
|
||||
pars.add_argument('--group', type=inkex.Boolean, default=False, help='Group paths with generated text elements')
|
||||
|
||||
def extract_path_attribute(self, attr, node):
|
||||
ret = ''
|
||||
if attr == 'id':
|
||||
ret = node.get(attr)
|
||||
elif attr == 'label':
|
||||
value = node.get(attr)
|
||||
ret = str(value) if value else (node.get("inkscape:label") or "")
|
||||
elif attr == 'width':
|
||||
ret = format(node.bounding_box().width, '.2f')
|
||||
elif attr == 'height':
|
||||
ret = format(node.bounding_box().height, '.2f')
|
||||
elif attr == 'fill' or attr == 'stroke':
|
||||
if 'style' in node.attrib:
|
||||
style = node.attrib.get('style')
|
||||
style = dict(inkex.styles.Style.parse_str(style))
|
||||
if attr in style:
|
||||
ret = style.get(attr)
|
||||
elif attr in node.attrib:
|
||||
ret = node.attrib.get(attr)
|
||||
return ret
|
||||
|
||||
def effect(self):
|
||||
if len(self.svg.selected) == 0:
|
||||
if len(self.svg.selection.filter(inkex.PathElement)) == 0:
|
||||
inkex.errormsg("Please select some paths first.")
|
||||
exit()
|
||||
|
||||
for id, node in self.svg.selected.items():
|
||||
id = node.get('id')
|
||||
self.group = node.getparent().add(TextElement())
|
||||
csp = node.path.transform(node.composed_transform()).to_superpath()
|
||||
path_attribute = self.options.path_attribute
|
||||
is_text_attribute = path_attribute in ['id', 'label']
|
||||
for id, node in self.svg.selection.filter(inkex.PathElement).items():
|
||||
to_show = self.extract_path_attribute(path_attribute, node)
|
||||
|
||||
node.path.transform(node.composed_transform()).to_superpath()
|
||||
bbox = node.bounding_box()
|
||||
tx, ty = bbox.center
|
||||
anchor = 'middle'
|
||||
|
||||
node = self.group
|
||||
new = node.add(Tspan())
|
||||
new.set('sodipodi:role', 'line')
|
||||
s = {'text-align': 'center', 'vertical-align': 'bottom',
|
||||
'text-anchor': 'middle', 'font-size': str(self.options.fontsize) + 'px',
|
||||
'font-weight': self.options.fontweight, 'font-style': 'normal', 'font-family': self.options.font, 'fill': str(self.options.color)}
|
||||
new.set('style', str(inkex.Style(s)))
|
||||
new.set('dy', '0')
|
||||
if self.options.group:
|
||||
group_element = node.getparent().add(inkex.Group())
|
||||
group_element.add(node)
|
||||
group_element.set('id', node.get('id') + "_group")
|
||||
text_element = group_element.add(inkex.TextElement())
|
||||
else:
|
||||
text_element = node.getparent().add(inkex.TextElement())
|
||||
|
||||
if self.options.capitals:
|
||||
id = id.upper()
|
||||
tspan_element = text_element.add(inkex.Tspan())
|
||||
tspan_element.set('sodipodi:role', 'line')
|
||||
styles = {'text-align': 'center',
|
||||
'vertical-align': 'bottom',
|
||||
'text-anchor': 'middle',
|
||||
'font-size': str(self.options.fontsize) + 'px',
|
||||
'font-weight': self.options.fontweight,
|
||||
'font-style': 'normal',
|
||||
'font-family': self.options.font,
|
||||
'fill': str(self.options.color)
|
||||
}
|
||||
tspan_element.set('style', str(inkex.Style(styles)))
|
||||
tspan_element.set('dy', '0')
|
||||
|
||||
new.text = id.replace(self.options.replaced, self.options.replacewith)
|
||||
node.set('x', str(tx))
|
||||
node.set('y', str(ty))
|
||||
node.set('transform', 'rotate(%s, %s, %s)' % (-int(self.options.angle), tx, ty))
|
||||
if is_text_attribute:
|
||||
if self.options.capitals:
|
||||
to_show = to_show.upper()
|
||||
|
||||
if self.options.matchre != '':
|
||||
matches = re.findall(self.options.matchre, to_show)
|
||||
if len(matches) > 0:
|
||||
to_show = matches[0]
|
||||
|
||||
if self.options.replaced != '':
|
||||
to_show = to_show.replace(
|
||||
self.options.replaced, self.options.replacewith)
|
||||
|
||||
tspan_element.text = to_show
|
||||
tspan_element.set('id', node.get('id') + "_tspan")
|
||||
text_element.set('id', node.get('id') + "_text")
|
||||
text_element.set('x', str(tx))
|
||||
text_element.set('y', str(ty))
|
||||
text_element.set('transform', 'rotate(%s, %s, %s)' %
|
||||
(-int(self.options.angle), tx, ty))
|
||||
|
||||
if __name__ == '__main__':
|
||||
IdsToText().run()
|
20
extensions/fablabchemnitz/ids_to_text/meta.json
Normal file
20
extensions/fablabchemnitz/ids_to_text/meta.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "Ids To Text",
|
||||
"id": "fablabchemnitz.de.ids_to_text",
|
||||
"path": "ids_to_text",
|
||||
"original_name": "Ids To Text",
|
||||
"original_id": "org.inkscape.render.ids_to_text",
|
||||
"license": "GNU GPL v3",
|
||||
"license_url": "https://github.com/whiplashoo/ids_to_text_inkscape/blob/master/LICENSE",
|
||||
"comment": "",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/ids_to_text",
|
||||
"fork_url": "https://github.com/whiplashoo/ids_to_text_inkscape",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Ids+To+Text",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"github.com/whiplashoo",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
20
extensions/fablabchemnitz/ifs_fractals/meta.json
Normal file
20
extensions/fablabchemnitz/ifs_fractals/meta.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "IFS Fractals",
|
||||
"id": "fablabchemnitz.de.ifs_fractals",
|
||||
"path": "ifs_fractals",
|
||||
"original_name": "IFS",
|
||||
"original_id": "org.inkscape.filter.ifs",
|
||||
"license": "GNU GPL v2",
|
||||
"license_url": "https://github.com/dylex/inkscape-ifs/blob/master/ifs.py",
|
||||
"comment": "",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/ifs_fractals",
|
||||
"fork_url": "https://github.com/dylex/inkscape-ifs",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/IFS+Fractals",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"github.com/dylex",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
@ -13,8 +13,8 @@
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Inset+Alignment",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"lukerazor@hotmail.com",
|
||||
"Luke Phillips:lukerazor@hotmail.com",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -5,7 +5,7 @@
|
||||
"path": "layer_clip",
|
||||
"original_name": "<various>",
|
||||
"original_id": "org.pernsteiner.inkscape.layerclip.<various>",
|
||||
"license": "MIT License",
|
||||
"license": "BSD-2-Clause License",
|
||||
"license_url": "https://gitlab.com/jczapla79/inkscape-extension-layer-clip/-/blob/master/clip.py",
|
||||
"comment": "Fixed and ported to Inkscape 1.2+ by Mario Voigt",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/layer_clip",
|
||||
|
@ -15,7 +15,7 @@
|
||||
"documentation_url": "the URL where MightyScape documentation can be found",
|
||||
"inkscape_gallery_url": "the URL for the gallery location. Set to 'null' if it's not listed in the gallery",
|
||||
"main_authors": [
|
||||
"a comma separated list of authors which work(ed) on the extension. We use either an email address or pattern '<platform>/<user name or full name>'"
|
||||
"a comma separated list of authors which work(ed) on the extension. We use either an email address and/or pattern '<platform>/<user name or full name>:<mailbox@tl.domaind>'"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -13,8 +13,8 @@
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Purge+Duplicate+Path+Nodes",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"gitlab.com/EllenWasbo/",
|
||||
"gitlab.com/EllenWasbo",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -13,8 +13,8 @@
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Remove+Duplicate+Guides",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"lukerazor@hotmail.com",
|
||||
"Luke Phillips:lukerazor@hotmail.com",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -5,7 +5,7 @@
|
||||
"path": "set_view_box",
|
||||
"original_name": "Set viewBox",
|
||||
"original_id": "org.pernsteiner.inkscape.viewbox",
|
||||
"license": "MIT License",
|
||||
"license": "BSD-2-Clause License",
|
||||
"license_url": "http://www.pernsteiner.org/inkscape/viewbox/inkscape-viewbox-0.1.0.zip",
|
||||
"comment": "ported to Inkscape v1 manually by Mario Voigt",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/set_view_box",
|
||||
@ -17,4 +17,4 @@
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -13,8 +13,8 @@
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Tuckbox",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"Luke Phillips (lukerazor@hotmail.com)",
|
||||
"Luke Phillips:lukerazor@hotmail.com",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -13,8 +13,8 @@
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Vektorkollektor",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"https://niklasroy.com",
|
||||
"http://katihyyppa.com",
|
||||
"niklasroy.com/Niklas Roy",
|
||||
"katihyyppa.com/Kati Hyyppä",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user