aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/md')
-rw-r--r--doc/md/3rd-party-libraries.md13
-rw-r--r--doc/md/Backup,-restore,-import-and-export.md63
-rw-r--r--doc/md/Bookmarklet.md30
-rw-r--r--doc/md/Browsing-and-searching.md23
-rw-r--r--doc/md/Coding-guidelines.md5
-rw-r--r--doc/md/Community-&-Related-software.md60
-rw-r--r--doc/md/Continuous-integration-tools.md24
-rw-r--r--doc/md/Copy-an-existing-installation-over-SSH-and-serve-it-locally.md66
-rw-r--r--doc/md/Create-and-serve-multiple-Shaarlis-(farm).md57
-rw-r--r--doc/md/Datastore-hacks.md25
-rw-r--r--doc/md/Development-guidelines.md9
-rw-r--r--doc/md/Directory-structure.md34
-rw-r--r--doc/md/Docker-101.md62
-rw-r--r--doc/md/Docker-resources.md19
-rw-r--r--doc/md/Download-CSS-styles-from-an-OPML-list.md154
-rw-r--r--doc/md/Download-and-Installation.md99
-rw-r--r--doc/md/Example-patch---add-new-via-field-for-links.md189
-rw-r--r--doc/md/FAQ.md43
-rw-r--r--doc/md/Features.md24
-rw-r--r--doc/md/Firefox-share.md15
-rw-r--r--doc/md/GnuPG-signature.md76
-rw-r--r--doc/md/Plugin-System.md710
-rw-r--r--doc/md/Plugins.md75
-rw-r--r--doc/md/REST-API.md104
-rw-r--r--doc/md/RSS-feeds.md26
-rw-r--r--doc/md/Release-Shaarli.md168
-rw-r--r--doc/md/Reverse-proxy-configuration.md6
-rw-r--r--doc/md/Security.md27
-rw-r--r--doc/md/Server-configuration.md392
-rw-r--r--doc/md/Server-requirements.md40
-rw-r--r--doc/md/Server-security.md73
-rw-r--r--doc/md/Shaarli-configuration.md215
-rw-r--r--doc/md/Shaarli-images.md72
-rw-r--r--doc/md/Static-analysis.md11
-rw-r--r--doc/md/Theming.md84
-rw-r--r--doc/md/Troubleshooting.md123
-rw-r--r--doc/md/Unit-tests.md152
-rw-r--r--doc/md/Upgrade-and-migration.md194
-rw-r--r--doc/md/Versioning-and-Branches.md75
-rw-r--r--doc/md/_Footer.md1
-rw-r--r--doc/md/_Sidebar.md45
-rw-r--r--doc/md/config.json6
-rw-r--r--doc/md/github-markdown.css287
-rw-r--r--doc/md/images/bookmarklet.pngbin0 -> 53346 bytes
-rw-r--r--doc/md/images/doc-logo.pngbin0 -> 19543 bytes
-rw-r--r--doc/md/images/doc-logo.svg522
-rw-r--r--doc/md/images/firefoxshare.pngbin0 -> 757 bytes
-rw-r--r--doc/md/images/rss-filter-1.pngbin0 -> 18682 bytes
-rw-r--r--doc/md/images/rss-filter-2.pngbin0 -> 15604 bytes
-rw-r--r--doc/md/index.md11
50 files changed, 4509 insertions, 0 deletions
diff --git a/doc/md/3rd-party-libraries.md b/doc/md/3rd-party-libraries.md
new file mode 100644
index 00000000..ebab7a46
--- /dev/null
+++ b/doc/md/3rd-party-libraries.md
@@ -0,0 +1,13 @@
1## CSS
2- Yahoo UI [CSS Reset](http://yuilibrary.com/yui/docs/cssreset/)
3 - resets default CSS properties for all HTML elements (overriding browsers' default values)
4 - ensures custom CSS stylessheets will provide the same results on all browsers
5
6## Javascript
7- [Awesomeplete](https://leaverou.github.io/awesomplete/) ([GitHub](https://github.com/LeaVerou/awesomplete)) - autocompletion in input forms
8- [bLazy](http://dinbror.dk/blazy/) ([GitHub](https://github.com/dinbror/blazy)) - lazy loading for thumbnails
9- [qr.js](http://neocotic.com/qr.js/) ([GitHub](https://github.com/neocotic/qr.js)) - QR code generation
10
11## PHP
12- [shaarli/netscape-bookmark-parser](https://github.com/shaarli/netscape-bookmark-parser) - Netscape bookmark parser
13- [RainTPL](https://github.com/rainphp/raintpl) - HTML templating for PHP
diff --git a/doc/md/Backup,-restore,-import-and-export.md b/doc/md/Backup,-restore,-import-and-export.md
new file mode 100644
index 00000000..d3252226
--- /dev/null
+++ b/doc/md/Backup,-restore,-import-and-export.md
@@ -0,0 +1,63 @@
1
2 * [Backup and restore the datastore file](#backup-and-restore-the-datastore-file)
3 * [Export links as...](#export-links-as)
4 * [Import links from...](#import-links-from)
5 * [Import Shaarli links to Firefox](#import-shaarli-links-to-firefox)
6
7----------------------
8
9## Backup and restore the datastore file
10
11Backup the file `data/datastore.php` (by FTP or SSH). Restore by putting the file back in place.
12
13Example command:
14```bash
15rsync -avzP my.server.com:/var/www/shaarli/data/datastore.php datastore-$(date +%Y-%m-%d_%H%M).php
16```
17
18## Export links as...
19
20To export links as an HTML file, under _Tools > Export_, choose:
21- _Export all_ to export both public and private links
22- _Export public_ to export public links only
23- _Export private_ to export private links only
24
25Restore by using the `Import` feature.
26* This can be done using the [shaarchiver](https://github.com/nodiscc/shaarchiver) tool.
27
28Example command:
29```bash
30./export-bookmarks.py --url=https://my.server.com/shaarli --username=myusername --password=mysupersecretpassword --download-dir=./ --type=all
31```
32
33## Import links from...
34
35### Diigo
36
37If you export your bookmark from Diigo, make sure you use the Delicious export, not the Netscape export. (Their Netscape export is broken, and they don't seem to be interested in fixing it.)
38
39### Mister Wong
40
41See [this issue](https://github.com/sebsauvage/Shaarli/issues/146) for import tweaks.
42
43### SemanticScuttle
44
45To correctly import the tags from a [SemanticScuttle](http://semanticscuttle.sourceforge.net/) HTML export, edit the HTML file before importing and replace all occurences of `tags=` (lowercase) to `TAGS=` (uppercase).
46
47### Scuttle
48
49Shaarli cannot import data directly from [Scuttle](https://github.com/scronide/scuttle). However, you can use this third party tool: https://github.com/q2apro/scuttle-to-shaarli to export the Scuttle database to the Netscape HTML format compatible with the Shaarli importer.
50
51## Import Shaarli links to Firefox
52
53 * Export your Shaarli links as described above.
54 * For compatibility reasons, check `Prepend note permalinks with this Shaarli instance's URL (useful to import bookmarks in a web browser)`
55 * In Firefox, open the bookmark manager (not the sidebar! `Bookmarks menu > Show all bookmarks` or `Ctrl+Shift+B`)
56 * Select `Import and Backup > Import bookmarks in HTML format`
57
58Your bookmarks will be imported in Firefox, ready to use, with tags and descriptions retained. "Self" (notes) shaares will still point to the Shaarli instance you exported them from, but the note text can be viewed directly in the bookmark properties inside your browser. Depending on the number of bookmarks, the import can take some time.
59
60You may be interested in these Firefox addons to manage links imported from Shaarli
61
62 * [Bookmark Deduplicator](https://addons.mozilla.org/en-US/firefox/addon/bookmark-deduplicator/) - provides an easy way to deduplicate your bookmarks
63 * [TagSieve](https://addons.mozilla.org/en-US/firefox/addon/tagsieve/) - browse your bookmarks by their tags
diff --git a/doc/md/Bookmarklet.md b/doc/md/Bookmarklet.md
new file mode 100644
index 00000000..265ced44
--- /dev/null
+++ b/doc/md/Bookmarklet.md
@@ -0,0 +1,30 @@
1### Add the sharing button (_bookmarklet_) to your browser
2
3 * Open your Shaarli and `Login`
4 * Click the `Tools` button in the top bar
5 * Drag the **`✚Shaare link` button**, and drop it to your browser's bookmarks bar.
6
7_This bookmarklet button is compatible with Firefox, Opera, Chrome and Safari. Under Opera, you can't drag'n drop the button: You have to right-click on it and add a bookmark to your personal toolbar._
8
9![](images/bookmarklet.png)
10
11### Share links using the _bookmarklet_
12
13 * When you are visiting a webpage you would like to share with Shaarli, click the _bookmarklet_ you just added.
14 * A window opens.
15 * You can freely edit title, description, tags... to find it later using the text search or tag filtering.
16 * You will be able to edit this link later using the ![](https://raw.githubusercontent.com/shaarli/Shaarli/master/images/edit_icon.png) edit button.
17 * You can also check the “Private” box so that the link is saved but only visible to you.
18 * Click `Save`.**Voilà! Your link is now shared.**
19
20### Troubleshooting: The bookmarklet doesn't work with a few website (e.g. Github.com)
21
22Websites which enforce Content Security Policy (CSP), such as github.com, disallow usage of bookmarklets. Unfortunatly, there is nothing Shaarli can do about it.
23
24See [#196](https://github.com/shaarli/Shaarli#196).
25
26There is an open bug for both Firefox and Chromium:
27
28 * https://bugzilla.mozilla.org/show_bug.cgi?id=866522
29 * https://code.google.com/p/chromium/issues/detail?id=233903
30
diff --git a/doc/md/Browsing-and-searching.md b/doc/md/Browsing-and-searching.md
new file mode 100644
index 00000000..ad62c2f0
--- /dev/null
+++ b/doc/md/Browsing-and-searching.md
@@ -0,0 +1,23 @@
1## Plain text search
2
3Use the `Search text` field to search in _any_ of the fields of all links (Title, URL, Description...)
4
5**Exclude text/tags:** Use the `-` operator before a word or tag (example `-uninteresting`) to prevent entries containing (or tagged) `uninteresting` from showing up in the search results.
6
7**Exact text search:** Use double-quotes (example `"exact search"`) to search for the exact expression.
8
9Both exclude patterns and exact searches can be combined with normal searches (example `"exact search" term otherterm -notthis "very exact" stuff -notagain`)
10
11## Tags search
12
13Use the `Filter by tags` field to restrict displayed links to entries tagged with one or multiple tags (use space to separate tags).
14
15**Hidden tags:** Tags starting with a dot `.` (example `.secret`) are private. They can only be seen and searched when logged in.
16
17Alternatively you can use the `Tag cloud` to discover all tags and click on any of them to display related links.
18
19To search for links that are not tagged, enter `""` in the tag search field.
20
21## Filtering RSS feeds/Picture wall
22
23RSS feeds can also be restricted to only return items matching a text/tag search: see [[RSS feeds]].
diff --git a/doc/md/Coding-guidelines.md b/doc/md/Coding-guidelines.md
new file mode 100644
index 00000000..da47c498
--- /dev/null
+++ b/doc/md/Coding-guidelines.md
@@ -0,0 +1,5 @@
1## WIP
2
3This topic is currently being discussed here:
4- [Fix coding style (static analysis)](https://github.com/shaarli/Shaarli/issues/95) (#95)
5- [Continuous Integration tools & features](https://github.com/shaarli/Shaarli/issues/130) (#130)
diff --git a/doc/md/Community-&-Related-software.md b/doc/md/Community-&-Related-software.md
new file mode 100644
index 00000000..6ff7ed45
--- /dev/null
+++ b/doc/md/Community-&-Related-software.md
@@ -0,0 +1,60 @@
1_Unofficial but related work on Shaarli. If you maintain one of these, please get in touch with us to help us find a way to adapt your work to our fork._
2
3_TODO: contact repos owners to see if they'd like to standardize their work with the community fork._
4
5## Community
6- [Liens en vrac de sebsauvage](http://sebsauvage.net/links/) - the original Shaarli
7- [A large list of Shaarlis](http://porneia.free.fr/pub/links/ou-est-shaarli.html)
8- [A list of working Shaarli aggregators](https://raw.githubusercontent.com/Oros42/find_shaarlis/master/annuaires.json)
9- [A list of some known Shaarlis](https://github.com/Oros42/shaarlis_list)
10- [Adieu Delicious, Diigo et StumbleUpon. Salut Shaarli ! - sebsauvage.net](http://sebsauvage.net/rhaa/index.php?2011/09/16/09/29/58-adieu-delicious-diigo-et-stumbleupon-salut-shaarli-) (fr) _16/09/2011 - the original post about Shaarli_
11- [Original ideas/fixme/TODO page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:ideas)
12- [Original discussion page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion) (fr)
13- [Original revisions history](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history)
14- [Shaarli.fr/my](https://www.shaarli.fr/my.php) - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of [DMeloni](https://github.com/DMeloni)
15
16### Articles and social media discussions
17- 2016-09-22 - Hacker News - https://news.ycombinator.com/item?id=12552176
18- 2015-08-15 - Reddit - [Question about migrating from WordPress to Shaarli.](https://www.reddit.com/r/selfhosted/comments/3h3zwh/question_about_migrating_from_wordpress_to_shaarli/)
19- 2015-06-22 - Hacker News - https://news.ycombinator.com/item?id=9755366
20- 2015-05-12 - Reddit - [shaarli - Self hosted Bookmarking / Delicious (PHP, MySQL)](https://www.reddit.com/r/selfhosted/comments/35pkkc/shaarli_self_hosted_bookmarking_delicious_php/)
21
22### Third party plugins
23
24
25 * [autosave](https://github.com/kalvn/shaarli-plugin-autosave) by [@kalvn](https://github.com/kalvn): Automatically saves data when editing a link to avoid any loss in case of crash or unexpected shutdown.
26 * [Code Coloration](https://github.com/ArthurHoaro/code-coloration) by [@ArthurHoaro](https://github.com/ArthurHoaro): client side code syntax highlighter.
27 * [Disqus](https://github.com/kalvn/shaarli-plugin-disqus) by [@kalvn](https://github.com/kalvn): Adds Disqus comment system to your Shaarli.
28 * [emojione](https://github.com/NerosTie/emojione) by [@NerosTie](https://github.com/NerosTie): Add colorful emojis to your Shaarli.
29 * [google analytics](https://github.com/ericjuden/Shaarli-Google-Analytics-Plugin) by [@ericjuden](http://github.com/ericjuden): Adds Google Analytics tracking support
30 * [launch](https://github.com/ArthurHoaro/launch-plugin) - Launch Plugin is a plugin designed to enhance and customize Launch Theme for Shaarli.
31 * [related](https://github.com/ilesinge/shaarli-related) by [@ilesinge](https://github.com/ilesinge) - Show related links based on the number of identical tags.
32 * [social](https://github.com/alexisju/social) by [@alexisju](https://github.com/alexisju): share links to social networks.
33 * [shaarli2twitter](https://github.com/ArthurHoaro/shaarli2twitter) by [@ArthurHoaro](https://github.com/ArthurHoaro) - Automatically tweet your shared links from Shaarli
34
35
36### Themes
37See [[Theming]] for the list of community-contributed themes, and an installation guide.
38
39### Server apps
40- [shaarchiver](https://github.com/nodiscc/shaarchiver) - Archive your Shaarli bookmarks and their content
41- [shaarli-river](https://github.com/mknexen/shaarli-river) - An aggregator for shaarlis with many features
42- [Shaarlo](https://github.com/DMeloni/shaarlo) - An aggregator for shaarlis with many features (a very popular running instance among french shaarliers: [shaarli.fr](http://shaarli.fr/))
43- [Shaarlimages](https://github.com/BoboTiG/shaarlimages) - An image-oriented aggregator for Shaarlis
44- [mknexen/shaarli-api](https://github.com/mknexen/shaarli-api) - A REST API for Shaarli
45- [Self dead link](https://github.com/qwertygc/shaarli-dev-code/blob/master/self-dead-link.php) - Detect dead links on shaarli. This version use the database of shaarli. [Another version](https://github.com/qwertygc/shaarli-dev-code/blob/master/dead-link.php), can be used for other shaarli instances (but is more resource consuming).
46- [Bookmark Archiver](https://github.com/pirate/bookmark-archiver) - Save an archived copy of all websites starred using browser bookmarks/Shaarli/Delicious/Instapaper/Unmark.it/Pocket/Pinboard. Outputs browseable html.
47
48### Mobile Apps
49- [ShaarliOS](https://github.com/mro/ShaarliOS) iOS share extension - see [#308](https://github.com/shaarli/Shaarli/issues/308#issuecomment-184592070) for some promo codes,
50- [Shaarli for Android](http://sebsauvage.net/links/?ZAyDzg) - Android application that adds Shaarli as a sharing provider
51- [Shaarlier for Android](https://github.com/dimtion/Shaarlier) - Android application to simply add links directly into your Shaarli
52
53## Integration with other platforms
54- [tt-rss-shaarli](https://github.com/jcsaaddupuy/tt-rss-shaarli) - [Tiny-Tiny RSS](http://tt-rss.org/) plugin that adds support for sharing articles with Shaarli
55- [octopress-shaarli](https://github.com/ahmet2mir/octopress-shaarli) - Octopress plugin to retrieve Shaarli links on the sidebar
56- [Scuttle to Shaarli](https://github.com/q2apro/scuttle-to-shaarli) - Import bookmarks from Scuttle
57
58## Alternatives to Shaarli
59
60See the [bookmarks & link sharing](https://github.com/Kickball/awesome-selfhosted/#bookmarks--link-sharing) section on [awesome-selfhosted](https://github.com/Kickball/awesome-selfhosted/).
diff --git a/doc/md/Continuous-integration-tools.md b/doc/md/Continuous-integration-tools.md
new file mode 100644
index 00000000..30dc474d
--- /dev/null
+++ b/doc/md/Continuous-integration-tools.md
@@ -0,0 +1,24 @@
1## Local development
2A [`Makefile`](https://github.com/shaarli/Shaarli/blob/master/Makefile) is available to perform project-related operations:
3- Documentation - generate a local HTML copy of the GitHub wiki
4- [[Static analysis]] - check that the code is compliant to PHP conventions
5- [[Unit tests]] - ensure there are no regressions introduced by new commits
6
7## Automatic builds
8[Travis CI](http://docs.travis-ci.com/) is a Continuous Integration build server, that runs a build:
9- each time a commit is merged to the mainline (`master` branch)
10- each time a Pull Request is submitted or updated
11
12A build is composed of several jobs: one for each supported PHP version (see [[Server requirements]]).
13
14Each build job:
15- updates Composer
16- installs 3rd-party test dependencies with Composer
17- runs [[Unit tests]]
18
19After all jobs have finished, Travis returns the results to GitHub:
20- a status icon represents the result for the `master` branch: [![](https://api.travis-ci.org/shaarli/Shaarli.svg)](https://travis-ci.org/shaarli/Shaarli)
21- Pull Requests are updated with the Travis result
22 - Green: all tests have passed
23 - Red: some tests failed
24 - Orange: tests are pending
diff --git a/doc/md/Copy-an-existing-installation-over-SSH-and-serve-it-locally.md b/doc/md/Copy-an-existing-installation-over-SSH-and-serve-it-locally.md
new file mode 100644
index 00000000..7583c9ea
--- /dev/null
+++ b/doc/md/Copy-an-existing-installation-over-SSH-and-serve-it-locally.md
@@ -0,0 +1,66 @@
1Example bash script:
2
3```bash
4#!/bin/bash
5#Description: Copy a Shaarli installation over SSH/SCP, serve it locally with php-cli
6#Will create a local-shaarli/ directory when you run it, backup your Shaarli there, and serve it locally.
7#Will NOT download linked pages. It's just a directly usable backup/copy/mirror of your Shaarli
8#Requires: ssh, scp and a working SSH access to the server where your Shaarli is installed
9#Usage: ./local-shaarli.sh
10#Author: nodiscc (nodiscc@gmail.com)
11#License: MIT (http://opensource.org/licenses/MIT)
12set -o errexit
13set -o nounset
14
15##### CONFIG #################
16#The port used by php's local server
17php_local_port=7431
18
19#Name of the SSH server and path where Shaarli is installed
20#TODO: pass these as command-line arguments
21remotehost="my.ssh.server"
22remote_shaarli_dir="/var/www/shaarli"
23
24
25###### FUNCTIONS #############
26_main() {
27 _CBSyncShaarli
28 _CBServeShaarli
29}
30
31_CBSyncShaarli() {
32 remote_temp_dir=$(ssh $remotehost mktemp -d)
33 remote_ssh_user=$(ssh $remotehost whoami)
34 ssh -t "$remotehost" sudo cp -r "$remote_shaarli_dir" "$remote_temp_dir"
35 ssh -t "$remotehost" sudo chown -R "$remote_ssh_user":"$remote_ssh_user" "$remote_temp_dir"
36 scp -rq "$remotehost":"$remote_temp_dir" local-shaarli
37 ssh "$remotehost" rm -r "$remote_temp_dir"
38}
39
40_CBServeShaarli() {
41 #TODO: allow serving a previously downloaded Shaarli
42 #TODO: ask before overwriting local copy, if it exists
43 cd local-shaarli/
44 php -S localhost:${php_local_port}
45 echo "Please go to http://localhost:${php_local_port}"
46}
47
48
49##### MAIN #################
50
51_main
52```
53
54This outputs:
55
56```bash
57$ ./local-shaarli.sh
58PHP 5.6.0RC4 Development Server started at Mon Sep 1 21:56:19 2014
59Listening on http://localhost:7431
60Document root is /home/user/local-shaarli/shaarli
61Press Ctrl-C to quit.
62
63[Mon Sep 1 21:56:27 2014] ::1:57868 [200]: /
64[Mon Sep 1 21:56:27 2014] ::1:57869 [200]: /index.html
65[Mon Sep 1 21:56:37 2014] ::1:57881 [200]: /...
66```
diff --git a/doc/md/Create-and-serve-multiple-Shaarlis-(farm).md b/doc/md/Create-and-serve-multiple-Shaarlis-(farm).md
new file mode 100644
index 00000000..d0d812a3
--- /dev/null
+++ b/doc/md/Create-and-serve-multiple-Shaarlis-(farm).md
@@ -0,0 +1,57 @@
1Example bash script (creates multiple shaarli instances and generates an HTML index of them)
2
3```bash
4#!/bin/bash
5set -o errexit
6set -o nounset
7
8#config
9shaarli_base_dir='/var/www/shaarli'
10accounts='bob john whatever username'
11shaarli_repo_url='https://github.com/shaarli/Shaarli'
12ref="master"
13
14#clone multiple shaarli instances
15if [ ! -d "$shaarli_base_dir" ]; then mkdir "$shaarli_base_dir"; fi
16
17for account in $accounts; do
18 if [ -d "$shaarli_base_dir/$account" ];
19 then echo "[info] account $account already exists, skipping";
20 else echo "[info] creating new account $account ..."; git clone --quiet "$shaarli_repo_url" -b "$ref" "$shaarli_base_dir/$account"; fi
21done
22
23#generate html index of shaarlis
24htmlhead='<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
25<!-- Minimal html template thanks to http://www.sitepoint.com/a-minimal-html-document/ -->
26<html lang="en">
27 <head>
28 <meta http-equiv="content-type" content="text/html; charset=utf-8">
29 <title>My Shaarli farm</title>
30 <style>body {font-family: "Open Sans"}</style>
31 </head>
32 <body>
33 <div>
34 <h1>My Shaarli farm</h1>
35 <ul style="list-style-type: none;">'
36
37accountlinks=''
38
39htmlfooter='
40 </ul>
41 </div>
42 </body>
43</html>'
44
45
46
47for account in $accounts; do accountlinks="$accountlinks\n<li><a href=\"$account\">$account</a></li>"; done
48if [ -d "$shaarli_base_dir/index.html" ]; then echo "[removing old index.html]"; rm "$shaarli_base_dir/index.html" ]; fi
49echo "[info] generating new index of shaarlis"
50echo -e "$htmlhead $accountlinks $htmlfooter" > "$shaarli_base_dir/index.html"
51echo '[info] done.'
52echo "[info] list of accounts: $accounts"
53echo "[info] contents of $shaarli_base_dir:"
54tree -a -L 1 "$shaarli_base_dir"
55```
56
57This script just serves as an example. More precise or complex (applying custom configuration, etc) automation is possible using configuration management software like [Ansible](https://www.ansible.com/) \ No newline at end of file
diff --git a/doc/md/Datastore-hacks.md b/doc/md/Datastore-hacks.md
new file mode 100644
index 00000000..78baa005
--- /dev/null
+++ b/doc/md/Datastore-hacks.md
@@ -0,0 +1,25 @@
1### Decode datastore content
2
3To display the array representing the data saved in `data/datastore.php`, use the following snippet:
4
5```php
6$data = "tZNdb9MwFIb... <Commented content inside datastore.php>";
7$out = unserialize(gzinflate(base64_decode($data)));
8echo "<pre>"; // Pretty printing is love, pretty printing is life
9print_r($out);
10echo "</pre>";
11exit;
12```
13This will output the internal representation of the datastore, "unobfuscated" (if this can really be considered obfuscation).
14
15Alternatively, you can transform to JSON format (and pretty-print if you have `jq` installed):
16```
17php -r 'print(json_encode(unserialize(gzinflate(base64_decode(preg_replace("!.*/\* (.+) \*/.*!", "$1", file_get_contents("data/datastore.php")))))));' | jq .
18```
19
20### Changing the timestamp for a link
21
22* Look for `<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">` in `tpl/editlink.tpl` (line 14)
23* Replace `type="hidden"` with `type="text"` from this line
24* A new date/time field becomes available in the edit/new link dialog.
25* You can set the timestamp manually by entering it in the format `YYYMMDD_HHMMS`.
diff --git a/doc/md/Development-guidelines.md b/doc/md/Development-guidelines.md
new file mode 100644
index 00000000..1480ec89
--- /dev/null
+++ b/doc/md/Development-guidelines.md
@@ -0,0 +1,9 @@
1## Development guidelines
2
3Please have a look at the following pages:
4- [Contributing to Shaarli](https://github.com/shaarli/Shaarli/tree/master/CONTRIBUTING.md)
5- [[Static analysis]] - patches should try to stick to the [PHP Standard Recommendations](http://www.php-fig.org/psr/) (PSR), especially:
6 - [PSR-1](http://www.php-fig.org/psr/psr-1/) - Basic Coding Standard
7 - [PSR-2](http://www.php-fig.org/psr/psr-2/) - Coding Style Guide
8- [[Unit tests]]
9- [[GnuPG signature]] for tags/releases
diff --git a/doc/md/Directory-structure.md b/doc/md/Directory-structure.md
new file mode 100644
index 00000000..eb50965b
--- /dev/null
+++ b/doc/md/Directory-structure.md
@@ -0,0 +1,34 @@
1TODO: This page is out of date
2
3Here is the directory structure of Shaarli and the purpose of the different files:
4
5```bash
6 index.php # Main program
7 application/ # Shaarli classes
8 ├── LinkDB.php
9 └── Utils.php
10 tests/ # Shaarli unitary & functional tests
11 ├── LinkDBTest.php
12 ├── utils # utilities to ease testing
13 │ └── ReferenceLinkDB.php
14 └── UtilsTest.php
15 COPYING # Shaarli license
16 inc/ # static assets and 3rd party libraries
17 ├── awesomplete.* # tags autocompletion library
18 ├── blazy.* # picture wall lazy image loading library
19 ├── shaarli.css, reset.css # Shaarli stylesheet.
20 ├── qr.* # qr code generation library
21 └──rain.tpl.class.php # RainTPL templating library
22 tpl/ # RainTPL templates for Shaarli. They are used to build the pages.
23 images/ # Images and icons used in Shaarli
24 data/ # data storage: bookmark database, configuration, logs, banlist…
25 ├── config.php # Shaarli configuration (login, password, timezone, title…)
26 ├── datastore.php # Your link database (compressed).
27 ├── ipban.php # IP address ban system data
28 ├── lastupdatecheck.txt # Update check timestamp file
29 └──log.txt # login/IPban log.
30 cache/ # thumbnails cache
31 # This directory is automatically created. You can erase it anytime you want.
32 tmp/ # Temporary directory for compiled RainTPL templates.
33 # This directory is automatically created. You can erase it anytime you want.
34```
diff --git a/doc/md/Docker-101.md b/doc/md/Docker-101.md
new file mode 100644
index 00000000..b02dd149
--- /dev/null
+++ b/doc/md/Docker-101.md
@@ -0,0 +1,62 @@
1## Basics
2Install [Docker](https://www.docker.com/), by following the instructions relevant
3to your OS / distribution, and start the service.
4
5### Search an image on [DockerHub](https://hub.docker.com/)
6
7```bash
8$ docker search debian
9
10NAME DESCRIPTION STARS OFFICIAL AUTOMATED
11ubuntu Ubuntu is a Debian-based Linux operating s... 2065 [OK]
12debian Debian is a Linux distribution that's comp... 603 [OK]
13google/debian 47 [OK]
14```
15
16### Show available tags for a repository
17```bash
18$ curl https://index.docker.io/v1/repositories/debian/tags | python -m json.tool
19
20% Total % Received % Xferd Average Speed Time Time Time Current
21Dload Upload Total Spent Left Speed
22100 1283 0 1283 0 0 433 0 --:--:-- 0:00:02 --:--:-- 433
23```
24
25Sample output:
26```json
27[
28 {
29 "layer": "85a02782",
30 "name": "stretch"
31 },
32 {
33 "layer": "59abecbc",
34 "name": "testing"
35 },
36 {
37 "layer": "bf0fd686",
38 "name": "unstable"
39 },
40 {
41 "layer": "60c52dbe",
42 "name": "wheezy"
43 },
44 {
45 "layer": "c5b806fe",
46 "name": "wheezy-backports"
47 }
48]
49
50```
51
52### Pull an image from DockerHub
53```bash
54$ docker pull repository[:tag]
55
56$ docker pull debian:wheezy
57wheezy: Pulling from debian
584c8cbfd2973e: Pull complete
5960c52dbe9d91: Pull complete
60Digest: sha256:c584131da2ac1948aa3e66468a4424b6aea2f33acba7cec0b631bdb56254c4fe
61Status: Downloaded newer image for debian:wheezy
62```
diff --git a/doc/md/Docker-resources.md b/doc/md/Docker-resources.md
new file mode 100644
index 00000000..082d4a46
--- /dev/null
+++ b/doc/md/Docker-resources.md
@@ -0,0 +1,19 @@
1### Docker
2
3- [Interactive Docker training portal](https://www.katacoda.com/courses/docker/) on [Katakoda](https://www.katacoda.com/)
4- [Where are Docker images stored?](http://blog.thoward37.me/articles/where-are-docker-images-stored/)
5- [Dockerfile reference](https://docs.docker.com/reference/builder/)
6- [Dockerfile best practices](https://docs.docker.com/articles/dockerfile_best-practices/)
7- [Volumes](https://docs.docker.com/userguide/dockervolumes/)
8
9### DockerHub
10
11- [Repositories](https://docs.docker.com/userguide/dockerrepos/)
12- [Teams and organizations](https://docs.docker.com/docker-hub/orgs/)
13- [GitHub automated build](https://docs.docker.com/docker-hub/github/)
14
15### Service management
16
17- [Using supervisord](https://docs.docker.com/articles/using_supervisord/)
18- [Nginx in the foreground](http://nginx.org/en/docs/ngx_core_module.html#daemon)
19- [supervisord](http://supervisord.org/)
diff --git a/doc/md/Download-CSS-styles-from-an-OPML-list.md b/doc/md/Download-CSS-styles-from-an-OPML-list.md
new file mode 100644
index 00000000..26b7fb3e
--- /dev/null
+++ b/doc/md/Download-CSS-styles-from-an-OPML-list.md
@@ -0,0 +1,154 @@
1###Download CSS styles for shaarlis listed in an opml file
2Example php script:
3
4```php
5<!---- ?php -->
6<!---- Copyright (c) 2014 Nicolas Delsaux (https://github.com/Riduidel) -->
7<!---- License: zlib (http://www.gzip.org/zlib/zlib_license.html) -->
8
9/**
10 * Source: https://github.com/Riduidel
11 * Download css styles for shaarlis listed in an opml file
12 */
13define("SHAARLI_RSS_OPML", "https://www.ecirtam.net/shaarlirss/custom/people.opml");
14
15define("THEMES_TEMP_FOLDER", "new_themes");
16
17if(!file_exists(THEMES_TEMP_FOLDER)) {
18 mkdir(THEMES_TEMP_FOLDER);
19}
20
21function siteUrl($pathInSite) {
22 $indexPos = strpos($pathInSite, "index.php");
23 if(!$indexPos) {
24 return $pathInSite;
25 } else {
26 return substr($pathInSite, 0, $indexPos);
27 }
28}
29
30function createShaarliHashFromOPMLL($opmlFile) {
31 $result = array();
32 $opml = file_get_contents($opmlFile);
33 $opmlXml = simplexml_load_string($opml);
34 $outlineElements = $opmlXml->xpath("body/outline");
35 foreach($outlineElements as $site) {
36 $siteUrl = siteUrl((string) $site['htmlUrl']);
37 $result[$siteUrl]=((string) $site['text']);
38 }
39 return $result;
40}
41
42function getSiteFolder($url) {
43 $domain = parse_url($url, PHP_URL_HOST);
44 return THEMES_TEMP_FOLDER."/".str_replace(".", "_", $domain);
45}
46
47function get_http_response_code($theURL) {
48 $headers = get_headers($theURL);
49 return substr($headers[0], 9, 3);
50}
51
52/**
53 * This makes the code PHP-5 only (particularly the call to "get_headers")
54 */
55function copyUserStyleFrom($url, $name, $knownStyles) {
56 $userStyle = $url."inc/user.css";
57 if(in_array($url, $knownStyles)) {
58 // TODO add log message
59 } else {
60 $statusCode = get_http_response_code($userStyle);
61 if(intval($statusCode)<300) {
62 $styleSheet = file_get_contents($userStyle);
63 $siteFolder = getSiteFolder($url);
64 if(!file_exists($siteFolder)) {
65 mkdir($siteFolder);
66 }
67 if(!file_exists($siteFolder.'/user.css')) {
68 // Copy stylesheet
69 file_put_contents($siteFolder.'/user.css', $styleSheet);
70 }
71 if(!file_exists($siteFolder.'/README.md')) {
72 // Then write a readme.md file
73 file_put_contents($siteFolder.'/README.md',
74 "User style from ".$name."\n"
75 ."============================="
76 ."\n\n"
77 ."This stylesheet was downloaded from ".$userStyle." on ".date(DATE_RFC822)
78 );
79 }
80 if(!file_exists($siteFolder.'/config.ini')) {
81 // Write a config file containing useful informations
82 file_put_contents($siteFolder.'/config.ini',
83 "site_url=".$url."\n"
84 ."site_name=".$name."\n"
85 );
86 }
87 if(!file_exists($siteFolder.'/home.png')) {
88 // And finally copy generated thumbnail
89 $homeThumb = $siteFolder.'/home.png';
90 file_put_contents($siteFolder.'/home.png', file_get_contents(getThumbnailUrl($url)));
91 }
92 echo 'Theme have been downloaded from <a href="'.$url.'">'.$url.'</a> into '.$siteFolder
93 .'. It looks like <img src="'.$homeThumb.'"><br/>';
94 }
95 }
96}
97
98function getThumbnailUrl($url) {
99 return 'http://api.webthumbnail.org/?url='.$url;
100}
101
102function copyUserStylesFrom($urlToNames, $knownStyles) {
103 foreach($urlToNames as $url => $name) {
104 copyUserStyleFrom($url, $name, $knownStyles);
105 }
106}
107
108/**
109 * Reading directory list, courtesy of http://www.laughing-buddha.net/php/dirlist/
110 * @param directory the directory we want to list files of
111 * @return a simple array containing the list of absolute file paths. Notice that current file (".") and parent one("..")
112 * are not listed here
113 */
114function getDirectoryList ($directory) {
115 $realPath = realpath($directory);
116 // create an array to hold directory list
117 $results = array();
118 // create a handler for the directory
119 $handler = opendir($directory);
120 // open directory and walk through the filenames
121 while ($file = readdir($handler)) {
122 // if file isn't this directory or its parent, add it to the results
123 if ($file != "." && $file != "..") {
124 $results[] = realpath($realPath . "/" . $file);
125 }
126 }
127 // tidy up: close the handler
128 closedir($handler);
129 // done!
130 return $results;
131}
132
133/**
134 * Start in themes folder and look in all subfolders for config.ini files.
135 * These config.ini files allow us not to download styles again and again
136 */
137function findKnownStyles() {
138 $result = array();
139 $subFolders = getDirectoryList("themes");
140 foreach($subFolders as $folder) {
141 $configFile = $folder."/config.ini";
142 if(file_exists($configFile)) {
143 $iniParameters = parse_ini_file($configFile);
144 array_push($result, $iniParameters['site_url']);
145 }
146 }
147 return $result;
148}
149
150$knownStyles = findKnownStyles();
151copyUserStylesFrom(createShaarliHashFromOPMLL(SHAARLI_RSS_OPML), $knownStyles);
152
153<!--- ? ---->
154``` \ No newline at end of file
diff --git a/doc/md/Download-and-Installation.md b/doc/md/Download-and-Installation.md
new file mode 100644
index 00000000..7880aef4
--- /dev/null
+++ b/doc/md/Download-and-Installation.md
@@ -0,0 +1,99 @@
1To install Shaarli, simply place the files in a directory under your webserver's Document Root (or directly at the document root). Make sure your [server](Server-requirements) is properly [configured](Server-configuration).
2
3Several releases are available:
4
5--------------------------------------------------------
6
7## Latest release (recommended)
8### Download as an archive
9Get the latest released version from the [releases](https://github.com/shaarli/Shaarli/releases) page.
10
11**Download our *shaarli-full* archive** to include dependencies.
12
13The current latest released version is `v0.8.4`
14
15Or in command lines:
16
17```bash
18$ wget https://github.com/shaarli/Shaarli/releases/download/v0.8.4/shaarli-v0.8.4-full.zip
19$ unzip shaarli-v0.8.4-full.zip
20$ mv Shaarli /path/to/shaarli/
21```
22
23| ! |In most cases, download Shaarli from the [releases](https://github.com/shaarli/Shaarli/releases) page. Cloning using `git` or downloading Github branches as zip files requires additional steps (see below).|
24|-----|--------------------------|
25
26### Using git
27
28```
29mkdir -p /path/to/shaarli && cd /path/to/shaarli/
30git clone -b v0.8 https://github.com/shaarli/Shaarli.git .
31composer install --no-dev
32```
33
34--------------------------------------------------------
35
36## Stable version
37
38The stable version has been experienced by Shaarli users, and will receive security updates.
39
40### Download as an archive
41
42As a .zip archive:
43
44```bash
45$ wget https://github.com/shaarli/Shaarli/archive/stable.zip
46$ unzip stable.zip
47$ mv Shaarli-stable /path/to/shaarli/
48```
49
50As a .tar.gz archive :
51
52```bash
53$ wget https://github.com/shaarli/Shaarli/archive/stable.tar.gz
54$ tar xvf stable.tar.gz
55$ mv Shaarli-stable /path/to/shaarli/
56```
57
58### Clone with Git
59
60[Composer](https://getcomposer.org/) is required to build a functional Shaarli installation when pulling from git.
61
62```bash
63$ git clone https://github.com/shaarli/Shaarli.git -b stable /path/to/shaarli/
64# install/update third-party dependencies
65$ cd /path/to/shaarli/
66$ composer install --no-dev
67```
68
69--------------------------------------------------------
70
71## Development version (mainline)
72
73_Use at your own risk!_
74
75To get the latest changes from the `master` branch:
76
77```bash
78# clone the repository
79$ git clone https://github.com/shaarli/Shaarli.git -b master /path/to/shaarli/
80# install/update third-party dependencies
81$ cd /path/to/shaarli
82$ composer install --no-dev
83```
84
85--------------------------------------------------------
86
87## Finish Installation
88
89Once Shaarli is downloaded and files have been placed at the correct location, open it this location your favorite browser.
90
91![install screenshot](http://i.imgur.com/wuMpDSN.png)
92
93Setup your Shaarli installation, and it's ready to use!
94
95--------------------------------------------------------
96
97## Updating Shaarli
98
99See [Upgrade and Migration](Upgrade-and-migration)
diff --git a/doc/md/Example-patch---add-new-via-field-for-links.md b/doc/md/Example-patch---add-new-via-field-for-links.md
new file mode 100644
index 00000000..d84ef25a
--- /dev/null
+++ b/doc/md/Example-patch---add-new-via-field-for-links.md
@@ -0,0 +1,189 @@
1Example patch to add a new field ("via") for links, an input field to set the "via" property from the "edit link" dialog, and display the "via" field in the link list display. **Untested, use at your own risk**
2
3Thanks to @Knah-Tsaeb in https://github.com/sebsauvage/Shaarli/pull/158
4
5```
6From e0f363c18e8fe67990ed2bb1a08652e24e70bbcb Mon Sep 17 00:00:00 2001
7From: Knah Tsaeb <knah-tsaeb@knah-tsaeb.org>
8Date: Fri, 11 Oct 2013 15:18:37 +0200
9Subject: [PATCH] Add a "via"/origin property for links, add new input in "edit link" dialog
10Thanks to:
11* https://github.com/Knah-Tsaeb/Shaarli/commit/040eb18ec8cdabd5ea855e108f81f97fbf0478c4
12* https://github.com/Knah-Tsaeb/Shaarli/commit/4123658eae44d7564d1128ce52ddd5689efee813
13* https://github.com/Knah-Tsaeb/Shaarli/commit/f1a8ca9cc8fe49b119d51b2d8382cc1a34542f96
14
15---
16 index.php | 43 ++++++++++++++++++++++++++++++++-----------
17 tpl/editlink.html | 1 +
18 tpl/linklist.html | 1 +
19 3 files changed, 34 insertions(+), 11 deletions(-)
20
21diff --git a/index.php b/index.php
22index 6fae2f8..53f798e 100644
23--- a/index.php
24+++ b/index.php
25@@ -436,6 +436,12 @@ if (isset($_POST['login']))
26 // ------------------------------------------------------------------------------------------
27 // Misc utility functions:
28
29+// Try to get just domain for @via
30+function getJustDomain($url){
31+ $parts = parse_url($url);
32+ return trim($parts['host']);
33+ }
34+
35 // Returns the server URL (including port and http/https), without path.
36 // e.g. "http://myserver.com:8080"
37 // You can append $_SERVER['SCRIPT_NAME'] to get the current script URL.
38@@ -799,7 +805,8 @@ class linkdb implements Iterator, Countable, ArrayAccess
39 $found= (strpos(strtolower($l['title']),$s)!==false)
40 || (strpos(strtolower($l['description']),$s)!==false)
41 || (strpos(strtolower($l['url']),$s)!==false)
42- || (strpos(strtolower($l['tags']),$s)!==false);
43+ || (strpos(strtolower($l['tags']),$s)!==false)
44+ || (!empty($l['via']) && (strpos(strtolower($l['via']),$s)!==false));
45 if ($found) $filtered[$l['linkdate']] = $l;
46 }
47 krsort($filtered);
48@@ -814,7 +821,7 @@ class linkdb implements Iterator, Countable, ArrayAccess
49 $t = str_replace(',',' ',($casesensitive?$tags:strtolower($tags)));
50 $searchtags=explode(' ',$t);
51 $filtered=array();
52- foreach($this->links as $l)
53+ foreach($this-> links as $l)
54 {
55 $linktags = explode(' ',($casesensitive?$l['tags']:strtolower($l['tags'])));
56 if (count(array_intersect($linktags,$searchtags)) == count($searchtags))
57@@ -905,7 +912,7 @@ function showRSS()
58 else $linksToDisplay = $LINKSDB;
59 $nblinksToDisplay = 50; // Number of links to display.
60 if (!empty($_GET['nb'])) // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
61- {
62+ {
63 $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ;
64 }
65
66@@ -944,7 +951,12 @@ function showRSS()
67 // If user wants permalinks first, put the final link in description
68 if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
69 if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
70- echo '<description><![CDATA['.nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))).$descriptionlink.']]></description>'."\n</item>\n";
71+ if(!empty($link['via'])){
72+ $via = '<br>Origine => <a href="'.htmlspecialchars($link['via']).'">'.htmlspecialchars(getJustDomain($link['via'])).'</a>';
73+ } else {
74+ $via = '';
75+ }
76+ echo '<description><![CDATA['.nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))).$via.$descriptionlink.']]></description>'."\n</item>\n";
77 $i++;
78 }
79 echo '</channel></rss><!-- Cached version of '.htmlspecialchars(pageUrl()).' -->';
80@@ -980,7 +992,7 @@ function showATOM()
81 else $linksToDisplay = $LINKSDB;
82 $nblinksToDisplay = 50; // Number of links to display.
83 if (!empty($_GET['nb'])) // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
84- {
85+ {
86 $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ;
87 }
88
89@@ -1006,11 +1018,16 @@ function showATOM()
90
91 // Add permalink in description
92 $descriptionlink = htmlspecialchars('(<a href="'.$guid.'">Permalink</a>)');
93+ if(isset($link['via']) && !empty($link['via'])){
94+ $via = htmlspecialchars('</br> Origine => <a href="'.$link['via'].'">'.getJustDomain($link['via']).'</a>');
95+ } else {
96+ $via = '';
97+ }
98 // If user wants permalinks first, put the final link in description
99 if ($usepermalinks===true) $descriptionlink = htmlspecialchars('(<a href="'.$absurl.'">Link</a>)');
100 if (strlen($link['description'])>0) $descriptionlink = '&lt;br&gt;'.$descriptionlink;
101
102- $entries.='<content type="html">'.htmlspecialchars(nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description']))))).$descriptionlink."</content>\n";
103+ $entries.='<content type="html">'.htmlspecialchars(nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description']))))).$descriptionlink.$via."</content>\n";
104 if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
105 {
106 foreach(explode(' ',$link['tags']) as $tag)
107@@ -1478,7 +1495,7 @@ function renderPage()
108 if (!startsWith($url,'http:') && !startsWith($url,'https:') && !startsWith($url,'ftp:') && !startsWith($url,'magnet:') && !startsWith($url,'?'))
109 $url = 'http://'.$url;
110 $link = array('title'=>trim($_POST['lf_title']),'url'=>$url,'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0),
111- 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags));
112+ 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags), 'via'=>trim($_POST['lf_via']));
113 if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title.
114 $LINKSDB[$linkdate] = $link;
115 $LINKSDB->savedb(); // Save to disk.
116@@ -1556,7 +1573,8 @@ function renderPage()
117 $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet).
118 $description = (empty($_GET['description']) ? '' : $_GET['description']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that]
119 $tags = (empty($_GET['tags']) ? '' : $_GET['tags'] ); // Get tags if it was provided in URL
120- $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); // Get private if it was provided in URL
121+ $via = (empty($_GET['via']) ? '' : $_GET['via'] );
122+ $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); // Get private if it was provided in URL
123 if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url;
124 // If this is an HTTP link, we try go get the page to extract the title (otherwise we will to straight to the edit form.)
125 if (empty($title) && parse_url($url,PHP_URL_SCHEME)=='http')
126@@ -1567,7 +1585,7 @@ function renderPage()
127 {
128 // Look for charset in html header.
129 preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
130-
131+
132 // If found, extract encoding.
133 if (!empty($meta[0]))
134 {
135@@ -1577,7 +1595,7 @@ function renderPage()
136 $html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
137 }
138 else { $html_charset = 'utf-8'; }
139-
140+
141 // Extract title
142 $title = html_extract_title($data);
143 if (!empty($title))
144@@ -1592,7 +1610,7 @@ function renderPage()
145 $url='?'.smallHash($linkdate);
146 $title='Note: ';
147 }
148- $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>$private);
149+ $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'via' => $via,'private'=>$private);
150 }
151
152 $PAGE = new pageBuilder;
153@@ -1842,6 +1860,9 @@ function buildLinkList($PAGE,$LINKSDB)
154 $taglist = explode(' ',$link['tags']);
155 uasort($taglist, 'strcasecmp');
156 $link['taglist']=$taglist;
157+ if(!empty($link['via'])){
158+ $link['via']=htmlspecialchars($link['via']);
159+ }
160 $linkDisp[$keys[$i]] = $link;
161 $i++;
162 }
163diff --git a/tpl/editlink.html b/tpl/editlink.html
164index 4a2c30c..14d4f9c 100644
165--- a/tpl/editlink.html
166+++ b/tpl/editlink.html
167@@ -16,6 +16,7 @@
168 <i>Title</i><br><input type="text" name="lf_title" value="{$link.title|htmlspecialchars}" style="width:100%"><br>
169 <i>Description</i><br><textarea name="lf_description" rows="4" cols="25" style="width:100%">{$link.description|htmlspecialchars}</textarea><br>
170 <i>Tags</i><br><input type="text" id="lf_tags" name="lf_tags" value="{$link.tags|htmlspecialchars}" style="width:100%"><br>
171+ <i>Origine</i><br><input type="text" name="lf_via" value="{$link.via|htmlspecialchars}" style="width:100%"><br>
172 {if condition="($link_is_new && $GLOBALS['privateLinkByDefault']==true) || $link.private == true"}
173 <input type="checkbox" checked="checked" name="lf_private" id="lf_private">
174 &nbsp;<label for="lf_private"><i>Private</i></label><br>
175diff --git a/tpl/linklist.html b/tpl/linklist.html
176index ddc38cb..0a8475f 100644
177--- a/tpl/linklist.html
178+++ b/tpl/linklist.html
179@@ -43,6 +43,7 @@
180 <span class="linktitle"><a href="{$redirector}{$value.url|htmlspecialchars}">{$value.title|htmlspecialchars}</a></span>
181 <br>
182 {if="$value.description"}<div class="linkdescription"{if condition="$search_type=='permalink'"} style="max-height:none !important;"{/if}>{$value.description}</div>{/if}
183+ {if condition="isset($value.via) && !empty($value.via)"}<div><a href="{$value.via}">Origine => {$value.via|getJustDomain}</a></div>{/if}
184 {if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"}
185 <span class="linkdate" title="Permalink"><a href="?{$value.linkdate|smallHash}">{$value.localdate|htmlspecialchars} - permalink</a> - </span>
186 {else}
187--
1882.1.1
189``` \ No newline at end of file
diff --git a/doc/md/FAQ.md b/doc/md/FAQ.md
new file mode 100644
index 00000000..151dcef5
--- /dev/null
+++ b/doc/md/FAQ.md
@@ -0,0 +1,43 @@
1### Why did you create Shaarli ?
2
3I was a StumbleUpon user. Then I got fed up with they big toolbar. I switched to delicious, which was lighter, faster and more beautiful. Until Yahoo bought it. Then the export API broke all the time, delicious became slow and was ditched by Yahoo. I switched to Diigo, which is not bad, but does too much. And Diigo is sslllooooowww and their Firefox extension a bit buggy. And… oh… **their Firefox addon sends to Diigo every single URL you visit** (Don't believe me ? Use [Tamper Data](https://addons.mozilla.org/en-US/firefox/addon/tamper-data/) and open any page).
4
5Enough is enough. Saving simple links should not be a complicated heavy thing. I ditched them all and wrote my own: Shaarli. It's simple, but it does the job and does it well. And my data is not hosted on a foreign server, but on my server.
6
7### Why use Shaarli and not Delicious/Diigo ?
8
9With Shaarli:
10
11* The data is yours: It's hosted on your server.
12* Never fear of having your data locked-in.
13* Never fear to have your data sold to third party.
14* Your private links are not hosted on a third party server.
15* You are not tracked by browser addons (like Diigo does)
16* You can change the look and feel of the pages if you want.
17* You can change the behaviour of the program.
18* It's magnitude faster than most bookmarking services.
19
20### What does Shaarli mean?
21
22Shaarli is for shaaring your links.
23
24### My Shaarli is broken!
25First of all, ensure that both the [web server](Server-configuration) and [Shaarli](Shaarli-configuration) are correctly configured, and that your installation is [supported](Server-requirements).
26
27If everything looks right but the issue(s) remain(s), please:
28- take a look at the [troubleshooting](Troubleshooting) section
29- come [chat with us](https://gitter.im/shaarli/Shaarli) on Gitter, we'll be happy to help ;-)
30- browse active [issues](https://github.com/shaarli/Shaarli/issues) and [Pull Requests](https://github.com/shaarli/Shaarli/pulls)
31 - if you find one that is related to the issue, feel free to comment and provide additional details (host/Shaarli setup)
32 - else, [open a new issue](https://github.com/shaarli/Shaarli/issues/new), and provide information about the problem:
33 - _what happens?_ - display glitches, invalid data, security flaws...
34 - _what is your configuration?_ - OS, server version, activated extensions, web browser...
35 - _is it reproducible?_
36
37### Why not use a real database? Files are slow!
38
39Does browsing [this page](http://sebsauvage.net/links/) feel slow? Try browsing older pages, too.
40
41It's not slow at all, is it? And don't forget the database contains more than 16000 links, and it's on a shared host, with 32000 visitors/day for my website alone. And it's still damn fast. Why?
42
43The data file is only 3.7 Mb. It's read 99% of the time, and is probably already in the operation system disk cache. So generating a page involves no I/O at all most of the time.
diff --git a/doc/md/Features.md b/doc/md/Features.md
new file mode 100644
index 00000000..116b1c9c
--- /dev/null
+++ b/doc/md/Features.md
@@ -0,0 +1,24 @@
1### Main features
2Shaarli is intended:
3 * to share, comment and save interesting links and news
4 * to bookmark useful/frequent personal links (as private links) and share them between computers
5 * as a minimal blog/microblog/writing platform (no character limit)
6 * as a read-it-later list (for example items tagged `readlater`)
7 * to draft and save articles/ideas
8 * to keep code snippets
9 * to keep notes and documentation
10 * as a shared clipboard between machines
11 * as a todo list
12 * to store playlists (e.g. with the `music` or `video` tags)
13 * to keep extracts/comments from webpages that may disappear
14 * to keep track of ongoing discussions (for example items tagged `discussion`)
15 * [to feed RSS aggregators](http://shaarli.chassegnouf.net/?9Efeiw) (planets) with specific tags
16 * to feed other social networks, blogs... using RSS feeds and external services (dlvr.it, ifttt.com ...)
17
18### Using Shaarli as a blog, notepad, pastebin...
19
20 * Go to your Shaarli setup and log in
21 * Click the `Add Link` button
22 * To share text only, do not enter any URL in the corresponding input field and click `Add Link`
23 * Pick a title and enter your article, or note, in the description field; add a few tags; optionally check `Private` then click `Save`
24 * Voilà! Your article is now published (privately if you selected that option) and accessible using its permalink.
diff --git a/doc/md/Firefox-share.md b/doc/md/Firefox-share.md
new file mode 100644
index 00000000..9ba57b04
--- /dev/null
+++ b/doc/md/Firefox-share.md
@@ -0,0 +1,15 @@
1### Add Shaarli as a sharing service to Firefox
2
3 * Open your Shaarli and `Login`
4 * Click the `Tools` button in the top bar
5 * Click the `✚Add to Firefox social` button and accept the activation.
6
7
8### Sharing links using Firefox share
9
10 * Add the sharing service as described above
11 * When you are visiting a webpage you would like to share with Shaarli, click the Firefox _Share_ button [[images/firefoxshare.png]]
12 * You can edit your link before and after saving, just like the bookmarklet above.
13
14|  | Your Shaarli instance must be hosted on an HTTPS (SSL/TLS secure connection) enabled server for Firefox Share to work. Firefox Share will not work over plain HTTP connections. |
15|------|-------------------------------------------------------------------------------|
diff --git a/doc/md/GnuPG-signature.md b/doc/md/GnuPG-signature.md
new file mode 100644
index 00000000..1fb3b42f
--- /dev/null
+++ b/doc/md/GnuPG-signature.md
@@ -0,0 +1,76 @@
1## Introduction
2### PGP and GPG
3[Gnu Privacy Guard](https://gnupg.org/) (GnuPG) is an Open Source implementation of the [Pretty Good
4Privacy](https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP) (OpenPGP) specification. Its main purposes are digital authentication,
5signature and encryption.
6
7It is often used by the [FLOSS](https://en.wikipedia.org/wiki/Free_and_open-source_software) community to verify:
8- Linux package signatures: Debian [SecureApt](https://wiki.debian.org/SecureApt), ArchLinux [Master
9Keys](https://www.archlinux.org/master-keys/)
10- [SCM](https://en.wikipedia.org/wiki/Revision_control) releases & maintainer identity
11
12### Trust
13To quote Phil Pennock (the author of the [SKS](https://bitbucket.org/skskeyserver/sks-keyserver/wiki/Home) key server - http://sks.spodhuis.org/):
14
15> You MUST understand that presence of data in the keyserver (pools) in no way connotes trust. Anyone can generate a key, with any name or email address, and upload it. All security and trust comes from evaluating security at the “object level”, via PGP Web-Of-Trust signatures. This keyserver makes it possible to retrieve keys, looking them up via various indices, but the collection of keys in this public pool is KNOWN to contain malicious and fraudulent keys. It is the common expectation of server operators that users understand this and use software which, like all known common OpenPGP implementations, evaluates trust accordingly. This expectation is so common that it is not normally explicitly stated.
16
17Trust can be gained by having your key signed by other people (and signing their key back, too :) ), for instance during [key signing parties](https://en.wikipedia.org/wiki/Key_signing_party), see:
18- [The Keysigning party HOWTO](http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html)
19- [Web of trust](https://en.wikipedia.org/wiki/Web_of_trust)
20
21## Generate a GPG key
22- [Generating a GPG key for Git tagging](http://stackoverflow.com/a/16725717) (StackOverflow)
23- [Generating a GPG key](https://help.github.com/articles/generating-a-gpg-key/) (GitHub)
24
25### gpg - provide identity information
26```bash
27$ gpg --gen-key
28
29gpg (GnuPG) 2.1.6; Copyright (C) 2015 Free Software Foundation, Inc.
30This is free software: you are free to change and redistribute it.
31There is NO WARRANTY, to the extent permitted by law.
32
33Note: Use "gpg2 --full-gen-key" for a full featured key generation dialog.
34
35GnuPG needs to construct a user ID to identify your key.
36
37Real name: Marvin the Paranoid Android
38Email address: marvin@h2g2.net
39You selected this USER-ID:
40 "Marvin the Paranoid Android <marvin@h2g2.net>"
41
42Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
43We need to generate a lot of random bytes. It is a good idea to perform
44some other action (type on the keyboard, move the mouse, utilize the
45disks) during the prime generation; this gives the random number
46generator a better chance to gain enough entropy.
47```
48
49### gpg - entropy interlude
50At this point, you will:
51- be prompted for a secure password to protect your key (the input method will depend on your Desktop Environment and configuration)
52- be asked to use your machine's input devices (mouse, keyboard, etc.) to generate random entropy; this step _may take some time_
53
54### gpg - key creation confirmation
55```bash
56gpg: key A9D53A3E marked as ultimately trusted
57public and secret key created and signed.
58
59gpg: checking the trustdb
60gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
61gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
62pub rsa2048/A9D53A3E 2015-07-31
63 Key fingerprint = AF2A 5381 E54B 2FD2 14C4 A9A3 0E35 ACA4 A9D5 3A3E
64uid [ultimate] Marvin the Paranoid Android <marvin@h2g2.net>
65sub rsa2048/8C0EACF1 2015-07-31
66```
67
68### gpg - submit your public key to a PGP server (Optional)
69``` bash
70$ gpg --keyserver pgp.mit.edu --send-keys A9D53A3E
71gpg: sending key A9D53A3E to hkp server pgp.mit.edu
72```
73
74## Create and push a GPG-signed tag
75
76See [[Release Shaarli]].
diff --git a/doc/md/Plugin-System.md b/doc/md/Plugin-System.md
new file mode 100644
index 00000000..d55ffe7e
--- /dev/null
+++ b/doc/md/Plugin-System.md
@@ -0,0 +1,710 @@
1[**I am a developer.** Developer API.](#developer-api)
2
3[**I am a template designer.** Guide for template designer.](#guide-for-template-designer)
4
5## Developer API
6
7### What can I do with plugins?
8
9The plugin system let you:
10
11 * insert content into specific places across templates.
12 * alter data before templates rendering.
13 * alter data before saving new links.
14
15### How can I create a plugin for Shaarli?
16
17First, chose a plugin name, such as `demo_plugin`.
18
19Under `plugin` folder, create a folder named with your plugin name. Then create a <plugin_name>.php file in that folder.
20
21You should have the following tree view:
22
23```
24| index.php
25| plugins/
26|---| demo_plugin/
27| |---| demo_plugin.php
28```
29
30### Plugin initialization
31
32At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an `init()` function to execute and run it if it exists. This function must be named this way, and takes the `ConfigManager` as parameter.
33
34 <plugin_name>_init($conf)
35
36This function can be used to create initial data, load default settings, etc. But also to set *plugin errors*. If the initialization function returns an array of strings, they will be understand as errors, and displayed in the header to logged in users.
37
38### Understanding hooks
39
40A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
41
42These functions need to be named with this pattern:
43
44```
45hook_<plugin_name>_<hook_name>($data, $conf)
46```
47
48Parameters:
49
50 - data: see [$data section](https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data)
51 - conf: the `ConfigManager` instance.
52
53For exemple, if my plugin want to add data to the header, this function is needed:
54
55 hook_demo_plugin_render_header
56
57If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
58
59### Plugin's data
60
61#### Parameters
62
63Every hook function has a `$data` parameter. Its content differs for each hooks.
64
65**This parameter needs to be returned every time**, otherwise data is lost.
66
67 return $data;
68
69#### Filling templates placeholder
70
71Template placeholders are displayed in template in specific places.
72
73RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.
74
75For example, let's add a value in the placeholder `top_placeholder` which is displayed at the top of my page:
76
77```php
78$data['top_placeholder'][] = 'My content';
79# OR
80array_push($data['top_placeholder'], 'My', 'content');
81
82return $data;
83```
84
85#### Data manipulation
86
87When a page is displayed, every variable send to the template engine is passed to plugins before that in `$data`.
88
89The data contained by this array can be altered before template rendering.
90
91For exemple, in linklist, it is possible to alter every title:
92
93```php
94// mind the reference if you want $data to be altered
95foreach ($data['links'] as &$value) {
96 // String reverse every title.
97 $value['title'] = strrev($value['title']);
98}
99
100return $data;
101```
102
103### Metadata
104
105Every plugin needs a `<plugin_name>.meta` file, which is in fact an `.ini` file (`KEY="VALUE"`), to be listed in plugin administration.
106
107Each file contain two keys:
108
109 * `description`: plugin description
110 * `parameters`: user parameter names, separated by a `;`.
111 * `parameter.<PARAMETER_NAME>`: add a text description the specified parameter.
112
113> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
114
115### It's not working!
116
117Use `demo_plugin` as a functional example. It covers most of the plugin system features.
118
119If it's still not working, please [open an issue](https://github.com/shaarli/Shaarli/issues/new).
120
121### Hooks
122
123| Hooks | Description |
124| ------------- |:-------------:|
125| [render_header](#render_header) | Allow plugin to add content in page headers. |
126| [render_includes](#render_includes) | Allow plugin to include their own CSS files. |
127| [render_footer](#render_footer) | Allow plugin to add content in page footer and include their own JS files. |
128| [render_linklist](#render_linklist) | It allows to add content at the begining and end of the page, after every link displayed and to alter link data. |
129| [render_editlink](#render_editlink) | Allow to add fields in the form, or display elements. |
130| [render_tools](#render_tools) | Allow to add content at the end of the page. |
131| [render_picwall](#render_picwall) | Allow to add content at the top and bottom of the page. |
132| [render_tagcloud](#render_tagcloud) | Allow to add content at the top and bottom of the page, and after all tags. |
133| [render_taglist](#render_taglist) | Allow to add content at the top and bottom of the page, and after all tags. |
134| [render_daily](#render_daily) | Allow to add content at the top and bottom of the page, the bottom of each link and to alter data. |
135| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |
136| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
137| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
138
139
140
141#### render_header
142
143Triggered on every page.
144
145Allow plugin to add content in page headers.
146
147##### Data
148
149`$data` is an array containing:
150
151 * `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
152 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
153
154##### Template placeholders
155
156Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
157
158List of placeholders:
159
160 * `buttons_toolbar`: after the list of buttons in the header.
161
162![buttons_toolbar_example](http://i.imgur.com/ssJUOrt.png)
163
164 * `fields_toolbar`: after search fields in the header.
165
166> Note: This will only be called in linklist.
167
168![fields_toolbar_example](http://i.imgur.com/3GMifI2.png)
169
170#### render_includes
171
172Triggered on every page.
173
174Allow plugin to include their own CSS files.
175
176##### Data
177
178`$data` is an array containing:
179
180 * `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
181 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
182
183##### Template placeholders
184
185Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
186
187List of placeholders:
188
189 * `css_files`: called after loading default CSS.
190
191> Note: only add the path of the CSS file. E.g: `plugins/demo_plugin/custom_demo.css`.
192
193#### render_footer
194
195Triggered on every page.
196
197Allow plugin to add content in page footer and include their own JS files.
198
199##### Data
200
201`$data` is an array containing:
202
203 * `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
204 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
205
206##### Template placeholders
207
208Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
209
210List of placeholders:
211
212 * `text`: called after the end of the footer text.
213 * `endofpage`: called at the end of the page.
214
215![text_example](http://i.imgur.com/L5S2YEH.png)
216
217 * `js_files`: called at the end of the page, to include custom JS scripts.
218
219> Note: only add the path of the JS file. E.g: `plugins/demo_plugin/custom_demo.js`.
220
221#### render_linklist
222
223Triggered when `linklist` is displayed (list of links, permalink, search, tag filtered, etc.).
224
225It allows to add content at the begining and end of the page, after every link displayed and to alter link data.
226
227##### Data
228
229`$data` is an array containing:
230
231 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
232 * All templates data, including links.
233
234##### Template placeholders
235
236Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
237
238List of placeholders:
239
240 * `action_plugin`: next to the button "private only" at the top and bottom of the page.
241
242![action_plugin_example](http://i.imgur.com/Q12PWg0.png)
243
244 * `link_plugin`: for every link, between permalink and link URL.
245
246![link_plugin_example](http://i.imgur.com/3oDPhWx.png)
247
248 * `plugin_start_zone`: before displaying the template content.
249
250![plugin_start_zone_example](http://i.imgur.com/OVBkGy3.png)
251
252 * `plugin_end_zone`: after displaying the template content.
253
254![plugin_end_zone_example](http://i.imgur.com/6IoRuop.png)
255
256#### render_editlink
257
258Triggered when the link edition form is displayed.
259
260Allow to add fields in the form, or display elements.
261
262##### Data
263
264`$data` is an array containing:
265
266 * All templates data.
267
268##### Template placeholders
269
270Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
271
272List of placeholders:
273
274 * `edit_link_plugin`: after tags field.
275
276![edit_link_plugin_example](http://i.imgur.com/5u17Ens.png)
277
278#### render_tools
279
280Triggered when the "tools" page is displayed.
281
282Allow to add content at the end of the page.
283
284##### Data
285
286`$data` is an array containing:
287
288 * All templates data.
289
290##### Template placeholders
291
292Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
293
294List of placeholders:
295
296 * `tools_plugin`: at the end of the page.
297
298![tools_plugin_example](http://i.imgur.com/Bqhu9oQ.png)
299
300#### render_picwall
301
302Triggered when picwall is displayed.
303
304Allow to add content at the top and bottom of the page.
305
306##### Data
307
308`$data` is an array containing:
309
310 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
311 * All templates data.
312
313##### Template placeholders
314
315Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
316
317List of placeholders:
318
319 * `plugin_start_zone`: before displaying the template content.
320
321 * `plugin_end_zone`: after displaying the template content.
322
323![plugin_start_end_zone_example](http://i.imgur.com/tVTQFER.png)
324
325#### render_tagcloud
326
327Triggered when tagcloud is displayed.
328
329Allow to add content at the top and bottom of the page.
330
331##### Data
332
333`$data` is an array containing:
334
335 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
336 * All templates data.
337
338##### Template placeholders
339
340Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
341
342List of placeholders:
343
344 * `plugin_start_zone`: before displaying the template content.
345
346 * `plugin_end_zone`: after displaying the template content.
347
348For each tag, the following placeholder can be used:
349
350 * `tag_plugin`: after each tag
351
352![plugin_start_end_zone_example](http://i.imgur.com/vHmyT3a.png)
353
354
355#### render_taglist
356
357Triggered when taglist is displayed.
358
359Allow to add content at the top and bottom of the page.
360
361##### Data
362
363`$data` is an array containing:
364
365 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
366 * All templates data.
367
368##### Template placeholders
369
370Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
371
372List of placeholders:
373
374 * `plugin_start_zone`: before displaying the template content.
375
376 * `plugin_end_zone`: after displaying the template content.
377
378For each tag, the following placeholder can be used:
379
380 * `tag_plugin`: after each tag
381
382#### render_daily
383
384Triggered when tagcloud is displayed.
385
386Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
387
388##### Data
389
390`$data` is an array containing:
391
392 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
393 * All templates data, including links.
394
395##### Template placeholders
396
397Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
398
399List of placeholders:
400
401 * `link_plugin`: used at bottom of each link.
402
403![link_plugin_example](http://i.imgur.com/hzhMfSZ.png)
404
405 * `plugin_start_zone`: before displaying the template content.
406
407 * `plugin_end_zone`: after displaying the template content.
408
409#### render_feed
410
411Triggered when the ATOM or RSS feed is displayed.
412
413Allow to add tags in the feed, either in the header or for each items. Items (links) can also be altered before being rendered.
414
415##### Data
416
417`$data` is an array containing:
418
419 * `_LOGGEDIN_`: true if user is logged in, false otherwise.
420 * `_PAGE_`: containing either `rss` or `atom`.
421 * All templates data, including links.
422
423##### Template placeholders
424
425Tags can be added in feeds by adding an entry in `$data['<placeholder>']` array.
426
427List of placeholders:
428
429 * `feed_plugins_header`: used as a header tag in the feed.
430
431For each links:
432
433 * `feed_plugins`: additional tag for every link entry.
434
435#### save_link
436
437Triggered when a link is save (new link or edit).
438
439Allow to alter the link being saved in the datastore.
440
441##### Data
442
443`$data` is an array containing the link being saved:
444
445 * id
446 * title
447 * url
448 * shorturl
449 * description
450 * private
451 * tags
452 * created
453 * updated
454
455
456#### delete_link
457
458Triggered when a link is deleted.
459
460Allow to execute any action before the link is actually removed from the datastore
461
462##### Data
463
464`$data` is an array containing the link being saved:
465
466 * id
467 * title
468 * url
469 * shorturl
470 * description
471 * private
472 * tags
473 * created
474 * updated
475
476## Guide for template designer
477
478### Plugin administration
479
480Your theme must include a plugin administration page: `pluginsadmin.html`.
481
482> Note: repo's template link needs to be added when the PR is merged.
483
484Use the default one as an example.
485
486Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include `plugin_admin.js`, only if:
487
488 * you're using a table.
489 * you call orderUp() and orderUp() onclick on arrows.
490 * you add data-line and data-order to your rows.
491
492Otherwise, you can use your own JS as long as this field is send by the form:
493
494<input type="hidden" name="order_{$key}" value="{$counter}">
495
496### Placeholder system
497
498In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
499
500It's a RainTPL loop like this:
501
502 {loop="$plugin_variable"}
503 {$value}
504 {/loop}
505
506You should enable `demo_plugin` for testing purpose, since it uses every placeholder available.
507
508### List of placeholders
509
510**page.header.html**
511
512At the end of the menu:
513
514 {loop="$plugins_header.buttons_toolbar"}
515 {$value}
516 {/loop}
517
518At the end of file, before clearing floating blocks:
519
520 {if="!empty($plugin_errors) && isLoggedIn()"}
521 <ul class="errors">
522 {loop="plugin_errors"}
523 <li>{$value}</li>
524 {/loop}
525 </ul>
526 {/if}
527
528**includes.html**
529
530At the end of the file:
531
532```html
533{loop="$plugins_includes.css_files"}
534<link type="text/css" rel="stylesheet" href="{$value}#"/>
535{/loop}
536```
537
538**page.footer.html**
539
540At the end of your footer notes:
541
542```html
543{loop="$plugins_footer.text"}
544 {$value}
545{/loop}
546```
547
548At the end of file:
549
550```html
551{loop="$plugins_footer.js_files"}
552 <script src="{$value}#"></script>
553{/loop}
554```
555
556**linklist.html**
557
558After search fields:
559
560```html
561{loop="$plugins_header.fields_toolbar"}
562 {$value}
563{/loop}
564```
565
566Before displaying the link list (after paging):
567
568```html
569{loop="$plugin_start_zone"}
570 {$value}
571{/loop}
572```
573
574For every links (icons):
575
576```html
577{loop="$value.link_plugin"}
578 <span>{$value}</span>
579{/loop}
580```
581
582Before end paging:
583
584```html
585{loop="$plugin_end_zone"}
586 {$value}
587{/loop}
588```
589
590**linklist.paging.html**
591
592After the "private only" icon:
593
594```html
595{loop="$action_plugin"}
596 {$value}
597{/loop}
598```
599
600**editlink.html**
601
602After tags field:
603
604```html
605{loop="$edit_link_plugin"}
606 {$value}
607{/loop}
608```
609
610**tools.html**
611
612After the last tool:
613
614```html
615{loop="$tools_plugin"}
616 {$value}
617{/loop}
618```
619
620**picwall.html**
621
622Top:
623
624```html
625<div id="plugin_zone_start_picwall" class="plugin_zone">
626 {loop="$plugin_start_zone"}
627 {$value}
628 {/loop}
629</div>
630```
631
632Bottom:
633
634```html
635<div id="plugin_zone_end_picwall" class="plugin_zone">
636 {loop="$plugin_end_zone"}
637 {$value}
638 {/loop}
639</div>
640```
641
642**tagcloud.html**
643
644Top:
645
646```html
647 <div id="plugin_zone_start_tagcloud" class="plugin_zone">
648 {loop="$plugin_start_zone"}
649 {$value}
650 {/loop}
651 </div>
652```
653
654Bottom:
655
656```html
657 <div id="plugin_zone_end_tagcloud" class="plugin_zone">
658 {loop="$plugin_end_zone"}
659 {$value}
660 {/loop}
661 </div>
662```
663
664**daily.html**
665
666Top:
667
668```html
669<div id="plugin_zone_start_picwall" class="plugin_zone">
670 {loop="$plugin_start_zone"}
671 {$value}
672 {/loop}
673</div>
674```
675
676After every link:
677
678```html
679<div class="dailyEntryFooter">
680 {loop="$link.link_plugin"}
681 {$value}
682 {/loop}
683</div>
684```
685
686Bottom:
687
688```html
689<div id="plugin_zone_end_picwall" class="plugin_zone">
690 {loop="$plugin_end_zone"}
691 {$value}
692 {/loop}
693</div>
694```
695
696**feed.atom.xml** and **feed.rss.xml**:
697
698In headers tags section:
699```xml
700{loop="$feed_plugins_header"}
701 {$value}
702{/loop}
703```
704
705After each entry:
706```xml
707{loop="$value.feed_plugins"}
708 {$value}
709{/loop}
710```
diff --git a/doc/md/Plugins.md b/doc/md/Plugins.md
new file mode 100644
index 00000000..b52b8090
--- /dev/null
+++ b/doc/md/Plugins.md
@@ -0,0 +1,75 @@
1## Plugin installation
2
3There is a bunch of plugins shipped with Shaarli, where there is nothing to do to install them.
4
5If you want to install a third party plugin:
6
7 * Download it.
8 * Put it in the `plugins` directory in Shaarli's installation folder.
9 * Make sure you put it correctly:
10
11```
12| index.php
13| plugins/
14|---| custom_plugin/
15| |---| custom_plugin.php
16| |---| ...
17
18```
19
20 * Make sure your webserver can read and write the files in your plugin folder.
21
22## Plugin configuration
23
24In Shaarli's administration page (`Tools` link), go to `Plugin administration`.
25
26Here you can enable and disable all plugins available, and configure them.
27
28![administration screenshot](https://camo.githubusercontent.com/5da68e191969007492ca0fbeb25f3b2357b748cc/687474703a2f2f692e696d6775722e636f6d2f766837544643712e706e67)
29
30## Plugin order
31
32In the plugin administration page, you can move enabled plugins to the top or bottom of the list. The first plugins in the list will be processed first.
33
34This is important in case plugins are depending on each other. Read plugins README details for more information.
35
36**Use case**: The (non existent) plugin `shaares_footer` adds a footer to every shaare in Markdown syntax. It needs to be processed *before* (higher in the list) the Markdown plugin. Otherwise its syntax won't be translated in HTML.
37
38## File mode
39
40Enabled plugin are stored in your `config.php` parameters file, under the `array`:
41
42```php
43$GLOBALS['config']['ENABLED_PLUGINS']
44```
45
46You can edit them manually here.
47Example:
48
49```php
50$GLOBALS['config']['ENABLED_PLUGINS'] = array(
51 'qrcode',
52 'archiveorg',
53 'wallabag',
54 'markdown',
55);
56```
57
58### Plugin usage
59
60#### Official plugins
61
62Usage of each plugin is documented in it's README file:
63
64 * `addlink-toolbar`: Adds the addlink input on the linklist page
65 * `archiveorg`: For each link, add an Archive.org icon
66 * [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax.
67 * [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos.
68 * `qrcode`: For each link, add a QRCode icon.
69 * [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance.
70
71
72
73#### Third party plugins
74
75See [Community & related software](https://github.com/shaarli/Shaarli/wiki/Community-%26-Related-software#third-party-plugins)
diff --git a/doc/md/REST-API.md b/doc/md/REST-API.md
new file mode 100644
index 00000000..8f3f7303
--- /dev/null
+++ b/doc/md/REST-API.md
@@ -0,0 +1,104 @@
1## Usage
2
3See the [REST API documentation](http://shaarli.github.io/api-documentation/).
4
5## Authentication
6
7All requests to Shaarli's API must include a JWT token to verify their authenticity.
8
9This token has to be included as an HTTP header called `Authentication: Bearer <jwt token>`.
10
11JWT resources :
12
13 * [jwt.io](https://jwt.io) (including a list of client per language).
14 * RFC : https://tools.ietf.org/html/rfc7519
15 * https://float-middle.com/json-web-tokens-jwt-vs-sessions/
16 * HackerNews thread: https://news.ycombinator.com/item?id=11929267
17
18
19### Shaarli JWT Token
20
21JWT tokens are composed by three parts, separated by a dot `.` and encoded in base64:
22
23```
24[header].[payload].[signature]
25```
26
27#### Header
28
29Shaarli only allow one hash algorithm, so the header will always be the same:
30
31```json
32{
33 "typ": "JWT",
34 "alg": "HS512"
35}
36```
37
38Encoded in base64, it gives:
39
40```
41ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ==
42```
43
44#### Payload
45
46**Validity duration**
47
48To avoid infinite token validity, JWT tokens must include their creation date in UNIX timestamp format (timezone independant - UTC) under the key `iat` (issued at). This token will be accepted during 9 minutes.
49
50```json
51{
52 "iat": 1468663519
53}
54```
55
56See [RFC reference](https://tools.ietf.org/html/rfc7519#section-4.1.6).
57
58
59#### Signature
60
61The signature authenticate the token validity. It contains the base64 of the header and the body, separated by a dot `.`, hashed in SHA512 with the API secret available in Shaarli administration page.
62
63Signature example with PHP:
64
65```php
66$content = base64_encode($header) . '.' . base64_encode($payload);
67$signature = hash_hmac('sha512', $content, $secret);
68```
69
70
71### Complete example
72
73#### PHP
74
75```php
76function generateToken($secret) {
77 $header = base64_encode('{
78 "typ": "JWT",
79 "alg": "HS512"
80 }');
81 $payload = base64_encode('{
82 "iat": '. time() .'
83 }');
84 $signature = hash_hmac('sha512', $header .'.'. $payload , $secret);
85 return $header .'.'. $payload .'.'. $signature;
86}
87
88$secret = 'mysecret';
89$token = generateToken($secret);
90echo $token;
91```
92
93> `ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ==.ewogICAgICAgICJpYXQiOiAxNDY4NjY3MDQ3CiAgICB9.1d2c54fa947daf594fdbf7591796195652c8bc63bffad7f6a6db2a41c313f495a542cbfb595acade79e83f3810d709b4251d7b940bbc10b531a6e6134af63a68`
94
95```php
96$options = [
97 'http' => [
98 'method' => 'GET',
99 'jwt' => $token,
100 ],
101];
102$context = stream_context_create($options);
103file_get_contents($apiEndpoint, false, $context);
104```
diff --git a/doc/md/RSS-feeds.md b/doc/md/RSS-feeds.md
new file mode 100644
index 00000000..9d718172
--- /dev/null
+++ b/doc/md/RSS-feeds.md
@@ -0,0 +1,26 @@
1### Feeds options
2
3Feeds are available in ATOM with `?do=atom` and RSS with `do=RSS`.
4
5Options:
6- You can use `permalinks` in the feed URL to get permalink to Shaares instead of direct link to shaared URL.
7 - E.G. `https://my.shaarli.domain/?do=atom&permalinks`.
8- You can use `nb` parameter in the feed URL to specify the number of Shaares you want in a feed (default if not specified: `50`). The keyword `all` is available if you want everything.
9 - `https://my.shaarli.domain/?do=atom&permalinks&nb=42`
10 - `https://my.shaarli.domain/?do=atom&permalinks&nb=all`
11
12### RSS Feeds or Picture Wall for a specific search/tag
13
14It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to **only display results of a specific search, or for a specific tag**.
15
16For example, if you want to subscribe only to links tagged `photography`:
17- Go to the desired Shaarli instance.
18- Search for the `photography` tag in the _Filter by tag_ box. Links tagged `photography` are displayed.
19- Click on the `RSS Feed` button.
20- You are presented with an RSS feed showing only these links. Subscribe to it to receive only updates with this tag.
21- The same method **also works for a full-text search** (_Search_ box) **and for the Picture Wall** (want to only see pictures about `nature`?)
22- You can also build the URLs manually:
23 - `https://my.shaarli.domain/?do=rss&searchtags=nature`
24 - `https://my.shaarli.domain/links/?do=picwall&searchterm=poney`
25
26![](images/rss-filter-1.png) ![](images/rss-filter-2.png)
diff --git a/doc/md/Release-Shaarli.md b/doc/md/Release-Shaarli.md
new file mode 100644
index 00000000..cce5e209
--- /dev/null
+++ b/doc/md/Release-Shaarli.md
@@ -0,0 +1,168 @@
1See [Git - Maintaining a project - Tagging your
2releases](http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases).
3
4## Prerequisites
5This guide assumes that you have:
6- a GPG key matching your GitHub authentication credentials
7 - i.e., the email address identified by the GPG key is the same as the one in your `~/.gitconfig`
8- a GitHub fork of Shaarli
9- a local clone of your Shaarli fork, with the following remotes:
10 - `origin` pointing to your GitHub fork
11 - `upstream` pointing to the main Shaarli repository
12- maintainer permissions on the main Shaarli repository, to:
13 - push the signed tag
14 - create a new release
15- [Composer](https://getcomposer.org/) and [Pandoc](http://pandoc.org/) need to be installed
16
17## GitHub release draft and `CHANGELOG.md`
18See http://keepachangelog.com/en/0.3.0/ for changelog formatting.
19
20### GitHub release draft
21GitHub allows drafting the release note for the upcoming release, from the [Releases](https://github.com/shaarli/Shaarli/releases) page. This way, the release note can be drafted while contributions are merged to `master`.
22
23### `CHANGELOG.md`
24This file should contain the same information as the release note draft for the upcoming version.
25
26Update it to:
27- add new entries (additions, fixes, etc.)
28- mark the current version as released by setting its date and link
29- add a new section for the future unreleased version
30
31```bash
32$ cd /path/to/shaarli
33
34$ nano CHANGELOG.md
35
36[...]
37## vA.B.C - UNRELEASED
38TBA
39
40## [vX.Y.Z](https://github.com/shaarli/Shaarli/releases/tag/vX.Y.Z) - YYYY-MM-DD
41[...]
42```
43
44
45## Increment the version code, updated docs, create and push a signed tag
46### Generate documentation
47```bash
48$ cd /path/to/shaarli
49
50# create a new branch
51$ git fetch upstream
52$ git checkout upstream/master -b v0.5.0
53
54# rebuild the documentation from the wiki
55$ make htmldoc
56
57# commit the changes
58$ git add doc
59$ git commit -s -m "Generate documentation for v0.5.0"
60
61# push the commit on your GitHub fork
62$ git push origin v0.5.0
63```
64
65### Create and merge a Pull Request
66This one is pretty straightforward ;-)
67
68### Bump Shaarli version to v0.x branch
69
70```
71$ git checkout master
72$ git fetch upstream
73$ git pull upstream master
74
75# IF the branch doesn't exists
76$ git checkout -b v0.5
77# OR if the branch already exists
78$ git checkout v0.5
79$ git rebase upstream/master
80
81# Bump shaarli version from dev to 0.5.0, **without the `v`**
82$ vim shaarli_version.php
83$ git add shaarli_version
84$ git commit -s -m "Bump Shaarli version to v0.5.0"
85$ git push upstream v0.5
86```
87
88### Create and push a signed tag
89```bash
90# update your local copy
91$ git checkout v0.5
92$ git fetch upstream
93$ git pull upstream v0.5
94
95# create a signed tag
96$ git tag -s -m "Release v0.5.0" v0.5.0
97
98# push it to "upstream"
99$ git push --tags upstream
100```
101
102### Verify a signed tag
103[`v0.5.0`](https://github.com/shaarli/Shaarli/releases/tag/v0.5.0) is the first GPG-signed tag pushed on the Community Shaarli.
104
105Let's have a look at its signature!
106
107```bash
108$ cd /path/to/shaarli
109$ git fetch upstream
110
111# get the SHA1 reference of the tag
112$ git show-ref tags/v0.5.0
113f7762cf803f03f5caf4b8078359a63783d0090c1 refs/tags/v0.5.0
114
115# verify the tag signature information
116$ git verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
117gpg: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
118gpg: Good signature from "VirtualTam <virtualtam@flibidi.net>" [ultimate]
119```
120
121## Publish the GitHub release
122### Update release badges
123Update `README.md` so version badges display and point to the newly released Shaarli version(s), in the `master` branch.
124
125### Create a GitHub release from a Git tag
126From the previously drafted release:
127- edit the release notes (if needed)
128- specify the appropriate Git tag
129- publish the release
130- profit!
131
132### Generate and upload all-in-one release archives
133Users with a shared hosting may have:
134- no SSH access
135- no possibility to install PHP packages or server extensions
136- no possibility to run scripts
137
138To ease Shaarli installations, it is possible to generate and upload additional release archives,
139that will contain Shaarli code plus all required third-party libraries.
140
141**From the `v0.5` branch:**
142
143```bash
144$ make release_archive
145```
146
147This will create the following archives:
148- `shaarli-vX.Y.Z-full.tar`
149- `shaarli-vX.Y.Z-full.zip`
150
151The archives need to be manually uploaded on the previously created GitHub release.
152
153### Update `stable` and `latest` branches
154
155```
156$ git checkout latest
157# latest release
158$ git merge v0.5.0
159# fix eventual conflicts
160$ make test
161$ git push upstream latest
162$ git checkout stable
163# latest previous major
164$ git merge v0.4.5
165# fix eventual conflicts
166$ make test
167$ git push upstream stable
168```
diff --git a/doc/md/Reverse-proxy-configuration.md b/doc/md/Reverse-proxy-configuration.md
new file mode 100644
index 00000000..91ffecff
--- /dev/null
+++ b/doc/md/Reverse-proxy-configuration.md
@@ -0,0 +1,6 @@
1
2TODO, see https://github.com/shaarli/Shaarli/issues/888
3
4## HAProxy
5
6## Nginx
diff --git a/doc/md/Security.md b/doc/md/Security.md
new file mode 100644
index 00000000..aec37fa0
--- /dev/null
+++ b/doc/md/Security.md
@@ -0,0 +1,27 @@
1## Client browser
2* Shaarli relies on `HTTP_REFERER` for some functions (like redirects and clicking on tags). If you have disabled or masqueraded `HTTP_REFERER` in your browser, some features of Shaarli may not work
3
4## PHP
5* `magic_quotes` is an horrible option of PHP which is often activated on servers. No serious developer should rely on this horror to secure their code against SQL injections. You should disable it (and Shaarli expects this option to be disabled). Nevertheless, I have added code to cope with `magic_quotes` on, so you should not be bothered even on crappy hosts.
6
7## Server and sessions
8* Directories are protected using `.htaccess` files
9* Forms are protected against XSRF (Cross-site requests forgery):
10 * Forms which act on data (save,delete…) contain a token generated by the server.
11 * Any posted form which does not contain a valid token is rejected.
12 * Any token can only be used once.
13 * Tokens are attached to the session and cannot be reused in another session.
14* Sessions automatically expire after 60 minutes.
15* Sessions are protected against hijacking: the session ID cannot be used from a different IP address.
16
17## Shaarli datastore and configuration
18* The password is salted, hashed and stored in the data subdirectory, in a PHP file, and protected by htaccess. Even if the webserver does not support htaccess, the hash is not readable by URL. Even if the .php file is stolen, the password cannot deduced from the hash. The salt prevents rainbow-tables attacks.
19* Links are stored as an associative array which is serialized, compressed (with deflate), base64-encoded and saved as a comment in a `.php` file.
20* Even if the server does not support `.htaccess` files, the data file will still not be readable by URL.
21* The database looks like this:
22```php
23<?php /* zP1ZjxxJtiYIvvevEPJ2lDOaLrZv7o...
24...ka7gaco/Z+TFXM2i7BlfMf8qxpaSSYfKlvqv/x8= */ ?>
25```
26
27* Small hashes are used to make a link to an entry in Shaarli. They are unique. In fact, the date of the items (eg. `20110923_150523`) is hashed with CRC32, then converted to base64 and some characters are replaced. They are always 6 characters longs and use only `A-Z a-z 0-9 - _` and `@`.
diff --git a/doc/md/Server-configuration.md b/doc/md/Server-configuration.md
new file mode 100644
index 00000000..23fdbc8b
--- /dev/null
+++ b/doc/md/Server-configuration.md
@@ -0,0 +1,392 @@
1*Example virtual host configurations for popular web servers*
2
3- [Apache](#apache)
4- [Nginx](#nginx)
5
6## Prerequisites
7### Shaarli
8* Shaarli is installed in a directory readable/writeable by the user
9* the correct read/write permissions have been granted to the web server _user and/or group_
10* for HTTPS / SSL:
11 * a key pair (public, private) and a certificate have been generated
12 * the appropriate server SSL extension is installed and active
13
14### HTTPS, TLS and self-signed certificates
15Related guides:
16* [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)
17* [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
18* Generate a self-signed certificate (will trigger browser warnings) with apache2: `make-ssl-cert generate-default-snakeoil --force-overwrite` will create `/etc/ssl/certs/ssl-cert-snakeoil.pem` and `/etc/ssl/private/ssl-cert-snakeoil.key`
19
20### Proxies
21If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:
22- `X-Forwarded-Proto`;
23- `X-Forwarded-Host`;
24- `X-Forwarded-For`.
25
26See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
27
28## Apache
29### Minimal
30```apache
31<VirtualHost *:80>
32 ServerName shaarli.my-domain.org
33 DocumentRoot /absolute/path/to/shaarli/
34</VirtualHost>
35```
36### Debug - Log all the things!
37This configuration will log both Apache and PHP errors, which may prove useful to identify server configuration errors.
38
39See:
40* [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)
41* [PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)
42
43```apache
44<VirtualHost *:80>
45 ServerName shaarli.my-domain.org
46 DocumentRoot /absolute/path/to/shaarli/
47
48 LogLevel warn
49 ErrorLog /var/log/apache2/shaarli-error.log
50 CustomLog /var/log/apache2/shaarli-access.log combined
51
52 php_flag log_errors on
53 php_flag display_errors on
54 php_value error_reporting 2147483647
55 php_value error_log /var/log/apache2/shaarli-php-error.log
56</VirtualHost>
57```
58
59### Standard - Keep access and error logs
60```apache
61<VirtualHost *:80>
62 ServerName shaarli.my-domain.org
63 DocumentRoot /absolute/path/to/shaarli/
64
65 LogLevel warn
66 ErrorLog /var/log/apache2/shaarli-error.log
67 CustomLog /var/log/apache2/shaarli-access.log combined
68</VirtualHost>
69```
70
71### Paranoid - Redirect HTTP (:80) to HTTPS (:443)
72See [Server-side TLS](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache) (Mozilla).
73
74```apache
75<VirtualHost *:443>
76 ServerName shaarli.my-domain.org
77 DocumentRoot /absolute/path/to/shaarli/
78
79 SSLEngine on
80 SSLCertificateFile /absolute/path/to/the/website/certificate.pem
81 SSLCertificateKeyFile /absolute/path/to/the/website/key.key
82
83 <Directory /absolute/path/to/shaarli/>
84 AllowOverride All
85 Options Indexes FollowSymLinks MultiViews
86 Order allow,deny
87 allow from all
88 </Directory>
89
90 LogLevel warn
91 ErrorLog /var/log/apache2/shaarli-error.log
92 CustomLog /var/log/apache2/shaarli-access.log combined
93</VirtualHost>
94<VirtualHost *:80>
95 ServerName shaarli.my-domain.org
96 Redirect 301 / https://shaarli.my-domain.org
97
98 LogLevel warn
99 ErrorLog /var/log/apache2/shaarli-error.log
100 CustomLog /var/log/apache2/shaarli-access.log combined
101</VirtualHost>
102```
103
104### .htaccess
105
106Shaarli use `.htaccess` Apache files to deny access to files that shouldn't be directly accessed (datastore, config, etc.). You need the directive `AllowOverride All` in your virtual host configuration for them to work.
107
108**Warning**: If you use Apache 2.2 or lower, you need [mod_version](https://httpd.apache.org/docs/current/mod/mod_version.html) to be installed and enabled.
109
110Apache module `mod_rewrite` **must** be enabled to use the REST API. URL rewriting rules for the Slim microframework are stated in the root `.htaccess` file.
111
112## LightHttpd
113
114## Nginx
115### Foreword
116Nginx does not natively interpret PHP scripts; to this effect, we will run a [FastCGI](https://en.wikipedia.org/wiki/FastCGI) service, to which Nginx's FastCGI module will proxy all requests to PHP resources.
117
118Required packages:
119- [nginx](http://nginx.org)
120- [php-fpm](http://php-fpm.org) - PHP FastCGI Process Manager
121
122Official documentation:
123- [Beginner's guide](http://nginx.org/en/docs/beginners_guide.html)
124- [ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
125- [Pitfalls](http://wiki.nginx.org/Pitfalls)
126
127Community resources:
128- [Server-side TLS (Nginx)](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx) (Mozilla)
129- [PHP configuration examples](http://kbeezie.com/nginx-configuration-examples/) (Karl Blessing)
130
131### Common setup
132Once Nginx and PHP-FPM are installed, we need to ensure:
133- Nginx and PHP-FPM are running using the _same user and group_
134- both these user and group have
135 - `read` permissions for Shaarli resources
136 - `execute` permissions for Shaarli directories _AND_ their parent directories
137
138On a production server:
139- `user:group` will likely be `http:http`, `www:www` or `www-data:www-data`
140- files will be located under `/var/www`, `/var/http` or `/usr/share/nginx`
141
142On a development server:
143- files may be located in a user's home directory
144- in this case, make sure both Nginx and PHP-FPM are running as the local user/group!
145
146For all following configuration examples, this user/group pair will be used:
147- `user:group = john:users`,
148
149which corresponds to the following service configuration:
150
151```ini
152; /etc/php/php-fpm.conf
153user = john
154group = users
155
156[...]
157listen.owner = john
158listen.group = users
159```
160
161```nginx
162# /etc/nginx/nginx.conf
163user john users;
164
165http {
166 [...]
167}
168```
169
170### (Optional) Increase the maximum file upload size
171Some bookmark dumps generated by web browsers can be _huge_ due to the presence of Base64-encoded images and favicons, as well as extra verbosity when nesting links in (sub-)folders.
172
173To increase upload size, you will need to modify both nginx and PHP configuration:
174
175```nginx
176# /etc/nginx/nginx.conf
177
178http {
179 [...]
180
181 client_max_body_size 10m;
182
183 [...]
184}
185```
186
187```ini
188# /etc/php5/fpm/php.ini
189
190[...]
191post_max_size = 10M
192[...]
193upload_max_filesize = 10M
194```
195
196### Minimal
197_WARNING: Use for development only!_
198
199```nginx
200user john users;
201worker_processes 1;
202events {
203 worker_connections 1024;
204}
205
206http {
207 include mime.types;
208 default_type application/octet-stream;
209 keepalive_timeout 20;
210
211 index index.html index.php;
212
213 server {
214 listen 80;
215 server_name localhost;
216 root /home/john/web;
217
218 access_log /var/log/nginx/access.log;
219 error_log /var/log/nginx/error.log;
220
221 location /shaarli/ {
222 try_files $uri /shaarli/index.php$is_args$args;
223 access_log /var/log/nginx/shaarli.access.log;
224 error_log /var/log/nginx/shaarli.error.log;
225 }
226
227 location ~ (index)\.php$ {
228 try_files $uri =404;
229 fastcgi_split_path_info ^(.+\.php)(/.+)$;
230 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
231 fastcgi_index index.php;
232 include fastcgi.conf;
233 }
234 }
235}
236```
237
238### Modular
239The previous setup is sufficient for development purposes, but has several major caveats:
240- every content that does not match the PHP rule will be sent to client browsers:
241 - dotfiles - in our case, `.htaccess`
242 - temporary files, e.g. Vim or Emacs files: `index.php~`
243- asset / static resource caching is not optimized
244- if serving several PHP sites, there will be a lot of duplication: `location /shaarli/`, `location /mysite/`, etc.
245
246To solve this, we will split Nginx configuration in several parts, that will be included when needed:
247
248```nginx
249# /etc/nginx/deny.conf
250location ~ /\. {
251 # deny access to dotfiles
252 access_log off;
253 log_not_found off;
254 deny all;
255}
256
257location ~ ~$ {
258 # deny access to temp editor files, e.g. "script.php~"
259 access_log off;
260 log_not_found off;
261 deny all;
262}
263```
264
265```nginx
266# /etc/nginx/php.conf
267location ~ (index)\.php$ {
268 # Slim - split URL path into (script_filename, path_info)
269 try_files $uri =404;
270 fastcgi_split_path_info ^(.+\.php)(/.+)$;
271
272 # filter and proxy PHP requests to PHP-FPM
273 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
274 fastcgi_index index.php;
275 include fastcgi.conf;
276}
277
278location ~ \.php$ {
279 # deny access to all other PHP scripts
280 deny all;
281}
282```
283
284```nginx
285# /etc/nginx/static_assets.conf
286location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
287 expires max;
288 add_header Pragma public;
289 add_header Cache-Control "public, must-revalidate, proxy-revalidate";
290}
291```
292
293```nginx
294# /etc/nginx/nginx.conf
295[...]
296
297http {
298 [...]
299
300 root /home/john/web;
301 access_log /var/log/nginx/access.log;
302 error_log /var/log/nginx/error.log;
303
304 server {
305 # virtual host for a first domain
306 listen 80;
307 server_name my.first.domain.org;
308
309 location /shaarli/ {
310 # Slim - rewrite URLs
311 try_files $uri /shaarli/index.php$is_args$args;
312
313 access_log /var/log/nginx/shaarli.access.log;
314 error_log /var/log/nginx/shaarli.error.log;
315 }
316
317 location = /shaarli/favicon.ico {
318 # serve the Shaarli favicon from its custom location
319 alias /var/www/shaarli/images/favicon.ico;
320 }
321
322 include deny.conf;
323 include static_assets.conf;
324 include php.conf;
325 }
326
327 server {
328 # virtual host for a second domain
329 listen 80;
330 server_name second.domain.com;
331
332 location /minigal/ {
333 access_log /var/log/nginx/minigal.access.log;
334 error_log /var/log/nginx/minigal.error.log;
335 }
336
337 include deny.conf;
338 include static_assets.conf;
339 include php.conf;
340 }
341}
342```
343
344### Redirect HTTP to HTTPS
345Assuming you have generated a (self-signed) key and certificate, and they are located under `/home/john/ssl/localhost.{key,crt}`, it is pretty straightforward to set an HTTP (:80) to HTTPS (:443) redirection to force SSL/TLS usage.
346
347```nginx
348# /etc/nginx/nginx.conf
349[...]
350
351http {
352 [...]
353
354 index index.html index.php;
355
356 root /home/john/web;
357 access_log /var/log/nginx/access.log;
358 error_log /var/log/nginx/error.log;
359
360 server {
361 listen 80;
362 server_name localhost;
363
364 return 301 https://localhost$request_uri;
365 }
366
367 server {
368 listen 443 ssl;
369 server_name localhost;
370
371 ssl_certificate /home/john/ssl/localhost.crt;
372 ssl_certificate_key /home/john/ssl/localhost.key;
373
374 location /shaarli/ {
375 # Slim - rewrite URLs
376 try_files $uri /index.php$is_args$args;
377
378 access_log /var/log/nginx/shaarli.access.log;
379 error_log /var/log/nginx/shaarli.error.log;
380 }
381
382 location = /shaarli/favicon.ico {
383 # serve the Shaarli favicon from its custom location
384 alias /var/www/shaarli/images/favicon.ico;
385 }
386
387 include deny.conf;
388 include static_assets.conf;
389 include php.conf;
390 }
391}
392```
diff --git a/doc/md/Server-requirements.md b/doc/md/Server-requirements.md
new file mode 100644
index 00000000..b6bbd66a
--- /dev/null
+++ b/doc/md/Server-requirements.md
@@ -0,0 +1,40 @@
1## PHP
2
3### Release information
4- [PHP: Supported versions](http://php.net/supported-versions.php)
5- [PHP: Unsupported versions](http://php.net/eol.php) _(EOL - End Of Life)_
6- [PHP 7 Changelog](http://php.net/ChangeLog-7.php)
7- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)
8- [PHP: Bugs](https://bugs.php.net/)
9
10### Supported versions
11Version | Status | Shaarli compatibility
12:---:|:---:|:---:
137.1 | Supported (v0.9.x) | :white_check_mark:
147.0 | Supported | :white_check_mark:
155.6 | Supported | :white_check_mark:
165.5 | EOL: 2016-07-10 | :white_check_mark:
175.4 | EOL: 2015-09-14 | :white_check_mark: (up to Shaarli 0.8.x)
185.3 | EOL: 2014-08-14 | :white_check_mark: (up to Shaarli 0.8.x)
19
20See also:
21- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)
22
23### Dependency management
24Starting with Shaarli `v0.8.x`, [Composer](https://getcomposer.org/) is used to resolve,
25download and install third-party PHP dependencies.
26
27Library | Required? | Usage
28---|:---:|---
29[`shaarli/netscape-bookmark-parser`](https://packagist.org/packages/shaarli/netscape-bookmark-parser) | All | Import bookmarks from Netscape files
30[`erusev/parsedown`](https://packagist.org/packages/erusev/parsedown) | All | Parse MarkDown syntax for the MarkDown plugin
31[`slim/slim`](https://packagist.org/packages/slim/slim) | All | Handle routes and middleware for the REST API
32
33### Extensions
34Extension | Required? | Usage
35---|:---:|---
36[`openssl`](http://php.net/manual/en/book.openssl.php) | All | OpenSSL, HTTPS
37[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows | multibyte (Unicode) string support
38[`php-gd`](http://php.net/manual/en/book.image.php) | optional | thumbnail resizing
39[`php-intl`](http://php.net/manual/en/book.intl.php) | optional | localized text sorting (e.g. `e->è->f`)
40[`php-curl`](http://php.net/manual/en/book.curl.php) | optional | using cURL for fetching webpages and thumbnails in a more robust way
diff --git a/doc/md/Server-security.md b/doc/md/Server-security.md
new file mode 100644
index 00000000..8df36f46
--- /dev/null
+++ b/doc/md/Server-security.md
@@ -0,0 +1,73 @@
1## php.ini
2PHP settings are defined in:
3- a main configuration file, usually found under `/etc/php5/php.ini`; some distributions provide different configuration environments, e.g.
4 - `/etc/php5/php.ini` - used when running console scripts
5 - `/etc/php5/apache2/php.ini` - used when a client requests PHP resources from Apache
6 - `/etc/php5/php-fpm.conf` - used when PHP requests are proxied to PHP-FPM
7- additional configuration files/entries, depending on the installed/enabled extensions:
8 - `/etc/php/conf.d/xdebug.ini`
9
10### Locate .ini files
11#### Console environment
12```bash
13$ php --ini
14Configuration File (php.ini) Path: /etc/php
15Loaded Configuration File: /etc/php/php.ini
16Scan for additional .ini files in: /etc/php/conf.d
17Additional .ini files parsed: /etc/php/conf.d/xdebug.ini
18```
19
20#### Server environment
21- create a `phpinfo.php` script located in a path supported by the web server, e.g.
22 - Apache (with user dirs enabled): `/home/myself/public_html/phpinfo.php`
23 - `/var/www/test/phpinfo.php`
24- make sure the script is readable by the web server user/group (usually, `www`, `www-data` or `httpd`)
25- access the script from a web browser
26- look at the _Loaded Configuration File_ and _Scan this dir for additional .ini files_ entries
27```php
28<?php phpinfo(); ?>
29```
30
31## fail2ban
32`fail2ban` is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses `iptables` profiles to block brute-force attempts:
33- [Official website](http://www.fail2ban.org/wiki/index.php/Main_Page)
34- [Source code](https://github.com/fail2ban/fail2ban)
35
36### Read Shaarli logs to ban IPs
37Example configuration:
38- allow 3 login attempts per IP address
39- after 3 failures, permanently ban the corresponding IP adddress
40
41`/etc/fail2ban/jail.local`
42```ini
43[shaarli-auth]
44enabled = true
45port = https,http
46filter = shaarli-auth
47logpath = /var/www/path/to/shaarli/data/log.txt
48maxretry = 3
49bantime = -1
50```
51
52`/etc/fail2ban/filter.d/shaarli-auth.conf`
53```ini
54[INCLUDES]
55before = common.conf
56[Definition]
57failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
58ignoreregex =
59```
60
61## Robots - Restricting search engines and web crawler traffic
62
63Creating a `robots.txt` with the following contents at the root of your Shaarli installation will prevent _honest_ web crawlers from indexing each and every link and Daily page from a Shaarli instance, thus getting rid of a certain amount of unsollicited network traffic.
64
65```
66User-agent: *
67Disallow: /
68```
69
70See:
71- http://www.robotstxt.org/
72- http://www.robotstxt.org/robotstxt.html
73- http://www.robotstxt.org/meta.html
diff --git a/doc/md/Shaarli-configuration.md b/doc/md/Shaarli-configuration.md
new file mode 100644
index 00000000..933f5245
--- /dev/null
+++ b/doc/md/Shaarli-configuration.md
@@ -0,0 +1,215 @@
1## Foreword
2
3**Do not edit configuration options in index.php! Your changes would be lost.**
4
5Once your Shaarli instance is installed, the file `data/config.json.php` is generated:
6* it contains all settings in JSON format, and can be edited to customize values
7* it defines which [plugins](Plugin-System) are enabled[](.html)
8* its values override those defined in `index.php`
9* it is wrap in a PHP comment to prevent anyone accessing it, regardless of server configuration
10
11## File and directory permissions
12
13The server process running Shaarli must have:
14- `read` access to the following resources:
15 - PHP scripts: `index.php`, `application/*.php`, `plugins/*.php`
16 - 3rd party PHP and Javascript libraries: `inc/*.php`, `inc/*.js`
17 - static assets:
18 - CSS stylesheets: `inc/*.css`
19 - `images/*`
20 - RainTPL templates: `tpl/*.html`
21- `read`, `write` and `execution` access to the following directories:
22 - `cache` - thumbnail cache
23 - `data` - link data store, configuration options
24 - `pagecache` - Atom/RSS feed cache
25 - `tmp` - RainTPL page cache
26
27On a Linux distribution:
28- the web server user will likely be `www` or `http` (for Apache2)
29- it will be a member of a group of the same name: `www:www`, `http:http`
30- to give it access to Shaarli, either:
31 - unzip Shaarli in the default web server location (usually `/var/www/`) and set the web server user as the owner
32 - put users in the same group as the web server, and set the appropriate access rights
33- if you have a domain / subdomain to serve Shaarli, [configure the server](Server-configuration) accordingly[](.html)
34
35## Configuration
36
37In `data/config.json.php`.
38
39See also [Plugin System](Plugin-System.html).
40
41### Credentials
42
43> You shouldn't edit those.
44
45**login**: Login username.
46**hash**: Generated password hash.
47**salt**: Password salt.
48
49### General
50
51**title**: Shaarli's instance title.
52**header_link**: Link to the homepage.
53**links_per_page**: Number of shaares displayed per page.
54**timezone**: See [the list of supported timezones](http://php.net/manual/en/timezones.php).
55**enabled_plugins**: List of enabled plugins.
56
57### Security
58
59**session_protection_disabled**: Disable session cookie hijacking protection (not recommended).
60It might be useful if your IP adress often changes.
61**ban_after**: Failed login attempts before being IP banned.
62**ban_duration**: IP ban duration in seconds.
63**open_shaarli**: Anyone can add a new link while logged out if enabled.
64**trusted_proxies**: List of trusted IP which won't be banned after failed login attemps. Useful if Shaarli is behind a reverse proxy.
65**allowed_protocols**: List of allowed protocols in shaare URLs or markdown-rendered descriptions. Useful if you want to store `javascript:` links (bookmarklets) in Shaarli (default: `["ftp", "ftps", "magnet"]`).
66
67### Resources
68
69**data_dir**: Data directory.
70**datastore**: Shaarli's links database file path.
71**history**: Shaarli's operation history file path.
72**updates**: File path for the ran updates file.
73**log**: Log file path.
74**update_check**: Last update check file path.
75**raintpl_tpl**: Templates directory.
76**raintpl_tmp**: Template engine cache directory.
77**thumbnails_cache**: Thumbnails cache directory.
78**page_cache**: Shaarli's internal cache directory.
79**ban_file**: Banned IP file path.
80
81### Updates
82
83**check_updates**: Enable or disable update check to the git repository.
84**check_updates_branch**: Git branch used to check updates (e.g. `stable` or `master`).
85**check_updates_interval**: Look for new version every N seconds (default: every day).
86
87### Privacy
88
89**default_private_links**: Check the private checkbox by default for every new link.
90**hide_public_links**: All links are hidden while logged out.
91**hide_timestamps**: Timestamps are hidden.
92
93### Feed
94
95**rss_permalinks**: Enable this to redirect RSS links to Shaarli's permalinks instead of shaared URL.
96**show_atom**: Display ATOM feed button.
97
98### Thumbnail
99
100**enable_thumbnails**: Enable or disable thumbnail display.
101**enable_localcache**: Enable or disable local cache.
102
103### Redirector
104
105**url**: Redirector URL, such as `anonym.to`.
106**encode_url**: Enable this if the redirector needs encoded URL to work properly.
107
108## Configuration file example
109
110```json
111<?php /*
112{
113 "credentials": {
114 "login": "<login>",
115 "hash": "<password hash>",
116 "salt": "<password salt>"
117 },
118 "security": {
119 "ban_after": 4,
120 "session_protection_disabled": false,
121 "ban_duration": 1800,
122 "trusted_proxies": [
123 "1.2.3.4",
124 "5.6.7.8"
125 ],
126 "allowed_protocols": [
127 "ftp",
128 "ftps",
129 "magnet"
130 ]
131 },
132 "resources": {
133 "data_dir": "data",
134 "config": "data\/config.php",
135 "datastore": "data\/datastore.php",
136 "ban_file": "data\/ipbans.php",
137 "updates": "data\/updates.txt",
138 "log": "data\/log.txt",
139 "update_check": "data\/lastupdatecheck.txt",
140 "raintpl_tmp": "tmp\/",
141 "raintpl_tpl": "tpl\/",
142 "thumbnails_cache": "cache",
143 "page_cache": "pagecache"
144 },
145 "general": {
146 "check_updates": true,
147 "rss_permalinks": true,
148 "links_per_page": 20,
149 "default_private_links": true,
150 "enable_thumbnails": true,
151 "enable_localcache": true,
152 "check_updates_branch": "stable",
153 "check_updates_interval": 86400,
154 "enabled_plugins": [
155 "markdown",
156 "wallabag",
157 "archiveorg"
158 ],
159 "timezone": "Europe\/Paris",
160 "title": "My Shaarli",
161 "header_link": "?"
162 },
163 "extras": {
164 "show_atom": false,
165 "hide_public_links": false,
166 "hide_timestamps": false,
167 "open_shaarli": false,
168 "redirector": "http://anonym.to/?",
169 "redirector_encode_url": false
170 },
171 "general": {
172 "header_link": "?",
173 "links_per_page": 20,
174 "enabled_plugins": [
175 "markdown",
176 "wallabag"
177 ],
178 "timezone": "Europe\/Paris",
179 "title": "My Shaarli"
180 },
181 "updates": {
182 "check_updates": true,
183 "check_updates_branch": "stable",
184 "check_updates_interval": 86400
185 },
186 "feed": {
187 "rss_permalinks": true,
188 "show_atom": false
189 },
190 "privacy": {
191 "default_private_links": true,
192 "hide_public_links": false,
193 "hide_timestamps": false
194 },
195 "thumbnail": {
196 "enable_thumbnails": true,
197 "enable_localcache": true
198 },
199 "redirector": {
200 "url": "http://anonym.to/?",
201 "encode_url": false
202 },
203 "plugins": {
204 "WALLABAG_URL": "http://demo.wallabag.org",
205 "WALLABAG_VERSION": "1"
206 }
207} ?>
208```
209
210## Additional configuration
211
212The playvideos plugin may require that you adapt your server's
213[Content Security Policy](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md#troubleshooting)
214configuration to work properly.[](.html)
215
diff --git a/doc/md/Shaarli-images.md b/doc/md/Shaarli-images.md
new file mode 100644
index 00000000..25f6cfdd
--- /dev/null
+++ b/doc/md/Shaarli-images.md
@@ -0,0 +1,72 @@
1## Get and run a Shaarli image
2
3### DockerHub repository
4The images can be found in the [`shaarli/shaarli`](https://hub.docker.com/r/shaarli/shaarli/)
5repository.
6
7### Available image tags
8- `latest`: master branch (tarball release)
9- `stable`: stable branch (tarball release)
10- `dev`: master branch (Git clone)
11
12All images rely on:
13- [Debian 8 Jessie](https://hub.docker.com/_/debian/)
14- [PHP5-FPM](http://php-fpm.org/)
15- [Nginx](http://nginx.org/)
16
17### Download from DockerHub
18```bash
19$ docker pull shaarli/shaarli
20latest: Pulling from shaarli/shaarli
2132716d9fcddb: Pull complete
2284899d045435: Pull complete
234b6ad7444763: Pull complete
24e0345ef7a3e0: Pull complete
255c1dd344094f: Pull complete
266422305a200b: Pull complete
277d63f861dbef: Pull complete
283eb97210645c: Pull complete
29869319d746ff: Already exists
30869319d746ff: Pulling fs layer
31902b87aaaec9: Already exists
32Digest: sha256:f836b4627b958b3f83f59c332f22f02fcd495ace3056f2be2c4912bd8704cc98
33Status: Downloaded newer image for shaarli/shaarli:latest
34```
35
36### Create and start a new container from the image
37```bash
38# map the host's :8000 port to the container's :80 port
39$ docker create -p 8000:80 shaarli/shaarli
40d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
41
42# launch the container in the background
43$ docker start d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
44d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
45
46# list active containers
47$ docker ps
48CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 15 seconds ago Up 4 seconds 0.0.0.0:8000->80/tcp backstabbing_galileo
50```
51
52### Stop and destroy a container
53```bash
54$ docker stop backstabbing_galileo # those docker guys are really rude to physicists!
55backstabbing_galileo
56
57# check the container is stopped
58$ docker ps
59CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60
61# list ALL containers
62$ docker ps -a
63CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 5 minutes ago Exited (0) 48 seconds ago backstabbing_galileo
65
66# destroy the container
67$ docker rm backstabbing_galileo # let's put an end to these barbarian practices
68backstabbing_galileo
69
70$ docker ps -a
71CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72```
diff --git a/doc/md/Static-analysis.md b/doc/md/Static-analysis.md
new file mode 100644
index 00000000..ee4f5978
--- /dev/null
+++ b/doc/md/Static-analysis.md
@@ -0,0 +1,11 @@
1## WIP
2This topic is currently being discussed here:
3- [Fix coding style (static analysis)](https://github.com/shaarli/Shaarli/issues/95) (#95)
4- [Continuous Integration tools & features](https://github.com/shaarli/Shaarli/issues/130) (#130)
5
6### Usage
7Static analysis tools can be installed with Composer, and used through Shaarli's [Makefile](https://github.com/shaarli/Shaarli/blob/master/Makefile).
8
9For an overview of the available features, see:
10- [Code quality: Makefile to run static code checkers](https://github.com/shaarli/Shaarli/pull/124) (#124)
11- [Run PHPCS against different coding standards](https://github.com/shaarli/Shaarli/pull/276) (#276)
diff --git a/doc/md/Theming.md b/doc/md/Theming.md
new file mode 100644
index 00000000..ae68db38
--- /dev/null
+++ b/doc/md/Theming.md
@@ -0,0 +1,84 @@
1## Foreword
2
3There are two ways of customizing how Shaarli looks:
4
51. by using a custom CSS to override Shaarli's CSS
62. by using a full theme that provides its own RainTPL templates, CSS and Javascript resources
7
8## Custom CSS
9
10Shaarli's appearance can be modified by adding CSS rules to:
11- Shaarli < `v0.9.0`: `inc/user.css`
12- Shaarli >= `v0.9.0`: `data/user.css`
13
14This file allows overriding rules defined in the template CSS files (only add changed rules), or define a whole new theme.
15
16**Note**: Do not edit `tpl/default/css/shaarli.css`! Your changes would be overridden when updating Shaarli.
17
18See also [[Download CSS styles from an OPML list]]
19
20## Themes
21
22_WARNING - This feature is currently being worked on and will be improved in the next releases. Experimental._
23
24Installation:
25- find a theme you'd like to install
26- copy or clone the theme folder under `tpl/<a_sweet_theme>`
27- enable the theme:
28 - Shaarli < `v0.9.0`: edit `data/config.json.php` and set the value of `raintpl_tpl` to the new theme name:
29 `"raintpl_tpl": "tpl\/my-template\/"`
30 - Shaarli >= `v0.9.0`: select the theme through the _Tools_ page
31
32## Community CSS & themes
33
34### Custom CSS
35
36- [mrjovanovic/serious-theme-shaarli](https://github.com/mrjovanovic/serious-theme-shaarli) - A serious theme for Shaarli
37- [shaarli/shaarli-themes](https://github.com/shaarli/shaarli-themes)
38
39### Themes
40
41- [AkibaTech/Shaarli Superhero Theme](https://github.com/AkibaTech/Shaarli---SuperHero-Theme) - A template/theme for Shaarli
42- [alexisju/albinomouse-template](https://github.com/alexisju/albinomouse-template) - A full template for Shaarli
43- [ArthurHoaro/shaarli-launch](https://github.com/ArthurHoaro/shaarli-launch) - Customizable Shaarli theme
44- [dhoko/ShaarliTemplate](https://github.com/dhoko/ShaarliTemplate) - A template/theme for Shaarli
45- [kalvn/shaarli-blocks](https://github.com/kalvn/shaarli-blocks) - A template/theme for Shaarli
46- [kalvn/Shaarli-Material](https://github.com/kalvn/Shaarli-Material) - A theme (template) based on Google's Material Design for Shaarli, the superfast delicious clone
47- [ManufacturaInd/shaarli-2004licious-theme](https://github.com/ManufacturaInd/shaarli-2004licious-theme) - A template/theme as a humble homage to the early looks of the del.icio.us site
48
49### Shaarli forks
50
51- [misterair/Limonade](https://github.com/misterair/limonade) - A fork of (legacy) Shaarli with a new template
52- [vivienhaese/shaarlitheme](https://github.com/vivienhaese/shaarlitheme) - A Shaarli fork meant to be run in an openshift instance
53
54## Example installation: AlbinoMouse theme
55
56With the following configuration:
57- Apache 2 / PHP 5.6
58- user sites are enabled, e.g. `/home/user/public_html/somedir` is served as `http://localhost/~user/somedir`
59- `http` is the name of the Apache user
60
61```bash
62$ cd ~/public_html
63
64# clone repositories
65$ git clone https://github.com/shaarli/Shaarli.git shaarli
66$ pushd shaarli/tpl
67$ git clone https://github.com/alexisju/albinomouse-template.git
68$ popd
69
70# set access rights for Apache
71$ chgrp -R http shaarli
72$ chmod g+rwx shaarli shaarli/cache shaarli/data shaarli/pagecache shaarli/tmp
73```
74
75Get config written:
76- go to the freshly installed site
77- fill the install form
78- log in to Shaarli
79
80Edit Shaarli's [[configuration|Shaarli configuration]]:
81```bash
82# the file should be owned by Apache, thus not writeable => sudo
83$ sudo sed -i s=tpl=tpl/albinomouse-template=g shaarli/data/config.php
84```
diff --git a/doc/md/Troubleshooting.md b/doc/md/Troubleshooting.md
new file mode 100644
index 00000000..13005526
--- /dev/null
+++ b/doc/md/Troubleshooting.md
@@ -0,0 +1,123 @@
1# Troubleshooting
2
3## Browser
4
5### Redirection issues (HTTP Referer)
6
7Depending on its configuration and installed plugins, the browser may remove or alter (spoof) HTTP referers, thus preventing Shaarli from properly redirecting between pages.
8
9See:
10- [HTTP referer](https://en.wikipedia.org/wiki/HTTP_referer) (Wikipedia)
11- [Improve online privacy by controlling referrer information](http://www.ghacks.net/2015/01/22/improve-online-privacy-by-controlling-referrer-information/)
12- [Better security, privacy and anonymity in Firefox](http://b.agilob.net/better-security-privacy-and-anonymity-in-firefox/)
13
14### Firefox HTTP Referer options
15
16HTTP settings are available by browsing `about:config`, here are the available settings and their values.
17
18`network.http.sendRefererHeader` - determines when to send the Referer HTTP header
19- 0: Never send the referring URL
20 - not recommended, may break some sites
21- 1: Send only on clicked links
22- 2 (default): Send for links and images
23
24`network.http.referer.XOriginPolicy` - Cross-domain origin policy
25- 0 (default): Always send
26- 1: Send if base domains match
27- 2: Send if hosts match
28
29`network.http.referer.spoofSource` - Referer spoofing (~faking)
30- false (default): real referer
31- true: spoof referer (use target URI as referer)
32 - known to break some functionality in Shaarli
33
34`network.http.referer.trimmingPolicy` - trim the URI not to send a full Referer
35- 0 (default): send full URI
36- 1: scheme+host+port+path
37- 2: scheme+host+port
38
39### Firefox, localhost and redirections
40
41`localhost` is not a proper Fully Qualified Domain Name (FQDN); if Firefox has been set up to spoof referers, or only accept requests from the same base domain/host, Shaarli redirections will not work properly.
42
43To solve this, assign a local domain to your host, e.g.
44```
45127.0.0.1 localhost desktop localhost.lan
46::1 localhost desktop localhost.lan
47```
48
49and browse Shaarli at http://localhost.lan/.
50
51Related threads:
52- [What is localhost.localdomain for?](https://bbs.archlinux.org/viewtopic.php?id=156064)
53- [Stop returning to the first page after editing a bookmark from another page](https://github.com/shaarli/Shaarli/issues/311)
54
55## Login
56
57### I forgot my password!
58
59Delete the file `data/config.php` and display the page again. You will be asked for a new login/password.
60
61### I'm locked out - Login bruteforce protection
62
63Login form is protected against brute force attacks: 4 failed logins will ban the IP address from login for 30 minutes. Banned IPs can still browse links.
64
65To remove the current IP bans, delete the file `data/ipbans.php`
66
67### List of all login attempts
68
69The file `data/log.txt` shows all logins (successful or failed) and bans/lifted bans.
70Search for `failed` in this file to look for unauthorized login attempts.
71
72## Hosting problems
73
74### Old PHP versions
75
76 * On **free.fr** : free.fr now support php 5.6.x([link](http://les.pages.perso.chez.free.fr/migrations/php5v6.io))and so support now the tag autocompletion but you have to do the following : At the root of your webspace create a `sessions` directory and a `.htaccess` file containing:
77
78```ini
79<IfDefine Free>
80php56 1
81</IfDefine>
82```
83
84 * If you have an error such as: `Parse error: syntax error, unexpected '=', expecting '(' in /links/index.php on line xxx`, it means that your host is using php4, not php5. Shaarli requires php 5.1. Try changing the file extension to `.php5`
85 * On **1and1** : If you add the link from the page (and not from the bookmarklet), Shaarli will no be able to get the title of the page. You will have to enter it manually. (Because they have disabled the ability to download a file through HTTP).
86 * If you have the error `Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /…/index.php on line xxx`, it means that your host has disabled the ability to fetch a file by HTTP in the php config (Typically in 1and1 hosting). Bad host. Change host. Or comment the following lines:
87
88```php
89//list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive.
90// FIXME: Decode charset according to charset specified in either 1) HTTP response headers or 2) <head> in html
91//if (strpos($status,'200 OK')) $title=html_extract_title($data);
92```
93
94 * On hosts which forbid outgoing HTTP requests (such as free.fr), some thumbnails will not work.
95 * On **lost-oasis**, RSS doesn't work correctly, because of this message at the begining of the RSS/ATOM feed : `<? // tout ce qui est charge ici (generalement des includes et require) est charge en permanence. ?>`. To fix this, remove this message from `php-include/prepend.php`
96
97### Dates are not properly formatted
98
99Shaarli tries to sniff the language of the browser (using HTTP_ACCEPT_LANGUAGE headers) and choose a date format accordingly. But Shaarli can only use the date formats (and more generaly speaking, the locales) provided by the webserver. So even if you have a browser in French, you may end up with dates in US format (it's the case on sebsauvage.net :-( )
100
101### Problems on CentOS servers
102
103On **CentOS**/RedHat derivatives, you may need to install the `php-mbstring` package.
104
105
106### My session expires! I can't stay logged in
107
108This can be caused by several things:
109
110* Your php installation may not have a proper directory setup for session files. (eg. on Free.fr you need to create a `session` directory on the root of your website.) You may need to create the session directory of set it up.
111* Most hosts regularly clean the temporary and session directories. Your host may be cleaning those directories too aggressively (eg.OVH hosts), forcing an expire of the session. You may want to set the session directory in your web root. (eg. Create the `sessions` subdirectory and add `ini_set('session.save_path', $_SERVER['DOCUMENT_ROOT'].'/../sessions');`. Make sure this directory is not browsable !)
112* If your IP address changes during surfing, Shaarli will force expire your session for security reasons (to prevent session cookie hijacking). This can happen when surfing from WiFi or 3G (you may have switched WiFi/3G access point), or in some corporate/university proxies which use load balancing (and may have proxies with several external IP addresses).
113* Some browser addons may interfer with HTTP headers (ipfuck/ipflood/GreaseMonkey…). Try disabling those.
114* You may be using OperaTurbo or OperaMini, which use their own proxies which may change from time to time.
115* If you have another application on the same webserver where Shaarli is installed, these application may forcefully expire php sessions.
116
117## Sessions do not seem to work correctly on your server
118
119Follow the instructions in the error message. Make sure you are accessing shaarli via a direct IP address or a proper hostname. If you have **no dots** in the hostname (e.g. `localhost` or `http://my-webserver/shaarli/`), some browsers will not store cookies at all (this respects the [HTTP cookie specification](http://curl.haxx.se/rfc/cookie_spec.html)).
120
121### pubsubhubbub support
122
123Download [publisher.php](https://pubsubhubbub.googlecode.com/git/publisher_clients/php/library/publisher.php) at the root of your Shaarli installation and set `$GLOBALS['config']['PUBSUBHUB_URL']` in your `config.php`
diff --git a/doc/md/Unit-tests.md b/doc/md/Unit-tests.md
new file mode 100644
index 00000000..19838721
--- /dev/null
+++ b/doc/md/Unit-tests.md
@@ -0,0 +1,152 @@
1### Setup your environment for tests
2
3The framework used is [PHPUnit](https://phpunit.de/); it can be installed with [Composer](https://getcomposer.org/), which is a dependency management tool.
4
5Regarding Composer, you can either use:
6* a system-wide version, e.g. installed through your distro's package manager
7* a local version, downloadable [here](https://getcomposer.org/download/)
8
9#### Sample usage
10
11```bash
12# system-wide version
13$ composer install
14$ composer update
15
16# local version
17$ php composer.phar self-update
18$ php composer.phar install
19$ php composer.phar update
20```
21
22#### Install Shaarli dev dependencies
23
24```bash
25$ cd /path/to/shaarli
26$ composer update
27```
28
29#### Install and enable Xdebug to generate PHPUnit coverage reports
30
31For Debian-based distros:
32```bash
33$ aptitude install php5-xdebug
34```
35For ArchLinux:
36```bash
37$ pacman -S xdebug
38```
39
40Then add the following line to `/etc/php/php.ini`:
41```ini
42zend_extension=xdebug.so
43```
44
45#### Run unit tests
46
47Successful test suite:
48```bash
49$ make test
50
51-------
52PHPUNIT
53-------
54PHPUnit 4.6.9 by Sebastian Bergmann and contributors.
55
56Configuration read from /home/virtualtam/public_html/shaarli/phpunit.xml
57
58....................................
59
60Time: 759 ms, Memory: 8.25Mb
61
62OK (36 tests, 65 assertions)
63```
64
65Test suite with failures and errors:
66```bash
67$ make test
68-------
69PHPUNIT
70-------
71PHPUnit 4.6.9 by Sebastian Bergmann and contributors.
72
73Configuration read from /home/virtualtam/public_html/shaarli/phpunit.xml
74
75E..FF...............................
76
77Time: 802 ms, Memory: 8.25Mb
78
79There was 1 error:
80
811) LinkDBTest::testConstructLoggedIn
82Missing argument 2 for LinkDB::__construct(), called in /home/virtualtam/public_html/shaarli/tests/Link\
83DBTest.php on line 79 and defined
84
85/home/virtualtam/public_html/shaarli/application/LinkDB.php:58
86/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:79
87
88--
89
90There were 2 failures:
91
921) LinkDBTest::testCheckDBNew
93Failed asserting that two strings are equal.
94--- Expected
95+++ Actual
96@@ @@
97-'e3edea8ea7bb50be4bcb404df53fbb4546a7156e'
98+'85eab0c610d4f68025f6ed6e6b6b5fabd4b55834'
99
100/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:121
101
1022) LinkDBTest::testCheckDBLoad
103Failed asserting that two strings are equal.
104--- Expected
105+++ Actual
106@@ @@
107-'e3edea8ea7bb50be4bcb404df53fbb4546a7156e'
108+'85eab0c610d4f68025f6ed6e6b6b5fabd4b55834'
109
110/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:133
111
112FAILURES!
113Tests: 36, Assertions: 63, Errors: 1, Failures: 2.
114```
115
116#### Test results and coverage
117
118By default, PHPUnit will run all suitable tests found under the `tests` directory.
119
120Each test has 3 possible outcomes:
121* `.` - success
122* `F` - failure: the test was run but its results are invalid
123 * the code does not behave as expected
124 * dependencies to external elements: globals, session, cache...
125* `E` - error: something went wrong and the tested code has crashed
126 * typos in the code, or in the test code
127 * dependencies to missing external elements
128
129If Xdebug has been installed and activated, two coverage reports will be generated:
130* a summary in the console
131* a detailed HTML report with metrics for tested code
132 * to open it in a web browser: `firefox coverage/index.html &`
133
134### Executing specific tests
135
136Add a [`@group`](https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group) annotation in a test class or method comment:
137
138```php
139/**
140 * Netscape bookmark import
141 * @group WIP
142 */
143class BookmarkImportTest extends PHPUnit_Framework_TestCase
144{
145 [...]
146}
147```
148
149To run all tests annotated with `@group WIP`:
150```bash
151$ vendor/bin/phpunit --group WIP tests/
152```
diff --git a/doc/md/Upgrade-and-migration.md b/doc/md/Upgrade-and-migration.md
new file mode 100644
index 00000000..7348891f
--- /dev/null
+++ b/doc/md/Upgrade-and-migration.md
@@ -0,0 +1,194 @@
1## Preparation
2
3### Note your current version
4
5If anything goes wrong, it's important for us to know which version you're upgrading from.
6The current version is present in the `version.php` file.
7
8### Backup your data
9
10Shaarli stores all user data under the `data` directory:
11- `data/config.php` - main configuration file
12- `data/datastore.php` - bookmarked links
13- `data/ipbans.php` - banned IP addresses
14- `data/updates.txt` - contains all automatic update to the configuration and datastore files already run
15
16See [[Shaarli configuration]] for more information about Shaarli resources.
17
18It is recommended to backup this repository _before_ starting updating/upgrading Shaarli:
19- users with SSH access: copy or archive the directory to a temporary location
20- users with FTP access: download a local copy of your Shaarli installation using your favourite client
21
22### Migrating data from a previous installation
23
24As all user data is kept under `data`, this is the only directory you need to worry about when migrating to a new installation, which corresponds to the following steps:
25
26- backup the `data` directory
27- install or update Shaarli:
28 - fresh installation - see [[Download and installation]]
29 - update - see the following sections
30- check or restore the `data` directory
31
32## Recommended : Upgrading from release archives
33
34All tagged revisions can be downloaded as tarballs or ZIP archives from the [releases](https://github.com/shaarli/Shaarli/releases) page.
35
36We recommend that you use the latest release tarball with the `-full` suffix. It contains the dependencies, please read [[Download and installation]] for `git` complete instructions.
37
38Once downloaded, extract the archive locally and update your remote installation (e.g. via FTP) -be sure you keep the content of the `data` directory!
39
40After upgrading, access your fresh Shaarli installation from a web browser; the configuration and data store will then be automatically updated, and new settings added to `data/config.json.php` (see [[Shaarli configuration]] for more details).
41
42## Upgrading with Git
43
44### Updating a community Shaarli
45
46If you have installed Shaarli from the [community Git repository](Download#clone-with-git-recommended), simply [pull new changes](https://www.git-scm.com/docs/git-pull) from your local clone:
47
48```bash
49$ cd /path/to/shaarli
50$ git pull
51
52From github.com:shaarli/Shaarli
53 * branch master -> FETCH_HEAD
54Updating ebd67c6..521f0e6
55Fast-forward
56 application/Url.php | 1 +
57 shaarli_version.php | 2 +-
58 tests/Url/UrlTest.php | 1 +
59 3 files changed, 3 insertions(+), 1 deletion(-)
60```
61
62Shaarli >= `v0.8.x`: install/update third-party PHP dependencies using [Composer](https://getcomposer.org/):
63
64```bash
65$ composer install --no-dev
66
67Loading composer repositories with package information
68Updating dependencies
69 - Installing shaarli/netscape-bookmark-parser (v1.0.1)
70 Downloading: 100%
71```
72
73### Migrating and upgrading from Sebsauvage's repository
74
75If you have installed Shaarli from [Sebsauvage's original Git repository](https://github.com/sebsauvage/Shaarli), you can use [Git remotes](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) to update your working copy.
76
77The following guide assumes that:
78- you have a basic knowledge of Git [branching](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) and [remote repositories](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes)
79- the default remote is named `origin` and points to Sebsauvage's repository
80- the current branch is `master`
81 - if you have personal branches containing customizations, you will need to [rebase them](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) after the upgrade; beware though, a lot of changes have been made since the community fork has been created, so things are very likely to break!
82- the working copy is clean:
83 - no versioned file has been locally modified
84 - no untracked files are present
85
86#### Step 0: show repository information
87
88```bash
89$ cd /path/to/shaarli
90
91$ git remote -v
92origin https://github.com/sebsauvage/Shaarli (fetch)
93origin https://github.com/sebsauvage/Shaarli (push)
94
95$ git branch -vv
96* master 029f75f [origin/master] Update README.md
97
98$ git status
99On branch master
100Your branch is up-to-date with 'origin/master'.
101nothing to commit, working directory clean
102```
103
104#### Step 1: update Git remotes
105
106```
107$ git remote rename origin sebsauvage
108$ git remote -v
109sebsauvage https://github.com/sebsauvage/Shaarli (fetch)
110sebsauvage https://github.com/sebsauvage/Shaarli (push)
111
112$ git remote add origin https://github.com/shaarli/Shaarli
113$ git fetch origin
114
115remote: Counting objects: 3015, done.
116remote: Compressing objects: 100% (19/19), done.
117remote: Total 3015 (delta 446), reused 457 (delta 446), pack-reused 2550
118Receiving objects: 100% (3015/3015), 2.59 MiB | 918.00 KiB/s, done.
119Resolving deltas: 100% (1899/1899), completed with 48 local objects.
120From https://github.com/shaarli/Shaarli
121 * [new branch] master -> origin/master
122 * [new branch] stable -> origin/stable
123[...]
124 * [new tag] v0.6.4 -> v0.6.4
125 * [new tag] v0.7.0 -> v0.7.0
126```
127
128#### Step 2: use the stable community branch
129
130```bash
131$ git checkout origin/stable -b stable
132Branch stable set up to track remote branch stable from origin.
133Switched to a new branch 'stable'
134
135$ git branch -vv
136 master 029f75f [sebsauvage/master] Update README.md
137* stable 890afc3 [origin/stable] Merge pull request #509 from ArthurHoaro/v0.6.5
138```
139
140Shaarli >= `v0.8.x`: install/update third-party PHP dependencies using [Composer](https://getcomposer.org/):
141
142```bash
143$ composer install --no-dev
144
145Loading composer repositories with package information
146Updating dependencies
147 - Installing shaarli/netscape-bookmark-parser (v1.0.1)
148 Downloading: 100%
149```
150
151Optionally, you can delete information related to the legacy version:
152
153```bash
154$ git branch -D master
155Deleted branch master (was 029f75f).
156
157$ git remote remove sebsauvage
158
159$ git remote -v
160origin https://github.com/shaarli/Shaarli (fetch)
161origin https://github.com/shaarli/Shaarli (push)
162
163$ git gc
164Counting objects: 3317, done.
165Delta compression using up to 8 threads.
166Compressing objects: 100% (1237/1237), done.
167Writing objects: 100% (3317/3317), done.
168Total 3317 (delta 2050), reused 3301 (delta 2034)to
169```
170
171#### Step 3: configuration
172
173After migrating, access your fresh Shaarli installation from a web browser; the configuration will then be automatically updated, and new settings added to `data/config.php` (see [[Shaarli configuration]] for more details).
174
175## Troubleshooting
176
177If the solutions provided here doesn't work, please open an issue specifying which version you're upgrading from and to.
178
179### You must specify an integer as a key
180
181In `v0.8.1` we changed how link keys are handled (from timestamps to incremental integers).
182Take a look at `data/updates.txt` content.
183
184#### `updates.txt` contains `updateMethodDatastoreIds`
185
186Try to delete it and refresh your page while being logged in.
187
188#### `updates.txt` doesn't exists or doesn't contain `updateMethodDatastoreIds`
189
190 1. Create `data/updates.txt` if it doesn't exist.
191 2. Paste this string in the update file `;updateMethodRenameDashTags;`
192 3. Login to Shaarli.
193 4. Delete the update file.
194 5. Refresh.
diff --git a/doc/md/Versioning-and-Branches.md b/doc/md/Versioning-and-Branches.md
new file mode 100644
index 00000000..e1d998e0
--- /dev/null
+++ b/doc/md/Versioning-and-Branches.md
@@ -0,0 +1,75 @@
1**WORK IN PROGRESS**
2
3It's important to understand how Shaarli branches work, especially if you're maintaining a 3rd party tools for Shaarli (theme, plugin, etc.), to be sure stay compatible.
4
5## `master` branch
6
7The `master` branch is the development branch. Any new change MUST go through this branch using Pull Requests.
8
9Remarks:
10
11 * This branch shouldn't be used for production as it isn't necessary stable.
12 * 3rd party aren't required to be compatible with the latest changes.
13 * Official plugins, themes and libraries (contained within Shaarli organization repos) must be compatible with the master branch.
14 * The version in this branch is always `dev`.
15
16## `v0.x` branch
17
18This `v0.x` branch, points to the latest `v0.x.y` release.
19
20Explanation:
21
22When a new version is released, it might contains a major bug which isn't detected right away. For example, a new PHP version is released, containing backward compatibility issue which doesn't work with Shaarli.
23
24In this case, the issue is fixed in the `master` branch, and the fix is backported the to the `v0.x` branch. Then a new release is made from the `v0.x` branch.
25
26This workflow allow us to fix any major bug detected, without having to release bleeding edge feature too soon.
27
28## `latest` branch
29
30This branch point the latest release. It recommended to use it to get the latest tested changes.
31
32## `stable` branch
33
34The `stable` branch doesn't contain any major bug, and is one major digit version behind the latest release.
35
36For example, the current latest release is `v0.8.3`, the stable branch is an alias to the latest `v0.7.x` release. When the `v0.9.0` version will be released, the stable will move to the latest `v0.8.x` release.
37
38Remarks:
39
40 * Shaarli release pace isn't fast, and the stable branch might be a few months behind the latest release.
41
42## Releases
43
44Releases are always made from the latest `v0.x` branch.
45
46Note that for every release, we manually generate a tarball which contains all Shaarli dependencies, making Shaarli's installation only one step.
47
48## Advices on 3rd party git repos workflow
49
50### Versioning
51
52Any time a new Shaarli release is published, you should publish a new release of your repo if the changes affected you since the latest release (take a look at the [changelog](https://github.com/shaarli/Shaarli/releases) (*Draft* means not released yet) and the commit log (like [`tpl` folder](https://github.com/shaarli/Shaarli/commits/master/tpl/default) for themes)). You can either:
53
54 - use the Shaarli version number, with your repo version. For example, if Shaarli `v0.8.3` is released, publish a `v0.8.3-1` release, where `v0.8.3` states Shaarli compatibility and `-1` is your own version digit for the current Shaarli version.
55 - use your own versioning scheme, and state Shaarli compatibility in the release description.
56
57Using this, any user will be able to pick the release matching his own Shaarli version.
58
59### Major bugfix backport releases
60
61To be able to support backported fixes, it recommended to use our workflow:
62
63```bash
64# In master, fix the major bug
65git commit -m "Katastrophe"
66git push origin master
67# Get your commit hash
68git log --format="%H" -n 1
69# Create a new branch from your latest release, let's say v0.8.2-1 (the tag name)
70git checkout -b katastrophe v0.8.2-1
71# Backport the fix commit to your brand new branch
72git cherry-pick <fix commit hash>
73git push origin katastrophe
74# Then you just have to make a new release from the `katastrophe` branch tagged `v0.8.3-1`
75```
diff --git a/doc/md/_Footer.md b/doc/md/_Footer.md
new file mode 100644
index 00000000..648b1298
--- /dev/null
+++ b/doc/md/_Footer.md
@@ -0,0 +1 @@
_Shaarli, the personal, minimalist, super-fast, database-free bookmarking service_ \ No newline at end of file
diff --git a/doc/md/_Sidebar.md b/doc/md/_Sidebar.md
new file mode 100644
index 00000000..fe0e4229
--- /dev/null
+++ b/doc/md/_Sidebar.md
@@ -0,0 +1,45 @@
1- [[Home]]
2- Setup
3 - [[Download and Installation]]
4 - [[Upgrade and migration]]
5 - [[Server requirements]]
6 - [[Server configuration]]
7 - [[Server security]]
8 - [[Shaarli configuration]]
9 - [[Plugins]]
10- Docker
11 - [[Docker 101]]
12 - [[Shaarli images]]
13 - [[Reverse proxy configuration]]
14 - [[Docker resources]]
15- Usage
16 - [[Features]]
17 - [[Bookmarklet]]
18 - [[Browsing and Searching]]
19 - [[Firefox share]]
20 - [[RSS feeds]]
21 - [[REST API]]
22- How To
23 - [[Backup, restore, import and export]]
24 - [[Copy an existing installation over SSH and serve it locally]]
25 - [[Create and serve multiple Shaarlis (farm)]]
26 - [[Download CSS styles from an OPML list]]
27 - [[Datastore hacks]]
28- [[Troubleshooting]]
29- Development:
30 - [[Development guidelines]]
31 - [[Continuous integration tools]]
32 - [[GnuPG signature]]
33 - [[Coding guidelines]]
34 - [[Directory structure]]
35 - [[3rd party libraries]]
36 - [[Plugin System]]
37 - [[Release Shaarli]]
38 - [[Versioning and Branches]]
39 - [[Security]]
40 - [[Static analysis]]
41 - [[Theming]]
42 - [[Unit tests]]
43- About
44 - [[FAQ]]
45 - [[Community & Related software]]
diff --git a/doc/md/config.json b/doc/md/config.json
new file mode 100644
index 00000000..cc4de307
--- /dev/null
+++ b/doc/md/config.json
@@ -0,0 +1,6 @@
1{
2 "useSideMenu": true,
3 "lineBreaks": "gfm",
4 "additionalFooterText": "",
5 "title": "Shaarli documentation"
6} \ No newline at end of file
diff --git a/doc/md/github-markdown.css b/doc/md/github-markdown.css
new file mode 100644
index 00000000..581350ae
--- /dev/null
+++ b/doc/md/github-markdown.css
@@ -0,0 +1,287 @@
1#local-sidebar {
2 width: 230px;
3 float: right;
4 position: relative;
5 z-index: 4;
6 background-color: #fff;
7 border: 1px solid #e2e2e2;
8 border-radius: 3px;
9}
10
11body {
12 font-family: Helvetica, arial, sans-serif;
13 font-size: 14px;
14 line-height: 1.6;
15 padding-top: 10px;
16 padding-bottom: 10px;
17 background-color: white;
18 padding: 10px 20%; }
19
20body > *:first-child {
21 margin-top: 0 !important; }
22body > *:last-child {
23 margin-bottom: 0 !important; }
24
25a {
26 color: #4183C4; }
27a.absent {
28 color: #cc0000; }
29a.anchor {
30 display: block;
31 padding-left: 30px;
32 margin-left: -30px;
33 cursor: pointer;
34 position: absolute;
35 top: 0;
36 left: 0;
37 bottom: 0; }
38
39h1, h2, h3, h4, h5, h6 {
40 margin: 20px 0 10px;
41 padding: 0;
42 font-weight: bold;
43 -webkit-font-smoothing: antialiased;
44 cursor: text;
45 position: relative; }
46
47h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
48 background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;
49 text-decoration: none; }
50
51h1 tt, h1 code {
52 font-size: inherit; }
53
54h2 tt, h2 code {
55 font-size: inherit; }
56
57h3 tt, h3 code {
58 font-size: inherit; }
59
60h4 tt, h4 code {
61 font-size: inherit; }
62
63h5 tt, h5 code {
64 font-size: inherit; }
65
66h6 tt, h6 code {
67 font-size: inherit; }
68
69h1 {
70 font-size: 28px;
71 color: black; }
72
73h2 {
74 font-size: 24px;
75 border-bottom: 1px solid #cccccc;
76 color: black; }
77
78h3 {
79 font-size: 18px; }
80
81h4 {
82 font-size: 16px; }
83
84h5 {
85 font-size: 14px; }
86
87h6 {
88 color: #777777;
89 font-size: 14px; }
90
91p, blockquote, ol, dl, table, pre {
92 margin: 15px 0; }
93
94hr {
95 background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0;
96 border: 0 none;
97 color: #cccccc;
98 height: 4px;
99 padding: 0; }
100
101body > h2:first-child {
102 margin-top: 0;
103 padding-top: 0; }
104body > h1:first-child {
105 margin-top: 0;
106 padding-top: 0; }
107 body > h1:first-child + h2 {
108 margin-top: 0;
109 padding-top: 0; }
110body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
111 margin-top: 0;
112 padding-top: 0; }
113
114a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
115 margin-top: 0;
116 padding-top: 0; }
117
118h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
119 margin-top: 0; }
120
121li p.first {
122 display: inline-block; }
123
124ul, ol {
125 padding-left: 30px; }
126
127ul :first-child, ol :first-child {
128 margin-top: 0; }
129
130ul :last-child, ol :last-child {
131 margin-bottom: 0; }
132
133dl {
134 padding: 0; }
135 dl dt {
136 font-size: 14px;
137 font-weight: bold;
138 font-style: italic;
139 padding: 0;
140 margin: 15px 0 5px; }
141 dl dt:first-child {
142 padding: 0; }
143 dl dt > :first-child {
144 margin-top: 0; }
145 dl dt > :last-child {
146 margin-bottom: 0; }
147 dl dd {
148 margin: 0 0 15px;
149 padding: 0 15px; }
150 dl dd > :first-child {
151 margin-top: 0; }
152 dl dd > :last-child {
153 margin-bottom: 0; }
154
155blockquote {
156 border-left: 4px solid #dddddd;
157 padding: 0 15px;
158 color: #777777; }
159 blockquote > :first-child {
160 margin-top: 0; }
161 blockquote > :last-child {
162 margin-bottom: 0; }
163
164table {
165 padding: 0; }
166 table tr {
167 border-top: 1px solid #cccccc;
168 background-color: white;
169 margin: 0;
170 padding: 0; }
171 table tr:nth-child(2n) {
172 background-color: #f8f8f8; }
173 table tr th {
174 font-weight: bold;
175 border: 1px solid #cccccc;
176 text-align: left;
177 margin: 0;
178 padding: 6px 13px; }
179 table tr td {
180 border: 1px solid #cccccc;
181 text-align: left;
182 margin: 0;
183 padding: 6px 13px; }
184 table tr th :first-child, table tr td :first-child {
185 margin-top: 0; }
186 table tr th :last-child, table tr td :last-child {
187 margin-bottom: 0; }
188
189img {
190 max-width: 100%; }
191
192span.frame {
193 display: block;
194 overflow: hidden; }
195 span.frame > span {
196 border: 1px solid #dddddd;
197 display: block;
198 float: left;
199 overflow: hidden;
200 margin: 13px 0 0;
201 padding: 7px;
202 width: auto; }
203 span.frame span img {
204 display: block;
205 float: left; }
206 span.frame span span {
207 clear: both;
208 color: #333333;
209 display: block;
210 padding: 5px 0 0; }
211span.align-center {
212 display: block;
213 overflow: hidden;
214 clear: both; }
215 span.align-center > span {
216 display: block;
217 overflow: hidden;
218 margin: 13px auto 0;
219 text-align: center; }
220 span.align-center span img {
221 margin: 0 auto;
222 text-align: center; }
223span.align-right {
224 display: block;
225 overflow: hidden;
226 clear: both; }
227 span.align-right > span {
228 display: block;
229 overflow: hidden;
230 margin: 13px 0 0;
231 text-align: right; }
232 span.align-right span img {
233 margin: 0;
234 text-align: right; }
235span.float-left {
236 display: block;
237 margin-right: 13px;
238 overflow: hidden;
239 float: left; }
240 span.float-left span {
241 margin: 13px 0 0; }
242span.float-right {
243 display: block;
244 margin-left: 13px;
245 overflow: hidden;
246 float: right; }
247 span.float-right > span {
248 display: block;
249 overflow: hidden;
250 margin: 13px auto 0;
251 text-align: right; }
252
253code, tt {
254 margin: 0 2px;
255 padding: 0 5px;
256 white-space: nowrap;
257 border: 1px solid #eaeaea;
258 background-color: #f8f8f8;
259 border-radius: 3px; }
260
261pre code {
262 margin: 0;
263 padding: 0;
264 white-space: pre;
265 border: none;
266 background: transparent; }
267
268.highlight pre {
269 background-color: #f8f8f8;
270 border: 1px solid #cccccc;
271 font-size: 13px;
272 line-height: 19px;
273 overflow: auto;
274 padding: 6px 10px;
275 border-radius: 3px; }
276
277pre {
278 background-color: #f8f8f8;
279 border: 1px solid #cccccc;
280 font-size: 13px;
281 line-height: 19px;
282 overflow: auto;
283 padding: 6px 10px;
284 border-radius: 3px; }
285 pre code, pre tt {
286 background-color: transparent;
287 border: none; }
diff --git a/doc/md/images/bookmarklet.png b/doc/md/images/bookmarklet.png
new file mode 100644
index 00000000..0262578e
--- /dev/null
+++ b/doc/md/images/bookmarklet.png
Binary files differ
diff --git a/doc/md/images/doc-logo.png b/doc/md/images/doc-logo.png
new file mode 100644
index 00000000..3d8d1787
--- /dev/null
+++ b/doc/md/images/doc-logo.png
Binary files differ
diff --git a/doc/md/images/doc-logo.svg b/doc/md/images/doc-logo.svg
new file mode 100644
index 00000000..37fc6658
--- /dev/null
+++ b/doc/md/images/doc-logo.svg
@@ -0,0 +1,522 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 xmlns:dc="http://purl.org/dc/elements/1.1/"
4 xmlns:cc="http://creativecommons.org/ns#"
5 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6 xmlns:svg="http://www.w3.org/2000/svg"
7 xmlns="http://www.w3.org/2000/svg"
8 xmlns:xlink="http://www.w3.org/1999/xlink"
9 width="600"
10 height="240"
11 id="svg2"
12 version="1.1">
13 <title
14 id="title6384">Shaarli Logo</title>
15 <defs
16 id="defs4">
17 <linearGradient
18 id="linearGradient4405">
19 <stop
20 style="stop-color:#000000;stop-opacity:1;"
21 offset="0"
22 id="stop4407" />
23 <stop
24 style="stop-color:#ffffff;stop-opacity:1;"
25 offset="1"
26 id="stop4409" />
27 </linearGradient>
28 <linearGradient
29 id="linearGradient3780">
30 <stop
31 style="stop-color:#8aea00;stop-opacity:1;"
32 offset="0"
33 id="stop3782" />
34 <stop
35 style="stop-color:#ebff36;stop-opacity:1;"
36 offset="1"
37 id="stop3784" />
38 </linearGradient>
39 <linearGradient
40 id="linearGradient4333-6-7">
41 <stop
42 style="stop-color:#ffffff;stop-opacity:1;"
43 offset="0"
44 id="stop4335-0-4" />
45 <stop
46 style="stop-color:#e1e1e1;stop-opacity:1;"
47 offset="1"
48 id="stop4337-49-0" />
49 </linearGradient>
50 <linearGradient
51 xlink:href="#linearGradient4333-6-7"
52 id="linearGradient4435"
53 gradientUnits="userSpaceOnUse"
54 gradientTransform="translate(-606.51586,-487.01655)"
55 x1="845.7998"
56 y1="637.30005"
57 x2="845.7998"
58 y2="509.84348" />
59 <linearGradient
60 xlink:href="#linearGradient3780"
61 id="linearGradient4437"
62 gradientUnits="userSpaceOnUse"
63 gradientTransform="translate(-1434.0326,365.55395)"
64 x1="1984.2427"
65 y1="-348.63434"
66 x2="1984.2427"
67 y2="-293.69879" />
68 <linearGradient
69 xlink:href="#linearGradient4333-6-7"
70 id="linearGradient4439"
71 gradientUnits="userSpaceOnUse"
72 gradientTransform="translate(-699.19746,-487.01655)"
73 x1="845.7998"
74 y1="637.30005"
75 x2="845.7998"
76 y2="509.84348" />
77 <linearGradient
78 xlink:href="#linearGradient4333-6-7"
79 id="linearGradient4441"
80 gradientUnits="userSpaceOnUse"
81 gradientTransform="translate(-699.87915,-487.01655)"
82 x1="845.7998"
83 y1="637.30005"
84 x2="845.7998"
85 y2="509.84348" />
86 <linearGradient
87 xlink:href="#linearGradient4333-6-7"
88 id="linearGradient4443"
89 gradientUnits="userSpaceOnUse"
90 gradientTransform="translate(-703.2869,-487.01655)"
91 x1="845.7998"
92 y1="637.30005"
93 x2="845.7998"
94 y2="509.84348" />
95 <linearGradient
96 xlink:href="#linearGradient4333-6-7"
97 id="linearGradient4445"
98 gradientUnits="userSpaceOnUse"
99 gradientTransform="translate(-701.24225,-487.01655)"
100 x1="845.7998"
101 y1="637.30005"
102 x2="845.7998"
103 y2="509.84348" />
104 <linearGradient
105 xlink:href="#linearGradient4333-6-7"
106 id="linearGradient4447"
107 gradientUnits="userSpaceOnUse"
108 gradientTransform="translate(-699.1976,-487.01655)"
109 x1="845.7998"
110 y1="637.30005"
111 x2="845.7998"
112 y2="509.84348" />
113 <linearGradient
114 xlink:href="#linearGradient4333-6-7"
115 id="linearGradient4449"
116 gradientUnits="userSpaceOnUse"
117 gradientTransform="translate(-701.24225,-487.01655)"
118 x1="845.7998"
119 y1="637.30005"
120 x2="845.7998"
121 y2="509.84348" />
122 <linearGradient
123 xlink:href="#linearGradient4333-6-7"
124 id="linearGradient4451"
125 gradientUnits="userSpaceOnUse"
126 gradientTransform="translate(-701.24225,-487.01655)"
127 x1="845.7998"
128 y1="637.30005"
129 x2="845.7998"
130 y2="509.84348" />
131 <linearGradient
132 xlink:href="#linearGradient4333-6-7"
133 id="linearGradient4453"
134 gradientUnits="userSpaceOnUse"
135 gradientTransform="translate(-701.24225,-487.01655)"
136 x1="845.7998"
137 y1="637.30005"
138 x2="845.7998"
139 y2="509.84348" />
140 <linearGradient
141 y2="509.84348"
142 x2="845.7998"
143 y1="637.30005"
144 x1="845.7998"
145 gradientTransform="translate(-701.24225,-487.01655)"
146 gradientUnits="userSpaceOnUse"
147 id="linearGradient6071"
148 xlink:href="#linearGradient4333-6-7" />
149 <linearGradient
150 y2="509.84348"
151 x2="845.7998"
152 y1="637.30005"
153 x1="845.7998"
154 gradientTransform="translate(-701.24225,-487.01655)"
155 gradientUnits="userSpaceOnUse"
156 id="linearGradient6073"
157 xlink:href="#linearGradient4333-6-7" />
158 <linearGradient
159 y2="509.84348"
160 x2="845.7998"
161 y1="637.30005"
162 x1="845.7998"
163 gradientTransform="translate(-701.24225,-487.01655)"
164 gradientUnits="userSpaceOnUse"
165 id="linearGradient6075"
166 xlink:href="#linearGradient4333-6-7" />
167 <linearGradient
168 y2="509.84348"
169 x2="845.7998"
170 y1="637.30005"
171 x1="845.7998"
172 gradientTransform="translate(-699.1976,-487.01655)"
173 gradientUnits="userSpaceOnUse"
174 id="linearGradient6077"
175 xlink:href="#linearGradient4333-6-7" />
176 <linearGradient
177 y2="509.84348"
178 x2="845.7998"
179 y1="637.30005"
180 x1="845.7998"
181 gradientTransform="translate(-701.24225,-487.01655)"
182 gradientUnits="userSpaceOnUse"
183 id="linearGradient6079"
184 xlink:href="#linearGradient4333-6-7" />
185 <linearGradient
186 y2="509.84348"
187 x2="845.7998"
188 y1="637.30005"
189 x1="845.7998"
190 gradientTransform="translate(-703.2869,-487.01655)"
191 gradientUnits="userSpaceOnUse"
192 id="linearGradient6081"
193 xlink:href="#linearGradient4333-6-7" />
194 <linearGradient
195 y2="509.84348"
196 x2="845.7998"
197 y1="637.30005"
198 x1="845.7998"
199 gradientTransform="translate(-699.87915,-487.01655)"
200 gradientUnits="userSpaceOnUse"
201 id="linearGradient6083"
202 xlink:href="#linearGradient4333-6-7" />
203 <linearGradient
204 y2="509.84348"
205 x2="845.7998"
206 y1="637.30005"
207 x1="845.7998"
208 gradientTransform="translate(-699.19746,-487.01655)"
209 gradientUnits="userSpaceOnUse"
210 id="linearGradient6085"
211 xlink:href="#linearGradient4333-6-7" />
212 <linearGradient
213 y2="-293.69879"
214 x2="1984.2427"
215 y1="-348.63434"
216 x1="1984.2427"
217 gradientTransform="translate(-1434.0326,365.55395)"
218 gradientUnits="userSpaceOnUse"
219 id="linearGradient6087"
220 xlink:href="#linearGradient3780" />
221 <linearGradient
222 y2="509.84348"
223 x2="845.7998"
224 y1="637.30005"
225 x1="845.7998"
226 gradientTransform="translate(-606.51586,-487.01655)"
227 gradientUnits="userSpaceOnUse"
228 id="linearGradient6089"
229 xlink:href="#linearGradient4333-6-7" />
230 <linearGradient
231 y2="-5.3252554"
232 x2="1795.8763"
233 y1="-116.8399"
234 x1="1795.8763"
235 gradientTransform="translate(-1431.3064,219.11539)"
236 gradientUnits="userSpaceOnUse"
237 id="linearGradient6095"
238 xlink:href="#linearGradient4405" />
239 <mask
240 id="mask6091"
241 maskUnits="userSpaceOnUse">
242 <rect
243 y="11.978719"
244 x="8.1208458"
245 height="153.34807"
246 width="582.72266"
247 id="rect6093"
248 style="color:#000000;fill:url(#linearGradient6095);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0" />
249 </mask>
250 </defs>
251 <metadata
252 id="metadata7">
253 <rdf:RDF>
254 <cc:Work
255 rdf:about="">
256 <dc:format>image/svg+xml</dc:format>
257 <dc:type
258 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
259 <dc:title>Shaarli Logo</dc:title>
260 <dc:creator>
261 <cc:Agent>
262 <dc:title>http://blog.idleman.fr/</dc:title>
263 </cc:Agent>
264 </dc:creator>
265 <dc:date>2012-08-29 22:36:01+02:00</dc:date>
266 <dc:publisher>
267 <cc:Agent>
268 <dc:title>http://sebsauvage.net/</dc:title>
269 </cc:Agent>
270 </dc:publisher>
271 <dc:subject>
272 <rdf:Bag>
273 <rdf:li>Shaarli</rdf:li>
274 <rdf:li>Logo</rdf:li>
275 </rdf:Bag>
276 </dc:subject>
277 <dc:contributor>
278 <cc:Agent>
279 <dc:title>http://thatguynamedandy.com/,
280http://mro.name/me</dc:title>
281 </cc:Agent>
282 </dc:contributor>
283 <cc:license
284 rdf:resource="http://www.opensource.org/licenses/zlib-license.php" />
285 <dc:source>http://sebsauvage.net/files/shaarli_logo.zip</dc:source>
286 <dc:relation>http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion#comment_09a1e91bc0abc7db6d186a6abf429877</dc:relation>
287 </cc:Work>
288 </rdf:RDF>
289 </metadata>
290 <g
291 style="display:inline"
292 id="layer9">
293 <g
294 id="g6232">
295 <g
296 style="display:inline"
297 id="g5987"
298 transform="matrix(1,0,0,-1,0,323.7441)"
299 mask="url(#mask6091)">
300 <path
301 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
302 d="m 549.36434,78.11349 c -9.4946,1.99352 -9.7027,14.03504 -9.8352,21.77668 0.1121,11.0831 -0.2095,22.9628 4.1417,33.27264 2.0054,4.85047 9.7812,4.74809 10.3195,-1.06753 4.7624,-15.20498 4.7481,-32.01281 1.4946,-47.50541 -0.983,-2.75668 -3.069,-6.35036 -6.1206,-6.47638 z"
303 id="path5989" />
304 <path
305 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
306 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
307 id="path5991" />
308 <path
309 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
310 d="m 132.42293,35.23407 c -7.6945,2.17125 -5.9206,12.79289 -6.2273,19.00216 1.6106,23.24538 0.8475,46.57408 2.1706,69.81693 0.068,7.09423 3.2021,16.90233 11.8853,16.22657 7.5709,-1.76417 5.7778,-11.8325 5.6557,-17.71589 -0.047,-7.84014 -4.5559,-19.23884 3.9165,-24.30949 7.6405,-5.37547 19.848,0.64078 18.6463,10.39069 -0.3251,8.83089 -2.0837,22.16882 7.8287,26.47493 6.4024,2.92649 10.6176,-5.21693 9.3943,-10.71096 -0.3749,-13.55442 1.2727,-30.22607 -10.711,-39.6768 -7.9735,-4.05845 -18.9828,-5.54515 -26.8307,-0.21351 -1.0372,2.42576 -6.9951,6.95054 -6.4053,1.24546 -1.6949,-15.3749 2.056,-31.45755 -2.3485,-46.40228 -1.2024,-2.63946 -4.0324,-4.45898 -6.9746,-4.12781 z"
311 id="path5993" />
312 <path
313 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
314 d="m 442.14024,64.05759 c -10.165,-0.2579 -20.6562,1.86137 -28.1474,9.18081 -2.8958,2.05591 -1.2663,-4.94966 -4.8395,-5.01742 -5.4074,-2.93338 -11.5829,2.98762 -9.5367,8.75381 0.099,20.06919 -1.977,40.97889 3.8787,60.387 3.1796,4.95849 13.7562,4.09337 12.7037,-2.9891 1.546,-15.53942 -2.968,-32.10549 3.167,-46.86488 4.3319,-8.66318 18.41,-14.13659 25.3718,-5.90704 3.521,6.12624 -0.9752,16.78774 6.8323,20.31879 7.6504,1.3481 9.6041,-9.08157 8.825,-14.7676 -1.6539,-6.72434 -2.1565,-14.5353 -6.6544,-19.99852 -3.1376,-2.78799 -7.564,-3.22067 -11.6005,-3.09585 z"
315 id="path5995" />
316 <path
317 style="color:#000000;fill:url(#linearGradient6071);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
318 d="m 442.38294,54.04595 c -0.1827,-0.005 -0.3789,0.0345 -0.5625,0.0312 -8.6942,-0.15632 -18.301,1.16995 -26.7813,5.96876 -0.368,-0.21564 -0.7676,-0.37654 -1.1562,-0.5625 l 0.031,-0.0625 c -0.2019,-0.10958 -0.4204,-0.1194 -0.625,-0.21875 -0.5569,-0.23563 -1.1103,-0.37966 -1.6874,-0.53125 -6.0741,-2.10894 -12.7994,-0.4336 -16.8438,3.34375 -3.8577,3.60298 -6.0063,9.29062 -5.1562,15.125 0.085,19.31578 -2.292,41.23535 4.3124,63.12499 l 0.4063,1.3125 0.75,1.1875 c 4.4521,6.94297 11.5862,8.53059 18,7.46875 3.2069,-0.53092 6.701,-1.89897 9.5,-5.03125 2.2725,-2.54317 3.5121,-6.27514 3.5937,-9.84375 0,-0.0435 0,-0.0816 0,-0.125 1.7478,-17.81793 -1.8544,-32.72457 2.2813,-43.375 0.6976,-1.23208 3.1856,-3.39065 5.4063,-4.03125 1.1119,-0.32077 1.7363,-0.44325 2.1874,-0.40625 0.051,0.8996 0.2789,2.71568 0.5313,6.0625 0.1821,2.41445 0.4732,5.42185 2.0313,8.8125 1.558,3.39065 4.8419,6.94014 8.8437,8.75 l 1.1563,0.5 1.2187,0.21875 c 4.1545,0.73208 8.9361,-0.28467 12.2187,-2.59375 3.2827,-2.30908 5.1358,-5.31163 6.3126,-8.0625 2.3534,-5.50175 2.5912,-10.54096 1.9374,-15.3125 l -0.062,-0.53125 -0.125,-0.5 c -1.3372,-5.43656 -1.418,-15.17693 -8.6563,-23.96874 l -0.4687,-0.59375 -0.5938,-0.53125 c -6.0316,-5.35952 -13.0425,-5.71213 -18,-5.59376 l 0,-0.0312 z m -20.9688,14.62501 c 0.3103,0.61975 0.1924,0.76755 0.063,0.28125 -0.016,-0.0599 -0.046,-0.21107 -0.063,-0.28125 z m -11.8437,14.15624 c 0.271,0.10418 0.5347,0.22752 0.8125,0.3125 l -0.125,0.21875 -0.125,0.3125 c -0.2313,0.55649 -0.3535,1.10135 -0.5625,1.65625 0.01,-0.84699 -0.01,-1.64903 0,-2.5 z"
319 id="path5997" />
320 <path
321 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:38"
322 d="m 334.93614,43.42895 -1.125,0.0625 c -11.4541,0.68757 -31.1299,2.13948 -42.5313,20.5 l -0.6875,1.15625 -0.5312,1.21875 c -4.0155,9.09454 -1.1737,19.34928 5,25.5 -7.1006,9.03999 -10.5361,20.69833 -9.25,32.65625 -0.7932,13.71238 8.5163,26.58972 21.5624,30.34375 l -0.031,0.0625 c 14.5936,5.02387 28.3345,3.89176 40,1.875 1.1383,0.61027 2.377,1.24208 3.8438,1.84375 3.1932,1.30991 7.6804,2.60895 13.1874,1.96875 5.5071,-0.6402 11.3463,-3.71585 15.0626,-7.53125 l 0.6562,-0.6875 0.5938,-0.75 c 7.375,-9.27994 7.6766,-20.19393 7.1874,-26.8125 -0.4891,-6.61857 -1.0653,-10.99648 -1.0312,-11.375 l 0.125,-1.46875 -0.094,-1.5 c -0.9045,-13.69999 -0.4438,-31.50909 -8.6874,-49.71875 -0.8869,-3.14352 -2.6183,-4.60975 -5,-6.625 -14.193,-12.04738 -29.8012,-10.22761 -37.125,-10.65625 z m -5,69.25 c -0.6975,0.25422 -0.096,-0.059 3.5937,0.375 3.1757,0.3735 8.4922,1.29071 15.3437,0.34375 -0.042,1.60674 -0.047,3.10046 0.031,4.46875 l -1.2187,0.25 c -9.4296,1.92946 -17.7526,2.70557 -24.0626,1.71875 0.3089,-2.61777 2.5558,-6.11412 4.2813,-6.53125 l 1.0313,-0.25 1,-0.375 z"
323 id="path5999" />
324 <path
325 id="path6001"
326 d="m 242.86794,62.94328 c -9.8451,0.59098 -21.9234,2.57343 -27.5069,11.56498 -1.5225,3.44827 2.5155,7.16458 5.8003,4.55483 11.6876,-3.18405 25.8772,-8.64334 36.9368,-1.03196 3.4255,4.6575 3.2712,13.73214 -2.1351,16.8315 -8.1137,1.83399 -16.456,-2.50178 -24.589,0.4626 -12.7407,3.08001 -20.924,16.83116 -18.6463,29.53519 -1.221,6.03853 2.7535,11.58045 8.7182,12.59694 12.2603,4.22059 25.7141,2.25842 37.9688,-0.24909 3.9671,2.72001 9.7011,7.85911 14.3406,3.09585 6.2596,-7.87653 1.273,-19.02318 2.088,-28.06851 -0.9577,-14.50429 -1.0481,-29.91302 -7.0343,-43.1362 -7.0905,-6.01862 -17.2216,-5.6458 -25.9411,-6.15613 z"
327 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
328 <path
329 style="color:#000000;fill:url(#linearGradient6073);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
330 d="m 132.71733,24.19589 c -0.5004,0.0152 -1.0205,0.0363 -1.5312,0.0937 l -0.9063,0.0937 -0.8437,0.25 c -4.2861,1.20943 -8.1936,4.24904 -10.375,7.56249 -2.1816,3.31346 -2.9841,6.56659 -3.4063,9.375 -0.8444,5.61682 -0.3823,10.37282 -0.4687,12.125 l -0.031,0.65625 0.062,0.625 c 1.548,22.34205 0.8033,45.46456 2.125,69.1875 5e-4,0.0505 0.031,0.10568 0.031,0.15625 0.01,0.1151 -0.01,0.22862 0,0.34375 l 0.031,0 c 0.099,4.98929 0.9665,10.43113 4.125,15.90625 3.2605,5.65198 11.0145,11.32149 19.5625,10.65625 l 0.8438,-0.0625 0.8124,-0.1875 c 4.2384,-0.98762 8.3269,-3.79564 10.625,-7.09375 2.1728,-3.63384 4.3342,-6.89183 5.1872,-10.22818 3.8402,7.13335 5.9507,8.04619 13.1566,11.44693 l 0,0.0312 c 0.059,0.0269 0.1281,0.0362 0.1875,0.0625 3.7423,1.65403 8.4312,1.97661 12.2813,0.65625 3.91101,-1.34132 6.71761,-3.90092 8.59371,-6.5 3.336,-4.62154 4.6441,-9.64143 3.9063,-15.25 -0.1718,-6.20746 0.2238,-14.23226 -1.1563,-22.8125 -1.3801,-8.58024 -5.0962,-18.36284 -13.75001,-25.1875 l -0.8437,-0.6875 -0.9688,-0.5 c -7.7653,-3.95251 -17.7087,-6.355 -27.4062,-4.09375 0.4086,-10.28331 1.089,-21.96033 -2.625,-34.5625 l -0.2188,-0.75 -0.3125,-0.71875 c -2.9167,-6.40275 -9.181,-10.82231 -16.6875,-10.59374 z m 6.0625,53.99999 c 0,0.0101 0.05,0.0315 0.062,0.0625 l -0.6245,1.46875 c 0.3311,-0.86163 0.5542,-1.56647 0.5625,-1.53125 z m 36.0625,48.28125 c 0.012,-0.004 0.019,0.005 0.031,0 l 0.063,0.3125 c -0.043,-0.19086 -0.061,-0.25465 -0.094,-0.3125 z"
331 id="path6003" />
332 <path
333 style="fill:#484848;fill-opacity:1;stroke:none"
334 id="path6005"
335 d="m 133.3461,36.09636 c -1.692,0.49428 -2.8155,1.39846 -3.625,2.625 -0.8214,1.24442 -1.3243,2.85069 -1.5938,4.625 -0.5342,3.51732 -0.1953,7.61208 -0.3438,10.8125 0,0.0285 0,0.0654 0,0.0937 1.6063,23.27388 0.8692,46.5905 2.1876,69.75 a 0.88388823,0.88388823 0 0 1 0,0.0625 c 0.033,3.4213 0.83,7.53419 2.5937,10.59375 1.7438,3.02495 4.2922,5.00636 8.2187,4.75 0.011,-7.3e-4 0.02,7.7e-4 0.031,0 1.6857,-0.39978 2.7542,-1.19719 3.5313,-2.3125 0.7819,-1.12237 1.2391,-2.59827 1.4687,-4.25 0.4593,-3.30346 2e-4,-7.22907 -0.062,-10.25 a 0.88388823,0.88388823 0 0 1 0,-0.0312 c -0.023,-3.75401 -1.179,-8.58343 -1.25,-13.1875 -0.071,-4.59014 1.0512,-9.12033 5.5625,-11.84375 0.012,-0.008 0.019,-0.023 0.031,-0.0312 8.2411,-5.75335 21.2001,0.72746 19.9687,11.1875 0,0.011 0,0.0202 0,0.0312 -4e-4,0.01 4e-4,0.0216 0,0.0312 -0.1662,4.44678 -0.6416,9.92071 0.094,14.71875 0.7386,4.81878 2.5857,8.83105 7.2188,10.84375 a 0.88388823,0.88388823 0 0 1 0.031,0 c 1.4264,0.65196 2.625,0.67804 3.6876,0.3125 1.0625,-0.36554 2.0152,-1.15367 2.7812,-2.21875 1.532,-2.13016 2.2012,-5.36524 1.6562,-7.8125 a 0.88388823,0.88388823 0 0 1 0,-0.15625 c -0.1887,-6.82351 0.1073,-14.35845 -1,-21.28125 -1.1026,-6.89383 -3.5864,-13.13587 -9.3124,-17.6875 -7.7294,-3.90433 -18.3437,-5.25802 -25.7813,-0.25 -0.7734,1.48479 -2.3237,3.00623 -4,3.78125 -0.9043,0.41808 -1.982,0.65336 -2.875,0.0312 -0.8519,-0.59346 -1.0866,-1.72753 -0.9687,-3.1875 0.01,-0.0705 -0.01,-0.11538 0,-0.1875 -1.6634,-15.48034 1.9617,-31.38045 -2.2813,-45.9375 -1.0363,-2.2749 -3.4784,-3.85945 -5.9687,-3.625 z" />
336 <path
337 style="color:#000000;fill:url(#linearGradient6075);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
338 d="m 500.00794,37.6397 c -0.47,-0.0246 -0.9099,0.13839 -1.375,0.15625 -0.3182,0.036 -0.6564,-0.0583 -0.9688,0 l 0,0.0937 c -5.9486,0.59666 -11.3199,4.27914 -13.8124,8.625 -2.5191,4.39212 -3.1643,9.07388 -2.4688,13.75001 -0.5691,24.07161 -0.3288,48.17845 0.031,71.96874 l 0.031,1.1875 0.2813,1.125 c 2.2758,9.05358 10.1204,12.94327 17.2812,13.3125 3.5804,0.18461 7.6057,-0.50128 11.25,-3.21875 3.4431,-2.56742 5.753,-7.21537 6.0625,-11.6875 l 0.062,0 c 0.024,-0.26477 0.01,-0.51719 0.031,-0.78125 1.2169,-14.32127 -0.1813,-27.63851 0.6563,-39.5625 0.8412,-12.28307 -0.4559,-23.97948 -0.6563,-34.18749 0.9168,-4.19732 0.7514,-8.64033 -1.75,-13.09376 -2.5398,-4.52202 -8.6787,-7.57722 -14.4374,-7.5625 -0.073,1.9e-4 -0.1457,-0.001 -0.2188,0 l 0,-0.125 z m -0.4375,10.46875 1.5625,8.375 c -0.089,0.0884 -0.5399,0.26586 -0.9688,0.50001 -0.4433,-0.17558 -0.588,-0.31717 -1.125,-0.59376 l 0.5313,-8.28125 z m 1.625,8.6875 0.125,0.65626 c 0,-5.2e-4 -0.146,-0.0578 -0.1563,-0.0625 0.013,-0.26164 0.01,-0.41632 0.031,-0.59376 z"
339 id="path6007" />
340 <path
341 style="fill:#484848;fill-opacity:1;stroke:none"
342 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
343 id="path6009" />
344 <path
345 style="fill:#000000;fill-opacity:1;stroke:none"
346 d="m 544.51954,53.6313 c -7.5784,-0.46784 -10.6755,10.08558 -4.626,14.19825 6.4831,5.13984 16.9776,-2.57743 12.9884,-10.24836 -1.4384,-3.20261 -5.1136,-4.25984 -8.3624,-3.94989 z"
347 id="path6011" />
348 <path
349 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:38;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
350 d="m 66.312222,57.93009 c -17.370703,0.62829 -30.0641,20.09681 -26.023403,36.39781 2.1928,10.05075 13.8541,12.09708 22.635103,11.4922 7.1377,-0.5151 17.6041,2.45346 16.7319,11.49222 -1.8676,6.29718 -10.9897,4.97438 -16.0667,5.21679 -7.019003,0.3042 -14.551803,-2.83467 -21.309203,-1.0251 -5.546297,3.71601 -0.7698,11.63178 4.4362,13.09902 11.6204,3.85396 24.776703,2.98561 36.677203,0.52396 8.494404,-1.78465 13.976704,-9.66183 14.007304,-18.12905 0.5362,-8.45978 -0.1252,-18.85777 -9.082,-22.63511 -7.833304,-4.5437 -17.524404,-2.59996 -25.744004,-4.64578 -6.504303,-3.75215 -4.590203,-15.08325 3.2137,-15.54417 8.376,-2.645 16.5844,3.54335 24.730904,1.74653 6.8027,-2.75685 5.6777,-13.26551 -1.2924,-15.19486 C 82.177322,57.19274 73.972122,57.9802 66.312222,57.93009 Z"
351 id="path6013" />
352 <path
353 style="color:#000000;fill:url(#linearGradient6077);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
354 d="m 66.146122,46.92095 -0.2187,0.0312 c -25.268203,0.91394 -41.9786,26.29641 -36.375,49.71875 0,0.01 0,0.0214 0,0.0312 0.023,0.0937 0.039,0.18758 0.062,0.28125 l 0.062,0 c 1.4158,6.03031 5.2241,10.72981 9.5937,13.9375 l -1.5937,0.4375 -1.5313,1 c -3.4934,2.34058 -6.2461,6.40677 -7.0312,10.4375 -0.7852,4.03073 0.016,7.64447 1.2812,10.53125 2.4625,5.61698 6.4364,9.72109 12.843797,11.6875 l 0,0.0312 c 0.1235,0.0409 0.2514,0.0537 0.375,0.0937 0.044,0.0142 0.081,0.0484 0.125,0.0625 14.2876,4.59699 29.052403,3.33987 41.875007,0.6875 l 0.031,0 c 13.703,-2.87897 22.354804,-15.23519 22.687504,-28.1875 l 0.031,0 c 0.01,-0.1043 -0.01,-0.23849 0,-0.34375 0,-0.10511 0.031,-0.20733 0.031,-0.3125 l -0.031,0 c 0.275,-4.68022 0.3633,-10.21921 -1.4063,-16.21875 -1.6128,-5.46789 -5.6186,-11.40935 -11.718704,-15.03125 C 110.28983,79.05558 108.57813,56.15757 93.550926,50.6395 83.076822,45.62854 73.121622,46.96476 66.394622,46.92075 l -0.25,0 z M 49.927419,124.0772 c 0.4736,0.11312 0.7429,0.17483 0.6875,0.1875 -0.1379,-0.0437 -0.3009,-0.0484 -0.4375,-0.0937 l -0.25,-0.0937 z"
355 id="path6015" />
356 <path
357 style="fill:#484848;fill-opacity:1;stroke:none"
358 id="path6017"
359 d="M 67.047,59.37761 C 50.7565,60.01346 38.6203,78.63489 42.422,93.97136 a 1.4420115,1.4420115 0 0 1 0,0.0312 c 0.9874,4.52574 3.9833,7.14275 7.9688,8.71875 3.9854,1.576 8.921,1.948 13.1562,1.65625 3.8182,-0.27555 8.4163,0.35581 12.1562,2.34375 3.74,1.98794 6.6157,5.6345 6.125,10.71875 a 1.4420115,1.4420115 0 0 1 -0.062,0.28125 c -0.5618,1.89409 -1.746,3.32797 -3.1876,4.25 -1.4415,0.92203 -3.0867,1.39395 -4.7812,1.65625 -3.3889,0.5246 -7.0334,0.23046 -9.4062,0.34375 -7.4077,0.32104 -14.726,-2.60314 -20.7813,-1.09375 -0.9228,0.69289 -1.3969,1.4625 -1.5625,2.3125 -0.1806,0.92739 -0.017,2.01851 0.4688,3.125 0.9708,2.21298 3.281,4.32492 5.3437,4.90625 a 1.4420115,1.4420115 0 0 1 0.062,0 c 11.2515,3.73156 24.1465,2.93253 35.9062,0.5 7.7821,-1.63499 12.8466,-8.87337 12.875,-16.71875 a 1.4420115,1.4420115 0 0 1 0,-0.0937 c 0.2634,-4.15469 0.2008,-8.71518 -0.9374,-12.5625 -1.1383,-3.84732 -3.227,-6.9152 -7.2813,-8.625 a 1.4420115,1.4420115 0 0 1 -0.1563,-0.0937 c -7.233,-4.1955 -16.6908,-2.33856 -25.375,-4.5 a 1.4420115,1.4420115 0 0 1 -0.375,-0.15625 c -7.593,-4.38022 -5.364,-17.27483 3.5,-18.15625 l 0,-0.0312 c 0.1153,-0.0364 0.2288,-0.0291 0.3438,-0.0625 4.5012,-1.3064 8.8395,-0.37995 12.875,0.59375 4.0804,0.98454 7.88,1.92841 11.4688,1.1875 5.4755,-2.31046 4.4951,-10.8333 -1.1876,-12.40625 a 1.4420115,1.4420115 0 0 1 -0.2812,-0.0937 c -6.5535,-3.28332 -14.4405,-2.57842 -22.1875,-2.625 -0.021,-1.3e-4 -0.042,1.4e-4 -0.062,0 z" />
360 <path
361 style="color:#000000;fill:url(#linearGradient6079);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
362 d="m 334.91414,52.45217 -0.5624,0.0312 c -10.692,0.64182 -26.7608,2.35866 -35.4063,16.28126 l -0.375,0.59375 -0.2813,0.625 c -2.6168,5.92672 -0.4865,12.63582 3.8126,16.24999 2.47,2.0766 6.1544,2.97511 9.8124,2.75 -12.1731,7.16212 -18.9579,21.29295 -17.0937,35.5 -0.9321,10.0329 5.7963,19.42583 15.4375,21.90625 l 0,0.0312 c 13.5839,4.67628 27.0449,3.11875 38.7812,0.90625 1.4491,0.98507 3.2876,2.06677 5.5626,3 2.2748,0.93323 5.2583,1.74964 8.75,1.34375 3.4915,-0.40589 7.1195,-2.30283 9.625,-4.875 l 0.375,-0.34375 0.3124,-0.40625 c 5.3642,-6.74967 5.6479,-14.75709 5.2188,-20.5625 -0.4291,-5.80541 -1.211,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.75 c -0.9297,-14.08097 -0.732,-30.77734 -7.9062,-46.62499 -0.4593,-1.65783 -1.3753,-2.43205 -2.625,-3.4999 -10.8288,-9.19166 -23.8588,-8.03267 -31.8438,-8.50001 l -0.5938,-0.0312 z m 22.0626,47.46875 c 0.2983,4.01025 0.663,7.89337 0.9374,12.09375 -0.3619,6.15055 0.7536,11.18085 1.0313,14.9375 0.091,1.23358 -3e-4,1.89681 -0.031,2.71875 -0.7261,-0.49389 -0.8804,-0.56988 -1.7812,-1.1875 l -3.5,-2.40625 -4.1562,0.84375 c -11.8502,2.42474 -23.4896,3.77093 -32.7188,0.59375 l -0.75,-0.25 -0.8125,-0.15625 c -0.7563,-0.12889 -0.7437,-0.008 -0.5937,-0.75 l 0.375,-1.875 -0.3438,-1.875 c -1.3223,-7.37497 4.0726,-16.31882 11.1562,-18.03125 l 0.5626,-0.15625 0.5312,-0.1875 c 1.5591,-0.56829 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.48444 15.6563,0.0312 l 1.4687,-0.34375 1.3125,-0.75 c 1.5458,-0.8862 2.8481,-1.95265 3.9688,-3.125 z"
363 id="path6019" />
364 <path
365 style="fill:#484848;fill-opacity:1;stroke:none"
366 id="path6021"
367 d="m 442.8461,65.50261 c -9.9417,-0.25223 -20.0112,1.83054 -27.125,8.78125 a 1.4249747,1.4249747 0 0 1 -0.1876,0.125 c -0.4923,0.34955 -1.0141,0.64308 -1.6874,0.65625 -0.6734,0.0132 -1.3402,-0.39879 -1.6876,-0.8125 -0.6947,-0.82743 -0.7686,-1.5945 -0.9687,-2.34375 -0.2001,-0.74925 -0.4246,-1.47139 -0.6563,-1.84375 -0.2316,-0.37236 -0.2624,-0.39819 -0.6874,-0.40625 a 1.4249747,1.4249747 0 0 1 -0.6563,-0.1875 c -2.1511,-1.16691 -4.3134,-0.58174 -5.9063,0.90625 -1.5928,1.48799 -2.4145,3.81205 -1.5937,6.125 a 1.4249747,1.4249747 0 0 1 0.094,0.46875 c 0.099,20.08519 -1.9054,40.73856 3.75,59.71875 1.2377,1.74956 4.0539,2.66609 6.4063,2.28125 1.2075,-0.19755 2.2216,-0.71247 2.8437,-1.40625 0.6222,-0.69378 0.9615,-1.54589 0.75,-2.96875 a 1.4249747,1.4249747 0 0 1 0,-0.375 c 1.5091,-15.16756 -3.1254,-31.94343 3.25,-47.28125 a 1.4249747,1.4249747 0 0 1 0.031,-0.0625 c 2.3884,-4.77662 7.2847,-8.50018 12.5937,-10.03125 5.3091,-1.53107 11.2689,-0.75156 15.1563,3.84375 a 1.4249747,1.4249747 0 0 1 0.1563,0.1875 c 2.0694,3.60071 1.6918,8.0153 1.9687,11.75 0.1385,1.86735 0.4194,3.54061 1.0313,4.875 0.5916,1.2904 1.4751,2.25734 3.0312,3 1.4606,0.20734 2.5297,-0.051 3.4375,-0.6875 0.9587,-0.67214 1.771,-1.81376 2.375,-3.21875 1.2079,-2.80999 1.508,-6.6831 1.1563,-9.25 -1.6601,-6.82503 -2.269,-14.23556 -6.2813,-19.1875 -2.6943,-2.32961 -6.6692,-2.77567 -10.5313,-2.65625 a 1.4249747,1.4249747 0 0 1 -0.062,0 z" />
368 <path
369 style="color:#000000;fill:url(#linearGradient6081);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
370 d="m 548.52594,68.07721 -1.2187,0.25 c -8.6956,1.82574 -14.1425,9.53796 -15.9688,15.68749 -1.8263,6.14954 -1.7462,11.84707 -1.8125,15.71875 l 0,0.125 0,0.125 c 0.1092,10.79916 -0.5536,24.0134 4.9063,37 0.01,0.0225 0.022,0.0401 0.031,0.0625 2.7726,6.62078 9.3817,9.9621 15.5625,9.5625 5.6001,-0.36206 11.8353,-5.2195 13.5,-11.53125 5.3924,-17.21633 5.3013,-35.62075 1.75,-52.53125 l -0.1563,-0.6875 -0.2187,-0.62499 c -0.7814,-2.19128 -1.853,-4.62969 -3.9375,-7.1875 -2.0845,-2.55781 -5.8401,-5.71667 -11.1875,-5.9375 l -1.25,-0.0312 z"
371 id="path6023" />
372 <path
373 style="fill:#484848;fill-opacity:1;stroke:none"
374 id="path6025"
375 d="m 550.1139,78.59636 c -4.5226,0.97522 -6.7823,4.26272 -8,8.375 -1.2232,4.13111 -1.3087,9.03503 -1.375,12.90625 0.1123,11.09592 -0.2043,22.90976 4.0938,33.09375 0.9213,2.22841 3.1731,3.32073 5.25,3.1875 2.0769,-0.13323 3.906,-1.39 4.1562,-4.09375 a 0.46475483,0.46475483 0 0 1 0.031,-0.0937 c 4.7332,-15.11164 4.7084,-31.85462 1.4687,-47.28125 -0.4788,-1.32581 -1.2248,-2.85305 -2.1874,-4.03125 -0.9629,-1.17844 -2.1146,-1.98485 -3.4376,-2.0625 z" />
376 <path
377 style="color:#000000;fill:url(#linearGradient6083);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
378 d="m 242.87094,52.92092 -0.5938,0.0312 c -10.6919,0.64192 -26.7607,2.35873 -35.4062,16.28131 l -0.375,0.59375 -0.2813,0.65625 c -2.6168,5.92671 -0.4864,12.60456 3.8125,16.21874 2.4771,2.0825 6.1757,2.98309 9.8438,2.75 -12.176,7.14722 -18.9659,21.26849 -17.125,35.46875 -0.9665,10.0609 5.7999,19.48906 15.4687,21.96875 l -0.031,0.0312 c 13.5891,4.67806 27.073,3.12012 38.8125,0.90625 1.4445,0.97996 3.2715,2.07302 5.5313,3 2.2749,0.93323 5.2585,1.71839 8.75,1.3125 3.4915,-0.40589 7.1509,-2.27156 9.6562,-4.84375 l 0.3438,-0.375 0.3125,-0.40625 c 5.3641,-6.74969 5.6478,-14.72585 5.2187,-20.53125 -0.4291,-5.8054 -1.2109,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.78125 c -0.9297,-14.081 -0.7006,-30.74608 -7.875,-46.59374 l -0.9375,-2.0625 -1.7187,-1.4375 c -10.8287,-9.19167 -23.8276,-8.06392 -31.8125,-8.53126 l -0.5938,-0.0312 z m 22.0312,47.5 c 0.2974,4.00059 0.6637,7.87292 0.9375,12.0625 -0.3619,6.15055 0.7536,11.2121 1.0313,14.96875 0.091,1.22812 0,1.86766 -0.031,2.6875 -0.7261,-0.49388 -0.8805,-0.56989 -1.7813,-1.1875 l -3.5,-2.40625 -4.1562,0.875 c -11.8502,2.42475 -23.4582,3.77094 -32.6875,0.59375 l -0.7813,-0.28125 -0.8125,-0.125 c -0.7563,-0.12888 -0.7437,-0.0396 -0.5938,-0.78125 l 0.375,-1.84375 -0.3437,-1.875 c -1.3223,-7.37494 4.0726,-16.35008 11.1562,-18.0625 l 0.5625,-0.125 0.5313,-0.1875 c 1.5591,-0.56828 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.45313 15.6562,0 l 1.4688,-0.3125 1.3125,-0.75 c 1.5458,-0.8862 2.8482,-1.95265 3.9687,-3.125 z"
379 id="path6027" />
380 <path
381 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
382 id="path6029"
383 d="m 243.6361,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z" />
384 <path
385 style="color:#000000;fill:url(#linearGradient6085);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
386 id="path6031"
387 d="m 252.9376,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z" />
388 <path
389 style="color:#000000;fill:#305f00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10"
390 d="m 550.24144,11.97714 c -4.7431,8e-5 -9.3884,1.94508 -12.1562,5.65625 -2.3938,3.20927 -3.2655,7.28209 -3.5,11.84374 -5.2417,0.10768 -9.658,0.71067 -13.2813,2.53125 -3.7519,1.88519 -6.5576,5.75636 -6.9063,9.9375 l -0.062,0 c -0.013,0.1027 0.011,0.20947 0,0.3125 0,0.043 -0.03,0.0819 -0.031,0.125 l 0.031,0 c -0.383,3.94189 0.8037,8.08581 3.625,10.84375 1.7434,1.70445 3.9242,2.79035 6.3124,3.59375 l -0.875,2.4375 -0.062,0.125 -0.031,0.125 c -1.0239,3.32791 -0.9882,7.09444 0.8437,10.15625 1.8322,3.06181 4.9132,4.85334 8.3438,5.90625 l 0.7188,0.21875 0.75,0 2.2812,0 c 4.1038,5e-5 8.0184,-1.11288 11.1562,-3.5 1.388,-1.05587 2.5677,-2.38102 3.5938,-3.8125 2.738,2.5559 6.0541,4.80834 10,6.78125 l 0.5,0.25 0.5312,0.15625 c 3.235,0.79227 6.3972,0.95306 9.4063,-0.1875 2.9956,-1.13542 5.3523,-3.78973 6.4375,-6.71875 l 0.031,0 0,-0.0312 c 1.3188,-3.58119 1.0754,-7.65809 -0.4687,-11.1875 -0.3593,-0.82136 -0.9637,-1.56048 -1.4375,-2.34375 0.7988,-0.35352 1.5774,-0.75006 2.3125,-1.28125 3.1456,-2.2731 4.4669,-6.43958 4.1563,-10.25 l 0.031,0 c 0,-0.12851 -0.061,-0.24691 -0.062,-0.375 -0.017,-0.15367 0.023,-0.31671 0,-0.46875 l -0.062,0 c -0.2506,-3.85862 -2.6242,-7.47641 -5.875,-9.5625 -3.1968,-2.05143 -7.2278,-3.19745 -12.0625,-4.03124 -0.5947,-4.02941 -1.4462,-7.64148 -3.125,-10.53125 -2.2702,-3.9078 -6.5646,-6.71865 -11.0625,-6.71875 z m 18.3125,50.62499 c 0.2654,0.97712 0.2969,1.7705 -0.031,2.65625 l 0,0.0312 c -0.3181,0.86918 -0.3036,0.72198 -0.625,0.84375 -0.2585,0.098 -1.2073,0.14918 -2.5624,-0.0625 0.3313,-0.1475 0.7366,-0.14338 1.0312,-0.34375 l 0.4375,-0.28125 0.375,-0.40625 c 0.5814,-0.62017 0.9776,-1.55372 1.375,-2.4375 z"
391 id="path6033" />
392 <g
393 id="text6035"
394 style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:165.01513672px;line-height:125%;font-family:'comic andy';-inkscape-font-specification:'comic andy';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4437);fill-opacity:1;stroke:none">
395 <path
396 id="path98"
397 style="fill:url(#linearGradient6087);fill-opacity:1"
398 d="m 550.24549,16.984496 q 8.54083,0 9.83001,16.920498 l 2.33664,0 q 15.22844,2.33664 15.0673,9.668855 1.28918,8.621397 -11.03861,7.976806 9.42713,8.299101 6.7682,15.470169 -2.09492,5.72074 -9.99116,3.786969 -8.70197,-4.350985 -12.32779,-9.991151 l -1.5309,0 q -3.3841,9.991151 -13.13353,9.991151 l -2.25606,0 q -8.13796,-2.497788 -5.88189,-9.830003 l 2.82008,-7.815659 -0.80574,0 q -11.92492,-1.692049 -10.79688,-10.555167 0.32229,-8.137954 16.35648,-8.218527 4.43155,-0.483443 3.70639,-2.820083 0,-14.583858 10.87746,-14.583858 z m -4.5927,16.034186 -0.16115,4.512133 q -0.24172,3.384099 -2.17549,3.384099 l -12.73066,0.725164 q -2.98123,0.08057 -2.98123,2.417214 0,2.256067 3.22295,2.417214 11.19976,-0.564016 10.47459,1.530902 l -2.25606,4.834428 q -5.72074,8.621396 -2.82009,10.152299 3.86754,2.33664 10.95804,-12.08607 1.69205,-1.530902 2.82008,0 4.99558,5.317871 8.21853,8.70197 3.30353,3.3841 5.31787,2.014345 2.41721,-2.578361 -1.28918,-5.559592 -3.62582,-3.061804 -8.2991,-8.379675 -0.48344,-1.772623 0.24172,-1.772623 15.79246,1.047459 15.14787,-2.014345 0.48345,-3.3841 -13.69754,-3.3841 -2.17549,0.402869 -3.54525,-1.047459 l 0,-7.896232 q 0,-6.607052 -3.14238,-6.526478 -3.3841,-0.805738 -3.30352,7.976806 z" />
399 </g>
400 <path
401 d="m 335.7911,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z"
402 id="path6039"
403 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
404 <path
405 d="m 345.6192,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z"
406 id="path6041"
407 style="color:#000000;fill:url(#linearGradient6089);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
408 </g>
409 <g
410 id="g5958">
411 <path
412 id="path4188"
413 d="m 549.36434,78.11349 c -9.4946,1.99352 -9.7027,14.03504 -9.8352,21.77668 0.1121,11.0831 -0.2095,22.9628 4.1417,33.27264 2.0054,4.85047 9.7812,4.74809 10.3195,-1.06753 4.7624,-15.20498 4.7481,-32.01281 1.4946,-47.50541 -0.983,-2.75668 -3.069,-6.35036 -6.1206,-6.47638 z"
414 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
415 <path
416 id="path4190"
417 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
418 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
419 <path
420 id="path4192"
421 d="m 132.42293,35.23407 c -7.6945,2.17125 -5.9206,12.79289 -6.2273,19.00216 1.6106,23.24538 0.8475,46.57408 2.1706,69.81693 0.068,7.09423 3.2021,16.90233 11.8853,16.22657 7.5709,-1.76417 5.7778,-11.8325 5.6557,-17.71589 -0.047,-7.84014 -4.5559,-19.23884 3.9165,-24.30949 7.6405,-5.37547 19.848,0.64078 18.6463,10.39069 -0.3251,8.83089 -2.0837,22.16882 7.8287,26.47493 6.4024,2.92649 10.6176,-5.21693 9.3943,-10.71096 -0.3749,-13.55442 1.2727,-30.22607 -10.711,-39.6768 -7.9735,-4.05845 -18.9828,-5.54515 -26.8307,-0.21351 -1.0372,2.42576 -6.9951,6.95054 -6.4053,1.24546 -1.6949,-15.3749 2.056,-31.45755 -2.3485,-46.40228 -1.2024,-2.63946 -4.0324,-4.45898 -6.9746,-4.12781 z"
422 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
423 <path
424 id="path4194"
425 d="m 442.14024,64.05759 c -10.165,-0.2579 -20.6562,1.86137 -28.1474,9.18081 -2.8958,2.05591 -1.2663,-4.94966 -4.8395,-5.01742 -5.4074,-2.93338 -11.5829,2.98762 -9.5367,8.75381 0.099,20.06919 -1.977,40.97889 3.8787,60.387 3.1796,4.95849 13.7562,4.09337 12.7037,-2.9891 1.546,-15.53942 -2.968,-32.10549 3.167,-46.86488 4.3319,-8.66318 18.41,-14.13659 25.3718,-5.90704 3.521,6.12624 -0.9752,16.78774 6.8323,20.31879 7.6504,1.3481 9.6041,-9.08157 8.825,-14.7676 -1.6539,-6.72434 -2.1565,-14.5353 -6.6544,-19.99852 -3.1376,-2.78799 -7.564,-3.22067 -11.6005,-3.09585 z"
426 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
427 <path
428 id="path4196"
429 d="m 442.38294,54.04595 c -0.1827,-0.005 -0.3789,0.0345 -0.5625,0.0312 -8.6942,-0.15632 -18.301,1.16995 -26.7813,5.96876 -0.368,-0.21564 -0.7676,-0.37654 -1.1562,-0.5625 l 0.031,-0.0625 c -0.2019,-0.10958 -0.4204,-0.1194 -0.625,-0.21875 -0.5569,-0.23563 -1.1103,-0.37966 -1.6874,-0.53125 -6.0741,-2.10894 -12.7994,-0.4336 -16.8438,3.34375 -3.8577,3.60298 -6.0063,9.29062 -5.1562,15.125 0.085,19.31578 -2.292,41.23535 4.3124,63.12499 l 0.4063,1.3125 0.75,1.1875 c 4.4521,6.94297 11.5862,8.53059 18,7.46875 3.2069,-0.53092 6.701,-1.89897 9.5,-5.03125 2.2725,-2.54317 3.5121,-6.27514 3.5937,-9.84375 0,-0.0435 0,-0.0816 0,-0.125 1.7478,-17.81793 -1.8544,-32.72457 2.2813,-43.375 0.6976,-1.23208 3.1856,-3.39065 5.4063,-4.03125 1.1119,-0.32077 1.7363,-0.44325 2.1874,-0.40625 0.051,0.8996 0.2789,2.71568 0.5313,6.0625 0.1821,2.41445 0.4732,5.42185 2.0313,8.8125 1.558,3.39065 4.8419,6.94014 8.8437,8.75 l 1.1563,0.5 1.2187,0.21875 c 4.1545,0.73208 8.9361,-0.28467 12.2187,-2.59375 3.2827,-2.30908 5.1358,-5.31163 6.3126,-8.0625 2.3534,-5.50175 2.5912,-10.54096 1.9374,-15.3125 l -0.062,-0.53125 -0.125,-0.5 c -1.3372,-5.43656 -1.418,-15.17693 -8.6563,-23.96874 l -0.4687,-0.59375 -0.5938,-0.53125 c -6.0316,-5.35952 -13.0425,-5.71213 -18,-5.59376 l 0,-0.0312 z m -20.9688,14.62501 c 0.3103,0.61975 0.1924,0.76755 0.063,0.28125 -0.016,-0.0599 -0.046,-0.21107 -0.063,-0.28125 z m -11.8437,14.15624 c 0.271,0.10418 0.5347,0.22752 0.8125,0.3125 l -0.125,0.21875 -0.125,0.3125 c -0.2313,0.55649 -0.3535,1.10135 -0.5625,1.65625 0.01,-0.84699 -0.01,-1.64903 0,-2.5 z"
430 style="color:#000000;fill:url(#linearGradient4453);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
431 <path
432 id="path4198"
433 d="m 334.93614,43.42895 -1.125,0.0625 c -11.4541,0.68757 -31.1299,2.13948 -42.5313,20.5 l -0.6875,1.15625 -0.5312,1.21875 c -4.0155,9.09454 -1.1737,19.34928 5,25.5 -7.1006,9.03999 -10.5361,20.69833 -9.25,32.65625 -0.7932,13.71238 8.5163,26.58972 21.5624,30.34375 l -0.031,0.0625 c 14.5936,5.02387 28.3345,3.89176 40,1.875 1.1383,0.61027 2.377,1.24208 3.8438,1.84375 3.1932,1.30991 7.6804,2.60895 13.1874,1.96875 5.5071,-0.6402 11.3463,-3.71585 15.0626,-7.53125 l 0.6562,-0.6875 0.5938,-0.75 c 7.375,-9.27994 7.6766,-20.19393 7.1874,-26.8125 -0.4891,-6.61857 -1.0653,-10.99648 -1.0312,-11.375 l 0.125,-1.46875 -0.094,-1.5 c -0.9045,-13.69999 -0.4438,-31.50909 -8.6874,-49.71875 -0.8869,-3.14352 -2.6183,-4.60975 -5,-6.625 -14.193,-12.04738 -29.8012,-10.22761 -37.125,-10.65625 z m -5,69.25 c -0.6975,0.25422 -0.096,-0.059 3.5937,0.375 3.1757,0.3735 8.4922,1.29071 15.3437,0.34375 -0.042,1.60674 -0.047,3.10046 0.031,4.46875 l -1.2187,0.25 c -9.4296,1.92946 -17.7526,2.70557 -24.0626,1.71875 0.3089,-2.61777 2.5558,-6.11412 4.2813,-6.53125 l 1.0313,-0.25 1,-0.375 z"
434 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:38" />
435 <path
436 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
437 d="m 242.86794,62.94328 c -9.8451,0.59098 -21.9234,2.57343 -27.5069,11.56498 -1.5225,3.44827 2.5155,7.16458 5.8003,4.55483 11.6876,-3.18405 25.8772,-8.64334 36.9368,-1.03196 3.4255,4.6575 3.2712,13.73214 -2.1351,16.8315 -8.1137,1.83399 -16.456,-2.50178 -24.589,0.4626 -12.7407,3.08001 -20.924,16.83116 -18.6463,29.53519 -1.221,6.03853 2.7535,11.58045 8.7182,12.59694 12.2603,4.22059 25.7141,2.25842 37.9688,-0.24909 3.9671,2.72001 9.7011,7.85911 14.3406,3.09585 6.2596,-7.87653 1.273,-19.02318 2.088,-28.06851 -0.9577,-14.50429 -1.0481,-29.91302 -7.0343,-43.1362 -7.0905,-6.01862 -17.2216,-5.6458 -25.9411,-6.15613 z"
438 id="path4200" />
439 <path
440 id="path4202"
441 d="m 132.71733,24.19589 c -0.5004,0.0152 -1.0205,0.0363 -1.5312,0.0937 l -0.9063,0.0937 -0.8437,0.25 c -4.2861,1.20943 -8.1936,4.24904 -10.375,7.56249 -2.1816,3.31346 -2.9841,6.56659 -3.4063,9.375 -0.8444,5.61682 -0.3823,10.37282 -0.4687,12.125 l -0.031,0.65625 0.062,0.625 c 1.548,22.34205 0.8033,45.46456 2.125,69.1875 5e-4,0.0505 0.031,0.10568 0.031,0.15625 0.01,0.1151 -0.01,0.22862 0,0.34375 l 0.031,0 c 0.099,4.98929 0.9665,10.43113 4.125,15.90625 3.2605,5.65198 11.0145,11.32149 19.5625,10.65625 l 0.8438,-0.0625 0.8124,-0.1875 c 4.2384,-0.98762 8.3269,-3.79564 10.625,-7.09375 2.1728,-3.63384 4.3342,-6.89183 5.1872,-10.22818 3.8402,7.13335 5.9507,8.04619 13.1566,11.44693 l 0,0.0312 c 0.059,0.0269 0.1281,0.0362 0.1875,0.0625 3.7423,1.65403 8.4312,1.97661 12.2813,0.65625 3.91101,-1.34132 6.71761,-3.90092 8.59371,-6.5 3.336,-4.62154 4.6441,-9.64143 3.9063,-15.25 -0.1718,-6.20746 0.2238,-14.23226 -1.1563,-22.8125 -1.3801,-8.58024 -5.0962,-18.36284 -13.75001,-25.1875 l -0.8437,-0.6875 -0.9688,-0.5 c -7.7653,-3.95251 -17.7087,-6.355 -27.4062,-4.09375 0.4086,-10.28331 1.089,-21.96033 -2.625,-34.5625 l -0.2188,-0.75 -0.3125,-0.71875 c -2.9167,-6.40275 -9.181,-10.82231 -16.6875,-10.59374 z m 6.0625,53.99999 c 0,0.0101 0.05,0.0315 0.062,0.0625 l -0.6245,1.46875 c 0.3311,-0.86163 0.5542,-1.56647 0.5625,-1.53125 z m 36.0625,48.28125 c 0.012,-0.004 0.019,0.005 0.031,0 l 0.063,0.3125 c -0.043,-0.19086 -0.061,-0.25465 -0.094,-0.3125 z"
442 style="color:#000000;fill:url(#linearGradient4451);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
443 <path
444 d="m 133.3461,36.09636 c -1.692,0.49428 -2.8155,1.39846 -3.625,2.625 -0.8214,1.24442 -1.3243,2.85069 -1.5938,4.625 -0.5342,3.51732 -0.1953,7.61208 -0.3438,10.8125 0,0.0285 0,0.0654 0,0.0937 1.6063,23.27388 0.8692,46.5905 2.1876,69.75 a 0.88388823,0.88388823 0 0 1 0,0.0625 c 0.033,3.4213 0.83,7.53419 2.5937,10.59375 1.7438,3.02495 4.2922,5.00636 8.2187,4.75 0.011,-7.3e-4 0.02,7.7e-4 0.031,0 1.6857,-0.39978 2.7542,-1.19719 3.5313,-2.3125 0.7819,-1.12237 1.2391,-2.59827 1.4687,-4.25 0.4593,-3.30346 2e-4,-7.22907 -0.062,-10.25 a 0.88388823,0.88388823 0 0 1 0,-0.0312 c -0.023,-3.75401 -1.179,-8.58343 -1.25,-13.1875 -0.071,-4.59014 1.0512,-9.12033 5.5625,-11.84375 0.012,-0.008 0.019,-0.023 0.031,-0.0312 8.2411,-5.75335 21.2001,0.72746 19.9687,11.1875 0,0.011 0,0.0202 0,0.0312 -4e-4,0.01 4e-4,0.0216 0,0.0312 -0.1662,4.44678 -0.6416,9.92071 0.094,14.71875 0.7386,4.81878 2.5857,8.83105 7.2188,10.84375 a 0.88388823,0.88388823 0 0 1 0.031,0 c 1.4264,0.65196 2.625,0.67804 3.6876,0.3125 1.0625,-0.36554 2.0152,-1.15367 2.7812,-2.21875 1.532,-2.13016 2.2012,-5.36524 1.6562,-7.8125 a 0.88388823,0.88388823 0 0 1 0,-0.15625 c -0.1887,-6.82351 0.1073,-14.35845 -1,-21.28125 -1.1026,-6.89383 -3.5864,-13.13587 -9.3124,-17.6875 -7.7294,-3.90433 -18.3437,-5.25802 -25.7813,-0.25 -0.7734,1.48479 -2.3237,3.00623 -4,3.78125 -0.9043,0.41808 -1.982,0.65336 -2.875,0.0312 -0.8519,-0.59346 -1.0866,-1.72753 -0.9687,-3.1875 0.01,-0.0705 -0.01,-0.11538 0,-0.1875 -1.6634,-15.48034 1.9617,-31.38045 -2.2813,-45.9375 -1.0363,-2.2749 -3.4784,-3.85945 -5.9687,-3.625 z"
445 id="path4440"
446 style="fill:#484848;fill-opacity:1;stroke:none" />
447 <path
448 id="path4206"
449 d="m 500.00794,37.6397 c -0.47,-0.0246 -0.9099,0.13839 -1.375,0.15625 -0.3182,0.036 -0.6564,-0.0583 -0.9688,0 l 0,0.0937 c -5.9486,0.59666 -11.3199,4.27914 -13.8124,8.625 -2.5191,4.39212 -3.1643,9.07388 -2.4688,13.75001 -0.5691,24.07161 -0.3288,48.17845 0.031,71.96874 l 0.031,1.1875 0.2813,1.125 c 2.2758,9.05358 10.1204,12.94327 17.2812,13.3125 3.5804,0.18461 7.6057,-0.50128 11.25,-3.21875 3.4431,-2.56742 5.753,-7.21537 6.0625,-11.6875 l 0.062,0 c 0.024,-0.26477 0.01,-0.51719 0.031,-0.78125 1.2169,-14.32127 -0.1813,-27.63851 0.6563,-39.5625 0.8412,-12.28307 -0.4559,-23.97948 -0.6563,-34.18749 0.9168,-4.19732 0.7514,-8.64033 -1.75,-13.09376 -2.5398,-4.52202 -8.6787,-7.57722 -14.4374,-7.5625 -0.073,1.9e-4 -0.1457,-0.001 -0.2188,0 l 0,-0.125 z m -0.4375,10.46875 1.5625,8.375 c -0.089,0.0884 -0.5399,0.26586 -0.9688,0.50001 -0.4433,-0.17558 -0.588,-0.31717 -1.125,-0.59376 l 0.5313,-8.28125 z m 1.625,8.6875 0.125,0.65626 c 0,-5.2e-4 -0.146,-0.0578 -0.1563,-0.0625 0.013,-0.26164 0.01,-0.41632 0.031,-0.59376 z"
450 style="color:#000000;fill:url(#linearGradient4449);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
451 <path
452 id="path4208"
453 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
454 style="fill:#484848;fill-opacity:1;stroke:none" />
455 <path
456 id="path4210"
457 d="m 544.51954,53.6313 c -7.5784,-0.46784 -10.6755,10.08558 -4.626,14.19825 6.4831,5.13984 16.9776,-2.57743 12.9884,-10.24836 -1.4384,-3.20261 -5.1136,-4.25984 -8.3624,-3.94989 z"
458 style="fill:#000000;fill-opacity:1;stroke:none" />
459 <path
460 id="path4212"
461 d="m 66.312222,57.93009 c -17.370703,0.62829 -30.0641,20.09681 -26.023403,36.39781 2.1928,10.05075 13.8541,12.09708 22.635103,11.4922 7.1377,-0.5151 17.6041,2.45346 16.7319,11.49222 -1.8676,6.29718 -10.9897,4.97438 -16.0667,5.21679 -7.019003,0.3042 -14.551803,-2.83467 -21.309203,-1.0251 -5.546297,3.71601 -0.7698,11.63178 4.4362,13.09902 11.6204,3.85396 24.776703,2.98561 36.677203,0.52396 8.494404,-1.78465 13.976704,-9.66183 14.007304,-18.12905 0.5362,-8.45978 -0.1252,-18.85777 -9.082,-22.63511 -7.833304,-4.5437 -17.524404,-2.59996 -25.744004,-4.64578 -6.504303,-3.75215 -4.590203,-15.08325 3.2137,-15.54417 8.376,-2.645 16.5844,3.54335 24.730904,1.74653 6.8027,-2.75685 5.6777,-13.26551 -1.2924,-15.19486 C 82.177322,57.19274 73.972122,57.9802 66.312222,57.93009 Z"
462 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:38;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
463 <path
464 id="path4214"
465 d="m 66.146122,46.92095 -0.2187,0.0312 c -25.268203,0.91394 -41.9786,26.29641 -36.375,49.71875 0,0.01 0,0.0214 0,0.0312 0.023,0.0937 0.039,0.18758 0.062,0.28125 l 0.062,0 c 1.4158,6.03031 5.2241,10.72981 9.5937,13.9375 l -1.5937,0.4375 -1.5313,1 c -3.4934,2.34058 -6.2461,6.40677 -7.0312,10.4375 -0.7852,4.03073 0.016,7.64447 1.2812,10.53125 2.4625,5.61698 6.4364,9.72109 12.843797,11.6875 l 0,0.0312 c 0.1235,0.0409 0.2514,0.0537 0.375,0.0937 0.044,0.0142 0.081,0.0484 0.125,0.0625 14.2876,4.59699 29.052403,3.33987 41.875007,0.6875 l 0.031,0 c 13.703,-2.87897 22.354804,-15.23519 22.687504,-28.1875 l 0.031,0 c 0.01,-0.1043 -0.01,-0.23849 0,-0.34375 0,-0.10511 0.031,-0.20733 0.031,-0.3125 l -0.031,0 c 0.275,-4.68022 0.3633,-10.21921 -1.4063,-16.21875 -1.6128,-5.46789 -5.6186,-11.40935 -11.718704,-15.03125 C 110.28983,79.05558 108.57813,56.15757 93.550926,50.6395 83.076822,45.62854 73.121622,46.96476 66.394622,46.92075 l -0.25,0 z M 49.927419,124.0772 c 0.4736,0.11312 0.7429,0.17483 0.6875,0.1875 -0.1379,-0.0437 -0.3009,-0.0484 -0.4375,-0.0937 l -0.25,-0.0937 z"
466 style="color:#000000;fill:url(#linearGradient4447);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
467 <path
468 d="M 67.047,59.37761 C 50.7565,60.01346 38.6203,78.63489 42.422,93.97136 a 1.4420115,1.4420115 0 0 1 0,0.0312 c 0.9874,4.52574 3.9833,7.14275 7.9688,8.71875 3.9854,1.576 8.921,1.948 13.1562,1.65625 3.8182,-0.27555 8.4163,0.35581 12.1562,2.34375 3.74,1.98794 6.6157,5.6345 6.125,10.71875 a 1.4420115,1.4420115 0 0 1 -0.062,0.28125 c -0.5618,1.89409 -1.746,3.32797 -3.1876,4.25 -1.4415,0.92203 -3.0867,1.39395 -4.7812,1.65625 -3.3889,0.5246 -7.0334,0.23046 -9.4062,0.34375 -7.4077,0.32104 -14.726,-2.60314 -20.7813,-1.09375 -0.9228,0.69289 -1.3969,1.4625 -1.5625,2.3125 -0.1806,0.92739 -0.017,2.01851 0.4688,3.125 0.9708,2.21298 3.281,4.32492 5.3437,4.90625 a 1.4420115,1.4420115 0 0 1 0.062,0 c 11.2515,3.73156 24.1465,2.93253 35.9062,0.5 7.7821,-1.63499 12.8466,-8.87337 12.875,-16.71875 a 1.4420115,1.4420115 0 0 1 0,-0.0937 c 0.2634,-4.15469 0.2008,-8.71518 -0.9374,-12.5625 -1.1383,-3.84732 -3.227,-6.9152 -7.2813,-8.625 a 1.4420115,1.4420115 0 0 1 -0.1563,-0.0937 c -7.233,-4.1955 -16.6908,-2.33856 -25.375,-4.5 a 1.4420115,1.4420115 0 0 1 -0.375,-0.15625 c -7.593,-4.38022 -5.364,-17.27483 3.5,-18.15625 l 0,-0.0312 c 0.1153,-0.0364 0.2288,-0.0291 0.3438,-0.0625 4.5012,-1.3064 8.8395,-0.37995 12.875,0.59375 4.0804,0.98454 7.88,1.92841 11.4688,1.1875 5.4755,-2.31046 4.4951,-10.8333 -1.1876,-12.40625 a 1.4420115,1.4420115 0 0 1 -0.2812,-0.0937 c -6.5535,-3.28332 -14.4405,-2.57842 -22.1875,-2.625 -0.021,-1.3e-4 -0.042,1.4e-4 -0.062,0 z"
469 id="path4442"
470 style="fill:#484848;fill-opacity:1;stroke:none" />
471 <path
472 id="path4218"
473 d="m 334.91414,52.45217 -0.5624,0.0312 c -10.692,0.64182 -26.7608,2.35866 -35.4063,16.28126 l -0.375,0.59375 -0.2813,0.625 c -2.6168,5.92672 -0.4865,12.63582 3.8126,16.24999 2.47,2.0766 6.1544,2.97511 9.8124,2.75 -12.1731,7.16212 -18.9579,21.29295 -17.0937,35.5 -0.9321,10.0329 5.7963,19.42583 15.4375,21.90625 l 0,0.0312 c 13.5839,4.67628 27.0449,3.11875 38.7812,0.90625 1.4491,0.98507 3.2876,2.06677 5.5626,3 2.2748,0.93323 5.2583,1.74964 8.75,1.34375 3.4915,-0.40589 7.1195,-2.30283 9.625,-4.875 l 0.375,-0.34375 0.3124,-0.40625 c 5.3642,-6.74967 5.6479,-14.75709 5.2188,-20.5625 -0.4291,-5.80541 -1.211,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.75 c -0.9297,-14.08097 -0.732,-30.77734 -7.9062,-46.62499 -0.4593,-1.65783 -1.3753,-2.43205 -2.625,-3.4999 -10.8288,-9.19166 -23.8588,-8.03267 -31.8438,-8.50001 l -0.5938,-0.0312 z m 22.0626,47.46875 c 0.2983,4.01025 0.663,7.89337 0.9374,12.09375 -0.3619,6.15055 0.7536,11.18085 1.0313,14.9375 0.091,1.23358 -3e-4,1.89681 -0.031,2.71875 -0.7261,-0.49389 -0.8804,-0.56988 -1.7812,-1.1875 l -3.5,-2.40625 -4.1562,0.84375 c -11.8502,2.42474 -23.4896,3.77093 -32.7188,0.59375 l -0.75,-0.25 -0.8125,-0.15625 c -0.7563,-0.12889 -0.7437,-0.008 -0.5937,-0.75 l 0.375,-1.875 -0.3438,-1.875 c -1.3223,-7.37497 4.0726,-16.31882 11.1562,-18.03125 l 0.5626,-0.15625 0.5312,-0.1875 c 1.5591,-0.56829 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.48444 15.6563,0.0312 l 1.4687,-0.34375 1.3125,-0.75 c 1.5458,-0.8862 2.8481,-1.95265 3.9688,-3.125 z"
474 style="color:#000000;fill:url(#linearGradient4445);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
475 <path
476 d="m 442.8461,65.50261 c -9.9417,-0.25223 -20.0112,1.83054 -27.125,8.78125 a 1.4249747,1.4249747 0 0 1 -0.1876,0.125 c -0.4923,0.34955 -1.0141,0.64308 -1.6874,0.65625 -0.6734,0.0132 -1.3402,-0.39879 -1.6876,-0.8125 -0.6947,-0.82743 -0.7686,-1.5945 -0.9687,-2.34375 -0.2001,-0.74925 -0.4246,-1.47139 -0.6563,-1.84375 -0.2316,-0.37236 -0.2624,-0.39819 -0.6874,-0.40625 a 1.4249747,1.4249747 0 0 1 -0.6563,-0.1875 c -2.1511,-1.16691 -4.3134,-0.58174 -5.9063,0.90625 -1.5928,1.48799 -2.4145,3.81205 -1.5937,6.125 a 1.4249747,1.4249747 0 0 1 0.094,0.46875 c 0.099,20.08519 -1.9054,40.73856 3.75,59.71875 1.2377,1.74956 4.0539,2.66609 6.4063,2.28125 1.2075,-0.19755 2.2216,-0.71247 2.8437,-1.40625 0.6222,-0.69378 0.9615,-1.54589 0.75,-2.96875 a 1.4249747,1.4249747 0 0 1 0,-0.375 c 1.5091,-15.16756 -3.1254,-31.94343 3.25,-47.28125 a 1.4249747,1.4249747 0 0 1 0.031,-0.0625 c 2.3884,-4.77662 7.2847,-8.50018 12.5937,-10.03125 5.3091,-1.53107 11.2689,-0.75156 15.1563,3.84375 a 1.4249747,1.4249747 0 0 1 0.1563,0.1875 c 2.0694,3.60071 1.6918,8.0153 1.9687,11.75 0.1385,1.86735 0.4194,3.54061 1.0313,4.875 0.5916,1.2904 1.4751,2.25734 3.0312,3 1.4606,0.20734 2.5297,-0.051 3.4375,-0.6875 0.9587,-0.67214 1.771,-1.81376 2.375,-3.21875 1.2079,-2.80999 1.508,-6.6831 1.1563,-9.25 -1.6601,-6.82503 -2.269,-14.23556 -6.2813,-19.1875 -2.6943,-2.32961 -6.6692,-2.77567 -10.5313,-2.65625 a 1.4249747,1.4249747 0 0 1 -0.062,0 z"
477 id="path4436"
478 style="fill:#484848;fill-opacity:1;stroke:none" />
479 <path
480 id="path4224"
481 d="m 548.52594,68.07721 -1.2187,0.25 c -8.6956,1.82574 -14.1425,9.53796 -15.9688,15.68749 -1.8263,6.14954 -1.7462,11.84707 -1.8125,15.71875 l 0,0.125 0,0.125 c 0.1092,10.79916 -0.5536,24.0134 4.9063,37 0.01,0.0225 0.022,0.0401 0.031,0.0625 2.7726,6.62078 9.3817,9.9621 15.5625,9.5625 5.6001,-0.36206 11.8353,-5.2195 13.5,-11.53125 5.3924,-17.21633 5.3013,-35.62075 1.75,-52.53125 l -0.1563,-0.6875 -0.2187,-0.62499 c -0.7814,-2.19128 -1.853,-4.62969 -3.9375,-7.1875 -2.0845,-2.55781 -5.8401,-5.71667 -11.1875,-5.9375 l -1.25,-0.0312 z"
482 style="color:#000000;fill:url(#linearGradient4443);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
483 <path
484 d="m 550.1139,78.59636 c -4.5226,0.97522 -6.7823,4.26272 -8,8.375 -1.2232,4.13111 -1.3087,9.03503 -1.375,12.90625 0.1123,11.09592 -0.2043,22.90976 4.0938,33.09375 0.9213,2.22841 3.1731,3.32073 5.25,3.1875 2.0769,-0.13323 3.906,-1.39 4.1562,-4.09375 a 0.46475483,0.46475483 0 0 1 0.031,-0.0937 c 4.7332,-15.11164 4.7084,-31.85462 1.4687,-47.28125 -0.4788,-1.32581 -1.2248,-2.85305 -2.1874,-4.03125 -0.9629,-1.17844 -2.1146,-1.98485 -3.4376,-2.0625 z"
485 id="path4438"
486 style="fill:#484848;fill-opacity:1;stroke:none" />
487 <path
488 id="path4229"
489 d="m 242.87094,52.92092 -0.5938,0.0312 c -10.6919,0.64192 -26.7607,2.35873 -35.4062,16.28131 l -0.375,0.59375 -0.2813,0.65625 c -2.6168,5.92671 -0.4864,12.60456 3.8125,16.21874 2.4771,2.0825 6.1757,2.98309 9.8438,2.75 -12.176,7.14722 -18.9659,21.26849 -17.125,35.46875 -0.9665,10.0609 5.7999,19.48906 15.4687,21.96875 l -0.031,0.0312 c 13.5891,4.67806 27.073,3.12012 38.8125,0.90625 1.4445,0.97996 3.2715,2.07302 5.5313,3 2.2749,0.93323 5.2585,1.71839 8.75,1.3125 3.4915,-0.40589 7.1509,-2.27156 9.6562,-4.84375 l 0.3438,-0.375 0.3125,-0.40625 c 5.3641,-6.74969 5.6478,-14.72585 5.2187,-20.53125 -0.4291,-5.8054 -1.2109,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.78125 c -0.9297,-14.081 -0.7006,-30.74608 -7.875,-46.59374 l -0.9375,-2.0625 -1.7187,-1.4375 c -10.8287,-9.19167 -23.8276,-8.06392 -31.8125,-8.53126 l -0.5938,-0.0312 z m 22.0312,47.5 c 0.2974,4.00059 0.6637,7.87292 0.9375,12.0625 -0.3619,6.15055 0.7536,11.2121 1.0313,14.96875 0.091,1.22812 0,1.86766 -0.031,2.6875 -0.7261,-0.49388 -0.8805,-0.56989 -1.7813,-1.1875 l -3.5,-2.40625 -4.1562,0.875 c -11.8502,2.42475 -23.4582,3.77094 -32.6875,0.59375 l -0.7813,-0.28125 -0.8125,-0.125 c -0.7563,-0.12888 -0.7437,-0.0396 -0.5938,-0.78125 l 0.375,-1.84375 -0.3437,-1.875 c -1.3223,-7.37494 4.0726,-16.35008 11.1562,-18.0625 l 0.5625,-0.125 0.5313,-0.1875 c 1.5591,-0.56828 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.45313 15.6562,0 l 1.4688,-0.3125 1.3125,-0.75 c 1.5458,-0.8862 2.8482,-1.95265 3.9687,-3.125 z"
490 style="color:#000000;fill:url(#linearGradient4441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
491 <path
492 d="m 243.6361,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z"
493 id="path4426"
494 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
495 <path
496 d="m 252.9376,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z"
497 id="path5306"
498 style="color:#000000;fill:url(#linearGradient4439);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
499 <path
500 id="text4338"
501 d="m 550.24144,11.97714 c -4.7431,8e-5 -9.3884,1.94508 -12.1562,5.65625 -2.3938,3.20927 -3.2655,7.28209 -3.5,11.84374 -5.2417,0.10768 -9.658,0.71067 -13.2813,2.53125 -3.7519,1.88519 -6.5576,5.75636 -6.9063,9.9375 l -0.062,0 c -0.013,0.1027 0.011,0.20947 0,0.3125 0,0.043 -0.03,0.0819 -0.031,0.125 l 0.031,0 c -0.383,3.94189 0.8037,8.08581 3.625,10.84375 1.7434,1.70445 3.9242,2.79035 6.3124,3.59375 l -0.875,2.4375 -0.062,0.125 -0.031,0.125 c -1.0239,3.32791 -0.9882,7.09444 0.8437,10.15625 1.8322,3.06181 4.9132,4.85334 8.3438,5.90625 l 0.7188,0.21875 0.75,0 2.2812,0 c 4.1038,5e-5 8.0184,-1.11288 11.1562,-3.5 1.388,-1.05587 2.5677,-2.38102 3.5938,-3.8125 2.738,2.5559 6.0541,4.80834 10,6.78125 l 0.5,0.25 0.5312,0.15625 c 3.235,0.79227 6.3972,0.95306 9.4063,-0.1875 2.9956,-1.13542 5.3523,-3.78973 6.4375,-6.71875 l 0.031,0 0,-0.0312 c 1.3188,-3.58119 1.0754,-7.65809 -0.4687,-11.1875 -0.3593,-0.82136 -0.9637,-1.56048 -1.4375,-2.34375 0.7988,-0.35352 1.5774,-0.75006 2.3125,-1.28125 3.1456,-2.2731 4.4669,-6.43958 4.1563,-10.25 l 0.031,0 c 0,-0.12851 -0.061,-0.24691 -0.062,-0.375 -0.017,-0.15367 0.023,-0.31671 0,-0.46875 l -0.062,0 c -0.2506,-3.85862 -2.6242,-7.47641 -5.875,-9.5625 -3.1968,-2.05143 -7.2278,-3.19745 -12.0625,-4.03124 -0.5947,-4.02941 -1.4462,-7.64148 -3.125,-10.53125 -2.2702,-3.9078 -6.5646,-6.71865 -11.0625,-6.71875 z m 18.3125,50.62499 c 0.2654,0.97712 0.2969,1.7705 -0.031,2.65625 l 0,0.0312 c -0.3181,0.86918 -0.3036,0.72198 -0.625,0.84375 -0.2585,0.098 -1.2073,0.14918 -2.5624,-0.0625 0.3313,-0.1475 0.7366,-0.14338 1.0312,-0.34375 l 0.4375,-0.28125 0.375,-0.40625 c 0.5814,-0.62017 0.9776,-1.55372 1.375,-2.4375 z"
502 style="color:#000000;fill:#305f00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10" />
503 <g
504 id="text4342"
505 style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:165.01513672px;line-height:125%;font-family:'comic andy';-inkscape-font-specification:'comic andy';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4437);fill-opacity:1;stroke:none">
506 <path
507 id="path101"
508 style="fill:url(#linearGradient4437);fill-opacity:1"
509 d="m 550.24549,16.984496 q 8.54083,0 9.83001,16.920498 l 2.33664,0 q 15.22844,2.33664 15.0673,9.668855 1.28918,8.621397 -11.03861,7.976806 9.42713,8.299101 6.7682,15.470169 -2.09492,5.72074 -9.99116,3.786969 -8.70197,-4.350985 -12.32779,-9.991151 l -1.5309,0 q -3.3841,9.991151 -13.13353,9.991151 l -2.25606,0 q -8.13796,-2.497788 -5.88189,-9.830003 l 2.82008,-7.815659 -0.80574,0 q -11.92492,-1.692049 -10.79688,-10.555167 0.32229,-8.137954 16.35648,-8.218527 4.43155,-0.483443 3.70639,-2.820083 0,-14.583858 10.87746,-14.583858 z m -4.5927,16.034186 -0.16115,4.512133 q -0.24172,3.384099 -2.17549,3.384099 l -12.73066,0.725164 q -2.98123,0.08057 -2.98123,2.417214 0,2.256067 3.22295,2.417214 11.19976,-0.564016 10.47459,1.530902 l -2.25606,4.834428 q -5.72074,8.621396 -2.82009,10.152299 3.86754,2.33664 10.95804,-12.08607 1.69205,-1.530902 2.82008,0 4.99558,5.317871 8.21853,8.70197 3.30353,3.3841 5.31787,2.014345 2.41721,-2.578361 -1.28918,-5.559592 -3.62582,-3.061804 -8.2991,-8.379675 -0.48344,-1.772623 0.24172,-1.772623 15.79246,1.047459 15.14787,-2.014345 0.48345,-3.3841 -13.69754,-3.3841 -2.17549,0.402869 -3.54525,-1.047459 l 0,-7.896232 q 0,-6.607052 -3.14238,-6.526478 -3.3841,-0.805738 -3.30352,7.976806 z" />
510 </g>
511 <path
512 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
513 id="path4714"
514 d="m 335.7911,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z" />
515 <path
516 style="color:#000000;fill:url(#linearGradient4435);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
517 id="path5310"
518 d="m 345.6192,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z" />
519 </g>
520 </g>
521 </g>
522</svg>
diff --git a/doc/md/images/firefoxshare.png b/doc/md/images/firefoxshare.png
new file mode 100644
index 00000000..98c2fdd3
--- /dev/null
+++ b/doc/md/images/firefoxshare.png
Binary files differ
diff --git a/doc/md/images/rss-filter-1.png b/doc/md/images/rss-filter-1.png
new file mode 100644
index 00000000..d2a03f67
--- /dev/null
+++ b/doc/md/images/rss-filter-1.png
Binary files differ
diff --git a/doc/md/images/rss-filter-2.png b/doc/md/images/rss-filter-2.png
new file mode 100644
index 00000000..538b126e
--- /dev/null
+++ b/doc/md/images/rss-filter-2.png
Binary files differ
diff --git a/doc/md/index.md b/doc/md/index.md
new file mode 100644
index 00000000..37a9c1fc
--- /dev/null
+++ b/doc/md/index.md
@@ -0,0 +1,11 @@
1Welcome to the [Shaarli](https://github.com/shaarli/Shaarli/) wiki!
2
3Here you can find some info on how to use, configure, tweak and solve problems with your Shaarli.
4
5For general info, read the [README](https://github.com/shaarli/Shaarli/blob/master/README.md).
6
7If you have any questions or ideas, please join the [chat](https://gitter.im/shaarli/Shaarli) (also reachable via [IRC](https://irc.gitter.im/)), post them in our [general discussion](https://github.com/shaarli/Shaarli/issues/308) ([archive](https://github.com/shaarli/Shaarli/issues/44)) or read the current [issues](https://github.com/shaarli/Shaarli/issues). If you've found a bug, please create a [new issue](https://github.com/shaarli/Shaarli/issues/new).
8
9If you would like a feature added to Shaarli, check the issues labeled [`feature`](https://github.com/shaarli/Shaarli/labels/feature), [`enhancement`](https://github.com/shaarli/Shaarli/labels/enhancement), and [`plugin`](https://github.com/shaarli/Shaarli/labels/plugin).
10
11_Note: This documentation is available online at https://github.com/shaarli/Shaarli/wiki, and locally in the `doc/` directory of your Shaarli installation._