.. You may want to use the usual include line. Uncomment and adjust the path. .. include:: ../Includes.txt =============== EXT: Easy Login =============== :Author: Christopher :Created: 2010-12-18T19:57:23 :Changed: 2015-09-04T10:48:06.225000000 :Classification: easylogin :Keywords: forDevelopers, forIntermediates, login, openID, Google, facebook, myOpenID, Yahoo!, Wordpress, Twitter, Xing :Author: Markus Kappe :Email: markus.kappe@dix.at :Language: en .. _img-1-img-2-EXT-Easy-Login: |img-1| |img-2| EXT: Easy Login =============================== Extension Key: easylogin Language: en Keywords: forDevelopers, forIntermediates, login, openID, Google, facebook, myOpenID, Yahoo!, Wordpress, Twitter, Xing Copyright 2011-now, Markus Kappe, This document is published under the Open Content License available from http://www.opencontent.org/opl.shtml The content of this document is related to TYPO3 \- a GNU/GPL CMS/Framework available from www.typo3.org .. _Table-of-Contents: Table of Contents ----------------- **`EXT: Easy Login 1 <#__RefHeading__5708_1738894311>`_** **`Introduction 3 <#__RefHeading__5710_1738894311>`_** `What does it do? 3 <#__RefHeading__463_413120346>`_ `Screenshots 3 <#__RefHeading__465_413120346>`_ **`Users manual 4 <#__RefHeading__467_413120346>`_** `FAQ 4 <#__RefHeading__31509_818911409>`_ **`Installation 5 <#__RefHeading__31511_818911409>`_** **`Configuration 7 <#__RefHeading__31515_818911409>`_** `CONTENTELEMENT Example 9 <#__RefHeading__1340_1208785427>`_ `OPENID Example 9 <#__RefHeading__1342_1208785427>`_ `FACEBOOK Example 9 <#__RefHeading__1344_1208785427>`_ `OAUTH1 Example 10 <#__RefHeading__1346_1208785427>`_ **`Known problems 11 <#__RefHeading__31525_818911409>`_** **`To-Do list 12 <#__RefHeading__477_413120346>`_** **`ChangeLog 13 <#__RefHeading__31623_818911409>`_** `Upgrade 13 <#__RefHeading__1099_1092570689>`_ `References 13 <#__RefHeading__1487_377959828>`_ .. _Introduction: Introduction ------------ .. _What-does-it-do: What does it do? ^^^^^^^^^^^^^^^^ Enables Login via facebook, OpenID (Google, Yahoo!, etc.) and OAuth (twitter) additionally to the common TYPO3 Login. .. _Screenshots: Screenshots ^^^^^^^^^^^ Here you see what the extension does: |img-3| Users manual ------------ How it works: click on the Login button, and after supplying your credentials (e.g. on the facebook site) and confirming the authorization you are logged in as an ordinary TYPO3 frontend user. You may get redirected if configured so in the felogin plugin. .. _FAQ: FAQ ^^^ Q: Can this extension be used to register a user? A: Yes, a TYPO3 user record is created, if configured so (see allowCreate) Q: What is XRDS? A: OpenID checks if the returnurl is allowed, so that no hacker can redirect your request to a spoof url. It does this by asking the server from which the authentication request originated from. XRDS is an XML document which defines the allowed returnurl. A HTTP header in your TYPO3 site contains the url to the XRDS document. Q: What is my verification URL? A: Take a look in your HTML source (the page with the easylogin plugin) and search for verifyUrl. Q: I get the error “No template has been specified” ( `https://forge.typo3.org/issues/44640 `_ ) A: Are you working on Windows? Then you must configure the template\_path (TypoScript Setup) with backslashes like this: :: plugin.tx_dixeasylogin_pi1.template_path = typo3conf\ext\dix_easylogin\templates Q: My page object is not named “page” or my TypoScript already uses the page.2 path. What should I do? ( `https://forge.typo3.org/issues/44642 `_ ) A: Instead of including the static template, have a look in static/setup.txt and constants.txt within this extension. Copy the code to your own TypoScript and change it as you need (e.g. replace page.2 with seite.3) Q: How do I configure a custom OpenID Server? ( `https://forge.typo3.org/issues/48973 `_ ) A: Please take a look at static/setup.txt. You can easily add your own OPENID provider. Just add something like this to your TypoScript Setup: :: plugin.tx_dixeasylogin_pi1.provider { 100 = OPENID 100.name = MyOwnOpenIdService 100.url = https://www.myserver.xyz/ 100.icon = fileadmin/icons/myicon.gif 100.showWhenLoggedIn = {$plugin.tx_dixeasylogin_pi1.allowUpdate} } Q: How do I configure redirects after login? ( `https://forge.typo3.org/issues/48972 `_ ) A: Redirect are not part of dix\_easylogin. You can do it with felogin (just include the regular felogin in easylogin as described in the install section). Q: I don't want to be asked for my MyOpenID username by TYPO3. (https://forge.typo3.org/issues/49010) A: If you want to disable the input, this TypoScript Setup does the trick: :: plugin.tx_dixeasylogin_pi1.provider.30.url = http://myopenid.com/ .. _Installation: Installation ------------ Be sure you have cURL installed. Create a facebook app (https://developers.facebook.com/apps) with your domain and write down the App ID and the App Secret Create a twitter app (https://dev.twitter.com/apps/new) with your domain and write down the Consumer ID and the Consumer Secret Create a Linkedin app (https://www.linkedin.com/secure/developer) with your domain and write down the API Key and the Secret Key. You will need to enter the verification URL (see FAQ). Google changed from OpenID to OAuth2, so you should register a Google app as well ( `https://console.developers.google.com/ `_ → APIS & AUTH) and write down the Client ID and the Client Secret. You will need to enter the verification URL (see FAQ). Note that due to compatibility you have to enable “google\_oauth2” and disable “google” in TS constants. Install extension Insert a content element "login" on any page, it can be on a page not visible to the user (e.g. "hide in menu").Write down uid of that record.That login should work (that means a user storage page with a user record and usergroup record has been created and the page id of the user storage is configured. If you are not sure what that means, read this: `http://wiki.typo3.org/Felogin `_ ) Insert a content element "plugin" - "easylogin" on the login page Include the static TypoScript (Include static (from extensions): Easylogin), insert these constants into your TS template and fit them to your needs: :: plugin.tx_dixeasylogin_pi1 { # if jQuery, jQueryUI and the lightness theme should be included by default. # if turned off, you have to take care for yourself that the libraries # are loaded (smart if other extensions also include jQuery) include_jQuery = 1 # if the user should be created when not already found in the database allowCreate = 1 # if a mail should be sent to the admin if the user is created mailAdminOnCreate = 0 mailAdminFrom = user@domain.com mailAdminTo = user@domain.com # create user only if email address matches this domain(s) # e.g. "example.com, *.mycompany.org" trustedDomains = * # if the user should be able to connect his login with a login provider # when already authenticated allowUpdate = 1 # where the fe_users records should be stored when created user_pid = 6 # when a user is created, he will get this usergroup(s) usergroup = 1 # page where the "easylogin" plugin is located # used for the xrds definition pid_loginPage = 21 # uid of the common login uid_felogin = 10 # register a facebook app to get these two values facebook_appID = YOUR-APP-ID facebook_appSecret = YOUR-APP-SECRET # register a twitter app to get these two values twitter_consumerKey = YOUR-CONSUMER-KEY twitter_consumerSecret = YOUR-CONSUMER-SECRET # register a xing app to get these two values xing_consumerKey = YOUR-CONSUMER-KEY xing_consumerSecret = YOUR-CONSUMER-SECRET # register a linkedin app to get these two values linkedin_consumerKey = YOUR-CONSUMER-KEY linkedin_consumerSecret = YOUR-CONSUMER-SECRET # register a google app to get these two values google_clientID = YOUR-CONSUMER-KEY google_clientSecret = YOUR-CONSUMER-SECRET # enable or disable login methods disable.felogin = 0 disable.google = 1 disable.yahoo = 0 disable.myopenid = 0 disable.wordpress = 0 disable.facebook = 0 disable.facebook_oauth2 = 1 disable.twitter = 0 disable.xing = 0 disable.linkedin = 0 disable.google_oauth2 = 0 } .. _Configuration: Configuration ------------- TypoScript Constants .. ### BEGIN~OF~TABLE ### .. _include-jQuery: include\_jQuery ^^^^^^^^^^^^^^^ .. container:: table-row Property include\_jQuery Data type bool Description If jQuery, jQueryUI and the lightness theme should be included by default. If turned off, you have to take care for yourself that the libraries are loaded (smart if other extensions also include jQuery) Default 1 .. _allowCreate: allowCreate ^^^^^^^^^^^ .. container:: table-row Property allowCreate Data type bool Description If the user should be created when not already found in the database Default 1 .. _mailAdminOnCreate: mailAdminOnCreate ^^^^^^^^^^^^^^^^^ .. container:: table-row Property mailAdminOnCreate Data type bool Description If set to true, the admin receives a notification when an account is created Default 0 .. _mailAdminFrom: mailAdminFrom ^^^^^^^^^^^^^ .. container:: table-row Property mailAdminFrom Data type string Description Email address of the sender Default user@example.com .. _mailAdminTo: mailAdminTo ^^^^^^^^^^^ .. container:: table-row Property mailAdminTo Data type string Description Email address of the recipient Default user@example.com .. _trustedDomains: trustedDomains ^^^^^^^^^^^^^^ .. container:: table-row Property trustedDomains Data type string Description comma separated, \* is wildcard. user will only be created if this matches the email address. Default \* .. _allowUpdate: allowUpdate ^^^^^^^^^^^ .. container:: table-row Property allowUpdate Data type bool Description if the user should be able to connect his login with a login provider when already authenticated Default 1 .. _user-pid: user\_pid ^^^^^^^^^ .. container:: table-row Property user\_pid Data type int Description Where the fe\_users records should be stored when created Default 6 .. _usergroup: usergroup ^^^^^^^^^ .. container:: table-row Property usergroup Data type list of integers Description When a user is created, he will get this usergroup(s) Default 1 .. _pid-loginPage: pid\_loginPage ^^^^^^^^^^^^^^ .. container:: table-row Property pid\_loginPage Data type int Description Page where the "easylogin" plugin is located used for the xrds definition Default 21 .. _uid-felogin: uid\_felogin ^^^^^^^^^^^^ .. container:: table-row Property uid\_felogin Data type int Description uid of the common login Default 10 .. _facebook-appID: facebook\_appID ^^^^^^^^^^^^^^^ .. container:: table-row Property facebook\_appID Data type string Description You must fill this in if you want facebook auth to work. Get this at `https://developers.facebook.com/apps `_ Default YOUR-APP-ID .. _facebook-appSecret: facebook\_appSecret ^^^^^^^^^^^^^^^^^^^ .. container:: table-row Property facebook\_appSecret Data type string Description You must fill this in if you want facebook auth to work. Get this at `https://developers.facebook.com/apps `_ Default YOUR-APP-SECRET .. _twitter-consumerKey: twitter\_consumerKey ^^^^^^^^^^^^^^^^^^^^ .. container:: table-row Property twitter\_consumerKey Data type string Description You must fill this in if you want twitter auth to work. Get this at `https://dev.twitter.com/apps/new `_ Default YOUR-CONSUMER-KEY .. _twitter-consumerSecret: twitter\_consumerSecret ^^^^^^^^^^^^^^^^^^^^^^^ .. container:: table-row Property twitter\_consumerSecret Data type string Description You must fill this in if you want twitter auth to work. Get this at `https://dev.twitter.com/apps/new `_ Default YOUR-CONSUMER-SECRET .. _xing-consumerKey: xing\_consumerKey ^^^^^^^^^^^^^^^^^ .. container:: table-row Property xing\_consumerKey Data type string Description You must fill this in if you want xing auth to work. Get this at `https://dev.xing.com/applications `_ Default YOUR-CONSUMER-KEY .. _xing-consumerSecret: xing\_consumerSecret ^^^^^^^^^^^^^^^^^^^^ .. container:: table-row Property xing\_consumerSecret Data type string Description You must fill this in if you want twitter auth to work. Get this at `https://dev.xing.com/applications `_ Default YOUR-CONSUMER-SECRET .. _disable: disable ^^^^^^^ .. container:: table-row Property disable Data type array Description Define which login methods are enabled :: disable.felogin = 0 disable.google = 0 disable.yahoo = 0 disable.myopenid = 0 disable.wordpress = 0 disable.facebook = 0 disable.twitter = 0 disable.xing = 0 disable.linkedin = 0 Default (see description) .. ###### END~OF~TABLE ###### [ts constants:plugin.tx\_dixeasylogin\_pi1] TypoScript Setup .. ### BEGIN~OF~TABLE ### .. _allowCreate: allowCreate ^^^^^^^^^^^ .. container:: table-row Property allowCreate Data type bool Description If the user should be created when not already found in the database Default (see constants) .. _allowUpdate: allowUpdate ^^^^^^^^^^^ .. container:: table-row Property allowUpdate Data type bool Description if the user should be able to connect his login with a login provider when already authenticated Default (see constants) .. _trustedDomains: trustedDomains ^^^^^^^^^^^^^^ .. container:: table-row Property trustedDomains Data type string Description comma separated, \* is wildcard. user will only be created if this matches the email address Default (see constants) .. _user-pid: user\_pid ^^^^^^^^^ .. container:: table-row Property user\_pid Data type int Description Where the fe\_users records should be stored when created Default (see constants) .. _usergroup: usergroup ^^^^^^^^^ .. container:: table-row Property usergroup Data type list of integers Description When a user is created, he will get this usergroup(s) Default (see constants) .. _pid-loginPage: pid\_loginPage ^^^^^^^^^^^^^^ .. container:: table-row Property pid\_loginPage Data type int Description Page where the "easylogin" plugin is located used for the xrds definition Default (see constants) .. _optionalInfo: optionalInfo ^^^^^^^^^^^^ .. container:: table-row Property optionalInfo Data type list of strings Description These attributes are optionally requested when authenticating via OpenID Default nickname,email,fullname,postcode,country,prefix,firstname,lastname,suf fix .. _requiredInfo: requiredInfo ^^^^^^^^^^^^ .. container:: table-row Property requiredInfo Data type list of strings Description These attributes are requested when authenticating via OpenID Default nickname,email,fullname,postcode,country,prefix,firstname,lastname,suf fix .. _template-path: template\_path ^^^^^^^^^^^^^^ .. container:: table-row Property template\_path Data type string Description Where the fluid templates are located Default EXT:dix\_easylogin/templates .. _provider: provider ^^^^^^^^ .. container:: table-row Property provider Data type array of ->providers Description Array of login methods. An element can have the types CONTENTELEMENT, OPENID, FACEBOOK and OAUTH1 Default (see typoscript\_setup.txt) .. _preserveGETvars: preserveGETvars ^^^^^^^^^^^^^^^ .. container:: table-row Property preserveGETvars Data type keyword or comma separated list Description “all” or list of GET variables that should be preserved during the authentication process. Works just like in fe\_login. Beware that facebook cannot handle URLs with QUERY\_STRING (that means with a question mark in it) Default tx\_ttnews .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1] Providers / common attributes .. ### BEGIN~OF~TABLE ### .. _name: name ^^^^ .. container:: table-row Property name Data type string Description Display name for the tab-nav Default .. _icon: icon ^^^^ .. container:: table-row Property icon Data type string Description Icon for display on the side of the name Default .. _showWhenLoggedIn: showWhenLoggedIn ^^^^^^^^^^^^^^^^ .. container:: table-row Property showWhenLoggedIn Data type bool Description If the tab should be rendered when the user is logged in. Probably makes sense only with felogin Default depends on allowUpdate .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1.provider.#] Providers / CONTENTELEMENT .. ### BEGIN~OF~TABLE ### .. _uid: uid ^^^ .. container:: table-row Property uid Data type int Description The uid of the content element that should be rendered. Inteded for the use of felogin Default .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1.provider.# CONTENTELEMENT] .. _CONTENTELEMENT-Example: CONTENTELEMENT Example ^^^^^^^^^^^^^^^^^^^^^^ :: plugin.tx_dixeasylogin_pi1.provider { 5 = CONTENTELEMENT 5.name = User/Pass 5.uid = 212 5.showWhenLoggedIn = 1 } Providers / OPENID .. ### BEGIN~OF~TABLE ### .. _url: url """ .. container:: table-row Property url Data type string Description The discovery url of the OpenID Provider. When it contains the string ###NAME### a input field for the username is rendered. What the user entered here will substitute the marker Default .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1.provider.# OPENID] .. _OPENID-Example: OPENID Example ^^^^^^^^^^^^^^ :: plugin.tx_dixeasylogin_pi1.provider { 30 = OPENID 30.name = myOpenID 30.url = http://###NAME###.myopenid.com/ 30.icon = EXT:dix_easylogin/res/icons/myopenid.ico 30.showWhenLoggedIn = {$plugin.tx_dixeasylogin_pi1.allowUpdate} } Providers / FACEBOOK .. ### BEGIN~OF~TABLE ### .. _appId: appId """"" .. container:: table-row Property appId Data type string Description You must fill this in if you want facebook auth to work. Get this at `https://developers.facebook.com/apps `_ Default .. _appSecret: appSecret """"""""" .. container:: table-row Property appSecret Data type string Description You must fill this in if you want facebook auth to work. Get this at `https://developers.facebook.com/apps `_ Default .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1.provider.# FACEBOOK] .. _FACEBOOK-Example: FACEBOOK Example ^^^^^^^^^^^^^^^^ :: plugin.tx_dixeasylogin_pi1.provider { 50 = FACEBOOK 50.name = facebook 50.icon = EXT:dix_easylogin/res/icons/facebook.jpg 50.appId = {$plugin.tx_dixeasylogin_pi1.facebook_appID} 50.appSecret = {$plugin.tx_dixeasylogin_pi1.facebook_appSecret} 50.showWhenLoggedIn = {$plugin.tx_dixeasylogin_pi1.allowUpdate} } Providers / OAUTH1 .. ### BEGIN~OF~TABLE ### .. _sigMethod: sigMethod """"""""" .. container:: table-row Property sigMethod Data type string Description sigMethod is one of these: HMAC\_SHA1 PLAINTEXT RSA\_SHA1 Default HMAC\_SHA1 .. _consumerKey: consumerKey """"""""""" .. container:: table-row Property consumerKey Data type string Description You must fill this in if you want OAuth to work. Get this at your OAuth provider docs. Default .. _consumerSecret: consumerSecret """""""""""""" .. container:: table-row Property consumerSecret Data type string Description You must fill this in if you want OAuth to work. Get this at your OAuth provider docs. Default .. _requestTokenUrl: requestTokenUrl """"""""""""""" .. container:: table-row Property requestTokenUrl Data type string Description You must fill this in if you want OAuth to work. Get this at your OAuth provider docs. Default .. _authorizeUrl: authorizeUrl """""""""""" .. container:: table-row Property authorizeUrl Data type string Description You must fill this in if you want OAuth to work. Get this at your OAuth provider docs. Default .. _accessTokenUrl: accessTokenUrl """""""""""""" .. container:: table-row Property accessTokenUrl Data type string Description You must fill this in if you want OAuth to work. Get this at your OAuth provider docs. Default .. _requestProfileUrl: requestProfileUrl """"""""""""""""" .. container:: table-row Property requestProfileUrl Data type string Description You must fill this in if you want OAuth to work. This is the url for the API call to retrieve details about the user. You can use markers in the requestProfileUrl, the corresponding values from the accessToken-response will be substituted Get this at your OAuth provider API docs. Default .. _profileMap: profileMap """""""""" .. container:: table-row Property profileMap Data type array Description Associate internal fields with the response parameters from the profile request. Possible keys: fullname, firstname, lastname, suffix, prefix, postcode, country, nickname, email. See example below. Default .. ###### END~OF~TABLE ###### [ts setup:plugin.tx\_dixeasylogin\_pi1.provider.# OAUTH1] .. _OAUTH1-Example: OAUTH1 Example ^^^^^^^^^^^^^^ :: plugin.tx_dixeasylogin_pi1.provider { # OAuth Version 1.1 as used by Twitter 60 = OAUTH1 60.name = Twitter 60.icon = EXT:dix_easylogin/res/icons/twitter.gif 60.sigMethod = HMAC_SHA1 60.consumerKey = {$plugin.tx_dixeasylogin_pi1.twitter_consumerKey} 60.consumerSecret = {$plugin.tx_dixeasylogin_pi1.twitter_consumerSecret} 60.requestTokenUrl = https://api.twitter.com/oauth/request_token 60.authorizeUrl = https://api.twitter.com/oauth/authorize 60.accessTokenUrl = https://api.twitter.com/oauth/access_token # you can use markers in the requestProfileUrl, the corresponding values from the accessToken-response will be substituted 60.requestProfileUrl = https://api.twitter.com/1/users/lookup.json?user_id=###user_id### 60.showWhenLoggedIn = {$plugin.tx_dixeasylogin_pi1.allowUpdate} 60.profileMap { # format: # key = response parameter # possible keys: fullname, firstname, lastname, suffix, prefix, postcode, country, nickname, email nickname = screen_name fullname = name id = id } } Please have a look at the file static/setup.txt within this extension for more examples .. _Known-problems: Known problems -------------- - Does not work without cURL - Without realurl or cooluri properly configured, the facebook login will not work. The reason is that the dynamically constructed URL that contains plugin-vars must not have a question mark '?' in it. Have a look at the extension configuration (Extension Manager). Example configuration for realurl: :: $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['postVarSets']['_DEFAULT']['easylogin'] = array( '0' => array ( 'GETvar' => 'tx_dixeasylogin_pi1[action]', ), ); - Thus the preserveGETvars = all configuration will not work with easylogin. Restore the configuration on the login page to the default, or see forge 45222 for further details. - If you have - directly under your root - a page with the name easylogin and try to install easylogin on any other than that specific page you get an error that the piVars are unknown. This is due to the realurl configuration mentioned above. Solution: rename the page (or at least the nav title or the realurl title). - Fixed: Logout doesn't work directly after a “connect” action (forge 65724) - If you find some problems, please report them to `markus.kappe@dix.at `_ - When someone logs in by two different means, there will be created two different user accounts (fe\_users records). To avoid that, use the “connect” option (TS constant: allowUpdate = 1). The user has to connect to his second account (e.g. facebook) **while he is already logged in** with his first account (e.g. authenticated by Google). .. _To-Do-list: To-Do list ---------- - Better error handling, including check if username is filled in. - **DONE** with version 0.4.0: Feature: include OAuth2 - **DONE** with version 0.3.0: Check for duplicate usernames - Better manual (maybe someone will help on that? → `markus.kappe@dix.at `_ :) - Testing - Translations - **DONE** : Enable authentication with more than one authentication provider. - **DONE** with version 0.2.5: Better connection of foreign-identified user with fe\_user record. E.g. someone logs in with username/password and then connects to facebook and/or twitter. So these identifiers will get connected to the current user.Thanx to jan- hendrik.schreier[at]bits-iserlohn.de for some code on that feature - Feature “reviewed create”: Someone identifies via foreign provider, identifier is not in the database. The admin gets an email and if he clicks a confirmation link, the user gets confirmed (usergroup set or disabled=0). - **DONE** with version 0.2.4: Feature: redirect after login (just like felogin, probably get the redirect from felogin to work even when logging in with 3 :sup:`rd` party authentication providers) .. _ChangeLog: ChangeLog --------- See CHANGELOG.txt .. _Upgrade: Upgrade ^^^^^^^ The TypoScript Configuration changed from Version 0.1.2 to 0.2.0 completly When upgrading from 0.1.2 to 0.2.0 or above, you better delete your TypoScript and start over with the “Installation” section When upgrading from below 0.3.0, you have to run the Update Wizard. Otherwise your existing users will not be able to log in with their existing account anymore (the connection between user record and identifier has changed and will be broken without the update script). .. _References: References ^^^^^^^^^^ Google OAuth 2.0: `https://developers.google.com/accounts/docs/OAuth2Login `_ LinkedIn OAUth 2.0: https://developer.linkedin.com/documents/authentication Facebook OAuth 2.0: `https://developers.facebook.com/docs/facebook- login/manually-build-a-login-flow/v2.0 `_ .. ######CUTTER_MARK_IMAGES###### .. |img-1| image:: img-1.png .. :align: left .. :border: 0 .. :height: 44 .. :id: graphics5 .. :name: graphics5 .. :vspace: 57 .. :width: 161 .. |img-2| image:: img-2.png .. :align: left .. |img-3| image:: img-3.png .. :align: left .. :border: 0 .. :height: 529 .. :id: Grafik1 .. :name: Grafik1 .. :width: 631