en

designoir

Silbentrennung

Die Klasse Silbentrennung kann eingesetzt werden, um in einem Text lange Wörter automatisch zu trennen und somit Layoutprobleme zu vermeiden. Lücken wegen zu langer Wörter können vor allem Blocksatz unlesbar machen, aber auch wenn rechtsbündiger Fließtext in der Breite wenig Platz hat, können unschöne, den Lesefluss behindernde Effekte auftreten:

Screenshot welt.de

Hier hätte eine automatische Silbentrennung einen guten Dienst getan – optimalerweise nur auf den bebilderten Einleitungsabsatz angewandt, da die restlichen Absätze in der Regel breiter sind.

An dieser Stelle sei aber angemerkt, dass „automatisch“ in diesem Fall eher halb- als vollautomatisch bedeutet. Das Verfahren ist konzeptbedingt nicht perfekt, wie spätere Beispiele zeigen werden. Und ein falsch getrenntes Wort ist nicht weniger peinlich als eines, das für eine schmale Spalte zu breit ist. Ein guter Kompromiss ist es, den Text beim Veröffentlichungsprozess vom Autor oder Lektor gegengelesen zu lassen (was ja in der Regel sowieso passiert – oder passieren sollte), sodass dieser nebenbei die Trennung kontrollieren kann. Im Gegenzug spart man sich, wenn ein Wort mal wieder das Layout sprengt, die Suche nach einem alternativen Begriff oder das manuelle Trennen mit , was ebenfalls fehleranfällig ist:

Screenshot sport1.de

Silbentrennung.php

Benötigt: Preprocess

<?php

/**
 * class Silbentrennung
 * Zum Erkennen von Silben und Trennen von Wörtern in deutschsprachigen Texten.
 * Copyright (C) 2006  Dao Gottwald  <dao at design-noir.de>
 * 
 * Licensed under the terms of the GNU Lesser General Public License:
 *   http://www.opensource.org/licenses/lgpl-license.php
 *
 * Die Trennregeln wurden mithilfe folgender Seiten erstellt:
 *   http://www.ruediger-weingarten.de/Orthographie/Silbentrennung.htm
 *   http://www.ifi.unizh.ch/CL/volk/LexMorphVorl/Lexikon12.Gener.html
 *   http://www.schneid9.de/pdf/ling07.pdf
 *
 * @version  1.2.6
 */

require_once 'Preprocess.php';

class Silbentrennung extends Preprocess {
    private
        $zeichen, $rZeichen,        /* Trennzeichen */
        $min_wortlaenge,        /* minimale Länge zu trennender Wörter */
        $min_silbenlaenge,        /* minimale Länge einer Silbe */
        $offset;            /* Anzahl der Buchstaben, die am Wortanfang/-ende nicht abgetrennt werden sollen */
    private static
        $a = '[a-zßäÄüÜöÖ]',        /* alle Buchstaben */
        $v = 'aeiouäÄüÜöÖy',        /* Vokalbuchstaben */
        $pattern = array();
    
    public function __construct ($min_wortlaenge = 16, $min_silbenlaenge = 3, $offset = 4, $zeichen = '&shy;') {
        $this->min_wortlaenge = (int) $min_wortlaenge;
        $this->min_silbenlaenge = (int) $min_silbenlaenge;
        $this->offset = (int) $offset;
        $this->zeichen = (string) $zeichen;
        $this->rZeichen = preg_quote ($this->zeichen, '~');
        
        if (empty (self::$pattern)) {
            /* Konsonantenbuchstaben */
            $k = 'bcdfghklmnpqrßtvwxz';
            
            /* besondere Konsonanten */
            $_k = 's';
            
            /* Vokale */
            $v = self::$v;
            
            /* Digraphen und Konsonanten */
            $d = "(?:s?ch|s[tp]|[$k]|s(?!ch))";
            
            self::$pattern[] = "ß(?![$v])";
            /* Prefixe */
            self::$pattern[] = "(?:durch|hinter|hinaus|miss|[üÜ]ber)";
            self::$pattern[] = "\B(?=durch|hinter|hinaus|miss|[üÜ]ber)";
            self::$pattern[] = "(?>\b)(?:a[nb](?![$v])|au[fs]|be|ent|emp|er|ge|[vz]er|fehl|um|unter|voll|wie?der|ex)";
            self::$pattern[] = "(?:au[fs]|be|ein|ent|emp|er|ge|[vz]er|fehl|um|unter|voll|wie?der|ex)(?![$v])";
            
            /* Suffixe */
            self::$pattern[] = "(?:igen?|lichen?|schafts?|[$k$_k]ungs?|[hk]eits?)";
            self::$pattern[] = "\B(?=igen?|lichen?|schaft|[$k$_k]ung|[hk]eit)";
            
            /* bei mindestens einem Konsonanten zwischen zwei Vokalen wird vor dem letzten Konsonant getrennt */
            self::$pattern[] = "[$v]$d{1,3}?(?={$d}h?[$v])";
            
            self::$pattern = implode ('|', self::$pattern);
        }
    }
    
