diff --git a/.gitignore b/.gitignore index 57a1574..9f7ad62 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,6 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +OpenAntrag/Video/OpenAntrag-Administration.mp4 +OpenAntrag/Video/OpenAntrag-Administration.ogv +OpenAntrag/Video/OpenAntrag-Administration.webm diff --git a/OpenAntrag/App_Data/FederalStates.xml b/OpenAntrag/App_Data/FederalStates.xml new file mode 100644 index 0000000..556d4ec --- /dev/null +++ b/OpenAntrag/App_Data/FederalStates.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/App_Data/FeedbackStatusCodes.xml b/OpenAntrag/App_Data/FeedbackStatusCodes.xml new file mode 100644 index 0000000..9267d8b --- /dev/null +++ b/OpenAntrag/App_Data/FeedbackStatusCodes.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/OpenAntrag/App_Data/FeedbackTypes.xml b/OpenAntrag/App_Data/FeedbackTypes.xml new file mode 100644 index 0000000..3a1556b --- /dev/null +++ b/OpenAntrag/App_Data/FeedbackTypes.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/OpenAntrag/App_Data/GovernmentalLevels.xml b/OpenAntrag/App_Data/GovernmentalLevels.xml new file mode 100644 index 0000000..272c4b4 --- /dev/null +++ b/OpenAntrag/App_Data/GovernmentalLevels.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/App_Data/GroupTypes.xml b/OpenAntrag/App_Data/GroupTypes.xml new file mode 100644 index 0000000..1686892 --- /dev/null +++ b/OpenAntrag/App_Data/GroupTypes.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/App_Data/Teaser.xml b/OpenAntrag/App_Data/Teaser.xml new file mode 100644 index 0000000..71fad01 --- /dev/null +++ b/OpenAntrag/App_Data/Teaser.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/OpenAntrag/App_Data/piratenmandate.dtd b/OpenAntrag/App_Data/piratenmandate.dtd new file mode 100644 index 0000000..dabb990 --- /dev/null +++ b/OpenAntrag/App_Data/piratenmandate.dtd @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenAntrag/App_Data/piratenmandate.xml b/OpenAntrag/App_Data/piratenmandate.xml new file mode 100644 index 0000000..df60ed2 --- /dev/null +++ b/OpenAntrag/App_Data/piratenmandate.xml @@ -0,0 +1,2631 @@ + + + + + + + + + Oliver Dedow + + + + + + + + Axel Sieck + + + + + + Timo Ploog + + + + + + Christian Thiessen + + + + + + + + + Sven Lange + + + + + + + + + Toni Köppen + Claudia Beyer + + Einer der beiden PIRATEN-Mandatsträger war im November 2014 zur Neuen Liberalen übergelaufen, hatte aber in der Folge in einer gemeinsamen Fraktion „PIRATEN/Neue Liberale“ mitgewirkt. Als er im März 2015 sein Mandat niederlegte, fiel das Mandat wieder an die PIRATEN, die nun erneut eine eigene Fraktion bilden. + + + + + + Dr. Siegfried Hansen + Ilona Adamski + Susann Laatz + + Dr. Siegfried Hansen war als einziger Pirat in den Kreistag gewählt worden. Kurz vor der konstituierenden Sitzung gaben mit Ilona Adamski und Susann Laatz zwei der insgesamt dreizehn Abgeordneten der SPD ihren Übertritt zu den Piraten und die Gründung einer PIRATEN-Fraktion bekannt. Ilona Adamski übernahm den Vorsitz dieser Fraktion. + + + + + Dr. Siegfried Hansen + Sebastian Kolpert + + + + + + + + + + Andreas Gerhold + Wolfdietrich Thürnagel + + 2011 zogen die PIRATEN erstmals mit 2 Mandaten in die Bezirksversammlung Hamburg-Mitte ein. Ab 2012 bestand eine Fraktion nach dem Übertritt einer Grünen-Abgeordneten. Bei der folgenden Wahl zur Bezirksversammlung am 25. Mai 2014 wurden mit 4,4% der Stimmen erneut 2 Mandate errungen, aber das notwendige 3. Mandat für den Fortbestand der Fraktion knapp verpasst. Andreas Gerhold konnte als erster Pirat deutschlandweit zum zweiten Mal in Folge das gleiche Mandat erringen. + + + + + + Dorle Olszewski + Markus Pöstinger + + Bei der Wahl zur Bezirksversammlung am 25. Mai 2014 wurden 3,5% der Stimmen erreicht. Die PIRATEN sind damit in der BV mit 2 Mandaten erstmals vertreten, nachdem sie 2011 noch an der 3%-Hürde gescheitert waren. + + + + + + + + + Hans-Jürgen Hey + + + + + Ralf Kleyer und Hans-Jürgen Hey waren im September 2011 auf der PIRATEN-Liste in die Regionsversammlung gewählt worden und hatten eine PIRATEN-Fraktion gebildet. Im September 2013 trat aber Ralf Kleyer aus der Piratenpartei aus. Mit Auflösung der PIRATEN-Fraktion schloss sich Hans-Jürgen Hey mit einem Abgeordneten der Linken zu einer Gruppe zusammen. + + + + + Dirk Hillbrecht + + Im März 2013 ist ein Abgeordneter von der PIRATEN-Liste nachgerückt, der wenig später die Partei verlassen hat. So ist nur ein Sitz von einem Mitglied der Piratenpartei besetzt, die vorher bestehende Fraktion wurde aufgelöst. + + + + + Reiner Budnick + + + + + + Andis Rave + + + + + + Thomas Grote + + + + + + + Jan Nadaczinski + + + + + + + + + + Friedrich Bohm + + + + + + + + + Jens-Wolfhard Schicke-Uffmann + Claudia Jonda + + + + + + + Andreas Neugebauer + Florian Beyer + + + + + + Jan-Martin Meyer + + + + + + + + + Ralf ter Veer + + + + + + + + + Piroska Evenburg + Svante Evenburg + + + + + Svante Evenburg + + + + + + + + Frank Schulz + + Frank Schulz wurde am 11. September 2011 für die CDU in den Gemeinderat Schiffdorf gewählt. Im Februar 2012 trat zur der Piratenpartei über. + + + + Thomas Behra + + Thomas Behra wurde am 11. September 2011 für CDU in den Ortsrat Schiffdorf gewählt. Im April 2012 trat zur der Piratenpartei über. + + + + + Frank Schulz + + Frank Schulz wurde am 11. September 2011 für die CDU neben dem Gemeinderat Schiffdorf auch in den Ortsrat Sellstedt gewählt. Im Februar 2012 trat zur der Piratenpartei über. + + + + + + + Janto Just + + Janto Just wurde am 11. September 2011 auf der Liste „Bürger für Bürger“ in den Kreistag Friesland gewählt. Ende 2011 ist er in die Piratenpartei eingetreten, bleibt aber ebenfalls in der BfB-Fraktion aktiv. + + + + Janto Just + + Janto Just wurde am 11. September 2011 auf der Liste „Bürger für Bürger“ in den Stadtrat Schortens gewählt. Ende 2011 ist er in die Piratenpartei eingetreten, bleibt aber ebenfalls in der BfB-Fraktion aktiv. + + + + + + Stefan Domke + + + + + + + + + Matthias Stoll + + + + + + + Sören Tesch + + + + + + + + Stefan Domke + + + + + + + Stefan Domke + + + + + + + + + + + + Martin Rieth + Meinhart Ramaswamy + + + + + + + + + Arne Ludwig + + + + + + + Maik Bröse + + + + + + + + + Maik Bröse + + + + + + + + + + + + + Ortwin Regel + + + + + Zunächst war der gewählte Pirat mit einem parteilosen Abgeordneten in einer PIRATEN-Fraktion. Dieser Parteilose war der Vorsitzende („Sprecher“) der Fraktion. Die zweiköpfige PIRATEN-Fraktion war ihrerseits Teil des Fraktionsverbunds („Gruppe“) aus SPD, Grünen und Piraten. Nach einem Streit um Unstimmigkeiten mit den Fraktionsfinanzen wurde die Fraktion aufgelöst. Der gewählte Pirat ist nunmehr Einzelmitglied in dieser Gruppe. + + + + + + + + Torbjörn Bartels + Daniel Brügge + + + + + + + + Aljoscha Rittner + + + + + + + + + + + + Matthias Roll + + + + + + + + + Carsten Bartels + + + + + + + + + + + Rolf Tischer + + + + + + + + + + + + Werner Heise + Arne Hattendorf + + + + Anfangs bildeten die beiden Piraten im Stadtrat die PIRATEN-Fraktion. Nach etwa einem Jahr schlossen sie sich mit dem einzigen FDP-Abgeordneten zu der Gruppe PIRATEN und FDP zusammen. Die PIRATEN-Fraktion ist damit praktisch in der Gruppe aufgegangen. + + + + + Jens Golland + + + + + + + + Ralf Möhle + + Im September 2013 wechselte Ralf Möhle von der CDU im Gemeinderat zur Piratenpartei. + + + + + + + + + + Alexander Niedermeier + + Bei der Wahl zur Stadtverordnetenversammlung am 10. Mai 2015 wurden 2,8% der Stimmen erzielt. Bereits 2011 warendie PIRATEN mit 2,2% eingezogen. + + + + + + Gunnar Christiansen + + + + + + Arend Vogtländer + + + + + + + + + + Rudi Ernst Lennartz + Kai Hemsteeg + + + + Die beiden „Landschaftsverbände“ in Nordrhein-Westfalen, die jeweils grob die Hälfte des Gebiets und der Bevölkerung abdecken, sind Gebietskörperschaften der kommunalen Selbstverwaltung und haben je eine „Landschaftsversammlung“ als Parlament. Diese wird nicht direkt gewählt, sondern nach den Wahlergebnissen bei allgemeinen Kommunalwahlen nach Proporz besetzt. Die Piraten haben nach den Kommunalwahlen am 25. Mai 2014 Anspruch auf zwei Sitze. Ähnlich den Bezirkstagen in Bayern sind sie hauptsächlich für die Trägerschaft der Sozial-, Behinderten- und Jugendhilfe, insbesondere für Fach- und psychiatrische Krankenhäuser sowie Förderschulen zuständig. + + + + + + Sven Sladek + Christina Worm + + Die beiden „Landschaftsverbände“ in Nordrhein-Westfalen, die jeweils grob die Hälfte des Gebiets und der Bevölkerung abdecken, sind Gebietskörperschaften der kommunalen Selbstverwaltung und haben je eine „Landschaftsversammlung“ als Parlament. Diese wird nicht direkt gewählt, sondern nach den Wahlergebnissen bei allgemeinen Kommunalwahlen nach Proporz besetzt. Die Piraten haben nach den Kommunalwahlen am 25. Mai 2014 Anspruch auf zwei Sitze. Ähnlich den Bezirkstagen in Bayern sind sie hauptsächlich für die Trägerschaft der Sozial-, Behinderten- und Jugendhilfe, insbesondere für Fach- und psychiatrische Krankenhäuser sowie Förderschulen zuständig. + + + + + Frank Fitzke + Dieter McDevitt + Kai Hemsteeg + Dirk Pullem + + Der Regionalverband Ruhr ist ein Zusammenschluss einiger kreisfreier Städte und Landkreise im Ruhrgebiet, dessen Gebietsgrenzen weder mit denen der fünf Regierungsbezirke noch mit denen der beiden Landschaftsverbände in Nordrhein-Westfalen übereinstimmen. Das Ruhrparlament wird nicht direkt gewählt, sondern nach den Wahlergebnissen bei allgemeinen Kommunalwahlen nach Proporz besetzt. Die Piraten haben nach den Kommunalwahlen am 25. Mai 2014 Anspruch auf zwei Sitze. Das Ruhrparlament war historisch für die Planung der Kohleabbaus zuständig, heute befasst es sich hauptsächlich mit Regionsmarketing, Umwelt- und Freizeitförderung sowie Raumplanung und Geodaten. Wegen enorm vieler Überhangmandate ist das Ruhrparlament aktuell extrem groß. + + + + + + Britta Söntgerath + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht und eine Fraktionsgemeinschaft mit den Wählervereinigungen „Bürgerlich Liberale (BL)“ und „Sozial Gerecht Unabhängig (SGU)“ eingegangen. + + + + + + Frank Grenda + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + + + Kai Hemsteeg + Wilfried Adamy + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht und eine Fraktionsgemeinschaft mit einem Stadtverordneten der PARTEI und einer ausgetretenen Ex-Linken eingegangen. + + + + Nils Malescha + + Bei der Kommunalwahl am 25. Mai 2014 wurden im Stadtbezirk Essen I (Mitte, Frillendorf, Huttrop) 3,8% der Stimmen erreicht. + + + + + Markus Hansmeier + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden im Stadtbezirk Essen VI (Katernberg, Schonnebeck, Stoppenberg) 2,5% der Stimmen erreicht. + + + + + Andreas Hering + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden im Stadtbezirk Essen VIII (Ruhrhalbinsel) 2,9% der Stimmen erreicht. + + + + + + Peter Klein + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. Es wurde eine gemeinsame Gruppe mit einem Stadtverordneten der PARTEI gegründet, die im März 2015 von Seiten der PARTEI wieder aufgekündigt würde. + + + + + + Reiner Gutowski + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,5% der Stimmen erreicht. Es besteht eine Gruppe zusammen mit der PARTEI. + + + + Doris Kroll-Hartge + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + + + Carsten Trojahn + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + + Gerd Paul Schlupp + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + Oliver Graf + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. + + + + Gabriele Weingärtner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + + + Tim Reuter + Rainer Severin + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. Im Februar 2014 trat Rainer Severin von der LINKEN zur Piratenpartei über, der schon zuvor mit dem zweiten LINKEN-Abgeordneten eine gemeinsame Fraktion mit den Piraten gebildet hatte. + + + + + Markus Peukes + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + + Thomas Küppers + Ria Angelika Garcia Rodriguez + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + Ria Angelika Garcia Rodriguez + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + + + Thomas Woywod + Jochen Drahorad + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + Martin Schwarz + Martin Leonhardt + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + + + Kirsten Eickler + Bianca Staubitz + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + Rafael Kazior + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + Sandra Schäfer + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + + + Markus Wetzler + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,4% der Stimmen erreicht. + + + + + Marc Janßen + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + Hugo Hoff + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + + + Emanuel Mitromaras + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + Manfred Friedrich Schramm + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + Jochen Lobnig + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + + Manfred Friedrich Schramm + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,3% der Stimmen erreicht und eine Fraktionsgemeinschaft mit der Liste „WWW – die junge Alternative“ geschlossen. + + + + + + + Yvonne Plum + + In Nordrhein-Westfalen hat jeder der fünf Regierungsbezirke einen Regionalrat. Er wird nicht direkt gewählt, sondern nach den Wahlergebnissen bei allgemeinen Kommunalwahlen nach Proporz besetzt. Die Piraten haben nach den Kommunalwahlen am 25. Mai 2014 Anspruch auf einen Sitz. Der Regionalrat ist hauptsächlich zuständig für die Aufstellung des „Regionalplans“ (früher „Gebietsentwicklungsplan“). + + + + + Bertram Eckert + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,1% der Stimmen erreicht und 2 Mandate errungen. Eine gemeinsame Fraktion mit einem Abgeordneten der Unabhängigen und freie Wähler (UFW) wurde gegründet. Ein Abgeordneter wechselte jedoch im Dezember 2014 zur CDU, woraufhin der Fraktionsstatus verloren ging. + + + + + Marc Teuku + Udo Pütz + Sait Başkaya + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,5% der Stimmen erreicht. + + + + Bertram Eckert + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,4% der Stimmen erreicht. + + + + + + Rudi Ernst Lennartz + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,2% der Stimmen erreicht. + + + + + Kai Baumann + Stefan Kuklik + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,7% der Stimmen erreicht. + + + + + + + Felix Kopinski + Dr. Carsten Euwens + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + Christoph Grenz + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + + + + + Thomas Hegenbarth + Lisa Hanna Gerlach + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + Thomas Geffe + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + Diana Lantzen + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + + Dietmar Schwindt + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + Sascha Zuther + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + Ioannis Milios + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + Harry Hupp + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. + + + + + Birgit Foken-Brock + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,4% der Stimmen erreicht. + + + + + Alexandra Osburg + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,2% der Stimmen erreicht. + + + + + + Bernd Janotta + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + + + Knut Schumann + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,3% der Stimmen erreicht. + + + + Astrid Schumann + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + + + Anja Moersch + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. Es besteht eine Gruppe einer Abgeordneten der Freien Wähler. + + + + + Wolfgang Roth + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + Jürgen Weiler + + Pirat Jürgen Weiler kandidierte erfolgreich auf der Liste „Aktive Bürger Bornheim“ und ist jetzt Teil einer zweiköpfigen Fraktion. + + + + + + + + Gabriele Schmeer + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. Zusammen mit der FDP besteht eine Ratsgruppe. + + + + + Jürgen Hansen + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + Johannes Schmanck + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht und damit 2 Sitze gewonnen. Es wurde eine gemeinsame Fraktion mit dem Abgeordneten der ÖDP gegründet. Nach dem Parteiaustritt eines der Mandatsträger aus der Piratenpartei wurde die Fraktion aufgelöst. + + + + Peter Hemecker + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,8% der Stimmen erreicht. + + + + + Birgit Hemecker + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,2% der Stimmen erreicht. + + + + + + Maria Strestik + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,4% der Stimmen erreicht. Es besteht eine gemeinsame Gruppe mit der Linken. Die Gründung der Gruppe war vom Landrat zunächst nicht anerkannt worden. Seine Position erwies sich aber später als unbegründet und unhaltbar. + + + + Stephan Strestik + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. Es wurde eine gemeinsame Fraktion mit der Wählergruppierung „Pro! Bürgerschaft“ (kein Zusammenhang mit Pro NRW) gegründet. Die Gründung der Fraktion war von der Bürgermeisterin zunächst nicht anerkannt worden. Ihre Position erwies sich aber später als unbegründet und unhaltbar. + + + + + + + Melanie Kalkowski + Michael Herbert Levedag + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + Thomas Weijers + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + + Michael Levedag + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,3% der Stimmen erreicht. + + + + + + Pia Hermans + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + Michael Ortner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + Thomas Lohmann + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,9% der Stimmen erreicht. + + + + + + + + + Michael Gugat + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. Am 3.9.2014 hat sich Michael Gugat mit Christian Heißenberg von der Wählergemeinschaft Bürgernähe zur Ratsgruppe Bürgernähe/Piraten zusammengeschlossen. Die Gruppe wurde zunächst vom Oberbürgermeister nicht anerkannt, was sich jedoch als haltlos erwies. + + + + + Rüdiger Linde + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,2% der Stimmen erreicht. + + + + + + + + Mirjam Sturman-Püttcher + Matthias Obenhaus + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen und damit 1 Mandat erreicht. Nach der Wahl entschied sich der einzig verbleibende Stadtverordnete der „Bunten Liste Bad Salzuflen“, Matthias Obenhaus, in die Piratenpartei einzutreten und eine gemeinsame Fraktion zu gründen. + + + + + + Christian Woelk + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + + + Karl-Heinz Detert + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,5% der Stimmen erreicht. + + + + Sven Brandhorst + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + Sabine Martiny + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,2% der Stimmen erreicht. + + + + Arndt Heuvel + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,2% der Stimmen erreicht. + + + + + + + + Andre Kasper + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. Nach dem Austritt einer Mandatsträgerin aus der Piratenpartei wurde im April 2015 die bis dahin bestehende Gruppe aufgelöst. + + + + Jannis Mehring + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + + + Achim Wilde + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,8% der Stimmen erreicht. + + + + + Sandra Schulze + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + + Christian Gebel + Nadja Reigl + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,3% der Stimmen erreicht. + + + + David Grade + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,5% der Stimmen erreicht. + + + + + Uwe Martinschledde + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,1% der Stimmen erreicht. + + + + + Frank Rupprecht + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,1% der Stimmen erreicht. + + + + + Holger Knöpker + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,8% der Stimmen erreicht. + + + + + Nadja Reigl + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + Dieter McDevitt + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + + Thorsten Kiszkenow + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. Die Bildung einer Gruppe mit der Wähervereinigung „Bürger für Hohenlimburg“ wird bisher verweigert. Dagegen ist Klage eingereicht. + + + + + Martin Kesztyüs + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + + Andreas Prennig + Bernd Schroeder + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + Günter Nierstenhöfer + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,9% der Stimmen erreicht. + + + + + Michael James Eilebrecht + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,4% der Stimmen erreicht. + + + + + + Chris Demmer + Jörg Müller + + + + Bei der Kommunalwahl am 25. Mai 2014 (inkl. Nachwahlen in zwei Wahlkreisen am 15.6.) wurden 2,3% der Stimmen erreicht. + + + + Wilhelm Völlmecke + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + + Sascha Kursawe + + + + Nach Spaltung der zunächst vierköpfigen LINKE-Fraktion, in welcher auch der Piraten-Vertreter Mitglied war, bildet dieser nun mit einem einzelnen LINKEN-Parteimitglied eine zweiköpfige Fraktion. + + + + + Martin Debold + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,8% der Stimmen erreicht. + + + + + + Roland Löpke + Stefan Borggraefe + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + + + Daniel Wagner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + Daniel Wagner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. + + + + + Julius Hahn + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + + + + Stefan Hermann Handzik + > + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + Hans Immanuel Herbers + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht und eine gemeinsame Fraktion mit der Unabhängigen Wählergemeinschaft (UWG) gegründet. + + + + + Rudolf Hantschel + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,3% der Stimmen erreicht. + + + + + + + Sven Sladek + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + + + + Ralf Schaefer + Christian Roß + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + Ralf Schaefer + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,3% der Stimmen erreicht. + + + + + + Heike Palm + Christoph Tetzner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,5% der Stimmen erreicht. Die beiden Ratsmitglieder der PIRATEN bildeten eine Fraktion, die jedoch im November 2014 wegen politischer Differenzen aufgelöst wurde. + + + + + + + + + + + Volker Berkhout + + Das Gebiet der Planungsregion Nordhessen ist identisch mit dem des Regierungsbezirks Kassel. Es umfasst die kreisfreie Stadt Kassel sowie die Landkreise Kassel, Werra-Meißner, Waldeck-Frankenberg, Schwalm-Eder, Hersfeld-Rotenburg und Fulda. Die Regionalversammlung der Planungsregion wird nicht direkt, sondern von den Vertretungen großer Mitgliedskörperschaften gewählt. Derzeit wird ein Sitz von den PIRATEN gehalten. Die Regionalversammlung ist vor allem für die Regionalplanung in Sachen Flächennutzung und Verkehr zuständig. + + + + + Kristof Zerbe + + Das Gebiet der Planungsregion Südhessen ist identisch mit dem des Regierungsbezirks Darmstadt. Die Regionalversammlung der Planungsregion wird nicht direkt, sondern von den Vertretungen großer Mitgliedskörperschaften gewählt. Derzeit wird ein Sitz von den PIRATEN gehalten. Die Regionalversammlung ist vor allem für die Regionalplanung in Sachen Flächennutzung und Verkehr zuständig. + + + + + + Claudia Stricker + Roland Cuny + + Im „Magistrat“, dem ausführenden und überwiegend ehrenamtlich besetzten Verwaltungsvorstand der Stadt Darmstadt, sitzt der Pirat Markus Drenger in der Funktion eines „Stadtrats“. + + + + + + Herbert Förster + + Zunächst wurde die „Bunte Fraktion“ aus je einer Abgeordneten der Liste ÖkoLinX und der Europaliste für Frankfurt (ELF) sowie den beiden Piraten gebildet. Im September 2011 traten Piraten und ELF aus der Fraktion aus und gründeten die neue Fraktion „ELF Piraten“. Im September 2014 ist Martin Kliehm aus der Piratenpartei ausgetreten und hat sich zusammen mit Luigi Brillante der LINKE-Fraktion angeschlossen. Herbert Förster führt sein Mandat nun ohne Fraktion weiter. + + + + + Jörg-Peter Bayer + + Die beiden in die Stadtverordnetenversammlung gewählten Piraten bildeten zunächst eine Fraktion mit mit einem parteilosen Stadtverordneten (ehemals SPD) als Fraktionschef. Diese wurde im März 2013 aufgelöst. Im Mai 2013 trat schließlich einer der beiden PIRATEN-Abgeordneten aus der Partei aus. + + + + + Volker Berkhout + + + + + + + Gregory Engels + Helmut Eisenkolb + + + + Olga Eisenkolb + + + + + + Kristof Zerbe + + + + + + + + Markus Kairies + + + + + + Peter Dambier + Veronika Zenker + + Die am 27. März 2011 für die LINKE in den Kreistag gewählte Abgeordnete Veronika Zenker ist im Januar 2012 zur Piratenpartei übergetreten. Sie hat daraufhin mit Peter Dambier, der bei der gleichen Wahl für die PIRATEN gewählt wurde, eine Piratenfraktion gegründet und den Fraktionsvorsitz übernommen. + + + + + + Markus Brechtel + + + + + + + + Iwan Lappo-Danilewski + Paulo Rommel + + + + + + + Michael Geurts + + + + + + + Swen Schmidt + + + + + + + Birgit Simon + Sören Siegismund-Poschmann + + + + + + + Jens Fricke + + + + + + Michael Weber + + Am 27. März 2011 war Sascha Klee für die Piratenpartei in die Stadtverordnetenversammlung gewählt worden. Im Juli 2012 trat er aus der Piratenpartei aus, legte aber zunächst das Mandat nicht nieder. Im Januar 2013 trat er schließlich doch zurück, sodass Michael Weber als Pirat nachrücken konnte. + + + + + + + Christoph Hampe + Eduard Baumann + + + + + + Alexander Kaufmann + + + + + Alexander Kaufmann + + + + + Alexander Kaufmann + Alexander Kaufmann ist als Vorsitzender des Ortsbeirates der Ortsvorsteher des Ortsteils Frankenau. + + + + + + + + Stephan Flindt + + + + + + + + + + Jakob Wagner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + + Heinz Zell + + Bei der Kommunalwahl am 25. Mai 2014 wurden 0,8% der Stimmen erreicht. Heinz Zell schloss sich daraufhin der Grünen-Fraktion an. + + + + + Xander Dorn + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + + Dr. Darja Henseler + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + Hans-Peter König + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,2% der Stimmen erreicht. + + + + + + Bernhard Furch + + + + + + + + Ralf Berger + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,5% der Stimmen erreicht. + + + + + Felix Würtz + + + + + + + Patrick Walter + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,1% der Stimmen erreicht. Kurz nach der Wahl trat Michael Stüber, gewählt als einer von sechs Abgeorndeten auf der Liste der Grünen, aus seiner Partei aus und bildet fortan als Parteiloser eine Fraktion mit dem einzigen Piraten der Versammlung. + + + + + + Dr. Karl-Georg Schroll + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + Ottmar Muno + + Bereits 2009 wurde Ottmar Muno für die Wählergruppe „Bürger für Bürger“ in den Verbandsgemeinderat Hermeskeil gewählt und trat später in die Piratenpartei ein. Bei der Kommunalwahl am 25. Mai 2014 konnte er sein Mandat mit 2,9% der Stimmen verteidigen. + + + + Ottmar Muno + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,3% der Stimmen erreicht. Ottmar Muno vertritt die Piraten auf Stadt- und Verbandsgemeindeebene. + + + + + + + + + + + Ingo Mörl + + Als einziger der 12 Regionalverbände in Baden-Württemberg hat die Region Stuttgart eine politische Vertretung. Sie wird bei allgemeinen Kommunalwahlen direkt gewählt. Ihre Zuständigkeiten liegen in der Regionalplanung, insbesondere in den Bereichen Verkehr, Wirtschaft und Verwaltung. Bei der Kommunalwahl am 25. Mai 2014 erreichten die PIRATEN 1,1% der Stimmen. + + + + + Alexander Schestag + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + + + Uwe Lancier + Erik Wohlfeil + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,4% der Stimmen erreicht. + + + + + + Stefan Urbat + + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,6% der Stimmen erreicht. + + + + Michael Knödler + + + + + David Münzing + + + + + Nikolai Kliewer + + + + + László Peters + + + + + Christian Brugger-Burg + + + + + Jochen Buchholz + + + + + Dr. Rainer Blind + + + + + + + Denise Niggemeier + + + + + + Markus Arnold + + + + Mit dem auf der Liste der LINKEN gewählten Piraten konnte eine Fraktion gebildet werden, nachdem zwei LINKE durch Ausgleichsmandate zusätzlich eingezogen sind. + + + + + + Claudia Moosmann + In Leinfelden-Echterdingen sind Kandidaten der Piratenpartei als „Filderpiraten e.V.“ organisiert und mit der Liste „Freunde der Filderpiraten e.V.“ angetreten, die 2,2% der Stimmen erhielt. + + + + + Jochen Jansen + + Bei der Kommunalwahl am 25. Mai 2014 wurden 6,5% der Stimmen erreicht. + + + + + + + + Michael Freche + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + + + + Hartmut Schönherr + + Bei der Kommunalwahl 2009 wurde Hartmut Schönherr für die Wählervereinigung „Neue Köpfe“ über die Liste „Grüne/Neue Köpfe“ in den Gemeinderat der Stadt Bruchsal gewählt. Noch im selben Jahr trat er der Piratenpartei bei, blieb aber in der Fraktion „Die Grünen/Neue Köpfe“. 2014 wurde er auf der gleichen Liste wiedergewählt und übt sein Mandat seitdem aus wie zuvor. + + + + + + + Thomas Buck + + + + + + + + Rainer Nase + + Bei der Kommunalwahl 2009 wurde Rainer Nase auf der SPD-Liste als Nachrücker für den Gemeinderat der Stadt Weikersheim gewählt. 2011 trat er aus der SPD aus und in die Piratenpartei ein. Durch den Wegzug einer Mandatsträgerin 2012 rückte er als Pirat in den Gemeinderat nach. 2014 konnte er auf der PIRATEN-Liste sein Mandat verteidigen. + + + + + + + + + + + Martina Wenta + Dr. Gabriela Berg + + Die bayerischen Bezirkstage stehen als Kommunalparlamente auf der Ebene der Regierungsbezirke. Sind sind jedoch den kreisfreien Städten und Landkreisen in ihren Entscheiden nicht übergeordnet, sondern haben spezielle, eigene Zuständigkeiten. Diese umfassen insbesondere psychiatrische Einrichtungen, die Trägerschaft für Einrichtungen der Sozialhilfe sowie Förderschulen. + + + + + Thomas Ranft + + + + + + + + + + + Stefan Lorenz + + Stefan Lorenz wurde auf der gemeinsamen Liste LINKE/PIRATEN gewählt. + + + + + + + Andreas Ströhle + + Andreas Ströhle hat im Rat eine Ausschussgemeinschaft mit FDP und ÖDP + + + + + + + + Tobias Mc Fadden + + Ausschussgemeinschaft mit ÖDP, UBG und Einzelbewerber + + + + + + + + + Tina Lorenz + + Die fraktionslose PIRATEN-Abgeordnete ist an einer Regierungskoalition mit SPD, Grünen, FDP und Freien Wählern beteiligt, aufgrund derer auch zusätzliche Ausschusssitze besetzt werden können. + + + + + + + + Marcus Dinglreiter + + + + + + + + + Daniel Gruber + + Die bayerischen Bezirkstage stehen als Kommunalparlamente auf der Ebene der Regierungsbezirke. Sind sind jedoch den kreisfreien Städten und Landkreisen in ihren Entscheiden nicht übergeordnet, sondern haben spezielle, eigene Zuständigkeiten. Diese umfassen insbesondere psychiatrische Einrichtungen, die Trägerschaft für Einrichtungen der Sozialhilfe sowie Förderschulen. + + + + Michael Bengl + + Ausschussgemeinschaft mit Freien Wählern, FDP, ÖDP und den "Guten". + + + + + + + + Benjamin Wildenauer + + Benjamin Wildenauer wurde auf der Liste der SPD gewählt, die 8,2% erlangte. + + + + + + Jürgen Neuwirth + + Jürgen Neuwirth wurde auf der gemeinsamen Liste „Die Sonstigen“ von ÖDP, PIRATEN und LINKE gewählt, die 2,3% erlangte. + + + + + + + Fritz Effenberger + + + + Die bayerischen Bezirkstage stehen als Kommunalparlamente auf der Ebene der Regierungsbezirke. Sind sind jedoch den kreisfreien Städten und Landkreisen in ihren Entscheiden nicht übergeordnet, sondern haben spezielle, eigene Zuständigkeiten. Diese umfassen insbesondere psychiatrische Einrichtungen, die Trägerschaft für Einrichtungen der Sozialhilfe sowie Förderschulen. Im Bezirkstag Schwaben bilden die zwei Abgeordneten von PIRATEN und LINKE eine Fraktionsgemeinschaft. + + + + + + + + Markus Hansen + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + José Ignacio Rodriguez Maicas + Thomas Brass + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,6% der Stimmen erreicht. + + + + Markus Hansen + + Bei der Kommunalwahl am 25. Mai 2014 wurden 5,1% der Stimmen erreicht. + + + + + + + + Michael Grauer + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + + Michael Grauer + Bei der Kommunalwahl am 25. Mai 2014 wurden 19,5% der Stimmen erreicht. + + + + + + + Wolfgang Barth + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,0% der Stimmen erreicht. + + + + Hans Hirtz + Roman Thielen + Bei der Kommunalwahl am 25. Mai 2014 wurden 17,9% der Stimmen erreicht. + + + + + + + + Gerd Rainer Weber + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + Dieter Schmidt + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,3% der Stimmen erreicht. + + + + + + Rudi Berhard + Steven Latterner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,7% der Stimmen erreicht. + + + + + + Ralf Petermann + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,2% der Stimmen erreicht. + + + + + + + + Holger Gier + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + + + + + + + Tobias Kriesel + Christopher Lang + David Kirchner + Alexander Freitag + + Von 6 gewonnenen Sitzen konnten nur 5 besetzt werden, da ein Teil der Listenkandidaten gleichzeitig ins Abgeordnetenhaus gewählt wurde. Im August 2012 legte außerdem eine Bezirksverordnete ihr Amt nieder, ohne dass es Nachrücker gab. Somit sind zwei Sitze in der Versammlung unbesetzt. + + + + + + Ralf Gerlich + Barbara Wisniowska + Michael Herbst + Jessica Zinn + + Von 9 gewonnenen Sitzen konnten nur 5 besetzt werden, da es nur 8 Listenkandidaten gab, von denen zudem ein Teil gleichzeitig ins Abgeordnetenhaus gewählt wurde. Somit sind vier Sitze in der Versammlung unbesetzt. Ein Mandatsträger ist inzwischen aus der Piratenpartei ausgetreten, Jessica Zinn ist nicht mehr Mitglied der Fraktion. + + + + + Michael Mittelbach + Stephan Bliedung + Achim Bartsch + Frederik Bordfeld + Stephan Verbücheln + Jan Schrecker + + + + + + + Siegfried Schlosser + Holger Pabst + Gerlinde Behrendt + Merle von Wittich + + + + + + + Emilio Paolini + Mikk Schunke + Lasse Kosiol + + Von 4 gewonnenen Sitzen konnten nur 3 besetzt werden, da es nur 3 Listenkandidaten gab. Somit ist ein Sitz in der Versammlung unbesetzt. + + + + + + Georg von Boroviczeny + Eric Lüders + Paul Neumann + + + + + + Sven Wehrend + Jan-Ulrich Franz + + Zwei der ursprünglich vier auf der PIRATEN-Liste gewählten Mandatsträger sind inzwischen aus der Fraktion bzw. der Piratenpartei ausgetreten, sodass statt einer Fraktion nur noch eine Gruppe besteht. + + + + + + Steffen Burger + Mathias Zaech + Semih Kasap + + + + + + + Volker Schröder + René Pönitz + + Von 5 gewonnenen Sitzen konnten nur 4 besetzt werden, da es nur 4 Listenkandidaten gab, ein Sitz in der Versammlung ist damit unbesetzt. Zwei Mandatsträger sind im Jahr 2014 aus der Piratenpartei ausgetreten, bleiben aber Mitglieder der Fraktion. + + + + + + Steffen Ostehr + Volker Tanger + Steven Kelz + Marcel Geppert + + Von 5 gewonnenen Sitzen konnten nur 4 besetzt werden, da eine Listenkandidatin gleichzeitig ins Abgeordnetenhaus gewählt wurde. Somit ist ein Sitz in der Versammlung unbesetzt. + + + + + + Yannick Meyer + Steffen Bornfleth + Marvin Hemmerlein + Helge Eichelberg + Florian Lange + + + + + + + + + + + Steffen Kern + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,7% der Stimmen erreicht. + + + + + + Ulf Markarski + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + + + Ronny Friedrich + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,8% der Stimmen erreicht. + + + + + + Jürgen Willenberg + Für die 3 Sitze im Ortsbeirat Doberburg gab es 4 Bewerber, darunter Jürgen Willenberg für die PIRATEN. Er erhielt 76 von 194 Stimmen, was einem Wahlergebnis von 39,2% entspricht. + + + + + + + + + Kerstin Schenkel + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,4% der Stimmen erreicht. + + + + + + + + Nicole Niemoth + Zu den 3 Sitzen im Ortsbeirat Etzin sind 3 Listen angetreten (CDU, PIRATEN, FREIE WÄHLER Etzin). Nicole Niemoth erhielt für die PIRATEN 69 von 437 Stimmen, was einem Wahlergebnis von 15,8% entspricht. Die anderen beiden Sitze gingen an die FREIE WÄHLER. + + + + + + + + Thomas Bennühr + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + Markus Hoffmann + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,8% der Stimmen erreicht. + + + + + Thomas Bennühr + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,7% der Stimmen erreicht. + + + + + + Frank Behr + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 0,8% der Stimmen erreicht. + + + + Frank Behr + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,4% der Stimmen erreicht. + + + + + Kai Hamacher + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. + + + + + + + Jeannette Paech + + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + Raoul Schramm + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + + + Thomas Friedrich + + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + + + + + Nadine Heckendorn + + + + + + + + + + Matthias Reimann + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,1% der Stimmen erreicht. + + + + + Theodor Luttmer + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,1% der Stimmen erreicht. + + + + Robert Schuldt + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + + Dennis Klüver + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,4% der Stimmen erreicht. + + + + + Dr. Bernhard Schubach + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,6% der Stimmen erreicht. + + + + + + + Martin Banduch + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,3% der Stimmen erreicht. + + + + + Milos Rodatos + Petra Dörwald + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,8% der Stimmen erreicht. + + + + + + + Friedrich Smyra + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,3% der Stimmen erreicht. + + + + + André Bonitz + Am 7. Juni 2009 wurde André Bonitz als parteiloser Kandidat in die Gemeindevertretung gewählt. Dort wurde er ebenfalls zum Bürgermeister der Gemeinde gewählt. Im April 2012 ist er in die Piratenpartei eingetreten. Bei der Kommunalwahl am 25. Mai 2014 wurde er für „Eine Liste für Eixen“ in beiden Ämtern bestätigt. + + + + + + + + + + Toni Rotter + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + + + Dr. Martin Schulte-Wissermann + Norbert Engemaier + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,3% der Stimmen erreicht. Die PIRATEN verhelfen mit ihren 2 Sitzen Rot-Rot-Grün zur Mehrheit. + + + + Florian Andreas Vogelmaier + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + Marcel Ritschel + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + Annica Peter + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + Vanya Wagner + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + Frank Schirlitz + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + Florian-André Unterburger + Die Ortsbeiräte werden vom Stadtrat gewählt. Den PIRATEN steht 1 Sitz zu. + + + + + + Ute Elisabeth Gabelmann + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. + + + + + + Carolin Mahn-Gauseweg + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,0% der Stimmen erreicht. + + + + + + Sören Skalicks + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,5% der Stimmen erreicht. + + + + + + + + + Marc Blanck + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,0% der Stimmen erreicht. + + + + + Thomas May + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,8% der Stimmen erreicht. + + + + + Alexander Harms + + + + + + + Thomas Pfeffer + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + Jens Barthel + + + + + + + + Ernst Romoser + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 3,4% der Stimmen erreicht. + + + + + + + + + Denis Mau + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,2% der Stimmen erreicht. Im Juni 2014 hat der Piraten-Mandatsträger zusammen mit den Grünen eine Fraktion gebildet. + + + + + + + + Michel Vorsprach + + Bei der Kommunalwahl am 25.5.2014 wurde der Pirat Michel Vorsprach auf der Liste der Wählergruppe „Transparenz und Demokratie für ganz Möser (EHRLICH)“ in den Gemeinderat gewählt. Zusammen mit Dr. Maik Barthel (Bündnis 90/Grüne) wurde am 29.06.2014 die Fraktion Ehrlich/Grüne gebildet. + + + + + Michel Vorsprach + + Michael Vorsprach wurde als Pirat zusammen mit einer weiteren Kandidatin auf der Liste der Wählergruppe „Transparenz und Demokratie für ganz Möser (EHRLICH)“ in den Ortschaftsrat Lostau gewählt. Die Liste erzielte 22,2% der Stimmen. Am 14.07.2014 wurde die Fraktion Ehrlich/Grüne gebildet. + + + + + + + + Olaf Lincke + + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,4% der Stimmen erreicht. + + + + + + + René Schernikau + + + + + + + + + + + Johannes Erich Quentel + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,0% der Stimmen erreicht. + + + + + Peter Städter + + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,1% der Stimmen erreicht. + + + + + Uwe Rüdiger + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,9% der Stimmen erreicht. + + + + + + Prof. Dr. Clemens Beckstein + Dr. Heidrun Jänchen + + Bei der Kommunalwahl am 25. Mai 2014 wurden 4,6% der Stimmen erreicht. + + + + + Thomas Brückner + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,9% der Stimmen erreicht. + + + + + Bernhard Koim + + Bei der Kommunalwahl am 25. Mai 2014 wurden 2,5% der Stimmen erreicht. + + + + Enrico Stiller + Gerrit Jeron + + + + Bei der Kommunalwahl am 25. Mai 2014 wurden 5,4% der Stimmen erreicht. + + + + + + Lutz Gundlach + + Bei der Kommunalwahl am 25. Mai 2014 wurden 1,3% der Stimmen erreicht. + + + + + diff --git a/OpenAntrag/App_Start/AuthConfig.vb b/OpenAntrag/App_Start/AuthConfig.vb new file mode 100644 index 0000000..aabcb49 --- /dev/null +++ b/OpenAntrag/App_Start/AuthConfig.vb @@ -0,0 +1,22 @@ +'Imports Microsoft.Web.WebPages.OAuth + +Public Class AuthConfig + Public Shared Sub RegisterAuth() + ' To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter, + ' you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166 + + ' OAuthWebSecurity.RegisterMicrosoftClient( + ' clientId:="", + ' clientSecret:="") + + ' OAuthWebSecurity.RegisterTwitterClient( + ' consumerKey:="", + ' consumerSecret:="") + + ' OAuthWebSecurity.RegisterFacebookClient( + ' appId:="", + ' appSecret:="") + + ' OAuthWebSecurity.RegisterGoogleClient() + End Sub +End Class \ No newline at end of file diff --git a/OpenAntrag/App_Start/BundleConfig.vb b/OpenAntrag/App_Start/BundleConfig.vb new file mode 100644 index 0000000..1a6e3e1 --- /dev/null +++ b/OpenAntrag/App_Start/BundleConfig.vb @@ -0,0 +1,114 @@ +Imports System.Web +Imports System.Web.Optimization + +Public Class BundleConfig + ' For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 + + Public Shared Sub RegisterBundles(ByVal bundles As BundleCollection) + + bundles.Add(New ScriptBundle("~/bundle/jquery").Include( + "~/Scripts/jquery-{version}.js")) + + bundles.Add(New ScriptBundle("~/bundle/jqueryval").Include( + "~/Scripts/jquery.validate*")) + + ' Use the development version of Modernizr to develop with and learn from. Then, when you're + ' ready for production, use the build tool at http://modernizr.com to pick only the tests you need. + bundles.Add(New ScriptBundle("~/bundle/modernizr").Include( + "~/Scripts/modernizr-*")) + + bundles.Add(New ScriptBundle("~/bundle/plugins-pre") _ + .IncludeDirectory("~/Scripts/Plugins/_preload", "*.js")) + + bundles.Add(New ScriptBundle("~/bundle/plugins") _ + .IncludeDirectory("~/Scripts/Plugins", "*.js") _ + .Include("~/Scripts/Plugins/moment/moment.js") _ + .Include("~/Scripts/Plugins/moment/de.js") _ + .Include("~/Scripts/Plugins/bootstrap.js") _ + .Include("~/Scripts/Plugins/datetimepicker/bootstrap-datetimepicker.js") _ + .Include("~/Scripts/Plugins/datetimepicker/bootstrap-datetimepicker.de-DE.js") _ + .Include("~/Scripts/headroom.js") _ + .Include("~/Scripts/Plugins/perfect-scrollbar/perfect-scrollbar.js")) + + bundles.Add(New ScriptBundle("~/bundle/markdown") _ + .Include("~/Scripts/MarkdownDeep.js") _ + .Include("~/Scripts/MarkdownDeepEditor.js") _ + .Include("~/Scripts/MarkdownDeepEditorUI.js")) + + bundles.Add(New ScriptBundle("~/bundle/main").Include( + "~/ScriptsCustom/tools.js", + "~/ScriptsCustom/xhr.js", + "~/ScriptsCustom/main.js", + "~/ScriptsCustom/validation.js", + "~/ScriptsCustom/responsive-tables.js")) + + bundles.Add(New ScriptBundle("~/bundle/representations").Include( + "~/ScriptsCustom/representations.js")) + + bundles.Add(New ScriptBundle("~/bundle/teaser").Include( + "~/ScriptsCustom/teaser.js")) + + bundles.Add(New ScriptBundle("~/bundle/feedback").Include( + "~/ScriptsCustom/feedback.js")) + + bundles.Add(New ScriptBundle("~/bundle/notifications").Include( + "~/ScriptsCustom/notifications.js")) + + bundles.Add(New ScriptBundle("~/bundle/admin") _ + .Include("~/ScriptsCustom/admin.js") _ + .Include("~/Scripts/Plugins/picker/picker.js")) + + 'NICHT 'IncludeDirectory', weil Reihenfolge wichtig !!! + bundles.Add(New StyleBundle("~/css/plugins").Include( + "~/Content/Plugins/flatstrap.css", + "~/Content/Plugins/flatstrap-responsive.css", + "~/Content/Plugins/tooltipster.css", + "~/Content/Plugins/bootstrap-select.css", + "~/Content/Plugins/selectize.css", + "~/Content/Plugins/jqcloud.css", + "~/Scripts/mdd_styles.css", + "~/Content/Plugins/bootstrap-datetimepicker.css", + "~/Scripts/Plugins/perfect-scrollbar/perfect-scrollbar.css")) + '"~/Content/Plugins/jquery.mCustomScrollbar.css", + '"~/Content/Plugins/jquery.mCustomScrollbar.openantrag.css")) + '"~/Content/Plugins/jquery.jscrollpane.css", + + bundles.Add(New StyleBundle("~/css/styles-v2") _ + .Include("~/Content/style.css") _ + .Include("~/Content/domain.css")) + + bundles.Add(New StyleBundle("~/css/home").Include("~/Content/home.css")) + bundles.Add(New StyleBundle("~/css/statistics").Include("~/Content/statistics.css")) + bundles.Add(New StyleBundle("~/css/feedback").Include("~/Content/feedback.css")) + bundles.Add(New StyleBundle("~/css/api").Include("~/Content/api.css")) + bundles.Add(New StyleBundle("~/css/faq").Include("~/Content/faq.css")) + bundles.Add(New StyleBundle("~/css/list").Include("~/Content/list.css")) + bundles.Add(New StyleBundle("~/css/search").Include("~/Content/search.css")) + bundles.Add(New StyleBundle("~/css/success").Include("~/Content/success.css").Include("~/Content/proposal.css")) + bundles.Add(New StyleBundle("~/css/tags").Include("~/Content/tags.css")) + bundles.Add(New StyleBundle("~/css/notifications").Include("~/Content/notifications.css")) + bundles.Add(New StyleBundle("~/css/error").Include("~/Content/error.css")) + + For Each r As Representation In GlobalData.Representations.Items + + bundles.Add(New StyleBundle(String.Concat("~/css/representations-", r.Key)) _ + .Include("~/Content/representation.css") _ + .Include(String.Concat("~/Content/Representations/", r.Key, "/style-", r.Key, ".css"))) + + bundles.Add(New StyleBundle(String.Concat("~/css/proposal-", r.Key)) _ + .Include("~/Content/proposal.css") _ + .Include(String.Concat("~/Content/Representations/", r.Key, "/style-", r.Key, ".css"))) + Next + + Dim tss As New Teasers + For Each t As Teaser In tss.Items + + bundles.Add(New StyleBundle(String.Concat("~/css/teaser-", t.Key)) _ + .Include("~/Content/teaser.css") _ + .Include(String.Concat("~/Content/Teaser/", t.Key, "/style-", t.Key, ".css"))) + + Next + + End Sub + +End Class \ No newline at end of file diff --git a/OpenAntrag/App_Start/FilterConfig.vb b/OpenAntrag/App_Start/FilterConfig.vb new file mode 100644 index 0000000..5717148 --- /dev/null +++ b/OpenAntrag/App_Start/FilterConfig.vb @@ -0,0 +1,12 @@ +Imports System.Web +Imports System.Web.Mvc + +Public Class FilterConfig + + Public Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection) + + filters.Add(New HandleCustomErrorAttribute With {.View = "Uups"}) + + End Sub + +End Class \ No newline at end of file diff --git a/OpenAntrag/App_Start/FormatterConfig.vb b/OpenAntrag/App_Start/FormatterConfig.vb new file mode 100644 index 0000000..003ea82 --- /dev/null +++ b/OpenAntrag/App_Start/FormatterConfig.vb @@ -0,0 +1,24 @@ +Imports System.Net.Http.Formatting +Imports Newtonsoft.Json +Imports Newtonsoft.Json.Serialization +'Imports WebApiContrib.Formatting.Jsonp + +Public Class FormatterConfig + + Public Shared Sub RegisterFormatters(formatters As MediaTypeFormatterCollection) + + '>>> WebApiContrib.Formatting.Jsonp + '>>> STACKOVERFLOW-EXCEPTION: https://github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp/pull/10 + + 'Dim jsonFormatter = formatters.JsonFormatter + + 'jsonFormatter.SerializerSettings = New JsonSerializerSettings() With { + ' .ContractResolver = New CamelCasePropertyNamesContractResolver() + '} + + 'Dim jsonpFormatter = New JsonpMediaTypeFormatter(formatters.JsonFormatter) + 'formatters.Insert(0, jsonpFormatter) + + End Sub + +End Class diff --git a/OpenAntrag/App_Start/RouteConfig.vb b/OpenAntrag/App_Start/RouteConfig.vb new file mode 100644 index 0000000..6ec4941 --- /dev/null +++ b/OpenAntrag/App_Start/RouteConfig.vb @@ -0,0 +1,148 @@ +Imports System.Web.Mvc +Imports System.Web.Routing + +Public Class RouteConfig + + Public Shared Sub RegisterRoutes(ByVal routes As RouteCollection) + + routes.IgnoreRoute("{resource}.axd/{*pathInfo}") + + routes.MapRoute(name:="Overview", url:="Overview", + defaults:=New With {.controller = "Home", .action = "Overview"}) + + routes.MapRoute(name:="Faq", url:="faq", + defaults:=New With {.controller = "Home", .action = "Faq"}) + + routes.MapRoute(name:="Api", url:="api", + defaults:=New With {.controller = "Home", .action = "Api"}) + routes.MapRoute(name:="ApiDE", url:="schnittstellen", + defaults:=New With {.controller = "Home", .action = "Api"}) + + routes.MapRoute(name:="ProposalAllFeed", url:="feed", + defaults:=New With {.controller = "Home", .action = "ProposalAllFeed"}) + + routes.MapRoute(name:="Journal", url:="journal/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Journal", .pageNo = 1}) + + routes.MapRoute(name:="Success", url:="success/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Success", .pageNo = 1}) + routes.MapRoute(name:="SuccessDE", url:="erfolge/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Success", .pageNo = 1}) + + routes.MapRoute(name:="List", url:="list/", + defaults:=New With {.controller = "Home", .action = "List"}) + routes.MapRoute(name:="ListDE", url:="liste/", + defaults:=New With {.controller = "Home", .action = "List"}) + + routes.MapRoute(name:="Search", url:="search/{searchTerms}/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Search", .searchTerms = "", .pageNo = 1}) + routes.MapRoute(name:="SearchDE", url:="suche/{searchTerms}/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Search", .searchTerms = "", .pageNo = 1}) + + routes.MapRoute(name:="Tags", url:="tags/{tag}/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Tags", .tag = "", .pageNo = 1}) + routes.MapRoute(name:="TagsDE", url:="themen/{tag}/{pageNo}", + defaults:=New With {.controller = "Home", .action = "Tags", .tag = "", .pageNo = 1}) + + routes.MapRoute(name:="FeedbackService", url:="feedback/service/{action}", + defaults:=New With {.controller = "Feedback", .action = ""}) + + routes.MapRoute(name:="Feedback", url:="feedback/{key}", + defaults:=New With {.controller = "Feedback", .action = "Index", .key = ""}) + + routes.MapRoute(name:="NotificationsFeed", url:="notifications/feed/{type}", + defaults:=New With {.controller = "Notifications", .action = "Feed", .type = -1}) + routes.MapRoute(name:="NotificationsFeedDE", url:="mitteilungen/feed/{type}", + defaults:=New With {.controller = "Notifications", .action = "Feed", .type = -1}) + + routes.MapRoute(name:="NotificationsService", url:="notifications/service/{action}", + defaults:=New With {.controller = "Notifications", .action = ""}) + + routes.MapRoute(name:="Notifications", url:="notifications/{type}", + defaults:=New With {.controller = "Notifications", .action = "Index", .type = ""}) + routes.MapRoute(name:="NotificationsDE", url:="mitteilungen/{type}", + defaults:=New With {.controller = "Notifications", .action = "Index", .type = ""}) + + routes.MapRoute(name:="Statistics", url:="statistics/{statPart}", + defaults:=New With {.controller = "Statistics", .action = "Index", .statPart = ""}) + routes.MapRoute(name:="StatisticsDE", url:="statistiken/{statPart}", + defaults:=New With {.controller = "Statistics", .action = "Index", .statPart = ""}) + + routes.MapRoute(name:="AllRepresentationsStyle", url:="allrepresentationstyle.css", + defaults:=New With {.controller = "Home", .action = "AllRepresentationsStyle"}) + + + '*** Representation/Proposal-Routes *** + 'wiesbaden > Representation + 'wiesbaden/1 > Representation-Page + 'wiesbaden/mein-antrag > Proposal + + For Each rep As Representation In GlobalData.Representations.Items + 'Representation + + routes.MapRoute(name:=String.Concat("RepresentationHome-", rep.Key), url:=rep.Key, + defaults:=New With {.controller = "Representation", .action = "Index", .keyRepresentation = rep.Key}) + + routes.MapRoute(name:=String.Concat("RepresentationJournal-", rep.Key), url:=String.Concat(rep.Key, "/journal/{pageNo}"), + defaults:=New With {.controller = "Representation", .action = "Journal", .keyRepresentation = rep.Key, .pageNo = 1}, + constraints:=New With {.pageNo = "\d+"}) + + routes.MapRoute(name:=String.Concat("RepresentationList", rep.Key), url:=String.Concat(rep.Key, "/list"), + defaults:=New With {.controller = "Representation", .action = "List", .keyRepresentation = rep.Key}) + routes.MapRoute(name:=String.Concat("RepresentationListDE", rep.Key), url:=String.Concat(rep.Key, "/liste"), + defaults:=New With {.controller = "Representation", .action = "List", .keyRepresentation = rep.Key}) + + If (rep.Status And Representations.StatusConjuction.Ended) = 0 Then + routes.MapRoute(name:=String.Concat("RepresentationAdd", rep.Key), url:=String.Concat(rep.Key, "/add"), + defaults:=New With {.controller = "Representation", .action = "Add", .keyRepresentation = rep.Key}) + routes.MapRoute(name:=String.Concat("RepresentationAddDE", rep.Key), url:=String.Concat(rep.Key, "/neu"), + defaults:=New With {.controller = "Representation", .action = "Add", .keyRepresentation = rep.Key}) + + routes.MapRoute(name:=String.Concat("RepresentationBanner", rep.Key), url:=String.Concat(rep.Key, "/banner"), + defaults:=New With {.controller = "Representation", .action = "Banner", .keyRepresentation = rep.Key}) + + routes.MapRoute(name:=String.Concat("RepresentationSettings", rep.Key), url:=String.Concat(rep.Key, "/einstellungen"), + defaults:=New With {.controller = "Representation", .action = "Settings", .keyRepresentation = rep.Key}) + End If + + routes.MapRoute(name:=String.Concat("RepresentationStyle", rep.Key), url:=String.Concat(rep.Key, "/style-representation"), + defaults:=New With {.controller = "Representation", .action = "RepresentationStyle", .keyRepresentation = rep.Key}) + + routes.MapRoute(name:=String.Concat("RepresentationFeedRoute", rep.Key), url:=String.Concat(rep.Key, "/feed"), + defaults:=New With {.controller = "Representation", .action = "ProposalFeed", .keyRepresentation = rep.Key}) + + 'Proposal + routes.MapRoute(name:=String.Concat("ProposalRoute", rep.Key), url:=String.Concat(rep.Key, "/{titleUrl}"), + defaults:=New With {.controller = "Representation", .action = "Proposal", .keyRepresentation = rep.Key, .titleUrl = ""}) + + 'SuccessStory + routes.MapRoute(name:=String.Concat("SuccessStoryRoute", rep.Key), url:=String.Concat(rep.Key, "/{titleUrl}/success"), + defaults:=New With {.controller = "Representation", .action = "SuccessStory", .keyRepresentation = rep.Key, .titleUrl = ""}) + routes.MapRoute(name:=String.Concat("SuccessStoryRouteDE", rep.Key), url:=String.Concat(rep.Key, "/{titleUrl}/erfolg"), + defaults:=New With {.controller = "Representation", .action = "SuccessStory", .keyRepresentation = rep.Key, .titleUrl = ""}) + + Next + + Dim tss As New Teasers + For Each tsr As Teaser In tss.Items + + routes.MapRoute(name:=String.Concat("TeaserHome-", tsr.Key), url:=tsr.TeaserUrl, + defaults:=New With {.controller = "Teaser", .action = "Index", .keyTeaser = tsr.Key}) + + routes.MapRoute(name:=String.Concat("TeaserStyle", tsr.Key), url:=String.Concat(tsr.TeaserUrl, "/style-teaser"), + defaults:=New With {.controller = "Teaser", .action = "TeaserStyle", .keyTeaser = tsr.Key}) + + Next + + routes.MapRoute(name:="Error", url:="uups/{action}", + defaults:=New With {.controller = "Error", .action = "Index"}) + + routes.MapRoute(name:="ErrorLog", url:="errors/{id}", + defaults:=New With {.controller = "Error", .action = "ErrorLog"}) + + routes.MapRoute(name:="Default", url:="{controller}/{action}", + defaults:=New With {.controller = "Home", .action = "Index"}) + + End Sub + +End Class \ No newline at end of file diff --git a/OpenAntrag/App_Start/WebApiConfig.vb b/OpenAntrag/App_Start/WebApiConfig.vb new file mode 100644 index 0000000..7e8dff9 --- /dev/null +++ b/OpenAntrag/App_Start/WebApiConfig.vb @@ -0,0 +1,108 @@ + +Imports System.Web.Http + +Public Class WebApiConfig + Public Shared Sub Register(ByVal config As HttpConfiguration) + + Dim routes As HttpRouteCollection = config.Routes + + '************************************************************************* + + routes.MapHttpRoute(name:="RepresentationApi", + routeTemplate:="api/representation/{action}/{key}", + defaults:=New With {.controller = "RepresentationApi", + .key = RouteParameter.Optional}) + + routes.MapHttpRoute(name:="RepresentationApiExt", + routeTemplate:="api/representation/{action}/{key}/{id}", + defaults:=New With {.controller = "RepresentationApi", + .key = "", + .id = ""}) + + '************************************************************************* + + '(muss VOR der Default-Route stehen, damit ALL nicht als Action interpretiert wird) + routes.MapHttpRoute(name:="ProposalApiItemsCount", + routeTemplate:="api/proposal/{key}/getcount", + defaults:=New With {.controller = "ProposalApi", + .key = "ALL", + .action = "GetCount"}) + + routes.MapHttpRoute(name:="ProposalApi", + routeTemplate:="api/proposal/{action}/{id}", + defaults:=New With {.controller = "ProposalApi", + .id = RouteParameter.Optional}) + + routes.MapHttpRoute(name:="ProposalApiTitleUrl", + routeTemplate:="api/proposal/{key}/getbytitleurl/{titleUrl}", + defaults:=New With {.controller = "ProposalApi", + .key = "", + .titleUrl = ""}) + + routes.MapHttpRoute(name:="ProposalApiItemsTop", + routeTemplate:="api/proposal/{key}/gettop/{count}", + defaults:=New With {.controller = "ProposalApi", + .key = "ALL", + .action = "GetTop", + .count = 5}) + + routes.MapHttpRoute(name:="ProposalApiItemsPage", + routeTemplate:="api/proposal/{key}/getpage/{pageNo}/{pageCount}", + defaults:=New With {.controller = "ProposalApi", + .key = "ALL", + .action = "GetPage", + .pageNo = 1, + .pageCount = 5}) + + routes.MapHttpRoute(name:="ProposalApiItemsTag", + routeTemplate:="api/proposal/{key}/getbytag/{tag}", + defaults:=New With {.controller = "ProposalApi", + .key = "ALL", + .action = "GetByTag", + .tag = ""}) + + routes.MapHttpRoute(name:="ProposalApiTags", + routeTemplate:="api/proposal/gettags", + defaults:=New With {.controller = "ProposalApi", + .action = "GetTags"}) + + + routes.MapHttpRoute(name:="ProposalApiPost", + routeTemplate:="api/proposal/{action}", + defaults:=New With {.controller = "ProposalApi"}) + + '************************************************************************* + + routes.MapHttpRoute(name:="NotificationsApiItemsLast", + routeTemplate:="api/notifications/getlast/{count}", + defaults:=New With {.controller = "NotificationsApi", + .action = "GetLast", + .count = 5}) + + routes.MapHttpRoute(name:="NotificationsApiItemsLastByType", + routeTemplate:="api/notifications/getlastbytype/{typeId}/{count}", + defaults:=New With {.controller = "NotificationsApi", + .action = "GetLastByType", + .typeId = 0, + .count = 5}) + + routes.MapHttpRoute(name:="NotificationsApi", + routeTemplate:="api/notifications/{action}/{key}", + defaults:=New With {.controller = "NotificationsApi", + .key = RouteParameter.Optional}) + + '************************************************************************* + + 'routes.MapHttpRoute(name:="DefaultApi", + ' routeTemplate:="api/{controller}/{id}", + ' defaults:=New With {.id = RouteParameter.Optional}) + + 'Uncomment the following line of code to enable query support for actions + 'with an IQueryable or IQueryable(Of T) return type. + 'To avoid processing unexpected or malicious queries, use the validation + 'settings on QueryableAttribute to validate incoming queries. + 'For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. + 'config.EnableQuerySupport() + + End Sub +End Class \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/bootstrap-datetimepicker.css b/OpenAntrag/Content/Plugins/bootstrap-datetimepicker.css new file mode 100644 index 0000000..36044a0 --- /dev/null +++ b/OpenAntrag/Content/Plugins/bootstrap-datetimepicker.css @@ -0,0 +1,235 @@ +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, .clearfix:after { + display: table; + content: ""; + line-height: 0; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.bootstrap-datetimepicker-widget { + top: 0; + left: 0; + width: 250px; + padding: 4px; + margin-top: 1px; + z-index: 3000; + -webkit-box-shadow: 2px 2px 12px -4px rgba(0, 0, 0, 0.5); + box-shadow: 2px 2px 12px -4px rgba(0, 0, 0, 0.5); +} + +.bootstrap-datetimepicker-widget:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,0.2); + position: absolute; + top: -7px; + left: 6px; +} + +.bootstrap-datetimepicker-widget:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: -6px; + left: 7px; +} + +.bootstrap-datetimepicker-widget.pull-right:before { + left: auto; + right: 6px; +} + +.bootstrap-datetimepicker-widget.pull-right:after { + left: auto; + right: 7px; +} + +.bootstrap-datetimepicker-widget li { + list-style-type: none; + margin-bottom: 0; +} + +.bootstrap-datetimepicker-widget > ul { + list-style-type: none; + margin: 0; +} + +.bootstrap-datetimepicker-widget .timepicker-hour, .bootstrap-datetimepicker-widget .timepicker-minute, .bootstrap-datetimepicker-widget .timepicker-second { + width: 100%; + font-weight: bold; + font-size: 1.2em; +} + +.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator { + width: 4px; + padding: 0; + margin: 0; +} + +.bootstrap-datetimepicker-widget .datepicker > div { + display: none; +} + +.bootstrap-datetimepicker-widget .picker-switch { + text-align: center; + background-color: #f4f4f4; +} + +.bootstrap-datetimepicker-widget table { + width: 100%; + margin: 0; +} + +.bootstrap-datetimepicker-widget td, .bootstrap-datetimepicker-widget th { + text-align: center; + width: 20px; + height: 20px; +} + +.bootstrap-datetimepicker-widget td.day:hover, .bootstrap-datetimepicker-widget td.hour:hover, .bootstrap-datetimepicker-widget td.minute:hover, .bootstrap-datetimepicker-widget td.second:hover { + background: #eee; + cursor: pointer; +} + +.bootstrap-datetimepicker-widget td.old, .bootstrap-datetimepicker-widget td.new { + color: #999; +} + +.bootstrap-datetimepicker-widget td.active, .bootstrap-datetimepicker-widget td.active:hover { + color: #fff; + background-color: #333; + border-color: #333; + color: #fff; +} + +.bootstrap-datetimepicker-widget td.active:hover, .bootstrap-datetimepicker-widget td.active:hover:hover, .bootstrap-datetimepicker-widget td.active:active, .bootstrap-datetimepicker-widget td.active:hover:active, .bootstrap-datetimepicker-widget td.active.active, .bootstrap-datetimepicker-widget td.active:hover.active, .bootstrap-datetimepicker-widget td.active.disabled, .bootstrap-datetimepicker-widget td.active:hover.disabled, .bootstrap-datetimepicker-widget td.active[disabled], .bootstrap-datetimepicker-widget td.active:hover[disabled] { + color: #fff; + background-color: #333; +} + +.bootstrap-datetimepicker-widget td.active:active, .bootstrap-datetimepicker-widget td.active:hover:active, .bootstrap-datetimepicker-widget td.active.active, .bootstrap-datetimepicker-widget td.active:hover.active { + background-color: #333; +} + +.bootstrap-datetimepicker-widget td.disabled, .bootstrap-datetimepicker-widget td.disabled:hover { + background: 0; + color: #999; + cursor: not-allowed; +} + +.bootstrap-datetimepicker-widget td span { + display: block; + width: 47px; + height: 54px; + line-height: 54px; + float: left; + margin: 2px; + cursor: pointer; +} + +.bootstrap-datetimepicker-widget td span:hover { + background: #eee; +} + +.bootstrap-datetimepicker-widget td span.active { + color: #fff; + background-color: #333; + border-color: #333; + color: #fff; +} + +.bootstrap-datetimepicker-widget td span.active:hover, .bootstrap-datetimepicker-widget td span.active:active, .bootstrap-datetimepicker-widget td span.active.active, .bootstrap-datetimepicker-widget td span.active.disabled, .bootstrap-datetimepicker-widget td span.active[disabled] { + color: #fff; + background-color: #333; +} + +.bootstrap-datetimepicker-widget td span.active:active, .bootstrap-datetimepicker-widget td span.active.active { + background-color: #333; +} + +.bootstrap-datetimepicker-widget td span.old { + color: #999; +} + +.bootstrap-datetimepicker-widget td span.disabled, .bootstrap-datetimepicker-widget td span.disabled:hover { + background: 0; + color: #999; + cursor: not-allowed; +} + +.bootstrap-datetimepicker-widget th.switch { + width: 145px; +} + +.bootstrap-datetimepicker-widget th.next, .bootstrap-datetimepicker-widget th.prev { + font-size: 21px; +} + +.bootstrap-datetimepicker-widget th.disabled, .bootstrap-datetimepicker-widget th.disabled:hover { + background: 0; + color: #999; + cursor: not-allowed; +} + +.bootstrap-datetimepicker-widget thead tr:first-child th { + cursor: pointer; +} + +.bootstrap-datetimepicker-widget thead tr:first-child th:hover { + background: #eee; +} + +.input-append.date .add-on i, .input-prepend.date .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} + +.bootstrap-datetimepicker-widget.left-oriented:before { + left: auto; + right: 6px; +} + +.bootstrap-datetimepicker-widget.left-oriented:after { + left: auto; + right: 7px; +} diff --git a/OpenAntrag/Content/Plugins/bootstrap-select.css b/OpenAntrag/Content/Plugins/bootstrap-select.css new file mode 100644 index 0000000..0f21e36 --- /dev/null +++ b/OpenAntrag/Content/Plugins/bootstrap-select.css @@ -0,0 +1,183 @@ +.bootstrap-select.btn-group, +.bootstrap-select.btn-group[class*="span"] { + float: none; + display: inline-block; + /*KRZE: margin-bottom: 10px;*/ + margin-left: 0; +} +.form-search .bootstrap-select.btn-group, +.form-inline .bootstrap-select.btn-group, +.form-horizontal .bootstrap-select.btn-group { + margin-bottom: 0; +} + +.bootstrap-select.btn-group.pull-right, +.bootstrap-select.btn-group[class*="span"].pull-right, +.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right { + float: right; +} + +.input-append .bootstrap-select.btn-group { + margin-left: -1px; +} + +.input-prepend .bootstrap-select.btn-group { + margin-right: -1px; +} + +.bootstrap-select:not([class*="span"]) { + width: 220px; +} + +.bootstrap-select { + width: 220px\9; /*IE8 and below*/ +} + +.bootstrap-select .btn { + width: 100%; +} + +.bootstrap-select.show-menu-arrow.open .btn { + z-index: 1001; +} + +.bootstrap-select .btn:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; +} + +.bootstrap-select.btn-group .btn .filter-option { + overflow: hidden; + position: absolute; + left: 12px; + right: 25px; + text-align: left; +} + +.bootstrap-select.btn-group .btn .caret { + position: absolute; + right: 12px; +} + +.bootstrap-select.btn-group > .disabled, +.bootstrap-select.btn-group .dropdown-menu li.disabled > a { + cursor: not-allowed; +} + +.bootstrap-select.btn-group[class*="span"] .btn { + width: 100%; +} + +.bootstrap-select.btn-group .dropdown-menu { + min-width: 100%; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.bootstrap-select.btn-group .dropdown-menu dt { + display: block; + padding: 3px 20px; + cursor: default; +} + +.bootstrap-select.btn-group .div-contain { + overflow: hidden; +} + +.bootstrap-select.btn-group .dropdown-menu li > a.opt { + padding-left: 35px; +} + +.bootstrap-select.btn-group .dropdown-menu li > a { + min-height: 20px; + cursor: pointer; +} + +.bootstrap-select.btn-group .dropdown-menu li > dt small { + font-weight: normal; +} + +.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark { + display: inline-block; + position: absolute; + right: 15px; + margin-top: 2.5px; +} + +.bootstrap-select.btn-group .dropdown-menu li a i.check-mark { + display: none; +} + +.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text { + margin-right: 34px; +} + +.bootstrap-select.btn-group .dropdown-menu li small { + padding-left: 0.5em; +} + +.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:hover small, +.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:focus small { + color: #64b1d8; + color: rgba(255,255,255,0.4); +} + +.bootstrap-select.btn-group .dropdown-menu li > dt small { + font-weight: normal; +} + +.bootstrap-select.show-menu-arrow .dropdown-toggle:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #CCC; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: -4px; + left: 9px; + display: none; +} + +.bootstrap-select.show-menu-arrow .dropdown-toggle:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; +} + +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before { + bottom: auto; + top: -3px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after { + bottom: auto; + top: -3px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before { + right: 12px; + left: auto; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after { + right: 13px; + left: auto; +} + +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before, +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after { + display: block; +} diff --git a/OpenAntrag/Content/Plugins/flatstrap-responsive.css b/OpenAntrag/Content/Plugins/flatstrap-responsive.css new file mode 100644 index 0000000..034f714 --- /dev/null +++ b/OpenAntrag/Content/Plugins/flatstrap-responsive.css @@ -0,0 +1,1073 @@ +/*! + * Bootstrap Responsive v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +@-ms-viewport { + width: device-width; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +.visible-desktop { + display: inherit !important; +} +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .media .pull-left, + .media .pull-right { + float: none; + display: block; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + left: 10px; + right: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: none; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/OpenAntrag/Content/Plugins/flatstrap-responsive.min.css b/OpenAntrag/Content/Plugins/flatstrap-responsive.min.css new file mode 100644 index 0000000..42680cd --- /dev/null +++ b/OpenAntrag/Content/Plugins/flatstrap-responsive.min.css @@ -0,0 +1,145 @@ +/*!* Bootstrap Responsive v2.3.1 * * Copyright 2012 Twitter,Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */ .clearfix{*zoom:1;} +.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}.clearfix:after{clear:both;} +.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;} +.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +@-ms-viewport{width:device-width;}.hidden{display:none;visibility:hidden;}.visible-phone{display:none!important;} +.visible-tablet{display:none!important;}.hidden-desktop{display:none!important;} +.visible-desktop{display:inherit!important;}@media(min-width:768px) and(max-width:979px){.hidden-desktop{display:inherit!important;} +.visible-desktop{display:none!important;}.visible-tablet{display:inherit!important;} +.hidden-tablet{display:none!important;}}@media(max-width:767px){.hidden-desktop{display:inherit!important;} +.visible-desktop{display:none!important;}.visible-phone{display:inherit!important;} +.hidden-phone{display:none!important;}}.visible-print{display:none!important;}@media print{.visible-print{display:inherit!important;} +.hidden-print{display:none!important;}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1;} +.row:before,.row:after{display:table;content:"";line-height:0;}.row:after{clear:both;} +[class*="span"]{float:left;min-height:1px;margin-left:30px;}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} +.span12{width:1170px;}.span11{width:1070px;}.span10{width:970px;}.span9{width:870px;} +.span8{width:770px;}.span7{width:670px;}.span6{width:570px;}.span5{width:470px;} +.span4{width:370px;}.span3{width:270px;}.span2{width:170px;}.span1{width:70px;}.offset12{margin-left:1230px;} +.offset11{margin-left:1130px;}.offset10{margin-left:1030px;}.offset9{margin-left:930px;} +.offset8{margin-left:830px;}.offset7{margin-left:730px;}.offset6{margin-left:630px;} +.offset5{margin-left:530px;}.offset4{margin-left:430px;}.offset3{margin-left:330px;} +.offset2{margin-left:230px;}.offset1{margin-left:130px;}.row-fluid{width:100%;*zoom:1;} +.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}.row-fluid:after{clear:both;} +.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} +.row-fluid [class*="span"]:first-child{margin-left:0;}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} +.row-fluid .span12{width:100%;*width:99.94680851063829%;}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} +.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} +.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} +.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} +.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} +.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} +.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} +.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} +.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} +.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} +.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} +.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} +.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} +.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} +.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} +.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} +.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} +.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} +.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} +.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} +.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} +.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} +.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} +.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} +.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} +.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} +.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} +.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} +.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} +.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} +input,textarea,.uneditable-input{margin-left:0;}.controls-row [class*="span"]+[class*="span"]{margin-left:30px;} +input.span12,textarea.span12,.uneditable-input.span12{width:1156px;}input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} +input.span10,textarea.span10,.uneditable-input.span10{width:956px;}input.span9,textarea.span9,.uneditable-input.span9{width:856px;} +input.span8,textarea.span8,.uneditable-input.span8{width:756px;}input.span7,textarea.span7,.uneditable-input.span7{width:656px;} +input.span6,textarea.span6,.uneditable-input.span6{width:556px;}input.span5,textarea.span5,.uneditable-input.span5{width:456px;} +input.span4,textarea.span4,.uneditable-input.span4{width:356px;}input.span3,textarea.span3,.uneditable-input.span3{width:256px;} +input.span2,textarea.span2,.uneditable-input.span2{width:156px;}input.span1,textarea.span1,.uneditable-input.span1{width:56px;} +.thumbnails{margin-left:-30px;}.thumbnails>li{margin-left:30px;}.row-fluid .thumbnails{margin-left:0;} +}@media(min-width:768px) and(max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} +.row:after{clear:both;}[class*="span"]{float:left;min-height:1px;margin-left:20px;} +.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} +.span12{width:724px;}.span11{width:662px;}.span10{width:600px;}.span9{width:538px;} +.span8{width:476px;}.span7{width:414px;}.span6{width:352px;}.span5{width:290px;} +.span4{width:228px;}.span3{width:166px;}.span2{width:104px;}.span1{width:42px;}.offset12{margin-left:764px;} +.offset11{margin-left:702px;}.offset10{margin-left:640px;}.offset9{margin-left:578px;} +.offset8{margin-left:516px;}.offset7{margin-left:454px;}.offset6{margin-left:392px;} +.offset5{margin-left:330px;}.offset4{margin-left:268px;}.offset3{margin-left:206px;} +.offset2{margin-left:144px;}.offset1{margin-left:82px;}.row-fluid{width:100%;*zoom:1;} +.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}.row-fluid:after{clear:both;} +.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} +.row-fluid [class*="span"]:first-child{margin-left:0;}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} +.row-fluid .span12{width:100%;*width:99.94680851063829%;}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} +.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} +.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} +.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} +.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} +.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} +.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} +.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} +.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} +.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} +.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} +.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} +.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} +.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} +.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} +.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} +.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} +.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} +.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} +.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} +.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} +.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} +.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} +.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} +.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} +.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} +.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} +.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} +.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} +.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} +input,textarea,.uneditable-input{margin-left:0;}.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12,textarea.span12,.uneditable-input.span12{width:710px;}input.span11,textarea.span11,.uneditable-input.span11{width:648px;} +input.span10,textarea.span10,.uneditable-input.span10{width:586px;}input.span9,textarea.span9,.uneditable-input.span9{width:524px;} +input.span8,textarea.span8,.uneditable-input.span8{width:462px;}input.span7,textarea.span7,.uneditable-input.span7{width:400px;} +input.span6,textarea.span6,.uneditable-input.span6{width:338px;}input.span5,textarea.span5,.uneditable-input.span5{width:276px;} +input.span4,textarea.span4,.uneditable-input.span4{width:214px;}input.span3,textarea.span3,.uneditable-input.span3{width:152px;} +input.span2,textarea.span2,.uneditable-input.span2{width:90px;}input.span1,textarea.span1,.uneditable-input.span1{width:28px;} +}@media(max-width:767px){body{padding-left:20px;padding-right:20px;}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} +.container-fluid{padding:0;}.dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} +.dl-horizontal dd{margin-left:0;}.container{width:auto;}.row-fluid{width:100%;}.row,.thumbnails{margin-left:0;} +.thumbnails>li{float:none;margin-left:0;}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.row-fluid [class*="offset"]:first-child{margin-left:0;}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} +.controls-row [class*="span"]+[class*="span"]{margin-left:0;}.modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;} +.modal.fade{top:-100px;}.modal.fade.in{top:20px;}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0);} +.page-header h1 small{display:block;line-height:20px;}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} +.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} +.form-horizontal .controls{margin-left:0;}.form-horizontal .control-list{padding-top:0;} +.form-horizontal .form-actions{padding-left:10px;padding-right:10px;}.media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} +.media-object{margin-right:0;margin-left:0;}.modal{top:10px;left:10px;right:10px;} +.modal-header .close{padding:10px;margin:-10px;}.carousel-caption{position:static;} +}@media(max-width:979px){body{padding-top:0;}.navbar-fixed-top,.navbar-fixed-bottom{position:static;} +.navbar-fixed-top{margin-bottom:20px;}.navbar-fixed-bottom{margin-top:20px;}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} +.navbar .container{width:auto;padding:0;}.navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} +.nav-collapse{clear:both;}.nav-collapse .nav{float:none;margin:0 0 10px;}.nav-collapse .nav>li{float:none;} +.nav-collapse .nav>li>a{margin-bottom:2px;}.nav-collapse .nav>.divider-vertical{display:none;} +.nav-collapse .nav .nav-header{color:#777;text-shadow:none;}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;} +.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} +.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2;} +.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999;} +.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111;} +.nav-collapse.in .btn-group{margin-top:5px;padding:0;}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;} +.nav-collapse .open>.dropdown-menu{display:block;}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} +.nav-collapse .dropdown-menu .divider{display:none;}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} +.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;} +.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111;} +.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;}.nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} +.navbar .btn-navbar{display:block;}.navbar-static .navbar-inner{padding-left:10px;padding-right:10px;} +}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important;}} \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/flatstrap.css b/OpenAntrag/Content/Plugins/flatstrap.css new file mode 100644 index 0000000..1e6833b --- /dev/null +++ b/OpenAntrag/Content/Plugins/flatstrap.css @@ -0,0 +1,4138 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + /* Responsive images (ensure images don't scale beyond their parents) */ + + max-width: 100%; + /* Part 1: Set a maxium relative to the parent */ + + width: auto\9; + /* IE7-8 need help adjusting responsive images */ + + height: auto; + /* Part 2: Scale the height according to the width, otherwise you get stretching */ + + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img, +.google-maps img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} +a { + color: #0088cc; + text-decoration: none; +} +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; + line-height: 0; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; + line-height: 0; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} +small { + font-size: 85%; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +cite { + font-style: normal; +} +.muted { + color: #999999; +} +a.muted:hover, +a.muted:focus { + color: #808080; +} +.text-warning { + color: #c09853; +} +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} +.text-error { + color: #b94a48; +} +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} +.text-info { + color: #3a87ad; +} +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} +.text-success { + color: #468847; +} +a.text-success:hover, +a.text-success:focus { + color: #356635; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} +h1, +h2, +h3 { + line-height: 40px; +} +h1 { + font-size: 38.5px; +} +h2 { + font-size: 31.5px; +} +h3 { + font-size: 24.5px; +} +h4 { + font-size: 17.5px; +} +h5 { + font-size: 14px; +} +h6 { + font-size: 11.9px; +} +h1 small { + font-size: 24.5px; +} +h2 small { + font-size: 17.5px; +} +h3 small { + font-size: 14px; +} +h4 small { + font-size: 14px; +} +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +li { + line-height: 20px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-bottom: 20px; +} +dt, +dd { + line-height: 20px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 10px; +} +.dl-horizontal { + *zoom: 1; +} +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + content: ""; + line-height: 0; +} +.dl-horizontal:after { + clear: both; +} +.dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +blockquote.pull-right small:before { + content: ''; +} +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + white-space: nowrap; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); +} +pre.prettyprint { + margin-bottom: 20px; +} +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 20px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 15px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; +} +input, +textarea, +.uneditable-input { + width: 206px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-transition: border linear .2s, box-shadow linear .2s; + -moz-transition: border linear .2s, box-shadow linear .2s; + -o-transition: border linear .2s, box-shadow linear .2s; + transition: border linear .2s, box-shadow linear .2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; + /* IE7 */ + + margin-top: 1px \9; + /* IE8-9 */ + + line-height: normal; +} +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} +select { + width: 220px; + border: 1px solid #cccccc; + background-color: #ffffff; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.uneditable-input, +.uneditable-textarea { + color: #999999; + background-color: #fcfcfc; + border-color: #cccccc; + cursor: not-allowed; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} +.uneditable-textarea { + width: auto; + height: auto; +} +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} +.controls-row { + *zoom: 1; +} +.controls-row:before, +.controls-row:after { + display: table; + content: ""; + line-height: 0; +} +.controls-row:after { + clear: both; +} +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; +} +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; + line-height: 0; +} +.form-actions:after { + clear: both; +} +.help-block, +.help-inline { + color: #595959; +} +.help-block { + display: block; + margin-bottom: 10px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + vertical-align: middle; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; +} +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; +} +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 10px; +} +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; + line-height: 0; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 180px; +} +.form-horizontal .help-block { + margin-bottom: 0; +} +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} +.form-horizontal .form-actions { + padding-left: 180px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 20px; +} +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} +.table tbody tr.success > td { + background-color: #dff0d8; +} +.table tbody tr.error > td { + background-color: #f2dede; +} +.table tbody tr.warning > td { + background-color: #fcf8e3; +} +.table tbody tr.info > td { + background-color: #d9edf7; +} +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} +/*! + * Font Awesome 3.0.2 + * the iconic font designed for use with Twitter Bootstrap + * ------------------------------------------------------- + * The full suite of pictographic icons, examples, and documentation + * can be found at: http://fortawesome.github.com/Font-Awesome/ + * + * License + * ------------------------------------------------------- + * - The Font Awesome font is licensed under the SIL Open Font License - http://scripts.sil.org/OFL + * - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License - + * http://opensource.org/licenses/mit-license.html + * - The Font Awesome pictograms are licensed under the CC BY 3.0 License - http://creativecommons.org/licenses/by/3.0/ + * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: + * "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome" + + * Contact + * ------------------------------------------------------- + * Email: dave@davegandy.com + * Twitter: http://twitter.com/fortaweso_me + * Work: Lead Product Designer @ http://kyruus.com + */ + +/* ERSETZT DURCH FONT-AWESOME.CSS */ + +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + text-decoration: none; + color: #ffffff; + background-color: #3498DB; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #3498DB; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: default; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.dropdown-submenu { + position: relative; +} +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} +.dropdown-submenu.pull-left { + float: none; +} +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; +} +.dropdown .dropdown-menu .nav-header { + padding-left: 20px; + padding-right: 20px; +} +.typeahead { + z-index: 1051; + margin-top: 2px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; +} +.well-small { + padding: 9px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding: 4px 12px; + margin-bottom: 0; + font-size: 14px; + line-height: 20px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + background-color: #f5f5f5; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + *margin-left: .3em; +} +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + outline: 0; +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); +} +.btn-large { + padding: 11px 19px; + font-size: 17.5px; +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} +.btn-small { + padding: 2px 10px; + font-size: 11.9px; +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 0 6px; + font-size: 10.5px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #0044cc; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f89406; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: #0088cc; +} +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} +.btn-group { + position: relative; + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + font-size: 0; + vertical-align: middle; + white-space: nowrap; + *margin-left: .3em; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + font-size: 0; + margin-top: 10px; + margin-bottom: 10px; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; +} +.btn-group > .btn + .btn { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} +.btn-group > .btn-mini { + font-size: 10.5px; +} +.btn-group > .btn-small { + font-size: 11.9px; +} +.btn-group > .btn-large { + font-size: 17.5px; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn.large:first-child { + margin-left: 0; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.btn-group.open .dropdown-toggle { + background-image: none; +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +.dropup .btn-large .caret { + border-bottom-width: 5px; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; +} +.alert, +.alert h4 { + color: #c09853; +} +.alert h4 { + margin: 0; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} +.alert-success h4 { + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} +.alert-info h4 { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 20px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li > a > img { + max-width: none; +} +.nav > .pull-right { + float: right; +} +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; + line-height: 0; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; +} +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; +} +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav .dropdown-toggle .caret { + border-top-color: #0088cc; + border-bottom-color: #0088cc; + margin-top: 6px; +} +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} +/* move down carets for tabs */ +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; + line-height: 0; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; +} +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; +} +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.nav > .disabled > a { + color: #999999; +} +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + cursor: default; +} +.navbar { + overflow: visible; + margin-bottom: 20px; + *position: relative; + *z-index: 2; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #fafafa; + border: 1px solid #d4d4d4; + *zoom: 1; +} +.navbar-inner:before, +.navbar-inner:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-inner:after { + clear: both; +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; + overflow: visible; +} +.navbar .brand { + float: left; + display: block; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} +.navbar-link { + color: #777777; +} +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-left: 1px solid #f2f2f2; + border-right: 1px solid #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-search .search-query { + margin-bottom: 0; + padding: 4px 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; +} +.navbar-static-top { + position: static; + margin-bottom: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; +} +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} +.navbar .nav > li { + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + background-color: transparent; + color: #333333; + text-decoration: none; +} +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e5e5e5; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .nav > li > .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .nav > li > .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #e5e5e5; + color: #555555; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: -1px; +} +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + border-color: #252525; +} +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} +.navbar-inverse .brand { + color: #999999; +} +.navbar-inverse .navbar-text { + color: #999999; +} +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + background-color: transparent; + color: #ffffff; +} +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} +.navbar-inverse .navbar-link { + color: #999999; +} +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} +.navbar-inverse .divider-vertical { + border-left-color: #111111; + border-right-color: #222222; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #111111; + color: #ffffff; +} +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; +} +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #040404; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; +} +.breadcrumb > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #999999; +} +.pagination { + margin: 20px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; +} +.pagination ul > li { + display: inline; +} +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} +.pager { + margin: 20px 0; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; + line-height: 0; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: none; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 10%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-header h3 { + margin: 0; + line-height: 30px; +} +.modal-body { + position: relative; + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; + line-height: 0; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; + color: #555555; +} +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + margin-left: 0; + list-style: none; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.badge { + padding-left: 9px; + padding-right: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #b94a48; +} +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #468847; +} +.label-success[href], +.badge-success[href] { + background-color: #356635; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f7f7f7; +} +.progress .bar { + width: 0%; + height: 100%; + color: #ffffff; + float: left; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #149bdf; + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; +} +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; +} +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; +} +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; +} +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; +} +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; +} +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; +} +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; +} +.accordion { + margin-bottom: 20px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); +} +.carousel-indicators .active { + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; + line-height: 20px; +} +.carousel-caption h4 { + margin: 0 0 5px; +} +.carousel-caption p { + margin-bottom: 0; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit li { + line-height: 30px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} diff --git a/OpenAntrag/Content/Plugins/flatstrap.min.css b/OpenAntrag/Content/Plugins/flatstrap.min.css new file mode 100644 index 0000000..0b71aca --- /dev/null +++ b/OpenAntrag/Content/Plugins/flatstrap.min.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2)}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:gray}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'— '}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:' —'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15)}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,.8);outline:0;outline:thin dotted \9}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;border:1px solid #ccc;background-color:#fff}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;background-color:#fcfcfc;border-color:#ccc;cursor:not-allowed}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;vertical-align:middle;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#fff;background-color:#3498db}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#3498db}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:default}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px}.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px}.typeahead{z-index:1051;margin-top:2px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-large{padding:24px}.well-small{padding:9px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);background-color:#f5f5f5;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;*margin-left:.3em}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65)}.btn-large{padding:11px 19px;font-size:17.5px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#006dcc;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#faa732;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#da4f49;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#5bb75b;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#49afcd;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#363636;border-color:#222 #222 #000;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none}.btn-link{border-color:transparent;cursor:pointer;color:#08c}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn.large:first-child{margin-left:0}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px}.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px}.btn-group.open .dropdown-toggle{background-image:none}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%}.btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,.5);background-color:#fcf8e3;border:1px solid #fbeed5}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}.alert-success h4{color:#468847}.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-left:0;margin-bottom:20px;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255,255,255,.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav .dropdown-toggle .caret{border-top-color:#08c;border-bottom-color:#08c;margin-top:6px}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default}.navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2}.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;border:1px solid #d4d4d4;*zoom:1}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #fff}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1}.navbar-static-top{position:static;margin-bottom:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-bottom{bottom:0}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333;text-decoration:none}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#ededed;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:9px}.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);border-bottom:0;bottom:-7px;top:auto}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;border-color:#252525}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#fff}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-left-color:#111;border-right-color:#222}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111;color:#fff}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#0e0e0e;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;background-color:transparent;cursor:default}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:default}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.3);*border:1px solid #999;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none}.modal.fade{-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out;top:-25%}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c}.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#999}.badge{padding-left:9px;padding-right:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;}to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7}.progress .bar{width:0%;height:100%;color:#fff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,.25);background-color:#0e90d2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .bar{background-color:#149bdf;-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b}.progress-success .bar,.progress .bar-success{background-color:#5eb95e}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de}.progress-warning .bar,.progress .bar-warning{background-color:#faa732}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{overflow:hidden;width:100%;position:relative}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,.25)}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333;background:rgba(0,0,0,.75)}.carousel-caption h4,.carousel-caption p{color:#fff;line-height:20px}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/jqcloud.css b/OpenAntrag/Content/Plugins/jqcloud.css new file mode 100644 index 0000000..a3b3502 --- /dev/null +++ b/OpenAntrag/Content/Plugins/jqcloud.css @@ -0,0 +1,41 @@ + +div.jqcloud { + overflow: hidden; + position: relative; + font-family: 'PoliticsHeadBold', 'Helvetica Neue', 'Arial', Sans-Serif; + font-size: 10px; + line-height: normal; +} +div.jqcloud span { + padding: 0; +} +div.jqcloud a { + font-size: inherit; + text-decoration: none; +} + +div.jqcloud span.w10 { font-size: 400%; } +div.jqcloud span.w9 { font-size: 333%; } +div.jqcloud span.w8 { font-size: 300%; } +div.jqcloud span.w7 { font-size: 250%; } +div.jqcloud span.w6 { font-size: 225%; } +div.jqcloud span.w5 { font-size: 200%; } +div.jqcloud span.w4 { font-size: 175%; } +div.jqcloud span.w3 { font-size: 150%; } +div.jqcloud span.w2 { font-size: 125%; } +div.jqcloud span.w1 { font-size: 100%; } + +div.jqcloud { color: #333; } +div.jqcloud a { color: inherit; } +div.jqcloud a:hover { color: #ff8800 /*#3498DB*/; } +div.jqcloud a:hover { color: #ff8800 /*#3498DB*/; } +div.jqcloud span.w10 { color: #111; } +div.jqcloud span.w9 { color: #333; } +div.jqcloud span.w8 { color: #333; } +div.jqcloud span.w7 { color: #555; } +div.jqcloud span.w6 { color: #555; } +div.jqcloud span.w5 { color: #777; } +div.jqcloud span.w4 { color: #777; } +div.jqcloud span.w3 { color: #999; } +div.jqcloud span.w2 { color: #999; } +div.jqcloud span.w1 { color: #999; } diff --git a/OpenAntrag/Content/Plugins/jquery.jscrollpane.css b/OpenAntrag/Content/Plugins/jquery.jscrollpane.css new file mode 100644 index 0000000..a051cae --- /dev/null +++ b/OpenAntrag/Content/Plugins/jquery.jscrollpane.css @@ -0,0 +1,120 @@ +/* + * CSS Styles that are needed by jScrollPane for it to operate correctly. + * + * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane + * may not operate correctly without them. + */ + +.jspContainer +{ + overflow: hidden; + position: relative; +} + +.jspPane +{ + position: absolute; +} + +.jspVerticalBar +{ + position: absolute; + top: 0; + right: 0; + width: 16px; + height: 100%; + background: red; +} + +.jspHorizontalBar +{ + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 16px; + background: red; +} + +.jspVerticalBar *, +.jspHorizontalBar * +{ + margin: 0; + padding: 0; +} + +.jspCap +{ + display: none; +} + +.jspHorizontalBar .jspCap +{ + float: left; +} + +.jspTrack +{ + background: #dde; + position: relative; +} + +.jspDrag +{ + background: #bbd; + position: relative; + top: 0; + left: 0; + cursor: pointer; +} + +.jspHorizontalBar .jspTrack, +.jspHorizontalBar .jspDrag +{ + float: left; + height: 100%; +} + +.jspArrow +{ + background: #50506d; + text-indent: -20000px; + display: block; + cursor: pointer; +} + +.jspArrow.jspDisabled +{ + cursor: default; + background: #80808d; +} + +.jspVerticalBar .jspArrow +{ + height: 16px; +} + +.jspHorizontalBar .jspArrow +{ + width: 16px; + float: left; + height: 100%; +} + +.jspVerticalBar .jspArrow:focus +{ + outline: none; +} + +.jspCorner +{ + background: #eeeef4; + float: left; + height: 100%; +} + +/* Yuk! CSS Hack for IE6 3 pixel bug :( */ +* html .jspCorner +{ + margin: 0 -3px 0 0; +} \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.css b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.css new file mode 100644 index 0000000..b7c88cf --- /dev/null +++ b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.css @@ -0,0 +1,207 @@ +/* basic scrollbar styling */ +/* vertical scrollbar */ +.mCSB_container{ + width:auto; + margin-right:30px; + overflow:hidden; +} +.mCSB_container.mCS_no_scrollbar{ + margin-right:0; +} +.mCS_disabled>.mCustomScrollBox>.mCSB_container.mCS_no_scrollbar, +.mCS_destroyed>.mCustomScrollBox>.mCSB_container.mCS_no_scrollbar{ + margin-right:30px; +} +.mCustomScrollBox>.mCSB_scrollTools{ + width:16px; + height:100%; + top:0; + right:0; +} +.mCSB_scrollTools .mCSB_draggerContainer{ + position:absolute; + top:0; + left:0; + bottom:0; + right:0; + height:auto; +} +.mCSB_scrollTools a+.mCSB_draggerContainer{ + margin:20px 0; +} +.mCSB_scrollTools .mCSB_draggerRail{ + width:2px; + height:100%; + margin:0 auto; + -webkit-border-radius:10px; + -moz-border-radius:10px; + border-radius:10px; +} +.mCSB_scrollTools .mCSB_dragger{ + cursor:pointer; + width:100%; + height:30px; +} +.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:4px; + height:100%; + margin:0 auto; + -webkit-border-radius:10px; + -moz-border-radius:10px; + border-radius:10px; + text-align:center; +} +.mCSB_scrollTools .mCSB_buttonUp, +.mCSB_scrollTools .mCSB_buttonDown{ + display:block; + position:relative; + height:20px; + overflow:hidden; + margin:0 auto; + cursor:pointer; +} +.mCSB_scrollTools .mCSB_buttonDown{ + top:100%; + margin-top:-40px; +} +/* horizontal scrollbar */ +.mCSB_horizontal>.mCSB_container{ + height:auto; + margin-right:0; + margin-bottom:30px; + overflow:hidden; +} +.mCSB_horizontal>.mCSB_container.mCS_no_scrollbar{ + margin-bottom:0; +} +.mCS_disabled>.mCSB_horizontal>.mCSB_container.mCS_no_scrollbar, +.mCS_destroyed>.mCSB_horizontal>.mCSB_container.mCS_no_scrollbar{ + margin-right:0; + margin-bottom:30px; +} +.mCSB_horizontal.mCustomScrollBox>.mCSB_scrollTools{ + width:100%; + height:16px; + top:auto; + right:auto; + bottom:0; + left:0; + overflow:hidden; +} +.mCSB_horizontal>.mCSB_scrollTools a+.mCSB_draggerContainer{ + margin:0 20px; +} +.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:2px; + margin:7px 0; + -webkit-border-radius:10px; + -moz-border-radius:10px; + border-radius:10px; +} +.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger{ + width:30px; + height:100%; +} +.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:4px; + margin:6px auto; + -webkit-border-radius:10px; + -moz-border-radius:10px; + border-radius:10px; +} +.mCSB_horizontal>.mCSB_scrollTools .mCSB_buttonLeft, +.mCSB_horizontal>.mCSB_scrollTools .mCSB_buttonRight{ + display:block; + position:relative; + width:20px; + height:100%; + overflow:hidden; + margin:0 auto; + cursor:pointer; + float:left; +} +.mCSB_horizontal>.mCSB_scrollTools .mCSB_buttonRight{ + margin-left:-40px; + float:right; +} +.mCustomScrollBox{ + -ms-touch-action:none; /*MSPointer events - direct all pointer events to js*/ +} + +/* default scrollbar colors and backgrounds (default theme) */ +.mCustomScrollBox>.mCSB_scrollTools{ + opacity:0.75; + filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */ +} +.mCustomScrollBox:hover>.mCSB_scrollTools{ + opacity:1; + filter:"alpha(opacity=100)"; -ms-filter:"alpha(opacity=100)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_draggerRail{ + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.4); + filter:"alpha(opacity=40)"; -ms-filter:"alpha(opacity=40)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.75); + filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(255,255,255,0.85); + filter:"alpha(opacity=85)"; -ms-filter:"alpha(opacity=85)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(255,255,255,0.9); + filter:"alpha(opacity=90)"; -ms-filter:"alpha(opacity=90)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_buttonUp, +.mCSB_scrollTools .mCSB_buttonDown, +.mCSB_scrollTools .mCSB_buttonLeft, +.mCSB_scrollTools .mCSB_buttonRight{ + background-image:url(/images/mCSB_buttons.png); + background-repeat:no-repeat; + opacity:0.4; + filter:"alpha(opacity=40)"; -ms-filter:"alpha(opacity=40)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_buttonUp{ + background-position:0 0; + /* + sprites locations are 0 0/-16px 0/-32px 0/-48px 0 (light) and -80px 0/-96px 0/-112px 0/-128px 0 (dark) + */ +} +.mCSB_scrollTools .mCSB_buttonDown{ + background-position:0 -20px; + /* + sprites locations are 0 -20px/-16px -20px/-32px -20px/-48px -20px (light) and -80px -20px/-96px -20px/-112px -20px/-128px -20px (dark) + */ +} +.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:0 -40px; + /* + sprites locations are 0 -40px/-20px -40px/-40px -40px/-60px -40px (light) and -80px -40px/-100px -40px/-120px -40px/-140px -40px (dark) + */ +} +.mCSB_scrollTools .mCSB_buttonRight{ + background-position:0 -56px; + /* + sprites locations are 0 -56px/-20px -56px/-40px -56px/-60px -56px (light) and -80px -56px/-100px -56px/-120px -56px/-140px -56px (dark) + */ +} +.mCSB_scrollTools .mCSB_buttonUp:hover, +.mCSB_scrollTools .mCSB_buttonDown:hover, +.mCSB_scrollTools .mCSB_buttonLeft:hover, +.mCSB_scrollTools .mCSB_buttonRight:hover{ + opacity:0.75; + filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */ +} +.mCSB_scrollTools .mCSB_buttonUp:active, +.mCSB_scrollTools .mCSB_buttonDown:active, +.mCSB_scrollTools .mCSB_buttonLeft:active, +.mCSB_scrollTools .mCSB_buttonRight:active{ + opacity:0.9; + filter:"alpha(opacity=90)"; -ms-filter:"alpha(opacity=90)"; /* old ie */ +} diff --git a/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.openantrag.css b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.openantrag.css new file mode 100644 index 0000000..4d2e376 --- /dev/null +++ b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.openantrag.css @@ -0,0 +1,45 @@ +.mCS-openantrag>.mCSB_scrollTools .mCSB_draggerRail{ + width:4px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.1); +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:6px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.75); + -webkit-border-radius:0px; + -moz-border-radius:0px; + border-radius:0px; +} +.mCS-openantrag.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:4px; + margin:6px 0; + -webkit-border-radius:0px; + -moz-border-radius:0px; + border-radius:0px; +} +.mCS-openantrag.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:6px; + margin:5px auto; +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(255,255,255,0.85); +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-openantrag>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(255,255,255,0.9); +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-16px 0; +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-16px -20px; +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-20px -40px; +} +.mCS-openantrag>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-20px -56px; +} diff --git a/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.themes.css b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.themes.css new file mode 100644 index 0000000..6057226 --- /dev/null +++ b/OpenAntrag/Content/Plugins/jquery.mCustomScrollbar.themes.css @@ -0,0 +1,266 @@ +/*scrollbar themes*/ +/*dark (dark colored scrollbar)*/ +.mCS-dark>.mCSB_scrollTools .mCSB_draggerRail{ + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.15); +} +.mCS-dark>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.75); +} +.mCS-dark>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(0,0,0,0.85); +} +.mCS-dark>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-dark>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(0,0,0,0.9); +} +.mCS-dark>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-80px 0; +} +.mCS-dark>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-80px -20px; +} +.mCS-dark>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-80px -40px; +} +.mCS-dark>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-80px -56px; +} +/*light-2*/ +.mCS-light-2>.mCSB_scrollTools .mCSB_draggerRail{ + width:4px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.1); + -webkit-border-radius:1px; + -moz-border-radius:1px; + border-radius:1px; +} +.mCS-light-2>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:4px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.75); + -webkit-border-radius:1px; + -moz-border-radius:1px; + border-radius:1px; +} +.mCS-light-2.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:4px; + margin:6px 0; +} +.mCS-light-2.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:4px; + margin:6px auto; +} +.mCS-light-2>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(255,255,255,0.85); +} +.mCS-light-2>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-light-2>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(255,255,255,0.9); +} +.mCS-light-2>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-32px 0; +} +.mCS-light-2>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-32px -20px; +} +.mCS-light-2>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-40px -40px; +} +.mCS-light-2>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-40px -56px; +} +/*dark-2*/ +.mCS-dark-2>.mCSB_scrollTools .mCSB_draggerRail{ + width:4px; + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.1); + -webkit-border-radius:1px; + -moz-border-radius:1px; + border-radius:1px; +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:4px; + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.75); + -webkit-border-radius:1px; + -moz-border-radius:1px; + border-radius:1px; +} +.mCS-dark-2.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:4px; + margin:6px 0; +} +.mCS-dark-2.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:4px; + margin:6px auto; +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(0,0,0,0.85); +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-dark-2>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(0,0,0,0.9); +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-112px 0; +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-112px -20px; +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-120px -40px; +} +.mCS-dark-2>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-120px -56px; +} +/*light-thick*/ +.mCS-light-thick>.mCSB_scrollTools .mCSB_draggerRail{ + width:4px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.1); + -webkit-border-radius:2px; + -moz-border-radius:2px; + border-radius:2px; +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:6px; + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.75); + -webkit-border-radius:2px; + -moz-border-radius:2px; + border-radius:2px; +} +.mCS-light-thick.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:4px; + margin:6px 0; +} +.mCS-light-thick.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:6px; + margin:5px auto; +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(255,255,255,0.85); +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-light-thick>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(255,255,255,0.9); +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-16px 0; +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-16px -20px; +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-20px -40px; +} +.mCS-light-thick>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-20px -56px; +} +/*dark-thick*/ +.mCS-dark-thick>.mCSB_scrollTools .mCSB_draggerRail{ + width:4px; + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.1); + -webkit-border-radius:2px; + -moz-border-radius:2px; + border-radius:2px; +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:6px; + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.75); + -webkit-border-radius:2px; + -moz-border-radius:2px; + border-radius:2px; +} +.mCS-dark-thick.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; + height:4px; + margin:6px 0; +} +.mCS-dark-thick.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:6px; + margin:5px auto; +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(0,0,0,0.85); +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-dark-thick>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(0,0,0,0.9); +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-96px 0; +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-96px -20px; +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-100px -40px; +} +.mCS-dark-thick>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-100px -56px; +} +/*light-thin*/ +.mCS-light-thin>.mCSB_scrollTools .mCSB_draggerRail{ + background:#fff; /* rgba fallback */ + background:rgba(255,255,255,0.1); +} +.mCS-light-thin>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:2px; +} +.mCS-light-thin.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; +} +.mCS-light-thin.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:2px; + margin:7px auto; +} +/*dark-thin*/ +.mCS-dark-thin>.mCSB_scrollTools .mCSB_draggerRail{ + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.15); +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:2px; + background:#000; /* rgba fallback */ + background:rgba(0,0,0,0.75); +} +.mCS-dark-thin.mCSB_horizontal>.mCSB_scrollTools .mCSB_draggerRail{ + width:100%; +} +.mCS-dark-thin.mCSB_horizontal>.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width:100%; + height:2px; + margin:7px auto; +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background:rgba(0,0,0,0.85); +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, +.mCS-dark-thin>.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background:rgba(0,0,0,0.9); +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_buttonUp{ + background-position:-80px 0; +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_buttonDown{ + background-position:-80px -20px; +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_buttonLeft{ + background-position:-80px -40px; +} +.mCS-dark-thin>.mCSB_scrollTools .mCSB_buttonRight{ + background-position:-80px -56px; +} \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/selectize.css b/OpenAntrag/Content/Plugins/selectize.css new file mode 100644 index 0000000..7b34099 --- /dev/null +++ b/OpenAntrag/Content/Plugins/selectize.css @@ -0,0 +1,186 @@ +/********************************************************** + * THEME: "default" * + **********************************************************/ +.selectize-control.default.multi .selectize-input > div { + background-color: #ddd; + border: medium none; + color: #333; + margin-right: 10px; + padding: 5px 10px; +} +.selectize-control.default.multi .selectize-input > div:hover, +.selectize-control.default.multi .selectize-input > div.active, +.selectize-control.default.multi .selectize-dropdown .highlight, +.selectize-control.default.multi .selectize-dropdown > *.active { + background-color: #ddd; + color: #333; +} + +/********************************************************** + * BASIC AESTHETIC STYLES (common) * + **********************************************************/ +.selectize-input, .selectize-control.single .selectize-input.focus { + background: #fff; + padding: 10px; + cursor: text; + display: inline-block; + width: 100%; +} +.selectize-input.focus { +} +.selectize-input.dropdown-active { +} +.selectize-input.full { + background-color: #f4f4f4; +} +.selectize-input.dropdown-active::before { + content: ' '; + display: block; + position: absolute; + background: #f4f4f4; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} +.selectize-control.multi .selectize-input.has-items { + padding-top: 8px !important; + padding-bottom: 3px !important; +} +.selectize-control.multi .selectize-input > div { + cursor: pointer; + margin: 0 5px 5px 0; + padding: 1px 5px; + background-color: #333; + color: #fff; + border-style: solid; + border-width: 1px; + border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); +} +.selectize-input > div:last-child { + margin-right: 5px; +} +.selectize-input > input { + margin-right: 2px !important; +} +.selectize-dropdown, .selectize-input, .selectize-control.single .selectize-input.dropdown-active { + border: 1px solid rgba(0, 0, 0, 0.2); +} +.selectize-dropdown { + max-height: 200px; + overflow-y: auto; + overflow-x: hidden; + background: #fff; + margin-top: -1px; + border-top: 0 none; + -webkit-box-shadow: 2px 2px 12px -4px rgba(0, 0, 0, 0.5); + box-shadow: 2px 2px 12px -4px rgba(0, 0, 0, 0.5); +} +.selectize-dropdown > * { + padding: 4px 6px; +} +.selectize-dropdown > *.create { + color: #333; +} +.selectize-dropdown > *.active { + background-color: #333; + color: #fff; +} +.selectize-dropdown, +.selectize-input, +.selectize-input input { + color: #333; + font-family: Helvetica, arial, sans-serif; + font-size: 14px; + line-height: 20px; + -webkit-font-smoothing: antialiased; +} +.selectize-dropdown .highlight { + background: rgba(255, 237, 40, 0.4); +} + +/********************************************************** + * BASIC AESTHETIC STYLES (single) * + **********************************************************/ +.selectize-control.single .selectize-input { + cursor: pointer; + border-color: #b8b8b8; + background: #f6f6f6; +} + +.selectize-control.single .selectize-input::after { + content: ' '; + display: block; + position: absolute; + top: 50%; + right: 15px; + margin-top: -2px; + width: 0; + height: 0; + border-style: solid; + border-width: 5px 5px 0 5px; + border-color: #808080 transparent transparent transparent; +} + +.selectize-control.single .selectize-input.dropdown-active::after { + margin-top: -3px; + border-width: 0 5px 5px 5px; + border-color: transparent transparent #808080 transparent; +} + +/********************************************************** + * BASIC AESTHETIC STYLES (multi) * + **********************************************************/ + +/********************************************************** + * LAYOUT STYLES (mandatory) * + **********************************************************/ + +.selectize-control { + position: relative; +} +.selectize-input { + overflow: hidden; + position: relative; + z-index: 1; +} +.selectize-input:after { + content: ' '; + display: block; + clear: left; +} +.selectize-input .items { + display: inline; +} +.selectize-input > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; +} +.selectize-input > input { + max-width: 100% !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + padding: 0 !important; + margin: 0; + line-height: inherit !important; +} +.selectize-input > input:focus { + outline: none !important; +} +.selectize-dropdown { + position: absolute; + z-index: 2; +} +.selectize-dropdown > * { + cursor: pointer; + overflow: hidden; +} +.selectize-input, .selectize-dropdown { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} \ No newline at end of file diff --git a/OpenAntrag/Content/Plugins/tooltipster.css b/OpenAntrag/Content/Plugins/tooltipster.css new file mode 100644 index 0000000..985ff80 --- /dev/null +++ b/OpenAntrag/Content/Plugins/tooltipster.css @@ -0,0 +1,277 @@ +html { + -webkit-font-smoothing: antialiased; +} + + +/* This is the default Tooltipster theme (feel free to modify or duplicate and create multiple themes!): */ +.tooltipster-default { + border-radius: 5px; + border: 2px solid #000; + background: #4c4c4c; + color: #fff; +} + +/* Use this next selector to style things like font-size and line-height: */ +.tooltipster-default .tooltipster-content { + font-family: Arial, sans-serif; + font-size: 14px; + line-height: 16px; + padding: 8px 10px; + overflow: hidden; +} + +/* This next selector defines the color of the border on the outside of the arrow. This will automatically match the color and size of the border set on the main tooltip styles. Set display: none; if you would like a border around the tooltip but no border around the arrow */ +.tooltipster-default .tooltipster-arrow .tooltipster-arrow-border { + /* border-color: ... !important; */ +} + + +/* If you're using the icon option, use this next selector to style them */ +.tooltipster-icon { + cursor: help; + margin-left: 4px; +} + + + + + + + + +/* This is the base styling required to make all Tooltipsters work */ +.tooltipster-base { + padding: 0; + font-size: 0; + line-height: 0; + position: absolute; + z-index: 9999999; + pointer-events: none; + width: auto; + overflow: visible; +} +.tooltipster-base .tooltipster-content { + overflow: hidden; +} + + +/* These next classes handle the styles for the little arrow attached to the tooltip. By default, the arrow will inherit the same colors and border as what is set on the main tooltip itself. */ +.tooltipster-arrow { + display: block; + text-align: center; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: -1; +} +.tooltipster-arrow span, .tooltipster-arrow-border { + display: block; + width: 0; + height: 0; + position: absolute; +} +.tooltipster-arrow-top span, .tooltipster-arrow-top-right span, .tooltipster-arrow-top-left span { + border-left: 8px solid transparent !important; + border-right: 8px solid transparent !important; + border-top: 8px solid; + bottom: -8px; +} +.tooltipster-arrow-top .tooltipster-arrow-border, .tooltipster-arrow-top-right .tooltipster-arrow-border, .tooltipster-arrow-top-left .tooltipster-arrow-border { + border-left: 9px solid transparent !important; + border-right: 9px solid transparent !important; + border-top: 9px solid; + bottom: -8px; +} + +.tooltipster-arrow-bottom span, .tooltipster-arrow-bottom-right span, .tooltipster-arrow-bottom-left span { + border-left: 8px solid transparent !important; + border-right: 8px solid transparent !important; + border-bottom: 8px solid; + top: -8px; +} +.tooltipster-arrow-bottom .tooltipster-arrow-border, .tooltipster-arrow-bottom-right .tooltipster-arrow-border, .tooltipster-arrow-bottom-left .tooltipster-arrow-border { + border-left: 9px solid transparent !important; + border-right: 9px solid transparent !important; + border-bottom: 9px solid; + top: -8px; +} +.tooltipster-arrow-top span, .tooltipster-arrow-top .tooltipster-arrow-border, .tooltipster-arrow-bottom span, .tooltipster-arrow-bottom .tooltipster-arrow-border { + left: 0; + right: 0; + margin: 0 auto; +} +.tooltipster-arrow-top-left span, .tooltipster-arrow-bottom-left span { + left: 6px; +} +.tooltipster-arrow-top-left .tooltipster-arrow-border, .tooltipster-arrow-bottom-left .tooltipster-arrow-border { + left: 5px; +} +.tooltipster-arrow-top-right span, .tooltipster-arrow-bottom-right span { + right: 6px; +} +.tooltipster-arrow-top-right .tooltipster-arrow-border, .tooltipster-arrow-bottom-right .tooltipster-arrow-border { + right: 5px; +} +.tooltipster-arrow-left span, .tooltipster-arrow-left .tooltipster-arrow-border { + border-top: 8px solid transparent !important; + border-bottom: 8px solid transparent !important; + border-left: 8px solid; + top: 50%; + margin-top: -7px; + right: -8px; +} +.tooltipster-arrow-left .tooltipster-arrow-border { + border-top: 9px solid transparent !important; + border-bottom: 9px solid transparent !important; + border-left: 9px solid; + margin-top: -8px; +} +.tooltipster-arrow-right span, .tooltipster-arrow-right .tooltipster-arrow-border { + border-top: 8px solid transparent !important; + border-bottom: 8px solid transparent !important; + border-right: 8px solid; + top: 50%; + margin-top: -7px; + left: -8px; +} +.tooltipster-arrow-right .tooltipster-arrow-border { + border-top: 9px solid transparent !important; + border-bottom: 9px solid transparent !important; + border-right: 9px solid; + margin-top: -8px; +} + + +/* Some CSS magic for the awesome animations - feel free to make your own custom animations and reference it in your Tooltipster settings! */ + +.tooltipster-fade { + opacity: 0; + -webkit-transition-property: opacity; + -moz-transition-property: opacity; + -o-transition-property: opacity; + -ms-transition-property: opacity; + transition-property: opacity; +} +.tooltipster-fade-show { + opacity: 1; +} + +.tooltipster-grow { + -webkit-transform: scale(0,0); + -moz-transform: scale(0,0); + -o-transform: scale(0,0); + -ms-transform: scale(0,0); + transform: scale(0,0); + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + -o-transition-property: -o-transform; + -ms-transition-property: -ms-transform; + transition-property: transform; + -webkit-backface-visibility: hidden; +} +.tooltipster-grow-show { + -webkit-transform: scale(1,1); + -moz-transform: scale(1,1); + -o-transform: scale(1,1); + -ms-transform: scale(1,1); + transform: scale(1,1); + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); +} + +.tooltipster-swing { + opacity: 0; + -webkit-transform: rotateZ(4deg); + -moz-transform: rotateZ(4deg); + -o-transform: rotateZ(4deg); + -ms-transform: rotateZ(4deg); + transform: rotateZ(4deg); + -webkit-transition-property: -webkit-transform, opacity; + -moz-transition-property: -moz-transform; + -o-transition-property: -o-transform; + -ms-transition-property: -ms-transform; + transition-property: transform; +} +.tooltipster-swing-show { + opacity: 1; + -webkit-transform: rotateZ(0deg); + -moz-transform: rotateZ(0deg); + -o-transform: rotateZ(0deg); + -ms-transform: rotateZ(0deg); + transform: rotateZ(0deg); + -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 1); + -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); + -moz-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); + -ms-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); + -o-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); + transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); +} + +.tooltipster-fall { + top: 0; + -webkit-transition-property: top; + -moz-transition-property: top; + -o-transition-property: top; + -ms-transition-property: top; + transition-property: top; + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); +} +.tooltipster-fall-show { +} +.tooltipster-fall.tooltipster-dying { + -webkit-transition-property: all; + -moz-transition-property: all; + -o-transition-property: all; + -ms-transition-property: all; + transition-property: all; + top: 0px !important; + opacity: 0; +} + +.tooltipster-slide { + left: -40px; + -webkit-transition-property: left; + -moz-transition-property: left; + -o-transition-property: left; + -ms-transition-property: left; + transition-property: left; + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); + transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); +} +.tooltipster-slide.tooltipster-slide-show { +} +.tooltipster-slide.tooltipster-dying { + -webkit-transition-property: all; + -moz-transition-property: all; + -o-transition-property: all; + -ms-transition-property: all; + transition-property: all; + left: 0px !important; + opacity: 0; +} + + +/* CSS transition for when contenting is changing in a tooltip that is still open. The only properties that will NOT transition are: width, height, top, and left */ +.tooltipster-content-changing { + opacity: 0.5; + -webkit-transform: scale(1.1, 1.1); + -moz-transform: scale(1.1, 1.1); + -o-transform: scale(1.1, 1.1); + -ms-transform: scale(1.1, 1.1); + transform: scale(1.1, 1.1); +} \ No newline at end of file diff --git a/OpenAntrag/Content/Representations/testparlament/Info/fraktion.info b/OpenAntrag/Content/Representations/testparlament/Info/fraktion.info new file mode 100644 index 0000000..522a642 --- /dev/null +++ b/OpenAntrag/Content/Representations/testparlament/Info/fraktion.info @@ -0,0 +1 @@ +

\ No newline at end of file diff --git a/OpenAntrag/Content/Representations/testparlament/IntroBack/1200.jpg b/OpenAntrag/Content/Representations/testparlament/IntroBack/1200.jpg new file mode 100644 index 0000000..ff30c1c Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/IntroBack/1200.jpg differ diff --git a/OpenAntrag/Content/Representations/testparlament/IntroBack/770.jpg b/OpenAntrag/Content/Representations/testparlament/IntroBack/770.jpg new file mode 100644 index 0000000..da8c588 Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/IntroBack/770.jpg differ diff --git a/OpenAntrag/Content/Representations/testparlament/IntroBack/980.jpg b/OpenAntrag/Content/Representations/testparlament/IntroBack/980.jpg new file mode 100644 index 0000000..8e93437 Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/IntroBack/980.jpg differ diff --git a/OpenAntrag/Content/Representations/testparlament/IntroBack/full.jpg b/OpenAntrag/Content/Representations/testparlament/IntroBack/full.jpg new file mode 100644 index 0000000..66473a6 Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/IntroBack/full.jpg differ diff --git a/OpenAntrag/Content/Representations/testparlament/Portraits/hans-mustermann.png b/OpenAntrag/Content/Representations/testparlament/Portraits/hans-mustermann.png new file mode 100644 index 0000000..fd1a5e1 Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/Portraits/hans-mustermann.png differ diff --git a/OpenAntrag/Content/Representations/testparlament/banner-160x220.png b/OpenAntrag/Content/Representations/testparlament/banner-160x220.png new file mode 100644 index 0000000..9972afd Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/banner-160x220.png differ diff --git a/OpenAntrag/Content/Representations/testparlament/banner-275x80.png b/OpenAntrag/Content/Representations/testparlament/banner-275x80.png new file mode 100644 index 0000000..bbe7609 Binary files /dev/null and b/OpenAntrag/Content/Representations/testparlament/banner-275x80.png differ diff --git a/OpenAntrag/Content/Representations/testparlament/style-testparlament.css b/OpenAntrag/Content/Representations/testparlament/style-testparlament.css new file mode 100644 index 0000000..9212b3d --- /dev/null +++ b/OpenAntrag/Content/Representations/testparlament/style-testparlament.css @@ -0,0 +1,5 @@ +.fotoby:before { + content: "CC-BY-SA 3.0, Kristof Zerbe"; + background-color: rgba(255, 255, 255, 0.3) !important; + color: rgba(0, 0, 0, 0.75) !important; +} diff --git a/OpenAntrag/Content/api.css b/OpenAntrag/Content/api.css new file mode 100644 index 0000000..e3f5127 --- /dev/null +++ b/OpenAntrag/Content/api.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/api-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/api-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/api-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/api-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/domain.css b/OpenAntrag/Content/domain.css new file mode 100644 index 0000000..c1316c5 --- /dev/null +++ b/OpenAntrag/Content/domain.css @@ -0,0 +1,17 @@ +span.highlight2 { color: #ff8800; } +#topbar { background-color: #ff8800; } +#topbar div.left { background-color: #ff8800; } +header div.main h2 a:hover { color: #ff8800; } +header div.main h2 a:hover .caret { border-top-color: #ff8800 !important; } +#headnav #country-headnav a.selected { color: #ff8800; } +footer { background-color: #FF8800; } +footer #footer-commands > a { background-color: #FF8800; } +a#backtop { background-color: #ff8800; } + +footer div.left { background-color: #FFA948; } +footer div.right { background-color: #FFA948; } +footer #footer-commands > a:hover { background-color: #FFA948; } + +div.content-info .btn-group-invers > .btn-primary { + background-color: #ff8800; +} diff --git a/OpenAntrag/Content/error.css b/OpenAntrag/Content/error.css new file mode 100644 index 0000000..56dc800 --- /dev/null +++ b/OpenAntrag/Content/error.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/error-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/error-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/error-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/error-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/faq.css b/OpenAntrag/Content/faq.css new file mode 100644 index 0000000..7e02ce4 --- /dev/null +++ b/OpenAntrag/Content/faq.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/faq-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/faq-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/faq-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/faq-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/feedback.css b/OpenAntrag/Content/feedback.css new file mode 100644 index 0000000..f947a21 --- /dev/null +++ b/OpenAntrag/Content/feedback.css @@ -0,0 +1,62 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/feedback-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/feedback-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/feedback-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/feedback-770.jpg') no-repeat right center; + } +} + +#body div.content div.feedbackbox { + position: relative; +} +#body div.content div.feedbackbox > i { + display: block; + left: 0; + top: 0; + position: absolute; + margin: 0px 20px 20px 0px; + font-size: 50px; +} +#body div.content div.feedbackbox div.feedback { + padding-left: 75px; +} +#body div.content div.feedbackbox div.feedback h4 { + line-height: 18px; +} +#body div.content div.feedbackbox div.feedback p { + margin: 0 0 5px; +} +#fbt-filter { + margin-top: 10px; + display:inline-block; +} +#fbt-filter a.cmd-filter.fbt-type-all { color: #333333; border-color: #333333; } +#fbt-filter a.cmd-filter.fbt-type-0 { color: #2D76AA; border-color: #2D76AA; } +#fbt-filter a.cmd-filter.fbt-type-1 { color: #E47900; border-color: #E47900; } +#fbt-filter a.cmd-filter.fbt-type-2 { color: #B80000; border-color: #B80000; } + +#fbt-filter a.cmd-filter.fbt-type-all.selected, +#fbt-filter a.cmd-filter.fbt-type-all:hover { background-color: #333333; } +#fbt-filter a.cmd-filter.fbt-type-0.selected, +#fbt-filter a.cmd-filter.fbt-type-0:hover { background-color: #2D76AA; } +#fbt-filter a.cmd-filter.fbt-type-1.selected, +#fbt-filter a.cmd-filter.fbt-type-1:hover { background-color: #E47900; } +#fbt-filter a.cmd-filter.fbt-type-2.selected, +#fbt-filter a.cmd-filter.fbt-type-2:hover { background-color: #B80000; } diff --git a/OpenAntrag/Content/home.css b/OpenAntrag/Content/home.css new file mode 100644 index 0000000..62d09e1 --- /dev/null +++ b/OpenAntrag/Content/home.css @@ -0,0 +1,200 @@ + +#body table#workflow-schema th, +#body table#workflow-schema td { + text-align: center; + line-height: 16px; + height: 50px; + padding: 0; +} +#body table#workflow-schema th { + min-height: 80px; + padding: 10px; + width: 80px; +} +#body table#workflow-schema th span { + color: white; + white-space: pre-wrap; +} +#body table#workflow-schema th.wf1 { background-color: #AAAAAA; } +#body table#workflow-schema th.wf2 { background-color: #F2C900; } +#body table#workflow-schema th.wf3 { background-color: #D63333; } +#body table#workflow-schema th.wf4 { background-color: #FF8800; } +#body table#workflow-schema th.wf5 { background-color: #2D9D24; } +#body table#workflow-schema th.wf6 { background-color: #076FDC; } +#body table#workflow-schema th.wf7 { background-color: #3498DB; } +#body table#workflow-schema th.wf8 { background-color: #6456D5; } +#body table#workflow-schema th.wf9 { background-color: #333333; } + +#body div.content div.fraktionbox { + background-color: #fff; + margin-bottom: 15px; + position: relative; + overflow: hidden; +} +#body div.content div.fraktionbox > a { + display: block; + position: absolute; + padding: 10px 8px 0; + height: 100%; + float: left; + text-decoration: none; +} +#body div.content div.fraktionbox > a:hover { + background-color: #444 !important; +} +#body div.content div.fraktionbox > a > i { + font-size: 20px; + color: #fff; + text-decoration: none; +} +#body div.content div.fraktionbox div { + padding: 10px 5px 10px 45px; +} +#body div.content div.fraktionbox div small { + color: #aaa; + font-size: 12px; +} +#body div.content div.fraktionbox div a.rep-name { + text-decoration: none; +} +#body div.content div.fraktionbox div a.rep-name h4 { + line-height: 20px; + margin: 0 0 5px; + -ms-word-wrap: break-word; + word-wrap: break-word; + color: #333; +} +#body div.content div.fraktionbox div a.rep-name.ended h4, +#body div.content div.fraktionbox div em.group-name.ended { + text-decoration: line-through; +} +#body div.content div.fraktionbox div em { + display: block; +} +#body div.content div.fraktionbox div img { + float: right; + height: 60px; + padding: 10px; +} +#body div.content div#pm-container .pm-item { + background-color: #fff; + border-left: 10px solid #ddd; + display: inline-block; + margin: 2px 0; + padding: 4px 6px; + text-decoration: none; +} +#body div.content div#pm-container a.pm-item:hover { + background-color: #333; + color: #fff; +} +#body div.content div#rv-container a { + display: block; + float: left; + width: 80px; + height: 80px; + background-position: center center; + background-repeat: no-repeat; + -ms-background-size: 10px; + background-size: 90px; + border: 5px transparent solid; + -moz-transition: a 0.3s ease-in; + -webkit-transition: a 0.3s ease-in; + -o-transition: a 0.3s ease-in; + transition: all 0.3s ease-in; +} + +#body div.content div#rv-container a:hover { + -ms-background-size: 100px; + background-size: 100px; + border: 5px #ff8800 solid; + -webkit-box-shadow: inset 0 0 5px #333; + -ms-box-shadow: inset 0 0 5px #333; + box-shadow: inset 0 0 5px #333; +} + +#mapD { + width: 200px; + height: 271px; + position: relative; + background: url(/Images/Map/200-DE-white.png) no-repeat center center; +} +#mapD > a { + position: absolute; + top: 0; + left: -1000px; + opacity: 0; + z-index: 0; + -moz-transition: opacity 0.3s ease-in; + -webkit-transition: opacity 0.3s ease-in; + -o-transition: opacity 0.3s ease-in; + transition: opacity 0.3s ease-in; +} + +#mapD > a:hover { + opacity: 1 !important; +} +#mapD > a.active { opacity: 0.25; } +#mapD > a.inactive:hover { opacity: 0.25 !important; } + +#mapD a#mapBW { left: 33px; top: 183px; z-index: 1; } +#mapD a#mapBY { left: 68px; top: 157px; } +#mapD a#mapBE { left: 156px; top: 76px; z-index: 1; } +#mapD a#mapBB { left: 117px; top: 51px; } +#mapD a#mapHB { left: 59px; top: 51px; z-index: 1; } +#mapD a#mapHH { left: 85px; top: 42px; z-index: 1; } +#mapD a#mapHE { left: 41px; top: 119px; z-index: 1; } +#mapD a#mapMV { left: 102px; top: 13px; } +#mapD a#mapNI { left: 21px; top: 41px; } +#mapD a#mapNW { left: 0; top: 88px; } +#mapD a#mapRP { left: 5px; top: 143px; } +#mapD a#mapSL { left: 9px; top: 186px; } +#mapD a#mapSN { left: 132px; top: 117px; z-index: 1; } +#mapD a#mapST { left: 103px; top: 70px; } +#mapD a#mapSH { left: 48px; top: 1px; } +#mapD a#mapTH { left: 88px; top: 119px; } + +#mapD div#mapInfo { + color: #333333; + font-family: verdana; + left: 160px; + line-height: 16px; + position: absolute; + text-align: left; + top: 160px; + width: 220px; +} + +/* http://solemone.de/demos/fullsize-background-image-with-css3-background-size/ */ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/home-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/home-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #body table#workflow-schema th { padding: 4px; } + #body table#workflow-schema th span { font-size: 0.75em; } + #body table#workflow-schema td { line-height: 12px; } + #body table#workflow-schema td img { height: 50%; } + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/home-980.jpg') no-repeat right center; /*... / cover*/ + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/home-770.jpg') no-repeat right center; + } + #body table#workflow-schema th { padding: 4px; } + #body table#workflow-schema th span { font-size: 0.75em; } + #body table#workflow-schema td { line-height: 12px; } + #body table#workflow-schema td img { height: 50%; } +} \ No newline at end of file diff --git a/OpenAntrag/Content/list.css b/OpenAntrag/Content/list.css new file mode 100644 index 0000000..e87e01a --- /dev/null +++ b/OpenAntrag/Content/list.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/list-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/list-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/list-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/list-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/notifications.css b/OpenAntrag/Content/notifications.css new file mode 100644 index 0000000..8899a92 --- /dev/null +++ b/OpenAntrag/Content/notifications.css @@ -0,0 +1,107 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/notification-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/notification-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/notification-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/notification-770.jpg') no-repeat right center; + } +} + +#nf-wrapper { + position: relative; + margin-top: -30px; +} +#nf-list { + position: relative; + list-style-type: none; + margin: 0; + padding: 0; +} +#nf-list li { + list-style-type: none; + background-color: #f8f8f8; + display: none; + padding: 20px; + width: 250px; + border-top-width: 25px; + border-top-style: solid; +} +#nf-list li em { + color: #FFFFFF; + display: block; + font-size: 12px; + font-style: normal; + margin-bottom: 10px; + margin-left: -12px; + margin-top: -42px; +} +#nf-list li small { + display: inline-block; + margin-bottom: 0; + font-style: italic; +} +#nf-list li > a { + text-decoration: none; + color: #333; +} +#nf-list li > a:hover { + text-decoration: underline; +} +#nf-list li h4 { + padding: 0; + line-height: 18px; +} +#nf-list li strong { + display: inline-block; + line-height: 16px; +} +#nf-list li p { + margin-top: 10px; + margin-bottom: 0; +} + +#nf-filter { + margin-top: 10px; + display:inline-block; +} +#nf-filter a.cmd-filter.nf-type-all { color: #333333; border-color: #333333; } +#nf-filter a.cmd-filter.nf-type-0 { color: #B80000; border-color: #B80000; } +#nf-filter a.cmd-filter.nf-type-1 { color: #E47900; border-color: #E47900; } +#nf-filter a.cmd-filter.nf-type-2 { color: #CB7311; border-color: #CB7311; } +#nf-filter a.cmd-filter.nf-type-3 { color: #3498DB; border-color: #3498DB; } +#nf-filter a.cmd-filter.nf-type-4 { color: #2D76AA; border-color: #2D76AA; } +#nf-filter a.cmd-filter.nf-type-5 { color: #666666; border-color: #666666; } +#nf-filter a.cmd-filter.nf-type-6 { color: #1C8E31; border-color: #1C8E31; } + +#nf-filter a.cmd-filter.nf-type-all.selected, +#nf-filter a.cmd-filter.nf-type-all:hover { background-color: #333333; } +#nf-filter a.cmd-filter.nf-type-0.selected, +#nf-filter a.cmd-filter.nf-type-0:hover { background-color: #B80000; } +#nf-filter a.cmd-filter.nf-type-1.selected, +#nf-filter a.cmd-filter.nf-type-1:hover { background-color: #E47900; } +#nf-filter a.cmd-filter.nf-type-2.selected, +#nf-filter a.cmd-filter.nf-type-2:hover { background-color: #CB7311; } +#nf-filter a.cmd-filter.nf-type-3.selected, +#nf-filter a.cmd-filter.nf-type-3:hover { background-color: #3498DB; } +#nf-filter a.cmd-filter.nf-type-4.selected, +#nf-filter a.cmd-filter.nf-type-4:hover { background-color: #2D76AA; } +#nf-filter a.cmd-filter.nf-type-5.selected, +#nf-filter a.cmd-filter.nf-type-5:hover { background-color: #666666; } +#nf-filter a.cmd-filter.nf-type-6.selected, +#nf-filter a.cmd-filter.nf-type-6:hover { background-color: #1C8E31; } diff --git a/OpenAntrag/Content/proposal.css b/OpenAntrag/Content/proposal.css new file mode 100644 index 0000000..cb7cf66 --- /dev/null +++ b/OpenAntrag/Content/proposal.css @@ -0,0 +1,96 @@ +.proposal-head { + margin: 0 0 25px 80px; +} +.proposal-body h1, +.proposal-body h2, +.proposal-body h3, +.proposal-body h4, +.proposal-body h5, +.proposalstep-body h1, +.proposalstep-body h2, +.proposalstep-body h3, +.proposalstep-body h4, +.proposalstep-body h5 { + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.proposal-body h1, .proposalstep-body h1 { font-size: 22px; } +.proposal-body h2, .proposalstep-body h2 { font-size: 20px; } +.proposal-body h3, .proposalstep-body h3 { font-size: 18px; } +.proposal-body h4, .proposalstep-body h4 { font-size: 16px; } +.proposal-body h5, .proposalstep-body h5 { font-size: 14px; } + +div#mdd-editor-editproposal textarea, +div#mdd-editor-blockabuse textarea, +div#mdd-editor-newsuccessstory textarea{ + display: block; + width: 100%; +} +i.proposal-step-icon { + position: relative; +} +i.proposal-step-icon > i { + position: absolute; + left: -10px; + top: 35px; + color: #fff; + font-size: 2.2rem; +} +.proposalstep-item { + position: relative; +} +.proposalstep-item > span.bar { + color: #FFFFFF; + display: block; + float: left; + height: 100%; + margin-top: -5px; + padding: 10px 0 0; + min-width: 28px; + position: absolute; + text-decoration: none; +} +.proposalstep-item > div.proposalstep-body { + margin-left: 50px; +} +.proposalstep-item > div.proposalstep-body > img { + float: left; + margin-right: 15px; + width: 32px; +} +.proposalstep-item > div.proposalstep-body > small { + display: block; +} +.proposalstep-item > div.proposalstep-body > em { + display: block; + font-size: 14px; + font-weight: bold; + margin-top: 10px; +} +.proposalstep-item > div.proposalstep-body > div.info, +.proposalstep-item > div.proposalstep-body > div.info-edit { + margin-top: 20px; +} +.nextstep-item { + color: #fff !important; + font-weight: bold; + padding: 10px 15px; +} +a.nextstep-item { + display: block; + text-decoration: none; + -moz-transition: none; + -o-transition: none; + -webkit-transition: none; + transition: none; +} +#nextstep-info, +#nextstep-body > em { + font-size: 120%; +} +#nextstep-body > em > select { + margin: 0; +} +#nextstep-body > small, +#nextstep-body textarea { + font-size: 100%; +} \ No newline at end of file diff --git a/OpenAntrag/Content/representation.css b/OpenAntrag/Content/representation.css new file mode 100644 index 0000000..b55048a --- /dev/null +++ b/OpenAntrag/Content/representation.css @@ -0,0 +1,157 @@ +#body ul.schema-info { + margin: 0px; + overflow: hidden; +} +#body ul.schema-info > li { + list-style: none outside none; + border: none; +} +#body ul.schema-info > li > span { + display: inline-block; + width: 100%; + padding: 5px 0 5px 10px; +} +#body ul.schema-info > li > ul { + margin: 0 0 0 15px; +} +#body ul.schema-info > li > ul li { + list-style: none outside none; + margin: 0px; + clear: both; +} +#body ul.schema-info > li > ul li > i { + float: left; + font-size: 30px; + color: #fff !important; + margin-left: 0px; +} +#body ul.schema-info > li > ul li > span { + padding: 5px 0px 5px 10px; + display: inline-block; +} +#body ul.schema-info li span { + color: #fff; +} +#body ul.schema-info > li > span > strong, +#body ul.schema-info > li > ul li > span > strong { + padding: 0px 10px 0px 0px; +} +#body div#new-proposal input, +#body div#new-proposal textarea { + display: block; + /*width: calc(100% - 15px);*/ + width: 95%; +} +#journal-container .box-head { + position: relative; +} +#journal-container .box-head span.page-number { + color: #eee; + display: inline-block; + font-size: 34px; + font-weight: bold; + left: 336px; + position: absolute; + top: 28px; +} +#representation div.comm p { + font-size: 14px; + margin-bottom: 2px; +} +div.representative { + background-color: #f4f4f4; + clear: both; + margin-bottom: 10px; + margin-left: 0; + margin-right: -5px; + overflow: auto; + padding: 0 10px 0 0; +} +div.representative img { + float: left; + width: 90px; + margin-right: 10px; +} +div.representative > div { + margin-top: -4px; +} +div.representative > div h5 { + margin-bottom: 0; +} +div.representative > div span { + display: block; + margin-bottom: 8px; + -ms-word-wrap: break-word; + word-wrap: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + -ms-hyphens: auto; + -o-hyphens: auto; + hyphens: auto; +} +div.representative div.comm { + margin-top: 2px; +} +div.representative div.comm a { + display: block; + line-height: 14px; + margin-top: 4px; + -ms-word-wrap: break-word; + word-wrap: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + -ms-hyphens: auto; + -o-hyphens: auto; + hyphens: auto; + font-size: 12px; +} +div.representative div.comm a i { + margin-right: 5px; + font-style: normal; +} +div.representative div.comm a i[class^="icon-"]:before, +div.representative div.comm a i[class*=" icon-"]:before { + margin-left: 2px !important; + margin-right: 8px !important; + color: #333; +} +div.piratenmandate { + position: relative; + background-color: #f4f4f4; + padding: 15px 5px 10px; + margin-top: 20px; + margin-bottom: 20px; + overflow: hidden; +} +div.piratenmandate > a img { + height: 50px +} +div.piratenmandate > div { + margin: 15px 10px 0 15px; +} +div.piratenmandate div.links { + margin-top: 20px; + margin-bottom: 20px; +} +div.piratenmandate div.links a { + display: block; + margin-bottom: 10px; + margin-right: 0; +} +div.piratenmandate > i.icon-network { + color: #fff; + font-size: 75px; + position: absolute; + right: -20px; + top: -20px; +} +/*div.piratenmandate > div.triangle { + position: absolute; + top: -15px; + right: 10px; + width: 0; + height: 0; + border-style: solid; + border-width: 25px 25px 0 25px; + border-color: #fff transparent transparent transparent; +}*/ diff --git a/OpenAntrag/Content/search.css b/OpenAntrag/Content/search.css new file mode 100644 index 0000000..3fba018 --- /dev/null +++ b/OpenAntrag/Content/search.css @@ -0,0 +1,29 @@ +#body input#SearchTerms { + display: block; + /*width: calc(100% - 15px);*/ + width: 95%; +} +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/search-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/search-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/search-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/search-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/statistics.css b/OpenAntrag/Content/statistics.css new file mode 100644 index 0000000..8649e9a --- /dev/null +++ b/OpenAntrag/Content/statistics.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/statistics-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/statistics-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/statistics-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/statistics-770.jpg') no-repeat right center; + } +} diff --git a/OpenAntrag/Content/style-allrepresentations.template.css b/OpenAntrag/Content/style-allrepresentations.template.css new file mode 100644 index 0000000..22f7afa --- /dev/null +++ b/OpenAntrag/Content/style-allrepresentations.template.css @@ -0,0 +1,20 @@ +#mainsubnav-rep #mainsubnav-rep-list a.rid[ID]:hover, +#mainsubnav-rep #mainsubnav-rep-list a.rid[ID]:focus { + background-color: [COLOR] !important; +} +#body div.content div.fraktionbox.rid[ID] > a.rbar, +#body div.content div.success-item.rid[ID] > a.btn { + background-color: [COLOR]; color: #fff; +} +#body div.content div.success-item.rid[ID] > a.btn:hover { + background-color: [COLORBRIGHT]; +} +table tr.rid[ID] a, +#body div.content div.fraktionbox.rid[ID] a, +#body div.content div.rid[ID] div.proposal-body a, +#body div.content div.rid[ID] .sublinks a { + color: [COLORTEXT]; +} +#mainsubnav-rep #mainsubnav-rep-list a.rid[ID] { + border-color: [COLOR]; +} diff --git a/OpenAntrag/Content/style-representation.template.css b/OpenAntrag/Content/style-representation.template.css new file mode 100644 index 0000000..231cf35 --- /dev/null +++ b/OpenAntrag/Content/style-representation.template.css @@ -0,0 +1,71 @@ +/* CUSTOM-COLOR */ +#repnav, +#repnav a, +.content-representation .btn-primary, +#body div.content-edit, +.btn-represenation, +.btn-text:hover { + background-color: [COLOR]; color: #FFFFFF; +} +a.nextstep-item:hover, +.pagination ul > li.active > span, +.tooltipster-repnav { + background-color: [COLOR] !important; color: #FFFFFF !important; +} +#body div.content-info a { + color: [COLORBRIGHT] !important; +} +#body div.content-representation a:not(.btn), +.btn-text { + color: [COLORTEXT]; +} +a.nextstep-item.arrow-down:hover:after, +a.nextstep-item.arrow-down:hover:before { + border-top-color: [COLOR]; +} +.pagination ul > li > a:hover, +.dropdown-menu > li > a:hover, +.dropdown-submenu:hover > a, +.selectize-control.default.multi .selectize-input > div:hover, +.selectize-control.default.multi .selectize-input > div.active, +.selectize-control.default.multi .selectize-dropdown .highlight, +.selectize-control.default.multi .selectize-dropdown > *.active, +.btn-represenation:hover, +.btn-represenation:focus { + background-color: [COLORBRIGHT]; color: #FFFFFF; +} +.content-representation .btn-primary:hover, +.content-representation .btn-primary:active, +.content-representation .btn-primary.active, +.btn-inverse:hover, +.content-edit .btn-primary:hover, +#repnav div.main a:hover, +.pagination ul > li.dir > a:hover, +.pagination ul > li > a:hover { + background-color: [COLORBRIGHT] !important; color: #FFFFFF; +} +/* ---------- */ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Content/Representations/[KEY]/IntroBack/full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Content/Representations/[KEY]/IntroBack/1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Content/Representations/[KEY]/IntroBack/980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Content/Representations/[KEY]/IntroBack/770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/style-teaser.template.css b/OpenAntrag/Content/style-teaser.template.css new file mode 100644 index 0000000..be3d93d --- /dev/null +++ b/OpenAntrag/Content/style-teaser.template.css @@ -0,0 +1,69 @@ +/* CUSTOM-COLOR */ +#repnav, +#repnav a, +.content-teaser .btn-primary, +#body div.content-edit, +.btn-represenation { + background-color: [COLOR]; color: #FFFFFF; +} +a.nextstep-item:hover, +.pagination ul > li.active > span, +.tooltipster-repnav { + background-color: [COLOR] !important; color: #FFFFFF !important; +} +#body div.content-info a { + color: [COLORBRIGHT] !important; +} +#body div.content-teaser a:not(.btn) { + color: [COLORTEXT]; +} +a.nextstep-item.arrow-down:hover:after, +a.nextstep-item.arrow-down:hover:before { + border-top-color: [COLOR]; +} +.pagination ul > li > a:hover, +.dropdown-menu > li > a:hover, +.dropdown-submenu:hover > a, +.selectize-control.default.multi .selectize-input > div:hover, +.selectize-control.default.multi .selectize-input > div.active, +.selectize-control.default.multi .selectize-dropdown .highlight, +.selectize-control.default.multi .selectize-dropdown > *.active, +.btn-represenation:hover, +.btn-represenation:focus { + background-color: [COLORBRIGHT]; color: #FFFFFF; +} +.content-teaser .btn-primary:hover, +.content-teaser .btn-primary:active, +.content-teaser .btn-primary.active, +.btn-inverse:hover, +.content-edit .btn-primary:hover, +#repnav div.main a:hover, +.pagination ul > li.dir > a:hover, +.pagination ul > li > a:hover { + background-color: [COLORBRIGHT] !important; color: #FFFFFF; +} +/* ---------- */ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Content/Teaser/[KEY]/IntroBack/full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Content/Teaser/[KEY]/IntroBack/1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Content/Teaser/[KEY]/IntroBack/980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Content/Teaser/[KEY]/IntroBack/770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/style.css b/OpenAntrag/Content/style.css new file mode 100644 index 0000000..2f5173a --- /dev/null +++ b/OpenAntrag/Content/style.css @@ -0,0 +1,1686 @@ +@font-face { + font-family: "PoliticsHeadBold"; + font-style: normal; + font-weight: normal; + src: url("/Fonts/PoliticsHeadBold.woff") format("woff"); +} +@font-face { + font-family: 'BebasNeue'; + src: url('/Fonts/BebasNeue-webfont.eot'); + src: url('/Fonts/BebasNeue-webfont.eot?#iefix') format('embedded-opentype'), + url('/Fonts/BebasNeue-webfont.woff') format('woff'), + url('/Fonts/BebasNeue-webfont.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} +[class^="icon-"]:before, [class*=" icon-"]:before { + margin: 0 !important; + width: auto; +} +html, body { + height: 100%; +} +body { + padding: 0 !important; +} +form, +.pagination { + margin: 0; +} +#wrapper { + height: auto; + min-height: 100%; + margin: 0 auto 0; +} +h1, h2, h3, h4 { + font-family: 'PoliticsHeadBold','Helvetica Neue','Arial',Sans-Serif; + font-weight: 400; + margin: 10px 0; + line-height: 30px; +} +span.dimlight { color: #aaa; } +span.highlight { color: #ff8800 /*#3498DB*/; } +span.highlight-red { color: #D63333; } +span.highlight-green { color: #028C00; } + +.small { + font-size: 85%; +} +span.code { + font-family: Monaco,Menlo,Consolas,"Courier New",monospace; + font-weight: bold; +} +span.code, code { font-size: 14px; } +code { padding: 0 4px;} + +.markdown-text h1, +.markdown-text h2, +.markdown-text h3, +.markdown-text h4 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; +} +.markdown-text h1 { font-size: 24px; font-weight: bold; } +.markdown-text h2 { font-size: 20px; } +.markdown-text h3 { font-size: 18px; } +.markdown-text h4 { font-size: 16px; font-weight: bold; } + +video { + width: 100% !important; + height: auto !important; +} + +.caret { + border-left: 5px solid rgba(0, 0, 0, 0); + border-right: 5px solid rgba(0, 0, 0, 0); + border-top: 5px solid #000; + vertical-align: middle; + margin-left: 5px; +} + +ul li { + list-style-type: square; +} +li { + margin-bottom: 10px; +} +ul.tight li { + margin-bottom: 5px; + line-height: 18px; +} +ul.sublinks { + font-size: 85%; + margin: 0; +} +ul.sublinks li { + list-style-type: none; + margin: 5px 15px 0 0; + display:inline-block; +} +ul.sublinks li em { + opacity: 0.5; +} +ul.sublinks div.rating-group { + display: inline; + font-size: 120%; + margin-left: 3px; +} +hr { + background: url("/Images/hr.png") no-repeat scroll 50% -12px transparent; + height: 10px; + margin: 0; +} +a { + -moz-transition: background-color 0.3s ease-out, border-color 0.3s ease-out; + -webkit-transition: background-color 0.3s ease-out, border-color 0.3s ease-out; + -o-transition: background-color 0.3s ease-out, border-color 0.3s ease-out; + transition: background-color 0.3s ease-out, border-color 0.3s ease-out; + color: #DD7500 /*#3498DB*/; +} +a:hover { + -moz-transition: background-color 0.3s ease-in, border-color 0.3s ease-in; + -webkit-transition: background-color 0.3s ease-in, border-color 0.3s ease-in; + -o-transition: background-color 0.3s ease-in, border-color 0.3s ease-in; + transition: background-color 0.3s ease-in, border-color 0.3s ease-in; + color: #DD7500; +} +a:active, a:focus, :focus { outline: none; } +:focus, :active { outline:none; } +::-moz-focus-inner { border:0; } + +a.hash { + border-bottom: 1px dashed #333333; + color: #333333; + text-decoration: none; +} +a.hash:hover { + border-bottom: 1px solid #333333; +} +a.more { + display: block; + background-color: #f8f8f8; + padding: 20px 0; + text-align: center; + width: 100%; + margin: 0; + color: #333; + text-decoration: none; +} +a.more:hover { + background-color: #333; + color: #f8f8f8; +} +button::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + border: none; +} +.input-append { margin-bottom: 0 !important; } + +.btn, +.input-append .add-on { + background-color: #f4f4f4; + -moz-transition: background-color 0.3s ease-out; + -webkit-transition: background-color 0.3s ease-out; + -o-transition: background-color 0.3s ease-out; + transition: background-color 0.3s ease-out; +} +.btn { + border: medium none; + font-size: 16px; + line-height: 18px; + padding: 12px 15px; + -webkit-text-shadow: none; + text-shadow: none; + margin-right: 5px; +} +.btn:hover, +.input-append .add-on:hover { + /*background-color: #333 !important;*/ + /*color: #fff !important;*/ + -moz-transition: background-color 0.3s ease-in; + -webkit-transition: background-color 0.3s ease-in; + -o-transition: background-color 0.3s ease-in; + transition: background-color 0.3s ease-in; +} +.btn-medium { + padding: 10px 12px; +} +.btn-small { + padding: 6px 10px; +} +.btn-small:not(.cmd), +.btn-tiny:not(.cmd), +.btn-medium:not(.cmd) { + font-size: 14px; +} +.btn-small.cmd, +.input-append .add-on { + font-size: 16px; +} +.btn-tiny { + padding: 4px 8px; +} +.btn-icon { + font-size: 22px; + padding: 11px 16px 8px; +} +.btn-icon > i { + display: block !important; +} +.btn-info { background-color: #79B3D6; } +.btn-info:hover, +.btn-info:focus { + color: #ffffff; + background-color: #3498DB; +} +.btn-primary { + background-color: #333; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-inverse:hover, +.btn-inverse:focus { + background-color: #666; + color: #FFFFFF; +} +.btn-text { + background-color: transparent; +} +div.content-info .btn-inverse { + background-color: #666; + color: #ffffff; +} +.btn-group { + margin-bottom: -5px; +} +.btn-group > .btn-small { + float: left; + font-size: 13px; + margin-bottom: 5px; +} +.btn-group-invers > .btn-primary:not(.btn-selected) { + background-color: #666 !important; + color: #ffffff; +} +div.content-info .btn-inverse:hover, +.content-home .btn-group-invers > .btn-primary:not(.btn-selected):hover { + background-color: #888 !important; +} +div.content-info a:not(.btn) { + color: #FFB45F; +} +div.content-info a:not(.btn):hover { + color: #fff; +} +.btn-readmore-collapsed, +.btn-readmore-expanded { + opacity: 0.6; + font-size: 85% !important; + margin-bottom: 5px; + display: block; + width: 100%; +} +.btn-readmore-collapsed { + background-color: rgba(0, 0, 0, 0); + box-shadow: 0 -10px 10px -5px rgba(0, 0, 0, 0.2); +} +.btn-readmore-collapsed:hover { + background-color: rgba(0, 0, 0, 0.05); + color: #333; +} +.btn-readmore-expanded { + background-color: rgba(0, 0, 0, 0.025); +} +.btn-readmore-expanded:hover { + background-color: rgba(0, 0, 0, 0.075); +} +a.cmd-filter { + display: inline-block; + text-decoration: none; + padding: 4px 8px; + min-width: 50px; + text-align: center; + margin: 0 5px 8px 0; + border-style: solid; + border-width: 1px; +} +a.cmd-filter.selected, +a.cmd-filter:hover { color: #FFFFFF !important; } + +div.content-inverse { + color: #ffffff; + background-color: #ff8800 /*#3498DB*/; +} +div.content-edit h3 { + clear: both; + margin: 40px 0 20px +} +div.content-special { + background-color: #666; + color: #fff; +} +div.content-special div.row-fluid { + margin: 10px auto !important; +} +div.content-special div.row-fluid div.box { + margin-top: 10px; +} +div.content-special i { + display: block; + float: left; + font-size: 48px; + margin: -4px 20px 0 0; +} +div.content-special a { + color: #fff; + text-decoration: underline; +} +div.abuse-message { + font-weight: bold; + padding: 5px 0 0; +} +.btn.select-inline { + background-color: #fff; + padding: 5px !important; +} +.btn.select-inline > span.filter-option, +.btn.select-standard > span.filter-option { + left: 6px !important; +} +.btn.select-inline + ul.dropdown-menu > li, +.btn.select-standard + ul.dropdown-menu > li { + margin-bottom: 2px; +} +.btn.select-inline + ul.dropdown-menu > li > a, +.btn.select-standard + ul.dropdown-menu > li > a { + padding: 3px 10px; + font-style: normal; +} +.btn.select-standard { + background-color: #fff; + padding: 5px !important; + margin-bottom: 10px; + border: 1px #ccc solid; + -moz-transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; + -o-transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; + -webkit-transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; + transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s; +} +.btn.select-standard + ul.dropdown-menu { + top: calc(100% - 10px) +} +.dropdown-menu > li > ul > li > a, +.dropdown-menu > li > ul > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + white-space: nowrap; + background-color: #eee !important; + color: #333 !important; +} +.dropdown-menu > li > ul > li > a:hover, +.dropdown-menu > li > ul > li > a:hover { + text-decoration: none; +} +.inslide > a { + font-weight: bold; +} +.inslide .inslide-more { + background-color: #f4f4f4; + display: none; + margin: 0 5px; + padding: 0 5px; +} +.inslide .inslide-more a { + font-size: 0.8rem; + padding: 3px; +} +.inslide .inslide-more a.inslide-selected { color: #ccc; } +.inslide .inslide-more a.inslide-selected:hover { color: #ccc; text-decoration: none; } + +.checkrack { + position: relative; + height: 26px; + width: 100px; + background: none repeat scroll 0 0 #fff; + border: 1px solid #DDDDDD; +} +.checkrack:before, +.checkrack:after { + position: absolute; + height: 2px; + top: 4px; + font-size: 12px; + color: #333; +} +.checkrack:before { + content: "JA"; + left: 20px; +} +.checkrack:after { + content: "NEIN"; + left: 60px; +} +.checkrack > label { + display: block; + position: absolute; + left: 0; + top: 0; + height: 26px; + width: 50px; + cursor: pointer; + -moz-transition: all 0.5s ease 0s; + -o-transition: all 0.5s ease 0s; + -webkit-transition: all 0.5s ease 0s; + transition: all 0.5s ease 0s; + z-index: 1; + background: none repeat scroll 0 0 #D63333; +} +.checkrack > input[type="checkbox"] { visibility: hidden; } +.checkrack > input[type="checkbox"]:checked + label { + left: 50px; + background: none repeat scroll 0 0 #028C00; +} +.pagination ul > li { + display: block; + float: left; + margin-bottom: 0; + margin-right: 3px; +} +.pagination ul > li > a, +.pagination ul > li > span { + font-size: 14px; + padding: 6px 14px; + border: none; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #ff8800; + color: #fff; +} +.pagination ul > .disabled > a, +.pagination ul > .disabled > span { + background-color: #ccc; + color: #333; +} +.pagination ul > li > a > i, +.pagination ul > li > span > i { + min-width: 9px; + display: inline-block; + text-align: center; +} +div.modal .modal-footer .btn { + min-width: 80px; +} +div.modal .modal-header, +div.modal .modal-footer .btn-primary { color: #FFF; background-color: #333 /*#3498DB*/; } +div.modal-info .modal-header, +div.modal-info .modal-footer .btn-primary { color: #FFF; background-color: #028C00; } +div.modal-error .modal-header, +div.modal-error .modal-footer .btn-primary { color: #FFF; background-color: #D63333; } +div.modal-question .modal-header, +div.modal-question .modal-footer .btn-primary { color: #FFF; background-color: #516CFF; } +div.modal-warning .modal-header, +div.modal-warning .modal-footer .btn-primary { color: #333; background-color: #FFDC00; } + +.modal-backdrop, .modal-backdrop.fade.in { + opacity: 0.6; +} +.arrow-down { + position: relative; +} +.arrow-down:hover:after, +.arrow-down:hover:before { + top: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-top-color: #333; +} +.arrow-down:hover:after { + border-width: 20px; + left: 50%; + margin-left: -20px; +} +.arrow-down:hover:before { + border-width: 26px; + left: 50%; + margin-left: -26px; +} +input.color-picker { + width: 120px !important; +} +input.color-picker + div { + border: 1px solid transparent; + height: 26px; + margin-left: -39px; + padding: 0; + position: relative; + width: 32px; +} +.table-striped tbody > tr:nth-child(2n) > td, +.table-striped tbody > tr:nth-child(2n) > th, +.table-striped-reverse tbody > tr:nth-child(odd) > td, +.table-striped-reverse tbody > tr:nth-child(odd) > th, +.content-shaded .table-striped tbody > tr:nth-child(2n+1) > td, +.content-shaded .table-striped tbody > tr:nth-child(2n+1) > th, +.content-shaded .table-striped-reverse tbody > tr:nth-child(even) > td, +.content-shaded .table-striped-reverse tbody > tr:nth-child(even) > th { + background-color: #fff; +} +.table-striped tbody > tr:nth-child(2n+1) > td, +.table-striped tbody > tr:nth-child(2n+1) > th, +.table-striped-reverse tbody > tr:nth-child(even) > td, +.table-striped-reverse tbody > tr:nth-child(even) > th, +.content-shaded .table-striped tbody > tr:nth-child(2n) > td, +.content-shaded .table-striped tbody > tr:nth-child(2n) > th, +.content-shaded .table-striped-reverse tbody > tr:nth-child(odd) > td, +.content-shaded .table-striped-reverse tbody > tr:nth-child(odd) > th { + background-color: #f4f4f4; /* flatstrap-Overwrite */ +} +table td { + -ms-word-wrap: break-word; + word-wrap: break-word; +} +.table.clean th, +.table.clean td { + border: none; +} +table.table-form { + margin-bottom: 0; +} +table.table-form tfoot th, +table.table-form tfoot td { + background: #eee; +} +.content-shaded table.table-form tr th, +.content-shaded table.table-form tr td { + background-color: #fff; +} +table.table-form tr th, +table.table-form tr td { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} +table.table-form tr th, +table.table-form tr td[colspan] { + border-left: 1px solid #ddd; +} +table.table-form tr td { + border-right: 1px solid #ddd; +} +table.table-form tr.focus th, +table.table-form tr.focus td { + background-color: #333 !important; + color: #fff; +} +table.table-form th { + vertical-align: middle; + padding-left: 15px; +} +table.table-form td input, +table.table-form td textarea, +table.table-form td select { + margin-bottom: 0 !important; +} +table.table-form td input, +table.table-form td textarea{ + width: 98%; +} +table.table-form td select { + width: 99.9%; + padding-left: 3px; + padding-right: 4px; +} +table.settings { + display: inline-block; + margin: 0; +} +table.settings td { + padding: 5px 15px 5px 0; +} +table.api-info { + background-color: #F4F4F4; +} +table.api-info th, +table.api-info td { + text-align: left; + vertical-align: top; + min-width: 120px; + padding: 5px 15px; +} +table.api-info tr:first-child th, +table.api-info tr:first-child td { padding-top: 10px; } +table.api-info tr:last-child th, +table.api-info tr:last-child td { padding-bottom: 10px; } +.content-shaded pre, +.content-shaded table.api-info { + background-color: #fff; +} +table.api-info code { background-color: #fff; } +.content-shaded table.api-info code { background-color: #f4f4f4; } + +table.table-sorted thead th { + border-bottom: 5px #ccc solid !important; +} +table .header { + cursor: pointer; +} +table .header:after { + border-color: #333 rgba(0, 0, 0, 0); + border-style: solid; + border-width: 0 6px 6px; + content: ""; + float: right; + margin-top: 7px; + visibility: hidden; +} +table.table-sorted thead th.headerSortDown, +table.table-sorted thead th.headerSortUp { + border-bottom: 5px #333 solid !important; +} +table .header:hover:after { + -ms-opacity: 1; + opacity: 1; + visibility: visible; +} + +table .headerSortUp:after { + -ms-opacity: 1; + opacity: 1; + visibility: visible; +} + +table .headerSortUp:hover:after { + -ms-opacity: 1; + opacity: 1; + visibility: visible; +} + +table .headerSortDown:after { + border-color: #333 rgba(0, 0, 0, 0); + border-style: solid solid none; + border-width: 6px 6px medium; + -webkit-box-shadow: none; + -ms-box-shadow: none; + box-shadow: none; + -ms-opacity: 1; + opacity: 1; + visibility: visible; +} + +table th.wholly-highlight, +table td.wholly-highlight { background: #f5f5f5; } +pre { + outline: 1px solid #ccc; + border: none; + padding: 5px; + max-height: 300px; + overflow: scroll; + overflow-x: auto; + white-space: pre; /* css-3 */ + white-space: -moz-pre; /* Mozilla, since 1999 */ + white-space: -pre; /* Opera 4-6 */ + white-space: -o-pre; /* Opera 7 */ +} +pre .string { color: black; } +pre .number { color: blue; } +pre .boolean { color: blue; } +pre .null { color: gray; } +pre .key { color: brown; } + +div#toc {} +div#toc a.root { + display: block; + background-color: #ff8800 /*#3498DB*/; + margin-bottom: 5px; + padding: 10px 12px 8px; + width: 100%; +} +div#toc ul { + clear: both; +} +div#toc ul li { + margin: 0; +} +div.left, +div.right { + height: 100%; + width: 75px; +} +div.left { + float: left; +} +div.right { + float: right; +} +div.main, +div.nav > div, +div.subnav > div { + height: 100%; + overflow: hidden; +} +div.content-hide { + display: none; +} +div.content-info { + background-color: #444; + color: #fff; +} +div.content-info > div.row-fluid { + margin: 20px auto 15px; +} +div.content-info h4 { + margin-top: -4px; + line-height: 19px; +} +div.content-info h4 + small { + display: block; + margin-bottom: 15px; + margin-top: -10px; +} + +div.info h1 { font-size: 22px; line-height: 24px; } +div.info h2 { font-size: 20px; line-height: 22px; } +div.info h3 { font-size: 18px; line-height: 20px; } + +div.content-shaded { + background-color: #f4f4f4; +} +div.proposal-tags > a { + background-color: #F4F4F4; + color: #333333; + display: block; + margin: 4px 0; + padding: 5px 10px; + text-decoration: none; + text-align: left; + font-size: 12px; +} +div.proposal-tags > a:hover, +div.content-shaded div.proposal-tags > a:hover { + background-color: #333; + color: #fff; + -moz-transition: background-color 0.3s ease-in; + -webkit-transition: background-color 0.3s ease-in; + -o-transition: background-color 0.3s ease-in; + transition: background-color 0.3s ease-in; +} +div.content-shaded div.proposal-tags > a, +div.content-shaded .btn.cmd, +div.content-shaded .input-append .add-on { + background-color: #fff; + color: #333; +} +div.comment { + position: relative; + margin-top: 10px; + clear: both; +} +div.comment > span.brace { + display: block; + float: left; + height: 100%; + padding: 5px; + position: absolute; + border-top: 5px #ddd solid; + border-left: 5px #ddd solid; + border-bottom: 5px #ddd solid; +} +div.content-shaded div.comment > span.brace { + border-top: 5px #ccc solid; + border-left: 5px #ccc solid; + border-bottom: 5px #ccc solid; +} +div.comment > div.commands { + position: absolute; + left: -30px; + width: 30px; +} +div.comment > div.commands a.btn { background-color: transparent; } +div.comment > div.commands a.btn:hover { background-color: #ddd; } +div.content-shaded div.comment > div.commands a.btn:hover {color: #333; background-color: #ccc; } +div.comment > div.markdown-text { + padding: 15px 0 0 20px; +} +div.comment > div.markdown-text > h4 { + line-height: 18px; + margin: 8px 0; +} +#newcomment-form { + margin: 10px 0 30px; +} +#newcomment-form input, +#newcomment-form textarea { + display: block; + /*width: calc(100% - 15px);*/ + width: 95%; +} +span.field-validation-error { + background-color: #D63333; + color: #fff; + margin: -10px 0px 10px; + display: block; + padding: 2px 6px; +} +label.inputicon { + color: #AAAAAA !important; + display: inline-block; + font-size: 20px; + padding: 3px 5px; + position: absolute; +} +label.inputicon i { + padding: 1px; +} +label.inputicon + input { + padding-left: 30px; +} + +input.readonly { + background-color: #f4f4f4; +} +input.w1 { width: 200px; } +input.w1 + span.field-validation-error { width: 202px; } +label.inputicon + input.w1 + span.field-validation-error { width: 226px; } + +.input-append.date > input { + background-color: transparent; + border: 1px solid transparent; + width: auto; +} +.input-append.date > .add-on { border: 1px solid transparent; } + +#topbar { + height: 24px; + position: relative; + z-index: 1; +} +#topbar > a { + background-color: #D63333; + color: #FFFFFF; + float: right; + font-size: 12px; + padding: 2px 10px; +} +#topbar > a:hover { + text-decoration: none; + background-color: #333 /*#3498DB*/; +} + +#logobar { + position: relative; + background-color: #333; + height: 75px; +} +#logobar div.left { background-color: #666; } +#logobar div.right { background-color: #2F2F2F; } +#logobar div.main { } +#logobar div.main h1 { + display: block; + font-size: 100px; + left: 75px; + letter-spacing: -0.1em; + line-height: 65px; + margin: 0; + position: absolute; + top: 1px; +} +#logobar div.main h1 a { + color: #666666 !important; + text-decoration: none; +} +#logobar div.main h2 { + /* display: none; TEMP */ + font-size: 36px; + left: 555px; + letter-spacing: -0.1em; + margin: 0; + position: absolute; + top: 38px; +} +#logobar div.main h2 a { + color: #FFFFFF; + opacity: 0.4; + text-decoration: none; +} +#logobar div.main h2 a:hover { + /* domain: color: #ff8800;*/ + opacity: 1; +} +#logobar div.main h2 a .caret { + border-width: 6px; +} +#logobar div.main h2 a:hover .caret { + /* domain: border-top-color: #ff8800 !important;*/ +} +#logobar div.main a#notification-throbber { + display: block; + position: absolute; + right: 10px; + top: 10px; +} +#logobar div.main a#notification-throbber > i { + color: #666; + font-size: 24px; + -moz-transition: color 0.3s ease-out 0s; + -o-transition: color 0.3s ease-out 0s; + -webkit-transition: color 0.3s ease-out 0s; + transition: color 0.3s ease-out 0s; +} +#logobar div.main a#notification-throbber:hover > i { + color: #fff; +} +#logobar div.main div#notification-box { + display: block; + position: absolute; + right: 40px; + overflow: hidden; + width: 170px; + height: 75px; +} +#logobar div.main div#notification-box > a { + position: absolute; + width: 170px; + max-height: 60px; + overflow: hidden; + top: 8px; + display: none; + color: #ccc; + -moz-transition: color 0.3s ease-out 0s; + -o-transition: color 0.3s ease-out 0s; + -webkit-transition: color 0.3s ease-out 0s; + transition: color 0.3s ease-out 0s; +} +#logobar div.main div#notification-box > a:hover { + text-decoration: none; + color: #fff; +} +#logobar div.main div#notification-box > a > small { + display: block; + width: inherit; + line-height: 14px; + font-size: 80%; + font-style: italic; +} +#logobar div.main div#notification-box > a > span { + display: block; + width: inherit; + margin: 3px 0px; + font-size: 90%; + line-height: 14px; +} +#headnav { + background: #666; + padding: 0 75px; +} +#headnav #country-headnav a { + color: #FFFFFF; + display: inline-block; + font-family: 'PoliticsHeadBold','Helvetica Neue','Arial',Sans-Serif; + font-size: 20px; + padding: 10px 10px 10px 0; + text-decoration: none; +} +#intro { + position: relative; + background-color: transparent; + min-height: 200px; + padding: 10px 20px; + -moz-background-size: cover !important; + -o-background-size: cover !important; + -webkit-background-size: cover !important; + background-size: cover !important; +} +#intro * { + color: #fff; + -webkit-text-shadow: 0 0 4px #000000; + text-shadow: 0 0 4px #000000; +} +#intro p.group { + font-size: 2em; + line-height: 30px; + margin-top: 20px; +} +#intro p { + display: block; + margin-top: 25px; + font-size: 20px; + font-weight: bold; + line-height: 25px; + width: 75%; +} +#intro img { + margin-left: -10px; + display: block; +} +#intro small.fotoby:before { + position: absolute; + font-size: 10px; + color: rgba(255, 255, 255, 0.75); + background-color: rgba(0, 0, 0, 0.25); + -webkit-text-shadow: none; + text-shadow: none; + top: 0; + right: 0; + padding: 0 5px; + line-height: 1.6; +} +#intro h3 { + display: inline-block; + font-size: 2em; + margin-bottom: 0; + margin-top: 10px; +} +#intro a { text-decoration: underline; } +#intro h2, +#intro h3 { + -ms-word-wrap: break-word; + word-wrap: break-word; +} +nav.hrm { + -moz-transition: all 0.25s ease-in-out 0s; + -o-transition: all 0.25s ease-in-out 0s; + -webkit-transition: all 0.25s ease-in-out 0s; + transition: all 0.25s ease-in-out 0s; +} +nav.hrm.hrm-pinned { + -moz-transform: translateY(0px); + -ms-transform: translateY(0px); + -o-transform: translateY(0px); + -webkit-transform: translateY(0px); + transform: translateY(0px); + -webkit-box-shadow: -2px 2px 6px 1px #ccc; + -webkit-box-shadow: -2px 1px 4px 1px rgba(0, 0, 0, 0.4); + -ms-box-shadow: -2px 1px 4px 1px rgba(0, 0, 0, 0.4); + box-shadow: -2px 1px 4px 1px rgba(0, 0, 0, 0.4); +} + +nav.hrm.hrm-unpinned { + -moz-transform: translateY(-100%); + -ms-transform: translateY(-100%); + -o-transform: translateY(-100%); + -webkit-transform: translateY(-100%); + transform: translateY(-100%); +} +nav.hrm.hrm-not-top { + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 99; +} + +/* MAIN START */ +#mainnav { overflow: hidden; } +#mainnav, +#mainnav a, +.tooltipster-mainnav, +.pagination ul > li:not(.dir) > a, +.pagination ul > li > span { + background-color: #333 /*#3498DB*/; color: #FFFFFF; +} +.nav > div ul.dropdown-menu li.dropdown-node > a:hover, +.nav > div ul.dropdown-menu li.dropdown-node > a:focus { + background-color: #333 /*#3498DB*/ !important; color: #FFFFFF !important; +} +#mainnav a:hover, +#mainsubnav, +.pagination ul > li.dir > a { + background-color: #666; color: #FFFFFF; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.pagination ul > li.dir > a { + background-color: #666 /*#79B3D6*/; color: #FFFFFF; +} +/* MAIN END */ +.nav { + position: relative; + height: 36px; + margin-bottom: 0; +} +.nav div.nav-left { float: left; } +.nav div.nav-right { float: right; } + +a.nav-item, +#toc a.root { + color: #fff; + display: block; + float: left; + padding: 7px 10px; + font-family: BebasNeue,Helvetica,Arial,sans-serif; + font-size: 21px; + letter-spacing: 1px; + text-decoration: none; +} +.nav div.nav-right > .navmenu { + display: none; + position: absolute; + right: 0; +} +.nav .dropdown-toggle .caret, +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-bottom-color: #fff; + border-top-color: #fff; + margin-top: 0; +} +#mainnav a.nav-item .nav-icon, +#mainsubnav a.nav-item .nav-icon, +#mainnav a.nav-item:hover .nav-text, +#mainsubnav a.nav-item:hover .nav-text { opacity: 1; } +#mainnav a.nav-item .nav-text, +#mainsubnav a.nav-item .nav-text { opacity: 0.5; } + +#repnav a.nav-item .nav-icon, +#repnav a.nav-item:hover .nav-text { opacity: 1; } +#repnav a.nav-item .nav-text { opacity: 0.9; } + +a.nav-item.nav-icon-only span.nav-text { display: none; } +a.nav-item:hover span.nav-text { opacity: 1; } +a.nav-item span.nav-icon-sub { display: none; } +a.nav-item i.icon-group { margin-right: 8px; } + +#mainsubnav { + padding: 5px 0; +} +#mainnav, #mainsubnav, #mainsubnav-rep, #repnav { + padding: 0 85px; /* anstelle von div.left und div.right */ +} +#mainsubnav-rep { + background: #333; +} +#mainsubnav-rep #mainsubnav-rep-list { + position: relative; + overflow: hidden; + height: 150px; /* 6 x (rbox.height + ((rbox.margin + rbox.padding) x 2))) */ + margin: 10px 0 0; +} +#mainsubnav-rep #mainsubnav-rep-list a.rbox { + background-color: #666; + border-left: 10px solid #FFFFFF; + display: block; + float: left; + height: 20px; + margin: 3px; + padding: 2px 5px; + text-decoration: none; + overflow: hidden; + white-space: nowrap; + -ms-text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + color: #fff; +} +#mainsubnav-rep #mainsubnav-rep-list a.rbox.ended, +table tr.ended td { + text-decoration: line-through; +} +#mainsubnav-rep #mainsubnav-rep-list a.rbox.ended:hover, +table tr.ended:hover td { + text-decoration: none; +} +#mainsubnav-rep #mainsubnav-rep-list a.rbox:hover, +#mainsubnav-rep #mainsubnav-rep-list a.rbox:focus { + border-color: #666 !important; +} +#mainsubnav-rep #mainsubnav-rep-filter { +} +#mainsubnav-rep .mainsubnav-rep-filter a { + margin-right: 4px; +} +#mainsubnav-rep-filter-federalstate a {color: #AAA;} +#mainsubnav-rep-filter-governmentallevel a {color: #999;} +#mainsubnav-rep .mainsubnav-rep-filter a.selected { + color: #fff; + text-decoration: none; +} +#body { + position: relative; + overflow: auto; + background-color: #fff; +} +#body div.box { + margin-bottom: 10px; +} +#body div.content > div.row-fluid { + margin: 25px auto; + max-width: 960px; +} +#body div.content > div.row-fluid.row-small { + margin: 15px auto; +} +#body div.content .box-head > i { + display: block; + float: left; + font-size: 64px; +} +#body div.content .box-head > h2 { + display: block; + margin: 0 80px; +} +#body div.content div.row-small .box-head > i { + display: block; + float: left; + font-size: 32px; +} +#body div.content div.row-small .box-head > h3 { + display: block; + margin: 0 50px; + clear: none; +} +#body div.content-navigation {} +#body div.content-navigation > div.row-fluid { + margin: 0 auto; +} +#body div.content-navigation > div.row-fluid > div { + padding: 20px 0 10px; +} +#body div.content-navigation > div.row-fluid > div.right { + text-align: right +} +#body div.content-proposal div.proposal-item { + position: relative; +} +#body div.content-proposal div.proposal-item > a { + float: left; + height: 100%; + display: block; + position: absolute; + color: #fff; + padding: 10px 0 0; + margin-top: -5px; + text-decoration: none; +} +#body div.content-proposal div.proposal-item > a:hover { + background-color: #333 !important; +} +#body div.content-proposal div.proposal-item > a > i { + font-size: 20px; + text-decoration: none; + padding: 0 8px +} +#body div.content-proposal div.proposal-item .proposal-steps { + position: absolute; + bottom: 0; + width: 100%; +} +#body div.content-proposal div.proposal-item .proposal-steps > span { + display: block; + background: #AAAAAA; + height: 10px; + border-top: 1px #fff solid; +} +#body div.content-proposal div.proposal-item > div.proposal-body { + margin-left: 50px; +} +#body div.content-proposal div.proposal-item > div.proposal-body > a.representation { + display: block; + margin: -5px 0 10px; +} +#body div.content-proposal div.proposal-item > div.proposal-body > img { + width: 32px; + float: left; + margin-right: 10px; +} +#body div.content-proposal div.proposal-item > div.proposal-body > em { + display: block; + font-size: 14px; + padding-top: 6px; +} +#body div.content-proposal div.proposal-item > div.proposal-body > small { + display: block; + margin-top: 25px; +} + +#body div.content-proposal div.proposal-item > div.proposal-body > div h1, +#body div.content-proposal div.proposal-item > div.proposal-body > div h2, +#body div.content-proposal div.proposal-item > div.proposal-body > div h3, +#body div.content-proposal div.proposal-item > div.proposal-body > div h4, +#body div.content-proposal div.proposal-item > div.proposal-body > div h5 { + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +#body div.content-proposal div.proposal-item > div.proposal-body > div h1 { font-size: 22px; } +#body div.content-proposal div.proposal-item > div.proposal-body > div h2 { font-size: 20px; } +#body div.content-proposal div.proposal-item > div.proposal-body > div h3 { font-size: 18px; } +#body div.content-proposal div.proposal-item > div.proposal-body > div h4 { font-size: 16px; } +#body div.content-proposal div.proposal-item > div.proposal-body > div h5 { font-size: 14px; } +#body div.content-proposal div.proposal-item > div.proposal-body > h3 { + margin-top: 0; +} +#body div.content-proposal div.proposal-item > div.proposal-body > h3 > a, +#body div.content div.success-item > h3 > a { + color: #333; + -ms-word-wrap: break-word; + word-wrap: break-word; +} +#body div.content-faq > div > div > small { + background-color: #333; + color: #fff; + font-size: 90%; + padding: 3px 6px; +} +#proposallist-table tbody tr { + cursor: pointer; +} +#proposallist-table td.process-marker { + padding: 0; +} +#proposallist-table td.process-marker a { + display: block; + padding: 10px; + color: #fff !important; +} +#proposallist-table td.process-marker ~ td small { + display: block; + line-height: 14px; + opacity: 0.75; + margin-top: 5px; +} +footer { + position: relative; + height: 74px; + margin-top: 0; + /* domain: background-color: #FF8800;*/ + clear: both; +} +footer div.left { + /* domain: background-color: #FFA948;*/ +} +footer div.right { + /* domain: background-color: #FFA948;*/ +} +footer #footer-commands { + height: 100%; +} +footer #footer-commands > a { + color: #FFFFFF; + display: block; + font-family: BebasNeue,Helvetica,Arial,sans-serif; + font-size: 18px; + height: 100%; + letter-spacing: 1px; + padding: 10px 20px 0; + text-align: center; + text-decoration: none; + /* domain: background-color: #FF8800;*/ +} +footer #footer-commands > a > i { + display: inline-block; + font-size: 28px; + margin-bottom: 6px; +} +footer #footer-commands > a:hover { + /* domain: background-color: #FFA948;*/ +} +a#backtop { + display: none; + position: fixed; + /*bottom: -25px;*/ + bottom: 0; + right: 0; + font-size: 44px; + height: 44px; + margin: 0 10px 10px 0; + padding: 2px 6px; + border-radius: 30px 30px 30px 30px; + opacity: 0.75; + color: #fff; + text-decoration: none; + /* domain: background-color: #ff8800;*/ +} +a#backtop:hover { + opacity: 1; +} +.tooltipster-standard { + border-radius: 0px; + border: 3px solid #333; + background: #333; + color: #fff; +} +.tooltipster-standard .tooltipster-content, +.tooltipster-mainnav .tooltipster-content, +.tooltipster-repnav .tooltipster-content { + font-size: 14px; + line-height: 16px; + padding: 8px 10px; +} +.tooltipster-mainnav, +.tooltipster-repnav { + border-radius: 0px; +} +.tooltipster-standard, +.tooltipster-mainnav, +.tooltipster-repnav { + -webkit-box-shadow: 0px 2px 6px 2px rgba(0, 0, 0, 0.5); + box-shadow: 0px 2px 6px 2px rgba(0, 0, 0, 0.5); +} +#tag-cloud-container { + width: 560px; + height: 250px; + background-color: #f4f4f4; +} +/* flatstrap-override */ +.alert-danger, .alert-error { + background-color: #FEE8E8; + border-color: #FEE8E8; + color: #D63333; +} +.alert-success a, +.alert-info a, +.alert-danger a, +.alert-error a { + color: inherit; + text-decoration: underline; +} +@media (min-width: 1200px) { + #intro p { + width: 50%; + } + #tag-cloud-container { + float: right; + } + table.responsive { + table-layout: fixed; + width: 100%; + } +} +@media only screen and (max-width: 980px) { + /* responsive-tables.js */ + table.responsive { margin-bottom: 0; } + .pinned { + position: absolute; + left: 0; + top: 0; + background: #fff; + width: 30%; + overflow: hidden; + overflow-x: scroll; + border-right: 1px solid #666; + } + .pinned table { + border-right: none; + border-left: none; + width: 100%; + } + .pinned table th, + .pinned table td { white-space: nowrap; } + /*.pinned td:last-child { border-bottom: 0; }*/ + div.responsive-wrapper { + position: relative; + margin-bottom: 20px; + overflow: hidden; + border-right: 1px solid #ccc; + } + div.responsive-wrapper div.scrollable { + margin-left: 30%; + overflow: scroll; + overflow-y: hidden; + } + table.responsive td, + table.responsive th { + position: relative; + white-space: nowrap; + overflow: hidden; + } + table.responsive th.responsive-pin, + table.responsive td.responsive-pin, + table.responsive.pinned td { display: none; } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro p { + width: 60%; + } + #tag-cloud-container { + width: 480px; + height: 250px; + float: right; + } + + .nav div.left, + .nav div.right { display: none; } + + #mainnav, #mainsubnav, #mainsubnav-rep, #repnav { padding: 0 10px; /* anstelle von div.left und div.right */ } + +} +@media (min-width: 768px) and (max-width: 979px) { + #tag-cloud-container { + width: 480px; + height: 250px; + float: right; + } + .nav div.left, + .nav div.right { display: none; } + .nav div.nav-right > .navmenu { display: block; } + + #mainnav, #mainsubnav, #mainsubnav-rep, #repnav { padding: 0 10px; /* anstelle von div.left und div.right */ } + +} +@media (max-width: 767px) { + #logobar div.main h1 { + font-size: 80px; + left: 80px; + } + #logobar div.main h2 { + font-size: 28px; + left: 465px; + top: 36px; + } + .container-fluid { /* flatstrap-override */ + padding-left: 20px !important; + padding-right: 20px !important; + } + + .nav div.left, + .nav div.right { display: none; } + + #mainnav, #mainsubnav, #mainsubnav-rep, #repnav { padding: 0 5px; /* anstelle von div.left und div.right */ } + + #mainsubnav-rep { padding: 0; } + #mainsubnav-rep #mainsubnav-rep-list { padding: 10px 5px; } + #mainsubnav-rep .mainsubnav-rep-filter, + #mainsubnav-rep #no-representations { padding: 0 10px !important; } + #mainsubnav-rep #mainsubnav-rep-list a.rbox { width: 95% } + + #body div.content-info > div.row-fluid div.mtop { margin-top: 30px; } + + div.proposal-tags { margin-top: 20px; } + + #intro p { width: 90%; } + footer { height: 75px; } + footer div.left { display: none; } +} +@media (max-width: 680px) { + #logobar div.main div#notification-box { display: none; } + + a.nav-item.nav-icon-mere span.nav-text { display: none; } + + a.nav-item.nav-item-ellipsis { + white-space: nowrap; + overflow: hidden; + -ms-text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + max-width: 300px; + } + #body div.content-navigation > div.row-fluid > div.right { + text-align: left; + } + footer #footer-commands > a { + font-size: 16px; + padding: 16px 10px 0; + } + footer #footer-commands > a > i { font-size: 24px; } +} +@media (max-width: 480px) { + #logobar div.main h1 { + font-size: 50px; + left: 80px; + top: 5px; + } + #logobar div.main h2 { + font-size: 22px; + left: 318px; + top: 33px; + } + #tag-cloud-container { + width: 330px; + height: 330px; + } + + #body div.content-info > div.row-fluid div.mtop { margin-top: 30px; } + + a.nav-item, + #toc a.root { padding: 7px; } + + a.nav-item.nav-icon-mere span.nav-text { display: none; } + a.nav-item.nav-item-ellipsis { + white-space: nowrap; + overflow: hidden; + -ms-text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + max-width: 200px; + } + + .pagination ul > li > a, .pagination ul > li > span { padding: 4px 10px; } +} +@media (max-width: 360px) { + #logobar div.main a#notification-throbber { display: none; } +} +@media (max-width: 320px) { + #tag-cloud-container { + width: 280px; + height: 280px; + } + a.nav-item, + #toc a.root { padding: 7px 6px; } +} +@media print { + #topbar, + #logobar .main #notifications, + #intro img, + #intro h2, + section.nav, + #more, + #body #newproposal-container, + #body #banner-container, + #body #proposaledit-container, + #body div.content .box-head > h2 br, + #body div.content-proposal div.proposal-item > a, + #body .proposal-head span.add-on, + #body .proposal-head > a, + #body .representation-map, + #body .fraktionbox > a, + #body .fraktionbox img, + #body #tag-cloud-container, + footer, + a#backtop, + ul.sublinks, + form, + button, + a.btn, + .pagination { + display: none !important; + } + #logobar .left a[href]:after, + #logobar .main h1 a[href]:after, + #body div.content div.fraktionbox a[href]:after { + content: "" !important; + } + #logobar { height: 50px;} + #logobar .main h1 { + line-height: 30px !important; + top: 10px !important; + } + #logobar .main h1 a { + font-size: 50px; + letter-spacing: 0; + } + #intro { + min-height: 0; + margin: -15px 0 0 62px; + } + #intro h3 { + font-size: 20px; + } + #body div.content .box-head > i { + font-size: 24px; + } + #body div.content .box-head > h2 { + font-size: 26px; + line-height: 20px; + margin: 0 40px; + } + #body div.content-proposal div.proposal-item > div.proposal-body { + margin-left: 0; + } + #body div.content > div.row-fluid { + margin: 5px auto; + } + #body div.content-proposal div.proposal-item > div.proposal-body > small { + margin-top: 5px; + } + #body .proposal-head h2 { + font-size: 26px; + } + #body div.fraktionbox { + overflow: auto; + } + @page { + margin-top: 1cm; + margin-bottom: 1cm; + } +} diff --git a/OpenAntrag/Content/success.css b/OpenAntrag/Content/success.css new file mode 100644 index 0000000..f25e3d8 --- /dev/null +++ b/OpenAntrag/Content/success.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/success-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/success-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/success-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/success-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/tags.css b/OpenAntrag/Content/tags.css new file mode 100644 index 0000000..e87e277 --- /dev/null +++ b/OpenAntrag/Content/tags.css @@ -0,0 +1,24 @@ +@media (min-width: 1200px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/tags-full.jpg') no-repeat right center; + } +} +@media (min-width: 980px) and (max-width: 1199px) { + #intro { + background: url('/Images/bgtransgrad-500.png') no-repeat left center, + url('/Images/IntroBack/tags-1200.jpg') no-repeat right center; + } +} +@media (min-width: 768px) and (max-width: 979px) { + #intro { + background: url('/Images/bgtransgrad-250.png') no-repeat left center, + url('/Images/IntroBack/tags-980.jpg') no-repeat right center; + } +} +@media (max-width: 767px) { + #intro { + background: url('/Images/bgtransgrad-150.png') no-repeat left center, + url('/Images/IntroBack/tags-770.jpg') no-repeat right center; + } +} \ No newline at end of file diff --git a/OpenAntrag/Content/teaser.css b/OpenAntrag/Content/teaser.css new file mode 100644 index 0000000..08e5b91 --- /dev/null +++ b/OpenAntrag/Content/teaser.css @@ -0,0 +1,3 @@ +p { + margin: 0 0 20px; +} \ No newline at end of file diff --git a/OpenAntrag/Controllers/AccountController.vb b/OpenAntrag/Controllers/AccountController.vb new file mode 100644 index 0000000..91f68ef --- /dev/null +++ b/OpenAntrag/Controllers/AccountController.vb @@ -0,0 +1,127 @@ +Public Class AccountController + Inherits CommonController + + + Public Function Logon(ByVal model As LogonModel) As ActionResult + + Dim rp As Representation = Nothing + Dim exc As CustomException = Nothing + + If ModelState.IsValid Then + If Membership.ValidateUser(model.UserName, model.Password) Then + + FormsAuthentication.SetAuthCookie(model.UserName, True) + + Dim mu As MembershipUser = Membership.GetUser(model.UserName) + Members.EnsureMember(mu) + + Dim ur As String() = Roles.GetRolesForUser(mu.UserName) + + For Each r As Representation In GlobalData.Representations.Items + If ur.Contains(r.Key) = True Then + rp = r + Exit For + End If + Next + Else + exc = New CustomException("Der Benutzername oder das Passwort sind nicht korrekt.", "Login-Fehler") + End If + End If + + If exc IsNot Nothing Then + TempData("ExceptionAlert") = exc + End If + + If rp IsNot Nothing Then + Return RedirectToAction("Index", "Representation", New With {.keyRepresentation = rp.Key}) + Else + Return RedirectToAction("Index", "Home") + End If + + End Function + + Public Function Logoff() As ActionResult + + FormsAuthentication.SignOut() + + Dim strReturnUrl As String = Nothing + If HttpContext.Request.Params("returnUrl") IsNot Nothing Then + strReturnUrl = HttpContext.Request.Params("returnUrl") + End If + + If Url.IsLocalUrl(strReturnUrl.ToLocalUrl) Then + Return Redirect(strReturnUrl) + Else + Return RedirectToAction("Index", "Home") + End If + + End Function + + + Public Function ResetPassword(ByVal model As ResetPasswordModel) As JsonResult + + 'wg. Artem-ResetPassword-Bug + Throw New Exception("Diese Funktion steht aktuell nicht zur Verfügung") + + + 'If model.UserNameReset Is Nothing OrElse model.UserNameReset.Length = 0 Then + ' Throw New Exception("Der Benutzername ist leer") + 'End If + + 'Dim usr As MembershipUser = Membership.GetUser(model.UserNameReset, True) + 'If usr Is Nothing Then + ' Throw New Exception("Dieser Benutzername existiert nicht") + 'End If + + 'model.MailAddress = usr.Email + 'model.NewPassword = usr.ResetPassword() + ''Dim strReset As String = usr.ResetPassword() 'hässliches Passwort + ''model.NewPassword = Membership.GeneratePassword(10, 0) 'nettes Passwort + ''usr.ChangePassword(strReset, model.NewPassword) + + ''GEHT NICHT: Dim bolVal As Boolean = Membership.ValidateUser(model.UserNameReset, model.NewPassword) + + 'MailManager.SendResetPasswordToUser(model) + + 'Dim jr As New JsonResult + 'jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + 'jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_PasswordResetSuccessPartial")} + + 'Return jr + + End Function + + + + Public Function ChangePassword(ByVal model As ChangePasswordModel) As JsonResult + + If User.Identity.Name <> model.UserName Then + Throw New Exception("Diese Methode steht nur dem angemeldeten Benutzer zur Verfügung") + End If + + If ModelState.IsValid = False Then + Throw New Exception("Ungültige Kennwortdaten") + End If + + Dim bolSuccess As Boolean + + Try + Dim usr As MembershipUser = Membership.GetUser(User.Identity.Name, True) + bolSuccess = usr.ChangePassword(model.OldPassword, model.NewPassword) + Catch ex As Exception + bolSuccess = False + End Try + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + If bolSuccess = True Then + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_PasswordChangeSuccessPartial")} + Else + Throw New Exception("Das Passwort wurde nicht geändert. Bitte überprüfe Deine Eingaben.") + End If + + Return jr + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntrag/Controllers/ErrorController.vb b/OpenAntrag/Controllers/ErrorController.vb new file mode 100644 index 0000000..befb4ff --- /dev/null +++ b/OpenAntrag/Controllers/ErrorController.vb @@ -0,0 +1,68 @@ +Imports System.Net +Imports System.Web.Mvc + +Public Class ErrorController + Inherits CommonController + + Public Function Index() As ActionResult + Return InternalServerError() + End Function + + Public Function InternalServerError() As ActionResult + + Response.TrySkipIisCustomErrors = True + Response.StatusCode = CInt(HttpStatusCode.InternalServerError) + + Dim cei As CustomErrorInfo + Dim message As String = "Es ist ein Server-Fehler aufgetreten" + Dim referrerUrl As String = "" + + If Request.UrlReferrer IsNot Nothing Then + referrerUrl = Request.UrlReferrer.AbsolutePath + End If + + Dim ex As Exception = Server.GetLastError() + If ex IsNot Nothing Then + cei = New CustomErrorInfo(message, + Request.UrlReferrer.AbsoluteUri, + CustomErrorInfo.OriginEnum.Redirect, + 500, + ex, + RouteData.Values("controller").ToString(), + RouteData.Values("action").ToString()) + + PushoverManager.Send("InternalServerError", ex.Message) + + Else + cei = New CustomErrorInfo(message, CustomErrorInfo.OriginEnum.Redirect, 500) + cei.ReferrerUrl = referrerUrl + End If + + Return View("Uups", cei) + + End Function + + Public Function NotFound() As ActionResult + + Response.TrySkipIisCustomErrors = True + Response.StatusCode = CInt(HttpStatusCode.NotFound) + + Dim cei As New CustomErrorInfo("Diese Seite existiert nicht", CustomErrorInfo.OriginEnum.Redirect, 404) + If Request.UrlReferrer IsNot Nothing Then + cei.ReferrerUrl = Request.UrlReferrer.AbsoluteUri + End If + + Return View("Uups", cei) + + End Function + + + Public Function ErrorLog(id As String) As ActionResult + + Dim el As OpenAntrag.ErrorLog = OpenAntrag.ErrorLogs.GetById(id) + + Return View("ErrorLog", el) + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntrag/Controllers/FeedbackController.vb b/OpenAntrag/Controllers/FeedbackController.vb new file mode 100644 index 0000000..9eef37a --- /dev/null +++ b/OpenAntrag/Controllers/FeedbackController.vb @@ -0,0 +1,163 @@ +Public Class FeedbackController + Inherits DocumentStoreController + +#Region "View Actions" + + Public Function Index(key As String) As ActionResult + + Dim lst As List(Of Feedback) + Dim intFilterId As Integer = -1 + + If String.IsNullOrEmpty(key) = True Then + lst = Feedbacks.GetItems + Else + Dim fb As FeedbackType = (From ft As FeedbackType In GlobalData.FeedbackTypes.Items + Where ft.Key = key + Select ft).FirstOrDefault + + lst = Feedbacks.GetItemsByType(fb) + intFilterId = fb.ID + End If + + ViewBag.FilterId = intFilterId + + Return View(lst) + + End Function + +#End Region + +#Region "Service Actions" + + + Public Function CreateNew(type As Integer, + createdby As String, + title As String, + message As String) As JsonResult + + Dim fb As New Feedback With { + .Type = type, + .CreatedBy = createdby, + .Title = title, + .Message = message, + .Status = 0, + .Likes = 1, + .Dislikes = 0 + } + + Me.StoreAndSave(fb) + + PushoverManager.SendNewFeedback(fb) + NotificationManager.StoreNewFeedback(fb) + PushbulletManager.SendNewFeedback(fb) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function Delete(id As String) As JsonResult + + 'AKTUELL NICHT + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function CreateNewComment(feedbackID As String, + commentedby As String, + comment As String) As JsonResult + + Dim fb As Feedback = Feedbacks.GetByID(feedbackID) + + Dim fbc As New FeedbackComment With { + .CommentedBy = commentedby, + .CommentedByAdmin = Tools.IsAdmin(), + .Comment = comment, + .ID_Feedback = fb.Id + } + + If fb.Comments Is Nothing Then + fb.Comments = New List(Of FeedbackComment) + End If + + fb.Comments.Add(fbc) + + Me.StoreAndSave(fb) + + PushoverManager.SendNewFeedbackComment(fb, fbc) + NotificationManager.StoreNewFeedbackComment(fb, fbc) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_FeedbackCommentPartial", fbc)} + + Return jr + + End Function + + + Public Function DeleteComment(feedbackId As String, + commentedby As String, + timeStamp As Integer) As JsonResult + + If Tools.IsAdmin() = False Then + 'If HttpContext.User.IsInRole("admin") = False Then + Throw New CustomException("Dazu fehlt Dir die Berechtigung") + End If + + Dim fb As Feedback = Feedbacks.GetByID(feedbackId) + + Dim query = From c As FeedbackComment In fb.Comments + Where c.CommentedBy.ToLower = commentedby.ToLower And c.Timestamp = timeStamp + Select c + + If query.Count > 0 Then + Dim fbc As FeedbackComment = query.First + fb.Comments.Remove(fbc) + End If + + Me.StoreAndSave(fb) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function Vote(id As String, pro As Boolean) As JsonResult + + Dim fb As Feedback = Feedbacks.GetByID(id) + + If pro = True Then + fb.Likes += 1 + Else + fb.Dislikes += 1 + End If + + Me.StoreAndSave(fb) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = fb} + + Return jr + + End Function + +#End Region + +End Class diff --git a/OpenAntrag/Controllers/HomeController.vb b/OpenAntrag/Controllers/HomeController.vb new file mode 100644 index 0000000..ba9f571 --- /dev/null +++ b/OpenAntrag/Controllers/HomeController.vb @@ -0,0 +1,167 @@ +Imports System.ServiceModel.Syndication +Imports System.IO + +Public Class HomeController + Inherits DocumentStoreController + +#Region "View Actions" + + Public Function AllRepresentationsStyle() As FileResult + + Dim strTemplatePath As String = HttpContext.Server.MapPath("~/Content/style-allrepresentations.template.css") + Dim strTemplate As String = Nothing + If IO.File.Exists(strTemplatePath) = True Then + strTemplate = IO.File.ReadAllText(strTemplatePath) + End If + + Dim stb As New StringBuilder() + + For Each rep As Representation In GlobalData.Representations.Items + stb.Append(strTemplate) + Representations.ReplaceStyleColor(rep, stb) + Next + + Dim ba As Byte() = Encoding.UTF8.GetBytes(stb.ToString()) + Dim stm As MemoryStream = New MemoryStream(ba) + + Return File(stm, "text/css", "allrepresentationstyle.css") + + End Function + + Public Function Index() As ActionResult + Return View() + End Function + + Public Function Success(pageNo As Integer) As ActionResult + + Dim model As List(Of SuccessStory) = SuccessStories.GetItemsPage(pageNo, SettingsWrapper.DefaultPagerListPageSize) + + ViewData("ItemsCount") = SuccessStories.GetItemsCount() + ViewData("PageNo") = pageNo + + Return View(model) + + End Function + + Public Function Journal(pageNo As Integer) As ActionResult + + Dim model As List(Of Proposal) = Proposals.GetItemsPage(pageNo, SettingsWrapper.DefaultPagerListPageSize) + + ViewData("ItemsCount") = Proposals.GetItemsCount() + ViewData("PageNo") = pageNo + + Return View(model) + + End Function + + Public Function List() As ActionResult + + Dim model As List(Of Proposal) = Proposals.GetItemsPage(1, SettingsWrapper.ProposalListCount) + + ViewData("ItemsShown") = SettingsWrapper.ProposalListCount + ViewData("ItemsCount") = Proposals.GetItemsCount() + + Return View(model) + + End Function + + Public Function Search(searchTerms As String, pageNo As Integer) As ActionResult + + Dim model As SearchModel = Nothing + + If String.IsNullOrEmpty(searchTerms) = False Then + model = New SearchModel(searchTerms) + Proposals.SearchItems(model, pageNo, SettingsWrapper.DefaultPagerListPageSize) + End If + + ViewData("PageNo") = 1 + + Return View(model) + + End Function + + Public Function Tags(tag As String, pageNo As Integer) As ActionResult + + Dim model As ProposalTag = Nothing + + If String.IsNullOrEmpty(tag) = False Then + model = ProposalTags.GetTag(tag) + End If + + ViewData("PageNo") = pageNo + + Return View(model) + + End Function + + Public Function ProposalAllFeed() As FeedResult + + Dim lst As List(Of Proposal) = Proposals.GetItemsTop(25) + + Dim items As IEnumerable(Of SyndicationItem) = Nothing + + If lst IsNot Nothing Then + items = From prop As Proposal In lst + Select prop.FeedItem + End If + + Dim feed As New SyndicationFeed("OpenAntrag-Feed", + String.Concat("Aktuelle Bürgeranträge auf ", HttpContext.Request.Url.Authority), + New Uri(String.Concat("http://", HttpContext.Request.Url.Authority, "/feed")), + "", DateTime.Now, items) With {.Language = "de-DE"} + + Return New FeedResult(New Rss20FeedFormatter(feed)) + + End Function + + Public Function Api() As ActionResult + Return View() + End Function + + Public Function Overview() As ActionResult + Dim lst As List(Of Representation) = GlobalData.Representations.Items.Where(Function(r) r.Status > 0).ToList() + Return View(lst) + End Function + + Public Function Faq() As ActionResult + Return View() + End Function + +#End Region + +#Region "Service Actions" + + + Public Function GetProposalListTable(iCount As Integer) + + Dim model As List(Of Proposal) = Proposals.GetItemsPage(1, iCount) + + ViewData("ShowRepresentation") = True + Return Me.GetPartialModel("ProposalListTable", model) + + End Function + + + + Public Function SaveRepresentationSetting(key As String, + hasContactPossibility As Boolean) As JsonResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + Dim model As RepresentationSetting = RepresentationSettings.GetByKey(key) + + If model IsNot Nothing Then + model.HasContactPossibility = hasContactPossibility + Me.StoreAndSave(model) + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = rep.FullUrl} + + Return jr + + End Function + +#End Region + +End Class diff --git a/OpenAntrag/Controllers/NotificationsApiController.vb b/OpenAntrag/Controllers/NotificationsApiController.vb new file mode 100644 index 0000000..a7f53e6 --- /dev/null +++ b/OpenAntrag/Controllers/NotificationsApiController.vb @@ -0,0 +1,33 @@ +Imports System.Net +Imports System.Web.Http +Imports Raven.Client.Util + +Public Class NotificationsApiController + Inherits ApiController + + Public Function GetTypeList() As IEnumerable(Of KeyValueObject) + + Dim values() As Integer = CType([Enum].GetValues(GetType(NotificationTypes)), Integer()) + + Dim query = From v As Integer In values + Select New KeyValueObject With {.Key = v, + .Value = Notifications.GetTypeStringPlural(v)} + + Return query + + End Function + + Public Function GetLast(count As Integer) As IEnumerable(Of Notification) + + Return Notifications.GetItemsPage(-1, 1, count) + + End Function + + Public Function GetLastByType(typeId As Integer, + count As Integer) As IEnumerable(Of Notification) + + Return Notifications.GetItemsPage(typeId, 1, count) + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntrag/Controllers/NotificationsController.vb b/OpenAntrag/Controllers/NotificationsController.vb new file mode 100644 index 0000000..f7f33ff --- /dev/null +++ b/OpenAntrag/Controllers/NotificationsController.vb @@ -0,0 +1,94 @@ +Imports System.ServiceModel.Syndication + +Public Class NotificationsController + Inherits DocumentStoreController + +#Region "View Actions" + + Public Function Index(type As String) As ActionResult + + Dim typeID As Integer = Notifications.GetTypeId(type) + + Dim lst As List(Of Notification) = Notifications.GetItemsPage(typeID, 1, SettingsWrapper.NotificationPageCount) + + ViewData("Type") = type + ViewData("TypeId") = typeID + Return View(lst) + + End Function + + Public Function Feed(type As String) As FeedResult + + Dim typeID As Integer = Notifications.GetTypeId(type) + + Dim lst As List(Of Notification) = Notifications.GetItemsPage(typeID, 1, SettingsWrapper.NotificationPageCount) + + Dim items As IEnumerable(Of SyndicationItem) = Nothing + + If lst IsNot Nothing Then + items = From nf As Notification In lst + Select nf.FeedItem + End If + + Dim strFeedType As String = "Alle" + If typeID > -1 Then + strFeedType = Notifications.GetTypeStringPlural(typeID) + End If + + Dim oFeed As New SyndicationFeed(String.Concat("OpenAntrag-Mitteilungen (", strFeedType, ")"), + String.Concat("Alle Mitteilungen ", HttpContext.Request.Url.Authority), + New Uri(String.Concat("http://", HttpContext.Request.Url.Authority, "/mitteilungen/feed")), + "", DateTime.Now, items) With {.Language = "de-DE"} + + Return New FeedResult(New Rss20FeedFormatter(oFeed)) + + End Function + +#End Region + +#Region "Service Actions" + + + + Public Function GetNewPostPartial() As JsonResult + Return Me.GetPartialModel("NewPost", (New Notification)) + End Function + + + + Public Function CreateNewPost(sTitle As String, sText As String) As JsonResult + + NotificationManager.StoreNewPost(sTitle, sText) + TwitterManager.TweetNewPost(sTitle, sText) + PushbulletManager.SendNewPost(sTitle, sText) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = "/mitteilungen"} + + Return jr + + End Function + + + Public Function GetMoreNotifications(type As Integer, + page As Integer) As JsonResult + + Dim lst As List(Of Notification) = Notifications.GetItemsPage(type, page, SettingsWrapper.NotificationPageCount) + + Dim strHtml As String = "" + If lst.Count > 0 Then + strHtml = Me.RenderPartialViewToString("_NotificationPartial", lst) + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = strHtml} + + Return jr + + End Function + +#End Region + +End Class \ No newline at end of file diff --git a/OpenAntrag/Controllers/ProposalApiController.vb b/OpenAntrag/Controllers/ProposalApiController.vb new file mode 100644 index 0000000..f3ce685 --- /dev/null +++ b/OpenAntrag/Controllers/ProposalApiController.vb @@ -0,0 +1,198 @@ +Imports System.Net +Imports System.Web.Http +Imports System.Net.Http + +Public Class ProposalApiController + Inherits ApiController + + Public Function GetCount(key As String) As Integer + + Select Case key.ToUpper + Case "ALL" + Return Proposals.GetItemsCount() + Case Else + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + 'Dim lst As List(Of Proposal) = Proposals.GetByRepresentation(rep) + Dim intCount As Integer = Proposals.GetItemsCountByRepresentation(rep) + Return intCount + End Select + + End Function + + Public Function GetTop(key As String, + count As Integer) As IEnumerable(Of Proposal) + + Dim lst As List(Of Proposal) + + Select Case key.ToUpper + Case "ALL" + lst = Proposals.GetItemsTop(count) + Case Else + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + If rep Is Nothing Then Throw New HttpResponseException(HttpStatusCode.NotFound) + + lst = Proposals.GetItemsTopByRepresentation(rep, count) + End Select + + For Each ps As Proposal In lst + ps.FillProcessSteps() + Next + + Return lst + + End Function + + Public Function GetPage(key As String, + pageNo As Integer, + pageCount As Integer) As IEnumerable(Of Proposal) + + Dim lst As List(Of Proposal) + + Select Case key.ToUpper + Case "ALL" + lst = Proposals.GetItemsPage(pageNo, pageCount) + Case Else + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + If rep Is Nothing Then Throw New HttpResponseException(HttpStatusCode.NotFound) + + lst = Proposals.GetItemsPageByRepresentation(rep, pageNo, pageCount) + End Select + + For Each ps As Proposal In lst + ps.FillProcessSteps() + Next + + Return lst + + End Function + + Public Function GetByTag(key As String, + tag As String) As IEnumerable(Of Proposal) + + Dim proptag As ProposalTag = ProposalTags.GetTag(tag) + + If proptag Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Dim lst As List(Of Proposal) + + Select Case key.ToUpper + Case "ALL" + lst = Proposals.GetItemsByTag(proptag) + Case Else + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + If rep Is Nothing Then Throw New HttpResponseException(HttpStatusCode.NotFound) + + lst = Proposals.GetItemsByTagAndRepresentation(rep, proptag) + End Select + + For Each ps As Proposal In lst + ps.FillProcessSteps() + Next + + Return lst + + End Function + + Public Function GetById(id As String) As Proposal + + Dim prop As Proposal = Proposals.GetById(id) + + If prop Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return prop + + End Function + + Public Function GetByTitleUrl(key As String, + titleUrl As String) As Proposal + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + If rep Is Nothing Then Throw New HttpResponseException(HttpStatusCode.NotFound) + + Dim prop As Proposal = Proposals.GetByTitleUrl(rep, titleUrl) + + If prop Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return prop + + End Function + + Public Function GetComments(id As String) As IEnumerable(Of ProposalComment) + + Dim prop As Proposal = Proposals.GetById(id) + + If prop Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return prop.ProposalComments + + End Function + + Public Function GetTags() As IEnumerable(Of String) + + Return ProposalTags.TagsList() + + End Function + + Public Function PostNew( dto As ProposalDTO) As HttpResponseMessage + + Dim rep As Representation = GlobalData.Representations.GetByKey(dto.Key_Representation.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Falscher Representation-Key")) + End If + + If rep.ApiKey.Equals(dto.ApiKey) = False Then + Throw New HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Falscher Api-Key")) + End If + + Dim prop As Proposal = Proposals.CreateNew(dto.Key_Representation, + dto.Title, + dto.Text, + dto.TagList, + Nothing) + + Dim response = Request.CreateResponse(Of Proposal)(HttpStatusCode.Created, prop) + + 'Dim uri As String = prop.FullUrl + 'response.Headers.Location = New Uri(uri) + + Return response + + End Function + + Public Function PostNextStep( dto As ProposalNextStepDTO) As HttpResponseMessage + + Dim rep As Representation = GlobalData.Representations.GetByKey(dto.Key_Representation.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Falscher Representation-Key")) + End If + + Dim prop As Proposal = Proposals.GetById(dto.ID_Proposal) + + If prop Is Nothing Then + Throw New HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Falsche Proposal-ID")) + End If + + Proposals.SaveNextStep(prop, + dto.ID_ProcessStep, + dto.InfoText, + dto.Key_Representative, + dto.Key_Committee) + + + Dim response = Request.CreateResponse(Of Proposal)(HttpStatusCode.Created, prop) + + Return response + + End Function + +End Class diff --git a/OpenAntrag/Controllers/RepresentationApiController.vb b/OpenAntrag/Controllers/RepresentationApiController.vb new file mode 100644 index 0000000..a55cad3 --- /dev/null +++ b/OpenAntrag/Controllers/RepresentationApiController.vb @@ -0,0 +1,91 @@ +Imports System.Net +Imports System.Web.Http + +Public Class RepresentationApiController + Inherits ApiController + + Public Function GetKeyValueList() As IEnumerable(Of KeyValueObject) + + Dim query = (From rep As Representation In GlobalData.Representations.Items + Where rep.IsTest = False + Order By rep.Name + Select New KeyValueObject() With {.Key = rep.Key, .Value = rep.Name}).ToList + + Return query + + End Function + + Public Function GetAll() As IEnumerable(Of Representation) + + Dim query = From r As Representation In GlobalData.Representations.Items + Where r.IsTest = False + Select r + + Return query + + End Function + + Public Function GetByKey(key As String) As Representation + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return rep + + End Function + + Public Function GetRepresentatives(key As String) As IEnumerable(Of Representative) + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return rep.Representatives + + End Function + + Public Function GetCommittees(key As String) As IEnumerable(Of Committee) + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return rep.Committees + + End Function + + Public Function GetProcessSteps(key As String) As IEnumerable(Of ProcessStep) + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + + If rep Is Nothing Then + Throw New HttpResponseException(HttpStatusCode.NotFound) + End If + + Return rep.ProcessSteps + + End Function + + Public Function GetProcessStepById(key As String, id As String) As ProcessStep + + Dim rep As Representation = GlobalData.Representations.GetByKey(key.ToLower) + Dim query = From ps As ProcessStep In rep.ProcessSteps + Where ps.ID = CType(id, Integer) + Select ps + + If query.Count > 0 Then + Return query.First() + Else + Return Nothing + End If + + End Function + +End Class diff --git a/OpenAntrag/Controllers/RepresentationController.vb b/OpenAntrag/Controllers/RepresentationController.vb new file mode 100644 index 0000000..b130f17 --- /dev/null +++ b/OpenAntrag/Controllers/RepresentationController.vb @@ -0,0 +1,706 @@ +Imports System.ServiceModel.Syndication + +Public Class RepresentationController + Inherits DocumentStoreController + +#Region "View Actions" + + Public Function Index(keyRepresentation As String) As ActionResult + + 'Dim xxx As String = Representations.GetNewApiKey() + 'Stop + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Return View(rep) + + End Function + + Public Function Add(keyRepresentation As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Return View(rep) + + End Function + + Public Function Journal(keyRepresentation As String, pageNo As Integer) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + ViewData("PageNo") = pageNo + Return View(rep) + + End Function + + Public Function List(keyRepresentation As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Return View(rep) + + End Function + + Public Function Banner(keyRepresentation As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Return View(rep) + + End Function + + + Public Function Settings(keyRepresentation As String) As ActionResult + + If Tools.IsAdmin(keyRepresentation) = True Then + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + Return View(rep) + Else + Return RedirectToAction("Index", "Representation", New With {.keyRepresentation = keyRepresentation}) + End If + + End Function + + Public Function Proposal(keyRepresentation As String, titleUrl As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Dim model As Proposal = Nothing + + model = Proposals.GetByTitleUrl(rep, titleUrl) + If model IsNot Nothing Then + model.FillProcessSteps() + + Return View(model) + Else + Throw New HttpException(404, "Diese Seite existiert nicht") + End If + + End Function + + Public Function SuccessStory(keyRepresentation As String, titleUrl As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + ViewBag.CurrentRepresentation = rep + + Dim prop As Proposal = Nothing + + prop = Proposals.GetByTitleUrl(rep, titleUrl) + If prop IsNot Nothing Then + prop.FillProcessSteps() + + Dim model As SuccessStory = SuccessStories.GetById(prop.ID_SuccessStory) + model.Proposal = prop + + Return View(model) + Else + Throw New HttpException(404, "Diese Seite existiert nicht") + End If + + End Function + + Public Function RepresentationStyle(keyRepresentation As String) As ActionResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + + Dim strTemplatePath As String = HttpContext.Server.MapPath("~/Content/style-representation.template.css") + Dim strTemplate As String = Nothing + If System.IO.File.Exists(strTemplatePath) = True Then + strTemplate = System.IO.File.ReadAllText(strTemplatePath) + End If + + Dim stb As New StringBuilder() + + stb.Append(strTemplate) + Representations.ReplaceStyleColor(rep, stb) + + Return Content(stb.ToString, "text/css") + + End Function + + Public Function ProposalFeed(keyRepresentation As String) As FeedResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + + Dim lst As List(Of Proposal) = Proposals.GetItemsTopByRepresentation(rep, 25) + + Dim items As IEnumerable(Of SyndicationItem) = Nothing + + If lst IsNot Nothing Then + items = From prop As Proposal In lst + Select prop.FeedItem + End If + + Dim feed As New SyndicationFeed(String.Concat("OpenAntrag-Feed ", rep.Name), + String.Concat("Alle Bürgeranträge, gestellt an ", rep.GroupName), + New Uri(String.Concat("http://", HttpContext.Request.Url.Authority, "/", rep.Key, "/feed")), + "", DateTime.Now, items) With {.Language = "de-DE"} + + Return New FeedResult(New Rss20FeedFormatter(feed)) + + End Function + +#End Region + +#Region "Service Actions" + + + Public Function CreateProposal(keyRepresentation As String, + title As String, + text As String, + contactInfo As String) As JsonResult + + Dim model As Proposal = Proposals.CreateNew(keyRepresentation, title, text, "", contactInfo) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = model.FullUrl} + + Return jr + + End Function + + + + Public Function SaveProposalText(idProposal As String, + sText As String) As JsonResult + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + model.Text = sText + StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function SaveProposalRating(idProposal As String, + iRate As Integer) As JsonResult + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + model.RatingCount += 1 + model.RatingSum += iRate + StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function SaveProposalDate(idProposal As String, + sDate As String) As JsonResult + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + If IsDate(sDate) = True Then + model.CreatedAt = sDate + model.Timestamp = Tools.GetUnixTimestampFromDate(CType(model.CreatedAt, DateTime)) + StoreAndSave(model) + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function SaveProposalStepDate(idProposal As String, + idStep As Integer, + sDate As String) As JsonResult + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + If IsDate(sDate) = True And idStep > 0 Then + + Dim query = From ps As ProposalStep In model.ProposalSteps + Where ps.Id = idStep + Select ps + + If query.Count > 0 Then + Dim ps As ProposalStep = query.First + ps.CreatedAt = sDate + ps.Timestamp = Tools.GetUnixTimestampFromDate(CType(model.CreatedAt, DateTime)) + StoreAndSave(model) + End If + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function SaveProposalStepText(idProposal As String, + idStep As Integer, + sInfo As String) As JsonResult + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + If idStep > 0 Then + + Dim query = From ps As ProposalStep In model.ProposalSteps + Where ps.Id = idStep + Select ps + + If query.Count > 0 Then + Dim ps As ProposalStep = query.First + ps.Info = sInfo + StoreAndSave(model) + End If + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function DeleteProposal(idProposal As String) As JsonResult + + 'geht so nicht wg. unterschiedlicher Session... + 'Dim model As Proposal = Proposals.GetById(idProposal) + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + + If model Is Nothing Then + Throw New CustomException("Antrag nicht gefunden") + End If + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + Me.DocumentSession.Delete(model) + Me.DocumentSession.SaveChanges() + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = model.Representation.FullUrl} + + Return jr + + End Function + + + + Public Function DeleteProposalStep(idProposal As String, idStep As Integer) As JsonResult + + 'geht so nicht wg. unterschiedlicher Session... + 'Dim model As Proposal = Proposals.GetById(idProposal) + + Dim model As Proposal = Me.DocumentSession.Load(Of Proposal)(idProposal) + If model Is Nothing Then Throw New CustomException("Antrag nicht gefunden") + + If Tools.IsAdmin(model.Key_Representation) = False Then + Throw New CustomException("Für diesen Vorgang hast Du keine Berechtigung") + End If + + Dim psRemove As ProposalStep = (From ps As ProposalStep In model.ProposalSteps + Order By ps.Id + Select ps).Last + + If psRemove Is Nothing OrElse psRemove.Id <> idStep Then + Throw New CustomException("Antragsschritt nicht gefunden oder er ist nicht der letzte") + End If + + If psRemove.Id = 1 Then + Throw New CustomException("Der Eingangsschritt kann nicht gelöscht werden") + End If + + model.ProposalSteps.Remove(psRemove) + + Dim psLast As ProposalStep = (From ps As ProposalStep In model.ProposalSteps + Order By ps.Id + Select ps).Last + + model.ID_CurrentProposalStep = psLast.Id + + Me.DocumentSession.Store(model) + Me.DocumentSession.SaveChanges() + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = model.FullUrl} + + Return jr + + End Function + + + Public Function CreateProposalComment(idProposal As String, + commentBy As String, + commentText As String) As JsonResult + + Dim model As Proposal = Proposals.GetById(idProposal) + + If model Is Nothing Then + Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + End If + + If model.ProposalComments Is Nothing Then + model.ProposalComments = New List(Of ProposalComment) + End If + + Dim pc As New ProposalComment With {.ID_Proposal = idProposal, + .CommentedAt = DateAndTime.Now.ToString, + .CommentedBy = commentBy, + .Comment = commentText.EnsureMarkdown} + + model.ProposalComments.Add(pc) + + Me.StoreAndSave(model) + + MailManager.SendNewProposalComment(pc, model) + 'PushoverManager.SendNewProposalComment(pc, model) + NotificationManager.StoreNewProposalComment(pc, model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_ProposalCommentPartial", pc)} + + Return jr + + End Function + + + + Public Function DeleteProposalComment(proposalId As String, + commentedby As String, + timeStamp As Integer) As JsonResult + + Dim model As Proposal = Proposals.GetById(proposalId) + If model Is Nothing Then Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + + Dim rep As Representation = model.Representation + + If Tools.IsAdmin(rep.Key) = False Then + Throw New CustomException("Dazu fehlt Dir die Berechtigung") + End If + + Dim query = From c As ProposalComment In model.ProposalComments + Where c.CommentedBy.ToLower = commentedby.ToLower And c.CommentedAtTimestamp = timeStamp + Select c + + If query.Count > 0 Then + Dim pc As ProposalComment = query.First + model.ProposalComments.Remove(pc) + End If + + Me.StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function GetNextStepHtml(keyRepresentation As String, + idStep As Integer) As JsonResult + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + Dim ps As ProcessStep = Nothing + + Dim query = From p As ProcessStep In rep.ProcessSteps + Where p.ID = idStep + Select p + + If query.Count > 0 Then + ps = query.First + Else + Throw New Exception("Der Prozessschritt konnte nicht geladen werden") + End If + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_NextStepPartial", ps)} + + Return jr + + End Function + + + + Public Function SaveNextStep(idProposal As String, + keyRepresentation As String, + idStep As Integer, + info As String, + options As String) As JsonResult + + Dim model As Proposal = Proposals.GetById(idProposal) + + If model Is Nothing Then + Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + End If + + Dim keyRepresentative As String = Nothing + Dim keyCommittee As String = Nothing + + Dim aOptions As String() = options.Split(",") + For Each s As String In aOptions + Dim aOption As String() = s.Split("|") 'siehe representation.js > saveNextStep + Select Case aOption(0) 'siehe ProcessStep.GetCaptionHtml + Case "Key_Representative" : keyRepresentative = aOption(1) + Case "Key_Committee" : keyCommittee = aOption(1) + End Select + Next + + Proposals.SaveNextStep(model, idStep, info, + keyRepresentative, + keyCommittee) + + NotificationManager.StoreNextProposalStep(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function SendProposalAbuseNotice(idProposal As String, + abuseNotice As String) As JsonResult + + Dim model As Proposal = Proposals.GetById(idProposal) + + If model Is Nothing Then + Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + End If + + Dim pan As New ProposalAbuseNotice(model, abuseNotice) + MailManager.SendNewProposalAbuseNotice(pan) + PushoverManager.SendNewProposalAbuseNotice(pan) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function SaveProposalAbuseMessage(idProposal As String, + abuseMessage As String) As JsonResult + + Dim model As Proposal = Proposals.GetById(idProposal) + + If model Is Nothing Then + Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + End If + + model.AbuseMessage = abuseMessage + + Me.StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function SaveCommentingStatus(idProposal As String, + lock As Boolean) As JsonResult + + Dim model As Proposal = Proposals.GetById(idProposal) + + If model Is Nothing Then + Throw New Exception("Ein Antrag mit der angegebenen ID wurde nicht gefunden") + End If + + If lock = True Then + model.CommentingClosedDate = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + Else + model.CommentingClosedDate = "" + End If + + Me.StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + Public Function GetProposalTags() As JsonResult + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ProposalTags.TagsOrdered} + + Return jr + + End Function + + + Public Function GetTagCloudItems() As JsonResult + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ProposalTags.TagCloudItems} + + Return jr + + End Function + + + + Public Function SaveProposalTags(idProposal As String, + tagList As String) As JsonResult + + Dim prop As Proposal = Proposals.GetById(idProposal) + Dim tags As ProposalTags = ProposalTags.Load() + + Try + Proposals.SaveTags(prop, tags, tagList) + + Me.StoreAndSave(prop) + Me.StoreAndSave(tags) + + Catch ex As Exception + Throw ex + End Try + + 'Rückgabe... + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_ProposalTagListPartial", prop)} + + Return jr + + End Function + + + + Public Function SetSuccessStoryStatus(idProposal As String, + status As Integer) + + Dim model As Proposal = Proposals.GetById(idProposal) + model.SuccessStoryStatus = status + Me.StoreAndSave(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + + + + Public Function CreateSuccessStory(idProposal As String, + title As String, + stepDate As String, + text As String) As JsonResult + + Dim prop As Proposal = Proposals.GetById(idProposal) + + Dim sShortUrl As String = UrlShortener.GetShortUrl(String.Concat(prop.FullUrl, "/erfolg")) + + Dim model As New SuccessStory With { + .ID_Proposal = idProposal, + .Title = title, + .StepDate = stepDate, + .Text = text, + .ShortUrl = sShortUrl + } + Me.StoreAndSave(model) + + prop.SuccessStoryStatus = 1 + prop.ID_SuccessStory = model.Id + Me.StoreAndSave(prop) + + PushoverManager.SendNewSuccessStory(model) + TwitterManager.TweetNewSuccessStory(model) + NotificationManager.StoreNewSuccessStory(model) + PushbulletManager.SendNewSuccessStory(model) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = ""} + + Return jr + + End Function + +#End Region + +End Class \ No newline at end of file diff --git a/OpenAntrag/Controllers/StatisticsController.vb b/OpenAntrag/Controllers/StatisticsController.vb new file mode 100644 index 0000000..d9b3a99 --- /dev/null +++ b/OpenAntrag/Controllers/StatisticsController.vb @@ -0,0 +1,21 @@ +Imports Raven.Client + +Public Class StatisticsController + Inherits CommonController + + Public Function Index(ByVal statPart As String) As ActionResult + + If String.IsNullOrEmpty(statPart) = True Then + statPart = "ProposalCountByRepresentation" + ViewData("StatScroll") = False + Else + ViewData("StatScroll") = True + End If + + ViewData("StatPartial") = statPart + + Return View() + + End Function + +End Class diff --git a/OpenAntrag/Controllers/TeaserController.vb b/OpenAntrag/Controllers/TeaserController.vb new file mode 100644 index 0000000..3e28865 --- /dev/null +++ b/OpenAntrag/Controllers/TeaserController.vb @@ -0,0 +1,45 @@ +Imports System.Web.Mvc + +Public Class TeaserController + Inherits Controller + + Function Index(keyTeaser As String) As ActionResult + + Dim tsr As Teaser = (New Teasers).GetByKey(keyTeaser.ToLower) + ViewBag.CurrentTeaser = tsr + + If String.IsNullOrEmpty(tsr.KeyRepresenation) = False Then + Dim rep As Representation = GlobalData.Representations.GetByKey(tsr.KeyRepresenation) + If rep IsNot Nothing Then + Return RedirectToActionPermanent("Index", "Representation", + New With {.keyRepresentation = tsr.KeyRepresenation}) + Else + Return Nothing + End If + Else + Return View(tsr) + End If + + End Function + + Public Function TeaserStyle(keyTeaser As String) As ActionResult + + Dim tsr As Teaser = (New Teasers).GetByKey(keyTeaser.ToLower) + + Dim strTemplatePath As String = HttpContext.Server.MapPath("~/Content/style-teaser.template.css") + Dim strTemplate As String = Nothing + If System.IO.File.Exists(strTemplatePath) = True Then + strTemplate = System.IO.File.ReadAllText(strTemplatePath) + End If + + Dim stb As New StringBuilder() + + stb.Append(strTemplate) + Teasers.ReplaceStyleColor(tsr, stb) + + Return Content(stb.ToString, "text/css") + + End Function + + +End Class \ No newline at end of file diff --git a/OpenAntrag/Downloads/OpenAntrag-FraktionRegistrieren.xls b/OpenAntrag/Downloads/OpenAntrag-FraktionRegistrieren.xls new file mode 100644 index 0000000..4da1adb Binary files /dev/null and b/OpenAntrag/Downloads/OpenAntrag-FraktionRegistrieren.xls differ diff --git a/OpenAntrag/Fonts/BebasNeue-webfont.eot b/OpenAntrag/Fonts/BebasNeue-webfont.eot new file mode 100644 index 0000000..23df258 Binary files /dev/null and b/OpenAntrag/Fonts/BebasNeue-webfont.eot differ diff --git a/OpenAntrag/Fonts/BebasNeue-webfont.svg b/OpenAntrag/Fonts/BebasNeue-webfont.svg new file mode 100644 index 0000000..df90beb --- /dev/null +++ b/OpenAntrag/Fonts/BebasNeue-webfont.svg @@ -0,0 +1,245 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2010 by Ryoichi Tsunekawa All rights reserved +Designer : Ryoichi Tsunekawa +Foundry : Ryoichi Tsunekawa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/Fonts/BebasNeue-webfont.ttf b/OpenAntrag/Fonts/BebasNeue-webfont.ttf new file mode 100644 index 0000000..072487c Binary files /dev/null and b/OpenAntrag/Fonts/BebasNeue-webfont.ttf differ diff --git a/OpenAntrag/Fonts/BebasNeue-webfont.woff b/OpenAntrag/Fonts/BebasNeue-webfont.woff new file mode 100644 index 0000000..5ff9da7 Binary files /dev/null and b/OpenAntrag/Fonts/BebasNeue-webfont.woff differ diff --git a/OpenAntrag/Fonts/Flaticon/adobe21.png b/OpenAntrag/Fonts/Flaticon/adobe21.png new file mode 100644 index 0000000..dbc9677 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/adobe21.png differ diff --git a/OpenAntrag/Fonts/Flaticon/adobe21.svg b/OpenAntrag/Fonts/Flaticon/adobe21.svg new file mode 100644 index 0000000..812022d --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/adobe21.svg @@ -0,0 +1,26 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/css2.png b/OpenAntrag/Fonts/Flaticon/css2.png new file mode 100644 index 0000000..c1b7755 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/css2.png differ diff --git a/OpenAntrag/Fonts/Flaticon/css2.svg b/OpenAntrag/Fonts/Flaticon/css2.svg new file mode 100644 index 0000000..a28fae5 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/css2.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/excel2.png b/OpenAntrag/Fonts/Flaticon/excel2.png new file mode 100644 index 0000000..2fc78c5 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/excel2.png differ diff --git a/OpenAntrag/Fonts/Flaticon/excel2.svg b/OpenAntrag/Fonts/Flaticon/excel2.svg new file mode 100644 index 0000000..e31a289 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/excel2.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.css b/OpenAntrag/Fonts/Flaticon/flaticon.css new file mode 100644 index 0000000..1c4221e --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/flaticon.css @@ -0,0 +1,25 @@ +@font-face { + font-family: "Flaticon"; + src: url("flaticon.eot"); + src: url("flaticon.eot#iefix") format("embedded-opentype"), + url("flaticon.woff") format("woff"), + url("flaticon.ttf") format("truetype"), + url("flaticon.svg") format("svg"); + font-weight: normal; + font-style: normal; +} +[class^="flaticon-"]:before, [class*=" flaticon-"]:before, +[class^="flaticon-"]:after, [class*=" flaticon-"]:after { + font-family: Flaticon; + font-size: 20px; + font-style: normal; + margin-left: 0; + margin-right: 5px; +} +.flaticon-adobe21:before { content: "\e000"; } +.flaticon-css2:before { content: "\e001"; } +.flaticon-excel2:before { content: "\e002"; } +.flaticon-open92:before { content: "\e003"; } +.flaticon-word2:before { content: "\e004"; } +.flaticon-xml3:before { content: "\e005"; } +.flaticon-zip1:before { content: "\e006"; } diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.eot b/OpenAntrag/Fonts/Flaticon/flaticon.eot new file mode 100644 index 0000000..2011e61 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/flaticon.eot differ diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.html b/OpenAntrag/Fonts/Flaticon/flaticon.html new file mode 100644 index 0000000..2ab6b66 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/flaticon.html @@ -0,0 +1,285 @@ + + + + + Flaticon WebFont + + + + + + +
+

+ + FLATICON + Font Demo +

+
+ +
+
+ +
Instructions:
+ +
    +
  • +

    + 1Copy the "Fonts" files and CSS files to your website CSS folder. +

  • +
  • +

    + 2Add the CSS link to your website source code on header. +
    + <head> +
    ... +
    <link rel="stylesheet" type="text/css" href="your_website_domain/css_root/flaticon.css"> +
    ... +
    </head>
    +

  • + +
  • +

    + 3Use the icon class on "display:inline" elements: +
    + Use example: <i class="flaticon-airplane49"></i> or <span class="flaticon-airplane49"></span> +

  • +
+
+ +
+ +
+
+
.flaticon-adobe21
Author: Icomoon
+
+
.flaticon-css2
Author: Icomoon
+
+
.flaticon-excel2
Author: Icomoon
+
+
.flaticon-open92
Author: Icomoon
+
+
.flaticon-word2
Author: Icomoon
+
+
.flaticon-xml3
Author: Icomoon
+
+
.flaticon-zip1
Author: Icomoon
+ +
+ +
License and attribution:
Font generated by flaticon.com + under CC BY. The authors are: Icomoon.
Copy the Attribution License:
+ + + +
+ +
+
Examples:
+

<i class="flaticon-adobe21"></i>

<i class="flaticon-css2"></i>

<i class="flaticon-excel2"></i>

<i class="flaticon-open92"></i>

<i class="flaticon-word2"></i>

<span class="flaticon-xml3"></span>

<span class="flaticon-zip1"></span>

+
+ + + \ No newline at end of file diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.svg b/OpenAntrag/Fonts/Flaticon/flaticon.svg new file mode 100644 index 0000000..f6ca199 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/flaticon.svg @@ -0,0 +1,3 @@ + + + diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.ttf b/OpenAntrag/Fonts/Flaticon/flaticon.ttf new file mode 100644 index 0000000..9be5ba6 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/flaticon.ttf differ diff --git a/OpenAntrag/Fonts/Flaticon/flaticon.woff b/OpenAntrag/Fonts/Flaticon/flaticon.woff new file mode 100644 index 0000000..73c7a2e Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/flaticon.woff differ diff --git a/OpenAntrag/Fonts/Flaticon/open92.png b/OpenAntrag/Fonts/Flaticon/open92.png new file mode 100644 index 0000000..fc14b1f Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/open92.png differ diff --git a/OpenAntrag/Fonts/Flaticon/open92.svg b/OpenAntrag/Fonts/Flaticon/open92.svg new file mode 100644 index 0000000..05e5b23 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/open92.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/word2.png b/OpenAntrag/Fonts/Flaticon/word2.png new file mode 100644 index 0000000..46bb321 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/word2.png differ diff --git a/OpenAntrag/Fonts/Flaticon/word2.svg b/OpenAntrag/Fonts/Flaticon/word2.svg new file mode 100644 index 0000000..73db5b8 --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/word2.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/xml3.png b/OpenAntrag/Fonts/Flaticon/xml3.png new file mode 100644 index 0000000..d4e1c00 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/xml3.png differ diff --git a/OpenAntrag/Fonts/Flaticon/xml3.svg b/OpenAntrag/Fonts/Flaticon/xml3.svg new file mode 100644 index 0000000..c3e612f --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/xml3.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Flaticon/zip1.png b/OpenAntrag/Fonts/Flaticon/zip1.png new file mode 100644 index 0000000..68ab932 Binary files /dev/null and b/OpenAntrag/Fonts/Flaticon/zip1.png differ diff --git a/OpenAntrag/Fonts/Flaticon/zip1.svg b/OpenAntrag/Fonts/Flaticon/zip1.svg new file mode 100644 index 0000000..893522f --- /dev/null +++ b/OpenAntrag/Fonts/Flaticon/zip1.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/OpenAntrag/Fonts/Fontello/LICENSE.txt b/OpenAntrag/Fonts/Fontello/LICENSE.txt new file mode 100644 index 0000000..d38e52e --- /dev/null +++ b/OpenAntrag/Fonts/Fontello/LICENSE.txt @@ -0,0 +1,66 @@ +Font license info + + +## Elusive + + Copyright (C) 2013 by Aristeides Stathopoulos + + Author: Aristeides Stathopoulos + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://aristeides.com/ + + +## Font Awesome + + Copyright (C) 2012 by Dave Gandy + + Author: Dave Gandy + License: SIL () + Homepage: http://fortawesome.github.com/Font-Awesome/ + + +## Entypo + + Copyright (C) 2012 by Daniel Bruce + + Author: Daniel Bruce + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://www.entypo.com + + +## Zocial + + Copyright (C) 2012 by Sam Collins + + Author: Sam Collins + License: MIT (http://opensource.org/licenses/mit-license.php) + Homepage: http://zocial.smcllns.com/ + + +## Modern Pictograms + + Copyright (c) 2012 by John Caserta. All rights reserved. + + Author: John Caserta + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://thedesignoffice.org/project/modern-pictograms/ + + +## MFG Labs + + Copyright (C) 2012 by Daniel Bruce + + Author: MFG Labs + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://www.mfglabs.com/ + + +## Web Symbols + + Copyright (c) 2011 by Just Be Nice studio. All rights reserved. + + Author: Just Be Nice studio + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://www.justbenicestudio.com/ + + diff --git a/OpenAntrag/Fonts/Fontello/README.txt b/OpenAntrag/Fonts/Fontello/README.txt new file mode 100644 index 0000000..43e23f2 --- /dev/null +++ b/OpenAntrag/Fonts/Fontello/README.txt @@ -0,0 +1,75 @@ +This webfont is generated by http://fontello.com open source project. + + +================================================================================ +Please, note, that you should obey original font licences, used to make this +webfont pack. Details available in LICENSE.txt file. + +- Usually, it's enough to publish content of LICENSE.txt file somewhere on your + site in "About" section. + +- If your project is open-source, usually, it will be ok to make LICENSE.txt + file publically available in your repository. + +- Fonts, used in Fontello, don't require to make clickable links on your site. + But any kind of additional authors crediting is welcome. +================================================================================ + + +Comments on archive content +--------------------------- + +- /font/* - fonts in different formats + +- /css/* - different kinds of css, for all situations. Should be ok with + twitter bootstrap. Also, you can skip style and assign icon classes + directly to text elements, if you don't mind about IE7. + +- demo.html - demo file, to show your webfont content + +- LICENSE.txt - license info about source fonts, used to build your one. + +- config.json - keeps your settings. You can import it back to fontello anytime, + to continue your work + + +Why so many CSS files ? +----------------------- + +Because we like to fit all your needs :) + +- basic file, .css - is usually enougth, in contains @font-face + and character codes definition + +- *-ie7.css - if you need IE7 support, but still don't wish to put char codes + directly into html + +- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face + rules, but still wish to benefit of css generation. That can be very + convenient for automated assets build systems. When you need to update font - + no needs to manually edit files, just override old version with archive + content. See fontello source codes for example. + +- *-embedded.css - basic css file, but with embedded WOFF font, to avoid + CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain. + We strongly recommend to resolve this issue by `Access-Control-Allow-Origin` + server headers. But if you ok with dirty hack - this file is for you. Note, + that data url moved to separate @font-face to avoid problems with + + + + + + + + +
+

+ fontello-openantrag + font demo +

+ +
+
+
+
icon-road0xe800
+
icon-group0xe801
+
icon-group-circled0xe802
+
icon-lightbulb0xe803
+
+
+
icon-check0xe804
+
icon-tasks0xe805
+
icon-twitter0xe806
+
icon-right-open0xe807
+
+
+
icon-cancel0xe808
+
icon-level-up0xe809
+
icon-cw0xe80a
+
icon-tag0xe80b
+
+
+
icon-docs0xe80c
+
icon-key0xe80d
+
icon-time0xe80e
+
icon-cog0xe80f
+
+
+
icon-info0xe810
+
icon-plus-circled0xe811
+
icon-right-dir0xe812
+
icon-angle-double-left0xe813
+
+
+
icon-angle-double-right0xe814
+
icon-angle-left0xe815
+
icon-angle-right0xe816
+
icon-ok-circled0xe817
+
+
+
icon-up-circled0xe818
+
icon-network0xe819
+
icon-dot-30xe81a
+
icon-plus0xe81b
+
+
+
icon-email0xe81c
+
icon-left-open0xe81d
+
icon-attention0xe81e
+
icon-thumbs-down0xe81f
+
+
+
icon-down-open0xe820
+
icon-up-open0xe821
+
icon-angle-up0xe822
+
icon-angle-down0xe823
+
+
+
icon-left-dir0xe824
+
icon-up-dir0xe825
+
icon-down-dir0xe826
+
icon-tags0xe827
+
+
+
icon-direction0xe828
+
icon-ok0xe829
+
icon-globe0xe82a
+
icon-comment0xe82b
+
+
+
icon-megaphone0xe82c
+
icon-trash0xe82d
+
icon-chat0xe82e
+
icon-comment-10xe82f
+
+
+
icon-bug0xe830
+
icon-idea0xe831
+
icon-plus-squared0xe832
+
icon-thumbs-up0xe833
+
+
+
icon-rss0xe834
+
icon-info-circled0xe835
+
icon-edit0xe836
+
icon-doc0xe837
+
+
+
icon-calendar0xe838
+
icon-help-circled0xe839
+
icon-menu0xe83a
+
icon-search0xe83b
+
+
+
icon-bullseye0xe83c
+
icon-gplus-squared0xe83d
+
icon-coverflow-empty0xe83e
+
icon-gplus0xe83f
+
+
+
icon-gplus-rect0xe840
+
icon-block0xe841
+
icon-megaphone-10xe842
+
icon-bell0xe843
+
+
+
icon-user0xe844
+
icon-keyboard0xe845
+
icon-phone0xe846
+
icon-book0xe847
+
+
+
icon-star0xe848
+
icon-star-empty0xe849
+
icon-database0xe84a
+
icon-chart-line0xe84b
+
+
+
icon-chart-bar0xe84c
+
icon-edit-10xe84d
+
icon-chart-pie0xe84e
+
icon-home0xe84f
+
+
+
icon-list0xe850
+
icon-bank0xe851
+
icon-rocket0xe852
+
icon-lock0xe853
+
+
+
icon-lock-open0xe854
+
icon-floppy0xe855
+
icon-eye0xe856
+
icon-light-up0xe859
+
+
+ + + \ No newline at end of file diff --git a/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.eot b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.eot new file mode 100644 index 0000000..0ddbc96 Binary files /dev/null and b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.eot differ diff --git a/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.svg b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.svg new file mode 100644 index 0000000..86b61a9 --- /dev/null +++ b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.svg @@ -0,0 +1,99 @@ + + + +Copyright (C) 2014 by original authors @ fontello.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.ttf b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.ttf new file mode 100644 index 0000000..fc907f3 Binary files /dev/null and b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.ttf differ diff --git a/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.woff b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.woff new file mode 100644 index 0000000..d8da12c Binary files /dev/null and b/OpenAntrag/Fonts/Fontello/font/fontello-openantrag.woff differ diff --git a/OpenAntrag/Fonts/PoliticsHeadBold.woff b/OpenAntrag/Fonts/PoliticsHeadBold.woff new file mode 100644 index 0000000..049b6f6 Binary files /dev/null and b/OpenAntrag/Fonts/PoliticsHeadBold.woff differ diff --git a/OpenAntrag/Global.asax b/OpenAntrag/Global.asax new file mode 100644 index 0000000..13a14d6 --- /dev/null +++ b/OpenAntrag/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.vb" Inherits="OpenAntrag.MvcApplication" Language="VB" %> diff --git a/OpenAntrag/Global.asax.vb b/OpenAntrag/Global.asax.vb new file mode 100644 index 0000000..ce6fbdd --- /dev/null +++ b/OpenAntrag/Global.asax.vb @@ -0,0 +1,37 @@ +Imports System.Web.Http +Imports System.Web.Optimization +Imports System.Net.Http.Formatting +Imports System.Net.Http.Headers + +Public Class MvcApplication + Inherits System.Web.HttpApplication + + Sub Application_Start() + + MvcHandler.DisableMvcResponseHeader = True + + AreaRegistration.RegisterAllAreas() + + GlobalConfiguration.Configuration.Formatters.Add( + New CSVMediaTypeFormatter( + New QueryStringMapping("format", "csv", New MediaTypeHeaderValue("text/csv")))) + + GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add( + New QueryStringMapping("format", "json", New MediaTypeHeaderValue("application/json"))) + + GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add( + New QueryStringMapping("format", "xml", New MediaTypeHeaderValue("application/xml"))) + + + 'FormatterConfig.RegisterFormatters(GlobalConfiguration.Configuration.Formatters) + + WebApiConfig.Register(GlobalConfiguration.Configuration) + FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters) + RouteConfig.RegisterRoutes(RouteTable.Routes) + BundleConfig.RegisterBundles(BundleTable.Bundles) + 'AuthConfig.RegisterAuth() + + DataDocumentStore.Initialize() + + End Sub +End Class diff --git a/OpenAntrag/Images/Content/banner-160x220.png b/OpenAntrag/Images/Content/banner-160x220.png new file mode 100644 index 0000000..383854c Binary files /dev/null and b/OpenAntrag/Images/Content/banner-160x220.png differ diff --git a/OpenAntrag/Images/Content/banner-275x80.png b/OpenAntrag/Images/Content/banner-275x80.png new file mode 100644 index 0000000..4d2ba72 Binary files /dev/null and b/OpenAntrag/Images/Content/banner-275x80.png differ diff --git a/OpenAntrag/Images/Content/drupal-banner.png b/OpenAntrag/Images/Content/drupal-banner.png new file mode 100644 index 0000000..2970bcf Binary files /dev/null and b/OpenAntrag/Images/Content/drupal-banner.png differ diff --git a/OpenAntrag/Images/Icons/arrow-down-left.png b/OpenAntrag/Images/Icons/arrow-down-left.png new file mode 100644 index 0000000..6d24b8e Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-down-left.png differ diff --git a/OpenAntrag/Images/Icons/arrow-down-right.png b/OpenAntrag/Images/Icons/arrow-down-right.png new file mode 100644 index 0000000..98d6e3e Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-down-right.png differ diff --git a/OpenAntrag/Images/Icons/arrow-down.png b/OpenAntrag/Images/Icons/arrow-down.png new file mode 100644 index 0000000..b3f420e Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-down.png differ diff --git a/OpenAntrag/Images/Icons/arrow-left.png b/OpenAntrag/Images/Icons/arrow-left.png new file mode 100644 index 0000000..43ff9be Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-left.png differ diff --git a/OpenAntrag/Images/Icons/arrow-right.png b/OpenAntrag/Images/Icons/arrow-right.png new file mode 100644 index 0000000..6d92945 Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-right.png differ diff --git a/OpenAntrag/Images/Icons/arrow-up-left.png b/OpenAntrag/Images/Icons/arrow-up-left.png new file mode 100644 index 0000000..89507ec Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-up-left.png differ diff --git a/OpenAntrag/Images/Icons/arrow-up-right.png b/OpenAntrag/Images/Icons/arrow-up-right.png new file mode 100644 index 0000000..0e1a166 Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-up-right.png differ diff --git a/OpenAntrag/Images/Icons/arrow-up.png b/OpenAntrag/Images/Icons/arrow-up.png new file mode 100644 index 0000000..06be320 Binary files /dev/null and b/OpenAntrag/Images/Icons/arrow-up.png differ diff --git a/OpenAntrag/Images/Icons/step-abgelehnt.png b/OpenAntrag/Images/Icons/step-abgelehnt.png new file mode 100644 index 0000000..76bd8fe Binary files /dev/null and b/OpenAntrag/Images/Icons/step-abgelehnt.png differ diff --git a/OpenAntrag/Images/Icons/step-anfrage.png b/OpenAntrag/Images/Icons/step-anfrage.png new file mode 100644 index 0000000..f3e0366 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-anfrage.png differ diff --git a/OpenAntrag/Images/Icons/step-ausschuss.png b/OpenAntrag/Images/Icons/step-ausschuss.png new file mode 100644 index 0000000..adbe539 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-ausschuss.png differ diff --git a/OpenAntrag/Images/Icons/step-e-antrag.png b/OpenAntrag/Images/Icons/step-e-antrag.png new file mode 100644 index 0000000..93dda2a Binary files /dev/null and b/OpenAntrag/Images/Icons/step-e-antrag.png differ diff --git a/OpenAntrag/Images/Icons/step-eingang.png b/OpenAntrag/Images/Icons/step-eingang.png new file mode 100644 index 0000000..f7b2321 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-eingang.png differ diff --git a/OpenAntrag/Images/Icons/step-einreichung.png b/OpenAntrag/Images/Icons/step-einreichung.png new file mode 100644 index 0000000..7ae1cac Binary files /dev/null and b/OpenAntrag/Images/Icons/step-einreichung.png differ diff --git a/OpenAntrag/Images/Icons/step-entwurf.png b/OpenAntrag/Images/Icons/step-entwurf.png new file mode 100644 index 0000000..10f1fce Binary files /dev/null and b/OpenAntrag/Images/Icons/step-entwurf.png differ diff --git a/OpenAntrag/Images/Icons/step-erledigt.png b/OpenAntrag/Images/Icons/step-erledigt.png new file mode 100644 index 0000000..050b019 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-erledigt.png differ diff --git a/OpenAntrag/Images/Icons/step-feedback.png b/OpenAntrag/Images/Icons/step-feedback.png new file mode 100644 index 0000000..f100c14 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-feedback.png differ diff --git a/OpenAntrag/Images/Icons/step-fraktion.png b/OpenAntrag/Images/Icons/step-fraktion.png new file mode 100644 index 0000000..2e3e3f9 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-fraktion.png differ diff --git a/OpenAntrag/Images/Icons/step-parlament.png b/OpenAntrag/Images/Icons/step-parlament.png new file mode 100644 index 0000000..5370ede Binary files /dev/null and b/OpenAntrag/Images/Icons/step-parlament.png differ diff --git a/OpenAntrag/Images/Icons/step-pruefung.png b/OpenAntrag/Images/Icons/step-pruefung.png new file mode 100644 index 0000000..c7acdbd Binary files /dev/null and b/OpenAntrag/Images/Icons/step-pruefung.png differ diff --git a/OpenAntrag/Images/Icons/step-uebernahme.png b/OpenAntrag/Images/Icons/step-uebernahme.png new file mode 100644 index 0000000..68a872b Binary files /dev/null and b/OpenAntrag/Images/Icons/step-uebernahme.png differ diff --git a/OpenAntrag/Images/Icons/step-vertagt.png b/OpenAntrag/Images/Icons/step-vertagt.png new file mode 100644 index 0000000..47a4cc0 Binary files /dev/null and b/OpenAntrag/Images/Icons/step-vertagt.png differ diff --git a/OpenAntrag/Images/Icons/step_angenommen.png b/OpenAntrag/Images/Icons/step_angenommen.png new file mode 100644 index 0000000..e8734a1 Binary files /dev/null and b/OpenAntrag/Images/Icons/step_angenommen.png differ diff --git a/OpenAntrag/Images/Icons/step_voting.png b/OpenAntrag/Images/Icons/step_voting.png new file mode 100644 index 0000000..5289879 Binary files /dev/null and b/OpenAntrag/Images/Icons/step_voting.png differ diff --git a/OpenAntrag/Images/Icons/step_voting_OLD.png b/OpenAntrag/Images/Icons/step_voting_OLD.png new file mode 100644 index 0000000..319c4a3 Binary files /dev/null and b/OpenAntrag/Images/Icons/step_voting_OLD.png differ diff --git a/OpenAntrag/Images/IntroBack/api-1200.jpg b/OpenAntrag/Images/IntroBack/api-1200.jpg new file mode 100644 index 0000000..f06e6e3 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/api-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/api-770.jpg b/OpenAntrag/Images/IntroBack/api-770.jpg new file mode 100644 index 0000000..e59a168 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/api-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/api-980.jpg b/OpenAntrag/Images/IntroBack/api-980.jpg new file mode 100644 index 0000000..08518ff Binary files /dev/null and b/OpenAntrag/Images/IntroBack/api-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/api-full.jpg b/OpenAntrag/Images/IntroBack/api-full.jpg new file mode 100644 index 0000000..4a1c47f Binary files /dev/null and b/OpenAntrag/Images/IntroBack/api-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/error-1200.jpg b/OpenAntrag/Images/IntroBack/error-1200.jpg new file mode 100644 index 0000000..765940c Binary files /dev/null and b/OpenAntrag/Images/IntroBack/error-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/error-770.jpg b/OpenAntrag/Images/IntroBack/error-770.jpg new file mode 100644 index 0000000..519ace4 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/error-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/error-980.jpg b/OpenAntrag/Images/IntroBack/error-980.jpg new file mode 100644 index 0000000..3fbfe5b Binary files /dev/null and b/OpenAntrag/Images/IntroBack/error-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/error-full.jpg b/OpenAntrag/Images/IntroBack/error-full.jpg new file mode 100644 index 0000000..dcac0e8 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/error-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/faq-1200.jpg b/OpenAntrag/Images/IntroBack/faq-1200.jpg new file mode 100644 index 0000000..dbaad33 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/faq-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/faq-770.jpg b/OpenAntrag/Images/IntroBack/faq-770.jpg new file mode 100644 index 0000000..b7426f5 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/faq-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/faq-980.jpg b/OpenAntrag/Images/IntroBack/faq-980.jpg new file mode 100644 index 0000000..bc66de2 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/faq-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/faq-full.jpg b/OpenAntrag/Images/IntroBack/faq-full.jpg new file mode 100644 index 0000000..78b28bd Binary files /dev/null and b/OpenAntrag/Images/IntroBack/faq-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/feedback-1200.jpg b/OpenAntrag/Images/IntroBack/feedback-1200.jpg new file mode 100644 index 0000000..5056a08 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/feedback-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/feedback-770.jpg b/OpenAntrag/Images/IntroBack/feedback-770.jpg new file mode 100644 index 0000000..980d7d1 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/feedback-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/feedback-980.jpg b/OpenAntrag/Images/IntroBack/feedback-980.jpg new file mode 100644 index 0000000..406003a Binary files /dev/null and b/OpenAntrag/Images/IntroBack/feedback-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/feedback-full.jpg b/OpenAntrag/Images/IntroBack/feedback-full.jpg new file mode 100644 index 0000000..152c1f9 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/feedback-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/home-1200.jpg b/OpenAntrag/Images/IntroBack/home-1200.jpg new file mode 100644 index 0000000..7c1445c Binary files /dev/null and b/OpenAntrag/Images/IntroBack/home-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/home-770.jpg b/OpenAntrag/Images/IntroBack/home-770.jpg new file mode 100644 index 0000000..4cd2dc6 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/home-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/home-980.jpg b/OpenAntrag/Images/IntroBack/home-980.jpg new file mode 100644 index 0000000..9b40cf7 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/home-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/home-full.jpg b/OpenAntrag/Images/IntroBack/home-full.jpg new file mode 100644 index 0000000..f6449c6 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/home-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/list-1200.jpg b/OpenAntrag/Images/IntroBack/list-1200.jpg new file mode 100644 index 0000000..0463ccc Binary files /dev/null and b/OpenAntrag/Images/IntroBack/list-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/list-770.jpg b/OpenAntrag/Images/IntroBack/list-770.jpg new file mode 100644 index 0000000..a1dbc5f Binary files /dev/null and b/OpenAntrag/Images/IntroBack/list-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/list-980.jpg b/OpenAntrag/Images/IntroBack/list-980.jpg new file mode 100644 index 0000000..6939a92 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/list-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/list-full.jpg b/OpenAntrag/Images/IntroBack/list-full.jpg new file mode 100644 index 0000000..02e2e01 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/list-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/notification-1200.jpg b/OpenAntrag/Images/IntroBack/notification-1200.jpg new file mode 100644 index 0000000..e48af19 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/notification-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/notification-770.jpg b/OpenAntrag/Images/IntroBack/notification-770.jpg new file mode 100644 index 0000000..c571bd7 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/notification-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/notification-980.jpg b/OpenAntrag/Images/IntroBack/notification-980.jpg new file mode 100644 index 0000000..c93722d Binary files /dev/null and b/OpenAntrag/Images/IntroBack/notification-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/notification-full.jpg b/OpenAntrag/Images/IntroBack/notification-full.jpg new file mode 100644 index 0000000..843e821 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/notification-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/search-1200.jpg b/OpenAntrag/Images/IntroBack/search-1200.jpg new file mode 100644 index 0000000..d317746 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/search-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/search-770.jpg b/OpenAntrag/Images/IntroBack/search-770.jpg new file mode 100644 index 0000000..5f7eb5f Binary files /dev/null and b/OpenAntrag/Images/IntroBack/search-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/search-980.jpg b/OpenAntrag/Images/IntroBack/search-980.jpg new file mode 100644 index 0000000..a50e76d Binary files /dev/null and b/OpenAntrag/Images/IntroBack/search-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/search-full.jpg b/OpenAntrag/Images/IntroBack/search-full.jpg new file mode 100644 index 0000000..436ef8a Binary files /dev/null and b/OpenAntrag/Images/IntroBack/search-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/statistics-1200.jpg b/OpenAntrag/Images/IntroBack/statistics-1200.jpg new file mode 100644 index 0000000..148e270 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/statistics-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/statistics-770.jpg b/OpenAntrag/Images/IntroBack/statistics-770.jpg new file mode 100644 index 0000000..ffb2573 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/statistics-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/statistics-980.jpg b/OpenAntrag/Images/IntroBack/statistics-980.jpg new file mode 100644 index 0000000..bc2d89e Binary files /dev/null and b/OpenAntrag/Images/IntroBack/statistics-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/statistics-full.jpg b/OpenAntrag/Images/IntroBack/statistics-full.jpg new file mode 100644 index 0000000..de9bc36 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/statistics-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/success-1200.jpg b/OpenAntrag/Images/IntroBack/success-1200.jpg new file mode 100644 index 0000000..2508f22 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/success-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/success-770.jpg b/OpenAntrag/Images/IntroBack/success-770.jpg new file mode 100644 index 0000000..5031779 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/success-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/success-980.jpg b/OpenAntrag/Images/IntroBack/success-980.jpg new file mode 100644 index 0000000..b361c30 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/success-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/success-full.jpg b/OpenAntrag/Images/IntroBack/success-full.jpg new file mode 100644 index 0000000..02e4954 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/success-full.jpg differ diff --git a/OpenAntrag/Images/IntroBack/tags-1200.jpg b/OpenAntrag/Images/IntroBack/tags-1200.jpg new file mode 100644 index 0000000..bacfb1b Binary files /dev/null and b/OpenAntrag/Images/IntroBack/tags-1200.jpg differ diff --git a/OpenAntrag/Images/IntroBack/tags-770.jpg b/OpenAntrag/Images/IntroBack/tags-770.jpg new file mode 100644 index 0000000..f82896a Binary files /dev/null and b/OpenAntrag/Images/IntroBack/tags-770.jpg differ diff --git a/OpenAntrag/Images/IntroBack/tags-980.jpg b/OpenAntrag/Images/IntroBack/tags-980.jpg new file mode 100644 index 0000000..048f480 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/tags-980.jpg differ diff --git a/OpenAntrag/Images/IntroBack/tags-full.jpg b/OpenAntrag/Images/IntroBack/tags-full.jpg new file mode 100644 index 0000000..5843e72 Binary files /dev/null and b/OpenAntrag/Images/IntroBack/tags-full.jpg differ diff --git a/OpenAntrag/Images/Logos/OALogo315.png b/OpenAntrag/Images/Logos/OALogo315.png new file mode 100644 index 0000000..f27574c Binary files /dev/null and b/OpenAntrag/Images/Logos/OALogo315.png differ diff --git a/OpenAntrag/Images/Logos/OALogo50.png b/OpenAntrag/Images/Logos/OALogo50.png new file mode 100644 index 0000000..fbf0359 Binary files /dev/null and b/OpenAntrag/Images/Logos/OALogo50.png differ diff --git a/OpenAntrag/Images/Logos/PPLogo315.png b/OpenAntrag/Images/Logos/PPLogo315.png new file mode 100644 index 0000000..d3f2351 Binary files /dev/null and b/OpenAntrag/Images/Logos/PPLogo315.png differ diff --git a/OpenAntrag/Images/Logos/PPLogo50.png b/OpenAntrag/Images/Logos/PPLogo50.png new file mode 100644 index 0000000..9d43350 Binary files /dev/null and b/OpenAntrag/Images/Logos/PPLogo50.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-114x114.png b/OpenAntrag/Images/Logos/apple-touch-icon-114x114.png new file mode 100644 index 0000000..ef985e5 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-114x114.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-120x120.png b/OpenAntrag/Images/Logos/apple-touch-icon-120x120.png new file mode 100644 index 0000000..4a7ec77 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-120x120.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-144x144.png b/OpenAntrag/Images/Logos/apple-touch-icon-144x144.png new file mode 100644 index 0000000..1f350c7 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-144x144.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-152x152.png b/OpenAntrag/Images/Logos/apple-touch-icon-152x152.png new file mode 100644 index 0000000..a83d7fd Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-152x152.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-57x57.png b/OpenAntrag/Images/Logos/apple-touch-icon-57x57.png new file mode 100644 index 0000000..24ebaa9 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-57x57.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-60x60.png b/OpenAntrag/Images/Logos/apple-touch-icon-60x60.png new file mode 100644 index 0000000..cddf04f Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-60x60.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-72x72.png b/OpenAntrag/Images/Logos/apple-touch-icon-72x72.png new file mode 100644 index 0000000..66a9e50 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-72x72.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-76x76.png b/OpenAntrag/Images/Logos/apple-touch-icon-76x76.png new file mode 100644 index 0000000..615a082 Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-76x76.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon-precomposed.png b/OpenAntrag/Images/Logos/apple-touch-icon-precomposed.png new file mode 100644 index 0000000..f7c723c Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon-precomposed.png differ diff --git a/OpenAntrag/Images/Logos/apple-touch-icon.png b/OpenAntrag/Images/Logos/apple-touch-icon.png new file mode 100644 index 0000000..a83d7fd Binary files /dev/null and b/OpenAntrag/Images/Logos/apple-touch-icon.png differ diff --git a/OpenAntrag/Images/Logos/browserconfig.xml b/OpenAntrag/Images/Logos/browserconfig.xml new file mode 100644 index 0000000..7f93108 --- /dev/null +++ b/OpenAntrag/Images/Logos/browserconfig.xml @@ -0,0 +1,12 @@ + + + + + + + + + #ff8800 + + + diff --git a/OpenAntrag/Images/Logos/favicon-160x160.png b/OpenAntrag/Images/Logos/favicon-160x160.png new file mode 100644 index 0000000..abc36c0 Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon-160x160.png differ diff --git a/OpenAntrag/Images/Logos/favicon-16x16.png b/OpenAntrag/Images/Logos/favicon-16x16.png new file mode 100644 index 0000000..a69b73b Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon-16x16.png differ diff --git a/OpenAntrag/Images/Logos/favicon-196x196.png b/OpenAntrag/Images/Logos/favicon-196x196.png new file mode 100644 index 0000000..3e9215a Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon-196x196.png differ diff --git a/OpenAntrag/Images/Logos/favicon-32x32.png b/OpenAntrag/Images/Logos/favicon-32x32.png new file mode 100644 index 0000000..62545bc Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon-32x32.png differ diff --git a/OpenAntrag/Images/Logos/favicon-96x96.png b/OpenAntrag/Images/Logos/favicon-96x96.png new file mode 100644 index 0000000..092a7af Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon-96x96.png differ diff --git a/OpenAntrag/Images/Logos/favicon.ico b/OpenAntrag/Images/Logos/favicon.ico new file mode 100644 index 0000000..3a70784 Binary files /dev/null and b/OpenAntrag/Images/Logos/favicon.ico differ diff --git a/OpenAntrag/Images/Logos/mstile-144x144.png b/OpenAntrag/Images/Logos/mstile-144x144.png new file mode 100644 index 0000000..f2053ed Binary files /dev/null and b/OpenAntrag/Images/Logos/mstile-144x144.png differ diff --git a/OpenAntrag/Images/Logos/mstile-150x150.png b/OpenAntrag/Images/Logos/mstile-150x150.png new file mode 100644 index 0000000..66c87f7 Binary files /dev/null and b/OpenAntrag/Images/Logos/mstile-150x150.png differ diff --git a/OpenAntrag/Images/Logos/mstile-310x150.png b/OpenAntrag/Images/Logos/mstile-310x150.png new file mode 100644 index 0000000..bb4d380 Binary files /dev/null and b/OpenAntrag/Images/Logos/mstile-310x150.png differ diff --git a/OpenAntrag/Images/Logos/mstile-310x310.png b/OpenAntrag/Images/Logos/mstile-310x310.png new file mode 100644 index 0000000..5f1d789 Binary files /dev/null and b/OpenAntrag/Images/Logos/mstile-310x310.png differ diff --git a/OpenAntrag/Images/Logos/mstile-70x70.png b/OpenAntrag/Images/Logos/mstile-70x70.png new file mode 100644 index 0000000..634b5e9 Binary files /dev/null and b/OpenAntrag/Images/Logos/mstile-70x70.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-114.png b/OpenAntrag/Images/Logos/old/favicon-114.png new file mode 100644 index 0000000..b272f22 Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-114.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-120.png b/OpenAntrag/Images/Logos/old/favicon-120.png new file mode 100644 index 0000000..79fa20e Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-120.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-128.png b/OpenAntrag/Images/Logos/old/favicon-128.png new file mode 100644 index 0000000..5ba79aa Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-128.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-144.png b/OpenAntrag/Images/Logos/old/favicon-144.png new file mode 100644 index 0000000..f716663 Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-144.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-152.png b/OpenAntrag/Images/Logos/old/favicon-152.png new file mode 100644 index 0000000..e96d986 Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-152.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-57.png b/OpenAntrag/Images/Logos/old/favicon-57.png new file mode 100644 index 0000000..0f8ddea Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-57.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-64.png b/OpenAntrag/Images/Logos/old/favicon-64.png new file mode 100644 index 0000000..28f34a3 Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-64.png differ diff --git a/OpenAntrag/Images/Logos/old/favicon-72.png b/OpenAntrag/Images/Logos/old/favicon-72.png new file mode 100644 index 0000000..700bb06 Binary files /dev/null and b/OpenAntrag/Images/Logos/old/favicon-72.png differ diff --git a/OpenAntrag/Images/Map/200-BB-blue.png b/OpenAntrag/Images/Map/200-BB-blue.png new file mode 100644 index 0000000..1536b6d Binary files /dev/null and b/OpenAntrag/Images/Map/200-BB-blue.png differ diff --git a/OpenAntrag/Images/Map/200-BB-orange.png b/OpenAntrag/Images/Map/200-BB-orange.png new file mode 100644 index 0000000..e5b3c1d Binary files /dev/null and b/OpenAntrag/Images/Map/200-BB-orange.png differ diff --git a/OpenAntrag/Images/Map/200-BE-blue.png b/OpenAntrag/Images/Map/200-BE-blue.png new file mode 100644 index 0000000..5aa8f80 Binary files /dev/null and b/OpenAntrag/Images/Map/200-BE-blue.png differ diff --git a/OpenAntrag/Images/Map/200-BE-orange.png b/OpenAntrag/Images/Map/200-BE-orange.png new file mode 100644 index 0000000..d32bef4 Binary files /dev/null and b/OpenAntrag/Images/Map/200-BE-orange.png differ diff --git a/OpenAntrag/Images/Map/200-BW-blue.png b/OpenAntrag/Images/Map/200-BW-blue.png new file mode 100644 index 0000000..ee2e211 Binary files /dev/null and b/OpenAntrag/Images/Map/200-BW-blue.png differ diff --git a/OpenAntrag/Images/Map/200-BW-orange.png b/OpenAntrag/Images/Map/200-BW-orange.png new file mode 100644 index 0000000..c571285 Binary files /dev/null and b/OpenAntrag/Images/Map/200-BW-orange.png differ diff --git a/OpenAntrag/Images/Map/200-BY-blue.png b/OpenAntrag/Images/Map/200-BY-blue.png new file mode 100644 index 0000000..bb1862c Binary files /dev/null and b/OpenAntrag/Images/Map/200-BY-blue.png differ diff --git a/OpenAntrag/Images/Map/200-BY-orange.png b/OpenAntrag/Images/Map/200-BY-orange.png new file mode 100644 index 0000000..a600bcf Binary files /dev/null and b/OpenAntrag/Images/Map/200-BY-orange.png differ diff --git a/OpenAntrag/Images/Map/200-DE-gray.png b/OpenAntrag/Images/Map/200-DE-gray.png new file mode 100644 index 0000000..55c4248 Binary files /dev/null and b/OpenAntrag/Images/Map/200-DE-gray.png differ diff --git a/OpenAntrag/Images/Map/200-DE-white.png b/OpenAntrag/Images/Map/200-DE-white.png new file mode 100644 index 0000000..426bd9a Binary files /dev/null and b/OpenAntrag/Images/Map/200-DE-white.png differ diff --git a/OpenAntrag/Images/Map/200-DE.png b/OpenAntrag/Images/Map/200-DE.png new file mode 100644 index 0000000..b5908f3 Binary files /dev/null and b/OpenAntrag/Images/Map/200-DE.png differ diff --git a/OpenAntrag/Images/Map/200-HB-blue.png b/OpenAntrag/Images/Map/200-HB-blue.png new file mode 100644 index 0000000..31d1395 Binary files /dev/null and b/OpenAntrag/Images/Map/200-HB-blue.png differ diff --git a/OpenAntrag/Images/Map/200-HB-orange.png b/OpenAntrag/Images/Map/200-HB-orange.png new file mode 100644 index 0000000..e1d9f71 Binary files /dev/null and b/OpenAntrag/Images/Map/200-HB-orange.png differ diff --git a/OpenAntrag/Images/Map/200-HE-blue.png b/OpenAntrag/Images/Map/200-HE-blue.png new file mode 100644 index 0000000..2ce30ae Binary files /dev/null and b/OpenAntrag/Images/Map/200-HE-blue.png differ diff --git a/OpenAntrag/Images/Map/200-HE-orange.png b/OpenAntrag/Images/Map/200-HE-orange.png new file mode 100644 index 0000000..3aa23c7 Binary files /dev/null and b/OpenAntrag/Images/Map/200-HE-orange.png differ diff --git a/OpenAntrag/Images/Map/200-HH-blue.png b/OpenAntrag/Images/Map/200-HH-blue.png new file mode 100644 index 0000000..19e1f50 Binary files /dev/null and b/OpenAntrag/Images/Map/200-HH-blue.png differ diff --git a/OpenAntrag/Images/Map/200-HH-orange.png b/OpenAntrag/Images/Map/200-HH-orange.png new file mode 100644 index 0000000..9c62f87 Binary files /dev/null and b/OpenAntrag/Images/Map/200-HH-orange.png differ diff --git a/OpenAntrag/Images/Map/200-MV-blue.png b/OpenAntrag/Images/Map/200-MV-blue.png new file mode 100644 index 0000000..05f7053 Binary files /dev/null and b/OpenAntrag/Images/Map/200-MV-blue.png differ diff --git a/OpenAntrag/Images/Map/200-MV-orange.png b/OpenAntrag/Images/Map/200-MV-orange.png new file mode 100644 index 0000000..7a1e1f0 Binary files /dev/null and b/OpenAntrag/Images/Map/200-MV-orange.png differ diff --git a/OpenAntrag/Images/Map/200-NI-blue.png b/OpenAntrag/Images/Map/200-NI-blue.png new file mode 100644 index 0000000..58d5b1f Binary files /dev/null and b/OpenAntrag/Images/Map/200-NI-blue.png differ diff --git a/OpenAntrag/Images/Map/200-NI-orange.png b/OpenAntrag/Images/Map/200-NI-orange.png new file mode 100644 index 0000000..995816e Binary files /dev/null and b/OpenAntrag/Images/Map/200-NI-orange.png differ diff --git a/OpenAntrag/Images/Map/200-NW-blue.png b/OpenAntrag/Images/Map/200-NW-blue.png new file mode 100644 index 0000000..dd0d890 Binary files /dev/null and b/OpenAntrag/Images/Map/200-NW-blue.png differ diff --git a/OpenAntrag/Images/Map/200-NW-orange.png b/OpenAntrag/Images/Map/200-NW-orange.png new file mode 100644 index 0000000..0245c2b Binary files /dev/null and b/OpenAntrag/Images/Map/200-NW-orange.png differ diff --git a/OpenAntrag/Images/Map/200-RP-blue.png b/OpenAntrag/Images/Map/200-RP-blue.png new file mode 100644 index 0000000..8b5dc63 Binary files /dev/null and b/OpenAntrag/Images/Map/200-RP-blue.png differ diff --git a/OpenAntrag/Images/Map/200-RP-orange.png b/OpenAntrag/Images/Map/200-RP-orange.png new file mode 100644 index 0000000..63ae319 Binary files /dev/null and b/OpenAntrag/Images/Map/200-RP-orange.png differ diff --git a/OpenAntrag/Images/Map/200-SH-blue.png b/OpenAntrag/Images/Map/200-SH-blue.png new file mode 100644 index 0000000..7b5bceb Binary files /dev/null and b/OpenAntrag/Images/Map/200-SH-blue.png differ diff --git a/OpenAntrag/Images/Map/200-SH-orange.png b/OpenAntrag/Images/Map/200-SH-orange.png new file mode 100644 index 0000000..5a82892 Binary files /dev/null and b/OpenAntrag/Images/Map/200-SH-orange.png differ diff --git a/OpenAntrag/Images/Map/200-SL-blue.png b/OpenAntrag/Images/Map/200-SL-blue.png new file mode 100644 index 0000000..8a7d0d0 Binary files /dev/null and b/OpenAntrag/Images/Map/200-SL-blue.png differ diff --git a/OpenAntrag/Images/Map/200-SL-orange.png b/OpenAntrag/Images/Map/200-SL-orange.png new file mode 100644 index 0000000..d729dd9 Binary files /dev/null and b/OpenAntrag/Images/Map/200-SL-orange.png differ diff --git a/OpenAntrag/Images/Map/200-SN-blue.png b/OpenAntrag/Images/Map/200-SN-blue.png new file mode 100644 index 0000000..121cb52 Binary files /dev/null and b/OpenAntrag/Images/Map/200-SN-blue.png differ diff --git a/OpenAntrag/Images/Map/200-SN-orange.png b/OpenAntrag/Images/Map/200-SN-orange.png new file mode 100644 index 0000000..e401fe3 Binary files /dev/null and b/OpenAntrag/Images/Map/200-SN-orange.png differ diff --git a/OpenAntrag/Images/Map/200-ST-blue.png b/OpenAntrag/Images/Map/200-ST-blue.png new file mode 100644 index 0000000..0ce03fd Binary files /dev/null and b/OpenAntrag/Images/Map/200-ST-blue.png differ diff --git a/OpenAntrag/Images/Map/200-ST-orange.png b/OpenAntrag/Images/Map/200-ST-orange.png new file mode 100644 index 0000000..9debd22 Binary files /dev/null and b/OpenAntrag/Images/Map/200-ST-orange.png differ diff --git a/OpenAntrag/Images/Map/200-TH-blue.png b/OpenAntrag/Images/Map/200-TH-blue.png new file mode 100644 index 0000000..b4267d3 Binary files /dev/null and b/OpenAntrag/Images/Map/200-TH-blue.png differ diff --git a/OpenAntrag/Images/Map/200-TH-orange.png b/OpenAntrag/Images/Map/200-TH-orange.png new file mode 100644 index 0000000..4062e0a Binary files /dev/null and b/OpenAntrag/Images/Map/200-TH-orange.png differ diff --git a/OpenAntrag/Images/Map/_40-DE.png b/OpenAntrag/Images/Map/_40-DE.png new file mode 100644 index 0000000..ca5e3c1 Binary files /dev/null and b/OpenAntrag/Images/Map/_40-DE.png differ diff --git a/OpenAntrag/Images/bgtransgrad-150.png b/OpenAntrag/Images/bgtransgrad-150.png new file mode 100644 index 0000000..f96a89d Binary files /dev/null and b/OpenAntrag/Images/bgtransgrad-150.png differ diff --git a/OpenAntrag/Images/bgtransgrad-250.png b/OpenAntrag/Images/bgtransgrad-250.png new file mode 100644 index 0000000..b5cd6a9 Binary files /dev/null and b/OpenAntrag/Images/bgtransgrad-250.png differ diff --git a/OpenAntrag/Images/bgtransgrad-500.png b/OpenAntrag/Images/bgtransgrad-500.png new file mode 100644 index 0000000..126911c Binary files /dev/null and b/OpenAntrag/Images/bgtransgrad-500.png differ diff --git a/OpenAntrag/Images/dummy-portrait-invers.png b/OpenAntrag/Images/dummy-portrait-invers.png new file mode 100644 index 0000000..65aee3a Binary files /dev/null and b/OpenAntrag/Images/dummy-portrait-invers.png differ diff --git a/OpenAntrag/Images/dummy-portrait.png b/OpenAntrag/Images/dummy-portrait.png new file mode 100644 index 0000000..cb5053f Binary files /dev/null and b/OpenAntrag/Images/dummy-portrait.png differ diff --git a/OpenAntrag/Images/hr.png b/OpenAntrag/Images/hr.png new file mode 100644 index 0000000..902db0d Binary files /dev/null and b/OpenAntrag/Images/hr.png differ diff --git a/OpenAntrag/Images/mCSB_buttons.png b/OpenAntrag/Images/mCSB_buttons.png new file mode 100644 index 0000000..4438868 Binary files /dev/null and b/OpenAntrag/Images/mCSB_buttons.png differ diff --git a/OpenAntrag/Images/pattern.png b/OpenAntrag/Images/pattern.png new file mode 100644 index 0000000..00292d7 Binary files /dev/null and b/OpenAntrag/Images/pattern.png differ diff --git a/OpenAntrag/Images/workflow-schema.png b/OpenAntrag/Images/workflow-schema.png new file mode 100644 index 0000000..106a81f Binary files /dev/null and b/OpenAntrag/Images/workflow-schema.png differ diff --git a/OpenAntrag/My Project/Application.Designer.vb b/OpenAntrag/My Project/Application.Designer.vb new file mode 100644 index 0000000..0aecefe --- /dev/null +++ b/OpenAntrag/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/OpenAntrag/My Project/Application.myapp b/OpenAntrag/My Project/Application.myapp new file mode 100644 index 0000000..758895d --- /dev/null +++ b/OpenAntrag/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff --git a/OpenAntrag/My Project/AssemblyInfo.vb b/OpenAntrag/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..4dec3b5 --- /dev/null +++ b/OpenAntrag/My Project/AssemblyInfo.vb @@ -0,0 +1,34 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + +' The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: +' + + + diff --git a/OpenAntrag/My Project/Resources.Designer.vb b/OpenAntrag/My Project/Resources.Designer.vb new file mode 100644 index 0000000..ecf7e36 --- /dev/null +++ b/OpenAntrag/My Project/Resources.Designer.vb @@ -0,0 +1,63 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + ''' + ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("OpenAntrag.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/OpenAntrag/My Project/Resources.resx b/OpenAntrag/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/OpenAntrag/My Project/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OpenAntrag/My Project/Settings.Designer.vb b/OpenAntrag/My Project/Settings.Designer.vb new file mode 100644 index 0000000..a5215bf --- /dev/null +++ b/OpenAntrag/My Project/Settings.Designer.vb @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) + +#Region "My.Settings Auto-Save Functionality" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub +#End If +#End Region + + Public Shared ReadOnly Property [Default]() As MySettings + Get + +#If _MyType = "WindowsForms" Then + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If +#End If + Return defaultInstance + End Get + End Property + End Class +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.OpenAntrag.My.MySettings + Get + Return Global.OpenAntrag.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/OpenAntrag/My Project/Settings.settings b/OpenAntrag/My Project/Settings.settings new file mode 100644 index 0000000..85b890b --- /dev/null +++ b/OpenAntrag/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/OpenAntrag/OpenAntrag.sln b/OpenAntrag/OpenAntrag.sln new file mode 100644 index 0000000..1e1f36c --- /dev/null +++ b/OpenAntrag/OpenAntrag.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "OpenAntrag", "OpenAntrag.vbproj", "{5CDC6161-823C-408C-B8D5-37AB162C163D}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "OpenAntragLib", "..\OpenAntragLib\OpenAntragLib.vbproj", "{0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2}" +EndProject +Global + GlobalSection(TeamFoundationVersionControl) = preSolution + SccNumberOfProjects = 3 + SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} + SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs16 + SccLocalPath0 = . + SccProjectUniqueName1 = OpenAntrag.vbproj + SccLocalPath1 = . + SccProjectUniqueName2 = ..\\OpenAntragLib\\OpenAntragLib.vbproj + SccProjectName2 = ../OpenAntragLib + SccLocalPath2 = ..\\OpenAntragLib + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5CDC6161-823C-408C-B8D5-37AB162C163D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CDC6161-823C-408C-B8D5-37AB162C163D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CDC6161-823C-408C-B8D5-37AB162C163D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CDC6161-823C-408C-B8D5-37AB162C163D}.Release|Any CPU.Build.0 = Release|Any CPU + {0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OpenAntrag/OpenAntrag.vbproj b/OpenAntrag/OpenAntrag.vbproj new file mode 100644 index 0000000..bcb228b --- /dev/null +++ b/OpenAntrag/OpenAntrag.vbproj @@ -0,0 +1,684 @@ + + + + + Debug + AnyCPU + + + 2.0 + {5CDC6161-823C-408C-B8D5-37AB162C163D} + {349c5851-65df-11da-9384-00065b846f21};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} + Library + OpenAntrag + OpenAntrag + v4.5.1 + On + Binary + Off + On + false + true + + + + + SAK + SAK + SAK + SAK + + + + true + full + true + true + bin\ + + + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + false + + + pdbonly + false + true + true + bin\ + + + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + + packages\ActionMailer.0.7.4\lib\Net40\ActionMailer.Net.dll + + + packages\ActionMailer.0.7.4\lib\Net40\ActionMailer.Net.Mvc.dll + + + False + packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll + + + packages\Artem.XmlProviders40.4.0\lib\Artem.Web.Security.dll + + + packages\Artem.XmlProviders40.4.0\lib\Artem.Web.Security.Xml.dll + + + False + packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll + + + packages\MarkdownDeep.Full.1.5\lib\.NetFramework 3.5\MarkdownDeep.dll + + + True + packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + False + packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll + + + False + packages\RavenDB.Client.2.5.2935\lib\net45\Raven.Abstractions.dll + + + False + packages\RavenDB.Client.2.5.2935\lib\net45\Raven.Client.Lightweight.dll + + + + + + + + False + packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll + + + + + + + + + + + False + packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll + + + False + packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll + + + False + packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll + + + False + packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll + + + packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll + + + False + packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll + + + + + False + packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll + + + False + packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll + + + False + packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll + + + + + packages\WebGrease.1.6.0\lib\WebGrease.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Global.asax + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + Designer + + + + + Designer + + + Designer + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Designer + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + picker.js + + + + + + + + + + + + + + + + + + + + + + Designer + + + + + + + Designer + + + + + + + + {0fffc9e8-fe8f-485e-88fc-af0b947e9fb2} + OpenAntragLib + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + True + True + 51219 + / + http://localhost:55588/ + False + False + + + False + + + + + + xcopy /y "E:\DevProjects\piratenmandate\piratenmandate.xml" "$(ProjectDir)App_Data" +xcopy /y "E:\DevProjects\piratenmandate\piratenmandate.dtd" "$(ProjectDir)App_Data" + + + \ No newline at end of file diff --git a/OpenAntrag/Scripts/MarkdownDeep License.txt b/OpenAntrag/Scripts/MarkdownDeep License.txt new file mode 100644 index 0000000..3787ba8 --- /dev/null +++ b/OpenAntrag/Scripts/MarkdownDeep License.txt @@ -0,0 +1,16 @@ +MarkdownDeep License +==================== + +MarkdownDeep - +Copyright (C) 2010-2011 Topten Software + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this product except in +compliance with the License. You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software distributed under the License is +distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License. + + diff --git a/OpenAntrag/Scripts/MarkdownDeep Quick Reference.txt b/OpenAntrag/Scripts/MarkdownDeep Quick Reference.txt new file mode 100644 index 0000000..f8a2ff5 --- /dev/null +++ b/OpenAntrag/Scripts/MarkdownDeep Quick Reference.txt @@ -0,0 +1,60 @@ +MarkdownDeep Quick Reference +============================ + +Setting up the Client Side Editor +--------------------------------- + +The following assumes you've installed the full edition MarkdownDeep using NuGet and explains how to setup +a client side editor with toolbar, resize bar, real-time preview and syntax reference help. + +1. In either your master view page, or in the view containing the editor ensure the following references are in place: + + + + + +2. Insert the following markup at the location you want the editor to appear: + +
+ <%=Html.TextArea("content", new { @class="mdd_editor" }) %> +
+
+ + Note, the mdd_toolbar, mdd_resizer and mdd_preview divs are all optional. If ommitted, the jQuery plugin will + create them however this may cause the page to appear to "jump" as it loads. By using the above divs and the + associated mdd_styles.css stylesheet, the correct sizing can be in-place immediately, eliminating these jumps. + +3. Use the jQuery plugin to convert the textarea into a Markdown editor. For more options, see below. + + $(function () { + $("textarea.mdd_editor").MarkdownDeep({ + help_location:"/Scripts/mdd_help.htm", + ExtraMode: true + }); + }) + +See for more information on configuring the editor. + +Server Side Translation +----------------------- + +The above steps allow you to create forms where the user can enter and preview Markdown content. This section +explains how to perform the equivalent translation of the entered content server side. + +1. When you installed MarkdownDeep to your project with NuGet, a reference to MarkdownDeep.dll would already have + been created. + +2. To translate Markdown, instantiate an instance of the MarkdownDeep class and call it's Translate method to + do the translation: + + // Instantiate + var md=new MarkdownDeep.Markdown(); + + // Set options + md.ExtraMode=true; + + // Translate + var html=md.Transform(plaintext); + + +See for other methods and properties. diff --git a/OpenAntrag/Scripts/MarkdownDeep.js b/OpenAntrag/Scripts/MarkdownDeep.js new file mode 100644 index 0000000..b90a947 --- /dev/null +++ b/OpenAntrag/Scripts/MarkdownDeep.js @@ -0,0 +1,4373 @@ +// +//! MarkdownDeep - http://www.toptensoftware.com/markdowndeep +//! Copyright (C) 2010-2011 Topten Software +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this product except in +// compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and limitations under the License. +// + + +///////////////////////////////////////////////////////////////////////////// +// Markdown + +var MarkdownDeep = new function () { + + + function array_indexOf(array, obj) { + if (array.indexOf !== undefined) + return array.indexOf(obj); + + for (var i = 0; i < array.length; i++) { + if (array[i] === obj) + return i; + } + + return -1; + }; + + // private:p. + // private:.m_* + + function Markdown() { + this.m_SpanFormatter = new SpanFormatter(this); + this.m_SpareBlocks = []; + this.m_StringBuilder = new StringBuilder(); + this.m_StringBuilderFinal = new StringBuilder(); + } + + Markdown.prototype = + { + SafeMode: false, + ExtraMode: false, + MarkdownInHtml: false, + AutoHeadingIDs: false, + UrlBaseLocation: null, + UrlRootLocation: null, + NewWindowForExternalLinks: false, + NewWindowForLocalLinks: false, + NoFollowLinks: false, + HtmlClassFootnotes: "footnotes", + HtmlClassTitledImages: null, + RenderingTitledImage: false, + FormatCodeBlockAttributes: null, + FormatCodeBlock: null, + ExtractHeadBlocks: false, + HeadBlockContent: "" + }; + + var p = Markdown.prototype; + + function splice_array(dest, position, del, ins) { + return dest.slice(0, position).concat(ins).concat(dest.slice(position + del)); + } + + Markdown.prototype.GetListItems = function (input, offset) { + // Parse content into blocks + var blocks = this.ProcessBlocks(input); + + + // Find the block + var i; + for (i = 0; i < blocks.length; i++) { + var b = blocks[i]; + + if ((b.blockType == BlockType_Composite || b.blockType == BlockType_html || b.blockType == BlockType_HtmlTag) && b.children) { + blocks = splice_array(blocks, i, 1, b.children); + i--; + continue; + } + + if (offset < b.lineStart) { + break; + } + } + + i--; + + // Quit if at top + if (i < 0) + return null; + + // Get the block before + var block = blocks[i]; + + // Check if it's a list + if (block.blockType != BlockType_ul && block.blockType != BlockType_ol) + return null; + + // Build list of line offsets + var list = []; + var items = block.children; + for (var j = 0; j < items.length; j++) { + list.push(items[j].lineStart); + } + + // Also push the line offset of the following block + i++; + if (i < blocks.length) { + list.push(blocks[i].lineStart); + } + else { + list.push(input.length); + } + + return list; + } + + // Main entry point + Markdown.prototype.Transform = function (input) { + // Normalize line ends + var rpos = input.indexOf("\r"); + if (rpos >= 0) { + var npos = input.indexOf("\n"); + if (npos >= 0) { + if (npos < rpos) { + input = input.replace(/\n\r/g, "\n"); + } + else { + input = input.replace(/\r\n/g, "\n"); + } + } + + input = input.replace(/\r/g, "\n"); + } + + this.HeadBlockContent = ""; + + var blocks = this.ProcessBlocks(input); + + // Sort abbreviations by length, longest to shortest + if (this.m_Abbreviations != null) { + var list = []; + for (var a in this.m_Abbreviations) { + list.push(this.m_Abbreviations[a]); + } + list.sort( + function (a, b) { + return b.Abbr.length - a.Abbr.length; + } + ); + this.m_Abbreviations = list; + } + + // Render + var sb = this.m_StringBuilderFinal; + sb.Clear(); + for (var i = 0; i < blocks.length; i++) { + var b = blocks[i]; + b.Render(this, sb); + } + + // Render footnotes + if (this.m_UsedFootnotes.length > 0) { + + sb.Append("\n
\n"); + sb.Append("
\n"); + sb.Append("
    \n"); + for (var i = 0; i < this.m_UsedFootnotes.length; i++) { + var fn = this.m_UsedFootnotes[i]; + + sb.Append("
  1. \n"); + + + // We need to get the return link appended to the last paragraph + // in the footnote + var strReturnLink = ""; + + // Get the last child of the footnote + var child = fn.children[fn.children.length - 1]; + if (child.blockType == BlockType_p) { + child.blockType = BlockType_p_footnote; + child.data = strReturnLink; + } + else { + child = new Block(); + child.contentLen = 0; + child.blockType = BlockType_p_footnote; + child.data = strReturnLink; + fn.children.push(child); + } + + + fn.Render(this, sb); + + sb.Append("
  2. \n"); + } + sb.Append("\n"); + } + + + // Done + return sb.ToString(); + } + + Markdown.prototype.OnQualifyUrl = function (url) { + // Is the url already fully qualified? + if (IsUrlFullyQualified(url)) + return url; + + if (starts_with(url, "/")) { + var rootLocation = this.UrlRootLocation; + if (!rootLocation) { + // Quit if we don't have a base location + if (!this.UrlBaseLocation) + return url; + + // Need to find domain root + var pos = this.UrlBaseLocation.indexOf("://"); + if (pos == -1) + pos = 0; + else + pos += 3; + + // Find the first slash after the protocol separator + pos = this.UrlBaseLocation.indexOf('/', pos); + + // Get the domain name + rootLocation = pos < 0 ? this.UrlBaseLocation : this.UrlBaseLocation.substr(0, pos); + } + + // Join em + return rootLocation + url; + } + else { + // Quit if we don't have a base location + if (!this.UrlBaseLocation) + return url; + + if (!ends_with(this.UrlBaseLocation, "/")) + return this.UrlBaseLocation + "/" + url; + else + return this.UrlBaseLocation + url; + } + } + + + // Override and return an object with width and height properties + Markdown.prototype.OnGetImageSize = function (image, TitledImage) { + return null; + } + + Markdown.prototype.OnPrepareLink = function (tag) { + var url = tag.attributes["href"]; + + // No follow? + if (this.NoFollowLinks) { + tag.attributes["rel"] = "nofollow"; + } + + // New window? + if ((this.NewWindowForExternalLinks && IsUrlFullyQualified(url)) || + (this.NewWindowForLocalLinks && !IsUrlFullyQualified(url))) { + tag.attributes["target"] = "_blank"; + } + + // Qualify url + tag.attributes["href"] = this.OnQualifyUrl(url); + } + + Markdown.prototype.OnPrepareImage = function (tag, TitledImage) { + // Try to determine width and height + var size = this.OnGetImageSize(tag.attributes["src"], TitledImage); + if (size != null) { + tag.attributes["width"] = size.width; + tag.attributes["height"] = size.height; + } + + // Now qualify the url + tag.attributes["src"] = this.OnQualifyUrl(tag.attributes["src"]); + } + + // Get a link definition + Markdown.prototype.GetLinkDefinition = function (id) { + var x = this.m_LinkDefinitions[id]; + if (x == undefined) + return null; + else + return x; + } + + + + p.ProcessBlocks = function (str) { + // Reset the list of link definitions + this.m_LinkDefinitions = []; + this.m_Footnotes = []; + this.m_UsedFootnotes = []; + this.m_UsedHeaderIDs = []; + this.m_Abbreviations = null; + + // Process blocks + return new BlockProcessor(this, this.MarkdownInHtml).Process(str); + } + + // Add a link definition + p.AddLinkDefinition = function (link) { + this.m_LinkDefinitions[link.id] = link; + } + + p.AddFootnote = function (footnote) { + this.m_Footnotes[footnote.data] = footnote; + } + + // Look up a footnote, claim it and return it's index (or -1 if not found) + p.ClaimFootnote = function (id) { + var footnote = this.m_Footnotes[id]; + if (footnote != undefined) { + // Move the foot note to the used footnote list + this.m_UsedFootnotes.push(footnote); + delete this.m_Footnotes[id]; + + // Return it's display index + return this.m_UsedFootnotes.length - 1; + } + else + return -1; + } + + p.AddAbbreviation = function (abbr, title) { + if (this.m_Abbreviations == null) { + this.m_Abbreviations = []; + } + + // Store abbreviation + this.m_Abbreviations[abbr] = { Abbr: abbr, Title: title }; + } + + p.GetAbbreviations = function () { + return this.m_Abbreviations; + } + + + + + // private + p.MakeUniqueHeaderID = function (strHeaderText, startOffset, length) { + if (!this.AutoHeadingIDs) + return null; + + // Extract a pandoc style cleaned header id from the header text + var strBase = this.m_SpanFormatter.MakeID(strHeaderText, startOffset, length); + + // If nothing left, use "section" + if (!strBase) + strBase = "section"; + + // Make sure it's unique by append -n counter + var strWithSuffix = strBase; + var counter = 1; + while (this.m_UsedHeaderIDs[strWithSuffix] != undefined) { + strWithSuffix = strBase + "-" + counter.toString(); + counter++; + } + + // Store it + this.m_UsedHeaderIDs[strWithSuffix] = true; + + // Return it + return strWithSuffix; + } + + + // private + p.GetStringBuilder = function () { + this.m_StringBuilder.Clear(); + return this.m_StringBuilder; + } + + ///////////////////////////////////////////////////////////////////////////// + // CharTypes + + function is_digit(ch) { + return ch >= '0' && ch <= '9'; + } + function is_hex(ch) { + return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); + } + function is_alpha(ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); + } + function is_alphadigit(ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'); + } + function is_whitespace(ch) { + return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); + } + function is_linespace(ch) { + return (ch == ' ' || ch == '\t'); + } + function is_lineend(ch) { + return (ch == '\r' || ch == '\n'); + } + function is_emphasis(ch) { + return (ch == '*' || ch == '_'); + } + function is_escapable(ch, ExtraMode) { + switch (ch) { + case '\\': + case '`': + case '*': + case '_': + case '{': + case '}': + case '[': + case ']': + case '(': + case ')': + case '>': + case '#': + case '+': + case '-': + case '.': + case '!': + return true; + + case ':': + case '|': + case '=': + case '<': + return ExtraMode; + } + + return false; + } + + + // Utility functions + + // Check if str[pos] looks like a html entity + // Returns -1 if not, or offset of character after it yes. + function SkipHtmlEntity(str, pos) { + if (str.charAt(pos) != '&') + return -1; + + var save = pos; + pos++; + + var fn_test; + if (str.charAt(pos) == '#') { + pos++; + if (str.charAt(pos) == 'x' || str.charAt(pos) == 'X') { + pos++; + fn_test = is_hex; + } + else { + fn_test = is_digit; + } + } + else { + fn_test = is_alphadigit; + } + + if (fn_test(str.charAt(pos))) { + pos++; + while (fn_test(str.charAt(pos))) + pos++; + + if (str.charAt(pos) == ';') { + pos++; + return pos; + } + } + + pos = save; + return -1; + } + + function UnescapeString(str, ExtraMode) { + // Find first backslash + var bspos = str.indexOf('\\'); + if (bspos < 0) + return str; + + // Build new string with escapable backslashes removed + var b = new StringBuilder(); + var piece = 0; + while (bspos >= 0) { + if (is_escapable(str.charAt(bspos + 1), ExtraMode)) { + if (bspos > piece) + b.Append(str.substr(piece, bspos - piece)); + + piece = bspos + 1; + } + + bspos = str.indexOf('\\', bspos + 1); + } + + if (piece < str.length) + b.Append(str.substr(piece, str.length - piece)); + + return b.ToString(); + } + + function Trim(str) { + var i = 0; + var l = str.length; + + while (i < l && is_whitespace(str.charAt(i))) + i++; + while (l - 1 > i && is_whitespace(str.charAt(l - 1))) + l--; + + return str.substr(i, l - i); + } + + + /* + * These two functions IsEmailAddress and IsWebAddress + * are intended as a quick and dirty way to tell if a + * url is email, web address or neither. + * + * They are not intended as validating checks. + * + * (use of Regex for more correct test unnecessarily + * slowed down some test documents by up to 300%.) + */ + + // Check if a string looks like an email address + function IsEmailAddress(str) { + var posAt = str.indexOf('@'); + if (posAt < 0) + return false; + + var posLastDot = str.lastIndexOf('.'); + if (posLastDot < posAt) + return false; + + return true; + } + + // Check if a string looks like a url + function IsWebAddress(str) { + str = str.toLowerCase(); + if (str.substr(0, 7) == "http://") + return true; + if (str.substr(0, 8) == "https://") + return true; + if (str.substr(0, 6) == "ftp://") + return true; + if (str.substr(0, 7) == "file://") + return true; + + return false; + } + + + // Check if a string is a valid HTML ID identifier + function IsValidHtmlID(str) { + if (!str) + return false; + + // Must start with a letter + if (!is_alpha(str.charAt(0))) + return false; + + // Check the rest + for (var i = 0; i < str.length; i++) { + var ch = str.charAt(i); + if (is_alphadigit(ch) || ch == '_' || ch == '-' || ch == ':' || ch == '.') + continue; + + return false; + } + + // OK + return true; + } + + // Strip the trailing HTML ID from a header string + // ie: ## header text ## {#} + // ^start ^out end ^end + // + // Returns null if no header id + function StripHtmlID(str, start, end) { + // Skip trailing whitespace + var pos = end - 1; + while (pos >= start && is_whitespace(str.charAt(pos))) { + pos--; + } + + // Skip closing '{' + if (pos < start || str.charAt(pos) != '}') + return null; + + var endId = pos; + pos--; + + // Find the opening '{' + while (pos >= start && str.charAt(pos) != '{') + pos--; + + // Check for the # + if (pos < start || str.charAt(pos + 1) != '#') + return null; + + // Extract and check the ID + var startId = pos + 2; + var strID = str.substr(startId, endId - startId); + if (!IsValidHtmlID(strID)) + return null; + + // Skip any preceeding whitespace + while (pos > start && is_whitespace(str.charAt(pos - 1))) + pos--; + + // Done! + return { id: strID, end: pos }; + } + + function starts_with(str, match) { + return str.substr(0, match.length) == match; + } + + function ends_with(str, match) { + return str.substr(-match.length) == match; + } + + function IsUrlFullyQualified(url) { + return url.indexOf("://") >= 0 || starts_with(url, "mailto:"); + } + + + ///////////////////////////////////////////////////////////////////////////// + // StringBuilder + + function StringBuilder() { + this.m_content = []; + } + + p = StringBuilder.prototype; + + p.Append = function (value) { + if (value) + this.m_content.push(value); + } + p.Clear = function () { + this.m_content.length = 0; + } + p.ToString = function () { + return this.m_content.join(""); + } + + p.HtmlRandomize = function (url) { + // Randomize + var len = url.length; + for (var i = 0; i < len; i++) { + var x = Math.random(); + if (x > 0.90 && url.charAt(i) != '@') { + this.Append(url.charAt(i)); + } + else if (x > 0.45) { + this.Append("&#"); + this.Append(url.charCodeAt(i).toString()); + this.Append(";"); + } + else { + this.Append("&#x"); + this.Append(url.charCodeAt(i).toString(16)); + this.Append(";"); + } + } + } + + p.HtmlEncode = function (str, startOffset, length) { + var end = startOffset + length; + var piece = startOffset; + var i; + for (i = startOffset; i < end; i++) { + switch (str.charAt(i)) { + case '&': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("&"); + piece = i + 1; + break; + + case '<': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("<"); + piece = i + 1; + break; + + case '>': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append(">"); + piece = i + 1; + break; + + case '\"': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("""); + piece = i + 1; + break; + } + } + + if (i > piece) + this.Append(str.substr(piece, i - piece)); + } + + p.SmartHtmlEncodeAmpsAndAngles = function (str, startOffset, length) { + var end = startOffset + length; + var piece = startOffset; + var i; + for (i = startOffset; i < end; i++) { + switch (str.charAt(i)) { + case '&': + var after = SkipHtmlEntity(str, i); + if (after < 0) { + if (i > piece) { + this.Append(str.substr(piece, i - piece)); + } + this.Append("&"); + piece = i + 1; + } + else { + i = after - 1; + } + break; + + case '<': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("<"); + piece = i + 1; + break; + + case '>': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append(">"); + piece = i + 1; + break; + + case '\"': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("""); + piece = i + 1; + break; + } + } + + if (i > piece) + this.Append(str.substr(piece, i - piece)); + } + + p.SmartHtmlEncodeAmps = function (str, startOffset, length) { + var end = startOffset + length; + var piece = startOffset; + var i; + for (i = startOffset; i < end; i++) { + switch (str.charAt(i)) { + case '&': + var after = SkipHtmlEntity(str, i); + if (after < 0) { + if (i > piece) { + this.Append(str.substr(piece, i - piece)); + } + this.Append("&"); + piece = i + 1; + } + else { + i = after - 1; + } + break; + } + } + + if (i > piece) + this.Append(str.substr(piece, i - piece)); + } + + + p.HtmlEncodeAndConvertTabsToSpaces = function (str, startOffset, length) { + var end = startOffset + length; + var piece = startOffset; + var pos = 0; + var i; + for (i = startOffset; i < end; i++) { + switch (str.charAt(i)) { + case '\t': + + if (i > piece) { + this.Append(str.substr(piece, i - piece)); + } + piece = i + 1; + + this.Append(' '); + pos++; + while ((pos % 4) != 0) { + this.Append(' '); + pos++; + } + pos--; // Compensate for the pos++ below + break; + + case '\r': + case '\n': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append('\n'); + piece = i + 1; + continue; + + case '&': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("&"); + piece = i + 1; + break; + + case '<': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("<"); + piece = i + 1; + break; + + case '>': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append(">"); + piece = i + 1; + break; + + case '\"': + if (i > piece) + this.Append(str.substr(piece, i - piece)); + this.Append("""); + piece = i + 1; + break; + } + + pos++; + } + + if (i > piece) + this.Append(str.substr(piece, i - piece)); + } + + + + + ///////////////////////////////////////////////////////////////////////////// + // StringScanner + + function StringScanner() { + this.reset.apply(this, arguments); + } + + p = StringScanner.prototype; + p.bof = function () { + return this.m_position == this.start; + } + + p.eof = function () { + return this.m_position >= this.end; + } + + p.eol = function () { + if (this.m_position >= this.end) + return true; + var ch = this.buf.charAt(this.m_position); + return ch == '\r' || ch == '\n' || ch == undefined || ch == ''; + } + + p.reset = function (/*string, position, length*/) { + this.buf = arguments.length > 0 ? arguments[0] : null; + this.start = arguments.length > 1 ? arguments[1] : 0; + this.end = arguments.length > 2 ? this.start + arguments[2] : (this.buf == null ? 0 : this.buf.length); + this.m_position = this.start; + this.charset_offsets = {}; + } + + p.current = function () { + if (this.m_position >= this.end) + return "\0"; + return this.buf.charAt(this.m_position); + } + + p.remainder = function () { + return this.buf.substr(this.m_position); + } + + p.SkipToEof = function () { + this.m_position = this.end; + } + + p.SkipForward = function (count) { + this.m_position += count; + } + + p.SkipToEol = function () { + this.m_position = this.buf.indexOf('\n', this.m_position); + if (this.m_position < 0) + this.m_position = this.end; + } + + p.SkipEol = function () { + var save = this.m_position; + if (this.buf.charAt(this.m_position) == '\r') + this.m_position++; + if (this.buf.charAt(this.m_position) == '\n') + this.m_position++; + return this.m_position != save; + } + + p.SkipToNextLine = function () { + this.SkipToEol(); + this.SkipEol(); + } + + p.CharAtOffset = function (offset) { + if (this.m_position + offset >= this.end) + return "\0"; + return this.buf.charAt(this.m_position + offset); + } + + p.SkipChar = function (ch) { + if (this.buf.charAt(this.m_position) == ch) { + this.m_position++; + return true; + } + return false; + } + p.SkipString = function (s) { + if (this.buf.substr(this.m_position, s.length) == s) { + this.m_position += s.length; + return true; + } + return false; + } + p.SkipWhitespace = function () { + var save = this.m_position; + while (true) { + var ch = this.buf.charAt(this.m_position); + if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') + break; + this.m_position++; + } + return this.m_position != save; + } + p.SkipLinespace = function () { + var save = this.m_position; + while (true) { + var ch = this.buf.charAt(this.m_position); + if (ch != ' ' && ch != '\t') + break; + this.m_position++; + } + return this.m_position != save; + } + p.FindRE = function (re) { + re.lastIndex = this.m_position; + var result = re.exec(this.buf); + if (result == null) { + this.m_position = this.end; + return false; + } + + if (result.index + result[0].length > this.end) { + this.m_position = this.end; + return false; + } + + this.m_position = result.index; + return true; + } + p.FindOneOf = function (charset) { + var next = -1; + for (var ch in charset) { + var charset_info = charset[ch]; + + // Setup charset_info for this character + if (charset_info == null) { + charset_info = {}; + charset_info.m_searched_from = -1; + charset_info.m_found_at = -1; + charset[ch] = charset_info; + } + + // Search again? + if (charset_info.m_searched_from == -1 || + this.m_position < charset_info.m_searched_from || + (this.m_position >= charset_info.m_found_at && charset_info.m_found_at != -1)) { + charset_info.m_searched_from = this.m_position; + charset_info.m_found_at = this.buf.indexOf(ch, this.m_position); + } + + // Is this character next? + if (next == -1 || charset_info.m_found_at < next) { + next = charset_info.m_found_at; + } + + } + + if (next == -1) { + next = this.end; + return false; + } + + p.m_position = next; + return true; + } + p.Find = function (s) { + this.m_position = this.buf.indexOf(s, this.m_position); + if (this.m_position < 0) { + this.m_position = this.end; + return false; + } + return true; + } + p.Mark = function () { + this.mark = this.m_position; + } + p.Extract = function () { + if (this.mark >= this.m_position) + return ""; + else + return this.buf.substr(this.mark, this.m_position - this.mark); + } + p.SkipIdentifier = function () { + var ch = this.buf.charAt(this.m_position); + if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_') { + this.m_position++; + while (true) { + ch = this.buf.charAt(this.m_position); + if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_' || (ch >= '0' && ch <= '9')) + this.m_position++; + else + return true; + } + } + return false; + } + + p.SkipFootnoteID = function () { + var savepos = this.m_position; + + this.SkipLinespace(); + + this.Mark(); + + while (true) { + var ch = this.current(); + if (is_alphadigit(ch) || ch == '-' || ch == '_' || ch == ':' || ch == '.' || ch == ' ') + this.SkipForward(1); + else + break; + } + + if (this.m_position > this.mark) { + var id = Trim(this.Extract()); + if (id.length > 0) { + this.SkipLinespace(); + return id; + } + } + + this.m_position = savepos; + return null; + } + + p.SkipHtmlEntity = function () { + if (this.buf.charAt(this.m_position) != '&') + return false; + + var newpos = SkipHtmlEntity(this.buf, this.m_position); + if (newpos < 0) + return false; + + this.m_position = newpos; + return true; + } + + p.SkipEscapableChar = function (ExtraMode) { + if (this.buf.charAt(this.m_position) == '\\' && is_escapable(this.buf.charAt(this.m_position + 1), ExtraMode)) { + this.m_position += 2; + return true; + } + else { + if (this.m_position < this.end) + this.m_position++; + return false; + } + } + + + ///////////////////////////////////////////////////////////////////////////// + // HtmlTag + + var HtmlTagFlags_Block = 0x0001; // Block tag + var HtmlTagFlags_Inline = 0x0002; // Inline tag + var HtmlTagFlags_NoClosing = 0x0004; // No closing tag (eg:
    and ) + var HtmlTagFlags_ContentAsSpan = 0x0008; // When markdown=1 treat content as span, not block + + + function HtmlTag(name) { + this.name = name; + this.attributes = {}; + this.flags = 0; + this.closed = false; + this.closing = false; + } + + p = HtmlTag.prototype; + + p.attributeCount = function () { + if (!this.attributes) + return 0; + + var count = 0; + for (var x in this.attributes) + count++; + + return count; + } + + p.get_Flags = function () { + if (this.flags == 0) { + this.flags = tag_flags[this.name.toLowerCase()]; + if (this.flags == undefined) { + this.flags = HtmlTagFlags_Inline; + } + } + return this.flags; + } + + p.IsSafe = function () { + var name_lower = this.name.toLowerCase(); + + // Check if tag is in whitelist + if (!allowed_tags[name_lower]) + return false; + + // Find allowed attributes + var allowed = allowed_attributes[name_lower]; + if (!allowed) { + return this.attributeCount() == 0; + } + + // No attributes? + if (!this.attributes) + return true; + + // Check all are allowed + for (var i in this.attributes) { + if (!allowed[i.toLowerCase()]) + return false; + } + + // Check href attribute is ok + if (this.attributes["href"]) { + if (!IsSafeUrl(this.attributes["href"])) + return false; + } + + if (this.attributes["src"]) { + if (!IsSafeUrl(this.attributes["src"])) + return false; + } + + // Passed all white list checks, allow it + return true; + } + + // Render opening tag (eg: + p.RenderOpening = function (dest) { + dest.Append("<"); + dest.Append(this.name); + for (var i in this.attributes) { + dest.Append(" "); + dest.Append(i); + dest.Append("=\""); + dest.Append(this.attributes[i]); + dest.Append("\""); + } + + if (this.closed) + dest.Append(" />"); + else + dest.Append(">"); + } + + // Render closing tag (eg: ) + p.RenderClosing = function (dest) { + dest.Append(""); + } + + + + function IsSafeUrl(url) { + url = url.toLowerCase(); + return (url.substr(0, 7) == "http://" || + url.substr(0, 8) == "https://" || + url.substr(0, 6) == "ftp://"); + } + + function ParseHtmlTag(p) { + // Save position + var savepos = p.m_position; + + // Parse it + var ret = ParseHtmlTagHelper(p); + if (ret != null) + return ret; + + // Rewind if failed + p.m_position = savepos; + return null; + } + + function ParseHtmlTagHelper(p) { + // Does it look like a tag? + if (p.current() != '<') + return null; + + // Skip '<' + p.SkipForward(1); + + // Is it a comment? + if (p.SkipString("!--")) { + p.Mark(); + + if (p.Find("-->")) { + var t = new HtmlTag("!"); + t.attributes["content"] = p.Extract(); + t.closed = true; + p.SkipForward(3); + return t; + } + } + + // Is it a closing tag eg:
+ var bClosing = p.SkipChar('/'); + + // Get the tag name + p.Mark(); + if (!p.SkipIdentifier()) + return null; + + // Probably a tag, create the HtmlTag object now + var tag = new HtmlTag(p.Extract()); + tag.closing = bClosing; + + // If it's a closing tag, no attributes + if (bClosing) { + if (p.current() != '>') + return null; + + p.SkipForward(1); + return tag; + } + + + while (!p.eof()) { + // Skip whitespace + p.SkipWhitespace(); + + // Check for closed tag eg:
+ if (p.SkipString("/>")) { + tag.closed = true; + return tag; + } + + // End of tag? + if (p.SkipChar('>')) { + return tag; + } + + // attribute name + p.Mark(); + if (!p.SkipIdentifier()) + return null; + var attributeName = p.Extract(); + + // Skip whitespace + p.SkipWhitespace(); + + // Skip equal sign + if (!p.SkipChar('=')) + return null; + + // Skip whitespace + p.SkipWhitespace(); + + // Optional quotes + if (p.SkipChar('\"')) { + // Scan the value + p.Mark(); + if (!p.Find('\"')) + return null; + + // Store the value + tag.attributes[attributeName] = p.Extract(); + + // Skip closing quote + p.SkipForward(1); + } + else { + // Scan the value + p.Mark(); + while (!p.eof() && !is_whitespace(p.current()) && p.current() != '>' && p.current() != '/') + p.SkipForward(1); + + if (!p.eof()) { + // Store the value + tag.attributes[attributeName] = p.Extract(); + } + } + } + + return null; + } + + + var allowed_tags = { + "b": 1, "blockquote": 1, "code": 1, "dd": 1, "dt": 1, "dl": 1, "del": 1, "em": 1, + "h1": 1, "h2": 1, "h3": 1, "h4": 1, "h5": 1, "h6": 1, "i": 1, "kbd": 1, "li": 1, "ol": 1, "ul": 1, + "p": 1, "pre": 1, "s": 1, "sub": 1, "sup": 1, "strong": 1, "strike": 1, "img": 1, "a": 1 + }; + + var allowed_attributes = { + "a": { "href": 1, "title": 1 }, + "img": { "src": 1, "width": 1, "height": 1, "alt": 1, "title": 1 } + }; + + var b = HtmlTagFlags_Block; + var i = HtmlTagFlags_Inline; + var n = HtmlTagFlags_NoClosing; + var s = HtmlTagFlags_ContentAsSpan; + var tag_flags = { + "p": b | s, + "div": b, + "h1": b | s, + "h2": b | s, + "h3": b | s, + "h4": b | s, + "h5": b | s, + "h6": b | s, + "blockquote": b, + "pre": b, + "table": b, + "dl": b, + "ol": b, + "ul": b, + "form": b, + "fieldset": b, + "iframe": b, + "script": b | i, + "noscript": b | i, + "math": b | i, + "ins": b | i, + "del": b | i, + "img": b | i, + "li": s, + "dd": s, + "dt": s, + "td": s, + "th": s, + "legend": s, + "address": s, + "hr": b | n, + "!": b | n, + "head": b + }; + delete b; + delete i; + delete n; + + + + ///////////////////////////////////////////////////////////////////////////// + // LinkDefinition + + function LinkDefinition(id, url, title) { + this.id = id; + this.url = url; + if (title == undefined) + this.title = null; + else + this.title = title; + } + + p = LinkDefinition.prototype; + p.RenderLink = function (m, b, link_text) { + if (this.url.substr(0, 7).toLowerCase() == "mailto:") { + b.Append("'); + b.HtmlRandomize(link_text); + b.Append(""); + } + else { + var tag = new HtmlTag("a"); + + // encode url + var sb = m.GetStringBuilder(); + sb.SmartHtmlEncodeAmpsAndAngles(this.url, 0, this.url.length); + tag.attributes["href"] = sb.ToString(); + + // encode title + if (this.title) { + sb.Clear(); + sb.SmartHtmlEncodeAmpsAndAngles(this.title, 0, this.title.length); + tag.attributes["title"] = sb.ToString(); + } + + // Do user processing + m.OnPrepareLink(tag); + + // Render the opening tag + tag.RenderOpening(b); + + b.Append(link_text); // Link text already escaped by SpanFormatter + b.Append(""); + } + } + + p.RenderImg = function (m, b, alt_text) { + var tag = new HtmlTag("img"); + + // encode url + var sb = m.GetStringBuilder(); + sb.SmartHtmlEncodeAmpsAndAngles(this.url, 0, this.url.length); + tag.attributes["src"] = sb.ToString(); + + // encode alt text + if (alt_text) { + sb.Clear(); + sb.SmartHtmlEncodeAmpsAndAngles(alt_text, 0, alt_text.length); + tag.attributes["alt"] = sb.ToString(); + } + + // encode title + if (this.title) { + sb.Clear(); + sb.SmartHtmlEncodeAmpsAndAngles(this.title, 0, this.title.length); + tag.attributes["title"] = sb.ToString(); + } + + tag.closed = true; + + m.OnPrepareImage(tag, m.RenderingTitledImage); + + tag.RenderOpening(b); + + /* + b.Append("\"");"); + */ + } + + function ParseLinkDefinition(p, ExtraMode) { + var savepos = p.m_position; + var l = ParseLinkDefinitionInternal(p, ExtraMode); + if (l == null) + p.m_position = savepos; + return l; + } + + function ParseLinkDefinitionInternal(p, ExtraMode) { + // Skip leading white space + p.SkipWhitespace(); + + // Must start with an opening square bracket + if (!p.SkipChar('[')) + return null; + + // Extract the id + p.Mark(); + if (!p.Find(']')) + return null; + var id = p.Extract(); + if (id.length == 0) + return null; + if (!p.SkipString("]:")) + return null; + + // Parse the url and title + var link = ParseLinkTarget(p, id, ExtraMode); + + // and trailing whitespace + p.SkipLinespace(); + + // Trailing crap, not a valid link reference... + if (!p.eol()) + return null; + + return link; + } + + // Parse just the link target + // For reference link definition, this is the bit after "[id]: thisbit" + // For inline link, this is the bit in the parens: [link text](thisbit) + function ParseLinkTarget(p, id, ExtraMode) { + // Skip whitespace + p.SkipWhitespace(); + + // End of string? + if (p.eol()) + return null; + + // Create the link definition + var r = new LinkDefinition(id); + + // Is the url enclosed in angle brackets + if (p.SkipChar('<')) { + // Extract the url + p.Mark(); + + // Find end of the url + while (p.current() != '>') { + if (p.eof()) + return null; + p.SkipEscapableChar(ExtraMode); + } + + var url = p.Extract(); + if (!p.SkipChar('>')) + return null; + + // Unescape it + r.url = UnescapeString(Trim(url), ExtraMode); + + // Skip whitespace + p.SkipWhitespace(); + } + else { + // Find end of the url + p.Mark(); + var paren_depth = 1; + while (!p.eol()) { + var ch = p.current(); + if (is_whitespace(ch)) + break; + if (id == null) { + if (ch == '(') + paren_depth++; + else if (ch == ')') { + paren_depth--; + if (paren_depth == 0) + break; + } + } + + p.SkipEscapableChar(ExtraMode); + } + + r.url = UnescapeString(Trim(p.Extract()), ExtraMode); + } + + p.SkipLinespace(); + + // End of inline target + if (p.current() == ')') + return r; + + var bOnNewLine = p.eol(); + var posLineEnd = p.m_position; + if (p.eol()) { + p.SkipEol(); + p.SkipLinespace(); + } + + // Work out what the title is delimited with + var delim; + switch (p.current()) { + case '\'': + case '\"': + delim = p.current(); + break; + + case '(': + delim = ')'; + break; + + default: + if (bOnNewLine) { + p.m_position = posLineEnd; + return r; + } + else + return null; + } + + // Skip the opening title delimiter + p.SkipForward(1); + + // Find the end of the title + p.Mark(); + while (true) { + if (p.eol()) + return null; + + if (p.current() == delim) { + + if (delim != ')') { + var savepos = p.m_position; + + // Check for embedded quotes in title + + // Skip the quote and any trailing whitespace + p.SkipForward(1); + p.SkipLinespace(); + + // Next we expect either the end of the line for a link definition + // or the close bracket for an inline link + if ((id == null && p.current() != ')') || + (id != null && !p.eol())) { + continue; + } + + p.m_position = savepos; + } + + // End of title + break; + } + + p.SkipEscapableChar(ExtraMode); + } + + // Store the title + r.title = UnescapeString(p.Extract(), ExtraMode); + + // Skip closing quote + p.SkipForward(1); + + // Done! + return r; + } + + + ///////////////////////////////////////////////////////////////////////////// + // LinkInfo + + function LinkInfo(def, link_text) { + this.def = def; + this.link_text = link_text; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Token + + var TokenType_Text = 0; + var TokenType_HtmlTag = 1; + var TokenType_Html = 2; + var TokenType_open_em = 3; + var TokenType_close_em = 4; + var TokenType_open_strong = 5; + var TokenType_close_strong = 6; + var TokenType_code_span = 7; + var TokenType_br = 8; + var TokenType_link = 9; + var TokenType_img = 10; + var TokenType_opening_mark = 11; + var TokenType_closing_mark = 12; + var TokenType_internal_mark = 13; + var TokenType_footnote = 14; + var TokenType_abbreviation = 15; + + function Token(type, startOffset, length) { + this.type = type; + this.startOffset = startOffset; + this.length = length; + this.data = null; + } + + ///////////////////////////////////////////////////////////////////////////// + // SpanFormatter + + function SpanFormatter(markdown) { + this.m_Markdown = markdown; + this.m_Scanner = new StringScanner(); + this.m_SpareTokens = []; + this.m_DisableLinks = false; + this.m_Tokens = []; + } + + p = SpanFormatter.prototype; + + p.FormatParagraph = function (dest, str, start, len) { + // Parse the string into a list of tokens + this.Tokenize(str, start, len); + + // Titled image? + if (this.m_Tokens.length == 1 && this.m_Markdown.HtmlClassTitledImages != null && this.m_Tokens[0].type == TokenType_img) { + // Grab the link info + var li = this.m_Tokens[0].data; + + // Render the div opening + dest.Append("
\n"); + + // Render the img + this.m_Markdown.RenderingTitledImage = true; + this.Render(dest, str); + this.m_Markdown.RenderingTitledImage = false; + dest.Append("\n"); + + // Render the title + if (li.def.title) { + dest.Append("

"); + dest.SmartHtmlEncodeAmpsAndAngles(li.def.title, 0, li.def.title.length); + dest.Append("

\n"); + } + + dest.Append("
\n"); + } + else { + // Render the paragraph + dest.Append("

"); + this.Render(dest, str); + dest.Append("

\n"); + } + + } + + // Format part of a string into a destination string builder + p.Format2 = function (dest, str) { + this.Format(dest, str, 0, str.length); + } + + // Format part of a string into a destination string builder + p.Format = function (dest, str, start, len) { + // Parse the string into a list of tokens + this.Tokenize(str, start, len); + + // Render all tokens + this.Render(dest, str); + } + + // Format a string and return it as a new string + // (used in formatting the text of links) + p.FormatDirect = function (str) { + var dest = new StringBuilder(); + this.Format(dest, str, 0, str.length); + return dest.ToString(); + } + + p.MakeID = function (str, start, len) { + // Parse the string into a list of tokens + this.Tokenize(str, start, len); + var tokens = this.m_Tokens; + + var sb = new StringBuilder(); + for (var i = 0; i < tokens.length; i++) { + var t = tokens[i]; + switch (t.type) { + case TokenType_Text: + sb.Append(str.substr(t.startOffset, t.length)); + break; + + case TokenType_link: + sb.Append(t.data.link_text); + break; + } + this.FreeToken(t); + } + + // Now clean it using the same rules as pandoc + var p = this.m_Scanner; + p.reset(sb.ToString()); + + // Skip everything up to the first letter + while (!p.eof()) { + if (is_alpha(p.current())) + break; + p.SkipForward(1); + } + + // Process all characters + sb.Clear(); + while (!p.eof()) { + var ch = p.current(); + if (is_alphadigit(ch) || ch == '_' || ch == '-' || ch == '.') + sb.Append(ch.toLowerCase()); + else if (ch == ' ') + sb.Append("-"); + else if (is_lineend(ch)) { + sb.Append("-"); + p.SkipEol(); + continue; + } + + p.SkipForward(1); + } + + return sb.ToString(); + } + + + + // Render a list of tokens to a destination string builder. + p.Render = function (sb, str) { + var tokens = this.m_Tokens; + var len = tokens.length; + for (var i = 0; i < len; i++) { + var t = tokens[i]; + switch (t.type) { + case TokenType_Text: + // Append encoded text + sb.HtmlEncode(str, t.startOffset, t.length); + break; + + case TokenType_HtmlTag: + // Append html as is + sb.SmartHtmlEncodeAmps(str, t.startOffset, t.length); + break; + + case TokenType_Html: + case TokenType_opening_mark: + case TokenType_closing_mark: + case TokenType_internal_mark: + // Append html as is + sb.Append(str.substr(t.startOffset, t.length)); + break; + + case TokenType_br: + sb.Append("
\n"); + break; + + case TokenType_open_em: + sb.Append(""); + break; + + case TokenType_close_em: + sb.Append(""); + break; + + case TokenType_open_strong: + sb.Append(""); + break; + + case TokenType_close_strong: + sb.Append(""); + break; + + case TokenType_code_span: + sb.Append(""); + sb.HtmlEncode(str, t.startOffset, t.length); + sb.Append(""); + break; + + case TokenType_link: + var li = t.data; + var sf = new SpanFormatter(this.m_Markdown); + sf.m_DisableLinks = true; + + li.def.RenderLink(this.m_Markdown, sb, sf.FormatDirect(li.link_text)); + break; + + case TokenType_img: + var li = t.data; + li.def.RenderImg(this.m_Markdown, sb, li.link_text); + break; + + case TokenType_footnote: + var r = t.data; + sb.Append(""); + sb.Append(r.index + 1); + sb.Append(""); + break; + + case TokenType_abbreviation: + var a = t.data; + sb.Append(""); + sb.HtmlEncode(a.Abbr, 0, a.Abbr.length); + sb.Append(""); + break; + + + } + + this.FreeToken(t); + } + } + + p.Tokenize = function (str, start, len) { + // Reset the string scanner + var p = this.m_Scanner; + p.reset(str, start, len); + + var tokens = this.m_Tokens; + tokens.length = 0; + + var emphasis_marks = null; + var Abbreviations = this.m_Markdown.GetAbbreviations(); + + var re = Abbreviations == null ? /[\*\_\`\[\!\<\&\ \\]/g : null; + + var ExtraMode = this.m_Markdown.ExtraMode; + + // Scan string + var start_text_token = p.m_position; + while (!p.eof()) { + if (re != null && !p.FindRE(re)) + break; + + var end_text_token = p.m_position; + + // Work out token + var token = null; + switch (p.current()) { + case '*': + case '_': + + // Create emphasis mark + token = this.CreateEmphasisMark(); + + if (token != null) { + // Store marks in a separate list the we'll resolve later + switch (token.type) { + case TokenType_internal_mark: + case TokenType_opening_mark: + case TokenType_closing_mark: + if (emphasis_marks == null) { + emphasis_marks = []; + } + emphasis_marks.push(token); + break; + } + } + break; + + case '`': + token = this.ProcessCodeSpan(); + break; + + case '[': + case '!': + // Process link reference + var linkpos = p.m_position; + token = this.ProcessLinkOrImageOrFootnote(); + + // Rewind if invalid syntax + // (the '[' or '!' will be treated as a regular character and processed below) + if (token == null) + p.m_position = linkpos; + break; + + case '<': + // Is it a valid html tag? + var save = p.m_position; + var tag = ParseHtmlTag(p); + if (tag != null) { + // Yes, create a token for it + if (!this.m_Markdown.SafeMode || tag.IsSafe()) { + // Yes, create a token for it + token = this.CreateToken(TokenType_HtmlTag, save, p.m_position - save); + } + else { + // No, rewrite and encode it + p.m_position = save; + } + } + else { + // No, rewind and check if it's a valid autolink eg: + p.m_position = save; + token = this.ProcessAutoLink(); + + if (token == null) + p.m_position = save; + } + break; + + case '&': + // Is it a valid html entity + var save = p.m_position; + if (p.SkipHtmlEntity()) { + // Yes, create a token for it + token = this.CreateToken(TokenType_Html, save, p.m_position - save); + } + + break; + + case ' ': + // Check for double space at end of a line + if (p.CharAtOffset(1) == ' ' && is_lineend(p.CharAtOffset(2))) { + // Yes, skip it + p.SkipForward(2); + + // Don't put br's at the end of a paragraph + if (!p.eof()) { + p.SkipEol(); + token = this.CreateToken(TokenType_br, end_text_token, 0); + } + } + break; + + case '\\': + // Check followed by an escapable character + if (is_escapable(p.CharAtOffset(1), ExtraMode)) { + token = this.CreateToken(TokenType_Text, p.m_position + 1, 1); + p.SkipForward(2); + } + break; + } + + // Look for abbreviations. + if (token == null && Abbreviations != null && !is_alphadigit(p.CharAtOffset(-1))) { + var savepos = p.m_position; + for (var i in Abbreviations) { + var abbr = Abbreviations[i]; + if (p.SkipString(abbr.Abbr) && !is_alphadigit(p.current())) { + token = this.CreateDataToken(TokenType_abbreviation, abbr); + break; + } + + p.position = savepos; + } + } + + + // If token found, append any preceeding text and the new token to the token list + if (token != null) { + // Create a token for everything up to the special character + if (end_text_token > start_text_token) { + tokens.push(this.CreateToken(TokenType_Text, start_text_token, end_text_token - start_text_token)); + } + + // Add the new token + tokens.push(token); + + // Remember where the next text token starts + start_text_token = p.m_position; + } + else { + // Skip a single character and keep looking + p.SkipForward(1); + } + } + + // Append a token for any trailing text after the last token. + if (p.m_position > start_text_token) { + tokens.push(this.CreateToken(TokenType_Text, start_text_token, p.m_position - start_text_token)); + } + + // Do we need to resolve and emphasis marks? + if (emphasis_marks != null) { + this.ResolveEmphasisMarks(tokens, emphasis_marks); + } + } + + /* + * Resolving emphasis tokens is a two part process + * + * 1. Find all valid sequences of * and _ and create `mark` tokens for them + * this is done by CreateEmphasisMarks during the initial character scan + * done by Tokenize + * + * 2. Looks at all these emphasis marks and tries to pair them up + * to make the actual and tokens + * + * Any unresolved emphasis marks are rendered unaltered as * or _ + */ + + // Create emphasis mark for sequences of '*' and '_' (part 1) + p.CreateEmphasisMark = function () { + var p = this.m_Scanner; + + // Capture current state + var ch = p.current(); + var altch = ch == '*' ? '_' : '*'; + var savepos = p.m_position; + + // Check for a consecutive sequence of just '_' and '*' + if (p.bof() || is_whitespace(p.CharAtOffset(-1))) { + while (is_emphasis(p.current())) + p.SkipForward(1); + + if (p.eof() || is_whitespace(p.current())) { + return this.CreateToken(TokenType_Html, savepos, p.m_position - savepos); + } + + // Rewind + p.m_position = savepos; + } + + // Scan backwards and see if we have space before + while (is_emphasis(p.CharAtOffset(-1))) + p.SkipForward(-1); + var bSpaceBefore = p.bof() || is_whitespace(p.CharAtOffset(-1)); + p.m_position = savepos; + + // Count how many matching emphasis characters + while (p.current() == ch) { + p.SkipForward(1); + } + var count = p.m_position - savepos; + + // Scan forwards and see if we have space after + while (is_emphasis(p.CharAtOffset(1))) + p.SkipForward(1); + var bSpaceAfter = p.eof() || is_whitespace(p.current()); + p.m_position = savepos + count; + + if (bSpaceBefore) { + return this.CreateToken(TokenType_opening_mark, savepos, p.m_position - savepos); + } + + if (bSpaceAfter) { + return this.CreateToken(TokenType_closing_mark, savepos, p.m_position - savepos); + } + + if (this.m_Markdown.ExtraMode && ch == '_') + return null; + + + return this.CreateToken(TokenType_internal_mark, savepos, p.m_position - savepos); + } + + // Split mark token + p.SplitMarkToken = function (tokens, marks, token, position) { + // Create the new rhs token + var tokenRhs = this.CreateToken(token.type, token.startOffset + position, token.length - position); + + // Adjust down the length of this token + token.length = position; + + // Insert the new token into each of the parent collections + marks.splice(array_indexOf(marks, token) + 1, 0, tokenRhs); + tokens.splice(array_indexOf(tokens, token) + 1, 0, tokenRhs); + + // Return the new token + return tokenRhs; + } + + // Resolve emphasis marks (part 2) + p.ResolveEmphasisMarks = function (tokens, marks) { + var input = this.m_Scanner.buf; + + var bContinue = true; + while (bContinue) { + bContinue = false; + for (var i = 0; i < marks.length; i++) { + // Get the next opening or internal mark + var opening_mark = marks[i]; + if (opening_mark.type != TokenType_opening_mark && opening_mark.type != TokenType_internal_mark) + continue; + + // Look for a matching closing mark + for (var j = i + 1; j < marks.length; j++) { + // Get the next closing or internal mark + var closing_mark = marks[j]; + if (closing_mark.type != TokenType_closing_mark && closing_mark.type != TokenType_internal_mark) + break; + + // Ignore if different type (ie: `*` vs `_`) + if (input.charAt(opening_mark.startOffset) != input.charAt(closing_mark.startOffset)) + continue; + + // strong or em? + var style = Math.min(opening_mark.length, closing_mark.length); + + // Triple or more on both ends? + if (style >= 3) { + style = (style % 2) == 1 ? 1 : 2; + } + + // Split the opening mark, keeping the RHS + if (opening_mark.length > style) { + opening_mark = this.SplitMarkToken(tokens, marks, opening_mark, opening_mark.length - style); + i--; + } + + // Split the closing mark, keeping the LHS + if (closing_mark.length > style) { + this.SplitMarkToken(tokens, marks, closing_mark, style); + } + + // Connect them + opening_mark.type = style == 1 ? TokenType_open_em : TokenType_open_strong; + closing_mark.type = style == 1 ? TokenType_close_em : TokenType_close_strong; + + // Remove the matched marks + marks.splice(array_indexOf(marks, opening_mark), 1); + marks.splice(array_indexOf(marks, closing_mark), 1); + bContinue = true; + + break; + } + } + } + } + + // Process auto links eg: + p.ProcessAutoLink = function () { + if (this.m_DisableLinks) + return null; + + var p = this.m_Scanner; + + // Skip the angle bracket and remember the start + p.SkipForward(1); + p.Mark(); + + var ExtraMode = this.m_Markdown.ExtraMode; + + // Allow anything up to the closing angle, watch for escapable characters + while (!p.eof()) { + var ch = p.current(); + + // No whitespace allowed + if (is_whitespace(ch)) + break; + + // End found? + if (ch == '>') { + var url = UnescapeString(p.Extract(), ExtraMode); + + var li = null; + if (IsEmailAddress(url)) { + var link_text; + if (url.toLowerCase().substr(0, 7) == "mailto:") { + link_text = url.substr(7); + } + else { + link_text = url; + url = "mailto:" + url; + } + + li = new LinkInfo(new LinkDefinition("auto", url, null), link_text); + } + else if (IsWebAddress(url)) { + li = new LinkInfo(new LinkDefinition("auto", url, null), url); + } + + if (li != null) { + p.SkipForward(1); + return this.CreateDataToken(TokenType_link, li); + } + + return null; + } + + p.SkipEscapableChar(ExtraMode); + } + + // Didn't work + return null; + } + + // Process [link] and ![image] directives + p.ProcessLinkOrImageOrFootnote = function () { + var p = this.m_Scanner; + + // Link or image? + var token_type = p.SkipChar('!') ? TokenType_img : TokenType_link; + + // Opening '[' + if (!p.SkipChar('[')) + return null; + + // Is it a foonote? + var savepos = this.m_position; + if (this.m_Markdown.ExtraMode && token_type == TokenType_link && p.SkipChar('^')) { + p.SkipLinespace(); + + // Parse it + p.Mark(); + var id = p.SkipFootnoteID(); + if (id != null && p.SkipChar(']')) { + // Look it up and create footnote reference token + var footnote_index = this.m_Markdown.ClaimFootnote(id); + if (footnote_index >= 0) { + // Yes it's a footnote + return this.CreateDataToken(TokenType_footnote, { index: footnote_index, id: id }); + } + } + + // Rewind + this.m_position = savepos; + } + + if (this.m_DisableLinks) + return null; + + var ExtraMode = this.m_Markdown.ExtraMode; + + // Find the closing square bracket, allowing for nesting, watching for + // escapable characters + p.Mark(); + var depth = 1; + while (!p.eof()) { + var ch = p.current(); + if (ch == '[') { + depth++; + } + else if (ch == ']') { + depth--; + if (depth == 0) + break; + } + + p.SkipEscapableChar(ExtraMode); + } + + // Quit if end + if (p.eof()) + return null; + + // Get the link text and unescape it + var link_text = UnescapeString(p.Extract(), ExtraMode); + + // The closing ']' + p.SkipForward(1); + + // Save position in case we need to rewind + savepos = p.m_position; + + // Inline links must follow immediately + if (p.SkipChar('(')) { + // Extract the url and title + var link_def = ParseLinkTarget(p, null, this.m_Markdown.ExtraMode); + if (link_def == null) + return null; + + // Closing ')' + p.SkipWhitespace(); + if (!p.SkipChar(')')) + return null; + + // Create the token + return this.CreateDataToken(token_type, new LinkInfo(link_def, link_text)); + } + + // Optional space or tab + if (!p.SkipChar(' ')) + p.SkipChar('\t'); + + // If there's line end, we're allow it and as must line space as we want + // before the link id. + if (p.eol()) { + p.SkipEol(); + p.SkipLinespace(); + } + + // Reference link? + var link_id = null; + if (p.current() == '[') { + // Skip the opening '[' + p.SkipForward(1); + + // Find the start/end of the id + p.Mark(); + if (!p.Find(']')) + return null; + + // Extract the id + link_id = p.Extract(); + + // Skip closing ']' + p.SkipForward(1); + } + else { + // Rewind to just after the closing ']' + p.m_position = savepos; + } + + // Link id not specified? + if (!link_id) { + link_id = link_text; + + // Convert all whitespace+line end to a single space + while (true) { + // Find carriage return + var i = link_id.indexOf("\n"); + if (i < 0) + break; + + var start = i; + while (start > 0 && is_whitespace(link_id.charAt(start - 1))) + start--; + + var end = i; + while (end < link_id.length && is_whitespace(link_id.charAt(end))) + end++; + + link_id = link_id.substr(0, start) + " " + link_id.substr(end); + } + } + + // Find the link definition, abort if not defined + var def = this.m_Markdown.GetLinkDefinition(link_id); + if (def == null) + return null; + + // Create a token + return this.CreateDataToken(token_type, new LinkInfo(def, link_text)); + } + + // Process a ``` code span ``` + p.ProcessCodeSpan = function () { + var p = this.m_Scanner; + var start = p.m_position; + + // Count leading ticks + var tickcount = 0; + while (p.SkipChar('`')) { + tickcount++; + } + + // Skip optional leading space... + p.SkipWhitespace(); + + // End? + if (p.eof()) + return this.CreateToken(TokenType_Text, start, p.m_position - start); + + var startofcode = p.m_position; + + // Find closing ticks + if (!p.Find(p.buf.substr(start, tickcount))) + return this.CreateToken(TokenType_Text, start, p.m_position - start); + + // Save end position before backing up over trailing whitespace + var endpos = p.m_position + tickcount; + while (is_whitespace(p.CharAtOffset(-1))) + p.SkipForward(-1); + + // Create the token, move back to the end and we're done + var ret = this.CreateToken(TokenType_code_span, startofcode, p.m_position - startofcode); + p.m_position = endpos; + return ret; + } + + p.CreateToken = function (type, startOffset, length) { + if (this.m_SpareTokens.length != 0) { + var t = this.m_SpareTokens.pop(); + t.type = type; + t.startOffset = startOffset; + t.length = length; + t.data = null; + return t; + } + else + return new Token(type, startOffset, length); + } + + // CreateToken - create or re-use a token object + p.CreateDataToken = function (type, data) { + if (this.m_SpareTokens.length != 0) { + var t = this.m_SpareTokens.pop(); + t.type = type; + t.data = data; + return t; + } + else { + var t = new Token(type, 0, 0); + t.data = data; + return t; + } + } + + // FreeToken - return a token to the spare token pool + p.FreeToken = function (token) { + token.data = null; + this.m_SpareTokens.push(token); + } + + + + ///////////////////////////////////////////////////////////////////////////// + // Block + + var BlockType_Blank = 0; + var BlockType_h1 = 1; + var BlockType_h2 = 2; + var BlockType_h3 = 3; + var BlockType_h4 = 4; + var BlockType_h5 = 5; + var BlockType_h6 = 6; + var BlockType_post_h1 = 7; + var BlockType_post_h2 = 8; + var BlockType_quote = 9; + var BlockType_ol_li = 10; + var BlockType_ul_li = 11; + var BlockType_p = 12; + var BlockType_indent = 13; + var BlockType_hr = 14; + var BlockType_html = 15; + var BlockType_unsafe_html = 16; + var BlockType_span = 17; + var BlockType_codeblock = 18; + var BlockType_li = 19; + var BlockType_ol = 20; + var BlockType_ul = 21; + var BlockType_HtmlTag = 22; + var BlockType_Composite = 23; + var BlockType_table_spec = 24; + var BlockType_dd = 25; + var BlockType_dt = 26; + var BlockType_dl = 27; + var BlockType_footnote = 28; + var BlockType_p_footnote = 29; + + + function Block() { + } + + + p = Block.prototype; + p.buf = null; + p.blockType = BlockType_Blank; + p.contentStart = 0; + p.contentLen = 0; + p.lineStart = 0; + p.lineLen = 0; + p.children = null; + p.data = null; + + p.get_Content = function () { + if (this.buf == null) + return null; + if (this.contentStart == -1) + return this.buf; + + return this.buf.substr(this.contentStart, this.contentLen); + } + + + p.get_CodeContent = function () { + var s = new StringBuilder(); + for (var i = 0; i < this.children.length; i++) { + s.Append(this.children[i].get_Content()); + s.Append('\n'); + } + return s.ToString(); + } + + + p.RenderChildren = function (m, b) { + for (var i = 0; i < this.children.length; i++) { + this.children[i].Render(m, b); + } + } + + p.ResolveHeaderID = function (m) { + // Already resolved? + if (this.data != null) + return this.data; + + // Approach 1 - PHP Markdown Extra style header id + var res = StripHtmlID(this.buf, this.contentStart, this.get_contentEnd()); + var id = null; + if (res != null) { + this.set_contentEnd(res.end); + id = res.id; + } + else { + // Approach 2 - pandoc style header id + id = m.MakeUniqueHeaderID(this.buf, this.contentStart, this.contentLen); + } + + this.data = id; + return id; + } + + p.Render = function (m, b) { + switch (this.blockType) { + case BlockType_Blank: + return; + + case BlockType_p: + m.m_SpanFormatter.FormatParagraph(b, this.buf, this.contentStart, this.contentLen); + break; + + case BlockType_span: + m.m_SpanFormatter.Format(b, this.buf, this.contentStart, this.contentLen); + b.Append("\n"); + break; + + case BlockType_h1: + case BlockType_h2: + case BlockType_h3: + case BlockType_h4: + case BlockType_h5: + case BlockType_h6: + if (m.ExtraMode && !m.SafeMode) { + b.Append(""); + } + else { + b.Append(">"); + } + } + else { + b.Append(""); + } + m.m_SpanFormatter.Format(b, this.buf, this.contentStart, this.contentLen); + b.Append("\n"); + break; + + case BlockType_hr: + b.Append("
\n"); + return; + + case BlockType_ol_li: + case BlockType_ul_li: + b.Append("
  • "); + m.m_SpanFormatter.Format(b, this.buf, this.contentStart, this.contentLen); + b.Append("
  • \n"); + break; + + case BlockType_html: + b.Append(this.buf.substr(this.contentStart, this.contentLen)); + return; + + case BlockType_unsafe_html: + b.HtmlEncode(this.buf, this.contentStart, this.contentLen); + return; + + case BlockType_codeblock: + b.Append(""); + + var btemp = b; + if (m.FormatCodeBlock) { + btemp = b; + b = new StringBuilder(); + } + + for (var i = 0; i < this.children.length; i++) { + var line = this.children[i]; + b.HtmlEncodeAndConvertTabsToSpaces(line.buf, line.contentStart, line.contentLen); + b.Append("\n"); + } + + if (m.FormatCodeBlock) { + btemp.Append(m.FormatCodeBlock(b.ToString(), this.data)); + b = btemp; + } + b.Append("\n\n"); + return; + + case BlockType_quote: + b.Append("
    \n"); + this.RenderChildren(m, b); + b.Append("
    \n"); + return; + + case BlockType_li: + b.Append("
  • \n"); + this.RenderChildren(m, b); + b.Append("
  • \n"); + return; + + case BlockType_ol: + b.Append("
      \n"); + this.RenderChildren(m, b); + b.Append("
    \n"); + return; + + case BlockType_ul: + b.Append("
      \n"); + this.RenderChildren(m, b); + b.Append("
    \n"); + return; + + case BlockType_HtmlTag: + var tag = this.data; + + // Prepare special tags + var name = tag.name.toLowerCase(); + if (name == "a") { + m.OnPrepareLink(tag); + } + else if (name == "img") { + m.OnPrepareImage(tag, m.RenderingTitledImage); + } + + tag.RenderOpening(b); + b.Append("\n"); + this.RenderChildren(m, b); + tag.RenderClosing(b); + b.Append("\n"); + return; + + case BlockType_Composite: + case BlockType_footnote: + this.RenderChildren(m, b); + return; + + case BlockType_table_spec: + this.data.Render(m, b); + return; + + case BlockType_dd: + b.Append("
    "); + if (this.children != null) { + b.Append("\n"); + this.RenderChildren(m, b); + } + else + m.m_SpanFormatter.Format(b, this.buf, this.contentStart, this.contentLen); + b.Append("
    \n"); + break; + + case BlockType_dt: + if (this.children == null) { + var lines = this.get_Content().split("\n"); + for (var i = 0; i < lines.length; i++) { + var l = lines[i]; + b.Append("
    "); + m.m_SpanFormatter.Format2(b, Trim(l)); + b.Append("
    \n"); + } + } + else { + b.Append("
    \n"); + this.RenderChildren(m, b); + b.Append("
    \n"); + } + break; + + case BlockType_dl: + b.Append("
    \n"); + this.RenderChildren(m, b); + b.Append("
    \n"); + return; + + case BlockType_p_footnote: + b.Append("

    "); + if (this.contentLen > 0) { + m.m_SpanFormatter.Format(b, this.buf, this.contentStart, this.contentLen); + b.Append(" "); + } + b.Append(this.data); + b.Append("

    \n"); + break; + + } + } + + p.RevertToPlain = function () { + this.blockType = BlockType_p; + this.contentStart = this.lineStart; + this.contentLen = this.lineLen; + } + + p.get_contentEnd = function () { + return this.contentStart + this.contentLen; + } + + p.set_contentEnd = function (value) { + this.contentLen = value - this.contentStart; + } + + // Count the leading spaces on a block + // Used by list item evaluation to determine indent levels + // irrespective of indent line type. + p.get_leadingSpaces = function () { + var count = 0; + for (var i = this.lineStart; i < this.lineStart + this.lineLen; i++) { + if (this.buf.charAt(i) == ' ') { + count++; + } + else { + break; + } + } + return count; + } + + p.CopyFrom = function (other) { + this.blockType = other.blockType; + this.buf = other.buf; + this.contentStart = other.contentStart; + this.contentLen = other.contentLen; + this.lineStart = other.lineStart; + this.lineLen = other.lineLen; + return this; + } + + ///////////////////////////////////////////////////////////////////////////// + // BlockProcessor + + + function BlockProcessor(m, MarkdownInHtml) { + this.m_Markdown = m; + this.m_parentType = BlockType_Blank; + this.m_bMarkdownInHtml = MarkdownInHtml; + } + + p = BlockProcessor.prototype; + + p.Process = function (str) { + // Reset string scanner + var p = new StringScanner(str); + + return this.ScanLines(p); + } + + p.ProcessRange = function (str, startOffset, len) { + // Reset string scanner + var p = new StringScanner(str, startOffset, len); + + return this.ScanLines(p); + } + + p.StartTable = function (p, spec, lines) { + // Mustn't have more than 1 preceeding line + if (lines.length > 1) + return false; + + // Rewind, parse the header row then fast forward back to current pos + if (lines.length == 1) { + var savepos = p.m_position; + p.m_position = lines[0].lineStart; + spec.m_Headers = spec.ParseRow(p); + if (spec.m_Headers == null) + return false; + p.m_position = savepos; + lines.length = 0; + } + + // Parse all .m_Rows + while (true) { + var savepos = p.m_position; + + var row = spec.ParseRow(p); + if (row != null) { + spec.m_Rows.push(row); + continue; + } + + p.m_position = savepos; + break; + } + + return true; + } + + + + p.ScanLines = function (p) { + // The final set of blocks will be collected here + var blocks = []; + + // The current paragraph/list/codeblock etc will be accumulated here + // before being collapsed into a block and store in above `blocks` list + var lines = []; + + // Add all blocks + var PrevBlockType = -1; + while (!p.eof()) { + // Remember if the previous line was blank + var bPreviousBlank = PrevBlockType == BlockType_Blank; + + // Get the next block + var b = this.EvaluateLine(p); + PrevBlockType = b.blockType; + + // For dd blocks, we need to know if it was preceeded by a blank line + // so store that fact as the block's data. + if (b.blockType == BlockType_dd) { + b.data = bPreviousBlank; + } + + + // SetExt header? + if (b.blockType == BlockType_post_h1 || b.blockType == BlockType_post_h2) { + if (lines.length > 0) { + // Remove the previous line and collapse the current paragraph + var prevline = lines.pop(); + this.CollapseLines(blocks, lines); + + // If previous line was blank, + if (prevline.blockType != BlockType_Blank) { + // Convert the previous line to a heading and add to block list + prevline.RevertToPlain(); + prevline.blockType = b.blockType == BlockType_post_h1 ? BlockType_h1 : BlockType_h2; + blocks.push(prevline); + continue; + } + } + + + // Couldn't apply setext header to a previous line + + if (b.blockType == BlockType_post_h1) { + // `===` gets converted to normal paragraph + b.RevertToPlain(); + lines.push(b); + } + else { + // `---` gets converted to hr + if (b.contentLen >= 3) { + b.blockType = BlockType_hr; + blocks.push(b); + } + else { + b.RevertToPlain(); + lines.push(b); + } + } + + continue; + } + + + // Work out the current paragraph type + var currentBlockType = lines.length > 0 ? lines[0].blockType : BlockType_Blank; + + // Starting a table? + if (b.blockType == BlockType_table_spec) { + // Get the table spec, save position + var spec = b.data; + var savepos = p.m_position; + if (!this.StartTable(p, spec, lines)) { + // Not a table, revert the tablespec row to plain, + // fast forward back to where we were up to and continue + // on as if nothing happened + p.m_position = savepos; + b.RevertToPlain(); + } + else { + blocks.push(b); + continue; + } + } + + // Process this line + switch (b.blockType) { + case BlockType_Blank: + switch (currentBlockType) { + case BlockType_Blank: + this.FreeBlock(b); + break; + + case BlockType_p: + this.CollapseLines(blocks, lines); + this.FreeBlock(b); + break; + + case BlockType_quote: + case BlockType_ol_li: + case BlockType_ul_li: + case BlockType_dd: + case BlockType_footnote: + case BlockType_indent: + lines.push(b); + break; + } + break; + + case BlockType_p: + switch (currentBlockType) { + case BlockType_Blank: + case BlockType_p: + lines.push(b); + break; + + case BlockType_quote: + case BlockType_ol_li: + case BlockType_ul_li: + case BlockType_dd: + case BlockType_footnote: + var prevline = lines[lines.length - 1]; + if (prevline.blockType == BlockType_Blank) { + this.CollapseLines(blocks, lines); + lines.push(b); + } + else { + lines.push(b); + } + break; + + case BlockType_indent: + this.CollapseLines(blocks, lines); + lines.push(b); + break; + } + break; + + case BlockType_indent: + switch (currentBlockType) { + case BlockType_Blank: + // Start a code block + lines.push(b); + break; + + case BlockType_p: + case BlockType_quote: + var prevline = lines[lines.length - 1]; + if (prevline.blockType == BlockType_Blank) { + // Start a code block after a paragraph + this.CollapseLines(blocks, lines); + lines.push(b); + } + else { + // indented line in paragraph, just continue it + b.RevertToPlain(); + lines.push(b); + } + break; + + + case BlockType_ol_li: + case BlockType_ul_li: + case BlockType_indent: + case BlockType_dd: + case BlockType_footnote: + lines.push(b); + break; + } + break; + + case BlockType_quote: + if (currentBlockType != BlockType_quote) { + this.CollapseLines(blocks, lines); + } + lines.push(b); + break; + + case BlockType_ol_li: + case BlockType_ul_li: + switch (currentBlockType) { + case BlockType_Blank: + lines.push(b); + break; + + case BlockType_p: + case BlockType_quote: + var prevline = lines[lines.length - 1]; + if (prevline.blockType == BlockType_Blank || this.m_parentType == BlockType_ol_li || this.m_parentType == BlockType_ul_li || this.m_parentType == BlockType_dd) { + // List starting after blank line after paragraph or quote + this.CollapseLines(blocks, lines); + lines.push(b); + } + else { + // List's can't start in middle of a paragraph + b.RevertToPlain(); + lines.push(b); + } + break; + + case BlockType_ol_li: + case BlockType_ul_li: + case BlockType_dd: + case BlockType_footnote: + if (b.blockType != currentBlockType) { + this.CollapseLines(blocks, lines); + } + lines.push(b); + break; + + case BlockType_indent: + // List after code block + this.CollapseLines(blocks, lines); + lines.push(b); + break; + } + break; + + case BlockType_dd: + case BlockType_footnote: + switch (currentBlockType) { + case BlockType_Blank: + case BlockType_p: + case BlockType_dd: + case BlockType_footnote: + this.CollapseLines(blocks, lines); + lines.push(b); + break; + + default: + b.RevertToPlain(); + lines.push(b); + break; + } + break; + + default: + this.CollapseLines(blocks, lines); + blocks.push(b); + break; + } + } + + this.CollapseLines(blocks, lines); + + if (this.m_Markdown.ExtraMode) { + this.BuildDefinitionLists(blocks); + } + + return blocks; + } + + p.CreateBlock = function (lineStart) { + var b; + if (this.m_Markdown.m_SpareBlocks.length > 1) { + b = this.m_Markdown.m_SpareBlocks.pop(); + } + else { + b = new Block(); + } + b.lineStart = lineStart; + return b; + } + + p.FreeBlock = function (b) { + this.m_Markdown.m_SpareBlocks.push(b); + } + + p.FreeBlocks = function (blocks) { + for (var i = 0; i < blocks.length; i++) + this.m_Markdown.m_SpareBlocks.push(blocks[i]); + blocks.length = 0; + } + + p.RenderLines = function (lines) { + var b = this.m_Markdown.GetStringBuilder(); + for (var i = 0; i < lines.length; i++) { + var l = lines[i]; + b.Append(l.buf.substr(l.contentStart, l.contentLen)); + b.Append('\n'); + } + return b.ToString(); + } + + p.CollapseLines = function (blocks, lines) { + // Remove trailing blank lines + while (lines.length > 0 && lines[lines.length - 1].blockType == BlockType_Blank) { + this.FreeBlock(lines.pop()); + } + + // Quit if empty + if (lines.length == 0) { + return; + } + + + // What sort of block? + switch (lines[0].blockType) { + case BlockType_p: + // Collapse all lines into a single paragraph + var para = this.CreateBlock(lines[0].lineStart); + para.blockType = BlockType_p; + para.buf = lines[0].buf; + para.contentStart = lines[0].contentStart; + para.set_contentEnd(lines[lines.length - 1].get_contentEnd()); + blocks.push(para); + this.FreeBlocks(lines); + break; + + case BlockType_quote: + // Get the content + var str = this.RenderLines(lines); + + // Create the new block processor + var bp = new BlockProcessor(this.m_Markdown, this.m_bMarkdownInHtml); + bp.m_parentType = BlockType_quote; + + // Create a new quote block + var quote = this.CreateBlock(lines[0].lineStart); + quote.blockType = BlockType_quote; + quote.children = bp.Process(str); + this.FreeBlocks(lines); + blocks.push(quote); + break; + + case BlockType_ol_li: + case BlockType_ul_li: + blocks.push(this.BuildList(lines)); + break; + + case BlockType_dd: + if (blocks.length > 0) { + var prev = blocks[blocks.length - 1]; + switch (prev.blockType) { + case BlockType_p: + prev.blockType = BlockType_dt; + break; + + case BlockType_dd: + break; + + default: + var wrapper = this.CreateBlock(prev.lineStart); + wrapper.blockType = BlockType_dt; + wrapper.children = []; + wrapper.children.push(prev); + blocks.pop(); + blocks.push(wrapper); + break; + } + + } + blocks.push(this.BuildDefinition(lines)); + break; + + case BlockType_footnote: + this.m_Markdown.AddFootnote(this.BuildFootnote(lines)); + break; + + + case BlockType_indent: + var codeblock = this.CreateBlock(lines[0].lineStart); + codeblock.blockType = BlockType_codeblock; + codeblock.children = []; + var firstline = lines[0].get_Content(); + if (firstline.substr(0, 2) == "{{" && firstline.substr(firstline.length - 2, 2) == "}}") { + codeblock.data = firstline.substr(2, firstline.length - 4); + lines.splice(0, 1); + } + for (var i = 0; i < lines.length; i++) { + codeblock.children.push(lines[i]); + } + blocks.push(codeblock); + lines.length = 0; + break; + } + } + + p.EvaluateLine = function (p) { + // Create a block + var b = this.CreateBlock(p.m_position); + + // Store line start + b.buf = p.buf; + + // Scan the line + b.contentStart = p.m_position; + b.contentLen = -1; + b.blockType = this.EvaluateLineInternal(p, b); + + + // If end of line not returned, do it automatically + if (b.contentLen < 0) { + // Move to end of line + p.SkipToEol(); + b.contentLen = p.m_position - b.contentStart; + } + + // Setup line length + b.lineLen = p.m_position - b.lineStart; + + // Next line + p.SkipEol(); + + // Create block + return b; + } + + p.EvaluateLineInternal = function (p, b) { + // Empty line? + if (p.eol()) + return BlockType_Blank; + + // Save start of line position + var line_start = p.m_position; + + // ## Heading ## + var ch = p.current(); + if (ch == '#') { + // Work out heading level + var level = 1; + p.SkipForward(1); + while (p.current() == '#') { + level++; + p.SkipForward(1); + } + + // Limit of 6 + if (level > 6) + level = 6; + + // Skip any whitespace + p.SkipLinespace(); + + // Save start position + b.contentStart = p.m_position; + + // Jump to end + p.SkipToEol(); + + // In extra mode, check for a trailing HTML ID + if (this.m_Markdown.ExtraMode && !this.m_Markdown.SafeMode) { + var res = StripHtmlID(p.buf, b.contentStart, p.m_position); + if (res != null) { + b.data = res.id; + p.m_position = res.end; + } + } + + // Rewind over trailing hashes + while (p.m_position > b.contentStart && p.CharAtOffset(-1) == '#') { + p.SkipForward(-1); + } + + // Rewind over trailing spaces + while (p.m_position > b.contentStart && is_whitespace(p.CharAtOffset(-1))) { + p.SkipForward(-1); + } + + // Create the heading block + b.contentLen = p.m_position - b.contentStart; + + p.SkipToEol(); + return BlockType_h1 + (level - 1); + } + + // Check for entire line as - or = for setext h1 and h2 + if (ch == '-' || ch == '=') { + // Skip all matching characters + var chType = ch; + while (p.current() == chType) { + p.SkipForward(1); + } + + // Trailing whitespace allowed + p.SkipLinespace(); + + // If not at eol, must have found something other than setext header + if (p.eol()) { + return chType == '=' ? BlockType_post_h1 : BlockType_post_h2; + } + + p.m_position = line_start; + } + + if (this.m_Markdown.ExtraMode) { + // MarkdownExtra Table row indicator? + var spec = TableSpec_Parse(p); + if (spec != null) { + b.data = spec; + return BlockType_table_spec; + } + + p.m_position = line_start; + + + // Fenced code blocks? + if (ch == '~') { + if (this.ProcessFencedCodeBlock(p, b)) + return b.blockType; + + // Rewind + p.m_position = line_start; + } + } + + // Scan the leading whitespace, remembering how many spaces and where the first tab is + var tabPos = -1; + var leadingSpaces = 0; + while (!p.eol()) { + if (p.current() == ' ') { + if (tabPos < 0) + leadingSpaces++; + } + else if (p.current() == '\t') { + if (tabPos < 0) + tabPos = p.m_position; + } + else { + // Something else, get out + break; + } + p.SkipForward(1); + } + + // Blank line? + if (p.eol()) { + b.contentLen = 0; + return BlockType_Blank; + } + + // 4 leading spaces? + if (leadingSpaces >= 4) { + b.contentStart = line_start + 4; + return BlockType_indent; + } + + // Tab in the first 4 characters? + if (tabPos >= 0 && tabPos - line_start < 4) { + b.contentStart = tabPos + 1; + return BlockType_indent; + } + + // Treat start of line as after leading whitespace + b.contentStart = p.m_position; + + // Get the next character + ch = p.current(); + + // Html block? + if (ch == '<') { + if (this.ScanHtml(p, b)) + return b.blockType; + + // Rewind + p.m_position = b.contentStart; + } + + // Block quotes start with '>' and have one space or one tab following + if (ch == '>') { + // Block quote followed by space + if (is_linespace(p.CharAtOffset(1))) { + // Skip it and create quote block + p.SkipForward(2); + b.contentStart = p.m_position; + return BlockType_quote; + } + + p.SkipForward(1); + b.contentStart = p.m_position; + return BlockType_quote; + } + + // Horizontal rule - a line consisting of 3 or more '-', '_' or '*' with optional spaces and nothing else + if (ch == '-' || ch == '_' || ch == '*') { + var count = 0; + while (!p.eol()) { + var chType = p.current(); + if (p.current() == ch) { + count++; + p.SkipForward(1); + continue; + } + + if (is_linespace(p.current())) { + p.SkipForward(1); + continue; + } + + break; + } + + if (p.eol() && count >= 3) { + return BlockType_hr; + } + + // Rewind + p.m_position = b.contentStart; + } + + // Abbreviation definition? + if (this.m_Markdown.ExtraMode && ch == '*' && p.CharAtOffset(1) == '[') { + p.SkipForward(2); + p.SkipLinespace(); + + p.Mark(); + while (!p.eol() && p.current() != ']') { + p.SkipForward(1); + } + + var abbr = Trim(p.Extract()); + if (p.current() == ']' && p.CharAtOffset(1) == ':' && abbr) { + p.SkipForward(2); + p.SkipLinespace(); + + p.Mark(); + + p.SkipToEol(); + + var title = p.Extract(); + + this.m_Markdown.AddAbbreviation(abbr, title); + + return BlockType_Blank; + } + + p.m_position = b.contentStart; + } + + + // Unordered list + if ((ch == '*' || ch == '+' || ch == '-') && is_linespace(p.CharAtOffset(1))) { + // Skip it + p.SkipForward(1); + p.SkipLinespace(); + b.contentStart = p.m_position; + return BlockType_ul_li; + } + + // Definition + if (ch == ':' && this.m_Markdown.ExtraMode && is_linespace(p.CharAtOffset(1))) { + p.SkipForward(1); + p.SkipLinespace(); + b.contentStart = p.m_position; + return BlockType_dd; + } + + // Ordered list + if (is_digit(ch)) { + // Ordered list? A line starting with one or more digits, followed by a '.' and a space or tab + + // Skip all digits + p.SkipForward(1); + while (is_digit(p.current())) + p.SkipForward(1); + + if (p.SkipChar('.') && p.SkipLinespace()) { + b.contentStart = p.m_position; + return BlockType_ol_li; + } + + p.m_position = b.contentStart; + } + + // Reference link definition? + if (ch == '[') { + // Footnote definition? + if (this.m_Markdown.ExtraMode && p.CharAtOffset(1) == '^') { + var savepos = p.m_position; + + p.SkipForward(2); + + var id = p.SkipFootnoteID(); + if (id != null && p.SkipChar(']') && p.SkipChar(':')) { + p.SkipLinespace(); + b.contentStart = p.m_position; + b.data = id; + return BlockType_footnote; + } + + p.m_position = savepos; + } + + // Parse a link definition + var l = ParseLinkDefinition(p, this.m_Markdown.ExtraMode); + if (l != null) { + this.m_Markdown.AddLinkDefinition(l); + return BlockType_Blank; + } + } + + // Nothing special + return BlockType_p; + } + + var MarkdownInHtmlMode_NA = 0; + var MarkdownInHtmlMode_Block = 1; + var MarkdownInHtmlMode_Span = 2; + var MarkdownInHtmlMode_Deep = 3; + var MarkdownInHtmlMode_Off = 4; + + p.GetMarkdownMode = function (tag) { + // Get the markdown attribute + var md = tag.attributes["markdown"]; + if (md == undefined) { + if (this.m_bMarkdownInHtml) + return MarkdownInHtmlMode_Deep; + else + return MarkdownInHtmlMode_NA; + } + + // Remove it + delete tag.attributes["markdown"]; + + // Parse mode + if (md == "1") + return (tag.get_Flags() & HtmlTagFlags_ContentAsSpan) != 0 ? MarkdownInHtmlMode_Span : MarkdownInHtmlMode_Block; + + if (md == "block") + return MarkdownInHtmlMode_Block; + + if (md == "deep") + return MarkdownInHtmlMode_Deep; + + if (md == "span") + return MarkdownInHtmlMode_Span; + + return MarkdownInHtmlMode_Off; + } + + p.ProcessMarkdownEnabledHtml = function (p, b, openingTag, mode) { + // Current position is just after the opening tag + + // Scan until we find matching closing tag + var inner_pos = p.m_position; + var depth = 1; + var bHasUnsafeContent = false; + while (!p.eof()) { + // Find next angle bracket + if (!p.Find('<')) + break; + + // Is it a html tag? + var tagpos = p.m_position; + var tag = ParseHtmlTag(p); + if (tag == null) { + // Nope, skip it + p.SkipForward(1); + continue; + } + + // In markdown off mode, we need to check for unsafe tags + if (this.m_Markdown.SafeMode && mode == MarkdownInHtmlMode_Off && !bHasUnsafeContent) { + if (!tag.IsSafe()) + bHasUnsafeContent = true; + } + + // Ignore self closing tags + if (tag.closed) + continue; + + // Same tag? + if (tag.name == openingTag.name) { + if (tag.closing) { + depth--; + if (depth == 0) { + // End of tag? + p.SkipLinespace(); + p.SkipEol(); + + b.blockType = BlockType_HtmlTag; + b.data = openingTag; + b.set_contentEnd(p.m_position); + + switch (mode) { + case MarkdownInHtmlMode_Span: + var span = this.CreateBlock(inner_pos); + span.buf = p.buf; + span.blockType = BlockType_span; + span.contentStart = inner_pos; + span.contentLen = tagpos - inner_pos; + + b.children = []; + b.children.push(span); + break; + + case MarkdownInHtmlMode_Block: + case MarkdownInHtmlMode_Deep: + // Scan the internal content + var bp = new BlockProcessor(this.m_Markdown, mode == MarkdownInHtmlMode_Deep); + b.children = bp.ProcessRange(p.buf, inner_pos, tagpos - inner_pos); + break; + + case MarkdownInHtmlMode_Off: + if (bHasUnsafeContent) { + b.blockType = BlockType_unsafe_html; + b.set_contentEnd(p.m_position); + } + else { + var span = this.CreateBlock(inner_pos); + span.buf = p.buf; + span.blockType = BlockType_html; + span.contentStart = inner_pos; + span.contentLen = tagpos - inner_pos; + + b.children = []; + b.children.push(span); + } + break; + } + + + return true; + } + } + else { + depth++; + } + } + } + + // Missing closing tag(s). + return false; + } + + p.ScanHtml = function (p, b) { + // Remember start of html + var posStartPiece = p.m_position; + + // Parse a HTML tag + var openingTag = ParseHtmlTag(p); + if (openingTag == null) + return false; + + // Closing tag? + if (openingTag.closing) + return false; + + // Safe mode? + var bHasUnsafeContent = false; + if (this.m_Markdown.SafeMode && !openingTag.IsSafe()) + bHasUnsafeContent = true; + + var flags = openingTag.get_Flags(); + + // Is it a block level tag? + if ((flags & HtmlTagFlags_Block) == 0) + return false; + + // Closed tag, hr or comment? + if ((flags & HtmlTagFlags_NoClosing) != 0 || openingTag.closed) { + p.SkipLinespace(); + p.SkipEol(); + b.contentLen = p.m_position - b.contentStart; + b.blockType = bHasUnsafeContent ? BlockType_unsafe_html : BlockType_html; + return true; + } + + // Can it also be an inline tag? + if ((flags & HtmlTagFlags_Inline) != 0) { + // Yes, opening tag must be on a line by itself + p.SkipLinespace(); + if (!p.eol()) + return false; + } + + // Head block extraction? + var bHeadBlock = this.m_Markdown.ExtractHeadBlocks && openingTag.name.toLowerCase() == "head"; + var headStart = p.m_position; + + // Work out the markdown mode for this element + if (!bHeadBlock && this.m_Markdown.ExtraMode) { + var MarkdownMode = this.GetMarkdownMode(openingTag); + if (MarkdownMode != MarkdownInHtmlMode_NA) { + return this.ProcessMarkdownEnabledHtml(p, b, openingTag, MarkdownMode); + } + } + + var childBlocks = null; + + // Now capture everything up to the closing tag and put it all in a single HTML block + var depth = 1; + + while (!p.eof()) { + if (!p.Find('<')) + break; + + // Save position of current tag + var posStartCurrentTag = p.m_position; + + var tag = ParseHtmlTag(p); + if (tag == null) { + p.SkipForward(1); + continue; + } + + // Safe mode checks + if (this.m_Markdown.SafeMode && !tag.IsSafe()) + bHasUnsafeContent = true; + + + // Ignore self closing tags + if (tag.closed) + continue; + + // Markdown enabled content? + if (!bHeadBlock && !tag.closing && this.m_Markdown.ExtraMode && !bHasUnsafeContent) { + var MarkdownMode = this.GetMarkdownMode(tag); + if (MarkdownMode != MarkdownInHtmlMode_NA) { + var markdownBlock = this.CreateBlock(posStartPiece); + if (this.ProcessMarkdownEnabledHtml(p, markdownBlock, tag, MarkdownMode)) { + if (childBlocks == null) { + childBlocks = []; + } + + // Create a block for everything before the markdown tag + if (posStartCurrentTag > posStartPiece) { + var htmlBlock = this.CreateBlock(posStartPiece); + htmlBlock.buf = p.buf; + htmlBlock.blockType = BlockType_html; + htmlBlock.contentStart = posStartPiece; + htmlBlock.contentLen = posStartCurrentTag - posStartPiece; + + childBlocks.push(htmlBlock); + } + + // Add the markdown enabled child block + childBlocks.push(markdownBlock); + + // Remember start of the next piece + posStartPiece = p.m_position; + + continue; + } + else { + this.FreeBlock(markdownBlock); + } + } + } + + // Same tag? + if (tag.name == openingTag.name && !tag.closed) { + if (tag.closing) { + depth--; + if (depth == 0) { + // End of tag? + p.SkipLinespace(); + p.SkipEol(); + + // If anything unsafe detected, just encode the whole block + if (bHasUnsafeContent) { + b.blockType = BlockType_unsafe_html; + b.set_contentEnd(p.m_position); + return true; + } + + // Did we create any child blocks + if (childBlocks != null) { + // Create a block for the remainder + if (p.m_position > posStartPiece) { + var htmlBlock = this.CreateBlock(posStartPiece); + htmlBlock.buf = p.buf; + htmlBlock.blockType = BlockType_html; + htmlBlock.contentStart = posStartPiece; + htmlBlock.contentLen = p.m_position - posStartPiece; + + childBlocks.push(htmlBlock); + } + + // Return a composite block + b.blockType = BlockType_Composite; + b.set_contentEnd(p.m_position); + b.children = childBlocks; + return true; + } + + // Extract the head block content + if (bHeadBlock) { + var content = p.buf.substr(headStart, posStartCurrentTag - headStart); + this.m_Markdown.HeadBlockContent = this.m_Markdown.HeadBlockContent + Trim(content) + "\n"; + b.blockType = BlockType_html; + b.contentStart = p.position; + b.contentEnd = p.position; + b.lineStart = p.position; + return true; + } + + // Straight html block + b.blockType = BlockType_html; + b.contentLen = p.m_position - b.contentStart; + return true; + } + } + else { + depth++; + } + } + } + + // Missing closing tag(s). + return BlockType_Blank; + } + + /* + * BuildList - build a single
      or
        list + */ + p.BuildList = function (lines) { + // What sort of list are we dealing with + var listType = lines[0].blockType; + + // Preprocess + // 1. Collapse all plain lines (ie: handle hardwrapped lines) + // 2. Promote any unindented lines that have more leading space + // than the original list item to indented, including leading + // special chars + var leadingSpace = lines[0].get_leadingSpaces(); + for (var i = 1; i < lines.length; i++) { + // Join plain paragraphs + if ((lines[i].blockType == BlockType_p) && + (lines[i - 1].blockType == BlockType_p || lines[i - 1].blockType == listType)) { + lines[i - 1].set_contentEnd(lines[i].get_contentEnd()); + this.FreeBlock(lines[i]); + lines.splice(i, 1); + i--; + continue; + } + + if (lines[i].blockType != BlockType_indent && lines[i].blockType != BlockType_Blank) { + var thisLeadingSpace = lines[i].get_leadingSpaces(); + if (thisLeadingSpace > leadingSpace) { + // Change line to indented, including original leading chars + // (eg: '* ', '>', '1.' etc...) + lines[i].blockType = BlockType_indent; + var saveend = lines[i].get_contentEnd(); + lines[i].contentStart = lines[i].lineStart + thisLeadingSpace; + lines[i].set_contentEnd(saveend); + } + } + } + + + // Create the wrapping list item + var List = this.CreateBlock(0); + List.blockType = (listType == BlockType_ul_li ? BlockType_ul : BlockType_ol); + List.children = []; + + // Process all lines in the range + for (var i = 0; i < lines.length; i++) { + // Find start of item, including leading blanks + var start_of_li = i; + while (start_of_li > 0 && lines[start_of_li - 1].blockType == BlockType_Blank) + start_of_li--; + + // Find end of the item, including trailing blanks + var end_of_li = i; + while (end_of_li < lines.length - 1 && lines[end_of_li + 1].blockType != listType) + end_of_li++; + + // Is this a simple or complex list item? + if (start_of_li == end_of_li) { + // It's a simple, single line item item + List.children.push(this.CreateBlock().CopyFrom(lines[i])); + } + else { + // Build a new string containing all child items + var bAnyBlanks = false; + var sb = this.m_Markdown.GetStringBuilder(); + for (var j = start_of_li; j <= end_of_li; j++) { + var l = lines[j]; + sb.Append(l.buf.substr(l.contentStart, l.contentLen)); + sb.Append('\n'); + + if (lines[j].blockType == BlockType_Blank) { + bAnyBlanks = true; + } + } + + // Create the item and process child blocks + var item = this.CreateBlock(); + item.blockType = BlockType_li; + item.lineStart = lines[start_of_li].lineStart; + var bp = new BlockProcessor(this.m_Markdown); + bp.m_parentType = listType; + item.children = bp.Process(sb.ToString()); + + // If no blank lines, change all contained paragraphs to plain text + if (!bAnyBlanks) { + for (var j = 0; j < item.children.length; j++) { + var child = item.children[j]; + if (child.blockType == BlockType_p) { + child.blockType = BlockType_span; + } + } + } + + // Add the complex item + List.children.push(item); + } + + // Continue processing from end of li + i = end_of_li; + } + + List.lineStart = List.children[0].lineStart; + + this.FreeBlocks(lines); + lines.length = 0; + + // Continue processing after this item + return List; + } + + /* + * BuildDefinition - build a single
        item + */ + p.BuildDefinition = function (lines) { + // Collapse all plain lines (ie: handle hardwrapped lines) + for (var i = 1; i < lines.length; i++) { + // Join plain paragraphs + if ((lines[i].blockType == BlockType_p) && + (lines[i - 1].blockType == BlockType_p || lines[i - 1].blockType == BlockType_dd)) { + lines[i - 1].set_contentEnd(lines[i].get_contentEnd()); + this.FreeBlock(lines[i]); + lines.splice(i, 1); + i--; + continue; + } + } + + // Single line definition + var bPreceededByBlank = lines[0].data; + if (lines.length == 1 && !bPreceededByBlank) { + var ret = lines[0]; + lines.length = 0; + return ret; + } + + // Build a new string containing all child items + var sb = this.m_Markdown.GetStringBuilder(); + for (var i = 0; i < lines.length; i++) { + var l = lines[i]; + sb.Append(l.buf.substr(l.contentStart, l.contentLen)); + sb.Append('\n'); + } + + // Create the item and process child blocks + var item = this.CreateBlock(lines[0].lineStart); + item.blockType = BlockType_dd; + var bp = new BlockProcessor(this.m_Markdown); + bp.m_parentType = BlockType_dd; + item.children = bp.Process(sb.ToString()); + + this.FreeBlocks(lines); + lines.length = 0; + + // Continue processing after this item + return item; + } + + p.BuildDefinitionLists = function (blocks) { + var currentList = null; + for (var i = 0; i < blocks.length; i++) { + switch (blocks[i].blockType) { + case BlockType_dt: + case BlockType_dd: + if (currentList == null) { + currentList = this.CreateBlock(blocks[i].lineStart); + currentList.blockType = BlockType_dl; + currentList.children = []; + blocks.splice(i, 0, currentList); + i++; + } + + currentList.children.push(blocks[i]); + blocks.splice(i, 1); + i--; + break; + + default: + currentList = null; + break; + } + } + } + + + p.BuildFootnote = function (lines) { + // Collapse all plain lines (ie: handle hardwrapped lines) + for (var i = 1; i < lines.length; i++) { + // Join plain paragraphs + if ((lines[i].blockType == BlockType_p) && + (lines[i - 1].blockType == BlockType_p || lines[i - 1].blockType == BlockType_footnote)) { + lines[i - 1].set_contentEnd(lines[i].get_contentEnd()); + this.FreeBlock(lines[i]); + lines.splice(i, 1); + i--; + continue; + } + } + + // Build a new string containing all child items + var sb = this.m_Markdown.GetStringBuilder(); + for (var i = 0; i < lines.length; i++) { + var l = lines[i]; + sb.Append(l.buf.substr(l.contentStart, l.contentLen)); + sb.Append('\n'); + } + + var bp = new BlockProcessor(this.m_Markdown); + bp.m_parentType = BlockType_footnote; + + // Create the item and process child blocks + var item = this.CreateBlock(lines[0].lineStart); + item.blockType = BlockType_footnote; + item.data = lines[0].data; + item.children = bp.Process(sb.ToString()); + + this.FreeBlocks(lines); + lines.length = 0; + + // Continue processing after this item + return item; + } + + + p.ProcessFencedCodeBlock = function (p, b) { + var fenceStart = p.m_position; + + // Extract the fence + p.Mark(); + while (p.current() == '~') + p.SkipForward(1); + var strFence = p.Extract(); + + // Must be at least 3 long + if (strFence.length < 3) + return false; + + // Rest of line must be blank + p.SkipLinespace(); + if (!p.eol()) + return false; + + // Skip the eol and remember start of code + p.SkipEol(); + var startCode = p.m_position; + + // Find the end fence + if (!p.Find(strFence)) + return false; + + // Character before must be a eol char + if (!is_lineend(p.CharAtOffset(-1))) + return false; + + var endCode = p.m_position; + + // Skip the fence + p.SkipForward(strFence.length); + + // Whitespace allowed at end + p.SkipLinespace(); + if (!p.eol()) + return false; + + // Create the code block + b.blockType = BlockType_codeblock; + b.children = []; + + // Remove the trailing line end + // (Javascript version has already normalized line ends to \n) + endCode--; + + // Create the child block with the entire content + var child = this.CreateBlock(fenceStart); + child.blockType = BlockType_indent; + child.buf = p.buf; + child.contentStart = startCode; + child.contentLen = endCode - startCode; + b.children.push(child); + + // Done + return true; + } + + + var ColumnAlignment_NA = 0; + var ColumnAlignment_Left = 1; + var ColumnAlignment_Right = 2; + var ColumnAlignment_Center = 3; + + function TableSpec() { + this.m_Columns = []; + this.m_Headers = null; + this.m_Rows = []; + } + + p = TableSpec.prototype; + + p.LeadingBar = false; + p.TrailingBar = false; + + p.ParseRow = function (p) { + p.SkipLinespace(); + + if (p.eol()) + return null; // Blank line ends the table + + var bAnyBars = this.LeadingBar; + if (this.LeadingBar && !p.SkipChar('|')) { + bAnyBars = true; + return null; + } + + // Create the row + var row = []; + + // Parse all columns except the last + + while (!p.eol()) { + // Find the next vertical bar + p.Mark(); + while (!p.eol() && p.current() != '|') + p.SkipForward(1); + + row.push(Trim(p.Extract())); + + bAnyBars |= p.SkipChar('|'); + } + + // Require at least one bar to continue the table + if (!bAnyBars) + return null; + + // Add missing columns + while (row.length < this.m_Columns.length) { + row.push(" "); + } + + p.SkipEol(); + return row; + } + + p.RenderRow = function (m, b, row, type) { + for (var i = 0; i < row.length; i++) { + b.Append("\t<"); + b.Append(type); + + if (i < this.m_Columns.length) { + switch (this.m_Columns[i]) { + case ColumnAlignment_Left: + b.Append(" align=\"left\""); + break; + case ColumnAlignment_Right: + b.Append(" align=\"right\""); + break; + case ColumnAlignment_Center: + b.Append(" align=\"center\""); + break; + } + } + + b.Append(">"); + m.m_SpanFormatter.Format2(b, row[i]); + b.Append("\n"); + } + } + + p.Render = function (m, b) { + b.Append("\n"); + if (this.m_Headers != null) { + b.Append("\n\n"); + this.RenderRow(m, b, this.m_Headers, "th"); + b.Append("\n\n"); + } + + b.Append("\n"); + for (var i = 0; i < this.m_Rows.length; i++) { + var row = this.m_Rows[i]; + b.Append("\n"); + this.RenderRow(m, b, row, "td"); + b.Append("\n"); + } + b.Append("\n"); + + b.Append("
        \n"); + } + + function TableSpec_Parse(p) { + // Leading line space allowed + p.SkipLinespace(); + + // Quick check for typical case + if (p.current() != '|' && p.current() != ':' && p.current() != '-') + return null; + + // Don't create the spec until it at least looks like one + var spec = null; + + // Leading bar, looks like a table spec + if (p.SkipChar('|')) { + spec = new TableSpec(); + spec.LeadingBar = true; + } + + + // Process all columns + while (true) { + // Parse column spec + p.SkipLinespace(); + + // Must have something in the spec + if (p.current() == '|') + return null; + + var AlignLeft = p.SkipChar(':'); + while (p.current() == '-') + p.SkipForward(1); + var AlignRight = p.SkipChar(':'); + p.SkipLinespace(); + + // Work out column alignment + var col = ColumnAlignment_NA; + if (AlignLeft && AlignRight) + col = ColumnAlignment_Center; + else if (AlignLeft) + col = ColumnAlignment_Left; + else if (AlignRight) + col = ColumnAlignment_Right; + + if (p.eol()) { + // Not a spec? + if (spec == null) + return null; + + // Add the final spec? + spec.m_Columns.push(col); + return spec; + } + + // We expect a vertical bar + if (!p.SkipChar('|')) + return null; + + // Create the table spec + if (spec == null) + spec = new TableSpec(); + + // Add the column + spec.m_Columns.push(col); + + // Check for trailing vertical bar + p.SkipLinespace(); + if (p.eol()) { + spec.TrailingBar = true; + return spec; + } + + // Next column + } + } + + // Exposed stuff + this.Markdown = Markdown; + this.HtmlTag = HtmlTag; +} (); + diff --git a/OpenAntrag/Scripts/MarkdownDeepEditor.js b/OpenAntrag/Scripts/MarkdownDeepEditor.js new file mode 100644 index 0000000..e342f87 --- /dev/null +++ b/OpenAntrag/Scripts/MarkdownDeepEditor.js @@ -0,0 +1,1398 @@ +// +//! MarkdownDeep - http://www.toptensoftware.com/markdowndeep +//! Copyright (C) 2010-2011 Topten Software +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this product except in +// compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and limitations under the License. +// + +/* +Usage: + +// 1. Create the editor an bind to a text area, output div and an optional source view div + - text area: the text area that user types to. + - output div: a div where the transformed html will be displayed + - source view view: an optional div where a "source" view of the rendered html will be placed + + var editor=new MarkdownDeepEditor.Editor(textarea_element, output_div, source_div) + +// 2. Optionally set options + + editor.disableShortCutKeys=true; // Disable Ctrl+B, Ctrl+I etc... + editor.disableAutoIndent=true; // Disable auto indent on enter key + editor.disableTabHandling=true; // Disable tab/shift+tab for indent + +// 3. Optionally install hooks + + editor.onPreTransform=function(editor, markdown) {} + editor.onPostTransform=function(editor, html) {} + editor.onPostUpdateDom=function(editor) {} + +// 4. Optionally create a toolbar/UI that calls editor.InvokeCommand(cmd) where cmd is one of: + + - "undo", + - "redo", + - "bold", + - "italic", + - "heading", + - "code", + - "ullist", + - "ollist", + - "indent", + - "outdent", + - "link", + - "img", + - "hr", + - "h0", + - "h1", + - "h2", + - "h3", + - "h4", + - "h5", + - "h6" + + eg: editor.InvokeCommand("heading") to toggle heading style of selection + +*/ + +var MarkdownDeepEditor=new function(){ + + // private:priv. + // private:.m_* + // private:.m_listType + // private:.m_prefixLen + + + var ie=false; + + // Various keycodes + var keycode_tab = 9; + var keycode_enter = 13; + var keycode_pgup = 33; + var keycode_pgdn = 34; + var keycode_home = 36; + var keycode_end = 35; + var keycode_left = 37; + var keycode_right = 39; + var keycode_up = 38; + var keycode_down = 40; + var keycode_backspace = 8; + var keycode_delete = 46; + + // Undo modes for the undo stack + var undomode_unknown = 0; + var undomode_text = 1; + var undomode_erase = 2; + var undomode_navigate = 3; + var undomode_whitespace = 4; + + // Shortcut keys Ctrl+key + var shortcut_keys={ + "Z": "undo", + "Y": "redo", + "B": "bold", + "I": "italic", + "H": "heading", + "K": "code", + "U": "ullist", + "O": "ollist", + "Q": "indent", + "E": "outdent", + "L": "link", + "G": "img", + "R": "hr", + "0": "h0", + "1": "h1", + "2": "h2", + "3": "h3", + "4": "h4", + "5": "h5", + "6": "h6" + } + + function starts_with(str, match) + { + return str.substr(0, match.length)==match; + } + + function ends_with(str, match) + { + return str.substr(-match.length)==match; + } + + function is_whitespace(ch) + { + return (ch==' ' || ch=='\t' || ch=='\r' || ch=='\n'); + } + + function is_crlf(ch) + { + return (ch=='\r' || ch=='\n'); + } + + function trim(str) + { + var i=0; + var l=str.length; + + while (ii && is_whitespace(str.charAt(l-1))) + l--; + + return str.substr(i, l-i); + } + + + // Helper for binding events + function BindEvent(obj, event, handler) + { + if (obj.addEventListener) + { + obj.addEventListener(event, handler, false); + } + else if (obj.attachEvent) + { + obj.attachEvent("on"+event, handler); + } + } + + // Helper for unbinding events + function UnbindEvent(obj, event, handler) + { + if (obj.removeEventListener) + { + obj.removeEventListener(event, handler, false); + } + else if (obj.detachEvent) + { + obj.detachEvent("on"+event, handler); + } + } + + function PreventEventDefault(event) + { + if (event.preventDefault) + { + event.preventDefault(); + } + if (event.cancelBubble!==undefined) + { + event.cancelBubble=true; + event.keyCode=0; + event.returnValue=false; + } + return false; + } + + function offsetToRangeCharacterMove(el, offset) + { + return offset - (el.value.slice(0, offset).split("\r\n").length - 1); + } + + // EditorState represents the initial and final state of an edit + function EditorState() + { + } + + priv=EditorState.prototype; + + priv.InitFromTextArea=function(textarea) + { + this.m_textarea=textarea; + if (ie) + { + var sel=document.selection.createRange(); + var temp=sel.duplicate(); + temp.moveToElementText(textarea); + var basepos=-temp.moveStart('character', -10000000); + + this.m_selectionStart = -sel.moveStart('character', -10000000)-basepos; + this.m_selectionEnd = -sel.moveEnd('character', -10000000)-basepos; + this.m_text=textarea.value.replace(/\r\n/gm,"\n"); + } + else + { + this.m_selectionStart = textarea.selectionStart; + this.m_selectionEnd = textarea.selectionEnd; + this.m_text=textarea.value; + } + } + + priv.Duplicate=function() + { + var other=new EditorState(); + other.m_textarea=this.m_textarea; + other.m_selectionEnd=this.m_selectionEnd; + other.m_selectionStart=this.m_selectionStart; + other.m_text=this.m_text; + return other; + } + + priv.Apply=function() + { + if (ie) + { + this.m_textarea.value=this.m_text; + this.m_textarea.focus(); + var r=this.m_textarea.createTextRange(); + r.collapse(true); + r.moveEnd("character", this.m_selectionEnd); + r.moveStart("character", this.m_selectionStart); + r.select(); + } + else + { + // Set the new text + var scrollTop=this.m_textarea.scrollTop; + this.m_textarea.value=this.m_text; + this.m_textarea.focus(); + this.m_textarea.setSelectionRange(this.m_selectionStart, this.m_selectionEnd); + this.m_textarea.scrollTop=scrollTop; + } + } + + priv.ReplaceSelection=function(str) + { + this.m_text=this.m_text.substr(0, this.m_selectionStart) + str + this.m_text.substr(this.m_selectionEnd); + this.m_selectionEnd=this.m_selectionStart + str.length; + } + + function adjust_pos(pos2, editpos, del, ins) + { + if (pos2= str.length && this.m_text.substr(this.m_selectionStart-str.length, str.length)==str; + } + + priv.FollowedBy=function(str) + { + return this.m_text.substr(this.m_selectionEnd, str.length)==str; + } + + priv.TrimSelection=function() + { + while (is_whitespace(this.m_text.charAt(this.m_selectionStart))) + this.m_selectionStart++; + while (this.m_selectionEnd>this.m_selectionStart && is_whitespace(this.m_text.charAt(this.m_selectionEnd-1))) + this.m_selectionEnd--; + } + + priv.IsStartOfLine=function(pos) + { + return pos==0 || is_crlf(this.m_text.charAt(pos-1)); + } + + priv.FindStartOfLine=function(pos) + { + // Move start of selection back to line start + while (pos>0 && !is_crlf(this.m_text.charAt(pos-1))) + { + pos--; + } + return pos; + } + + priv.FindEndOfLine=function(pos) + { + while (pos2 && this.m_text.substr(pos-2, 2)=="\r\n") + return pos-2; + if (pos>1 && is_crlf(this.m_text.charAt(pos-1))) + return pos-1; + return pos; + } + + priv.SelectWholeLines=function() + { + // Move selection to start of line + this.m_selectionStart=this.FindStartOfLine(this.m_selectionStart); + + // Move end of selection to start of the next line + if (!this.IsStartOfLine(this.m_selectionEnd)) + { + this.m_selectionEnd=this.SkipEol(this.FindEndOfLine(this.m_selectionEnd)); + } + } + + priv.SkipPreceedingWhiteSpace=function(pos) + { + while (pos>0 && is_whitespace(this.m_text.charAt(pos-1))) + { + pos--; + } + return pos; + } + + priv.SkipFollowingWhiteSpace=function(pos) + { + while (is_whitespace(this.m_text.charAt(pos))) + { + pos++; + } + return pos; + } + priv.SelectSurroundingWhiteSpace=function() + { + this.m_selectionStart=this.SkipPreceedingWhiteSpace(this.m_selectionStart); + this.m_selectionEnd=this.SkipFollowingWhiteSpace(this.m_selectionEnd); + } + + priv.CheckSimpleSelection=function() + { + var text=this.getSelectedText(); + var m=text.match(/\n[ \t\r]*\n/); + + if (m) + { + alertEx("Bitte mache eine Auswahl, die keinen Zeilenumbruch einschliet", "warning"); + return false; + } + + return true; + } + + // Check if line is completely blank + priv.IsBlankLine=function(p) + { + var len=this.m_text.length; + for (var i=p; i0) + { + var p=this.FindStartOfLine(this.SkipPreceedingEol(pos)); + if (p==0) + break; + if (this.IsBlankLine(p)) + break; + pos=p; + } + + // Is it a list? + if (this.DetectListType(pos).m_prefixLen!=0) + { + // Do it again, but stop at line with list prefix + pos=this.FindStartOfLine(savepos); + + // Move to first line after blank line + while (pos>0) + { + if (this.DetectListType(pos).m_prefixLen!=0) + return pos; + + // go to line before + pos=this.FindStartOfLine(this.SkipPreceedingEol(pos)); + } + } + + return pos; + } + + priv.FindEndOfParagraph=function(pos) + { + // Skip all lines that aren't blank + while (pos 0) + { + // Capture current state at end of undo buffer. + if (this.m_undoPos==this.m_undoStack.length) + { + this.CaptureUndoState(); + this.m_undoPos--; + } + + this.m_undoPos--; + this.m_undoStack[this.m_undoPos].Apply(); + this.m_undoMode=undomode_unknown; + + // Update markdown rendering + this.onMarkdownChanged(); + } + } + + pub.cmd_redo=function() + { + if (this.m_undoPos+1 < this.m_undoStack.length) + { + this.m_undoPos++; + this.m_undoStack[this.m_undoPos].Apply(); + this.m_undoMode=undomode_unknown; + + // Update markdown rendering + this.onMarkdownChanged(); + + // We're back at the current state + if (this.m_undoPos==this.m_undoStack.length-1) + { + this.m_undoStack.pop(); + } + } + } + + priv.setHeadingLevel=function(state, headingLevel) + { + // Select the entire heading + state.SelectParagraph(); + state.SelectSurroundingWhiteSpace(); + + // Get the selected text + var text=state.getSelectedText(); + + // Trim all whitespace + text=trim(text); + + var currentHeadingLevel=0; + var m=text.match(/^(\#+)(.*?)(\#+)?$/); + if (m) + { + text=trim(m[2]); + currentHeadingLevel=m[1].length; + } + else + { + m=text.match(/^(.*?)(?:\r\n|\n|\r)\s*(\-*|\=*)$/); + if (m) + { + text=trim(m[1]); + currentHeadingLevel=m[2].charAt(0)=="=" ? 1 : 0; + } + else + { + // Remove blank lines + text=text.replace(/(\r\n|\n|\r)/gm,""); + currentHeadingLevel=0; + } + } + + if (headingLevel==-1) + headingLevel=(currentHeadingLevel+1) % 4; + + // Removing a heading + var selOffset=0; + var selLen=0; + if (headingLevel==0) + { + // Deleting selection + if (text=="Heading") + { + state.ReplaceSelection(""); + return true; + } + + selLen=text.length; + selOffset=0; + } + else + { + if (text=="") + text="Heading"; + + selOffset=headingLevel+1; + selLen=text.length; + + var h=""; + for (var i=0; i0) + { + this.IndentCodeBlock(state, true); + } + else + { + // If we're in the leading whitespace of a line + // insert spaces instead of an actual tab character + var lineStart=state.FindStartOfLine(state.m_selectionStart); + var p; + for (p=lineStart; p0) + { + this.IndentCodeBlock(state, false); + return true; + } + return false; + } + + priv.bold_or_italic=function(state, marker) + { + var t=state.m_text; + var ml=marker.length; + + // Work out if we're adding or removing bold markers + var text=state.getSelectedText(); + if (starts_with(text, marker) && ends_with(text, marker)) + { + // Remove + state.ReplaceSelection(text.substr(ml, text.length-ml*2)); + } + else + { + // Add + state.TrimSelection(); + text=state.getSelectedText(); + if (!text) + text="text"; + else + text=text.replace(/(\r\n|\n|\r)/gm,""); + state.ReplaceSelection(marker + text + marker); + state.InflateSelection(-ml, -ml); + } + return true; + } + + // Bold + pub.cmd_bold=function(state) + { + if (!state.CheckSimpleSelection()) + return false; + state.TrimSelection(); + + // Expand selection to include leading/trailing stars + if (state.PreceededBy("**")) + state.m_selectionStart-=2; + if (state.FollowedBy("**")) + state.m_selectionEnd+=2; + + return this.bold_or_italic(state, "**"); + } + + // Italic + pub.cmd_italic=function(state) + { + if (!state.CheckSimpleSelection()) + return false; + state.TrimSelection(); + + // Expand selection to include leading/trailing stars + if ((state.PreceededBy("*") && !state.PreceededBy("**")) || state.PreceededBy("***")) + state.m_selectionStart-=1; + if ((state.FollowedBy("*") && !state.PreceededBy("**")) || state.FollowedBy("***")) + state.m_selectionEnd+=1; + + return this.bold_or_italic(state, "*"); + } + + priv.indent_or_outdent=function(state, outdent) + { + if (false && state.m_selectionStart==state.m_selectionEnd) + { + state.SelectSurroundingWhiteSpace(); + state.ReplaceSelection("\n\n> Quote\n\n"); + state.m_selectionStart+=4; + state.m_selectionEnd=state.m_selectionStart+5; + return true; + } + + // Make sure whole lines are selected + state.SelectWholeLines(); + + // Get the text, split into lines and check if all lines + // are indented + var lines=state.getSelectedText().split("\n"); + + // Apply the changes + for (var i=0; i ")) + newline=lines[i].substr(2); + } + else + { + newline="> " + lines[i]; + } + + lines.splice(i, 1, newline); + } + + // Replace + state.ReplaceSelection(lines.join("\n")); + + return true; + } + + // Quote + pub.cmd_indent=function(state) + { + return this.indent_or_outdent(state, false); + } + + pub.cmd_outdent=function(state) + { + return this.indent_or_outdent(state, true); + } + + priv.handle_list=function(state, type) + { + // Build an array of selected line offsets + var lines=[]; + if (state.getSelectedText().indexOf("\n")>0) + { + state.SelectWholeLines(); + + var line=state.m_selectionStart; + lines.push(line); + + while (true) + { + line=state.FindNextLine(line); + if (line>=state.m_selectionEnd) + break; + lines.push(line); + } + } + else + { + lines.push(state.FindStartOfLine(state.m_selectionStart)); + } + + // Now work out the new list type + // If the current selection only contains the current list type + // then remove list items + var prefix = type=="*" ? "* " : "1. "; + for (var i=0; i=0; i--) + { + var line=lines[i]; + var lt=state.DetectListType(line); + state.ReplaceAt(line, lt.m_prefixLen, prefix); + } + + // We now need to find any surrounding lists and renumber them + var mdd=new MarkdownDeep.Markdown(); + mdd.ExtraMode=true; + var listitems=mdd.GetListItems(state.m_text, state.m_selectionStart); + + while (listitems!=null) + { + // Process each list item + var dx=0; + for (var i=0; i1) + { + state.SelectWholeLines(); + } + + return true; + } + + + pub.cmd_ullist = function(state) { + return this.handle_list(state, "*"); + }; + + pub.cmd_ollist = function(state) { + return this.handle_list(state, "1"); + }; + + pub.cmd_link = function(ctx) { + ctx.TrimSelection(); + if (!ctx.CheckSimpleSelection()) + return false; + + var url = prompt("Bitte gib eine URL an:"); + if (url === null) + return false; + + var text = ctx.getSelectedText(); + if (text.length == 0) { + text = "Linktext"; + } + + var str = "[" + text + "](" + url + ")"; + + ctx.ReplaceSelection(str); + ctx.m_selectionStart++; + ctx.m_selectionEnd = ctx.m_selectionStart + text.length; + return true; + }; + + pub.cmd_img = function(ctx) { + ctx.TrimSelection(); + if (!ctx.CheckSimpleSelection()) + return false; + + var url = prompt("Bitte gib eine Bild-Url an"); + if (url === null) + return false; + + var alttext = ctx.getSelectedText(); + if (alttext.length == 0) { + alttext = "Bildtext"; + } + + var str = "![" + alttext + "](" + url + ")"; + + ctx.ReplaceSelection(str); + ctx.m_selectionStart += 2; + ctx.m_selectionEnd = ctx.m_selectionStart + alttext.length; + return true; + }; + + pub.cmd_hr = function(state) { + state.SelectSurroundingWhiteSpace(); + if (state.m_selectionStart == 0) + state.ReplaceSelection("----------\n\n"); + else + state.ReplaceSelection("\n\n----------\n\n"); + state.m_selectionStart = state.m_selectionEnd; + ; + return true; + }; + + pub.IndentNewLine = function() { + var editor = this; + var timer; + var handler = function() { + window.clearInterval(timer); + + // Create an editor state from the current selection + var state = new EditorState(); + state.InitFromTextArea(editor.m_textarea); + + // Find start of previous line + var prevline = state.FindStartOfLine(state.SkipPreceedingEol(state.m_selectionStart)); + + // Count spaces and tabs + var i = prevline; + while (true) { + var ch = state.m_text.charAt(i); + if (ch != ' ' && ch != '\t') + break; + i++; + } + + // Copy spaces and tabs to the new line + if (i > prevline) { + state.ReplaceSelection(state.m_text.substr(prevline, i - prevline)); + state.m_selectionStart = state.m_selectionEnd; + } + + state.Apply(); + }; + + timer = window.setInterval(handler, 1); + + return false; + }; + + pub.cmd_indented_newline = function(state) { + // Do default new line + state.ReplaceSelection("\n"); + state.m_selectionStart = state.m_selectionEnd; + + // Find start of previous line + var prevline = state.FindStartOfLine(state.SkipPreceedingEol(state.m_selectionStart)); + + // Count spaces and tabs + var i = prevline; + while (true) { + var ch = state.m_text.charAt(i); + if (ch != ' ' && ch != '\t') + break; + i++; + } + + // Copy spaces and tabs to the new line + if (i > prevline) { + state.ReplaceSelection(state.m_text.substr(prevline, i - prevline)); + state.m_selectionStart = state.m_selectionEnd; + } + + return true; + }; + + // Handle toolbar button + pub.InvokeCommand = function(id) { + // Special handling for undo and redo + if (id == "undo" || id == "redo") { + this["cmd_" + id](); + this.m_textarea.focus(); + return; + } + + // Create an editor state from the current selection + var state = new EditorState(); + state.InitFromTextArea(this.m_textarea); + + // Create a copy for undo buffer + var originalState = state.Duplicate(); + + // Call the handler and apply changes + if (this["cmd_" + id](state)) { + // Save current state on undo stack + this.m_undoMode = undomode_unknown; + this.m_undoStack.splice(this.m_undoPos, this.m_undoStack.length - this.m_undoPos, originalState); + this.m_undoPos++; + + // Apply new state + state.Apply(); + + // Update markdown rendering + this.onMarkdownChanged(); + + return true; + } else { + this.m_textarea.focus(); + return false; + } + }; + + delete priv; + delete pub; + + // Exports + this.Editor=Editor; +}(); diff --git a/OpenAntrag/Scripts/MarkdownDeepEditorUI.js b/OpenAntrag/Scripts/MarkdownDeepEditorUI.js new file mode 100644 index 0000000..1fca631 --- /dev/null +++ b/OpenAntrag/Scripts/MarkdownDeepEditorUI.js @@ -0,0 +1,371 @@ +// +//! MarkdownDeep - http://www.toptensoftware.com/markdowndeep +//! Copyright (C) 2010-2011 Topten Software +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this product except in +// compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and limitations under the License. +// + +var MarkdownDeepEditorUI=new function(){ + + // private:priv. + // private:.m_* + // private:.m_listType + // private:.m_prefixLen + + this.HelpHtmlWritten=false; + + this.HelpHtml=function(help_location) + { + // Start with nothing + var str=''; + str+='\n'; + return str; + } + + // Helper function that returns the HTML content of the toolbar + this.ToolbarHtml = function() { + // Start with nothing + var str = ''; + + //// The toolbar div + //str += '\n'; + //str += '
          \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        • \n'; + //str += '
        \n'; + //str += '
        \n'; + //return str; + + ////KRZE + // The toolbar div + str += '\n'; + str += '
          \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        • \n'; + str += '
        \n'; + return str; + + }; + + // Handle click on resize bar + this.onResizerMouseDown=function(e) + { + // Initialize state + var textarea=$(e.srcElement).prevAll("textarea")[0]; + var iOriginalMouse = e.clientY; + var iOriginalHeight = $(textarea).height(); + + // Bind to required events + $(document).bind("mousemove.mdd", DoDrag); + $(document).bind("mouseup.mdd", EndDrag); + + // Suppress default + return false; + + // End the drag operation + function EndDrag(e) + { + $(document).unbind("mousemove.mdd"); + $(document).unbind("mouseup.mdd"); + return false; + } + + // Handle drag operation + function DoDrag(e) + { + var newHeight=iOriginalHeight + e.clientY - iOriginalMouse; + if (newHeight<50) + newHeight=50; + $(textarea).height(newHeight); + return false; + } + + } + + // Used to store the scroll position of the help + var scrollPos=0; + var contentLoaded=false; + + ////KRZE + //// Show the popup modal help + //this.onShowHelpPopup=function() + //{ + // // Show the help + // $("#mdd_syntax_container").fadeIn("fast"); + + // // Restore the scroll position + // $(".modal_content").scrollTop(scrollPos); + + // // Hook escape key to close + // $(document).bind("keydown.mdd", function(e){ + // if (e.keyCode==27) + // { + // MarkdownDeepEditorUI.onCloseHelpPopup(); + // return false; + // } + // }); + + // // Load content + // if (!contentLoaded) + // { + // contentLoaded=true; + + // var help_location=$("#mdd_help_location").attr("href"); + // if (!help_location) + // help_location="mdd_help.htm"; + + // $("#mdd_syntax").load(help_location); + // } + + // return false; + //} + + //// Close the popup help + //this.onCloseHelpPopup=function() + //{ + // // Save scroll position + // scrollPos=$(".modal_content").scrollTop(); + + // // Hide help + // $("#mdd_syntax_container").fadeOut("fast"); + + // // Unhook escape key + // $(document).unbind("keydown.mdd"); + // $(document).unbind("scroll.mdd"); + + // return false; + //} + + // Toolbar click handler + this.onToolbarButton=function(e) + { + // Find the editor, grab the MarkdownEditor.Editor class from it's data + var editor=$(e.target).closest("div.mdd_toolbar").nextAll("textarea.mdd_editor").data("mdd"); + + // Invoke the command + editor.InvokeCommand($(e.target).attr("id").substr(4)); + + // Supress default + return false; + } +}(); + +/* +MarkdownDeep jQuery plugin + +Markup: + +
        + +
        +
        + +Note: the associated divs are all optional and if missing, the plugin will create them. However... +you might experience the page jumping around during load if you do this. ie: it's recommended to +explicitly include them. + +Example: + + $("textarea.mdd_editor").MarkdownDeep({ + help_location: "/Content/mdd_help.html", + disableTabHandling:true + }); + +Plugin options: + +* resizebar - boolean to include the resize bar (default:true) +* toolbar - boolean to include the toolbar (default:true) +* help_location - URL of where the help syntax reference should be loaded from (default:"mdd_help.html") + +Transform options: + +* SafeMode - boolean to enable only safe markup (default:false) +* ExtraMode - boolean to enable MarkdownExtra extensions (default:true) +* MarkdownInHtml - boolean to allow markdown in nested html (eg: divs) (default:false) +* AutoHeadingIDs - boolean to automatically generate IDs for headings (default:false) +* UrlBaseLocation - string base location of document (default:null) +* UrlRootLocation - string root location of document (default:null) +* NewWindowForExternalLinks - boolean to add target=_blank for links to urls starting with http:// (default:true) +* NewWindowForLocalLinks - boolean to add target=_blank for local relative links (good for preview mode) (default:true) +* NoFollowLinks - boolean to add rel=nofollow to all external links (default:false) +* HtmlClassFootnotes - string, html class name for footnotes div (default:nul) +* HtmlClassTitledImages - string, html div class name to wrap single paragraph images in (default:null) + +Editor options/hooks: + +* disableShortCutKeys - boolean, disables Ctrl+key shortcuts (default:false) +* disableAutoIndent - boolean, disables auto tab-indent on pressing enter (default:false) +* disableTabHandling - boolean, disables tab key working in the editor (default:false) +* onPreTransform=function(editor, markdown) +* onPostTransform=function(editor, html) +* onPostUpdateDom=function(editor) + +How the associated UI components are located: + +1. If toolbar option true: + + * looks for a preceeding div.mdd_toolbar and load toolbar into it + * if can't find the div, creates it + * it's better to include the div in your markup as it prevents jumping on page load + +2. If resizerbar option is true: + + * looks for a div.mdd_resizer bar immediately after the text area + * creates it can't be found + * it's better to include the div in your markup as it prevents jumping on page load + +3. Looks for, or creates a div to show the HTML preview in: + + * looks for an attribute on the text area 'data-mdd-preview'. If found, uses it + as a jQuery selector to locate a the preview div. + * if data attribute not found, uses '.mdd_preview' - ie: looks for any class with + mdd_preview class + * if no preview div found by the above selector, creates one immediately after the + resize bar + +4. Applies the passed options to both the MarkdownDeep text transform object and the Markdown + editor so the one options array can be used to set any supported option + +*/ + + +(function($){ + + $.fn.MarkdownDeep = function( options ) { + + // Default settings + var settings= + { + resizebar: true, + toolbar: true, + help_location: 'mdd_help.html' + }; + + // Apply options + if (options) + { + $.extend(settings, options); + } + + // Create each markdown editor + return this.each(function() { + + // Create the toolbar + if (settings.toolbar) + { + var toolbar=$(this).prev(".mdd_toolbar"); + if (toolbar.length==0) + { + toolbar=$("
        " + MarkdownDeepEditorUI.ToolbarHtml() + "
        "); + toolbar.insertBefore(this); + } + else + { + toolbar.append($(MarkdownDeepEditorUI.ToolbarHtml())); + } + $("a.mdd_button", toolbar).click(MarkdownDeepEditorUI.onToolbarButton); + $("a.mdd_help", toolbar).click(MarkdownDeepEditorUI.onShowHelpPopup); + + if (!MarkdownDeepEditorUI.HelpHtmlWritten) + { + var help=$(MarkdownDeepEditorUI.HelpHtml(settings.help_location)); + help.appendTo($("body")); + $("#mdd_close_help").click(MarkdownDeepEditorUI.onCloseHelpPopup); + MarkdownDeepEditorUI.HelpHtmlWritten=true; + } + } + + // Create the resize bar + var resizer; + if (settings.resizebar) + { + resizer=$(this).next(".mdd_resizer"); + if (resizer.length==0) + { + resizer=$("
        "); + resizer.insertAfter(this); + } + resizer.bind("mousedown", MarkdownDeepEditorUI.onResizerMouseDown); + } + + // Work out the preview div, by: + // 1. Look for a selector as a data attribute on the textarea + // 2. If not present, assume
        + // 3. If not found, append a div with that class + var preview_selector=$(this).attr("data-mdd-preview"); + if (!preview_selector) + preview_selector=".mdd_preview"; + var preview=$(preview_selector)[0]; + if (!preview) + { + $("
        ").insertAfter(resizer ? resizer : this); + preview=$(".mdd_preview")[0]; + } + + // Create the editor helper + var editor=new MarkdownDeepEditor.Editor(this, preview); + + // Apply options to both the markdown component and the editor + // (Yes lazy but easier for client) + if (options) + { + jQuery.extend(editor.Markdown, options); + jQuery.extend(editor, options); + } + + // Notify editor that options have changed + editor.onOptionsChanged(); + + // Attach the editor to the text area in case we want to get it back + $(this).data("mdd", editor); + + + }); + }; +})( jQuery ); \ No newline at end of file diff --git a/OpenAntrag/Scripts/Plugins/_not-used/jquery.jscrollpane.js b/OpenAntrag/Scripts/Plugins/_not-used/jquery.jscrollpane.js new file mode 100644 index 0000000..9bc41f9 --- /dev/null +++ b/OpenAntrag/Scripts/Plugins/_not-used/jquery.jscrollpane.js @@ -0,0 +1,1438 @@ +/*! + * jScrollPane - v2.0.14 - 2013-05-01 + * http://jscrollpane.kelvinluck.com/ + * + * Copyright (c) 2010 Kelvin Luck + * Dual licensed under the MIT or GPL licenses. + */ + +// Script: jScrollPane - cross browser customisable scrollbars +// +// *Version: 2.0.14, Last updated: 2013-05-01* +// +// Project Home - http://jscrollpane.kelvinluck.com/ +// GitHub - http://github.com/vitch/jScrollPane +// Source - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js +// (Minified) - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.min.js +// +// About: License +// +// Copyright (c) 2013 Kelvin Luck +// Dual licensed under the MIT or GPL Version 2 licenses. +// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt +// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt +// +// About: Examples +// +// All examples and demos are available through the jScrollPane example site at: +// http://jscrollpane.kelvinluck.com/ +// +// About: Support and Testing +// +// This plugin is tested on the browsers below and has been found to work reliably on them. If you run +// into a problem on one of the supported browsers then please visit the support section on the jScrollPane +// website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also +// welcome to fork the project on GitHub if you can contribute a fix for a given issue. +// +// jQuery Versions - tested in 1.4.2+ - reported to work in 1.3.x +// Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8 +// +// About: Release History +// +// 2.0.14 - (2013-05-01) Updated to most recent mouse wheel plugin (see #106) and related changes for sensible scroll speed +// 2.0.13 - (2013-05-01) Switched to semver compatible version name +// 2.0.0beta12 - (2012-09-27) fix for jQuery 1.8+ +// 2.0.0beta11 - (2012-05-14) +// 2.0.0beta10 - (2011-04-17) cleaner required size calculation, improved keyboard support, stickToBottom/Left, other small fixes +// 2.0.0beta9 - (2011-01-31) new API methods, bug fixes and correct keyboard support for FF/OSX +// 2.0.0beta8 - (2011-01-29) touchscreen support, improved keyboard support +// 2.0.0beta7 - (2011-01-23) scroll speed consistent (thanks Aivo Paas) +// 2.0.0beta6 - (2010-12-07) scrollToElement horizontal support +// 2.0.0beta5 - (2010-10-18) jQuery 1.4.3 support, various bug fixes +// 2.0.0beta4 - (2010-09-17) clickOnTrack support, bug fixes +// 2.0.0beta3 - (2010-08-27) Horizontal mousewheel, mwheelIntent, keyboard support, bug fixes +// 2.0.0beta2 - (2010-08-21) Bug fixes +// 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable horizontal scrolling, initially hidden +// elements and dynamically sized elements. +// 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprecated + +(function($,window,undefined){ + + $.fn.jScrollPane = function(settings) + { + // JScrollPane "class" - public methods are available through $('selector').data('jsp') + function JScrollPane(elem, s) + { + var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight, + percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY, + verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition, + verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown, + horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight, + reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth, + wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false, + originalElement = elem.clone(false, false).empty(), + mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp'; + + originalPadding = elem.css('paddingTop') + ' ' + + elem.css('paddingRight') + ' ' + + elem.css('paddingBottom') + ' ' + + elem.css('paddingLeft'); + originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) + + (parseInt(elem.css('paddingRight'), 10) || 0); + + function initialise(s) + { + + var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY, + hasContainingSpaceChanged, originalScrollTop, originalScrollLeft, + maintainAtBottom = false, maintainAtRight = false; + + settings = s; + + if (pane === undefined) { + originalScrollTop = elem.scrollTop(); + originalScrollLeft = elem.scrollLeft(); + + elem.css( + { + overflow: 'hidden', + padding: 0 + } + ); + // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should + // come back to it later and check once it is unhidden... + paneWidth = elem.innerWidth() + originalPaddingTotalWidth; + paneHeight = elem.innerHeight(); + + elem.width(paneWidth); + + pane = $('
        ').css('padding', originalPadding).append(elem.children()); + container = $('
        ') + .css({ + 'width': paneWidth + 'px', + 'height': paneHeight + 'px' + } + ).append(pane).appendTo(elem); + + /* + // Move any margins from the first and last children up to the container so they can still + // collapse with neighbouring elements as they would before jScrollPane + firstChild = pane.find(':first-child'); + lastChild = pane.find(':last-child'); + elem.css( + { + 'margin-top': firstChild.css('margin-top'), + 'margin-bottom': lastChild.css('margin-bottom') + } + ); + firstChild.css('margin-top', 0); + lastChild.css('margin-bottom', 0); + */ + } else { + elem.css('width', ''); + + maintainAtBottom = settings.stickToBottom && isCloseToBottom(); + maintainAtRight = settings.stickToRight && isCloseToRight(); + + hasContainingSpaceChanged = elem.innerWidth() + originalPaddingTotalWidth != paneWidth || elem.outerHeight() != paneHeight; + + if (hasContainingSpaceChanged) { + paneWidth = elem.innerWidth() + originalPaddingTotalWidth; + paneHeight = elem.innerHeight(); + container.css({ + width: paneWidth + 'px', + height: paneHeight + 'px' + }); + } + + // If nothing changed since last check... + if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) { + elem.width(paneWidth); + return; + } + previousContentWidth = contentWidth; + + pane.css('width', ''); + elem.width(paneWidth); + + container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end(); + } + + pane.css('overflow', 'auto'); + if (s.contentWidth) { + contentWidth = s.contentWidth; + } else { + contentWidth = pane[0].scrollWidth; + } + contentHeight = pane[0].scrollHeight; + pane.css('overflow', ''); + + percentInViewH = contentWidth / paneWidth; + percentInViewV = contentHeight / paneHeight; + isScrollableV = percentInViewV > 1; + + isScrollableH = percentInViewH > 1; + + //console.log(paneWidth, paneHeight, contentWidth, contentHeight, percentInViewH, percentInViewV, isScrollableH, isScrollableV); + + if (!(isScrollableH || isScrollableV)) { + elem.removeClass('jspScrollable'); + pane.css({ + top: 0, + width: container.width() - originalPaddingTotalWidth + }); + removeMousewheel(); + removeFocusHandler(); + removeKeyboardNav(); + removeClickOnTrack(); + } else { + elem.addClass('jspScrollable'); + + isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition); + if (isMaintainingPositon) { + lastContentX = contentPositionX(); + lastContentY = contentPositionY(); + } + + initialiseVerticalScroll(); + initialiseHorizontalScroll(); + resizeScrollbars(); + + if (isMaintainingPositon) { + scrollToX(maintainAtRight ? (contentWidth - paneWidth ) : lastContentX, false); + scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false); + } + + initFocusHandler(); + initMousewheel(); + initTouch(); + + if (settings.enableKeyboardNavigation) { + initKeyboardNav(); + } + if (settings.clickOnTrack) { + initClickOnTrack(); + } + + observeHash(); + if (settings.hijackInternalLinks) { + hijackInternalLinks(); + } + } + + if (settings.autoReinitialise && !reinitialiseInterval) { + reinitialiseInterval = setInterval( + function() + { + initialise(settings); + }, + settings.autoReinitialiseDelay + ); + } else if (!settings.autoReinitialise && reinitialiseInterval) { + clearInterval(reinitialiseInterval); + } + + originalScrollTop && elem.scrollTop(0) && scrollToY(originalScrollTop, false); + originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalScrollLeft, false); + + elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]); + } + + function initialiseVerticalScroll() + { + if (isScrollableV) { + + container.append( + $('
        ').append( + $('
        '), + $('
        ').append( + $('
        ').append( + $('
        '), + $('
        ') + ) + ), + $('
        ') + ) + ); + + verticalBar = container.find('>.jspVerticalBar'); + verticalTrack = verticalBar.find('>.jspTrack'); + verticalDrag = verticalTrack.find('>.jspDrag'); + + if (settings.showArrows) { + arrowUp = $('').bind( + 'mousedown.jsp', getArrowScroll(0, -1) + ).bind('click.jsp', nil); + arrowDown = $('').bind( + 'mousedown.jsp', getArrowScroll(0, 1) + ).bind('click.jsp', nil); + if (settings.arrowScrollOnHover) { + arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1, arrowUp)); + arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1, arrowDown)); + } + + appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown); + } + + verticalTrackHeight = paneHeight; + container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each( + function() + { + verticalTrackHeight -= $(this).outerHeight(); + } + ); + + + verticalDrag.hover( + function() + { + verticalDrag.addClass('jspHover'); + }, + function() + { + verticalDrag.removeClass('jspHover'); + } + ).bind( + 'mousedown.jsp', + function(e) + { + // Stop IE from allowing text selection + $('html').bind('dragstart.jsp selectstart.jsp', nil); + + verticalDrag.addClass('jspActive'); + + var startY = e.pageY - verticalDrag.position().top; + + $('html').bind( + 'mousemove.jsp', + function(e) + { + positionDragY(e.pageY - startY, false); + } + ).bind('mouseup.jsp mouseleave.jsp', cancelDrag); + return false; + } + ); + sizeVerticalScrollbar(); + } + } + + function sizeVerticalScrollbar() + { + verticalTrack.height(verticalTrackHeight + 'px'); + verticalDragPosition = 0; + scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth(); + + // Make the pane thinner to allow for the vertical scrollbar + pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth); + + // Add margin to the left of the pane if scrollbars are on that side (to position + // the scrollbar on the left or right set it's left or right property in CSS) + try { + if (verticalBar.position().left === 0) { + pane.css('margin-left', scrollbarWidth + 'px'); + } + } catch (err) { + } + } + + function initialiseHorizontalScroll() + { + if (isScrollableH) { + + container.append( + $('
        ').append( + $('
        '), + $('
        ').append( + $('
        ').append( + $('
        '), + $('
        ') + ) + ), + $('
        ') + ) + ); + + horizontalBar = container.find('>.jspHorizontalBar'); + horizontalTrack = horizontalBar.find('>.jspTrack'); + horizontalDrag = horizontalTrack.find('>.jspDrag'); + + if (settings.showArrows) { + arrowLeft = $('').bind( + 'mousedown.jsp', getArrowScroll(-1, 0) + ).bind('click.jsp', nil); + arrowRight = $('').bind( + 'mousedown.jsp', getArrowScroll(1, 0) + ).bind('click.jsp', nil); + if (settings.arrowScrollOnHover) { + arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft)); + arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0, arrowRight)); + } + appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight); + } + + horizontalDrag.hover( + function() + { + horizontalDrag.addClass('jspHover'); + }, + function() + { + horizontalDrag.removeClass('jspHover'); + } + ).bind( + 'mousedown.jsp', + function(e) + { + // Stop IE from allowing text selection + $('html').bind('dragstart.jsp selectstart.jsp', nil); + + horizontalDrag.addClass('jspActive'); + + var startX = e.pageX - horizontalDrag.position().left; + + $('html').bind( + 'mousemove.jsp', + function(e) + { + positionDragX(e.pageX - startX, false); + } + ).bind('mouseup.jsp mouseleave.jsp', cancelDrag); + return false; + } + ); + horizontalTrackWidth = container.innerWidth(); + sizeHorizontalScrollbar(); + } + } + + function sizeHorizontalScrollbar() + { + container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each( + function() + { + horizontalTrackWidth -= $(this).outerWidth(); + } + ); + + horizontalTrack.width(horizontalTrackWidth + 'px'); + horizontalDragPosition = 0; + } + + function resizeScrollbars() + { + if (isScrollableH && isScrollableV) { + var horizontalTrackHeight = horizontalTrack.outerHeight(), + verticalTrackWidth = verticalTrack.outerWidth(); + verticalTrackHeight -= horizontalTrackHeight; + $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each( + function() + { + horizontalTrackWidth += $(this).outerWidth(); + } + ); + horizontalTrackWidth -= verticalTrackWidth; + paneHeight -= verticalTrackWidth; + paneWidth -= horizontalTrackHeight; + horizontalTrack.parent().append( + $('
        ').css('width', horizontalTrackHeight + 'px') + ); + sizeVerticalScrollbar(); + sizeHorizontalScrollbar(); + } + // reflow content + if (isScrollableH) { + pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px'); + } + contentHeight = pane.outerHeight(); + percentInViewV = contentHeight / paneHeight; + + if (isScrollableH) { + horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth); + if (horizontalDragWidth > settings.horizontalDragMaxWidth) { + horizontalDragWidth = settings.horizontalDragMaxWidth; + } else if (horizontalDragWidth < settings.horizontalDragMinWidth) { + horizontalDragWidth = settings.horizontalDragMinWidth; + } + horizontalDrag.width(horizontalDragWidth + 'px'); + dragMaxX = horizontalTrackWidth - horizontalDragWidth; + _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons + } + if (isScrollableV) { + verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight); + if (verticalDragHeight > settings.verticalDragMaxHeight) { + verticalDragHeight = settings.verticalDragMaxHeight; + } else if (verticalDragHeight < settings.verticalDragMinHeight) { + verticalDragHeight = settings.verticalDragMinHeight; + } + verticalDrag.height(verticalDragHeight + 'px'); + dragMaxY = verticalTrackHeight - verticalDragHeight; + _positionDragY(verticalDragPosition); // To update the state for the arrow buttons + } + } + + function appendArrows(ele, p, a1, a2) + { + var p1 = "before", p2 = "after", aTemp; + + // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear + // at the top or the bottom of the bar? + if (p == "os") { + p = /Mac/.test(navigator.platform) ? "after" : "split"; + } + if (p == p1) { + p2 = p; + } else if (p == p2) { + p1 = p; + aTemp = a1; + a1 = a2; + a2 = aTemp; + } + + ele[p1](a1)[p2](a2); + } + + function getArrowScroll(dirX, dirY, ele) + { + return function() + { + arrowScroll(dirX, dirY, this, ele); + this.blur(); + return false; + }; + } + + function arrowScroll(dirX, dirY, arrow, ele) + { + arrow = $(arrow).addClass('jspActive'); + + var eve, + scrollTimeout, + isFirst = true, + doScroll = function() + { + if (dirX !== 0) { + jsp.scrollByX(dirX * settings.arrowButtonSpeed); + } + if (dirY !== 0) { + jsp.scrollByY(dirY * settings.arrowButtonSpeed); + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq); + isFirst = false; + }; + + doScroll(); + + eve = ele ? 'mouseout.jsp' : 'mouseup.jsp'; + ele = ele || $('html'); + ele.bind( + eve, + function() + { + arrow.removeClass('jspActive'); + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + ele.unbind(eve); + } + ); + } + + function initClickOnTrack() + { + removeClickOnTrack(); + if (isScrollableV) { + verticalTrack.bind( + 'mousedown.jsp', + function(e) + { + if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) { + var clickedTrack = $(this), + offset = clickedTrack.offset(), + direction = e.pageY - offset.top - verticalDragPosition, + scrollTimeout, + isFirst = true, + doScroll = function() + { + var offset = clickedTrack.offset(), + pos = e.pageY - offset.top - verticalDragHeight / 2, + contentDragY = paneHeight * settings.scrollPagePercent, + dragY = dragMaxY * contentDragY / (contentHeight - paneHeight); + if (direction < 0) { + if (verticalDragPosition - dragY > pos) { + jsp.scrollByY(-contentDragY); + } else { + positionDragY(pos); + } + } else if (direction > 0) { + if (verticalDragPosition + dragY < pos) { + jsp.scrollByY(contentDragY); + } else { + positionDragY(pos); + } + } else { + cancelClick(); + return; + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq); + isFirst = false; + }, + cancelClick = function() + { + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + $(document).unbind('mouseup.jsp', cancelClick); + }; + doScroll(); + $(document).bind('mouseup.jsp', cancelClick); + return false; + } + } + ); + } + + if (isScrollableH) { + horizontalTrack.bind( + 'mousedown.jsp', + function(e) + { + if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) { + var clickedTrack = $(this), + offset = clickedTrack.offset(), + direction = e.pageX - offset.left - horizontalDragPosition, + scrollTimeout, + isFirst = true, + doScroll = function() + { + var offset = clickedTrack.offset(), + pos = e.pageX - offset.left - horizontalDragWidth / 2, + contentDragX = paneWidth * settings.scrollPagePercent, + dragX = dragMaxX * contentDragX / (contentWidth - paneWidth); + if (direction < 0) { + if (horizontalDragPosition - dragX > pos) { + jsp.scrollByX(-contentDragX); + } else { + positionDragX(pos); + } + } else if (direction > 0) { + if (horizontalDragPosition + dragX < pos) { + jsp.scrollByX(contentDragX); + } else { + positionDragX(pos); + } + } else { + cancelClick(); + return; + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq); + isFirst = false; + }, + cancelClick = function() + { + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + $(document).unbind('mouseup.jsp', cancelClick); + }; + doScroll(); + $(document).bind('mouseup.jsp', cancelClick); + return false; + } + } + ); + } + } + + function removeClickOnTrack() + { + if (horizontalTrack) { + horizontalTrack.unbind('mousedown.jsp'); + } + if (verticalTrack) { + verticalTrack.unbind('mousedown.jsp'); + } + } + + function cancelDrag() + { + $('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp'); + + if (verticalDrag) { + verticalDrag.removeClass('jspActive'); + } + if (horizontalDrag) { + horizontalDrag.removeClass('jspActive'); + } + } + + function positionDragY(destY, animate) + { + if (!isScrollableV) { + return; + } + if (destY < 0) { + destY = 0; + } else if (destY > dragMaxY) { + destY = dragMaxY; + } + + // can't just check if(animate) because false is a valid value that could be passed in... + if (animate === undefined) { + animate = settings.animateScroll; + } + if (animate) { + jsp.animate(verticalDrag, 'top', destY, _positionDragY); + } else { + verticalDrag.css('top', destY); + _positionDragY(destY); + } + + } + + function _positionDragY(destY) + { + if (destY === undefined) { + destY = verticalDrag.position().top; + } + + container.scrollTop(0); + verticalDragPosition = destY; + + var isAtTop = verticalDragPosition === 0, + isAtBottom = verticalDragPosition == dragMaxY, + percentScrolled = destY/ dragMaxY, + destTop = -percentScrolled * (contentHeight - paneHeight); + + if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) { + wasAtTop = isAtTop; + wasAtBottom = isAtBottom; + elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]); + } + + updateVerticalArrows(isAtTop, isAtBottom); + pane.css('top', destTop); + elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll'); + } + + function positionDragX(destX, animate) + { + if (!isScrollableH) { + return; + } + if (destX < 0) { + destX = 0; + } else if (destX > dragMaxX) { + destX = dragMaxX; + } + + if (animate === undefined) { + animate = settings.animateScroll; + } + if (animate) { + jsp.animate(horizontalDrag, 'left', destX, _positionDragX); + } else { + horizontalDrag.css('left', destX); + _positionDragX(destX); + } + } + + function _positionDragX(destX) + { + if (destX === undefined) { + destX = horizontalDrag.position().left; + } + + container.scrollTop(0); + horizontalDragPosition = destX; + + var isAtLeft = horizontalDragPosition === 0, + isAtRight = horizontalDragPosition == dragMaxX, + percentScrolled = destX / dragMaxX, + destLeft = -percentScrolled * (contentWidth - paneWidth); + + if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) { + wasAtLeft = isAtLeft; + wasAtRight = isAtRight; + elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]); + } + + updateHorizontalArrows(isAtLeft, isAtRight); + pane.css('left', destLeft); + elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll'); + } + + function updateVerticalArrows(isAtTop, isAtBottom) + { + if (settings.showArrows) { + arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled'); + arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled'); + } + } + + function updateHorizontalArrows(isAtLeft, isAtRight) + { + if (settings.showArrows) { + arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled'); + arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled'); + } + } + + function scrollToY(destY, animate) + { + var percentScrolled = destY / (contentHeight - paneHeight); + positionDragY(percentScrolled * dragMaxY, animate); + } + + function scrollToX(destX, animate) + { + var percentScrolled = destX / (contentWidth - paneWidth); + positionDragX(percentScrolled * dragMaxX, animate); + } + + function scrollToElement(ele, stickToTop, animate) + { + var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX; + + // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any + // errors from the lookup... + try { + e = $(ele); + } catch (err) { + return; + } + eleHeight = e.outerHeight(); + eleWidth= e.outerWidth(); + + container.scrollTop(0); + container.scrollLeft(0); + + // loop through parents adding the offset top of any elements that are relatively positioned between + // the focused element and the jspPane so we can get the true distance from the top + // of the focused element to the top of the scrollpane... + while (!e.is('.jspPane')) { + eleTop += e.position().top; + eleLeft += e.position().left; + e = e.offsetParent(); + if (/^body|html$/i.test(e[0].nodeName)) { + // we ended up too high in the document structure. Quit! + return; + } + } + + viewportTop = contentPositionY(); + maxVisibleEleTop = viewportTop + paneHeight; + if (eleTop < viewportTop || stickToTop) { // element is above viewport + destY = eleTop - settings.verticalGutter; + } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport + destY = eleTop - paneHeight + eleHeight + settings.verticalGutter; + } + if (destY) { + scrollToY(destY, animate); + } + + viewportLeft = contentPositionX(); + maxVisibleEleLeft = viewportLeft + paneWidth; + if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport + destX = eleLeft - settings.horizontalGutter; + } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport + destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter; + } + if (destX) { + scrollToX(destX, animate); + } + + } + + function contentPositionX() + { + return -pane.position().left; + } + + function contentPositionY() + { + return -pane.position().top; + } + + function isCloseToBottom() + { + var scrollableHeight = contentHeight - paneHeight; + return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10); + } + + function isCloseToRight() + { + var scrollableWidth = contentWidth - paneWidth; + return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10); + } + + function initMousewheel() + { + container.unbind(mwEvent).bind( + mwEvent, + function (event, delta, deltaX, deltaY) { + var dX = horizontalDragPosition, dY = verticalDragPosition; + jsp.scrollBy(deltaX * settings.mouseWheelSpeed, -deltaY * settings.mouseWheelSpeed, false); + // return true if there was no movement so rest of screen can scroll + return dX == horizontalDragPosition && dY == verticalDragPosition; + } + ); + } + + function removeMousewheel() + { + container.unbind(mwEvent); + } + + function nil() + { + return false; + } + + function initFocusHandler() + { + pane.find(':input,a').unbind('focus.jsp').bind( + 'focus.jsp', + function(e) + { + scrollToElement(e.target, false); + } + ); + } + + function removeFocusHandler() + { + pane.find(':input,a').unbind('focus.jsp'); + } + + function initKeyboardNav() + { + var keyDown, elementHasScrolled, validParents = []; + isScrollableH && validParents.push(horizontalBar[0]); + isScrollableV && validParents.push(verticalBar[0]); + + // IE also focuses elements that don't have tabindex set. + pane.focus( + function() + { + elem.focus(); + } + ); + + elem.attr('tabindex', 0) + .unbind('keydown.jsp keypress.jsp') + .bind( + 'keydown.jsp', + function(e) + { + if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){ + return; + } + var dX = horizontalDragPosition, dY = verticalDragPosition; + switch(e.keyCode) { + case 40: // down + case 38: // up + case 34: // page down + case 32: // space + case 33: // page up + case 39: // right + case 37: // left + keyDown = e.keyCode; + keyDownHandler(); + break; + case 35: // end + scrollToY(contentHeight - paneHeight); + keyDown = null; + break; + case 36: // home + scrollToY(0); + keyDown = null; + break; + } + + elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition; + return !elementHasScrolled; + } + ).bind( + 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls... + function(e) + { + if (e.keyCode == keyDown) { + keyDownHandler(); + } + return !elementHasScrolled; + } + ); + + if (settings.hideFocus) { + elem.css('outline', 'none'); + if ('hideFocus' in container[0]){ + elem.attr('hideFocus', true); + } + } else { + elem.css('outline', ''); + if ('hideFocus' in container[0]){ + elem.attr('hideFocus', false); + } + } + + function keyDownHandler() + { + var dX = horizontalDragPosition, dY = verticalDragPosition; + switch(keyDown) { + case 40: // down + jsp.scrollByY(settings.keyboardSpeed, false); + break; + case 38: // up + jsp.scrollByY(-settings.keyboardSpeed, false); + break; + case 34: // page down + case 32: // space + jsp.scrollByY(paneHeight * settings.scrollPagePercent, false); + break; + case 33: // page up + jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false); + break; + case 39: // right + jsp.scrollByX(settings.keyboardSpeed, false); + break; + case 37: // left + jsp.scrollByX(-settings.keyboardSpeed, false); + break; + } + + elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition; + return elementHasScrolled; + } + } + + function removeKeyboardNav() + { + elem.attr('tabindex', '-1') + .removeAttr('tabindex') + .unbind('keydown.jsp keypress.jsp'); + } + + function observeHash() + { + if (location.hash && location.hash.length > 1) { + var e, + retryInt, + hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS + ; + try { + e = $('#' + hash + ', a[name="' + hash + '"]'); + } catch (err) { + return; + } + + if (e.length && pane.find(hash)) { + // nasty workaround but it appears to take a little while before the hash has done its thing + // to the rendered page so we just wait until the container's scrollTop has been messed up. + if (container.scrollTop() === 0) { + retryInt = setInterval( + function() + { + if (container.scrollTop() > 0) { + scrollToElement(e, true); + $(document).scrollTop(container.position().top); + clearInterval(retryInt); + } + }, + 50 + ); + } else { + scrollToElement(e, true); + $(document).scrollTop(container.position().top); + } + } + } + } + + function hijackInternalLinks() + { + // only register the link handler once + if ($(document.body).data('jspHijack')) { + return; + } + + // remember that the handler was bound + $(document.body).data('jspHijack', true); + + // use live handler to also capture newly created links + $(document.body).delegate('a[href*=#]', 'click', function(event) { + // does the link point to the same page? + // this also takes care of cases with a -Tag or Links not starting with the hash # + // e.g. when the current url already is index.html + var href = this.href.substr(0, this.href.indexOf('#')), + locationHref = location.href, + hash, + element, + container, + jsp, + scrollTop, + elementTop; + if (location.href.indexOf('#') !== -1) { + locationHref = location.href.substr(0, location.href.indexOf('#')); + } + if (href !== locationHref) { + // the link points to another page + return; + } + + // check if jScrollPane should handle this click event + hash = escape(this.href.substr(this.href.indexOf('#') + 1)); + + // find the element on the page + element; + try { + element = $('#' + hash + ', a[name="' + hash + '"]'); + } catch (e) { + // hash is not a valid jQuery identifier + return; + } + + if (!element.length) { + // this link does not point to an element on this page + return; + } + + container = element.closest('.jspScrollable'); + jsp = container.data('jsp'); + + // jsp might be another jsp instance than the one, that bound this event + // remember: this event is only bound once for all instances. + jsp.scrollToElement(element, true); + + if (container[0].scrollIntoView) { + // also scroll to the top of the container (if it is not visible) + scrollTop = $(window).scrollTop(); + elementTop = element.offset().top; + if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) { + container[0].scrollIntoView(); + } + } + + // jsp handled this event, prevent the browser default (scrolling :P) + event.preventDefault(); + }); + } + + // Init touch on iPad, iPhone, iPod, Android + function initTouch() + { + var startX, + startY, + touchStartX, + touchStartY, + moved, + moving = false; + + container.unbind('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').bind( + 'touchstart.jsp', + function(e) + { + var touch = e.originalEvent.touches[0]; + startX = contentPositionX(); + startY = contentPositionY(); + touchStartX = touch.pageX; + touchStartY = touch.pageY; + moved = false; + moving = true; + } + ).bind( + 'touchmove.jsp', + function(ev) + { + if(!moving) { + return; + } + + var touchPos = ev.originalEvent.touches[0], + dX = horizontalDragPosition, dY = verticalDragPosition; + + jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY); + + moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5; + + // return true if there was no movement so rest of screen can scroll + return dX == horizontalDragPosition && dY == verticalDragPosition; + } + ).bind( + 'touchend.jsp', + function(e) + { + moving = false; + /*if(moved) { + return false; + }*/ + } + ).bind( + 'click.jsp-touchclick', + function(e) + { + if(moved) { + moved = false; + return false; + } + } + ); + } + + function destroy(){ + var currentY = contentPositionY(), + currentX = contentPositionX(); + elem.removeClass('jspScrollable').unbind('.jsp'); + elem.replaceWith(originalElement.append(pane.children())); + originalElement.scrollTop(currentY); + originalElement.scrollLeft(currentX); + + // clear reinitialize timer if active + if (reinitialiseInterval) { + clearInterval(reinitialiseInterval); + } + } + + // Public API + $.extend( + jsp, + { + // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it + // was initialised). The settings object which is passed in will override any settings from the + // previous time it was initialised - if you don't pass any settings then the ones from the previous + // initialisation will be used. + reinitialise: function(s) + { + s = $.extend({}, settings, s); + initialise(s); + }, + // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so + // that it can be seen within the viewport. If stickToTop is true then the element will appear at + // the top of the viewport, if it is false then the viewport will scroll as little as possible to + // show the element. You can also specify if you want animation to occur. If you don't provide this + // argument then the animateScroll value from the settings object is used instead. + scrollToElement: function(ele, stickToTop, animate) + { + scrollToElement(ele, stickToTop, animate); + }, + // Scrolls the pane so that the specified co-ordinates within the content are at the top left + // of the viewport. animate is optional and if not passed then the value of animateScroll from + // the settings object this jScrollPane was initialised with is used. + scrollTo: function(destX, destY, animate) + { + scrollToX(destX, animate); + scrollToY(destY, animate); + }, + // Scrolls the pane so that the specified co-ordinate within the content is at the left of the + // viewport. animate is optional and if not passed then the value of animateScroll from the settings + // object this jScrollPane was initialised with is used. + scrollToX: function(destX, animate) + { + scrollToX(destX, animate); + }, + // Scrolls the pane so that the specified co-ordinate within the content is at the top of the + // viewport. animate is optional and if not passed then the value of animateScroll from the settings + // object this jScrollPane was initialised with is used. + scrollToY: function(destY, animate) + { + scrollToY(destY, animate); + }, + // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate + // is optional and if not passed then the value of animateScroll from the settings object this + // jScrollPane was initialised with is used. + scrollToPercentX: function(destPercentX, animate) + { + scrollToX(destPercentX * (contentWidth - paneWidth), animate); + }, + // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate + // is optional and if not passed then the value of animateScroll from the settings object this + // jScrollPane was initialised with is used. + scrollToPercentY: function(destPercentY, animate) + { + scrollToY(destPercentY * (contentHeight - paneHeight), animate); + }, + // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then + // the value of animateScroll from the settings object this jScrollPane was initialised with is used. + scrollBy: function(deltaX, deltaY, animate) + { + jsp.scrollByX(deltaX, animate); + jsp.scrollByY(deltaY, animate); + }, + // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then + // the value of animateScroll from the settings object this jScrollPane was initialised with is used. + scrollByX: function(deltaX, animate) + { + var destX = contentPositionX() + Math[deltaX<0 ? 'floor' : 'ceil'](deltaX), + percentScrolled = destX / (contentWidth - paneWidth); + positionDragX(percentScrolled * dragMaxX, animate); + }, + // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then + // the value of animateScroll from the settings object this jScrollPane was initialised with is used. + scrollByY: function(deltaY, animate) + { + var destY = contentPositionY() + Math[deltaY<0 ? 'floor' : 'ceil'](deltaY), + percentScrolled = destY / (contentHeight - paneHeight); + positionDragY(percentScrolled * dragMaxY, animate); + }, + // Positions the horizontal drag at the specified x position (and updates the viewport to reflect + // this). animate is optional and if not passed then the value of animateScroll from the settings + // object this jScrollPane was initialised with is used. + positionDragX: function(x, animate) + { + positionDragX(x, animate); + }, + // Positions the vertical drag at the specified y position (and updates the viewport to reflect + // this). animate is optional and if not passed then the value of animateScroll from the settings + // object this jScrollPane was initialised with is used. + positionDragY: function(y, animate) + { + positionDragY(y, animate); + }, + // This method is called when jScrollPane is trying to animate to a new position. You can override + // it if you want to provide advanced animation functionality. It is passed the following arguments: + // * ele - the element whose position is being animated + // * prop - the property that is being animated + // * value - the value it's being animated to + // * stepCallback - a function that you must execute each time you update the value of the property + // You can use the default implementation (below) as a starting point for your own implementation. + animate: function(ele, prop, value, stepCallback) + { + var params = {}; + params[prop] = value; + ele.animate( + params, + { + 'duration' : settings.animateDuration, + 'easing' : settings.animateEase, + 'queue' : false, + 'step' : stepCallback + } + ); + }, + // Returns the current x position of the viewport with regards to the content pane. + getContentPositionX: function() + { + return contentPositionX(); + }, + // Returns the current y position of the viewport with regards to the content pane. + getContentPositionY: function() + { + return contentPositionY(); + }, + // Returns the width of the content within the scroll pane. + getContentWidth: function() + { + return contentWidth; + }, + // Returns the height of the content within the scroll pane. + getContentHeight: function() + { + return contentHeight; + }, + // Returns the horizontal position of the viewport within the pane content. + getPercentScrolledX: function() + { + return contentPositionX() / (contentWidth - paneWidth); + }, + // Returns the vertical position of the viewport within the pane content. + getPercentScrolledY: function() + { + return contentPositionY() / (contentHeight - paneHeight); + }, + // Returns whether or not this scrollpane has a horizontal scrollbar. + getIsScrollableH: function() + { + return isScrollableH; + }, + // Returns whether or not this scrollpane has a vertical scrollbar. + getIsScrollableV: function() + { + return isScrollableV; + }, + // Gets a reference to the content pane. It is important that you use this method if you want to + // edit the content of your jScrollPane as if you access the element directly then you may have some + // problems (as your original element has had additional elements for the scrollbars etc added into + // it). + getContentPane: function() + { + return pane; + }, + // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the + // animateScroll value from settings is used instead. + scrollToBottom: function(animate) + { + positionDragY(dragMaxY, animate); + }, + // Hijacks the links on the page which link to content inside the scrollpane. If you have changed + // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the + // contents of your scroll pane will work then call this function. + hijackInternalLinks: $.noop, + // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was + // initialised. + destroy: function() + { + destroy(); + } + } + ); + + initialise(s); + } + + // Pluginifying code... + settings = $.extend({}, $.fn.jScrollPane.defaults, settings); + + // Apply default speed + $.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function() { + settings[this] = settings[this] || settings.speed; + }); + + return this.each( + function() + { + var elem = $(this), jspApi = elem.data('jsp'); + if (jspApi) { + jspApi.reinitialise(settings); + } else { + $("script",elem).filter('[type="text/javascript"],:not([type])').remove(); + jspApi = new JScrollPane(elem, settings); + elem.data('jsp', jspApi); + } + } + ); + }; + + $.fn.jScrollPane.defaults = { + showArrows : false, + maintainPosition : true, + stickToBottom : false, + stickToRight : false, + clickOnTrack : true, + autoReinitialise : false, + autoReinitialiseDelay : 500, + verticalDragMinHeight : 0, + verticalDragMaxHeight : 99999, + horizontalDragMinWidth : 0, + horizontalDragMaxWidth : 99999, + contentWidth : undefined, + animateScroll : false, + animateDuration : 300, + animateEase : 'linear', + hijackInternalLinks : false, + verticalGutter : 4, + horizontalGutter : 4, + mouseWheelSpeed : 3, + arrowButtonSpeed : 0, + arrowRepeatFreq : 50, + arrowScrollOnHover : false, + trackClickSpeed : 0, + trackClickRepeatFreq : 70, + verticalArrowPositions : 'split', + horizontalArrowPositions : 'split', + enableKeyboardNavigation : true, + hideFocus : false, + keyboardSpeed : 0, + initialDelay : 300, // Delay before starting repeating + speed : 30, // Default speed when others falsey + scrollPagePercent : .8 // Percent of visible area scrolled when pageUp/Down or track area pressed + }; + +})(jQuery,this); + diff --git a/OpenAntrag/Scripts/Plugins/_not-used/jquery.mCustomScrollbar.js b/OpenAntrag/Scripts/Plugins/_not-used/jquery.mCustomScrollbar.js new file mode 100644 index 0000000..984118c --- /dev/null +++ b/OpenAntrag/Scripts/Plugins/_not-used/jquery.mCustomScrollbar.js @@ -0,0 +1,946 @@ +/* +== malihu jquery custom scrollbars plugin == +version: 2.8.2 +author: malihu (http://manos.malihu.gr) +plugin home: http://manos.malihu.gr/jquery-custom-content-scroller +*/ + +/* +Copyright 2010-2013 Manos Malihutsakis + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/lgpl.html. +*/ +(function($){ + /*plugin script*/ + var methods={ + init:function(options){ + var defaults={ + set_width:false, /*optional element width: boolean, pixels, percentage*/ + set_height:false, /*optional element height: boolean, pixels, percentage*/ + horizontalScroll:false, /*scroll horizontally: boolean*/ + scrollInertia:950, /*scrolling inertia: integer (milliseconds)*/ + mouseWheel:true, /*mousewheel support: boolean*/ + mouseWheelPixels:"auto", /*mousewheel pixels amount: integer, "auto"*/ + autoDraggerLength:true, /*auto-adjust scrollbar dragger length: boolean*/ + autoHideScrollbar:false, /*auto-hide scrollbar when idle*/ + snapAmount:null, /* optional element always snaps to a multiple of this number in pixels */ + snapOffset:0, /* when snapping, snap with this number in pixels as an offset */ + scrollButtons:{ /*scroll buttons*/ + enable:false, /*scroll buttons support: boolean*/ + scrollType:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/ + scrollSpeed:"auto", /*scroll buttons continuous scrolling speed: integer, "auto"*/ + scrollAmount:40 /*scroll buttons pixels scroll amount: integer (pixels)*/ + }, + advanced:{ + updateOnBrowserResize:true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/ + updateOnContentResize:false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/ + autoExpandHorizontalScroll:false, /*auto-expand width for horizontal scrolling: boolean*/ + autoScrollOnFocus:true, /*auto-scroll on focused elements: boolean*/ + normalizeMouseWheelDelta:false /*normalize mouse-wheel delta (-1/1)*/ + }, + contentTouchScroll:true, /*scrolling by touch-swipe content: boolean*/ + callbacks:{ + onScrollStart:function(){}, /*user custom callback function on scroll start event*/ + onScroll:function(){}, /*user custom callback function on scroll event*/ + onTotalScroll:function(){}, /*user custom callback function on scroll end reached event*/ + onTotalScrollBack:function(){}, /*user custom callback function on scroll begin reached event*/ + onTotalScrollOffset:0, /*scroll end reached offset: integer (pixels)*/ + onTotalScrollBackOffset:0, /*scroll begin reached offset: integer (pixels)*/ + whileScrolling:function(){} /*user custom callback function on scrolling event*/ + }, + theme:"light" /*"light", "dark", "light-2", "dark-2", "light-thick", "dark-thick", "light-thin", "dark-thin"*/ + }, + options=$.extend(true,defaults,options); + return this.each(function(){ + var $this=$(this); + /*set element width/height, create markup for custom scrollbars, add classes*/ + if(options.set_width){ + $this.css("width",options.set_width); + } + if(options.set_height){ + $this.css("height",options.set_height); + } + if(!$(document).data("mCustomScrollbar-index")){ + $(document).data("mCustomScrollbar-index","1"); + }else{ + var mCustomScrollbarIndex=parseInt($(document).data("mCustomScrollbar-index")); + $(document).data("mCustomScrollbar-index",mCustomScrollbarIndex+1); + } + $this.wrapInner("
        ").addClass("mCustomScrollbar _mCS_"+$(document).data("mCustomScrollbar-index")); + var mCustomScrollBox=$this.children(".mCustomScrollBox"); + if(options.horizontalScroll){ + mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("
        "); + var mCSB_h_wrapper=mCustomScrollBox.children(".mCSB_h_wrapper"); + mCSB_h_wrapper.wrapInner("
        ").children(".mCSB_container").css({"width":mCSB_h_wrapper.children().outerWidth(),"position":"relative"}).unwrap(); + }else{ + mCustomScrollBox.wrapInner("
        "); + } + var mCSB_container=mCustomScrollBox.children(".mCSB_container"); + if($.support.touch){ + mCSB_container.addClass("mCS_touch"); + } + mCSB_container.after("
        "); + var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), + mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), + mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); + if(options.horizontalScroll){ + mCSB_dragger.data("minDraggerWidth",mCSB_dragger.width()); + }else{ + mCSB_dragger.data("minDraggerHeight",mCSB_dragger.height()); + } + if(options.scrollButtons.enable){ + if(options.horizontalScroll){ + mCSB_scrollTools.prepend("
        ").append(""); + }else{ + mCSB_scrollTools.prepend("").append(""); + } + } + /*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/ + mCustomScrollBox.bind("scroll",function(){ + if(!$this.is(".mCS_disabled")){ /*native focus scrolling for disabled scrollbars*/ + mCustomScrollBox.scrollTop(0).scrollLeft(0); + } + }); + /*store options, global vars/states, intervals*/ + $this.data({ + /*init state*/ + "mCS_Init":true, + /*instance index*/ + "mCustomScrollbarIndex":$(document).data("mCustomScrollbar-index"), + /*option parameters*/ + "horizontalScroll":options.horizontalScroll, + "scrollInertia":options.scrollInertia, + "scrollEasing":"mcsEaseOut", + "mouseWheel":options.mouseWheel, + "mouseWheelPixels":options.mouseWheelPixels, + "autoDraggerLength":options.autoDraggerLength, + "autoHideScrollbar":options.autoHideScrollbar, + "snapAmount":options.snapAmount, + "snapOffset":options.snapOffset, + "scrollButtons_enable":options.scrollButtons.enable, + "scrollButtons_scrollType":options.scrollButtons.scrollType, + "scrollButtons_scrollSpeed":options.scrollButtons.scrollSpeed, + "scrollButtons_scrollAmount":options.scrollButtons.scrollAmount, + "autoExpandHorizontalScroll":options.advanced.autoExpandHorizontalScroll, + "autoScrollOnFocus":options.advanced.autoScrollOnFocus, + "normalizeMouseWheelDelta":options.advanced.normalizeMouseWheelDelta, + "contentTouchScroll":options.contentTouchScroll, + "onScrollStart_Callback":options.callbacks.onScrollStart, + "onScroll_Callback":options.callbacks.onScroll, + "onTotalScroll_Callback":options.callbacks.onTotalScroll, + "onTotalScrollBack_Callback":options.callbacks.onTotalScrollBack, + "onTotalScroll_Offset":options.callbacks.onTotalScrollOffset, + "onTotalScrollBack_Offset":options.callbacks.onTotalScrollBackOffset, + "whileScrolling_Callback":options.callbacks.whileScrolling, + /*events binding state*/ + "bindEvent_scrollbar_drag":false, + "bindEvent_content_touch":false, + "bindEvent_scrollbar_click":false, + "bindEvent_mousewheel":false, + "bindEvent_buttonsContinuous_y":false, + "bindEvent_buttonsContinuous_x":false, + "bindEvent_buttonsPixels_y":false, + "bindEvent_buttonsPixels_x":false, + "bindEvent_focusin":false, + "bindEvent_autoHideScrollbar":false, + /*buttons intervals*/ + "mCSB_buttonScrollRight":false, + "mCSB_buttonScrollLeft":false, + "mCSB_buttonScrollDown":false, + "mCSB_buttonScrollUp":false + }); + /*max-width/max-height*/ + if(options.horizontalScroll){ + if($this.css("max-width")!=="none"){ + if(!options.advanced.updateOnContentResize){ /*needs updateOnContentResize*/ + options.advanced.updateOnContentResize=true; + } + } + }else{ + if($this.css("max-height")!=="none"){ + var percentage=false,maxHeight=parseInt($this.css("max-height")); + if($this.css("max-height").indexOf("%")>=0){ + percentage=maxHeight, + maxHeight=$this.parent().height()*percentage/100; + } + $this.css("overflow","hidden"); + mCustomScrollBox.css("max-height",maxHeight); + } + } + $this.mCustomScrollbar("update"); + /*window resize fn (for layouts based on percentages)*/ + if(options.advanced.updateOnBrowserResize){ + var mCSB_resizeTimeout,currWinWidth=$(window).width(),currWinHeight=$(window).height(); + $(window).bind("resize."+$this.data("mCustomScrollbarIndex"),function(){ + if(mCSB_resizeTimeout){ + clearTimeout(mCSB_resizeTimeout); + } + mCSB_resizeTimeout=setTimeout(function(){ + if(!$this.is(".mCS_disabled") && !$this.is(".mCS_destroyed")){ + var winWidth=$(window).width(),winHeight=$(window).height(); + if(currWinWidth!==winWidth || currWinHeight!==winHeight){ /*ie8 fix*/ + if($this.css("max-height")!=="none" && percentage){ + mCustomScrollBox.css("max-height",$this.parent().height()*percentage/100); + } + $this.mCustomScrollbar("update"); + currWinWidth=winWidth; currWinHeight=winHeight; + } + } + },150); + }); + } + /*content resize fn (for dynamically generated content)*/ + if(options.advanced.updateOnContentResize){ + var mCSB_onContentResize; + if(options.horizontalScroll){ + var mCSB_containerOldSize=mCSB_container.outerWidth(); + }else{ + var mCSB_containerOldSize=mCSB_container.outerHeight(); + } + mCSB_onContentResize=setInterval(function(){ + if(options.horizontalScroll){ + if(options.advanced.autoExpandHorizontalScroll){ + mCSB_container.css({"position":"absolute","width":"auto"}).wrap("
        ").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap(); + } + var mCSB_containerNewSize=mCSB_container.outerWidth(); + }else{ + var mCSB_containerNewSize=mCSB_container.outerHeight(); + } + if(mCSB_containerNewSize!=mCSB_containerOldSize){ + $this.mCustomScrollbar("update"); + mCSB_containerOldSize=mCSB_containerNewSize; + } + },300); + } + }); + }, + update:function(){ + var $this=$(this), + mCustomScrollBox=$this.children(".mCustomScrollBox"), + mCSB_container=mCustomScrollBox.children(".mCSB_container"); + mCSB_container.removeClass("mCS_no_scrollbar"); + $this.removeClass("mCS_disabled mCS_destroyed"); + mCustomScrollBox.scrollTop(0).scrollLeft(0); /*reset scrollTop/scrollLeft to prevent browser focus scrolling*/ + var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), + mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), + mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); + if($this.data("horizontalScroll")){ + var mCSB_buttonLeft=mCSB_scrollTools.children(".mCSB_buttonLeft"), + mCSB_buttonRight=mCSB_scrollTools.children(".mCSB_buttonRight"), + mCustomScrollBoxW=mCustomScrollBox.width(); + if($this.data("autoExpandHorizontalScroll")){ + mCSB_container.css({"position":"absolute","width":"auto"}).wrap("
        ").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap(); + } + var mCSB_containerW=mCSB_container.outerWidth(); + }else{ + var mCSB_buttonUp=mCSB_scrollTools.children(".mCSB_buttonUp"), + mCSB_buttonDown=mCSB_scrollTools.children(".mCSB_buttonDown"), + mCustomScrollBoxH=mCustomScrollBox.height(), + mCSB_containerH=mCSB_container.outerHeight(); + } + if(mCSB_containerH>mCustomScrollBoxH && !$this.data("horizontalScroll")){ /*content needs vertical scrolling*/ + mCSB_scrollTools.css("display","block"); + var mCSB_draggerContainerH=mCSB_draggerContainer.height(); + /*auto adjust scrollbar dragger length analogous to content*/ + if($this.data("autoDraggerLength")){ + var draggerH=Math.round(mCustomScrollBoxH/mCSB_containerH*mCSB_draggerContainerH), + minDraggerH=mCSB_dragger.data("minDraggerHeight"); + if(draggerH<=minDraggerH){ /*min dragger height*/ + mCSB_dragger.css({"height":minDraggerH}); + }else if(draggerH>=mCSB_draggerContainerH-10){ /*max dragger height*/ + var mCSB_draggerContainerMaxH=mCSB_draggerContainerH-10; + mCSB_dragger.css({"height":mCSB_draggerContainerMaxH}); + }else{ + mCSB_dragger.css({"height":draggerH}); + } + mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height":mCSB_dragger.height()+"px"}); + } + var mCSB_draggerH=mCSB_dragger.height(), + /*calculate and store scroll amount, add scrolling*/ + scrollAmount=(mCSB_containerH-mCustomScrollBoxH)/(mCSB_draggerContainerH-mCSB_draggerH); + $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); + /*scroll*/ + var mCSB_containerP=Math.abs(mCSB_container.position().top); + $this.mCustomScrollbar("scrollTo",mCSB_containerP,{scrollInertia:0,trigger:"internal"}); + }else if(mCSB_containerW>mCustomScrollBoxW && $this.data("horizontalScroll")){ /*content needs horizontal scrolling*/ + mCSB_scrollTools.css("display","block"); + var mCSB_draggerContainerW=mCSB_draggerContainer.width(); + /*auto adjust scrollbar dragger length analogous to content*/ + if($this.data("autoDraggerLength")){ + var draggerW=Math.round(mCustomScrollBoxW/mCSB_containerW*mCSB_draggerContainerW), + minDraggerW=mCSB_dragger.data("minDraggerWidth"); + if(draggerW<=minDraggerW){ /*min dragger height*/ + mCSB_dragger.css({"width":minDraggerW}); + }else if(draggerW>=mCSB_draggerContainerW-10){ /*max dragger height*/ + var mCSB_draggerContainerMaxW=mCSB_draggerContainerW-10; + mCSB_dragger.css({"width":mCSB_draggerContainerMaxW}); + }else{ + mCSB_dragger.css({"width":draggerW}); + } + } + var mCSB_draggerW=mCSB_dragger.width(), + /*calculate and store scroll amount, add scrolling*/ + scrollAmount=(mCSB_containerW-mCustomScrollBoxW)/(mCSB_draggerContainerW-mCSB_draggerW); + $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); + /*scroll*/ + var mCSB_containerP=Math.abs(mCSB_container.position().left); + $this.mCustomScrollbar("scrollTo",mCSB_containerP,{scrollInertia:0,trigger:"internal"}); + }else{ /*content does not need scrolling*/ + /*unbind events, reset content position, hide scrollbars, remove classes*/ + mCustomScrollBox.unbind("mousewheel focusin"); + if($this.data("horizontalScroll")){ + mCSB_dragger.add(mCSB_container).css("left",0); + }else{ + mCSB_dragger.add(mCSB_container).css("top",0); + } + mCSB_scrollTools.css("display","none"); + mCSB_container.addClass("mCS_no_scrollbar"); + $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false}); + } + }, + scrolling:function(mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight){ + var $this=$(this); + /*scrollbar drag scrolling*/ + if(!$this.data("bindEvent_scrollbar_drag")){ + var mCSB_draggerDragY,mCSB_draggerDragX; + if($.support.msPointer){ /*MSPointer*/ + mCSB_dragger.bind("MSPointerDown",function(e){ + e.preventDefault(); + $this.data({"on_drag":true}); mCSB_dragger.addClass("mCSB_dragger_onDrag"); + var elem=$(this), + elemOffset=elem.offset(), + x=e.originalEvent.pageX-elemOffset.left, + y=e.originalEvent.pageY-elemOffset.top; + if(x0 && y0){ + mCSB_draggerDragY=y; + mCSB_draggerDragX=x; + } + }); + $(document).bind("MSPointerMove."+$this.data("mCustomScrollbarIndex"),function(e){ + e.preventDefault(); + if($this.data("on_drag")){ + var elem=mCSB_dragger, + elemOffset=elem.offset(), + x=e.originalEvent.pageX-elemOffset.left, + y=e.originalEvent.pageY-elemOffset.top; + scrollbarDrag(mCSB_draggerDragY,mCSB_draggerDragX,y,x); + } + }).bind("MSPointerUp."+$this.data("mCustomScrollbarIndex"),function(e){ + $this.data({"on_drag":false}); mCSB_dragger.removeClass("mCSB_dragger_onDrag"); + }); + }else{ /*mouse/touch*/ + mCSB_dragger.bind("mousedown touchstart",function(e){ + e.preventDefault(); e.stopImmediatePropagation(); + var elem=$(this),elemOffset=elem.offset(),x,y; + if(e.type==="touchstart"){ + var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + x=touch.pageX-elemOffset.left; y=touch.pageY-elemOffset.top; + }else{ + $this.data({"on_drag":true}); mCSB_dragger.addClass("mCSB_dragger_onDrag"); + x=e.pageX-elemOffset.left; y=e.pageY-elemOffset.top; + } + if(x0 && y0){ + mCSB_draggerDragY=y; mCSB_draggerDragX=x; + } + }).bind("touchmove",function(e){ + e.preventDefault(); e.stopImmediatePropagation(); + var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], + elem=$(this), + elemOffset=elem.offset(), + x=touch.pageX-elemOffset.left, + y=touch.pageY-elemOffset.top; + scrollbarDrag(mCSB_draggerDragY,mCSB_draggerDragX,y,x); + }); + $(document).bind("mousemove."+$this.data("mCustomScrollbarIndex"),function(e){ + if($this.data("on_drag")){ + var elem=mCSB_dragger, + elemOffset=elem.offset(), + x=e.pageX-elemOffset.left, + y=e.pageY-elemOffset.top; + scrollbarDrag(mCSB_draggerDragY,mCSB_draggerDragX,y,x); + } + }).bind("mouseup."+$this.data("mCustomScrollbarIndex"),function(e){ + $this.data({"on_drag":false}); mCSB_dragger.removeClass("mCSB_dragger_onDrag"); + }); + } + $this.data({"bindEvent_scrollbar_drag":true}); + } + function scrollbarDrag(mCSB_draggerDragY,mCSB_draggerDragX,y,x){ + if($this.data("horizontalScroll")){ + $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().left-(mCSB_draggerDragX))+x,{moveDragger:true,trigger:"internal"}); + }else{ + $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().top-(mCSB_draggerDragY))+y,{moveDragger:true,trigger:"internal"}); + } + } + /*content touch-drag*/ + if($.support.touch && $this.data("contentTouchScroll")){ + if(!$this.data("bindEvent_content_touch")){ + var touch, + elem,elemOffset,y,x,mCSB_containerTouchY,mCSB_containerTouchX; + mCSB_container.bind("touchstart",function(e){ + e.stopImmediatePropagation(); + touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + elem=$(this); + elemOffset=elem.offset(); + x=touch.pageX-elemOffset.left; + y=touch.pageY-elemOffset.top; + mCSB_containerTouchY=y; + mCSB_containerTouchX=x; + }); + mCSB_container.bind("touchmove",function(e){ + e.preventDefault(); e.stopImmediatePropagation(); + touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + elem=$(this).parent(); + elemOffset=elem.offset(); + x=touch.pageX-elemOffset.left; + y=touch.pageY-elemOffset.top; + if($this.data("horizontalScroll")){ + $this.mCustomScrollbar("scrollTo",mCSB_containerTouchX-x,{trigger:"internal"}); + }else{ + $this.mCustomScrollbar("scrollTo",mCSB_containerTouchY-y,{trigger:"internal"}); + } + }); + } + } + /*dragger rail click scrolling*/ + if(!$this.data("bindEvent_scrollbar_click")){ + mCSB_draggerContainer.bind("click",function(e){ + var scrollToPos=(e.pageY-mCSB_draggerContainer.offset().top)*$this.data("scrollAmount"),target=$(e.target); + if($this.data("horizontalScroll")){ + scrollToPos=(e.pageX-mCSB_draggerContainer.offset().left)*$this.data("scrollAmount"); + } + if(target.hasClass("mCSB_draggerContainer") || target.hasClass("mCSB_draggerRail")){ + $this.mCustomScrollbar("scrollTo",scrollToPos,{trigger:"internal",scrollEasing:"draggerRailEase"}); + } + }); + $this.data({"bindEvent_scrollbar_click":true}); + } + /*mousewheel scrolling*/ + if($this.data("mouseWheel")){ + if(!$this.data("bindEvent_mousewheel")){ + mCustomScrollBox.bind("mousewheel",function(e,delta){ + var scrollTo,mouseWheelPixels=$this.data("mouseWheelPixels"),absPos=Math.abs(mCSB_container.position().top), + draggerPos=mCSB_dragger.position().top,limit=mCSB_draggerContainer.height()-mCSB_dragger.height(); + if($this.data("normalizeMouseWheelDelta")){ + if(delta<0){delta=-1;}else{delta=1;} + } + if(mouseWheelPixels==="auto"){ + mouseWheelPixels=100+Math.round($this.data("scrollAmount")/2); + } + if($this.data("horizontalScroll")){ + draggerPos=mCSB_dragger.position().left; + limit=mCSB_draggerContainer.width()-mCSB_dragger.width(); + absPos=Math.abs(mCSB_container.position().left); + } + if((delta>0 && draggerPos!==0) || (delta<0 && draggerPos!==limit)){e.preventDefault(); e.stopImmediatePropagation();} + scrollTo=absPos-(delta*mouseWheelPixels); + $this.mCustomScrollbar("scrollTo",scrollTo,{trigger:"internal"}); + }); + $this.data({"bindEvent_mousewheel":true}); + } + } + /*buttons scrolling*/ + if($this.data("scrollButtons_enable")){ + if($this.data("scrollButtons_scrollType")==="pixels"){ /*scroll by pixels*/ + if($this.data("horizontalScroll")){ + mCSB_buttonRight.add(mCSB_buttonLeft).unbind("mousedown touchstart MSPointerDown mouseup MSPointerUp mouseout MSPointerOut touchend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); + $this.data({"bindEvent_buttonsContinuous_x":false}); + if(!$this.data("bindEvent_buttonsPixels_x")){ + /*scroll right*/ + mCSB_buttonRight.bind("click",function(e){ + e.preventDefault(); + PixelsScrollTo(Math.abs(mCSB_container.position().left)+$this.data("scrollButtons_scrollAmount")); + }); + /*scroll left*/ + mCSB_buttonLeft.bind("click",function(e){ + e.preventDefault(); + PixelsScrollTo(Math.abs(mCSB_container.position().left)-$this.data("scrollButtons_scrollAmount")); + }); + $this.data({"bindEvent_buttonsPixels_x":true}); + } + }else{ + mCSB_buttonDown.add(mCSB_buttonUp).unbind("mousedown touchstart MSPointerDown mouseup MSPointerUp mouseout MSPointerOut touchend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); + $this.data({"bindEvent_buttonsContinuous_y":false}); + if(!$this.data("bindEvent_buttonsPixels_y")){ + /*scroll down*/ + mCSB_buttonDown.bind("click",function(e){ + e.preventDefault(); + PixelsScrollTo(Math.abs(mCSB_container.position().top)+$this.data("scrollButtons_scrollAmount")); + }); + /*scroll up*/ + mCSB_buttonUp.bind("click",function(e){ + e.preventDefault(); + PixelsScrollTo(Math.abs(mCSB_container.position().top)-$this.data("scrollButtons_scrollAmount")); + }); + $this.data({"bindEvent_buttonsPixels_y":true}); + } + } + function PixelsScrollTo(to){ + if(!mCSB_dragger.data("preventAction")){ + mCSB_dragger.data("preventAction",true); + $this.mCustomScrollbar("scrollTo",to,{trigger:"internal"}); + } + } + }else{ /*continuous scrolling*/ + if($this.data("horizontalScroll")){ + mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click"); + $this.data({"bindEvent_buttonsPixels_x":false}); + if(!$this.data("bindEvent_buttonsContinuous_x")){ + /*scroll right*/ + mCSB_buttonRight.bind("mousedown touchstart MSPointerDown",function(e){ + e.preventDefault(); + var scrollButtonsSpeed=ScrollButtonsSpeed(); + $this.data({"mCSB_buttonScrollRight":setInterval(function(){ + $this.mCustomScrollbar("scrollTo",Math.abs(mCSB_container.position().left)+scrollButtonsSpeed,{trigger:"internal",scrollEasing:"easeOutCirc"}); + },17)}); + }); + var mCSB_buttonRight_stop=function(e){ + e.preventDefault(); clearInterval($this.data("mCSB_buttonScrollRight")); + } + mCSB_buttonRight.bind("mouseup touchend MSPointerUp mouseout MSPointerOut",mCSB_buttonRight_stop); + /*scroll left*/ + mCSB_buttonLeft.bind("mousedown touchstart MSPointerDown",function(e){ + e.preventDefault(); + var scrollButtonsSpeed=ScrollButtonsSpeed(); + $this.data({"mCSB_buttonScrollLeft":setInterval(function(){ + $this.mCustomScrollbar("scrollTo",Math.abs(mCSB_container.position().left)-scrollButtonsSpeed,{trigger:"internal",scrollEasing:"easeOutCirc"}); + },17)}); + }); + var mCSB_buttonLeft_stop=function(e){ + e.preventDefault(); clearInterval($this.data("mCSB_buttonScrollLeft")); + } + mCSB_buttonLeft.bind("mouseup touchend MSPointerUp mouseout MSPointerOut",mCSB_buttonLeft_stop); + $this.data({"bindEvent_buttonsContinuous_x":true}); + } + }else{ + mCSB_buttonDown.add(mCSB_buttonUp).unbind("click"); + $this.data({"bindEvent_buttonsPixels_y":false}); + if(!$this.data("bindEvent_buttonsContinuous_y")){ + /*scroll down*/ + mCSB_buttonDown.bind("mousedown touchstart MSPointerDown",function(e){ + e.preventDefault(); + var scrollButtonsSpeed=ScrollButtonsSpeed(); + $this.data({"mCSB_buttonScrollDown":setInterval(function(){ + $this.mCustomScrollbar("scrollTo",Math.abs(mCSB_container.position().top)+scrollButtonsSpeed,{trigger:"internal",scrollEasing:"easeOutCirc"}); + },17)}); + }); + var mCSB_buttonDown_stop=function(e){ + e.preventDefault(); clearInterval($this.data("mCSB_buttonScrollDown")); + } + mCSB_buttonDown.bind("mouseup touchend MSPointerUp mouseout MSPointerOut",mCSB_buttonDown_stop); + /*scroll up*/ + mCSB_buttonUp.bind("mousedown touchstart MSPointerDown",function(e){ + e.preventDefault(); + var scrollButtonsSpeed=ScrollButtonsSpeed(); + $this.data({"mCSB_buttonScrollUp":setInterval(function(){ + $this.mCustomScrollbar("scrollTo",Math.abs(mCSB_container.position().top)-scrollButtonsSpeed,{trigger:"internal",scrollEasing:"easeOutCirc"}); + },17)}); + }); + var mCSB_buttonUp_stop=function(e){ + e.preventDefault(); clearInterval($this.data("mCSB_buttonScrollUp")); + } + mCSB_buttonUp.bind("mouseup touchend MSPointerUp mouseout MSPointerOut",mCSB_buttonUp_stop); + $this.data({"bindEvent_buttonsContinuous_y":true}); + } + } + function ScrollButtonsSpeed(){ + var speed=$this.data("scrollButtons_scrollSpeed"); + if($this.data("scrollButtons_scrollSpeed")==="auto"){ + speed=Math.round(($this.data("scrollInertia")+100)/40); + } + return speed; + } + } + } + /*scrolling on element focus (e.g. via TAB key)*/ + if($this.data("autoScrollOnFocus")){ + if(!$this.data("bindEvent_focusin")){ + mCustomScrollBox.bind("focusin",function(){ + mCustomScrollBox.scrollTop(0).scrollLeft(0); + var focusedElem=$(document.activeElement); + if(focusedElem.is("input,textarea,select,button,a[tabindex],area,object")){ + var mCSB_containerPos=mCSB_container.position().top, + focusedElemPos=focusedElem.position().top, + visibleLimit=mCustomScrollBox.height()-focusedElem.outerHeight(); + if($this.data("horizontalScroll")){ + mCSB_containerPos=mCSB_container.position().left; + focusedElemPos=focusedElem.position().left; + visibleLimit=mCustomScrollBox.width()-focusedElem.outerWidth(); + } + if(mCSB_containerPos+focusedElemPos<0 || mCSB_containerPos+focusedElemPos>visibleLimit){ + $this.mCustomScrollbar("scrollTo",focusedElemPos,{trigger:"internal"}); + } + } + }); + $this.data({"bindEvent_focusin":true}); + } + } + /*auto-hide scrollbar*/ + if($this.data("autoHideScrollbar")){ + if(!$this.data("bindEvent_autoHideScrollbar")){ + mCustomScrollBox.bind("mouseenter",function(e){ + mCustomScrollBox.addClass("mCS-mouse-over"); + functions.showScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools")); + }).bind("mouseleave touchend",function(e){ + mCustomScrollBox.removeClass("mCS-mouse-over"); + if(e.type==="mouseleave"){functions.hideScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools"));} + }); + $this.data({"bindEvent_autoHideScrollbar":true}); + } + } + }, + scrollTo:function(scrollTo,options){ + var $this=$(this), + defaults={ + moveDragger:false, + trigger:"external", + callbacks:true, + scrollInertia:$this.data("scrollInertia"), + scrollEasing:$this.data("scrollEasing") + }, + options=$.extend(defaults,options), + draggerScrollTo, + mCustomScrollBox=$this.children(".mCustomScrollBox"), + mCSB_container=mCustomScrollBox.children(".mCSB_container"), + mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), + mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), + mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"), + contentSpeed=draggerSpeed=options.scrollInertia, + scrollBeginning,scrollBeginningOffset,totalScroll,totalScrollOffset; + if(!mCSB_container.hasClass("mCS_no_scrollbar")){ + $this.data({"mCS_trigger":options.trigger}); + if($this.data("mCS_Init")){options.callbacks=false;} + if(scrollTo || scrollTo===0){ + if(typeof(scrollTo)==="number"){ /*if integer, scroll by number of pixels*/ + if(options.moveDragger){ /*scroll dragger*/ + draggerScrollTo=scrollTo; + if($this.data("horizontalScroll")){ + scrollTo=mCSB_dragger.position().left*$this.data("scrollAmount"); + }else{ + scrollTo=mCSB_dragger.position().top*$this.data("scrollAmount"); + } + draggerSpeed=0; + }else{ /*scroll content by default*/ + draggerScrollTo=scrollTo/$this.data("scrollAmount"); + } + }else if(typeof(scrollTo)==="string"){ /*if string, scroll by element position*/ + var target; + if(scrollTo==="top"){ /*scroll to top*/ + target=0; + }else if(scrollTo==="bottom" && !$this.data("horizontalScroll")){ /*scroll to bottom*/ + target=mCSB_container.outerHeight()-mCustomScrollBox.height(); + }else if(scrollTo==="left"){ /*scroll to left*/ + target=0; + }else if(scrollTo==="right" && $this.data("horizontalScroll")){ /*scroll to right*/ + target=mCSB_container.outerWidth()-mCustomScrollBox.width(); + }else if(scrollTo==="first"){ /*scroll to first element position*/ + target=$this.find(".mCSB_container").find(":first"); + }else if(scrollTo==="last"){ /*scroll to last element position*/ + target=$this.find(".mCSB_container").find(":last"); + }else{ /*scroll to element position*/ + target=$this.find(scrollTo); + } + if(target.length===1){ /*if such unique element exists, scroll to it*/ + if($this.data("horizontalScroll")){ + scrollTo=target.position().left; + }else{ + scrollTo=target.position().top; + } + draggerScrollTo=scrollTo/$this.data("scrollAmount"); + }else{ + draggerScrollTo=scrollTo=target; + } + } + /*scroll to*/ + if($this.data("horizontalScroll")){ + if($this.data("onTotalScrollBack_Offset")){ /*scroll beginning offset*/ + scrollBeginningOffset=-$this.data("onTotalScrollBack_Offset"); + } + if($this.data("onTotalScroll_Offset")){ /*total scroll offset*/ + totalScrollOffset=mCustomScrollBox.width()-mCSB_container.outerWidth()+$this.data("onTotalScroll_Offset"); + } + if(draggerScrollTo<0){ /*scroll start position*/ + draggerScrollTo=scrollTo=0; clearInterval($this.data("mCSB_buttonScrollLeft")); + if(!scrollBeginningOffset){scrollBeginning=true;} + }else if(draggerScrollTo>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*scroll end position*/ + draggerScrollTo=mCSB_draggerContainer.width()-mCSB_dragger.width(); + scrollTo=mCustomScrollBox.width()-mCSB_container.outerWidth(); clearInterval($this.data("mCSB_buttonScrollRight")); + if(!totalScrollOffset){totalScroll=true;} + }else{scrollTo=-scrollTo;} + var snapAmount = $this.data("snapAmount"); + if (snapAmount) { + scrollTo = Math.round(scrollTo / snapAmount) * snapAmount - $this.data("snapOffset"); + } + /*scrolling animation*/ + functions.mTweenAxis.call(this,mCSB_dragger[0],"left",Math.round(draggerScrollTo),draggerSpeed,options.scrollEasing); + functions.mTweenAxis.call(this,mCSB_container[0],"left",Math.round(scrollTo),contentSpeed,options.scrollEasing,{ + onStart:function(){ + if(options.callbacks && !$this.data("mCS_tweenRunning")){callbacks("onScrollStart");} + if($this.data("autoHideScrollbar")){functions.showScrollbar.call(mCSB_scrollTools);} + }, + onUpdate:function(){ + if(options.callbacks){callbacks("whileScrolling");} + }, + onComplete:function(){ + if(options.callbacks){ + callbacks("onScroll"); + if(scrollBeginning || (scrollBeginningOffset && mCSB_container.position().left>=scrollBeginningOffset)){callbacks("onTotalScrollBack");} + if(totalScroll || (totalScrollOffset && mCSB_container.position().left<=totalScrollOffset)){callbacks("onTotalScroll");} + } + mCSB_dragger.data("preventAction",false); $this.data("mCS_tweenRunning",false); + if($this.data("autoHideScrollbar")){if(!mCustomScrollBox.hasClass("mCS-mouse-over")){functions.hideScrollbar.call(mCSB_scrollTools);}} + } + }); + }else{ + if($this.data("onTotalScrollBack_Offset")){ /*scroll beginning offset*/ + scrollBeginningOffset=-$this.data("onTotalScrollBack_Offset"); + } + if($this.data("onTotalScroll_Offset")){ /*total scroll offset*/ + totalScrollOffset=mCustomScrollBox.height()-mCSB_container.outerHeight()+$this.data("onTotalScroll_Offset"); + } + if(draggerScrollTo<0){ /*scroll start position*/ + draggerScrollTo=scrollTo=0; clearInterval($this.data("mCSB_buttonScrollUp")); + if(!scrollBeginningOffset){scrollBeginning=true;} + }else if(draggerScrollTo>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*scroll end position*/ + draggerScrollTo=mCSB_draggerContainer.height()-mCSB_dragger.height(); + scrollTo=mCustomScrollBox.height()-mCSB_container.outerHeight(); clearInterval($this.data("mCSB_buttonScrollDown")); + if(!totalScrollOffset){totalScroll=true;} + }else{scrollTo=-scrollTo;} + var snapAmount = $this.data("snapAmount"); + if (snapAmount) { + scrollTo = Math.round(scrollTo / snapAmount) * snapAmount - $this.data("snapOffset"); + } + /*scrolling animation*/ + functions.mTweenAxis.call(this,mCSB_dragger[0],"top",Math.round(draggerScrollTo),draggerSpeed,options.scrollEasing); + functions.mTweenAxis.call(this,mCSB_container[0],"top",Math.round(scrollTo),contentSpeed,options.scrollEasing,{ + onStart:function(){ + if(options.callbacks && !$this.data("mCS_tweenRunning")){callbacks("onScrollStart");} + if($this.data("autoHideScrollbar")){functions.showScrollbar.call(mCSB_scrollTools);} + }, + onUpdate:function(){ + if(options.callbacks){callbacks("whileScrolling");} + }, + onComplete:function(){ + if(options.callbacks){ + callbacks("onScroll"); + if(scrollBeginning || (scrollBeginningOffset && mCSB_container.position().top>=scrollBeginningOffset)){callbacks("onTotalScrollBack");} + if(totalScroll || (totalScrollOffset && mCSB_container.position().top<=totalScrollOffset)){callbacks("onTotalScroll");} + } + mCSB_dragger.data("preventAction",false); $this.data("mCS_tweenRunning",false); + if($this.data("autoHideScrollbar")){if(!mCustomScrollBox.hasClass("mCS-mouse-over")){functions.hideScrollbar.call(mCSB_scrollTools);}} + } + }); + } + if($this.data("mCS_Init")){$this.data({"mCS_Init":false});} + } + } + /*callbacks*/ + function callbacks(cb){ + this.mcs={ + top:mCSB_container.position().top,left:mCSB_container.position().left, + draggerTop:mCSB_dragger.position().top,draggerLeft:mCSB_dragger.position().left, + topPct:Math.round((100*Math.abs(mCSB_container.position().top))/Math.abs(mCSB_container.outerHeight()-mCustomScrollBox.height())), + leftPct:Math.round((100*Math.abs(mCSB_container.position().left))/Math.abs(mCSB_container.outerWidth()-mCustomScrollBox.width())) + }; + switch(cb){ + /*start scrolling callback*/ + case "onScrollStart": + $this.data("mCS_tweenRunning",true).data("onScrollStart_Callback").call($this,this.mcs); + break; + case "whileScrolling": + $this.data("whileScrolling_Callback").call($this,this.mcs); + break; + case "onScroll": + $this.data("onScroll_Callback").call($this,this.mcs); + break; + case "onTotalScrollBack": + $this.data("onTotalScrollBack_Callback").call($this,this.mcs); + break; + case "onTotalScroll": + $this.data("onTotalScroll_Callback").call($this,this.mcs); + break; + } + } + }, + stop:function(){ + var $this=$(this), + mCSB_container=$this.children().children(".mCSB_container"), + mCSB_dragger=$this.children().children().children().children(".mCSB_dragger"); + functions.mTweenAxisStop.call(this,mCSB_container[0]); + functions.mTweenAxisStop.call(this,mCSB_dragger[0]); + }, + disable:function(resetScroll){ + var $this=$(this), + mCustomScrollBox=$this.children(".mCustomScrollBox"), + mCSB_container=mCustomScrollBox.children(".mCSB_container"), + mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), + mCSB_dragger=mCSB_scrollTools.children().children(".mCSB_dragger"); + mCustomScrollBox.unbind("mousewheel focusin mouseenter mouseleave touchend"); + mCSB_container.unbind("touchstart touchmove") + if(resetScroll){ + if($this.data("horizontalScroll")){ + mCSB_dragger.add(mCSB_container).css("left",0); + }else{ + mCSB_dragger.add(mCSB_container).css("top",0); + } + } + mCSB_scrollTools.css("display","none"); + mCSB_container.addClass("mCS_no_scrollbar"); + $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false,"bindEvent_content_touch":false,"bindEvent_autoHideScrollbar":false}).addClass("mCS_disabled"); + }, + destroy:function(){ + var $this=$(this); + $this.removeClass("mCustomScrollbar _mCS_"+$this.data("mCustomScrollbarIndex")).addClass("mCS_destroyed").children().children(".mCSB_container").unwrap().children().unwrap().siblings(".mCSB_scrollTools").remove(); + $(document).unbind("mousemove."+$this.data("mCustomScrollbarIndex")+" mouseup."+$this.data("mCustomScrollbarIndex")+" MSPointerMove."+$this.data("mCustomScrollbarIndex")+" MSPointerUp."+$this.data("mCustomScrollbarIndex")); + $(window).unbind("resize."+$this.data("mCustomScrollbarIndex")); + } + }, + functions={ + /*hide/show scrollbar*/ + showScrollbar:function(){ + this.stop().animate({opacity:1},"fast"); + }, + hideScrollbar:function(){ + this.stop().animate({opacity:0},"fast"); + }, + /*js animation tween*/ + mTweenAxis:function(el,prop,to,duration,easing,callbacks){ + var callbacks=callbacks || {}, + onStart=callbacks.onStart || function(){},onUpdate=callbacks.onUpdate || function(){},onComplete=callbacks.onComplete || function(){}; + var startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style; + if(prop==="left"){from=el.offsetLeft;} + var diff=to-from; + _cancelTween(); + _startTween(); + function _getTime(){ + if(window.performance && window.performance.now){ + return window.performance.now(); + }else{ + if(window.performance && window.performance.webkitNow){ + return window.performance.webkitNow(); + }else{ + if(Date.now){return Date.now();}else{return new Date().getTime();} + } + } + } + function _step(){ + if(!progress){onStart.call();} + progress=_getTime()-startTime; + _tween(); + if(progress>=el._time){ + el._time=(progress>el._time) ? progress+_delay-(progress- el._time) : progress+_delay-1; + if(el._time0){ + el.currVal=_ease(el._time,from,diff,duration,easing); + elStyle[prop]=Math.round(el.currVal)+"px"; + }else{ + elStyle[prop]=to+"px"; + } + onUpdate.call(); + } + function _startTween(){ + _delay=1000/60; + el._time=progress+_delay; + _request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame; + el._id=_request(_step); + } + function _cancelTween(){ + if(el._id==null){return;} + if(!window.requestAnimationFrame){clearTimeout(el._id); + }else{window.cancelAnimationFrame(el._id);} + el._id=null; + } + function _ease(t,b,c,d,type){ + switch(type){ + case "linear": + return c*t/d + b; + break; + case "easeOutQuad": + t /= d; return -c * t*(t-2) + b; + break; + case "easeInOutQuad": + t /= d/2; + if (t < 1) return c/2*t*t + b; + t--; + return -c/2 * (t*(t-2) - 1) + b; + break; + case "easeOutCubic": + t /= d; t--; return c*(t*t*t + 1) + b; + break; + case "easeOutQuart": + t /= d; t--; return -c * (t*t*t*t - 1) + b; + break; + case "easeOutQuint": + t /= d; t--; return c*(t*t*t*t*t + 1) + b; + break; + case "easeOutCirc": + t /= d; t--; return c * Math.sqrt(1 - t*t) + b; + break; + case "easeOutSine": + return c * Math.sin(t/d * (Math.PI/2)) + b; + break; + case "easeOutExpo": + return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b; + break; + case "mcsEaseOut": + var ts=(t/=d)*t,tc=ts*t; + return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t); + break; + case "draggerRailEase": + t /= d/2; + if (t < 1) return c/2*t*t*t + b; + t -= 2; + return c/2*(t*t*t + 2) + b; + break; + } + } + }, + /*stop js animation tweens*/ + mTweenAxisStop:function(el){ + if(el._id==null){return;} + if(!window.requestAnimationFrame){clearTimeout(el._id); + }else{window.cancelAnimationFrame(el._id);} + el._id=null; + }, + /*detect requestAnimationFrame and polyfill*/ + rafPolyfill:function(){ + var pfx=["ms","moz","webkit","o"],i=pfx.length; + while(--i > -1 && !window.requestAnimationFrame){ + window.requestAnimationFrame=window[pfx[i]+"RequestAnimationFrame"]; + window.cancelAnimationFrame=window[pfx[i]+"CancelAnimationFrame"] || window[pfx[i]+"CancelRequestAnimationFrame"]; + } + } + } + /*detect features*/ + functions.rafPolyfill.call(); /*requestAnimationFrame*/ + $.support.touch=!!('ontouchstart' in window); /*touch*/ + $.support.msPointer=window.navigator.msPointerEnabled; /*MSPointer support*/ + /*plugin dependencies*/ + var _dlp=("https:"==document.location.protocol) ? "https:" : "http:"; + $.event.special.mousewheel || document.write('l +End Section + +@Section Intro +

        Fehler sind die Würze, die dem Erfolg sein Aroma geben
        - Truman Capote

        +End Section + +
        +
        +
        + + + @If Model Is Nothing Then + @

        Fehler-ID nicht gefunden

        + Else + @

        @(Model.AbsoluteUri)

        + End if +
        +
        +
        + +@If Model IsNot Nothing Then +@
        +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Controller@(Model.Controller)
        Action@(Model.Action)
        RequestType@(Model.RequestType)
        ReferrerUrl@(Model.ReferrerUrl)
        AjaxCall@(Model.AjaxCall)
        Parameters + @For Each pm As String In Model.Parameter + @@pm + @
        + Next +
        +

        @(Model.Message)

        + + + + + + + + + + @For Each eo As ErrorOccurrence In Model.Occurrences + @ + + + + + Next + +
        CreatedAtCreatedByUserAgent
        @(eo.CreatedAtFormat)@(eo.CreatedBy)@(eo.UserAgent)
        + +
        +
        +
        +End If \ No newline at end of file diff --git a/OpenAntrag/Views/Error/Uups.vbhtml b/OpenAntrag/Views/Error/Uups.vbhtml new file mode 100644 index 0000000..b29f2b2 --- /dev/null +++ b/OpenAntrag/Views/Error/Uups.vbhtml @@ -0,0 +1,42 @@ +@Imports OpenAntrag +@Modeltype CustomErrorInfo + +@Code + ViewData("Title") = "Uups, ein Fehler" + + Dim message As String + + If Model IsNot Nothing Then + If Model.Origin = CustomErrorInfo.OriginEnum.Redirect OrElse TypeOf Model.Exception Is CustomException Then + message = Model.ErrorMessage + Else + message = "Es ist ein interner Fehler aufgetreten" + End If + Else + message = "Es ist kein Fehler aufgetreten" + End If + +End Code + +@Section Styles + @Styles.Render("~/css/error") +End Section + +@Section Intro +

        Fehler sind die Würze, die dem Erfolg sein Aroma geben
        - Truman Capote

        +End Section + + +
        +
        +
        + +

        Uups,
        ein Fehler

        +
        +

        @message

        + @If Model.ReferrerUrl IsNot Nothing Then + @

        zurück zur letzten Seite.

        + End If +
        +
        +
        diff --git a/OpenAntrag/Views/Feedback/Index.vbhtml b/OpenAntrag/Views/Feedback/Index.vbhtml new file mode 100644 index 0000000..af000bb --- /dev/null +++ b/OpenAntrag/Views/Feedback/Index.vbhtml @@ -0,0 +1,98 @@ +@Imports OpenAntrag +@ModelType List(Of Feedback) + +@Code + ViewData("Title") = "Feedback" + Dim intFilterId As Integer = ViewBag.FilterId +End Code + +@Section Styles + @Styles.Render("~/css/feedback") +End Section + +@Section Scripts + @Scripts.Render("~/bundle/feedback") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro +

        Es gibt immer was zu tun, wenn man denn weiß was.
        + Lasst uns OpenAntrag noch besser machen... +

        +End Section + +
        +
        +
        + +

        Das 
        + Feedback

        +
        +

        Eine Website wie diese lebt von ihren Nutzern und entwickelt sich weiter durch ihre Nutzer. + Jeder ist aufgerufen hier seinen Kommentar abzugeben, einen Verbesserungsvorschlag + zu machen oder gar einen Fehler zu melden, damit dieser schnellst möglich behoben werden kann. +

        +

        Alle bisher eingegangenen Feedbacks findest Du hier in chronologischer Reihenfolge und filterbar über folgende Kategorien:

        +
        + Alle + @For Each ft As FeedbackType In GlobalData.FeedbackTypes.Items + @@(ft.Name) + Next +
        +
        +
        +

        Dein Feedback

        + @Using Html.BeginForm("CreateFeedback", "Feedback", FormMethod.Post, New With {.id = "newfeedback-form", .name = "newfeedback-form"}) + @Html.Partial("_NewFeedbackPartial", New Feedback) + End Using +
        +
        +
        + +@Code + Dim bolShaded As Boolean = True +End Code + +@For Each fb As Feedback In Model + + Dim fbType As FeedbackType = (From fbt As FeedbackType In GlobalData.FeedbackTypes.Items + Where fbt.ID = fb.Type + Select fbt).FirstOrDefault + + @ + @
        +
        +
        + + +
        +
        +
        + bolShaded = Not bolShaded +Next + + diff --git a/OpenAntrag/Views/Feedback/_FeedbackCommentPartial.vbhtml b/OpenAntrag/Views/Feedback/_FeedbackCommentPartial.vbhtml new file mode 100644 index 0000000..3064e28 --- /dev/null +++ b/OpenAntrag/Views/Feedback/_FeedbackCommentPartial.vbhtml @@ -0,0 +1,19 @@ +@Imports OpenAntrag +@ModelType FeedbackComment + +
        + @If Tools.IsAdmin = True Then + @
        + +
        + End If +   +
        + @Model.CommentedBy am @Model.CommentedAtFormat +
        @Model.CommentHtml
        +
        +
        +
        \ No newline at end of file diff --git a/OpenAntrag/Views/Feedback/_NewFeedbackCommentPartial.vbhtml b/OpenAntrag/Views/Feedback/_NewFeedbackCommentPartial.vbhtml new file mode 100644 index 0000000..1e5ebc5 --- /dev/null +++ b/OpenAntrag/Views/Feedback/_NewFeedbackCommentPartial.vbhtml @@ -0,0 +1,16 @@ +@Imports OpenAntrag +@ModelType FeedbackComment + +@Html.TextBoxFor(Function(m) m.CommentedBy, New With {.placeholder = "Dein Name"}) +@Html.ValidationMessageFor(Function(m) m.CommentedBy) + +
        + @Html.TextAreaFor(Function(m) m.Comment, 5, 0, New With {.placeholder = "Dein Kommentar"}) + @Html.ValidationMessageFor(Function(m) m.Comment) +
        + + + +
        + +
        diff --git a/OpenAntrag/Views/Feedback/_NewFeedbackPartial.vbhtml b/OpenAntrag/Views/Feedback/_NewFeedbackPartial.vbhtml new file mode 100644 index 0000000..38d171e --- /dev/null +++ b/OpenAntrag/Views/Feedback/_NewFeedbackPartial.vbhtml @@ -0,0 +1,27 @@ +@Imports OpenAntrag +@ModelType Feedback + + + +@Html.TextBoxFor(Function(m) m.CreatedBy, New With {.placeholder = "Dein Name", .style = "width:95%"}) +@Html.ValidationMessageFor(Function(m) m.CreatedBy) + +@Html.TextBoxFor(Function(m) m.Title, New With {.placeholder = "Titel", .style = "width:95%"}) +@Html.ValidationMessageFor(Function(m) m.Title) + +
        + @Html.TextAreaFor(Function(m) m.Message, 5, 0, New With {.placeholder = "Dein Feedback", .style = "width:95%"}) + @Html.ValidationMessageFor(Function(m) m.Message) +
        + +
        + + + Du kannst Dein Feedback auch jederzeit an feedback@openantrag.de richten. + +
        diff --git a/OpenAntrag/Views/Home/Api.vbhtml b/OpenAntrag/Views/Home/Api.vbhtml new file mode 100644 index 0000000..2e99005 --- /dev/null +++ b/OpenAntrag/Views/Home/Api.vbhtml @@ -0,0 +1,1050 @@ +@Imports OpenAntrag +@Code + ViewData("Title") = "API" +End Code + +@Section Styles + @Styles.Render("~/css/api") +End Section + +@Section Scripts + +End Section + +@Section Intro +

        Daten müssen fließen, um sie nutzbar zu machen.
        + Am besten über eine API wie diese, die die + OpenAntrag-Daten öffentlich zugänglich macht. +

        +End Section + +
        +
        +
        + +

        Die 
        + Schnittstellen

        +
        +
        +
        +
        +
        +

        Alle Daten von OpenAntrag, bis auf die Kontodaten der Benutzer, + sind öffentlich zugänglich. Jeder kann sie maschinell einlesen und weiterverarbeiten

        +

        Um Vandalismus und dergleichen zu verhindern, ist der schreibende Zugriff durch + einen Schlüssel (API-Key) gesichert, den die Fraktionen auf Anfrage (kurze Mail) erhalten.

        +

        Alle Dienstmethoden wurden als HTTP-Services (REST) via Web API umgesetzt. Das Ausgabeformat + richtet sich nach dem im Request angegebenen Content-Type. + Unterstützt werden aktuell folgende Content-Types: +

          +
        • application/json
        • + @*
        • application/xml
        • *@ +
        • text/csv (nur Listen)
        • +
        +

        +

        + Alternativ kann auch der Url-Parameter format zur erzwungenen Ausgabe eines + bestimmten Formats verwenden werden. Beispiel: +

        +

        + http://@(Tools.GetRequestDomain)/api/ ... ?format=json +

        +

        Im Folgenden werden die einzelnen Methoden und ihre Ausgaben dokumentiert. + Sollten sich daraus Fragen ergeben, gerne via Mail an + @("api@" & Tools.GetRequestDomain)

        +
        +
        +
        + +@Code + Dim bolShaded As Boolean = False +End Code + +
        +
        +
        + +

        Parlament (Fraktion):
        Representation

        +
        +
        +
        + +
        +
        +
        +

        /api/representation/GetKeyValueList

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetKeyValueList
        HTTP-MethodeGET
        Ausgabe + Eine Key-Value-Liste aller in OpenAntrag vertretenen Parlamente (Fraktionen) + mit Schlüsselwert und Namen +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetAll

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetAll
        HTTP-MethodeGET
        Ausgabe + Liste aller Representation-Objekte (Parlamente). +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetByKey/{key}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetByKey/{KEY}
        HTTP-MethodeGET
        Ausgabe + Ein Representation-Objekt (Parlament) anhand seines + Schlüsselwertes (KEY). +
        Beispielergebnisse: + +@* *@ +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetRepresentatives/{key}

        + + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetRepresentatives/{KEY}
        HTTP-MethodeGET
        Ausgabe + Liste aller Representative-Objekte (Abgeordnete) + einer Fraktion anhand des Schlüsselwertes eines Parlamentes (KEY). +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetCommittees/{key}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetCommittees/{KEY}
        HTTP-MethodeGET
        Ausgabe + Liste aller Committee-Objekte (Ausschüsse) + eines Parlaments (Fraktion) anhand des Schlüsselwertes eines Parlamentes + (KEY). +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetProcessSteps/{key}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetProcessSteps/{KEY}
        HTTP-MethodeGET
        Ausgabe + Liste aller ProcessStep-Objekte (Prozessschritte), + inklusive der Folgeschritte, eines Parlaments (Fraktion) anhand des + Schlüsselwertes eines Parlamentes (Key). +

        + In der Caption-Eigenschaft sind Platzhalter wie %REPRESENTATIVE% oder + %COMMITTEE% enthalten, wenn ein Schritt bei der Weitergabe eines Antrags einen + zusätzlichen Wert benötigt. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/representation/GetProcessStepById/{key}/{id}

        + + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/representation/GetProcessStepById/{KEY}/{ID}
        HTTP-MethodeGET
        Ausgabe + Gibt ein ProcessStep-Objekt (Prozessschritt) + eines Parlamentes (Key) anhand seiner ID zurück. +
        +
        + In der Caption-Eigenschaft sind Platzhalter wie %REPRESENTATIVE% oder + %COMMITTEE% enthalten, wenn ein Schritt bei der Weitergabe eines Antrags einen + zusätzlichen Wert benötigt. +
        Beispielergebnisse: + +@* *@ +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        + +

        Antrag:
        Proposal

        +
        +
        +
        +@Code bolShaded = False End Code + +
        +
        +
        +

        /api/proposal/{Key}/GetCount

        + + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/{KEY}/GetCount
        HTTP-MethodeGET
        Ausgabe + Anzahl der in OpenAntrag erfassten Anträge. +
        +
        + Der KEY bezeichnet entweder den Schlüsselwert eines + Parlaments (Fraktion) oder den festen Wert ALL, um über alle Äntrage zu gehen. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/{Key}/GetTop/{count}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/{KEY}/GetTop/{COUNT}
        HTTP-MethodeGET
        Ausgabe + Liste der letzten eingegangenen Proposal-Objekte (Anträge), + mit dem Parameter COUNT zur Angabe der Anzahl. +

        + Der KEY bezeichnet entweder den Schlüsselwert eines + Parlaments (Fraktion) oder den festen Wert ALL, um über alle Äntrage zu gehen. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/{Key}/GetPage/{pageNo}/{pageCount}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/{KEY}/GetPage/{PAGENO}/{PAGECOUNT}
        HTTP-MethodeGET
        Ausgabe + Seitenweise Liste der Proposal-Objekte (Anträge), + mit den Parametern PAGENO zur Angabe der Seitenzahl + und PAGECOUNT, der Anzahl der Anträge pro Seite. + Die Zählung der Seiten beginnt bei 1. +
        +
        + Der KEY bezeichnet entweder den Schlüsselwert eines + Parlaments (Fraktion) oder den festen Wert ALL, um über alle Äntrage zu gehen. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/{Key}/GetByTag/{tag}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/{KEY}/GetByTag/{TAG}
        HTTP-MethodeGET
        Ausgabe + Liste aller Proposal-Objekte (Anträge), + die mit einem Thema (TAG) gekennzeichnet wurden. +
        +
        + Der KEY bezeichnet entweder den Schlüsselwert eines + Parlaments (Fraktion) oder den festen Wert ALL, um über alle Äntrage zu gehen. +

        + Das Thema (TAG) muss Url-kodiert sein. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/GetByTitleUrl/{Key}/{titleurl}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/GetByTitleUrl/{KEY}/{TITLEURL}
        HTTP-MethodeGET
        Ausgabe + Gibt ein Proposal-Objekt (Antrag), + anhand seiner suchmaschinenfreundlichen Url zurück. +
        +
        + Der KEY bezeichnet entweder den Schlüsselwert eines + Parlaments (Fraktion) oder den festen Wert ALL, um über alle Äntrage zu gehen. +
        Beispielergebnisse: + +@* *@ +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/GetById/{id}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/GetById/{ID}
        HTTP-MethodeGET
        Ausgabe + Gibt ein Proposal-Objekt (Antrag), + anhand seiner systemweit eindeutigen ID zurück. +
        Beispielergebnisse: + +@* *@ +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/GetComments/{id}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/GetComments/{ID}
        HTTP-MethodeGET
        Ausgabe + Liste aller ProposalComment-Objekte (Kommentare zu einem Antrag) + eines Antrags anhand der eindeutigen ID des Antrags. +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/GetTags

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/GetTags
        HTTP-MethodeGET
        Ausgabe + Liste aller bereits verfügbaren Tags (Themen). +
        Beispielergebnisse: + +@* *@ + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/PostNew

        + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/PostNew
        HTTP-MethodePOST
        Übergabe + ProposalDTO-Objekt mit folgenden Eigenschaften: +

        + + + + + + + + + + + + + + + + + + + + + +
        Api-KeyApi-Schlüssel der Fraktion
        Key_RepresentationSchlüsselwert des Parlaments (Fraktion)
        TitleTitle des neuen Antrags
        TextText des neuen Antrags in Markdown-Syntax
        TagListKomma-separierte Liste der dem Antrag zuzuweisenden Themen
        + Beispiel: +
        +
        +{
        +  "ApiKey" : "abcdefghijklmnopqrstuvwxyz",
        +  "Key_Representation": "wiesbaden",
        +  "Title": "Dies ist ein Test...",
        +  "Text": "Dies ist ein Test",
        +  "TagList": "Transparenz,Bildung"
        +}
        +                        
        +
        Ausgabe + Neu erzeugtes Proposal-Objekt (Antrag) mit allen Eigenschaften. +
        +
        + @If Tools.IsAdmin = True Then + @ + End If +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/proposal/PostNextStep

        + + + + + + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/proposal/PostNextStep
        HTTP-MethodePOST
        Hinweis + Ein Proposal-Objekt (Antrag) enthält eine Auflistung von + ProposalStep-Objekten (Antragsschritt). Der aktuell gültige + Antragsschritt aus der Liste kann über die Eigenschaft ID_CurrentProposalStep + ermittelt werden. Dieser Wert verweist auf die fortlaufende Id der Antragsschritte. +
        +
        + Ein Antragsschritt ist die Ausformulierung eines Prozessschrittes. In einem ProposalStep-Objekt + wird dieses über das untergeordnete ProcessStep-Objekt zur Verfügung gestellt. +
        +
        + Die nächsten möglichen Schritte lassen sich über die ProcessStep-Eigenschaft + ID_NextSteps als komma-separierte ID-Liste abrufen. Ein komplettes + ProcessStep-Objekt kann /api/representation/GetProcessSteps abgerufen werden. +
        +
        + In einigen Prozessschritten sind Variablen enthalten, die kennzeichnen, dass weitere Daten zu diesem + Schritt benötigt werden. Dies wären aktuell: + + + + + + + + + +
        %REPRESENTATIVE% + Abgeordneter
        + Auswahlliste über /api/representation/GetRepresentatives +
        %COMMITTEE% + Ausschuss
        + Auswahlliste über /api/representation/GetCommittees +
        + Benötigt ein Antragsschritt eine der Variablen, muss der entsprechende Wert im + zu übergebenden Data Transfer Object gefüllt sein. +

        +
        Übergabe + ProposalNextStepDTO-Objekt mit folgenden Eigenschaften: +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Api-KeyApi-Schlüssel der Fraktion
        Key_RepresentationSchlüsselwert des Parlaments (Fraktion)
        ID_ProposalID des Antrags
        ID_ProcessStepID des einzustellenden Prozessschrittes
        InfoTextInformationstext in Markdown-Syntax
        Key_RepresentativeSchlüsselwert des Abgeordneten, wenn der Prozesschritt dies benötigt
        Key_CommitteeSchlüsselwert des Ausschusses, wenn der Prozesschritt dies benötigt
        + Beispiel: +
        +
        +{
        +  "ApiKey" : "abcdefghijklmnopqrstuvwxyz",
        +  "Key_Representation": "wiesbaden",
        +  "ID_Proposal" : "proposals-66",
        +  "ID_ProcessStep" : "10",
        +  "InfoText" : "Antrag wurde einstimmig angenommen",
        +  "Key_Representative" : null,
        +  "Key_Committee" : null
        +}
        +                        
        +
        Ausgabe + Neu erzeugtes ProposalStep-Objekt (Antragsschritt) mit allen Eigenschaften. +
        +
        + @If Tools.IsAdmin = True Then + @ + End If +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        + +

        Mitteilungen:
        Notifications

        +
        +
        +
        + +
        +
        +
        +

        /api/notifications/GetTypeList

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/notifications/GetTypeList
        HTTP-MethodeGET
        Ausgabe + Eine Key-Value-Liste aller in OpenAntrag verwendeten Mitteilungstypen +
        Beispielergebnisse: + + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/notifications/GetLast/{count}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/notifications/GetLast/{count}
        HTTP-MethodeGET
        Ausgabe + Liste der letzten Notification-Objekte (Mitteilungen), + mit dem Parameter COUNT zur Angabe der Anzahl. +
        Beispielergebnisse: + + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code + +
        +
        +
        +

        /api/notifications/GetLastByType/{typeId}/{count}

        + + + + + + + + + + + + + + + + +
        Urlhttp://@(HttpContext.Current.Request.Url.Authority)/api/notifications/GetLast/{typeId}/{count}
        HTTP-MethodeGET
        Ausgabe + Liste der letzten Notification-Objekte (Mitteilungen) + eines bestimmten Typs (TYPEID), + mit dem Parameter COUNT zur Angabe der Anzahl. +
        Beispielergebnisse: + + +
        +
        +
        +
        +@Code bolShaded = Not bolShaded End Code diff --git a/OpenAntrag/Views/Home/Faq.vbhtml b/OpenAntrag/Views/Home/Faq.vbhtml new file mode 100644 index 0000000..5be9f87 --- /dev/null +++ b/OpenAntrag/Views/Home/Faq.vbhtml @@ -0,0 +1,407 @@ +@Imports OpenAntrag + +@Code + ViewData("Title") = "FAQ" +End Code + +@Section Styles + @Styles.Render("~/css/faq") +End Section + +@Section Scripts + +End Section + +@Section Intro +

        Fragen über Fragen ...
        + Hier gibts ein paar Antworten

        +End Section + +
        +
        +
        + +

        Die
        + FAQ

        +
        +
        +
        +

        FAQ - "Frequently Asked Questions" ist traditionell der Bereich einer Website + wo häufig gestellte Fragen beantwortet werden. So auch hier. Interessant auch + für Fraktionsadministratoren... ;) +

        +

        Dein drängende Frage wurde noch nicht gestellt? Dann nutze das + Feedback und es wird Dir geholfen.

        + +
          +
          +
          +
          + +@Code + Dim bolShaded As Boolean = True +End Code + +@* + +
          +
          +
          + +

          +

          +
          +
          +
          + @Code bolShaded = Not bolShaded End Code +*@ + + +
          +
          +
          + für Fraktionen/Einzelabgeordnete +

          Wie bekomme ich für meine Fraktion eine eigene OpenAntrag-Seite?

          +

          Stell zunächst sicher, dass noch kein Kollege schneller war. War dies keiner, + dann schicke an die Mail-Adresse @("fraktion-registrieren@" & Tools.GetRequestDomain) + eine Mail mit folgenden Informationen... +

          + +

          ...zum Parlament

          +
            +
          • Name des Parlaments
          • +
          • Liste aller Ausschüsse (Name und Link, falls vorhanden)
          • +
          • Bild der Region (JPG-Datei, mind. 2100 Pixel breit; falls vorhanden)
          • +
          +

          ...zur Fraktion

          +
            +
          • Name der Fraktion / des Abgeordneten
          • +
          • Beschreibung der Fraktion (Fließtext; Historie, Wissenswertes, ...)
          • +
          • zentrale Mail-Adresse
          • +
          • Mail-Adresse für Hinweisnachrichten
          • +
          • zentrale Telefonnummer (falls vorhanden)
          • +
          • Twitter-Account (falls vorhanden)
          • +
          • Logo der Fraktion (PNG-Datei; falls vorhanden)
          • +
          +

          ...zu den einzenen Abgeordneten

          +
            +
          • Vorname, Nachname
          • +
          • Mail-Adresse
          • +
          • Twitter-Account (falls vorhanden)
          • +
          • Telefonnummer (falls gewünscht)
          • +
          • Foto (JPG-Datei, 100 x 125 Pixel)
          • +
          +

          ...zum Antragsprozess

          +

          + Beschreibung des Antragsprozesses des Parlaments in einzelnen Schritten + mit jeweiligen Verknüpfungen zu den nächsten möglichen Schritten. +

          +

          Beispiel:

          +
          +1. Eingang des Antrags
          +   > 2   
          +2. Prüfung des Antrags
          +   > 3
          +   > 4
          +3. Behandlung in der Fraktionssitzung
          +   > 4
          +   > 5
          +4. Keine Übernahme durch die Fraktion
          +5. Übernahme durch Fraktionsmitglied
          +   > 6
          +   > 7
          +   > 8
          +6. Antrag in Ausschuss
          +   > 6
          +   > 7  
          +7. Antrag im Parlament
          +   > 6
          +   > 8
          +   > 9   
          +8. Antrag angenommen
          +9. Antrag abgelehnt
          +            
          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Fraktionen/Einzelabgeordnete +

          Wie administriere ich die Anträge (Webcast)

          +

          Im folgenden Webcast (14 Minuten) wird die Bearbeitung eines Antrags erläutert:

          + +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Alle +

          Wie kann ich mich über neue Fraktionen oder Anträge informieren?

          +

          OpenAntrag nutzt diverse Kanäle, um Informationen zu verbreiten.

          + +

          RSS-Feed

          +

          + OpenAntrag bietet zwei klassische RSS-Feeds. Der allgemeine Feed, der über die Adresse + http://openantrag.de/feed abonniert werden kann, + beinhaltet alle eingegangenen Anträge. Jede Parlaments- bzw. Fraktionsseite bietet zudem + einen eigenen Feed, nur mit den Anträgen die dort eingegangen sind: http://openantrag.de/<Schlüssel des Parlaments (Fraktion)>/feed. +

          +

          + RSS-Feeds lassen sich mit vielen Programmen verarbeiten und lesen. Ein recht bekanntes Exemplar ist + zum Beispiel der Online-Feed-Reader feedly.com, das aus dem Google Reader hervorgegangen ist. + Eine recht gute Übersicht über die verfügbaren Programme bietet about-rss.de. +

          + +

          Twitter

          +

          + Jeder neue Antrag wird automatisch auf dem Twitter-Konto @@OpenAntrag + veröffentlicht. Daneben gibt es dort auch immer wieder manuelle Tweets, wenn zum Beispiel eine neue + Fraktion an dem System teilnimmt. Es lohnt sich also dem Account zu folgen... +

          + +

          Pushbullet

          +

          + Pushbullet ist ein sog. Notification Service (Hinweisdienst) für Smartphones (Andropid, iOS, Windows) und + Browser (Chrome, Firefox). +

          +

          + Mit Einführung der abonnierbaren Pushbullet-Channels gibt es auch einen + OpenAntrag-Channel, + über den alle Mitteilungen, neue Anträge, Erfolgsgeschichten und Feedbacks gepostet werden: + http://pushbullet.com/channel?tag=openantrag +

          + +

          Google+

          +

          + Es gibt eine OpenAntrag-Community auf Google+ + auf der neben neuen Fraktionen auch neue Features angekündigt werden. + Sie dient auch zur Informationssammlung von Presseberichten und anderem Wissenswertem über OpenAntrag. +

          + +

          API

          +

          + Neben den oben genannten, recht bequemen Wegen, zur Information, gibt es auch noch die API (Application Programming Interface) + für die Techies unter uns: http://openantrag.de/api Mit den verschiedenen Methoden + der Schnittstellen lassen sich recht unkompliziert neue Informationsangebote kreieren, wenn man damit umzugehen weiß. +

          + +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Alle +

          Warum kann der Antragsteller seinen Namen und seine Kontaktdaten nicht angeben?

          +

          Jeder Piratenabgeordneter wird das schon mal erlebt haben: man bringt einen Antrag ins Parlament ein und er + wird von den Etablierten nur abgelehnt, weil er von den Piraten kommt. Man merkt das meist daran, dass das + Thema ein oder zwei Jahre später fast wortgleich von einer Fraktion eingebracht wird, die den eigenen zuvor + abgelehnt hat. +

          +

          So, und nun stelle man sich vor, alle Anträge kämen anonymisiert ins Parlament, sprich die Abgeordneten müssten + sich nur mit dem Thema auseinandersetzen..!? Ergebnis: Viele gute Dinge würden wesentlich schneller umgesetzt + und unser Land hätte weniger Probleme. +

          +

          Wir Piraten können nun nicht umhin zuzugeben, dass auch wir der Versuchung erliegen können, die + persönliche und/oder ideologische Ebene in unsere Entscheidungen mit einfließen zu lassen. Dieser + Erfahrungen haben wir in unserem Pilotprojekt in der Stadtverordnetenfraktion "Linke & Piraten Wiesbaden" + bereits gemacht und uns deswegen dazu entschlossen uns auf das eigentliche Thema zu konzentrieren, auch wenn + es manchmal schade ist, den Antragssteller nicht direkt kontaktieren zu können, wenn zum Beispiel etwas unklar ist. + Die Kommentarfunktion schafft da allerdings Abhilfe, denn wenn ein Antragsteller wirklich an der Umsetzung + interessiert ist, wird er die Seite erneut besuchen, den Rückfragekommentar lesen und antworten. +

          +

          Inzwischen ist es jeder Fraktion möglich einzustellen, ob unter dem Antragstext ein Feld zur freiwilligen + Angabe von Kontaktinformationen eingblendet wird. Diese Daten werden allerdings nur in die Hinweisnachricht + an die Fraktion übernommen und nicht auf der OpenAntrag-Server gespeichert. +

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Alle +

          Was ist "Missbrauch melden" und was passiert danach?

          +

          + Die Plattform ist für jeden und alles offen, soll aber nicht dazu dienen, sie für + Denunziationen, Beleidigungen oder Ähnliches zu missbrauchen. + Daher gibt es unter jedem Antrag den Link Missbrauch melden und + jeder ist aufgerufen Anträge darüber zu melden, die + widerrechtlich sind! +

          +

          + Klickt man auf den Link, so öffnet sich ein Feld zur Angabe der Begründung. + Diese Begründung wird an die Fraktion und die Administration geschickt, die den + Antrag dann stumm schalten kann. Dazu gibt es im Administrationsmodus + eines Antrags einen entsprechenden Button, der wiederum eine Begründung einfordert, + die anschließend anstelle des ursprünglichen Antragstextes für alle sichtbar gemacht wird. +

          +

          + Ist ein Antrag stumm geschaltet, hat die Fraktion die Möglichkeit den Antragstext zu + "schwärzen", also einzelne Passagen durch "XXX" oder Ähnliches zu ersetzen, um zum + Beispiel persönliche Angaben herauszunehmen. Danach kann sie den Antrag wieder "scharf" + schalten, wobei die Fraktionsbegründung gespeichert bleibt. +

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Alle +

          Warum ist OpenAntrag ein privates Projekt?

          +

          Bei den Piraten in Hessen ist ein Bürgerportal schon seit fast zwei Jahren immer wieder in der + Diskussion, auch weil die Stadtverordentenfraktion "Linke & Piraten Wiesbaden" mit dem Pilotprojekt + "Bürgeranträge" zumindest einen Teil in der Umsetzung hatte. Bis auf ein Anforderungsprofil, welches + fast so dick wie Tolstois "Krieg und Frieden" wurde, ist aber nicht viel passiert. +

          +

          Einige andere hessische Fraktionen wollten nun aber ebenfalls Bürgeranträge anbieten und in das + Pilotprojekt einsteigen. Da Portierungen auf unterschiedlichste Web-Systeme resourcenintensiv und + mit Reibungsverlusten behaftet sind, wurde die Idee eines bundesweiten, gemeinsamen Portals geboren. + Da ich (Kristof Zerbe) eher zu Abteilung "Machen statt Labern" gehöre, mein Engagement für die Piratenpartei + seit 2009 ungebrochen ist (Kreisvorstand, Landesvorstand, PG's, AG's, et cetera pp) und schlicht gerne moderne + Webseiten entwickele, habe ich mich an die Tastatur gesetzt... +

          +

          Das OpenAntrag einen solchen Zuspruch erhält, habe ich nicht erwartet und mir ist durchaus bewußt, dass es + den Abgeordneten und Bürgern ein wenig Vertrauen in meine Person abverlangt, auch wenn ich aktuell die Kosten + und die Verantwortung trage. In naher Zukunft möchte ich allerdings das Projekt unter die Ägide der Partei + bringen, da es dort meiner Meinung nach hingehört und die Akzeptanz erhöht. Als Gegenleistung erwarte ich + dafür: Nichts, denn ich bin Idealist und möchte mit meiner Arbeit für die Piraten dazu beitragen etwas zu + verbessern. +

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Alle +

          Wie wurde OpenAntrag umgesetzt, ist der Code verfügbar und wo kann man ihn herunterladen?

          +

          OpenAntrag ist ein ASP.NET MVC-Projekt und läuft auf einem Internet Information Server (IIS) 7.5 unter + Windows Server 2008 R2.
          Die Entscheidung das .NET-Framework einzusetzen hat einen simplen Hintergrund: + der Entwickler beherrscht es am besten ;) +

          +

          Die wichtigsten Standards und Tools: +

          +

          +

          In OpenAntrag findet keinerlei Logging oder Tracking statt. Die IIS-Standardlogs sind ausgeschaltet. + So werden auch keinerlei externe Services eingebunden, die einem Logging unterliegen könnten.

          +

          Das Projekt wurde auf https://openantrag.codeplex.com veröffentlicht.

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Administratoren +

          Kann ich den Antragstext im Nachhinein verändern?

          +

          Klare Antwort: Jain. Stellt ein Bürger einen Antrag ein, wäre es natürlich fatal, + wenn diese "Willensbekundung" manipuliert werden könnte.

          +

          Bist Du allerdings als Administrator angemeldet und stellst selbst einen Antrag ein, + um zum Beispiel ältere Anträge nachzupflegen, wird Dein Benutzername im Antrag + vermerkt, um Dich in die Lage zu versetzen Deinen eigenen Text auch später noch + ändern zu können. +

          +

          Weiterhin haben die Fraktionen die Möglichkeit Anträge zum Beispiel aus + Datenschutzgründen stummzuschalten, wenn jemand schützenswerte Informationen + in seinen Antrag geschrieben hat, und den Antragstext dann entsprechend zu + verändern. +

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code + + +
          +
          +
          + für Webmaster + +

          Ich würde gerne ein OpenAntrag-Banner auf meine Seite stellen. Gibt es eins?

          +

          Ja. Ralf Praschak hat ein dynamisches Banner gebaut, dass über die API + aktuelle Zahlen zieht und einblendet: +
          +

          +

          +

          Daraus hat Ralf auch ein Drupal 6-Modul entwickelt: +
          +

          +

          +
          +

          Individuelle, statische Banner findet man auf den jeweiligen Seiten der Parlamente (Fraktionen) unter:

          +

          + http://openantrag.de/<Schlüssel des Parlaments (Fraktion)>/banner +
          + also z.B.: http://openantrag.de/wiesbaden/banner +

          +
          +
          +
          +@Code bolShaded = Not bolShaded End Code diff --git a/OpenAntrag/Views/Home/Index.vbhtml b/OpenAntrag/Views/Home/Index.vbhtml new file mode 100644 index 0000000..29733a1 --- /dev/null +++ b/OpenAntrag/Views/Home/Index.vbhtml @@ -0,0 +1,327 @@ +@Imports OpenAntrag +@Code + ViewData("Title") = "Start" + + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And (Representations.StatusConjuction.Active + Representations.StatusConjuction.Ended)) > 0) _ + .OrderBy(Function(x) x.Level) _ + .ThenBy(Function(x) x.Key) _ + .ToList() + +End Code + +@Section Styles + @Styles.Render("~/css/home") +End Section + +@Section Scripts + +End Section + +@Section Intro + + + +

          Für Piraten ist Bürgerbeteiligung nicht nur ein Wort. Wir sind schon in vielen Parlamenten + vertreten und geben Dir hier die Möglichkeit, Dein Anliegen dort einzubringen.

          +End Section + +
          +
          +
          + +

          Die 
          + Idee

          +
          +
          +
          +

          Es gibt so wunderbare Ideen von wunderbaren Menschen, die es nie in irgendein Parlament + schaffen; wir stellen uns die Frage warum.

          +

          Piraten sind landauf und landab angetreten, um den Menschen zu mehr Mitbestimmungsrecht + zu verhelfen. Dazu ist es notwendig, das Ohr ganz nah am Bürger und seinen Ideen zu haben.

          +

          Nun gibt es in unserer repräsentativen Demokratie die Regel, dass nur Parlamentarier Anträge + in die Versammlung einbringen können. Aber wer sagt denn, dass wir deswegen nicht zuhören sollten?

          +

          Wir nehmen das Wort Volksvertreter wörtlich und geben Dir mit dieser Website + die Möglichkeit, Deine Ideen in Dein Parlament zu bringen. +

          +
          +
          +
          + +
          +
          +
          + +

          Das 
          + Verfahren

          +
          +

          Dreh- und Angelpunkt sind die einzelnen Fraktionen oder Einzelabgeordneten der Piratenpartei. + Sie dienen als Vermittler Deines Anliegens.

          +

          Das grundlegende Prinzip ist recht einfach: Du bringst Dein Anliegen über diese Website ein. + Anschließend wird es von uns geprüft und zu einem Antrag ausgearbeitet. Dieser wird dann ins + Parlament oder einen Ausschuss eingebracht, bzw. eine Anfrage wird gestartet.

          +

          Der Antragsprozess kann sich von Fraktion zu Fraktion ein wenig unterscheiden (je nach Gremium), + aber der Status eines Antrags ist immer transparent und nachvollziehbar.

          +
          +
          +
          + +
          +
          +
          + +
          +
          +
          + +

          Die 
          + Regeln

          +
          +
          +
          +

          Natürlich braucht es ein paar Regeln, um der Idee eine Form zu geben, aber es sind nicht viele:

          +
            +
          1. Jeder Antrag wird geprüft. Wir behalten uns jedoch vor, nur solche Anträge weiterzuverfolgen, die unserem politischen Selbstverständnis entsprechen.
          2. +
          3. Anträge werden grundsätzlich anonym behandelt, um die persönliche/ideologische Ebene außen vor zu lassen.
          4. +
          5. Die Bearbeitung der Anträge erfolgt transparent auf dieser Seite. Eine Benachrichtigung des Antragsstellers erfolgt nicht.
          6. +
          7. Alle Anträge sind öffentlich und können auch öffentlich kommentiert werden.
          8. +
          +
          +
          +
          + +
          +
          +
          + +

          Die 
          + Parlamente

          +
          +

          + In OpenAntrag sind aktuell @(lst.Count) Parlamente gelistet, + in denen Abgeordnete oder Fraktionen der Piraten Deine Anträge entgegennehmen oder dies getan haben. +

          +@*

          Wir können bzw. Du kannst in folgenden @(intActiveCount) Parlamenten Anträge einbringen, weil wir dort + Einzelabgeordnete oder eine Fraktion haben:

          *@ +
          +
          + @Html.Partial("_FederalMap", GlobalData.FederalStates) +
          +
          +

          Deine Piratenfraktion oder Du als Einzelabgeordneter bist hier noch nicht vertreten?

          + Informationen zur Teilnahme +
          +
          +
          + + + +@Code + Dim intMid As Integer = CInt(Math.Round(lst.Count / 2)) + If intMid Mod 2 = 1 Then intMid += 1 + Dim lstOne = lst.Where(Function(r, index) (index + 1) <= intMid) + Dim lstTwo = lst.Where(Function(r, index) (index + 1) > intMid) +End Code + +
          +
          +
          + @For Each r As Representation In lstOne + Html.RenderPartial("_RepresentationBox", r) + Next +
          +
          + @For Each r As Representation In lstTwo + Html.RenderPartial("_RepresentationBox", r) + Next +
          +
          + +
          + +@Code + Dim lstRV As List(Of Representative) = GlobalData.Representations.GetRepresentatives + lstRV = Tools.RandomizeList(Of Representative)(lstRV) +End Code +
          +
          +
          + +

          Die 
          + Abgeordneten

          +
          +
          +
          +

          + Diese @(lstRV.Count) Piraten + und viele viele weitere, sowie die Kollegen anderer Parteien aus den hier + vertretenen Fraktionen, setzen sich für Deine Idee und Deinen Antrag ein.

          +
          +
          +
          + +
          +
          +
          + @For Each rv As Representative In lstRV + Dim rp As Representation = GlobalData.Representations.Items.Where(Function(x) x.Key = rv.Key_Representation).FirstOrDefault() + Dim stbTitle As New StringBuilder + stbTitle.Append("").Append(rv.Name).Append("").Append("
          ") + stbTitle.Append(rp.Name).Append("
          ") + stbTitle.Append("").Append(rp.FederalName).Append("") + + @ + Next +
          +
          +
          + +@Code + Dim lstP = GlobalData.piratenmandate.Items _ + .Where(Function(x) String.IsNullOrEmpty(x.OpenAntragKey) = True and x.MandateCount > 0) _ + .OrderBy(Function(x) x.Bundesland.Name) _ + .ThenBy(Function(x) x.GebietName).ToList() +End Code +
          +
          +
          + +

          Die 
          + Möglichkeiten

          +
          +
          +
          +

          + Auf kommunalpiraten.de trägt Michael Büker + alle Parlamente zusammen, in denen Mandatsträger der Piratenpartei Deutschland + vertreten sind. Viele davon nutzen bereits das Angebot von OpenAntrag. + Aktuell gibt es noch @lstP.Count + Möglichkeiten ... +

          +
          +
          +
          + +
          +
          +
          + @For Each p In lstP + Dim stbTitle As New StringBuilder + stbTitle.Append("").Append(p.GebietType).Append("").Append(" ").Append("").Append(p.Bundesland.Name).Append("").Append("
          ") + stbTitle.Append(p.MandateCount).Append(" von ").Append(p.ParlamentSeats).Append(" Sitzen") + If String.IsNullOrEmpty(p.FraktionName) = False Then + stbTitle.Append("
          ") + stbTitle.Append(p.FraktionText) + End If + + @If String.IsNullOrEmpty(p.GebietLocalpirates) = false Then + @ + @p.GebietTypeAndName + + Else + @
          + @p.GebietTypeAndName +
          + End If + Next +
          +
          +
          + diff --git a/OpenAntrag/Views/Home/Journal.vbhtml b/OpenAntrag/Views/Home/Journal.vbhtml new file mode 100644 index 0000000..a1df98a --- /dev/null +++ b/OpenAntrag/Views/Home/Journal.vbhtml @@ -0,0 +1,103 @@ +@Imports OpenAntrag +@ModelType List(Of Proposal) + +@Code + ViewData("Title") = "Antragsjournal" + + Dim pageNo As Integer = 0 + If ViewData("PageNo") IsNot Nothing Then + pageNo = CType(ViewData("PageNo"), Integer) + End If + + Dim itemsCount As Integer = 0 + If ViewData("ItemsCount") IsNot Nothing Then + itemsCount = CType(ViewData("ItemsCount"), Integer) + End If + + 'Dim rps As New Representations(Representations.StatusConjuction.Active) + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And Representations.StatusConjuction.Active) > 0) _ + .ToList() + +End Code + +@Section Styles + @Styles.Render("~/css/list") +End Section + +@Section Scripts + +End Section + +@Section Intro +

          Jeder Bürgerantrag ist ein Zeichen dass Demokratie funktioniert, + sofern man denn will und jeder mitwirken kann der möchte.

          +End Section + +
          +
          + +
          +

          + Es ist nicht leicht etwas zu verändern, aber es geht!
          + Schau Dir unsere Erfolgsgeschichten an... +

          +
          +
          +
          + +
          +
          +
          + +

          Das 
          + Antragsjournal +
          +
          +
          +

          +
          +

          + An dieser Stelle findest Du alle @(itemsCount) + Bürgeranträge, die auf OpenAntrag bislang in die + @(lst.Count) teilnehmenden Parlamente (Fraktionen) + eingestellt wurden, in voller Länge und sortiert nach Eingang.

          +
          +
          +
          + +@Code + Dim bolShaded As Boolean = True + + If Model IsNot Nothing Then + + Dim pager As PagerModel = Nothing + If itemsCount > 0 Then + + pager = New PagerModel(pageNo, itemsCount, String.Concat("/journal/@Page")) + + For Each prop In Model + prop.FillProcessSteps() + Html.RenderPartialWithData("_ProposalBlockPartial", prop, New With {.Shaded = bolShaded, + .ShowRepresentation = True}) + bolShaded = Not bolShaded + Next + End If + + @
          +
          + @Html.Pager(pager) +
          +
          + + End If +End Code diff --git a/OpenAntrag/Views/Home/List.vbhtml b/OpenAntrag/Views/Home/List.vbhtml new file mode 100644 index 0000000..f6dcb30 --- /dev/null +++ b/OpenAntrag/Views/Home/List.vbhtml @@ -0,0 +1,78 @@ +@Imports OpenAntrag +@ModelType List(Of Proposal) + +@Code + ViewData("Title") = "Antragsjournal" + + Dim itemsShown As Integer = CType(ViewData("ItemsShown"), Integer) + Dim itemsCount As Integer = CType(ViewData("ItemsCount"), Integer) + + 'Dim rps As New Representations(Representations.StatusConjuction.Active) + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And Representations.StatusConjuction.Active) > 0) _ + .ToList() + +End Code + +@Section Styles + @Styles.Render("~/css/list") +End Section + +@Section Scripts + +End Section + +@Section Intro +

          Jeder Bürgerantrag ist ein Zeichen dass Demokratie funktioniert, + sofern man denn will und jeder mitwirken kann der möchte.

          +End Section + +
          +
          + +
          +

          + Es ist nicht leicht etwas zu verändern, aber es geht!
          + Schau Dir unsere Erfolgsgeschichten an... +

          +
          +
          +
          + +
          +
          +
          + +

          Die 
          + Antragsliste

          +
          +
          +

          + In dieser Liste findest Du die letzten + @(SettingsWrapper.ProposalListCount) + von @(itemsCount) Bürgeranträgen, die auf OpenAntrag in die + @(lst.Count) teilnehmenden Parlamente (Fraktionen) + eingestellt wurden, als sortierbare Liste. +

          +
          +
          +
          + +
          +
          + @Html.Partial("_ProposalListTablePartial", Model, New ViewDataDictionary() From {{"ShowRepresentation", True}}) +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Home/Overview.vbhtml b/OpenAntrag/Views/Home/Overview.vbhtml new file mode 100644 index 0000000..18162f7 --- /dev/null +++ b/OpenAntrag/Views/Home/Overview.vbhtml @@ -0,0 +1,62 @@ +@Imports OpenAntrag +@ModelType List(Of Representation) + +@Code + ViewData("Title") = "Übersicht" +End Code + +@Section Styles + @Styles.Render("~/css/api") +End Section + +@Section Intro +

          Mit jedem in OpenAntrag vertretenen Parlament bringen wir Piraten die Bürger ein Stück naher heran an die Politik

          +End Section + +
          +
          +
          +

          Parlamente/Fraktionen

          + + + + + + + + + + + + + @For Each rp As Representation In Model + Representations.EnsureRepresentationClone(rp) + @ + + + + + + + + Next + +
          IDParlamentLandFraktionMailTelefon
          @(rp.ID)@(rp.Name2)@(rp.Federal.Name)@(rp.GroupName)@(rp.Mail)@(rp.Phone)
          +
          +
          +
          + +@If HttpContext.Current.User.Identity.IsAuthenticated = True Then +@
          +
          +
          +

          Mail-Liste

          +

          + @For Each rp As Representation In Model + @(rp.InfoMail & "; ") + Next +

          +
          +
          +
          +End If diff --git a/OpenAntrag/Views/Home/Search.vbhtml b/OpenAntrag/Views/Home/Search.vbhtml new file mode 100644 index 0000000..dcef96e --- /dev/null +++ b/OpenAntrag/Views/Home/Search.vbhtml @@ -0,0 +1,93 @@ +@Imports OpenAntrag +@ModelType SearchModel + +@Code + ViewData("Title") = "Suche" + + Dim pageNo As Integer = 0 + If ViewData("PageNo") IsNot Nothing Then + pageNo = CType(ViewData("PageNo"), Integer) + End If + +End Code + +@Section Styles + @Styles.Render("~/css/search") +End Section + +@Section Scripts + l +End Section + +@Section Intro +

          Jede Idee ist wertvoll, wenn man denn von ihr hört oder liest.
          + Wer suchet, der findet.

          +End Section + +
          +
          +
          + +

          Die
          + Suche

          +
          +
          +
          +
          +
          +

          Täglich das Rad neu zu erfinden ist verschwendete Zeit. + Vielleicht hat schon jemand anderes eine Idee gehabt, + die man übernehmen kann. Hier kannst Du mit freigewählten + Begriffen danach suchen. Gesucht wird im Titel und im Text des Antrags

          + + @Using Html.BeginForm("Search", "Home", FormMethod.Post, New With {.id = "search-form", .name = "search-form"}) + + @
          + @Html.TextBoxFor(Function(m) m.SearchTerms, New With {.placeholder = "Suchbegriffe"}) + @Html.ValidationMessageFor(Function(m) m.SearchTerms) +
          + + @
          + +
          + End Using +
          +
          +
          + +@Code + If Model IsNot Nothing Then + Dim strResultString As String + Select Case Model.Results.Count + Case 0 : strResultString = "keine Ergebnisse" + Case 1 : strResultString = "1 Ergebnis" + Case Else : strResultString = String.Concat(Model.Results.Count, " Ergebnisse") + End Select + + @
          +
          +
          + +

          Suche:
          @(strResultString)

          +
          +
          +
          + + Dim bolShaded As Boolean = False + + For Each prop In Model.Results + prop.FillProcessSteps() + Html.RenderPartialWithData("_ProposalBlockPartial", prop, New With {.Shaded = bolShaded, + .ShowRepresentation = True}) + bolShaded = Not bolShaded + Next + + End If +End Code diff --git a/OpenAntrag/Views/Home/Success.vbhtml b/OpenAntrag/Views/Home/Success.vbhtml new file mode 100644 index 0000000..ac63fd0 --- /dev/null +++ b/OpenAntrag/Views/Home/Success.vbhtml @@ -0,0 +1,90 @@ +@Imports OpenAntrag +@ModelType List(Of SuccessStory) + + +@Code + ViewData("Title") = "Erfolgsgeschichten" + + Dim pageNo As Integer = 0 + If ViewData("PageNo") IsNot Nothing Then + pageNo = CType(ViewData("PageNo"), Integer) + End If + + Dim itemsCount As Integer = 0 + If ViewData("ItemsCount") IsNot Nothing Then + itemsCount = CType(ViewData("ItemsCount"), Integer) + End If + +End code + +@Section Styles + @Styles.Render("~/css/success") +End Section + +@Section Scripts + +End Section + +@Section Intro +

          + Etwas zu verändern ist nicht leicht, aber es geht, wie unsere erfolgreichen Bürgeranträge beweisen. +

          +End Section + +
          +
          +
          + +

          Die 
          + Erfolgs
          + geschichten +
          +
          +

          +
          +

          + Diese Seite dient dazu die erfolgreiche Arbeit der an OpenAntrag teilnehmenden + Fraktionen/Einzelabgeordneten sichtbar zu machen. Wurde ein Bürgerantrag im + Parlament positiv abgestimmt, kann die Fraktion diesen im Anschluss hier einstellen, + um den Erfolg zu dokumentieren. +

          +

          Im folgenden findest Du diese @(itemsCount) Erfolgsgeschichten.

          + @If itemsCount < 10 Then + @

          + Hinweis: + Diese Seite ist erst seit Kurzem in OpenAntrag verfügbar. + Die Fraktionen arbeiten daran schnellstmöglich die in den vergangenen Monaten erfolgreich + abgeschlossenen Anträge hier einzustellen. +

          + End If +
          +
          +
          + +@Code + Dim bolShaded As Boolean = True + + If Model IsNot Nothing Then + + Dim pager As PagerModel = Nothing + If itemsCount > 0 Then + + pager = New PagerModel(pageNo, itemsCount, String.Concat("/erfolge/@Page")) + + For Each suc As SuccessStory In Model + Html.RenderPartialWithData("_SuccessStoryBlockPartial", suc, New With {.Shaded = bolShaded}) + bolShaded = Not bolShaded + Next + End If + + @
          +
          + @Html.Pager(pager) +
          +
          + + End If +End Code diff --git a/OpenAntrag/Views/Home/Tags.vbhtml b/OpenAntrag/Views/Home/Tags.vbhtml new file mode 100644 index 0000000..5fd547c --- /dev/null +++ b/OpenAntrag/Views/Home/Tags.vbhtml @@ -0,0 +1,88 @@ +@Imports OpenAntrag +@ModelType ProposalTag + +@Code + ViewData("Title") = "Themen" + + Dim pageNo As Integer = 0 + If ViewData("PageNo") IsNot Nothing Then + pageNo = CType(ViewData("PageNo"), Integer) + End If + +End Code + +@Section Styles + @Styles.Render("~/css/tags") +End Section + +@Section Scripts + +End Section + +@Section Intro +

          Piraten stehen für Themen, für eine Politik in der Sache, über Grenzen hinweg.

          +End Section + +
          +
          +
          + +

          Die 
          + Themen

          +
          +

          Die Bürgeranträge werden von den Fraktionen mit Themenschlagworten versehen. + Nach diesen kannst Du hier fraktionsübergreifend filtern.

          + @If Model Is Nothing Then + @

          Bitte wähle ein Thema...

          + End If +
          +
          +
          +
          +
          +
          + +@Code + If Model IsNot Nothing Then + + @
          +
          +
          + +

          Thema:
          @Model.Tag

          +
          +
          +
          + + Dim bolShaded As Boolean = False + Dim pager As PagerModel = Nothing + Dim lst As List(Of Proposal) = Proposals.GetItemsByTag(Model) + If lst IsNot Nothing AndAlso lst.Count > 0 Then + + pager = New PagerModel(pageNo, lst.Count, String.Concat("/tags/", HttpUtility.UrlEncode(Model.Tag), "/@Page")) + lst.GetPageData(pageNo) + + For Each prop In lst + prop.FillProcessSteps() + Html.RenderPartialWithData("_ProposalBlockPartial", prop, New With {.Shaded = bolShaded, + .ShowRepresentation = True}) + bolShaded = Not bolShaded + Next + End If + + @
          +
          + @Html.Pager(pager) +
          +
          + + End If +End Code \ No newline at end of file diff --git a/OpenAntrag/Views/Home/_RepresentationBox.vbhtml b/OpenAntrag/Views/Home/_RepresentationBox.vbhtml new file mode 100644 index 0000000..615c124 --- /dev/null +++ b/OpenAntrag/Views/Home/_RepresentationBox.vbhtml @@ -0,0 +1,19 @@ +@Imports OpenAntrag +@ModelType Representation + +
          + +
          + @Model.Federal.Name + +

          @Model.[Name]

          +
          + @Model.GroupName + @If String.IsNullOrEmpty(Model.Link) = False Then + @@Model.Link + End If + @If String.IsNullOrEmpty(Model.LogoImage) = False Then + @ + End If +
          +
          diff --git a/OpenAntrag/Views/Home/_WorkflowSchemaPartial.vbhtml b/OpenAntrag/Views/Home/_WorkflowSchemaPartial.vbhtml new file mode 100644 index 0000000..6a58eba --- /dev/null +++ b/OpenAntrag/Views/Home/_WorkflowSchemaPartial.vbhtml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          Eingang des AntragsPrüfung des Antragskeine Übernahme
          Fraktions-sitzung
          Übernahme durch Fraktions-mitglied
          AusschussParlamentAnfrage
          Antrag erledigt
          \ No newline at end of file diff --git a/OpenAntrag/Views/Mail/NewProposalAbuseNoticeEmail.txt.vbhtml b/OpenAntrag/Views/Mail/NewProposalAbuseNoticeEmail.txt.vbhtml new file mode 100644 index 0000000..5301925 --- /dev/null +++ b/OpenAntrag/Views/Mail/NewProposalAbuseNoticeEmail.txt.vbhtml @@ -0,0 +1,21 @@ +@Imports OpenAntrag +@Imports ActionMailer.Net +@ModelType ProposalAbuseNotice + +@Code + Layout = Nothing +End Code + +Ahoi, + +folgender Antrag wurde von einem Website-Benutzer als Missbrauch gemeldet: + +Titel: @Html.Raw(Model.Proposal.Title) + +Url: @Model.Proposal.FullUrl + +Bitte prüfe den Antrag umgehend und schalte den Antrag stumm, sofern sich die Meldung bestätigt! + +Begründung: +----------- +@Html.Raw(Model.Notice) \ No newline at end of file diff --git a/OpenAntrag/Views/Mail/NewProposalCommentEmail.txt.vbhtml b/OpenAntrag/Views/Mail/NewProposalCommentEmail.txt.vbhtml new file mode 100644 index 0000000..131932b --- /dev/null +++ b/OpenAntrag/Views/Mail/NewProposalCommentEmail.txt.vbhtml @@ -0,0 +1,16 @@ +@Imports OpenAntrag +@Imports ActionMailer.Net + +@ModelType ProposalComment + +@Code + Layout = Nothing +End Code + +Ahoi, + +@Html.Raw(ViewData("Subject")): + +@Html.Raw(Model.CommentedBy) um @Model.CommentedAtFormat + +@Html.Raw(Model.CommentText) \ No newline at end of file diff --git a/OpenAntrag/Views/Mail/NewProposalEmail.txt.vbhtml b/OpenAntrag/Views/Mail/NewProposalEmail.txt.vbhtml new file mode 100644 index 0000000..21b70ca --- /dev/null +++ b/OpenAntrag/Views/Mail/NewProposalEmail.txt.vbhtml @@ -0,0 +1,25 @@ +@Imports OpenAntrag +@Imports ActionMailer.Net + +@ModelType Proposal + +@Code + Layout = Nothing +End Code + +Ahoi, + +es ist ein neuer OpenAntrag eingegangen, der Deine Aufmerksamkeit benötigt: + +Titel: @Html.Raw(Model.Title) + +Url: @Model.FullUrl + +Text: +------------------------------------------------------- +@Html.Raw(Model.TextRaw) +------------------------------------------------------- + +@If String.IsNullOrEmpty(Model.ContactInfo) = False Then + @Model.ContactInfo +End If \ No newline at end of file diff --git a/OpenAntrag/Views/Mail/ResetPasswordEmail.txt.vbhtml b/OpenAntrag/Views/Mail/ResetPasswordEmail.txt.vbhtml new file mode 100644 index 0000000..d08da43 --- /dev/null +++ b/OpenAntrag/Views/Mail/ResetPasswordEmail.txt.vbhtml @@ -0,0 +1,16 @@ +@Imports OpenAntrag +@Imports ActionMailer.Net + +@ModelType ResetPasswordModel + +@Code + Layout = Nothing +End Code + +Ahoi, + +Du hast ein neues Passwort für Dein Konto '@Model.UserNameReset' angefordert. Hier ist es: + + @Model.NewPassword + +Du kannst Dich mit diesem nun wieder bei OpenAntrag anmelden. \ No newline at end of file diff --git a/OpenAntrag/Views/Notifications/Index.vbhtml b/OpenAntrag/Views/Notifications/Index.vbhtml new file mode 100644 index 0000000..4fa823c --- /dev/null +++ b/OpenAntrag/Views/Notifications/Index.vbhtml @@ -0,0 +1,98 @@ +@Imports OpenAntrag +@ModelType List(Of Notification) + +@Code + ViewData("Title") = "Mitteilungen" + + Dim strType As String = "" + If ViewData("Type") IsNot Nothing Then + strType = ViewData("Type") + End If + + Dim intTypeId As Integer = -1 + If ViewData("TypeId") IsNot Nothing Then + intTypeId = ViewData("TypeId") + End If + + Dim stbFeedUrl As New StringBuilder("/mitteilungen/feed") + Dim strFeedType As String = "Alle" + If intTypeId > -1 Then + stbFeedUrl.Append("/").Append(strType) + strFeedType = Notifications.GetTypeStringPlural(intTypeId) + End If +End Code + +@Section Styles + @Styles.Render("~/css/notifications") +End Section + +@Section Scripts + @Scripts.Render("~/bundle/notifications") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro +

          + Was passiert hier eigentlich? Was ist wo los?
          + Hier findest Du eine Chronologie der Aktivitäten... +

          +End Section + +
          +
          +
          + +

          Die
          + Mitteilungen

          +
          +
          +

          Abonniere den Mitteilungs-Feed (@(strFeedType)), + um auf dem Laufenden zu bleiben.

          +
          +
          +
          +

          In OpenAntrag gibt es viele verschiedene Aktivtäten, die meist eine Mail an + die betreffende Fraktion, einen Tweet auf Twitter oder Ähnliches nach sich ziehen, + um zu informieren. +

          +

          Alle diese Nachrichten und noch ein paar mehr findest Du hier in chronologischer + Reihenfolge und filterbar über folgende Kategorien:

          + + + + +
          +
          +
          + +
          +
          +
          +
            + @Html.Partial("_NotificationPartial", Model) +
          +
          +
          +
          + +
          +
          +
          + Mehr... + +
          +
          +
          diff --git a/OpenAntrag/Views/Notifications/_NotificationPartial.vbhtml b/OpenAntrag/Views/Notifications/_NotificationPartial.vbhtml new file mode 100644 index 0000000..c8a5e80 --- /dev/null +++ b/OpenAntrag/Views/Notifications/_NotificationPartial.vbhtml @@ -0,0 +1,32 @@ +@Imports OpenAntrag +@ModelType List(Of Notification) + +@Code + Dim strUpperText As String + Dim strText As String + Dim intDoubleQuote As Integer + + For Each nf As Notification In Model + intDoubleQuote = InStr(nf.Text, ": ") + If intDoubleQuote > 0 Then + strUpperText = Left(nf.Text, intDoubleQuote - 1) + strText = Mid(nf.Text, intDoubleQuote + 1, nf.Text.Length - intDoubleQuote) + Else + strUpperText = Nothing + strText = nf.Text + End If + @
        • + @(nf.NotificationTypeString) + + @If String.IsNullOrEmpty(nf.Url) = True Then + @

          @(nf.Title)

          + Else + @

          @(nf.Title)

          + End If + @If String.IsNullOrEmpty(strUpperText) = False Then + @@(strUpperText) + End If +

          @(strText)

          +
        • + Next +End Code diff --git a/OpenAntrag/Views/Representation/Add.vbhtml b/OpenAntrag/Views/Representation/Add.vbhtml new file mode 100644 index 0000000..0adee9e --- /dev/null +++ b/OpenAntrag/Views/Representation/Add.vbhtml @@ -0,0 +1,132 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name & " | Dein Antrag" +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +
          +
          +
          + +

          Dein 
          Antrag

          +

          +

          Du hast etwas was Du gerne in diesem Parlament behandelt sehen möchtest? + Hier hast Du @IIf(Model.IsActive = False Or Model.IsViewOnly = True, Html.Raw("bald"), "") die Gelegenheit dazu... +

          +
          +
          + @Using Html.BeginForm("CreateProposal", "Proposal", FormMethod.Post, New With {.id = "newproposal-form", .name = "newproposal-form"}) + @Html.Partial("_NewProposalPartial", New Proposal(Model)) + End Using +
          +
          +
          + +
          +
          +
          +
          +
          +

          + Trag ins erste Feld einen + aussagekräftigen Titel ein und beschreib im zweiten Feld deine Idee. + Dabei musst du keinen perfekt ausformulierten Antragstext haben, wir + werden ihn an die Regeln des Parlaments anpassen, wenn uns die Idee + überzeugt.

          +

          Abschließend musst du nur noch auf Antrag senden klicken.

          +
          +
          +

          Die Regeln

          +
            +
          1. Jeder Antrag wird geprüft. Wir behalten uns jedoch vor, nur solche Anträge weiterzuverfolgen, die unserem politischen Selbstverständnis entsprechen.
          2. +
          3. Anträge werden grundsätzlich anonym behandelt, um die persönliche/ideologische Ebene außen vor zu lassen.
          4. +
          5. Die Bearbeitung der Anträge erfolgt transparent auf dieser Seite. Eine Benachrichtigung des Antragsstellers erfolgt nicht.
          6. +
          7. Alle Anträge sind öffentlich und können auch öffentlich kommentiert werden.
          8. +
          +
          +
          + + @If Tools.IsAdmin() = True Then + @
          +
          +

          Hinweis für Fraktionen/Abgeordnete

          +

          + Der Antragsprozess ist JEDERZEIT anpassbar! Dies gilt sowohl für die + Schritte selbst, als auch für die damit verknüpften Folgeschritte. +

          +

          + Soll z.B. ein Schritt entfernt werden, genügt es, ihn als Folgeschritt + aus allen verknüpften Schritten herauszunehmen und er wird in der Übersicht + nicht mehr ausgegeben. +

          +

          + Aktuell können Änderungen noch nicht online vorgenommen werden, + aber das ist geplant. Bis dahin schicke Deine Änderungen oder am Besten + den gesamten neuen Prozess via Mail an + webmaster@openantrag.de.

          +
          +
          + End If + +
          + +
          + +

          Der Antragsprozess in @Model.Label

          +
            + @For Each ps As ProcessStep In Model.ProcessSteps + If ps.IsInactive = False Then + @
          • + + @ps.ShortCaption + + @If ps.NextSteps IsNot Nothing AndAlso ps.NextSteps.Count > 0 Then + @
              + @For Each ns As ProcessStep In ps.NextSteps + @
            • + + @ns.ShortCaption +
            • + Next +
            + End If +
          • + + End If + Next +
          +
          +
          +
          + +@Section PreFooter + @Html.PartialOrNull("_BannerTeaserPartial", Model) +End Section \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/Banner.vbhtml b/OpenAntrag/Views/Representation/Banner.vbhtml new file mode 100644 index 0000000..854b380 --- /dev/null +++ b/OpenAntrag/Views/Representation/Banner.vbhtml @@ -0,0 +1,122 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name & " | Banner" +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +
          +
          +
          + +

          Die
          + Banner

          +
          +
          +
          +

          OpenAntrag lebt von den Anträgen der Bürger, die natürlich erstmal + wissen müssen, dass es die Seite überhaupt gibt. Da hilft nur + Werbung, Werbung, Werbung. Hier ein paar Banner für Web-Seiten...

          +

          Bitte kopiere Dir die Grafiken und setze keine Hotlinks, + denn die kosten Bandbreite, die wir besser für Anträge nutzen sollten.

          +
          +
          +
          + +
          +
          +
          + individuell +

          160 x 220 Pixel, statisch

          +
          + + + @If HttpContext.Current.User.IsInRole("admin") Then + @
          +
          + + OpenAntrag +
          +
          + +
          +
          Bürgeranträge
          +
          Dein Anliegen : Unser Antrag
          +
          +
          +
          + @(Model.Name) +
          +
          +
          + End If +
          +
          +
          + +
          +
          +
          + individuell +

          275 x 80 Pixel, statisch

          +
          + + + @If HttpContext.Current.User.IsInRole("admin") Then + @
          +
          + +
          OpenAntrag
          + +
          +
          + @(Model.Name) +
          +
          + End If + +
          +
          +
          + +
          +
          +
          + generisch +

          160 x 220 Pixel, statisch

          +
          + +
          +
          +
          + +
          +
          +
          + generisch +

          275 x 80 Pixel, statisch

          +
          + +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/Index.vbhtml b/OpenAntrag/Views/Representation/Index.vbhtml new file mode 100644 index 0000000..3918613 --- /dev/null +++ b/OpenAntrag/Views/Representation/Index.vbhtml @@ -0,0 +1,172 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name +End Code + +@Section Links + +End Section + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro + + + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +
          +
          +
          +
          + + +
          +
          + @If (Model.Status And Representations.StatusConjuction.Ended) = 0 Then + @
          +

          + Du hast eine Idee für @(Model.LabelWithArticle)?
          + Schreib jetzt Deinen Antrag! +

          +
          + End If +
          +
          + +
          +
          +
          +
          + +
          +
          +
          +

          @Model.GroupName

          +
          + @If String.IsNullOrEmpty(Model.Link) = False Then + @

          +   + @Model.Link +

          + End If + @If String.IsNullOrEmpty(Model.Mail) = False Then + @

          +   + @Model.Mail +

          + End If + @If String.IsNullOrEmpty(Model.Phone) = False Then + @

          +    + @Model.Phone +

          + End If + @If String.IsNullOrEmpty(Model.Twitter) = False Then + @

          +   + @@@Model.Twitter +

          + End If +
          +
          + @Html.Raw(Model.FraktionInfoHtml) +
          +
          +
          +
          + + @If (Model.Status And Representations.StatusConjuction.Ended) = 0 Then + @
          +
          + @If Model.piratenmandate Is Nothing Then + @
          + @For i As Integer = 0 To Model.Representatives.Count - 1 Step 2 + @Html.Partial("_RepresentativePartial", Model.Representatives(i)) + Next +
          + @
          + @For i As Integer = 1 To Model.Representatives.Count - 1 Step 2 + @Html.Partial("_RepresentativePartial", Model.Representatives(i)) + Next +
          + Else + @
          + @For Each r As Representative In Model.Representatives + @Html.Partial("_RepresentativePartial", r) + Next +
          + End If +
          +
          + End If + +
          + + +
          + + @If Model.piratenmandate IsNot Nothing Then + @Html.PartialOrNull("_PiratenmandatePartial", Model.piratenmandate) + End If + +
          +
          + +@Section PreFooter + @Html.PartialOrNull("_BannerTeaserPartial", Model) +End Section \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/Journal.vbhtml b/OpenAntrag/Views/Representation/Journal.vbhtml new file mode 100644 index 0000000..7b7bcc6 --- /dev/null +++ b/OpenAntrag/Views/Representation/Journal.vbhtml @@ -0,0 +1,114 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name & " | Journal" + + Dim pageNo As Integer = 0 + If ViewData("PageNo") IsNot Nothing Then + pageNo = CType(ViewData("PageNo"), Integer) + End If +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +@Code + Dim bolShaded As Boolean = True + Dim intCount As Integer = Proposals.GetItemsCountByRepresentation(Model) + Dim lst As List(Of Proposal) = Proposals.GetItemsPageByRepresentation(Model, pageNo, SettingsWrapper.DefaultPagerListPageSize) + Dim pager As PagerModel = New PagerModel(pageNo, intCount, String.Concat("/", Model.Key, "/journal/@Page")) +End Code + +
          +
          + + @If (Model.Status And Representations.StatusConjuction.Ended) = 0 Then + @
          +

          + Du hast eine Idee für @(Model.LabelWithArticle)?
          + Schreib jetzt Deinen Antrag! +

          +
          + End If +
          +
          + +
          +
          +
          + +

          Das 
          + Antragsjournal + @If pager.MaxPages > 1 Then + @_@pageNo + End If +

          +
          +
          +

          + Nachfolgend findest Du alle @(intCount) eingangenen + Bürgeranträge für @(Model.LabelWithArticle) + in voller Länge und sortiert nach Eingang. +

          +
          +
          +
          + +@Code + If lst IsNot Nothing AndAlso intCount > 0 Then + + 'lst.GetPageData(pageNo) + + For Each prop In lst + prop.FillProcessSteps() + Html.RenderPartialWithData("_ProposalBlockPartial", prop, New With {.Shaded = bolShaded, + .ShowRepresentation = False}) + bolShaded = Not bolShaded + Next + Else + @
          +
          +
          +

          Es wurden bislang noch keine Anträge eingestellt. Sei der Erste...!

          +
          +
          +
          + End If +End Code + +@If pager.MaxPages > 1 Then + @
          +
          + @Html.Pager(pager) +
          +
          +End If + +@Section PreFooter + @Html.PartialOrNull("_BannerTeaserPartial", Model) +End Section \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/List.vbhtml b/OpenAntrag/Views/Representation/List.vbhtml new file mode 100644 index 0000000..bf8416c --- /dev/null +++ b/OpenAntrag/Views/Representation/List.vbhtml @@ -0,0 +1,93 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name & " | Liste" +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +@Code + Dim lst As List(Of Proposal) = Proposals.GetByRepresentation(Model) + 'Dim lst As List(Of Proposal) = Proposals.GetItemsPageByRepresentation(Model, 1, SettingsWrapper.DefaultPagerListPageSize) +End Code + +
          +
          + + @If (Model.Status And Representations.StatusConjuction.Ended) = 0 Then + @
          +

          + Du hast eine Idee für @(Model.LabelWithArticle)?
          + Schreib jetzt Deinen Antrag! +

          +
          + End If +
          +
          + +
          +
          +
          + +

          Die 
          + Antragsliste

          +
          +
          +

          + Nachfolgend findest Du alle @(lst.Count) eingangenen + Bürgeranträge für @(Model.LabelWithArticle) + als sortierbare Liste. +

          +
          +
          +
          + +
          +
          + @If lst IsNot Nothing AndAlso lst.Count > 0 Then + @Html.Partial("_ProposalListTablePartial", lst, New ViewDataDictionary() From {{"ShowRepresentation", False}}) + Else + @
          +

          Es wurden bislang noch keine Anträge eingestellt. Sei der Erste...!

          +
          + End If +
          +
          + +@Section PreFooter + @Html.PartialOrNull("_BannerTeaserPartial", Model) +End Section \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/Proposal.vbhtml b/OpenAntrag/Views/Representation/Proposal.vbhtml new file mode 100644 index 0000000..d42bf0d --- /dev/null +++ b/OpenAntrag/Views/Representation/Proposal.vbhtml @@ -0,0 +1,359 @@ +@Imports OpenAntrag +@ModelType Proposal + +@Code + ViewData("Title") = Model.Representation.Name & " | " & Model.Title +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/proposal-", Model.Representation.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model.Representation) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model.Representation) +End Section + +@* --- Abuse-Message --- *@ +@If Model.IsAbuse = True Then + @
          +
          + Dieser Antrag wurde wegen Missbrauchs stumm geschaltet +
          @Html.Raw(Model.AbuseMessageHtml)
          +
          +
          +End If + +@* --- Success-Story-Message --- *@ +@If Model.CurrentProposalStep.ProcessStep.SuccessStory = True AndAlso Model.SuccessStoryStatus = 0 AndAlso Tools.IsAdmin(Model.Representation.Key) = True Then + @
          +
          + Der Prozessschritt dieses Antrags erlaubt die Anlage einer 'Success-Story' (Erfolgsgeschichte), + die unter Erfolge aufgelistet wird.
          + Jetzt Erfolgsgeschichte anlegen, wenn der Antrag denn erfolgreich war ;) +
          +
          +End If + +@* --- Antrag --- *@ +
          +
          +
          + +@* @If Model.HasSuccessStory = True Then + @ + End If*@ + + + +
          + @If Tools.IsAdmin(Model.Representation.Key) = False Then + @ + @Model.CreatedAtFormat + + @Model.CurrentProposalStep.CreatedAtFormat + + @
          + @ + + @Proposals.GetProcessStepCaption(Model.CurrentProposalStep.ProcessStep.Caption, Model, Model.Representation) + + Else + @
          + + +
          + @ + @If Model.IsAbuse = False Then + @ + Else + @ + End If + End If +

          @Model.Title

          +
          + + @If Tools.IsCreatedByAdmin(Model.Representation.Key, Model.CreatedBy) = True OrElse (Model.IsAbuse = True And Tools.IsAdmin(Model.Representation.Key) = True) Then + @
          + @Html.TextAreaFor(Function(m) m.TextMarkdown, 5, 0, New With {.placeholder = "Dein Antragstext"}) +
          + @
          + +
          + Else + If Model.IsAbuse = False Then + @
          @Html.Raw(Model.TextHtml)
          + @Html.Partial("_ProposalSublinksPartial", Model) + End If + End If + +
          +
          + @Html.Partial("_ProposalTagListPartial", Model) +
          +
          +
          + +@* --- Antrag stummschalten [EDIT] --- *@ +@If Model.IsAbuse = False AndAlso Tools.IsAdmin(Model.Representation.Key) = True Then + @ +End If + +@Code + Dim bolShaded As Boolean = True +End Code + +@* --- Schrittliste --- *@ +@For Each ps As ProposalStep In Model.ProposalStepList + @
          +
          +
          +   +
          + + @If Tools.IsAdmin(Model.Representation.Key) = False Then + @@ps.CreatedAtFormat + Else + @
          + + +
          + + @If ps.Id > 1 Then + @ + End If + + @If ps Is Model.ProposalStepList.Last And ps.Id > 1 Then + @ + End If + + End If + + @Proposals.GetProcessStepCaption(ps.ProcessStep.Caption, Model, Model.Representation) +
          @Html.Raw(ps.InfoHtml)
          + +
          +
          +
          +
          + bolShaded = Not bolShaded +Next + +@* --- Success-Story --- *@ +@If Model.CurrentProposalStep.ProcessStep.SuccessStory = True AndAlso Model.SuccessStoryStatus = 0 AndAlso Tools.IsAdmin(Model.Representation.Key) = True Then +@ +@ +@ +End If + +@If Model.CurrentProposalStep.ProcessStep.NextSteps IsNot Nothing AndAlso Model.CurrentProposalStep.ProcessStep.NextSteps.Count > 0 Then + + @* --- Nächste Schritte --- *@ + @
          +
          +
          + +

          Die
          + nächsten Schritte

          +
          +

          Einer der folgende Schritte ist nun als nächster Schritt für den Antrag möglich:

          +
          +@Code + Dim intNextColWidth As Integer = Math.Abs(12 / Model.CurrentProposalStep.ProcessStep.NextSteps.Count) + If intNextColWidth > 3 then intNextColWidth = 3 + For Each ps As ProcessStep In Model.CurrentProposalStep.ProcessStep.NextSteps + @If Tools.IsAdmin(Model.Representation.Key) = True Then + @ + @ps.ShortCaption + + Else + @
          + @ps.ShortCaption +
          + End If + Next +End Code +
          +
          +
          +
          + + @If Tools.IsAdmin(Model.Representation.Key) = True Then + + @* --- Nächster Schritt [EDIT] --- *@ + @
          +
          +
          + +

          [Bearbeitung]

          +
          + +

          Nächster Schritt

          +
          +

          Bitte wähle oben den nächsten Schritt aus...

          + + +
          + +
          +
          +
          + + @* --- Themen [EDIT] --- *@ + @
          +
          +
          +

          Zugeordnete Themen

          + +
          +
          +
          + End If + + bolShaded = Not bolShaded +End If + +@* --- Kommentare --- *@ + +
          +
          +
          + +

          Die
          + Kommentare

          +
          + + @If Model.IsCommentingClosed = False Then + @ + + @If Tools.IsAdmin(Model.Representation.Key) = True Then + @ + End if + + @Using Html.BeginForm("CreateProposalComment", "Proposal", FormMethod.Post, New With {.id = "newcomment-form", .name = "newcomment-form", .style = "display:none;"}) + @Html.Partial("_NewProposalCommentPartial", New ProposalComment(Model)) + End Using + Else + @

          Kommentarfunktion wurde geschlossen am @(CType(Model.CommentingClosedDate, DateTime).ToString("dd. MMMM yyyy HH:mm"))

          + @If Tools.IsAdmin(Model.Representation.Key) = True Then + @ + End If + End If + +
          + @For Each pc As ProposalComment In Model.ProposalComments + pc.ID_Proposal = Model.Id + Html.RenderPartial("_ProposalCommentPartial", pc) + Next +
          +
          +
          +
          + +@Section PreFooter + @Html.PartialOrNull("_BannerTeaserPartial", Model.Representation) +End Section \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/Settings.vbhtml b/OpenAntrag/Views/Representation/Settings.vbhtml new file mode 100644 index 0000000..0ae64d9 --- /dev/null +++ b/OpenAntrag/Views/Representation/Settings.vbhtml @@ -0,0 +1,528 @@ +@Imports OpenAntrag +@ModelType Representation + +@Code + ViewData("Title") = Model.Name & " | Einstellungen" +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/representations-", Model.Key)) + +End Section + +@Section Scripts + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model) +End Section + +
          +
          +
          + +

          Die
          + Einstellungen

          +
          +
          +
          +

          + Über die Einstellungen in diesem Bereich kannst Du das Aussehen und + Verhalten Deiner OpenAntrag-Seite steuern. @*Änderungen treten, im + Gegensatz zu den Seitendaten weiter unten, sofort in Kraft.*@ +

          +
          +
          +
          +@Code + Dim rst As RepresentationSetting = RepresentationSettings.GetByKey(Model.Key) +End Code +
          +
          +
          + + + + + + + + + + + + +
          API-Key
          Kontaktmöglichkeit bei neuem Antrag anzeigen? +
          + @If rst.HasContactPossibility = True Then + @ + Else + @ + End If + +
          +
          +
          + +
          +
          +
          + +@Code Return End Code + + +
          +
          +
          + +

          Die
          + Seitendaten

          +
          +
          +
          +

          + Die Informationen in diesem Abschnitt definieren Deine OpenAntrag-Seite. +

          +

          + Du kannst sie nach Deinen Wünschen anpassen, wobei die Änderungen + nicht sofort wirksam werden. Vielmehr kannst Du am Ende des Bereichs + (Punkt 5) die Änderungen als Datenpaket an die Administrations senden. +

          +

          + Bestehende Abgeordnete und Ausschüsse lassen sich + lediglich deaktivieren, + damit sichergestellt ist, + dass Verknüpfungen zu bestehenden Anträgen nicht verloren gehen. +

          +
          +
          +
          + +
          +
          +
          + +

          1. Parlament

          +
          +
          +
          +@Code + +End Code +
          +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          ID | Key + @Model.ID | @Model.Key + + +
          Status + +
          Label
          Name
          Name 2
          Bundesland + +
          Ebene + +
          Farbe + +
          +
          +
          +
          +
          +
          + +
          +
          +
          +

          Ausschüsse

          + @For Each cm In Model.Committees + @ + + + + + + + + + + + + + + + + + + + + +
          ID | Key + @cm.ID | @cm.Key + + +
          Name
          Kurzname
          Link
          Deaktivieren
          + Next + + + + + + + + + + + +
          +
          +
          + +
          +
          +
          + +

          2. Fraktion / Einzelabgeordneter

          +
          +
          +
          +
          +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          Gruppenname
          Gruppentyp + +
          Mail
          Info-Mail
          Website
          Telefon
          Twitter
          Infotext Fraktion (HTML) + +
          Infotext Parlament (HTML) + +
          API-Key + @Model.ApiKey + +
          +
          +
          +
          + +
          +
          +
          + +

          3. Abgeordnete

          +
          +
          +
          +@Code + Dim bolShaded As Boolean = False +End Code +@For Each rp In Model.Representatives + @
          +
          +
          +

          @rp.Name

          + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          ID | Key + @rp.ID | @rp.Key + + +
          Name
          Mail
          Telefon
          Twitter
          Partei
          Deaktivieren
          +
          +
          +
          + bolShaded = Not bolShaded +Next + +
          +
          +
          + +
          +
          +
          + + +
          +
          +
          + +

          4. Antragsprozess

          +
          +
          +
          +
          +
          +
          +

          + Der Antragsprozess ist hier aktuell noch nicht änderbar. + Wenn Du neue Schritte in Deinen Prozess aufnehmen willst, + schreib bitte ein Mail an + webmaster@openantrag.de. +

          +
          +
          +
          +
          +
          +
          + +

          5. Speichern & Senden

          +
          +
          +
          +
          +
          +
          +

          + Die Änderungen an den Seitendaten treten nicht sofort in Kraft, sondern werden + als Datenpaket an die Administration verschickt, wo sie zunächst geprüft und + dann eingestellt werden. +

          +

          + +

          +
          +
          +
          diff --git a/OpenAntrag/Views/Representation/SuccessStory.vbhtml b/OpenAntrag/Views/Representation/SuccessStory.vbhtml new file mode 100644 index 0000000..5d9f63f --- /dev/null +++ b/OpenAntrag/Views/Representation/SuccessStory.vbhtml @@ -0,0 +1,118 @@ +@Imports OpenAntrag +@ModelType SuccessStory + +@Code + ViewData("Title") = "Erfolgsgeschichte " & Model.Proposal.Representation.Name & " | " & Model.Proposal.Title +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/proposal-", Model.Proposal.Representation.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/representations") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro + @Html.PartialOrNull("_RepresentationIntro", Model.Proposal.Representation) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavRepresentation", Model.Proposal.Representation) +End Section + +
          +
          +
          + +
          + @Model.StepDateFormat +

          Die Erfolgsgeschichte des Antrags

          +

          @Model.Title

          +
          +
          @Html.Raw(Model.TextHtml)
          + @Html.Partial("_SuccessStorySublinksPartial", Model) +
          +
          +
          + +@* --- Antrag --- *@ +
          +
          +
          + +
          + @Model.Proposal.CreatedAtFormat +

          Der Antrag

          +
          +
          @Html.Raw(Model.Proposal.TextHtml)
          +
          +
          +
          + +@Code + Dim bolShaded As Boolean = False +End Code + +@* --- Schrittliste --- *@ +@For Each ps As ProposalStep In Model.Proposal.ProposalStepList + @
          +
          +
          +   +
          + + @ps.CreatedAtFormat + @Proposals.GetProcessStepCaption(ps.ProcessStep.Caption, Model.Proposal, Model.Proposal.Representation) +
          @Html.Raw(ps.InfoHtml)
          +
          +
          +
          +
          + bolShaded = Not bolShaded +Next + +@* --- Kommentare --- *@ + +
          +
          +
          + +

          Die
          + Kommentare

          +
          + + @If Model.Proposal.IsCommentingClosed = False Then + @ + + @If Tools.IsAdmin(Model.Proposal.Representation.Key) = True Then + @ + End if + + @Using Html.BeginForm("CreateProposalComment", "Proposal", FormMethod.Post, New With {.id = "newcomment-form", .name = "newcomment-form", .style = "display:none;"}) + @Html.Partial("_NewProposalCommentPartial", New ProposalComment(Model.Proposal)) + End Using + Else + @

          Kommentarfunktion wurde geschlossen am @(CType(Model.Proposal.CommentingClosedDate, DateTime).ToString("dd. MMMM yyyy HH:mm"))

          + @If Tools.IsAdmin(Model.Proposal.Representation.Key) = True Then + @ + End If + End If + +
          + @For Each pc As ProposalComment In Model.Proposal.ProposalComments + pc.ID_Proposal = Model.Id + Html.RenderPartial("_ProposalCommentPartial", pc) + Next +
          +
          +
          +
          diff --git a/OpenAntrag/Views/Representation/_BannerTeaserPartial.vbhtml b/OpenAntrag/Views/Representation/_BannerTeaserPartial.vbhtml new file mode 100644 index 0000000..dc7a7f3 --- /dev/null +++ b/OpenAntrag/Views/Representation/_BannerTeaserPartial.vbhtml @@ -0,0 +1,15 @@ +@Imports OpenAntrag +@ModelType Representation + +@If (Model.Status And Representations.StatusConjuction.Ended) = 0 Then +@ +End If \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/_NavRepresentation.vbhtml b/OpenAntrag/Views/Representation/_NavRepresentation.vbhtml new file mode 100644 index 0000000..5fd997b --- /dev/null +++ b/OpenAntrag/Views/Representation/_NavRepresentation.vbhtml @@ -0,0 +1,48 @@ +@Imports OpenAntrag +@ModelType Representation + + + diff --git a/OpenAntrag/Views/Representation/_NewProposalCommentPartial.vbhtml b/OpenAntrag/Views/Representation/_NewProposalCommentPartial.vbhtml new file mode 100644 index 0000000..d4c0f34 --- /dev/null +++ b/OpenAntrag/Views/Representation/_NewProposalCommentPartial.vbhtml @@ -0,0 +1,16 @@ +@Imports OpenAntrag +@ModelType ProposalComment + +@Html.TextBoxFor(Function(m) m.CommentedBy, New With {.placeholder = "Dein Name"}) +@Html.ValidationMessageFor(Function(m) m.CommentedBy) + +
          + @Html.TextAreaFor(Function(m) m.Comment, 5, 0, New With {.placeholder = "Dein Kommentar"}) + @Html.ValidationMessageFor(Function(m) m.Comment) +
          + + + +
          + +
          diff --git a/OpenAntrag/Views/Representation/_NewProposalPartial.vbhtml b/OpenAntrag/Views/Representation/_NewProposalPartial.vbhtml new file mode 100644 index 0000000..0aae0f2 --- /dev/null +++ b/OpenAntrag/Views/Representation/_NewProposalPartial.vbhtml @@ -0,0 +1,44 @@ +@Imports OpenAntrag +@ModelType Proposal + +@Code + Dim rep As Representation = Model.Representation + Dim rps As RepresentationSetting = RepresentationSettings.GetByKey(rep.Key) +End Code + +@If rep.IsViewOnly = False And rep.IsActive = True Then + @Html.TextBoxFor(Function(m) m.Title, New With {.placeholder = "Titel Deines Antrags"}) + @Html.ValidationMessageFor(Function(m) m.Title) + + @
          + @Html.TextAreaFor(Function(m) m.Text, 5, 0, New With {.placeholder = "Dein Antragstext"}) + @Html.ValidationMessageFor(Function(m) m.Text) +
          +Else + @

          Diese Antragsseite befindet sich noch im Aufbau und wird, sobald alle notwendigen + Informationen zusammengetragen sind und die Fraktion bzw. der Abgeordnete grünes Licht + gibt, aktiviert. +
          Stay tuned... +

          +

          +End If + + + +
          + @If rps.HasContactPossibility = True Then + @ + Wenn Du möchtest, daß die Fraktion mit Dir Kontakt aufnehmen kann, kannst Du + + hier die von Dir gewünschten Kontaktinformationen eingeben. + Diese werden nicht gespeichert, sondern lediglich via Mail an die Fraktion übermittelt! + + @ + @ + End If + + @If rep.IsViewOnly = False And rep.IsActive = True Then + @ + End If +
          diff --git a/OpenAntrag/Views/Representation/_NewSuccessStoryPartial.vbhtml b/OpenAntrag/Views/Representation/_NewSuccessStoryPartial.vbhtml new file mode 100644 index 0000000..3e2c82b --- /dev/null +++ b/OpenAntrag/Views/Representation/_NewSuccessStoryPartial.vbhtml @@ -0,0 +1,15 @@ +@Imports OpenAntrag +@ModelType SuccessStory + + + + + +

          Schreib einen kurzen Text, in dem Du den Antrag und seinen Werdegang kurz vorstellst:

          + +
          + @Html.TextAreaFor(Function(m) m.Text, 5, 0, New With {.placeholder = "Infotext zum erfolgreichen Antrag"}) + @Html.ValidationMessageFor(Function(m) m.Text) +
          + + \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/_NextStepPartial.vbhtml b/OpenAntrag/Views/Representation/_NextStepPartial.vbhtml new file mode 100644 index 0000000..b4b0c3d --- /dev/null +++ b/OpenAntrag/Views/Representation/_NextStepPartial.vbhtml @@ -0,0 +1,13 @@ +@Imports OpenAntrag +@ModelType ProcessStep + + +@Now.ToString("dd. MMMM yyyy HH:mm") +@Html.Raw(Model.GetCaptionHtml) +
          +
          + +
          + diff --git a/OpenAntrag/Views/Representation/_PiratenmandatePartial.vbhtml b/OpenAntrag/Views/Representation/_PiratenmandatePartial.vbhtml new file mode 100644 index 0000000..09976b6 --- /dev/null +++ b/OpenAntrag/Views/Representation/_PiratenmandatePartial.vbhtml @@ -0,0 +1,33 @@ +@ModelType OpenAntrag.piratenmandate.Item + +
          + + +
          + @Model.GebietName + @If String.IsNullOrEmpty(Model.ParlamentSeats) = False Then + @

          @Model.MandateCount von @Model.ParlamentSeats Sitze

          + End If + @If String.IsNullOrEmpty(Model.ParlamentStory) = False Then + @

          + @Model.ParlamentStory + @If String.IsNullOrEmpty(Model.ParlamentStorySource) = False Then + @
          + @Quelle... + End If +

          + End If +

          @Html.Raw(Model.FraktionText)

          + + @If String.IsNullOrEmpty(Model.MapUrl) = False Then + @ + End If +
          +
          diff --git a/OpenAntrag/Views/Representation/_ProposalCommentPartial.vbhtml b/OpenAntrag/Views/Representation/_ProposalCommentPartial.vbhtml new file mode 100644 index 0000000..0f9199c --- /dev/null +++ b/OpenAntrag/Views/Representation/_ProposalCommentPartial.vbhtml @@ -0,0 +1,20 @@ +@Imports OpenAntrag +@ModelType ProposalComment + +
          + @If Tools.IsAdmin = True Then + @
          + +
          + End If +   +
          + @Model.CommentedAtFormat +

          @Model.CommentedBy

          + @Html.Raw(Model.CommentHtml) +
          +
          +
          diff --git a/OpenAntrag/Views/Representation/_RepresentationIntro.vbhtml b/OpenAntrag/Views/Representation/_RepresentationIntro.vbhtml new file mode 100644 index 0000000..81bc360 --- /dev/null +++ b/OpenAntrag/Views/Representation/_RepresentationIntro.vbhtml @@ -0,0 +1,11 @@ +@Imports OpenAntrag +@ModelType Representation + +

          @Model.Name

          + +@If Model.LogoImagePage IsNot Nothing Then + @@Model.GroupName +Else + @

          @Model.GroupName

          +End If + \ No newline at end of file diff --git a/OpenAntrag/Views/Representation/_RepresentativePartial.vbhtml b/OpenAntrag/Views/Representation/_RepresentativePartial.vbhtml new file mode 100644 index 0000000..0cc8241 --- /dev/null +++ b/OpenAntrag/Views/Representation/_RepresentativePartial.vbhtml @@ -0,0 +1,26 @@ +@ModelType OpenAntrag.Representative + +
          + @Model.Key +
          +
          @Model.Name
          + @Model.Party +
          + @If String.IsNullOrEmpty(Model.Mail) = False Then + @ + @Model.Mail + + End If + @If String.IsNullOrEmpty(Model.Phone) = False Then + @ +  @(Model.Phone) + + End If + @If String.IsNullOrEmpty(Model.Twitter) = False Then + @ + @@@(Model.Twitter) + + End If +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/AsciiArtPartial.cshtml b/OpenAntrag/Views/Shared/AsciiArtPartial.cshtml new file mode 100644 index 0000000..495878d --- /dev/null +++ b/OpenAntrag/Views/Shared/AsciiArtPartial.cshtml @@ -0,0 +1,39 @@ + diff --git a/OpenAntrag/Views/Shared/_ErrorBoxPartial.vbhtml b/OpenAntrag/Views/Shared/_ErrorBoxPartial.vbhtml new file mode 100644 index 0000000..0c7285a --- /dev/null +++ b/OpenAntrag/Views/Shared/_ErrorBoxPartial.vbhtml @@ -0,0 +1,13 @@ +@Imports OpenAntrag +@ModelType CustomErrorInfo + +
          + + @Model.ErrorMessage + + @If Model.ReferrerUrl IsNot Nothing Then + @
          + @zurück zur letzten Seite + End If + +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_FederalMap.vbhtml b/OpenAntrag/Views/Shared/_FederalMap.vbhtml new file mode 100644 index 0000000..fe1ddb7 --- /dev/null +++ b/OpenAntrag/Views/Shared/_FederalMap.vbhtml @@ -0,0 +1,31 @@ +@Imports OpenAntrag + +@ModelType FederalStates + +
          + +@Code + 'Dim rps As New Representations(Representations.StatusConjuction.Active) + + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And (Representations.StatusConjuction.Active)) > 0) _ + .ToList() + + For Each m In Model.Items + + Dim query = From rp As Representation In lst + Where rp.FederalKey.ToUpper = m.Key.ToUpper And rp.Status > 0 + Select rp + + Dim stat As String = "active" + If query.Count = 0 Then stat = "inactive" + + @ + @(m.Name) + + + Next +End Code +
           
          +
          diff --git a/OpenAntrag/Views/Shared/_Layout.vbhtml b/OpenAntrag/Views/Shared/_Layout.vbhtml new file mode 100644 index 0000000..4bdecbb --- /dev/null +++ b/OpenAntrag/Views/Shared/_Layout.vbhtml @@ -0,0 +1,291 @@ +@Imports OpenAntrag + + + + + @Html.Partial("AsciiArtPartial") + + OpenAntrag - @ViewData("Title") + + + + + + + + + + + + + + + + + + + + + + + + @RenderSection("links", required:=False) + + @Styles.Render("~/css/plugins") + + + @Styles.Render("~/css/styles-v2") + + @RenderSection("styles", required:=False) + + @Scripts.Render("~/bundle/modernizr") + + + +
          + +
          +
          + @If Tools.IsAdmin Then + @Neue Meldung + End If +
          + +
          +
          + +
          +
          +

          OpenAntrag

          + @*

          DE

          *@ +
          + @Code + Dim lstNF As List(Of Notification) = Notifications.GetItemsPage(-1, 1, 10) + + If lstNF.Count > 0 Then + @ + End If + + @
          + @For Each nf As Notification In lstNF + @ + + @(nf.Title) + + Next +
          + End Code +
          +
          +
          + + + +
          +

          Bürgeranträge
          Dein Anliegen : Unser Antrag

          + @RenderSection("Intro", required:=True) +
          +
          + + + +
          + @RenderBody() +
          + +
          + + @RenderSection("PreFooter", required:=False) + +
          + + + @If HttpContext.Current.User.Identity.IsAuthenticated = False Then + @ + Else + @ + End If +
          + + + + + + @Scripts.Render("~/bundle/jquery") + @Scripts.Render("~/bundle/jqueryval") + @Scripts.Render("~/bundle/plugins-pre") + @Scripts.Render("~/bundle/plugins") + @Scripts.Render("~/bundle/main") + @If Tools.IsAdmin Then + @Scripts.Render("~/bundle/admin") + End If + @RenderSection("scripts", required:=False) + + + + @If TempData("ExceptionAlert") IsNot Nothing Then + Dim exc As CustomException = CType(TempData("ExceptionAlert"), CustomException) + @ + End If + + + diff --git a/OpenAntrag/Views/Shared/_LogonPartial.vbhtml b/OpenAntrag/Views/Shared/_LogonPartial.vbhtml new file mode 100644 index 0000000..41f9d95 --- /dev/null +++ b/OpenAntrag/Views/Shared/_LogonPartial.vbhtml @@ -0,0 +1,19 @@ +@Imports OpenAntrag +@ModelType LogonModel + +

          Login

          +
          + + @Html.TextBoxFor(Function(m) m.UserName, New With {.class = "w1", .placeholder = "Benutzername"}) + @Html.ValidationMessageFor(Function(m) m.UserName) +
          +
          + + @Html.PasswordFor(Function(m) m.Password, New With {.class = "w1", .placeholder = "Kennwort"}) + @Html.ValidationMessageFor(Function(m) m.Password) +
          + + +Kennwort vergessen? diff --git a/OpenAntrag/Views/Shared/_NavCommonLeftPartial.vbhtml b/OpenAntrag/Views/Shared/_NavCommonLeftPartial.vbhtml new file mode 100644 index 0000000..2b89fb9 --- /dev/null +++ b/OpenAntrag/Views/Shared/_NavCommonLeftPartial.vbhtml @@ -0,0 +1,60 @@ +@Imports OpenAntrag + + + + + + + + + Parlamente + + + + + Anträge + + + + Erfolge + + + + Themen + + + + Suche + + + + FAQ + + + + Feedback + + + + Statistiken + + + + Schnittstellen (API) + + + + Mitteilungen + diff --git a/OpenAntrag/Views/Shared/_NavCommonRightPartial.vbhtml b/OpenAntrag/Views/Shared/_NavCommonRightPartial.vbhtml new file mode 100644 index 0000000..bc2b37b --- /dev/null +++ b/OpenAntrag/Views/Shared/_NavCommonRightPartial.vbhtml @@ -0,0 +1,23 @@ +@Imports OpenAntrag + + + + RSS + + + + + Blog + + + + Google+ + + + + Twitter + diff --git a/OpenAntrag/Views/Shared/_NewPostPartial.vbhtml b/OpenAntrag/Views/Shared/_NewPostPartial.vbhtml new file mode 100644 index 0000000..4fdb3a3 --- /dev/null +++ b/OpenAntrag/Views/Shared/_NewPostPartial.vbhtml @@ -0,0 +1,20 @@ +@Imports OpenAntrag +@ModelType Notification + + diff --git a/OpenAntrag/Views/Shared/_PasswordChangePartial.vbhtml b/OpenAntrag/Views/Shared/_PasswordChangePartial.vbhtml new file mode 100644 index 0000000..e427c2c --- /dev/null +++ b/OpenAntrag/Views/Shared/_PasswordChangePartial.vbhtml @@ -0,0 +1,22 @@ +@Imports OpenAntrag +@ModelType ChangePasswordModel + +

          Kennwort ändern

          +
          +
          + + @Html.PasswordFor(Function(m) m.OldPassword, New With {.class = "w1", .placeholder = "Altes Kennwort"}) + @Html.ValidationMessageFor(Function(m) m.OldPassword) +
          +
          + + @Html.PasswordFor(Function(m) m.NewPassword, New With {.class = "w1", .placeholder = "Neues Kennwort"}) + @Html.ValidationMessageFor(Function(m) m.NewPassword) +
          +
          + + @Html.PasswordFor(Function(m) m.ConfirmPassword, New With {.class = "w1", .placeholder = "Wiederholung"}) + @Html.ValidationMessageFor(Function(m) m.ConfirmPassword) +
          + +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_PasswordChangeSuccessPartial.vbhtml b/OpenAntrag/Views/Shared/_PasswordChangeSuccessPartial.vbhtml new file mode 100644 index 0000000..fe8ddec --- /dev/null +++ b/OpenAntrag/Views/Shared/_PasswordChangeSuccessPartial.vbhtml @@ -0,0 +1 @@ +

          Dein Kennwort wurde erfolgreich geändert

          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_PasswordResetPartial.vbhtml b/OpenAntrag/Views/Shared/_PasswordResetPartial.vbhtml new file mode 100644 index 0000000..0a9c760 --- /dev/null +++ b/OpenAntrag/Views/Shared/_PasswordResetPartial.vbhtml @@ -0,0 +1,21 @@ +@Imports OpenAntrag +@ModelType ResetPasswordModel + +

          Kennwort vergessen?

          +
          + +

          Diese Funtkion steht aktuell nicht zur Verfügung. + Bitte wende Dich via Mail an: @("webmaster@" & Tools.GetRequestDomain)

          +@* +
          + + @Html.TextBoxFor(Function(m) m.UserNameReset, New With {.class = "w1", .placeholder = "Benutzername"}) + @Html.ValidationMessageFor(Function(m) m.UserNameReset) +
          + +*@ +
          + +...zurück zum Login diff --git a/OpenAntrag/Views/Shared/_PasswordResetSuccessPartial.vbhtml b/OpenAntrag/Views/Shared/_PasswordResetSuccessPartial.vbhtml new file mode 100644 index 0000000..fd9c640 --- /dev/null +++ b/OpenAntrag/Views/Shared/_PasswordResetSuccessPartial.vbhtml @@ -0,0 +1 @@ +

          Dein neues Kennwort wurde an Deine Mail-Adresse versandt.

          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_ProposalBlockPartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalBlockPartial.vbhtml new file mode 100644 index 0000000..9d00b64 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalBlockPartial.vbhtml @@ -0,0 +1,46 @@ +@Imports OpenAntrag +@ModelType Proposal + +@Code + Dim bolShaded As Boolean = ViewData("Shaded") + Dim bolShowRep As Boolean = ViewData("ShowRepresentation") +End Code + +
          +
          +
          + + +
          + @For Each ps As ProposalStep In Model.ProposalStepStack + @  + Next +
          +
          +
          + @If bolShowRep = True Then + @@Model.Representation.[Name] + End If + + @Proposals.GetProcessStepCaption(Model.CurrentProposalStep.ProcessStep.Caption, Model, Model.Representation) + @Model.CreatedAtFormat + +

          @Model.Title

          + @If Model.IsAbuse = True Then + @
          + Dieser Antrag wurde wegen Missbrauchs stumm geschaltet +
          @Html.Raw(Model.AbuseMessageHtml)
          +
          + Else + @
          @Html.Raw(Model.TextHtml)
          + End If + @Html.Partial("_ProposalSublinksPartial", Model) +
          +
          +
          + @Html.Partial("_ProposalTagListPartial", Model) +
          +
          +
          diff --git a/OpenAntrag/Views/Shared/_ProposalListTablePartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalListTablePartial.vbhtml new file mode 100644 index 0000000..1ffe147 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalListTablePartial.vbhtml @@ -0,0 +1,17 @@ +@Imports OpenAntrag +@ModelType List(Of Proposal) + +@Code + Dim bolShowRep As Boolean = ViewData("ShowRepresentation") +End Code + + + + @Html.Partial("_ProposalRowHeadPartial", New ViewDataDictionary() From {{"ShowRepresentation", bolShowRep}}) + + + @For Each prop In Model + Html.RenderPartialWithData("_ProposalRowPartial", prop, New With {.ShowRepresentation = bolShowRep}) + Next + +
          diff --git a/OpenAntrag/Views/Shared/_ProposalRowHeadPartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalRowHeadPartial.vbhtml new file mode 100644 index 0000000..71e0ad7 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalRowHeadPartial.vbhtml @@ -0,0 +1,23 @@ +@Code + Dim bolShowRep As Boolean = ViewData("ShowRepresentation") +End Code + + + + + + Datum + @If bolShowRep = True Then + @Fraktion + End If + Titel + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_ProposalRowPartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalRowPartial.vbhtml new file mode 100644 index 0000000..7652083 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalRowPartial.vbhtml @@ -0,0 +1,38 @@ +@Imports OpenAntrag +@ModelType Proposal + +@Code + Dim bolShowRep As Boolean = ViewData("ShowRepresentation") + + Model.FillProcessSteps() +End Code + + + + @(Model.CurrentProposalStep.ID_ProcessStep) + + + + @Model.Timestamp +
          @(CType(Model.CreatedAt, DateTime).ToString("dd.MM.yy hh:mm"))
          + @(Model.CurrentProposalStep.ProcessStep.ShortCaption) + + @If bolShowRep = True Then + @ + + @Model.Representation.Label + + + End If + + + @Model.Title + + + + @Model.UpdatedTimestamp + @(Model.UpdatedAtFormat) + + @(Model.ProposalComments.Count) + @(Model.Rating) + diff --git a/OpenAntrag/Views/Shared/_ProposalSublinksPartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalSublinksPartial.vbhtml new file mode 100644 index 0000000..1844f81 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalSublinksPartial.vbhtml @@ -0,0 +1,58 @@ +@Imports OpenAntrag +@ModelType Proposal + + + + diff --git a/OpenAntrag/Views/Shared/_ProposalTagListPartial.vbhtml b/OpenAntrag/Views/Shared/_ProposalTagListPartial.vbhtml new file mode 100644 index 0000000..d453ba0 --- /dev/null +++ b/OpenAntrag/Views/Shared/_ProposalTagListPartial.vbhtml @@ -0,0 +1,10 @@ +@Imports OpenAntrag +@ModelType Proposal + +@If Model.Tags IsNot Nothing Then + For Each tag As String In Model.Tags + If String.IsNullOrEmpty(tag) = False Then + @  @tag + End If + Next +End If diff --git a/OpenAntrag/Views/Shared/_SubnavRepresentations.vbhtml b/OpenAntrag/Views/Shared/_SubnavRepresentations.vbhtml new file mode 100644 index 0000000..1174ef9 --- /dev/null +++ b/OpenAntrag/Views/Shared/_SubnavRepresentations.vbhtml @@ -0,0 +1,65 @@ +@Imports OpenAntrag + +@Code + + 'Dim rps As New Representations(Representations.StatusConjuction.Active + Representations.StatusConjuction.Ended) + 'Dim lstRepresentations As List(Of Representation) = rps.Items.OrderBy(Function(x) x.Level).ThenBy(Function(x) x.Key).ToList + + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And (Representations.StatusConjuction.Active + Representations.StatusConjuction.Ended)) > 0) _ + .OrderBy(Function(x) x.Level) _ + .ThenBy(Function(x) x.Key) _ + .ToList() + + Dim gls As New GovernmentalLevels + + Dim gCookie As String = Tools.GetCookie("OpenAntrag-NavFilter-G", True) + Dim fCookie As String = Tools.GetCookie("OpenAntrag-NavFilter-F", true) + +End Code + + diff --git a/OpenAntrag/Views/Shared/_SuccessStoryBlockPartial.vbhtml b/OpenAntrag/Views/Shared/_SuccessStoryBlockPartial.vbhtml new file mode 100644 index 0000000..d24cfac --- /dev/null +++ b/OpenAntrag/Views/Shared/_SuccessStoryBlockPartial.vbhtml @@ -0,0 +1,20 @@ +@Imports OpenAntrag +@ModelType SuccessStory + +@Code + Dim bolShaded As Boolean = ViewData("Shaded") +End Code + +
          +
          +
          + + @(Model.Proposal.Representation.Label) + + @(Model.StepDateFormat) +

          @(Model.Title)

          +
          @Html.Raw(Model.TextHtml)
          + @Html.Partial("_SuccessStorySublinksPartial", Model) +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Shared/_SuccessStorySublinksPartial.vbhtml b/OpenAntrag/Views/Shared/_SuccessStorySublinksPartial.vbhtml new file mode 100644 index 0000000..171dd74 --- /dev/null +++ b/OpenAntrag/Views/Shared/_SuccessStorySublinksPartial.vbhtml @@ -0,0 +1,11 @@ +@Imports OpenAntrag +@ModelType SuccessStory + + \ No newline at end of file diff --git a/OpenAntrag/Views/Statistics/Index.vbhtml b/OpenAntrag/Views/Statistics/Index.vbhtml new file mode 100644 index 0000000..2b4aa9e --- /dev/null +++ b/OpenAntrag/Views/Statistics/Index.vbhtml @@ -0,0 +1,84 @@ +@Imports OpenAntrag +@ModelType String +@Code + ViewData("Title") = "Statistik" + + Dim strPart As String = ViewData("StatPartial") + Dim strPartial As String = Nothing + + Dim bolHasPart As Boolean = Not String.IsNullOrEmpty(strPart) + If bolHasPart = True Then strPartial = String.Concat("_", strPart, "Partial") + + 'Dim intRepresentationCount As Integer = (New Representations(Representations.StatusConjuction.Active)).Items.Count + Dim intRepresentationCount As Integer = GlobalData.Representations.Items _ + .Where(Function(x) x.Status And Representations.StatusConjuction.Active = Representations.StatusConjuction.Active) _ + .Count() + + Dim intProposalCount As Integer = Proposals.GetItemsCount() + Dim intCommentCount As Integer = Proposals.GetItemsCommentCount + Dim intFeedbackCount As Integer = Feedbacks.GetCount + +End Code + +@Section Styles + @Styles.Render("~/css/statistics") +End Section + +@Section Scripts + + @If bolHasPart = True Then + @ + End If +End Section + +@Section Intro +

          + Wo der Glaube versagt, hilft die Statistik
          + Die Anträge in Zahlen, Form und Farbe +

          +End Section + + + +
          +
          +
          + +

          Die 
          + Statistiken

          +
          +
          +
          +

          + Hier finden Statistik-Fans nützliche Zahlen und Grafiken rund um die + @(intRepresentationCount) Parlamente (Fraktionen), + @(intProposalCount) Anträge, + @(intCommentCount) Antragskommentare und + @(intFeedbackCount) Feedback-Beiträge, +

          +
          +
          +
          + +@Code + If bolHasPart = True Then + @Html.Partial(strPartial) + End If +End Code diff --git a/OpenAntrag/Views/Statistics/_FeedbackCountByTypePartial.vbhtml b/OpenAntrag/Views/Statistics/_FeedbackCountByTypePartial.vbhtml new file mode 100644 index 0000000..829f7e2 --- /dev/null +++ b/OpenAntrag/Views/Statistics/_FeedbackCountByTypePartial.vbhtml @@ -0,0 +1,65 @@ +@Imports OpenAntrag + +@Code + + Dim lstData As New List(Of PieSliceDataSDM) + StatisticsManager.GetFeedbackCountByType(lstData) + + Dim jData As String = Newtonsoft.Json.JsonConvert.SerializeObject(lstData, Newtonsoft.Json.Formatting.None) + +End Code + + + +
          +
          +
          + +

          Statistik:
          Verteilung Feedback

          +
          +
          +
          + +
          +
          +
          +
          +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Statistics/_ProposalCountByRepresentationPartial.vbhtml b/OpenAntrag/Views/Statistics/_ProposalCountByRepresentationPartial.vbhtml new file mode 100644 index 0000000..04b65a5 --- /dev/null +++ b/OpenAntrag/Views/Statistics/_ProposalCountByRepresentationPartial.vbhtml @@ -0,0 +1,92 @@ +@Imports OpenAntrag + +@Code + + Dim lstCategories As New List(Of String) + Dim lstData As New List(Of BarColumnDataSDM) + StatisticsManager.GetProposalCountByRepresentationData(lstCategories, lstData) + + Dim jCategories As String = Newtonsoft.Json.JsonConvert.SerializeObject(lstCategories) + Dim jData As String = Newtonsoft.Json.JsonConvert.SerializeObject(lstData) + + Dim intHeight As Integer = lstCategories.Count * 50 + +End Code + + + +
          +
          +
          + +

          Statistik:
          Anzahl Anträge je Parlament

          +
          +
          +
          + +
          +
          +
          +
          +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Statistics/_RepresentationCountByTypePartial.vbhtml b/OpenAntrag/Views/Statistics/_RepresentationCountByTypePartial.vbhtml new file mode 100644 index 0000000..a44122f --- /dev/null +++ b/OpenAntrag/Views/Statistics/_RepresentationCountByTypePartial.vbhtml @@ -0,0 +1,65 @@ +@Imports OpenAntrag + +@Code + + Dim lstData As New List(Of PieSliceDataSDM) + StatisticsManager.GetRepresentationCountByType(lstData) + + Dim jData As String = Newtonsoft.Json.JsonConvert.SerializeObject(lstData, Newtonsoft.Json.Formatting.None) + +End Code + + + +
          +
          +
          + +

          Statistik:
          Verteilung Gruppentypen Parlamente

          +
          +
          +
          + +
          +
          +
          +
          +
          +
          +
          \ No newline at end of file diff --git a/OpenAntrag/Views/Teaser/Index.vbhtml b/OpenAntrag/Views/Teaser/Index.vbhtml new file mode 100644 index 0000000..e14c8c1 --- /dev/null +++ b/OpenAntrag/Views/Teaser/Index.vbhtml @@ -0,0 +1,83 @@ +@Imports OpenAntrag +@ModelType Teaser + +@Code + ViewData("Title") = Model.Name + + 'Dim rps As New Representations(Representations.StatusConjuction.Active) + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And Representations.StatusConjuction.Active) > 0) _ + .ToList() + +End Code + +@Section Styles + @Styles.Render(String.Concat("~/css/teaser-", Model.Key)) + +End Section + +@Section Scripts + @Scripts.Render("~/bundle/teaser") + @Scripts.Render("~/bundle/markdown") + +End Section + +@Section Intro + @Html.PartialOrNull("_TeaserIntro", Model) +End Section + +@Section RepNav + @Html.PartialOrNull("_NavTeaser", Model) +End Section + + + + diff --git a/OpenAntrag/Views/Teaser/_NavTeaser.vbhtml b/OpenAntrag/Views/Teaser/_NavTeaser.vbhtml new file mode 100644 index 0000000..458b99f --- /dev/null +++ b/OpenAntrag/Views/Teaser/_NavTeaser.vbhtml @@ -0,0 +1,17 @@ +@Imports OpenAntrag +@ModelType Teaser + + + diff --git a/OpenAntrag/Views/Teaser/_TeaserIntro.vbhtml b/OpenAntrag/Views/Teaser/_TeaserIntro.vbhtml new file mode 100644 index 0000000..a50bd7e --- /dev/null +++ b/OpenAntrag/Views/Teaser/_TeaserIntro.vbhtml @@ -0,0 +1,6 @@ +@Imports OpenAntrag +@ModelType Teaser + +

          @Model.Name

          + + \ No newline at end of file diff --git a/OpenAntrag/Views/Web.config b/OpenAntrag/Views/Web.config new file mode 100644 index 0000000..b895fb7 --- /dev/null +++ b/OpenAntrag/Views/Web.config @@ -0,0 +1,59 @@ + + + + + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenAntrag/Views/_ViewStart.vbhtml b/OpenAntrag/Views/_ViewStart.vbhtml new file mode 100644 index 0000000..8d4dcd1 --- /dev/null +++ b/OpenAntrag/Views/_ViewStart.vbhtml @@ -0,0 +1,3 @@ +@Code + Layout = "~/Views/Shared/_Layout.vbhtml" +End Code diff --git a/OpenAntrag/favicon.ico b/OpenAntrag/favicon.ico new file mode 100644 index 0000000..5f52651 Binary files /dev/null and b/OpenAntrag/favicon.ico differ diff --git a/OpenAntrag/packages.config b/OpenAntrag/packages.config new file mode 100644 index 0000000..5edcee1 --- /dev/null +++ b/OpenAntrag/packages.config @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntragLib/Attributes/HandleCustomErrorAttribute.vb b/OpenAntragLib/Attributes/HandleCustomErrorAttribute.vb new file mode 100644 index 0000000..e934e6e --- /dev/null +++ b/OpenAntragLib/Attributes/HandleCustomErrorAttribute.vb @@ -0,0 +1,148 @@ +Imports System.Collections.Generic +Imports System.Web +Imports System.Web.Mvc + +Public Class HandleCustomErrorAttribute + Inherits HandleErrorAttribute + + Public Overrides Sub OnException(filterContext As System.Web.Mvc.ExceptionContext) + + If filterContext.ExceptionHandled OrElse Not filterContext.HttpContext.IsCustomErrorEnabled Then Return + If New HttpException(Nothing, filterContext.Exception).GetHttpCode() <> 500 Then Return + If Not ExceptionType.IsInstanceOfType(filterContext.Exception) Then Return + + Dim log As New ErrorLog() + + log.AbsoluteUri = filterContext.HttpContext.Request.Url.AbsoluteUri + log.Controller = filterContext.RouteData.Values("controller").ToString() + log.Action = filterContext.RouteData.Values("action").ToString() + log.RequestType = filterContext.HttpContext.Request.RequestType + log.Message = filterContext.Exception.Message + + log.AjaxCall = (filterContext.HttpContext.Request.Headers("X-Requested-With") IsNot Nothing AndAlso + filterContext.HttpContext.Request.Headers("X-Requested-With") = "XMLHttpRequest") + + Dim userAgent As String = filterContext.HttpContext.Request.UserAgent + + For Each kv As KeyValuePair(Of String, Object) In filterContext.RouteData.Values + log.Parameter.Add(String.Concat(kv.Key, ": ", kv.Value)) + Next + + If filterContext.HttpContext.Request.UrlReferrer IsNot Nothing Then + log.ReferrerUrl = filterContext.HttpContext.Request.UrlReferrer.AbsolutePath + End If + + If log.AjaxCall Then + + 'JSON, wenn [HandleCustomErrorAttribute] nicht gesetzt ist + + filterContext.Result = New JsonResult() With { + .Data = New With { + .success = False, + .error = filterContext.Exception.Message + }, + .JsonRequestBehavior = JsonRequestBehavior.AllowGet + } + + Else + + 'STANDARD + + Dim cei As New CustomErrorInfo(log.Message, log.ReferrerUrl, CustomErrorInfo.OriginEnum.Exception, -1, filterContext.Exception, log.Controller, _ + log.Action) + + filterContext.Result = New ViewResult() With { + .ViewName = Me.View, _ + .MasterName = Master, _ + .ViewData = New ViewDataDictionary(Of HandleErrorInfo)(cei), + .TempData = filterContext.Controller.TempData _ + } + + End If + + If TypeOf filterContext.Exception Is CustomException = False Then + ErrorLogs.NewLog(log, userAgent) + End If + + filterContext.ExceptionHandled = True + filterContext.HttpContext.Response.Clear() + filterContext.HttpContext.Response.StatusCode = 500 + + filterContext.HttpContext.Response.TrySkipIisCustomErrors = True + + End Sub + + 'Public Overrides Sub OnException(filterContext As System.Web.Mvc.ExceptionContext) + + ' If filterContext.ExceptionHandled OrElse Not filterContext.HttpContext.IsCustomErrorEnabled Then Return + ' If New HttpException(Nothing, filterContext.Exception).GetHttpCode() <> 500 Then Return + ' If Not ExceptionType.IsInstanceOfType(filterContext.Exception) Then Return + + ' Dim controllerName As String = filterContext.RouteData.Values("controller").ToString() + ' Dim actionName As String = filterContext.RouteData.Values("action").ToString() + ' Dim requestType As String = filterContext.HttpContext.Request.RequestType + ' Dim absoluteUri As String = filterContext.HttpContext.Request.Url.AbsoluteUri + ' Dim userAgent As String = filterContext.HttpContext.Request.UserAgent + + ' Dim ajaxCall As Boolean = (filterContext.HttpContext.Request.Headers("X-Requested-With") IsNot Nothing AndAlso + ' filterContext.HttpContext.Request.Headers("X-Requested-With") = "XMLHttpRequest") + + ' Dim stbValues As New StringBuilder() + ' stbValues.Append("requestType").Append(": ").Append(String.Concat(requestType, If((ajaxCall = True), " (AJAX)", ""))).Append(vbLf) + ' stbValues.Append("userAgent").Append(": ").Append(userAgent).Append(vbLf) + ' For Each kv As KeyValuePair(Of String, Object) In filterContext.RouteData.Values + ' stbValues.Append(kv.Key).Append(": ").Append(kv.Value.ToString()).Append(vbLf) + ' Next + + ' Dim referrerUrl As String = "" + ' If filterContext.HttpContext.Request.UrlReferrer IsNot Nothing Then + ' referrerUrl = filterContext.HttpContext.Request.UrlReferrer.AbsolutePath + ' End If + + ' If ajaxCall Then + + ' 'JSON, wenn [HandleErrorAsJsonAttribute] nicht gesetzt ist + + ' filterContext.Result = New JsonResult() With { + ' .Data = New With { + ' .success = False, + ' .error = filterContext.Exception.Message + ' }, + ' .JsonRequestBehavior = JsonRequestBehavior.AllowGet + ' } + ' Else + + ' 'STANDARD + + ' Dim cei As New CustomErrorInfo(filterContext.Exception.Message, + ' referrerUrl, + ' CustomErrorInfo.OriginEnum.Exception, + ' -1, + ' filterContext.Exception, controllerName, + ' actionName) + + ' filterContext.Result = New ViewResult() With { + ' .ViewName = Me.View, _ + ' .MasterName = Master, _ + ' .ViewData = New ViewDataDictionary(Of HandleErrorInfo)(cei), + ' .TempData = filterContext.Controller.TempData _ + ' } + ' End If + + ' 'TODO: Logging + + ' If TypeOf filterContext.Exception Is CustomException = False Then + ' PushoverManager.Send( + ' New PushoverMessage(String.Concat("Exception auf ", absoluteUri), + ' String.Concat(stbValues, filterContext.Exception.Message), + ' referrerUrl, referrerUrl, True)) + ' End If + + ' filterContext.ExceptionHandled = True + ' filterContext.HttpContext.Response.Clear() + ' filterContext.HttpContext.Response.StatusCode = 500 + + ' filterContext.HttpContext.Response.TrySkipIisCustomErrors = True + 'End Sub + +End Class diff --git a/OpenAntragLib/Attributes/HandleErrorAsJsonAttribute.vb b/OpenAntragLib/Attributes/HandleErrorAsJsonAttribute.vb new file mode 100644 index 0000000..52dea93 --- /dev/null +++ b/OpenAntragLib/Attributes/HandleErrorAsJsonAttribute.vb @@ -0,0 +1,20 @@ +Imports System.Web.Mvc + +Public Class HandleErrorAsJsonAttribute + Inherits FilterAttribute + Implements IExceptionFilter + + Public Sub OnException(filterContext As ExceptionContext) Implements IExceptionFilter.OnException + + filterContext.ExceptionHandled = True + filterContext.Result = New JsonResult() With { + .Data = New With { + .success = False, + .error = filterContext.Exception.Message + }, + .JsonRequestBehavior = JsonRequestBehavior.AllowGet + } + + End Sub + +End Class diff --git a/OpenAntragLib/CDataSyndicationContent.vb b/OpenAntragLib/CDataSyndicationContent.vb new file mode 100644 index 0000000..6693b1c --- /dev/null +++ b/OpenAntragLib/CDataSyndicationContent.vb @@ -0,0 +1,14 @@ +Imports System.ServiceModel.Syndication + +Public Class CDataSyndicationContent + Inherits TextSyndicationContent + + Public Sub New(content As TextSyndicationContent) + MyBase.New(content) + End Sub + + Protected Overrides Sub WriteContentsTo(writer As System.Xml.XmlWriter) + writer.WriteCData(Text) + End Sub + +End Class diff --git a/OpenAntragLib/CSVIgnore.vb b/OpenAntragLib/CSVIgnore.vb new file mode 100644 index 0000000..c72b66b --- /dev/null +++ b/OpenAntragLib/CSVIgnore.vb @@ -0,0 +1,4 @@ +Public Class CSVIgnore + Inherits System.Attribute + +End Class diff --git a/OpenAntragLib/CSVMediaTypeFormatter.vb b/OpenAntragLib/CSVMediaTypeFormatter.vb new file mode 100644 index 0000000..28ff733 --- /dev/null +++ b/OpenAntragLib/CSVMediaTypeFormatter.vb @@ -0,0 +1,151 @@ +Imports System.Net.Http.Formatting +Imports System.Net.Http.Headers +Imports System.IO +Imports System.Net +Imports System.Net.Http +Imports System.Reflection + +Public Class CSVMediaTypeFormatter + Inherits MediaTypeFormatter + + Public Sub New() + + SupportedMediaTypes.Add(New MediaTypeHeaderValue("text/csv")) + + End Sub + + Public Sub New(mediaTypeMapping As MediaTypeMapping) + + Me.New() + + MediaTypeMappings.Add(mediaTypeMapping) + + End Sub + + Public Sub New(mtm As IEnumerable(Of MediaTypeMapping)) + + Me.New() + + For Each m As MediaTypeMapping In mtm + MediaTypeMappings.Add(m) + Next + + End Sub + + Public Overrides Function CanWriteType(type As Type) As Boolean + + If type Is Nothing Then + Throw New ArgumentNullException("type") + End If + + Return Me.IsTypeOfIEnumerable(type) + + End Function + + Private Function IsTypeOfIEnumerable(type As Type) As Boolean + + For Each interfaceType As Type In type.GetInterfaces() + + If interfaceType = GetType(IEnumerable) Then + Return True + End If + Next + + Return False + + End Function + + Public Overrides Function CanReadType(type As Type) As Boolean + Return False + End Function + + Public Overrides Function WriteToStreamAsync(type As Type, + value As Object, + stream As Stream, + content As HttpContent, + transportContext As TransportContext) As Task + + writeStream(type, value, stream, content) + + Dim tcs = New TaskCompletionSource(Of Integer)() + tcs.SetResult(0) + Return tcs.Task + + End Function + + Private Sub writeStream(type As Type, + value As Object, + stream As Stream, + content As HttpContent) + + 'NOTE: We have check the type inside CanWriteType method + 'If request comes this far, the type is IEnumerable. We are safe. + + Dim _stringWriter As New StringWriter() + + Dim bHeaders As Boolean + Dim lstHeaders As New List(Of String) + + Try + For Each obj In DirectCast(value, IEnumerable(Of Object)) + + Dim oType As Type = obj.GetType() + Dim lstValues As New List(Of Object) + + For Each oProp As PropertyInfo In oType.GetProperties() + + Dim attrIgnore As CSVIgnore() = DirectCast(oProp.GetCustomAttributes(GetType(CSVIgnore), True), CSVIgnore()) + If attrIgnore.Count = 0 Then + + If bHeaders = False Then + lstHeaders.Add(oProp.Name) + End If + + lstValues.Add(New With {.Value = oProp.GetValue(obj)}) + End If + Next + + If bHeaders = False Then + _stringWriter.WriteLine(String.Join(";", lstHeaders.ToArray)) + bHeaders = True + End If + + 'Dim vals = obj.GetType().GetProperties().Select(Function(x) New With {.Value = x.GetValue(obj)}) + + Dim _valueLine As String = String.Empty + + For Each val As Object In lstValues + + If val.Value IsNot Nothing Then + + Dim _val = val.Value.ToString() + + 'Check if the value contans a comma and place it in quotes if so + If _val.Contains(";") Then + _val = String.Concat("""", _val, """") + End If + + 'Replace any \r or \n special characters from a new line with a space + If _val.Contains(vbCr) Then + _val = _val.Replace(vbCr, " ") + End If + If _val.Contains(vbLf) Then + _val = _val.Replace(vbLf, " ") + End If + + _valueLine = String.Concat(_valueLine, _val, ";") + Else + _valueLine = String.Concat(_valueLine, String.Empty, ";") + End If + Next + + _stringWriter.WriteLine(_valueLine.TrimEnd(";"c)) + Next + Catch ex As Exception + End Try + + Dim streamWriter = New StreamWriter(stream, System.Text.Encoding.UTF8) + streamWriter.Write(_stringWriter.ToString()) + End Sub + +End Class diff --git a/OpenAntragLib/Controller/CommonController.vb b/OpenAntragLib/Controller/CommonController.vb new file mode 100644 index 0000000..71ba561 --- /dev/null +++ b/OpenAntragLib/Controller/CommonController.vb @@ -0,0 +1,51 @@ +Imports System.Web.Mvc + +Public Class CommonController + Inherits System.Web.Mvc.Controller + + + Public Function GetPartial(namepart As String) As JsonResult + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_" & namepart & "Partial")} + Return jr + + End Function + + + Public Function GetPartialModel(namepart As String, model As Object) As JsonResult + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = Me.RenderPartialViewToString("_" & namepart & "Partial", model)} + Return jr + + End Function + + + Public Function GetErrorHtml(strErrorMessage As String) As JsonResult + + Dim cei As New CustomErrorInfo With {.ErrorMessage = strErrorMessage} + Dim strHtml As String = Me.RenderPartialViewToString("_ErrorBoxPartial", cei) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = False, .errorHtml = strHtml} + Return jr + + End Function + + + Public Function GetHash(strValue As String) As JsonResult + + Dim strHash As String = Tools.GetMd5(strValue) + + Dim jr As New JsonResult + jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet + jr.Data = New With {.success = True, .data = strHash} + Return jr + + End Function + +End Class diff --git a/OpenAntragLib/Controller/DocumentStoreController.vb b/OpenAntragLib/Controller/DocumentStoreController.vb new file mode 100644 index 0000000..45d318c --- /dev/null +++ b/OpenAntragLib/Controller/DocumentStoreController.vb @@ -0,0 +1,51 @@ +Imports System.Web.Mvc +Imports Raven.Client + +Public Class DocumentStoreController + Inherits CommonController + + Public Property DocumentSession() As IDocumentSession + Public Property AlreadySaved As Boolean = False + + Public Sub StoreAndSave(entity As Object) + + Me.DocumentSession.Store(entity) + Me.DocumentSession.SaveChanges() + Me.AlreadySaved = True + + End Sub + + Protected Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext) + + If filterContext.IsChildAction Then + Return + End If + + Me.DocumentSession = DataDocumentStore.Session() + + MyBase.OnActionExecuting(filterContext) + + End Sub + + Protected Overrides Sub OnActionExecuted(ByVal filterContext As ActionExecutedContext) + + If filterContext.IsChildAction Then + Return + End If + + If Me.AlreadySaved = True Then + 'es wurde bereits gespeichert; Kennwert zurücksetzen + Me.AlreadySaved = False + Else + If Me.DocumentSession IsNot Nothing AndAlso filterContext.Exception Is Nothing Then + Me.DocumentSession.SaveChanges() + End If + End If + + Me.DocumentSession.Dispose() + + MyBase.OnActionExecuted(filterContext) + + End Sub + +End Class \ No newline at end of file diff --git a/OpenAntragLib/Controller/MailController.vb b/OpenAntragLib/Controller/MailController.vb new file mode 100644 index 0000000..3016833 --- /dev/null +++ b/OpenAntragLib/Controller/MailController.vb @@ -0,0 +1,73 @@ +Imports ActionMailer.Net.Mvc + +Public Class MailController + Inherits MailerBase + + Public Function ResetPassword(model As ResetPasswordModel) As EmailResult + + Me.To.Add(model.MailAddress) + Me.From = SettingsWrapper.MailSender + Me.Subject = "Dein neues Passwort für OpenAntrag" + + Return Email("ResetPasswordEmail", model) + + End Function + + Public Function NewProposal(model As Proposal) As EmailResult + + Dim arrMailAdresses As String() = model.Representation.InfoMail.Split(";") + For Each s As String In arrMailAdresses + Me.To.Add(s) + Next + + If SettingsWrapper.InfoMailCC.Length > 0 Then + Me.BCC.Add(SettingsWrapper.InfoMailCC) + End If + + Me.From = SettingsWrapper.MailSender + Me.Subject = "Ein neuer OpenAntrag ist eingegangen" + + Return Email("NewProposalEmail", model) + + End Function + + Public Function NewProposalComment(model As ProposalComment, prop As Proposal) As EmailResult + + Dim arrMailAdresses As String() = prop.Representation.InfoMail.Split(";") + For Each s As String In arrMailAdresses + Me.To.Add(s) + Next + + If SettingsWrapper.InfoMailCC.Length > 0 Then + Me.BCC.Add(SettingsWrapper.InfoMailCC) + End If + + Me.From = SettingsWrapper.MailSender + + Dim strSubject As String = String.Concat("Ein neuer OpenAntrag-Kommentar für '", prop.Title, "' ist eingegangen") + Me.Subject = strSubject + + ViewData("Subject") = strSubject + Return Email("NewProposalCommentEmail", model) + + End Function + + Public Function NewProposalAbuseNotice(model As ProposalAbuseNotice) As EmailResult + + Dim arrMailAdresses As String() = model.Proposal.Representation.InfoMail.Split(";") + For Each s As String In arrMailAdresses + Me.To.Add(s) + Next + + If SettingsWrapper.InfoMailCC.Length > 0 Then + Me.BCC.Add(SettingsWrapper.InfoMailCC) + End If + + Me.From = SettingsWrapper.MailSender + Me.Subject = "ACHTUNG: Eine OpenAntrag-Missbrauchsmeldung!" + + Return Email("NewProposalAbuseNoticeEmail", model) + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntragLib/CustomErrorInfo.vb b/OpenAntragLib/CustomErrorInfo.vb new file mode 100644 index 0000000..e9b99d3 --- /dev/null +++ b/OpenAntragLib/CustomErrorInfo.vb @@ -0,0 +1,53 @@ +Imports System.Web.Mvc + +Public Class CustomErrorInfo + Inherits HandleErrorInfo + + Public Enum OriginEnum + Undefined + Exception + Redirect + End Enum + + Public Sub New() + MyBase.New(New Exception(), "Error", "Index") + + Me.Origin = OriginEnum.Undefined + + End Sub + + Public Sub New(errorMessage As String, + origin As OriginEnum, + code As Integer) + + MyBase.New(New Exception(), "Error", "Index") + + Me.ErrorMessage = errorMessage + Me.Origin = origin + Me.Code = code + + End Sub + + Public Sub New(errorMessage As String, + referrerUrl As String, + origin As OriginEnum, + code As Integer, + exception As Exception, + controllerName As String, + actionName As String) + + MyBase.New(exception, controllerName, actionName) + + Me.ErrorMessage = errorMessage + Me.ReferrerUrl = referrerUrl + Me.Origin = origin + Me.Code = code + + End Sub + + Public Property ErrorMessage() As String + Public Property ReferrerUrl() As String + Public Property Origin() As OriginEnum + Public Property Code() As Integer + +End Class diff --git a/OpenAntragLib/CustomException.vb b/OpenAntragLib/CustomException.vb new file mode 100644 index 0000000..71316c8 --- /dev/null +++ b/OpenAntragLib/CustomException.vb @@ -0,0 +1,38 @@ +Imports System.Runtime.Serialization + + +Public Class CustomException + Inherits Exception + + Public Property Title As String = "Fehlerhinweis" + + Public Sub New() + MyBase.New() + End Sub + + Public Sub New(message As String) + MyBase.New(message) + End Sub + + Public Sub New(ByVal message As String, ByVal title As String) + Me.New(message) + Me.Title = title + End Sub + + Public Sub New(format As String, ParamArray args As Object()) + MyBase.New(String.Format(format, args)) + End Sub + + Public Sub New(message As String, innerException As Exception) + MyBase.New(message, innerException) + End Sub + + Public Sub New(format As String, innerException As Exception, ParamArray args As Object()) + MyBase.New(String.Format(format, args), innerException) + End Sub + + Protected Sub New(info As SerializationInfo, context As StreamingContext) + MyBase.New(info, context) + End Sub + +End Class diff --git a/OpenAntragLib/CustomHeaderModule.vb b/OpenAntragLib/CustomHeaderModule.vb new file mode 100644 index 0000000..90a19e4 --- /dev/null +++ b/OpenAntragLib/CustomHeaderModule.vb @@ -0,0 +1,18 @@ +Imports System.Web + +Public Class CustomHeaderModule + Implements IHttpModule + + Public Sub Init(context As HttpApplication) Implements IHttpModule.Init + AddHandler context.PreSendRequestHeaders, AddressOf OnPreSendRequestHeaders + End Sub + + Public Sub Dispose() Implements IHttpModule.Dispose + End Sub + + Private Sub OnPreSendRequestHeaders(sender As Object, e As EventArgs) + 'HttpContext.Current.Response.Headers.Remove("Server"); + ' Or you can set something funny + HttpContext.Current.Response.Headers.[Set]("Server", "HAL 9000.l") + End Sub +End Class diff --git a/OpenAntragLib/DataDocumentStore.vb b/OpenAntragLib/DataDocumentStore.vb new file mode 100644 index 0000000..4828e0c --- /dev/null +++ b/OpenAntragLib/DataDocumentStore.vb @@ -0,0 +1,51 @@ +Imports System +Imports Raven.Client +Imports Raven.Client.Indexes +Imports System.Reflection +Imports Raven.Abstractions.Indexing +Imports System.Threading + +Public Class DataDocumentStore + + 'http://msdn.microsoft.com/pt-br/magazine/hh547101%28en-us%29.aspx + 'http://ravendb.net/docs/client-api/connecting-to-a-ravendb-datastore + + Private Shared _ds As IDocumentStore + + Public Shared Function Initialize() As IDocumentStore + + _ds = New Document.DocumentStore With {.ConnectionStringName = "RavenDBServer"} + + 'Predefined Indexes... + 'http://codeofrob.com/entries/ravendb-image-gallery-project-xiii--understanding-indexes.html + + _ds.Conventions.IdentityPartsSeparator = "-" + _ds.Initialize() + + IndexCreation.CreateIndexes(Assembly.GetCallingAssembly(), _ds) + + Return _ds + + End Function + + Public Shared ReadOnly Property Instance() As IDocumentStore + Get + If _ds Is Nothing Then + Throw New InvalidOperationException("IDocumentStore wurde nicht initialisiert") + End If + Return _ds + End Get + End Property + + Public Shared ReadOnly Property Session() As IDocumentSession + Get + Dim ses As IDocumentSession = DataDocumentStore.Instance.OpenSession + 'If ses Is Nothing Then + ' Thread.Sleep(10) + ' ses = DataDocumentStore.Instance.OpenSession + 'End If + Return ses + End Get + End Property + +End Class diff --git a/OpenAntragLib/Extensions/ControllerExtensions.vb b/OpenAntragLib/Extensions/ControllerExtensions.vb new file mode 100644 index 0000000..f1814a9 --- /dev/null +++ b/OpenAntragLib/Extensions/ControllerExtensions.vb @@ -0,0 +1,69 @@ +Imports System.IO +Imports System.Runtime.CompilerServices +Imports System.Web.Mvc + +''' +''' Controller extension class that adds controller methods +''' to render a partial view and return the result as string. +''' http://blog.janjonas.net/2011-06-18/aspnet-mvc3-controller-extension-method-render-partial-view-string +''' Based on http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ +''' +Public Module ControllerExtensions + + ''' + ''' Renders a (partial) view to string. + ''' + ''' Controller to extend + ''' (Partial) view to render + ''' Rendered (partial) view as string + _ + Public Function RenderPartialViewToString(controller As Controller, viewName As String) As String + Return controller.RenderPartialViewToString(viewName, Nothing) + End Function + + ''' + ''' Renders a (partial) view to string. + ''' + ''' Controller to extend + ''' (Partial) view to render + ''' Model + ''' Rendered (partial) view as string + _ + Public Function RenderPartialViewToString(controller As Controller, viewName As String, model As Object) As String + + If String.IsNullOrEmpty(viewName) Then + viewName = controller.ControllerContext.RouteData.GetRequiredString("action") + End If + + controller.ViewData.Model = model + + Dim strRetVal As String = "" + + Using sw = New StringWriter() + Try + Dim viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName) + + Dim viewContext = New ViewContext(controller.ControllerContext, + viewResult.View, + controller.ViewData, + controller.TempData, + sw) + + viewResult.View.Render(viewContext, sw) + + strRetVal = sw.GetStringBuilder().ToString().CleanHtmlCode + + Catch ex As Exception + 'Throw New Exception("Fehler beim Rendern vom " & viewName) + + Dim cei As New CustomErrorInfo With {.ErrorMessage = "Fehler bei der Darstellung von '" & viewName & "'"} + strRetVal = controller.RenderPartialViewToString("_ErrorBoxPartial", cei) + + End Try + End Using + + Return strRetVal + + End Function + +End Module diff --git a/OpenAntragLib/Extensions/GeneralExtensions.vb b/OpenAntragLib/Extensions/GeneralExtensions.vb new file mode 100644 index 0000000..3923208 --- /dev/null +++ b/OpenAntragLib/Extensions/GeneralExtensions.vb @@ -0,0 +1,11 @@ +Imports System.Runtime.CompilerServices + +Public Module GeneralExtensions + + + Public Sub GetPageData(Of T)(ByRef lst As List(Of T), + ByVal pageNo As Integer) + lst = lst.Skip((pageNo - 1) * SettingsWrapper.DefaultPagerListPageSize).Take(SettingsWrapper.DefaultPagerListPageSize).ToList() + End Sub + +End Module diff --git a/OpenAntragLib/Extensions/TagBuilderExtension.vb b/OpenAntragLib/Extensions/TagBuilderExtension.vb new file mode 100644 index 0000000..7a48ce9 --- /dev/null +++ b/OpenAntragLib/Extensions/TagBuilderExtension.vb @@ -0,0 +1,25 @@ +Imports System.Runtime.CompilerServices +Imports System.Web.Mvc +Imports System.Text + +Public Module TagBuilderExtension + + + Public Sub Append(tb As TagBuilder, value As String) + + Dim stb As New StringBuilder(tb.InnerHtml) + stb.Append(value) + tb.InnerHtml = stb.ToString + + End Sub + + + Public Sub Append(tb As TagBuilder, value As TagBuilder) + + Dim stb As New StringBuilder(tb.InnerHtml) + stb.Append(value.ToString) + tb.InnerHtml = stb.ToString + + End Sub + +End Module diff --git a/OpenAntragLib/FeedResult.vb b/OpenAntragLib/FeedResult.vb new file mode 100644 index 0000000..38bc708 --- /dev/null +++ b/OpenAntragLib/FeedResult.vb @@ -0,0 +1,48 @@ +Imports System.ServiceModel.Syndication +Imports System.Text +Imports System.Web +Imports System.Web.Mvc +Imports System.Xml + +'http://damieng.com/blog/2010/04/26/creating-rss-feeds-in-asp-net-mvc + +Public Class FeedResult + Inherits ActionResult + + Public Property ContentEncoding() As Encoding + Public Property ContentType() As String + + Private ReadOnly m_feed As SyndicationFeedFormatter + Public ReadOnly Property Feed() As SyndicationFeedFormatter + Get + Return m_feed + End Get + End Property + + Public Sub New(feed As SyndicationFeedFormatter) + Me.m_feed = feed + End Sub + + Public Overrides Sub ExecuteResult(context As ControllerContext) + + If context Is Nothing Then + Throw New ArgumentNullException("context") + End If + + Dim response As HttpResponseBase = context.HttpContext.Response + response.ContentType = If(Not String.IsNullOrEmpty(ContentType), ContentType, "application/rss+xml") + + If ContentEncoding IsNot Nothing Then + response.ContentEncoding = ContentEncoding + End If + + If m_feed IsNot Nothing Then + Using xmlWriter = New XmlTextWriter(response.Output) + xmlWriter.Formatting = Formatting.Indented + m_feed.WriteTo(xmlWriter) + End Using + End If + + End Sub + +End Class diff --git a/OpenAntragLib/GlobalData.vb b/OpenAntragLib/GlobalData.vb new file mode 100644 index 0000000..c9173c3 --- /dev/null +++ b/OpenAntragLib/GlobalData.vb @@ -0,0 +1,73 @@ +Public Class GlobalData + + Private Shared _Representations As Representations + Public Shared ReadOnly Property Representations As Representations + Get + If GlobalData._Representations Is Nothing Then + GlobalData._Representations = New Representations() + End If + Return _Representations + End Get + End Property + + Private Shared _piratenmandate As piratenmandate + Public Shared ReadOnly Property piratenmandate As piratenmandate + Get + If GlobalData._piratenmandate Is Nothing Then + GlobalData._piratenmandate = New piratenmandate() + End If + Return _piratenmandate + End Get + End Property + + Private Shared _ProcessStepDefinitions As ProcessStepDefinitions + Public Shared ReadOnly Property ProcessStepDefinitions As ProcessStepDefinitions + Get + If GlobalData._ProcessStepDefinitions Is Nothing Then + GlobalData._ProcessStepDefinitions = New ProcessStepDefinitions() + End If + Return _ProcessStepDefinitions + End Get + End Property + + Private Shared _GroupTypes As GroupTypes + Public Shared ReadOnly Property GroupTypes As GroupTypes + Get + If GlobalData._GroupTypes Is Nothing Then + GlobalData._GroupTypes = New GroupTypes() + End If + Return _GroupTypes + End Get + End Property + + Private Shared _FeedbackTypes As FeedbackTypes + Public Shared ReadOnly Property FeedbackTypes As FeedbackTypes + Get + If GlobalData._FeedbackTypes Is Nothing Then + GlobalData._FeedbackTypes = New FeedbackTypes() + End If + Return _FeedbackTypes + End Get + End Property + + Private Shared _FederalStates As FederalStates + Public Shared ReadOnly Property FederalStates As FederalStates + Get + If GlobalData._FederalStates Is Nothing Then + GlobalData._FederalStates = New FederalStates() + End If + Return _FederalStates + End Get + End Property + + Private Shared _GovernmentalLevels As GovernmentalLevels + Public Shared ReadOnly Property GovernmentalLevels As GovernmentalLevels + Get + If GlobalData._GovernmentalLevels Is Nothing Then + GlobalData._GovernmentalLevels = New GovernmentalLevels() + End If + Return _GovernmentalLevels + End Get + End Property + +End Class diff --git a/OpenAntragLib/Helper/MarkdownHelper.vb b/OpenAntragLib/Helper/MarkdownHelper.vb new file mode 100644 index 0000000..83bd821 --- /dev/null +++ b/OpenAntragLib/Helper/MarkdownHelper.vb @@ -0,0 +1,62 @@ +Imports System.Runtime.CompilerServices +Imports MarkdownDeep +Imports System.Web +Imports System.Web.Mvc + +'http://blog.dantup.com/2011/03/an-asp-net-mvc-htmlhelper-extension-method-for-markdown-using-markdownsharp + +Public Module MarkdownHelper + + ''' + ''' Transforms a string of Markdown into HTML. + ''' + ''' The Markdown that should be transformed. + ''' The HTML representation of the supplied Markdown. + Public Function Markdown(ByVal text As String, + Optional ByVal bolSafeMode As Boolean = True) As IHtmlString + + Dim md = New Markdown() + + md.ExtraMode = True + md.SafeMode = bolSafeMode + md.NewWindowForExternalLinks = True + + Dim html As String = md.Transform(text) + + Return New MvcHtmlString(html) + + End Function + + ''' + ''' Transforms a string of Markdown into Plain Text + ''' + ''' + ''' + ''' + Public Function MarkdownText(text As String) As String + + Dim str As String = Nothing + + Try + Dim md = New Markdown() + md.SummaryLength = -1 + str = md.Transform(text) + Catch ex As Exception + End Try + + Return str + + End Function + + ''' + ''' Transforms a string of Markdown into HTML. + ''' + ''' HtmlHelper - Not used, but required to make this an extension method. + ''' The Markdown that should be transformed. + ''' The HTML representation of the supplied Markdown. + _ + Public Function Markdown(helper As HtmlHelper, text As String) As MvcHtmlString + Return Markdown(text) + End Function + +End Module diff --git a/OpenAntragLib/Helper/PagerHelper.vb b/OpenAntragLib/Helper/PagerHelper.vb new file mode 100644 index 0000000..50f79d5 --- /dev/null +++ b/OpenAntragLib/Helper/PagerHelper.vb @@ -0,0 +1,178 @@ +Imports System.Runtime.CompilerServices +Imports System.Web.Mvc + +Public Module PagerHelper + + + Public Function Pager(htmlHelper As HtmlHelper, + m As PagerModel) As MvcHtmlString + + If m Is Nothing Then + Return MvcHtmlString.Empty + End If + + '--- Berechnung ------------------------------------------------------ + + Dim pagerLength = (m.PagerWingLength * 2) + 1 + If pagerLength > m.MaxPages Then pagerLength = m.MaxPages + + Dim pivotLeft As Integer = m.PagerWingLength + 1 + Dim pivotRight As Integer = m.MaxPages - m.PagerWingLength + + Dim pageFirst As Integer + Dim pageLast As Integer + + If m.CurrentPage <= pivotLeft Then + pageFirst = 1 + pageLast = pagerLength + ElseIf m.CurrentPage >= pivotRight Then + pageFirst = (m.MaxPages - pagerLength) + 1 + pageLast = m.MaxPages + Else + pageFirst = m.CurrentPage - m.PagerWingLength + pageLast = m.CurrentPage + m.PagerWingLength + End If + + 'Dim pageLast As Integer = m.TotalSize \ m.PageSize + 'If m.TotalSize Mod m.PageSize > 0 Then + ' pageLast += 1 + 'End If + + '------------------------------------------------------ + + Dim ePager As New TagBuilder("ul") + + 'Dim eDots As New TagBuilder("span") + 'eDots.SetInnerText("...") + + If m.CurrentPage > m.MaxPages Then + Dim eInfo As New TagBuilder("span") + eInfo.SetInnerText("Auf dieser Seite gibt es leider noch nichts zu sehen...") + ePager.Append(eInfo) + '-- + 'ePager.Append(eDots) + '-- + Dim ePageOne As New TagBuilder("a") + ePageOne.Attributes.Add("href", m.PageUrl.Replace("@Page", 1)) + ePageOne.SetInnerText("zurück zum Anfang") + ePager.Append(ePageOne) + '-- + Return MvcHtmlString.Create(ePager.ToString(TagRenderMode.Normal)) + End If + + '--- Direction LEFT ------------------------------------------------------ + + 'First + Dim eFirstOuter As New TagBuilder("li") + With eFirstOuter + Dim e As TagBuilder + If m.CurrentPage > 1 Then + e = New TagBuilder("a") + e.AddCssClass("tt-std") + e.Attributes.Add("title", "Erste Seite") + e.Attributes.Add("href", m.PageUrl.Replace("@Page", 1)) + Else + .AddCssClass("disabled") + e = New TagBuilder("span") + End If + e.Append(.ToString) + .AddCssClass("dir") + .Append(e) + End With + ePager.Append(eFirstOuter) + + 'Previous + Dim ePrevOuter As New TagBuilder("li") + With ePrevOuter + Dim e As TagBuilder + If m.CurrentPage > 1 Then + e = New TagBuilder("a") + e.AddCssClass("tt-std") + e.Attributes.Add("title", "Vorherige Seite") + e.Attributes.Add("href", m.PageUrl.Replace("@Page", m.CurrentPage - 1)) + Else + .AddCssClass("disabled") + e = New TagBuilder("span") + End If + e.Append(.ToString) + .AddCssClass("dir") + .Append(e) + End With + ePager.Append(ePrevOuter) + + '--- Wing ------------------------------------------------------ + + 'If intPageFirst > 1 Then eWing.Append(eDots) + + For i As Integer = pageFirst To pageLast + Dim ePageOuter As New TagBuilder("li") + With ePageOuter + Dim e As TagBuilder + If i = m.CurrentPage Then + .AddCssClass("active") + e = New TagBuilder("span") + Else + e = New TagBuilder("a") + e.AddCssClass("tt-std") + e.Attributes.Add("title", String.Concat("Seite ", i)) + e.Attributes.Add("href", m.PageUrl.Replace("@Page", i)) + End If + e.SetInnerText(i) + ePageOuter.Append(e) + End With + ePager.Append(ePageOuter) + Next + + 'If intPageLast < m.MaxPages Then eWing.Append(eDots) + + '--- Direction RIGHT ------------------------------------------------------ + + 'Next + Dim eNextOuter As New TagBuilder("li") + With eNextOuter + Dim e As TagBuilder + If m.CurrentPage < m.MaxPages Then + e = New TagBuilder("a") + e.AddCssClass("tt-std") + e.Attributes.Add("title", "Nächste Seite") + e.Attributes.Add("href", m.PageUrl.Replace("@Page", m.CurrentPage + 1)) + Else + .AddCssClass("disabled") + e = New TagBuilder("span") + End If + e.Append(.ToString) + .AddCssClass("dir") + .Append(e) + End With + ePager.Append(eNextOuter) + + 'Last + Dim eLastOuter As New TagBuilder("li") + With eLastOuter + Dim e As TagBuilder + If m.CurrentPage < m.MaxPages Then + e = New TagBuilder("a") + e.AddCssClass("tt-std") + e.Attributes.Add("title", "Letzte Seite") + e.Attributes.Add("href", m.PageUrl.Replace("@Page", m.MaxPages)) + Else + .AddCssClass("disabled") + e = New TagBuilder("span") + End If + e.Append(.ToString) + .AddCssClass("dir") + .Append(e) + End With + ePager.Append(eLastOuter) + + '------------------------------------------------------ + + Dim ePagerWrapper As New TagBuilder("div") + ePagerWrapper.AddCssClass("pagination") + ePagerWrapper.Append(ePager) + + Return MvcHtmlString.Create(ePagerWrapper.ToString(TagRenderMode.Normal)) + + End Function + +End Module diff --git a/OpenAntragLib/Helper/PartialHelper.vb b/OpenAntragLib/Helper/PartialHelper.vb new file mode 100644 index 0000000..426e2ac --- /dev/null +++ b/OpenAntragLib/Helper/PartialHelper.vb @@ -0,0 +1,181 @@ +Imports System.Collections.Generic +Imports System.Linq +Imports System.Text +Imports System.Web.Mvc +Imports System.Web.Mvc.Html +Imports System.Web.WebPages +Imports System.IO +Imports System.Globalization +Imports System.Runtime.CompilerServices + +Public Module PartialExtensions + + 'http://aspnet.codeplex.com/workitem/8872 + 'https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs + + ' copied from HtmlHelper.FindPartialView because it's original is internal + Public Function FindPartialView(viewContext As ViewContext, + partialViewName As String, + viewEngineCollection As ViewEngineCollection) As IView + + Dim result As ViewEngineResult = viewEngineCollection.FindPartialView(viewContext, partialViewName) + + If result.View IsNot Nothing Then + Return result.View + End If + + Dim builder As New StringBuilder() + + For Each str As String In result.SearchedLocations + builder.AppendLine() + builder.Append(str) + Next + + Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "The partial view '{0}' was not found or no view engine supports the searched locations. The following locations were searched:{1}", New Object() {partialViewName, builder})) + + End Function + + ' copied from HtmlHelper.RenderPartialInternal (thanks Red Gate!) + ' modified the logics to OrNull functionality + Public Sub RenderPartialInternalOrNull(htmlHelper As HtmlHelper, + partialViewName As String, + viewData As ViewDataDictionary, + model As Object, + writer As TextWriter, + viewEngineCollection As ViewEngineCollection) + + If String.IsNullOrEmpty(partialViewName) Then + Throw New ArgumentNullException("partialViewName") + End If + Dim dictionary As New ViewDataDictionary(If(viewData, htmlHelper.ViewData)) + + ' we explicitly set the model here so we don't get the current Model as fallback. + dictionary.Model = model + + Dim viewContext As New ViewContext(htmlHelper.ViewContext, htmlHelper.ViewContext.View, dictionary, htmlHelper.ViewContext.TempData, writer) + FindPartialView(viewContext, partialViewName, viewEngineCollection).Render(viewContext, writer) + + End Sub + + ''' + ''' Renders the specified partial view as an HTML-encoded string (even if the model is null). + ''' This is a safer method than the normal HtmlHelper.Partial() because that one will use the current Model as a fallback when the given model is null. + ''' + ''' The HTML helper instance that this method extends. + ''' The name of the partial view to render. + ''' The model for the partial view, may be null + ''' A new dictionary or null (in which case the current view data is used as a fallback) + ''' + _ + Public Function PartialOrNull(htmlHelper As HtmlHelper, partialViewName As String, model As Object, Optional viewData As ViewDataDictionary = Nothing) As MvcHtmlString + Using writer As New StringWriter(CultureInfo.CurrentCulture) + RenderPartialInternalOrNull(htmlHelper, partialViewName, viewData, model, writer, ViewEngines.Engines) + Return MvcHtmlString.Create(writer.ToString()) + End Using + End Function + + ''' + ''' Renders the specified partial view as an HTML-encoded string unless the model is null. + ''' Note that the partial is not exectued when the model is null. + ''' + ''' The HTML helper instance that this method extends. + ''' The name of the partial view to render. + ''' The model for the partial view, may be null + ''' A new dictionary or null (in which case the current view data is used as a fallback) + ''' The partial view that is rendered as an HTML-encoded string or null if the model is null. + + Public Function PartialOrDiscard(htmlHelper As HtmlHelper, partialViewName As String, model As Object, Optional viewData As ViewDataDictionary = Nothing) As MvcHtmlString + If model Is Nothing Then + Return Nothing + End If + Return htmlHelper.[Partial](partialViewName, model, viewData) + End Function + + ''' + ''' Renders the specified partial view as an HTML-encoded string unless the model is null. + ''' The given wrapper is used to wrap around the output of the partial result, it uses the Razor @item to place the partial output within the wrapper's template. + ''' Note the partial and the wrapper are not exectued when the model is null. + ''' + ''' + ''' Note that the partial is rendered before wrapper is executed (should there be side-effects in either of them). + ''' + ''' The HTML helper instance that this method extends. + ''' The name of the partial view to render. + ''' The model for the partial view, may be null + ''' This wrapper is excuted when the model is not null, use @item to render the output of the partial + ''' A new dictionary or null (in which case the current view data is used as a fallback) + ''' The partial view that is rendered as an HTML-encoded string or null if the model is null. + + Public Function PartialOrDiscard(htmlHelper As HtmlHelper, + partialViewName As String, + model As Object, + wrapper As Func(Of MvcHtmlString, HelperResult), + Optional viewData As ViewDataDictionary = Nothing) As HelperResult + + If model Is Nothing Then + Return Nothing + End If + + 'krze: 'Function' geändert zu 'Sub' !? + Return New HelperResult(Sub(writer) + Dim partialResult = htmlHelper.[Partial](partialViewName, model, viewData) + wrapper(partialResult).WriteTo(writer) + End Sub) + End Function + + ''' + ''' Renders the specified partial view as an HTML-encoded string unless the model is null or empty. + ''' Note that the partial is not exectued when the model is null or empty. + ''' + ''' + ''' The enumerable passed into the model is checked with Any() to see whether it is empty. + ''' In case of a LINQ query this may cause the enumerable to be called twice (once for the Any() check and once propably inside the partial). + ''' + ''' The HTML helper instance that this method extends. + ''' The name of the partial view to render. + ''' The model for the partial view, may be null or an empty enumerable + ''' A new dictionary or null (in which case the current view data is used as a fallback) + ''' The partial view that is rendered as an HTML-encoded string or null if the model is null or empty. + + Public Function PartialOrDiscardIfEmpty(htmlHelper As HtmlHelper, partialViewName As String, model As IEnumerable(Of Object), Optional viewData As ViewDataDictionary = Nothing) As MvcHtmlString + If model Is Nothing OrElse Not model.Any() Then + Return Nothing + End If + Return htmlHelper.[Partial](partialViewName, model, viewData) + End Function + + ''' + ''' Renders the specified partial view as an HTML-encoded string unless the model is null or empty.
          + ''' The given wrapper is used to wrap around the output of the partial result, it uses the Razor @item to place the partial output within the wrapper's template. + ''' Note the partial and the wrapper are not exectued when the model is null or empty. + '''
          + ''' + ''' The enumerable passed into the model is checked with Any() to see whether it is empty. + ''' In case of a LINQ query this may cause the enumerable to be called twice (once for the Any() check and once propably inside the partial). + ''' Note that the partial is rendered before wrapper is executed (should there be side-effects in either of them). + ''' + ''' The HTML helper instance that this method extends. + ''' The name of the partial view to render. + ''' The model for the partial view, may be null or an empty enumerable + ''' This wrapper is excuted when the model is not null or empty, use @item to render the output of the partial + ''' A new dictionary or null (in which case the current view data is used as a fallback) + ''' The partial view that is rendered as an HTML-encoded string or null if the model is null or empty. + + Public Function PartialOrDiscardIfEmpty(htmlHelper As HtmlHelper, + partialViewName As String, + model As IEnumerable(Of Object), + wrapper As Func(Of MvcHtmlString, HelperResult), + Optional viewData As ViewDataDictionary = Nothing) As HelperResult + + If model Is Nothing OrElse Not model.Any() Then + Return Nothing + End If + + 'krze: 'Function' geändert zu 'Sub' !? + Return New HelperResult(Sub(writer) + Dim partialResult = htmlHelper.[Partial](partialViewName, model, viewData) + wrapper(partialResult).WriteTo(writer) + End Sub) + End Function + +End Module diff --git a/OpenAntragLib/HtmlHelperExtensions.vb b/OpenAntragLib/HtmlHelperExtensions.vb new file mode 100644 index 0000000..be9f6a4 --- /dev/null +++ b/OpenAntragLib/HtmlHelperExtensions.vb @@ -0,0 +1,27 @@ +Imports System.ComponentModel +Imports System.Runtime.CompilerServices +Imports System.Web.Mvc +Imports System.Web.Mvc.Html + +Public Module HtmlHelperExtensions + + + Public Sub RenderPartialWithData(htmlHelper As HtmlHelper, + partialViewName As String, + model As Object, + viewData As Object) + + Dim viewDataDictionary = New ViewDataDictionary() + + If viewData IsNot Nothing Then + For Each prop As PropertyDescriptor In TypeDescriptor.GetProperties(viewData) + Dim val As Object = prop.GetValue(viewData) + viewDataDictionary(prop.Name) = val + Next + End If + + htmlHelper.RenderPartial(partialViewName, model, viewDataDictionary) + + End Sub + +End Module diff --git a/OpenAntragLib/Interfaces/IXMLClass.vb b/OpenAntragLib/Interfaces/IXMLClass.vb new file mode 100644 index 0000000..f9f1722 --- /dev/null +++ b/OpenAntragLib/Interfaces/IXMLClass.vb @@ -0,0 +1,5 @@ +Public Interface IXMLClass + + Function GetXElement(xD As XmlData) As XElement + +End Interface diff --git a/OpenAntragLib/Libraries/LinqToTwitter.dll b/OpenAntragLib/Libraries/LinqToTwitter.dll new file mode 100644 index 0000000..3be818b Binary files /dev/null and b/OpenAntragLib/Libraries/LinqToTwitter.dll differ diff --git a/OpenAntragLib/Manager/MailManager.vb b/OpenAntragLib/Manager/MailManager.vb new file mode 100644 index 0000000..cf19a5b --- /dev/null +++ b/OpenAntragLib/Manager/MailManager.vb @@ -0,0 +1,69 @@ +Imports ActionMailer.Net.Mvc + +Public Module MailManager + + Public Sub SendResetPasswordToUser(model As ResetPasswordModel) + + If SettingsWrapper.SendMail = True Then + Try + If Not String.IsNullOrEmpty(model.MailAddress) Then + Dim mc As New MailController + Dim result As EmailResult = mc.ResetPassword(model) + result.Deliver() + End If + Catch ex As Exception + PushoverManager.SendError("SendResetPasswordToUser", ex) + End Try + End If + + End Sub + + Public Sub SendNewProposal(model As Proposal) + + If SettingsWrapper.SendMail = True Then + Try + If Not String.IsNullOrEmpty(model.Representation.InfoMail) Then + Dim mc As New MailController + Dim result As EmailResult = mc.NewProposal(model) + result.Deliver() + End If + Catch ex As Exception + PushoverManager.SendError("SendNewProposal", ex) + End Try + End If + + End Sub + + Public Sub SendNewProposalComment(model As ProposalComment, prop As Proposal) + + If SettingsWrapper.SendMail = True Then + Try + If Not String.IsNullOrEmpty(prop.Representation.InfoMail) Then + Dim mc As New MailController + Dim result As EmailResult = mc.NewProposalComment(model, prop) + result.Deliver() + End If + Catch ex As Exception + PushoverManager.SendError("SendNewProposalComment", ex) + End Try + End If + + End Sub + + Public Sub SendNewProposalAbuseNotice(model As ProposalAbuseNotice) + + If SettingsWrapper.SendMail = True Then + Try + If Not String.IsNullOrEmpty(model.Proposal.Representation.InfoMail) Then + Dim mc As New MailController + Dim result As EmailResult = mc.NewProposalAbuseNotice(model) + result.Deliver() + End If + Catch ex As Exception + PushoverManager.SendError("SendNewProposalAbuseNotice", ex) + End Try + End If + + End Sub + +End Module diff --git a/OpenAntragLib/Manager/NotificationManager.vb b/OpenAntragLib/Manager/NotificationManager.vb new file mode 100644 index 0000000..34a9d04 --- /dev/null +++ b/OpenAntragLib/Manager/NotificationManager.vb @@ -0,0 +1,199 @@ +Imports Raven.Client +Imports System.Text +Imports System.Web + +Public Enum NotificationTypes + Post = 0 + NewProposal = 1 + NewProposalComment = 2 + NewFeedback = 3 + NewFeedbackComment = 4 + NextProposalStep = 5 + SuccessStories = 6 +End Enum + +Public Module NotificationManager + + Public Sub StoreNewPost(strTitle As String, strText As String) + + Try + Dim nf As New Notification(NotificationTypes.Post, + Nothing, + strTitle, + strText, + Nothing) + StoreNotification(nf) + Catch ex As Exception + End Try + + End Sub + + Public Sub StoreNewProposal(ByVal model As Proposal) + + If model.IsTest = False Then + Try + Dim stbTitle As New StringBuilder + stbTitle.Append(model.Representation.Label).Append(": ") + stbTitle.Append("Neuer Antrag ") + stbTitle.Append("'").Append(model.Title).Append("'") + + Dim stbText As New StringBuilder + stbText.Append(model.TextRaw.CutEllipsis(100)) + + Dim nf As New Notification(NotificationTypes.NewProposal, + model.Representation, + stbTitle.ToString, + stbText.ToString, + model.FullUrl) + StoreNotification(nf) + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub StoreNewProposalComment(model As ProposalComment, prop As Proposal) + + If prop.IsTest = False Then + Try + Dim stbTitle As New StringBuilder + stbTitle.Append(prop.Representation.Label).Append(": ") + stbTitle.Append("Antragskommentar von ") + stbTitle.Append("'").Append(model.CommentedBy).Append("'") + + Dim stbText As New StringBuilder + stbText.Append(prop.Title).Append(": ") + stbText.Append(model.CommentText.CutEllipsis(50)) + + Dim stbUrl As New StringBuilder() + stbUrl.Append(prop.FullUrl) + stbUrl.Append("#comments") + + Dim nf As New Notification(NotificationTypes.NewProposalComment, + prop.Representation, + stbTitle.ToString, + stbText.ToString, + stbUrl.ToString) + StoreNotification(nf) + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub StoreNextProposalStep(ByVal prop As Proposal) + + If prop.IsTest = False Then + Try + prop.FillProcessSteps() + Dim ps As ProposalStep = prop.CurrentProposalStep + + Dim stbTitle As New StringBuilder() + stbTitle.Append(ps.ProcessStep.Representation.Label).Append(": ") + stbTitle.Append(ps.ProcessStep.ShortCaption) + + Dim stbText As New StringBuilder + stbText.Append(prop.Title).Append(": ") + stbText.Append(ps.InfoText.CutEllipsis(100)) + + Dim nf As New Notification(NotificationTypes.NextProposalStep, + ps.ProcessStep.Representation, + stbTitle.ToString, + stbText.ToString, + prop.FullUrl.ToString) + StoreNotification(nf) + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub StoreNewFeedback(ByVal feedback As Feedback) + + Try + Dim stbTitle As New StringBuilder() + stbTitle.Append("Neues Feedback ") + stbTitle.Append("(").Append(feedback.TypeObject.Name).Append(")") + stbTitle.Append(" von ") + stbTitle.Append("'").Append(feedback.CreatedBy).Append("'") + + Dim stbText As New StringBuilder + stbText.Append(feedback.Title).Append(": ") + stbText.Append(feedback.MessageText.CutEllipsis(100)) + + Dim stbUrl As New StringBuilder() + stbUrl.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stbUrl.Append("/feedback") + stbUrl.Append("#").Append(feedback.IdNumber) + + Dim nf As New Notification(NotificationTypes.NewFeedback, + Nothing, + stbTitle.ToString, + stbText.ToString, + stbUrl.ToString) + StoreNotification(nf) + Catch ex As Exception + End Try + + End Sub + + Public Sub StoreNewFeedbackComment(ByVal feedback As Feedback, comment As FeedbackComment) + + Try + Dim stbTitle As New StringBuilder() + stbTitle.Append("Feedback-Kommentar von ") + stbTitle.Append("'").Append(comment.CommentedBy).Append("'") + + Dim stbText As New StringBuilder + stbText.Append(feedback.Title).Append(": ") + stbText.Append(comment.CommentText.CutEllipsis(50)) + + Dim stbUrl As New StringBuilder() + stbUrl.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stbUrl.Append("/feedback") + stbUrl.Append("#").Append(feedback.IdNumber) + + Dim nf As New Notification(NotificationTypes.NewFeedbackComment, + Nothing, + stbTitle.ToString, + stbText.ToString, + stbUrl.ToString) + StoreNotification(nf) + Catch ex As Exception + End Try + + End Sub + + Private Sub StoreNotification(nf As Notification) + + Using ds As IDocumentSession = DataDocumentStore.Session() + ds.Store(nf) + ds.SaveChanges() + End Using + End Sub + + Public Sub StoreNewSuccessStory(ByVal model As SuccessStory) + + If model.Proposal.IsTest = False Then + Try + Dim stbTitle As New StringBuilder + stbTitle.Append("Erfolgsgeschichte in ") + stbTitle.Append(model.Proposal.Representation.Label).Append(": ") + stbTitle.Append("'").Append(model.Title).Append("'") + + Dim stbText As New StringBuilder + stbText.Append(model.TextRaw.CutEllipsis(100)) + + Dim nf As New Notification(NotificationTypes.SuccessStories, + model.Proposal.Representation, + stbTitle.ToString, + stbText.ToString, + model.FullUrl) + StoreNotification(nf) + Catch ex As Exception + End Try + End If + + End Sub + +End Module diff --git a/OpenAntragLib/Manager/PushbulletManager.vb b/OpenAntragLib/Manager/PushbulletManager.vb new file mode 100644 index 0000000..cd77cb7 --- /dev/null +++ b/OpenAntragLib/Manager/PushbulletManager.vb @@ -0,0 +1,99 @@ +Imports System.Net +Imports System.Text +Imports System.Web + +Public Module PushbulletManager + + 'https://docs.pushbullet.com/http/ + + Public Sub Send(pb As PushbulletMessage) + + Try + Using webClient As New WebClient + + Dim strToken As String = SettingsWrapper.PushbulletAccessToken + webClient.Headers(HttpRequestHeader.Authorization) = String.Format("Bearer {0}", strToken) + + webClient.UploadValues(New Uri(SettingsWrapper.PushbulletApiUrl), pb.Params) + End Using + Catch ex As Exception + End Try + + End Sub + + Public Sub SendNewProposal(ByVal model As Proposal) + + Try + Dim stbTitle As New StringBuilder("Neuer Antrag in ") + stbTitle.Append(model.Representation.Label) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Id).Append(": ") + stbMsg.Append(model.Title) + + Dim pb As New PushbulletMessage(stbTitle.ToString, stbMsg.ToString, model.FullUrl) + Send(pb) + + Catch ex As Exception + End Try + + End Sub + + Public Sub SendNewSuccessStory(ByVal model As SuccessStory) + + Try + Dim stbTitle As New StringBuilder("Neue Erfolgsgeschichte in ") + stbTitle.Append(model.Proposal.Representation.Label) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Id).Append(": ") + stbMsg.Append(model.Title) + + Dim pb As New PushbulletMessage(stbTitle.ToString, stbMsg.ToString, model.FullUrl) + Send(pb) + + Catch ex As Exception + End Try + + End Sub + + Public Sub SendNewFeedback(ByVal model As Feedback) + + Try + Dim stbTitle As New StringBuilder() + stbTitle.Append("Neues Feedback ") + stbTitle.Append("[").Append(model.TypeObject.Name).Append("]") + stbTitle.Append(" von ") + stbTitle.Append(model.CreatedBy) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Title).Append(" : ").Append(model.MessageText) + + Dim stbUrl As New StringBuilder() + stbUrl.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stbUrl.Append("/feedback") + + Dim pb As New PushbulletMessage(stbTitle.ToString, stbMsg.ToString, stbUrl.ToString) + Send(pb) + + Catch ex As Exception + End Try + + End Sub + + Public Sub SendNewPost(ByVal strTitle As String, strText As String) + + Try + Dim stb As New StringBuilder + stb.Append(strTitle) + stb.Append(" - ").Append(strText) + + Dim pb As New PushbulletMessage(strTitle, strText) + Send(pb) + + Catch ex As Exception + End Try + + End Sub + +End Module diff --git a/OpenAntragLib/Manager/PushbulletMessage.vb b/OpenAntragLib/Manager/PushbulletMessage.vb new file mode 100644 index 0000000..b4445c8 --- /dev/null +++ b/OpenAntragLib/Manager/PushbulletMessage.vb @@ -0,0 +1,33 @@ +Imports System.Collections.Specialized + +Public Class PushbulletMessage + + Public Params As NameValueCollection + + Public Sub New(strTitle As String, + strBody As String) + + Params = New NameValueCollection + + Params.Add("type", "note") + Params.Add("title", strTitle) + Params.Add("body", strBody) + Params.Add("channel_tag", "openantrag") + + End Sub + + Public Sub New(strTitle As String, + strBody As String, + strUrl As String) + + Params = New NameValueCollection + + Params.Add("type", "link") + Params.Add("url", strUrl) + Params.Add("title", strTitle) + Params.Add("body", strBody) + Params.Add("channel_tag", "openantrag") + + End Sub + +End Class diff --git a/OpenAntragLib/Manager/PushoverManager.vb b/OpenAntragLib/Manager/PushoverManager.vb new file mode 100644 index 0000000..be59f94 --- /dev/null +++ b/OpenAntragLib/Manager/PushoverManager.vb @@ -0,0 +1,175 @@ +Imports System.Text +Imports System.Web +Imports System.Net + +Public Module PushoverManager + +#Region "Owner Messages" + + Public Sub Send(title As String, msg As String) + Dim pm As New PushoverMessage(title, msg) + Send(pm) + End Sub + + Public Sub Send(pm As PushoverMessage) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Using webClient = New WebClient + webClient.UploadValues(New Uri(SettingsWrapper.PushoverApiUrl), pm.Params) + End Using + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub SendError(ByVal methodName As String, ByVal exc As Exception) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder("ERROR in ") + stbTitle.Append(methodName) + + Dim stbMsg As New StringBuilder + stbMsg.Append(exc.Message) + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString) + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub SendNewProposal(ByVal model As Proposal) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder("Neuer Antrag in ") + stbTitle.Append(model.Representation.Label) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Id).Append(": ") + stbMsg.Append(model.Title) + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, model.FullUrl, "") + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + + 'Public Sub SendNewProposalComment(model As ProposalComment, prop As Proposal) + + ' If SettingsWrapper.SendPushoverNotification = True Then + ' Try + ' Dim stbTitle As New StringBuilder("Antragskommentar in ") + ' stbTitle.Append(prop.Representation.Key) + + ' Dim stbMsg As New StringBuilder + ' stbMsg.Append(prop.Title).Append(" : ") + ' stbMsg.Append(Left(model.CommentText, 50)).Append("...") + + ' Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, prop.FullUrl, "") + ' Send(poMessage) + + ' Catch ex As Exception + ' End Try + ' End If + + 'End Sub + + Public Sub SendNewProposalAbuseNotice(model As ProposalAbuseNotice) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder("Missbrauchsmeldung für ") + stbTitle.Append(model.Proposal.Title) + + Dim stbMsg As New StringBuilder + stbMsg.Append(Left(model.Notice, 50)).Append("...") + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, model.Proposal.FullUrl, "", True) + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub SendNewSuccessStory(ByVal model As SuccessStory) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder("Neue Erfolgsgeschichte in ") + stbTitle.Append(model.Proposal.Representation.Label) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Id).Append(": ") + stbMsg.Append(model.Title) + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, + model.FullUrl, + "") + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub SendNewFeedback(ByVal model As Feedback) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder() + stbTitle.Append("Neues Feedback ") + stbTitle.Append("[").Append(model.TypeObject.Name).Append("]") + stbTitle.Append(" von ") + stbTitle.Append(model.CreatedBy) + + Dim stbMsg As New StringBuilder + stbMsg.Append(model.Title).Append(" : ").Append(model.MessageText) + + Dim stbUrl As New StringBuilder() + stbUrl.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stbUrl.Append("/feedback") + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, True, stbUrl.ToString) + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub SendNewFeedbackComment(ByVal feedback As Feedback, comment As FeedbackComment) + + If SettingsWrapper.SendPushoverNotification = True Then + Try + Dim stbTitle As New StringBuilder() + stbTitle.Append("Feedback-Kommentar auf '") + stbTitle.Append(feedback.Title).Append("'") + + Dim stbMsg As New StringBuilder + stbMsg.Append(comment.CommentText) + + Dim poMessage As New PushoverMessage(stbTitle.ToString, stbMsg.ToString, True) + Send(poMessage) + + Catch ex As Exception + End Try + End If + + End Sub + +#End Region + +End Module diff --git a/OpenAntragLib/Manager/PushoverMessage.vb b/OpenAntragLib/Manager/PushoverMessage.vb new file mode 100644 index 0000000..61388f7 --- /dev/null +++ b/OpenAntragLib/Manager/PushoverMessage.vb @@ -0,0 +1,94 @@ + +Imports System.Collections.Specialized + +Public Class PushoverMessage + + Public Params As NameValueCollection + + Public Sub New(strUser As String, + strTitle As String, + strMessage As String) + + Params = New NameValueCollection + + Params.Add("token", SettingsWrapper.PushoverAppToken) + Params.Add("user", strUser) + Params.Add("title", strTitle) + Params.Add("message", strMessage) + + End Sub + + Public Sub New(strUser As String, + strTitle As String, + strMessage As String, + strUrl As String, + strUrlTitle As String) + + Me.New(strUser, strTitle, strMessage) + + If String.IsNullOrEmpty(strUrl) = False Then + Params.Add("url", strUrl) + End If + + If String.IsNullOrEmpty(strUrlTitle) = False Then + Params.Add("url_title", strUrlTitle) + End If + + End Sub + + Public Sub New(strTitle As String, + strMessage As String) + + Params = New NameValueCollection + + Params.Add("token", SettingsWrapper.PushoverAppToken) + Params.Add("user", SettingsWrapper.PushoverUserKey) + Params.Add("title", strTitle) + Params.Add("message", strMessage) + + End Sub + + Public Sub New(strTitle As String, + strMessage As String, + bolHighPriority As Boolean) + + Me.New(strTitle, strMessage) + + If bolHighPriority = True Then + Params.Add("priority", "1") + End If + + End Sub + + Public Sub New(strTitle As String, + strMessage As String, + strUrl As String, + strUrlTitle As String) + + Me.New(strTitle, strMessage) + + If String.IsNullOrEmpty(strUrl) = False Then + Params.Add("url", strUrl) + End If + + If String.IsNullOrEmpty(strUrlTitle) = False Then + Params.Add("url_title", strUrlTitle) + End If + + End Sub + + Public Sub New(strTitle As String, + strMessage As String, + strUrl As String, + strUrlTitle As String, + bolHighPriority As Boolean) + + Me.New(strTitle, strMessage, strUrl, strUrlTitle) + + If bolHighPriority = True Then + Params.Add("priority", "1") + End If + + End Sub + +End Class diff --git a/OpenAntragLib/Manager/StatisticsManager.vb b/OpenAntragLib/Manager/StatisticsManager.vb new file mode 100644 index 0000000..c35c205 --- /dev/null +++ b/OpenAntragLib/Manager/StatisticsManager.vb @@ -0,0 +1,76 @@ +Imports Raven.Client + +Public Module StatisticsManager + + Public Sub GetProposalCountByRepresentationData(ByRef lstCategories As List(Of String), + ByRef lstData As List(Of BarColumnDataSDM)) + + Dim lst As List(Of ProposalCountByRepresentationRIM) + + Using ds As IDocumentSession = DataDocumentStore.Session + Dim query = ds.Query(Of ProposalCountByRepresentationRIM)("Statistics/ProposalCountByRepresentation") + lst = query.ToList() + End Using + + lst = lst.OrderByDescending(Function(m) m.Count).ToList() + + 'Dim rps As New Representations() + + For Each m As ProposalCountByRepresentationRIM In lst + Dim rep As Representation = (From r As Representation In GlobalData.Representations.Items + Where r.Key = m.Key + Select r).First() + + If rep.Status And Representations.StatusConjuction.Active Then + lstCategories.Add(rep.Label.BreakWordsHtml(15)) + + lstData.Add(New BarColumnDataSDM With {.y = m.Count, + .color = rep.Color, + .url = rep.FullUrl}) + End If + Next + + End Sub + + Public Sub GetRepresentationCountByType(ByRef lstData As List(Of PieSliceDataSDM)) + + 'Dim rps As New Representations(Representations.StatusConjuction.Active) + Dim lst As List(Of Representation) = GlobalData.Representations.Items _ + .Where(Function(x) (x.Status And (Representations.StatusConjuction.Active)) > 0) _ + .ToList() + + Dim query = From rp In lst + Group rp By rpg = New With {Key .Common = rp.GroupTypeObject.Common, + Key .Color = rp.GroupTypeObject.Color} + Into Group + Select New PieSliceDataSDM With { + .y = Group.Count, + .name = rpg.Common, + .color = rpg.Color} + + lstData = query.ToList() + + End Sub + + Public Sub GetFeedbackCountByType(ByRef lstData As List(Of PieSliceDataSDM)) + + Dim lst As List(Of FeedbackCountByTypeRIM) + + Using ds As IDocumentSession = DataDocumentStore.Session + Dim query = ds.Query(Of FeedbackCountByTypeRIM)("Statistics/FeedbackCountByType") + lst = query.ToList() + End Using + + For Each m As FeedbackCountByTypeRIM In lst + Dim fbt As FeedbackType = (From f As FeedbackType In GlobalData.FeedbackTypes.Items + Where f.ID = m.Type + Select f).FirstOrDefault() + + lstData.Add(New PieSliceDataSDM() With {.y = m.Count, + .name = fbt.Name, + .color = fbt.Color}) + Next + + End Sub + +End Module diff --git a/OpenAntragLib/Manager/TwitterManager.vb b/OpenAntragLib/Manager/TwitterManager.vb new file mode 100644 index 0000000..9d3f92b --- /dev/null +++ b/OpenAntragLib/Manager/TwitterManager.vb @@ -0,0 +1,88 @@ +Imports LinqToTwitter +Imports System.Text + +Public Class TwitterWrapper + + Private ReadOnly _Context As TwitterContext + Public ReadOnly Property Context As TwitterContext + Get + Return _Context + End Get + End Property + + Public Sub New() + + Dim auth As New LinqToTwitter.SingleUserAuthorizer With { + .Credentials = New InMemoryCredentials With { + .ConsumerKey = SettingsWrapper.TwitterConsumerKey, + .ConsumerSecret = SettingsWrapper.TwitterConsumerSecret, + .AccessToken = SettingsWrapper.TwitterAccessTokenSecret, + .OAuthToken = SettingsWrapper.TwitterAccessToken}} + + _Context = New TwitterContext(auth) + + End Sub + +End Class + +Public Module TwitterManager + + Public Sub TweetNewProposal(ByVal model As Proposal) + + If SettingsWrapper.SendTweets = True And model.IsTest = False Then + Try + Dim stb As New StringBuilder + If String.IsNullOrEmpty(model.Representation.Twitter) = False Then + stb.Append("@").Append(model.Representation.Twitter).Append(" ") + End If + stb.Append("Neuer Antrag für ") + stb.Append("#").Append(model.Representation.Key) + stb.Append(" : ").Append(model.Title) + stb.Append(" - ").Append(model.ShortUrl) + + Dim tw As New TwitterWrapper + tw.Context.UpdateStatus(stb.ToString) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub TweetNewPost(ByVal strTitle As String, strText As String) + + If SettingsWrapper.SendTweets = True Then + Try + Dim stb As New StringBuilder + stb.Append(strTitle) + stb.Append(" - ").Append(strText) + + Dim tw As New TwitterWrapper + tw.Context.UpdateStatus(stb.CutEllipsis(140)) + + Catch ex As Exception + End Try + End If + + End Sub + + Public Sub TweetNewSuccessStory(ByVal model As SuccessStory) + + If SettingsWrapper.SendTweets = True And model.Proposal.IsTest = False Then + Try + Dim stb As New StringBuilder + stb.Append("Erfolgsgeschichte in ") + stb.Append("#").Append(model.Proposal.Representation.Key) + stb.Append(" : ").Append(model.Title) + stb.Append(" - ").Append(model.ShortUrl) + + Dim tw As New TwitterWrapper + tw.Context.UpdateStatus(stb.ToString) + + Catch ex As Exception + End Try + End If + + End Sub + +End Module diff --git a/OpenAntragLib/Models/Account/ChangePasswordModel.vb b/OpenAntragLib/Models/Account/ChangePasswordModel.vb new file mode 100644 index 0000000..6d9af3e --- /dev/null +++ b/OpenAntragLib/Models/Account/ChangePasswordModel.vb @@ -0,0 +1,43 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web +Imports System.Web.Security + +Public Class ChangePasswordModel + + Private _User As MembershipUser + + Public Sub New() + If String.IsNullOrEmpty(_UserName) = True Then + _User = Membership.GetUser(HttpContext.Current.User.Identity.Name) + End If + End Sub + + Private _UserName As String + Public Property UserName() As String + Get + Return _User.UserName + End Get + Set(value As String) + _User = Membership.GetUser(value) + End Set + End Property + + + + + Public Property OldPassword() As String + + + + + + Public Property NewPassword() As String + + + + + + Public Property ConfirmPassword() As String + +End Class + diff --git a/OpenAntragLib/Models/Account/LogonModel.vb b/OpenAntragLib/Models/Account/LogonModel.vb new file mode 100644 index 0000000..cd94aa8 --- /dev/null +++ b/OpenAntragLib/Models/Account/LogonModel.vb @@ -0,0 +1,19 @@ +Imports System.ComponentModel.DataAnnotations + +Public Class LogonModel + + + + Public Property UserName() As String + + + + + Public Property Password() As String + + + Public Property RememberMe() As Boolean + + Public Property ReturnUrl As String + +End Class diff --git a/OpenAntragLib/Models/Account/Member.vb b/OpenAntragLib/Models/Account/Member.vb new file mode 100644 index 0000000..5749a88 --- /dev/null +++ b/OpenAntragLib/Models/Account/Member.vb @@ -0,0 +1,46 @@ +Imports System.ComponentModel.DataAnnotations +Imports Raven.Client +Imports System.Web.Script.Serialization +Imports System.IO +Imports System.Web.Security + +Public Class Member + + ' + + Public ReadOnly Property User As MembershipUser + Get + If String.IsNullOrEmpty(Me.UserName) = False Then + Return Membership.GetUser(Me.UserName) + Else + Return Nothing + End If + End Get + End Property + + + Public Property Id As String + + + Public Property UserKey As String + + + Public Property UserName() As String + + + Public Property Mail() As String + + + Public Property APIKey As String + + + Public ReadOnly Property HasAPIKey As Boolean + Get + Return Not String.IsNullOrEmpty(Me.APIKey) + End Get + End Property + + + Public Property PushoverUserKey As String + +End Class diff --git a/OpenAntragLib/Models/Account/Members.vb b/OpenAntragLib/Models/Account/Members.vb new file mode 100644 index 0000000..238c8d2 --- /dev/null +++ b/OpenAntragLib/Models/Account/Members.vb @@ -0,0 +1,136 @@ +Imports Raven.Client +Imports System.Web +Imports System.Web.Security + +Public Class Members + +#Region "Shared Methods" + + Public Shared Function GetMembers() As List(Of Member) + + Dim lst As List(Of Member) + + Using ds As IDocumentSession = DataDocumentStore.Session() + + Dim query = From m As Member In ds.Query(Of Member)() + Select m + + 'http://stackoverflow.com/questions/10048943/proper-way-to-retrieve-more-than-128-documents-with-ravendb + + lst = query.Take(1024).ToList() + + End Using + + Return lst + + End Function + + Public Shared Function GetCurrentMember() As Member + + Dim model As New Member + + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + Using ds As IDocumentSession = DataDocumentStore.Session() + + Dim query = From m As Member In ds.Query(Of Member)() + Where m.UserName = HttpContext.Current.User.Identity.Name + Select m + + If query.Count > 0 Then + model = query.First + End If + + End Using + End If + + Return model + + End Function + + Public Shared Function GetMember(ByVal strUserName As String) As Member + + Dim model As Member = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session() + + Dim query = From m As Member In ds.Query(Of Member)() + Where m.UserName = strUserName + Select m + + If query.Count > 0 Then + model = query.First + End If + + End Using + + Return model + + End Function + + Public Shared Function GetMemberByUserKey(ByVal strUserKey As String) As Member + + Dim model As Member = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session() + + Dim query = From m As Member In ds.Query(Of Member)() + Where m.UserKey = strUserKey + Select m + + If query.Count > 0 Then + model = query.First + End If + + End Using + + Return model + + End Function + + Public Shared Function GetMemberByApiKey(ByVal strApiKey As String) As Member + + Dim model As Member = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session() + + Dim query = From m As Member In ds.Query(Of Member)() + Where m.APIKey = strApiKey + Select m + + If query.Count > 0 Then + model = query.First + End If + + End Using + + Return model + + End Function + + Public Shared Function EnsureMember(mu As MembershipUser) As Member + + Dim mb As Member = GetMember(mu.UserName) + + If mb Is Nothing Then + mb = New Member With {.UserKey = mu.ProviderUserKey.ToString, + .UserName = mu.UserName, + .Mail = mu.Email} + SaveMember(mb) + End If + + Return mb + + End Function + + Public Shared Sub SaveMember(model As Member) + + Using ds As IDocumentSession = DataDocumentStore.Session() + ds.Store(model) + ds.SaveChanges() + End Using + + End Sub + +#End Region + +End Class diff --git a/OpenAntragLib/Models/Account/ResetPasswordModel.vb b/OpenAntragLib/Models/Account/ResetPasswordModel.vb new file mode 100644 index 0000000..fedb42f --- /dev/null +++ b/OpenAntragLib/Models/Account/ResetPasswordModel.vb @@ -0,0 +1,13 @@ +Imports System.ComponentModel.DataAnnotations + +Public Class ResetPasswordModel + + + + Public Property UserNameReset() As String + + Public Property MailAddress As String + + Public Property NewPassword() As String + +End Class diff --git a/OpenAntragLib/Models/Home/SearchModel.vb b/OpenAntragLib/Models/Home/SearchModel.vb new file mode 100644 index 0000000..f546015 --- /dev/null +++ b/OpenAntragLib/Models/Home/SearchModel.vb @@ -0,0 +1,15 @@ +Imports System.ComponentModel.DataAnnotations + +Public Class SearchModel + + + Public Property SearchTerms As String + + Public Property Results As List(Of Proposal) + + Public Sub New(searchTerms As String) + Me.SearchTerms = searchTerms + Me.Results = New List(Of Proposal) + End Sub + +End Class diff --git a/OpenAntragLib/Models/IModelBase.vb b/OpenAntragLib/Models/IModelBase.vb new file mode 100644 index 0000000..87c7509 --- /dev/null +++ b/OpenAntragLib/Models/IModelBase.vb @@ -0,0 +1,9 @@ + +Public Interface IModelBase + + Property CreatedAt As String + ReadOnly Property CreatedAtFormat As String + Property CreatedBy As String + Property Timestamp As Integer + +End Interface diff --git a/OpenAntragLib/Models/IRavenModelBase.vb b/OpenAntragLib/Models/IRavenModelBase.vb new file mode 100644 index 0000000..86973d9 --- /dev/null +++ b/OpenAntragLib/Models/IRavenModelBase.vb @@ -0,0 +1,8 @@ + +Public Interface IRavenModelBase + Inherits IModelBase + + Property Id As String + ReadOnly Property IdNumber As Integer + +End Interface diff --git a/OpenAntragLib/Models/KeyValueObject.vb b/OpenAntragLib/Models/KeyValueObject.vb new file mode 100644 index 0000000..1e4fdbb --- /dev/null +++ b/OpenAntragLib/Models/KeyValueObject.vb @@ -0,0 +1,4 @@ +Public Class KeyValueObject + Public Property Key As String + Public Property Value As String +End Class diff --git a/OpenAntragLib/Models/ModelBase.vb b/OpenAntragLib/Models/ModelBase.vb new file mode 100644 index 0000000..0502902 --- /dev/null +++ b/OpenAntragLib/Models/ModelBase.vb @@ -0,0 +1,48 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Script.Serialization + +Public Class ModelBase + Implements IModelBase + + + Public Property CreatedAt As String Implements IModelBase.CreatedAt + + + + + + Public ReadOnly Property CreatedAtFormat As String Implements IModelBase.CreatedAtFormat + Get + Return CType(Me.CreatedAt, DateTime).ToString("dd. MMMM yyyy HH:mm") + End Get + End Property + + Private _createdBy As String + + + Public Property CreatedBy As String Implements IModelBase.CreatedBy + Get + Return _createdBy + End Get + Set(value As String) + _createdBy = value + End Set + End Property + + Private _timeStamp As Integer = 0 + Public Property Timestamp As Integer Implements IModelBase.Timestamp + Get + Try + If _timeStamp = 0 Then + _timeStamp = Tools.GetUnixTimestampFromDate(CType(Me.CreatedAt, DateTime)) + End If + Catch ex As Exception + End Try + Return _timeStamp + End Get + Set(value As Integer) + _timeStamp = value + End Set + End Property + +End Class diff --git a/OpenAntragLib/Models/Proposal/ProcessStep.vb b/OpenAntragLib/Models/Proposal/ProcessStep.vb new file mode 100644 index 0000000..f96ff68 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/ProcessStep.vb @@ -0,0 +1,194 @@ +Imports System.Web.Mvc +Imports Raven.Imports +Imports System.Text + +Public Class ProcessStep + + + Public Property Key_Representation As String + Private _Representation As Representation + + Public Property Representation As Representation + Get + If _Representation Is Nothing Then + _Representation = GlobalData.Representations.GetByKey(Me.Key_Representation.ToLower) + End If + Return _Representation + End Get + Set(value As Representation) + _Representation = value + End Set + End Property + + Public Property ID As Integer + Public Property IsInactive As Boolean = False + + + Public Property Key_Definition As String + + Public Property Caption As String + Public Property ShortCaption As String + Public Property SuccessStory As Boolean = False + + Public Property Color As String + + + Public Property Icon As String + + + Public ReadOnly Property IconPath As String + Get + Return String.Concat("/Images/Icons/", Me.Icon) + End Get + End Property + + + Public Property NextSteps As List(Of ProcessStep) + + Public ReadOnly Property ID_NextSteps As String + Get + Dim retVal As String = Nothing + Try + Dim query = From ps As ProcessStep In Me.NextSteps + Select ps.ID + + If query.Count > 0 Then + retVal = String.Join(",", query.ToArray) + End If + + Catch ex As Exception + End Try + + Return retVal + + End Get + End Property + + Public Sub New(rep As Representation) + _Representation = rep + Me.Key_Representation = rep.Key + End Sub + + Public Sub New(rep As Representation, ex As XElement) + Me.New(rep) + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + + If ex.Attribute("inactive") IsNot Nothing Then + .IsInactive = CType(ex.Attribute("inactive").Value, Boolean) + End If + + If ex.Attribute("def") IsNot Nothing Then + .Key_Definition = ex.Attribute("def").Value + + 'Definition als Standard setzen + Dim def = (From d In GlobalData.ProcessStepDefinitions.Items + Where d.Key = .Key_Definition + Select d).FirstOrDefault + + .Icon = def.Icon + .Color = def.Color + .Caption = def.Caption + .ShortCaption = def.ShortCaption + Else + Throw New Exception("Schritt ohne Definition") + End If + + If ex.Attribute("icon") IsNot Nothing Then + .Icon = ex.Attribute("icon").Value + End If + If ex.Attribute("color") IsNot Nothing Then + .Color = ex.Attribute("color").Value + End If + If ex.Attribute("caption") IsNot Nothing Then + .Caption = ex.Attribute("caption").Value + End If + If ex.Attribute("short-caption") IsNot Nothing Then + .ShortCaption = ex.Attribute("short-caption").Value + End If + + If .Icon Is Nothing Or .Color Is Nothing Then + Throw New Exception("Prozesschritt ohne Icon oder Farbe") + End If + + If .Caption Is Nothing Or .ShortCaption Is Nothing Then + Throw New Exception("Prozesschritt ohne Caption") + End If + + If .Caption.Contains("[") Or .ShortCaption.Contains("[") Then + Throw New Exception("Prozesschritt mit unaufgelöster Definitionsvariable") + End If + + If ex.Attribute("success-story") IsNot Nothing Then + .SuccessStory = ex.Attribute("success-story").Value + End If + + End With + End Sub + + Public Function CloneForNextStep() As ProcessStep + + Return New ProcessStep(Me.Representation) With { + .Key_Representation = Me.Key_Representation, + .ID = Me.ID, + .Caption = Me.Caption, + .ShortCaption = Me.ShortCaption, + .Color = Me.Color, + .Icon = Me.Icon, + .NextSteps = Nothing} + + End Function + + Public Function GetXElement() As XElement + + Dim ex As New XElement("item") + ex.SetAttributeValue("id", Me.ID.ToString) + ex.SetAttributeValue("caption", Me.Caption.ToString) + ex.SetAttributeValue("sort-caption", Me.ShortCaption.ToString) + ex.SetAttributeValue("icon", Me.Icon.ToString) + ex.SetAttributeValue("color", Me.Color.ToString) + If String.IsNullOrEmpty(Me.SuccessStory) = False Then ex.SetAttributeValue("success-story", Me.SuccessStory.ToString) + + Return ex + + End Function + + Public Function GetCaptionHtml() As String + + Dim stb As New StringBuilder(Me.Caption) + + If Me.Caption.ToUpper.Contains("%REPRESENTATIVE%") Then + Dim eRep As New TagBuilder("select") + eRep.Attributes.Add("id", "Key_Representative") + eRep.AddCssClass("nextstep-option") + eRep.AddCssClass("selectpicker") + For Each r As Representative In Me.Representation.Representatives + Dim eOpt As New TagBuilder("option") + eOpt.Attributes.Add("value", r.Key) + eOpt.Append(r.Name) + eRep.Append(eOpt) + Next + stb.Replace("%REPRESENTATIVE%", + String.Concat(" ", eRep.ToString(TagRenderMode.Normal), " ")) + End If + + If Me.Caption.ToUpper.Contains("%COMMITTEE%") Then + Dim eCom As New TagBuilder("select") + eCom.Attributes.Add("id", "Key_Committee") + eCom.AddCssClass("nextstep-option") + eCom.AddCssClass("selectpicker") + For Each c As Committee In Me.Representation.Committees + Dim eOpt As New TagBuilder("option") + eOpt.Attributes.Add("value", c.Key) + eOpt.Append(c.Name) + eCom.Append(eOpt) + Next + stb.Replace("%COMMITTEE%", + String.Concat(" ", eCom.ToString(TagRenderMode.Normal), " ")) + End If + + Return stb.ToString + + End Function + +End Class diff --git a/OpenAntragLib/Models/Proposal/Proposal.vb b/OpenAntragLib/Models/Proposal/Proposal.vb new file mode 100644 index 0000000..0888e48 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/Proposal.vb @@ -0,0 +1,440 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Script.Serialization +Imports System.ServiceModel.Syndication +Imports System.Web +Imports System.Text + +Public Class Proposal + Inherits RavenModelBase + + Public Property Key_Representation As String + + Private _Representation As Representation + + + + Public Property Representation As Representation + Get + If _Representation Is Nothing Then + _Representation = GlobalData.Representations.GetByKey(Me.Key_Representation.ToLower) + End If + Return _Representation + End Get + Set(value As Representation) + _Representation = value + End Set + End Property + + + Public Property Title As String + + + + Public Property IsTest() As Boolean + + + + + Public Property Text As String + + + + Public ReadOnly Property TextHtml() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Dim str As String = MarkdownHelper.Markdown(txt).ToHtmlString + 'str = str.CleanHtmlCode() + Return str + End Get + End Property + + + Public ReadOnly Property TextRaw() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Return MarkdownHelper.MarkdownText(txt) + End Get + End Property + + + + + Public ReadOnly Property TextMarkdown() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Return txt + End Get + End Property + + Public Property TitleUrl As String + + Public ReadOnly Property FullUrl As String + Get + Dim stb As New StringBuilder(Me.Representation.FullUrl) + If String.IsNullOrEmpty(Me.TitleUrl) = False Then + stb.Append("/").Append(Me.TitleUrl) + End If + Return stb.ToString + End Get + End Property + + Public Property UpdatedAt As String + + + + + + Public ReadOnly Property UpdatedAtFormat As String + Get + If String.IsNullOrEmpty(Me.UpdatedAt) = False Then + Return CType(Me.UpdatedAt, DateTime).ToString("dd.MM.yy HH:mm") + Else + Return "" + End If + End Get + End Property + + Private _updatedTimestamp As Integer = 0 + Public Property UpdatedTimestamp As Integer + Get + Try + If _updatedTimestamp = 0 Then + _updatedTimestamp = Tools.GetUnixTimestampFromDate(CType(Me.UpdatedAt, DateTime)) + End If + Catch ex As Exception + End Try + Return _updatedTimestamp + End Get + Set(value As Integer) + _updatedTimestamp = value + End Set + End Property + + Private _UpdatedBy As String + + Public Property UpdatedBy As String + Get + Return _UpdatedBy + End Get + Set(value As String) + _UpdatedBy = value + End Set + End Property + + + Public Property Tags As List(Of String) + + + Public ReadOnly Property TagsList As String + Get + If Me.Tags IsNot Nothing Then + Return String.Join(",", Me.Tags) + Else + Return "" + End If + End Get + End Property + + + + Public ReadOnly Property HasTags As Boolean + Get + Dim b As Boolean + b = Me.Tags Is Nothing + If b = False Then b = (Me.Tags.Count = 0) + If b = False Then b = Me.Tags.Count = 1 AndAlso Me.Tags(0).Length = 0 + Return Not b + End Get + End Property + + Public Property ShortUrl As String + Public Property ExternalUrl As String + Public Property ExternalShortUrl As String + + Public Property Key_Representative As String + + + + Public ReadOnly Property Representative As Representative + Get + Dim rv As Representative = Nothing + If String.IsNullOrEmpty(Me.Key_Representative) = False And Me.Representation.Representatives.Count > 0 Then + Dim query = From r As Representative In Me.Representation.Representatives + Where r.Key = Me.Key_Representative + Select r + + If query.Count > 0 Then + rv = query.First + End If + End If + Return rv + End Get + End Property + + Public Property Key_Committee As String + + + + Public ReadOnly Property Committee As Committee + Get + Dim cm As Committee = Nothing + If String.IsNullOrEmpty(Me.Key_Committee) = False And Me.Representation.Committees.Count > 0 Then + Dim query = From c As Committee In Me.Representation.Committees + Where c.Key = Me.Key_Committee + Select c + + If query.Count > 0 Then + cm = query.First + End If + End If + Return cm + End Get + End Property + + Public Property AbuseMessage() As String + + + + + Public ReadOnly Property AbuseMessageHtml() As String + Get + Dim cmt As String = HttpUtility.UrlDecode(Me.AbuseMessage) + Return MarkdownHelper.Markdown(cmt).ToHtmlString + End Get + End Property + + + Public ReadOnly Property AbuseMessageText() As String + Get + Dim msg As String = HttpUtility.UrlDecode(Me.AbuseMessage) + Return MarkdownHelper.MarkdownText(msg) + End Get + End Property + + + Public ReadOnly Property IsAbuse() As Boolean + Get + Return Not String.IsNullOrEmpty(Me.AbuseMessage) + End Get + End Property + + Public Property CommentingClosedDate As String + + + Public ReadOnly Property IsCommentingClosed() As Boolean + Get + Return Not String.IsNullOrEmpty(Me.CommentingClosedDate) + End Get + End Property + + Public Property ID_CurrentProposalStep As String + + + + Public ReadOnly Property CurrentProposalStep As ProposalStep + Get + Dim ps As ProposalStep = Nothing + If String.IsNullOrEmpty(Me.ID_CurrentProposalStep) = False And Me.ProposalSteps.Count > 0 Then + Dim query = From s As ProposalStep In Me.ProposalSteps + Where s.Id = Me.ID_CurrentProposalStep + Select s + + If query.Count > 0 Then + ps = query.First + End If + End If + Return ps + End Get + End Property + + + Public Property ProposalSteps As New List(Of ProposalStep) + + + + + Public ReadOnly Property ProposalStepStack As List(Of ProposalStep) + Get + Dim query = From ps As ProposalStep In Me.ProposalSteps + Where ps.Id <> Me.ID_CurrentProposalStep + Order By ps.Id Descending + Select ps + + Return query.ToList + End Get + End Property + + + + + Public ReadOnly Property ProposalStepList As List(Of ProposalStep) + Get + Dim query = From ps As ProposalStep In Me.ProposalSteps + Order By ps.Id + Select ps + + Return query.ToList + End Get + End Property + + + + Public Property ProposalComments As New List(Of ProposalComment) + + + + Public ReadOnly Property ProposalCommentCountCaption As String + Get + Select Case Me.ProposalComments.Count + Case 0 : Return "keine Kommentare" + Case 1 : Return "1 Kommentar" + Case Else : Return String.Concat(Me.ProposalComments.Count, " Kommentare") + End Select + End Get + End Property + + + + Public Property ContactInfo() As String = Nothing + + Public Property RatingCount As Integer = 0 + Public Property RatingSum As Integer = 0 + + + + Public ReadOnly Property Rating As Integer + Get + If Me.RatingSum > 0 Then + Return Math.Round(Me.RatingSum / Me.RatingCount, 0, MidpointRounding.AwayFromZero) + Else + Return 0 + End If + End Get + End Property + + + + Public Property SuccessStoryStatus As Integer = 0 + + + + Public Property ID_SuccessStory As String + + + + + Public ReadOnly Property HasSuccessStory As Boolean + Get + Return (Not String.IsNullOrEmpty(Me.ID_SuccessStory)) + End Get + End Property + + + + + Public ReadOnly Property FeedItem As SyndicationItem + Get + Dim stbText As New StringBuilder + 'stbText.Append("") + 'stbText.Append("]]>") + + Dim si As New SyndicationItem(String.Concat(Me.Title, " (", Me.Representation.Name, ")"), + "", + New Uri(Me.FullUrl), + Me.IdNumber, + Me.CreatedAt) + + si.Content = New CDataSyndicationContent(New TextSyndicationContent(stbText.ToString, TextSyndicationContentKind.Html)) + + With si + .PublishDate = CType(Me.CreatedAt, DateTimeOffset) + End With + + Return si + + End Get + End Property + + Public Sub New() + End Sub + + Public Sub New(representation As Representation) + + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + Me.Representation = representation + Me.Key_Representation = Me.Representation.Key + + End Sub + + Public Sub FillProcessSteps() + + If Me.Representation IsNot Nothing AndAlso Me.Representation.ProcessSteps IsNot Nothing Then + For Each ps As ProposalStep In Me.ProposalSteps + Dim query = From p As ProcessStep In Me.Representation.ProcessSteps + Where p.ID = ps.ID_ProcessStep + Select p + + If query.Count > 0 Then + ps.ProcessStep = query.First() + End If + Next + End If + + End Sub + +End Class + +Public Class ProposalStep + Inherits RavenModelBase + + Public Property ID_ProcessStep As Integer + + + Public Property ProcessStep As ProcessStep + + + Public Property Info As String + + + Public ReadOnly Property InfoHtml() As String + Get + Dim cmt As String = HttpUtility.UrlDecode(Me.Info) + Return MarkdownHelper.Markdown(cmt).ToHtmlString + End Get + End Property + + + Public ReadOnly Property InfoText() As String + Get + Dim cmt As String = HttpUtility.UrlDecode(Me.Info) + Return MarkdownHelper.MarkdownText(cmt) + End Get + End Property + + + Public ReadOnly Property InfoMarkdown() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Info) + Return txt + End Get + End Property + + Public Sub New() + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + Me.CreatedBy = HttpContext.Current.User.Identity.Name + End If + End Sub + +End Class diff --git a/OpenAntragLib/Models/Proposal/ProposalAbuseNotice.vb b/OpenAntragLib/Models/Proposal/ProposalAbuseNotice.vb new file mode 100644 index 0000000..d6656af --- /dev/null +++ b/OpenAntragLib/Models/Proposal/ProposalAbuseNotice.vb @@ -0,0 +1,11 @@ +Public Class ProposalAbuseNotice + + Public Property Proposal As Proposal + Public Property Notice As String + + Public Sub New(prop As Proposal, notice As String) + Me.Proposal = prop + Me.Notice = notice + End Sub + +End Class diff --git a/OpenAntragLib/Models/Proposal/ProposalComment.vb b/OpenAntragLib/Models/Proposal/ProposalComment.vb new file mode 100644 index 0000000..9dcd813 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/ProposalComment.vb @@ -0,0 +1,84 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Script.Serialization +Imports System.Web + +Public Class ProposalComment + + + Public Property ID_Proposal As String + + + + + + + Public Property Comment As String + + + + Public ReadOnly Property CommentHtml() As String + Get + Dim cmt As String = HttpUtility.UrlDecode(Me.Comment) + Return MarkdownHelper.Markdown(cmt).ToHtmlString + End Get + End Property + + + + + Public ReadOnly Property CommentText() As String + Get + Dim msg As String = HttpUtility.UrlDecode(Me.Comment) + Return MarkdownHelper.MarkdownText(msg) + End Get + End Property + + + Public ReadOnly Property CommentRaw() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Comment) + Return MarkdownHelper.MarkdownText(txt) + End Get + End Property + + + + Public Property CommentedBy As String + + Public Property CommentedAt As String + + + + Public ReadOnly Property CommentedAtFormat As String + Get + Return CType(Me.CommentedAt, DateTime).ToString("dd. MMMM yyyy HH:mm") + End Get + End Property + + Private _CommentedAtTimestamp As Integer = 0 + Public Property CommentedAtTimestamp As Integer + Get + Try + If _CommentedAtTimestamp = 0 Then + _CommentedAtTimestamp = Tools.GetUnixTimestampFromDate(CType(Me.CommentedAt, DateTime)) + End If + Catch ex As Exception + End Try + Return _CommentedAtTimestamp + End Get + Set(value As Integer) + _CommentedAtTimestamp = value + End Set + End Property + + + Public Sub New() + End Sub + + Public Sub New(ps As Proposal) + + Me.ID_Proposal = ps.Id + + End Sub + +End Class diff --git a/OpenAntragLib/Models/Proposal/ProposalDTO.vb b/OpenAntragLib/Models/Proposal/ProposalDTO.vb new file mode 100644 index 0000000..4f92d78 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/ProposalDTO.vb @@ -0,0 +1,21 @@ +Public Class ProposalDTO + + Public Property ApiKey As String + Public Property Key_Representation As String + Public Property Title As String + Public Property Text As String + Public Property TagList As String + +End Class + +Public Class ProposalNextStepDTO + + Public Property ApiKey As String + Public Property Key_Representation As String + Public Property ID_Proposal As String + Public Property ID_ProcessStep As String + Public Property InfoText As String + Public Property Key_Representative As String + Public Property Key_Committee As String + +End Class diff --git a/OpenAntragLib/Models/Proposal/ProposalTags.vb b/OpenAntragLib/Models/Proposal/ProposalTags.vb new file mode 100644 index 0000000..19cf9e3 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/ProposalTags.vb @@ -0,0 +1,146 @@ +Imports System.ComponentModel.DataAnnotations +Imports Raven.Client +Imports System.Web.Script.Serialization + +Public Class ProposalTags + Inherits RavenModelBase + + Public Property Items As List(Of ProposalTag) + + Public Sub New() + End Sub + + Public Shared Function Load() As ProposalTags + + Using ds As IDocumentSession = DataDocumentStore.Session + Dim entity = ds.Load(Of ProposalTags)("ProposalTags-1") + If entity IsNot Nothing Then + Return entity + End If + End Using + + Return Nothing + + End Function + + Public Shared Function Tags() As List(Of ProposalTag) + + Using ds As IDocumentSession = DataDocumentStore.Session + Dim entity = ds.Load(Of ProposalTags)("ProposalTags-1") + If entity IsNot Nothing Then + Return entity.Items + End If + End Using + + Return Nothing + + End Function + + Public Shared Function TagsOrdered() As List(Of ProposalTag) + + Dim lst As List(Of ProposalTag) = Nothing + + Try + lst = (From t As ProposalTag In ProposalTags.Tags + Order By t.Tag Ascending + Select t).ToList + + Catch ex As Exception + End Try + + Return lst + + End Function + + Public Shared Function TagsList() As List(Of String) + + Dim lst As List(Of String) + + lst = (From t As ProposalTag In ProposalTags.Tags + Order By t.Tag Ascending + Select t.Tag).ToList + + Return lst + + End Function + + Public Shared Function GetTag(tag As String) As ProposalTag + + Dim model As ProposalTag = Nothing + + Dim lst As List(Of ProposalTag) = ProposalTags.Tags() + + Dim query = From pt As ProposalTag In lst + Where pt.Tag.ToLower = tag.ToLower + Select pt + + If query.Count > 0 Then + model = query.First + End If + + Return model + + End Function + + Public Shared Function TagCloudItems() As List(Of TagCloudItem) + + Dim lst As New List(Of TagCloudItem) + + Try + Dim query = From pt As ProposalTag In ProposalTags.TagsOrdered + Select New TagCloudItem With { + .text = pt.Tag, + .weight = pt.ProposalCount, + .link = String.Concat("/themen/", pt.Tag.ToLower), + .html = New TagCloudHtmlAttribute With { + .title = pt.Tag + } + } + + lst = query.ToList + + Catch ex As Exception + End Try + + Return lst + + End Function + +End Class + +Public Class ProposalTag + + Public Property Tag As String + Public Property Proposals As List(Of String) + + + Public ReadOnly Property ProposalCount As Integer + Get + If Me.Proposals Is Nothing Then + Return 0 + Else + Return Me.Proposals.Count + End If + End Get + End Property + + Public Sub New() + End Sub + + Public Sub New(tag As String) + Me.Tag = tag + End Sub + +End Class + +Public Class TagCloudItem + Public Property text As String + Public Property weight As Integer + Public Property link As String + Public Property html As TagCloudHtmlAttribute +End Class + +Public Class TagCloudHtmlAttribute + Public Property title As String + Public Property [class] As String +End Class diff --git a/OpenAntragLib/Models/Proposal/Proposals.vb b/OpenAntragLib/Models/Proposal/Proposals.vb new file mode 100644 index 0000000..25d8a99 --- /dev/null +++ b/OpenAntragLib/Models/Proposal/Proposals.vb @@ -0,0 +1,553 @@ +Imports Raven.Client +Imports System.Text +Imports System.Web + +Public Class Proposals + + Public Shared Function SearchFor(strTerms As String) As List(Of Proposal) + + '... http://stackoverflow.com/questions/4314545/ravendb-full-text-search + 'http://ravendb.net/docs/2.0/client-api/querying/static-indexes/searching + 'http://ravendb.net/docs/client-api/querying/static-indexes/configuring-index-options + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + lst = ds.Query(Of Proposal)().Search(Function(x) x.Text, strTerms).ToList() + + End Using + + Return lst + + End Function + + Public Shared Function GetByRepresentation(rep As Representation) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + 'max. 128 / 1024! > http://ravendb.net/docs/2.0/intro/safe-by-default + ' http://ravendb.net/kb/31/my-10-tips-and-tricks-with-ravendb + ' https://groups.google.com/forum/#!msg/ravendb/UcLmIajTTq4/Lpke9qd13woJ + + Dim query = ds.Query(Of Proposal)() _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Where(Function(e) e.Key_Representation = rep.Key) + + If query.Count > 0 Then + lst = query.ToList + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsTop(count As Integer) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + 'TODO: Order & Take + 'http://stackoverflow.com/questions/8931289/ravendb-orderbydescending-and-take-incorrect-results + 'http://ravendb.net/docs/client-api/querying/stale-indexes + 'http://ravendb.net/docs/2.0/client-api/querying/query-and-lucene-query + 'Dim stats As New Raven.Client.RavenQueryStatistics + 'Dim query = ds.Query(Of Proposal)() _ + ' .Statistics(stats) _ + ' .Customize(Function(x) x.WaitForNonStaleResultsAsOfNow()) _ + ' .OrderByDescending(Function(e) e.CreatedAt) _ + ' .Take(count) + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(e) e.IsTest = False) _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Take(count) + + If query.Count > 0 Then + lst = query.ToList + 'lst = lst.Take(count).ToList() + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsTopByRepresentation(rep As Representation, + count As Integer) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(e) e.Key_Representation = rep.Key) _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Take(count) + + If query.Count > 0 Then + lst = query.ToList + 'lst = lst.Take(count).ToList() + End If + + End Using + + Return lst + + + End Function + + Public Shared Function GetItemsCount() As Integer + + Dim intCount As Integer = -1 + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim stats As New RavenQueryStatistics + Dim query = ds.Query(Of Proposal)() _ + .Statistics(stats) _ + .Where(Function(e) e.IsTest = False) _ + .Take(0).ToArray() + intCount = stats.TotalResults + + End Using + + Return intCount + + End Function + + Public Shared Function GetItemsCountByRepresentation(rep As Representation) As Integer + + Dim intCount As Integer = -1 + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim stats As New RavenQueryStatistics + Dim query = ds.Query(Of Proposal)() _ + .Statistics(stats) _ + .Where(Function(e) e.Key_Representation = rep.Key) _ + .Take(0).ToArray() + 'AndAlso e.IsTest = False + intCount = stats.TotalResults + + End Using + + Return intCount + + End Function + + Public Shared Function GetItemsPage(pageNo As Integer, + pageCount As Integer) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(e) e.IsTest = False) _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Skip((pageNo - 1) * pageCount).Take(pageCount) + + If query.Count > 0 Then + lst = query.ToList + End If + + End Using + + Return lst + + End Function + + 'TODO: http://daniellang.net/joining-documents-in-ravendb-2-0/ + ' http://ravendb.net/docs/2.0/client-api/querying/handling-document-relationships + ' http://www.w3enterprises.com/articles/beginner-guide-to-ravendb.aspx + 'Public Shared Function GetItemsPageByFederalState(federal As String, + ' pageNo As Integer, + ' pageCount As Integer) As List(Of Proposal) + + ' Dim lst As New List(Of Proposal) + + ' Using ds As IDocumentSession = DataDocumentStore.Session + + ' Dim query = ds.Query(Of Proposal)() _ + ' .Where(Function(e) e.IsTest = False) _ + ' .OrderByDescending(Function(e) e.Timestamp) _ + ' .Skip((pageNo - 1) * pageCount).Take(pageCount) + + ' If query.Count > 0 Then + ' lst = query.ToList + ' End If + + ' End Using + + ' Return lst + + 'End Function + + Public Shared Function GetItemsPageByRepresentation(rep As Representation, + pageNo As Integer, + pageCount As Integer) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(e) e.Key_Representation = rep.Key) _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Skip((pageNo - 1) * pageCount).Take(pageCount) + + If query.Count > 0 Then + lst = query.ToList + 'lst = lst.ToList.Skip((pageNo - 1) * pageCount).Take(pageCount).ToList() + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsByTag(tag As ProposalTag) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(x) x.Tags.Contains(tag.Tag) = True AndAlso x.IsTest = False) _ + .OrderByDescending(Function(e) e.Timestamp) + + If query.Count > 0 Then + lst = query.ToList + 'lst.Sort(New Comparison(Of Proposal)(Function(x As Proposal, y As Proposal) CType(y.CreatedAt, DateTime).CompareTo(CType(x.CreatedAt, DateTime)))) + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsByTagAndRepresentation(rep As Representation, + tag As ProposalTag) As List(Of Proposal) + + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() _ + .Where(Function(x) x.Key_Representation = rep.Key AndAlso x.Tags.Contains(tag.Tag)) _ + .OrderByDescending(Function(e) e.Timestamp) + + If query.Count > 0 Then + lst = query.ToList + 'lst.Sort(New Comparison(Of Proposal)(Function(x As Proposal, y As Proposal) CType(y.CreatedAt, DateTime).CompareTo(CType(x.CreatedAt, DateTime)))) + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsCommentCount() As Integer + + Dim intRetVal As Integer = -1 + Dim lst As New List(Of Proposal) + + Using ds As IDocumentSession = DataDocumentStore.Session + Dim query = ds.Query(Of Proposal)("ProposalsWithComments") + + intRetVal += query.ToList().Sum(Function(p) p.ProposalComments.Count) + + End Using + + Return intRetVal + + End Function + + Public Shared Function GetById(id As String) As Proposal + + Dim prop As Proposal = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim entity = ds.Load(Of Proposal)(id) + + If entity IsNot Nothing Then + prop = entity + End If + + End Using + + Return prop + + End Function + + Public Shared Function GetByTitleUrl(rep As Representation, + titleUrl As String) As Proposal + + Dim prop As Proposal = Nothing + + Dim lst As List(Of Proposal) = GetByRepresentation(rep) + + 'Dim query = From p As Proposal In lst + ' Where p.TitleUrl = titleUrl + ' Select p + + 'If query.Count > 0 Then + ' prop = query.First + 'End If + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)() + query = query.Where(Function(e) e.Key_Representation = rep.Key) + query = query.Where(Function(e) e.TitleUrl = titleUrl) + + If query.Count > 0 Then + prop = query.First + End If + + End Using + + Return prop + + End Function + + Public Shared Sub SearchItems(ByRef srm As SearchModel, + pageNo As Integer, + pageCount As Integer) + + Try + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Proposal)("FulltextByTextAndTitle") _ + .Search(Function(m) m.Text, srm.SearchTerms, options:=SearchOptions.Or) _ + .Search(Function(m) m.Title, srm.SearchTerms, options:=SearchOptions.Or) + + If query.Count > 0 Then + srm.Results = query.ToList() + End If + + End Using + + Catch ex As Exception + End Try + + End Sub + + Public Shared Function TitleUrlExists(rep As Representation, + titleUrl As String) As Boolean + + Dim bolRetVal As Boolean = False + + Dim lst As List(Of Proposal) = GetByRepresentation(rep) + + Dim query = From p As Proposal In lst + Where p.TitleUrl = titleUrl + Select p + + If query.Count > 0 Then + bolRetVal = True + End If + + Return bolRetVal + + End Function + + Public Shared Function GetProcessStepCaption(caption As String, + p As Proposal, + m As Representation) As String + + Dim stb As New StringBuilder(caption) + + If caption.Contains("%COMMITTEE%") = True Then + If String.IsNullOrEmpty(p.Key_Committee) = False Then + Dim query = From c As Committee In m.Committees + Where c.Key = p.Key_Committee + Select c + + If query.Count > 0 Then + stb.Replace("%COMMITTEE%", query.First.Name) + End If + End If + End If + + If caption.Contains("%REPRESENTATIVE%") = True Then + If String.IsNullOrEmpty(p.Key_Representative) = False Then + Dim query = From r As Representative In m.Representatives + Where r.Key = p.Key_Representative + Select r + + If query.Count > 0 Then + stb.Replace("%REPRESENTATIVE%", query.First.Name) + End If + End If + End If + + Return stb.ToString + + End Function + + Public Shared Function CreateNew(keyRepresentation As String, + title As String, + text As String, + tagList As String, + contactInfo As String) As Proposal + + Dim rep As Representation = GlobalData.Representations.GetByKey(keyRepresentation.ToLower) + + Dim model As New Proposal(rep) + model.Title = title.StripSpecialCharsForTitle + model.Text = text + model.ContactInfo = contactInfo + + If title.StartsWith("TEST:") Or rep.IsTest = True Then + model.IsTest = True + End If + + Dim stbUrl As New StringBuilder(Tools.MakeReadableUrl(model.Title)) + If Proposals.TitleUrlExists(rep, stbUrl.ToString) = True Then + stbUrl.Append("-").Append(Format(DateTime.Now, "yyMMddHHmm")) + End If + model.TitleUrl = stbUrl.ToString + + If model.IsTest = False Then + model.ShortUrl = UrlShortener.GetShortUrl(model.FullUrl) + End If + + Dim ps As New ProposalStep + ps.Id = "1" + ps.ID_ProcessStep = 1 + 'ps.Info = "Eingang des Antrags" + + model.ProposalSteps.Add(ps) + + model.ID_CurrentProposalStep = ps.Id + + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + model.CreatedBy = HttpContext.Current.User.Identity.Name + End If + + Dim newID As String + Using ds As IDocumentSession = DataDocumentStore.Session() + ds.Store(model) + newID = model.Id + + Dim tags As ProposalTags = ProposalTags.Load() + SaveTags(model, tags, tagList) + ds.Store(tags) + + ds.SaveChanges() + End Using + + MailManager.SendNewProposal(model) + PushoverManager.SendNewProposal(model) + TwitterManager.TweetNewProposal(model) + NotificationManager.StoreNewProposal(model) + PushbulletManager.SendNewProposal(model) + + Return model + + End Function + + Public Shared Sub SaveTags(ByRef prop As Proposal, + ByRef tags As ProposalTags, + ByVal tagList As String) + + If prop.Tags Is Nothing Then prop.Tags = New List(Of String) + + Dim lstTagsNew As List(Of String) = tagList.Split(",").ToList + Dim lstTagsOld As List(Of String) = prop.Tags + + 'Tag in Proposal speichern + prop.Tags = lstTagsNew + + 'Proposal in Tag speichern (Add/Delete) + Dim lstAddTags As IEnumerable(Of String) = lstTagsNew.Except(lstTagsOld) + Dim lstDeleteTags As IEnumerable(Of String) = lstTagsOld.Except(lstTagsNew) + + '(Add) + For Each s As String In lstAddTags + If String.IsNullOrEmpty(s) = False Then + Dim query = From tag As ProposalTag In tags.Items + Where tag.Tag = s + Select tag + + If query.Count > 0 Then + Dim tag As ProposalTag = query.First + If prop.IsTest = False Then + If tag.Proposals Is Nothing Then tag.Proposals = New List(Of String) + tag.Proposals.Add(prop.Id) + End If + Else + Dim newTag As New ProposalTag(s) + newTag.Proposals = New List(Of String) + newTag.Proposals.Add(prop.Id) + tags.Items.Add(newTag) + End If + End If + Next + + '(Delete) + For Each s As String In lstDeleteTags + If String.IsNullOrEmpty(s) = False Then + Dim query = From tag As ProposalTag In tags.Items + Where tag.Tag = s + Select tag + + If query.Count > 0 Then + Dim tag As ProposalTag = query.First + tag.Proposals.Remove(prop.Id) + If tag.Proposals.Count = 0 Then + tags.Items.Remove(tag) + End If + End If + End If + Next + + End Sub + + Public Shared Sub SaveNextStep(ByRef prop As Proposal, + idStep As Integer, + info As String, + keyRepresentative As String, + keyCommittee As String) + + Dim ps As New ProposalStep + ps.Id = CType(prop.ID_CurrentProposalStep, Integer) + 1 + ps.ID_ProcessStep = idStep + ps.Info = info.EnsureMarkdown + + prop.ProposalSteps.Add(ps) + prop.ID_CurrentProposalStep = ps.Id + + If keyRepresentative IsNot Nothing Then + prop.Key_Representative = keyRepresentative + End If + + If keyCommittee IsNot Nothing Then + prop.Key_Committee = keyCommittee + End If + + prop.UpdatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + prop.UpdatedBy = HttpContext.Current.User.Identity.Name + End If + + Using ds As IDocumentSession = DataDocumentStore.Session() + ds.Store(prop) + ds.SaveChanges() + End Using + + End Sub + +End Class diff --git a/OpenAntragLib/Models/RavenIndexModels.vb b/OpenAntragLib/Models/RavenIndexModels.vb new file mode 100644 index 0000000..5cf84dc --- /dev/null +++ b/OpenAntragLib/Models/RavenIndexModels.vb @@ -0,0 +1,10 @@ + +Public Class ProposalCountByRepresentationRIM + Public Property Key As String + Public Property Count As Integer +End Class + +Public Class FeedbackCountByTypeRIM + Public Property Type As String + Public Property Count As Integer +End Class \ No newline at end of file diff --git a/OpenAntragLib/Models/RavenModelBase.vb b/OpenAntragLib/Models/RavenModelBase.vb new file mode 100644 index 0000000..abdfad3 --- /dev/null +++ b/OpenAntragLib/Models/RavenModelBase.vb @@ -0,0 +1,25 @@ +Imports System.ComponentModel.DataAnnotations + +Public Class RavenModelBase + Inherits ModelBase + Implements IRavenModelBase + + + Public Property Id As String Implements IRavenModelBase.Id + + + + Public ReadOnly Property IdNumber As Integer Implements IRavenModelBase.IdNumber + Get + If Me.Id IsNot Nothing AndAlso Me.Id.Length > 0 Then + 'Dim strClassTypeName As String = Me.GetType().Name.ToLower + 'Return CType(Me.Id.ToLower.Replace(strClassTypeName & "s-", ""), Integer) + Dim arr As String() = Split(Me.Id, "-") + Return arr(arr.Length - 1) + Else + Return 0 + End If + End Get + End Property + +End Class diff --git a/OpenAntragLib/Models/Representation/Representation.vb b/OpenAntragLib/Models/Representation/Representation.vb new file mode 100644 index 0000000..a0030b4 --- /dev/null +++ b/OpenAntragLib/Models/Representation/Representation.vb @@ -0,0 +1,440 @@ +Imports System.IO +Imports System.Text +Imports System.Web +Imports System.Drawing + +Public Class Representation + Implements IXMLClass + + + + Public Property ID As Integer + + 'Private _piratenmandate As piratenmandate.Item + + + Public Property piratenmandate As piratenmandate.Item + ' Get + ' If _piratenmandate Is Nothing Then + ' _piratenmandate = (From pm As piratenmandate.Item In GlobalData.piratenmandate.Items + ' Where pm.OpenAntragKey = Me.Key + ' Select pm).FirstOrDefault() + ' End If + ' Return _piratenmandate + ' End Get + ' Set(value As piratenmandate.Item) + ' _piratenmandate = value + ' End Set + 'End Property + + Public Property Status As Representations.StatusConjuction + + + + Public ReadOnly Property StatusName() As String + Get + Dim s As String = [Enum].GetName(GetType(Representations.StatusConjuction), Me.Status) + If String.IsNullOrEmpty(s) = False Then + Return s.ToLower() + Else + Return "" + End If + End Get + End Property + + + + Public ReadOnly Property IsActive As Boolean + Get + Return (Me.Status And Representations.StatusConjuction.Active) = Representations.StatusConjuction.Active + End Get + End Property + + + + Public ReadOnly Property IsViewOnly As Boolean + Get + Return (Me.Status And Representations.StatusConjuction.ViewOnly) = Representations.StatusConjuction.ViewOnly + End Get + End Property + + + + Public Property IsTest As Boolean + + Public Property Key As String + Public Property Label As String + Public Property LabelArticle As String = "" + + Public ReadOnly Property LabelWithArticle As String + Get + If String.IsNullOrEmpty(Me.LabelArticle) = False Then + Return String.Concat(Me.LabelArticle, " ", Me.Label) + Else + Return Me.Label + End If + End Get + End Property + + + + Public Property ApiKey As String + + Public Property Color As String + + + + Public ReadOnly Property ColorRGB As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim stb As New StringBuilder + stb.Append(cColor.R.ToString).Append(",") + stb.Append(cColor.G.ToString).Append(",") + stb.Append(cColor.B.ToString) + Return stb.ToString() + End Get + End Property + + + + Public ReadOnly Property ColorBright As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim cBrightColor As Color = cColor.ChangeColorBrightness(0.25) + Return ColorTranslator.ToHtml(cBrightColor) + End Get + End Property + + + + Public ReadOnly Property ColorText As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim cBrightColor As Color = cColor.ChangeColorBrightness(-0.15) + Return ColorTranslator.ToHtml(cBrightColor) + End Get + End Property + + Public Property [Name] As String + Public Property [Name2] As String + Public Property Level As Integer + + Public Property FederalKey As String + + + Public Property Federal As FederalState + Public ReadOnly Property FederalName As String 'nur für API + Get + Return Me.Federal.Name + End Get + End Property + + Public Property GroupType As Integer + Public Property GroupName As String + Public Property Link As String + Public Property Twitter As String + Public Property Phone As String + Public Property Mail As String + Public Property InfoMail As String + Public Property MapUrl As String + + + + Public Property Representatives As List(Of Representative) + + + + Public Property HasCommittees As Boolean = True + + + + Public Property Committees As List(Of Committee) + + + + Public Property ProcessSteps As List(Of ProcessStep) + + + + Public ReadOnly Property GroupTypeCaption As String + Get + Dim strRetVal As String = "" + Try + Dim query = From gt As GroupType In GlobalData.GroupTypes.Items + Where gt.ID = Me.GroupType + Select gt + + If query.Count > 0 Then + strRetVal = query.First.Name + End If + Catch ex As Exception + + End Try + Return strRetVal + End Get + End Property + + + + Public ReadOnly Property GroupTypeGen As String + Get + Dim strRetVal As String = "" + Try + Dim query = From gt As GroupType In GlobalData.GroupTypes.Items + Where gt.ID = Me.GroupType + Select gt + + If query.Count > 0 Then + strRetVal = query.First.NameGen + End If + Catch ex As Exception + + End Try + Return strRetVal + End Get + End Property + + + + Public ReadOnly Property GroupTypeObject As GroupType + Get + Dim objRetVal As GroupType = Nothing + Try + Dim query = From gt As GroupType In GlobalData.GroupTypes.Items + Where gt.ID = Me.GroupType + Select gt + + If query.Count > 0 Then + objRetVal = query.First + End If + Catch ex As Exception + + End Try + Return objRetVal + End Get + End Property + + Public ReadOnly Property FullUrl As String + Get + Dim stb As New StringBuilder() + stb.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stb.Append("/").Append(Me.Key) + Return stb.ToString + End Get + End Property + + + + Public ReadOnly Property HasLogoImage As Boolean + Get + Return (Me.LogoImage IsNot Nothing) + End Get + End Property + + Public ReadOnly Property LogoImage As String + Get + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key).Append("/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles("logo.*") + If fi.Count > 0 Then + Return String.Concat(stbPath.ToString, fi(0).Name) + Else : Return Nothing + End If + End Get + End Property + + Public ReadOnly Property LogoImagePage As String + Get + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key).Append("/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles("logo-page.*") + If fi.Count > 0 Then + Return String.Concat(stbPath.ToString, fi(0).Name) + Else : Return Me.LogoImage + End If + End Get + End Property + + + + Public ReadOnly Property FraktionInfo As HtmlString + Get + Dim hs As New HtmlString("") + + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key).Append("/Info/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles("fraktion.info") + If fi.Count > 0 Then + Dim sr As New StreamReader(fi(0).FullName, Encoding.UTF8) + Dim strContent As String = sr.ReadToEnd() + sr.Close() + hs = New HtmlString(strContent) + End If + + Return hs + End Get + End Property + + + Public ReadOnly Property FraktionInfoHtml() As String + Get + Return Me.FraktionInfo.ToHtmlString + End Get + End Property + + + + Public ReadOnly Property ParlamentInfo As HtmlString + Get + Dim hs As New HtmlString("") + + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key).Append("/Info/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles("parlament.info") + If fi.Count > 0 Then + Dim sr As New StreamReader(fi(0).FullName, Encoding.UTF8) + Dim strContent As String = sr.ReadToEnd() + sr.Close() + hs = New HtmlString(strContent) + End If + + Return hs + End Get + End Property + + + Public ReadOnly Property ParlamentInfoHtml() As String + Get + Return Me.ParlamentInfo.ToHtmlString + End Get + End Property + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Status = CType(ex.Attribute("status").Value, Integer) + .IsTest = (CType(ex.Attribute("id").Value, Integer) >= 999) + .Key = ex.Attribute("key").Value + .Label = ex.Attribute("label").Value + If ex.Attribute("label-article") IsNot Nothing Then + .LabelArticle = ex.Attribute("label-article").Value + End If + .ApiKey = ex.Attribute("api-key").Value + .Color = ex.Attribute("color").Value + .[Name] = ex.Attribute("name").Value + .[Name2] = ex.Attribute("name2").Value + .Level = CType(ex.Attribute("level").Value, Integer) + .FederalKey = ex.Attribute("federal").Value + .GroupType = CType(ex.Attribute("group-type").Value, Integer) + .GroupName = ex.Attribute("group-name").Value + .Link = ex.Attribute("link").Value + .Twitter = ex.Attribute("twitter").Value.Replace("@", "") + .Phone = ex.Attribute("phone").Value + .Mail = ex.Attribute("mail").Value + .InfoMail = ex.Attribute("info-mail").Value + If ex.Attribute("map-url") IsNot Nothing Then + .MapUrl = ex.Attribute("map-url").Value + End If + + Me.Representatives = New List(Of Representative) + For Each xM As XElement In ex.Element("representatives").Elements("item") + Me.Representatives.Add(New Representative(xM, ex.Attribute("key").Value)) + Next + + Me.Committees = New List(Of Committee) + If ex.Element("committees").Attribute("has-committees") IsNot Nothing Then + .HasCommittees = CType(ex.Element("committees").Attribute("has-committees").Value, Boolean) + End If + For Each xM As XElement In ex.Element("committees").Elements("item") + Me.Committees.Add(New Committee(xM, ex.Attribute("key").Value)) + Next + + Me.ProcessSteps = New List(Of ProcessStep) + For Each xS As XElement In ex.Element("process").Elements("step") + Me.ProcessSteps.Add(New ProcessStep(Me, xS)) + Next + '--- + For Each xS As XElement In ex.Element("process").Elements("step") + Dim parentStep As ProcessStep = (From p As ProcessStep In Me.ProcessSteps + Where p.ID = CType(xS.Attribute("id").Value, Integer) + Select p).First + + For Each xN As XElement In xS.Element("next").Elements("step") + Dim nextStep = (From p As ProcessStep In Me.ProcessSteps + Where p.ID = CType(xN.Attribute("id").Value, Integer) + Select p).First + + If parentStep.NextSteps Is Nothing Then parentStep.NextSteps = New List(Of ProcessStep) + parentStep.NextSteps.Add(nextStep.CloneForNextStep) + Next + Next + + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("status", Me.Status.ToString) + xE.SetAttributeValue("key", Me.Key.ToString) + xE.SetAttributeValue("label", Me.Label.ToString) + If String.IsNullOrEmpty(Me.LabelArticle) = False Then + xE.SetAttributeValue("label-article", Me.LabelArticle.ToString) + End If + xE.SetAttributeValue("api-key", Me.ApiKey.ToString) + xE.SetAttributeValue("color", Me.Color.ToString) + xE.SetAttributeValue("name", Me.[Name].ToString) + xE.SetAttributeValue("level", Me.Level.ToString) + xE.SetAttributeValue("federal", Me.FederalKey.ToString) + xE.SetAttributeValue("name2", Me.Name2.ToString) + xE.SetAttributeValue("group-type", Me.GroupType.ToString) + xE.SetAttributeValue("group-name", Me.GroupName.ToString) + xE.SetAttributeValue("link", Me.Link.ToString) + xE.SetAttributeValue("twitter", Me.Twitter.ToString) + xE.SetAttributeValue("phone", Me.Phone.ToString) + xE.SetAttributeValue("mail", Me.Mail.ToString) + xE.SetAttributeValue("info-mail", Me.InfoMail.ToString) + If String.IsNullOrEmpty(Me.MapUrl) = False Then + xE.SetAttributeValue("map-url", Me.MapUrl.ToString) + End If + + Dim xR As New XElement("representatives") + For Each m As Representative In Me.Representatives + xR.Add(m.GetXElement) + Next + xE.Add(xR) + + Dim xC As New XElement("committees") + For Each m As Committee In Me.Committees + xC.Add(m.GetXElement) + Next + xE.Add(xC) + + Dim xP As New XElement("process") + For Each s As ProcessStep In Me.ProcessSteps + xP.Add(s.GetXElement) + Next + xE.Add(xP) + + Return xE + + End Function + +End Class diff --git a/OpenAntragLib/Models/Representation/RepresentationClone.vb b/OpenAntragLib/Models/Representation/RepresentationClone.vb new file mode 100644 index 0000000..7e80d8f --- /dev/null +++ b/OpenAntragLib/Models/Representation/RepresentationClone.vb @@ -0,0 +1,27 @@ +Imports System.ComponentModel.DataAnnotations +Imports Raven.Client +Imports System.Web.Script.Serialization + +Public Class RepresentationClone + + Public Property Id As String + + Public Property OriginalId As Integer + Public Property Key As String + Public Property Label As String + Public Property ApiKey As String + Public Property Color As String + Public Property [Name] As String + Public Property [Name2] As String + Public Property Level As Integer + Public Property FederalKey As String + Public Property GroupType As Integer + Public Property GroupName As String + Public Property Link As String + Public Property Twitter As String + Public Property Phone As String + Public Property Mail As String + Public Property InfoMail As String + Public Property MapUrl As String + +End Class diff --git a/OpenAntragLib/Models/Representation/RepresentationSetting.vb b/OpenAntragLib/Models/Representation/RepresentationSetting.vb new file mode 100644 index 0000000..44c05eb --- /dev/null +++ b/OpenAntragLib/Models/Representation/RepresentationSetting.vb @@ -0,0 +1,44 @@ +Imports System.ComponentModel.DataAnnotations +Imports Raven.Client +Imports System.Web + +Public Class RepresentationSetting + Inherits RavenModelBase + + Public Property Key As String + Public Property HasContactPossibility As Boolean = False + + Public Sub New() + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + End Sub + +End Class + +Public Class RepresentationSettings + + Public Shared Function GetByKey(key As String) As RepresentationSetting + + Dim model As RepresentationSetting + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of RepresentationSetting)() _ + .Where(Function(s) s.Key = key) + + If query.Count > 0 Then + model = query.First() + Else + model = New RepresentationSetting() + model.Key = key + model.CreatedBy = HttpContext.Current.User.Identity.Name + ds.Store(model) + ds.SaveChanges() + End If + + End Using + + Return model + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntragLib/Models/Representation/Representations.vb b/OpenAntragLib/Models/Representation/Representations.vb new file mode 100644 index 0000000..1af8d84 --- /dev/null +++ b/OpenAntragLib/Models/Representation/Representations.vb @@ -0,0 +1,170 @@ +Imports Raven.Client +Imports System.Text + +Public Class Representations + + Public Enum StatusConjuction + Inactive = 0 + Active = 1 + ViewOnly = 2 + Ended = 4 + End Enum + + Public Property Items As List(Of Representation) + + Public Sub New() + + Dim xh As New XmlHelper + Me.Items = xh.GetInstance(Of Representation)() + + For Each rp As Representation In Me.Items + + If String.IsNullOrEmpty(rp.FederalKey) = False Then + rp.Federal = (From fs As FederalState In GlobalData.FederalStates.Items + Where fs.Key.ToUpper = rp.FederalKey.ToUpper + Select fs).First + + End If + + rp.piratenmandate = (From pm As piratenmandate.Item In GlobalData.piratenmandate.Items + Where pm.OpenAntragKey = rp.Key + Select pm).FirstOrDefault() + + If rp.piratenmandate IsNot Nothing Then + rp.piratenmandate.MapUrl = rp.MapUrl + End If + + Next + + End Sub + + Public Function GetById(id As Integer) As Representation + + Dim rep As Representation = Nothing + + Dim query = From a As Representation In Me.Items + Where a.ID = id + Select a + + If query.Count > 0 Then + rep = query.First + End If + + Return rep + + End Function + + Public Function GetByKey(keyRepresentation As String) As Representation + + Dim rep As Representation = Nothing + + Dim query = From a As Representation In Me.Items + Where a.Key = keyRepresentation + Select a + + If query.Count > 0 Then + rep = query.First + End If + + Return rep + + End Function + + Public Function GetByList(arrKeyList As String()) As List(Of Representation) + + Return (From s In arrKeyList Select GetByKey(s)).ToList() + + End Function + + Public Shared Function GetNewApiKey() As String + + Dim x As New RandomKeyGenerator(42) + Dim sx As String = x.Generate() + Return sx + + End Function + + Public Function GetRepresentatives() As List(Of Representative) + + Dim lst As New List(Of Representative) + + For Each rp As Representation In Me.Items.Where(Function(x) (x.Status And Representations.StatusConjuction.Active) > 0) + lst.AddRange(From rv In rp.Representatives Where rv.HasPortraitImage = True And rv.Party.ToLower.Contains("piratenpartei")) + Next + + Return lst + + End Function + + Public Shared Sub EnsureRepresentationClone(rep As Representation) + + Dim model As RepresentationClone + Dim bSave As Boolean = False + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = From m As RepresentationClone In ds.Query(Of RepresentationClone)() + Where m.OriginalId = rep.ID + Select m + + If query.Count > 0 Then + model = query.First + + If Not model.Label = rep.Label Then model.Label = rep.Label : bSave = True + If Not model.ApiKey = rep.ApiKey Then model.ApiKey = rep.ApiKey : bSave = True + If Not model.Color = rep.Color Then model.Color = rep.Color : bSave = True + If Not model.Name = rep.Name Then model.Name = rep.Name : bSave = True + If Not model.Name2 = rep.Name2 Then model.Name2 = rep.Name2 : bSave = True + If Not model.Level = rep.Level Then model.Level = rep.Level : bSave = True + If Not model.FederalKey = rep.FederalKey Then model.FederalKey = rep.FederalKey : bSave = True + If Not model.GroupType = rep.GroupType Then model.GroupType = rep.GroupType : bSave = True + If Not model.GroupName = rep.GroupName Then model.GroupName = rep.GroupName : bSave = True + If Not model.Link = rep.Link Then model.Link = rep.Link : bSave = True + If Not model.Twitter = rep.Twitter Then model.Twitter = rep.Twitter : bSave = True + If Not model.Phone = rep.Phone Then model.Phone = rep.Phone : bSave = True + If Not model.Mail = rep.Mail Then model.Mail = rep.Mail : bSave = True + If Not model.InfoMail = rep.InfoMail Then model.InfoMail = rep.InfoMail : bSave = True + If Not model.MapUrl = rep.MapUrl Then model.MapUrl = rep.MapUrl : bSave = True + + Else + bSave = True + model = New RepresentationClone With {.OriginalId = rep.ID, + .Key = rep.Key, + .ApiKey = rep.ApiKey, + .Color = rep.Color, + .Name = rep.Name, + .Name2 = rep.Name2, + .Level = rep.Level, + .FederalKey = rep.FederalKey, + .GroupType = rep.GroupType, + .GroupName = rep.GroupName, + .Link = rep.Link, + .Twitter = rep.Twitter, + .Mail = rep.Mail, + .InfoMail = rep.InfoMail, + .MapUrl = rep.MapUrl} + End If + + If bSave = True Then + ds.Store(model) + ds.SaveChanges() + End If + + End Using + + + End Sub + + Public Shared Sub ReplaceStyleColor(ByRef rep As Representation, + ByVal stb As StringBuilder) + + stb.Replace("[ID]", rep.ID.ToString) + stb.Replace("[KEY]", rep.Key) + stb.Replace("[COLOR]", rep.Color) + stb.Replace("[COLOR-RGB]", rep.ColorRGB) + stb.Replace("[COLORBRIGHT]", rep.ColorBright) + stb.Replace("[COLORTEXT]", rep.ColorText) + + End Sub + +End Class diff --git a/OpenAntragLib/Models/Representation/piratenmandate.vb b/OpenAntragLib/Models/Representation/piratenmandate.vb new file mode 100644 index 0000000..c4e686c --- /dev/null +++ b/OpenAntragLib/Models/Representation/piratenmandate.vb @@ -0,0 +1,212 @@ +Imports System.IO +Imports Microsoft.VisualBasic.CompilerServices +Imports System.Web +Imports System.Text + +Public Class piratenmandate + + Public Property Items As New List(Of Item) + + Public Sub New() + + Dim xmlFile As String = HttpContext.Current.Server.MapPath("~/App_Data/piratenmandate.xml") + + If File.Exists(xmlFile) = True Then + Dim xT As XElement = XElement.Load(xmlFile) + + For Each xB In xT.Elements("bundesland") + Dim cB As New Item.BundeslandInfo With {.Name = xB.Attribute("name"), + .GS = xB.Attribute("gs"), + .Localpirates = xB.Attribute("localpirates")} + + cB.Key = (From f As FederalState In GlobalData.FederalStates.Items + Where f.Name = cB.Name + Select f.Key).FirstOrDefault() + + For Each xG In xB.Elements("gebiet") + ProcessItem(Nothing, xG, cB) + Next + Next + + End If + + End Sub + + Public Sub ProcessItem(ByVal cParent As piratenmandate.Item, + ByVal xG As XElement, + ByVal cB As Item.BundeslandInfo) + + Dim cG As New Item With {.Bundesland = cB, + .GebietName = xG.Attribute("name"), + .GebietGS = xG.Attribute("gs"), + .GebietType = xG.Attribute("type"), + .GebietLocalpirates = xG.Attribute("localpirates")} + + 'Behandlung von Ausnahmen in Bezug auf Type und Name + Select Case cG.GebietType.ToLower() + Case "stadtbezirk", "ortsteil" + If cParent IsNot Nothing AndAlso + String.IsNullOrEmpty(cParent.GebietName) = False AndAlso + cG.GebietName.StartsWith(cParent.GebietName) = False Then + + cG.GebietName.Prepend(cParent.GebietName, " ") + End If + End Select + + If xG.Elements("parlament").Any() Then + Dim xP As XElement = xG.Elements("parlament").First() 'DTD = *, aber es gibt immer nur ein Parlament + cG.ParlamentName = xP.Attribute("name") + cG.ParlamentSeats = xP.Attribute("seats") + cG.ParlamentRIS = xP.Attribute("ris") + + If xP.Elements("fraktion").Any() Then + Dim xF As XElement = xP.Elements("fraktion").First() + cG.FraktionName = xF.Attribute("name") + cG.FraktionType = xF.Attribute("type") + cG.FraktionUrl = xF.Attribute("url") + + If xF.Elements("partner").Any() Then + cG.FraktionPartner = New List(Of Item.PartnerInfo) + For Each xR As XElement In xF.Elements("partner") + Dim cR As New Item.PartnerInfo With {.Name = xR.Attribute("name"), + .Partei = xR.Attribute("partei"), + .Num = xR.Attribute("num")} + cG.FraktionPartner.Add(cR) + Next + End If + End If + + If xP.Elements("mandat").Any() Then + cG.MandateCount = xP.Elements("mandat").Count() + End If + + If xP.Elements("story").Any() Then + Dim xS As XElement = xP.Elements("story").First() + cG.ParlamentStory = xS.Value + cG.ParlamentStorySource = xS.Attribute("source") + End If + + If xP.Elements("feed").Any() Then + Dim xD As XElement = xP.Elements("feed").First() + cG.ParlamentFeedUrl = xD.Attribute("url") + End If + + If xP.Elements("oa").Any() Then + Dim xO As XElement = xP.Elements("oa").First() + Dim strUrl = xO.Attribute("url") + If String.IsNullOrEmpty(strUrl) = False Then + Dim arr As String() = Split(strUrl, "/") + If arr.Length >= 4 Then cG.OpenAntragKey = arr(3) + End If + + End If + + End If + + Me.Items.Add(cG) + + If xG.Elements("gebiet").Any() Then + For Each xC In xG.Elements("gebiet") + ProcessItem(cG, xC, cB) 'rekursiver Aufruf + Next + End If + + End Sub + + Public Class Item + + Public Property Bundesland As BundeslandInfo + + Public Property GebietName As String + Public Property GebietType As String + + Public ReadOnly Property GebietTypeAndName As String + Get + Dim lstNoType As New List(Of String) + lstNoType.Add("kreis") + lstNoType.Add("landkreis") + lstNoType.Add("landschaftsverband") + lstNoType.Add("regionalverband") + lstNoType.Add("kommunalverband besonderer art") + + If lstNoType.Contains(Me.GebietType.ToLower()) = True Or + Me.GebietName.ToLower.Contains("ortsamtsbereich") = True Then + Return Me.GebietName + Else + Return String.Concat(Me.GebietType, " ", Me.GebietName) + End If + + End Get + End Property + + Public Property GebietGS As String + Public Property GebietLocalpirates As String + + Public Property ParlamentName As String + Public Property ParlamentSeats As String + Public Property ParlamentRIS As String + Public Property ParlamentStory As String + Public Property ParlamentStorySource As String + Public Property ParlamentFeedUrl As String + + Public Property FraktionName As String + Public Property FraktionType As String + Public Property FraktionUrl As String + Public Property FraktionPartner As List(Of PartnerInfo) + + Public ReadOnly Property FraktionText As String + Get + Dim stb As New StringBuilder + If Me.FraktionType IsNot Nothing Then + Select Case Me.FraktionType.ToLower + Case "piraten" + stb.Append("Piratenfraktion") + Case "gemeinsam" + stb.Append("Gemeinsame Gruppe/Fraktion ").Append(FraktionName).Append(" mit ") + Dim spi As New StringBuilder + For Each pi As PartnerInfo In Me.FraktionPartner + spi.AppendWithSeperator(pi.NameParteiNum, " und ") + Next + stb.Append(spi.ToString()) + Case Else + 'nichts zu tun + End Select + End If + Return stb.ToString() + End Get + End Property + + Public Property MandateCount As Integer + + Public Property OpenAntragKey As String + + Public Property MapUrl As String + + Public Class BundeslandInfo + Public Property Key As String + Public Property [Name] As String + Public Property GS As String + Public Property Localpirates As String + End Class + + Public Class PartnerInfo + Public Property [Name] As String + Public Property Partei As String + Public Property Num As String + + Public ReadOnly Property NameParteiNum As String + Get + Dim stb As New StringBuilder + If String.IsNullOrEmpty(Me.Name) = False Then + stb.Append(Me.Name) + Else + stb.Append(Me.Partei) + End If + stb.Append(" (").Append(Me.Num).Append(")") + Return stb.ToString() + End Get + End Property + End Class + End Class + +End Class \ No newline at end of file diff --git a/OpenAntragLib/Models/Shared/Committee.vb b/OpenAntragLib/Models/Shared/Committee.vb new file mode 100644 index 0000000..c2eba95 --- /dev/null +++ b/OpenAntragLib/Models/Shared/Committee.vb @@ -0,0 +1,43 @@ +Imports Raven.Imports + +Public Class Committee + + + Public Property Key_Representation As String + + + Public Property ID As Integer + + Public Property Key As String + Public Property [Name] As String + Public Property Caption As String + Public Property Url As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement, keyRepresentation As String) + Me.New() + With Me + .Key_Representation = keyRepresentation + .ID = CType(ex.Attribute("id").Value, Integer) + .Key = ex.Attribute("key").Value + .[Name] = ex.Attribute("name").Value + .Caption = ex.Attribute("caption").Value + .Url = ex.Attribute("url").Value + End With + End Sub + + Public Function GetXElement() As XElement + + Dim ex As New XElement("item") + ex.SetAttributeValue("id", Me.ID.ToString) + ex.SetAttributeValue("key", Me.Key.ToString) + ex.SetAttributeValue("name", Me.[Name].ToString) + ex.SetAttributeValue("caption", Me.Caption.ToString) + ex.SetAttributeValue("url", Me.Url.ToString) + + Return ex + + End Function +End Class diff --git a/OpenAntragLib/Models/Shared/ErrorLog.vb b/OpenAntragLib/Models/Shared/ErrorLog.vb new file mode 100644 index 0000000..73db336 --- /dev/null +++ b/OpenAntragLib/Models/Shared/ErrorLog.vb @@ -0,0 +1,41 @@ +Imports System.Web + +Public Class ErrorLog + Inherits RavenModelBase + + Public Sub New() + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + Me.Parameter = New List(Of String)() + End Sub + + Public Property AbsoluteUri() As String + Public Property Controller() As String + Public Property Action() As String + Public Property RequestType() As String + Public Property Parameter() As List(Of String) + Public Property ReferrerUrl() As String + Public Property AjaxCall() As Boolean + Public Property Message() As String + Public Property Occurrences() As List(Of ErrorOccurrence) + + + Public ReadOnly Property Url() As String + Get + Return String.Concat("http://", Tools.GetRequestDomain(), "/errors/", Me.Id) + End Get + End Property +End Class + +Public Class ErrorOccurrence + Inherits ModelBase + + Public Sub New() + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + If HttpContext.Current.Request.IsAuthenticated Then + CreatedBy = (HttpContext.Current.User.Identity.Name) + End If + End Sub + + Public Property UserAgent() As String + +End Class diff --git a/OpenAntragLib/Models/Shared/ErrorLogs.vb b/OpenAntragLib/Models/Shared/ErrorLogs.vb new file mode 100644 index 0000000..d722664 --- /dev/null +++ b/OpenAntragLib/Models/Shared/ErrorLogs.vb @@ -0,0 +1,83 @@ +Imports Raven.Client + +Public Class ErrorLogs + + Public Shared Sub NewLog(log As ErrorLog, userAgent As String) + + Dim el As ErrorLog = Nothing + Dim isNewLog As Boolean = False + + Using ds As IDocumentSession = DataDocumentStore.Session + 'el = ds.Query(Of ErrorLog)() _ + ' .Where(Function(x) x.AbsoluteUri = log.AbsoluteUri AndAlso x.Message = log.Message).FirstOrDefault() + + el = ds.Query(Of ErrorLog)() _ + .FirstOrDefault(Function(x) x.AbsoluteUri = log.AbsoluteUri AndAlso x.Message = log.Message) + + If el Is Nothing Then + el = log + el.Occurrences = New List(Of ErrorOccurrence)() + ds.Store(el) + isNewLog = True + End If + + el.Occurrences.Add(New ErrorOccurrence() With { + .UserAgent = userAgent + }) + ds.SaveChanges() + End Using + + Dim pm As PushoverMessage + + If isNewLog = True Then + pm = New PushoverMessage( + String.Concat("Exception auf ", el.AbsoluteUri), + String.Concat((String.Join(vbLf, el.Parameter)), vbLf, el.Message), + el.Url, el.Url, + True) + Else + pm = New PushoverMessage( + String.Concat("Exception ", el.IdNumber, " auf ", el.AbsoluteUri), + String.Concat("Wiederholter Fehler ", el.Occurrences.Count), + el.Url, el.Url, + True) + End If + + PushoverManager.Send(pm) + + End Sub + + ''' + ''' Lädt einen Log-Eintrag anhand seiner ID + ''' + ''' + ''' + Public Shared Function GetById(id As String) As ErrorLog + + Dim el As ErrorLog = Nothing + + Using session As IDocumentSession = DataDocumentStore.Session + el = session.Load(Of ErrorLog)(id) + End Using + + Return el + End Function + + ''' + ''' Gibt eine Liste aller Log-Einträge zurück + ''' + ''' + Public Shared Function GetList() As List(Of ErrorLog) + + Dim lst As New List(Of ErrorLog)() + + Using session As IDocumentSession = DataDocumentStore.Session + lst = session.Query(Of ErrorLog)().OrderByDescending(Function(x) x.Timestamp).ToList() + End Using + + Return lst + + End Function + +End Class + diff --git a/OpenAntragLib/Models/Shared/FederalStates.vb b/OpenAntragLib/Models/Shared/FederalStates.vb new file mode 100644 index 0000000..5a57543 --- /dev/null +++ b/OpenAntragLib/Models/Shared/FederalStates.vb @@ -0,0 +1,38 @@ +Public Class FederalStates + + Public Property Items As List(Of FederalState) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of FederalState)() + End Sub + +End Class + +Public Class FederalState + Implements IXMLClass + + Public Property Key As String + Public Property [Name] As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .Key = ex.Attribute("key").Value + .Name = ex.Attribute("name").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("key", Me.Key.ToString) + xE.SetAttributeValue("name", Me.Name.ToString) + Return xE + + End Function + +End Class \ No newline at end of file diff --git a/OpenAntragLib/Models/Shared/Feedback.vb b/OpenAntragLib/Models/Shared/Feedback.vb new file mode 100644 index 0000000..5ecb065 --- /dev/null +++ b/OpenAntragLib/Models/Shared/Feedback.vb @@ -0,0 +1,84 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Mvc +Imports System.Web + +Public Class Feedback + Inherits RavenModelBase + +#Region "Constructors" + + Public Sub New() + Me.CreatedAt = DateTime.Now.ToString + End Sub + +#End Region + +#Region "Properties" + + + Public Property Type As Integer + + + Public Property Status As Integer + + + Public ReadOnly Property TypeObject As FeedbackType + Get + Dim oRetVal As FeedbackType = Nothing + Dim query = From f As FeedbackType In GlobalData.FeedbackTypes.Items Where f.ID = Me.Type Select f + If query.Count > 0 Then oRetVal = query.First + Return oRetVal + End Get + End Property + + + Public ReadOnly Property StatusObject As FeedbackStatusCode + Get + Dim oRetVal As FeedbackStatusCode = Nothing + Dim fbs As New FeedbackStatusCodes + Dim query = From f As FeedbackStatusCode In fbs.Items Where f.ID = Me.Type Select f + If query.Count > 0 Then oRetVal = query.First + Return oRetVal + End Get + End Property + + + + Public Property Title As String + + + + + Public Property Message As String + + + Public ReadOnly Property MessageHtml() As MvcHtmlString + Get + Dim msg As String = HttpUtility.UrlDecode(Me.Message) + Return MarkdownHelper.Markdown(msg) + End Get + End Property + + + Public ReadOnly Property MessageText() As String + Get + Dim msg As String = HttpUtility.UrlDecode(Me.Message) + Return MarkdownHelper.MarkdownText(msg) + End Get + End Property + + + + Public Shadows Property CreatedBy As String + + + Public Property Likes As Integer + + + Public Property Dislikes As Integer + + Public Property Comments As List(Of FeedbackComment) + +#End Region + +End Class diff --git a/OpenAntragLib/Models/Shared/FeedbackComment.vb b/OpenAntragLib/Models/Shared/FeedbackComment.vb new file mode 100644 index 0000000..2ae3e42 --- /dev/null +++ b/OpenAntragLib/Models/Shared/FeedbackComment.vb @@ -0,0 +1,85 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web +Imports System.Web.Mvc + +Public Class FeedbackComment + +#Region "Constructors" + + Public Sub New() + + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + Me.CommentedBy = HttpContext.Current.User.Identity.Name + End If + + Me.CommentedAt = DateTime.Now.ToString + End Sub + + Public Sub New(feedbackID As String) + Me.New() + Me.ID_Feedback = feedbackID + End Sub + +#End Region + +#Region "Properties" + + + Public Property ID_Feedback As String + + + + + Public Property Comment As String + + + Public ReadOnly Property CommentHtml() As MvcHtmlString + Get + Dim cmt As String = HttpUtility.UrlDecode(Me.Comment) + Return MarkdownHelper.Markdown(cmt) + End Get + End Property + + + Public ReadOnly Property CommentText() As String + Get + Dim msg As String = HttpUtility.UrlDecode(Me.Comment) + Return MarkdownHelper.MarkdownText(msg) + End Get + End Property + + + + Public Property CommentedBy As String + + Public Property CommentedByAdmin As Boolean + + + Public Property CommentedAt As String + + + Public ReadOnly Property CommentedAtFormat As String + Get + Return CType(Me.CommentedAt, DateTime).ToString("dd. MMMM yyyy HH:mm") + End Get + End Property + + Private _timeStamp As Integer = 0 + Public Property Timestamp As Integer + Get + Try + If _timeStamp = 0 Then + _timeStamp = Tools.GetUnixTimestampFromDate(CType(Me.CommentedAt, DateTime)) + End If + Catch ex As Exception + End Try + Return _timeStamp + End Get + Set(value As Integer) + _timeStamp = value + End Set + End Property + +#End Region + +End Class diff --git a/OpenAntragLib/Models/Shared/FeedbackStatusCodes.vb b/OpenAntragLib/Models/Shared/FeedbackStatusCodes.vb new file mode 100644 index 0000000..cc3d54d --- /dev/null +++ b/OpenAntragLib/Models/Shared/FeedbackStatusCodes.vb @@ -0,0 +1,39 @@ +Public Class FeedbackStatusCodes + + Public Property Items As List(Of FeedbackStatusCode) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of FeedbackStatusCode)() + End Sub + +End Class + +Public Class FeedbackStatusCode + Implements IXMLClass + + Public Property ID As Integer + Public Property [Name] As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Name = ex.Attribute("name").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("name", Me.Name.ToString) + Return xE + + End Function + +End Class + diff --git a/OpenAntragLib/Models/Shared/FeedbackTypes.vb b/OpenAntragLib/Models/Shared/FeedbackTypes.vb new file mode 100644 index 0000000..c355207 --- /dev/null +++ b/OpenAntragLib/Models/Shared/FeedbackTypes.vb @@ -0,0 +1,50 @@ +Public Class FeedbackTypes + + Public Property Items As List(Of FeedbackType) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of FeedbackType)() + End Sub + +End Class + +Public Class FeedbackType + Implements IXMLClass + + Public Property ID As Integer + Public Property Key As String + Public Property [Name] As String + Public Property Icon As String + Public Property Voting As Boolean + Public Property Color As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Key = ex.Attribute("key").Value + .Name = ex.Attribute("name").Value + .Icon = ex.Attribute("icon").Value + .Voting = CType(ex.Attribute("voting").Value, Boolean) + .Color = ex.Attribute("color").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("key", Me.Key.ToString) + xE.SetAttributeValue("name", Me.Name.ToString) + xE.SetAttributeValue("icon", Me.Icon.ToString) + xE.SetAttributeValue("voting", Me.Voting.ToString) + xE.SetAttributeValue("color", Me.Color.ToString) + Return xE + + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/Feedbacks.vb b/OpenAntragLib/Models/Shared/Feedbacks.vb new file mode 100644 index 0000000..b29cb86 --- /dev/null +++ b/OpenAntragLib/Models/Shared/Feedbacks.vb @@ -0,0 +1,79 @@ +Imports Raven.Client + +Public Class Feedbacks + + Public Shared Function GetItems() As List(Of Feedback) + + Dim lst As New List(Of Feedback) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Feedback)() + + If query.Count > 0 Then + lst = query.ToList + lst.Sort(New Comparison(Of Feedback)(Function(x As Feedback, y As Feedback) CType(y.CreatedAt, DateTime).CompareTo(CType(x.CreatedAt, DateTime)))) + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetItemsByType(fb As FeedbackType) As List(Of Feedback) + + Dim lst As New List(Of Feedback) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of Feedback)().Where(Function(f) f.Type = fb.ID) + + If query.Count > 0 Then + lst = query.ToList + lst.Sort(New Comparison(Of Feedback)(Function(x As Feedback, y As Feedback) CType(y.CreatedAt, DateTime).CompareTo(CType(x.CreatedAt, DateTime)))) + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetByID(id As String) As Feedback + + Dim fb As Feedback = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim entity = ds.Load(Of Feedback)(id) + + If entity IsNot Nothing Then + fb = entity + End If + + End Using + + Return fb + + End Function + + Public Shared Function GetCount() As Integer + + Dim intCount As Integer = -1 + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim stats As New RavenQueryStatistics + Dim query = ds.Query(Of Feedback)() _ + .Statistics(stats) _ + .Take(0).ToArray() + intCount = stats.TotalResults + + End Using + + Return intCount + + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/GovernmentalLevels.vb b/OpenAntragLib/Models/Shared/GovernmentalLevels.vb new file mode 100644 index 0000000..7aedf73 --- /dev/null +++ b/OpenAntragLib/Models/Shared/GovernmentalLevels.vb @@ -0,0 +1,38 @@ +Public Class GovernmentalLevels + + Public Property Items As List(Of GovernmentalLevel) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of GovernmentalLevel)() + End Sub + +End Class + +Public Class GovernmentalLevel + Implements IXMLClass + + Public Property ID As Integer + Public Property [Name] As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Name = ex.Attribute("name").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("name", Me.Name.ToString) + Return xE + + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/GroupTypes.vb b/OpenAntragLib/Models/Shared/GroupTypes.vb new file mode 100644 index 0000000..02dac24 --- /dev/null +++ b/OpenAntragLib/Models/Shared/GroupTypes.vb @@ -0,0 +1,46 @@ +Public Class GroupTypes + + Public Property Items As List(Of GroupType) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of GroupType)() + End Sub + +End Class + +Public Class GroupType + Implements IXMLClass + + Public Property ID As Integer + Public Property [Name] As String + Public Property NameGen As String + Public Property Common As String + Public Property Color As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Name = ex.Attribute("name").Value + .NameGen = ex.Attribute("name-gen").Value + .Common = ex.Attribute("common").Value + .Color = ex.Attribute("color").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("name", Me.Name.ToString) + xE.SetAttributeValue("name-gen", Me.NameGen.ToString) + xE.SetAttributeValue("color", Me.Color.ToString) + Return xE + + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/Notification.vb b/OpenAntragLib/Models/Shared/Notification.vb new file mode 100644 index 0000000..78f54c2 --- /dev/null +++ b/OpenAntragLib/Models/Shared/Notification.vb @@ -0,0 +1,121 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.ServiceModel.Syndication +Imports System.Text +Imports System.Web + +Public Class Notification + Inherits RavenModelBase + +#Region "Constructors" + + Public Sub New() + Me.CreatedAt = DateTime.Now.ToString + End Sub + + Public Sub New(ByVal intType As NotificationTypes, + ByVal rep As Representation, + ByVal strTitle As String, + ByVal strText As String) + Me.New() + Me.NotificationType = intType + Me.Representation = rep + Me.Title = strTitle + Me.Text = strText + End Sub + + Public Sub New(ByVal intType As NotificationTypes, + ByVal rep As Representation, + ByVal strTitle As String, + ByVal strText As String, + ByVal strurl As String) + Me.New(intType, rep, strTitle, strText) + Me.Url = strurl + End Sub + + + + Public ReadOnly Property FeedItem As SyndicationItem + Get + + Dim si As New SyndicationItem(String.Concat("[", Me.NotificationTypeString, "] ", Me.Title), + "", + New Uri(Me.FullUrl), + Me.IdNumber, + Me.CreatedAt) + + si.Content = New CDataSyndicationContent(New TextSyndicationContent(Me.Text, TextSyndicationContentKind.Html)) + + With si + .PublishDate = CType(Me.CreatedAt, DateTimeOffset) + End With + + Return si + + End Get + End Property + +#End Region + +#Region "Properties" + + Public Property NotificationType As Integer + + + Public ReadOnly Property NotificationTypeString() As String + Get + Return Notifications.GetTypeStringSingular(Me.NotificationType) + End Get + End Property + + + Public ReadOnly Property NotificationTypeColor() As String + Get + Return Notifications.GetTypeColor(Me.NotificationType) + End Get + End Property + + Private _RepresentationKey As String + Public Property RepresentationKey As String + Get + If String.IsNullOrEmpty(_RepresentationKey) AndAlso Not IsNothing(Me.Representation) Then + _RepresentationKey = Me.Representation.Key + End If + Return _RepresentationKey + End Get + Set(value As String) + _RepresentationKey = value + End Set + End Property + + + + Public Property Representation As Representation + + + Public Property Title As String + + + + Public Property Text As String + + + + Public Property Url As String + + + Public ReadOnly Property FullUrl As String + Get + If String.IsNullOrEmpty(Me.Url) = False And Tools.IsUri(Me.Url) = True Then + Return Me.Url + Else + Dim stb As New StringBuilder() + stb.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stb.Append("/notifications") + Return stb.ToString + End If + End Get + End Property + +#End Region + +End Class diff --git a/OpenAntragLib/Models/Shared/Notifications.vb b/OpenAntragLib/Models/Shared/Notifications.vb new file mode 100644 index 0000000..ba406d3 --- /dev/null +++ b/OpenAntragLib/Models/Shared/Notifications.vb @@ -0,0 +1,88 @@ +Imports Raven.Client + +Public Class Notifications + + Public Shared Function GetItemsPage(type As Integer, + pageNo As Integer, + pageCount As Integer) As List(Of Notification) + + Dim lst As New List(Of Notification) + + Using ds As IDocumentSession = DataDocumentStore.Session + + If type = -1 Then + + Dim query = ds.Query(Of Notification)() _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Skip((pageNo - 1) * pageCount).Take(pageCount) + + If query.Count > 0 Then lst = query.ToList + Else + Dim query = ds.Query(Of Notification)() _ + .OrderByDescending(Function(e) e.Timestamp) _ + .Where(Function(n) n.NotificationType = type) _ + .Skip((pageNo - 1) * pageCount).Take(pageCount) + + If query.Count > 0 Then lst = query.ToList + + End If + + End Using + + Return lst + + End Function + + Public Shared Function GetTypeId(strType As String) As Integer + Select Case strType.ToLower + Case "meldungen" : Return NotificationTypes.Post + Case "antragseingänge" : Return NotificationTypes.NewProposal + Case "antragskommentare" : Return NotificationTypes.NewProposalComment + Case "feedback" : Return NotificationTypes.NewFeedback + Case "feedback-kommentare" : Return NotificationTypes.NewFeedbackComment + Case "antragsschritte" : Return NotificationTypes.NextProposalStep + Case "erfolge" : Return NotificationTypes.SuccessStories + Case Else : Return -1 + End Select + End Function + + Public Shared Function GetTypeStringSingular(intType As Integer) As String + Select Case intType + Case NotificationTypes.Post : Return "Meldung" + Case NotificationTypes.NewProposal : Return "Antragseingang" + Case NotificationTypes.NewProposalComment : Return "Antragskommentar" + Case NotificationTypes.NewFeedback : Return "Feedback" + Case NotificationTypes.NewFeedbackComment : Return "Feedback-Kommentar" + Case NotificationTypes.NextProposalStep : Return "Antragsschritt" + Case NotificationTypes.SuccessStories : Return "Erfolg" + Case Else : Return "" + End Select + End Function + + Public Shared Function GetTypeStringPlural(intType As Integer) As String + Select Case intType + Case NotificationTypes.Post : Return "Meldungen" + Case NotificationTypes.NewProposal : Return "Antragseingänge" + Case NotificationTypes.NewProposalComment : Return "Antragskommentare" + Case NotificationTypes.NewFeedback : Return "Feedback" + Case NotificationTypes.NewFeedbackComment : Return "Feedback-Kommentare" + Case NotificationTypes.NextProposalStep : Return "Antragsschritte" + Case NotificationTypes.SuccessStories : Return "Erfolge" + Case Else : Return "" + End Select + End Function + + Public Shared Function GetTypeColor(intType As Integer) As String + Select Case intType + Case NotificationTypes.Post : Return "#B80000" + Case NotificationTypes.NewProposal : Return "#E47900" + Case NotificationTypes.NewProposalComment : Return "#CB7311" + Case NotificationTypes.NewFeedback : Return "#3498DB" + Case NotificationTypes.NewFeedbackComment : Return "#2D76AA" + Case NotificationTypes.NextProposalStep : Return "#666666" + Case NotificationTypes.SuccessStories : Return "#1C8E31" + Case Else : Return "" + End Select + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/PagerModel.vb b/OpenAntragLib/Models/Shared/PagerModel.vb new file mode 100644 index 0000000..db9f054 --- /dev/null +++ b/OpenAntragLib/Models/Shared/PagerModel.vb @@ -0,0 +1,44 @@ +Public Class PagerModel + + Public Property CurrentPage As Integer + Public Property PageSize As Integer + Public Property TotalSize As Integer + Public Property PagerWingLength As Integer + Public Property PageUrl As String + + Public Sub New(currentPage As Integer, + pageSize As Integer, + totalSize As Integer, + pagerWingLength As Integer, + pageUrl As Integer) + Me.CurrentPage = currentPage + Me.PageSize = pageSize + Me.TotalSize = totalSize + Me.PagerWingLength = pagerWingLength + Me.PageUrl = pageUrl + End Sub + + Public Sub New(currentPage As Integer, + totalSize As Integer, + pageUrl As String) + Me.CurrentPage = currentPage + Me.PageSize = SettingsWrapper.DefaultPagerListPageSize + Me.TotalSize = totalSize + Me.PagerWingLength = SettingsWrapper.DefaultPagerListWingLength + Me.PageUrl = pageUrl + End Sub + + Public ReadOnly Property MaxPages As Integer + Get + Dim intPages = Me.TotalSize \ Me.PageSize + + If Me.TotalSize Mod Me.PageSize > 0 Then + intPages += 1 + End If + + Return intPages + + End Get + End Property + +End Class diff --git a/OpenAntragLib/Models/Shared/ProcessStepDefinitions.vb b/OpenAntragLib/Models/Shared/ProcessStepDefinitions.vb new file mode 100644 index 0000000..e02d960 --- /dev/null +++ b/OpenAntragLib/Models/Shared/ProcessStepDefinitions.vb @@ -0,0 +1,47 @@ +Public Class ProcessStepDefinitions + + Public Property Items As List(Of ProcessStepDefinition) + + Public Sub New() + Dim xh As New XmlHelper() + Me.Items = xh.GetInstance(Of ProcessStepDefinition)() + End Sub + +End Class + +Public Class ProcessStepDefinition + Implements IXMLClass + + Public Property Key As String + Public Property Icon As String + Public Property Color As String + Public Property Caption As String + Public Property ShortCaption As String + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .Key = ex.Attribute("key").Value + .Icon = ex.Attribute("icon").Value + .Color = ex.Attribute("color").Value + .Caption = ex.Attribute("caption").Value + .ShortCaption = ex.Attribute("short-caption").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("key", Me.Key.ToString) + xE.SetAttributeValue("icon", Me.Icon.ToString) + xE.SetAttributeValue("color", Me.Color.ToString) + xE.SetAttributeValue("caption", Me.Caption.ToString) + xE.SetAttributeValue("short-caption", Me.ShortCaption.ToString) + Return xE + + End Function + +End Class diff --git a/OpenAntragLib/Models/Shared/Representative.vb b/OpenAntragLib/Models/Shared/Representative.vb new file mode 100644 index 0000000..3bce2ab --- /dev/null +++ b/OpenAntragLib/Models/Shared/Representative.vb @@ -0,0 +1,107 @@ +Imports System.IO +Imports System.Text +Imports System.Web + +Public Class Representative + + + Public Property Key_Representation As String + + + + Public Property ID As Integer + + Public Property Key As String + Public Property [Name] As String + Public Property Party As String + Public Property Mail As String + Public Property Twitter As String + Public Property Phone() As String + + Public ReadOnly Property PortraitImage() As String + Get + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key_Representation).Append("/Portraits/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles(Me.Key & ".*") + If fi.Count > 0 Then + Return String.Concat(stbPath.ToString, fi(0).Name) + Else + Return "/Images/dummy-portrait-invers.png" + End If + End Get + End Property + + + + Public ReadOnly Property HasPortraitImage() As Boolean + Get + Return (Me.PortraitImage <> "/Images/dummy-portrait-invers.png") + End Get + End Property + + + + Public ReadOnly Property Info As HtmlString + Get + Dim hs As New HtmlString("") + + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Representations/") + stbPath.Append(Me.Key_Representation).Append("/Info/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles(Me.Key & ".info") + If fi.Count > 0 Then + Dim sr As New StreamReader(fi(0).FullName, Encoding.UTF8) + Dim strContent As String = sr.ReadToEnd() + sr.Close() + hs = New HtmlString(strContent) + End If + + Return hs + End Get + End Property + + + Public ReadOnly Property InfoHtml() As String + Get + Return Me.Info.ToHtmlString + End Get + End Property + + Public Sub New() + End Sub + + Public Sub New(ex As XElement, keyRepresentation As String) + Me.New() + With Me + .Key_Representation = keyRepresentation + .ID = CType(ex.Attribute("id").Value, Integer) + .Key = ex.Attribute("key").Value + .[Name] = ex.Attribute("name").Value + .Party = ex.Attribute("party").Value + .Mail = ex.Attribute("mail").Value + .Twitter = ex.Attribute("twitter").Value.Replace("@", "") + .Phone = ex.Attribute("phone").Value + End With + End Sub + + Public Function GetXElement() As XElement + + Dim ex As New XElement("item") + ex.SetAttributeValue("id", Me.ID.ToString) + ex.SetAttributeValue("key", Me.Key.ToString) + ex.SetAttributeValue("name", Me.[Name].ToString) + ex.SetAttributeValue("party", Me.Party.ToString) + ex.SetAttributeValue("mail", Me.Mail.ToString) + ex.SetAttributeValue("phone", Me.Phone.ToString) + + Return ex + + End Function + +End Class + diff --git a/OpenAntragLib/Models/StatisticDataModels.vb b/OpenAntragLib/Models/StatisticDataModels.vb new file mode 100644 index 0000000..9004af5 --- /dev/null +++ b/OpenAntragLib/Models/StatisticDataModels.vb @@ -0,0 +1,12 @@ +Public Class BarColumnDataSDM + Public Property y As Integer + Public Property color As String + Public Property url As String +End Class + +Public Class PieSliceDataSDM + Public Property y As Integer + Public Property name As String + Public Property color As String + Public Property sliced As Boolean = False +End Class diff --git a/OpenAntragLib/Models/SuccessStory/SuccessStories.vb b/OpenAntragLib/Models/SuccessStory/SuccessStories.vb new file mode 100644 index 0000000..2742e2d --- /dev/null +++ b/OpenAntragLib/Models/SuccessStory/SuccessStories.vb @@ -0,0 +1,62 @@ +Imports Raven.Client + +Public Class SuccessStories + + Public Shared Function GetItemsCount() As Integer + + Dim intCount As Integer = -1 + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim stats As New RavenQueryStatistics + Dim query = ds.Query(Of SuccessStory)() _ + .Statistics(stats) _ + .Take(0).ToArray() + intCount = stats.TotalResults + + End Using + + Return intCount + + End Function + + Public Shared Function GetItemsPage(pageNo As Integer, + pageCount As Integer) As List(Of SuccessStory) + + Dim lst As New List(Of SuccessStory) + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim query = ds.Query(Of SuccessStory)() _ + .OrderByDescending(Function(e) e.StepDateTimestamp) _ + .Skip((pageNo - 1) * pageCount).Take(pageCount) + + If query.Count > 0 Then + lst = query.ToList + End If + + End Using + + Return lst.Where(Function(x) x.Proposal.Representation.IsTest = False).ToList + + End Function + + Public Shared Function GetById(id As String) As SuccessStory + + Dim model As SuccessStory = Nothing + + Using ds As IDocumentSession = DataDocumentStore.Session + + Dim entity = ds.Load(Of SuccessStory)(id) + + If entity IsNot Nothing Then + model = entity + End If + + End Using + + Return model + + End Function + +End Class diff --git a/OpenAntragLib/Models/SuccessStory/SuccessStory.vb b/OpenAntragLib/Models/SuccessStory/SuccessStory.vb new file mode 100644 index 0000000..453e7c8 --- /dev/null +++ b/OpenAntragLib/Models/SuccessStory/SuccessStory.vb @@ -0,0 +1,112 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Script.Serialization +Imports System.Web +Imports System.Text + +Public Class SuccessStory + Inherits RavenModelBase + + Public Property ID_Proposal As String + + Private _Proposal As Proposal + + + Public Property Proposal As Proposal + Get + If _Proposal Is Nothing Then + _Proposal = Proposals.GetById(Me.ID_Proposal) + End If + Return _Proposal + End Get + Set(value As Proposal) + _Proposal = value + End Set + End Property + + Public Property Title As String + + Public Property StepDate As String + + + + + Public ReadOnly Property StepDateFormat As String + Get + Return CType(Me.StepDate, DateTime).ToString("dd. MMMM yyyy") + End Get + End Property + + Private _StepDateTimestamp As Integer = 0 + Public Property StepDateTimestamp As Integer + Get + Try + If _StepDateTimestamp = 0 Then + _StepDateTimestamp = Tools.GetUnixTimestampFromDate(CType(Me.StepDate, DateTime)) + End If + Catch ex As Exception + End Try + Return _StepDateTimestamp + End Get + Set(value As Integer) + _StepDateTimestamp = value + End Set + End Property + + + + Public Property Text As String + + + Public ReadOnly Property TextHtml() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Dim str As String = MarkdownHelper.Markdown(txt).ToHtmlString + Return str + End Get + End Property + + + Public ReadOnly Property TextRaw() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Return MarkdownHelper.MarkdownText(txt) + End Get + End Property + + + Public ReadOnly Property TextMarkdown() As String + Get + Dim txt As String = HttpUtility.UrlDecode(Me.Text) + Return txt + End Get + End Property + + + Public ReadOnly Property FullUrl As String + Get + Return String.Concat(Me.Proposal.FullUrl, "/erfolg") + End Get + End Property + + Public Property ShortUrl As String + + Public Sub New() + + Me.CreatedAt = Format(DateTime.Now, "dd.MM.yyyy HH:mm:ss") + If HttpContext.Current.User.Identity.IsAuthenticated = True Then + Me.CreatedBy = HttpContext.Current.User.Identity.Name + End If + + End Sub + + Public Sub New(prop As Proposal) + + Me.New() + + Me.ID_Proposal = prop.Id + Me.Title = prop.Title + Me.StepDate = prop.CurrentProposalStep.CreatedAt + + End Sub + +End Class diff --git a/OpenAntragLib/Models/Teaser/Teaser.vb b/OpenAntragLib/Models/Teaser/Teaser.vb new file mode 100644 index 0000000..c51f0d1 --- /dev/null +++ b/OpenAntragLib/Models/Teaser/Teaser.vb @@ -0,0 +1,168 @@ +Imports System.Drawing +Imports System.Text +Imports System.Web +Imports System.IO + +Public Class Teaser + Implements IXMLClass + + + + Public Property ID As Integer + + Public Property Key As String + Public Property Label As String + Public Property Color As String + + + + Public ReadOnly Property ColorRGB As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim stb As New StringBuilder + stb.Append(cColor.R.ToString).Append(",") + stb.Append(cColor.G.ToString).Append(",") + stb.Append(cColor.B.ToString) + Return stb.ToString() + End Get + End Property + + + + Public ReadOnly Property ColorBright As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim cBrightColor As Color = cColor.ChangeColorBrightness(0.25) + Return ColorTranslator.ToHtml(cBrightColor) + End Get + End Property + + + + Public ReadOnly Property ColorText As String + Get + Dim cColor As Color = ColorTranslator.FromHtml(Me.Color) + Dim cBrightColor As Color = cColor.ChangeColorBrightness(-0.15) + Return ColorTranslator.ToHtml(cBrightColor) + End Get + End Property + + Public Property [Name] As String + Public Property [Name2] As String + Public Property Level As Integer + + Public Property FederalKey As String + + + Public Property Federal As FederalState + + Public Property Mail As String + Public Property Link As String + Public Property Twitter As String + + Public Property ElectionDate As String + + Public Property KeyRepresenation As String + + + + Public ReadOnly Property ElectionDateFormat As String + Get + If String.IsNullOrEmpty(Me.ElectionDate) = False Then + Return CType(Me.ElectionDate, DateTime).ToString("dd. MMMM yyyy") + Else + Return "" + End If + End Get + End Property + + Public Property TeaserUrl As String + + Public ReadOnly Property FullUrl As String + Get + Dim stb As New StringBuilder() + stb.Append("http://").Append(HttpContext.Current.Request.Url.Authority) + stb.Append("/").Append(TeaserUrl) + Return stb.ToString + End Get + End Property + + + + Public ReadOnly Property FraktionInfo As HtmlString + Get + Dim hs As New HtmlString("") + + Dim stbPath As New StringBuilder() + stbPath.Append("/Content/Teaser/") + stbPath.Append(Me.Key).Append("/Info/") + + Dim di As New DirectoryInfo(HttpContext.Current.Server.MapPath(stbPath.ToString)) + Dim fi As FileInfo() = di.GetFiles("teaser.info") + If fi.Count > 0 Then + Dim sr As New StreamReader(fi(0).FullName, Encoding.UTF8) + Dim strContent As String = sr.ReadToEnd() + sr.Close() + hs = New HtmlString(strContent) + End If + + Return hs + End Get + End Property + + + Public ReadOnly Property FraktionInfoHtml() As String + Get + Return Me.FraktionInfo.ToHtmlString + End Get + End Property + + Public Sub New() + End Sub + + Public Sub New(ex As XElement) + Me.New() + With Me + .ID = CType(ex.Attribute("id").Value, Integer) + .Key = ex.Attribute("key").Value + .Label = ex.Attribute("label").Value + .Color = ex.Attribute("color").Value + .[Name] = ex.Attribute("name").Value + .[Name2] = ex.Attribute("name2").Value + .Level = CType(ex.Attribute("level").Value, Integer) + .FederalKey = ex.Attribute("federal").Value + .Mail = ex.Attribute("mail").Value + .Link = ex.Attribute("link").Value + .Twitter = ex.Attribute("twitter").Value + + .TeaserUrl = ex.Attribute("teaser-url").Value + .ElectionDate = ex.Attribute("election-date").Value + + .KeyRepresenation = ex.Attribute("key-represenation").Value + End With + End Sub + + Public Function GetXElement(xD As XmlData) As XElement Implements IXMLClass.GetXElement + + Dim xE As New XElement(xD.ElementName) + xE.SetAttributeValue("id", Me.ID.ToString) + xE.SetAttributeValue("key", Me.Key.ToString) + xE.SetAttributeValue("label", Me.Label.ToString) + xE.SetAttributeValue("color", Me.Color.ToString) + xE.SetAttributeValue("name", Me.[Name].ToString) + xE.SetAttributeValue("level", Me.Level.ToString) + xE.SetAttributeValue("federal", Me.FederalKey.ToString) + xE.SetAttributeValue("name2", Me.Name2.ToString) + xE.SetAttributeValue("mail", Me.Mail.ToString) + xE.SetAttributeValue("link", Me.Link.ToString) + xE.SetAttributeValue("twitter", Me.Twitter.ToString) + + xE.SetAttributeValue("teaser-url", Me.TeaserUrl.ToString) + xE.SetAttributeValue("election-date", Me.ElectionDate.ToString) + + xE.SetAttributeValue("key-represenation", Me.KeyRepresenation) + + Return xE + + End Function +End Class diff --git a/OpenAntragLib/Models/Teaser/Teasers.vb b/OpenAntragLib/Models/Teaser/Teasers.vb new file mode 100644 index 0000000..a130a0b --- /dev/null +++ b/OpenAntragLib/Models/Teaser/Teasers.vb @@ -0,0 +1,67 @@ +Imports System.Text + +Public Class Teasers + + Public Property Items As List(Of Teaser) + + Public Sub New() + Dim xh As New XmlHelper + Me.Items = xh.GetInstance(Of Teaser)() + + Dim fed As New FederalStates + + For Each ts As Teaser In Me.Items + If String.IsNullOrEmpty(ts.FederalKey) = False Then + ts.Federal = (From fs As FederalState In fed.Items + Where fs.Key.ToUpper = ts.FederalKey.ToUpper + Select fs).First + End If + Next + + End Sub + + Public Function GetById(id As Integer) As Teaser + + Dim rep As Teaser = Nothing + + Dim query = From a As Teaser In Me.Items + Where a.ID = id + Select a + + If query.Count > 0 Then + rep = query.First + End If + + Return rep + + End Function + + Public Function GetByKey(keyTeaser As String) As Teaser + + Dim rep As Teaser = Nothing + + Dim query = From a As Teaser In Me.Items + Where a.Key = keyTeaser + Select a + + If query.Count > 0 Then + rep = query.First + End If + + Return rep + + End Function + + Public Shared Sub ReplaceStyleColor(ByRef rep As Teaser, + ByVal stb As StringBuilder) + + stb.Replace("[ID]", rep.ID.ToString) + stb.Replace("[KEY]", rep.Key) + stb.Replace("[COLOR]", rep.Color) + stb.Replace("[COLOR-RGB]", rep.ColorRGB) + stb.Replace("[COLORBRIGHT]", rep.ColorBright) + stb.Replace("[COLORTEXT]", rep.ColorText) + + End Sub + +End Class diff --git a/OpenAntragLib/My Project/Application.Designer.vb b/OpenAntragLib/My Project/Application.Designer.vb new file mode 100644 index 0000000..0aecefe --- /dev/null +++ b/OpenAntragLib/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/OpenAntragLib/My Project/Application.myapp b/OpenAntragLib/My Project/Application.myapp new file mode 100644 index 0000000..758895d --- /dev/null +++ b/OpenAntragLib/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff --git a/OpenAntragLib/My Project/AssemblyInfo.vb b/OpenAntragLib/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..fe96e18 --- /dev/null +++ b/OpenAntragLib/My Project/AssemblyInfo.vb @@ -0,0 +1,35 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: +' + + + diff --git a/OpenAntragLib/My Project/Resources.Designer.vb b/OpenAntragLib/My Project/Resources.Designer.vb new file mode 100644 index 0000000..ecf7e36 --- /dev/null +++ b/OpenAntragLib/My Project/Resources.Designer.vb @@ -0,0 +1,63 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + ''' + ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("OpenAntrag.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/OpenAntragLib/My Project/Resources.resx b/OpenAntragLib/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/OpenAntragLib/My Project/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OpenAntragLib/My Project/Settings.Designer.vb b/OpenAntragLib/My Project/Settings.Designer.vb new file mode 100644 index 0000000..a5215bf --- /dev/null +++ b/OpenAntragLib/My Project/Settings.Designer.vb @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.18444 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) + +#Region "My.Settings Auto-Save Functionality" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub +#End If +#End Region + + Public Shared ReadOnly Property [Default]() As MySettings + Get + +#If _MyType = "WindowsForms" Then + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If +#End If + Return defaultInstance + End Get + End Property + End Class +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.OpenAntrag.My.MySettings + Get + Return Global.OpenAntrag.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/OpenAntragLib/My Project/Settings.settings b/OpenAntragLib/My Project/Settings.settings new file mode 100644 index 0000000..85b890b --- /dev/null +++ b/OpenAntragLib/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/OpenAntragLib/OpenAntragLib.vbproj b/OpenAntragLib/OpenAntragLib.vbproj new file mode 100644 index 0000000..6567f4a --- /dev/null +++ b/OpenAntragLib/OpenAntragLib.vbproj @@ -0,0 +1,278 @@ + + + + + Debug + AnyCPU + {0FFFC9E8-FE8F-485E-88FC-AF0B947E9FB2} + Library + OpenAntrag + OpenAntragLib + 512 + Windows + v4.5.1 + SAK + SAK + SAK + SAK + + + + true + full + true + true + bin\Debug\ + OpenAntragLib.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + pdbonly + false + true + true + bin\Release\ + OpenAntragLib.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + packages\ActionMailer.0.7.4\lib\Net40\ActionMailer.Net.dll + + + packages\ActionMailer.0.7.4\lib\Net40\ActionMailer.Net.Mvc.dll + + + ..\OpenAntrag\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll + + + False + Libraries\LinqToTwitter.dll + + + packages\MarkdownDeep.NET.1.5\lib\.NetFramework 3.5\MarkdownDeep.dll + + + True + ..\OpenAntrag\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + False + ..\OpenAntrag\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll + + + False + ..\OpenAntrag\packages\RavenDB.Client.2.5.2935\lib\net45\Raven.Abstractions.dll + + + False + ..\OpenAntrag\packages\RavenDB.Client.2.5.2935\lib\net45\Raven.Client.Lightweight.dll + + + + + + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll + + + + + + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll + + + ..\OpenAntrag\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll + + + False + ..\OpenAntrag\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + + + + \ No newline at end of file diff --git a/OpenAntragLib/RandomKeyGenerator.vb b/OpenAntragLib/RandomKeyGenerator.vb new file mode 100644 index 0000000..f739ec6 --- /dev/null +++ b/OpenAntragLib/RandomKeyGenerator.vb @@ -0,0 +1,154 @@ +Imports System.Text + +'http://www.codeproject.com/Articles/11142/Generate-a-Random-String-Key-in-VB-NET + +Public Class RandomKeyGenerator + + Public Property Letters() As String + Public Property Numbers() As String + Public Property CharCount() As Integer + Public Property Capatalize As Boolean + + Public Sub New(intKeyChars As Integer) + + Me.New(intKeyChars, + SettingsWrapper.RandomKey_AllowCapitalLetters) + + End Sub + + Public Sub New(intKeyChars As Integer, + Optional ByVal bolCapitalize As Boolean = True) + + Me.New(intKeyChars, + SettingsWrapper.RandomKey_Letters, + SettingsWrapper.RandomKey_Numbers, + bolCapitalize) + + End Sub + + Public Sub New(intKeyChars As Integer, + strKeyLetters As String, + strKeyNumbers As String, + Optional ByVal bolCapitalize As Boolean = True) + + Me.CharCount = intKeyChars + Me.Letters = strKeyLetters + Me.Numbers = strKeyNumbers + Me.Capatalize = bolCapitalize + + End Sub + + Public Function Generate() As String + + Dim intKey As Integer + Dim sngRandom As Single + Dim arrIndex As Int16 + Dim stb As New StringBuilder + Dim strLetter As String + + 'CONVERT LettersArray & NumbersArray TO CHARACTR ARRAYS + Dim LettersArray As Char() = Me.Letters.ToCharArray + Dim NumbersArray As Char() = Me.Numbers.ToCharArray + + For intKey = 1 To Me.CharCount + + Randomize() + sngRandom = Rnd() + arrIndex = -1 + + 'IF THE VALUE IS AN EVEN NUMBER WE GENERATE A LETTER, OTHERWISE WE GENERATE A NUMBER + 'THE NUMBER '111' WAS RANDOMLY CHOSEN. ANY NUMBER WILL DO, WE JUST NEED TO BRING THE VALUE ABOVE '0' + If NumbersArray.Length > 1 AndAlso (CType(sngRandom * 111, Integer)) Mod 2 = 0 Then + + 'GENERATE A RANDOM INDEX IN THE LETTERS CHARACTER ARRAY + Do While arrIndex < 0 + arrIndex = Convert.ToInt16(LettersArray.GetUpperBound(0) * sngRandom) + Loop + strLetter = LettersArray(arrIndex) + + 'CREATE ANOTHER RANDOM NUMBER. IF IT IS ODD, WE CAPITALIZE THE LETTER + If (CType(arrIndex * sngRandom * 99, Integer)) Mod 2 <> 0 Then + strLetter = LettersArray(arrIndex).ToString + If Me.Capatalize = True Then strLetter = strLetter.ToUpper + End If + stb.Append(strLetter) + Else + 'GENERATE A RANDOM INDEX IN THE NUMBERS CHARACTER ARRAY + Do While arrIndex < 0 + arrIndex = Convert.ToInt16(NumbersArray.GetUpperBound(0) * sngRandom) + Loop + stb.Append(NumbersArray(arrIndex)) + End If + Next + + Return stb.ToString + + End Function + + Public Function GenerateLettersOnly() As String + + Dim intKey As Integer + Dim sngRandom As Single + Dim arrIndex As Int16 + Dim stb As New StringBuilder + Dim strLetter As String + + 'CONVERT LettersArray & NumbersArray TO CHARACTR ARRAYS + Dim LettersArray As Char() = Me.Letters.ToCharArray + Dim NumbersArray As Char() = Me.Numbers.ToCharArray + + For intKey = 1 To Me.CharCount + + Randomize() + sngRandom = Rnd() + arrIndex = -1 + + 'GENERATE A RANDOM INDEX IN THE LETTERS CHARACTER ARRAY + Do While arrIndex < 0 + arrIndex = Convert.ToInt16(LettersArray.GetUpperBound(0) * sngRandom) + Loop + strLetter = LettersArray(arrIndex) + + 'CREATE ANOTHER RANDOM NUMBER. IF IT IS ODD, WE CAPITALIZE THE LETTER + If (CType(arrIndex * sngRandom * 99, Integer)) Mod 2 <> 0 Then + strLetter = LettersArray(arrIndex).ToString + If Me.Capatalize = True Then strLetter = strLetter.ToUpper + End If + stb.Append(strLetter) + + Next + + Return stb.ToString + + End Function + + Public Function GenerateNumbersOnly() As String + + Dim intKey As Integer + Dim sngRandom As Single + Dim arrIndex As Int16 + Dim stb As New StringBuilder + + 'CONVERT LettersArray & NumbersArray TO CHARACTR ARRAYS + Dim LettersArray As Char() = Me.Letters.ToCharArray + Dim NumbersArray As Char() = Me.Numbers.ToCharArray + + For intKey = 1 To Me.CharCount + + Randomize() + sngRandom = Rnd() + arrIndex = -1 + + 'GENERATE A RANDOM INDEX IN THE NUMBERS CHARACTER ARRAY + Do While arrIndex < 0 + arrIndex = Convert.ToInt16(NumbersArray.GetUpperBound(0) * sngRandom) + Loop + stb.Append(NumbersArray(arrIndex)) + + Next + + Return stb.ToString + + End Function + +End Class diff --git a/OpenAntragLib/RepresentationRouteConstraint.vb b/OpenAntragLib/RepresentationRouteConstraint.vb new file mode 100644 index 0000000..00d2e18 --- /dev/null +++ b/OpenAntragLib/RepresentationRouteConstraint.vb @@ -0,0 +1,35 @@ +Imports System.Web +Imports System.Web.Routing + +Public Class RepresentationRouteConstraint + Implements IRouteConstraint + + Public Function Match(httpContext As HttpContextBase, + route As Route, + parameterName As String, + values As RouteValueDictionary, + routeDirection As RouteDirection) As Boolean Implements IRouteConstraint.Match + + Dim intLength As Integer = values.Count - 1 + + Dim strController As String = values.Values(intLength - 1) + Dim strAction As String = values.Values(intLength) + + Dim strParameterName As String = parameterName + Dim strParameterValue As String = values.Item(parameterName) + + If strParameterName = "keyRepresentation" AndAlso + String.IsNullOrEmpty(strParameterValue) = False AndAlso + strController = "Representation" Then + + Dim rep As Representation = GlobalData.Representations.GetByKey(strParameterValue.ToLower) + + Return rep IsNot Nothing + + End If + + Return False + + End Function + +End Class diff --git a/OpenAntragLib/Tools.vb b/OpenAntragLib/Tools.vb new file mode 100644 index 0000000..c793963 --- /dev/null +++ b/OpenAntragLib/Tools.vb @@ -0,0 +1,574 @@ +Imports System.Runtime.CompilerServices +Imports System.Security.Cryptography +Imports System.IO +Imports System.Drawing +Imports System.Drawing.Drawing2D +Imports System.Web +Imports System.Text +Imports System.Text.RegularExpressions +Imports System.Web.Security + +Public Module Tools + + Public Function GetCookie(ByVal key As String, + Optional ByVal returnEmptyString As Boolean = False) As String + + If HttpContext.Current.Request.Cookies(key) IsNot Nothing Then + Return HttpContext.Current.Request.Cookies(key).Value + Else + If returnEmptyString = True Then + Return "" + Else + Return Nothing + End If + End If + + End Function + + Public Function GetRequestDomain() As String + + Dim arrAuthority As String() = HttpContext.Current.Request.Url.Authority.Split(".") + + Dim stb As New StringBuilder + + If arrAuthority.Length >= 2 Then + stb.Append(arrAuthority(arrAuthority.Length - 2)).Append(".") + End If + + stb.Append(arrAuthority(arrAuthority.Length - 1)) + + Return stb.ToString + + End Function + + + Public Function RepresentationRoles(user As System.Security.Principal.IPrincipal) As String() + + Dim arrRepRoles As String() + Dim arrRoles As String() = Roles.GetRolesForUser(user.Identity.Name) + + arrRepRoles = (From s As String In arrRoles + Where s.ToUpper() <> "ADMIN" + Select s).ToArray() + + Return arrRepRoles + + End Function + + Public Function IsAdmin(Optional repKey As String = Nothing) As Boolean + + If HttpContext.Current.User.IsInRole("admin") = True OrElse + (String.IsNullOrEmpty(repKey) = False And HttpContext.Current.User.IsInRole(repKey) = True) Then + Return True + End If + + Return False + + End Function + + Public Function IsCreatedByAdmin(repKey As String, createdBy As String) As Boolean + + If String.IsNullOrEmpty(createdBy) = False Then + If HttpContext.Current.User.IsInRole("admin") = True Then + Return True + Else + If IsAdmin(repKey) = True Then + Return (HttpContext.Current.User.Identity.Name.ToLower = createdBy.ToLower) + End If + End If + End If + + Return False + + End Function + + Public Function ControllerExists(strControllerNamePart As String) As Boolean + + 'http://stackoverflow.com/questions/7033428/how-to-make-sure-controller-and-action-exists-before-doing-redirect-asp-net-mvc + + Dim stbControllerName As New StringBuilder(strControllerNamePart.ToLower) + stbControllerName.Append("controller") + + Dim types As Type() = System.Reflection.Assembly.GetExecutingAssembly().GetTypes() + Dim type As Type = types.Where(Function(t) t.Name.ToLower = stbControllerName.ToString).SingleOrDefault + + If type IsNot Nothing Then + Return True + Else + Return False + End If + + End Function + + Public Function GetUnixTimestampFromDate(dat As DateTime) As Integer + + Dim datStart As DateTime = #1/1/1970# + Dim ts As TimeSpan + + ts = dat.Subtract(datStart) + Return CType(Math.Abs(ts.TotalSeconds()), Integer) + + End Function + + Public Function GetDateFromTimestamp(ByVal intTimestamp As Integer) As DateTime + + Dim ts As TimeSpan + Dim datStart As Date = #1/1/1970# + + If intTimestamp = 0 Then Return datStart + + ts = New TimeSpan(0, 0, intTimestamp) + Return datStart.Add(ts) + + End Function + + Public Function FormatTwoDates(strDate1 As String, strDate2 As String) As String + + Dim dat1 As DateTime = CType(strDate1, DateTime) + Dim dat2 As DateTime = CType(strDate2, DateTime) + + Dim intDayDelta As Integer = DateDiff("d", dat1, dat2) + Dim intMonthDelta As Integer = dat2.Month - dat1.Month + Dim intYearDelta As Integer = dat2.Year - dat1.Year + + Dim stb As New StringBuilder + + If intYearDelta <> 0 Then + stb.Append(Format(dat1, "dd. MMMM yyyy")) + stb.Append(" - ") + stb.Append(Format(dat2, "dd. MMMM yyyy")) + ElseIf intMonthDelta <> 0 Then + stb.Append(Format(dat1, "dd. MMMM ")) + stb.Append(" - ") + stb.Append(Format(dat2, "dd. MMMM yyyy")) + Else + stb.Append(Format(dat1, "dd. ")) + If intDayDelta = 1 Then + stb.Append(" / ") + Else + stb.Append(" - ") + End If + stb.Append(Format(dat2, "dd. MMMM yyyy")) + End If + + Return stb.ToString + + End Function + + Public Function GetMd5(ByVal str As String) As String + + 'Dim strHash As String = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str.Trim(), "MD5") + 'strHash = strHash.Trim().ToLower() + + Dim strHash As String + Using md5Hash As MD5 = MD5.Create() + Dim data As Byte() = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(str)) + Dim sBuilder As New StringBuilder() + + Dim i As Integer + For i = 0 To data.Length - 1 + sBuilder.Append(data(i).ToString("x2")) + Next i + + strHash = sBuilder.ToString().Trim().ToLower() + + End Using + + Return strHash + + End Function + + Public Function VerifyMd5(ByVal input As String, ByVal hash As String) As Boolean + + Dim hashOfInput As String = GetMd5(input) + + Dim comparer As StringComparer = StringComparer.OrdinalIgnoreCase + + If comparer.Compare(hashOfInput, hash.Trim().ToLower()) = 0 Then + Return True + Else + Return False + End If + + End Function + + + Public Function GetExtension(strFileName As String) As String + + Dim arr As String() = Split(strFileName, ".") + Return arr(arr.Length - 1) + + End Function + + + Public Function GetFilesMultiExtension(ByVal di As DirectoryInfo, + ByVal strExtensionList As String) As FileInfo() + + Dim lstFileInfo As New List(Of FileInfo) + Dim arrExtensions As String() = Split(strExtensionList, ",") + + For Each ext As String In arrExtensions + lstFileInfo.AddRange(di.GetFiles("*." & ext)) + Next + + Return lstFileInfo.ToArray() + + End Function + + + Public Function RandomizeList(Of T)(ByVal list As List(Of T)) As List(Of T) + + Dim rnd As New Random() + Return list.OrderBy(Function(m) rnd.Next()).ToList() + + End Function + + + Public Function ToFourDigitYear(intToDigitYear As Integer) As Integer + + Dim stb As New StringBuilder + stb.Append(20).Append(intToDigitYear) + Return CType(stb.ToString, Integer) + + End Function + + + Public Sub Prepend(ByRef str As String, + ByVal strPrepend As String, + Optional ByVal strDelimiter As String = "") + str = String.Concat(strPrepend, strDelimiter, str) + End Sub + + + Public Sub Prepend(ByRef stb As StringBuilder, + ByVal strValue As String, + Optional ByVal strDelimiter As String = "") + + Dim stbNew As New StringBuilder(strValue) + If stb.ToString.Length > 0 AndAlso strDelimiter.Length > 0 Then stbNew.Append(strDelimiter) + stbNew.Append(stb.ToString()) + stb = stbNew + + End Sub + + + Public Function CleanHtmlCode(strHtml As String, + Optional ByVal bolCleanEmptyTags As Boolean = False) As String + + Dim strRetVal As String + + 'Whitespace + Dim regex1 As New Regex(">[\s]*<") + strRetVal = regex1.Replace(strHtml, "><") + + 'Empty Tags + If bolCleanEmptyTags = True Then + Dim regex2 As New Regex("<(\w+)\b[^>]*>\s*") + strRetVal = regex2.Replace(strHtml, "") + End If + + 'Linebreaks + strRetVal = strRetVal.Replace(vbCrLf, "").Replace(vbCr, "") + + Return strRetVal + + End Function + + + Public Function StripHtmlCode(strHtml As String) As String + + Dim oRegEx As New Regex("<.*?>") + + Return oRegEx.Replace(strHtml, "") + + End Function + + + Public Function StripSpecialCharsForTitle(strText As String) As String + Return Regex.Replace(strText, "[^\w-_ ]+", "") + End Function + + + Public Function CutEllipsis(stbText As StringBuilder, intMaxLength As Integer) As String + Return stbText.ToString.CutEllipsis(intMaxLength) + End Function + + + Public Function CutEllipsis(strText As String, intMaxLength As Integer) As String + + If strText.Length <= intMaxLength Then + Return strText + Else + Return String.Concat(Left(strText, intMaxLength - 3), "...") + End If + + End Function + + + Public Function PreserveLines(strValue As String) As String + + Dim stb As New StringBuilder(strValue) + stb.Replace(vbCrLf, "\n") + Return stb.ToString + + End Function + + + Public Function EnsureMarkdown(strValue As String) As String + + Return strValue.StripHtmlCode.PreserveLines + + End Function + + + Public Function ShowNone(strValue) As String + + If String.IsNullOrEmpty(strValue) = False Then + Return strValue + Else + Return "- keine Angabe -" + End If + + End Function + + + Public Function HasHtmlCode(strValue As String) As Boolean + + Dim oRegEx As New Regex("<.*?>") + Return oRegEx.IsMatch(strValue) + + End Function + + + Public Function ToLocalUrl(strUrlPart As String) As String + + Dim strUrl As String = Nothing + + If strUrlPart IsNot Nothing Then + If strUrlPart.Length > 1 AndAlso + Not strUrlPart.StartsWith("//") AndAlso + Not strUrlPart.StartsWith("/\\") Then + strUrl = String.Concat("http://", HttpContext.Current.Request.Url.Authority, strUrlPart) + End If + End If + + Return strUrl + + End Function + + Public Function IsValidMail(strMail As String) As Boolean + Try + Static rx As New Regex("^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$") + Return rx.IsMatch(strMail) + Catch ex As Exception + Return False + End Try + End Function + + Public Function IsUri(strUrl As String) As Boolean + Dim bolRetVal As Boolean = False + Try + Dim u As New Uri(strUrl) + If u IsNot Nothing Then bolRetVal = True + Catch ex As Exception + End Try + Return bolRetVal + End Function + + Public Function IsValidUrl(strUrl As String) As Boolean + Try + 'Const strRegExPattern As String = "^(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'.,<>?«»""‘’]))$" + Const strRegExPattern As String = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?" + + Static rx As New Regex(strRegExPattern) + Return rx.IsMatch(strUrl) + Catch ex As Exception + Return False + End Try + End Function + + Public Function GetRfc822Date(ByVal [date] As DateTime) As String + + 'http://madskristensen.net/post/Convert-a-date-to-the-RFC822-standard-for-use-in-RSS-feeds.aspx + + Dim offset As Integer = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours + + Dim timeZone1 As String = "+" & offset.ToString().PadLeft(2, "0"c) + + If offset < 0 Then + Dim i As Integer = offset * -1 + timeZone1 = "-" & i.ToString().PadLeft(2, "0"c) + End If + + Return [date].ToString("ddd, dd MMM yyyy HH:mm:ss " & timeZone1.PadRight(5, "0"c)) + + End Function + + Public Function MakeReadableUrl(ByVal strValue As String, + Optional ByVal bolExcludeDot As Boolean = False) As String + + strValue = strValue.ToLower + + strValue = Regex.Replace(strValue, "[\s_]", "-") '(Leerezeichen und Interpunktion) + + strValue = Regex.Replace(strValue, "[ä]", "ae") '(Umlaute...) + strValue = Regex.Replace(strValue, "[ü]", "ue") + strValue = Regex.Replace(strValue, "[ö]", "oe") + strValue = Regex.Replace(strValue, "[áà]", "a") '(Accénts...) + strValue = Regex.Replace(strValue, "[úù]", "u") + strValue = Regex.Replace(strValue, "[óò]", "o") + strValue = Regex.Replace(strValue, "[éè]", "e") + strValue = Regex.Replace(strValue, "[íì]", "i") + + strValue = Regex.Replace(strValue, "[ß]", "ss") + strValue = Regex.Replace(strValue, "[\[\]\(\)\{\}\|\?\+\*\^\$\\]", "") '(RegEx-Metazeichen) + strValue = Regex.Replace(strValue, "[,:;'""@#~^<>°!§%&/=]", "") + + If bolExcludeDot = False Then + strValue = Regex.Replace(strValue, "[.]", "") + End If + + strValue = Regex.Replace(strValue, "(\-)+", "-") '(mehrfache Striche zu einem zusammenfassen) + + Return strValue.ToLower() + + End Function + + + Public Function ReadableLength(fi As FileInfo) As String + + Dim arrSizeDef As String() = {"Byte", "KB", "MB", "GB"} + Dim intLen As Double = fi.Length + Dim intOrder As Integer = 0 + + While intLen >= 1024 AndAlso intOrder + 1 < arrSizeDef.Length + intOrder += 1 + intLen = intLen / 1024 + End While + + ' Adjust the format string to your preferences. For example "{0:0.#}{1}" would + ' show a single decimal place, and no space. + Return [String].Format("{0:0.##} {1}", intLen, arrSizeDef(intOrder)) + + End Function + + ''' + ''' Fügt einen neuen Text an einen bestehenden an. Sofern der bestehende Text nicht leer ist, wird DAVOR der Separator angefügt. + ''' + ''' + ''' + ''' + ''' + ''' + + Public Function AppendWithSeperator(ByVal stb As StringBuilder, + ByVal strValue As String, + ByVal strSeperator As String) As StringBuilder + + If stb.Length > 0 Then + stb.Append(strSeperator).Append(strValue) + Else + stb.Append(strValue) + End If + + Return stb + + End Function + + ''' + ''' http://www.codeproject.com/Articles/191424/Resizing-an-Image-On-The-Fly-using-NET + ''' + ''' + ''' + ''' + ''' + ''' + Public Function ResizeImage(ByVal image As Image, + ByVal size As Size, + Optional ByVal preserveAspectRatio As Boolean = True) As Image + + Dim newWidth As Integer + Dim newHeight As Integer + + If preserveAspectRatio Then + Dim originalWidth As Integer = image.Width + Dim originalHeight As Integer = image.Height + Dim percentWidth As Single = CSng(size.Width) / CSng(originalWidth) + Dim percentHeight As Single = CSng(size.Height) / CSng(originalHeight) + Dim percent As Single = If(percentHeight < percentWidth, + percentHeight, percentWidth) + newWidth = CInt(originalWidth * percent) + newHeight = CInt(originalHeight * percent) + Else + newWidth = size.Width + newHeight = size.Height + End If + + Dim newImage As Image = New Bitmap(newWidth, newHeight) + + Using graphicsHandle As Graphics = Graphics.FromImage(newImage) + graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic + graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight) + End Using + + Return newImage + + End Function + + + Public Function nz(Of T)(ByVal Value As T, ByVal Replacement As T) As T + + Try + If Value Is Nothing OrElse IsDBNull(Value) Then + Return Replacement + Else + Return Value + End If + Catch e As Exception + Return Replacement + End Try + + End Function + + + Public Function BreakWordsHtml(strValue As String, Optional intLimit As Integer = 10) As String + + Dim stb As New StringBuilder(strValue) + + If strValue.Length > intLimit Then + stb.Replace(" ", "
          ") + stb.Replace("-", "-
          ") + End If + + Return stb.ToString + + End Function + + + Public Function ChangeColorBrightness(col As Color, + correctionFactor As Single) As Color + + 'http://stackoverflow.com/questions/801406/c-create-a-lighter-darker-color-based-on-a-system-color + + Dim red As Single = CSng(col.R) + Dim green As Single = CSng(col.G) + Dim blue As Single = CSng(col.B) + + If correctionFactor < 0 Then + correctionFactor = 1 + correctionFactor + red *= correctionFactor + green *= correctionFactor + blue *= correctionFactor + Else + red = (255 - red) * correctionFactor + red + green = (255 - green) * correctionFactor + green + blue = (255 - blue) * correctionFactor + blue + End If + + Return Color.FromArgb(col.A, + CInt(Math.Truncate(red)), + CInt(Math.Truncate(green)), + CInt(Math.Truncate(blue))) + End Function + +End Module diff --git a/OpenAntragLib/UrlShortener.vb b/OpenAntragLib/UrlShortener.vb new file mode 100644 index 0000000..e961fc2 --- /dev/null +++ b/OpenAntragLib/UrlShortener.vb @@ -0,0 +1,36 @@ +Imports System.Net +Imports System.Text + +Public Class UrlShortener + + Public Shared Function GetShortUrl(strFullUrl As String) As String + + Const strRequestUrl As String = "http://pirat.ly/shortener/api/createplain/{ApiKey}/?{Url}" + + Dim strRetVal As String = "" + + Dim stbUrl As New StringBuilder(strRequestUrl) + stbUrl.Replace("{ApiKey}", SettingsWrapper.PiratlyApiKey) + stbUrl.Replace("{Url}", strFullUrl) + + Try + Dim req As HttpWebRequest = HttpWebRequest.Create(stbUrl.ToString) + req.Method = "GET" + req.ContentType = "text/xml; encoding='utf-8'" + req.Timeout = 1000 + + Dim res As HttpWebResponse = req.GetResponse() + Dim rd As New IO.StreamReader(res.GetResponseStream()) + strRetVal = rd.ReadToEnd + + If strRetVal.StartsWith("http://pirat.ly") = False Then strRetVal = "" + + Catch ex As Exception + 'TODO: GetShortUrl-Errors + End Try + + Return strRetVal + + End Function + +End Class diff --git a/OpenAntragLib/ValidationAttributes/AccountMailUniqueAttribute.vb b/OpenAntragLib/ValidationAttributes/AccountMailUniqueAttribute.vb new file mode 100644 index 0000000..335aef6 --- /dev/null +++ b/OpenAntragLib/ValidationAttributes/AccountMailUniqueAttribute.vb @@ -0,0 +1,43 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Mvc +Imports System.Web.Security + +Public Class AccountMailUniqueAttribute + Inherits ValidationAttribute + Implements IClientValidatable + + Private Const strDefaultErrorMessage As String = "Dieser Benutzer-Mail-Adresse existiert bereits" + + Public Sub New() + MyBase.New(strDefaultErrorMessage) + End Sub + + Protected Overrides Function IsValid(ByVal value As Object, context As ValidationContext) As ValidationResult + + '--ClientValidation: AccountController.IsAccountMailUnique + + Dim strWantedMail As String = CType(value, String) + + Dim strUserName As String = Membership.GetUserNameByEmail(strWantedMail) + + If String.IsNullOrEmpty(strUserName) = False Then + Return New ValidationResult(FormatErrorMessage(context.DisplayName)) + End If + + Return ValidationResult.Success + + End Function + + Public Overrides Function FormatErrorMessage(name As String) As String + Return String.Format(ErrorMessageString, name) + End Function + + Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, + context As System.Web.Mvc.ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules + + Dim rule As New ModelClientValidationRule() With {.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), + .ValidationType = "accountmailunique"} + Return New ModelClientValidationRule() {rule} + End Function + +End Class diff --git a/OpenAntragLib/ValidationAttributes/AccountNameUniqueAttribute.vb b/OpenAntragLib/ValidationAttributes/AccountNameUniqueAttribute.vb new file mode 100644 index 0000000..d2dba9c --- /dev/null +++ b/OpenAntragLib/ValidationAttributes/AccountNameUniqueAttribute.vb @@ -0,0 +1,43 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Mvc +Imports System.Web.Security + +Public NotInheritable Class AccountNameUniqueAttribute + Inherits ValidationAttribute + Implements IClientValidatable + + Private Const strDefaultErrorMessage As String = "Dieser Benutzername existiert bereits" + + Public Sub New() + MyBase.New(strDefaultErrorMessage) + End Sub + + Protected Overrides Function IsValid(ByVal value As Object, context As ValidationContext) As ValidationResult + + '--ClientValidation: AccountController.IsAccountNameUnique + + Dim strWantedName As String = CType(value, String) + + Dim usr As MembershipUser = Membership.GetUser(strWantedName) + + If usr IsNot Nothing Then + Return New ValidationResult(FormatErrorMessage(context.DisplayName)) + End If + + Return ValidationResult.Success + + End Function + + Public Overrides Function FormatErrorMessage(name As String) As String + Return String.Format(ErrorMessageString, name) + End Function + + Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, + context As System.Web.Mvc.ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules + + Dim rule As New ModelClientValidationRule() With {.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), + .ValidationType = "accountnameunique"} + Return New ModelClientValidationRule() {rule} + End Function + +End Class diff --git a/OpenAntragLib/ValidationAttributes/MailValidAttribute.vb b/OpenAntragLib/ValidationAttributes/MailValidAttribute.vb new file mode 100644 index 0000000..bfc712c --- /dev/null +++ b/OpenAntragLib/ValidationAttributes/MailValidAttribute.vb @@ -0,0 +1,38 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Mvc + +Public Class MailValidAttribute + Inherits ValidationAttribute + Implements IClientValidatable + + Private Const strDefaultErrorMessage As String = "Ungültige Mail-Adresse" + + Public Sub New() + MyBase.New(strDefaultErrorMessage) + End Sub + + Protected Overrides Function IsValid(ByVal value As Object, context As ValidationContext) As ValidationResult + + Dim strMailAddress As String = CType(value, String) + + If Tools.IsValidMail(strMailAddress) = False Then + Return New ValidationResult(FormatErrorMessage(context.DisplayName)) + End If + + Return ValidationResult.Success + + End Function + + Public Overrides Function FormatErrorMessage(name As String) As String + Return String.Format(ErrorMessageString, name) + End Function + + Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, + context As System.Web.Mvc.ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules + + Dim rule As New ModelClientValidationRule() With {.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), + .ValidationType = "mailvalid"} + Return New ModelClientValidationRule() {rule} + End Function + +End Class diff --git a/OpenAntragLib/ValidationAttributes/UrlValidAttribute.vb b/OpenAntragLib/ValidationAttributes/UrlValidAttribute.vb new file mode 100644 index 0000000..d039226 --- /dev/null +++ b/OpenAntragLib/ValidationAttributes/UrlValidAttribute.vb @@ -0,0 +1,39 @@ +Imports System.ComponentModel.DataAnnotations +Imports System.Web.Mvc + +Public Class UrlValidAttribute + Inherits ValidationAttribute + Implements IClientValidatable + + Private Const strDefaultErrorMessage As String = "Ungültige Url" + + Public Sub New() + MyBase.New(strDefaultErrorMessage) + End Sub + + Protected Overrides Function IsValid(ByVal value As Object, + context As ValidationContext) As ValidationResult + + Dim strUrl As String = CType(value, String) + + If String.IsNullOrEmpty(strUrl) = False AndAlso Tools.IsValidUrl(strUrl) = False Then + Return New ValidationResult(FormatErrorMessage(context.DisplayName)) + End If + + Return ValidationResult.Success + + End Function + + Public Overrides Function FormatErrorMessage(name As String) As String + Return String.Format(ErrorMessageString, name) + End Function + + Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, + context As System.Web.Mvc.ControllerContext) As IEnumerable(Of ModelClientValidationRule) Implements IClientValidatable.GetClientValidationRules + + Dim rule As New ModelClientValidationRule() With {.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), + .ValidationType = "urlvalid"} + Return New ModelClientValidationRule() {rule} + End Function + +End Class diff --git a/OpenAntragLib/Wrapper/CookieWrapper.vb b/OpenAntragLib/Wrapper/CookieWrapper.vb new file mode 100644 index 0000000..a2b1592 --- /dev/null +++ b/OpenAntragLib/Wrapper/CookieWrapper.vb @@ -0,0 +1,43 @@ +Imports System.Web + +Public Class CookieWrapper + + Public Overloads Shared Function GetCookie(ByVal strName As String) As String + + If Not HttpContext.Current.Request.Cookies(strName) Is Nothing Then + Return HttpContext.Current.Request.Cookies(strName).Value + Else + Return Nothing + End If + + End Function + + Public Overloads Shared Function GetCookie(ByVal strName As String, ByVal strDefaultValue As String) As String + + If HttpContext.Current.Request.Cookies(strName) Is Nothing Then + Call SetCookie(strName, strDefaultValue, 1) + End If + + Return HttpContext.Current.Request.Cookies(strName).Value + + End Function + + Public Shared Sub SetCookie(ByVal strName As String, + ByVal strValue As String, + Optional ByVal intExpiresInDays As Integer = 1) + + Dim oCookie As New HttpCookie(strName, strValue) + oCookie.Expires = DateTime.Now.AddDays(1) + HttpContext.Current.Response.Cookies.Add(oCookie) + + End Sub + + Public Shared Sub RemoveCookie(ByVal strName As String) + + Dim oCookie As HttpCookie = New HttpCookie(strName) + oCookie.Expires = DateTime.Now.AddDays(-1D) + HttpContext.Current.Response.Cookies.Add(oCookie) + + End Sub + +End Class diff --git a/OpenAntragLib/Wrapper/SessionWrapper.vb b/OpenAntragLib/Wrapper/SessionWrapper.vb new file mode 100644 index 0000000..40f48b2 --- /dev/null +++ b/OpenAntragLib/Wrapper/SessionWrapper.vb @@ -0,0 +1,34 @@ +Imports System.Web + +Public Class SessionWrapper + +#Region "Helper" + + Private Shared Function GetFromSession(Of T)(ByVal strKey As String) As T + + If HttpContext.Current.Session IsNot Nothing Then + Dim obj As Object = HttpContext.Current.Session(strKey) + If (obj Is Nothing) Then + Return Nothing + Else + Return CType(obj, T) + End If + End If + + End Function + + Private Shared Sub SetInSession(Of T)(ByVal strKey As String, ByVal tValue As T) + + If HttpContext.Current.Session IsNot Nothing Then + If (tValue Is Nothing) Then + HttpContext.Current.Session.Remove(strKey) + Else + HttpContext.Current.Session(strKey) = tValue + End If + End If + + End Sub + +#End Region + +End Class \ No newline at end of file diff --git a/OpenAntragLib/Wrapper/SettingsWrapper.vb b/OpenAntragLib/Wrapper/SettingsWrapper.vb new file mode 100644 index 0000000..e502071 --- /dev/null +++ b/OpenAntragLib/Wrapper/SettingsWrapper.vb @@ -0,0 +1,172 @@ +Imports System.Web.Configuration.WebConfigurationManager + +Public Class SettingsWrapper + +#Region "Properties: AppSettings" + + Public Shared ReadOnly Property PushbulletApiUrl() As String + Get + Return GetFromSettings(Of String)("PushbulletApiUrl") + End Get + End Property + + Public Shared ReadOnly Property PushbulletAccessToken() As String + Get + Return GetFromSettings(Of String)("PushbulletAccessToken") + End Get + End Property + + Public Shared ReadOnly Property PushoverApiUrl() As String + Get + Return GetFromSettings(Of String)("PushoverApiUrl") + End Get + End Property + + Public Shared ReadOnly Property PushoverAppToken() As String + Get + Return GetFromSettings(Of String)("PushoverAppToken") + End Get + End Property + + Public Shared ReadOnly Property PushoverUserKey() As String + Get + Return GetFromSettings(Of String)("PushoverUserKey") + End Get + End Property + + Public Shared ReadOnly Property TwitterConsumerKey() As String + Get + Return GetFromSettings(Of String)("TwitterConsumerKey") + End Get + End Property + + Public Shared ReadOnly Property TwitterConsumerSecret() As String + Get + Return GetFromSettings(Of String)("TwitterConsumerSecret") + End Get + End Property + + Public Shared ReadOnly Property TwitterAccessToken() As String + Get + Return GetFromSettings(Of String)("TwitterAccessToken") + End Get + End Property + + Public Shared ReadOnly Property TwitterAccessTokenSecret() As String + Get + Return GetFromSettings(Of String)("TwitterAccessTokenSecret") + End Get + End Property + + Public Shared ReadOnly Property TwitterRequestUrl() As String + Get + Return GetFromSettings(Of String)("TwitterRequestUrl") + End Get + End Property + + Public Shared ReadOnly Property PiratlyApiKey() As String + Get + Return GetFromSettings(Of String)("PiratlyApiKey") + End Get + End Property + + Public Shared ReadOnly Property SendMail As Boolean + Get + Return GetFromSettings(Of Boolean)("SendMail") + End Get + End Property + + Public Shared ReadOnly Property InfoMailCC() As String + Get + Return GetFromSettings(Of String)("InfoMailCC") + End Get + End Property + + Public Shared ReadOnly Property MailSender() As String + Get + Return GetFromSettings(Of String)("MailSender") + End Get + End Property + + Public Shared ReadOnly Property SendTweets As Boolean + Get + Return GetFromSettings(Of Boolean)("SendTweets") + End Get + End Property + + Public Shared ReadOnly Property SendPushoverNotification As Boolean + Get + Return GetFromSettings(Of Boolean)("SendPushoverNotification") + End Get + End Property + + Public Shared ReadOnly Property DefaultPagerListPageSize() As Integer + Get + Return GetFromSettings(Of Integer)("DefaultPagerListPageSize") + End Get + End Property + + Public Shared ReadOnly Property DefaultPagerListWingLength() As Integer + Get + Return GetFromSettings(Of Integer)("DefaultPagerListWingLength") + End Get + End Property + + Public Shared ReadOnly Property RandomKey_AllowCapitalLetters() As Boolean + Get + Return GetFromSettings(Of Boolean)("RandomKey_AllowCapitalLetters") + End Get + End Property + + Public Shared ReadOnly Property RandomKey_Letters() As String + Get + Return GetFromSettings(Of String)("RandomKey_Letters") + End Get + End Property + + Public Shared ReadOnly Property RandomKey_Numbers() As String + Get + Return GetFromSettings(Of String)("RandomKey_Numbers") + End Get + End Property + + Public Shared ReadOnly Property NotificationPageCount() As Integer + Get + Return GetFromSettings(Of Integer)("NotificationPageCount") + End Get + End Property + + Public Shared ReadOnly Property ProposalListCount() As Integer + Get + Return GetFromSettings(Of Integer)("ProposalListCount") + End Get + End Property + +#End Region + +#Region "Properties: Global" + + Public Shared ReadOnly Property GetSetting(ByVal strKey As String) As String + Get + Return GetFromSettings(Of String)(strKey) + End Get + End Property + +#End Region + +#Region "Methoden" + + Private Shared Function GetFromSettings(Of T)(ByVal strKey As String) As T + + Dim obj As Object = AppSettings(strKey) + If (obj Is Nothing) Then + Return Nothing + Else + Return CType(obj, T) + End If + + End Function + +#End Region + +End Class diff --git a/OpenAntragLib/XmlHelper.vb b/OpenAntragLib/XmlHelper.vb new file mode 100644 index 0000000..bbf4627 --- /dev/null +++ b/OpenAntragLib/XmlHelper.vb @@ -0,0 +1,330 @@ +Imports System.IO +Imports System.Web + +Public Class XmlData + + Public Property Type As XmlDataType + Public Property TypeName As String + Public Property FileName() As String + Public Property RootElementName() As String + Public Property ElementName() As String + + Public ReadOnly Property RelativePath() As String + Get + Return "~/App_Data/" & Me.FileName + End Get + End Property + + Public ReadOnly Property MappedPath() As String + Get + Return HttpContext.Current.Server.MapPath(Me.RelativePath) + End Get + End Property + +End Class + +Public Enum XmlDataType 'Namen referenzieren auf den Single-Objekttyp + Representations = 0 + FeedbackType = 1 + FeedbackStatus = 2 + GovernmentalLevels = 3 + FederalStates = 4 + GroupType = 5 + Teaser = 6 + ProcessStepDefinition = 7 +End Enum + +Public Class XmlHelper + + Private _XmlInfo As New List(Of XmlData) + + Public Sub New() + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.Representations, + .TypeName = "Representation", + .FileName = "Representations.xml", + .RootElementName = "representations", + .ElementName = "item"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.FeedbackType, + .TypeName = "FeedbackType", + .FileName = "FeedbackTypes.xml", + .RootElementName = "types", + .ElementName = "type"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.FeedbackStatus, + .TypeName = "FeedbackStatusCode", + .FileName = "FeedbackStatusCodes.xml", + .RootElementName = "statuscodes", + .ElementName = "statuscode"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.GroupType, + .TypeName = "GroupType", + .FileName = "GroupTypes.xml", + .RootElementName = "types", + .ElementName = "type"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.GovernmentalLevels, + .TypeName = "GovernmentalLevel", + .FileName = "GovernmentalLevels.xml", + .RootElementName = "levels", + .ElementName = "level"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.FederalStates, + .TypeName = "FederalState", + .FileName = "FederalStates.xml", + .RootElementName = "federalstates", + .ElementName = "federalstate"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.Teaser, + .TypeName = "Teaser", + .FileName = "Teaser.xml", + .RootElementName = "teaser", + .ElementName = "item"}) + + _XmlInfo.Add(New XmlData With { + .Type = XmlDataType.ProcessStepDefinition, + .TypeName = "ProcessStepDefinition", + .FileName = "ProcessStepDefinitions.xml", + .RootElementName = "steps", + .ElementName = "step"}) + + End Sub + + Public Function ConvertInstance(Of T As IXMLClass)(lst As List(Of T)) As XElement + + Dim typ As Type = GetType(T) + Dim strTypename As String = typ.Name + + Dim query = From xd As XmlData In _XmlInfo + Where xd.TypeName = strTypename + Select xd + + If query.Count > 0 Then + Dim xD As XmlData = query.First + Dim xE As New XElement(xd.RootElementName) + + For Each m As T In lst + Dim xNew As XElement = m.GetXElement(xd) + xE.Add(xNew) + Next + + Return xE + Else + Return Nothing + End If + + End Function + + Public Function GetInstance(Of T As IXMLClass)() As List(Of T) + + Dim typ As Type = GetType(T) + Dim strTypename As String = typ.Name + + Dim query = From xd As XmlData In _XmlInfo + Where xd.TypeName = strTypename + Select xd + + If query.Count > 0 Then + Dim xd As XmlData = query.First + Dim xE As XElement = GetXml(xd.Type) + + Dim lst As New List(Of T) + Dim querx = From ex In xE.Elements(xd.ElementName) + Select ex + + For Each ex In querx + Dim cT As T = Activator.CreateInstance(typ, {ex}) + lst.Add(cT) + Next + + Return lst + Else + Return Nothing + End If + + End Function + + Public Function GetXmlDataFromType(ByVal intType As XmlDataType) As XmlData + + Return (From xd As XmlData In _XmlInfo + Where xd.Type = intType + Select xd).First() + + End Function + + Public Function GetXml(ByVal intType As XmlDataType) As XElement + + Dim cXmlData As XmlData = GetXmlInfo(intType) + Return SetupXml(cXmlData) + + End Function + + Public Function GetXmlInfo(ByVal intType As XmlDataType) As XmlData + + Dim cXmlData As XmlData = Nothing + + Dim query = From xd As XmlData In _XmlInfo + Where xd.Type = intType + Select xd + + If query.Count > 0 Then + cXmlData = query.First + End If + + Return cXmlData + + End Function + + Public Function SetupXml(cXmlData As XmlData) As XElement + + Dim xE As XElement = XElement.Load(cXmlData.MappedPath) + + Dim strTemplateFile As String = HttpContext.Current.Server.MapPath("~/App_Data/XmlTemplates/" & cXmlData.FileName) + + If File.Exists(strTemplateFile) = True Then + + Dim xT As XElement = XElement.Load(strTemplateFile) + + Dim bolChanged As Boolean = False + DoMerge(bolChanged, xE, xT) 'rekursiver Aufruf + + If bolChanged = True Then + Call BackupXml(cXmlData.Type) + Call SaveXml(xE, cXmlData.Type) + End If + + End If + + Return xE + + End Function + + Public Function BackupXml(ByVal intType As XmlDataType) As Boolean + + Dim cXmlData As XmlData = GetXmlInfo(intType) + Dim strBackupFile As String = HttpContext.Current.Server.MapPath("~/App_Data/XmlBackup/") & cXmlData.FileName + + Try + Dim fi As New FileInfo(cXmlData.MappedPath) + If fi.Exists = True Then + fi.CopyTo(strBackupFile, True) + End If + Return True + Catch ex As Exception + Return False + End Try + + End Function + + Public Function SaveXml(ByVal xE As XElement, + ByVal intType As XmlDataType) As Boolean + + Dim cXmlData As XmlData = GetXmlInfo(intType) + + If xE.Name.LocalName.ToLower <> cXmlData.RootElementName.ToLower Then + Throw New Exception("Falsche XML-Struktur") + End If + + Try + xE.Save(cXmlData.MappedPath) + Return True + Catch ex As Exception + Throw New Exception("Fehler beim Speichern der XML-Struktur") + End Try + + End Function + + Public Function GetMaxID(ByVal intType As XmlDataType) As Integer + + Dim intMaxID As Integer = 0 + Dim xE As XElement = GetXml(intType) + Dim xD As XmlData = GetXmlDataFromType(intType) + + Try + intMaxID = Aggregate node In xE.Elements(xD.ElementName) + Into Max(CType(node.@id, Integer)) + Catch ex As Exception + End Try + + Return intMaxID + + End Function + +#Region "Helper Methods" + + Private Shared Sub DoMerge(ByRef bolChanged As Boolean, xE As XElement, xT As XElement) + + For Each node In xE.Elements + + 'Attribute + If XmlHelper.MergeTemplateAttributes(node, xT.Elements(node.Name).First) = True Then bolChanged = True + 'Elemente + If XmlHelper.MergeTemplateElements(node, xT.Elements(node.Name).First) = True Then bolChanged = True + + If node.HasElements = True Then + DoMerge(bolChanged, node, xT.Elements(node.Name).First) + End If + + Next + + End Sub + + Private Shared Function MergeTemplateAttributes(ByVal xE As XElement, ByVal xTemplate As XElement) As Boolean + + Dim bolChanged As Boolean = False + + Dim CurrentAttributeNames = From attr In xE.Attributes Select attr.Name + For Each xAttr In xTemplate.Attributes + If Not CurrentAttributeNames.Contains(xAttr.Name) Then + xE.Add(xAttr) + bolChanged = True + End If + Next + + Dim TemplateAttributeNames = From attr In xTemplate.Attributes Select attr.Name + For Each xAttr In xE.Attributes + If Not TemplateAttributeNames.Contains(xAttr.Name) Then + xAttr.Remove() + bolChanged = True + End If + Next + + Return bolChanged + + End Function + + Private Shared Function MergeTemplateElements(ByVal xE As XElement, ByVal xTemplate As XElement) As Boolean + + Dim bolChanged As Boolean = False + + Dim CurrentElementNames = From elm In xE.Elements Select elm.Name + For Each xElm In xTemplate.Elements + If Not CurrentElementNames.Contains(xElm.Name) Then + xE.Add(xElm) + bolChanged = True + End If + Next + + Dim TemplateElementNames = From elm In xTemplate.Elements Select elm.Name + For Each xElm In xE.Elements + If Not TemplateElementNames.Contains(xElm.Name) Then + xElm.Remove() + bolChanged = True + End If + Next + + Return bolChanged + + End Function + +#End Region + +End Class diff --git a/OpenAntragLib/app.config b/OpenAntragLib/app.config new file mode 100644 index 0000000..78e5c1f --- /dev/null +++ b/OpenAntragLib/app.config @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAntragLib/packages.config b/OpenAntragLib/packages.config new file mode 100644 index 0000000..0c57e2a --- /dev/null +++ b/OpenAntragLib/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file