    public function run ($text) {
        if (is_array ($text)) {
            $text = $text[0];
        }
        
        if (strpos ($text, '<') !== false && strpos ($text, '<') < strpos ($text, '>')) {
            $this->text =& $text;
            $this->_escape_init();
            $this->_escape_comments_cdata();
            $this->_escape_content ('head', 'pre', 'code', 'blockcode', 'textarea');
            $text = '>'. $text. '<';
            $text = preg_replace_callback ('~>[^<]+<~s', array ($this,'run'), $text);
            $this->_escape_fin();
            return substr ($text, 1, -1);
        }
        
        if ($this->min_wortlaenge > 1) {
            $text = preg_replace_callback ('~'.self::$a.'{'.$this->min_wortlaenge.',}~i', array ($this,'_worttrenn'), $text);
        } else {
            $text = preg_replace_callback ('~'.self::$a.'+~i', array ($this,'_worttrenn'), $text);
        }
        return $text;
    }
    
    private function _worttrenn (array $wort) {
        $wort = $wort[0];
        $a = self::$a;
        $v = self::$v;
        $z = $this->rZeichen;
        
        $wort = preg_replace ('~'.self::$pattern.'~i', '\\0'.$this->zeichen, $wort);
        $wort = preg_replace ("~$z\$~", '', $wort);
        $wort = preg_replace ("~$z([^$v]+)\$~i", '\\1', $wort);
        if ($this->offset) {
            $o = $this->offset;
            $wort = preg_replace ("~^($a{1,$o})$z~i", '\\1', $wort);
            $wort = preg_replace ("~$z($a{1,$o})\$~i", '\\1', $wort);
        }
        if ($this->min_silbenlaenge) {
            $m = $this->min_silbenlaenge;
            $wort = preg_replace ("~(?<=$z)($a{1,$m})$z~i", '\\1', $wort);
        }
        return $wort;
    }
}

?>

Dem Konstruktor können folgende optionale Argumente übergeben werden:

int $min_wortlaenge
Bestimmt, wie lang ein Wort mindestens sein muss, um getrennt zu werden. Es kann 0 angegeben werden, um alle Wörter zu behandeln. Der Standardwert ist 16.
int $min_silbenlaenge
Gibt an, wie viele Buchstaben eine Silbe mindestens umfassen muss, um abgetrennt zu werden. Auch hier kann 0 angegeben werden, um keine Mindestlänge festzulegen. Der Standardwert ist 3.
int $offset
Die Anzahl der Buchstaben, die am Anfang und Ende eines Wortes nicht abgetrennt werden sollen. 0 deaktiviert diese Funktionalität. Der Standardwert ist 4.
string $zeichen
Das Zeichen, mit dem die Wörter getrennt werden. Standardwert ist &shy; – ein „nachgiebiger“ Bindestrich, der Wörter nur trennt, wenn sie sich am Zeilenende befinden, und ansonsten nicht sichtbar ist. MSIE, Opera und Konqueror haben &shy; korrekt implementiert, Firefox erst ab der Version 3 (in älteren Version wird der Trennstrich nie angezeigt).

Nach einer Instanziierung kann die Methode run() aufgerufen werden. Sie erwartet den zu behandelnden Text als Argument und gibt diesen nach der vollzogenen Silbentrennung zurück. Der Text darf HTML-Code enthalten. HTML-Tags werden dabei nicht behandelt, außerdem wird der gesamte Inhalt von <!--...-->, <![CDATA[...]]>, <head>...</head>, <pre>...</pre>, <code>...</code> und <textarea>...</textarea> ignoriert.

Beispiel #1: Zusammensetzung.php

Es folgt ein Beispiel mit einigen zusammengesetzten Wörtern. Zur Anschaulichkeit wird ein immer sichtbares Trennzeichen und keine minimale Wort- und Silbenlänge verwendet.

<?php

ob_start (array (new Silbentrennung (0, 0, 0, '-'), 'run'));

?>Ehre + Tribüne
Ehrentribüne

Moskau + treu
moskautreu

Widerstand + Gruppe
Widerstandsgruppe

selbst + verständlich
selbstverständlich

Unterhaltung + Software
Unterhaltungssoftware

Bildung + Ministerien
Bildungsministerien

national + Sozialismus
Nationalsozialismus

Geschwindigkeit + Begrenzer
Geschwindigkeitsbegrenzer

Geschwindigkeit + Überschreitung
Geschwindigkeitsüberschreitung

Krieg + Gedenken + Tag
Kriegsgedenktag

mehr + Spieler + Namen
Mehrspielernamen

Licht + Spiel + Theater
Lichtspieltheater

Zusammensetzung.php ausführen

Wie man sieht, arbeitet die automatische Trennung in einzelnen Wörtern recht zuverlässig. Doch wenn zwei Wörter zusammentreffen, hat der Algorithmus in ungünstigen Fällen keine Chance, die Konsonanten einer Silbe zuzuordnen. Treffen mehr als drei Konsonanten aufeinander, wird daher nicht getrennt.

Zwar werden auf diese Weise einige Wortgrenzen sowie Silben (die im Deutschen bis zu fünf Konsonanten hintereinander enthalten können) übersehen, aber Ziel war es auch nicht, alle Silben zu finden. Und für die Praxis ist eine übersehene Silbe besser als eine falsche. Dennoch ist es ein offensichtlicher Nachteil, dass gerade einige der besten Stellen zum Trennen nicht gefunden werden (nämlich Wortgrenzen). Um dieses Manko zu beheben, müsste man mindestens auf eine Datenbank von Wortstämmen zurückgreifen.

Ebenfalls um potenzielle Fehlerquellen zu dezimieren, werden die meisten Silben, die mit einem Vokal enden und eigentlich korrekt erkannt werden könnten, übergangen. Auch diese Einschränkung sollte in Kauf genommen werden, da sie tatsächlich keinen Nachteil darstellt – in den interessanten, überlangen Wörtern finden sich noch genügend Möglichkeiten für eine Trennung.

Nicht abgefangen werden kann der Fall, dass bei zusammengesetzten Wörtern eines mit einem Konsonanten endet und das folgende mit zwei Konsonanten beginnt. Hier schlägt die wichtigste Trennregel unweigerlich zu: „Bei mindestens einem Konsonanten zwischen zwei Vokalen wird vor dem letzten Konsonant getrennt.“

Beispiel #2: lange_Wörter.php

Hier werden noch einmal gezielt lange Wörter betrachtet. Diesmal mit praxistauglichen Parametern, abgesehen vom Trennzeichen.

<?php

ob_start (array (new Silbentrennung (12, 3, 4, '-'), 'run'));

?>mehrere
Unterprivilegierter
auseinanderzusetzen
Ehrentribüne
moskautreu
Widerstandsgruppe
selbstverständlich
Unterhaltungssoftware
Bildungsministerien
Nationalsozialismus
Geschwindigkeitsbegrenzer
Geschwindigkeitsüberschreitung
Kriegsgedenktag
Mehrspielernamen
Lichtspieltheater

lange_Wörter.php ausführen

Beispiel #3

Absatz.php

Es folgt eine Anwendung, wie sie in der Praxis aussehen könnte. Die Klasse wird sinnvoll instanziiert und die Silbentrennung auf die gesamte Ausgabe angewandt:

<?php

ob_start (array (new Silbentrennung (14), 'run'));

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
    <title>Silbentrennung</title>
    <style type="text/css"><!--
    
    p {
        border: 1px solid red;
        width: 10em;
    }
    
    --></style>
</head>
<body>
    <p>
        Der moskautreue tschetschenische Präsident Achmad Kadyrow ist tot: Attentäter hatten während der Feiern zum
        Kriegsgedenktag mit einer Mine die voll besetzte Ehrentribüne des Stadions in Grosny gesprengt. Die Explosion
        tötete mehrere Menschen und verletzte Dutzende. Russlands Präsident Putin kündigte Vergeltung an.
    </p>
</body>
</html>

Silbentrennung_opt.php

Abschließend noch eine kürzere, auf Geschwindigkeit optimierte Implementierung der Klasse:

<?php

/**
 * class Silbentrennung
 * Zum Erkennen von Silben und Trennen von Wörtern in deutschsprachigen Texten.
 * Copyright (C) 2006  Dao Gottwald  <dao at design-noir.de>
 * 
 * Licensed under the terms of the GNU Lesser General Public License:
 *   http://www.opensource.org/licenses/lgpl-license.php
 *
 * Die Trennregeln wurden mithilfe folgender Seiten erstellt:
 *   http://www.ruediger-weingarten.de/Orthographie/Silbentrennung.htm
 *   http://www.ifi.unizh.ch/CL/volk/LexMorphVorl/Lexikon12.Gener.html
 *   http://www.schneid9.de/pdf/ling07.pdf
 *
 * @version  1.2.6_opt
 */

require_once 'Preprocess.php';

class Silbentrennung extends Preprocess {
    private
        $zeichen, $rZeichen,        /* Trennzeichen */
        $min_wortlaenge,        /* minimale Länge zu trennender Wörter */
        $min_silbenlaenge,        /* minimale Länge einer Silbe */
        $offset;            /* Anzahl der Buchstaben, die am Wortanfang/-ende nicht abgetrennt werden sollen */
    
    public function __construct ($min_wortlaenge = 16, $min_silbenlaenge = 3, $offset = 4, $zeichen = '&shy;') {
        $this->min_wortlaenge = (int) $min_wortlaenge;
        $this->min_silbenlaenge = (int) $min_silbenlaenge;
        $this->offset = (int) $offset;
        $this->zeichen = (string) $zeichen;
        $this->rZeichen = preg_quote ($this->zeichen, '~');
    }
    
    public function run ($text) {
        if (is_array ($text)) {
            $text = $text[0];
        }
        
        if (strpos ($text, '<') !== false && strpos ($text, '<') < strpos ($text, '>')) {
            $this->text =& $text;
            $this->_escape_init();
            $this->_escape_comments_cdata();
            $this->_escape_content ('head', 'pre', 'code', 'blockcode', 'textarea');
            $text = '>'. $text. '<';
            $text = preg_replace_callback ('~>[^<]+<~s', array ($this,'run'), $text);
            $this->_escape_fin();
            return substr ($text, 1, -1);
        }
        
        if ($this->min_wortlaenge > 1) {
            $text = preg_replace_callback ('~[a-zßäÄüÜöÖ]{'.$this->min_wortlaenge.',}~i', array ($this,'_worttrenn'), $text);
        } else {
            $text = preg_replace_callback ('~[a-zßäÄüÜöÖ]+~i', array ($this,'_worttrenn'), $text);
        }
        return $text;
    }
    
    private function _worttrenn (array $wort) {
        $wort = $wort[0];
        $wort = preg_replace ('~ß(?![aeiouäÄüÜöÖy])|(?:durch|hinter|hinaus|miss|[üÜ]ber)|\B(?=durch|hinter|hinaus|miss|[üÜ]ber)|(?>\b)(?:a[nb](?![aeiouäÄüÜöÖy])|au[fs]|be|ent|emp|er|ge|[vz]er|fehl|um|unter|voll|wie?der|ex)|(?:au[fs]|be|ein|ent|emp|er|ge|[vz]er|fehl|um|unter|voll|wie?der|ex)(?![aeiouäÄüÜöÖy])|(?:igen?|lichen?|schafts?|[bcdfghklmnpqrßtvwxzs]ungs?|[hk]eits?)|\B(?=igen?|lichen?|schaft|[bcdfghklmnpqrßtvwxzs]ung|[hk]eit)|[aeiouäÄüÜöÖy](?:s?ch|s[tp]|[bcdfghklmnpqrßtvwxz]|s(?!ch)){1,3}?(?=(?:s?ch|s[tp]|[bcdfghklmnpqrßtvwxz]|s(?!ch))h?[aeiouäÄüÜöÖy])~i', '\\0'.$this->zeichen, $wort);
        $wort = preg_replace ('~'.$this->rZeichen.'$~', '', $wort);
        $wort = preg_replace ('~'.$this->rZeichen.'([^aeiouäÄüÜöÖy]+)$~i', '\\1', $wort);
        if ($this->offset) {
            $wort = preg_replace ('~^([a-zßäÄüÜöÖ]{1,'.$this->offset.'})'.$this->rZeichen.'~i', '\\1', $wort);
            $wort = preg_replace ('~'.$this->rZeichen.'([a-zßäÄüÜöÖ]{1,'.$this->offset.'})$~i', '\\1', $wort);
        }
        if ($this->min_silbenlaenge) {
            $wort = preg_replace ('~'.$this->rZeichen.'([a-zßäÄüÜöÖ]{1,'.$this->min_silbenlaenge.'})(?='.$this->rZeichen.')~i', '\\1', $wort);
        }
        return $wort;
    }
}

?>

Kommentare

  1. Timmy meinte am 22. Mai ’07, 12:04 Uhr ():
    Ein tolles Tutorial!
    So stellt man sich das vor. Da ja die deutsche (wie auch so gut wie jede andere) Sprache nur im Groben mathematischen regeln folgt, ist das hier schließlich ein sehr schwieriges Thema. Tolle Lösung auf jeden Fall!
    Grüße aus München, Timmy
  2. Jofris meinte am 24. Mai ’07, 22:47 Uhr ():
    Tolles Script,

    nur leider bekomme ich immer die Fehlermeldung:

    Parse error: syntax error, unexpected T_ARRAY, expecting ’&’ or T_VARIABLE.

    Bekomme ich leider auch nicht weg…
  3. Dao meinte am 24. Mai ’07, 23:58 Uhr ():
    Timmy: Danke!

    Jofris, ich empfehle PHP 5.1.0 – damit sollte es keine Probleme geben. Mit PHP 5.0 geht es eventuell auch, wenn du |array| aus |private function _worttrenn (array $wort) {| entfernst.
  4. Haze meinte am 21. Juni ’07, 19:25 Uhr ():
    Wirklich klasse gemacht und die Ergebnisse können sich sehen lassen!
  5. nate meinte am 4. Juli ’07, 12:02 Uhr ():
    Das Skript ist wirklich toll!
    Leider habe ich das Problem, dass es nicht alle Wörter trennt und Wörter in denen Umlaute vorkommen trennt es auch nicht.
  6. Dao meinte am 4. Juli ’07, 12:11 Uhr ():
    nate: Das Script ist als UTF-8 gespeichert. Wenn deine Umlaute anders kodiert sind, speicher das Script einfach in derselben Kodierung ab.
  7. nate meinte am 4. Juli ’07, 13:24 Uhr ():
    ja danke das hat schon mal geklappt, allerdings wird z.B. das Wort „jedoch“ nicht getrennt. Kannst du mir da einen Tipp geben.

    Im Voraus schon mal danke
  8. Dao meinte am 4. Juli ’07, 16:21 Uhr ():
    Nach „je“ wird nicht getrennt, weil die Silbe mit einem Vokal endet (steht unter Beispiel #1). Das Script könnte die Silbe zwar in diesem Fall korrekt trennen, in anderen Wörtern würde das aber zu falschen Resultaten führen.
  9. Yves meinte am 31. Oktober ’07, 13:00 Uhr ():
    Hallo Dao. Die Klasse ist wirklich erstaunlich, jedoch erziele ich oft falsche Resultate. Ich spiele dann immer ein bisschen mit den Settings rum, jedoch komme ich noch nicht zu befriedigenden Resultaten. Ein Beispiel ist das Wort „Filmproduktionsfirma“, welches laut meinem Ansatz durch die Silbentrennung wiefolgt getrennt wird:
    Filmp-roduk-tions-fir-ma, mich stört hauptsächlich der Vorschlag Filmp-roduk. Hast du irgend eine Möglichkeit, wie ich die Settings richtig machen kann, dass es wirklich nur dann trennt, wenns zu 99,9999% richtig ist? Grüsse Yves
  10. Timo meinte am 15. Juli ’08, 13:11 Uhr ():
    Hallo Dao…
    super Sache diese Klasse…nur leider komm ich mit meinem Anfänger PHP Wissen leider nicht weiter…ich habe eine Variable $titel in der z.B. der Text „Unfall beim Vielseitigkeitsspringturnier“ gespeichert ist. Wie sollte dann der „Aufruf“ erfolgen???

    Danke
    Timo
  11. Dao meinte am 15. Juli ’08, 13:15 Uhr ():
    z.B.:
    $sb = new Silbentrennung();
    echo $sb->run($titel);
  12. Mathias Haimerl meinte am 16. September ’08, 09:09 Uhr ():
    Hallo Miteinander,
    Ich hätte einen Vorschlag die Funktionalität des scripts zu erhöhen.

    PHP bietet mit der GD-Bibliothek, die so gut wie jede PHP-Kopie enthält, eine Funktion namens imagettfbox (http://de2.php.net/imagettfbox).
    Mit Hilfe dieser Funktion und der ttf-Datei der Schrift, die auf der Seite verwendet wird könnte man die breite, die der Text haben darf besser abschätzen. Bereits ein einfaches Script, dass ich zur Füllung eines Layers beutzt geschrieben habe (Umbruch nach einer bestimmten Breite) funktioniert hiermit wunderbar.

    Grüße
    Mathias
  13. arokim meinte am 5. März ’09, 13:03 Uhr ():
    ich habe einen fehler bemerkt:
    wenn man $offset auf 2 stellt gibt es probleme bei wörtern mit „ß“ z.B. „Rege­lmäßig“. Es werden zwei kryptische Zeichen anstelle des „ß“ ausgegeben

    ich versuche gerade einen drupal input filter (http://drupal.org/project/modules?filters=tid…tle_sort%20asc) daraus zu machen. wenns mir gelingt werde ich auf jeden fall spenden.

    gute arbeit
  14. arokim meinte am 5. März ’09, 13:12 Uhr ():
    achja, bei $offset auf 4 passiert das auch bei „Dreißiger“
  15. Georg Klimm meinte am 5. Juni ’10, 13:41 Uhr ():
    Sehr gute Arbeit! Ein überaus hilfreiches Modul! Vielen Dank!
  16. CroneKorkN meinte am 29. Juni ’10, 20:31 Uhr ():
    @arokim:
    PHP ist bis 5.2 nicht UTF-8-kompatibel, daher werden 2-bytige Sonderzeichen wie Umlaute oder das o.g. „ß“ wie zwei ein-byte-Zeichen behandelt. Wird genau zwischen diesen beiden Bytes getrennt, die eigentlich zu einem Zeichen gehören, kommen zwei ungewollte Zeichen heraus.
  17. ElDong meinte am 16. August ’10, 19:55 Uhr ():
    Klasse gemacht.
    Frage: Gibt es bereits eine Datenbank mit fertig getrennten Begriffen? Wenn ja: Kann man die irgendwo beziehen? Falls nein: Besteht die Möglichkeit, zentral eine Wörterliste aufzubauen, die jeder nutzen kann?
    Ich finde die Silbentrennung sehr gut - zumindest besserals alles was ich bisher auf dem PHP-Sektor gesehen habe. Ich werde die Klasse mal mit vielen langen Texten einsetzen und die getrennten Wörter sowie die ggfs. manuell korrigierten/getrennten sammeln. Kann die gerne der Allgemeinheit zur Verfügung stellen, wenn da eine zentrale Anlaufstelle existiert.
  18. Keks meinte am 7. September ’10, 15:34 Uhr ():
    Hallo,

    ich würde das Script gern ausprobieren, bekomme aber die Fehlermeldung:

    Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ’}’ in /www/htdocs/Adresse-hier-entfernt/Silbentrennung.php on line 24

    Ich habe es so aufgerufen wie in der Antwort auf Timos Frage (mit eigener Variable mit normalem String). Und PHP5 wird unterstützt.
  19. Keks meinte am 7. September ’10, 19:23 Uhr ():
    Sorry, hat sich geklärt, der Server war versehentlich noch auf PHP4 geschaltet ;-)

Kommentare sind geschlossen.

Geändert am 28. Januar ’07 Kontakt
aggressiv akt andromeda bar beine blue efeu frontal fugaetu industriell komet land noir rost rot sonnenblume splash split winter wolke zeit