aboutsummaryrefslogtreecommitdiff
path: root/External
diff options
context:
space:
mode:
authorYuchen Pei <hi@ypei.me>2021-10-14 15:16:42 +1100
committerYuchen Pei <hi@ypei.me>2021-10-14 15:16:42 +1100
commit07f5140771388c9e0c8a99b0dd2e5d950bdb173b (patch)
tree323c00faef1edc7dea2e88ff581cc2258b2b6432 /External
parente119be145500700f3c465e12664403a07530a421 (diff)
moving h-source subdir out.
Diffstat (limited to 'External')
-rwxr-xr-xExternal/Fonts/FreeFont/AUTHORS208
-rwxr-xr-xExternal/Fonts/FreeFont/COPYING674
-rwxr-xr-xExternal/Fonts/FreeFont/CREDITS528
-rwxr-xr-xExternal/Fonts/FreeFont/ChangeLog4525
-rwxr-xr-xExternal/Fonts/FreeFont/FreeMono.ttfbin0 -> 314348 bytes
-rwxr-xr-xExternal/Fonts/FreeFont/INSTALL86
-rwxr-xr-xExternal/Fonts/FreeFont/README108
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift.php57
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Attachment.php75
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php178
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php190
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php177
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReader.php60
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php96
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php83
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php183
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php29
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php119
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterStream.php86
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php319
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php300
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/DependencyContainer.php349
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/DependencyException.php30
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/EmbeddedFile.php73
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Encoder.php32
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php63
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php263
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php89
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Encoding.php70
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/CommandEvent.php67
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/CommandListener.php29
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/Event.php39
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php81
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/EventListener.php19
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/EventObject.php65
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php65
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/ResponseListener.php29
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/SendEvent.php127
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/SendListener.php35
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php175
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php31
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php53
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php50
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php30
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/FailoverTransport.php48
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/FileStream.php28
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Filterable.php34
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Image.php62
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/InputByteStream.php72
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/IoException.php30
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache.php99
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php209
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php316
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php53
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php110
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php131
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php48
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/MailTransport.php48
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mailer.php173
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php59
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php34
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Message.php82
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Attachment.php143
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php26
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php41
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php81
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php175
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php117
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php51
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php28
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Header.php85
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php28
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php99
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php72
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php170
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php596
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php118
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php161
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php316
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php274
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php126
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php108
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/Message.php230
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php108
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/MimePart.php196
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php35
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php187
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php396
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php609
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php803
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/MimePart.php65
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/OutputByteStream.php41
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php147
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php173
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php201
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Logger.php37
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php160
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php73
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php64
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php34
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php288
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Reporter.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php82
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php63
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php47
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php26
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php188
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Plugins/Timer.php26
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Preferences.php76
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php27
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/RfcComplianceException.php30
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/SendmailTransport.php48
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/SmtpTransport.php56
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/StreamFilter.php33
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php188
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php66
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php53
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/SwiftException.php28
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport.php60
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php543
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php88
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php58
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php57
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php262
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php38
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php82
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php340
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php97
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php65
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php188
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/MailTransport.php242
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php173
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php58
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php36
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php276
-rwxr-xr-xExternal/swiftmailer/lib/classes/Swift/TransportException.php31
-rwxr-xr-xExternal/swiftmailer/lib/dependency_maps/cache_deps.php25
-rwxr-xr-xExternal/swiftmailer/lib/dependency_maps/mime_deps.php97
-rwxr-xr-xExternal/swiftmailer/lib/dependency_maps/transport_deps.php62
-rwxr-xr-xExternal/swiftmailer/lib/mime_types.php76
-rwxr-xr-xExternal/swiftmailer/lib/preferences.php20
-rwxr-xr-xExternal/swiftmailer/lib/swift_init.php21
-rwxr-xr-xExternal/swiftmailer/lib/swift_required.php22
-rwxr-xr-xExternal/swiftmailer/lib/swift_required_pear.php22
148 files changed, 22499 insertions, 0 deletions
diff --git a/External/Fonts/FreeFont/AUTHORS b/External/Fonts/FreeFont/AUTHORS
new file mode 100755
index 0000000..4148c93
--- /dev/null
+++ b/External/Fonts/FreeFont/AUTHORS
@@ -0,0 +1,208 @@
+-*- mode:text; coding:utf-8; -*-
+ GNU FreeFont Authors
+ ====================
+
+The FreeFont collection is being maintained by
+ Steve White <stevan.white AT googlemail.com>
+The folowing list cites the other contributors that contributed to
+particular ISO 10646 blocks.
+
+* URW++ Design & Development GmbH <http://www.urwpp.de/>
+
+ Basic Latin (U+0041-U+007A)
+ Latin-1 Supplement (U+00C0-U+00FF) (most)
+ Latin Extended-A (U+0100-U+017F)
+ Spacing Modifier Letters (U+02B0-U+02FF)
+ Mathematical Operators (U+2200-U+22FF) (parts)
+ Block Elements (U+2580-U+259F)
+ Dingbats (U+2700-U+27BF)
+
+* Yannis Haralambous <yannis.haralambous AT enst-bretagne.fr> and John
+ Plaice <plaice AT omega.cse.unsw.edu.au>
+
+ Latin Extended-B (U+0180-U+024F)
+ IPA Extensions (U+0250-U+02AF)
+ Greek (U+0370-U+03FF)
+ Armenian (U+0530-U+058F)
+ Hebrew (U+0590-U+05FF)
+ Arabic (U+0600-U+06FF)
+ Currency Symbols (U+20A0-U+20CF)
+ Arabic Presentation Forms-A (U+FB50-U+FDFF)
+ Arabic Presentation Forms-B (U+FE70-U+FEFF)
+
+* Young U. Ryu <ryoung AT utdallas.edu>
+
+ Arrows (U+2190-U+21FF)
+ Mathematical Symbols (U+2200-U+22FF)
+ Mathematical Alphanumeric Symbols (U+1D400-U+1D7FF)
+
+* Valek Filippov <frob AT df.ru>
+
+ Cyrillic (U+0400-U+04FF)
+
+* Wadalab Kanji Comittee
+
+ Hiragana (U+3040-U+309F)
+ Katakana (U+30A0-U+30FF)
+
+* Angelo Haritsis <ah AT computer.org>
+
+ Greek (U+0370-U+03FF)
+
+* Yannis Haralambous and Virach Sornlertlamvanich
+
+ Thai (U+0E00-U+0E7F)
+
+* Shaheed R. Haque <srhaque AT iee.org>
+
+ Bengali (U+0980-U+09FF)
+
+* Sam Stepanyan <sam AT arminco.com>
+
+ Armenian (U+0530-U+058F)
+
+* Mohamed Ishan <ishan AT mitf.f2s.com>
+
+ Thaana (U+0780-U+07BF)
+
+* Sushant Kumar Dash <sushant AT writeme.com>
+
+ Oriya (U+0B00-U+0B7F)
+
+* Harsh Kumar <harshkumar AT vsnl.com>
+
+ Devanagari (U+0900-U+097F)
+ Bengali (U+0980-U+09FF)
+ Gurmukhi (U+0A00-U+0A7F)
+ Gujarati (U+0A80-U+0AFF)
+
+* Prasad A. Chodavarapu <chprasad AT hotmail.com>
+
+ Telugu (U+0C00-U+0C7F)
+
+* Frans Velthuis <velthuis AT rc.rug.nl> and Anshuman Pandey
+ <apandey AT u.washington.edu>
+
+ Devanagari (U+0900-U+097F)
+
+* Hardip Singh Pannu <HSPannu AT aol.com>
+
+ Gurmukhi (U+0A00-U+0A7F)
+
+* Jeroen Hellingman <jehe AT kabelfoon.nl>
+
+ Oriya (U+0B00-U+0B7F)
+ Malayalam (U+0D00-U+0D7F)
+
+* Thomas Ridgeway <email needed>
+
+ Tamil (U+0B80-U+0BFF)
+
+* Berhanu Beyene <1beyene AT informatik.uni-hamburg.de>,
+ Prof. Dr. Manfred Kudlek <kudlek AT informatik.uni-hamburg.de>, Olaf
+ Kummer <kummer AT informatik.uni-hamburg.de>, and Jochen Metzinger <?>
+
+ Ethiopic (U+1200-U+137F)
+
+* Maxim Iorsh <iorsh AT users.sourceforge.net>
+
+ Hebrew (U+0590-U+05FF)
+
+* Vyacheslav Dikonov <sdiconov AT mail.ru>
+
+ Syriac (U+0700-U+074A)
+ Braille (U+2800-U+28FF)
+
+* Panayotis Katsaloulis <panayotis AT panayotis.com>
+
+ Greek Extended (U+1F00-U+1FFF)
+
+* M.S. Sridhar <mssridhar AT vsnl.com>
+
+ Devanagari (U+0900-U+097F)
+ Bengali (U+0980-U+09FF)
+ Gurmukhi (U+0A00-U+0A7F)
+ Gujarati (U+0A80-U+0AFF)
+ Oriya (U+0B00-U+0B7F)
+ Tamil (U+0B80-U+0BFF)
+ Telugu (U+0C00-U+0C7F)
+ Kannada (U+0C80-U+0CFF)
+ Malayalam (U+0D00-U+0D7F)
+
+* DMS Electronics, The Sri Lanka Tipitaka Project, and Noah Levitt
+ <nlevitt AT columbia.edu>
+
+ Sinhala (U+0D80-U+0DFF)
+
+* Dan Shurovich Chirkov <dansh AT chirkov.com>
+
+ Cyrillic (U+0400-U+04FF)
+
+* Abbas Izad <abbasizad AT hotmail.com>
+
+ Arabic (U+0600-U+06FF)
+ Arabic Presentation Forms-A (U+FB50-U+FDFF)
+ Arabic Presentation Forms-B (U+FE70-U+FEFF)
+
+* Denis Jacquerye <moyogo AT gmail.com>
+
+ Latin Extended-B (U+0180-U+024F)
+ IPA Extensions (U+0250-U+02AF)
+
+* K.H. Hussain <hussain AT kfri.org> and R. Chitrajan
+
+ Malayalam (U+0D00-U+0D7F)
+
+* Solaiman Karim <solaiman AT ekushey.org> and Omi Azad <omi AT ekushey.org>
+
+ Bengali (U+0980-U+09FF)
+
+* Sonali Sonania <sonalisonania AT gmail.com> and Monika Shah
+ <monikapatira AT gmail.com>
+
+ Devanagari (U+0900-U+097F)
+ Gujarati (U+0A80-U+0AFF)
+
+* Pravin Satpute <pravin_ind21 AT hotmail.com>, Bageshri Salvi
+ <sbagrshri AT yahoo.co.in>, Rahul Bhalerao <rahul_pb_india AT
+ yahoo.com> and Sandeep Shedmake <surgs2k47 AT yahoo.co.in>
+
+ Devanagari (U+0900-U+097F)
+ Gujarati (U+0A80-U+0AFF)
+ Oriya (U+0B00-U+0B7F)
+ Malayalam (U+0D00-U+0D7F)
+ Tamil (U+0B80-U+0BFF)
+
+* Kulbir Singh Thind
+
+ Gurmukhi (U+0A00-U+0A7F)
+
+* Gia Shervashidze <giasher AT telenet.ge>
+
+ Georgian (U+10A0-U+10FF)
+
+* Daniel Johnson
+
+ Cherokee (U+13A0-U+13FF)
+
+* George Douros
+
+ Gothic (U+10330-U+1034F)
+ Phoenecian (U+10900-U+1091F)
+ Byzantine Musical Symbols (U+1D000-U+1D0FF)
+ Western Musical Symbols (U+1D100-U+1D1DF)
+ Mathematical Alphanumeric Symbols (U+1D400-U+1D7FF)
+ Mah Jong Tiles (U+1F000-U+1F02B)
+ Dominoes (U+1F030-U+1F093)
+
+* Steve White <stevan_white AT gmail.com>
+ Coptic (U+2C80-U+2CFF)
+
+* Primož Peterlin <primoz.peterlin AT biofiz.mf.uni-lj.si>
+ maintained FreeFont for several years, and is thanked for all his work.
+
+Please see the CREDITS file for details on who contributed particular
+subsets of the glyphs in font files.
+
+--------------------------------------------------------------------------
+$Id: AUTHORS,v 1.18 2009/01/04 15:57:54 Stevan_White Exp $
diff --git a/External/Fonts/FreeFont/COPYING b/External/Fonts/FreeFont/COPYING
new file mode 100755
index 0000000..94a9ed0
--- /dev/null
+++ b/External/Fonts/FreeFont/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/External/Fonts/FreeFont/CREDITS b/External/Fonts/FreeFont/CREDITS
new file mode 100755
index 0000000..0f47440
--- /dev/null
+++ b/External/Fonts/FreeFont/CREDITS
@@ -0,0 +1,528 @@
+-*- mode:text; coding:utf-8; -*-
+ GNU FreeFont Credits
+ ====================
+
+This file lists contributors and contributions to the GNU FreeFont project.
+
+
+* URW++ Design & Development GmbH <http://www.urwpp.de/>
+
+URW++ donated a set of 35 core PostScript Type 1 fonts to the
+Ghostscript project <http://www.cs.wisc.edu/~ghost/>, to be available
+under the terms of GNU General Public License (GPL).
+
+ Basic Latin (U+0041-U+007A)
+ Latin-1 Supplement (U+00C0-U+00FF)
+ Latin Extended-A (U+0100-U+017F)
+ Spacing Modifier Letters (U+02B0-U+02FF)
+ Mathematical Operators (U+2200-U+22FF)
+ Block Elements (U+2580-U+259F)
+ Dingbats (U+2700-U+27BF)
+
+
+* Yannis Haralambous <yannis.haralambous AT enst-bretagne.fr> and John
+ Plaice <plaice AT omega.cse.unsw.edu.au>
+
+Yannis Haralambous and John Plaice are the authors of Omega typesetting
+system, <http://omega.enstb.org/>. Omega is an extension of TeX.
+Its first release, aims primarily at improving TeX's multilingual abilities.
+In Omega all characters and pointers into data-structures are 16-bit wide,
+instead of 8-bit, thereby eliminating many of the trivial limitations of TeX.
+Omega also allows multiple input and output character sets, and uses
+programmable filters to translate from one encoding to another, to perform
+contextual analysis, etc. Internally, Omega uses the universal 16-bit Unicode
+standard character set, based on ISO-10646. These improvements not only make
+it a lot easier for TeX users to cope with multiple or complex languages,
+like Arabic, Indic, Khmer, Chinese, Japanese or Korean, in one document, but
+will also form the basis for future developments in other areas, such as
+native color support and hypertext features. ... Fonts for UT1 (omlgc family)
+and UT2 (omah family) are under development: these fonts are in PostScript
+format and visually close to Times and Helvetica font families.
+Omega fonts are available subject to GPL
+
+ Latin Extended-B (U+0180-U+024F)
+ IPA Extensions (U+0250-U+02AF)
+ Greek (U+0370-U+03FF)
+ Armenian (U+0530-U+058F)
+ Hebrew (U+0590-U+05FF)
+ Arabic (U+0600-U+06FF)
+ Currency Symbols (U+20A0-U+20CF)
+ Arabic Presentation Forms-A (U+FB50-U+FDFF)
+ Arabic Presentation Forms-B (U+FE70-U+FEFF)
+
+Current info: <http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=omega>
+
+* Valek Filippov <frob AT df.ru>
+
+Valek Filippov added Cyrillic glyphs and composite Latin Extended A to
+the whole set of the abovementioned URW set of 35 PostScript core fonts,
+<ftp://ftp.gnome.ru/fonts/urw/>. The fonts are available under GPL.
+
+ Latin Extended-A (U+0100-U+017F)
+ Cyrillic (U+0400-U+04FF)
+
+
+* Wadalab Kanji Comittee
+
+Between April 1990 and March 1992, Wadalab Kanji Comittee put together
+a series of scalable font files with Japanese scripts, in four forms:
+Sai Micho, Chu Mincho, Cho Kaku and Saimaru. The font files are
+written in custom file format, while tools for conversion into
+Metafont and PostScript Type 1 are also supplied. The Wadalab Kanji
+Comittee has later been dismissed, and the resulting files can be now
+found on the FTP server of the Depertment of Mathematical Engineering
+and Information Physics, Faculty of Engineering, University of Tokyo
+<ftp://ftp.ipl.t.u-tokyo.ac.jp/Font/>.
+
+ Hiragana (U+3040-U+309F)
+ Katakana (U+30A0-U+30FF)
+
+
+* Young U. Ryu <ryoung AT utdallas.edu>
+
+Young Ryu is the author of Txfonts, a set of mathematical symbols
+designed to accompany text typeset in Times or its variants. In the
+documentation, Young adresses the design of mathematical symbols: "The
+Adobe Times fonts are thicker than the CM fonts. Designing math fonts
+for Times based on the rule thickness of Times = , , + , / , < ,
+etc. would result in too thick math symbols, in my opinion. In the TX
+fonts, these glyphs are thinner than those of original Times
+fonts. That is, the rule thickness of these glyphs is around 85% of
+that of the Times fonts, but still thicker than that of the CM fonts."
+TX fonts are are distributed under the GNU public license (GPL).
+<http://www.ctan.org/tex-archive/fonts/txfonts/>.
+
+ Arrows (U+2190-U+21FF)
+ Mathematical Symbols (U+2200-U+22FF)
+
+
+* Angelo Haritsis <ah AT computer.org>
+
+Angelo Haritsis has compiled a set of Greek Type 1 fonts, available on
+<ftp://ftp.hellug.gr/pub/unix/linux/GREEK/fonts/greekXfonts-Type1-1.1.tgz>.
+The glyphs from this source has been used to compose Greek glyphs in
+FreeSans and FreeMono.
+
+Angelo's licence says: "You can enjoy free use of these fonts for
+educational or commercial purposes. All derived works should include
+this paragraph. If you want to change something please let me have
+your changes (via email) so that they can go into the next
+version. You can also send comments etc to the above address."
+
+ Greek (U+0370-U+03FF)
+
+
+* Yannis Haralambous and Virach Sornlertlamvanich
+
+In 1999, Yannis Haralambous and Virach Sornlertlamvanich made a set of
+glyphs covering the Thai national standard Nf3, in both upright and
+slanted shape. The collection of glyphs have been made part of GNU
+intlfonts 1.2 package and is available under the GPL at
+<ftp://ftp.gnu.org/pub/gnu/intlfonts/>.
+
+ Thai (U+0E00-U+0E7F)
+
+
+* Shaheed R. Haque <srhaque AT iee.org>
+
+Shaheed Haque has developed a basic set of basic Bengali glyphs
+(without ligatures), using ISO10646 encoding. They are available under
+the XFree86 license at <http://www.btinternet.com/~shaheedhaque/>.
+
+Copyright (C) 2001 S.R.Haque <srhaque AT iee.org>. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL S.R.HAQUE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of S.R.Haque shall not be
+used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from
+S.R.Haque.
+
+ Bengali (U+0980-U+09FF)
+
+
+* Sam Stepanyan <sam AT arminco.com>
+
+Sam Stepanyan created a set of Armenian sans serif glyphs visually
+compatible with Helvetica or Arial. Available on
+<http://www.editum.com.ar/mashtots/html/fonts/ara.tar.gz>. On
+2002-01-24, Sam writes: "Arial Armenian font is free for
+non-commercial use, so it is OK to use under GPL license."
+
+ Armenian (U+0530-U+058F)
+
+
+* Mohamed Ishan <ishan AT mitf.f2s.com>
+
+Mohamed Ishan has started a Thaana Unicode Project
+<http://thaana.sourceforge.net/> and among other things created a
+couple of Thaana fonts, available under FDL or BDF license.
+
+ Thaana (U+0780-U+07BF)
+
+
+* Sushant Kumar Dash <sushant AT writeme.com> (*)
+
+Sushant Dash has created a font in his mother tongue, Oriya. As he
+states on his web page <http://members.tripod.com/~sushantdash/>:
+"Please feel free to foreword this mail to your Oriya friends. No
+copyright law is applied for this font. It is totally free!!! Feel
+free to modify this using any font editing tools. This is designed for
+people like me, who are away from Orissa and want to write letters
+home using Computers, but suffer due to unavailability of Oriya
+fonts.(Or the cost of the available packages are too much)."
+
+ Oriya (U+0B00-U+0B7F)
+
+
+* Harsh Kumar <harshkumar AT vsnl.com>
+
+Harsh Kumar has started BharatBhasha <http://www.bharatbhasha.net/> -
+an effort to provide "FREE software, Tutorial, Source Codes
+etc. available for working in Hindi, Marathi, Gujarati, Gurmukhi and
+Bangla. You can type text, write Web pages or develop Indian Languages
+Applications on Windows and on Linux. We also offer FREE help to
+users, enthusiasts and software developers for their work in Indian
+languages."
+
+ Devanagari (U+0900-U+097F)
+ Bengali (U+0980-U+09FF)
+ Gurmukhi (U+0A00-U+0A7F)
+ Gujarati (U+0A80-U+0AFF)
+
+
+* Prasad A. Chodavarapu <chprasad AT hotmail.com>
+
+Prasad A. Chodavarapu created Tikkana, a Telugu font available in Type
+1 and TrueType format on <http://chaitanya.bhaavana.net/fonts/>.
+Tikkana exceeds the Unicode Telugu range with some composite glyphs.
+Available under the GNU General Public License.
+
+ Telugu (U+0C00-U+0C7F)
+
+
+* Frans Velthuis <velthuis AT rc.rug.nl> and Anshuman Pandey
+ <apandey AT u.washington.edu>
+
+In 1991, Frans Velthuis from the Groningen University, The
+Netherlands, released a Devanagari font as Metafont source, available
+under the terms of GNU GPL. Later, Anshuman Pandey from the Washington
+University, Seattle, USA, took over the maintenance of font. Fonts can
+be found on CTAN, <ftp://ftp.dante.de/tex-archive/language/devanagari/>. I
+converted the font to Type 1 format using Péter Szabó's TeXtrace
+program <http://www.inf.bme.hu/~pts/textrace/> and removed some
+redundant control points with PfaEdit.
+
+ Devanagari (U+0900-U+097F)
+
+
+* Hardip Singh Pannu <HSPannu AT aol.com>
+
+In 1991, Hardip Singh Pannu has created a free Gurmukhi TrueType font,
+available as regular, bold, oblique and bold oblique form. Its license
+says "Please remember that these fonts are copyrighted (by me) and are
+for non-profit use only."
+
+ Gurmukhi (U+0A00-U+0A7F)
+
+
+* Jeroen Hellingman <jehe AT kabelfoon.nl>
+
+Jeroen Hellingman created a set of Malayalam metafonts in 1994, and a
+set of Oriya metafonts in 1996. Malayalam fonts were created as
+uniform stroke only, while Oriya metafonts exist in both uniform and
+modulated stroke. From private communication: "It is my intention to
+release the fonts under GPL, but not all copies around have this
+notice on them." Metafonts can be found on CTAN,
+<ftp://ftp.dante.de/tex-archive/language/oriya/> and
+<ftp://ftp.dante.de/tex-archive/language/malayalam/>.
+
+ Oriya (U+0B00-U+0B7F)
+ Malayalam (U+0D00-U+0D7F)
+
+
+* Thomas Ridgeway <> (*)
+
+Thomas Ridgeway, then at the Humanities And Arts Computing Center,
+Washington University, Seattle, USA, (now defunct), created a Tamil
+metafont in 1990. Anshuman Pandey from the same university took over
+the maintenance of font. Fonts can be found at CTAN,
+<ftp://ftp.dante.de/tex-archive/language/tamil/wntamil/>.
+
+ Tamil (U+0B80-U+0BFF)
+
+
+* Berhanu Beyene <1beyene AT informatik.uni-hamburg.de>,
+ Prof. Dr. Manfred Kudlek <kudlek AT informatik.uni-hamburg.de>, Olaf
+ Kummer <kummer AT informatik.uni-hamburg.de>, and Jochen Metzinger <?>
+
+Beyene, Kudlek, Kummer and Metzinger from the Theoretical Foundations
+of Computer Science, University of Hamburg, prepared a set of Ethiopic
+metafonts, found on
+<ftp://ftp.dante.de/tex-archive/language/ethiopia/ethiop/>. They also
+maintain home page on the Ethiopic font project,
+<http://www.informatik.uni-hamburg.de/TGI/mitarbeiter/wimis/kummer/ethiop_eng.html>,
+and can be reached at <ethiop AT informatik.uni-hamburg.de>. The current
+version of fonts is 0.7 (1998), and they are released under GNU GPL. I
+converted the fonts to Type 1 format using Péter Szabó's TeXtrace-A
+program <http://www.inf.bme.hu/~pts/textrace/> and removed some
+redundant control points with PfaEdit.
+
+ Ethiopic (U+1200-U+137F)
+
+
+* Maxim Iorsh <iorsh AT users.sourceforge.net>
+
+In 2002, Maxim Iorsh started the Culmus project, aiming at providing
+Hebrew-speaking Linux and Unix community with a basic collection of
+Hebrew fonts for X Windows. The fonts are visually compatible with
+URW++ Century Schoolbook L, URW++ Nimbus Sans L and URW++ Nimbus Mono
+L families, respectively, and are released under GNU GPL license. See
+also <http://culmus.sourceforge.net/>.
+
+ Hebrew (U+0590-U+05FF)
+
+
+* Panayotis Katsaloulis <panayotis AT panayotis.com>
+
+Panayotis Katsaloulis helped fixing Greek accents in the Greek
+Extended area.
+
+ Greek Extended (U+1F00-U+1FFF)
+
+
+* Vyacheslav Dikonov <sdiconov AT mail.ru>
+
+Vyacheslav Dikonov made a Braille unicode font that could be merged
+with the UCS fonts to fill the 2800-28FF range completely. (uniform
+scaling is possible to adapt it to any cell size). He also contributed
+a free syriac font, whose glyphs (about half of them) are borrowed
+from the "Carlo Ator" font freely downloadable from
+<http://www.aacf.asso.fr/>. Vyacheslav also filled in a few missing
+spots in the U+2000-U+27FF area, e.g. the box drawing section, sets of
+subscript and superscript digits and capital Roman numbers.
+
+ Syriac (U+0700-U+074A)
+ Box Drawing (U+2500-U+257F)
+ Braille (U+2800-U+28FF)
+
+
+* M.S. Sridhar <mssridhar AT vsnl.com>
+
+M/S Cyberscape Multimedia Limited, Mumbai, developers of Akruti
+Software for Indian Languages (http://www.akruti.com/), have released
+a set of TTF fonts for nine Indian scripts (Devanagari, Gujarati,
+Telugu, Tamil, Malayalam, Kannada, Bengali, Oriya, and Gurumukhi)
+under the GNU General Public License (GPL). You can download the fonts
+from the Free Software Foundation of India WWW site
+(http://www.gnu.org.in/akruti-fonts/) or from the Akruti website.
+
+For any further information or assistance regarding these fonts,
+please contact mssridhar AT vsnl.com.
+
+ Devanagari (U+0900-U+097F)
+ Bengali (U+0980-U+09FF)
+ Gurmukhi (U+0A00-U+0A7F)
+ Gujarati (U+0A80-U+0AFF)
+ Oriya (U+0B00-U+0B7F)
+ Tamil (U+0B80-U+0BFF)
+ Telugu (U+0C00-U+0C7F)
+ Kannada (U+0C80-U+0CFF)
+ Malayalam (U+0D00-U+0D7F)
+
+
+* DMS Electronics, The Sri Lanka Tipitaka Project, and Noah Levitt
+ <nlevitt AT columbia.edu>
+
+Noah Levitt found out that the Sinhalese fonts available on the site
+<http://www.metta.lk/fonts/> are released under GNU GPL, or,
+precisely, "Public Domain under GNU Licence Produced by DMS
+Electronics for The Sri Lanka Tipitaka Project" (taken from the font
+comment), and took the effort of recoding the font to Unicode.
+
+ Sinhala (U+0D80-U+0DFF)
+
+
+* Daniel Shurovich Chirkov <dansh AT chirkov.com>
+
+Dan Chirkov updated the FreeSerif font with the missing Cyrillic
+glyphs needed for conformance to Unicode 3.2. The effort is part of
+the Slavjanskij package for Mac OS X,
+<http://www.versiontracker.com/dyn/moreinfo/macosx/18680>.
+
+ Cyrillic (U+0400-U+04FF)
+
+
+* Denis Jacquerye <moyogo AT gmail.com>
+
+Denis Jacquerye added new glyphs and corrected existing ones in the
+Latin Extended-B and IPA Extensions ranges.
+
+ Latin Extended-B (U+0180-U+024F)
+ IPA Extensions (U+0250-U+02AF)
+
+
+* K.H. Hussain <hussain AT kfri.org> and R. Chitrajan
+
+`Rachana' in Malayalam means `to write', `to create'. Rachana Akshara Vedi,
+a team of socially committed information technology professionals and
+philologists, has applied developments in computer technology and desktop
+publishing to resurrect the Malayalam language from the disorder,
+fragmentation and degeneration it had suffered since the attempt to adapt
+the Malayalam script for using with a regular mechanical typewriter, which
+took place in 1967-69. K.H. Hussein at the Kerala Forest Research Institute
+has released "Rachana Normal" fonts with approximately 900 glyphs required
+to typeset traditional Malayalam. R. Chitrajan apparently encoded the
+glyphs in the OpenType table.
+
+In 2008, the Malayalam ranges in FreeSerif were updated under the advise
+and supervision of Hiran Venugopalan of Swathanthra Malayalam Computing,
+to reflect the revised edition Rachana_04.
+
+ Malayalam (U+0D00-U+0D7F)
+
+
+* Solaiman Karim <solaiman AT ekushey.org>
+
+ Bengali (U+0980-U+09FF)
+
+Solaiman Karim has developed several OpenType Bangla fonts and
+released them under GNU GPL on <http://www.ekushey.org>.
+
+
+* Sonali Sonania <sonalisonania AT gmail.com> and Monika Shah
+ <monikapatira AT gmail.com>
+
+ Devanagari (U+0900-U+097F)
+ Gujarati (U+0A80-U+0AFF)
+
+Glyphs were drawn by Cyberscape Multimedia Ltd., #101,Mahalakshmi
+Mansion 21st Main 22nd "A" Cross Banashankari 2nd stage Banglore
+560070, India. Converted to OTF by IndicTrans Team, Powai, Mumbai,
+lead by Prof. Jitendra Shah. Maintained by Monika Shah and Sonali
+Sonania of janabhaaratii Team, C-DAC, Mumbai. This font is released
+under GPL by Dr. Alka Irani and Prof Jitendra Shah, janabhaaratii
+Team, C-DAC, Mumabi. janabhaaratii is localisation project at C-DAC
+Mumbai (formerly National Centre for Software Technology); funded by
+TDIL, Govt. of India. Contact:monika_shah AT lycos.com,
+sonalisonania AT yahoo.com, jitendras AT vsnl.com, alka AT ncst.ernet.in.
+website: www.janabhaaratii.org.in.
+
+
+* Pravin Satpute <pravin_ind21 AT hotmail.com>, Bageshri Salvi
+ <sbagrshri AT yahoo.co.in>, Rahul Bhalerao <rahul_pb_india AT
+ yahoo.com> and Sandeep Shedmake <surgs2k47 AT yahoo.co.in>
+
+ Devanagari (U+0900-U+097F)
+ Gujarati (U+0A80-U+0AFF)
+ Oriya (U+0B00-U+0B7F)
+ Malayalam (U+0D00-U+0D7F)
+ Tamil (U+0B80-U+0BFF)
+
+In December 2005 the team at www.gnowledge.org released a set of two
+Unicode pan-Indic fonts: "Samyak" and "Samyak Sans". "Samyak" font
+belongs to serif style and is an original work of the team; "Samyak
+Sans" font belongs to sans serif style and is actually a compilation
+of already released Indic fonts (Gargi, Padma, Mukti, Utkal, Akruti
+and ThendralUni). Both fonts are based on Unicode standard. You can
+download the font files (released under GNU/GPL License) from
+http://www.gnowledge.org/Gnoware/localization/font.htm
+
+
+* Kulbir Singh Thind
+
+ Gurmukhi (U+0A00-U+0A7F)
+
+Dr. Kulbir Singh Thind designed a set of Gurmukhi Unicode fonts,
+AnmolUni and AnmolUni-Bold, which are available under the terms of GNU
+Generel Public Licens from the Punjabu Computing Resource Center,
+http://guca.sourceforge.net/typography/fonts/anmoluni/.
+
+
+* Gia Shervashidze <giasher AT telenet.ge>
+
+ Georgian (U+10A0-U+10FF)
+
+Starting in mid-1990s, Gia Shervashidze designed many
+Unicode-compliant Georgian fonts: Times New Roman Georgian, Arial
+Georgian, Courier New Georgian. His work on Georgian localization can
+be reached at http://www.gia.ge/.
+
+
+* Primož Peterlin <primoz.peterlin AT biofiz.mf.uni-lj.si>
+
+Primož Peterlin filled in missing glyphs here and there (e.g. Latin
+Extended-B and IPA Extensions ranges in the FreeMono familiy), and
+created the following UCS blocks:
+
+ Latin Extended-B (U+0180-U+024F)
+ IPA Extensions (U+0250-U+02AF)
+ Arrows (U+2190-U+21FF)
+ Box Drawing (U+2500-U+257F)
+ Block Elements (U+2580-U+259F)
+ Geometrical Shapes (U+25A0-U+25FF)
+
+* Mark Williamson
+
+Made the MPH 2 Damase font, from which
+ Hanunóo (U+1720-U+173F)
+ Buginese (U+1A00-U+1A1F)
+ Tai Le (U+1950-U+197F)
+ Ugaritic (U+10380-U+1039F)
+ Old Persian (U+103A0-U+103DF)
+
+* Jacob Poon
+
+Submitted a very thorough survey of glyph problems and other suggestions.
+
+* Alexey Kryukov
+
+Made the TemporaLCGUni fonts, based on the URW++ fonts, from which at one
+point FreeSerif Cyrillic, and some of the Greek, was drawn. He also provided
+valuable direction about Cyrillic and Greek typesetting.
+
+* George Douros
+
+The creator of several fonts focusing on ancient scripts and symbols.
+Many of the glyphs are created by making outlines from scanned images
+of ancient sources.
+
+ Aegean: Phoenecian
+ Analecta: Gothic (U+10330-U+1034F)
+ Musical: Byzantine & Western
+ Unicode: many Miscellaneous Symbols, Miscellaneous Technical,
+ supplemental Symbols, and Mathematical Alphanumeric symbols,
+ Mah Jong, and the outline of the Domino.
+
+* Daniel Johnson
+
+Created by hand a Cherokee range specially for FreeFont to be "in line with
+the classic Cherokee typefaces used in 19th century printing", but also to
+fit well with ranges previously in FreeFont.
+ Cherokee (U+13A0-U+13FF)
+
+Notes:
+
+*: The glyph collection looks license-compatible, but its author has
+ not yet replied and agreed on their work being used in part of
+ this glyph collection.
+
+--------------------------------------------------------------------------
+$Id: CREDITS,v 1.23 2009/01/04 15:57:54 Stevan_White Exp $
diff --git a/External/Fonts/FreeFont/ChangeLog b/External/Fonts/FreeFont/ChangeLog
new file mode 100755
index 0000000..d5345d0
--- /dev/null
+++ b/External/Fonts/FreeFont/ChangeLog
@@ -0,0 +1,4525 @@
+$Id: ChangeLog,v 1.254 2009/01/04 16:12:59 Stevan_White Exp $
+2009-01-04 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added 2009 to copyright dates
+
+ * AUTHORS, CREDITS:
+
+ Removed Glagolitic range author
+
+ * FreeSans.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added some TrueType names
+
+2009-01-01 Stevan_White
+ * FreeSerif.sfd:
+
+ Removde Glagolitic range, since have not (yet) received OK from author.
+
+ Added some TrueType Names
+
+2008-12-31 Stevan_White
+ * COPYING:
+
+ Updated license to GPL v3
+
+2008-12-30 Stevan_White
+ * FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Oblique versions of Daniel Johnson's Cherokee.
+
+ * FreeSerifBold.sfd:
+
+ Cherokee Bold range from Daniel Johnson.
+
+2008-12-27 Stevan_White
+ * isMonoMono.py:
+
+ 900 EM -> 800
+
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd:
+
+ Made glyphs to lie between -200 and 800 EM
+
+ * isMonoMono.py:
+
+ check that glyphs lie in vertical bounding boxes
+
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Extensible bracket characters didn't exactly line up. Fixed.
+ Mono: a couple of glyphs had gotten out of their bounding boxes again.
+
+2008-12-26 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Final pre-release cleanup
+
+ * FreeSerif.sfd:
+
+ Buginese vowel u was misnamed
+
+ * FreeMono.sfd:
+
+ Yatcyrillic somehow was a mark character ... fixed
+
+ * FreeSans.sfd, FreeSansOblique.sfd:
+
+ Had to un-link references in
+ Sans: uni02B2, uni02B5
+ SansOblique: uni0363
+ because validation of the TTF file said the glyph
+ "is drawn in wrong direction"
+ I would have preferred to have understand this...
+
+ * Makefile:
+
+ Added quick test for FontForge version.
+
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd:
+
+ Removed kerning tables (?? what were they doing here anyway??)
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Kerning tables for Thai.
+ Handles one common case: short letter followed by a tall one with
+ an overhang to the left.
+
+2008-12-25 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ More putzing with kerning tables
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Copied kerning classes
+ Serif -> SerifBold
+ SerifItalic -> SerifBoldItalic
+ Sans -> SansOblique SansBold SansBoldOblique
+ Some associated naming of characters, etc
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Additions and correction in Spacing Modifier letters and IPA Extensions
+
+2008-12-23 Stevan_White
+ * FreeSerif.sfd:
+
+ Applied patch to Cherokee range
+
+2008-12-20 Stevan_White
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Fixed kern classes that end in space (crashes FontForge)
+
+ * FreeSerifItalic.sfd, FreeSerif.sfd:
+
+ kerning
+
+2008-12-19 Stevan_White
+ * FreeSerifItalic.sfd:
+
+ kerning
+
+ * FreeSerif.sfd:
+
+ kerning
+ Some adjustments to Glagolitc spacing, mark positioning
+
+2008-12-18 Stevan_White
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ kerning
+
+2008-12-17 Stevan_White
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ kerning
+
+2008-12-11 Stevan_White
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ kerning
+
+2008-12-10 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd:
+
+ kerning
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd:
+
+ kerning
+
+2008-12-09 Stevan_White
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ kerning
+
+2008-12-08 Stevan_White
+ * FreeSansOblique.sfd:
+
+ Slanted small final sigma. Remedies
+ bug #24993: U+03C2 "Greek small letter final sigma" not slanted in
+ Free Sans Oblique
+ https://savannah.gnu.org/bugs/index.php?24993
+
+2008-12-07 Stevan_White
+ * FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ kerning, etc
+
+2008-12-06 Stevan_White
+ * FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ kerning
+ Tweek in Sans having to do with addition of Latin Extended
+
+2008-12-05 Stevan_White
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd:
+
+ Tweeks to Latin Extended Additional
+
+ * FreeSansBoldOblique.sfd:
+
+ Added Latin Extended Additional range
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Extra space at end of kern class names has bad effect on FornForge
+ script that try to run through kern classes. Some FontForge call
+ corrupts memory.
+ Got rid of extra space.
+
+2008-12-02 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Replaced U+0387 GREEK ANO TELEIA with top dot of colon.
+ See bug #24987: U+0387 GREEK ANO TELEIA too low
+ https://savannah.gnu.org/bugs/index.php?24987
+
+ * FreeSerif.sfd:
+
+ more kerning in Cyrillic (broke into two tables of classes)
+
+2008-12-01 Stevan_White
+ * FreeSerif.sfd:
+
+ tweeks to kernin
+
+ * FreeSerifBoldItalic.sfd:
+
+ kerning
+
+2008-11-30 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Kerning for Latin and Cyrillic fairly complete in Serif faces.
+ Complete in sense that it looks pretty good under Pango for
+ English French German Spanish Polish Czech Latvian
+ But have not done Vietnamese (will require many more entries).
+ I adjust roman and italic, then copy tables by hand to bold and
+ bolditalic.
+ Misgiving: bolditalic is much too crammed
+ Overall, I may have over-kerned. (A difficult temptation to master.)
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ kerning
+
+ * FreeSans.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ kerning
+ In Serif, modified widths of some extended latin glyphs
+
+2008-11-29 Stevan_White
+ * FreeSerif.sfd:
+
+ Broke Latin kerning subtable into four, hoping it will be easier to
+ understand and maintain.
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSerif.sfd,
+ FreeSerifItalic.sfd, FreeSerifBold.sfd, FreeSansOblique.sfd,
+ FreeSans.sfd:
+
+ kerninig
+
+2008-11-28 Stevan_White
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ more kerning;
+ made guillemot narrower
+
+ * FreeSansOblique.sfd, FreeSerif.sfd:
+
+ previous commit was incomplete
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Adjusted width of single quotes (and apostrophe) to be "punctuation width"
+ More fiddling with kerning.
+
+2008-11-27 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ much fiddling with kerning
+
+2008-11-26 Stevan_White
+ * FreeSerifBold.sfd:
+
+ Basic kerning, named main Cyrillic letters
+
+ * FreeSerifItalic.sfd:
+
+ Basic Cyrillic kerning
+
+ * FreeSerif.sfd:
+
+ Tweeks to Cyrillic kerning
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifItalic.sfd, Makefile:
+
+ Much fiddling with kerning, tables, and generating fonts whose kerning
+ tables work with OpenOffice.
+
+2008-11-24 Stevan_White
+ * FreeSerif.sfd:
+
+ regularized padding in Miscellaneous symbols.
+ At least within related ranges tried to make similar.
+ Made to validate
+
+2008-11-23 Stevan_White
+ * FreeSerif.sfd:
+
+ Filled out Miscellaneous Symbols. Used George Douros' Unicode font.
+ Completed Miscellaneous Symbols, with some drawings from George Douros'
+ Unicode Symbols, and some of mine.
+
+ * FreeMono.sfd, FreeMonoOblique.sfd:
+
+ Replaced Greek Exteded psili and dasia with scaled versions of the
+ "bent quote" mark. I think it's distinctive enough, but not so silly.
+
+ Remedies bug #22997: Mono: Greek Extended psili is ugly
+ https://savannah.gnu.org/bugs/?22997
+
+ * FreeSerif.sfd:
+
+ Made some recycling symbols
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Finished with Hebrew Pointed letters in all faces.
+
+2008-11-22 Stevan_White
+ * FreeSans.sfd:
+
+ Fiddled with Hebrew Pointed letters
+
+ * FreeSerifItalic.sfd:
+
+ Marks for Vietnamese
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Letter pe had strange thick middle ear that looked awful. lamed had ben
+ bumped at some point. Fixed. Adjusted some of the points.
+
+2008-11-21 Stevan_White
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ repairs to Pointed Hebrew
+
+ * FreeSerif.sfd:
+
+ Numeral line positioning marks for Gothic
+
+ * FreeSerifItalic.sfd:
+
+ Added Combining Marks for Symbols (some question about obliqueness of
+ some symbols)
+ Cleaned up some empty glyphs in Pointed Hebrew.
+
+2008-11-20 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Provided Hebrew pointed letters, with lookups, for all Serif faces.
+
+2008-11-19 Stevan_White
+ * FreeSerifBoldItalic.sfd:
+
+ renamed Hebrew lookups
+
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Completed Hebrew in Bold faces.
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ More tweeks to Hebrew points
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Adjustments corrections and additions to Hebrew points
+
+2008-11-18 Stevan_White
+ * FreeSansBold.sfd:
+
+ Cleaned out a lot of ridiculous kernings
+
+2008-11-17 Stevan_White
+ * FreeSansBoldOblique.sfd:
+
+ fiddled with Armenian ligatures
+
+ * FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Added Armenian (with ligatures) to BoldOblique
+ Fiddled with character spacing
+
+2008-11-16 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added U+01f9 and paragraph end marker to Georgian
+ Fiddled with Armenian ligatures
+
+2008-11-15 Stevan_White
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Another pass at letter spacing in Cyrillic.
+ Also went through ancient letters.
+
+ Added Georgian paragraph separator 10FB
+ Added Georgian turned gan 10F9 (because it was easy)
+
+ Re-worked letter spacing through modern Cyrillic range.
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSerif.sfd:
+
+ Letter spacing
+
+2008-11-14 Stevan_White
+ * FreeSerif.sfd:
+
+ Added several characters to Cyrillic Extended-B
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd:
+
+ Made Cyrillic hooked e U+04BC-F to look less goofy.
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Based on assertion on Pechatnyj Dvor's web site, Cyrillic Fita
+ U+0472-3 and "Barred O" U+04E8-9 are different styles the same letter,
+ and the fact that the tilde in the O never looked good in Sans, I
+ made them all barred O's.
+
+ * FreeSerif.sfd:
+
+ Added Cyrillic Yn, yn (U+a65e-f)
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Synced up Cyrillic and Combining Diacritics ranges,
+ Couple of tweeks in Gujarati to make TT validate
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Changes to older Cyrillic letters, in response to further information.
+ Made omegas, omegas with titlo, and OT to all be of the same size and
+ shape in Serif.
+ Un-linked Cyrillic Psi and psi from Greek, made squarer versions.
+
+ Some more Cyrillic diacritical marks in Sans. Re-worked U+04bc-f .
+ Experimenting with mark positioning for Cyrillic
+
+2008-11-12 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Strove to make Euro look more like the EC logo design, while making
+ glyph fit better with the design of its face. Bug #3576: Euro design
+ https://savannah.gnu.org/bugs/?23576
+
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Adjustments mostly to GPOS tables having to do with Vietnamese marks.
+ The WAZU Vietnamese test page looks pretty good in Sans now.
+ Still not thrilled with below-dot when it appears with a mark over
+ e.g. U+0102. Pango positions one or the other but not both.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Extensive modification of GPOS lookup tables for mark positioning.
+ I think they're now all functional (except styled Mono faces have none).
+ Also added lots of marks to faces that didn't have them, and also
+ fiddled with Combining Diacritical Marks.
+
+2008-11-10 Stevan_White
+ * FreeSerif.sfd:
+
+ Made one combining mark really combining
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made a few combining characters to be zero-width in Mono,
+ Added them to other styles.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Figured out why below marks in Thai weren't working in the lowest
+ letters. I think Pango and other font renderers ignore 'blwm'.
+ However, 'mark' works.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Tweeks to Thai marks
+
+2008-11-09 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Several bugfixes in Thai, mostly having to do with mark placement and
+ ligatures. Implemented ru-saraaa and lu-saraaa with ligatures.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ added and named dottedcircle (used by Pango to render
+ combining mark base)
+
+ * FreeSerif.sfd:
+
+ Tweeks to Coptic, after viewing more papyrus samples and web pages.
+
+ * FreeSerif.sfd:
+
+ Weight of Coptic small letters made to match that of Latin and Greek ones.
+
+2008-11-08 Stevan_White
+ * FreeSerif.sfd:
+
+ Made Coptic to comply better with
+ http://www.wazu.jp/gallery/Test_Coptic.html
+ Made a flourish at foot of letters with long diagonal.
+
+ More tweeks to Coptic; put in a mark lookup table.
+
+ Note: for small letters I made scaled references to captials.
+ Results in those letters looking quite light next to the capitals and
+ next to small Latin letters. Also, there are a few variant forms for
+ capitals (Unicode samples don't show this). It would be good to
+ re-work
+
+ Added Coptic alphabet in u+2C80-2CB1 and u+03E2-u+03EF, drawn/built by
+ me, based on Unicode samples, TeX font copte, and scans at WikiPedia.
+
+2008-11-07 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Further tweeks to dieresis in Greek and Cyrillic
+
+ * FreeSerif.sfd:
+
+ replaced Greek I dieresis with references, tweeked height of dieresis.
+
+2008-11-04 Stevan_White
+ * FreeSerif.sfd:
+
+ Added a few Cyrillic Extended-B letters seen in web pages while looking
+ for Glagolitic text.
+
+ * FreeMono.sfd, FreeMonoOblique.sfd:
+
+ Added a few old Cyrillic characters.
+
+ * FreeSerif.sfd:
+
+ Several corrections and tweeks to Glagolitic.
+ Still missing six slots from Unicode, but don't see them in the TeX
+ fonts.
+ On the other hand, several on-line Glagolitic pages (bibles etc) don't
+ seem to use these. Maybe it's OK as-is.
+
+2008-11-03 Stevan_White
+ * FreeSerif.sfd:
+
+ Added lowercase range to Glagolitic, as a facile scaling of the
+ uppercase.
+
+ Added letter to Glagolitic, scaled range.
+
+2008-11-02 Stevan_White
+ * FreeSerif.sfd:
+
+ Replaced fraktur bold from Mathematical Alphanumeric Symbols with that
+ from TX Fonts by Young Ryu.
+ One concern: letter k is damaged (in both medium and bold). I just
+ hacked something up.
+
+ Added Glagolitic "round type" font (Croation capitols only) from the
+ collection of Croatian fonts for LaTeX by Darko Zubrinić
+ ftp://ftp.dante.de/tex-archive/languages/croatian/
+ http://www.tug.org/TUGboat/Articles/tb17-1/tb50zubr.pdf
+
+ Several letters are missing besides the small letters.
+
+ * FreeSerifBoldItalic.sfd:
+
+ A couple of Thai references got obliqued twice.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ By popular demand, removed 'ears' from Greek Upsilon and Psi.
+ Copied resulting glyphs to Serif Mathematical Alphanumeric Symbols.
+
+ * FreeSerif.sfd:
+
+ Some pointwise cleanup of main Tamil range
+
+ Tried some things with lookups. Didn't make much headway.
+
+2008-11-01 Stevan_White
+ * FreeMono.sfd:
+
+ somehow made a letter with wrong width
+
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added similar lookups and ligatures to Thai ranges.
+
+ * FreeSerif.sfd:
+
+ Lookups now work no worse than those for other Thai fonts, at least
+ in Pango. Still perplexed by behaviour of "Required" lookups.
+
+ For Thai, made ligatures and lookups for yoying and thothan combined
+ with a lower vowel. These work well.
+ Attempted looksups for saraaa with ru and lu, and for saraam.
+ Not working.
+
+ Cleaned up a few of the Bengali ligatures
+
+ * FreeSerifBold.sfd:
+
+ Tweek Thai
+
+2008-10-31 Stevan_White
+ * FreeSerif.sfd:
+
+ Fixed ligatures and mark positioning for Hanunóo.
+ Problem with ligatures: Gnome pango doesn't do 'rlig', only 'liga'
+
+ * FreeSerifItalic.sfd:
+
+ Changed lookup table scripts for Devanagari and Bengali.
+ Find Problems -> ATT found several problems showing lookups acting on
+ glyphs that weren't listed in the script ranges, including dev2, bng2
+ (why not deva and beng, I don't know).
+
+ danda and doubledanda of Devanagari I understand are to be shared among
+ Indic scripts. So included bng2 and dev2 in the 'aalt' table for those.
+
+ The 'init' and 'half' tables for Bengali made active for bng2.
+
+ The 'locl' table for Bengali didn't do anything I could see: It mapped
+ the Devanagari danda to itself, and the doubledanda to itself. Deleted.
+
+ Cleaned up some kern tables.
+ adjustments of under 5 EM are invisible. Some others I just didn't like.
+ Some were putting a letter beneath another, with is wrong.
+
+ * FreeSerifBoldItalic.sfd:
+
+ Added Thai
+
+ * FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Changes to mark positioning lookups, esp. in Italic.
+ Widened numerals in Bold
+
+2008-10-27 Stevan_White
+ * FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Tweeks regarding Armenian and lookups
+
+ * FreeSansBold.sfd:
+
+ Added Armenian ligatures FB13-FB17 with lookups
+ Also made a historical ligature ('hlig') table for u+0587.
+
+ Toward bug #15183: missing characters from Armenian range
+ https://savannah.gnu.org/bugs/index.php?15183
+
+ * FreeSansOblique.sfd:
+
+ Added Armenian ligatures, lookups. Cleaned up contours.
+
+ * FreeSans.sfd:
+
+ Added 5 Armenian ligatures to U+FB13 – FB17, and made corresponding
+ 'liga' lookup. Found there one ligature u+0587 that according to
+ http://en.wikipedia.org/wiki/Armenian_alphabet
+
+ "in new orthography the Ö‡ character is not a typographical ligature anymore, and must never be treated as such. It is a distinct letter and has its place in the new alphabetic sequence."
+ So moved this out of the 'liga' lookup and into a new 'hlig' lookup.
+
+2008-10-26 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Lots of improvements to Thai.
+ Completely revised letter spacing in Italic, and fiddled with combining
+ marks in all.
+ Still aren't working quite right, especially in Italic.
+ Still need to work over digits (in Bold they aren't even bold yet)
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Bold Thai : added (painstakingly) constructed glyphs, lookups
+ roman Thai: tweeks
+ Italic Thai: tweeks (Note this still has multiple problems)
+
+2008-10-25 Stevan_White
+ * FreeSerif.sfd:
+
+ WAZU says
+ http://www.wazu.jp/gallery/Fonts_Hanunoo.html
+
+ MPH 2B Damase doesn't support the consonant-vowel ligatures necessary
+ to render Buhid writing.
+
+ OK, so I made 'mark' lookups for combining marks and a bunch of
+ ligatures in an 'rlig' lookup. The latter still not working:
+ don't know why.
+
+ Made page to match the example of the combining forms at
+ http://www.omniglot.com/writing/hanunoo.htm
+
+2008-10-24 Stevan_White
+ * FreeSerif.sfd:
+
+ Removed some marks from Mathematical Alphanumeric Symbols
+
+ * FreeSerif.sfd:
+
+ Tweeked combining marks for Vietnamese. Made to satisfy
+ WAZU JAPAN Comprehensive Unicode Test Page for Vietnamese
+ http://www.wazu.jp/gallery/Test_Vietnamese.html
+ Could still use some tweeking...
+
+ * FreeSerif.sfd:
+
+ Added marks for composition of Vietnamese
+
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Put "below" combining mark on lots of vowels and derivatives,
+ for Vietnamese.
+ Named a bunch of composit Latin, expecting to make substitutions.
+
+2008-10-23 Stevan_White
+ * FreeSerif.sfd:
+
+ Thai spacing alterations based on advice of a native speaker.
+
+2008-10-22 Stevan_White
+ * FreeSerif.sfd:
+
+ re-named Thai lookups according to order
+
+2008-10-21 Stevan_White
+ * FreeSans.sfd:
+
+ Cleanup of glyphs in Gujarati, Devanagari.
+
+ Note: Serious problem with Sans GPOS abvm in Devanagari
+ "'abvm' Above Base Mark in Devanagari subtable" "gujr-0"
+ But all the characters that list gujr-0 are in Gujarati.
+ Not sure how this got broken or how to fix it.
+
+ * FreeSerif.sfd:
+
+ Fiddled with Thai mark positioning: passes my tests now OK.
+ Made a few more references in Math Symbols; more regularization of
+ stroke.
+
+ * FreeSerif.sfd:
+
+ Added mark class for Vietnamese "horn"
+ Several references made in General Punctuation, Arrows
+
+ * FreeMono.sfd:
+
+ added some Combining Diacritical Marks
+
+2008-10-20 Stevan_White
+ * FreeSerif.sfd:
+
+ Made some references from serifed Latin capitals to Greek counterparts.
+
+ * FreeSerif.sfd:
+
+ Made a few repeated glyphs into references in Musical Symbols
+
+2008-10-19 Stevan_White
+ * FreeSerif.sfd:
+
+ Moved several glypns from Mathematical Alphanumeric Symbols to
+ Letterlike Symbols.
+ Couple tweeks in Mathematical Symbols.
+
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Fiddling with Mathematical Symbols.
+ In Serif, trying to make stroke width more consistent.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd:
+
+ Added some Greek symbols in Mono and Sans to make a little more regular
+ and correspond better with TeX.
+ Tweek of serif.
+
+ * FreeSansBold.sfd:
+
+ a few more improvements.
+
+ One problem with the Mathematical Alphanumeric area is, one must
+ remember to change it any time another face is altered...
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSerifBold.sfd:
+
+ Several improvements and additions to Sans faces (mostly in Greek) from
+ experience of pasting into FreeSerif Mathematical Alphanumeric Symbols.
+
+ * FreeSerif.sfd:
+
+ Replaced most of Mathematical Alphanumeric Symbols
+ roman italic bold (latin and greek)
+ gothic italic bold (latin and greek)
+ typewriter
+ and numerals
+ with glyphs from FreeFont. These were scaled to uniform height.
+
+ Remains: Blackboard Bold, Fraktur, Calligraphic, Script
+
+ * FreeSerif.sfd:
+
+ Tidied lookup table names for Malayalam
+
+ * FreeSerif.sfd:
+
+ Applied Malayalam patch from Hiran Venugopalan
+
+ * FreeMono.sfd:
+
+ Added/corrected many Mathematical Symbols
+
+ * FreeSansOblique.sfd:
+
+ more IPA
+
+2008-10-18 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Made lots more IPA and Phonetic Extensions
+ Note: fontforge is reporting an error in a few glyphs made by scaling
+ another, that the glyphs are drawn in the wrong direction--only in
+ TrueType though. Suspect a FontForge bug.
+
+ Added several Combining Diacritical Marks
+
+2008-10-17 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Made several Spacing Modifier Letters, Combining Diacritical Marks,
+ and IPA and Phonetic Extensions
+
+2008-10-16 Stevan_White
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added some Superscripts and Subscripts
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Finished off Superscripts and subscripts
+
+ Completed General Punctuation for Mono faces
+
+ Added some General Punctuation
+
+2008-10-15 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ more Letterlike Symbols, Currency Symbols
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Made some Combining Diacritical Marks for Symbols, Letterlike Symbols
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Added some General Punctuation
+
+2008-10-14 Stevan_White
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Added double slanted hyphen, made General Punctuaton Supplement like
+ Serif's
+
+ * FreeSansBoldOblique.sfd:
+
+ Filled out Greek Extended
+
+ * FreeMono.sfd, FreeSerifItalic.sfd:
+
+ fixes to last 2 commits
+
+ * FreeSerifItalic.sfd:
+
+ Last character to General Punctuation
+
+ * FreeMono.sfd:
+
+ Built some Enclosed Alphanumerics (1-10)
+
+ * FreeSerif.sfd:
+
+ Copied in Daniel Johnson's changes to Cherokee.
+
+2008-10-12 Stevan_White
+ * FreeSerif.sfd:
+
+ Included Daniel Johnson's Cherokee glyphs.
+
+2008-10-05 Stevan_White
+ * FreeMono.sfd:
+
+ Further corrections to diaresis in Cyrillic -- legibility in small sizes
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoOblique.sfd, FreeSerif.sfd:
+
+ Regularized placement of diaresis in Cyrillic
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added same set of glyphs to Cyrillic Supplement
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Added some of the easier letters from Cyrillic Supplement
+
+2008-10-04 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeSerifItalic.sfd:
+
+ Finished high Cyrillic range for MonoBold and MonoBoldOblique.
+ (Remaining: historic ranges, Cyrillic extensions)
+ Tweeked others.
+
+ * FreeMonoBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Serif*Italic: Added last Abkhazian letters to Cyrillic
+ MonoBold: tweek
+
+2008-10-03 Stevan_White
+ * FreeMono.sfd, FreeMonoOblique.sfd, FreeSerif.sfd, FreeSerifBoldItalic.sfd:
+
+ Mono: Some additions to historic letters
+
+ * FreeSerif.sfd:
+
+ Added some punctuation and combining numeric marks from
+ Cyrillic Extended B
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Various technical tweeks, mostly concerning recent additions.
+ Also did a bit more "Points too close" and "irrelevant control points".
+ Cyrillic millions redesign meant could not maintain use of refrences
+ for it.
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More high Cyrillic
+ Included old Cyrillic millions combining mark in Sans, changed design
+ in Serif
+
+2008-10-02 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ More high Cyrillic
+
+ * FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifBoldItalic.sfd:
+
+ More high Cyrillic glyphs
+
+ * FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More glyphs in high Cyrillic. Remains only some whose form I'm unsure
+ of in italic.
+
+ * FreeSerifBoldItalic.sfd:
+
+ More glyphs in higher Cyrillic range
+
+ * FreeSerifItalic.sfd:
+
+ Same process of tightening el, em, ge (but a P.S. to previous commit:
+ also did ya, ze for SerifBold.)
+
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ BoldItalic: Tightened up spacing on left of el, em, ge (could go
+ farther, but it is partly a problem with glyph design...
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More additions to Cyrillic. Finished SerifBold except for Nivkh
+ additions.
+ Used references on number combining forms.
+
+2008-09-30 Stevan_White
+ * FreeSerif.sfd:
+
+ Added four (obsolete) Chuvash letters to Cyrillic Supplement
+ - completing it.
+
+2008-09-29 Stevan_White
+ * FreeSerif.sfd:
+
+ Greek adjustments
+ Adjusted spacing of kappa slightly
+ Got rid of ears on Psi, following similar request for Upsilon.
+
+2008-09-28 Stevan_White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Adding and fiddling with Spacing Modifiers and Combining Diacriticals
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Revisions of several Combining Diacritical marks
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ A few Combining Diacriticals and Spacing Modifiers
+
+ MonoBoldOblique: Primarily filling out Spacing Modifier Letters
+ others: little fixes found along the way
+
+2008-09-27 Stevan_White
+ * FreeSerif.sfd:
+
+ Replaced Malayalam range with that from Rachana_04 found on
+ Swathanthra Malayalam Computing project page
+ http://savannah.nongnu.org/projects/smc/
+ Besides scaling and converting to cubic, performed much clean-up of
+ glyphs, added an r2 character, and re-named a bunch of characters.
+
+2008-09-22 Stevan_White
+ * FreeSerif.sfd:
+
+ Filled in as much of Phonetic Extensions as I could without artistic
+ abilities.
+ Note 1D48-9 are not references due to apparent FontForge bug, that says
+ scaled references go in wrong direction.
+
+ * FreeSerif.sfd:
+
+ Cleaup of some Bengali glyphs.
+ Note many of the ligatures remain very very messy.
+
+ * Makefile:
+
+ added more validations
+ made to work with GenerateOpenType
+
+ * FreeSerif.sfd:
+
+ Built two more easy Phonetic Extensions
+
+ * FreeSerif.sfd:
+
+ Built some Phonetic Extensions letters, those with middle tilde
+
+2008-09-21 Stevan_White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Added lots of Spacing Modifier Letters and Combining Diacritical Marks.
+
+ * FreeMono.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSerif.sfd:
+
+ Wrote script to check if glyph encodings were in stated ranges, fixed
+ most discrepancies.
+
+ There were a bunch of incompletely deleted characters in several faces.
+
+ Sans: found several other problems in the process
+ # Tamil
+ Four slots labelled 0BDA-D have glyphs, not in Unicode. also 0BE1
+ I think they are misplaced; added 0010 to each of them
+
+ # Devanagari
+ Slot labelled U+093B is not in Unicode--can't find glyph: deleted
+ likewise 094F (may have been meant to be 0954)
+ 0955, 0973-0976
+
+ 0954 should be a combining mark, but it appears on the wrong side of 0.
+ 0971 was just wrong--made into simple dot.
+ 0972 is also wrong--made my own Candra A.
+
+ # Gujarati
+ Slots labelled 0AE4-5 are not in Unicode; seem not to belong at all.
+ Deleted. 2800 is a dup of 2790. Deleted
+
+ Serif: phillipine_double u1736 was misplaced
+
+ A bunch of the Math Alphanumeric symbols are empty in the standard,
+ because they're represented elsewhere. These should be deleted
+ First need to make style consistent with existing symbols.
+
+ * FreeSerif.sfd:
+
+ Applied patch from Daniel J
+ Remedies bug
+ FreeSerif: Missing glyphs with palatal hook
+ https://savannah.gnu.org/bugs/index.php?24298
+ Adding several letters to Phoenetic Extensions range U+1D80-BF
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made four characters U+200C-F to be zero-width
+ Remedy to bug #23593: Mono 0-width chars: zero-width or space?
+ https://savannah.gnu.org/bugs/index.php?23593
+
+ * FreeSerif.sfd:
+
+ Made Mahjong tiles to take up less space using references
+ Cleaned up several validation problems
+
+2008-09-19 Stevan_White
+ * FreeSerif.sfd:
+
+ Added several Hebrew Alphabetic Presentation Forms (some easy ones), to
+ make its coverage the same as Serif Bold.
+
+ * FreeSerifBold.sfd:
+
+ Re-encoded.
+ Deleted several glyphs in Hebrew Alphabetic Presentation Forms that
+ didn't correspond valid Unicode
+
+ * FreeMonoBold.sfd, FreeSans.sfd, FreeSerifItalic.sfd:
+
+ Ran script to find mis-numbered glyphs. Several were simply typos,
+ some offset by one.
+
+ * FreeSansOblique.sfd:
+
+ Numerous cases of glyphs in Private Use area incorrectly assigned
+ Unicode numbers and names. Gave all -1 for Unicode and named like
+ "slot.XXXX".
+
+ * FreeSerif.sfd:
+
+ Adapted Mahjong Tiles from George Douros' Unicode Symbols font.
+
+ * FreeSerif.sfd:
+
+ Added Domino Tiles. Domino outline is copied from George Douros'
+ Unicode Symbols, but the rest I preferred to do with references.
+
+2008-09-18 Stevan_White
+ * FreeSerif.sfd:
+
+ Adapted Mathematical Alphanumeric Symbols from George Douros' Unicode
+ Symbols font.
+
+ * FreeMonoBoldOblique.sfd:
+
+ This one got away from me--I don't know what I did.
+ Looks like some small contour edits.
+
+ * FreeSansBoldOblique.sfd:
+
+ Fixed one mis-numberd character in Latin Extended-B
+
+ * FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Fixed several mis-numbered characters.
+
+ * FreeSansBold.sfd:
+
+ SansBold: one Georgian letter with no name, one Zapf Dingbat was
+ unnumbered
+ ATT test shows a bunch of problems with Gurmukhi and 'blwf' table
+ indeed shows those letters at 0x10000+
+ Sans names them like uni0A30_uni0A4D.blwf: they are in range
+ ECC6 to ED06
+
+ I meant to move this range into Private Use in last release, and
+ missed it. So now it is moved, into same range as Sans.
+
+ Both Sans and SansBold in nukt table for Gurmukhi have duplicate
+ entries for uni0A15 uni0A3C. Deleted dups.
+
+ * FreeMonoOblique.sfd:
+
+ fixed a number of Unassigned Code Points in Greek Extended
+
+ * FreeSansOblique.sfd:
+
+ mis-numbered Combining Diacritics
+
+ * FreeSansOblique.sfd:
+
+ Several chars in Latin Extended hadn't been named.
+ One spurious letter in Letterlike Symbols
+
+2008-09-16 Stevan_White
+ * FreeMono.sfd, FreeSans.sfd, FreeSerif.sfd:
+
+ Lots of additions: unless otherwise noted, they are from George Duros'
+ fonts Analecta, Music, and Unicode (haven't got final confirmation of
+ the eligibility of these glyphs, so this is just for testing.)
+
+ Added some combining marks, fiddled a bit. In both Serif & Mono, tried
+ to get a key symbol characters to fit inside the key combining mark
+
+ Serif
+ Got rid of ears on Upsilon
+ Added:
+ # Gothic
+ # Western & Byzantine Musical Symbols
+
+ # Misc Symbols, Misc Technical Symbols (drew many myself)
+ # Supplemental Symbols and Arrows
+
+ Mono
+ Added:
+ # lotsa Misc Technical Symbols
+ # OCR Symbols
+ # drew many Supplemental Symbols and Arrows, Misc Technical
+
+ Sans
+ Added # Phoenecian
+ Made a few Letterlike Symbols; Made Re and Im to be sans-serif.
+
+2008-09-11 Stevan_White
+ * FreeSerif.sfd:
+
+ Removed pointless entries from Latin kern table
+
+ Tidied points in Sinhala
+
+2008-09-07 Stevan_White
+ * FreeSerif.sfd:
+
+ Tidied up Tamil ligatures EEA8-EEAB to fix TT build warning
+ "MonotonicFindAlong: Never found our spline."
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, Makefile:
+
+
+ Added APL characters to FreeMono (why?...)
+
+ Fixed several last-minute problems, including
+
+ Serif: Tweeked GPOS mark table for Cyrillic
+ Sans: Added a GPOS table for Cyrillic (but several diacritics missing)
+
+ Serif, Mono: tweeked some bugs in extensible brackets & integrals
+
+ Serif: Vietnamese o circumflex: accent was a bit high. fixed.
+
+ MonoBoldOblique OTF build
+ uni213b intersects self
+
+ Generation of TT fonts complains about several things to stderr,
+ including:
+
+ SerifBold: "There exists a 'fpgm' code that seems incompatible with FontForge's. Instructions generated will be of lower quality. If legacy hinting is to be scrapped, it is suggested to clear the `fpgm` and repeat autoinstructing. It will be then possible to append user's code to FontForge's 'fpgm', but due to possible future updates, it is extremely advised to use high numbers for user's functions."
+ Probably has been there since I first copied the TT instructions in.
+ Just repeated the copying process carefully, and the warning went away.
+
+ Serif: "FindMatchingHVEdge fell into an impossible position"
+ fixed a bunch of point too close
+
+ REMAINING PROBLEM in Serif TT build
+ "MonotonicFindAlong: Never found our spline."
+ fixed several bad TT matrices-- there are several more
+ fixed many "control points too close" no luck
+
+2008-09-03 Stevan_White
+ * FreeSans.sfd, FreeSansOblique.sfd:
+
+ Added/corrected some Misc. Symbols by copying from Serif.
+ Note this is only a stopgap solution. Want real sans-serif symbols.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added minimal Miscellaneous Symbols: card suites and some musical notes.
+ Note not happy with shapes...some I just drew. Sans isn't really sans.
+
+ Fixed one APL symbol in Mono so it verified in OTF version
+
+2008-08-31 Stevan_White
+ * FreeMono.sfd:
+
+ Built set of APL symbols.
+
+2008-08-30 Stevan_White
+ * FreeSans.sfd:
+
+ Un-linked references in uni02B2 and uni02B5, because when validating the
+ TrueType version, FontForge gave an error "is drawn in wrong direction".
+ I suspect a bug in FontForge. Other similar glyphs make no errors.
+
+ Fixed missing extrema in TrueType.
+ These were the last cases being reported by validate in all the faces.
+
+ * FreeSerifItalic.sfd:
+
+ fixed last missing extrema in TrueType
+
+ * Makefile:
+
+ restructured validation to look in a directory
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd:
+
+ Fixed missing extrema in TrueType versions
+
+2008-08-15 Stevan_White
+ * FreeSans.sfd:
+
+ Same problem with uni0A83 as with bn_llikaar. Just made zero-width.
+
+2008-08-14 Stevan_White
+ * FreeSans.sfd, FreeSansOblique.sfd:
+
+ Glyph bn_llikaar, U+09E3 BENGALI VOWEL SIGN VOCALIC LL,
+ has right bound positioned far into the negative. Causes a warning in
+ FontForge when opening OTF version.
+ Comparing with other fonts supporting Bengali, found no others that
+ do this.
+ Serif makes glyph width 0 (which sounds right according to Unicode)
+ and puts glyph wholly to left of 0. But, I haven't found this letter
+ in text anywhere. I wonder if it is really used in writing.
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Further TrueType validation fixes.
+ Sans still has two glyps in wrong direction.
+
+ * FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Fixed more TrueType problems...all missing extrema in TTF validation
+
+2008-08-13 Stevan_White
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ fixed all the TrueType validation problems of type "intersects itself"
+ and all but two of the "wrong directions", as well as a lot of
+ "missing extrema". But there remain hundreds of missing extrema in the
+ TrueType version.
+ Also, bn_llikaar in Sans and Oblique still has a problem in OTF version.
+
+ * FreeMono.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd:
+
+ Made .ttf files to validate. Other faces have many more problems still.
+
+2008-08-12 Stevan_White
+ * FreeMonoOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Continuing to make OTF versions validate.
+
+ * FreeMonoOblique.sfd:
+ lots of missing points at extrema
+ * FreeSerif.sfd:
+ 12 wrong directions, 1 missing extrema
+ * FreeSerifItalic.sfd:
+ many missing points at extrema, 1 self-intersecting
+
+ What was wrong: in several oblique cases, an already-italic glyph was
+ made more italic, thereby fouling up extrema (although why it passed
+ validation in the SFD I don't know). Some glyphs were
+ overly-complicated with many near points. Cleaned up, rounded to int.
+
+ Remaining problem: OTF FreeSansOblique FreeSans. one Bengali glyph in
+ each whose advance width and htmx don't match.
+
+ Moral of story: validate the OTF and TTF versions too before a release.
+
+ * FreeSansOblique.sfd:
+
+ Reverse a mistake from last commit: somehow this file was converted to
+ quadratic, or something.
+
+2008-08-11 Stevan_White
+ * FreeMonoBoldOblique.sfd, FreeSans.sfd, FreeSansOblique.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Found that SFD files that validated produced OpenType files that don't.
+ These represent the easy fixes. Some were result of conversion to
+ quadratic; some shouldn't have validated in the SFD...
+
+ * MonoBoldOblique: uni0250 missing pts at extrema [reference glyph rotated...]
+ * Sans: uni0AC4 wrong direction [simplified, rounded to int]
+ * SansOblique: uni01EA wrong direction [rounded to int]
+ * SerifBold: uni023f wrong direction [round to int]
+ * SerifBoldItalic: uni0245 missing pts at extrema [ungrouped ref, added extrema]
+
+2008-08-06 Stevan_White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoOblique.sfd:
+
+ Re-set font metrics, which were somehow making uneven vertical spacing.
+
+2008-06-22 Steve White
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Made to validate
+
+ * ranges.py:
+
+ Brought more into line with OpenType
+ Added some ranges
+ Fixed bug with ranges outside of font
+
+ * CREDITS:
+
+ 3 new ranges
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Cyrillic: tweeked accents for consistency, and for readability in small
+ sizes.
+
+ * FreeSerif.sfd:
+
+ Thanna range: tweeking
+
+ Thaana range: Scaled up by about 15%, raised by 100EM, tightened
+ some of the diacritics to get inside 900 to -300 EM limits.
+
+ * FreeSans.sfd:
+
+ Added Old Persian and Ugaritic from MPH2BDamase font.
+
+2008-06-21 Steve White
+ * FreeSerif.sfd:
+
+ Added Tai Le range adapted from MPH2BDamase font.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Added some ancient Greek numerals from Tempora to high Unicode area,
+ (partly just to show it can now be done.)
+
+ * FreeSerifItalic.sfd:
+
+ Couple of tweeks putting glyphs above -300EM.
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Surgery to Thai letter 'tho than', u+0e10, to push it above -300 EM.
+ This makes Thai range completely between 900 and -300 EM.
+
+ * FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Many auxilary characters (esp. for Malayalam, Bengla, and Tamil)
+ representing ligatures and alternative forms without their own Unicode,
+ were moved from
+ ranges above 0xFFFF (which ought to have been slots for other defined
+ Unicode ranges) into the Private Use area.
+
+ In Serif, I segregated the scripts, in Sans it was hard to see where one
+ began and another ended, so I moved them en masse.
+
+ Note several problems with wrongly-named characters:
+ I already re-named glyph570 and glyph582.
+ But there are others with names starting with A...
+
+ * FreeSansBold.sfd, FreeSansOblique.sfd:
+
+ Fixed (I hope the last) problem with scripts in lookups
+ Find Problems -> ATT (all selected) finds multiple issues,
+
+ * FreeSansBold.sfd:
+ In addition to script 'guru', added 'gur2' to the scripts for these
+ lookups
+ 'nukt' Nukta forms in Gurmukhi
+ 'blwf' Below Base Forms in Gurmukhi
+ 'pstf' Post Base Forms in Gurmukhi
+ 'blws' Below Base Substitutions in Gurmukhi
+ 'abvs' Above Base Substitutions in Gurmukhi
+ 'psts' Post Base Substitutions in Gurmukhi
+
+ * FreeSansOblique.sfd:
+ In addition to script 'beng', added 'bng2' to the scripts for the lookup
+ 'half' Half Forms in Bengali
+
+ Moreover, the lookup
+ 'aalt' Access All Alternates in Latin
+ contains only Bengali letters.
+ Re-named as Bengali, made to work on beng, bng2 scripts
+
+2008-06-20 Steve White
+ * FreeSerif.sfd:
+
+ Scaled Sinhala range.
+ Remedies bug #23656: Sinhala letters over-sized
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Mostly messing with Greek Extended accents again.
+ re-positioned ypogegrammani on advice of Alexey Kryukov
+ Put prosgegrammani beneath main letters in Mono, to make narrower glyphs
+ Implemented more distinction between tonos and acute.
+
+2008-06-19 Steve White
+ * FreeMonoBoldOblique.sfd:
+
+ Completed fit of Mono to 800 to -200 EM.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoOblique.sfd:
+
+ Set Metrics to recommended values
+
+ * FreeMonoOblique.sfd:
+
+ Now Mono Oblique, as well as roman and Bold, are within 800 to -200 EM.
+ Just BoldOblique to go.
+
+ * FreeMono.sfd, FreeMonoBold.sfd:
+
+ More toward fitting to 800 to -200 EM.
+ Basically, reduced Georgian by 92%.
+ Also made an over-all offset, so Georgian is somehow centered (Bold...I
+ guess I already did this in roman).
+ Want to also do an emboldening to make stroke like rest of font, but
+ current FontForge has a nasty crash that loses data on this function.
+
+ * FreeMono.sfd:
+
+ In effort to make fit in 800 to -200 EM,
+ Scaled Georgian by 92%, centered on 600 wide box.
+ Next: Embolden a bit.
+
+2008-06-18 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Toward making all glyphs lie between -200 and 800 EM.
+ Numerous small changes, especially raising descenders of some Hebrew
+ letters.
+ Georgian remains a problem
+
+2008-06-13 Steve White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Moved prosgegrammeni up to baseline,
+ (and then moved all references down to baseline)
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added Control Picture "blank" to all faces.
+ Switched U+0222-3 from TemporaLGCUni
+
+2008-06-11 Steve White
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More fiddling with Greek Extended accents
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Tweeks to accents etc in Greek Extended and Cyrillic
+
+2008-06-10 Steve White
+ * FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Fixed a few big horizontal spacing problems
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Implemented TemporaLCGUni glyphs in Cyrillic ranges.
+ Added a breve_cyrillic for the moustache breve mark.
+
+2008-06-08 Steve White
+ * FreeSerif.sfd:
+
+ Replaced most of Cyrillic range with TemporaLGCUni.
+ Remodelled many of the derived Cyrillic characters after these.
+ Fiddled globally with spacing of small letters.
+ Unclear on diacritics 485-6, unhappy with breve.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Started implementing TemporaLCGUni in Greek ranges.
+
+ Replaced 3DC-3E1 from Tempora, because I thought they looked nicer and
+ more like the other existing FreeFont glyphs.
+ Replaced 3DA-B from Tempora, because they look more like Unicode
+ samples, and nicer.
+ Added 03f3-4, 03F7-F.
+ Prefer my own lunate epsilon.
+ Replaced Phi and Omega from Tempora.
+ These plainly fit the other FreeFont glyphs better than the origninals.
+ (How did this happen?)
+
+ In bold, replaced U+03D7
+
+ Copied lbbar u+2114
+
+ Small italic greek--replaced most except phi, psi, omega
+
+ Based on new information, broke the identification of oxia with Latin
+ acute.
+
+2008-06-07 Steve White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Efforts to control heights of characters
+
+2008-06-06 Steve White
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made to validate
+
+2008-06-05 Steve White
+ * FreeSans.sfd:
+
+ Fixed undefined character in kerning classes
+
+2008-06-04 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ tweeks and additions to General Punctuation
+
+2008-06-03 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSansOblique.sfd:
+
+ Completed/tweeked Number Forms
+
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Added some Miscellaneous Technical symbols
+
+2008-06-02 Steve White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Tweeks...mostly Letterlike
+
+2008-06-01 Steve White
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Added Box Drawing characters to Serif.
+ Tweeked a glyph in Mono
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Added several glyphs to Letterlike Characters
+
+2008-05-31 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Validation pass
+
+ SansOblique and SansBoldOblique had validation problem with BlueValues
+ Private Dictionary
+ Elements in BlueValues/OtherBlues array are disordered
+ Elements in BlueValues/OtherBlues array are too close
+ (Change BlueFuzz)
+ StemSnapV does not contain StdVW value.
+ So I ordered the array, and based on other slanted fonts,
+ removed StemSnapV.
+
+ Note however, I still think the two top Blues lines are too close
+ But I don't even know what the second-to-top line is meant to do.
+
+ * FreeSerif.sfd:
+
+ Added to Block Elements, Geometric Shapes
+ Made to validate
+
+2008-05-29 Steve White
+ * FreeMono.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Looking at special symbols.
+ Drew several Miscellaneous Symbols in Mono and Serif
+ > Completed/corrected planetary symbols, added Dice,
+ some other easy ones
+ > Completed Dingbats in Serif (using URW Dingbats)
+ Added some Block Elements to Serif
+
+2008-05-26 Steve White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More changes stemming from J. Poon's report.
+
+2008-05-25 Steve White
+ * FreeSerif.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Height surgery on SerifBoldItalic.
+ More fiddling with accents in others.
+
+ * FreeSerifItalic.sfd:
+
+ More height surgery. Only a few left in Benglai and Thai
+
+ * FreeSerifBold.sfd:
+
+ Re-applied surgery to make glyphs between 900 and -300EM
+
+ *** Regression
+ Inadvertently un-linked all references in SerifBold in r1.83.
+ This reverses that error (but also un-does the surgery mentioned there)
+
+ * FreeSerifBold.sfd, FreeSerifItalic.sfd:
+
+ Applied surgery to make Latin letters go under 900EM.
+ One exception yet...
+
+2008-05-24 Steve White
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Serif: much fiddling with accents in Latin ranges.
+ Re-thought some glyphs (there are still a few messy ones, especially
+ in bold)
+ Checked horizontal spacing...fixed a number of problems.
+
+2008-05-23 Steve White
+ * FreeSansBold.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Made Latin Extended-B coverage consistent across Serif; cleaned up some
+ glyphs
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Filled more of General Punctuation in Sans and Serif
+ Made all agree on coverage of Latin Extended Additional
+
+2008-05-22 Steve White
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansOblique.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Added Latin Extended Additional to SansOblique.
+ Made Latin Extended Additional coverage consistent across Sans, B, I
+ Made Latin Extended-B coverage same in SerifBold.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeSansBold.sfd:
+
+ Mono* made Latin-B coverage consistent across faces
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Made set of Latin Extended-B consistent across Sans faces
+
+ * FreeSans.sfd, FreeSansBold.sfd:
+
+ More filling in General Punctuation
+
+ * FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Another bunch of J. Poon's reports
+ also, filling in some Combining Diacriticals, Spacing Modifiers, and
+ General Punctuation in bold faces
+
+2008-05-21 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Mucking about with mark tables in Thai (Serif)
+ Other faces: Making changes from J. Poon's report
+
+2008-05-20 Steve White
+ * CREDITS:
+
+ Mark Williamson
+ Jacob Poon
+
+ * Makefile:
+
+ added tests target
+
+2008-05-18 Steve White
+ * ranges.py:
+
+ Put table explanation back in
+
+ Improved behaviour for high Unicode
+
+ * FreeSans.sfd:
+
+ Revision of kerning
+
+ * FreeSerif.sfd:
+
+ Made Latin kerning a little more reasonable:
+ reduced many excessive kerns (some had letters apparently
+ overlapping, which shouldn't happen)
+ made kerns increment by 5EM for ease of reading
+ got rid of kerns too small to be seen
+
+ * FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSerifBold.sfd:
+
+ Made to verify
+
+2008-05-13 Steve White
+ * FreeSerif.sfd:
+
+ Made to validate
+
+ * FreeSerif.sfd:
+
+ Gurmukhi: filled range in Serif, taking glyphs from the original
+ Punjabi font by Hardip Singh Pannu
+ http://members.aol.com/hspannu/punjabi.html (file pb_win95.exe)
+
+2008-05-12 Steve White
+ * FreeSans.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Hebrew, basic. Some faces missing punctuation marks, added.
+
+ * FreeMono.sfd, FreeSans.sfd:
+
+ Armenian: Sans tried to make verticals and horizontals of more uniform
+ width both, finddled with punctuation
+
+ * FreeMonoOblique.sfd:
+
+ made to validate
+
+ * FreeMonoBold.sfd:
+
+ made to validate
+
+ * FreeSans.sfd, FreeSansBold.sfd:
+
+ Armenian in Sans: regularized letter spacing
+
+ * FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd:
+
+ Armenian: fill out ranges and clean up
+ SansBold especially had a lot of incorrect references.
+ Now all the ranges with Armenian at least share the same set of
+ characters.
+
+ * FreeMono.sfd:
+
+ Fixed glyph with wrong width.
+
+2008-05-11 Steve White
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerifItalic.sfd:
+
+ 1) made to validate
+ 2) Mono: copied in Spacing Modifier Letters (glyphs not yet named)
+ 3) SerifItalic: Filled in General Punctuation
+
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made to validate, and pass all other FontForge tests.
+ Expedient: rounded everything to int
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Made to have the same Greek Symbols,
+ Made to validate
+
+ * FreeSans.sfd, FreeSansBold.sfd:
+
+ Made Greek Symbols as full as rest of Sans. Changed a name in Sans.
+
+ * FreeMonoOblique.sfd:
+
+ Made Greek as full as other faces
+ Made to validate
+
+ * FreeSansBold.sfd:
+
+ Deleted seven orphaned Arabic characters; looks like somebody started,
+ didn't get very far, putting Arabic in bold.
+
+ Deleted orphaned Arabic glyph from Arabic Presentation forms-B
+
+ * FreeSerifBold.sfd:
+
+ Deleted the single Arabic character: it was clearly there by mistake.
+
+ * FreeSansOblique.sfd:
+
+ Made Greek Symbols as full as rest of Sans
+
+ Tweeks to Armenian
+
+ Comment from previous commit of FreeSans was meant for FreeSansOblique.
+ In FreeSans, only tweeked a few letters during putting more characters
+ in this face.
+
+ Filled in Spacing Modifier Letters, increased General Punctuation.
+
+ * FreeSans.sfd:
+
+ Filled in Spacing Modifier Letters, increased General Punctuation
+
+ * FreeMono.sfd:
+
+ Made Armenian as full as other roman faces.
+
+ Completed Spacing Modifier Letters
+ Added a couple of Greek Punctuation
+
+ added more Spacing Modifier Letters
+
+2008-05-10 Steve White
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Did same process of scaling and sizing for Thai in Sans as in Serif.
+ Added mark tables to Sans. Improvement, but there are questions...
+
+ * FreeSans.sfd:
+
+ Tidied some Gurmukhi glyphs, validated.
+
+ Deleted ranges for Oriya, Kannada, on account of
+ 1) they only contained a subset of the consonant glyphs of the scripts,
+ few if any vowels, and had no ligature lookups as required
+ 2) Kannada was based on the Akurti fonts, which have copyright issues.
+
+ See
+ bug #23225: Oriya range only partial
+ bug #23224: Kannada range only partial
+
+ * FreeMonoBoldOblique.sfd:
+
+ Made metrics like rest of Mono
+
+2008-05-09 Steve White
+ * ranges.py:
+
+ More info on range intervals
+
+ * FreeSerif.sfd:
+
+ Deleted Telugu range.
+ It didn't represent a complete writing system for the language.
+
+ See notes at https://savannah.gnu.org/bugs/index.php?23202
+ Serif: Telugu range missing many characters; many wrong
+
+ Got a copy of the original Tikkana font,
+ Copied in remaining consonants and vowels that I could find there.
+ I think one vowel 0C55 is missing according to unicode).
+ Strangely, the Telugu digits are alo missing.
+ In Tikkana, the default "checkmark" structural mark is missing from many
+ consonants, according to Unicode, but is a separate glyph. I put
+ the checkmark on.
+ This, and scaled up by 150% and cleaned up intersecting glyphs and
+ many unnecessary points.
+
+2008-05-08 Steve White
+ * FreeSerif.sfd:
+
+ Filled out Telugu consonants.
+ Vowels still need to be done
+
+2008-05-07 Steve White
+ * FreeSerif.sfd:
+
+ Operated on Latin glyphs with stacked accents to make them fit under
+ 900EM.
+ Scaled Telugu bu 150%.
+
+2008-05-06 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeSansBold.sfd, FreeSerif.sfd:
+
+ Corrected further fontforge "find problems"
+ Added some math characters to FreeSerif
+
+2008-05-05 Steve White
+ * FreeSansBold.sfd:
+
+ Made to validate, and fixed bad TT transformations
+
+2008-05-04 Steve White
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Mainly TeX additions trying to satisfy Markus Kuhn's TeX-as-Unicode page
+
+ * FreeMono.sfd:
+
+ Adjusted heights of extensible brackets
+
+ Fixed problems with extensible brackets, thanks to Markus Kuhn's page
+ http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
+
+ * ranges.py:
+
+ fiddled with ranges, doc
+
+ made some ranges more correct?
+
+ fixed some bugs in ranges
+ better error reporting
+
+ Got rid of Unicode 1.1 references
+
+ made to use OpenType table
+
+ * FreeMono.sfd, FreeSans.sfd, FreeSerif.sfd:
+
+ made to validate
+
+2008-05-03 Steve White
+ * FreeMono.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Removed digits from Private Use Area.
+ See bug 23050.
+
+ * FreeMono.sfd, FreeSans.sfd:
+
+ Completed General Punctuation
+
+ * FreeSans.sfd:
+
+ Completed IPA Extensions
+
+ * FreeMono.sfd, FreeSans.sfd, FreeSerif.sfd:
+
+ More work on Superscripts and Subscripts, Spacing Modifiers.
+ Sans is now complete in both.
+ Added Pfennig to Sans and Mono.
+
+ * ranges.py:
+
+ Restructure text output
+ Rearrangement and cosmetic ...except I had broken it. now fixed
+ Seems to be in a useful form at this point.
+ More docs, date
+
+ * FreeSerif.sfd:
+
+ Added a hand-drawn old German Pfennig to Currency Symbols
+
+ * FreeMono.sfd, FreeSans.sfd, FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Further additions to General Punctuation, Super and Sub Scripts,
+ Spacing Modifiers, etc.
+
+2008-05-02 Steve White
+ * FreeSans.sfd:
+
+ additions to Spacing Modifiers, IPA
+
+ * FreeSerifItalic.sfd:
+
+ Shortening stacked accents to maintain readability when clipped
+
+2008-05-01 Steve White
+ * FreeSans.sfd:
+
+ Additions to Spacing Modifiers and changes to Combining Diacritics
+
+ * FreeSerif.sfd:
+
+ Made sure all the half rings in Combining Diacriticals and Spacing
+ Modifiers were really half rings (J. Poon had complained about this)
+
+ Filled out General Punctuation
+ Some work on Spacing Modifiers
+
+ Filled out Mathematical Operators
+ still needs lots of work
+ Made to validate
+
+ Filled out Latin Extended B
+ Added some letters with curls to Latin Extended B
+ More fiddling with Latin Extended B accents
+
+2008-04-30 Steve White
+ * FreeSerif.sfd:
+
+ Added Hanunóo script, with characters based on those in
+ font MPH2BDamase, on request from the maintainer of that font,
+ http://packages.debian.org/sid/ttf-mph-2b-damase
+
+ Glyphs are simple vector strokes. Could be a little more uniform.
+
+ Added Buginese script "Lontara", with characters based on those in
+ font MPH2BDamase, on request from the maintainer of that font,
+ http://packages.debian.org/sid/ttf-mph-2b-damase
+
+ Note the glyphs are pretty rough, clearly a digitization of handwriting.
+ I just cleaned them up, and corrected discrepancies with Unicode,
+ and compared with some pictorial samples of the script I could find.
+
+2008-04-29 Steve White
+ * ranges.py:
+
+ Improved look a lot--still unhappy with some ranges
+ OS/2 seems sometimes bang-on, sometimes unrelated to anything (including
+ fontforge's OS/2 listing)
+
+ * FreeSerif.sfd:
+
+ Much fiddling with Tamil range.
+ First scaled to 78% (avoiding the references)
+ This gets it in the ballpark height-wise. [A bit taller than the Latin
+ letters, but the stroke is narrower, but then the glyphs are busier.]
+ Then had to re-align combined references, the trickiest being the
+ halants.
+ Checked with other fonts with Tamil text.
+
+2008-04-28 Steve White
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Cleanup of control points in Arabic and Thaana
+
+ * FreeSerif.sfd:
+
+ Cleanup of missing extrema in Arabic and Thaana
+
+ Many changes to Thai, trying to make the script fit between some lines,
+ so accents won't get clipped, etc.
+ Also, stroke weight was heavier than that of Latin.
+
+ Scaled whole thing by 93%.
+ Shrank the tallest letters 0E42-4 to get them under 900EM.
+ Shaved off top of maiek.
+ Fiddled with positioning of all accents.
+ Made positioning tables for accents.
+ Note: unclear these are working correctly
+
+ Fixed a bug having to do with character replacements for characters
+ named 'ng' and 'nj'; these names had been taken on by other characters.
+
+ Made to validate
+
+ Unicode positions of two Cyrillic Extended characters were switched.
+ Fiddled with a couple of Cyrillic combining diacritics
+
+2008-04-27 Steve White
+ * FreeSans.sfd:
+
+ bugfix: a left harpoon mysteriously appeared to the left of letter p!
+
+2008-04-26 Steve White
+ * FreeMono.sfd:
+
+ Made to validate
+
+ * FreeSans.sfd:
+
+ Made to validate
+
+ Toward J. Poons report
+ Made 032B more like proper double-arches (and distinct fro 033C seagull)
+ Made 032b more like a seagull
+
+ * FreeSans.sfd, FreeSansBold.sfd:
+
+ Sans: fiddling with widths and terminators of math symbols,
+ toward J. Poon's report
+ R & B: removed u+2741 because it didn't match the Unicode description
+
+ * FreeMono.sfd:
+
+ Extensible parenthesis symbols weight/terminators
+ Toward bug # 23064: https://savannah.gnu.org/bugs/index.php?23064
+ Rounded a bunch of terminators
+
+2008-04-22 Steve White
+ * FreeSerif.sfd:
+
+ Small alignment problem in Greek Extended
+
+ One more tweek to spacing in Cyrillic Extended
+
+ Corrected spacing in Cyrillic Supplement
+
+ Added Cyrillic Supplement letters for
+ Enets, Khanty, Chukchi, Itelmen, Mordvin, Kurdish, Aleut
+
+ Added Cyrillic letters for Nivkh (completing Cyrillic range)
+ More tightening of accents in Latin Extended.
+
+ * FreeSans.sfd:
+
+ Fiddled with math--consequences of changing the "similar" operator
+
+ More tightening of accents
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Adjustments to h and k with caron and cedilla in Latin A and B
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd:
+
+ FreeSerifBold: deleted 3 dotted Hebrew letters in Private/Corporate use
+ (E801-3). They weren't ligatures or in any other lookup, and they
+ weren't present in FreeSerif.
+
+ * FreeSansBold:
+ Unlinked and deleted F6C3, which called itself commaaccent.
+ Made some new spacing and non-spacing accents to make up for it.
+
+ * FreeSansBoldOblique:
+ Made references of many Latin Extended.
+ Also corrected several wrong ones.
+
+ * Freeserif:
+ Re-named commaaccent
+
+2008-04-21 Steve White
+ * FreeMono.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSerif.sfd, FreeSerifBold.sfd:
+
+ Deleted Hiragana and Katakana ranges, as discussed on bugs list.
+ Cleaned up some encoding issues, unnamed glyphs
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Roman: added 'sine' -- not beautiful, but I liked drawing it
+ All: Made special lookup for Dutch ligatures 'IJ' and 'ij'
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Roman: ffi etc Latin ligatures from 'liga' to 'dlig' (these weren't
+ really ligatures anyway, and only looked very bad when used.
+ Retain for condensed type.
+ Others: deleted Latin 'liga' table altogether
+ BoldOblique : added j to ij ligature
+
+ Toward J. Poon's Report:
+ Except for issues of terminators not always vertical or horizontal,
+ and a few things that were too hard or I was unsure of.
+
+2008-04-20 Steve White
+ * FreeSerif.sfd:
+
+ Futzing with accents in Latin Extended Additional and Latin Extended-B
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Added primemod character, referenced by Greek number sign
+
+ * FreeMono.sfd, FreeMonoOblique.sfd:
+
+ Following J. Poon's report, disconnected NJ (01CA)
+
+2008-04-19 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ First pass throught J. Poon's bug list.
+ See bug reports for details.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made underscore slanted in Oblique faces, made all to be width of
+ space character.
+ Towards J. Poon's report.
+ Disturbed that xterm and some other apps put small space between
+ characters when none was called for.
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeSans.sfd, FreeSansOblique.sfd:
+
+ Corrections on Currency Symbols
+
+ * FreeMono.sfd, FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More corrections, additions to Currency Symbols
+
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Filled out and corrected Currency Symbols
+
+2008-04-18 Steve White
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Adjustments to Combining Marks for Symbols
+ Additions to range in Sans, and re-structured its marks table so that
+ "middle" can apply to any range
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Made reference between combining koronis and lenis of Greek Extended.
+ In Serif, re-worked combining marks lookup tables, added anchors in
+ Latin, moved so without marks they work in kedit (but now I'm doubting
+ kedit does a reasonable thing...what is a better application for
+ testing this?)
+
+2008-04-16 Steve White
+ * FreeSerifItalic.sfd:
+
+ Adjusting of spacing and accents in Greek
+
+ * FreeMono.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansOblique.sfd, FreeSerif.sfd:
+
+ Much futzing with Greek letter spacing and accents.
+ Added lenis to FreeMono.
+
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Adjusted spacing of dots of Greek dieresistonons in Serif
+ Whipped up something for Greek kappascript in Mono (could use revision)
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Raised dots on double-dotted Cyrillic i, to match that of i and j.
+
+2008-04-14 Steve White
+ * FreeMono.sfd:
+
+ Corrected 27e6-7 "white bracket"
+ Note it is probably a FontForge bug these symbols aren't showing up.
+ FontForge thinks they are in Supplemental Arrows, but they should be
+ in Supplemental Math-A
+
+ Named some Greek characters
+
+ * FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd:
+
+ Spacing of some Cyrillic characters
+
+2008-04-13 Steve White
+ * FreeSerif.sfd:
+
+ Some fiddling with accents
+ 'yogh' was too wide
+
+ * FreeSansBold.sfd, FreeSansOblique.sfd:
+
+ Character spacing was chaos--tried to improve. BoldOblique also needs
+ it.
+
+ * FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd:
+
+ Completed the fix of bug #12798, Greek glyphs with accents to side
+ Much mucking with accents here, and fixed a few things that were just
+ wrong.
+
+2008-04-12 Steve White
+ * FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Made Mono curly quotes "bent"
+
+ * FreeMono.sfd:
+
+ More fiddling with Greek accents
+ Made quotes "bent"
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Adjustments on Greek diaresistonos etc.
+ Adjustments in Serif on combining marks for symbols
+
+ * FreeSerif.sfd:
+
+ More additions to Combining marks for Symbols
+
+ Additions to Combining marks for Symbols -- now mostly full.
+ Lots of adjustments to middle anchor point in Latin to make big circle
+ (nearly) encircle preceding latter
+
+2008-04-11 Steve White
+ * FreeMono.sfd:
+
+ Bugfix:
+ Had indroduce a glyph of width other than 600, making kterminal not
+ recognize it as a monospace font.
+
+2008-04-10 Steve White
+ * FreeSans.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More messing with accents.
+ Further to bug #12798, Greek glyphs with accents to side
+ Much messing with glyphs in Greek Extended range
+
+2008-04-09 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSerif.sfd:
+
+ Revisited Latin-1 and Latin-A accents.
+ Glyph B7 was called "periodcentered", but Unicode callse it Mid Dot,
+ and the description doesn't refer to the period. I made it like the
+ dot accent. throughout, and referred L-dot to it.
+
+ Also double-checked "commaaccent" characters (some in Unicode called
+ cedilla, but the Unicode example shows a comma...mystery)
+
+ Also the funny IPA upside-down f often had two bars, incorrectly.
+
+ To do: go through rest of Serif, and Sans
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Completed re-structuring of stacked Latin accents in Mono.
+ Also: lots of associated adjustments of Greek Extended accents.
+ (Trying to at least center extremely wide characters on their box)
+ Repaired some victems of "find overlaps" sweeps
+ Worked on glyphs with apostrope/comma parts
+ Corrected a few wrong glyphs.
+
+ Trying out a "bent quotes" solution to making primes distinct from
+ quotes.
+
+2008-04-08 Steve White
+ * FreeMonoOblique.sfd:
+
+ Toward reducing overall height
+ Did similar process as for Mono, fixing a few errors along the way.
+ Also the Greek Extended range was very messed up vertical and
+ horizontally.
+ Horizonal spacing of the heavily accented Greek is a real problem in
+ Mono...
+ To do:
+ revisit "commaaccent" characters in all faces: do some have
+ edillas?
+ some Hebrew glyphs are a little low
+ Georgian generally is way out of bounds
+
+2008-04-07 Steve White
+ * INSTALL:
+
+ Various updates and corrections, tweeked formatting
+
+ * FreeMonoBold.sfd:
+
+ Tweeking of accents
+
+2008-04-06 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd:
+
+ Re-worked accents in FreeMonoBold.sfd to make Latin ranges lie between
+ 800 and -200 EM, as with FreeMono.
+
+ * FreeMono.sfd:
+
+ Latin Extended ranges: Implemented new policy of shortening the letters
+ of the characters with the highest-stacked accents.
+
+ At this point all the Latin glyphs lie betweeen 800 and -200 EM.
+
+ Also checked for readability of all the Latin extended letters in xterm.
+ (Issue: it chops letters outside their bounding boxes; many accents had
+ been a bit outside. Made sure that if they were chopped, they were at
+ least still recognizable.)
+
+2008-04-05 Steve White
+ * FreeMono.sfd:
+
+ Following exchange about Mono on freefont-bugs with Joe Wells, who
+ > doesn't like the curly quote marks
+ > wants combining diacritics to work
+ > wants tight line spacing
+
+ Trying to reduce font height:
+ > exclamdown was below -200
+ > Throughout Extended Greek, ypogegrammeni were too low. Shortened
+ glyph, and raised all references.
+ > Lots of messing with Latin Extended ranges to make glyphs mostly
+ fit into 800 height. Mostly succeeded. A couple will get chopped.
+ > Messed with "commaaccent" glyphs, which were very low
+ > Cyrillic 04B1 had a tail that was incorrectly low
+ > Much mucking with Georgian range. Moved up by 95 (read that Georgian
+ is written as though centered between two horizontal lines, rather than
+ as sitting on a baseline) There are still a few very high glyphs.
+
+ FontForge U+0122 called Gcommaaccent, glyph looks like that, but
+ Unicode says it's Gcedilla. Made the ones called cedilla by Unicode
+ to be cedillas
+
+ Note bug in Unicode: standard for 0122, 0123, 0136, 0137, 013B, 013C,
+ 0145, 0146, 0156, 0157 all talk about cedilla, say to make it with
+ cedilla, but example shows comma.
+
+ By the way:
+ > Got rid of commaaccent and dotlessj in Corporate Use
+ > Replaced shadedark, with little squares now not overlapping.
+ > Corrected IPA symbol 'ts' 02A6, added 02a8, 02a9, 02aa, 02ab, 02ac,
+ 02ad, 02ae, 02af
+
+ (so many changes...the CVS server was down...)
+
+ * FreeSerif.sfd:
+
+ Re-named arabic and hebrew characters
+ Big adjustment to comma-accents. Mostly effects Greek Extended.
+ Made such accents to be like comma, rather than like Russian apostrophe
+ (and de-referenced that symbol)
+
+2008-04-04 Steve White
+ * FreeMono.sfd, FreeSerif.sfd:
+
+ Raised dot on superscript i (2071) -- more distinct at small sizes
+
+ * FreeMono.sfd:
+
+ added two IPA symbols
+
+2008-04-02 Steve White
+ * FreeSerif.sfd:
+
+ fixed a few more control points too close
+
+ Fixed names of languages in ligature table for latn "w/i".
+ This fixes a crash when FontForge opened the ttf table
+
+ Motivated by bug crashing FontForge when opening ttf file,
+ started cleanup of useless control points. Not finished.
+ Got partway through Sinhala
+
+2008-03-31 Steve White
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoOblique.sfd, FreeSans.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Fixed various "Find Problems", including glyphs with mixed-up names,
+ and bad TT matrices. (lots more bad TT matrices remain)
+
+ * FreeSerif.sfd:
+
+ Re-named a bunch of Cyrillic letters
+
+ * FreeSerif.sfd:
+
+ Put above mark on Cyrillic i and double-dot i for Slavonic number forms
+
+2008-03-30 Steve White
+ * FreeSans.sfd:
+
+ Tightened spacing on glyphs of last commit
+
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Concerning bug #16120, Include upper case Wynn and upper case Yogh
+ Adapted Herman Miller's Thyromanes letters 01F7 021C 021D for Serif
+ Drew my own versions for Sans.
+
+ * FreeSerif.sfd:
+
+ Added 04F6,7
+
+ * FreeSerif.sfd, FreeSerifItalic.sfd:
+
+ Made more Cyrillic diacritics really combine.
+ Made a mark lookup just for Cyrillic diacritics,
+ Marked most of the unadorned Cyrillic alphabet.
+
+ Still not clear on correct shapes for some of the marks.
+
+ * FreeMono.sfd, FreeMonoOblique.sfd:
+
+ Tweeks to accents
+
+2008-03-29 Steve White
+ * FreeSans.sfd, FreeSerifItalic.sfd:
+
+ Small adjustments in Cyrillic
+
+ * FreeSerif.sfd:
+
+ Corrected small palochka
+ Made Cyrillic combining hundred-thousands and millions really combine
+ Named some combining diacriticals
+
+ * FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd:
+
+ Mostly adjusted horizontal spacing of mono oblique faces
+
+ * FreeMono.sfd, FreeMonoBold.sfd, FreeMonoBoldOblique.sfd, FreeMonoOblique.sfd, FreeSansBold.sfd, FreeSansBoldOblique.sfd, FreeSansOblique.sfd, FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ More cleanup of Cyrillic ranges
+
+ Completely re-did horizontal spacing of SerifItalic and SerifBoldItalic.
+ See bug #17912, poor kerning in Cyrillic oblique...
+ https://savannah.gnu.org/bugs/index.php?17912
+ It looked like chaos to me.
+ Only so much can be done: the font is flawed.
+ But I think the changes make text readable in these faces.
+
+ There were dozens of incorrect glyphs in higher-numbered characters.
+ I deleted all those I found. No glyph is better than a wrong glyph.
+
+ Futzt with accents, shooting for consistency and readability.
+
+ A maintenance thing: making correct references (acyrillic vs a,
+ although they may be the same glyph) I made a lot of headway, but
+ it isn't finished.
+
+ Likewise, a large fraction of these are compound characters, which can
+ be made with references, resulting in easier maintenance, reduced
+ likelihood of errors, and smaller files. I replaced many.
+
+ * FreeSerif.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Cyrillic italic
+ Added italic, bolditalic
+ 0493, 04a7, 04AD
+ because their form clearly varies in italic. But was just guessing...
+
+ * FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Cyrillic italic
+
+ Added italic, bolditalic
+ 0493, 04AD
+ because their form clearly varies in italic.
+ But was just guessing as to exact form.
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Overhaul of Cyrillic
+
+ Italic, BoldItalic
+ added small yat for bug #22588 (note Times New Roman doesn't use
+ alternate form in Italic)
+
+ All forms of Serif have big problems in Cyrillic.
+
+ The ugliest is in roman. The letters, even of the Russian alphabet, are
+ of inconsistent height (awfully, small 0438 (ii) 0446 (tse))
+ and they vary from the height of Latin
+ and they vary from the height of italic and bold.
+ They are a mish-mash of letters from several fonts, of similar (but not
+ quite identical) weight, and similar, (but not quite identical) size.
+
+ I think the best solution would be to identify the face that best
+ matches Latin, and fill the range with that. I think this is possible
+ because the rarer letters seem to be better: the common letters are the
+ ones that are wrong.
+
+ For now, I just increased the sized of 0438 and 0446, and 048a, 048b,
+ also 0459 (lje) 045A (nje) 0464 (dje)
+
+ Other issues
+
+2008-03-27 Steve White
+ * FreeSerifBoldItalic.sfd:
+
+ Moving all Greek capitals with accent so they don't cover previous
+ letter. Remedies bug #12798
+
+ * FreeSerif.sfd, FreeSerifBold.sfd, FreeSerifBoldItalic.sfd, FreeSerifItalic.sfd:
+
+ Various tweeks to accented Latin letters.
+ Connected O-ogonek correctly
+
+ * FreeSerifItalic.sfd:
+
+ Accents of numerous accented Latin letters got shifted in a previous
+ commit. This fixes it.
+
+ * FreeSerif.sfd:
+
+ Adjusted combining tack left and right (0318-0319) to be above -300 EM.
+
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Added some "middle" marks for positioning of diacritics
+
+ * FreeSans.sfd:
+
+ Copied 4 enclosing combining diacriticals from Serif 20DD - 20E0
+
+ * FreeSerif.sfd:
+
+ Adjusted and added some enclosing diacritics 20DD - 20E0
+ In response to Debian bug #472566
+ ttf-freefont: U+20DD COMBINING ENCOLSING CIRCLE doesn't combine
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=472566
+
+2008-03-26 Steve White
+ * FreeSerif.sfd:
+
+ Lowered a few over-high Latin accents
+
+ * FreeSansBold:
+
+ Devangari--only digits 1 and 2, and nothing else. Deleted
+
+ * FreeMonoBold, FreeMonoOblique,
+ FreeSerifBold, FreeSeriftalic, FreeSerifBoldItalic,
+ FreeSansOblique, FreeSansBold, FreeSansBoldOblique:
+
+ Got rid of dotlessj, comma in Corporate Use
+ Single Substitution lookup, ccmp table
+ Made proper dotlessj, re-linked j-circumflex
+
+ Note:
+ FreeSansBold has a commaaccent in Corporate Use, used by several other
+ characers. Haven't done anything about this.
+
+2008-03-25 Steve White
+ * FreeSerif.sfd:
+
+ Added/corrected glyphs for yeh hamza in Arabic,
+ Added init and medi lookups for yeh hamza.
+
+2008-03-24 Steve White
+ * FreeSerif.sfd:
+
+ Added isolated and final forms for
+ 0629 teh marbuta
+ 0624 waw hamza
+ 0626 yeh hamza
+ 0649 alef maksura
+ A previous commit had added lookups that referred to these,
+
+ More fiddling with super/subscripts
+
+ * Makefile, Makefile, GenerateTrueType:
+
+ Scripts and Make targets to generate OpenType fonts and zip file
+
+ * maintenance.txt:
+
+ Added gnupload and info about tagging
+
+2008-03-23 Steve White
+ * FreeSerif.sfd:
+
+ Last of Find Problems -> ATT
+ 'mark' Latin lookup: afii10026 is in 'cyrl', also afii10074
+ Upper and lower Cyrillic i. Just removed mark from both letters.
+
+ 'half' Bengali lookup Khanda_Ta is in 'bng2'. Added bng2 to lookup
+ Added TtTable etc
+
+ Clean-up of Points too Close through to end of font.
+ This episode completes the paths/points clean-up of Serif.
+ But note: many ranges, esp. Ethiopic, Japanese, and Indic, have way
+ too many points, resulting in lumpiness.
+
+ At this point, FontForge can convert splines to quadratic, auto-hint,
+ and auto-instrument without segfault.
+
+ * Makefile, sfd/Makefile, tools/GenerateTrueType:
+
+ Alterations to build process: added a Makefile, and made to work
+ on my system. Now auto-hints before generating TrueType.
+
+2008-03-22 Steve White
+ * sfd/FreeSans.sfd:
+ Lots of additions of math characters. Should complete for
+ LaTeX 2e, except for extensible brackets.
+
+2008-03-21 Steve White
+ * *.sfd:
+
+ Regularized stacking of accents in Latin Extended Additional
+ Changed name of 00B5 from 'mu' to 'micro',
+ 2206 from 'Delta' to 'Delta.math',
+ 0308 from 'diaerisis' to 'diaerisiscomb'
+
+ * FreeMono.sfd:
+
+ additions to IPA
+
+ * FreeMonoBoldOblique.sfd:
+
+ Moved dotlessj from Corporate Use,
+ Deleted commaaccent there
+ Fixed mis-named glyphs tcommaaccent, Tcommaaccent
+ Changed name of 030A from 'dieresis' to 'ringcomb'
+
+ * FreeSans.sfd:
+
+ Added some arrows, and a couple of blackboard bold characters
+
+ Several characters in U+F600 Corporate Use range
+ dotlessj, onefitted, commaaccent
+
+ dotlessj referred to by: jcircumflex, uni01F0:
+ renamed it to uFFFF, re-linked others by hand
+
+ commaaccent
+ http://diacritics.typo.cz/index.php?id=9
+ should be u+0326 but wasn't linked to anything
+
+ * FreeSansBold.sfd:
+
+ U+0617 etc: read glyphs "4GWglm". It should be Arabic. Deleted
+
+ * FreeSansBold.sfd, FreeSansOblique.sfd, FreeSansBoldOblique.sfd:
+
+ Removed bogus glyphs for 200C 200D, ZWJ and ZWNJ
+
+ * FreeSerif.sfd:
+
+ Split lookup for ligatures in latin into two classes;
+ ff, ffl, fl which are appropriate for all languages,
+ and fi, ffi, which are not appropriate in Turkish (due to distinction
+ between short and long i)
+ Needs to be done for other faces.
+
+ Filled set of extensible brackets in Miscellaneous Technical
+
+ Think IPA is now complete.
+
+2008-03-18 Steve White
+ * FreeSans.sfd:
+
+ clean-up of all path issues and points too close
+
+2008-03-18 Steve White
+ * FreeSans.sfd:
+
+ Something was causing crashing effects in Windows. Cleanup of
+ problems eventually made it go away. Now works well.
+
+ Cleaned up many "points too close"
+
+ Cleaned up all ATT problems, of which there were many and various.
+
+ # Incorrectly labelled zero-width joiner used in a ligature
+
+ # Incorrect substitution of dotlessi and dotlessj with i and j was
+ somehow connected with FontForge crash. Attemts to remove the
+ substitution would damage a 'ccmp' table; subsequent changes would
+ result in FontForge crashing on save, and truncating the sfd file.
+ Surgically removed with vi.
+
+ # A couple of Indic lookups had incorrect script DFLT; one had 'latn'.
+
+ # Don't understand why there are scripts named
+ dev2 bng2 grj2 gur2 when there are already deva beng gurj guru
+ But anyway, lots of 'vatu' 'pres' 'haln' and 'liga' lookups contained
+ characters in the '2' scripts but were lablled only for the 'non-2'
+ ones. Added the '2' scripts to all these lookups. Suspect a mistake.
+
+ Note: several of these problems are repeated in other Sans faces.
+
+2008-03-16 Steve White
+ * FreeMono.sfd:
+
+ Cleanup of many path problems "points too close"
+
+ Strove to make accents Latin Extended range legible at small sizes
+
+ Named some unnamed characters; removed a duplicate
+
+ At this point, all fonts are passing FontForge Validate.
+
+2008-03-15 Steve White
+ * FreeSerif.sfd:
+
+ CJK punctuation: made some of the very high glyphs smaller (under 900EM)
+ The brackets in Sans were very ugly, and not even Sans-serif.
+ Serif: added extensible square brackets, diddled with integral
+ corrected direction of some added glyphs
+
+ Several bugs having to do with missing glyphs in Tamil range.
+ Also a buggy ligature in Devangari.
+
+ Shortened names of many lookup tables
+
+ Futzt with some combining diacriticals
+
+ Added extensible square brackets.
+
+ * FreeSans.sfd:
+
+ Changed names of a bunch of glyphs with invalid
+ TrueType names, in range 0x1025f+ (not real Unicode).
+ Took pains to retain information contained in the names.
+ Wonder if these glyphs have ever been of any use.
+
+ CJK Punctuation: brackets were hand-drawn and very ugly. Improved.
+
+ * *.sfd:
+
+ Set OS/2 Metrics back to absolute 900/300. Offsets are not
+ interpreted uniformly.
+
+ Cleanup of many path problems up to extrema and self-intersecting
+
+ Ordered PS Blue values.
+
+2008-03-14 Steve White
+ * FreeSerif.sfd:
+
+ Got rid of mixed references and contours
+ Cleanup of many path problems "points too close"
+
+ Started clean-up to satisfy FontForge Validate
+
+ Changed names of three glyphs in the
+ Tamil ligatures range...all clearly bugs.
+
+ * FreeSans.sfd:
+
+ Added slanted-hyphen
+
+ * *.sfd:
+
+ Unified OS/2 Metrics
+ Added Grid Fit
+
+2008-03-13 Steve White
+ * FreeSans.sfd:
+
+ Rearranged PS BluesValues so they were in increasing order,
+ Made all 20 in width.
+
+2008-03-12 Steve White
+ * FreeSans.sfd, FreeMono.sfd:
+
+ Added TrueType hinting tables.
+ Fixed glyphs that didn't convert well to quadratics
+ Got rid of mixed contours and refs
+
+ * FreeSerifBold.sfd:
+
+ Cleanup of path problems
+
+2008-03-11 Steve White
+ * FreeMonoOblique.sfd:
+
+ Cleanup of path problems
+
+2008-03-09 Steve White
+ * FreeSerif.sfd:
+
+ Corrected L-dot
+ Further cleanup of path/ref problems
+
+ Found several ligatures that referred to a missing glyph "ZWJ".
+ Took this to mean the "zero width joiner" u+200D
+
+ * *.sfd:
+
+ Changed OS/2 metrics to be absolute 900/300
+
+ * FreeSerifItalic.sfd:
+
+ Added Greek lunate epsilon
+
+ * FreeMono.sfd:
+
+ Many additions in math range
+ Reduced size of binary union, intersection, vee, wedge
+ Corrected empty set
+ Corrected logical 'assert' relations, etc. 22a2-22af
+ Efforts to make Math glyphs legible at small point sizes
+
+ * FreeSans.sfd:
+
+ Added Greek lunate epsilon and rho symbol
+ Unstacked more stacked diacriticals
+
+ Further cleanup of path/reference problems
+
+2008-03-08 Steve White
+ * FreeSans.sfd, FreeSerif.sfd:
+
+ Added some "n-ary" Math operators
+
+ * FreeSerif.sfd:
+
+ Further clean-up of path problems...up to Ethiopic
+ > Started adding and correcting Math operators for LaTeX 2e
+ > Corrected n-ary union, intersection, and spikes to be larger
+ than the binary operators
+ > Made (many of) the operators based on + - = to use those
+ symbols directly (by reference or copying).
+ > Added lunate epsilon
+ > Corrected empty set
+ > Tightened up spacing of some other technical characters
+ > Worked on some more math operators involving =
+ > triangle
+ > Several arrows
+ > Supplemental Arrows-A
+
+ * FreeSans.sfd:
+
+ Clean-up of font paths
+ Open self-intersecting outermost-clockwise missing-extrema
+ also flipped references (unlinked)
+
+ Added Greek lunate epsilon and rho symbol
+
+2008-03-06 Steve White
+ * sfd/FreeSerif.sfd: Shortened and thickened the combining hook mark,
+ U+0309, to make more like Unicode samples.
+ Also see (bug #22499) un-stacked incorrectly stacked accents
+
+2008-03-05 Steve White
+ * sfd/FreeSerif.sfd: vertical lines: combining diacritical marks
+ corrected 0300 030D 0329 0348 (were rendered as straight apostrophes)
+ Spacing Modifier letters added 02C8 02CC
+ 02B9 02Ba prime and double-prime
+ Fixed positioning U+1EC8, 9, I with hook above
+
+2008-03-03 Steve White
+ * sfd/FreeSerif.sfd: TT strings updates.
+ updated Copyright to 2008
+ Added Vendor URL as the Savannah freefont site
+ * sfd/FreeMono.sfd: A standard pangram as the Sample Text for Russian
+ It reads: In the thickets of the South once there was a citrus
+ ...--yes, but a fake specimen!
+ * sfd/*.sfd: Set the OS/2 Sup/Sub settings, which by default looked
+ like random trash.
+
+2008-03-02 Steve White
+ * sfd/FreeSerif.sfd: began cleanup of problems given by FontForge
+ "Find Problems" feature. (bug #22454)
+
+2008-03-01 Steve White
+ * sfd/FreeSerif.sfd: made Arabic work for text display (bug #22329)
+ Added required contextual replacement tables,
+ Made a few missing characters,
+ * sfd/*.sfd: Removde all back layers from glyphs that had them.
+
+2008-02-27 Steve White
+ * sfd/FreeSans.sfd: filled in Combining Diacriticals
+ * sfd/FreeSerif.sfd: shifted whole Arabic range down by 200EM.
+
+2008-02-26 Steve White
+ * sfd/FreeSerif.sfd: enabled DPOS table.
+
+2008-02-24 Steve White
+ * sfd/*.sfd: Much fiddling with the "combining diacriticals"
+ range 0300-036F. Made to align with medium-size lowercase
+ preceding character if not using DPOS table.
+
+2008-02-23 Steve White
+ * sfd/FreeSerif.sfd, FreeSans.sfd, FreeMono.sfd: (bug #21784) Filled
+ in set of HTML 4 Character Entities.
+
+ * sfd/FreeSerif.sfd, FreeSans.sfd, FreeMono.sfd: (bug #18413)
+ undertie too low -- went on to tidy other similar characters in
+ Combining Diacriticals range.
+
+2008-02-21 Steve White
+ * sfd/*.sfd: Moved capital Greek letters with tonos so tonos doesn't
+ cover preceding letter (bug #12798)
+
+ * sfd/FreeSerif.sfd, FreeSans.sfd: (bug #13370) made extended
+ integrals to line up.
+
+2008-02-20 Steve White
+ * sfd/*.sfd: started removing glyphs with back layers (printing bug)
+ * sfd/*.sfd: adjusted vulgar fractions (bug #17756)
+ * sfd/*.sfd: adjusted numerical superscripts (bug #20278)
+
+2008-02-18 Steve White
+ * sfd/FreeSerif.sfd: Offset Hiragana and Katakana ranges (bug #22326)
+ * sfd/FreeSerif.sfd: U+30FB, KATAKANA MIDDLE DOT to be full width
+ (bug #18326)
+
+ * sfd/FreeSerif.sfd: Re-promoted
+ ff ffi ffl fi fl
+ as standard ligatures in Latin.
+
+2008-02-17 Steve White
+ * sfd/*.sfd: committed to FontForge Spline Font Database (SFD) 2
+ format.
+
+2008-02-10 Steve White
+ * sfd/*.sfd: brought into line with Debian ttf-freefont
+ Deleted a couple of patches, and applied those applied to Debian.
+
+2006-09-20 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * INSTALL: added installation procedure for MacOS X, courtesy
+ Philipp Kempgen.
+
+2006-05-04 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd: deleted Russian sample text, which did not
+ conform to UTF-7.
+
+2006-04-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: corrected U+10D3.
+
+ * sfd/FreeSans.sfd: ligature U+FB06 (LATIN SMALL LIGATURE S T)
+ changed from mandatory ("liga") to discretionary ("dlig") (bug
+ #16253).
+
+ * sfd/FreeMono.sfd: deleted incomplete glyph U+FB06 (LATIN SMALL
+ LIGATURE S T); deleted U+FB00, U+FB01, U+FB02, U+FB05 as
+ ligatures (bug #16253).
+
+ * sfd/FreeMonoOblique.sfd, sfd/FreeMonoBoldOblique.sfd: added
+ U+FB00; deleted U+FB01, U+FB02 as ligatures (bug #16253).
+
+ * sfd/FreeMonoBold.sfd: deleted U+FB00, U+FB01, U+FB02 as
+ ligatures (bug #16253).
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd: added Georgian letters, donated by
+ Gia Shervashidze
+
+2006-02-22 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd: ligature U+FB4F
+ changed from mandatory ("liga") to discretionary ("dlig"). This is
+ respons to Bug#349657: [bug #15792] Freefont Alef and Lamed
+ combine
+
+2006-02-21 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBoldOblique.sfd,
+ sfd/FreeSansBold.sfd: ligature U+FB4F changed from mandatory
+ ("liga") to discretionary ("dlig"). This is respons to Bug#349657:
+ [bug #15792] Freefont Alef and Lamed combine
+
+ * sfd/FreeSerif.sfd: corrected bug#275759: [bug #15790] FreeSerif
+ glyphs for U+2198/U+2199 were reversed.
+
+2006-02-15 Denis Jacquerye <moyogo@gmail.com>
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeMonoBold.sfd: removed ij
+ and IJ ligatures.
+
+2006-02-10 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: added small Georgian letters (mkhedruli),
+ donated by Gia Shervashidze
+
+ * AUTHORS: Added Gia Shervashidze
+
+ * CREDITS: Added Gia Shervashidze
+
+2006-01-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * notes/maintenance.txt: Added information on the Makefile now
+ used; username for FTP login is anonymous.
+
+ * sfd/FreeSansBold.sfd: added U+0569, U+0571, U+0579, U+057B,
+ U+0586. Armenian small letters completed.
+
+ * sfd/FreeSerif.sfd: added U+0297, U+02AD-02AF. IPA Extensions
+ section is now complete. Copied a dozen of glyphs from Omega IPA
+ to Phonetic Extension section.
+
+2006-01-25 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+01A, U+01A3, U+01A6, U+01B2, U+01BA,
+ U+01BB, U+01BE, U+01BF.
+
+ * sfd/FreeSans.sfd: aligned small Armenian letters to x-height in
+ response to bug #15480. Armenian in Free Sans needs a major
+ cleanup.
+
+2006-01-24 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: changed U+0452, U+045B. Cleanup: U+0460,
+ U+0461, U+04Bc, U+04BD, U+0508.
+
+ * sfd/FreeSansOblique.sfd: replaced accented chars in Latin-1 and
+ Latin Extended-B sections with references, where possible.
+
+ * sfd/FreeSerif.sfd: changed U+0285.
+
+2006-01-23 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+0195, U+01AA, U+0297, U+03D7,
+ U+03F0. Several flipped references replaced by outlines.
+
+ * sfd/FreeSansOblique.sfd: Latin Extended-B section more or less
+ brought in sync with FreeSans.
+
+ * sfd/FreeMonoBoldOblique.sfd: added glyphs from FreeMonoBold in
+ the Latin Extended-B and IPA Extensions sections.
+
+ * sfd/FreeSerifBold.sfd: Added U+0224, U+0225. Changed U+01B7,
+ U+01B8, U+04E0, U+0452, U+045B. Replaced accented characters in
+ the Cyrillic region with references.
+
+2006-01-21 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+0255, U+0264, U+0277, U+0286,
+ U+029D. Changed U+0261. Deleted spurious glyphs in the control
+ code area.
+
+2006-01-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: replaced Hardip Pannu Singh's Gurmukhi with
+ AnmolUni by Kulbir Singh Thind.
+
+2006-01-17 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd: Added U+018D, U+0194, U+01B5, U+01B6,
+ U+01BE, U+0262, U+02A2.
+
+ * sfd/FreeSansBold.sfd: Changed U+0261 in order to distinguish it
+ from U+0067. Changed U+0251, U+0252.
+
+ * sfd/FreeSerifBold.sfd: Small changes in the Cyrillic
+ section. Added U+0183, U+018C.
+
+ * sfd/FreeSans.sfd: Added U+2045, U+2046.
+
+ * sfd/FreeSansBold.sfd: Filled in the Gurkmukhi part with the
+ AnmolUni-Bold by Kulbir Singh Thind. Also some minor corrections
+ in the Cyrillic part.
+
+ * CREDITS: Added Kulbir Singh Thind.
+
+ * AUTHORS: Added Kulbir Singh Thind.
+
+2006-01-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: Thomas Ridgeway's Tamil characters replaced
+ by the ones released by the Samyak font project.
+
+ * CREDITS: Added Pravin Satpute, Bageshri Salvi, Rahul Bhalerao
+ and Sandeep Shedmake
+
+ * AUTHORS: Added Pravin Satpute, Bageshri Salvi, Rahul Bhalerao
+ and Sandeep Shedmake
+
+2006-01-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd, sfd/FreeMonoBoldOblique.sfd: minor changes.
+
+2006-01-05 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd: added cedi sign U+20B5, Ghanaian
+ currency
+
+2005-12-29 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: minor cleanup in the Gujarati part.
+
+2005-12-22 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: Devanagari and Gujarati parts cleared; once
+ again merged with Gargi 1.9 and Padmaa 0.6, this time correctly so
+ that the anchor points survived the merger.
+
+2005-12-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+0577.
+
+2005-12-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+0559, U+055F, U+2024.
+
+ * sfd/FreeSansBold.sfd: added U+056E, U+0573.
+
+2005-12-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: Merged with Gargi 1.9 and Padmaa 0.6,
+ courtesy Monika Shah and Sonali Sonania from C-DAC, Mumbai.
+
+ * CREDITS: Added Monika Shah and Sonali Sonania.
+
+ * AUTHORS: Added Monika Shah and Sonali Sonania.
+
+2005-12-13 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Removed Sinhala glyphs.
+
+ * sfd/FreeSerif.sfd - Added Sinhala glyphs, formerly in FreeSans.
+
+2005-12-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: added U+20AF, U+211E. Changed U+20AC (EURO
+ SIGN).
+
+ * tools/freefont-ttf.spec: Added specification file for building
+ RPM package, courtesy Rok Papez.
+
+ * sfd/FreeSerifBold.sfd: added more glyphs from Txfonts to the
+ Arrows and Mathematical Symbols ranges.
+
+ * sfd/FreeSerifBoldItalic.sfd: added U+03F5 from Txfonts.
+
+2005-12-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: added U+0567, U+056A, U+056C, U+0582.
+
+ * sfd/FreeSerifBold.sfd: copied Box Drawing range from FreeSans.
+
+ * sfd/FreeSerifBold.sfd: added glyphs from Txfonts to the Arrows
+ and Mathematical Symbols ranges.
+
+ * sfd/FreeSerif.sfd: added U+2259-225A, U+22BA, U+2308-230B,
+ U+2322-2323. Cyrillic composite characters replaced with
+ references.
+
+2005-12-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd: added U+025A, U+025D, U+026B, U+029B,
+ U+02AE, U+02AF, U+02DE.
+
+ * sfd/FreeSerifBold.sfd: updated Hebrew part with Drugulin font
+ from the Culmus project.
+
+ * sfd/FreeSerif.sfd: added U+207A-207C, U+208A-208C, U+2215-2216.
+
+ * sfd/FreeSans.sfd: added U+2320 TOP HALF INTEGRAL, U+23AE
+ INTEGRAL EXTENSION, U+2321 BOTTOM HALF INTEGRAL (bug #13370).
+
+2005-12-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd: added U+0294-0296, U+02A1-02A2. Started
+ adding "below" anchors. Performed hinting on characters that were
+ not hinted "en masse".
+
+2005-12-06 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: fixed some more metrics problems in the
+ Extended Greek area; performed hinting on characters that were not
+ hinted "en masse".
+
+ * Makefile: clean also signature files.
+
+ * sfd/FreeMonoBoldOblique.sfd, sfd/FreeMonoBold.sfd: cosmetic
+ changes; cleaning background of referenced composed characters.
+
+2005-12-05 Panayotis Katsaloulis <panayotis@panayotis.com>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd: Some changes to the greek glyphs,
+ mostly having to do with "tonos" (accent)
+
+2005-12-05 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: minor cosmetic changes.
+
+ * sfd/FreeSans.sfd: adjusted widths of characters in the Extended
+ Greek range; accents are not any more considerably overhanging on
+ the left side. Added U+1EDA-1EE3, U+1EE8-1EF1.
+
+ * sfd/FreeSans.sfd: continued working on Extended Greek range;
+ metrics still not finished.
+
+2005-12-03 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd: fixed combined Greek accents (bug
+ #12800). Width of characters still need to be adjusted as in
+ FreeSerif.
+
+ * sfd/FreeSerif.sfd: fixed positions of Greek accents (bug #12798).
+
+ * CREDITS: Added Panayotis Katsaloulis.
+
+ * AUTHORS: Added Panayotis Katsaloulis.
+
+ * Makefile: minor changes; now creating also a tarfile with sfds.
+
+2005-12-01 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifItalic.sfd: added U+0183, U+018C, U+01C0, U+01C1,
+ U+01C3, U+01E0, U+01E1, U+01F8, U+01F9.
+
+ * Makefile: created a Makefile to assist building.
+
+ * README: an update.
+
+ * COPYING: added GNU General Public License, version 2.
+
+ * tools/GenerateTrueType: wrote a FontForge script for conversion
+ to TrueType.
+
+ * sfd/FreeSerif.sfd: merged with SolaimanLipi Bangla OpenType font
+ from www.ekushey.org, courtesy Solaiman Karim.
+
+ * sfd/FreeSerifItalic.sfd: merged with SolaimanLipi Bangla
+ OpenType font from www.ekushey.org, slanted by 15.5 degrees.
+
+ * sfd/FreeSans.sfd: merged with Rupali Bangla OpenType font from
+ www.ekushey.org
+
+ * sfd/FreeSansOblique.sfd: merged with Rupali Bangla OpenType font from
+ www.ekushey.org, slanted by 12 degrees.
+
+ * CREDITS: added Solaiman Karim
+
+ * AUTHORS: added Solaiman Karim
+
+2005-11-30 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd: merged with the Rachana Normal.
+
+ * AUTHORS: added K.H. Hussain and R. Chitrajan
+
+ * CREDITS: added K.H. Hussain and R. Chitrajan
+
+2005-11-23 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - cleaned some background images.
+
+ * sfd/FreeSans.sfd - added U+01A0-01A1, U+01AF-01B0, U+026E,
+ U+028F, U+0291, U+02A3-02A5, U+031B. Modified U+0198.
+
+2005-11-22 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added U+2504-250B.
+
+ * sfd/FreeSans.sfd - added U+2591-25A1, U+25A3-25A5, U+25AA, U+25AC.
+
+ * sfd/FreeSans.sfd, sfd/FreeSansBold.sfd - added U+0263.
+
+2005-11-21 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - corrected positions of some Greek diacritics
+ on page 0x1F.
+
+ * sfd/FreeMonoOblique.sfd - working on bringing it in sync with
+ FreeMono.sfd.
+
+ * sfd/FreeSerifBoldItalic.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points. Added a couple of
+ glyphs in the IPA Extensions region.
+
+ * sfd/FreeSansBold.sfd - added U+0574, U+0576. Removed overlaps.
+
+2005-11-20 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - added U+02AA-02AC, U+02B0-02B2.
+
+2005-11-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added U+01B7-01B9, U+0196, U+019A, U+01C3,
+ U+0224-0225, U+025E, U+029A, U+2422. Changed U+0184-0185, U+0192,
+ U+01B4, U+0282, U+0284.
+
+2005-11-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - added U+02EE, U+207F.
+
+ * sfd/FreeSans.sfd - started Box Drawing area.
+
+2005-11-17 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd - added glyphs from the Omega project to
+ Latin Extended-B, IPA Extensions and Greek ranges.
+
+ * sfd/FreeSerifBoldItalic.sfd - added glyphs from the Omega
+ project to Latin Extended-B, IPA Extensions and Greek ranges.
+
+ * sfd/FreeSerifItalic.sfd - added glyphs from the Omega
+ project to Latin Extended-B, IPA Extensions and Greek ranges.
+
+ * sfd/FreeSerifItalic.sfd - added U+018B, U+025C, U+0265, U+026F,
+ U+0279, U+0287, U+028C-028E, U+029E.
+
+ * sfd/FreeSerifBoldItalic.sfd - added U+1EDA-1EE3, U+1EE8-1EF1,
+ U+2190-219B, U+219E-21A8, U+21B9-21BA, U+21C4-21CA, U+21E4-21E5,
+ U+2669-266F. MES-1 compliant.
+
+ * sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSansOblique.sfd,
+ sfd/FreeSansBold.sfd, sfd/FreeSansBoldOblique.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - added U+FFFD.
+
+ * sfd/FreeSerif.sfd - removed overlaps in Latin Extended-B and IPA
+ Extensions ranges.
+
+2005-11-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifItalic.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points.
+
+ * sfd/papers/eurotex2003/freefont.tex,
+ sfd/papers/eurotex2003/freefont.bib - Revised version, sent back
+ by Karl Berry on 20050110, that should match the one published in
+ TUGboat.
+
+ * sfd/FreeSerifItalic.sfd - started added accent anchors. Added a
+ handful of Greek letters from Omega font collection.
+
+ * sfd/FreeSerif.sfd - added a handful of letters in the Latin
+ Extended-B and IPA Extension ranges from the Omega font collection.
+
+2005-11-16 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSerif.sfd - moved U+0263 to U+0264; added U+0263
+
+ * sfd/FreeSerifItalic.sfd - fixe U+01EE; added U+01B7-U+01B9
+
+2005-11-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Made small Greek letters the same height as
+ Latin and Cyrillic ones and replaced them with references, where
+ applicable.
+
+ * sfd/FreeSerif.sfd - replaced Greek letters with references,
+ where applicable. Added U+03D7, U+03F0-03F2.
+
+ * sfd/FreeSerif.sfd - added U+0255, U+025A, U+025D, U+025F,
+ U+0262-0263, U+026B-026C, U+0274, U+0276-0277, U+028F, U+0291,
+ U+029D.
+
+ * sfd/FreeMonoOblique.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points. Added U+F6BE.
+
+ * sfd/FreeSansOblique.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points.
+
+ * sfd/FreeSans.sfd - changed U+01A5.
+
+2005-11-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - applied the sequence suggested by Werner
+ Lemberg for reducing redundant points. Replaced accented glyphs in
+ the Latin-1 and Latin Extended-A areas with references. Made
+ capital Greek letters the same height as Latin and Cyrillic ones
+ and replaced them with references, where applicable.
+
+2005-11-15 Denis Jacquerye <moyog@gmail.com>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSansOblique.sfd - fixed
+ U+026A, it was a dotlessi and therefore like U+0069 when
+ accented.
+
+2005-11-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoBold.sfd - corrected Greek tonos (slanted instead of
+ a vertical line).
+
+ * sfd/FreeMonoBoldOblique.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points. Replaced accented
+ glyphs in the Latin-1 and Latin Extended-A areas with references.
+
+2005-11-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - Added 2005 in copyright info.
+
+ * sfd/FreeSansBoldOblique.sfd - applied the sequence suggested by
+ Werner Lemberg for reducing redundant points. Replaced accented
+ glyphs in the Latin-1 area with references.
+
+ * sfd/FreeSansBoldOblique.sfd - added U+0180, U+0184, U+0185,
+ U+0195, U+01A0-01A2, U+01AF-01B0, U+025E, U+026E, U+0292,
+ U+0294-0296, U+029A, U+02A1, U+2126-2127, U+2190-219B,
+ U+219E-21A8, U+21C4-21CA, U+2669-266F. MES-1 compliant.
+
+ * sfd/FreeMono.sfd - Replaced accented glyphs in the Greek and
+ Cyrillic areas with references.
+
+ * sfd/FreeMonoBold.sfd - applied the sequence suggested by Werner
+ Lemberg for reducing redundant points. Replaced accented glyphs in
+ the Latin-1 and Latin Extended-A areas with references.
+
+2005-11-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - applied the sequence suggested by Werner
+ Lemberg for reducing redundant points.
+
+ * sfd/FreeSansBold.sfd - added U+219A, U+219B, U+2669-266F.
+
+ * sfd/FreeSerifBold.sfd - added U+2669-266F.
+
+2005-11-12 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - added U+0180, U+0181, U+0183, U+0187,
+ U+0188, U+018A, U+018C, U+018D, U+0193, U+019C, U+01A0, U+01A1,
+ U+01AC, U+01AF, U+01B0, U+025C, U+0260, U+026E, U+0277, U+0281,
+ U+0284.
+
+2005-11-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - added U+195, U+1A6, U+025E, U+026E,
+ U+029A, U+0313, U+0314, U+0342, U+0344, U+0345. Started adding
+ accent anchors.
+
+ * sfd/FreeMono.sfd - applied the sequence for reducing redundant
+ points, suggested by Werner Lemberg.
+
+ * sfd/FreeMono.sfd - corrected Greek letters (using tonos instead
+ of a vertical line). Added U+026E, U+F6BE. Accented characters in
+ Latin 1, Latin Extended A and partly Latin Extended B replaced by
+ references.
+
+ * sfd/FreeSerifBold.sfd - applied the sequence for reducing
+ redundant points, suggested by Werner Lemberg. Added U+01A5,
+ U+02A0, U+2190-219B, U+219E-21A8, U+21B8, U+21B9, U+21C4-21CA,
+ U+21E4, U+21E5.
+
+2005-11-10 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansOblique - changed U+0192, U+01A5; added U+01C0-01C3.
+
+ * sfd/FreeSansBold.sfd - replaced glyphs with references in the
+ Cyrillic area. Removed U+04A8, U+04A9. Added U+04C5, U+04C6,
+ U+04C9, U+04CA, U+04CD, U+04CE, U+0535, U+053F, U+0546, U+0565,
+ U+0584, U+0587, U+0589.
+
+2005-11-10 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSans.sfd - added U+028A-U+028B
+
+ * sfd/FreeSansOblique - added U+028A-U+028B, U+0276,
+ U+0292, U+0294-U+0296, U+0298-U+0299 and U+029B; fixed some
+ other glyphs
+
+2005-11-10 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - added U+01A6. Simplified outlines in the
+ ASCII range.
+
+ * sfd/FreeSansBold.sfd - added U+00A0, U+00AD, U+0531, U+2126,
+ U+2190-2199, U+219E-21A8, U+21C4-21CA.
+
+ * sfd/FreeSansBold.sfd - applied the sequence for reducing
+ redundant points, suggested by Werner Lemberg. Added automatically
+ constructed accented characters in page 0x1E.
+
+2005-11-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - added U+0183, U+018C.
+
+ * sfd/FreeSans.sfd - added U+1EA2, U+1EA3, U+1EA8, U+1EA9, U+1EB2,
+ U+1EB3, U+1EBA, U+1EBB, U+1EC2, U+1EC3, U+1EC8, U+1EC9, U+1ECE,
+ U+1ECF, U+1ED4, U+1ED5, U+1EE6, U+1EE7, U+1EF6, U+1EF7, U+220A,
+ U+220B, U+220D, U+2272, U+2273, U+2282, U+2283.
+
+ * sfd/FreeSerifItalic.sfd - changed U+03D5.
+
+ * sfd/FreeSerifBoldItalic.sfd - changed U+03C6; added U+2070,
+ U+2075-2079, U+207F, U+2080, U+2085-2089, U+2155-217F.
+
+ * sfd/FreeSerif.sfd - added U+0184, U+0185, U+018D, U+0195,
+ U+0197, U+019A, U+019B, U+01A0, U+01A1, U+01AC, U+01B5, U+01B6,
+ U+01C0, U+01C1, U+01C3, U+01F6, U+0294-0296, U+1E9A, U+1EDA-1EE3,
+ U+1EE8-1EF1.
+
+2005-11-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - added U+0562, U+056D. U+0575.
+
+ * sfd/FreeMono.sfd - added U+0589.
+
+2005-11-06 Primoz Peterlin <peterlin@localhost.localdomain>
+
+ * sfd/FreeSans.sfd - added U+0278, U+03D5, U+2248. Corrected
+ U+2071, U+222E, U+2242, U+2243 in response to bug reports
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=276118
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=276120
+
+ * sfd/FreeMono.sfd - added U+2227, U+2228, U+2262. Corrected
+ U+2299-229D in response to bug report
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=276121
+
+ * sfd/FreeMonoBold.sfd - added U+2010, U+2012 in response to bug
+ report http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=289032
+ Swapped U+03C6 (Greek small letter phi) and U+03D5 (Greek phi
+ symbol) in order to conform to Unicode standard. Simplified glyph
+ shapes in ASCII range. Started adding "above" and "below" anchors.
+
+2005-11-05 Primoz Peterlin <peterlin@localhost.localdomain>
+
+ * sfd/FreeSerif.sfd - accented letters in Latin Extended-A
+ replaced by references wherever possible.
+
+ * sfd/FreeSerif.sfd - added U+0180, U+0181, U+0187, U+0188,
+ U+018A, U+0193, U+019C, U+01A4, U+01A5, U+01A7, U+01A8, U+01AF,
+ U+01B0, U+026E, U+0270, U+0278, U+0280, U+0281, U+028B, U+0299,
+ U+029C, U+029F.
+
+2005-11-03 Primoz Peterlin <peterlin@localhost.localdomain>
+
+ * sfd/FreeSansBold.sfd - added U+0180, U+0184, U+0185, U+0192,
+ U+019B, U+01A0-01A2, U+01AF, U+01B0, U+01EE, U+01EF, U+0292,
+ U+0294-0296, U+02A1, U+0532, U+054C, U+057C, U+222B. Changed
+ U+014B, U+01A5, U+01B4, U+03BB.
+
+ * sfd/FreeSans.sfd - added U+04C5, U+04C6, U+04C9, U+04CA, U+04D,
+ U+04CE.
+
+ * sfd/FreeSansBold.sfd - cleaner Arabic outlines. Added U+01E4,
+ U+01E5.
+
+2005-11-02 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - started Armenian; added U+0538, U+0542,
+ U+0544, U+0548, U+054D, U+054F, U+0550, U+0553, U+0555, U+0561,
+ U+0563, U+0564, U+0566, U+0568 U+056B, U+056F, U+0570, U+0572,
+ U+0578, U+057A, U+057D-057F, U+0580, U+0581, U+0583, U+0585.
+
+ * sfd/FreeMono.sfd - swapped U+03C6 (Greek small letter phi) and
+ U+03D5 (Greek phi symbol) in order to conform to Unicode standard.
+ Added U+04C5, U+04C6, U+04C9, U+04CA, U+04D, U+04CE.
+
+2005-11-01 Primoz Peterlin <peterlin@localhost.localdomain>
+
+ * sfd/FreeSansBold.sfd - modified U+019C.
+
+ * sfd/FreeSansBoldOblique.sfd - added U+00A0, U+00AD, U+019C,
+ U+01B7, U+01B8, U+0275, U+0278, U+0298, U+2012, U+2015,
+ U+2070-207F, U+2080-208E, U+2153-217F, U+2213, U+2215.
+
+2005-10-31 Primoz Peterlin <peterlin@localhost.localdomain>
+
+ * sfd/FreeSerif.sfd - added U+0199, U+01AB, U+0265, U+0282,
+ U+0288, U+028C-028E, U+0290, U+029E, U+02A0.
+
+2005-10-28 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd - added U+019E, U+01AB, U+01AD, U+01B1,
+ U+0256, U+025F, U+0265, U+0269, U+026F, U+0270, U+0279-027F,
+ U+0282, U+0287, U+0288, U+028C-028E, U+0290.
+
+ * sfd/FreeSerifBold.sfd - added U+2070, U+2075-2079, U+2080,
+ U+2085-2089, U+2153-215E, U+2113-2115, U+2119.
+
+ * sfd/FreeSerifBold.sfd - added U+0199, U+019B, U+01B8, U+01B9,
+ U+01BE, U+01C0, U+0262, U+0274, U+0278, U+0280, U+028F, U+0298,
+ U+0299, U+029C, U+029E, U+029F, U+2012, U+2015, U+2016, U+2129,
+ U+2217.
+
+2005-10-27 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added U+018D, U+0194, U+019B, U+019C, U+01B5,
+ U+01B6, U+0295, U+0296, U+029B, U+02A2, U+0472, U+0473, U+2114,
+ U+2119.
+
+ * sfd/FreeSerifItalic.sfd - minor cleanup in the superscript range
+ (U+2070-2079).
+
+ * sfd/FreeSansBold.sfd - added subscripts and superscripts
+ (U+2070-208F), completed fractions (U+2152-215F) and Roman
+ numerals (U+2160-217F).
+
+ * sfd/FreeSerifBold.sfd - added U+018B, U+018E, U+018F, U+0191,
+ U+019D, U+01A7, U+01A8, U+01AE, U+0253, U+0266, U+0267, U+026A,
+ U+0271-0273, U+0283, U+0285.
+
+2005-10-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added "above" anchors to selected Cyrillic
+ characters. Added U+0294, U+02A1.
+
+ * sfd/FreeMono.sfd - added U+2011, U+2012, U+203B, U+204A, U+2071,
+ U+2129, U+2232, U+2233. Changed and/or corrected U+2106, U+211E,
+ U+2126, U+2127, U+2153-215F, U+2202.
+
+ * sfd/FreeMono.sfd - a try to imitate Denis' work on adding
+ anchors by adding "above" anchor to a couple of basic Latin
+ characters.
+
+ * sfd/FreeSansBold.sfd - added U+0278, U+0298. Cleaned up outlines
+ of most Greek letters.
+
+ * sfd/FreeSansBold.sfd - Added U+2010-2012, U+2015, U+2032,
+ U+203C, U+2047-2049.
+
+ * sfd/FreeSans.sfd - Added U+01C0-01C2, U+0276, U+0292,
+ U+0298. Changed U+0251, U+0294, U+02A1.
+
+2005-10-25 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifItalic.sfd - added U+00A0, U+00AD, U+2010-2012,
+ U+2015, U+2126, U+2127, U+2153-215E, U+2160-217F, U+2190-2193,
+ U+2669-266F. FreeSerifItalic is now MES-1 compliant.
+
+ * sfd/FreeSerif.sfd - added U+0191, U+019D, U+01AE, U+027E,
+ U+027F, U+0283, U+0285.
+
+ * sfd/FreeSerif.sfd - added U+019E, U+01AD, U+01B8, U+01B9,
+ U+0253, U+0256, U+0257, U+025C, U+0260, U+0266, U+0267, U+0269,
+ U+026D, U+0271-0273, U+0279-027D.
+
+ * sfd/FreeSerifBoldItalic.sfd - added U+00A0, U+00AD, U+2010-2012,
+ U+2015, U+2032-2034, U+203C, U+2047-204A, U+2074, U+2081-2084,
+ U+2126, U+2153, U+2154, U+215F, U+2215. Corrected positions of
+ diacritics on U+0200-0217.
+
+ * sfd/FreeSansOblique.sfd, sfd/FreeSans.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeMonoBoldOblique.sfd,
+ sfd/FreeMonoBold.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBold.sfd sfd/FreeSerifBoldItalic.sfd - brought in
+ sync with Valek Filipov's urw-fonts-1.0.7pre41.
+
+ * sfd/FreeSansOblique.sfd - added U+00A0, U+2011-2012, U+2015,
+ U+2070, U+2071, U+2074-2079, U+2080-2089, U+2126, U+2153-215F,
+ U+2190-2195, U+2215, U+266A. FreeSansOblique is now MES-1
+ compliant.
+
+2005-10-24 Denis Jacquerye <moyogo@altern.org>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBoldOblique.sfd - added
+ ccmp for i and j to be substituted with dotless i or j when
+ followed by above diacritic
+
+2005-10-24 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added U+2011, U+2012, U+2015. FreeSans is now
+ MES-1 conformant.
+
+2005-10-23 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSans.sfd - added above, below, abovemk and belowmk
+ anchors for diacritics placement to many Basic Latin characters,
+ some Latin Extented A and B, and some IPA characters; fixed a
+ couple of precomposed characters to have diacritics at the same
+ height as similar characters.
+
+2005-10-21 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - added U+02B9, U+02BA, U+02CD, U+2017,
+ U+2036, U+2037, U+203C, U+203E, U+2047-204A.
+
+2005-10-20 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd - added U+0182, U+0189, U+0192, U+019F,
+ U+01A9, U+01B7, U+01C4-01CC, U+01E0-1E2, U+01F0-01F3, U+F6BE.
+ Corrected position of diacritics on U+0200-0217.
+
+ * sfd/FreeSerif.sfd - added U+00A0, U+00AD, U+0182, U+0189,
+ U+018B, U+018E, U+018F, U+0192, U+019F, U+01A9, U+01B1, U+01B7,
+ U+01DD, U+2010-2013, U+2015. FreeSerif is now MES-1 conformant.
+
+2005-10-19 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSerif.sfd - added U+0268, U+026A, U+0289, U+0292; and
+ anchor "above" to more base glyphs.
+
+ * sfd/FreeSerifBold.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBoldItalic.sfd - added U+0250-0252, U+0258-0259,
+ U+0261, U+0268, U+026A, U+0279, U+0289
+
+ * sfd/FreeSerifBold.sfd - added anchor "above" to marks
+ U+0300-0314, and to base glyphs (vowels).
+
+2005-10-18 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSerif.sfd - added anchor "above" to marks U+0300-0314,
+ and bases vowel of the U+0041-007A range, U+00E6, U+0186, U+0190,
+ U+0254 and U+025B; fixed Latin-1 Supplement block accented glyphs
+ to use references.
+
+2005-10-17 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - added U+01B7, U+01B8, U+0275.
+
+2005-10-16 Denis Jacquerye <moyogo@gmail.com>
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd - added some Latin
+ Extended-B African letters: U+0181, U+018A, U+0197-0198, U+01A4,
+ U+01AC, U+01B1, U+01B3-01B4;
+
+ * sfd/FreeSansBold.sfd, sfd/FreeSansBoldOblique.sfd - added Latin
+ Extended-B U+0187, 018E-018F, U+0191, U+0193, U+0197-0199,
+ U+019D-019F, U+01AB-01AE; correcting width of non-space
+ Combining Diacrtical Marks; added more glyphs to IPA Extensions
+ to match non Bold
+
+ * sfd/FreeSansBoldOblique.sfd - added many accented glyphs to
+ Latin Extended-B
+
+2005-10-15 Denis Jacquerye <moyogo@gmail.com>
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd - added IPA Extensions
+ U+0262,U+0274,U+0280-0281, U+0299, U+029F, and Spacing Modifier
+ Letters U+02C9-02CB; fixed U+0287,029E height to baseline; added
+ stroke to U+0268
+
+ * sfd/FreeSansOblique.sfd - fixed skew on U+027F
+
+ * sfd/FreeSansBold.sfd, sfd/FreeSansBoldOblique.sfd - added to Latin
+ Extended-B U+01A7-01A8, IPA Extensions U+0251-0253, U+0256-0257,
+ U+0261, U+0265-026A, U+026F-0273, U+0289, U+028C-028E
+
+ * sfd/FreeSansBoldOblique.sfd - added to Latin extended-B U+0189,
+ U+01A8, U+01B1, U+0283, U+02C9 and Spacing Modifiers U+02C9-02CB
+
+2005-10-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - Added a couple of composite glyphs,
+ mostly in the IPA and Latin Extended B ranges.
+
+2005-10-13 Denis Jacquerye <moyogo@gmail.com>
+
+ * FreeSans.sfd - removed overlap and simplified U+0187, 0191,
+ 0193, 01A5, 01AE, 0260, 0271, 0272, 0273, 027B; fixed diacritics
+ placement on U+0200-0217; fixed glyph for U+0283 to correct esh
+ without stroke; added U+025F and fixed U+025F from it; fixed
+ height of glyph at U+0285; arranged U+027E,027F to make more
+ distinguishable from U+0072.
+
+ * FreeSansOblique.sfd - added the corrected or new glyphs from
+ FreeSans; diacritics on U+200-0217 will need height readjustements.
+
+ * FreeSansBold.sfd, FreeSansBoldOblique.sfd - added U+0186, 0190,
+ 0250, 0254, 0258, 0259, 025B, 025C
+
+2005-10-13 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Minor changes: U+22A2, U+22A3, U+22A6, U+23AE.
+ Added U+0250, U+0251, U+0258, U+0259, U+0275.
+
+ * sfd/FreeSerifItalic.sfd - Added glyphs U+222B-U+222F, U+2320,
+ U+2321. Fixed diacritics on U+0200-U+0217.
+
+2005-10-12 Denis Jacquerye <moyogo@gmail.com>
+
+ * sfd/FreeSerif.sfd - Corrected diacritics position on
+ U+01D5-01D9,01DB,01EA-01ED,0200-0217 and U+022A.
+
+ * sfd/FreeSerif.sfd, sfd/FreeSerifBold.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBoldItalic.sfd - added U+0186,0190,0254 and U+025B.
+
+2005-10-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Fixed bug #13399 (glyphs for U+0360 and
+ U+0361 were swapped).
+
+ * sfd/FreeSerif.sfd - Attempt to correct bug #13370: INTEGRAL
+ EXTENSION does not align with TOP/BOTTOM HALF INTEGRAL; added
+ glyph U+23AE.
+
+2005-05-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Corrected shapes for Cross of Lorraine and
+ Cross of Jerusalem.
+
+2005-04-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSansBold.sfd - Added some combining accents, just to
+ test the a version of FontForge.
+
+2003-12-05 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Some composite Latin characters rebuilt, as
+ they had accents 600 points to the left due to changes on October
+ 2. Some other minor changes in the mathematics area.
+
+2003-10-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoOblique.sfd, sfd/FreeSerifBoldItalic.sfd,
+ FreeSerifItalic.sfd - applied Josef Segur's corrections from
+ Oct. 5.
+
+2003-10-02 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Abbas Izad's contributed Arabic/Farsi
+ characters added.
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - Combining characters (U+0300 -
+ U+036F) moved left, so that they have negative horizontal values
+ and zero advance width.
+
+2003-09-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBold.sfd, sfd/FreeSerifItalic.sfd - Started working
+ on super- and subscripts.
+
+2003-09-12 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd, sfd/FreeSerif.sfd - Added some missing
+ Hiragana and Katakana characters.
+
+ * sfd/FreeSansBold.sfd - Cleared background characters in Latin
+ Extended-A. Added some automatically constructed characters in
+ Latin Extended-B. Started with superscripts and subscripts.
+
+ * sfd/FreeSans.sfd - Subscript numerals (U+2080-U+2089) completed.
+
+2003-05-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Thai characters po pla and bo baimai
+ swapped; Thai character fongman corrected; all courtesy Theppitak
+ Karoonboonyanan.
+
+2003-05-17 Panayotis Katsaloulis <panayotis@panayotis.com>
+
+ * sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - Full support
+ of all ancient greek glyphs
+
+2003-05-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * tools/KerningNumerals.pl - A Perl script for moving kerning
+ information from ASCII numerals (U+0030...) to characters in the
+ Adobe corporate use area (U+F6xx).
+
+ * sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd,
+ sfd/FreeSansBoldOblique.sfd - Created kerned numerals in the Adobe
+ corporate use area (U+F6xx) and moved kerning information from
+ ASCII numerals to the kerned numerals.
+
+2003-05-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - First approximation of super- and subscript
+ numerals and vulgar fractions.
+
+ * sfd/FreeSerif.sfd - Super- and subscript numerals complete,
+ vulgar fractions completed and redone as references rather than
+ outlines.
+
+2003-05-12 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Clean-up of the Cyrillic letters added on
+ March 27; super- and subscripts, vulgar fractions.
+
+2003-05-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoBold.sfd - Added a couple of characters to
+ the Latin Extended-B area and the IPA extensions area.
+
+2003-05-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifBoldItalic.sfd - Added a couple of characters to
+ the Latin Extended-B area.
+
+ * sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - ASCII
+ numerals now monospaced; kerned numerals moved to Adobe corporate
+ use area
+ (U+F6xx).
+
+2003-05-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Roman numerals now more complete.
+
+ * sfd/FreeSansOblique.sfd, sfd/FreeSansBoldOblique.sfd - Accented
+ characters added in the Latin Extended-B area.
+
+ * sfd/FreeSans.sfd - Greek accents added in the Greek Extended
+ area, characters added in the Latin Extended-B area, Roman
+ numerals added.
+
+ * sfd/FreeMonoOblique.sfd - Kerning pairs removed (what were they
+ doing in a monospaced font, anyway?).
+
+ * sfd/FreeMonoBoldOblique.sfd - Additions in Latin Extended-B and
+ Basic Greek.
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd, sfd/FreeMonoOblique.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd,
+ sfd/FreeSansBoldOblique.sfd - Major cleanup (fixed widths, open
+ paths, path directions (clockwise/counter-clockwise), points
+ rounded to integer values; outlines simplified etc.)
+
+2003-05-06 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * tools/OS2UnicodeRange - A simple script to display OS/2 Unicode
+ range table in TrueType fonts.
+
+ * sfd/FreeSans.sfd, sfd/FreeSansBold.sfd - ASCII numerals now
+ monospaced; kerned numerals moved to Adobe corporate use area
+ (U+F6xx). FreeSans is done, FreeSansBold half-way.
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - Added 2003 in copyright info.
+
+2003-03-27 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Cyrillic and Cyrillic Supplement blocks
+ brought to conformance with Unicode 3.2, courtesy Daniel Shurovich
+ Chirkov.
+
+2003-03-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd - somewhat wider
+ germandbls (U+00DF), due to complaints by Walter Schmidt.
+
+2003-03-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Added Sinhala glyphs from the Tipitaka
+ project <http://www.metta.lk>, recoded to Unicode by Noah Levitt.
+
+2003-02-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Minor changes on mathematical operators.
+
+2003-02-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - minor cleanup of glyph backgrounds; changed
+ integral signs (U+222B - U+2230)
+
+2003-02-05 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - added a couple of glyphs in the IPA and
+ African Latin ranges.
+
+2003-01-30 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd - Corrected Maltese Hbar (U+0126)
+ and/or hbar (U+0127).
+
+2003-01-28 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerifItalic.sfd - Corrected Maltese hbar (U+0127).
+
+2002-12-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * tools/ConvertFont - PfaEdit script for converting SFD files to
+ TrueType fonts.
+
+ * sfd/FreeSans.sfd - Added Tamil and Kannada glyphs from the
+ Akruti Indic fonts.
+
+2002-12-17 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Added Devanagari and Gujarati glyphs from the
+ Akruti Indic fonts.
+
+ * www/index.html - Added information on Rogier van Dalen's tools.
+
+ * AUTHORS - Added M.S. Sridhar.
+
+ * CREDITS - Correct spelling of Culmus project. Added M.S. Sridhar.
+
+2002-12-06 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added Braille glyphs, courtesy Vyacheslav
+ Dikonov.
+
+ * sfd/FreeSans.sfd - Added Unicode Syriac glyphs, courtesy
+ Vyacheslav Dikonov.
+
+2002-10-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * www/index.html - Added information on the availability of the
+ Debian GNU/Linux package.
+
+ * sfd/FreeSerif.sfd, sfd/FreeSans.sfd - added some kern pairs
+ beyond Latin-1 area.
+
+ * sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - re-introduced
+ all the emtpy glyph slots (changes from Sep 23 made PfaEdit
+ crash).
+
+2002-09-23 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd,
+ sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - imported
+ kerning information from the URW++ AFM files
+
+2002-09-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoOblique.sfd - updated Hebrew parts to comply with
+ Culmus v0.6.
+
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansOblique.sfd - Added Danilo Segan's Serbian Cyrillic
+ glyphs; updated Hebrew parts to comply with Culmus v0.6.
+
+2002-09-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansOblique.sfd - Updated Cyrillic part to match
+ Filippov's 1.0.7pre14
+
+ * sfd/FreeSansOblique.sfd - added Sam Stepanyan's Armenian glyphs
+ from FreeSans (skewed for 12 degrees).
+
+2002-09-06 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd,
+ sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd - Added Maxim
+ Iorsh's Hebrew characters.
+
+2002-08-29 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd,
+ sfd/FreeMonoBold.sfd, sfd/FreeMonoOblique.sfd - Added Maxim
+ Iorsh's Hebrew characters.
+
+ * AUTHORS, CREDITS - Added Maxim Iorsh as author.
+
+2002-08-28 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * www/index.html - Added information of Microsoft's withdrawal of
+ freely available Unicode TrueType fonts
+
+ * www/resources.html - Added link to Maxim Iorsh's Culmus project.
+
+2002-07-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added a couple of characters (Arrows area).
+
+2002-06-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Applied Michalis Kabrianis's patch concerning
+ perispomeni in Greek politoniko.
+
+2002-05-23 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Applied Michalis Kabrianis's patch concerning
+ psili in Greek politoniko. Also added two working variants of
+ chars in the IPA range.
+
+2002-05-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd, sfd/FreeSansBold.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifBold.sfd - Deleted explicit ".notdef" character with
+ no contours.
+
+2002-05-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - The new version of PfaEdit saves
+ correctly formed Panose and LineGap lines.
+
+ * sfd/FreeSansBoldOblique.sfd - Filled-in the missing TTFWidth and
+ TTFWeight values.
+
+2002-05-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Added diacritics to the Spacing Modifier
+ Letters and Combining Diacritical Marks areas. Added composed
+ glyphs to the Latin Extended-B area.
+
+2002-05-07 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - Updated Panose information with data
+ provided by Josef W. Segur. Updated TTF headers with English and
+ Slovenian text.
+
+2002-04-30 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoBold.sfd - Working on Greek small letters. Several
+ minor changes (lower carons etc.)
+
+2002-04-29 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * FreeMonoBoldOblique.sfd - Started adding Greek.
+
+ * sfd/FreeMonoBold.sfd - Added glyphs in the Geometrical Shapes
+ and Miscellaneous Symbols area. Harmonizing Greek with Latin. Done
+ with capitals.
+
+ * sfd/FreeMono.sfd - Deleted the explicit .notdef character. Added
+ one glyph to the Geometrical Shapes area, which is now completed;
+ added three glyphs to the Miscellaneous Symbols area. Harmonizing
+ Greek with Latin. Done with the capitals.
+
+2002-04-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - Adjusted accent positions on several glyphs
+ in the Latin Extended-A area.
+
+2002-04-25 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoBold.sfd - Box Drawing area completed. Added a
+ couple of glyphs in the Geometrical Shapes area.
+
+ * sfd/FreeMono.sfd - Small corrections in the Box Drawing area.
+
+2002-04-24 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Box Drawing area completed.
+
+2002-04-23 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * tools/WGL4.lst - corrected.
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd - Working on Box Drawing
+ area.
+
+2002-04-22 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd - Working on Latin
+ Extended-B and Greek.
+
+2002-04-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Somewhat cleaner chess figures.
+
+ * tools/MES-2.txt, tools/MES-2.lst - Corrected list (it is not
+ 203C-203E, it is 203C and 203E).
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd,
+ sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd,
+ sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd,
+ sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd,
+ sfd/FreeSerifBoldItalic.sfd - Changed "Family Name" from Free to
+ FreeSerif, FreeSans and FreeMono, as appropriate. Changed Font
+ Modifiers from MonoBold etc. to Bold, Italic, Oblique, BoldOblique
+ and BoldItalic.
+
+2002-04-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd,
+ sfd/FreeMonoBoldOblique.sfd - Corrected metrics; now all character
+ widths are set to 600.
+
+2002-04-17 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Corrected glyphs in the Box Drawing area and
+ Block Elements area, which should extend through the ascender *and
+ descender* height.
+
+ * sfd/FreeMonoBold.sfd - Continued working on harmonizing Greek
+ letters with Latin and Cyrillic.
+
+ * sfd/FreeMonoBold.sfd - Added some box drawing characters.
+
+2002-04-16 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * www/design-notes.html - Updated notes on stroke width for
+ symbols in Free Mono Bold.
+
+ * sfd/FreeMono.sfd - Added a handful of characters in the
+ Miscellaneous Symbols area.
+
+ * sfd/FreeMonoBoldOblique.sfd - Added subscripts, superscripts and
+ vulgar fractions.
+
+ * sfd/FreeMonoBold.sfd - Started harmonizing Greek letters with
+ Latin and Cyrillic.
+
+ * sfd/FreeMonoBold.sfd - Added subscripts, superscripts and vulgar
+ fractions.
+
+2002-04-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * www/design-notes.html - Updated notes on super-/subscripts in
+ Free Mono Bold. Separate subsections for Free Mono regular and
+ Free Mono Bold.
+
+2002-04-12 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Added Ethiopian glyphs, converted from the
+ Metafont sources from TGI, Universität Hamburg (authors Berhanu
+ Beyene, Prof. Dr. Manfred Kudlek, Olaf Kummer, and Jochen
+ Metzinger) using Szabo's TeXtrace and retouched using
+ PfaEdit. Ethiopian metafonts are released under GNU GPL,
+ <http://www.informatik.uni-hamburg.de/TGI/mitarbeiter/wimis/kummer/ethiop_eng.html>.
+
+ * sfd/FreeMonoBold.sfd - Added 40 characters, mostly in the Latin
+ Extended-B and IPA Extensions areas.
+
+2002-04-11 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added a handful of characters in the Latin
+ Extended-B, IPA Extensions, Currency Symbols and Miscellaneous
+ Symbols areas.
+
+2002-04-09 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Correcting accent positioning in the Extended
+ Greek area; adding a couple of characters here and there. Still 20
+ characters short of MES-2 conformance.
+
+2002-04-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added some characters in the Arrows area;
+ more or less completed Extended Greek area (accents still need to
+ be fine-tuned).
+
+2002-04-05 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Modern non-Russian Cyrilic mostly completed.
+
+ * sfd/FreeMonoOblique.sfd - Synchronized with FreeMono.
+
+ * sfd/FreeSerif.sfd - Added Thomas Ridgeway's Tamil characters
+ (converted from Metafont and edited somehwat).
+
+2002-04-04 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoOblique.sfd - Armenian letters added.
+
+ * sfd/FreeMonoBold.sfd - Serbian Cyrillic letters dje, tshe, lje
+ and nje corrected.
+
+ * sfd/FreeMono.sfd - Serbian Cyrillic letters dje and tshe
+ corrected. Some other non-Russian Cyrillic letters modified and
+ "welded together".
+
+2002-04-03 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added more or less complete Armenian
+ area. The glyphs are a tidied-up version based on the Armenian
+ Courier on the <http://www.cilicia.com/armo8.html>. Now we have
+ 1673 characters.
+
+2002-03-28 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Added some mathematical symbols.
+
+2002-03-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSans.sfd - took H.S. Pannu's Gurmukhi from FreeSerif. It
+ actually fits to FreeSans much better. It seems I'll have to look
+ for another Gurmukhi font with modulated stroke for FreeSerif.
+
+ * sfd/FreeSerifItalic.sfd - replaced existing Hebrew glyphs by
+ those from FreeSerif (slanted for 15.5 degrees).
+
+ * sfd/FreeSerif.sfd - Added dotted Hebrew letters. Changed barred H.
+
+ * sfd/FreeMono.sfd - Completed vulgar fractions; minor changes in
+ Greek; added some mathematical operators.
+
+ * sfd/FreeMonoBold.sfd - added 12 characters to Latin Extended-B
+ and IPA Extensions areas (total 984).
+
+2002-03-25 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMonoBold.sfd - started adding Latin Extended-B and IPA
+ Extensions.
+
+ * sfd/FreeMono.sfd - Minor cosmetic changes; cleaning up Greek
+ (removing redundant control points), added some non-European
+ Cyrillic glyphs as a test.
+
+2002-03-22 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - Some minor modifications; letters in Latin
+ Extended-B area "welded" together.
+
+2002-03-20 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * www/index.html - finally linked the resources and design notes
+ pages.
+
+ * www/design-notes.html - added scaling information for super- and
+ subscript numerals in FreeMono.
+
+2002-03-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - the Latin Extended-B and IPA Extension area
+ characters moved from FreeMono and skewed for 12 degrees.
+
+2002-03-18 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - added a dozen or two of new characters, in
+ particular in the Latin Extended-B and IPA Extension area.
+
+2002-03-15 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - added a dozen of two of new characters, in
+ particular in the IPA Extension area.
+
+ * www/design-notes.html - Corrected data for x-height in FreeMono;
+ information on constructing small caps.
+
+2002-03-14 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeMono.sfd - added three smiley characters to the
+ Miscallaneous Symbols area.
+
+2002-03-10 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Anshuman Pandey has only converted Gurmukhi
+ from TrueType to Metafont; the original author of Gurkmukhi font
+ is Hardip Singh Pannu <http://members.aol.com/hspannu/punjabi.html>.
+ Got the permission from him to include the Gurmukhi glyph set.
+
+2002-03-08 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Added some more glyphs in the Mathematical
+ Symbols area to a total number of 3374.
+
+2002-03-06 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Added a basic Gurmukhi set.
+
+ * www/design-notes.html - started a page on design notes
+
+ * sfd/FreeMono.sfd - realized that glyphs in the Box Drawing area
+ and Block Elements area should extend through the ascender *and
+ descender* height, and corrected it.
+
+ * sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd - added some musical
+ glyphs, linking "no-break space" to space, "soft hyphen" to
+ hyphen-minus etc.
+
+2002-03-05 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * tools/WGL4.lst - Added Windows Glyph List 4.0
+
+ * tools/LigatureList.pl - Wrote a Perl script, which lists the
+ GSUB list (ligature list) of a OpenType font.
+
+ * sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd,
+ sfd/FreeSerifItalic.sfd - auxilliary Hebrew glyphs added. They are
+ too light compared with Latin and will be substituted with better
+ ones.
+
+2002-03-04 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Added some more glyphs to the Mathematical
+ Operators area (page 0x22).
+
+ * sfd/FreeSerif.sfd - Incomplete and fragmentary support for
+ Devanagari, originating from Harsh Kumar's Shusha fonts was
+ replaced by Frans Velthuis' Devanagari metafont, now maintained by
+ Anshuman Pandey <apandey@u.washington.edu> and available under
+ GPL. Until I figure out how to provide glyph substitution table in
+ OpenType, only the Unicode part is there.
+
+2002-02-28 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * ChangeLog file created
+
+ * sfd/FreeSerif.sfd - Added some Telugu glyphs to page 0x0C,
+ courtesy Prasad A. Chodavarapu <http://chaitanya.bhaavana.net/fonts/>
+
+ * sfd/FreeSerif.sfd - Added some glyphs to the Miscellaneous
+ Symbols page (0x26).
+
+2002-02-26 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * mailing lists freefont-announce and freefont-bugs created
+
+2002-02-25 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/FreeSerif.sfd - Added a couple of glyphs in Mathematics
+ Operators area.
+
+ * sfd/FreeMono.sfd
+ - Added some more glyphs, in particular in the Mathematical
+ Operators section.
+ - Changed FamilyName to Free, FontName to FreeMono, and Full name
+ to "Free Monospaced".
+
+2002-02-20 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * sfd/ directory added containing FreeSerif, FreeSans and FreeMono
+ families.
+
+ * tools/ directory added containing lists with characters required
+ for MES (Multilinguag European Subset) compliance.
+
+ * tools/mes-list-expand.pl created - a Perl script for expanding MES
+ ranges into simple one-char-per-line format
+
+ * tools/CheckConformance.pl created - a Perl script for checking
+ conformance of a font file with a given coded character set
+
+ * homepage <http://www.freesoftware.fsf.org/freefont/> created
+
+2002-02-19 Primoz Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>
+
+ * freefont (Free UCS Scalable Fonts) project approved on
+ savannah.gnu.org: <http://savannah.gnu.org/projects/freefont/>
diff --git a/External/Fonts/FreeFont/FreeMono.ttf b/External/Fonts/FreeFont/FreeMono.ttf
new file mode 100755
index 0000000..ba90adb
--- /dev/null
+++ b/External/Fonts/FreeFont/FreeMono.ttf
Binary files differ
diff --git a/External/Fonts/FreeFont/INSTALL b/External/Fonts/FreeFont/INSTALL
new file mode 100755
index 0000000..fbbbe80
--- /dev/null
+++ b/External/Fonts/FreeFont/INSTALL
@@ -0,0 +1,86 @@
+ Installing GNU FreeFont
+ =======================
+
+GNU FreeFont can be used in any modern operating system.
+
+This document explains how to install FreeFont on some common systems.
+
+UNIX/GNU/Linux/BSD Systems
+--------------------------
+
+FreeFont works with any system using the free font rasterizer FreeType
+<http://www.freetype.org/>.
+
+* Debian GNU/Linux
+
+Users of Debian GNU/Linux system will probably want to use the Debian package,
+available from the Debian site,
+
+ <http://packages.debian.org/unstable/x11/ttf-freefont.html>,
+
+or any of its mirrors.
+
+Install them by issuing the command
+ apt-get install ttf-freefont
+
+
+* KDE local installation
+
+Users of KDE can install .ttf files on a per-user basis using the KDE
+Control Center module "kcmfontinst", which may appear in the menu as
+
+ Settings -> System Administration -> Font Installer
+
+This is especially helpful for developers and testers.
+
+
+* Generic X-windows
+
+ 1) Fetch the freefont-ttf.tar.gz package with Free UCS outline fonts
+ in the TrueType format.
+
+ 2) Unpack TrueType fonts into a suitable directory,
+ e.g. /usr/local/share/fonts/default/TrueType/
+
+ 3) If you have chosen any other directory, make sure the directory you
+ used to install the fonts is listed in the path searched by the X
+ Font Server by editing the config file in /etc/X11/.
+
+ In some systems, you list the directory in the item "catalogue="
+ in the file /etc/X11/fs/config.
+
+ 4) Run ttmkfdir in the directory where you unpacked the fonts.
+
+
+Windows 95/98/NT/2000/XP; Vista
+-------------------------------
+
+Note that in at least Vista, XP and 2000, the OpenType versions perform much
+better than, and are recommended over, the TrueType ones.
+
+* Vista:
+ 1) From the Start menu, open Control Panels
+ 2) Drag-n-drop font files onto Fonts control panel
+ You may get a dialog saying
+ "Windows needs your permission to continue"
+ a) Click Continue
+
+* 95/98/NT:
+ The font installation is similar to Vista.
+
+ In order to use OpenType, users of Windows 95, 98 and NT 4.0 can
+ install Adobe's 'Type Manager Light'. It is available for download
+ without cost from Adobe's web site.
+
+ Otherwise, use the TrueType versions.
+
+Mac OS X
+--------
+
+Installing on Mac OS X consists of moving the .ttf files to either
+ /Library/Fonts/ or ~/Library/Fonts/
+depending on whether they should be available to all users on your system
+or just to yourself.
+
+--------------------------------------------------------------------------
+$Id: INSTALL,v 1.7 2008/12/26 12:33:31 Stevan_White Exp $
diff --git a/External/Fonts/FreeFont/README b/External/Fonts/FreeFont/README
new file mode 100755
index 0000000..60e67f2
--- /dev/null
+++ b/External/Fonts/FreeFont/README
@@ -0,0 +1,108 @@
+-*-text-*-
+ GNU FreeFont
+
+The GNU FreeFont project aims to provide a useful set of free scalable
+(i.e., OpenType) fonts covering as much as possible of the ISO 10646/Unicode
+UCS (Universal Character Set).
+
+Statement of Purpose
+--------------------
+
+The practical reason for putting glyphs together in a single font face is
+to conveniently mix symbols and characters from different writing systems,
+without having to switch fonts.
+
+Coverage
+--------
+
+FreeFont covers the following character sets
+
+* ISO 8859 parts 1-15
+* CEN MES-3 European Unicode Subset
+ http://www.evertype.com/standards/iso10646/pdf/cwa13873.pdf
+* IBM/Microsoft code pages 437, 850, 852, 1250, 1252 and more
+* Microsoft/Adobe Windows Glyph List 4 (WGL4)
+ http://www.microsoft.com/typography/otspec/WGL4.htm
+* KOI8-R and KOI8-RU
+* DEC VT100 graphics symbols
+* International Phonetic Alphabet
+* Arabic, Hebrew, Armenian, Georgian, Ethiopian and Thai alphabets,
+ including Arabic presentation forms A/B
+* mathematical symbols, including the whole TeX repertoire of symbols
+* APL symbols
+ etc.
+
+Editing
+-------
+
+The free outline font editor, George Williams's FontForge
+<http://fontforge.sourceforge.net/> is used for editing the fonts.
+
+Design Issues
+-------------
+
+Which font shapes should be made? Historical style terms like Renaissance
+or Baroque letterforms cannot be applied beyond Latin/Cyrillic/Greek
+scripts to any greater extent than Kufi or Nashki can be applied beyond
+Arabic script; "italic" is really only meaningful for Latin letters.
+
+However, most modern writing systems have typographic formulations for
+contrasting uniform and modulated character stroke widths, and have some
+history with "oblique", faces. Since the advent of the typewriter, most
+have developed a typographic style with uniform-width characters.
+
+Accordingly, the FreeFont family has one monospaced - FreeMono - and two
+proportional faces (one with uniform stroke - FreeSans - and one with
+modulated stroke - FreeSerif).
+
+To make text from different writing systems look good side-by-side, each
+FreeFont face is meant to contain characters of similar style and weight.
+
+Licensing
+---------
+
+Free UCS scalable fonts is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+The fonts are distributed in the hope that they will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+As a special exception, if you create a document which uses this font, and
+embed this font or unaltered portions of this font into the document, this
+font does not by itself cause the resulting document to be covered by the
+GNU General Public License. This exception does not however invalidate any
+other reasons why the document might be covered by the GNU General Public
+License. If you modify this font, you may extend this exception to your
+version of the font, but you are not obligated to do so. If you do not
+wish to do so, delete this exception statement from your version.
+
+
+Files and their suffixes
+------------------------
+
+The files with .sfd (Spline Font Database) are in FontForge's native format.
+Please use these if you plan to modify the font files.
+
+TrueType fonts for immediate consumption are the files with the .ttf
+(TrueType Font) suffix. These are ready to use in Xwindows based
+systems using FreeType, on Mac OS, and on older Windows systems.
+
+OpenType fonts (with suffix .otf) are for use in Windows Vista.
+Note that although they can be installed on Linux, but many applications
+in Linux still don't support them.
+
+
+--------------------------------------------------------------------------
+Primoz Peterlin, <primoz.peterlin@biofiz.mf.uni-lj.si>
+Steve White <stevan.white@googlemail.com>
+
+Free UCS scalable fonts: http://savannah.gnu.org/projects/freefont/
+$Id: README,v 1.6 2008/12/25 12:51:41 Stevan_White Exp $
diff --git a/External/swiftmailer/lib/classes/Swift.php b/External/swiftmailer/lib/classes/Swift.php
new file mode 100755
index 0000000..77abbbf
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * General utility class in Swift Mailer, not to be instantiated.
+ *
+ * @package Swift
+ *
+ * @author Chris Corbyn
+ */
+abstract class Swift
+{
+
+ /** Swift Mailer Version number generated during dist release process */
+ const VERSION = '4.0.6';
+
+ /**
+ * Internal autoloader for spl_autoload_register().
+ *
+ * @param string $class
+ */
+ public static function autoload($class)
+ {
+ //Don't interfere with other autoloaders
+ if (0 !== strpos($class, 'Swift'))
+ {
+ return false;
+ }
+
+ $path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php';
+
+ if (!file_exists($path))
+ {
+ return false;
+ }
+
+ require_once $path;
+ }
+
+ /**
+ * Configure autoloading using Swift Mailer.
+ *
+ * This is designed to play nicely with other autoloaders.
+ */
+ public static function registerAutoload()
+ {
+ spl_autoload_register(array('Swift', 'autoload'));
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Attachment.php b/External/swiftmailer/lib/classes/Swift/Attachment.php
new file mode 100755
index 0000000..d3779bf
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Attachment.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Attachment.php';
+//@require 'Swift/ByteStream/FileByteStream.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Attachment class for attaching files to a {@link Swift_Mime_Message}.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Attachment extends Swift_Mime_Attachment
+{
+
+ /**
+ * Create a new Attachment.
+ * Details may be optionally provided to the constructor.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ */
+ public function __construct($data = null, $filename = null,
+ $contentType = null)
+ {
+ call_user_func_array(
+ array($this, 'Swift_Mime_Attachment::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('mime.attachment')
+ );
+
+ $this->setBody($data);
+ $this->setFilename($filename);
+ if ($contentType)
+ {
+ $this->setContentType($contentType);
+ }
+ }
+
+ /**
+ * Create a new Attachment.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ * @return Swift_Mime_Attachment
+ */
+ public static function newInstance($data = null, $filename = null,
+ $contentType = null)
+ {
+ return new self($data, $filename, $contentType);
+ }
+
+ /**
+ * Create a new Attachment from a filesystem path.
+ * @param string $path
+ * @param string $contentType optional
+ * @return Swift_Mime_Attachment
+ */
+ public static function fromPath($path, $contentType = null)
+ {
+ return self::newInstance()->setFile(
+ new Swift_ByteStream_FileByteStream($path),
+ $contentType
+ );
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php b/External/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php
new file mode 100755
index 0000000..71bc3f1
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php
@@ -0,0 +1,178 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/Filterable.php';
+//@require 'Swift/StreamFilter.php';
+
+/**
+ * Provides the base functionality for an InputStream supporting filters.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+abstract class Swift_ByteStream_AbstractFilterableInputStream
+ implements Swift_InputByteStream, Swift_Filterable
+{
+
+ /** Write sequence */
+ private $_sequence = 0;
+
+ /** StreamFilters */
+ private $_filters = array();
+
+ /** A buffer for writing */
+ private $_writeBuffer = '';
+
+ /** Bound streams */
+ private $_mirrors = array();
+
+ /**
+ * Commit the given bytes to the storage medium immediately.
+ * @param string $bytes
+ * @access protected
+ */
+ abstract protected function _commit($bytes);
+
+ /**
+ * Flush any buffers/content with immediate effect.
+ * @access protected
+ */
+ abstract protected function _flush();
+
+ /**
+ * Add a StreamFilter to this InputByteStream.
+ * @param Swift_StreamFilter $filter
+ * @param string $key
+ */
+ public function addFilter(Swift_StreamFilter $filter, $key)
+ {
+ $this->_filters[$key] = $filter;
+ }
+
+ /**
+ * Remove an already present StreamFilter based on its $key.
+ * @param string $key
+ */
+ public function removeFilter($key)
+ {
+ unset($this->_filters[$key]);
+ }
+
+ /**
+ * Writes $bytes to the end of the stream.
+ * @param string $bytes
+ * @throws Swift_IoException
+ */
+ public function write($bytes)
+ {
+ $this->_writeBuffer .= $bytes;
+ foreach ($this->_filters as $filter)
+ {
+ if ($filter->shouldBuffer($this->_writeBuffer))
+ {
+ return;
+ }
+ }
+ $this->_doWrite($this->_writeBuffer);
+ return ++$this->_sequence;
+ }
+
+ /**
+ * For any bytes that are currently buffered inside the stream, force them
+ * off the buffer.
+ *
+ * @throws Swift_IoException
+ */
+ public function commit()
+ {
+ $this->_doWrite($this->_writeBuffer);
+ }
+
+ /**
+ * Attach $is to this stream.
+ * The stream acts as an observer, receiving all data that is written.
+ * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function bind(Swift_InputByteStream $is)
+ {
+ $this->_mirrors[] = $is;
+ }
+
+ /**
+ * Remove an already bound stream.
+ * If $is is not bound, no errors will be raised.
+ * If the stream currently has any buffered data it will be written to $is
+ * before unbinding occurs.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function unbind(Swift_InputByteStream $is)
+ {
+ foreach ($this->_mirrors as $k => $stream)
+ {
+ if ($is === $stream)
+ {
+ if ($this->_writeBuffer !== '')
+ {
+ $stream->write($this->_filter($this->_writeBuffer));
+ }
+ unset($this->_mirrors[$k]);
+ }
+ }
+ }
+
+ /**
+ * Flush the contents of the stream (empty it) and set the internal pointer
+ * to the beginning.
+ * @throws Swift_IoException
+ */
+ public function flushBuffers()
+ {
+ if ($this->_writeBuffer !== '')
+ {
+ $this->_doWrite($this->_writeBuffer);
+ }
+ $this->_flush();
+
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->flushBuffers();
+ }
+ }
+
+ // -- Private methods
+
+ /** Run $bytes through all filters */
+ private function _filter($bytes)
+ {
+ foreach ($this->_filters as $filter)
+ {
+ $bytes = $filter->filter($bytes);
+ }
+ return $bytes;
+ }
+
+ /** Just write the bytes to the stream */
+ private function _doWrite($bytes)
+ {
+ $this->_commit($this->_filter($bytes));
+
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->write($bytes);
+ }
+
+ $this->_writeBuffer = '';
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php b/External/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php
new file mode 100755
index 0000000..f918889
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php
@@ -0,0 +1,190 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Allows reading and writing of bytes to and from an array.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+class Swift_ByteStream_ArrayByteStream
+ implements Swift_InputByteStream, Swift_OutputByteStream
+{
+
+ /**
+ * The internal stack of bytes.
+ * @var string[]
+ * @access private
+ */
+ private $_array = array();
+
+ /**
+ * The size of the stack
+ * @var int
+ * @access private
+ */
+ private $_arraySize = 0;
+
+ /**
+ * The internal pointer offset.
+ * @var int
+ * @access private
+ */
+ private $_offset = 0;
+
+ /** Bound streams */
+ private $_mirrors = array();
+
+ /**
+ * Create a new ArrayByteStream.
+ * If $stack is given the stream will be populated with the bytes it contains.
+ * @param mixed $stack of bytes in string or array form, optional
+ */
+ public function __construct($stack = null)
+ {
+ if (is_array($stack))
+ {
+ $this->_array = $stack;
+ $this->_arraySize = count($stack);
+ }
+ elseif (is_string($stack))
+ {
+ $this->write($stack);
+ }
+ else
+ {
+ $this->_array = array();
+ }
+ }
+
+ /**
+ * Reads $length bytes from the stream into a string and moves the pointer
+ * through the stream by $length. If less bytes exist than are requested the
+ * remaining bytes are given instead. If no bytes are remaining at all, boolean
+ * false is returned.
+ * @param int $length
+ * @return string
+ */
+ public function read($length)
+ {
+ if ($this->_offset == $this->_arraySize)
+ {
+ return false;
+ }
+
+ // Don't use array slice
+ $end = $length + $this->_offset;
+ $end = $this->_arraySize<$end
+ ?$this->_arraySize
+ :$end;
+ $ret = '';
+ for (; $this->_offset < $end; ++$this->_offset)
+ {
+ $ret .= $this->_array[$this->_offset];
+ }
+ return $ret;
+ }
+
+ /**
+ * Writes $bytes to the end of the stream.
+ * @param string $bytes
+ */
+ public function write($bytes)
+ {
+ $to_add = str_split($bytes);
+ foreach ($to_add as $value)
+ {
+ $this->_array[] = $value;
+ }
+ $this->_arraySize = count($this->_array);
+
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->write($bytes);
+ }
+ }
+
+ /**
+ * Not used.
+ */
+ public function commit()
+ {
+ }
+
+ /**
+ * Attach $is to this stream.
+ * The stream acts as an observer, receiving all data that is written.
+ * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function bind(Swift_InputByteStream $is)
+ {
+ $this->_mirrors[] = $is;
+ }
+
+ /**
+ * Remove an already bound stream.
+ * If $is is not bound, no errors will be raised.
+ * If the stream currently has any buffered data it will be written to $is
+ * before unbinding occurs.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function unbind(Swift_InputByteStream $is)
+ {
+ foreach ($this->_mirrors as $k => $stream)
+ {
+ if ($is === $stream)
+ {
+ unset($this->_mirrors[$k]);
+ }
+ }
+ }
+
+ /**
+ * Move the internal read pointer to $byteOffset in the stream.
+ * @param int $byteOffset
+ * @return boolean
+ */
+ public function setReadPointer($byteOffset)
+ {
+ if ($byteOffset > $this->_arraySize)
+ {
+ $byteOffset = $this->_arraySize;
+ }
+ elseif ($byteOffset < 0)
+ {
+ $byteOffset = 0;
+ }
+
+ $this->_offset = $byteOffset;
+ }
+
+ /**
+ * Flush the contents of the stream (empty it) and set the internal pointer
+ * to the beginning.
+ */
+ public function flushBuffers()
+ {
+ $this->_offset = 0;
+ $this->_array = array();
+ $this->_arraySize = 0;
+
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->flushBuffers();
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php b/External/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php
new file mode 100755
index 0000000..14773c2
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/ByteStream/AbstractFilterableInputStream.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/FileStream.php';
+//@require 'Swift/IoException.php';
+
+/**
+ * Allows reading and writing of bytes to and from a file.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+class Swift_ByteStream_FileByteStream
+ extends Swift_ByteStream_AbstractFilterableInputStream
+ implements Swift_FileStream
+{
+
+ /** The internal pointer offset */
+ private $_offset = 0;
+
+ /** The path to the file */
+ private $_path;
+
+ /** The mode this file is opened in for writing */
+ private $_mode;
+
+ /** A lazy-loaded resource handle for reading the file */
+ private $_reader;
+
+ /** A lazy-loaded resource handle for writing the file */
+ private $_writer;
+
+ /** If magic_quotes_runtime is on, this will be true */
+ private $_quotes = false;
+
+ /**
+ * Create a new FileByteStream for $path.
+ * @param string $path
+ * @param string $writable if true
+ */
+ public function __construct($path, $writable = false)
+ {
+ $this->_path = $path;
+ $this->_mode = $writable ? 'w+b' : 'rb';
+ $this->_quotes = get_magic_quotes_runtime();
+ }
+
+ /**
+ * Get the complete path to the file.
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->_path;
+ }
+
+ /**
+ * Reads $length bytes from the stream into a string and moves the pointer
+ * through the stream by $length. If less bytes exist than are requested the
+ * remaining bytes are given instead. If no bytes are remaining at all, boolean
+ * false is returned.
+ * @param int $length
+ * @return string
+ * @throws Swift_IoException
+ */
+ public function read($length)
+ {
+ $fp = $this->_getReadHandle();
+ if (!feof($fp))
+ {
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(0);
+ }
+ $bytes = fread($fp, $length);
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(1);
+ }
+ $this->_offset = ftell($fp);
+ return $bytes;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Move the internal read pointer to $byteOffset in the stream.
+ * @param int $byteOffset
+ * @return boolean
+ */
+ public function setReadPointer($byteOffset)
+ {
+ if (isset($this->_reader))
+ {
+ fseek($this->_reader, $byteOffset, SEEK_SET);
+ }
+ $this->_offset = $byteOffset;
+ }
+
+ // -- Private methods
+
+ /** Just write the bytes to the file */
+ protected function _commit($bytes)
+ {
+ fwrite($this->_getWriteHandle(), $bytes);
+ $this->_resetReadHandle();
+ }
+
+ /** Not used */
+ protected function _flush()
+ {
+ }
+
+ /** Get the resource for reading */
+ private function _getReadHandle()
+ {
+ if (!isset($this->_reader))
+ {
+ if (!$this->_reader = fopen($this->_path, 'rb'))
+ {
+ throw new Swift_IoException(
+ 'Unable to open file for reading [' . $this->_path . ']'
+ );
+ }
+ fseek($this->_reader, $this->_offset, SEEK_SET);
+ }
+ return $this->_reader;
+ }
+
+ /** Get the resource for writing */
+ private function _getWriteHandle()
+ {
+ if (!isset($this->_writer))
+ {
+ if (!$this->_writer = fopen($this->_path, $this->_mode))
+ {
+ throw new Swift_IoException(
+ 'Unable to open file for writing [' . $this->_path . ']'
+ );
+ }
+ }
+ return $this->_writer;
+ }
+
+ /** Force a reload of the resource for writing */
+ private function _resetWriteHandle()
+ {
+ if (isset($this->_writer))
+ {
+ fclose($this->_writer);
+ $this->_writer = null;
+ }
+ }
+
+ /** Force a reload of the resource for reading */
+ private function _resetReadHandle()
+ {
+ if (isset($this->_reader))
+ {
+ fclose($this->_reader);
+ $this->_reader = null;
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReader.php b/External/swiftmailer/lib/classes/Swift/CharacterReader.php
new file mode 100755
index 0000000..53d39ec
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReader.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Analyzes characters for a specific character set.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ * @author Xavier De Cock <xdecock@gmail.com>
+ */
+interface Swift_CharacterReader
+{
+ const MAP_TYPE_INVALID = 0x01;
+ const MAP_TYPE_FIXED_LEN = 0x02;
+ const MAP_TYPE_POSITIONS = 0x03;
+
+ /**
+ * Returns the complete charactermap
+ *
+ * @param string $string
+ * @param int $startOffset
+ * @param array $currentMap
+ * @param mixed $ignoredChars
+ * @return int
+ */
+ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars);
+
+ /**
+ * Returns mapType
+ * @int mapType
+ */
+ public function getMapType();
+
+ /**
+ * Returns an integer which specifies how many more bytes to read.
+ * A positive integer indicates the number of more bytes to fetch before invoking
+ * this method again.
+ * A value of zero means this is already a valid character.
+ * A value of -1 means this cannot possibly be a valid character.
+ * @param int[] $bytes
+ * @return int
+ */
+ public function validateByteSequence($bytes, $size);
+
+ /**
+ * Returns the number of bytes which should be read to start each character.
+ * For fixed width character sets this should be the number of
+ * octets-per-character. For multibyte character sets this will probably be 1.
+ * @return int
+ */
+ public function getInitialByteSize();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php b/External/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php
new file mode 100755
index 0000000..26b13ff
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterReader.php';
+
+/**
+ * Provides fixed-width byte sizes for reading fixed-width character sets.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ * @author Xavier De Cock <xdecock@gmail.com>
+ */
+class Swift_CharacterReader_GenericFixedWidthReader
+ implements Swift_CharacterReader
+{
+
+ /**
+ * The number of bytes in a single character.
+ * @var int
+ * @access private
+ */
+ private $_width;
+
+ /**
+ * Creates a new GenericFixedWidthReader using $width bytes per character.
+ * @param int $width
+ */
+ public function __construct($width)
+ {
+ $this->_width = $width;
+ }
+
+ /**
+ * Returns the complete charactermap
+ *
+ * @param string $string
+ * @param int $startOffset
+ * @param array $currentMap
+ * @param mixed $ignoredChars
+ * @return $int
+ */
+ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
+ {
+ $strlen = strlen($string);
+ // % and / are CPU intensive, so, maybe find a better way
+ $ignored = $strlen%$this->_width;
+ $ignoredChars = substr($string, - $ignored);
+ $currentMap = $this->_width;
+ return ($strlen - $ignored)/$this->_width;
+
+ }
+
+ /**
+ * Returns mapType
+ * @int mapType
+ */
+ public function getMapType()
+ {
+ return self::MAP_TYPE_FIXED_LEN;
+ }
+
+ /**
+ * Returns an integer which specifies how many more bytes to read.
+ * A positive integer indicates the number of more bytes to fetch before invoking
+ * this method again.
+ * A value of zero means this is already a valid character.
+ * A value of -1 means this cannot possibly be a valid character.
+ * @param string $bytes
+ * @return int
+ */
+ public function validateByteSequence($bytes, $size)
+ {
+ $needed = $this->_width - $size;
+ return ($needed > -1)
+ ? $needed
+ : -1
+ ;
+ }
+
+ /**
+ * Returns the number of bytes which should be read to start each character.
+ * @return int
+ */
+ public function getInitialByteSize()
+ {
+ return $this->_width;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php b/External/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php
new file mode 100755
index 0000000..3e0228a
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterReader.php';
+
+/**
+ * Analyzes US-ASCII characters.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_CharacterReader_UsAsciiReader
+ implements Swift_CharacterReader
+{
+ /**
+ * Returns the complete charactermap
+ *
+ * @param string $string
+ * @param int $startOffset
+ * @param string $ignoredChars
+ */
+ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
+ {
+ $strlen=strlen($string);
+ $ignoredChars='';
+ for( $i = 0; $i < $strlen; ++$i)
+ {
+ if ($string[$i]>"\x07F")
+ { // Invalid char
+ $currentMap[$i+$startOffset]=$string[$i];
+ }
+ }
+ return $strlen;
+ }
+
+ /**
+ * Returns mapType
+ * @int mapType
+ */
+ public function getMapType()
+ {
+ return self::MAP_TYPE_INVALID;
+ }
+
+ /**
+ * Returns an integer which specifies how many more bytes to read.
+ * A positive integer indicates the number of more bytes to fetch before invoking
+ * this method again.
+ * A value of zero means this is already a valid character.
+ * A value of -1 means this cannot possibly be a valid character.
+ * @param string $bytes
+ * @return int
+ */
+ public function validateByteSequence($bytes, $size)
+ {
+ $byte = reset($bytes);
+ if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the number of bytes which should be read to start each character.
+ * @return int
+ */
+ public function getInitialByteSize()
+ {
+ return 1;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php b/External/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php
new file mode 100755
index 0000000..54ea9a4
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php
@@ -0,0 +1,183 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterReader.php';
+
+/**
+ * Analyzes UTF-8 characters.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ * @author Xavier De Cock <xdecock@gmail.com>
+ */
+class Swift_CharacterReader_Utf8Reader
+ implements Swift_CharacterReader
+{
+
+ /** Pre-computed for optimization */
+ private static $length_map=array(
+//N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x0N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x1N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x2N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x3N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x4N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x5N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x6N
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x7N
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x8N
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x9N
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xAN
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xBN
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xCN
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xDN
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, //0xEN
+ 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0 //0xFN
+ );
+ private static $s_length_map=array(
+ "\x00"=>1, "\x01"=>1, "\x02"=>1, "\x03"=>1, "\x04"=>1, "\x05"=>1, "\x06"=>1, "\x07"=>1,
+ "\x08"=>1, "\x09"=>1, "\x0a"=>1, "\x0b"=>1, "\x0c"=>1, "\x0d"=>1, "\x0e"=>1, "\x0f"=>1,
+ "\x10"=>1, "\x11"=>1, "\x12"=>1, "\x13"=>1, "\x14"=>1, "\x15"=>1, "\x16"=>1, "\x17"=>1,
+ "\x18"=>1, "\x19"=>1, "\x1a"=>1, "\x1b"=>1, "\x1c"=>1, "\x1d"=>1, "\x1e"=>1, "\x1f"=>1,
+ "\x20"=>1, "\x21"=>1, "\x22"=>1, "\x23"=>1, "\x24"=>1, "\x25"=>1, "\x26"=>1, "\x27"=>1,
+ "\x28"=>1, "\x29"=>1, "\x2a"=>1, "\x2b"=>1, "\x2c"=>1, "\x2d"=>1, "\x2e"=>1, "\x2f"=>1,
+ "\x30"=>1, "\x31"=>1, "\x32"=>1, "\x33"=>1, "\x34"=>1, "\x35"=>1, "\x36"=>1, "\x37"=>1,
+ "\x38"=>1, "\x39"=>1, "\x3a"=>1, "\x3b"=>1, "\x3c"=>1, "\x3d"=>1, "\x3e"=>1, "\x3f"=>1,
+ "\x40"=>1, "\x41"=>1, "\x42"=>1, "\x43"=>1, "\x44"=>1, "\x45"=>1, "\x46"=>1, "\x47"=>1,
+ "\x48"=>1, "\x49"=>1, "\x4a"=>1, "\x4b"=>1, "\x4c"=>1, "\x4d"=>1, "\x4e"=>1, "\x4f"=>1,
+ "\x50"=>1, "\x51"=>1, "\x52"=>1, "\x53"=>1, "\x54"=>1, "\x55"=>1, "\x56"=>1, "\x57"=>1,
+ "\x58"=>1, "\x59"=>1, "\x5a"=>1, "\x5b"=>1, "\x5c"=>1, "\x5d"=>1, "\x5e"=>1, "\x5f"=>1,
+ "\x60"=>1, "\x61"=>1, "\x62"=>1, "\x63"=>1, "\x64"=>1, "\x65"=>1, "\x66"=>1, "\x67"=>1,
+ "\x68"=>1, "\x69"=>1, "\x6a"=>1, "\x6b"=>1, "\x6c"=>1, "\x6d"=>1, "\x6e"=>1, "\x6f"=>1,
+ "\x70"=>1, "\x71"=>1, "\x72"=>1, "\x73"=>1, "\x74"=>1, "\x75"=>1, "\x76"=>1, "\x77"=>1,
+ "\x78"=>1, "\x79"=>1, "\x7a"=>1, "\x7b"=>1, "\x7c"=>1, "\x7d"=>1, "\x7e"=>1, "\x7f"=>1,
+ "\x80"=>0, "\x81"=>0, "\x82"=>0, "\x83"=>0, "\x84"=>0, "\x85"=>0, "\x86"=>0, "\x87"=>0,
+ "\x88"=>0, "\x89"=>0, "\x8a"=>0, "\x8b"=>0, "\x8c"=>0, "\x8d"=>0, "\x8e"=>0, "\x8f"=>0,
+ "\x90"=>0, "\x91"=>0, "\x92"=>0, "\x93"=>0, "\x94"=>0, "\x95"=>0, "\x96"=>0, "\x97"=>0,
+ "\x98"=>0, "\x99"=>0, "\x9a"=>0, "\x9b"=>0, "\x9c"=>0, "\x9d"=>0, "\x9e"=>0, "\x9f"=>0,
+ "\xa0"=>0, "\xa1"=>0, "\xa2"=>0, "\xa3"=>0, "\xa4"=>0, "\xa5"=>0, "\xa6"=>0, "\xa7"=>0,
+ "\xa8"=>0, "\xa9"=>0, "\xaa"=>0, "\xab"=>0, "\xac"=>0, "\xad"=>0, "\xae"=>0, "\xaf"=>0,
+ "\xb0"=>0, "\xb1"=>0, "\xb2"=>0, "\xb3"=>0, "\xb4"=>0, "\xb5"=>0, "\xb6"=>0, "\xb7"=>0,
+ "\xb8"=>0, "\xb9"=>0, "\xba"=>0, "\xbb"=>0, "\xbc"=>0, "\xbd"=>0, "\xbe"=>0, "\xbf"=>0,
+ "\xc0"=>2, "\xc1"=>2, "\xc2"=>2, "\xc3"=>2, "\xc4"=>2, "\xc5"=>2, "\xc6"=>2, "\xc7"=>2,
+ "\xc8"=>2, "\xc9"=>2, "\xca"=>2, "\xcb"=>2, "\xcc"=>2, "\xcd"=>2, "\xce"=>2, "\xcf"=>2,
+ "\xd0"=>2, "\xd1"=>2, "\xd2"=>2, "\xd3"=>2, "\xd4"=>2, "\xd5"=>2, "\xd6"=>2, "\xd7"=>2,
+ "\xd8"=>2, "\xd9"=>2, "\xda"=>2, "\xdb"=>2, "\xdc"=>2, "\xdd"=>2, "\xde"=>2, "\xdf"=>2,
+ "\xe0"=>3, "\xe1"=>3, "\xe2"=>3, "\xe3"=>3, "\xe4"=>3, "\xe5"=>3, "\xe6"=>3, "\xe7"=>3,
+ "\xe8"=>3, "\xe9"=>3, "\xea"=>3, "\xeb"=>3, "\xec"=>3, "\xed"=>3, "\xee"=>3, "\xef"=>3,
+ "\xf0"=>4, "\xf1"=>4, "\xf2"=>4, "\xf3"=>4, "\xf4"=>4, "\xf5"=>4, "\xf6"=>4, "\xf7"=>4,
+ "\xf8"=>5, "\xf9"=>5, "\xfa"=>5, "\xfb"=>5, "\xfc"=>6, "\xfd"=>6, "\xfe"=>0, "\xff"=>0,
+ );
+
+ /**
+ * Returns the complete charactermap
+ *
+ * @param string $string
+ * @param int $startOffset
+ * @param array $currentMap
+ * @param mixed $ignoredChars
+ */
+ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
+ {
+ if (!isset($currentMap['i']) || !isset($currentMap['p']))
+ {
+ $currentMap['p'] = $currentMap['i'] = array();
+ }
+ $strlen=strlen($string);
+ $charPos=count($currentMap['p']);
+ $foundChars=0;
+ $invalid=false;
+ for ($i=0; $i<$strlen; ++$i)
+ {
+ $char=$string[$i];
+ $size=self::$s_length_map[$char];
+ if ($size==0)
+ {
+ /* char is invalid, we must wait for a resync */
+ $invalid=true;
+ continue;
+ }
+ else
+ {
+ if ($invalid==true)
+ {
+ /* We mark the chars as invalid and start a new char */
+ $currentMap['p'][$charPos+$foundChars]=$startOffset+$i;
+ $currentMap['i'][$charPos+$foundChars]=true;
+ ++$foundChars;
+ $invalid=false;
+ }
+ if (($i+$size) > $strlen){
+ $ignoredChars=substr($string, $i);
+ break;
+ }
+ for ($j=1; $j<$size; ++$j)
+ {
+ $char=$string[$i+$j];
+ if ($char>"\x7F" && $char<"\xC0")
+ {
+ // Valid - continue parsing
+ }
+ else
+ {
+ /* char is invalid, we must wait for a resync */
+ $invalid=true;
+ continue 2;
+ }
+ }
+ /* Ok we got a complete char here */
+ $lastChar=$currentMap['p'][$charPos+$foundChars]=$startOffset+$i+$size;
+ $i+=$j-1;
+ ++$foundChars;
+ }
+ }
+ return $foundChars;
+ }
+
+ /**
+ * Returns mapType
+ * @int mapType
+ */
+ public function getMapType()
+ {
+ return self::MAP_TYPE_POSITIONS;
+ }
+
+ /**
+ * Returns an integer which specifies how many more bytes to read.
+ * A positive integer indicates the number of more bytes to fetch before invoking
+ * this method again.
+ * A value of zero means this is already a valid character.
+ * A value of -1 means this cannot possibly be a valid character.
+ * @param string $bytes
+ * @return int
+ */
+ public function validateByteSequence($bytes, $size)
+ {
+ if ($size<1){
+ return -1;
+ }
+ $needed = self::$length_map[$bytes[0]] - $size;
+ return ($needed > -1)
+ ? $needed
+ : -1
+ ;
+ }
+
+ /**
+ * Returns the number of bytes which should be read to start each character.
+ * @return int
+ */
+ public function getInitialByteSize()
+ {
+ return 1;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php b/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php
new file mode 100755
index 0000000..9e01de1
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterReader.php';
+
+/**
+ * A factory for creating CharacterReaders.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+interface Swift_CharacterReaderFactory
+{
+
+ /**
+ * Returns a CharacterReader suitable for the charset applied.
+ * @param string $charset
+ * @return Swift_CharacterReader
+ */
+ public function getReaderFor($charset);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php b/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php
new file mode 100755
index 0000000..a6f9f94
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterReaderFactory.php';
+
+/**
+ * Standard factory for creating CharacterReaders.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory
+ implements Swift_CharacterReaderFactory
+{
+
+ /**
+ * A map of charset patterns to their implementation classes.
+ * @var array
+ * @access private
+ */
+ private $_map = array();
+
+ /**
+ * Factories which have already been loaded.
+ * @var Swift_CharacterReaderFactory[]
+ * @access private
+ */
+ private $_loaded = array();
+
+ /**
+ * Creates a new CharacterReaderFactory.
+ */
+ public function __construct()
+ {
+ $prefix = 'Swift_CharacterReader_';
+
+ $singleByte = array(
+ 'class' => $prefix . 'GenericFixedWidthReader',
+ 'constructor' => array(1)
+ );
+
+ $doubleByte = array(
+ 'class' => $prefix . 'GenericFixedWidthReader',
+ 'constructor' => array(2)
+ );
+
+ $fourBytes = array(
+ 'class' => $prefix . 'GenericFixedWidthReader',
+ 'constructor' => array(4)
+ );
+
+ //Utf-8
+ $this->_map['utf-?8'] = array(
+ 'class' => $prefix . 'Utf8Reader',
+ 'constructor' => array()
+ );
+
+ //7-8 bit charsets
+ $this->_map['(us-)?ascii'] = $singleByte;
+ $this->_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte;
+ $this->_map['windows-?125[0-9]'] = $singleByte;
+ $this->_map['cp-?[0-9]+'] = $singleByte;
+ $this->_map['ansi'] = $singleByte;
+ $this->_map['macintosh'] = $singleByte;
+ $this->_map['koi-?7'] = $singleByte;
+ $this->_map['koi-?8-?.+'] = $singleByte;
+ $this->_map['mik'] = $singleByte;
+ $this->_map['(cork|t1)'] = $singleByte;
+ $this->_map['v?iscii'] = $singleByte;
+
+ //16 bits
+ $this->_map['(ucs-?2|utf-?16)'] = $doubleByte;
+
+ //32 bits
+ $this->_map['(ucs-?4|utf-?32)'] = $fourBytes;
+
+ //Fallback
+ $this->_map['.*'] = $singleByte;
+ }
+
+ /**
+ * Returns a CharacterReader suitable for the charset applied.
+ * @param string $charset
+ * @return Swift_CharacterReader
+ */
+ public function getReaderFor($charset)
+ {
+ $charset = trim(strtolower($charset));
+ foreach ($this->_map as $pattern => $spec)
+ {
+ $re = '/^' . $pattern . '$/D';
+ if (preg_match($re, $charset))
+ {
+ if (!array_key_exists($pattern, $this->_loaded))
+ {
+ $reflector = new ReflectionClass($spec['class']);
+ if ($reflector->getConstructor())
+ {
+ $reader = $reflector->newInstanceArgs($spec['constructor']);
+ }
+ else
+ {
+ $reader = $reflector->newInstance();
+ }
+ $this->_loaded[$pattern] = $reader;
+ }
+ return $this->_loaded[$pattern];
+ }
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterStream.php b/External/swiftmailer/lib/classes/Swift/CharacterStream.php
new file mode 100755
index 0000000..bf91528
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterStream.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once dirname(__FILE__) . '/OutputByteStream.php';
+require_once dirname(__FILE__) . '/CharacterReaderFactory.php';
+
+
+/**
+ * An abstract means of reading and writing data in terms of characters as opposed
+ * to bytes.
+ * Classes implementing this interface may use a subsystem which requires less
+ * memory than working with large strings of data.
+ * @package Swift
+ * @subpackage CharacterStream
+ * @author Chris Corbyn
+ */
+interface Swift_CharacterStream
+{
+
+ /**
+ * Set the character set used in this CharacterStream.
+ * @param string $charset
+ */
+ public function setCharacterSet($charset);
+
+ /**
+ * Set the CharacterReaderFactory for multi charset support.
+ * @param Swift_CharacterReaderFactory $factory
+ */
+ public function setCharacterReaderFactory(
+ Swift_CharacterReaderFactory $factory);
+
+ /**
+ * Overwrite this character stream using the byte sequence in the byte stream.
+ * @param Swift_OutputByteStream $os output stream to read from
+ */
+ public function importByteStream(Swift_OutputByteStream $os);
+
+ /**
+ * Import a string a bytes into this CharacterStream, overwriting any existing
+ * data in the stream.
+ * @param string $string
+ */
+ public function importString($string);
+
+ /**
+ * Read $length characters from the stream and move the internal pointer
+ * $length further into the stream.
+ * @param int $length
+ * @return string
+ */
+ public function read($length);
+
+ /**
+ * Read $length characters from the stream and return a 1-dimensional array
+ * containing there octet values.
+ * @param int $length
+ * @return int[]
+ */
+ public function readBytes($length);
+
+ /**
+ * Write $chars to the end of the stream.
+ * @param string $chars
+ */
+ public function write($chars);
+
+ /**
+ * Move the internal pointer to $charOffset in the stream.
+ * @param int $charOffset
+ */
+ public function setPointer($charOffset);
+
+ /**
+ * Empty the stream and reset the internal pointer.
+ */
+ public function flushContents();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php b/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php
new file mode 100755
index 0000000..9612365
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php
@@ -0,0 +1,319 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/CharacterStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+
+/**
+ * A CharacterStream implementation which stores characters in an internal array.
+ * @package Swift
+ * @subpackage CharacterStream
+ * @author Chris Corbyn
+ */
+class Swift_CharacterStream_ArrayCharacterStream
+ implements Swift_CharacterStream
+{
+
+ /** A map of byte values and their respective characters */
+ private static $_charMap;
+
+ /** A map of characters and their derivative byte values */
+ private static $_byteMap;
+
+ /** The char reader (lazy-loaded) for the current charset */
+ private $_charReader;
+
+ /** A factory for creatiing CharacterReader instances */
+ private $_charReaderFactory;
+
+ /** The character set this stream is using */
+ private $_charset;
+
+ /** Array of characters */
+ private $_array = array();
+
+ /** Size of the array of character */
+ private $_array_size = array();
+
+ /** The current character offset in the stream */
+ private $_offset = 0;
+
+ /**
+ * Create a new CharacterStream with the given $chars, if set.
+ * @param Swift_CharacterReaderFactory $factory for loading validators
+ * @param string $charset used in the stream
+ */
+ public function __construct(Swift_CharacterReaderFactory $factory,
+ $charset)
+ {
+ self::_initializeMaps();
+ $this->setCharacterReaderFactory($factory);
+ $this->setCharacterSet($charset);
+ }
+
+ /**
+ * Set the character set used in this CharacterStream.
+ * @param string $charset
+ */
+ public function setCharacterSet($charset)
+ {
+ $this->_charset = $charset;
+ $this->_charReader = null;
+ }
+
+ /**
+ * Set the CharacterReaderFactory for multi charset support.
+ * @param Swift_CharacterReaderFactory $factory
+ */
+ public function setCharacterReaderFactory(
+ Swift_CharacterReaderFactory $factory)
+ {
+ $this->_charReaderFactory = $factory;
+ }
+
+ /**
+ * Overwrite this character stream using the byte sequence in the byte stream.
+ * @param Swift_OutputByteStream $os output stream to read from
+ */
+ public function importByteStream(Swift_OutputByteStream $os)
+ {
+ if (!isset($this->_charReader))
+ {
+ $this->_charReader = $this->_charReaderFactory
+ ->getReaderFor($this->_charset);
+ }
+
+ $startLength = $this->_charReader->getInitialByteSize();
+ while (false !== $bytes = $os->read($startLength))
+ {
+ $c = array();
+ for ($i = 0, $len = strlen($bytes); $i < $len; ++$i)
+ {
+ $c[] = self::$_byteMap[$bytes[$i]];
+ }
+ $size = count($c);
+ $need = $this->_charReader
+ ->validateByteSequence($c, $size);
+ if ($need > 0 &&
+ false !== $bytes = $os->read($need))
+ {
+ for ($i = 0, $len = strlen($bytes); $i < $len; ++$i)
+ {
+ $c[] = self::$_byteMap[$bytes[$i]];
+ }
+ }
+ $this->_array[] = $c;
+ ++$this->_array_size;
+ }
+ }
+
+ /**
+ * Import a string a bytes into this CharacterStream, overwriting any existing
+ * data in the stream.
+ * @param string $string
+ */
+ public function importString($string)
+ {
+ $this->flushContents();
+ $this->write($string);
+ }
+
+ /**
+ * Read $length characters from the stream and move the internal pointer
+ * $length further into the stream.
+ * @param int $length
+ * @return string
+ */
+ public function read($length)
+ {
+ if ($this->_offset == $this->_array_size)
+ {
+ return false;
+ }
+
+ // Don't use array slice
+ $arrays = array();
+ $end = $length + $this->_offset;
+ for ($i = $this->_offset; $i < $end; ++$i)
+ {
+ if (!isset($this->_array[$i]))
+ {
+ break;
+ }
+ $arrays[] = $this->_array[$i];
+ }
+ $this->_offset += $i - $this->_offset; // Limit function calls
+ $chars = false;
+ foreach ($arrays as $array)
+ {
+ $chars .= implode('', array_map('chr', $array));
+ }
+ return $chars;
+ }
+
+ /**
+ * Read $length characters from the stream and return a 1-dimensional array
+ * containing there octet values.
+ * @param int $length
+ * @return int[]
+ */
+ public function readBytes($length)
+ {
+ if ($this->_offset == $this->_array_size)
+ {
+ return false;
+ }
+ $arrays = array();
+ $end = $length + $this->_offset;
+ for ($i = $this->_offset; $i < $end; ++$i)
+ {
+ if (!isset($this->_array[$i]))
+ {
+ break;
+ }
+ $arrays[] = $this->_array[$i];
+ }
+ $this->_offset += ($i - $this->_offset); // Limit function calls
+ return call_user_func_array('array_merge', $arrays);
+ }
+
+ /**
+ * Write $chars to the end of the stream.
+ * @param string $chars
+ */
+ public function write($chars)
+ {
+ if (!isset($this->_charReader))
+ {
+ $this->_charReader = $this->_charReaderFactory->getReaderFor(
+ $this->_charset);
+ }
+
+ $startLength = $this->_charReader->getInitialByteSize();
+
+ $fp = fopen('php://memory', 'w+b');
+ fwrite($fp, $chars);
+ unset($chars);
+ fseek($fp, 0, SEEK_SET);
+
+ $buffer = array(0);
+ $buf_pos = 1;
+ $buf_len = 1;
+ $has_datas = true;
+ do
+ {
+ $bytes = array();
+ // Buffer Filing
+ if ($buf_len - $buf_pos < $startLength)
+ {
+ $buf = array_splice($buffer, $buf_pos);
+ $new = $this->_reloadBuffer($fp, 100);
+ if ($new)
+ {
+ $buffer = array_merge($buf, $new);
+ $buf_len = count($buffer);
+ $buf_pos = 0;
+ }
+ else
+ {
+ $has_datas = false;
+ }
+ }
+ if ($buf_len - $buf_pos > 0)
+ {
+ $size = 0;
+ for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i)
+ {
+ ++$size;
+ $bytes[] = $buffer[$buf_pos++];
+ }
+ $need = $this->_charReader->validateByteSequence(
+ $bytes, $size);
+ if ($need > 0)
+ {
+ if ($buf_len - $buf_pos < $need)
+ {
+ $new = $this->_reloadBuffer($fp, $need);
+
+ if ($new)
+ {
+ $buffer = array_merge($buffer, $new);
+ $buf_len = count($buffer);
+ }
+ }
+ for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i)
+ {
+ $bytes[] = $buffer[$buf_pos++];
+ }
+ }
+ $this->_array[] = $bytes;
+ ++$this->_array_size;
+ }
+ }
+ while ($has_datas);
+
+ fclose($fp);
+ }
+
+ /**
+ * Move the internal pointer to $charOffset in the stream.
+ * @param int $charOffset
+ */
+ public function setPointer($charOffset)
+ {
+ if ($charOffset > $this->_array_size)
+ {
+ $charOffset = $this->_array_size;
+ }
+ elseif ($charOffset < 0)
+ {
+ $charOffset = 0;
+ }
+ $this->_offset = $charOffset;
+ }
+
+ /**
+ * Empty the stream and reset the internal pointer.
+ */
+ public function flushContents()
+ {
+ $this->_offset = 0;
+ $this->_array = array();
+ $this->_array_size = 0;
+ }
+
+ private function _reloadBuffer($fp, $len)
+ {
+ if (!feof($fp) && ($bytes = fread($fp, $len)) !== false)
+ {
+ $buf = array();
+ for ($i = 0, $len = strlen($bytes); $i < $len; ++$i)
+ {
+ $buf[] = self::$_byteMap[$bytes[$i]];
+ }
+ return $buf;
+ }
+ return false;
+ }
+
+ private static function _initializeMaps()
+ {
+ if (!isset(self::$_charMap))
+ {
+ self::$_charMap = array();
+ for ($byte = 0; $byte < 256; ++$byte)
+ {
+ self::$_charMap[$byte] = chr($byte);
+ }
+ self::$_byteMap = array_flip(self::$_charMap);
+ }
+ }
+}
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php b/External/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php
new file mode 100755
index 0000000..f090aa7
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php
@@ -0,0 +1,300 @@
+<?php
+
+/*
+ CharacterStream implementation using an array in Swift Mailer.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+//@require 'Swift/CharacterStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+
+/**
+ * A CharacterStream implementation which stores characters in an internal array.
+ * @package Swift
+ * @subpackage CharacterStream
+ * @author Xavier De Cock <xdecock@gmail.com>
+ */
+
+Class Swift_CharacterStream_NgCharacterStream
+ implements Swift_CharacterStream
+{
+
+ /**
+ * The char reader (lazy-loaded) for the current charset.
+ * @var Swift_CharacterReader
+ * @access private
+ */
+ private $_charReader;
+
+ /**
+ * A factory for creatiing CharacterReader instances.
+ * @var Swift_CharacterReaderFactory
+ * @access private
+ */
+ private $_charReaderFactory;
+
+ /**
+ * The character set this stream is using.
+ * @var string
+ * @access private
+ */
+ private $_charset;
+
+ /**
+ * The datas stored as is
+ *
+ * @var string
+ */
+ private $_datas = "";
+
+ /**
+ * Number of bytes in the stream
+ *
+ * @var int
+ */
+ private $_datasSize = 0;
+
+ /**
+ * Map
+ *
+ * @var mixed
+ */
+ private $_map;
+
+ /**
+ * Map Type
+ *
+ * @var int
+ */
+ private $_mapType = 0;
+
+ /**
+ * Number of characters in the stream
+ *
+ * @var int
+ */
+ private $_charCount = 0;
+
+ /**
+ * Position in the stream
+ *
+ * @var unknown_type
+ */
+ private $_currentPos = 0;
+
+ /**
+ * The constructor
+ *
+ * @param Swift_CharacterReaderFactory $factory
+ * @param unknown_type $charset
+ */
+ public function __construct(Swift_CharacterReaderFactory $factory,
+ $charset)
+ {
+ $this->setCharacterReaderFactory($factory);
+ $this->setCharacterSet($charset);
+ }
+
+ /* -- Changing parameters of the stream -- */
+
+ /**
+ * Set the character set used in this CharacterStream.
+ * @param string $charset
+ */
+ public function setCharacterSet($charset)
+ {
+ $this->_charset = $charset;
+ $this->_charReader = null;
+ $this->_mapType = 0;
+ }
+
+ /**
+ * Set the CharacterReaderFactory for multi charset support.
+ * @param Swift_CharacterReaderFactory $factory
+ */
+ public function setCharacterReaderFactory(
+ Swift_CharacterReaderFactory $factory)
+ {
+ $this->_charReaderFactory = $factory;
+ }
+
+ /**
+ * @see Swift_CharacterStream::flushContents()
+ *
+ */
+ public function flushContents()
+ {
+ $this->_datas = null;
+ $this->_map = null;
+ $this->_charCount = 0;
+ $this->_currentPos = 0;
+ $this->_datasSize = 0;
+ }
+
+ /**
+ * @see Swift_CharacterStream::importByteStream()
+ *
+ * @param Swift_OutputByteStream $os
+ */
+ public function importByteStream(Swift_OutputByteStream $os)
+ {
+ $this->flushContents();
+ $blocks=512;
+ $os->setReadPointer(0);
+ while(false!==($read = $os->read($blocks)))
+ $this->write($read);
+ }
+
+ /**
+ * @see Swift_CharacterStream::importString()
+ *
+ * @param string $string
+ */
+ public function importString($string)
+ {
+ $this->flushContents();
+ $this->write($string);
+ }
+
+ /**
+ * @see Swift_CharacterStream::read()
+ *
+ * @param int $length
+ * @return string
+ */
+ public function read($length)
+ {
+ if ($this->_currentPos>=$this->_charCount)
+ {
+ return false;
+ }
+ $ret=false;
+ $length = ($this->_currentPos+$length > $this->_charCount)
+ ? $this->_charCount - $this->_currentPos
+ : $length;
+ switch ($this->_mapType)
+ {
+ case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
+ $len = $length*$this->_map;
+ $ret = substr($this->_datas,
+ $this->_currentPos * $this->_map,
+ $len);
+ $this->_currentPos += $length;
+ break;
+
+ case Swift_CharacterReader::MAP_TYPE_INVALID:
+ $end = $this->_currentPos + $length;
+ $end = $end > $this->_charCount
+ ?$this->_charCount
+ :$end;
+ $ret = '';
+ for (; $this->_currentPos < $length; ++$this->_currentPos)
+ {
+ if (isset ($this->_map[$this->_currentPos]))
+ {
+ $ret .= '?';
+ }
+ else
+ {
+ $ret .= $this->_datas[$this->_currentPos];
+ }
+ }
+ break;
+
+ case Swift_CharacterReader::MAP_TYPE_POSITIONS:
+ $end = $this->_currentPos + $length;
+ $end = $end > $this->_charCount
+ ?$this->_charCount
+ :$end;
+ $ret = '';
+ $start = 0;
+ if ($this->_currentPos>0)
+ {
+ $start = $this->_map['p'][$this->_currentPos-1];
+ }
+ $to = $start;
+ for (; $this->_currentPos < $end; ++$this->_currentPos)
+ {
+ if (isset($this->_map['i'][$this->_currentPos])) {
+ $ret .= substr($this->_datas, $start, $to - $start).'?';
+ $start = $this->_map['p'][$this->_currentPos];
+ } else {
+ $to = $this->_map['p'][$this->_currentPos];
+ }
+ }
+ $ret .= substr($this->_datas, $start, $to - $start);
+ break;
+ }
+ return $ret;
+ }
+
+ /**
+ * @see Swift_CharacterStream::readBytes()
+ *
+ * @param int $length
+ * @return int[]
+ */
+ public function readBytes($length)
+ {
+ $read=$this->read($length);
+ if ($read!==false)
+ {
+ $ret = array_map('ord', str_split($read, 1));
+ return $ret;
+ }
+ return false;
+ }
+
+ /**
+ * @see Swift_CharacterStream::setPointer()
+ *
+ * @param int $charOffset
+ */
+ public function setPointer($charOffset)
+ {
+ if ($this->_charCount<$charOffset){
+ $charOffset=$this->_charCount;
+ }
+ $this->_currentPos = $charOffset;
+ }
+
+ /**
+ * @see Swift_CharacterStream::write()
+ *
+ * @param string $chars
+ */
+ public function write($chars)
+ {
+ if (!isset($this->_charReader))
+ {
+ $this->_charReader = $this->_charReaderFactory->getReaderFor(
+ $this->_charset);
+ $this->_map = array();
+ $this->_mapType = $this->_charReader->getMapType();
+ }
+ $ignored='';
+ $this->_datas .= $chars;
+ $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored);
+ if ($ignored!==false) {
+ $this->_datasSize=strlen($this->_datas)-strlen($ignored);
+ }
+ else
+ {
+ $this->_datasSize=strlen($this->_datas);
+ }
+ }
+} \ No newline at end of file
diff --git a/External/swiftmailer/lib/classes/Swift/DependencyContainer.php b/External/swiftmailer/lib/classes/Swift/DependencyContainer.php
new file mode 100755
index 0000000..b6ba554
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/DependencyContainer.php
@@ -0,0 +1,349 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/DependencyException.php';
+
+/**
+ * Dependency Injection container.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_DependencyContainer
+{
+
+ /** Constant for literal value types */
+ const TYPE_VALUE = 0x0001;
+
+ /** Constant for new instance types */
+ const TYPE_INSTANCE = 0x0010;
+
+ /** Constant for shared instance types */
+ const TYPE_SHARED = 0x0100;
+
+ /** Constant for aliases */
+ const TYPE_ALIAS = 0x1000;
+
+ /** Singleton instance */
+ private static $_instance = null;
+
+ /** The data container */
+ private $_store = array();
+
+ /** The current endpoint in the data container */
+ private $_endPoint;
+
+ /**
+ * Constructor should not be used.
+ * Use {@link getInstance()} instead.
+ */
+ public function __construct() { }
+
+ /**
+ * Returns a singleton of the DependencyContainer.
+ * @return Swift_DependencyContainer
+ */
+ public static function getInstance()
+ {
+ if (!isset(self::$_instance))
+ {
+ self::$_instance = new self();
+ }
+ return self::$_instance;
+ }
+
+ /**
+ * List the names of all items stored in the Container.
+ * @return array
+ */
+ public function listItems()
+ {
+ return array_keys($this->_store);
+ }
+
+ /**
+ * Test if an item is registered in this container with the given name.
+ * @param string $itemName
+ * @return boolean
+ * @see register()
+ */
+ public function has($itemName)
+ {
+ return array_key_exists($itemName, $this->_store)
+ && isset($this->_store[$itemName]['lookupType']);
+ }
+
+ /**
+ * Lookup the item with the given $itemName.
+ * @param string $itemName
+ * @return mixed
+ * @throws Swift_DependencyException If the dependency is not found
+ * @see register()
+ */
+ public function lookup($itemName)
+ {
+ if (!$this->has($itemName))
+ {
+ throw new Swift_DependencyException(
+ 'Cannot lookup dependency "' . $itemName . '" since it is not registered.'
+ );
+ }
+
+ switch ($this->_store[$itemName]['lookupType'])
+ {
+ case self::TYPE_ALIAS:
+ return $this->_createAlias($itemName);
+ case self::TYPE_VALUE:
+ return $this->_getValue($itemName);
+ case self::TYPE_INSTANCE:
+ return $this->_createNewInstance($itemName);
+ case self::TYPE_SHARED:
+ return $this->_createSharedInstance($itemName);
+ }
+ }
+
+ /**
+ * Create an array of arguments passed to the constructor of $itemName.
+ * @param string $itemName
+ * @return array
+ */
+ public function createDependenciesFor($itemName)
+ {
+ $args = array();
+ if (isset($this->_store[$itemName]['args']))
+ {
+ $args = $this->_resolveArgs($this->_store[$itemName]['args']);
+ }
+ return $args;
+ }
+
+ /**
+ * Register a new dependency with $itemName.
+ * This method returns the current DependencyContainer instance because it
+ * requires the use of the fluid interface to set the specific details for the
+ * dependency.
+ *
+ * @param string $itemName
+ * @return Swift_DependencyContainer
+ * @see asNewInstanceOf(), asSharedInstanceOf(), asValue()
+ */
+ public function register($itemName)
+ {
+ $this->_store[$itemName] = array();
+ $this->_endPoint =& $this->_store[$itemName];
+ return $this;
+ }
+
+ /**
+ * Specify the previously registered item as a literal value.
+ * {@link register()} must be called before this will work.
+ *
+ * @param mixed $value
+ * @return Swift_DependencyContainer
+ */
+ public function asValue($value)
+ {
+ $endPoint =& $this->_getEndPoint();
+ $endPoint['lookupType'] = self::TYPE_VALUE;
+ $endPoint['value'] = $value;
+ return $this;
+ }
+
+ /**
+ * Specify the previously registered item as an alias of another item.
+ * @param string $lookup
+ * @return Swift_DependencyContainer
+ */
+ public function asAliasOf($lookup)
+ {
+ $endPoint =& $this->_getEndPoint();
+ $endPoint['lookupType'] = self::TYPE_ALIAS;
+ $endPoint['ref'] = $lookup;
+ return $this;
+ }
+
+ /**
+ * Specify the previously registered item as a new instance of $className.
+ * {@link register()} must be called before this will work.
+ * Any arguments can be set with {@link withDependencies()},
+ * {@link addConstructorValue()} or {@link addConstructorLookup()}.
+ *
+ * @param string $className
+ * @return Swift_DependencyContainer
+ * @see withDependencies(), addConstructorValue(), addConstructorLookup()
+ */
+ public function asNewInstanceOf($className)
+ {
+ $endPoint =& $this->_getEndPoint();
+ $endPoint['lookupType'] = self::TYPE_INSTANCE;
+ $endPoint['className'] = $className;
+ return $this;
+ }
+
+ /**
+ * Specify the previously registered item as a shared instance of $className.
+ * {@link register()} must be called before this will work.
+ * @param string $className
+ * @return Swift_DependencyContainer
+ */
+ public function asSharedInstanceOf($className)
+ {
+ $endPoint =& $this->_getEndPoint();
+ $endPoint['lookupType'] = self::TYPE_SHARED;
+ $endPoint['className'] = $className;
+ return $this;
+ }
+
+ /**
+ * Specify a list of injected dependencies for the previously registered item.
+ * This method takes an array of lookup names.
+ *
+ * @param array $lookups
+ * @return Swift_DependencyContainer
+ * @see addConstructorValue(), addConstructorLookup()
+ */
+ public function withDependencies(array $lookups)
+ {
+ $endPoint =& $this->_getEndPoint();
+ $endPoint['args'] = array();
+ foreach ($lookups as $lookup)
+ {
+ $this->addConstructorLookup($lookup);
+ }
+ return $this;
+ }
+
+ /**
+ * Specify a literal (non looked up) value for the constructor of the
+ * previously registered item.
+ *
+ * @param mixed $value
+ * @return Swift_DependencyContainer
+ * @see withDependencies(), addConstructorLookup()
+ */
+ public function addConstructorValue($value)
+ {
+ $endPoint =& $this->_getEndPoint();
+ if (!isset($endPoint['args']))
+ {
+ $endPoint['args'] = array();
+ }
+ $endPoint['args'][] = array('type' => 'value', 'item' => $value);
+ return $this;
+ }
+
+ /**
+ * Specify a dependency lookup for the constructor of the previously
+ * registered item.
+ *
+ * @param string $lookup
+ * @return Swift_DependencyContainer
+ * @see withDependencies(), addConstructorValue()
+ */
+ public function addConstructorLookup($lookup)
+ {
+ $endPoint =& $this->_getEndPoint();
+ if (!isset($this->_endPoint['args']))
+ {
+ $endPoint['args'] = array();
+ }
+ $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup);
+ return $this;
+ }
+
+ // -- Private methods
+
+ /** Get the literal value with $itemName */
+ private function _getValue($itemName)
+ {
+ return $this->_store[$itemName]['value'];
+ }
+
+ /** Resolve an alias to another item */
+ private function _createAlias($itemName)
+ {
+ return $this->lookup($this->_store[$itemName]['ref']);
+ }
+
+ /** Create a fresh instance of $itemName */
+ private function _createNewInstance($itemName)
+ {
+ $reflector = new ReflectionClass($this->_store[$itemName]['className']);
+ if ($reflector->getConstructor())
+ {
+ return $reflector->newInstanceArgs(
+ $this->createDependenciesFor($itemName)
+ );
+ }
+ else
+ {
+ return $reflector->newInstance();
+ }
+ }
+
+ /** Create and register a shared instance of $itemName */
+ private function _createSharedInstance($itemName)
+ {
+ if (!isset($this->_store[$itemName]['instance']))
+ {
+ $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName);
+ }
+ return $this->_store[$itemName]['instance'];
+ }
+
+ /** Get the current endpoint in the store */
+ private function &_getEndPoint()
+ {
+ if (!isset($this->_endPoint))
+ {
+ throw new BadMethodCallException(
+ 'Component must first be registered by calling register()'
+ );
+ }
+ return $this->_endPoint;
+ }
+
+ /** Get an argument list with dependencies resolved */
+ private function _resolveArgs(array $args)
+ {
+ $resolved = array();
+ foreach ($args as $argDefinition)
+ {
+ switch ($argDefinition['type'])
+ {
+ case 'lookup':
+ $resolved[] = $this->_lookupRecursive($argDefinition['item']);
+ break;
+ case 'value':
+ $resolved[] = $argDefinition['item'];
+ break;
+ }
+ }
+ return $resolved;
+ }
+
+ /** Resolve a single dependency with an collections */
+ private function _lookupRecursive($item)
+ {
+ if (is_array($item))
+ {
+ $collection = array();
+ foreach ($item as $k => $v)
+ {
+ $collection[$k] = $this->_lookupRecursive($v);
+ }
+ return $collection;
+ }
+ else
+ {
+ return $this->lookup($item);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/DependencyException.php b/External/swiftmailer/lib/classes/Swift/DependencyException.php
new file mode 100755
index 0000000..bb1681c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/DependencyException.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/SwiftException.php';
+
+/**
+ * DependencyException thrown when a requested dependeny is missing.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_DependencyException extends Swift_SwiftException
+{
+
+ /**
+ * Create a new DependencyException with $message.
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/EmbeddedFile.php b/External/swiftmailer/lib/classes/Swift/EmbeddedFile.php
new file mode 100755
index 0000000..34d096c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/EmbeddedFile.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Attachment.php';
+//@require 'Swift/DependencyContainer.php';
+//@require 'Swift/ByteStream/FileByteStream.php';
+
+/**
+ * An embedded file, in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_EmbeddedFile extends Swift_Mime_EmbeddedFile
+{
+
+ /**
+ * Create a new EmbeddedFile.
+ * Details may be optionally provided to the constructor.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ */
+ public function __construct($data = null, $filename = null,
+ $contentType = null)
+ {
+ call_user_func_array(
+ array($this, 'Swift_Mime_EmbeddedFile::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('mime.embeddedfile')
+ );
+
+ $this->setBody($data);
+ $this->setFilename($filename);
+ if ($contentType)
+ {
+ $this->setContentType($contentType);
+ }
+ }
+
+ /**
+ * Create a new EmbeddedFile.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ * @return Swift_Mime_EmbeddedFile
+ */
+ public static function newInstance($data = null, $filename = null,
+ $contentType = null)
+ {
+ return new self($data, $filename, $contentType);
+ }
+
+ /**
+ * Create a new EmbeddedFile from a filesystem path.
+ * @param string $path
+ * @return Swift_Mime_EmbeddedFile
+ */
+ public static function fromPath($path)
+ {
+ return self::newInstance()->setFile(
+ new Swift_ByteStream_FileByteStream($path)
+ );
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Encoder.php b/External/swiftmailer/lib/classes/Swift/Encoder.php
new file mode 100755
index 0000000..32aa96a
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Encoder.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/CharsetObserver.php';
+
+/**
+ * Interface for all Encoder schemes.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+interface Swift_Encoder extends Swift_Mime_CharsetObserver
+{
+
+ /**
+ * Encode a given string to produce an encoded string.
+ * @param string $string
+ * @param int $firstLineOffset if first line needs to be shorter
+ * @param int $maxLineLength - 0 indicates the default length for this encoding
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php b/External/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php
new file mode 100755
index 0000000..09c71ba
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Encoder.php';
+
+/**
+ * Handles Base 64 Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_Encoder_Base64Encoder implements Swift_Encoder
+{
+
+ /**
+ * Takes an unencoded string and produces a Base64 encoded string from it.
+ * Base64 encoded strings have a maximum line length of 76 characters.
+ * If the first line needs to be shorter, indicate the difference with
+ * $firstLineOffset.
+ * @param string $string to encode
+ * @param int $firstLineOffset
+ * @param int $maxLineLength, optional, 0 indicates the default of 76 bytes
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ if (0 >= $maxLineLength || 76 < $maxLineLength)
+ {
+ $maxLineLength = 76;
+ }
+
+ $encodedString = base64_encode($string);
+ $firstLine = '';
+
+ if (0 != $firstLineOffset)
+ {
+ $firstLine = substr(
+ $encodedString, 0, $maxLineLength - $firstLineOffset
+ ) . "\r\n";
+ $encodedString = substr(
+ $encodedString, $maxLineLength - $firstLineOffset
+ );
+ }
+
+ return $firstLine . trim(chunk_split($encodedString, $maxLineLength, "\r\n"));
+ }
+
+ /**
+ * Does nothing.
+ */
+ public function charsetChanged($charset)
+ {
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php b/External/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php
new file mode 100755
index 0000000..6914f6c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php
@@ -0,0 +1,263 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Encoder.php';
+//@require 'Swift/CharacterStream.php';
+
+/**
+ * Handles Quoted Printable (QP) Encoding in Swift Mailer.
+ * Possibly the most accurate RFC 2045 QP implementation found in PHP.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_Encoder_QpEncoder implements Swift_Encoder
+{
+
+ /**
+ * The CharacterStream used for reading characters (as opposed to bytes).
+ * @var Swift_CharacterStream
+ * @access protected
+ */
+ protected $_charStream;
+
+ /**
+ * A filter used if input should be canonicalized.
+ * @var Swift_StreamFilter
+ * @access protected
+ */
+ protected $_filter;
+
+ /**
+ * Pre-computed QP for HUGE optmization.
+ * @var string[]
+ * @access protected
+ */
+ protected static $_qpMap = array(
+ 0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04',
+ 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09',
+ 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E',
+ 15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13',
+ 20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18',
+ 25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D',
+ 30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22',
+ 35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27',
+ 40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C',
+ 45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31',
+ 50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36',
+ 55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B',
+ 60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40',
+ 65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45',
+ 70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A',
+ 75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F',
+ 80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54',
+ 85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59',
+ 90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E',
+ 95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63',
+ 100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68',
+ 105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D',
+ 110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72',
+ 115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77',
+ 120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C',
+ 125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81',
+ 130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86',
+ 135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B',
+ 140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90',
+ 145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95',
+ 150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A',
+ 155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F',
+ 160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4',
+ 165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9',
+ 170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE',
+ 175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3',
+ 180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8',
+ 185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD',
+ 190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2',
+ 195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7',
+ 200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC',
+ 205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1',
+ 210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6',
+ 215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB',
+ 220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0',
+ 225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5',
+ 230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA',
+ 235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF',
+ 240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4',
+ 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9',
+ 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE',
+ 255 => '=FF'
+ );
+
+ /**
+ * A map of non-encoded ascii characters.
+ * @var string[]
+ * @access protected
+ */
+ protected static $_safeMap = array();
+
+ /**
+ * Creates a new QpEncoder for the given CharacterStream.
+ * @param Swift_CharacterStream $charStream to use for reading characters
+ * @param Swift_StreamFilter $filter if input should be canonicalized
+ */
+ public function __construct(Swift_CharacterStream $charStream,
+ Swift_StreamFilter $filter = null)
+ {
+ $this->_charStream = $charStream;
+ if (empty(self::$_safeMap))
+ {
+ foreach (array_merge(
+ array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte)
+ {
+ self::$_safeMap[$byte] = chr($byte);
+ }
+ }
+ $this->_filter = $filter;
+ }
+
+ /**
+ * Takes an unencoded string and produces a QP encoded string from it.
+ * QP encoded strings have a maximum line length of 76 characters.
+ * If the first line needs to be shorter, indicate the difference with
+ * $firstLineOffset.
+ * @param string $string to encode
+ * @param int $firstLineOffset, optional
+ * @param int $maxLineLength, optional, 0 indicates the default of 76 chars
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ if ($maxLineLength > 76 || $maxLineLength <= 0)
+ {
+ $maxLineLength = 76;
+ }
+
+ $thisLineLength = $maxLineLength - $firstLineOffset;
+
+ $lines = array();
+ $lNo = 0;
+ $lines[$lNo] = '';
+ $currentLine =& $lines[$lNo++];
+ $size=$lineLen=0;
+
+ $this->_charStream->flushContents();
+ $this->_charStream->importString($string);
+
+ //Fetching more than 4 chars at one is slower, as is fetching fewer bytes
+ // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6
+ // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes
+ while (false !== $bytes = $this->_nextSequence())
+ {
+ //If we're filtering the input
+ if (isset($this->_filter))
+ {
+ //If we can't filter because we need more bytes
+ while ($this->_filter->shouldBuffer($bytes))
+ {
+ //Then collect bytes into the buffer
+ if (false === $moreBytes = $this->_nextSequence(1))
+ {
+ break;
+ }
+
+ foreach ($moreBytes as $b)
+ {
+ $bytes[] = $b;
+ }
+ }
+ //And filter them
+ $bytes = $this->_filter->filter($bytes);
+ }
+
+ $enc = $this->_encodeByteSequence($bytes, $size);
+ if ($currentLine && $lineLen+$size >= $thisLineLength)
+ {
+ $lines[$lNo] = '';
+ $currentLine =& $lines[$lNo++];
+ $thisLineLength = $maxLineLength;
+ $lineLen=0;
+ }
+ $lineLen+=$size;
+ $currentLine .= $enc;
+ }
+
+ return $this->_standardize(implode("=\r\n", $lines));
+ }
+
+ /**
+ * Updates the charset used.
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->_charStream->setCharacterSet($charset);
+ }
+
+ // -- Protected methods
+
+ /**
+ * Encode the given byte array into a verbatim QP form.
+ * @param int[] $bytes
+ * @return string
+ * @access protected
+ */
+ protected function _encodeByteSequence(array $bytes, &$size)
+ {
+ $ret = '';
+ $size=0;
+ foreach ($bytes as $b)
+ {
+ if (isset(self::$_safeMap[$b]))
+ {
+ $ret .= self::$_safeMap[$b];
+ ++$size;
+ }
+ else
+ {
+ $ret .= self::$_qpMap[$b];
+ $size+=3;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Get the next sequence of bytes to read from the char stream.
+ * @param int $size number of bytes to read
+ * @return int[]
+ * @access protected
+ */
+ protected function _nextSequence($size = 4)
+ {
+ return $this->_charStream->readBytes($size);
+ }
+
+ /**
+ * Make sure CRLF is correct and HT/SPACE are in valid places.
+ * @param string $string
+ * @return string
+ * @access protected
+ */
+ protected function _standardize($string)
+ {
+ $string = str_replace(array("\t=0D=0A", " =0D=0A", "=0D=0A"),
+ array("=09\r\n", "=20\r\n", "\r\n"), $string
+ );
+ switch ($end = ord(substr($string, -1)))
+ {
+ case 0x09:
+ case 0x20:
+ $string = substr_replace($string, self::$_qpMap[$end], -1);
+ }
+ return $string;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php b/External/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php
new file mode 100755
index 0000000..febc6ba
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Encoder.php';
+//@require 'Swift/CharacterStream.php';
+
+/**
+ * Handles RFC 2231 specified Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_Encoder_Rfc2231Encoder implements Swift_Encoder
+{
+
+ /**
+ * A character stream to use when reading a string as characters instead of bytes.
+ * @var Swift_CharacterStream
+ * @access private
+ */
+ private $_charStream;
+
+ /**
+ * Creates a new Rfc2231Encoder using the given character stream instance.
+ * @param Swift_CharacterStream
+ */
+ public function __construct(Swift_CharacterStream $charStream)
+ {
+ $this->_charStream = $charStream;
+ }
+
+ /**
+ * Takes an unencoded string and produces a string encoded according to
+ * RFC 2231 from it.
+ * @param string $string to encode
+ * @param int $firstLineOffset
+ * @param int $maxLineLength, optional, 0 indicates the default of 75 bytes
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ $lines = array(); $lineCount = 0;
+ $lines[] = '';
+ $currentLine =& $lines[$lineCount++];
+
+ if (0 >= $maxLineLength)
+ {
+ $maxLineLength = 75;
+ }
+
+ $this->_charStream->flushContents();
+ $this->_charStream->importString($string);
+
+ $thisLineLength = $maxLineLength - $firstLineOffset;
+
+ while (false !== $char = $this->_charStream->read(4))
+ {
+ $encodedChar = rawurlencode($char);
+ if (0 != strlen($currentLine)
+ && strlen($currentLine . $encodedChar) > $thisLineLength)
+ {
+ $lines[] = '';
+ $currentLine =& $lines[$lineCount++];
+ $thisLineLength = $maxLineLength;
+ }
+ $currentLine .= $encodedChar;
+ }
+
+ return implode("\r\n", $lines);
+ }
+
+ /**
+ * Updates the charset used.
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->_charStream->setCharacterSet($charset);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Encoding.php b/External/swiftmailer/lib/classes/Swift/Encoding.php
new file mode 100755
index 0000000..1849a82
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Encoding.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Provides quick access to each encoding type.
+ *
+ * @package Swift
+ * @subpackage Encoder
+ * @author Chris Corbyn
+ */
+class Swift_Encoding
+{
+
+ /**
+ * Get the Encoder that provides 7-bit encoding.
+ *
+ * @return Swift_Mime_ContentEncoder
+ */
+ public static function get7BitEncoding()
+ {
+ return self::_lookup('mime.7bitcontentencoder');
+ }
+
+ /**
+ * Get the Encoder that provides 8-bit encoding.
+ *
+ * @return Swift_Mime_ContentEncoder
+ */
+ public static function get8BitEncoding()
+ {
+ return self::_lookup('mime.8bitcontentencoder');
+ }
+
+ /**
+ * Get the Encoder that provides Quoted-Printable (QP) encoding.
+ *
+ * @return Swift_Mime_ContentEncoder
+ */
+ public static function getQpEncoding()
+ {
+ return self::_lookup('mime.qpcontentencoder');
+ }
+
+ /**
+ * Get the Encoder that provides Base64 encoding.
+ *
+ * @return Swift_Mime_ContentEncoder
+ */
+ public static function getBase64Encoding()
+ {
+ return self::_lookup('mime.base64contentencoder');
+ }
+
+ // -- Private Static Methods
+
+ private static function _lookup($key)
+ {
+ return Swift_DependencyContainer::getInstance()->lookup($key);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/CommandEvent.php b/External/swiftmailer/lib/classes/Swift/Events/CommandEvent.php
new file mode 100755
index 0000000..73eb585
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/CommandEvent.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventObject.php';
+//@require 'Swift/Transport.php';
+
+/**
+ * Generated when a command is sent over an SMTP connection.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_CommandEvent extends Swift_Events_EventObject
+{
+
+ /**
+ * The command sent to the server.
+ * @var string
+ */
+ private $_command;
+
+ /**
+ * An array of codes which a successful response will contain.
+ * @var int[]
+ */
+ private $_successCodes = array();
+
+ /**
+ * Create a new CommandEvent for $source with $command.
+ * @param Swift_Transport $source
+ * @param string $command
+ * @param array $successCodes
+ */
+ public function __construct(Swift_Transport $source,
+ $command, $successCodes = array())
+ {
+ parent::__construct($source);
+ $this->_command = $command;
+ $this->_successCodes = $successCodes;
+ }
+
+ /**
+ * Get the command which was sent to the server.
+ * @return string
+ */
+ public function getCommand()
+ {
+ return $this->_command;
+ }
+
+ /**
+ * Get the numeric response codes which indicate success for this command.
+ * @return int[]
+ */
+ public function getSuccessCodes()
+ {
+ return $this->_successCodes;
+ }
+
+} \ No newline at end of file
diff --git a/External/swiftmailer/lib/classes/Swift/Events/CommandListener.php b/External/swiftmailer/lib/classes/Swift/Events/CommandListener.php
new file mode 100755
index 0000000..2fd7117
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/CommandListener.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/CommandEvent.php';
+
+/**
+ * Listens for Transports to send commands to the server.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_CommandListener extends Swift_Events_EventListener
+{
+
+ /**
+ * Invoked immediately following a command being sent.
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function commandSent(Swift_Events_CommandEvent $evt);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/Event.php b/External/swiftmailer/lib/classes/Swift/Events/Event.php
new file mode 100755
index 0000000..c6726a7
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/Event.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * The minimum interface for an Event.
+ *
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_Event
+{
+
+ /**
+ * Get the source object of this event.
+ * @return object
+ */
+ public function getSource();
+
+ /**
+ * Prevent this Event from bubbling any further up the stack.
+ * @param boolean $cancel, optional
+ */
+ public function cancelBubble($cancel = true);
+
+ /**
+ * Returns true if this Event will not bubble any further up the stack.
+ * @return boolean
+ */
+ public function bubbleCancelled();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php b/External/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php
new file mode 100755
index 0000000..aaf1211
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Event.php';
+
+/**
+ * Interface for the EventDispatcher which handles the event dispatching layer.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_EventDispatcher
+{
+
+ /**
+ * Create a new SendEvent for $source and $message.
+ * @param Swift_Transport $source
+ * @param Swift_Mime_Message
+ * @return Swift_Events_SendEvent
+ */
+ public function createSendEvent(Swift_Transport $source,
+ Swift_Mime_Message $message);
+
+ /**
+ * Create a new CommandEvent for $source and $command.
+ * @param Swift_Transport $source
+ * @param string $command That will be executed
+ * @param array $successCodes That are needed
+ * @return Swift_Events_CommandEvent
+ */
+ public function createCommandEvent(Swift_Transport $source,
+ $command, $successCodes = array());
+
+ /**
+ * Create a new ResponseEvent for $source and $response.
+ * @param Swift_Transport $source
+ * @param string $response
+ * @param boolean $valid If the response is valid
+ * @return Swift_Events_ResponseEvent
+ */
+ public function createResponseEvent(Swift_Transport $source,
+ $response, $valid);
+
+ /**
+ * Create a new TransportChangeEvent for $source.
+ * @param Swift_Transport $source
+ * @return Swift_Events_TransportChangeEvent
+ */
+ public function createTransportChangeEvent(Swift_Transport $source);
+
+ /**
+ * Create a new TransportExceptionEvent for $source.
+ * @param Swift_Transport $source
+ * @param Swift_TransportException $ex
+ * @return Swift_Events_TransportExceptionEvent
+ */
+ public function createTransportExceptionEvent(Swift_Transport $source,
+ Swift_TransportException $ex);
+
+ /**
+ * Bind an event listener to this dispatcher.
+ * @param Swift_Events_EventListener $listener
+ */
+ public function bindEventListener(Swift_Events_EventListener $listener);
+
+ /**
+ * Dispatch the given Event to all suitable listeners.
+ * @param Swift_Events_EventObject $evt
+ * @param string $target method
+ */
+ public function dispatchEvent(Swift_Events_EventObject $evt, $target);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/EventListener.php b/External/swiftmailer/lib/classes/Swift/Events/EventListener.php
new file mode 100755
index 0000000..00fb799
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/EventListener.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An identity interface which all EventListeners must extend.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_EventListener
+{
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/EventObject.php b/External/swiftmailer/lib/classes/Swift/Events/EventObject.php
new file mode 100755
index 0000000..5d494fe
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/EventObject.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/Event.php';
+
+/**
+ * A base Event which all Event classes inherit from.
+ *
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_EventObject implements Swift_Events_Event
+{
+
+ /** The source of this Event */
+ private $_source;
+
+ /** The state of this Event (should it bubble up the stack?) */
+ private $_bubbleCancelled = false;
+
+ /**
+ * Create a new EventObject originating at $source.
+ * @param object $source
+ */
+ public function __construct($source)
+ {
+ $this->_source = $source;
+ }
+
+ /**
+ * Get the source object of this event.
+ * @return object
+ */
+ public function getSource()
+ {
+ return $this->_source;
+ }
+
+ /**
+ * Prevent this Event from bubbling any further up the stack.
+ * @param boolean $cancel, optional
+ */
+ public function cancelBubble($cancel = true)
+ {
+ $this->_bubbleCancelled = $cancel;
+ }
+
+ /**
+ * Returns true if this Event will not bubble any further up the stack.
+ * @return boolean
+ */
+ public function bubbleCancelled()
+ {
+ return $this->_bubbleCancelled;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php b/External/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php
new file mode 100755
index 0000000..addf9e7
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventObject.php';
+
+/**
+ * Generated when a response is received on a SMTP connection.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_ResponseEvent extends Swift_Events_EventObject
+{
+
+ /**
+ * The overall result.
+ * @var boolean
+ */
+ private $_valid;
+
+ /**
+ * The response received from the server.
+ * @var string
+ */
+ private $_response;
+
+ /**
+ * Create a new ResponseEvent for $source and $response.
+ * @param Swift_Transport $source
+ * @param string $response
+ * @param boolean $valid
+ */
+ public function __construct(Swift_Transport $source, $response, $valid = false)
+ {
+ parent::__construct($source);
+ $this->_response = $response;
+ $this->_valid = $valid;
+ }
+
+ /**
+ * Get the response which was received from the server.
+ * @return string
+ */
+ public function getResponse()
+ {
+ return $this->_response;
+ }
+
+ /**
+ * Get the success status of this Event.
+ * @return boolean
+ */
+ public function isValid()
+ {
+ return $this->_valid;
+ }
+
+} \ No newline at end of file
diff --git a/External/swiftmailer/lib/classes/Swift/Events/ResponseListener.php b/External/swiftmailer/lib/classes/Swift/Events/ResponseListener.php
new file mode 100755
index 0000000..092385b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/ResponseListener.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/ResponseEvent.php';
+
+/**
+ * Listens for responses from a remote SMTP server.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_ResponseListener extends Swift_Events_EventListener
+{
+
+ /**
+ * Invoked immediately following a response coming back.
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $evt);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/SendEvent.php b/External/swiftmailer/lib/classes/Swift/Events/SendEvent.php
new file mode 100755
index 0000000..49a8351
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/SendEvent.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventObject.php';
+
+/**
+ * Generated when a message is being sent.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_SendEvent extends Swift_Events_EventObject
+{
+
+ /** Sending has yet to occur */
+ const RESULT_PENDING = 0x0001;
+
+ /** Sending was successful */
+ const RESULT_SUCCESS = 0x0010;
+
+ /** Sending worked, but there were some failures */
+ const RESULT_TENTATIVE = 0x0100;
+
+ /** Sending failed */
+ const RESULT_FAILED = 0x1000;
+
+ /**
+ * The Message being sent.
+ * @var Swift_Mime_Message
+ */
+ private $_message;
+
+ /**
+ * The Transport used in sending.
+ * @var Swift_Transport
+ */
+ private $_transport;
+
+ /**
+ * Any recipients which failed after sending.
+ * @var string[]
+ */
+ private $failedRecipients = array();
+
+ /**
+ * The overall result as a bitmask from the class constants.
+ * @var int
+ */
+ private $result;
+
+ /**
+ * Create a new SendEvent for $source and $message.
+ * @param Swift_Transport $source
+ * @param Swift_Mime_Message $message
+ */
+ public function __construct(Swift_Transport $source,
+ Swift_Mime_Message $message)
+ {
+ parent::__construct($source);
+ $this->_message = $message;
+ $this->_result = self::RESULT_PENDING;
+ }
+
+ /**
+ * Get the Transport used to send the Message.
+ * @return Swift_Transport
+ */
+ public function getTransport()
+ {
+ return $this->getSource();
+ }
+
+ /**
+ * Get the Message being sent.
+ * @return Swift_Mime_Message
+ */
+ public function getMessage()
+ {
+ return $this->_message;
+ }
+
+ /**
+ * Set the array of addresses that failed in sending.
+ * @param array $recipients
+ */
+ public function setFailedRecipients($recipients)
+ {
+ $this->_failedRecipients = $recipients;
+ }
+
+ /**
+ * Get an recipient addresses which were not accepted for delivery.
+ * @return string[]
+ */
+ public function getFailedRecipients()
+ {
+ return $this->_failedRecipients;
+ }
+
+ /**
+ * Set the result of sending.
+ * @return int
+ */
+ public function setResult($result)
+ {
+ $this->_result = $result;
+ }
+
+ /**
+ * Get the result of this Event.
+ * The return value is a bitmask from
+ * {@link RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED}
+ * @return int
+ */
+ public function getResult()
+ {
+ return $this->_result;
+ }
+
+} \ No newline at end of file
diff --git a/External/swiftmailer/lib/classes/Swift/Events/SendListener.php b/External/swiftmailer/lib/classes/Swift/Events/SendListener.php
new file mode 100755
index 0000000..a8f0cc3
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/SendListener.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/SendEvent.php';
+
+/**
+ * Listens for Messages being sent from within the Transport system.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_SendListener extends Swift_Events_EventListener
+{
+
+ /**
+ * Invoked immediately before the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt);
+
+ /**
+ * Invoked immediately after the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php b/External/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php
new file mode 100755
index 0000000..3e6c0be
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php
@@ -0,0 +1,175 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventDispatcher.php';
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/EventObject.php';
+//@require 'Swift/Events/CommandEvent.php';
+//@require 'Swift/Events/ResponseEvent.php';
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Events/TransportChangeEvent.php';
+//@require 'Swift/Events/TransportExceptionEvent.php';
+
+/**
+ * The EventDispatcher which handles the event dispatching layer.
+ *
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher
+{
+
+ /** A map of event types to their associated listener types */
+ private $_eventMap = array();
+
+ /** Event listeners bound to this dispatcher */
+ private $_listeners = array();
+
+ /** Listeners queued to have an Event bubbled up the stack to them */
+ private $_bubbleQueue = array();
+
+ /**
+ * Create a new EventDispatcher.
+ */
+ public function __construct()
+ {
+ $this->_eventMap = array(
+ 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener',
+ 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener',
+ 'Swift_Events_SendEvent' => 'Swift_Events_SendListener',
+ 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener',
+ 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener'
+ );
+ }
+
+ /**
+ * Create a new SendEvent for $source and $message.
+ *
+ * @param Swift_Transport $source
+ * @param Swift_Mime_Message
+ * @return Swift_Events_SendEvent
+ */
+ public function createSendEvent(Swift_Transport $source,
+ Swift_Mime_Message $message)
+ {
+ return new Swift_Events_SendEvent($source, $message);
+ }
+
+ /**
+ * Create a new CommandEvent for $source and $command.
+ *
+ * @param Swift_Transport $source
+ * @param string $command That will be executed
+ * @param array $successCodes That are needed
+ * @return Swift_Events_CommandEvent
+ */
+ public function createCommandEvent(Swift_Transport $source,
+ $command, $successCodes = array())
+ {
+ return new Swift_Events_CommandEvent($source, $command, $successCodes);
+ }
+
+ /**
+ * Create a new ResponseEvent for $source and $response.
+ *
+ * @param Swift_Transport $source
+ * @param string $response
+ * @param boolean $valid If the response is valid
+ * @return Swift_Events_ResponseEvent
+ */
+ public function createResponseEvent(Swift_Transport $source,
+ $response, $valid)
+ {
+ return new Swift_Events_ResponseEvent($source, $response, $valid);
+ }
+
+ /**
+ * Create a new TransportChangeEvent for $source.
+ *
+ * @param Swift_Transport $source
+ * @return Swift_Events_TransportChangeEvent
+ */
+ public function createTransportChangeEvent(Swift_Transport $source)
+ {
+ return new Swift_Events_TransportChangeEvent($source);
+ }
+
+ /**
+ * Create a new TransportExceptionEvent for $source.
+ *
+ * @param Swift_Transport $source
+ * @param Swift_TransportException $ex
+ * @return Swift_Events_TransportExceptionEvent
+ */
+ public function createTransportExceptionEvent(Swift_Transport $source,
+ Swift_TransportException $ex)
+ {
+ return new Swift_Events_TransportExceptionEvent($source, $ex);
+ }
+
+ /**
+ * Bind an event listener to this dispatcher.
+ *
+ * @param Swift_Events_EventListener $listener
+ */
+ public function bindEventListener(Swift_Events_EventListener $listener)
+ {
+ foreach ($this->_listeners as $l)
+ {
+ //Already loaded
+ if ($l === $listener)
+ {
+ return;
+ }
+ }
+ $this->_listeners[] = $listener;
+ }
+
+ /**
+ * Dispatch the given Event to all suitable listeners.
+ *
+ * @param Swift_Events_EventObject $evt
+ * @param string $target method
+ */
+ public function dispatchEvent(Swift_Events_EventObject $evt, $target)
+ {
+ $this->_prepareBubbleQueue($evt);
+ $this->_bubble($evt, $target);
+ }
+
+ // -- Private methods
+
+ /** Queue listeners on a stack ready for $evt to be bubbled up it */
+ private function _prepareBubbleQueue(Swift_Events_EventObject $evt)
+ {
+ $this->_bubbleQueue = array();
+ $evtClass = get_class($evt);
+ foreach ($this->_listeners as $listener)
+ {
+ if (array_key_exists($evtClass, $this->_eventMap)
+ && ($listener instanceof $this->_eventMap[$evtClass]))
+ {
+ $this->_bubbleQueue[] = $listener;
+ }
+ }
+ }
+
+ /** Bubble $evt up the stack calling $target() on each listener */
+ private function _bubble(Swift_Events_EventObject $evt, $target)
+ {
+ if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue))
+ {
+ $listener->$target($evt);
+ $this->_bubble($evt, $target);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php b/External/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php
new file mode 100755
index 0000000..f069a4c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventObject.php';
+
+/**
+ * Generated when the state of a Transport is changed (i.e. stopped/started).
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_TransportChangeEvent extends Swift_Events_EventObject
+{
+
+ /**
+ * Get the Transport.
+ * @return Swift_Transport
+ */
+ public function getTransport()
+ {
+ return $this->getSource();
+ }
+
+} \ No newline at end of file
diff --git a/External/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php b/External/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php
new file mode 100755
index 0000000..ba729d0
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/TransportChangeEvent.php';
+
+/**
+ * Listens for changes within the Transport system.
+ *
+ * @package Swift
+ * @subpackage Events
+ *
+ * @author Chris Corbyn
+ */
+interface Swift_Events_TransportChangeListener extends Swift_Events_EventListener
+{
+
+ /**
+ * Invoked just before a Transport is started.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt);
+
+ /**
+ * Invoked immediately after the Transport is started.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function transportStarted(Swift_Events_TransportChangeEvent $evt);
+
+ /**
+ * Invoked just before a Transport is stopped.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt);
+
+ /**
+ * Invoked immediately after the Transport is stopped.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function transportStopped(Swift_Events_TransportChangeEvent $evt);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php b/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php
new file mode 100755
index 0000000..a1bf7d2
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventObject.php';
+//@require 'Swift/TransportException.php';
+
+/**
+ * Generated when a TransportException is thrown from the Transport system.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+class Swift_Events_TransportExceptionEvent extends Swift_Events_EventObject
+{
+
+ /**
+ * The Exception thrown.
+ * @var Swift_TransportException
+ */
+ private $_exception;
+
+ /**
+ * Create a new TransportExceptionEvent for $transport.
+ * @param Swift_Transport $transport
+ * @param Swift_TransportException $ex
+ */
+ public function __construct(Swift_Transport $transport,
+ Swift_TransportException $ex)
+ {
+ parent::__construct($transport);
+ $this->_exception = $ex;
+ }
+
+ /**
+ * Get the TransportException thrown.
+ * @return Swift_TransportException
+ */
+ public function getException()
+ {
+ return $this->_exception;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php b/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php
new file mode 100755
index 0000000..d6dce94
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/EventListener.php';
+//@require 'Swift/Events/TransportExceptionEvent.php';
+
+/**
+ * Listens for Exceptions thrown from within the Transport system.
+ * @package Swift
+ * @subpackage Events
+ * @author Chris Corbyn
+ */
+interface Swift_Events_TransportExceptionListener
+ extends Swift_Events_EventListener
+{
+
+ /**
+ * Invoked as a TransportException is thrown in the Transport system.
+ * @param Swift_Events_TransportExceptionEvent $evt
+ */
+ public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/FailoverTransport.php b/External/swiftmailer/lib/classes/Swift/FailoverTransport.php
new file mode 100755
index 0000000..6e6b7a8
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/FailoverTransport.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/FailoverTransport.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Contains a list of redundant Transports so when one fails, the next is used.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_FailoverTransport extends Swift_Transport_FailoverTransport
+{
+
+ /**
+ * Creates a new FailoverTransport with $transports.
+ * @param array $transports
+ */
+ public function __construct($transports = array())
+ {
+ call_user_func_array(
+ array($this, 'Swift_Transport_FailoverTransport::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('transport.failover')
+ );
+
+ $this->setTransports($transports);
+ }
+
+ /**
+ * Create a new FailoverTransport instance.
+ * @param string $transports
+ * @return Swift_FailoverTransport
+ */
+ public static function newInstance($transports = array())
+ {
+ return new self($transports);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/FileStream.php b/External/swiftmailer/lib/classes/Swift/FileStream.php
new file mode 100755
index 0000000..a7f894d
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/FileStream.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * An OutputByteStream which specifically reads from a file.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+interface Swift_FileStream extends Swift_OutputByteStream
+{
+
+ /**
+ * Get the complete path to the file.
+ * @return string
+ */
+ public function getPath();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Filterable.php b/External/swiftmailer/lib/classes/Swift/Filterable.php
new file mode 100755
index 0000000..c047967
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Filterable.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/StreamFilter.php';
+
+/**
+ * Allows StreamFilters to operate on a stream.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+interface Swift_Filterable
+{
+
+ /**
+ * Add a new StreamFilter, referenced by $key.
+ * @param Swift_StreamFilter $filter
+ * @param string $key
+ */
+ public function addFilter(Swift_StreamFilter $filter, $key);
+
+ /**
+ * Remove an existing filter using $key.
+ * @param string $key
+ */
+ public function removeFilter($key);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Image.php b/External/swiftmailer/lib/classes/Swift/Image.php
new file mode 100755
index 0000000..c161d7a
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Image.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Image.php';
+//@require 'Swift/ByteStream/FileByteStream.php';
+
+/**
+ * An image, embedded in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Image extends Swift_EmbeddedFile
+{
+
+ /**
+ * Create a new EmbeddedFile.
+ * Details may be optionally provided to the constructor.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ */
+ public function __construct($data = null, $filename = null,
+ $contentType = null)
+ {
+ parent::__construct($data, $filename, $contentType);
+ }
+
+ /**
+ * Create a new Image.
+ * @param string|Swift_OutputByteStream $data
+ * @param string $filename
+ * @param string $contentType
+ * @return Swift_Mime_EmbeddedFile
+ */
+ public static function newInstance($data = null, $filename = null,
+ $contentType = null)
+ {
+ return new self($data, $filename, $contentType);
+ }
+
+ /**
+ * Create a new Image from a filesystem path.
+ * @param string $path
+ * @return Swift_Mime_EmbeddedFile
+ */
+ public static function fromPath($path)
+ {
+ $image = self::newInstance()->setFile(
+ new Swift_ByteStream_FileByteStream($path)
+ );
+ return $image;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/InputByteStream.php b/External/swiftmailer/lib/classes/Swift/InputByteStream.php
new file mode 100755
index 0000000..e8f45f4
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/InputByteStream.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An abstract means of writing data.
+ * Classes implementing this interface may use a subsystem which requires less
+ * memory than working with large strings of data.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+interface Swift_InputByteStream
+{
+
+ /**
+ * Writes $bytes to the end of the stream.
+ *
+ * Writing may not happen immediately if the stream chooses to buffer. If
+ * you want to write these bytes with immediate effect, call {@link commit()}
+ * after calling write().
+ *
+ * This method returns the sequence ID of the write (i.e. 1 for first, 2 for
+ * second, etc etc).
+ *
+ * @param string $bytes
+ * @return int
+ * @throws Swift_IoException
+ */
+ public function write($bytes);
+
+ /**
+ * For any bytes that are currently buffered inside the stream, force them
+ * off the buffer.
+ *
+ * @throws Swift_IoException
+ */
+ public function commit();
+
+ /**
+ * Attach $is to this stream.
+ * The stream acts as an observer, receiving all data that is written.
+ * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function bind(Swift_InputByteStream $is);
+
+ /**
+ * Remove an already bound stream.
+ * If $is is not bound, no errors will be raised.
+ * If the stream currently has any buffered data it will be written to $is
+ * before unbinding occurs.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function unbind(Swift_InputByteStream $is);
+
+ /**
+ * Flush the contents of the stream (empty it) and set the internal pointer
+ * to the beginning.
+ * @throws Swift_IoException
+ */
+ public function flushBuffers();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/IoException.php b/External/swiftmailer/lib/classes/Swift/IoException.php
new file mode 100755
index 0000000..88a5b0d
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/IoException.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/SwiftException.php';
+
+/**
+ * I/O Exception class.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_IoException extends Swift_SwiftException
+{
+
+ /**
+ * Create a new IoException with $message.
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache.php b/External/swiftmailer/lib/classes/Swift/KeyCache.php
new file mode 100755
index 0000000..b942663
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Provides a mechanism for storing data using two keys.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+interface Swift_KeyCache
+{
+
+ /** Mode for replacing existing cached data */
+ const MODE_WRITE = 1;
+
+ /** Mode for appending data to the end of existing cached data */
+ const MODE_APPEND = 2;
+
+ /**
+ * Set a string into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param string $string
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function setString($nsKey, $itemKey, $string, $mode);
+
+ /**
+ * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_OutputByteStream $os
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
+ $mode);
+
+ /**
+ * Provides a ByteStream which when written to, writes data to $itemKey.
+ * NOTE: The stream will always write in append mode.
+ * If the optional third parameter is passed all writes will go through $is.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_InputByteStream $is, optional
+ * @return Swift_InputByteStream
+ */
+ public function getInputByteStream($nsKey, $itemKey,
+ Swift_InputByteStream $is = null);
+
+ /**
+ * Get data back out of the cache as a string.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return string
+ */
+ public function getString($nsKey, $itemKey);
+
+ /**
+ * Get data back out of the cache as a ByteStream.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_InputByteStream $is to write the data to
+ */
+ public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is);
+
+ /**
+ * Check if the given $itemKey exists in the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return boolean
+ */
+ public function hasKey($nsKey, $itemKey);
+
+ /**
+ * Clear data for $itemKey in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ * @param string $itemKey
+ */
+ public function clearKey($nsKey, $itemKey);
+
+ /**
+ * Clear all data in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ */
+ public function clearAll($nsKey);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php b/External/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php
new file mode 100755
index 0000000..fe3b7c9
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/KeyCache.php';
+//@require 'Swift/KeyCacheInputStream.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStrean.php';
+//@require 'Swift/SwiftException.php';
+
+/**
+ * A basic KeyCache backed by an array.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache
+{
+
+ /**
+ * Cache contents.
+ * @var array
+ * @access private
+ */
+ private $_contents = array();
+
+ /**
+ * An InputStream for cloning.
+ * @var Swift_KeyCache_KeyCacheInputStream
+ * @access private
+ */
+ private $_stream;
+
+ /**
+ * Create a new ArrayKeyCache with the given $stream for cloning to make
+ * InputByteStreams.
+ * @param Swift_KeyCache_KeyCacheInputStream $stream
+ */
+ public function __construct(Swift_KeyCache_KeyCacheInputStream $stream)
+ {
+ $this->_stream = $stream;
+ }
+
+ /**
+ * Set a string into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param string $string
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function setString($nsKey, $itemKey, $string, $mode)
+ {
+ $this->_prepareCache($nsKey);
+ switch ($mode)
+ {
+ case self::MODE_WRITE:
+ $this->_contents[$nsKey][$itemKey] = $string;
+ break;
+ case self::MODE_APPEND:
+ if (!$this->hasKey($nsKey, $itemKey))
+ {
+ $this->_contents[$nsKey][$itemKey] = '';
+ }
+ $this->_contents[$nsKey][$itemKey] .= $string;
+ break;
+ default:
+ throw new Swift_SwiftException(
+ 'Invalid mode [' . $mode . '] used to set nsKey='.
+ $nsKey . ', itemKey=' . $itemKey
+ );
+ }
+ }
+
+ /**
+ * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_OutputByteStream $os
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
+ $mode)
+ {
+ $this->_prepareCache($nsKey);
+ switch ($mode)
+ {
+ case self::MODE_WRITE:
+ $this->clearKey($nsKey, $itemKey);
+ case self::MODE_APPEND:
+ if (!$this->hasKey($nsKey, $itemKey))
+ {
+ $this->_contents[$nsKey][$itemKey] = '';
+ }
+ while (false !== $bytes = $os->read(8192))
+ {
+ $this->_contents[$nsKey][$itemKey] .= $bytes;
+ }
+ break;
+ default:
+ throw new Swift_SwiftException(
+ 'Invalid mode [' . $mode . '] used to set nsKey='.
+ $nsKey . ', itemKey=' . $itemKey
+ );
+ }
+ }
+
+ /**
+ * Provides a ByteStream which when written to, writes data to $itemKey.
+ * NOTE: The stream will always write in append mode.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return Swift_InputByteStream
+ */
+ public function getInputByteStream($nsKey, $itemKey,
+ Swift_InputByteStream $writeThrough = null)
+ {
+ $is = clone $this->_stream;
+ $is->setKeyCache($this);
+ $is->setNsKey($nsKey);
+ $is->setItemKey($itemKey);
+ if (isset($writeThrough))
+ {
+ $is->setWriteThroughStream($writeThrough);
+ }
+ return $is;
+ }
+
+ /**
+ * Get data back out of the cache as a string.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return string
+ */
+ public function getString($nsKey, $itemKey)
+ {
+ $this->_prepareCache($nsKey);
+ if ($this->hasKey($nsKey, $itemKey))
+ {
+ return $this->_contents[$nsKey][$itemKey];
+ }
+ }
+
+ /**
+ * Get data back out of the cache as a ByteStream.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_InputByteStream $is to write the data to
+ */
+ public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
+ {
+ $this->_prepareCache($nsKey);
+ $is->write($this->getString($nsKey, $itemKey));
+ }
+
+ /**
+ * Check if the given $itemKey exists in the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return boolean
+ */
+ public function hasKey($nsKey, $itemKey)
+ {
+ $this->_prepareCache($nsKey);
+ return array_key_exists($itemKey, $this->_contents[$nsKey]);
+ }
+
+ /**
+ * Clear data for $itemKey in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ * @param string $itemKey
+ */
+ public function clearKey($nsKey, $itemKey)
+ {
+ unset($this->_contents[$nsKey][$itemKey]);
+ }
+
+ /**
+ * Clear all data in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ */
+ public function clearAll($nsKey)
+ {
+ unset($this->_contents[$nsKey]);
+ }
+
+ // -- Private methods
+
+ /**
+ * Initialize the namespace of $nsKey if needed.
+ * @param string $nsKey
+ * @access private
+ */
+ private function _prepareCache($nsKey)
+ {
+ if (!array_key_exists($nsKey, $this->_contents))
+ {
+ $this->_contents[$nsKey] = array();
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php b/External/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php
new file mode 100755
index 0000000..599fd6c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php
@@ -0,0 +1,316 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/KeyCache.php';
+//@require 'Swift/KeyCacheInputStream.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStrean.php';
+//@require 'Swift/SwiftException.php';
+//@require 'Swift/IoException.php';
+
+/**
+ * A KeyCache which streams to and from disk.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache
+{
+
+ /** Signal to place pointer at start of file */
+ const POSITION_START = 0;
+
+ /** Signal to place pointer at end of file */
+ const POSITION_END = 1;
+
+ /**
+ * An InputStream for cloning.
+ * @var Swift_KeyCache_KeyCacheInputStream
+ * @access private
+ */
+ private $_stream;
+
+ /**
+ * A path to write to.
+ * @var string
+ * @access private
+ */
+ private $_path;
+
+ /**
+ * Stored keys.
+ * @var array
+ * @access private
+ */
+ private $_keys = array();
+
+ /**
+ * Will be true if magic_quotes_runtime is turned on.
+ * @var boolean
+ * @access private
+ */
+ private $_quotes = false;
+
+ /**
+ * Create a new DiskKeyCache with the given $stream for cloning to make
+ * InputByteStreams, and the given $path to save to.
+ * @param Swift_KeyCache_KeyCacheInputStream $stream
+ * @param string $path to save to
+ */
+ public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path)
+ {
+ $this->_stream = $stream;
+ $this->_path = $path;
+ $this->_quotes = get_magic_quotes_runtime();
+ }
+
+ /**
+ * Set a string into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param string $string
+ * @param int $mode
+ * @throws Swift_IoException
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function setString($nsKey, $itemKey, $string, $mode)
+ {
+ $this->_prepareCache($nsKey);
+ switch ($mode)
+ {
+ case self::MODE_WRITE:
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
+ break;
+ case self::MODE_APPEND:
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
+ break;
+ default:
+ throw new Swift_SwiftException(
+ 'Invalid mode [' . $mode . '] used to set nsKey='.
+ $nsKey . ', itemKey=' . $itemKey
+ );
+ break;
+ }
+ fwrite($fp, $string);
+ }
+
+ /**
+ * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_OutputByteStream $os
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ * @throws Swift_IoException
+ */
+ public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
+ $mode)
+ {
+ $this->_prepareCache($nsKey);
+ switch ($mode)
+ {
+ case self::MODE_WRITE:
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
+ break;
+ case self::MODE_APPEND:
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
+ break;
+ default:
+ throw new Swift_SwiftException(
+ 'Invalid mode [' . $mode . '] used to set nsKey='.
+ $nsKey . ', itemKey=' . $itemKey
+ );
+ break;
+ }
+ while (false !== $bytes = $os->read(8192))
+ {
+ fwrite($fp, $bytes);
+ }
+ }
+
+ /**
+ * Provides a ByteStream which when written to, writes data to $itemKey.
+ * NOTE: The stream will always write in append mode.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return Swift_InputByteStream
+ */
+ public function getInputByteStream($nsKey, $itemKey,
+ Swift_InputByteStream $writeThrough = null)
+ {
+ $is = clone $this->_stream;
+ $is->setKeyCache($this);
+ $is->setNsKey($nsKey);
+ $is->setItemKey($itemKey);
+ if (isset($writeThrough))
+ {
+ $is->setWriteThroughStream($writeThrough);
+ }
+ return $is;
+ }
+
+ /**
+ * Get data back out of the cache as a string.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return string
+ * @throws Swift_IoException
+ */
+ public function getString($nsKey, $itemKey)
+ {
+ $this->_prepareCache($nsKey);
+ if ($this->hasKey($nsKey, $itemKey))
+ {
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(0);
+ }
+ $str = '';
+ while (!feof($fp) && false !== $bytes = fread($fp, 8192))
+ {
+ $str .= $bytes;
+ }
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(1);
+ }
+ return $str;
+ }
+ }
+
+ /**
+ * Get data back out of the cache as a ByteStream.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_InputByteStream $is to write the data to
+ */
+ public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
+ {
+ if ($this->hasKey($nsKey, $itemKey))
+ {
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(0);
+ }
+ while (!feof($fp) && false !== $bytes = fread($fp, 8192))
+ {
+ $is->write($bytes);
+ }
+ if ($this->_quotes)
+ {
+ set_magic_quotes_runtime(1);
+ }
+ }
+ }
+
+ /**
+ * Check if the given $itemKey exists in the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return boolean
+ */
+ public function hasKey($nsKey, $itemKey)
+ {
+ return is_file($this->_path . '/' . $nsKey . '/' . $itemKey);
+ }
+
+ /**
+ * Clear data for $itemKey in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ * @param string $itemKey
+ */
+ public function clearKey($nsKey, $itemKey)
+ {
+ if ($this->hasKey($nsKey, $itemKey))
+ {
+ $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
+ fclose($fp);
+ unlink($this->_path . '/' . $nsKey . '/' . $itemKey);
+ }
+ unset($this->_keys[$nsKey][$itemKey]);
+ }
+
+ /**
+ * Clear all data in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ */
+ public function clearAll($nsKey)
+ {
+ if (array_key_exists($nsKey, $this->_keys))
+ {
+ foreach ($this->_keys[$nsKey] as $itemKey=>$null)
+ {
+ $this->clearKey($nsKey, $itemKey);
+ }
+ rmdir($this->_path . '/' . $nsKey);
+ unset($this->_keys[$nsKey]);
+ }
+ }
+
+ // -- Private methods
+
+ /**
+ * Initialize the namespace of $nsKey if needed.
+ * @param string $nsKey
+ * @access private
+ */
+ private function _prepareCache($nsKey)
+ {
+ $cacheDir = $this->_path . '/' . $nsKey;
+ if (!is_dir($cacheDir))
+ {
+ if (!mkdir($cacheDir))
+ {
+ throw new Swift_IoException('Failed to create cache directory ' . $cacheDir);
+ }
+ $this->_keys[$nsKey] = array();
+ }
+ }
+
+ /**
+ * Get a file handle on the cache item.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param int $position
+ * @return resource
+ * @access private
+ */
+ private function _getHandle($nsKey, $itemKey, $position)
+ {
+ if (!isset($this->_keys[$nsKey]) || !array_key_exists($itemKey, $this->_keys[$nsKey]))
+ {
+ $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, 'w+b');
+ $this->_keys[$nsKey][$itemKey] = $fp;
+ }
+ if (self::POSITION_START == $position)
+ {
+ fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET);
+ }
+ else
+ {
+ fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END);
+ }
+ return $this->_keys[$nsKey][$itemKey];
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ foreach ($this->_keys as $nsKey=>$null)
+ {
+ $this->clearAll($nsKey);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php b/External/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php
new file mode 100755
index 0000000..a1f4440
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/KeyCache.php';
+//@require 'Swift/InputByteStream.php';
+
+/**
+ * Writes data to a KeyCache using a stream.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream
+{
+
+ /**
+ * Set the KeyCache to wrap.
+ * @param Swift_KeyCache $keyCache
+ */
+ public function setKeyCache(Swift_KeyCache $keyCache);
+
+ /**
+ * Set the nsKey which will be written to.
+ * @param string $nsKey
+ */
+ public function setNsKey($nsKey);
+
+ /**
+ * Set the itemKey which will be written to.
+ * @param string $itemKey
+ */
+ public function setItemKey($itemKey);
+
+ /**
+ * Specify a stream to write through for each write().
+ * @param Swift_InputByteStream $is
+ */
+ public function setWriteThroughStream(Swift_InputByteStream $is);
+
+ /**
+ * Any implementation should be cloneable, allowing the clone to access a
+ * separate $nsKey and $itemKey.
+ */
+ public function __clone();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php b/External/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php
new file mode 100755
index 0000000..2646522
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/KeyCache.php';
+//@require 'Swift/KeyCacheInputStream.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStrean.php';
+
+/**
+ * A null KeyCache that does not cache at all.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+class Swift_KeyCache_NullKeyCache implements Swift_KeyCache
+{
+
+ /**
+ * Set a string into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param string $string
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function setString($nsKey, $itemKey, $string, $mode)
+ {
+ }
+
+ /**
+ * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_OutputByteStream $os
+ * @param int $mode
+ * @see MODE_WRITE, MODE_APPEND
+ */
+ public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
+ $mode)
+ {
+ }
+
+ /**
+ * Provides a ByteStream which when written to, writes data to $itemKey.
+ * NOTE: The stream will always write in append mode.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return Swift_InputByteStream
+ */
+ public function getInputByteStream($nsKey, $itemKey,
+ Swift_InputByteStream $writeThrough = null)
+ {
+ }
+
+ /**
+ * Get data back out of the cache as a string.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return string
+ */
+ public function getString($nsKey, $itemKey)
+ {
+ }
+
+ /**
+ * Get data back out of the cache as a ByteStream.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @param Swift_InputByteStream $is to write the data to
+ */
+ public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
+ {
+ }
+
+ /**
+ * Check if the given $itemKey exists in the namespace $nsKey.
+ * @param string $nsKey
+ * @param string $itemKey
+ * @return boolean
+ */
+ public function hasKey($nsKey, $itemKey)
+ {
+ return false;
+ }
+
+ /**
+ * Clear data for $itemKey in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ * @param string $itemKey
+ */
+ public function clearKey($nsKey, $itemKey)
+ {
+ }
+
+ /**
+ * Clear all data in the namespace $nsKey if it exists.
+ * @param string $nsKey
+ */
+ public function clearAll($nsKey)
+ {
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php b/External/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php
new file mode 100755
index 0000000..87cdced
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php
@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/KeyCache.php';
+//@require 'Swift/KeyCacheInputStream.php';
+
+/**
+ * Writes data to a KeyCache using a stream.
+ * @package Swift
+ * @subpackage KeyCache
+ * @author Chris Corbyn
+ */
+class Swift_KeyCache_SimpleKeyCacheInputStream
+ implements Swift_KeyCache_KeyCacheInputStream
+{
+
+ /** The KeyCache being written to */
+ private $_keyCache;
+
+ /** The nsKey of the KeyCache being written to */
+ private $_nsKey;
+
+ /** The itemKey of the KeyCache being written to */
+ private $_itemKey;
+
+ /** A stream to write through on each write() */
+ private $_writeThrough = null;
+
+ /**
+ * Set the KeyCache to wrap.
+ * @param Swift_KeyCache $keyCache
+ */
+ public function setKeyCache(Swift_KeyCache $keyCache)
+ {
+ $this->_keyCache = $keyCache;
+ }
+
+ /**
+ * Specify a stream to write through for each write().
+ * @param Swift_InputByteStream $is
+ */
+ public function setWriteThroughStream(Swift_InputByteStream $is)
+ {
+ $this->_writeThrough = $is;
+ }
+
+ /**
+ * Writes $bytes to the end of the stream.
+ * @param string $bytes
+ * @param Swift_InputByteStream $is, optional
+ */
+ public function write($bytes, Swift_InputByteStream $is = null)
+ {
+ $this->_keyCache->setString(
+ $this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND
+ );
+ if (isset($is))
+ {
+ $is->write($bytes);
+ }
+ if (isset($this->_writeThrough))
+ {
+ $this->_writeThrough->write($bytes);
+ }
+ }
+
+ /**
+ * Not used.
+ */
+ public function commit()
+ {
+ }
+
+ /**
+ * Not used.
+ */
+ public function bind(Swift_InputByteStream $is)
+ {
+ }
+
+ /**
+ * Not used.
+ */
+ public function unbind(Swift_InputByteStream $is)
+ {
+ }
+
+ /**
+ * Flush the contents of the stream (empty it) and set the internal pointer
+ * to the beginning.
+ */
+ public function flushBuffers()
+ {
+ $this->_keyCache->clearKey($this->_nsKey, $this->_itemKey);
+ }
+
+ /**
+ * Set the nsKey which will be written to.
+ * @param string $nsKey
+ */
+ public function setNsKey($nsKey)
+ {
+ $this->_nsKey = $nsKey;
+ }
+
+ /**
+ * Set the itemKey which will be written to.
+ * @param string $itemKey
+ */
+ public function setItemKey($itemKey)
+ {
+ $this->_itemKey = $itemKey;
+ }
+
+ /**
+ * Any implementation should be cloneable, allowing the clone to access a
+ * separate $nsKey and $itemKey.
+ */
+ public function __clone()
+ {
+ $this->_writeThrough = null;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php b/External/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php
new file mode 100755
index 0000000..14ae292
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/LoadBalancedTransport.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Redudantly and rotationally uses several Transport implementations when sending.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_LoadBalancedTransport extends Swift_Transport_LoadBalancedTransport
+{
+
+ /**
+ * Creates a new LoadBalancedTransport with $transports.
+ * @param array $transports
+ */
+ public function __construct($transports = array())
+ {
+ call_user_func_array(
+ array($this, 'Swift_Transport_LoadBalancedTransport::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('transport.loadbalanced')
+ );
+
+ $this->setTransports($transports);
+ }
+
+ /**
+ * Create a new LoadBalancedTransport instance.
+ * @param string $transports
+ * @return Swift_LoadBalancedTransport
+ */
+ public static function newInstance($transports = array())
+ {
+ return new self($transports);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/MailTransport.php b/External/swiftmailer/lib/classes/Swift/MailTransport.php
new file mode 100755
index 0000000..afe29c6
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/MailTransport.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/MailTransport.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Sends Messages using the mail() function.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_MailTransport extends Swift_Transport_MailTransport
+{
+
+ /**
+ * Create a new MailTransport, optionally specifying $extraParams.
+ * @param string $extraParams
+ */
+ public function __construct($extraParams = '-f%s')
+ {
+ call_user_func_array(
+ array($this, 'Swift_Transport_MailTransport::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('transport.mail')
+ );
+
+ $this->setExtraParams($extraParams);
+ }
+
+ /**
+ * Create a new MailTransport instance.
+ * @param string $extraParams To be passed to mail()
+ * @return Swift_MailTransport
+ */
+ public static function newInstance($extraParams = '-f%s')
+ {
+ return new self($extraParams);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mailer.php b/External/swiftmailer/lib/classes/Swift/Mailer.php
new file mode 100755
index 0000000..c92feb4
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mailer.php
@@ -0,0 +1,173 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport.php';
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Mailer/RecipientIterator.php';
+//@require 'Swift/Events/EventListener.php';
+
+/**
+ * Swift Mailer class.
+ *
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_Mailer
+{
+
+ /** The Transport used to send messages */
+ private $_transport;
+
+ /**
+ * Create a new Mailer using $transport for delivery.
+ *
+ * @param Swift_Transport $transport
+ */
+ public function __construct(Swift_Transport $transport)
+ {
+ $this->_transport = $transport;
+ }
+
+ /**
+ * Create a new Mailer instance.
+ *
+ * @param Swift_Transport $transport
+ * @return Swift_Mailer
+ */
+ public static function newInstance(Swift_Transport $transport)
+ {
+ return new self($transport);
+ }
+
+ /**
+ * Send the given Message like it would be sent in a mail client.
+ *
+ * All recipients (with the exception of Bcc) will be able to see the other
+ * recipients this message was sent to.
+ *
+ * If you need to send to each recipient without disclosing details about the
+ * other recipients see {@link batchSend()}.
+ *
+ * Recipient/sender data will be retreived from the Message object.
+ *
+ * The return value is the number of recipients who were accepted for
+ * delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param array &$failedRecipients, optional
+ * @return int
+ * @see batchSend()
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $failedRecipients = (array) $failedRecipients;
+
+ if (!$this->_transport->isStarted())
+ {
+ $this->_transport->start();
+ }
+
+ return $this->_transport->send($message, $failedRecipients);
+ }
+
+ /**
+ * Send the given Message to all recipients individually.
+ *
+ * This differs from {@link send()} in the way headers are presented to the
+ * recipient. The only recipient in the "To:" field will be the individual
+ * recipient it was sent to.
+ *
+ * If an iterator is provided, recipients will be read from the iterator
+ * one-by-one, otherwise recipient data will be retreived from the Message
+ * object.
+ *
+ * Sender information is always read from the Message object.
+ *
+ * The return value is the number of recipients who were accepted for
+ * delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param array &$failedRecipients, optional
+ * @param Swift_Mailer_RecipientIterator $it, optional
+ * @return int
+ * @see send()
+ */
+ public function batchSend(Swift_Mime_Message $message,
+ &$failedRecipients = null,
+ Swift_Mailer_RecipientIterator $it = null)
+ {
+ $failedRecipients = (array) $failedRecipients;
+
+ $sent = 0;
+ $to = $message->getTo();
+ $cc = $message->getCc();
+ $bcc = $message->getBcc();
+
+ if (!empty($cc))
+ {
+ $message->setCc(array());
+ }
+ if (!empty($bcc))
+ {
+ $message->setBcc(array());
+ }
+
+ //Use an iterator if set
+ if (isset($it))
+ {
+ while ($it->hasNext())
+ {
+ $message->setTo($it->nextRecipient());
+ $sent += $this->send($message, $failedRecipients);
+ }
+ }
+ else
+ {
+ foreach ($to as $address => $name)
+ {
+ $message->setTo(array($address => $name));
+ $sent += $this->send($message, $failedRecipients);
+ }
+ }
+
+ $message->setTo($to);
+
+ if (!empty($cc))
+ {
+ $message->setCc($cc);
+ }
+ if (!empty($bcc))
+ {
+ $message->setBcc($bcc);
+ }
+
+ return $sent;
+ }
+
+ /**
+ * Register a plugin using a known unique key (e.g. myPlugin).
+ *
+ * @param Swift_Events_EventListener $plugin
+ * @param string $key
+ */
+ public function registerPlugin(Swift_Events_EventListener $plugin)
+ {
+ $this->_transport->registerPlugin($plugin);
+ }
+
+ /**
+ * The Transport used to send messages.
+ * @return Swift_Transport
+ */
+ public function getTransport()
+ {
+ return $this->_transport;
+ }
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php b/External/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php
new file mode 100755
index 0000000..65d60c1
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mailer/RecipientIterator.php';
+
+/**
+ * Wraps a standard PHP array in an interator.
+ * @package Swift
+ * @subpackage Mailer
+ * @author Chris Corbyn
+ */
+class Swift_Mailer_ArrayRecipientIterator
+ implements Swift_Mailer_RecipientIterator
+{
+
+ /**
+ * The list of recipients.
+ * @var array
+ * @access private
+ */
+ private $_recipients = array();
+
+ /**
+ * Create a new ArrayRecipientIterator from $recipients.
+ * @param array $recipients
+ */
+ public function __construct(array $recipients)
+ {
+ $this->_recipients = $recipients;
+ }
+
+ /**
+ * Returns true only if there are more recipients to send to.
+ * @return boolean
+ */
+ public function hasNext()
+ {
+ return !empty($this->_recipients);
+ }
+
+ /**
+ * Returns an array where the keys are the addresses of recipients and the
+ * values are the names.
+ * e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL)
+ * @return array
+ */
+ public function nextRecipient()
+ {
+ return array_splice($this->_recipients, 0, 1);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php b/External/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php
new file mode 100755
index 0000000..2713841
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Provides an abstract way of specifying recipients for batch sending.
+ * @package Swift
+ * @subpackage Mailer
+ * @author Chris Corbyn
+ */
+interface Swift_Mailer_RecipientIterator
+{
+
+ /**
+ * Returns true only if there are more recipients to send to.
+ * @return boolean
+ */
+ public function hasNext();
+
+ /**
+ * Returns an array where the keys are the addresses of recipients and the
+ * values are the names.
+ * e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL)
+ * @return array
+ */
+ public function nextRecipient();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Message.php b/External/swiftmailer/lib/classes/Swift/Message.php
new file mode 100755
index 0000000..e8183ea
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Message.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/SimpleMessage.php';
+//@require 'Swift/MimePart.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * The Message class for building emails.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Message extends Swift_Mime_SimpleMessage
+{
+
+ /**
+ * Create a new Message.
+ * Details may be optionally passed into the constructor.
+ * @param string $subject
+ * @param string $body
+ * @param string $contentType
+ * @param string $charset
+ */
+ public function __construct($subject = null, $body = null,
+ $contentType = null, $charset = null)
+ {
+ call_user_func_array(
+ array($this, 'Swift_Mime_SimpleMessage::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('mime.message')
+ );
+
+ if (!isset($charset))
+ {
+ $charset = Swift_DependencyContainer::getInstance()
+ ->lookup('properties.charset');
+ }
+ $this->setSubject($subject);
+ $this->setBody($body);
+ $this->setCharset($charset);
+ if ($contentType)
+ {
+ $this->setContentType($contentType);
+ }
+ }
+
+ /**
+ * Create a new Message.
+ * @param string $subject
+ * @param string $body
+ * @param string $contentType
+ * @param string $charset
+ * @return Swift_Mime_Message
+ */
+ public static function newInstance($subject = null, $body = null,
+ $contentType = null, $charset = null)
+ {
+ return new self($subject, $body, $contentType, $charset);
+ }
+
+ /**
+ * Add a MimePart to this Message.
+ * @param string|Swift_OutputByteStream $body
+ * @param string $contentType
+ * @param string $charset
+ */
+ public function addPart($body, $contentType = null, $charset = null)
+ {
+ return $this->attach(Swift_MimePart::newInstance(
+ $body, $contentType, $charset
+ ));
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Attachment.php b/External/swiftmailer/lib/classes/Swift/Mime/Attachment.php
new file mode 100755
index 0000000..25ef68b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Attachment.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/SimpleMimeEntity.php';
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/Mime/HeaderSet.php';
+//@require 'Swift/FileStream.php';
+//@require 'Swift/KeyCache.php';
+
+/**
+ * An attachment, in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
+{
+
+ /** Recognized MIME types */
+ private $_mimeTypes = array();
+
+ /**
+ * Create a new Attachment with $headers, $encoder and $cache.
+ * @param Swift_Mime_HeaderSet $headers
+ * @param Swift_Mime_ContentEncoder $encoder
+ * @param Swift_KeyCache $cache
+ * @param array $mimeTypes optional
+ */
+ public function __construct(Swift_Mime_HeaderSet $headers,
+ Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache,
+ $mimeTypes = array())
+ {
+ parent::__construct($headers, $encoder, $cache);
+ $this->setDisposition('attachment');
+ $this->setContentType('application/octet-stream');
+ $this->_mimeTypes = $mimeTypes;
+ }
+
+ /**
+ * Get the nesting level used for this attachment.
+ * Always returns {@link LEVEL_MIXED}.
+ * @return int
+ */
+ public function getNestingLevel()
+ {
+ return self::LEVEL_MIXED;
+ }
+
+ /**
+ * Get the Content-Disposition of this attachment.
+ * By default attachments have a disposition of "attachment".
+ * @return string
+ */
+ public function getDisposition()
+ {
+ return $this->_getHeaderFieldModel('Content-Disposition');
+ }
+
+ /**
+ * Set the Content-Disposition of this attachment.
+ * @param string $disposition
+ */
+ public function setDisposition($disposition)
+ {
+ if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition))
+ {
+ $this->getHeaders()->addParameterizedHeader(
+ 'Content-Disposition', $disposition
+ );
+ }
+ return $this;
+ }
+
+ /**
+ * Get the filename of this attachment when downloaded.
+ * @return string
+ */
+ public function getFilename()
+ {
+ return $this->_getHeaderParameter('Content-Disposition', 'filename');
+ }
+
+ /**
+ * Set the filename of this attachment.
+ * @param string $filename
+ */
+ public function setFilename($filename)
+ {
+ $this->_setHeaderParameter('Content-Disposition', 'filename', $filename);
+ $this->_setHeaderParameter('Content-Type', 'name', $filename);
+ return $this;
+ }
+
+ /**
+ * Get the file size of this attachment.
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->_getHeaderParameter('Content-Disposition', 'size');
+ }
+
+ /**
+ * Set the file size of this attachment.
+ * @param int $size
+ */
+ public function setSize($size)
+ {
+ $this->_setHeaderParameter('Content-Disposition', 'size', $size);
+ return $this;
+ }
+
+ /**
+ * Set the file that this attachment is for.
+ * @param Swift_FileStream $file
+ * @param string $contentType optional
+ */
+ public function setFile(Swift_FileStream $file, $contentType = null)
+ {
+ $this->setFilename(basename($file->getPath()));
+ $this->setBody($file, $contentType);
+ if (!isset($contentType))
+ {
+ $extension = strtolower(substr(
+ $file->getPath(), strrpos($file->getPath(), '.') + 1
+ ));
+
+ if (array_key_exists($extension, $this->_mimeTypes))
+ {
+ $this->setContentType($this->_mimeTypes[$extension]);
+ }
+ }
+ return $this;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php b/External/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php
new file mode 100755
index 0000000..c26009f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Observes changes in an Mime entity's character set.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_CharsetObserver
+{
+
+ /**
+ * Notify this observer that the entity's charset has changed.
+ * @param string $charset
+ */
+ public function charsetChanged($charset);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php
new file mode 100755
index 0000000..e1c99c5
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Encoder.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Interface for all Transfer Encoding schemes.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_ContentEncoder extends Swift_Encoder
+{
+
+ /**
+ * Encode $in to $out.
+ * @param Swift_OutputByteStream $os to read from
+ * @param Swift_InputByteStream $is to write to
+ * @param int $firstLineOffset
+ * @param int $maxLineLength - 0 indicates the default length for this encoding
+ */
+ public function encodeByteStream(
+ Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0,
+ $maxLineLength = 0);
+
+ /**
+ * Get the MIME name of this content encoding scheme.
+ * @return string
+ */
+ public function getName();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php
new file mode 100755
index 0000000..e89938e
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/Encoder/Base64Encoder.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Handles Base 64 Transfer Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_ContentEncoder_Base64ContentEncoder
+ extends Swift_Encoder_Base64Encoder
+ implements Swift_Mime_ContentEncoder
+{
+
+ /**
+ * Encode stream $in to stream $out.
+ * @param Swift_OutputByteStream $in
+ * @param Swift_InputByteStream $out
+ * @param int $firstLineOffset
+ * @param int $maxLineLength, optional, 0 indicates the default of 76 bytes
+ */
+ public function encodeByteStream(
+ Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ if (0 >= $maxLineLength || 76 < $maxLineLength)
+ {
+ $maxLineLength = 76;
+ }
+
+ $remainder = 0;
+
+ while (false !== $bytes = $os->read(8190))
+ {
+ $encoded = base64_encode($bytes);
+ $encodedTransformed = '';
+ $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset;
+
+ while ($thisMaxLineLength < strlen($encoded))
+ {
+ $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength) . "\r\n";
+ $firstLineOffset = 0;
+ $encoded = substr($encoded, $thisMaxLineLength);
+ $thisMaxLineLength = $maxLineLength;
+ $remainder = 0;
+ }
+
+ if (0 < $remainingLength = strlen($encoded))
+ {
+ $remainder += $remainingLength;
+ $encodedTransformed .= $encoded;
+ $encoded = null;
+ }
+
+ $is->write($encodedTransformed);
+ }
+ }
+
+ /**
+ * Get the name of this encoding scheme.
+ * Returns the string 'base64'.
+ * @return string
+ */
+ public function getName()
+ {
+ return 'base64';
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php
new file mode 100755
index 0000000..4a725d8
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php
@@ -0,0 +1,175 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Handles binary/7/8-bit Transfer Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_ContentEncoder_PlainContentEncoder
+ implements Swift_Mime_ContentEncoder
+{
+
+ /**
+ * The name of this encoding scheme (probably 7bit or 8bit).
+ * @var string
+ * @access private
+ */
+ private $_name;
+
+ /**
+ * True if canonical transformations should be done.
+ * @var boolean
+ * @access private
+ */
+ private $_canonical;
+
+ /**
+ * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit).
+ * @param string $name
+ * @param boolean $canonical If canonicalization transformation should be done.
+ */
+ public function __construct($name, $canonical = false)
+ {
+ $this->_name = $name;
+ $this->_canonical = $canonical;
+ }
+
+ /**
+ * Encode a given string to produce an encoded string.
+ * @param string $string
+ * @param int $firstLineOffset, ignored
+ * @param int $maxLineLength - 0 means no wrapping will occur
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ if ($this->_canonical)
+ {
+ $string = $this->_canonicalize($string);
+ }
+ return $this->_safeWordWrap($string, $maxLineLength, "\r\n");
+ }
+
+ /**
+ * Encode stream $in to stream $out.
+ * @param Swift_OutputByteStream $in
+ * @param Swift_InputByteStream $out
+ * @param int $firstLineOffset, ignored
+ * @param int $maxLineLength, optional, 0 means no wrapping will occur
+ */
+ public function encodeByteStream(
+ Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ $leftOver = '';
+ while (false !== $bytes = $os->read(8192))
+ {
+ $toencode = $leftOver . $bytes;
+ if ($this->_canonical)
+ {
+ $toencode = $this->_canonicalize($toencode);
+ }
+ $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n");
+ $lastLinePos = strrpos($wrapped, "\r\n");
+ $leftOver = substr($wrapped, $lastLinePos);
+ $wrapped = substr($wrapped, 0, $lastLinePos);
+
+ $is->write($wrapped);
+ }
+ if (strlen($leftOver))
+ {
+ $is->write($leftOver);
+ }
+ }
+
+ /**
+ * Get the name of this encoding scheme.
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->_name;
+ }
+
+ /**
+ * Not used.
+ */
+ public function charsetChanged($charset)
+ {
+ }
+
+ // -- Private methods
+
+ /**
+ * A safer (but weaker) wordwrap for unicode.
+ * @param string $string
+ * @param int $length
+ * @param string $le
+ * @return string
+ * @access private
+ */
+ private function _safeWordwrap($string, $length = 75, $le = "\r\n")
+ {
+ if (0 >= $length)
+ {
+ return $string;
+ }
+
+ $originalLines = explode($le, $string);
+
+ $lines = array();
+ $lineCount = 0;
+
+ foreach ($originalLines as $originalLine)
+ {
+ $lines[] = '';
+ $currentLine =& $lines[$lineCount++];
+
+ //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine);
+ $chunks = preg_split('/(?<=\s)/', $originalLine);
+
+ foreach ($chunks as $chunk)
+ {
+ if (0 != strlen($currentLine)
+ && strlen($currentLine . $chunk) > $length)
+ {
+ $lines[] = '';
+ $currentLine =& $lines[$lineCount++];
+ }
+ $currentLine .= $chunk;
+ }
+ }
+
+ return implode("\r\n", $lines);
+ }
+
+ /**
+ * Canonicalize string input (fix CRLF).
+ * @param string $string
+ * @return string
+ * @access private
+ */
+ private function _canonicalize($string)
+ {
+ return str_replace(
+ array("\r\n", "\r", "\n"),
+ array("\n", "\n", "\r\n"),
+ $string
+ );
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php
new file mode 100755
index 0000000..3beeb63
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/Encoder/QpEncoder.php';
+//@require 'Swift/InputByteStrean.php';
+//@require 'Swift/OutputByteStream.php';
+//@require 'Swift/CharacterStream.php';
+
+/**
+ * Handles Quoted Printable (QP) Transfer Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder
+ implements Swift_Mime_ContentEncoder
+{
+
+ /**
+ * Creates a new QpContentEncoder for the given CharacterStream.
+ * @param Swift_CharacterStream $charStream to use for reading characters
+ * @param Swift_StreamFilter $filter if canonicalization should occur
+ */
+ public function __construct(Swift_CharacterStream $charStream,
+ Swift_StreamFilter $filter = null)
+ {
+ parent::__construct($charStream, $filter);
+ }
+
+ /**
+ * Encode stream $in to stream $out.
+ * QP encoded strings have a maximum line length of 76 characters.
+ * If the first line needs to be shorter, indicate the difference with
+ * $firstLineOffset.
+ * @param Swift_OutputByteStream $os output stream
+ * @param Swift_InputByteStream $is input stream
+ * @param int $firstLineOffset
+ * @param int $maxLineLength
+ */
+ public function encodeByteStream(
+ Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ if ($maxLineLength > 76 || $maxLineLength <= 0)
+ {
+ $maxLineLength = 76;
+ }
+
+ $thisLineLength = $maxLineLength - $firstLineOffset;
+
+ $this->_charStream->flushContents();
+ $this->_charStream->importByteStream($os);
+
+ $currentLine = '';
+ $prepend = '';
+ $size=$lineLen=0;
+
+ while (false !== $bytes = $this->_nextSequence())
+ {
+ //If we're filtering the input
+ if (isset($this->_filter))
+ {
+ //If we can't filter because we need more bytes
+ while ($this->_filter->shouldBuffer($bytes))
+ {
+ //Then collect bytes into the buffer
+ if (false === $moreBytes = $this->_nextSequence(1))
+ {
+ break;
+ }
+
+ foreach ($moreBytes as $b)
+ {
+ $bytes[] = $b;
+ }
+ }
+ //And filter them
+ $bytes = $this->_filter->filter($bytes);
+ }
+
+ $enc = $this->_encodeByteSequence($bytes, $size);
+ if ($currentLine && $lineLen+$size >= $thisLineLength)
+ {
+ $is->write($prepend . $this->_standardize($currentLine));
+ $currentLine = '';
+ $prepend = "=\r\n";
+ $thisLineLength = $maxLineLength;
+ $lineLen=0;
+ }
+ $lineLen+=$size;
+ $currentLine .= $enc;
+ }
+ if (strlen($currentLine))
+ {
+ $is->write($prepend . $this->_standardize($currentLine));
+ }
+ }
+
+ /**
+ * Get the name of this encoding scheme.
+ * Returns the string 'quoted-printable'.
+ * @return string
+ */
+ public function getName()
+ {
+ return 'quoted-printable';
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php b/External/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php
new file mode 100755
index 0000000..983b78d
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Attachment.php';
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/KeyCache.php';
+//@require
+
+/**
+ * An embedded file, in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_EmbeddedFile extends Swift_Mime_Attachment
+{
+
+ /**
+ * Creates a new Attachment with $headers and $encoder.
+ * @param Swift_Mime_HeaderSet $headers
+ * @param Swift_Mime_ContentEncoder $encoder
+ * @param Swift_KeyCache $cache
+ * @param array $mimeTypes optional
+ */
+ public function __construct(Swift_Mime_HeaderSet $headers,
+ Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache,
+ $mimeTypes = array())
+ {
+ parent::__construct($headers, $encoder, $cache, $mimeTypes);
+ $this->setDisposition('inline');
+ $this->setId($this->getId());
+ }
+
+ /**
+ * Get the nesting level of this EmbeddedFile.
+ * Returns {@link LEVEL_RELATED}.
+ * @return int
+ */
+ public function getNestingLevel()
+ {
+ return self::LEVEL_RELATED;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php b/External/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php
new file mode 100755
index 0000000..50472db
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/ContentEncoder.php';
+
+/**
+ * Observes changes for a Mime entity's ContentEncoder.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_EncodingObserver
+{
+
+ /**
+ * Notify this observer that the observed entity's ContentEncoder has changed.
+ * @param Swift_Mime_ContentEncoder $encoder
+ */
+ public function encoderChanged(Swift_Mime_ContentEncoder $encoder);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Header.php b/External/swiftmailer/lib/classes/Swift/Mime/Header.php
new file mode 100755
index 0000000..38fc40c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Header.php
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A MIME Header.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_Header
+{
+
+ /** Text headers */
+ const TYPE_TEXT = 2;
+
+ /** Parameterized headers (text + params) */
+ const TYPE_PARAMETERIZED = 6;
+
+ /** Mailbox and address headers */
+ const TYPE_MAILBOX = 8;
+
+ /** Date and time headers */
+ const TYPE_DATE = 16;
+
+ /** Identification headers */
+ const TYPE_ID = 32;
+
+ /** Address path headers */
+ const TYPE_PATH = 64;
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType();
+
+ /**
+ * Set the model for the field body.
+ * The actual types needed will vary depending upon the type of Header.
+ * @param mixed $model
+ */
+ public function setFieldBodyModel($model);
+
+ /**
+ * Set the charset used when rendering the Header.
+ * @param string $charset
+ */
+ public function setCharset($charset);
+
+ /**
+ * Get the model for the field body.
+ * The return type depends on the specifics of the Header.
+ * @return mixed
+ */
+ public function getFieldBodyModel();
+
+ /**
+ * Get the name of this header (e.g. Subject).
+ * The name is an identifier and as such will be immutable.
+ * @return string
+ */
+ public function getFieldName();
+
+ /**
+ * Get the field body, prepared for folding into a final header value.
+ * @return string
+ */
+ public function getFieldBody();
+
+ /**
+ * Get this Header rendered as a compliant string.
+ * @return string
+ */
+ public function toString();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php
new file mode 100755
index 0000000..cc70c5f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Encoder.php';
+
+/**
+ * Interface for all Header Encoding schemes.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_HeaderEncoder extends Swift_Encoder
+{
+
+ /**
+ * Get the MIME name of this content encoding scheme.
+ * @return string
+ */
+ public function getName();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php
new file mode 100755
index 0000000..feaba98
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once dirname(__FILE__) . '/../HeaderEncoder.php';
+require_once dirname(__FILE__) . '/../../Encoder/Base64Encoder.php';
+
+
+/**
+ * Handles Base64 (B) Header Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_HeaderEncoder_Base64HeaderEncoder
+ extends Swift_Encoder_Base64Encoder
+ implements Swift_Mime_HeaderEncoder
+{
+
+ /**
+ * Get the name of this encoding scheme.
+ * Returns the string 'B'.
+ * @return string
+ */
+ public function getName()
+ {
+ return 'B';
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php
new file mode 100755
index 0000000..d727da0
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once dirname(__FILE__) . '/../HeaderEncoder.php';
+require_once dirname(__FILE__) . '/../../Encoder/QpEncoder.php';
+require_once dirname(__FILE__) . '/../../CharacterStream.php';
+
+/**
+ * Handles Quoted Printable (Q) Header Encoding in Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_HeaderEncoder_QpHeaderEncoder extends Swift_Encoder_QpEncoder
+ implements Swift_Mime_HeaderEncoder
+{
+
+ private static $_headerSafeMap = array();
+
+ /**
+ * Creates a new QpHeaderEncoder for the given CharacterStream.
+ * @param Swift_CharacterStream $charStream to use for reading characters
+ */
+ public function __construct(Swift_CharacterStream $charStream)
+ {
+ parent::__construct($charStream);
+ if (empty(self::$_headerSafeMap))
+ {
+ foreach (array_merge(
+ range(0x61, 0x7A), range(0x41, 0x5A),
+ range(0x30, 0x39), array(0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F)
+ ) as $byte)
+ {
+ self::$_headerSafeMap[$byte] = chr($byte);
+ }
+ }
+ }
+
+ /**
+ * Get the name of this encoding scheme.
+ * Returns the string 'Q'.
+ * @return string
+ */
+ public function getName()
+ {
+ return 'Q';
+ }
+
+ /**
+ * Takes an unencoded string and produces a Q encoded string from it.
+ * @param string $string to encode
+ * @param int $firstLineOffset, optional
+ * @param int $maxLineLength, optional, 0 indicates the default of 76 chars
+ * @return string
+ */
+ public function encodeString($string, $firstLineOffset = 0,
+ $maxLineLength = 0)
+ {
+ return str_replace(array(' ', '=20', "=\r\n"), array('_', '_', "\r\n"),
+ parent::encodeString($string, $firstLineOffset, $maxLineLength)
+ );
+ }
+
+ // -- Overridden points of extension
+
+ /**
+ * Encode the given byte array into a verbatim QP form.
+ * @param int[] $bytes
+ * @return string
+ * @access protected
+ */
+ protected function _encodeByteSequence(array $bytes, &$size)
+ {
+ $ret = '';
+ $size=0;
+ foreach ($bytes as $b)
+ {
+ if (isset(self::$_headerSafeMap[$b]))
+ {
+ $ret .= self::$_headerSafeMap[$b];
+ ++$size;
+ }
+ else
+ {
+ $ret .= self::$_qpMap[$b];
+ $size+=3;
+ }
+ }
+ return $ret;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php b/External/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php
new file mode 100755
index 0000000..83bb35a
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/CharsetObserver.php';
+
+/**
+ * Creates MIME headers.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_HeaderFactory extends Swift_Mime_CharsetObserver
+{
+
+ /**
+ * Create a new Mailbox Header with a list of $addresses.
+ * @param string $name
+ * @param array|string $addresses
+ * @return Swift_Mime_Header
+ */
+ public function createMailboxHeader($name, $addresses = null);
+
+ /**
+ * Create a new Date header using $timestamp (UNIX time).
+ * @param string $name
+ * @param int $timestamp
+ * @return Swift_Mime_Header
+ */
+ public function createDateHeader($name, $timestamp = null);
+
+ /**
+ * Create a new basic text header with $name and $value.
+ * @param string $name
+ * @param string $value
+ * @return Swift_Mime_Header
+ */
+ public function createTextHeader($name, $value = null);
+
+ /**
+ * Create a new ParameterizedHeader with $name, $value and $params.
+ * @param string $name
+ * @param string $value
+ * @param array $params
+ * @return Swift_Mime_ParameterizedHeader
+ */
+ public function createParameterizedHeader($name, $value = null,
+ $params = array());
+
+ /**
+ * Create a new ID header for Message-ID or Content-ID.
+ * @param string $name
+ * @param string|array $ids
+ * @return Swift_Mime_Header
+ */
+ public function createIdHeader($name, $ids = null);
+
+ /**
+ * Create a new Path header with an address (path) in it.
+ * @param string $name
+ * @param string $path
+ * @return Swift_Mime_Header
+ */
+ public function createPathHeader($name, $path = null);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php b/External/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php
new file mode 100755
index 0000000..81e7a97
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php
@@ -0,0 +1,170 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/CharsetObserver.php';
+
+/**
+ * A collection of MIME headers.
+ *
+ * @package Swift
+ * @subpackage Mime
+ *
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_HeaderSet extends Swift_Mime_CharsetObserver
+{
+
+ /**
+ * Add a new Mailbox Header with a list of $addresses.
+ *
+ * @param string $name
+ * @param array|string $addresses
+ */
+ public function addMailboxHeader($name, $addresses = null);
+
+ /**
+ * Add a new Date header using $timestamp (UNIX time).
+ *
+ * @param string $name
+ * @param int $timestamp
+ */
+ public function addDateHeader($name, $timestamp = null);
+
+ /**
+ * Add a new basic text header with $name and $value.
+ *
+ * @param string $name
+ * @param string $value
+ */
+ public function addTextHeader($name, $value = null);
+
+ /**
+ * Add a new ParameterizedHeader with $name, $value and $params.
+ *
+ * @param string $name
+ * @param string $value
+ * @param array $params
+ */
+ public function addParameterizedHeader($name, $value = null,
+ $params = array());
+
+ /**
+ * Add a new ID header for Message-ID or Content-ID.
+ *
+ * @param string $name
+ * @param string|array $ids
+ */
+ public function addIdHeader($name, $ids = null);
+
+ /**
+ * Add a new Path header with an address (path) in it.
+ *
+ * @param string $name
+ * @param string $path
+ */
+ public function addPathHeader($name, $path = null);
+
+ /**
+ * Returns true if at least one header with the given $name exists.
+ *
+ * If multiple headers match, the actual one may be specified by $index.
+ *
+ * @param string $name
+ * @param int $index
+ *
+ * @return boolean
+ */
+ public function has($name, $index = 0);
+
+ /**
+ * Set a header in the HeaderSet.
+ *
+ * The header may be a previously fetched header via {@link get()} or it may
+ * be one that has been created separately.
+ *
+ * If $index is specified, the header will be inserted into the set at this
+ * offset.
+ *
+ * @param Swift_Mime_Header $header
+ * @param int $index
+ */
+ public function set(Swift_Mime_Header $header, $index = 0);
+
+ /**
+ * Get the header with the given $name.
+ * If multiple headers match, the actual one may be specified by $index.
+ * Returns NULL if none present.
+ *
+ * @param string $name
+ * @param int $index
+ *
+ * @return Swift_Mime_Header
+ */
+ public function get($name, $index = 0);
+
+ /**
+ * Get all headers with the given $name.
+ *
+ * @param string $name
+ *
+ * @return array
+ */
+ public function getAll($name = null);
+
+ /**
+ * Remove the header with the given $name if it's set.
+ *
+ * If multiple headers match, the actual one may be specified by $index.
+ *
+ * @param string $name
+ * @param int $index
+ */
+ public function remove($name, $index = 0);
+
+ /**
+ * Remove all headers with the given $name.
+ *
+ * @param string $name
+ */
+ public function removeAll($name);
+
+ /**
+ * Create a new instance of this HeaderSet.
+ *
+ * @return Swift_Mime_HeaderSet
+ */
+ public function newInstance();
+
+ /**
+ * Define a list of Header names as an array in the correct order.
+ *
+ * These Headers will be output in the given order where present.
+ *
+ * @param array $sequence
+ */
+ public function defineOrdering(array $sequence);
+
+ /**
+ * Set a list of header names which must always be displayed when set.
+ *
+ * Usually headers without a field value won't be output unless set here.
+ *
+ * @param array $names
+ */
+ public function setAlwaysDisplayed(array $names);
+
+ /**
+ * Returns a string with a representation of all headers.
+ *
+ * @return string
+ */
+ public function toString();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php
new file mode 100755
index 0000000..c3049c2
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php
@@ -0,0 +1,596 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Header.php';
+//@require 'Swift/Mime/HeaderEncoder.php';
+//@require 'Swift/RfcComplianceException.php';
+
+/**
+ * An abstract base MIME Header.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header
+{
+
+ /**
+ * Special characters used in the syntax which need to be escaped.
+ * @var string[]
+ * @access private
+ */
+ private $_specials = array();
+
+ /**
+ * Tokens defined in RFC 2822 (and some related RFCs).
+ * @var string[]
+ * @access private
+ */
+ private $_grammar = array();
+
+ /**
+ * The name of this Header.
+ * @var string
+ * @access private
+ */
+ private $_name;
+
+ /**
+ * The Encoder used to encode this Header.
+ * @var Swift_Encoder
+ * @access private
+ */
+ private $_encoder;
+
+ /**
+ * The maximum length of a line in the header.
+ * @var int
+ * @access private
+ */
+ private $_lineLength = 78;
+
+ /**
+ * The language used in this Header.
+ * @var string
+ */
+ private $_lang;
+
+ /**
+ * The character set of the text in this Header.
+ * @var string
+ * @access private
+ */
+ private $_charset = 'utf-8';
+
+ /**
+ * The value of this Header, cached.
+ * @var string
+ * @access private
+ */
+ private $_cachedValue = null;
+
+ /**
+ * Set the character set used in this Header.
+ * @param string $charset
+ */
+ public function setCharset($charset)
+ {
+ $this->clearCachedValueIf($charset != $this->_charset);
+ $this->_charset = $charset;
+ if (isset($this->_encoder))
+ {
+ $this->_encoder->charsetChanged($charset);
+ }
+ }
+
+ /**
+ * Get the character set used in this Header.
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->_charset;
+ }
+
+ /**
+ * Set the language used in this Header.
+ * For example, for US English, 'en-us'.
+ * This can be unspecified.
+ * @param string $lang
+ */
+ public function setLanguage($lang)
+ {
+ $this->clearCachedValueIf($this->_lang != $lang);
+ $this->_lang = $lang;
+ }
+
+ /**
+ * Get the language used in this Header.
+ * @return string
+ */
+ public function getLanguage()
+ {
+ return $this->_lang;
+ }
+
+ /**
+ * Set the encoder used for encoding the header.
+ * @param Swift_Mime_HeaderEncoder $encoder
+ */
+ public function setEncoder(Swift_Mime_HeaderEncoder $encoder)
+ {
+ $this->_encoder = $encoder;
+ $this->setCachedValue(null);
+ }
+
+ /**
+ * Get the encoder used for encoding this Header.
+ * @return Swift_Mime_HeaderEncoder
+ */
+ public function getEncoder()
+ {
+ return $this->_encoder;
+ }
+
+ /**
+ * Get the name of this header (e.g. charset).
+ * @return string
+ */
+ public function getFieldName()
+ {
+ return $this->_name;
+ }
+
+ /**
+ * Set the maximum length of lines in the header (excluding EOL).
+ * @param int $lineLength
+ */
+ public function setMaxLineLength($lineLength)
+ {
+ $this->clearCachedValueIf($this->_lineLength != $lineLength);
+ $this->_lineLength = $lineLength;
+ }
+
+ /**
+ * Get the maximum permitted length of lines in this Header.
+ * @return int
+ */
+ public function getMaxLineLength()
+ {
+ return $this->_lineLength;
+ }
+
+ /**
+ * Get this Header rendered as a RFC 2822 compliant string.
+ * @return string
+ * @throws Swift_RfcComplianceException
+ */
+ public function toString()
+ {
+ return $this->_tokensToString($this->toTokens());
+ }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return string
+ *
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+
+ // -- Points of extension
+
+ /**
+ * Set the name of this Header field.
+ * @param string $name
+ * @access protected
+ */
+ protected function setFieldName($name)
+ {
+ $this->_name = $name;
+ }
+
+ /**
+ * Initialize some RFC 2822 (and friends) ABNF grammar definitions.
+ * @access protected
+ */
+ protected function initializeGrammar()
+ {
+ $this->_specials = array(
+ '(', ')', '<', '>', '[', ']',
+ ':', ';', '@', ',', '.', '"'
+ );
+
+ /*** Refer to RFC 2822 for ABNF grammar ***/
+
+ //All basic building blocks
+ $this->_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]';
+ $this->_grammar['WSP'] = '[ \t]';
+ $this->_grammar['CRLF'] = '(?:\r\n)';
+ $this->_grammar['FWS'] = '(?:(?:' . $this->_grammar['WSP'] . '*' .
+ $this->_grammar['CRLF'] . ')?' . $this->_grammar['WSP'] . ')';
+ $this->_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]';
+ $this->_grammar['quoted-pair'] = '(?:\\\\' . $this->_grammar['text'] . ')';
+ $this->_grammar['ctext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
+ '|[\x21-\x27\x2A-\x5B\x5D-\x7E])';
+ //Uses recursive PCRE (?1) -- could be a weak point??
+ $this->_grammar['ccontent'] = '(?:' . $this->_grammar['ctext'] . '|' .
+ $this->_grammar['quoted-pair'] . '|(?1))';
+ $this->_grammar['comment'] = '(\((?:' . $this->_grammar['FWS'] . '|' .
+ $this->_grammar['ccontent']. ')*' . $this->_grammar['FWS'] . '?\))';
+ $this->_grammar['CFWS'] = '(?:(?:' . $this->_grammar['FWS'] . '?' .
+ $this->_grammar['comment'] . ')*(?:(?:' . $this->_grammar['FWS'] . '?' .
+ $this->_grammar['comment'] . ')|' . $this->_grammar['FWS'] . '))';
+ $this->_grammar['qtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
+ '|[\x21\x23-\x5B\x5D-\x7E])';
+ $this->_grammar['qcontent'] = '(?:' . $this->_grammar['qtext'] . '|' .
+ $this->_grammar['quoted-pair'] . ')';
+ $this->_grammar['quoted-string'] = '(?:' . $this->_grammar['CFWS'] . '?"' .
+ '(' . $this->_grammar['FWS'] . '?' . $this->_grammar['qcontent'] . ')*' .
+ $this->_grammar['FWS'] . '?"' . $this->_grammar['CFWS'] . '?)';
+ $this->_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]';
+ $this->_grammar['atom'] = '(?:' . $this->_grammar['CFWS'] . '?' .
+ $this->_grammar['atext'] . '+' . $this->_grammar['CFWS'] . '?)';
+ $this->_grammar['dot-atom-text'] = '(?:' . $this->_grammar['atext'] . '+' .
+ '(\.' . $this->_grammar['atext'] . '+)*)';
+ $this->_grammar['dot-atom'] = '(?:' . $this->_grammar['CFWS'] . '?' .
+ $this->_grammar['dot-atom-text'] . '+' . $this->_grammar['CFWS'] . '?)';
+ $this->_grammar['word'] = '(?:' . $this->_grammar['atom'] . '|' .
+ $this->_grammar['quoted-string'] . ')';
+ $this->_grammar['phrase'] = '(?:' . $this->_grammar['word'] . '+?)';
+ $this->_grammar['no-fold-quote'] = '(?:"(?:' . $this->_grammar['qtext'] .
+ '|' . $this->_grammar['quoted-pair'] . ')*")';
+ $this->_grammar['dtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
+ '|[\x21-\x5A\x5E-\x7E])';
+ $this->_grammar['no-fold-literal'] = '(?:\[(?:' . $this->_grammar['dtext'] .
+ '|' . $this->_grammar['quoted-pair'] . ')*\])';
+
+ //Message IDs
+ $this->_grammar['id-left'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' .
+ $this->_grammar['no-fold-quote'] . ')';
+ $this->_grammar['id-right'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' .
+ $this->_grammar['no-fold-literal'] . ')';
+
+ //Addresses, mailboxes and paths
+ $this->_grammar['local-part'] = '(?:' . $this->_grammar['dot-atom'] . '|' .
+ $this->_grammar['quoted-string'] . ')';
+ $this->_grammar['dcontent'] = '(?:' . $this->_grammar['dtext'] . '|' .
+ $this->_grammar['quoted-pair'] . ')';
+ $this->_grammar['domain-literal'] = '(?:' . $this->_grammar['CFWS'] . '?\[(' .
+ $this->_grammar['FWS'] . '?' . $this->_grammar['dcontent'] . ')*?' .
+ $this->_grammar['FWS'] . '?\]' . $this->_grammar['CFWS'] . '?)';
+ $this->_grammar['domain'] = '(?:' . $this->_grammar['dot-atom'] . '|' .
+ $this->_grammar['domain-literal'] . ')';
+ $this->_grammar['addr-spec'] = '(?:' . $this->_grammar['local-part'] . '@' .
+ $this->_grammar['domain'] . ')';
+ }
+
+ /**
+ * Get the grammar defined for $name token.
+ * @param string $name execatly as written in the RFC
+ * @return string
+ */
+ protected function getGrammar($name)
+ {
+ if (array_key_exists($name, $this->_grammar))
+ {
+ return $this->_grammar[$name];
+ }
+ else
+ {
+ throw new Swift_RfcComplianceException(
+ "No such grammar '" . $name . "' defined."
+ );
+ }
+ }
+
+ /**
+ * Escape special characters in a string (convert to quoted-pairs).
+ * @param string $token
+ * @param string[] $include additonal chars to escape
+ * @param string[] $exclude chars from escaping
+ * @return string
+ */
+ protected function escapeSpecials($token, $include = array(),
+ $exclude = array())
+ {
+ foreach (
+ array_merge(array('\\'), array_diff($this->_specials, $exclude), $include) as $char)
+ {
+ $token = str_replace($char, '\\' . $char, $token);
+ }
+ return $token;
+ }
+
+ /**
+ * Produces a compliant, formatted RFC 2822 'phrase' based on the string given.
+ * @param Swift_Mime_Header $header
+ * @param string $string as displayed
+ * @param string $charset of the text
+ * @param Swift_Mime_HeaderEncoder $encoder
+ * @param boolean $shorten the first line to make remove for header name
+ * @return string
+ */
+ protected function createPhrase(Swift_Mime_Header $header, $string, $charset,
+ Swift_Mime_HeaderEncoder $encoder = null, $shorten = false)
+ {
+ //Treat token as exactly what was given
+ $phraseStr = $string;
+ //If it's not valid
+ if (!preg_match('/^' . $this->_grammar['phrase'] . '$/D', $phraseStr))
+ {
+ // .. but it is just ascii text, try escaping some characters
+ // and make it a quoted-string
+ if (preg_match('/^' . $this->_grammar['text'] . '*$/D', $phraseStr))
+ {
+ $phraseStr = $this->escapeSpecials(
+ $phraseStr, array('"'), $this->_specials
+ );
+ $phraseStr = '"' . $phraseStr . '"';
+ }
+ else // ... otherwise it needs encoding
+ {
+ //Determine space remaining on line if first line
+ if ($shorten)
+ {
+ $usedLength = strlen($header->getFieldName() . ': ');
+ }
+ else
+ {
+ $usedLength = 0;
+ }
+ $phraseStr = $this->encodeWords($header, $string, $usedLength);
+ }
+ }
+
+ return $phraseStr;
+ }
+
+ /**
+ * Encode needed word tokens within a string of input.
+ * @param string $input
+ * @param string $usedLength, optional
+ * @return string
+ */
+ protected function encodeWords(Swift_Mime_Header $header, $input,
+ $usedLength = -1)
+ {
+ $value = '';
+
+ $tokens = $this->getEncodableWordTokens($input);
+
+ foreach ($tokens as $token)
+ {
+ //See RFC 2822, Sect 2.2 (really 2.2 ??)
+ if ($this->tokenNeedsEncoding($token))
+ {
+ //Don't encode starting WSP
+ $firstChar = substr($token, 0, 1);
+ switch($firstChar)
+ {
+ case ' ':
+ case "\t":
+ $value .= $firstChar;
+ $token = substr($token, 1);
+ }
+
+ if (-1 == $usedLength)
+ {
+ $usedLength = strlen($header->getFieldName() . ': ') + strlen($value);
+ }
+ $value .= $this->getTokenAsEncodedWord($token, $usedLength);
+
+ $header->setMaxLineLength(76); //Forefully override
+ }
+ else
+ {
+ $value .= $token;
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Test if a token needs to be encoded or not.
+ * @param string $token
+ * @return boolean
+ */
+ protected function tokenNeedsEncoding($token)
+ {
+ return preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token);
+ }
+
+ /**
+ * Splits a string into tokens in blocks of words which can be encoded quickly.
+ * @param string $string
+ * @return string[]
+ */
+ protected function getEncodableWordTokens($string)
+ {
+ $tokens = array();
+
+ $encodedToken = '';
+ //Split at all whitespace boundaries
+ foreach (preg_split('~(?=[\t ])~', $string) as $token)
+ {
+ if ($this->tokenNeedsEncoding($token))
+ {
+ $encodedToken .= $token;
+ }
+ else
+ {
+ if (strlen($encodedToken) > 0)
+ {
+ $tokens[] = $encodedToken;
+ $encodedToken = '';
+ }
+ $tokens[] = $token;
+ }
+ }
+ if (strlen($encodedToken))
+ {
+ $tokens[] = $encodedToken;
+ }
+
+ return $tokens;
+ }
+
+ /**
+ * Get a token as an encoded word for safe insertion into headers.
+ * @param string $token to encode
+ * @param int $firstLineOffset, optional
+ * @return string
+ */
+ protected function getTokenAsEncodedWord($token, $firstLineOffset = 0)
+ {
+ //Adjust $firstLineOffset to account for space needed for syntax
+ $charsetDecl = $this->_charset;
+ if (isset($this->_lang))
+ {
+ $charsetDecl .= '*' . $this->_lang;
+ }
+ $encodingWrapperLength = strlen(
+ '=?' . $charsetDecl . '?' . $this->_encoder->getName() . '??='
+ );
+
+ if ($firstLineOffset >= 75) //Does this logic need to be here?
+ {
+ $firstLineOffset = 0;
+ }
+
+ $encodedTextLines = explode("\r\n",
+ $this->_encoder->encodeString(
+ $token, $firstLineOffset, 75 - $encodingWrapperLength
+ )
+ );
+
+ foreach ($encodedTextLines as $lineNum => $line)
+ {
+ $encodedTextLines[$lineNum] = '=?' . $charsetDecl .
+ '?' . $this->_encoder->getName() .
+ '?' . $line . '?=';
+ }
+
+ return implode("\r\n ", $encodedTextLines);
+ }
+
+ /**
+ * Generates tokens from the given string which include CRLF as individual tokens.
+ * @param string $token
+ * @return string[]
+ * @access protected
+ */
+ protected function generateTokenLines($token)
+ {
+ return preg_split('~(\r\n)~', $token, -1, PREG_SPLIT_DELIM_CAPTURE);
+ }
+
+ /**
+ * Set a value into the cache.
+ * @param string $value
+ * @access protected
+ */
+ protected function setCachedValue($value)
+ {
+ $this->_cachedValue = $value;
+ }
+
+ /**
+ * Get the value in the cache.
+ * @return string
+ * @access protected
+ */
+ protected function getCachedValue()
+ {
+ return $this->_cachedValue;
+ }
+
+ /**
+ * Clear the cached value if $condition is met.
+ * @param boolean $condition
+ * @access protected
+ */
+ protected function clearCachedValueIf($condition)
+ {
+ if ($condition)
+ {
+ $this->setCachedValue(null);
+ }
+ }
+
+ // -- Private methods
+
+ /**
+ * Generate a list of all tokens in the final header.
+ * @param string $string input, optional
+ * @return string[]
+ * @access private
+ */
+ protected function toTokens($string = null)
+ {
+ if (is_null($string))
+ {
+ $string = $this->getFieldBody();
+ }
+
+ $tokens = array();
+
+ //Generate atoms; split at all invisible boundaries followed by WSP
+ foreach (preg_split('~(?=[ \t])~', $string) as $token)
+ {
+ $tokens = array_merge($tokens, $this->generateTokenLines($token));
+ }
+
+ return $tokens;
+ }
+
+ /**
+ * Takes an array of tokens which appear in the header and turns them into
+ * an RFC 2822 compliant string, adding FWSP where needed.
+ * @param string[] $tokens
+ * @return string
+ * @access private
+ */
+ private function _tokensToString(array $tokens)
+ {
+ $lineCount = 0;
+ $headerLines = array();
+ $headerLines[] = $this->_name . ': ';
+ $currentLine =& $headerLines[$lineCount++];
+
+ //Build all tokens back into compliant header
+ foreach ($tokens as $i => $token)
+ {
+ //Line longer than specified maximum or token was just a new line
+ if (("\r\n" == $token) ||
+ ($i > 0 && strlen($currentLine . $token) > $this->_lineLength)
+ && 0 < strlen($currentLine))
+ {
+ $headerLines[] = '';
+ $currentLine =& $headerLines[$lineCount++];
+ }
+
+ //Append token to the line
+ if ("\r\n" != $token)
+ {
+ $currentLine .= $token;
+ }
+ }
+
+ //Implode with FWS (RFC 2822, 2.2.3)
+ return implode("\r\n", $headerLines) . "\r\n";
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php
new file mode 100755
index 0000000..598c0c5
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/AbstractHeader.php';
+
+
+/**
+ * A Date MIME Header for Swift Mailer.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_DateHeader extends Swift_Mime_Headers_AbstractHeader
+{
+
+ /**
+ * The UNIX timestamp value of this Header.
+ * @var int
+ * @access private
+ */
+ private $_timestamp;
+
+ /**
+ * Creates a new DateHeader with $name and $timestamp.
+ * Example:
+ * <code>
+ * <?php
+ * $header = new Swift_Mime_Headers_DateHeader('Date', time());
+ * ?>
+ * </code>
+ * @param string $name of Header
+ */
+ public function __construct($name)
+ {
+ $this->setFieldName($name);
+ }
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_DATE;
+ }
+
+ /**
+ * Set the model for the field body.
+ * This method takes a UNIX timestamp.
+ * @param int $model
+ */
+ public function setFieldBodyModel($model)
+ {
+ $this->setTimestamp($model);
+ }
+
+ /**
+ * Get the model for the field body.
+ * This method returns a UNIX timestamp.
+ * @return mixed
+ */
+ public function getFieldBodyModel()
+ {
+ return $this->getTimestamp();
+ }
+
+ /**
+ * Get the UNIX timestamp of the Date in this Header.
+ * @return int
+ */
+ public function getTimestamp()
+ {
+ return $this->_timestamp;
+ }
+
+ /**
+ * Set the UNIX timestamp of the Date in this Header.
+ * @param int $timestamp
+ */
+ public function setTimestamp($timestamp)
+ {
+ if (!is_null($timestamp))
+ {
+ $timestamp = (int) $timestamp;
+ }
+ $this->clearCachedValueIf($this->_timestamp != $timestamp);
+ $this->_timestamp = $timestamp;
+ }
+
+ /**
+ * Get the string value of the body in this Header.
+ * This is not necessarily RFC 2822 compliant since folding white space will
+ * not be added at this stage (see {@link toString()} for that).
+ * @return string
+ * @see toString()
+ */
+ public function getFieldBody()
+ {
+ if (!$this->getCachedValue())
+ {
+ if (isset($this->_timestamp))
+ {
+ $this->setCachedValue(date('r', $this->_timestamp));
+ }
+ }
+ return $this->getCachedValue();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php
new file mode 100755
index 0000000..55ff737
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/AbstractHeader.php';
+//@require 'Swift/RfcComplianceException.php';
+
+/**
+ * An ID MIME Header for something like Message-ID or Content-ID.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_IdentificationHeader
+ extends Swift_Mime_Headers_AbstractHeader
+{
+
+ /**
+ * The IDs used in the value of this Header.
+ * This may hold multiple IDs or just a single ID.
+ * @var string[]
+ * @access private
+ */
+ private $_ids = array();
+
+ /**
+ * Creates a new IdentificationHeader with the given $name and $id.
+ * @param string $name
+ */
+ public function __construct($name)
+ {
+ $this->setFieldName($name);
+ $this->initializeGrammar();
+ }
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_ID;
+ }
+
+ /**
+ * Set the model for the field body.
+ * This method takes a string ID, or an array of IDs
+ * @param mixed $model
+ * @throws Swift_RfcComplianceException
+ */
+ public function setFieldBodyModel($model)
+ {
+ $this->setId($model);
+ }
+
+ /**
+ * Get the model for the field body.
+ * This method returns an array of IDs
+ * @return array
+ */
+ public function getFieldBodyModel()
+ {
+ return $this->getIds();
+ }
+
+ /**
+ * Set the ID used in the value of this header.
+ * @param string $id
+ * @throws Swift_RfcComplianceException
+ */
+ public function setId($id)
+ {
+ return $this->setIds(array($id));
+ }
+
+ /**
+ * Get the ID used in the value of this Header.
+ * If multiple IDs are set only the first is returned.
+ * @return string
+ */
+ public function getId()
+ {
+ if (count($this->_ids) > 0)
+ {
+ return $this->_ids[0];
+ }
+ }
+
+ /**
+ * Set a collection of IDs to use in the value of this Header.
+ * @param string[] $ids
+ * @throws Swift_RfcComplianceException
+ */
+ public function setIds(array $ids)
+ {
+ $actualIds = array();
+
+ foreach ($ids as $k => $id)
+ {
+ if (preg_match(
+ '/^' . $this->getGrammar('id-left') . '@' .
+ $this->getGrammar('id-right') . '$/D',
+ $id
+ ))
+ {
+ $actualIds[] = $id;
+ }
+ else
+ {
+ throw new Swift_RfcComplianceException(
+ 'Invalid ID given <' . $id . '>'
+ );
+ }
+ }
+
+ $this->clearCachedValueIf($this->_ids != $actualIds);
+ $this->_ids = $actualIds;
+ }
+
+ /**
+ * Get the list of IDs used in this Header.
+ * @return string[]
+ */
+ public function getIds()
+ {
+ return $this->_ids;
+ }
+
+ /**
+ * Get the string value of the body in this Header.
+ * This is not necessarily RFC 2822 compliant since folding white space will
+ * not be added at this stage (see {@link toString()} for that).
+ * @return string
+ * @see toString()
+ * @throws Swift_RfcComplianceException
+ */
+ public function getFieldBody()
+ {
+ if (!$this->getCachedValue())
+ {
+ $angleAddrs = array();
+
+ foreach ($this->_ids as $id)
+ {
+ $angleAddrs[] = '<' . $id . '>';
+ }
+
+ $this->setCachedValue(implode(' ', $angleAddrs));
+ }
+ return $this->getCachedValue();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php
new file mode 100755
index 0000000..77d3bba
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php
@@ -0,0 +1,316 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/AbstractHeader.php';
+//@require 'Swift/Mime/HeaderEncoder.php';
+
+/**
+ * A Mailbox Address MIME Header for something like From or Sender.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader
+{
+
+ /**
+ * The mailboxes used in this Header.
+ * @var string[]
+ * @access private
+ */
+ private $_mailboxes = array();
+
+ /**
+ * Creates a new MailboxHeader with $name.
+ * @param string $name of Header
+ * @param Swift_Mime_HeaderEncoder $encoder
+ */
+ public function __construct($name, Swift_Mime_HeaderEncoder $encoder)
+ {
+ $this->setFieldName($name);
+ $this->setEncoder($encoder);
+ $this->initializeGrammar();
+ }
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_MAILBOX;
+ }
+
+ /**
+ * Set the model for the field body.
+ * This method takes a string, or an array of addresses.
+ * @param mixed $model
+ * @throws Swift_RfcComplianceException
+ */
+ public function setFieldBodyModel($model)
+ {
+ $this->setNameAddresses($model);
+ }
+
+ /**
+ * Get the model for the field body.
+ * This method returns an associative array like {@link getNameAddresses()}
+ * @return array
+ * @throws Swift_RfcComplianceException
+ */
+ public function getFieldBodyModel()
+ {
+ return $this->getNameAddresses();
+ }
+
+ /**
+ * Set a list of mailboxes to be shown in this Header.
+ * The mailboxes can be a simple array of addresses, or an array of
+ * key=>value pairs where (email => personalName).
+ * Example:
+ * <code>
+ * <?php
+ * //Sets two mailboxes in the Header, one with a personal name
+ * $header->setNameAddresses(array(
+ * 'chris@swiftmailer.org' => 'Chris Corbyn',
+ * 'mark@swiftmailer.org' //No associated personal name
+ * ));
+ * ?>
+ * </code>
+ * @param string|string[] $mailboxes
+ * @throws Swift_RfcComplianceException
+ * @see __construct()
+ * @see setAddresses()
+ * @see setValue()
+ */
+ public function setNameAddresses($mailboxes)
+ {
+ $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes);
+ $this->setCachedValue(null); //Clear any cached value
+ }
+
+ /**
+ * Get the full mailbox list of this Header as an array of valid RFC 2822 strings.
+ * Example:
+ * <code>
+ * <?php
+ * $header = new Swift_Mime_Headers_MailboxHeader('From',
+ * array('chris@swiftmailer.org' => 'Chris Corbyn',
+ * 'mark@swiftmailer.org' => 'Mark Corbyn')
+ * );
+ * print_r($header->getNameAddressStrings());
+ * // array (
+ * // 0 => Chris Corbyn <chris@swiftmailer.org>,
+ * // 1 => Mark Corbyn <mark@swiftmailer.org>
+ * // )
+ * ?>
+ * </code>
+ * @return string[]
+ * @throws Swift_RfcComplianceException
+ * @see getNameAddresses()
+ * @see toString()
+ */
+ public function getNameAddressStrings()
+ {
+ return $this->_createNameAddressStrings($this->getNameAddresses());
+ }
+
+ /**
+ * Get all mailboxes in this Header as key=>value pairs.
+ * The key is the address and the value is the name (or null if none set).
+ * Example:
+ * <code>
+ * <?php
+ * $header = new Swift_Mime_Headers_MailboxHeader('From',
+ * array('chris@swiftmailer.org' => 'Chris Corbyn',
+ * 'mark@swiftmailer.org' => 'Mark Corbyn')
+ * );
+ * print_r($header->getNameAddresses());
+ * // array (
+ * // chris@swiftmailer.org => Chris Corbyn,
+ * // mark@swiftmailer.org => Mark Corbyn
+ * // )
+ * ?>
+ * </code>
+ * @return string[]
+ * @see getAddresses()
+ * @see getNameAddressStrings()
+ */
+ public function getNameAddresses()
+ {
+ return $this->_mailboxes;
+ }
+
+ /**
+ * Makes this Header represent a list of plain email addresses with no names.
+ * Example:
+ * <code>
+ * <?php
+ * //Sets three email addresses as the Header data
+ * $header->setAddresses(
+ * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld')
+ * );
+ * ?>
+ * </code>
+ * @param string[] $addresses
+ * @throws Swift_RfcComplianceException
+ * @see setNameAddresses()
+ * @see setValue()
+ */
+ public function setAddresses($addresses)
+ {
+ return $this->setNameAddresses(array_values((array) $addresses));
+ }
+
+ /**
+ * Get all email addresses in this Header.
+ * @return string[]
+ * @see getNameAddresses()
+ */
+ public function getAddresses()
+ {
+ return array_keys($this->_mailboxes);
+ }
+
+ /**
+ * Remove one or more addresses from this Header.
+ * @param string|string[] $addresses
+ */
+ public function removeAddresses($addresses)
+ {
+ $this->setCachedValue(null);
+ foreach ((array) $addresses as $address)
+ {
+ unset($this->_mailboxes[$address]);
+ }
+ }
+
+ /**
+ * Get the string value of the body in this Header.
+ * This is not necessarily RFC 2822 compliant since folding white space will
+ * not be added at this stage (see {@link toString()} for that).
+ * @return string
+ * @throws Swift_RfcComplianceException
+ * @see toString()
+ */
+ public function getFieldBody()
+ {
+ //Compute the string value of the header only if needed
+ if (is_null($this->getCachedValue()))
+ {
+ $this->setCachedValue($this->createMailboxListString($this->_mailboxes));
+ }
+ return $this->getCachedValue();
+ }
+
+ // -- Points of extension
+
+ /**
+ * Normalizes a user-input list of mailboxes into consistent key=>value pairs.
+ * @param string[] $mailboxes
+ * @return string[]
+ * @access protected
+ */
+ protected function normalizeMailboxes(array $mailboxes)
+ {
+ $actualMailboxes = array();
+
+ foreach ($mailboxes as $key => $value)
+ {
+ if (is_string($key)) //key is email addr
+ {
+ $address = $key;
+ $name = $value;
+ }
+ else
+ {
+ $address = $value;
+ $name = null;
+ }
+ $this->_assertValidAddress($address);
+ $actualMailboxes[$address] = $name;
+ }
+
+ return $actualMailboxes;
+ }
+
+ /**
+ * Produces a compliant, formatted display-name based on the string given.
+ * @param string $displayName as displayed
+ * @param boolean $shorten the first line to make remove for header name
+ * @return string
+ * @access protected
+ */
+ protected function createDisplayNameString($displayName, $shorten = false)
+ {
+ return $this->createPhrase($this, $displayName,
+ $this->getCharset(), $this->getEncoder(), $shorten
+ );
+ }
+
+ /**
+ * Creates a string form of all the mailboxes in the passed array.
+ * @param string[] $mailboxes
+ * @return string
+ * @throws Swift_RfcComplianceException
+ * @access protected
+ */
+ protected function createMailboxListString(array $mailboxes)
+ {
+ return implode(', ', $this->_createNameAddressStrings($mailboxes));
+ }
+
+ // -- Private methods
+
+ /**
+ * Return an array of strings conforming the the name-addr spec of RFC 2822.
+ * @param string[] $mailboxes
+ * @return string[]
+ * @access private
+ */
+ private function _createNameAddressStrings(array $mailboxes)
+ {
+ $strings = array();
+
+ foreach ($mailboxes as $email => $name)
+ {
+ $mailboxStr = $email;
+ if (!is_null($name))
+ {
+ $nameStr = $this->createDisplayNameString($name, empty($strings));
+ $mailboxStr = $nameStr . ' <' . $mailboxStr . '>';
+ }
+ $strings[] = $mailboxStr;
+ }
+
+ return $strings;
+ }
+
+ /**
+ * Throws an Exception if the address passed does not comply with RFC 2822.
+ * @param string $address
+ * @throws Exception If invalid.
+ * @access protected
+ */
+ private function _assertValidAddress($address)
+ {
+ if (!preg_match('/^' . $this->getGrammar('addr-spec') . '$/D',
+ $address))
+ {
+ throw new Swift_RfcComplianceException(
+ 'Address in mailbox given [' . $address .
+ '] does not comply with RFC 2822, 3.6.2.'
+ );
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php
new file mode 100755
index 0000000..974b44e
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php
@@ -0,0 +1,274 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/UnstructuredHeader.php';
+//@require 'Swift/Mime/HeaderEncoder.php';
+//@require 'Swift/Mime/ParameterizedHeader.php';
+//@require 'Swift/Encoder.php';
+
+/**
+ * An abstract base MIME Header.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_ParameterizedHeader
+ extends Swift_Mime_Headers_UnstructuredHeader
+ implements Swift_Mime_ParameterizedHeader
+{
+
+ /**
+ * The Encoder used to encode the parameters.
+ * @var Swift_Encoder
+ * @access private
+ */
+ private $_paramEncoder;
+
+ /**
+ * The parameters as an associative array.
+ * @var string[]
+ * @access private
+ */
+ private $_params = array();
+
+ /**
+ * RFC 2231's definition of a token.
+ * @var string
+ * @access private
+ */
+ private $_tokenRe;
+
+ /**
+ * Creates a new ParameterizedHeader with $name.
+ * @param string $name
+ * @param Swift_Mime_HeaderEncoder $encoder
+ * @param Swift_Encoder $paramEncoder, optional
+ */
+ public function __construct($name, Swift_Mime_HeaderEncoder $encoder,
+ Swift_Encoder $paramEncoder = null)
+ {
+ $this->setFieldName($name);
+ $this->setEncoder($encoder);
+ $this->_paramEncoder = $paramEncoder;
+ $this->initializeGrammar();
+ $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';
+ }
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_PARAMETERIZED;
+ }
+
+ /**
+ * Set the character set used in this Header.
+ * @param string $charset
+ */
+ public function setCharset($charset)
+ {
+ parent::setCharset($charset);
+ if (isset($this->_paramEncoder))
+ {
+ $this->_paramEncoder->charsetChanged($charset);
+ }
+ }
+
+ /**
+ * Set the value of $parameter.
+ * @param string $parameter
+ * @param string $value
+ */
+ public function setParameter($parameter, $value)
+ {
+ $this->setParameters(array_merge($this->getParameters(), array($parameter => $value)));
+ }
+
+ /**
+ * Get the value of $parameter.
+ * @return string
+ */
+ public function getParameter($parameter)
+ {
+ $params = $this->getParameters();
+ return array_key_exists($parameter, $params)
+ ? $params[$parameter]
+ : null;
+ }
+
+ /**
+ * Set an associative array of parameter names mapped to values.
+ * @param string[]
+ */
+ public function setParameters(array $parameters)
+ {
+ $this->clearCachedValueIf($this->_params != $parameters);
+ $this->_params = $parameters;
+ }
+
+ /**
+ * Returns an associative array of parameter names mapped to values.
+ * @return string[]
+ */
+ public function getParameters()
+ {
+ return $this->_params;
+ }
+
+ /**
+ * Get the value of this header prepared for rendering.
+ * @return string
+ */
+ public function getFieldBody() //TODO: Check caching here
+ {
+ $body = parent::getFieldBody();
+ foreach ($this->_params as $name => $value)
+ {
+ if (!is_null($value))
+ {
+ //Add the parameter
+ $body .= '; ' . $this->_createParameter($name, $value);
+ }
+ }
+ return $body;
+ }
+
+ // -- Protected methods
+
+ /**
+ * Generate a list of all tokens in the final header.
+ * This doesn't need to be overridden in theory, but it is for implementation
+ * reasons to prevent potential breakage of attributes.
+ * @return string[]
+ * @access protected
+ */
+ protected function toTokens($string = null)
+ {
+ $tokens = parent::toTokens(parent::getFieldBody());
+
+ //Try creating any parameters
+ foreach ($this->_params as $name => $value)
+ {
+ if (!is_null($value))
+ {
+ //Add the semi-colon separator
+ $tokens[count($tokens)-1] .= ';';
+ $tokens = array_merge($tokens, $this->generateTokenLines(
+ ' ' . $this->_createParameter($name, $value)
+ ));
+ }
+ }
+
+ return $tokens;
+ }
+
+ // -- Private methods
+
+ /**
+ * Render a RFC 2047 compliant header parameter from the $name and $value.
+ * @param string $name
+ * @param string $value
+ * @return string
+ * @access private
+ */
+ private function _createParameter($name, $value)
+ {
+ $origValue = $value;
+
+ $encoded = false;
+ //Allow room for parameter name, indices, "=" and DQUOTEs
+ $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1;
+ $firstLineOffset = 0;
+
+ //If it's not already a valid parameter value...
+ if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
+ {
+ //TODO: text, or something else??
+ //... and it's not ascii
+ if (!preg_match('/^' . $this->getGrammar('text') . '*$/D', $value))
+ {
+ $encoded = true;
+ //Allow space for the indices, charset and language
+ $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1;
+ $firstLineOffset = strlen(
+ $this->getCharset() . "'" . $this->getLanguage() . "'"
+ );
+ }
+ }
+
+ //Encode if we need to
+ if ($encoded || strlen($value) > $maxValueLength)
+ {
+ if (isset($this->_paramEncoder))
+ {
+ $value = $this->_paramEncoder->encodeString(
+ $origValue, $firstLineOffset, $maxValueLength
+ );
+ }
+ else //We have to go against RFC 2183/2231 in some areas for interoperability
+ {
+ $value = $this->getTokenAsEncodedWord($origValue);
+ $encoded = false;
+ }
+ }
+
+ $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value);
+
+ //Need to add indices
+ if (count($valueLines) > 1)
+ {
+ $paramLines = array();
+ foreach ($valueLines as $i => $line)
+ {
+ $paramLines[] = $name . '*' . $i .
+ $this->_getEndOfParameterValue($line, $encoded, $i == 0);
+ }
+ return implode(";\r\n ", $paramLines);
+ }
+ else
+ {
+ return $name . $this->_getEndOfParameterValue(
+ $valueLines[0], $encoded, true
+ );
+ }
+ }
+
+ /**
+ * Returns the parameter value from the "=" and beyond.
+ * @param string $value to append
+ * @param boolean $encoded
+ * @param boolean $firstLine
+ * @return string
+ * @access private
+ */
+ private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false)
+ {
+ if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
+ {
+ $value = '"' . $value . '"';
+ }
+ $prepend = '=';
+ if ($encoded)
+ {
+ $prepend = '*=';
+ if ($firstLine)
+ {
+ $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() .
+ "'";
+ }
+ }
+ return $prepend . $value;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php
new file mode 100755
index 0000000..0a8a100
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/AbstractHeader.php';
+//@require 'Swift/RfcComplianceException.php';
+
+/**
+ * A Path Header in Swift Mailer, such a Return-Path.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_PathHeader extends Swift_Mime_Headers_AbstractHeader
+{
+
+ /**
+ * The address in this Header (if specified).
+ * @var string
+ * @access private
+ */
+ private $_address;
+
+ /**
+ * Creates a new PathHeader with the given $name.
+ * @param string $name
+ */
+ public function __construct($name)
+ {
+ $this->setFieldName($name);
+ $this->initializeGrammar();
+ }
+
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_PATH;
+ }
+
+ /**
+ * Set the model for the field body.
+ * This method takes a string for an address.
+ * @param string $model
+ * @throws Swift_RfcComplianceException
+ */
+ public function setFieldBodyModel($model)
+ {
+ $this->setAddress($model);
+ }
+
+ /**
+ * Get the model for the field body.
+ * This method returns a string email address.
+ * @return mixed
+ */
+ public function getFieldBodyModel()
+ {
+ return $this->getAddress();
+ }
+
+ /**
+ * Set the Address which should appear in this Header.
+ * @param string $address
+ * @throws Swift_RfcComplianceException
+ */
+ public function setAddress($address)
+ {
+ if (is_null($address))
+ {
+ $this->_address = null;
+ }
+ elseif ('' == $address
+ || preg_match('/^' . $this->getGrammar('addr-spec') . '$/D', $address))
+ {
+ $this->_address = $address;
+ }
+ else
+ {
+ throw new Swift_RfcComplianceException(
+ 'Address set in PathHeader does not comply with addr-spec of RFC 2822.'
+ );
+ }
+ $this->setCachedValue(null);
+ }
+
+ /**
+ * Get the address which is used in this Header (if any).
+ * Null is returned if no address is set.
+ * @return string
+ */
+ public function getAddress()
+ {
+ return $this->_address;
+ }
+
+ /**
+ * Get the string value of the body in this Header.
+ * This is not necessarily RFC 2822 compliant since folding white space will
+ * not be added at this stage (see {@link toString()} for that).
+ * @return string
+ * @see toString()
+ */
+ public function getFieldBody()
+ {
+ if (!$this->getCachedValue())
+ {
+ if (isset($this->_address))
+ {
+ $this->setCachedValue('<' . $this->_address . '>');
+ }
+ }
+ return $this->getCachedValue();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php
new file mode 100755
index 0000000..fdcc21e
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Headers/AbstractHeader.php';
+//@require 'Swift/Mime/HeaderEncoder.php';
+
+/**
+ * A Simple MIME Header.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_Headers_UnstructuredHeader
+ extends Swift_Mime_Headers_AbstractHeader
+{
+
+ /**
+ * The value of this Header.
+ * @var string
+ * @access private
+ */
+ private $_value;
+
+ /**
+ * Creates a new SimpleHeader with $name.
+ * @param string $name
+ * @param Swift_Mime_HeaderEncoder $encoder
+ */
+ public function __construct($name, Swift_Mime_HeaderEncoder $encoder)
+ {
+ $this->setFieldName($name);
+ $this->setEncoder($encoder);
+ }
+ /**
+ * Get the type of Header that this instance represents.
+ * @return int
+ * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
+ * @see TYPE_DATE, TYPE_ID, TYPE_PATH
+ */
+ public function getFieldType()
+ {
+ return self::TYPE_TEXT;
+ }
+
+ /**
+ * Set the model for the field body.
+ * This method takes a string for the field value.
+ * @param string $model
+ */
+ public function setFieldBodyModel($model)
+ {
+ $this->setValue($model);
+ }
+
+ /**
+ * Get the model for the field body.
+ * This method returns a string.
+ * @return string
+ */
+ public function getFieldBodyModel()
+ {
+ return $this->getValue();
+ }
+
+ /**
+ * Get the (unencoded) value of this header.
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->_value;
+ }
+
+ /**
+ * Set the (unencoded) value of this header.
+ * @param string $value
+ */
+ public function setValue($value)
+ {
+ $this->clearCachedValueIf($this->_value != $value);
+ $this->_value = $value;
+ }
+
+ /**
+ * Get the value of this header prepared for rendering.
+ * @return string
+ */
+ public function getFieldBody()
+ {
+ if (!$this->getCachedValue())
+ {
+ $this->setCachedValue(
+ str_replace('\\', '\\\\', $this->encodeWords(
+ $this, $this->_value, -1, $this->getCharset(), $this->getEncoder()
+ ))
+ );
+ }
+ return $this->getCachedValue();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/Message.php b/External/swiftmailer/lib/classes/Swift/Mime/Message.php
new file mode 100755
index 0000000..0496c08
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/Message.php
@@ -0,0 +1,230 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/MimeEntity.php';
+
+/**
+ * A Message (RFC 2822) object.
+ *
+ * @package Swift
+ * @subpackage Mime
+ *
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_Message extends Swift_Mime_MimeEntity
+{
+
+ /**
+ * Generates a valid Message-ID and switches to it.
+ *
+ * @return string
+ */
+ public function generateId();
+
+ /**
+ * Set the subject of the message.
+ *
+ * @param string $subject
+ */
+ public function setSubject($subject);
+
+ /**
+ * Get the subject of the message.
+ *
+ * @return string
+ */
+ public function getSubject();
+
+ /**
+ * Set the origination date of the message as a UNIX timestamp.
+ *
+ * @param int $date
+ */
+ public function setDate($date);
+
+ /**
+ * Get the origination date of the message as a UNIX timestamp.
+ *
+ * @return int
+ */
+ public function getDate();
+
+ /**
+ * Set the return-path (bounce-detect) address.
+ *
+ * @param string $address
+ */
+ public function setReturnPath($address);
+
+ /**
+ * Get the return-path (bounce-detect) address.
+ *
+ * @return string
+ */
+ public function getReturnPath();
+
+ /**
+ * Set the sender of this message.
+ *
+ * If multiple addresses are present in the From field, this SHOULD be set.
+ *
+ * According to RFC 2822 it is a requirement when there are multiple From
+ * addresses, but Swift itself does not require it directly.
+ *
+ * An associative array (with one element!) can be used to provide a display-
+ * name: i.e. array('email@address' => 'Real Name').
+ *
+ * If the second parameter is provided and the first is a string, then $name
+ * is associated with the address.
+ *
+ * @param mixed $address
+ * @param string $name optional
+ */
+ public function setSender($address, $name = null);
+
+ /**
+ * Get the sender address for this message.
+ *
+ * This has a higher significance than the From address.
+ *
+ * @return string
+ */
+ public function getSender();
+
+ /**
+ * Set the From address of this message.
+ *
+ * It is permissible for multiple From addresses to be set using an array.
+ *
+ * If multiple From addresses are used, you SHOULD set the Sender address and
+ * according to RFC 2822, MUST set the sender address.
+ *
+ * An array can be used if display names are to be provided: i.e.
+ * array('email@address.com' => 'Real Name').
+ *
+ * If the second parameter is provided and the first is a string, then $name
+ * is associated with the address.
+ *
+ * @param mixed $addresses
+ * @param string $name optional
+ */
+ public function setFrom($addresses, $name = null);
+
+ /**
+ * Get the From address(es) of this message.
+ *
+ * This method always returns an associative array where the keys are the
+ * addresses.
+ *
+ * @return string[]
+ */
+ public function getFrom();
+
+ /**
+ * Set the Reply-To address(es).
+ *
+ * Any replies from the receiver will be sent to this address.
+ *
+ * It is permissible for multiple reply-to addresses to be set using an array.
+ *
+ * This method has the same synopsis as {@link setFrom()} and {@link setTo()}.
+ *
+ * If the second parameter is provided and the first is a string, then $name
+ * is associated with the address.
+ *
+ * @param mixed $addresses
+ * @param string $name optional
+ */
+ public function setReplyTo($addresses, $name = null);
+
+ /**
+ * Get the Reply-To addresses for this message.
+ *
+ * This method always returns an associative array where the keys provide the
+ * email addresses.
+ *
+ * @return string[]
+ */
+ public function getReplyTo();
+
+ /**
+ * Set the To address(es).
+ *
+ * Recipients set in this field will receive a copy of this message.
+ *
+ * This method has the same synopsis as {@link setFrom()} and {@link setCc()}.
+ *
+ * If the second parameter is provided and the first is a string, then $name
+ * is associated with the address.
+ *
+ * @param mixed $addresses
+ * @param string $name optional
+ */
+ public function setTo($addresses, $name = null);
+
+ /**
+ * Get the To addresses for this message.
+ *
+ * This method always returns an associative array, whereby the keys provide
+ * the actual email addresses.
+ *
+ * @return string[]
+ */
+ public function getTo();
+
+ /**
+ * Set the Cc address(es).
+ *
+ * Recipients set in this field will receive a 'carbon-copy' of this message.
+ *
+ * This method has the same synopsis as {@link setFrom()} and {@link setTo()}.
+ *
+ * @param mixed $addresses
+ * @param string $name optional
+ */
+ public function setCc($addresses, $name = null);
+
+ /**
+ * Get the Cc addresses for this message.
+ *
+ * This method always returns an associative array, whereby the keys provide
+ * the actual email addresses.
+ *
+ * @return string[]
+ */
+ public function getCc();
+
+ /**
+ * Set the Bcc address(es).
+ *
+ * Recipients set in this field will receive a 'blind-carbon-copy' of this
+ * message.
+ *
+ * In other words, they will get the message, but any other recipients of the
+ * message will have no such knowledge of their receipt of it.
+ *
+ * This method has the same synopsis as {@link setFrom()} and {@link setTo()}.
+ *
+ * @param mixed $addresses
+ * @param string $name optional
+ */
+ public function setBcc($addresses, $name = null);
+
+ /**
+ * Get the Bcc addresses for this message.
+ *
+ * This method always returns an associative array, whereby the keys provide
+ * the actual email addresses.
+ *
+ * @return string[]
+ */
+ public function getBcc();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php b/External/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php
new file mode 100755
index 0000000..2b08009
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/Mime/EncodingObserver.php';
+//@require 'Swift/Mime/CharsetObserver.php';
+
+/**
+ * A MIME entity, such as an attachment.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_MimeEntity
+ extends Swift_Mime_CharsetObserver, Swift_Mime_EncodingObserver
+{
+
+ /** Main message document; there can only be one of these */
+ const LEVEL_TOP = 16;
+
+ /** An entity which nests with the same precedence as an attachment */
+ const LEVEL_MIXED = 256;
+
+ /** An entity which nests with the same precedence as a mime part */
+ const LEVEL_ALTERNATIVE = 4096;
+
+ /** An entity which nests with the same precedence as embedded content */
+ const LEVEL_RELATED = 65536;
+
+ /**
+ * Get the level at which this entity shall be nested in final document.
+ * The lower the value, the more outermost the entity will be nested.
+ * @return int
+ * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE
+ */
+ public function getNestingLevel();
+
+ /**
+ * Get the qualified content-type of this mime entity.
+ * @return string
+ */
+ public function getContentType();
+
+ /**
+ * Returns a unique ID for this entity.
+ * For most entities this will likely be the Content-ID, though it has
+ * no explicit semantic meaning and can be considered an identifier for
+ * programming logic purposes.
+ * If a Content-ID header is present, this value SHOULD match the value of
+ * the header.
+ * @return string
+ */
+ public function getId();
+
+ /**
+ * Get all children nested inside this entity.
+ * These are not just the immediate children, but all children.
+ * @return Swift_Mime_MimeEntity[]
+ */
+ public function getChildren();
+
+ /**
+ * Set all children nested inside this entity.
+ * This includes grandchildren.
+ * @param Swift_Mime_MimeEntity[] $children
+ */
+ public function setChildren(array $children);
+
+ /**
+ * Get the collection of Headers in this Mime entity.
+ * @return Swift_Mime_Header[]
+ */
+ public function getHeaders();
+
+ /**
+ * Get the body content of this entity as a string.
+ * Returns NULL if no body has been set.
+ * @return string
+ */
+ public function getBody();
+
+ /**
+ * Set the body content of this entity as a string.
+ * @param string $body
+ * @param string $contentType optional
+ */
+ public function setBody($body, $contentType = null);
+
+ /**
+ * Get this entire entity in its string form.
+ * @return string
+ */
+ public function toString();
+
+ /**
+ * Get this entire entity as a ByteStream.
+ * @param Swift_InputByteStream $is to write to
+ */
+ public function toByteStream(Swift_InputByteStream $is);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/MimePart.php b/External/swiftmailer/lib/classes/Swift/Mime/MimePart.php
new file mode 100755
index 0000000..78c6fe0
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/MimePart.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/SimpleMimeEntity.php';
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/Mime/HeaderSet.php';
+//@require 'Swift/KeyCache.php';
+
+/**
+ * A MIME part, in a multipart message.
+ *
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
+{
+
+ /** The format parameter last specified by the user */
+ protected $_userFormat;
+
+ /** The charset last specified by the user */
+ protected $_userCharset;
+
+ /** The delsp parameter last specified by the user */
+ protected $_userDelSp;
+
+ /** The nesting level of this MimePart */
+ private $_nestingLevel = self::LEVEL_ALTERNATIVE;
+
+ /**
+ * Create a new MimePart with $headers, $encoder and $cache.
+ *
+ * @param Swift_Mime_HeaderSet $headers
+ * @param Swift_Mime_ContentEncoder $encoder
+ * @param Swift_KeyCache $cache
+ * @param string $charset
+ */
+ public function __construct(Swift_Mime_HeaderSet $headers,
+ Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, $charset = null)
+ {
+ parent::__construct($headers, $encoder, $cache);
+ $this->setContentType('text/plain');
+ if (!is_null($charset))
+ {
+ $this->setCharset($charset);
+ }
+ }
+
+ /**
+ * Set the body of this entity, either as a string, or as an instance of
+ * {@link Swift_OutputByteStream}.
+ *
+ * @param mixed $body
+ * @param string $contentType optional
+ * @param string $charset optional
+ */
+ public function setBody($body, $contentType = null, $charset = null)
+ {
+ parent::setBody($body, $contentType);
+ if (isset($charset))
+ {
+ $this->setCharset($charset);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the character set of this entity.
+ *
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->_getHeaderParameter('Content-Type', 'charset');
+ }
+
+ /**
+ * Set the character set of this entity.
+ *
+ * @param string $charset
+ */
+ public function setCharset($charset)
+ {
+ $this->_setHeaderParameter('Content-Type', 'charset', $charset);
+ if ($charset !== $this->_userCharset)
+ {
+ $this->_clearCache();
+ }
+ $this->_userCharset = $charset;
+ parent::charsetChanged($charset);
+ return $this;
+ }
+
+ /**
+ * Get the format of this entity (i.e. flowed or fixed).
+ *
+ * @return string
+ */
+ public function getFormat()
+ {
+ return $this->_getHeaderParameter('Content-Type', 'format');
+ }
+
+ /**
+ * Set the format of this entity (flowed or fixed).
+ *
+ * @param string $format
+ */
+ public function setFormat($format)
+ {
+ $this->_setHeaderParameter('Content-Type', 'format', $format);
+ $this->_userFormat = $format;
+ return $this;
+ }
+
+ /**
+ * Test if delsp is being used for this entity.
+ *
+ * @return boolean
+ */
+ public function getDelSp()
+ {
+ return ($this->_getHeaderParameter('Content-Type', 'delsp') == 'yes')
+ ? true
+ : false;
+ }
+
+ /**
+ * Turn delsp on or off for this entity.
+ *
+ * @param boolean $delsp
+ */
+ public function setDelSp($delsp = true)
+ {
+ $this->_setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null);
+ $this->_userDelSp = $delsp;
+ return $this;
+ }
+
+ /**
+ * Get the nesting level of this entity.
+ *
+ * @return int
+ * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED
+ */
+ public function getNestingLevel()
+ {
+ return $this->_nestingLevel;
+ }
+
+ /**
+ * Receive notification that the charset has changed on this document, or a
+ * parent document.
+ *
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->setCharset($charset);
+ }
+
+ // -- Protected methods
+
+ /** Fix the content-type and encoding of this entity */
+ protected function _fixHeaders()
+ {
+ parent::_fixHeaders();
+ if (count($this->getChildren()))
+ {
+ $this->_setHeaderParameter('Content-Type', 'charset', null);
+ $this->_setHeaderParameter('Content-Type', 'format', null);
+ $this->_setHeaderParameter('Content-Type', 'delsp', null);
+ }
+ else
+ {
+ $this->setCharset($this->_userCharset);
+ $this->setFormat($this->_userFormat);
+ $this->setDelSp($this->_userDelSp);
+ }
+ }
+
+ /** Set the nesting level of this entity */
+ protected function _setNestingLevel($level)
+ {
+ $this->_nestingLevel = $level;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php b/External/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php
new file mode 100755
index 0000000..da65ca9
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Header.php';
+
+/**
+ * A MIME Header with parameters.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+interface Swift_Mime_ParameterizedHeader extends Swift_Mime_Header
+{
+
+ /**
+ * Set the value of $parameter.
+ * @param string $parameter
+ * @param string $value
+ */
+ public function setParameter($parameter, $value);
+
+ /**
+ * Get the value of $parameter.
+ * @return string
+ */
+ public function getParameter($parameter);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php b/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php
new file mode 100755
index 0000000..6954ac5
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php
@@ -0,0 +1,187 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/HeaderFactory.php';
+//@require 'Swift/Mime/HeaderEncoder.php';
+//@require 'Swift/Encoder.php';
+//@require 'Swift/Mime/Headers/MailboxHeader.php';
+//@require 'Swift/Mime/Headers/DateHeader.php';
+//@require 'Swift/Mime/Headers/UnstructuredHeader.php';
+//@require 'Swift/Mime/Headers/ParameterizedHeader.php';
+//@require 'Swift/Mime/Headers/IdentificationHeader.php';
+//@require 'Swift/Mime/Headers/PathHeader.php';
+
+/**
+ * Creates MIME headers.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_SimpleHeaderFactory implements Swift_Mime_HeaderFactory
+{
+
+ /** The HeaderEncoder used by these headers */
+ private $_encoder;
+
+ /** The Encoder used by parameters */
+ private $_paramEncoder;
+
+ /** The charset of created Headers */
+ private $_charset;
+
+ /**
+ * Creates a new SimpleHeaderFactory using $encoder and $paramEncoder.
+ * @param Swift_Mime_HeaderEncoder $encoder
+ * @param Swift_Encoder $paramEncoder
+ * @param string $charset
+ */
+ public function __construct(Swift_Mime_HeaderEncoder $encoder,
+ Swift_Encoder $paramEncoder, $charset = null)
+ {
+ $this->_encoder = $encoder;
+ $this->_paramEncoder = $paramEncoder;
+ $this->_charset = $charset;
+ }
+
+ /**
+ * Create a new Mailbox Header with a list of $addresses.
+ * @param string $name
+ * @param array|string $addresses
+ * @return Swift_Mime_Header
+ */
+ public function createMailboxHeader($name, $addresses = null)
+ {
+ $header = new Swift_Mime_Headers_MailboxHeader($name, $this->_encoder);
+ if (isset($addresses))
+ {
+ $header->setFieldBodyModel($addresses);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Create a new Date header using $timestamp (UNIX time).
+ * @param string $name
+ * @param int $timestamp
+ * @return Swift_Mime_Header
+ */
+ public function createDateHeader($name, $timestamp = null)
+ {
+ $header = new Swift_Mime_Headers_DateHeader($name);
+ if (isset($timestamp))
+ {
+ $header->setFieldBodyModel($timestamp);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Create a new basic text header with $name and $value.
+ * @param string $name
+ * @param string $value
+ * @return Swift_Mime_Header
+ */
+ public function createTextHeader($name, $value = null)
+ {
+ $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->_encoder);
+ if (isset($value))
+ {
+ $header->setFieldBodyModel($value);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Create a new ParameterizedHeader with $name, $value and $params.
+ * @param string $name
+ * @param string $value
+ * @param array $params
+ * @return Swift_Mime_ParameterizedHeader
+ */
+ public function createParameterizedHeader($name, $value = null,
+ $params = array())
+ {
+ $header = new Swift_Mime_Headers_ParameterizedHeader($name,
+ $this->_encoder, (strtolower($name) == 'content-disposition')
+ ? $this->_paramEncoder
+ : null
+ );
+ if (isset($value))
+ {
+ $header->setFieldBodyModel($value);
+ }
+ foreach ($params as $k => $v)
+ {
+ $header->setParameter($k, $v);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Create a new ID header for Message-ID or Content-ID.
+ * @param string $name
+ * @param string|array $ids
+ * @return Swift_Mime_Header
+ */
+ public function createIdHeader($name, $ids = null)
+ {
+ $header = new Swift_Mime_Headers_IdentificationHeader($name);
+ if (isset($ids))
+ {
+ $header->setFieldBodyModel($ids);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Create a new Path header with an address (path) in it.
+ * @param string $name
+ * @param string $path
+ * @return Swift_Mime_Header
+ */
+ public function createPathHeader($name, $path = null)
+ {
+ $header = new Swift_Mime_Headers_PathHeader($name);
+ if (isset($path))
+ {
+ $header->setFieldBodyModel($path);
+ }
+ $this->_setHeaderCharset($header);
+ return $header;
+ }
+
+ /**
+ * Notify this observer that the entity's charset has changed.
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->_charset = $charset;
+ $this->_encoder->charsetChanged($charset);
+ $this->_paramEncoder->charsetChanged($charset);
+ }
+
+ // -- Private methods
+
+ /** Apply the charset to the Header */
+ private function _setHeaderCharset(Swift_Mime_Header $header)
+ {
+ if (isset($this->_charset))
+ {
+ $header->setCharset($this->_charset);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php b/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php
new file mode 100755
index 0000000..eeb0221
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php
@@ -0,0 +1,396 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/HeaderSet.php';
+//@require 'Swift/Mime/HeaderFactory.php';
+
+/**
+ * A collection of MIME headers.
+ *
+ * @package Swift
+ * @subpackage Mime
+ *
+ * @author Chris Corbyn
+ */
+class Swift_Mime_SimpleHeaderSet implements Swift_Mime_HeaderSet
+{
+
+ /** HeaderFactory */
+ private $_factory;
+
+ /** Collection of set Headers */
+ private $_headers = array();
+
+ /** Field ordering details */
+ private $_order = array();
+
+ /** List of fields which are required to be displayed */
+ private $_required = array();
+
+ /** The charset used by Headers */
+ private $_charset;
+
+ /**
+ * Create a new SimpleHeaderSet with the given $factory.
+ *
+ * @param Swift_Mime_HeaderFactory $factory
+ * @param string $charset
+ */
+ public function __construct(Swift_Mime_HeaderFactory $factory,
+ $charset = null)
+ {
+ $this->_factory = $factory;
+ if (isset($charset))
+ {
+ $this->setCharset($charset);
+ }
+ }
+
+ /**
+ * Set the charset used by these headers.
+ *
+ * @param string $charset
+ */
+ public function setCharset($charset)
+ {
+ $this->_charset = $charset;
+ $this->_factory->charsetChanged($charset);
+ $this->_notifyHeadersOfCharset($charset);
+ }
+
+ /**
+ * Add a new Mailbox Header with a list of $addresses.
+ *
+ * @param string $name
+ * @param array|string $addresses
+ */
+ public function addMailboxHeader($name, $addresses = null)
+ {
+ $this->_storeHeader($name,
+ $this->_factory->createMailboxHeader($name, $addresses));
+ }
+
+ /**
+ * Add a new Date header using $timestamp (UNIX time).
+ *
+ * @param string $name
+ * @param int $timestamp
+ */
+ public function addDateHeader($name, $timestamp = null)
+ {
+ $this->_storeHeader($name,
+ $this->_factory->createDateHeader($name, $timestamp));
+ }
+
+ /**
+ * Add a new basic text header with $name and $value.
+ *
+ * @param string $name
+ * @param string $value
+ */
+ public function addTextHeader($name, $value = null)
+ {
+ $this->_storeHeader($name,
+ $this->_factory->createTextHeader($name, $value));
+ }
+
+ /**
+ * Add a new ParameterizedHeader with $name, $value and $params.
+ *
+ * @param string $name
+ * @param string $value
+ * @param array $params
+ */
+ public function addParameterizedHeader($name, $value = null,
+ $params = array())
+ {
+ $this->_storeHeader($name,
+ $this->_factory->createParameterizedHeader($name, $value,
+ $params));
+ }
+
+ /**
+ * Add a new ID header for Message-ID or Content-ID.
+ *
+ * @param string $name
+ * @param string|array $ids
+ */
+ public function addIdHeader($name, $ids = null)
+ {
+ $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids));
+ }
+
+ /**
+ * Add a new Path header with an address (path) in it.
+ *
+ * @param string $name
+ * @param string $path
+ */
+ public function addPathHeader($name, $path = null)
+ {
+ $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path));
+ }
+
+ /**
+ * Returns true if at least one header with the given $name exists.
+ *
+ * If multiple headers match, the actual one may be specified by $index.
+ *
+ * @param string $name
+ * @param int $index
+ *
+ * @return boolean
+ */
+ public function has($name, $index = 0)
+ {
+ $lowerName = strtolower($name);
+ return array_key_exists($lowerName, $this->_headers)
+ && array_key_exists($index, $this->_headers[$lowerName]);
+ }
+
+ /**
+ * Set a header in the HeaderSet.
+ *
+ * The header may be a previously fetched header via {@link get()} or it may
+ * be one that has been created separately.
+ *
+ * If $index is specified, the header will be inserted into the set at this
+ * offset.
+ *
+ * @param Swift_Mime_Header $header
+ * @param int $index
+ */
+ public function set(Swift_Mime_Header $header, $index = 0)
+ {
+ $this->_storeHeader($header->getFieldName(), $header, $index);
+ }
+
+ /**
+ * Get the header with the given $name.
+ *
+ * If multiple headers match, the actual one may be specified by $index.
+ * Returns NULL if none present.
+ *
+ * @param string $name
+ * @param int $index
+ *
+ * @return Swift_Mime_Header
+ */
+ public function get($name, $index = 0)
+ {
+ if ($this->has($name, $index))
+ {
+ $lowerName = strtolower($name);
+ return $this->_headers[$lowerName][$index];
+ }
+ }
+
+ /**
+ * Get all headers with the given $name.
+ *
+ * @param string $name
+ *
+ * @return array
+ */
+ public function getAll($name = null)
+ {
+ if (!isset($name))
+ {
+ $headers = array();
+ foreach ($this->_headers as $collection)
+ {
+ $headers = array_merge($headers, $collection);
+ }
+ return $headers;
+ }
+
+ $lowerName = strtolower($name);
+ if (!array_key_exists($lowerName, $this->_headers))
+ {
+ return array();
+ }
+ return $this->_headers[$lowerName];
+ }
+
+ /**
+ * Remove the header with the given $name if it's set.
+ *
+ * If multiple headers match, the actual one may be specified by $index.
+ *
+ * @param string $name
+ * @param int $index
+ */
+ public function remove($name, $index = 0)
+ {
+ $lowerName = strtolower($name);
+ unset($this->_headers[$lowerName][$index]);
+ }
+
+ /**
+ * Remove all headers with the given $name.
+ *
+ * @param string $name
+ */
+ public function removeAll($name)
+ {
+ $lowerName = strtolower($name);
+ unset($this->_headers[$lowerName]);
+ }
+
+ /**
+ * Create a new instance of this HeaderSet.
+ *
+ * @return Swift_Mime_HeaderSet
+ */
+ public function newInstance()
+ {
+ return new self($this->_factory);
+ }
+
+ /**
+ * Define a list of Header names as an array in the correct order.
+ *
+ * These Headers will be output in the given order where present.
+ *
+ * @param array $sequence
+ */
+ public function defineOrdering(array $sequence)
+ {
+ $this->_order = array_flip(array_map('strtolower', $sequence));
+ }
+
+ /**
+ * Set a list of header names which must always be displayed when set.
+ *
+ * Usually headers without a field value won't be output unless set here.
+ *
+ * @param array $names
+ */
+ public function setAlwaysDisplayed(array $names)
+ {
+ $this->_required = array_flip(array_map('strtolower', $names));
+ }
+
+ /**
+ * Notify this observer that the entity's charset has changed.
+ *
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->setCharset($charset);
+ }
+
+ /**
+ * Returns a string with a representation of all headers.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $string = '';
+ $headers = $this->_headers;
+ if ($this->_canSort())
+ {
+ uksort($headers, array($this, '_sortHeaders'));
+ }
+ foreach ($headers as $collection)
+ {
+ foreach ($collection as $header)
+ {
+ if ($this->_isDisplayed($header) || $header->getFieldBody() != '')
+ {
+ $string .= $header->toString();
+ }
+ }
+ }
+ return $string;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return string
+ *
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+
+ // -- Private methods
+
+ /** Save a Header to the internal collection */
+ private function _storeHeader($name, Swift_Mime_Header $header, $offset = null)
+ {
+ if (!isset($this->_headers[strtolower($name)]))
+ {
+ $this->_headers[strtolower($name)] = array();
+ }
+ if (!isset($offset))
+ {
+ $this->_headers[strtolower($name)][] = $header;
+ }
+ else
+ {
+ $this->_headers[strtolower($name)][$offset] = $header;
+ }
+ }
+
+ /** Test if the headers can be sorted */
+ private function _canSort()
+ {
+ return count($this->_order) > 0;
+ }
+
+ /** uksort() algorithm for Header ordering */
+ private function _sortHeaders($a, $b)
+ {
+ $lowerA = strtolower($a);
+ $lowerB = strtolower($b);
+ $aPos = array_key_exists($lowerA, $this->_order)
+ ? $this->_order[$lowerA]
+ : -1;
+ $bPos = array_key_exists($lowerB, $this->_order)
+ ? $this->_order[$lowerB]
+ : -1;
+
+ if ($aPos == -1)
+ {
+ return 1;
+ }
+ elseif ($bPos == -1)
+ {
+ return -1;
+ }
+
+ return ($aPos < $bPos) ? -1 : 1;
+ }
+
+ /** Test if the given Header is always displayed */
+ private function _isDisplayed(Swift_Mime_Header $header)
+ {
+ return array_key_exists(strtolower($header->getFieldName()), $this->_required);
+ }
+
+ /** Notify all Headers of the new charset */
+ private function _notifyHeadersOfCharset($charset)
+ {
+ foreach ($this->_headers as $headerGroup)
+ {
+ foreach ($headerGroup as $header)
+ {
+ $header->setCharset($charset);
+ }
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php b/External/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php
new file mode 100755
index 0000000..bbe1e8f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php
@@ -0,0 +1,609 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Mime/MimePart.php';
+//@require 'Swift/Mime/MimeEntity.php';
+//@require 'Swift/Mime/HeaderSet.php';
+//@require 'Swift/Mime/ContentEncoder.php';
+
+/**
+ * The default email message class.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart
+ implements Swift_Mime_Message
+{
+
+ /**
+ * Create a new SimpleMessage with $headers, $encoder and $cache.
+ * @param Swift_Mime_HeaderSet $headers
+ * @param Swift_Mime_ContentEncoder $encoder
+ * @param Swift_KeyCache $cache
+ * @param string $charset
+ */
+ public function __construct(Swift_Mime_HeaderSet $headers,
+ Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, $charset = null)
+ {
+ parent::__construct($headers, $encoder, $cache, $charset);
+ $this->getHeaders()->defineOrdering(array(
+ 'Return-Path',
+ 'Sender',
+ 'Message-ID',
+ 'Date',
+ 'Subject',
+ 'From',
+ 'Reply-To',
+ 'To',
+ 'Cc',
+ 'Bcc',
+ 'MIME-Version',
+ 'Content-Type',
+ 'Content-Transfer-Encoding'
+ ));
+ $this->getHeaders()->setAlwaysDisplayed(
+ array('Date', 'Message-ID', 'From')
+ );
+ $this->getHeaders()->addTextHeader('MIME-Version', '1.0');
+ $this->setDate(time());
+ $this->setId($this->getId());
+ $this->getHeaders()->addMailboxHeader('From');
+ }
+
+ /**
+ * Always returns {@link LEVEL_TOP} for a message instance.
+ * @return int
+ */
+ public function getNestingLevel()
+ {
+ return self::LEVEL_TOP;
+ }
+
+ /**
+ * Set the subject of this message.
+ * @param string $subject
+ */
+ public function setSubject($subject)
+ {
+ if (!$this->_setHeaderFieldModel('Subject', $subject))
+ {
+ $this->getHeaders()->addTextHeader('Subject', $subject);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the subject of this message.
+ * @return string
+ */
+ public function getSubject()
+ {
+ return $this->_getHeaderFieldModel('Subject');
+ }
+
+ /**
+ * Set the date at which this message was created.
+ * @param int $date
+ */
+ public function setDate($date)
+ {
+ if (!$this->_setHeaderFieldModel('Date', $date))
+ {
+ $this->getHeaders()->addDateHeader('Date', $date);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the date at which this message was created.
+ * @return int
+ */
+ public function getDate()
+ {
+ return $this->_getHeaderFieldModel('Date');
+ }
+
+ /**
+ * Set the return-path (the bounce address) of this message.
+ * @param string $address
+ */
+ public function setReturnPath($address)
+ {
+ if (!$this->_setHeaderFieldModel('Return-Path', $address))
+ {
+ $this->getHeaders()->addPathHeader('Return-Path', $address);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the return-path (bounce address) of this message.
+ * @return string
+ */
+ public function getReturnPath()
+ {
+ return $this->_getHeaderFieldModel('Return-Path');
+ }
+
+ /**
+ * Set the sender of this message.
+ * This does not override the From field, but it has a higher significance.
+ * @param string $sender
+ * @param string $name optional
+ */
+ public function setSender($address, $name = null)
+ {
+ if (!is_array($address) && isset($name))
+ {
+ $address = array($address => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('Sender', (array) $address))
+ {
+ $this->getHeaders()->addMailboxHeader('Sender', (array) $address);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the sender of this message.
+ * @return string
+ */
+ public function getSender()
+ {
+ return $this->_getHeaderFieldModel('Sender');
+ }
+
+ /**
+ * Add a From: address to this message.
+ *
+ * If $name is passed this name will be associated with the address.
+ *
+ * @param string $address
+ * @param string $name optional
+ */
+ public function addFrom($address, $name = null)
+ {
+ $current = $this->getFrom();
+ $current[$address] = $name;
+ return $this->setFrom($current);
+ }
+
+ /**
+ * Set the from address of this message.
+ *
+ * You may pass an array of addresses if this message is from multiple people.
+ *
+ * If $name is passed and the first parameter is a string, this name will be
+ * associated with the address.
+ *
+ * @param string $addresses
+ * @param string $name optional
+ */
+ public function setFrom($addresses, $name = null)
+ {
+ if (!is_array($addresses) && isset($name))
+ {
+ $addresses = array($addresses => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('From', (array) $addresses))
+ {
+ $this->getHeaders()->addMailboxHeader('From', (array) $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the from address of this message.
+ *
+ * @return string
+ */
+ public function getFrom()
+ {
+ return $this->_getHeaderFieldModel('From');
+ }
+
+ /**
+ * Add a Reply-To: address to this message.
+ *
+ * If $name is passed this name will be associated with the address.
+ *
+ * @param string $address
+ * @param string $name optional
+ */
+ public function addReplyTo($address, $name = null)
+ {
+ $current = $this->getReplyTo();
+ $current[$address] = $name;
+ return $this->setReplyTo($current);
+ }
+
+ /**
+ * Set the reply-to address of this message.
+ *
+ * You may pass an array of addresses if replies will go to multiple people.
+ *
+ * If $name is passed and the first parameter is a string, this name will be
+ * associated with the address.
+ *
+ * @param string $addresses
+ * @param string $name optional
+ */
+ public function setReplyTo($addresses, $name = null)
+ {
+ if (!is_array($addresses) && isset($name))
+ {
+ $addresses = array($addresses => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses))
+ {
+ $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the reply-to address of this message.
+ *
+ * @return string
+ */
+ public function getReplyTo()
+ {
+ return $this->_getHeaderFieldModel('Reply-To');
+ }
+
+ /**
+ * Add a To: address to this message.
+ *
+ * If $name is passed this name will be associated with the address.
+ *
+ * @param string $address
+ * @param string $name optional
+ */
+ public function addTo($address, $name = null)
+ {
+ $current = $this->getTo();
+ $current[$address] = $name;
+ return $this->setTo($current);
+ }
+
+ /**
+ * Set the to addresses of this message.
+ *
+ * If multiple recipients will receive the message and array should be used.
+ *
+ * If $name is passed and the first parameter is a string, this name will be
+ * associated with the address.
+ *
+ * @param array $addresses
+ * @param string $name optional
+ */
+ public function setTo($addresses, $name = null)
+ {
+ if (!is_array($addresses) && isset($name))
+ {
+ $addresses = array($addresses => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('To', (array) $addresses))
+ {
+ $this->getHeaders()->addMailboxHeader('To', (array) $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the To addresses of this message.
+ *
+ * @return array
+ */
+ public function getTo()
+ {
+ return $this->_getHeaderFieldModel('To');
+ }
+
+ /**
+ * Add a Cc: address to this message.
+ *
+ * If $name is passed this name will be associated with the address.
+ *
+ * @param string $address
+ * @param string $name optional
+ */
+ public function addCc($address, $name = null)
+ {
+ $current = $this->getCc();
+ $current[$address] = $name;
+ return $this->setCc($current);
+ }
+
+ /**
+ * Set the Cc addresses of this message.
+ *
+ * If $name is passed and the first parameter is a string, this name will be
+ * associated with the address.
+ *
+ * @param array $addresses
+ * @param string $name optional
+ */
+ public function setCc($addresses, $name = null)
+ {
+ if (!is_array($addresses) && isset($name))
+ {
+ $addresses = array($addresses => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('Cc', (array) $addresses))
+ {
+ $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the Cc address of this message.
+ *
+ * @return array
+ */
+ public function getCc()
+ {
+ return $this->_getHeaderFieldModel('Cc');
+ }
+
+ /**
+ * Add a Bcc: address to this message.
+ *
+ * If $name is passed this name will be associated with the address.
+ *
+ * @param string $address
+ * @param string $name optional
+ */
+ public function addBcc($address, $name = null)
+ {
+ $current = $this->getBcc();
+ $current[$address] = $name;
+ return $this->setBcc($current);
+ }
+
+ /**
+ * Set the Bcc addresses of this message.
+ *
+ * If $name is passed and the first parameter is a string, this name will be
+ * associated with the address.
+ *
+ * @param array $addresses
+ * @param string $name optional
+ */
+ public function setBcc($addresses, $name = null)
+ {
+ if (!is_array($addresses) && isset($name))
+ {
+ $addresses = array($addresses => $name);
+ }
+
+ if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses))
+ {
+ $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the Bcc addresses of this message.
+ *
+ * @return array
+ */
+ public function getBcc()
+ {
+ return $this->_getHeaderFieldModel('Bcc');
+ }
+
+ /**
+ * Set the priority of this message.
+ * The value is an integer where 1 is the highest priority and 5 is the lowest.
+ * @param int $priority
+ */
+ public function setPriority($priority)
+ {
+ $priorityMap = array(
+ 1 => 'Highest',
+ 2 => 'High',
+ 3 => 'Normal',
+ 4 => 'Low',
+ 5 => 'Lowest'
+ );
+ $pMapKeys = array_keys($priorityMap);
+ if ($priority > max($pMapKeys))
+ {
+ $priority = max($pMapKeys);
+ }
+ elseif ($priority < min($pMapKeys))
+ {
+ $priority = min($pMapKeys);
+ }
+ if (!$this->_setHeaderFieldModel('X-Priority',
+ sprintf('%d (%s)', $priority, $priorityMap[$priority])))
+ {
+ $this->getHeaders()->addTextHeader('X-Priority',
+ sprintf('%d (%s)', $priority, $priorityMap[$priority]));
+ }
+ return $this;
+ }
+
+ /**
+ * Get the priority of this message.
+ * The returned value is an integer where 1 is the highest priority and 5
+ * is the lowest.
+ * @return int
+ */
+ public function getPriority()
+ {
+ list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'),
+ '%[1-5]'
+ );
+ return isset($priority) ? $priority : 3;
+ }
+
+ /**
+ * Ask for a delivery receipt from the recipient to be sent to $addresses
+ * @param array $addresses
+ */
+ public function setReadReceiptTo($addresses)
+ {
+ if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses))
+ {
+ $this->getHeaders()
+ ->addMailboxHeader('Disposition-Notification-To', $addresses);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the addresses to which a read-receipt will be sent.
+ * @return string
+ */
+ public function getReadReceiptTo()
+ {
+ return $this->_getHeaderFieldModel('Disposition-Notification-To');
+ }
+
+ /**
+ * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart.
+ * @param Swift_Mime_MimeEntity $entity
+ */
+ public function attach(Swift_Mime_MimeEntity $entity)
+ {
+ $this->setChildren(array_merge($this->getChildren(), array($entity)));
+ return $this;
+ }
+
+ /**
+ * Remove an already attached entity.
+ * @param Swift_Mime_MimeEntity $entity
+ */
+ public function detach(Swift_Mime_MimeEntity $entity)
+ {
+ $newChildren = array();
+ foreach ($this->getChildren() as $child)
+ {
+ if ($entity !== $child)
+ {
+ $newChildren[] = $child;
+ }
+ }
+ $this->setChildren($newChildren);
+ return $this;
+ }
+
+ /**
+ * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source.
+ * This method should be used when embedding images or other data in a message.
+ * @param Swift_Mime_MimeEntity $entity
+ * @return string
+ */
+ public function embed(Swift_Mime_MimeEntity $entity)
+ {
+ $this->attach($entity);
+ return 'cid:' . $entity->getId();
+ }
+
+ /**
+ * Get this message as a complete string.
+ * @return string
+ */
+ public function toString()
+ {
+ if (count($children = $this->getChildren()) > 0 && $this->getBody() != '')
+ {
+ $this->setChildren(array_merge(array($this->_becomeMimePart()), $children));
+ $string = parent::toString();
+ $this->setChildren($children);
+ }
+ else
+ {
+ $string = parent::toString();
+ }
+ return $string;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return string
+ *
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+
+ /**
+ * Write this message to a {@link Swift_InputByteStream}.
+ * @param Swift_InputByteStream $is
+ */
+ public function toByteStream(Swift_InputByteStream $is)
+ {
+ if (count($children = $this->getChildren()) > 0 && $this->getBody() != '')
+ {
+ $this->setChildren(array_merge(array($this->_becomeMimePart()), $children));
+ parent::toByteStream($is);
+ $this->setChildren($children);
+ }
+ else
+ {
+ parent::toByteStream($is);
+ }
+ }
+
+ // -- Protected methods
+
+ /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */
+ protected function _getIdField()
+ {
+ return 'Message-ID';
+ }
+
+ // -- Private methods
+
+ /** Turn the body of this message into a child of itself if needed */
+ private function _becomeMimePart()
+ {
+ $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(),
+ $this->_getCache(), $this->_userCharset
+ );
+ $part->setContentType($this->_userContentType);
+ $part->setBody($this->getBody());
+ $part->setFormat($this->_userFormat);
+ $part->setDelSp($this->_userDelSp);
+ $part->_setNestingLevel($this->_getTopNestingLevel());
+ return $part;
+ }
+
+ /** Get the highest nesting level nested inside this message */
+ private function _getTopNestingLevel()
+ {
+ $highestLevel = $this->getNestingLevel();
+ foreach ($this->getChildren() as $child)
+ {
+ $childLevel = $child->getNestingLevel();
+ if ($highestLevel < $childLevel)
+ {
+ $highestLevel = $childLevel;
+ }
+ }
+ return $highestLevel;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php b/External/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php
new file mode 100755
index 0000000..1615822
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php
@@ -0,0 +1,803 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/HeaderSet.php';
+//@require 'Swift/OutputByteStream.php';
+//@require 'Swift/Mime/ContentEncoder.php';
+//@require 'Swift/KeyCache.php';
+
+/**
+ * A MIME entity, in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_Mime_SimpleMimeEntity implements Swift_Mime_MimeEntity
+{
+
+ /** A collection of Headers for this mime entity */
+ private $_headers;
+
+ /** The body as a string, or a stream */
+ private $_body;
+
+ /** The encoder that encodes the body into a streamable format */
+ private $_encoder;
+
+ /** A mime bounary, if any is used */
+ private $_boundary;
+
+ /** Mime types to be used based on the nesting level */
+ private $_compositeRanges = array(
+ 'multipart/mixed' => array(self::LEVEL_TOP, self::LEVEL_MIXED),
+ 'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE),
+ 'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED)
+ );
+
+ /** A set of filter rules to define what level an entity should be nested at */
+ private $_compoundLevelFilters = array();
+
+ /** The nesting level of this entity */
+ private $_nestingLevel = self::LEVEL_ALTERNATIVE;
+
+ /** A KeyCache instance used during encoding and streaming */
+ private $_cache;
+
+ /** Direct descendants of this entity */
+ private $_immediateChildren = array();
+
+ /** All descendants of this entity */
+ private $_children = array();
+
+ /** The maximum line length of the body of this entity */
+ private $_maxLineLength = 78;
+
+ /** The order in which alternative mime types should appear */
+ private $_alternativePartOrder = array(
+ 'text/plain' => 1,
+ 'text/html' => 2,
+ 'multipart/related' => 3
+ );
+
+ /** The CID of this entity */
+ private $_id;
+
+ /** The key used for accessing the cache */
+ private $_cacheKey;
+
+ protected $_userContentType;
+
+ /**
+ * Create a new SimpleMimeEntity with $headers, $encoder and $cache.
+ * @param Swift_Mime_HeaderSet $headers
+ * @param Swift_Mime_ContentEncoder $encoder
+ * @param Swift_KeyCache $cache
+ */
+ public function __construct(Swift_Mime_HeaderSet $headers,
+ Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache)
+ {
+ $this->_cacheKey = uniqid();
+ $this->_cache = $cache;
+ $this->_headers = $headers;
+ $this->setEncoder($encoder);
+ $this->_headers->defineOrdering(
+ array('Content-Type', 'Content-Transfer-Encoding')
+ );
+
+ // This array specifies that, when the entire MIME document contains
+ // $compoundLevel, then for each child within $level, if its Content-Type
+ // is $contentType then it should be treated as if it's level is
+ // $neededLevel instead. I tried to write that unambiguously! :-\
+ // Data Structure:
+ // array (
+ // $compoundLevel => array(
+ // $level => array(
+ // $contentType => $neededLevel
+ // )
+ // )
+ // )
+
+ $this->_compoundLevelFilters = array(
+ (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array(
+ self::LEVEL_ALTERNATIVE => array(
+ 'text/plain' => self::LEVEL_ALTERNATIVE,
+ 'text/html' => self::LEVEL_RELATED
+ )
+ )
+ );
+
+ $this->_id = $this->getRandomId();
+ }
+
+ /**
+ * Generate a new Content-ID or Message-ID for this MIME entity.
+ * @return string
+ */
+ public function generateId()
+ {
+ $this->setId($this->getRandomId());
+ return $this->_id;
+ }
+
+ /**
+ * Get the {@link Swift_Mime_HeaderSet} for this entity.
+ * @return Swift_Mime_HeaderSet
+ */
+ public function getHeaders()
+ {
+ return $this->_headers;
+ }
+
+ /**
+ * Get the nesting level of this entity.
+ * @return int
+ * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE
+ */
+ public function getNestingLevel()
+ {
+ return $this->_nestingLevel;
+ }
+
+ /**
+ * Get the Content-type of this entity.
+ * @return string
+ */
+ public function getContentType()
+ {
+ return $this->_getHeaderFieldModel('Content-Type');
+ }
+
+ /**
+ * Set the Content-type of this entity.
+ * @param string $type
+ */
+ public function setContentType($type)
+ {
+ $this->_setContentTypeInHeaders($type);
+ // Keep track of the value so that if the content-type changes automatically
+ // due to added child entities, it can be restored if they are later removed
+ $this->_userContentType = $type;
+ return $this;
+ }
+
+ /**
+ * Get the CID of this entity.
+ * The CID will only be present in headers if a Content-ID header is present.
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->_headers->has($this->_getIdField())
+ ? current((array) $this->_getHeaderFieldModel($this->_getIdField()))
+ : $this->_id;
+ }
+
+ /**
+ * Set the CID of this entity.
+ * @param string $id
+ */
+ public function setId($id)
+ {
+ if (!$this->_setHeaderFieldModel($this->_getIdField(), $id))
+ {
+ $this->_headers->addIdHeader($this->_getIdField(), $id);
+ }
+ $this->_id = $id;
+ return $this;
+ }
+
+ /**
+ * Get the description of this entity.
+ * This value comes from the Content-Description header if set.
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->_getHeaderFieldModel('Content-Description');
+ }
+
+ /**
+ * Set the description of this entity.
+ * This method sets a value in the Content-ID header.
+ * @param string $description
+ */
+ public function setDescription($description)
+ {
+ if (!$this->_setHeaderFieldModel('Content-Description', $description))
+ {
+ $this->_headers->addTextHeader('Content-Description', $description);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the maximum line length of the body of this entity.
+ * @return int
+ */
+ public function getMaxLineLength()
+ {
+ return $this->_maxLineLength;
+ }
+
+ /**
+ * Set the maximum line length of lines in this body.
+ * Though not enforced by the library, lines should not exceed 1000 chars.
+ * @param int $length
+ */
+ public function setMaxLineLength($length)
+ {
+ $this->_maxLineLength = $length;
+ return $this;
+ }
+
+ /**
+ * Get all children added to this entity.
+ * @return array of Swift_Mime_Entity
+ */
+ public function getChildren()
+ {
+ return $this->_children;
+ }
+
+ /**
+ * Set all children of this entity.
+ * @param array $children Swiift_Mime_Entity instances
+ * @param int $compoundLevel For internal use only
+ */
+ public function setChildren(array $children, $compoundLevel = null)
+ {
+ //TODO: Try to refactor this logic
+
+ $compoundLevel = isset($compoundLevel)
+ ? $compoundLevel
+ : $this->_getCompoundLevel($children)
+ ;
+
+ $immediateChildren = array();
+ $grandchildren = array();
+ $newContentType = $this->_userContentType;
+
+ foreach ($children as $child)
+ {
+ $level = $this->_getNeededChildLevel($child, $compoundLevel);
+ if (empty($immediateChildren)) //first iteration
+ {
+ $immediateChildren = array($child);
+ }
+ else
+ {
+ $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel);
+ if ($nextLevel == $level)
+ {
+ $immediateChildren[] = $child;
+ }
+ elseif ($level < $nextLevel)
+ {
+ //Re-assign immediateChildren to grandchilden
+ $grandchildren = array_merge($grandchildren, $immediateChildren);
+ //Set new children
+ $immediateChildren = array($child);
+ }
+ else
+ {
+ $grandchildren[] = $child;
+ }
+ }
+ }
+
+ if (!empty($immediateChildren))
+ {
+ $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel);
+
+ //Determine which composite media type is needed to accomodate the
+ // immediate children
+ foreach ($this->_compositeRanges as $mediaType => $range)
+ {
+ if ($lowestLevel > $range[0]
+ && $lowestLevel <= $range[1])
+ {
+ $newContentType = $mediaType;
+ break;
+ }
+ }
+
+ //Put any grandchildren in a subpart
+ if (!empty($grandchildren))
+ {
+ $subentity = $this->_createChild();
+ $subentity->_setNestingLevel($lowestLevel);
+ $subentity->setChildren($grandchildren, $compoundLevel);
+ array_unshift($immediateChildren, $subentity);
+ }
+ }
+
+ $this->_immediateChildren = $immediateChildren;
+ $this->_children = $children;
+ $this->_setContentTypeInHeaders($newContentType);
+ $this->_fixHeaders();
+ $this->_sortChildren();
+
+ return $this;
+ }
+
+ /**
+ * Get the body of this entity as a string.
+ * @return string
+ */
+ public function getBody()
+ {
+ return ($this->_body instanceof Swift_OutputByteStream)
+ ? $this->_readStream($this->_body)
+ : $this->_body;
+ }
+
+ /**
+ * Set the body of this entity, either as a string, or as an instance of
+ * {@link Swift_OutputByteStream}.
+ * @param mixed $body
+ * @param string $contentType optional
+ */
+ public function setBody($body, $contentType = null)
+ {
+ if ($body !== $this->_body)
+ {
+ $this->_clearCache();
+ }
+
+ $this->_body = $body;
+ if (isset($contentType))
+ {
+ $this->setContentType($contentType);
+ }
+ return $this;
+ }
+
+ /**
+ * Get the encoder used for the body of this entity.
+ * @return Swift_Mime_ContentEncoder
+ */
+ public function getEncoder()
+ {
+ return $this->_encoder;
+ }
+
+ /**
+ * Set the encoder used for the body of this entity.
+ * @param Swift_Mime_ContentEncoder $encoder
+ */
+ public function setEncoder(Swift_Mime_ContentEncoder $encoder)
+ {
+ if ($encoder !== $this->_encoder)
+ {
+ $this->_clearCache();
+ }
+
+ $this->_encoder = $encoder;
+ $this->_setEncoding($encoder->getName());
+ $this->_notifyEncoderChanged($encoder);
+ return $this;
+ }
+
+ /**
+ * Get the boundary used to separate children in this entity.
+ * @return string
+ */
+ public function getBoundary()
+ {
+ if (!isset($this->_boundary))
+ {
+ $this->_boundary = '_=_swift_v4_' . time() . uniqid() . '_=_';
+ }
+ return $this->_boundary;
+ }
+
+ /**
+ * Set the boundary used to separate children in this entity.
+ * @param string $boundary
+ * @throws Swift_RfcComplianceException
+ */
+ public function setBoundary($boundary)
+ {
+ $this->_assertValidBoundary($boundary);
+ $this->_boundary = $boundary;
+ return $this;
+ }
+
+ /**
+ * Receive notification that the charset of this entity, or a parent entity
+ * has changed.
+ * @param string $charset
+ */
+ public function charsetChanged($charset)
+ {
+ $this->_notifyCharsetChanged($charset);
+ }
+
+ /**
+ * Receive notification that the encoder of this entity or a parent entity
+ * has changed.
+ * @param Swift_Mime_ContentEncoder $encoder
+ */
+ public function encoderChanged(Swift_Mime_ContentEncoder $encoder)
+ {
+ $this->_notifyEncoderChanged($encoder);
+ }
+
+ /**
+ * Get this entire entity as a string.
+ * @return string
+ */
+ public function toString()
+ {
+ $string = $this->_headers->toString();
+ if (isset($this->_body) && empty($this->_immediateChildren))
+ {
+ if ($this->_cache->hasKey($this->_cacheKey, 'body'))
+ {
+ $body = $this->_cache->getString($this->_cacheKey, 'body');
+ }
+ else
+ {
+ $body = "\r\n" . $this->_encoder->encodeString($this->getBody(), 0,
+ $this->getMaxLineLength()
+ );
+ $this->_cache->setString($this->_cacheKey, 'body', $body,
+ Swift_KeyCache::MODE_WRITE
+ );
+ }
+ $string .= $body;
+ }
+
+ if (!empty($this->_immediateChildren))
+ {
+ foreach ($this->_immediateChildren as $child)
+ {
+ $string .= "\r\n\r\n--" . $this->getBoundary() . "\r\n";
+ $string .= $child->toString();
+ }
+ $string .= "\r\n\r\n--" . $this->getBoundary() . "--\r\n";
+ }
+
+ return $string;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return string
+ *
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+
+ /**
+ * Write this entire entity to a {@link Swift_InputByteStream}.
+ * @param Swift_InputByteStream
+ */
+ public function toByteStream(Swift_InputByteStream $is)
+ {
+ $is->write($this->_headers->toString());
+ $is->commit();
+
+ if (empty($this->_immediateChildren))
+ {
+ if (isset($this->_body))
+ {
+ if ($this->_cache->hasKey($this->_cacheKey, 'body'))
+ {
+ $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is);
+ }
+ else
+ {
+ $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body');
+ if ($cacheIs)
+ {
+ $is->bind($cacheIs);
+ }
+
+ $is->write("\r\n");
+
+ if ($this->_body instanceof Swift_OutputByteStream)
+ {
+ $this->_body->setReadPointer(0);
+
+ $this->_encoder->encodeByteStream($this->_body, $is, 0,
+ $this->getMaxLineLength()
+ );
+ }
+ else
+ {
+ $is->write($this->_encoder->encodeString(
+ $this->getBody(), 0, $this->getMaxLineLength()
+ ));
+ }
+
+ if ($cacheIs)
+ {
+ $is->unbind($cacheIs);
+ }
+ }
+ }
+ }
+
+ if (!empty($this->_immediateChildren))
+ {
+ foreach ($this->_immediateChildren as $child)
+ {
+ $is->write("\r\n\r\n--" . $this->getBoundary() . "\r\n");
+ $child->toByteStream($is);
+ }
+ $is->write("\r\n\r\n--" . $this->getBoundary() . "--\r\n");
+ }
+ }
+
+ // -- Protected methods
+
+ /**
+ * Get the name of the header that provides the ID of this entity */
+ protected function _getIdField()
+ {
+ return 'Content-ID';
+ }
+
+ /**
+ * Get the model data (usually an array or a string) for $field.
+ */
+ protected function _getHeaderFieldModel($field)
+ {
+ if ($this->_headers->has($field))
+ {
+ return $this->_headers->get($field)->getFieldBodyModel();
+ }
+ }
+
+ /**
+ * Set the model data for $field.
+ */
+ protected function _setHeaderFieldModel($field, $model)
+ {
+ if ($this->_headers->has($field))
+ {
+ $this->_headers->get($field)->setFieldBodyModel($model);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Get the parameter value of $parameter on $field header.
+ */
+ protected function _getHeaderParameter($field, $parameter)
+ {
+ if ($this->_headers->has($field))
+ {
+ return $this->_headers->get($field)->getParameter($parameter);
+ }
+ }
+
+ /**
+ * Set the parameter value of $parameter on $field header.
+ */
+ protected function _setHeaderParameter($field, $parameter, $value)
+ {
+ if ($this->_headers->has($field))
+ {
+ $this->_headers->get($field)->setParameter($parameter, $value);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Re-evaluate what content type and encoding should be used on this entity.
+ */
+ protected function _fixHeaders()
+ {
+ if (count($this->_immediateChildren))
+ {
+ $this->_setHeaderParameter('Content-Type', 'boundary',
+ $this->getBoundary()
+ );
+ $this->_headers->remove('Content-Transfer-Encoding');
+ }
+ else
+ {
+ $this->_setHeaderParameter('Content-Type', 'boundary', null);
+ $this->_setEncoding($this->_encoder->getName());
+ }
+ }
+
+ /**
+ * Get the KeyCache used in this entity.
+ */
+ protected function _getCache()
+ {
+ return $this->_cache;
+ }
+
+ /**
+ * Empty the KeyCache for this entity.
+ */
+ protected function _clearCache()
+ {
+ $this->_cache->clearKey($this->_cacheKey, 'body');
+ }
+
+ /**
+ * Returns a random Content-ID or Message-ID.
+ * @return string
+ */
+ protected function getRandomId()
+ {
+ $idLeft = time() . '.' . uniqid();
+ $idRight = !empty($_SERVER['SERVER_NAME'])
+ ? $_SERVER['SERVER_NAME']
+ : 'swift.generated';
+ return $idLeft . '@' . $idRight;
+ }
+
+ // -- Private methods
+
+ private function _readStream(Swift_OutputByteStream $os)
+ {
+ $string = '';
+ while (false !== $bytes = $os->read(8192))
+ {
+ $string .= $bytes;
+ }
+ return $string;
+ }
+
+ private function _setEncoding($encoding)
+ {
+ if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding))
+ {
+ $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding);
+ }
+ }
+
+ private function _assertValidBoundary($boundary)
+ {
+ if (!preg_match(
+ '/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di',
+ $boundary))
+ {
+ throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.');
+ }
+ }
+
+ private function _setContentTypeInHeaders($type)
+ {
+ if (!$this->_setHeaderFieldModel('Content-Type', $type))
+ {
+ $this->_headers->addParameterizedHeader('Content-Type', $type);
+ }
+ }
+
+ private function _setNestingLevel($level)
+ {
+ $this->_nestingLevel = $level;
+ }
+
+ private function _getCompoundLevel($children)
+ {
+ $level = 0;
+ foreach ($children as $child)
+ {
+ $level |= $child->getNestingLevel();
+ }
+ return $level;
+ }
+
+ private function _getNeededChildLevel($child, $compoundLevel)
+ {
+ $filter = array();
+ foreach ($this->_compoundLevelFilters as $bitmask => $rules)
+ {
+ if (($compoundLevel & $bitmask) === $bitmask)
+ {
+ $filter = $rules + $filter;
+ }
+ }
+
+ $realLevel = $child->getNestingLevel();
+ $lowercaseType = strtolower($child->getContentType());
+
+ if (isset($filter[$realLevel])
+ && isset($filter[$realLevel][$lowercaseType]))
+ {
+ return $filter[$realLevel][$lowercaseType];
+ }
+ else
+ {
+ return $realLevel;
+ }
+ }
+
+ private function _createChild()
+ {
+ return new self($this->_headers->newInstance(),
+ $this->_encoder, $this->_cache);
+ }
+
+ private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder)
+ {
+ foreach ($this->_immediateChildren as $child)
+ {
+ $child->encoderChanged($encoder);
+ }
+ }
+
+ private function _notifyCharsetChanged($charset)
+ {
+ $this->_encoder->charsetChanged($charset);
+ $this->_headers->charsetChanged($charset);
+ foreach ($this->_immediateChildren as $child)
+ {
+ $child->charsetChanged($charset);
+ }
+ }
+
+ private function _sortChildren()
+ {
+ $shouldSort = false;
+ foreach ($this->_immediateChildren as $child)
+ {
+ //NOTE: This include alternative parts moved into a related part
+ if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE)
+ {
+ $shouldSort = true;
+ break;
+ }
+ }
+
+ //Sort in order of preference, if there is one
+ if ($shouldSort)
+ {
+ usort($this->_immediateChildren, array($this, '_childSortAlgorithm'));
+ }
+ }
+
+ private function _childSortAlgorithm($a, $b)
+ {
+ $typePrefs = array();
+ $types = array(
+ strtolower($a->getContentType()),
+ strtolower($b->getContentType())
+ );
+ foreach ($types as $type)
+ {
+ $typePrefs[] = (array_key_exists($type, $this->_alternativePartOrder))
+ ? $this->_alternativePartOrder[$type]
+ : (max($this->_alternativePartOrder) + 1);
+ }
+ return ($typePrefs[0] >= $typePrefs[1]) ? 1 : -1;
+ }
+
+ // -- Destructor
+
+ /**
+ * Empties it's own contents from the cache.
+ */
+ public function __destruct()
+ {
+ $this->_cache->clearAll($this->_cacheKey);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/MimePart.php b/External/swiftmailer/lib/classes/Swift/MimePart.php
new file mode 100755
index 0000000..60b6d56
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/MimePart.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/MimePart.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * A MIME part, in a multipart message.
+ * @package Swift
+ * @subpackage Mime
+ * @author Chris Corbyn
+ */
+class Swift_MimePart extends Swift_Mime_MimePart
+{
+
+ /**
+ * Create a new MimePart.
+ * Details may be optionally passed into the constructor.
+ * @param string $body
+ * @param string $contentType
+ * @param string $charset
+ */
+ public function __construct($body = null, $contentType = null,
+ $charset = null)
+ {
+ call_user_func_array(
+ array($this, 'Swift_Mime_MimePart::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('mime.part')
+ );
+
+ if (!isset($charset))
+ {
+ $charset = Swift_DependencyContainer::getInstance()
+ ->lookup('properties.charset');
+ }
+ $this->setBody($body);
+ $this->setCharset($charset);
+ if ($contentType)
+ {
+ $this->setContentType($contentType);
+ }
+ }
+
+ /**
+ * Create a new MimePart.
+ * @param string $body
+ * @param string $contentType
+ * @param string $charset
+ * @return Swift_Mime_MimePart
+ */
+ public static function newInstance($body = null, $contentType = null,
+ $charset = null)
+ {
+ return new self($body, $contentType, $charset);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/OutputByteStream.php b/External/swiftmailer/lib/classes/Swift/OutputByteStream.php
new file mode 100755
index 0000000..951b838
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/OutputByteStream.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An abstract means of reading data.
+ * Classes implementing this interface may use a subsystem which requires less
+ * memory than working with large strings of data.
+ * @package Swift
+ * @subpackage ByteStream
+ * @author Chris Corbyn
+ */
+interface Swift_OutputByteStream
+{
+
+ /**
+ * Reads $length bytes from the stream into a string and moves the pointer
+ * through the stream by $length. If less bytes exist than are requested the
+ * remaining bytes are given instead. If no bytes are remaining at all, boolean
+ * false is returned.
+ * @param int $length
+ * @return string
+ * @throws Swift_IoException
+ */
+ public function read($length);
+
+ /**
+ * Move the internal read pointer to $byteOffset in the stream.
+ * @param int $byteOffset
+ * @return boolean
+ * @throws Swift_IoException
+ */
+ public function setReadPointer($byteOffset);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php
new file mode 100755
index 0000000..46a7f44
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/SendListener.php';
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Plugins/Sleeper.php';
+
+/**
+ * Reduces network flooding when sending large amounts of mail.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_AntiFloodPlugin
+ implements Swift_Events_SendListener, Swift_Plugins_Sleeper
+{
+
+ /**
+ * The number of emails to send before restarting Transport.
+ * @var int
+ * @access private
+ */
+ private $_threshold;
+
+ /**
+ * The number of seconds to sleep for during a restart.
+ * @var int
+ * @access private
+ */
+ private $_sleep;
+
+ /**
+ * The internal counter.
+ * @var int
+ * @access private
+ */
+ private $_counter = 0;
+
+ /**
+ * The Sleeper instance for sleeping.
+ * @var Swift_Plugins_Sleeper
+ * @access private
+ */
+ private $_sleeper;
+
+ /**
+ * Create a new AntiFloodPlugin with $threshold and $sleep time.
+ * @param int $threshold
+ * @param int $sleep time
+ * @param Swift_Plugins_Sleeper $sleeper (not needed really)
+ */
+ public function __construct($threshold = 99, $sleep = 0,
+ Swift_Plugins_Sleeper $sleeper = null)
+ {
+ $this->setThreshold($threshold);
+ $this->setSleepTime($sleep);
+ $this->_sleeper = $sleeper;
+ }
+
+ /**
+ * Set the number of emails to send before restarting.
+ * @param int $threshold
+ */
+ public function setThreshold($threshold)
+ {
+ $this->_threshold = $threshold;
+ }
+
+ /**
+ * Get the number of emails to send before restarting.
+ * @return int
+ */
+ public function getThreshold()
+ {
+ return $this->_threshold;
+ }
+
+ /**
+ * Set the number of seconds to sleep for during a restart.
+ * @param int $sleep time
+ */
+ public function setSleepTime($sleep)
+ {
+ $this->_sleep = $sleep;
+ }
+
+ /**
+ * Get the number of seconds to sleep for during a restart.
+ * @return int
+ */
+ public function getSleepTime()
+ {
+ return $this->_sleep;
+ }
+
+ /**
+ * Invoked immediately before the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt)
+ {
+ }
+
+ /**
+ * Invoked immediately after the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt)
+ {
+ ++$this->_counter;
+ if ($this->_counter >= $this->_threshold)
+ {
+ $transport = $evt->getTransport();
+ $transport->stop();
+ if ($this->_sleep)
+ {
+ $this->sleep($this->_sleep);
+ }
+ $transport->start();
+ $this->_counter = 0;
+ }
+ }
+
+ /**
+ * Sleep for $seconds.
+ * @param int $seconds
+ */
+ public function sleep($seconds)
+ {
+ if (isset($this->_sleeper))
+ {
+ $this->_sleeper->sleep($seconds);
+ }
+ else
+ {
+ sleep($seconds);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php
new file mode 100755
index 0000000..501cd80
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php
@@ -0,0 +1,173 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/SendListener.php';
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Events/CommandListener.php';
+//@require 'Swift/Events/CommandEvent.php';
+//@require 'Swift/Events/ResponseListener.php';
+//@require 'Swift/Events/ResponseEvent.php';
+//@require 'Swift/InputByteStream.php';
+
+/**
+ * Reduces network flooding when sending large amounts of mail.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_BandwidthMonitorPlugin
+ implements Swift_Events_SendListener, Swift_Events_CommandListener,
+ Swift_Events_ResponseListener, Swift_InputByteStream
+{
+
+ /**
+ * The outgoing traffic counter.
+ * @var int
+ * @access private
+ */
+ private $_out = 0;
+
+ /**
+ * The incoming traffic counter.
+ * @var int
+ * @access private
+ */
+ private $_in = 0;
+
+ /** Bound byte streams */
+ private $_mirrors = array();
+
+ /**
+ * Not used.
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt)
+ {
+ }
+
+ /**
+ * Invoked immediately after the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt)
+ {
+ $message = $evt->getMessage();
+ $message->toByteStream($this);
+ }
+
+ /**
+ * Invoked immediately following a command being sent.
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function commandSent(Swift_Events_CommandEvent $evt)
+ {
+ $command = $evt->getCommand();
+ $this->_out += strlen($command);
+ }
+
+ /**
+ * Invoked immediately following a response coming back.
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $evt)
+ {
+ $response = $evt->getResponse();
+ $this->_in += strlen($response);
+ }
+
+ /**
+ * Called when a message is sent so that the outgoing counter can be increased.
+ * @param string $bytes
+ */
+ public function write($bytes)
+ {
+ $this->_out += strlen($bytes);
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->write($bytes);
+ }
+ }
+
+ /**
+ * Not used.
+ */
+ public function commit()
+ {
+ }
+
+ /**
+ * Attach $is to this stream.
+ * The stream acts as an observer, receiving all data that is written.
+ * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function bind(Swift_InputByteStream $is)
+ {
+ $this->_mirrors[] = $is;
+ }
+
+ /**
+ * Remove an already bound stream.
+ * If $is is not bound, no errors will be raised.
+ * If the stream currently has any buffered data it will be written to $is
+ * before unbinding occurs.
+ *
+ * @param Swift_InputByteStream $is
+ */
+ public function unbind(Swift_InputByteStream $is)
+ {
+ foreach ($this->_mirrors as $k => $stream)
+ {
+ if ($is === $stream)
+ {
+ unset($this->_mirrors[$k]);
+ }
+ }
+ }
+
+ /**
+ * Not used.
+ */
+ public function flushBuffers()
+ {
+ foreach ($this->_mirrors as $stream)
+ {
+ $stream->flushBuffers();
+ }
+ }
+
+ /**
+ * Get the total number of bytes sent to the server.
+ * @return int
+ */
+ public function getBytesOut()
+ {
+ return $this->_out;
+ }
+
+ /**
+ * Get the total number of bytes received from the server.
+ * @return int
+ */
+ public function getBytesIn()
+ {
+ return $this->_in;
+ }
+
+ /**
+ * Reset the internal counters to zero.
+ */
+ public function reset()
+ {
+ $this->_out = 0;
+ $this->_in = 0;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php b/External/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php
new file mode 100755
index 0000000..9735d0a
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Allows customization of Messages on-the-fly.
+ *
+ * @package Swift
+ * @subpackage Plugins
+ *
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Decorator_Replacements
+{
+
+ /**
+ * Return the array of replacements for $address.
+ *
+ * This method is invoked once for every single recipient of a message.
+ *
+ * If no replacements can be found, an empty value (NULL) should be returned
+ * and no replacements will then be made on the message.
+ *
+ * @param string $address
+ *
+ * @return array
+ */
+ public function getReplacementsFor($address);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php
new file mode 100755
index 0000000..da1a307
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php
@@ -0,0 +1,201 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/SendListener.php';
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Plugins/Decorator/Replacements.php';
+
+/**
+ * Allows customization of Messages on-the-fly.
+ *
+ * @package Swift
+ * @subpackage Plugins
+ *
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_DecoratorPlugin
+ implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements
+{
+
+ /** The replacement map */
+ private $_replacements;
+
+ /** The body as it was before replacements */
+ private $_orginalBody;
+
+ /** The original subject of the message, before replacements */
+ private $_originalSubject;
+
+ /** Bodies of children before they are replaced */
+ private $_originalChildBodies = array();
+
+ /** The Message that was last replaced */
+ private $_lastMessage;
+
+ /**
+ * Create a new DecoratorPlugin with $replacements.
+ *
+ * The $replacements can either be an associative array, or an implementation
+ * of {@link Swift_Plugins_Decorator_Replacements}.
+ *
+ * When using an array, it should be of the form:
+ * <code>
+ * $replacements = array(
+ * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"),
+ * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y")
+ * )
+ * </code>
+ *
+ * When using an instance of {@link Swift_Plugins_Decorator_Replacements},
+ * the object should return just the array of replacements for the address
+ * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}.
+ *
+ * @param mixed $replacements
+ */
+ public function __construct($replacements)
+ {
+ if (!($replacements instanceof Swift_Plugins_Decorator_Replacements))
+ {
+ $this->_replacements = (array) $replacements;
+ }
+ else
+ {
+ $this->_replacements = $replacements;
+ }
+ }
+
+ /**
+ * Invoked immediately before the Message is sent.
+ *
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt)
+ {
+ $message = $evt->getMessage();
+ $this->_restoreMessage($message);
+ $to = array_keys($message->getTo());
+ $address = array_shift($to);
+ if ($replacements = $this->getReplacementsFor($address))
+ {
+ $body = $message->getBody();
+ $search = array_keys($replacements);
+ $replace = array_values($replacements);
+ $bodyReplaced = str_replace(
+ $search, $replace, $body
+ );
+ if ($body != $bodyReplaced)
+ {
+ $this->_originalBody = $body;
+ $message->setBody($bodyReplaced);
+ }
+ $subject = $message->getSubject();
+ $subjectReplaced = str_replace(
+ $search, $replace, $subject
+ );
+ if ($subject != $subjectReplaced)
+ {
+ $this->_originalSubject = $subject;
+ $message->setSubject($subjectReplaced);
+ }
+ $children = (array) $message->getChildren();
+ foreach ($children as $child)
+ {
+ list($type, ) = sscanf($child->getContentType(), '%[^/]/%s');
+ if ('text' == $type)
+ {
+ $body = $child->getBody();
+ $bodyReplaced = str_replace(
+ $search, $replace, $body
+ );
+ if ($body != $bodyReplaced)
+ {
+ $child->setBody($bodyReplaced);
+ $this->_originalChildBodies[$child->getId()] = $body;
+ }
+ }
+ }
+ $this->_lastMessage = $message;
+ }
+ }
+
+ /**
+ * Find a map of replacements for the address.
+ *
+ * If this plugin was provided with a delegate instance of
+ * {@link Swift_Plugins_Decorator_Replacements} then the call will be
+ * delegated to it. Otherwise, it will attempt to find the replacements
+ * from the array provided in the constructor.
+ *
+ * If no replacements can be found, an empty value (NULL) is returned.
+ *
+ * @param string $address
+ *
+ * @return array
+ */
+ public function getReplacementsFor($address)
+ {
+ if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements)
+ {
+ return $this->_replacements->getReplacementsFor($address);
+ }
+ else
+ {
+ return isset($this->_replacements[$address])
+ ? $this->_replacements[$address]
+ : null
+ ;
+ }
+ }
+
+ /**
+ * Invoked immediately after the Message is sent.
+ *
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt)
+ {
+ $this->_restoreMessage($evt->getMessage());
+ }
+
+ // -- Private methods
+
+ /** Restore a changed message back to its original state */
+ private function _restoreMessage(Swift_Mime_Message $message)
+ {
+ if ($this->_lastMessage === $message)
+ {
+ if (isset($this->_originalBody))
+ {
+ $message->setBody($this->_originalBody);
+ $this->_originalBody = null;
+ }
+ if (isset($this->_originalSubject))
+ {
+ $message->setSubject($this->_originalSubject);
+ $this->_originalSubject = null;
+ }
+ if (!empty($this->_originalChildBodies))
+ {
+ $children = (array) $message->getChildren();
+ foreach ($children as $child)
+ {
+ $id = $child->getId();
+ if (array_key_exists($id, $this->_originalChildBodies))
+ {
+ $child->setBody($this->_originalChildBodies[$id]);
+ }
+ }
+ $this->_originalChildBodies = array();
+ }
+ $this->_lastMessage = null;
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Logger.php b/External/swiftmailer/lib/classes/Swift/Plugins/Logger.php
new file mode 100755
index 0000000..9864da0
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Logger.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logs events in the Transport system.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Logger
+{
+
+ /**
+ * Add a log entry.
+ * @param string $entry
+ */
+ public function add($entry);
+
+ /**
+ * Clear the log contents.
+ */
+ public function clear();
+
+ /**
+ * Get this log as a string.
+ * @return string
+ */
+ public function dump();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php
new file mode 100755
index 0000000..d595f26
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/CommandListener.php';
+//@require 'Swift/Events/CommandEvent.php';
+//@require 'Swift/Events/ResponseListener.php';
+//@require 'Swift/Events/ResponseEvent.php';
+//@require 'Swift/Events/TransportChangeListener.php';
+//@require 'Swift/Events/TransportChangeEvent.php';
+//@require 'Swift/Events/TransportExceptionEvent.php';
+//@require 'Swift/Events/TransportExceptionListener.php';
+//@require 'Swift/Events/TransportException.php';
+//@require 'Swift/Plugins/Logger.php';
+
+/**
+ * Does real time logging of Transport level information.
+ *
+ * @package Swift
+ * @subpackage Plugins
+ *
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_LoggerPlugin
+ implements Swift_Events_CommandListener, Swift_Events_ResponseListener,
+ Swift_Events_TransportChangeListener, Swift_Events_TransportExceptionListener,
+ Swift_Plugins_Logger
+{
+
+ /** The logger which is delegated to */
+ private $_logger;
+
+ /**
+ * Create a new LoggerPlugin using $logger.
+ *
+ * @param Swift_Plugins_Logger $logger
+ */
+ public function __construct(Swift_Plugins_Logger $logger)
+ {
+ $this->_logger = $logger;
+ }
+
+ /**
+ * Add a log entry.
+ *
+ * @param string $entry
+ */
+ public function add($entry)
+ {
+ $this->_logger->add($entry);
+ }
+
+ /**
+ * Clear the log contents.
+ */
+ public function clear()
+ {
+ $this->_logger->clear();
+ }
+
+ /**
+ * Get this log as a string.
+ *
+ * @return string
+ */
+ public function dump()
+ {
+ return $this->_logger->dump();
+ }
+
+ /**
+ * Invoked immediately following a command being sent.
+ *
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function commandSent(Swift_Events_CommandEvent $evt)
+ {
+ $command = $evt->getCommand();
+ $this->_logger->add(sprintf(">> %s", $command));
+ }
+
+ /**
+ * Invoked immediately following a response coming back.
+ *
+ * @param Swift_Events_ResponseEvent $evt
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $evt)
+ {
+ $response = $evt->getResponse();
+ $this->_logger->add(sprintf("<< %s", $response));
+ }
+
+ /**
+ * Invoked just before a Transport is started.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt)
+ {
+ $transportName = get_class($evt->getSource());
+ $this->_logger->add(sprintf("++ Starting %s", $transportName));
+ }
+
+ /**
+ * Invoked immediately after the Transport is started.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function transportStarted(Swift_Events_TransportChangeEvent $evt)
+ {
+ $transportName = get_class($evt->getSource());
+ $this->_logger->add(sprintf("++ %s started", $transportName));
+ }
+
+ /**
+ * Invoked just before a Transport is stopped.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt)
+ {
+ $transportName = get_class($evt->getSource());
+ $this->_logger->add(sprintf("++ Stopping %s", $transportName));
+ }
+
+ /**
+ * Invoked immediately after the Transport is stopped.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function transportStopped(Swift_Events_TransportChangeEvent $evt)
+ {
+ $transportName = get_class($evt->getSource());
+ $this->_logger->add(sprintf("++ %s stopped", $transportName));
+ }
+
+ /**
+ * Invoked as a TransportException is thrown in the Transport system.
+ *
+ * @param Swift_Events_TransportExceptionEvent $evt
+ */
+ public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt)
+ {
+ $e = $evt->getException();
+ $message = $e->getMessage();
+ $this->_logger->add(sprintf("!! %s", $message));
+ $message .= PHP_EOL;
+ $message .= 'Log data:' . PHP_EOL;
+ $message .= $this->_logger->dump();
+ $evt->cancelBubble();
+ throw new Swift_TransportException($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php b/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php
new file mode 100755
index 0000000..930eca2
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logs to an Array backend.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_Loggers_ArrayLogger implements Swift_Plugins_Logger
+{
+
+ /**
+ * The log contents.
+ * @var array
+ * @access private
+ */
+ private $_log = array();
+
+ /**
+ * Max size of the log.
+ * @var int
+ * @access private
+ */
+ private $_size = 0;
+
+ /**
+ * Create a new ArrayLogger with a maximum of $size entries.
+ * @var int $size
+ */
+ public function __construct($size = 50)
+ {
+ $this->_size = $size;
+ }
+
+ /**
+ * Add a log entry.
+ * @param string $entry
+ */
+ public function add($entry)
+ {
+ $this->_log[] = $entry;
+ while (count($this->_log) > $this->_size)
+ {
+ array_shift($this->_log);
+ }
+ }
+
+ /**
+ * Clear the log contents.
+ */
+ public function clear()
+ {
+ $this->_log = array();
+ }
+
+ /**
+ * Get this log as a string.
+ * @return string
+ */
+ public function dump()
+ {
+ return implode(PHP_EOL, $this->_log);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php b/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php
new file mode 100755
index 0000000..83dd54b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Prints all log messages in real time.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_Loggers_EchoLogger implements Swift_Plugins_Logger
+{
+
+ /** Whether or not HTML should be output */
+ private $_isHtml;
+
+ /**
+ * Create a new EchoLogger.
+ *
+ * @param boolean $isHtml
+ */
+ public function __construct($isHtml = true)
+ {
+ $this->_isHtml = $isHtml;
+ }
+
+ /**
+ * Add a log entry.
+ * @param string $entry
+ */
+ public function add($entry)
+ {
+ if ($this->_isHtml)
+ {
+ printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '<br />', PHP_EOL);
+ }
+ else
+ {
+ printf('%s%s', $entry, PHP_EOL);
+ }
+ }
+
+ /**
+ * Not implemented.
+ */
+ public function clear()
+ {
+ }
+
+ /**
+ * Not implemented.
+ */
+ public function dump()
+ {
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php b/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php
new file mode 100755
index 0000000..1c96dcf
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Pop3Connection interface for connecting and disconnecting to a POP3 host.
+ *
+ * @package Swift
+ * @subpackage Plugins
+ *
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Pop_Pop3Connection
+{
+
+ /**
+ * Connect to the POP3 host and throw an Exception if it fails.
+ *
+ * @throws Swift_Plugins_Pop_Pop3Exception
+ */
+ public function connect();
+
+ /**
+ * Disconnect from the POP3 host and throw an Exception if it fails.
+ *
+ * @throws Swift_Plugins_Pop_Pop3Exception
+ */
+ public function disconnect();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php b/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php
new file mode 100755
index 0000000..e0205f4
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/IoException.php';
+
+/**
+ * Pop3Exception thrown when an error occurs connecting to a POP3 host.
+ *
+ * @package Swift
+ * @subpackage Transport
+ *
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_Pop_Pop3Exception extends Swift_IoException
+{
+
+ /**
+ * Create a new Pop3Exception with $message.
+ *
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php
new file mode 100755
index 0000000..fd1cf46
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php
@@ -0,0 +1,288 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/TransportChangeListener.php';
+//@require 'Swift/Events/TransportChangeEvent.php';
+
+/**
+ * Makes sure a connection to a POP3 host has been established prior to connecting to SMTP.
+ *
+ * @package Swift
+ * @subpackage Plugins
+ *
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_PopBeforeSmtpPlugin
+ implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection
+{
+
+ /** A delegate connection to use (mostly a test hook) */
+ private $_connection;
+
+ /** Hostname of the POP3 server */
+ private $_host;
+
+ /** Port number to connect on */
+ private $_port;
+
+ /** Encryption type to use (if any) */
+ private $_crypto;
+
+ /** Username to use (if any) */
+ private $_username;
+
+ /** Password to use (if any) */
+ private $_password;
+
+ /** Established connection via TCP socket */
+ private $_socket;
+
+ /** Connect timeout in seconds */
+ private $_timeout = 10;
+
+ /** SMTP Transport to bind to */
+ private $_transport;
+
+ /**
+ * Create a new PopBeforeSmtpPlugin for $host and $port.
+ *
+ * @param string $host
+ * @param int $port
+ * @param string $cypto as "tls" or "ssl"
+ */
+ public function __construct($host, $port = 110, $crypto = null)
+ {
+ $this->_host = $host;
+ $this->_port = $port;
+ $this->_crypto = $crypto;
+ }
+
+ /**
+ * Create a new PopBeforeSmtpPlugin for $host and $port.
+ *
+ * @param string $host
+ * @param int $port
+ * @param string $cypto as "tls" or "ssl"
+ *
+ * @return Swift_Plugins_PopBeforeSmtpPlugin
+ */
+ public static function newInstance($host, $port = 110, $crypto = null)
+ {
+ return new self($host, $port, $crypto);
+ }
+
+ /**
+ * Set a Pop3Connection to delegate to instead of connecting directly.
+ *
+ * @param Swift_Plugins_Pop_Pop3Connection $connection
+ */
+ public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection)
+ {
+ $this->_connection = $connection;
+ return $this;
+ }
+
+ /**
+ * Bind this plugin to a specific SMTP transport instance.
+ *
+ * @param Swift_Transport
+ */
+ public function bindSmtp(Swift_Transport $smtp)
+ {
+ $this->_transport = $smtp;
+ }
+
+ /**
+ * Set the connection timeout in seconds (default 10).
+ *
+ * @param int $timeout
+ */
+ public function setTimeout($timeout)
+ {
+ $this->_timeout = (int) $timeout;
+ return $this;
+ }
+
+ /**
+ * Set the username to use when connecting (if needed).
+ *
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->_username = $username;
+ return $this;
+ }
+
+ /**
+ * Set the password to use when connecting (if needed).
+ *
+ * @param string $password
+ */
+ public function setPassword($password)
+ {
+ $this->_password = $password;
+ return $this;
+ }
+
+ /**
+ * Connect to the POP3 host and authenticate.
+ *
+ * @throws Swift_Plugins_Pop_Pop3Exception if connection fails
+ */
+ public function connect()
+ {
+ if (isset($this->_connection))
+ {
+ $this->_connection->connect();
+ }
+ else
+ {
+ if (!isset($this->_socket))
+ {
+ if (!$socket = fsockopen(
+ $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout))
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr)
+ );
+ }
+ $this->_socket = $socket;
+
+ if (false === $greeting = fgets($this->_socket))
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('Failed to connect to POP3 host [%s]', trim($greeting))
+ );
+ }
+
+ $this->_assertOk($greeting);
+
+ if ($this->_username)
+ {
+ $this->_command(sprintf("USER %s\r\n", $this->_username));
+ $this->_command(sprintf("PASS %s\r\n", $this->_password));
+ }
+ }
+ }
+ }
+
+ /**
+ * Disconnect from the POP3 host.
+ */
+ public function disconnect()
+ {
+ if (isset($this->_connection))
+ {
+ $this->_connection->disconnect();
+ }
+ else
+ {
+ $this->_command("QUIT\r\n");
+ if (!fclose($this->_socket))
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('POP3 host [%s] connection could not be stopped', $this->_host)
+ );
+ }
+ $this->_socket = null;
+ }
+ }
+
+ /**
+ * Invoked just before a Transport is started.
+ *
+ * @param Swift_Events_TransportChangeEvent $evt
+ */
+ public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt)
+ {
+ if (isset($this->_transport))
+ {
+ if ($this->_transport !== $evt->getTransport())
+ {
+ return;
+ }
+ }
+
+ $this->connect();
+ $this->disconnect();
+ }
+
+ /**
+ * Not used.
+ */
+ public function transportStarted(Swift_Events_TransportChangeEvent $evt)
+ {
+ }
+
+ /**
+ * Not used.
+ */
+ public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt)
+ {
+ }
+
+ /**
+ * Not used.
+ */
+ public function transportStopped(Swift_Events_TransportChangeEvent $evt)
+ {
+ }
+
+ // -- Private Methods
+
+ private function _command($command)
+ {
+ if (!fwrite($this->_socket, $command))
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('Failed to write command [%s] to POP3 host', trim($command))
+ );
+ }
+
+ if (false === $response = fgets($this->_socket))
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('Failed to read from POP3 host after command [%s]', trim($command))
+ );
+ }
+
+ $this->_assertOk($response);
+
+ return $response;
+ }
+
+ private function _assertOk($response)
+ {
+ if (substr($response, 0, 3) != '+OK')
+ {
+ throw new Swift_Plugins_Pop_Pop3Exception(
+ sprintf('POP3 command failed [%s]', trim($response))
+ );
+ }
+ }
+
+ private function _getHostString()
+ {
+ $host = $this->_host;
+ switch (strtolower($this->_crypto))
+ {
+ case 'ssl':
+ $host = 'ssl://' . $host;
+ break;
+
+ case 'tls':
+ $host = 'tls://' . $host;
+ break;
+ }
+ return $host;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Reporter.php b/External/swiftmailer/lib/classes/Swift/Plugins/Reporter.php
new file mode 100755
index 0000000..00d5765
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Reporter.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Message.php';
+
+/**
+ * The Reporter plugin sends pass/fail notification to a Reporter.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Reporter
+{
+
+ /** The recipient was accepted for delivery */
+ const RESULT_PASS = 0x01;
+
+ /** The recipient could not be accepted */
+ const RESULT_FAIL = 0x10;
+
+ /**
+ * Notifies this ReportNotifier that $address failed or succeeded.
+ * @param Swift_Mime_Message $message
+ * @param string $address
+ * @param int $result from {@link RESULT_PASS, RESULT_FAIL}
+ */
+ public function notify(Swift_Mime_Message $message, $address, $result);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php
new file mode 100755
index 0000000..1beac5b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/SendListener.php';
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Plugins/Reporter.php';
+
+/**
+ * Does real time reporting of pass/fail for each recipient.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_ReporterPlugin
+ implements Swift_Events_SendListener
+{
+
+ /**
+ * The reporter backend which takes notifications.
+ * @var Swift_Plugin_Reporter
+ * @access private
+ */
+ private $_reporter;
+
+ /**
+ * Create a new ReporterPlugin using $reporter.
+ * @param Swift_Plugins_Reporter $reporter
+ */
+ public function __construct(Swift_Plugins_Reporter $reporter)
+ {
+ $this->_reporter = $reporter;
+ }
+
+ /**
+ * Not used.
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt)
+ {
+ }
+
+ /**
+ * Invoked immediately after the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt)
+ {
+ $message = $evt->getMessage();
+ $failures = array_flip($evt->getFailedRecipients());
+ foreach ((array) $message->getTo() as $address => $null)
+ {
+ $this->_reporter->notify(
+ $message, $address, (array_key_exists($address, $failures)
+ ? Swift_Plugins_Reporter::RESULT_FAIL
+ : Swift_Plugins_Reporter::RESULT_PASS)
+ );
+ }
+ foreach ((array) $message->getCc() as $address => $null)
+ {
+ $this->_reporter->notify(
+ $message, $address, (array_key_exists($address, $failures)
+ ? Swift_Plugins_Reporter::RESULT_FAIL
+ : Swift_Plugins_Reporter::RESULT_PASS)
+ );
+ }
+ foreach ((array) $message->getBcc() as $address => $null)
+ {
+ $this->_reporter->notify(
+ $message, $address, (array_key_exists($address, $failures)
+ ? Swift_Plugins_Reporter::RESULT_FAIL
+ : Swift_Plugins_Reporter::RESULT_PASS)
+ );
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php b/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php
new file mode 100755
index 0000000..0022f5e
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Plugins/Reporter.php';
+//@require 'Swift/Mime/Message.php';
+
+/**
+ * A reporter which "collects" failures for the Reporter plugin.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_Reporters_HitReporter implements Swift_Plugins_Reporter
+{
+
+ /**
+ * The list of failures.
+ * @var array
+ * @access private
+ */
+ private $_failures = array();
+ private $_failures_cache = array();
+
+ /**
+ * Notifies this ReportNotifier that $address failed or succeeded.
+ * @param Swift_Mime_Message $message
+ * @param string $address
+ * @param int $result from {@link RESULT_PASS, RESULT_FAIL}
+ */
+ public function notify(Swift_Mime_Message $message, $address, $result)
+ {
+ if (self::RESULT_FAIL == $result && !isset($this->_failures_cache[$address]))
+ {
+ $this->_failures[] = $address;
+ $this->_failures_cache[$address] = true;
+ }
+ }
+
+ /**
+ * Get an array of addresses for which delivery failed.
+ * @return array
+ */
+ public function getFailedRecipients()
+ {
+ return $this->_failures;
+ }
+
+ /**
+ * Clear the buffer (empty the list).
+ */
+ public function clear()
+ {
+ $this->_failures = $this->_failures_cache = array();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php b/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php
new file mode 100755
index 0000000..7370078
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Plugins/Reporter.php';
+//@require 'Swift/Mime/Message.php';
+
+/**
+ * A HTML output reporter for the Reporter plugin.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_Reporters_HtmlReporter implements Swift_Plugins_Reporter
+{
+
+ /**
+ * Notifies this ReportNotifier that $address failed or succeeded.
+ * @param Swift_Mime_Message $message
+ * @param string $address
+ * @param int $result from {@link RESULT_PASS, RESULT_FAIL}
+ */
+ public function notify(Swift_Mime_Message $message, $address, $result)
+ {
+ if (self::RESULT_PASS == $result)
+ {
+ echo "<div style=\"color: #fff; background: #006600; padding: 2px; margin: 2px;\">" . PHP_EOL;
+ echo "PASS " . $address . PHP_EOL;
+ echo "</div>" . PHP_EOL;
+ flush();
+ }
+ else
+ {
+ echo "<div style=\"color: #fff; background: #880000; padding: 2px; margin: 2px;\">" . PHP_EOL;
+ echo "FAIL " . $address . PHP_EOL;
+ echo "</div>" . PHP_EOL;
+ flush();
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php b/External/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php
new file mode 100755
index 0000000..148cbd3
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Sleeps for a duration of time.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Sleeper
+{
+
+ /**
+ * Sleep for $seconds.
+ * @param int $seconds
+ */
+ public function sleep($seconds);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php b/External/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php
new file mode 100755
index 0000000..43bb1f4
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Events/SendEvent.php';
+//@require 'Swift/Plugins/BandwidthMonitorPlugin.php';
+//@require 'Swift/Plugins/Sleeper.php';
+//@require 'Swift/Plugins/Timer.php';
+
+/**
+ * Throttles the rate at which emails are sent.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+class Swift_Plugins_ThrottlerPlugin
+ extends Swift_Plugins_BandwidthMonitorPlugin
+ implements Swift_Plugins_Sleeper, Swift_Plugins_Timer
+{
+
+ /** Flag for throttling in bytes per minute */
+ const BYTES_PER_MINUTE = 0x01;
+
+ /** Flag for throttling in emails per minute */
+ const MESSAGES_PER_MINUTE = 0x10;
+
+ /**
+ * The Sleeper instance for sleeping.
+ * @var Swift_Plugins_Sleeper
+ * @access private
+ */
+ private $_sleeper;
+
+ /**
+ * The Timer instance which provides the timestamp.
+ * @var Swift_Plugins_Timer
+ * @access private
+ */
+ private $_timer;
+
+ /**
+ * The time at which the first email was sent.
+ * @var int
+ * @access private
+ */
+ private $_start;
+
+ /**
+ * The rate at which messages should be sent.
+ * @var int
+ * @access private
+ */
+ private $_rate;
+
+ /**
+ * The mode for throttling.
+ * This is {@link BYTES_PER_MINUTE} or {@link MESSAGES_PER_MINUTE}
+ * @var int
+ * @access private
+ */
+ private $_mode;
+
+ /**
+ * An internal counter of the number of messages sent.
+ * @var int
+ * @access private
+ */
+ private $_messages = 0;
+
+ /**
+ * Create a new ThrottlerPlugin.
+ * @param int $rate
+ * @param int $mode, defaults to {@link BYTES_PER_MINUTE}
+ * @param Swift_Plugins_Sleeper $sleeper (only needed in testing)
+ * @param Swift_Plugins_Timer $timer (only needed in testing)
+ */
+ public function __construct($rate, $mode = self::BYTES_PER_MINUTE,
+ Swift_Plugins_Sleeper $sleeper = null, Swift_Plugins_Timer $timer = null)
+ {
+ $this->_rate = $rate;
+ $this->_mode = $mode;
+ $this->_sleeper = $sleeper;
+ $this->_timer = $timer;
+ }
+
+ /**
+ * Invoked immediately before the Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $evt)
+ {
+ $time = $this->getTimestamp();
+ if (!isset($this->_start))
+ {
+ $this->_start = $time;
+ }
+ $duration = $time - $this->_start;
+
+ if (self::BYTES_PER_MINUTE == $this->_mode)
+ {
+ $sleep = $this->_throttleBytesPerMinute($duration);
+ }
+ else
+ {
+ $sleep = $this->_throttleMessagesPerMinute($duration);
+ }
+
+ if ($sleep > 0)
+ {
+ $this->sleep($sleep);
+ }
+ }
+
+ /**
+ * Invoked when a Message is sent.
+ * @param Swift_Events_SendEvent $evt
+ */
+ public function sendPerformed(Swift_Events_SendEvent $evt)
+ {
+ parent::sendPerformed($evt);
+ ++$this->_messages;
+ }
+
+ /**
+ * Sleep for $seconds.
+ * @param int $seconds
+ */
+ public function sleep($seconds)
+ {
+ if (isset($this->_sleeper))
+ {
+ $this->_sleeper->sleep($seconds);
+ }
+ else
+ {
+ sleep($seconds);
+ }
+ }
+
+ /**
+ * Get the current UNIX timestamp
+ * @return int
+ */
+ public function getTimestamp()
+ {
+ if (isset($this->_timer))
+ {
+ return $this->_timer->getTimestamp();
+ }
+ else
+ {
+ return time();
+ }
+ }
+
+ // -- Private methods
+
+ /**
+ * Get a number of seconds to sleep for.
+ * @param int $timePassed
+ * @return int
+ * @access private
+ */
+ private function _throttleBytesPerMinute($timePassed)
+ {
+ $expectedDuration = $this->getBytesOut() / ($this->_rate / 60);
+ return (int) ceil($expectedDuration - $timePassed);
+ }
+
+ /**
+ * Get a number of seconds to sleep for.
+ * @param int $timePassed
+ * @return int
+ * @access private
+ */
+ private function _throttleMessagesPerMinute($timePassed)
+ {
+ $expectedDuration = $this->_messages / ($this->_rate / 60);
+ return (int) ceil($expectedDuration - $timePassed);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Plugins/Timer.php b/External/swiftmailer/lib/classes/Swift/Plugins/Timer.php
new file mode 100755
index 0000000..92207bf
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Plugins/Timer.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Provides timestamp data.
+ * @package Swift
+ * @subpackage Plugins
+ * @author Chris Corbyn
+ */
+interface Swift_Plugins_Timer
+{
+
+ /**
+ * Get the current UNIX timestamp.
+ * @return int
+ */
+ public function getTimestamp();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Preferences.php b/External/swiftmailer/lib/classes/Swift/Preferences.php
new file mode 100755
index 0000000..20a2e5f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Preferences.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Changes some global preference settings in Swift Mailer.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_Preferences
+{
+
+ /** Singleton instance */
+ private static $_instance = null;
+
+ /** Constructor not to be used */
+ private function __construct() { }
+
+ /**
+ * Get a new instance of Preferences.
+ * @return Swift_Preferences
+ */
+ public static function getInstance()
+ {
+ if (!isset(self::$_instance))
+ {
+ self::$_instance = new self();
+ }
+ return self::$_instance;
+ }
+
+ /**
+ * Set the default charset used.
+ * @param string
+ * @return Swift_Preferences
+ */
+ public function setCharset($charset)
+ {
+ Swift_DependencyContainer::getInstance()
+ ->register('properties.charset')->asValue($charset);
+ return $this;
+ }
+
+ /**
+ * Set the directory where temporary files can be saved.
+ * @param string $dir
+ * @return Swift_Preferences
+ */
+ public function setTempDir($dir)
+ {
+ Swift_DependencyContainer::getInstance()
+ ->register('tempdir')->asValue($dir);
+ return $this;
+ }
+
+ /**
+ * Set the type of cache to use (i.e. "disk" or "array").
+ * @param string $type
+ * @return Swift_Preferences
+ */
+ public function setCacheType($type)
+ {
+ Swift_DependencyContainer::getInstance()
+ ->register('cache')->asAliasOf(sprintf('cache.%s', $type));
+ return $this;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php b/External/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php
new file mode 100755
index 0000000..db29e6d
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Creates StreamFilters.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+interface Swift_ReplacementFilterFactory
+{
+
+ /**
+ * Create a filter to replace $search with $replace.
+ * @param mixed $search
+ * @param mixed $replace
+ * @return Swift_StreamFilter
+ */
+ public function createFilter($search, $replace);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/RfcComplianceException.php b/External/swiftmailer/lib/classes/Swift/RfcComplianceException.php
new file mode 100755
index 0000000..5bb394b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/RfcComplianceException.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/SwiftException.php';
+
+/**
+ * RFC Compliance Exception class.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_RfcComplianceException extends Swift_SwiftException
+{
+
+ /**
+ * Create a new RfcComplianceException with $message.
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/SendmailTransport.php b/External/swiftmailer/lib/classes/Swift/SendmailTransport.php
new file mode 100755
index 0000000..60a7000
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/SendmailTransport.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/SendmailTransport.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * SendmailTransport for sending mail through a sendmail/postfix (etc..) binary.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_SendmailTransport extends Swift_Transport_SendmailTransport
+{
+
+ /**
+ * Create a new SendmailTransport, optionally using $command for sending.
+ * @param string $command
+ */
+ public function __construct($command = '/usr/sbin/sendmail -bs')
+ {
+ call_user_func_array(
+ array($this, 'Swift_Transport_SendmailTransport::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('transport.sendmail')
+ );
+
+ $this->setCommand($command);
+ }
+
+ /**
+ * Create a new SendmailTransport instance.
+ * @param string $command
+ * @return Swift_SendmailTransport
+ */
+ public static function newInstance($command = '/usr/sbin/sendmail -bs')
+ {
+ return new self($command);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/SmtpTransport.php b/External/swiftmailer/lib/classes/Swift/SmtpTransport.php
new file mode 100755
index 0000000..65180d5
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/SmtpTransport.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/EsmtpTransport.php';
+//@require 'Swift/DependencyContainer.php';
+
+/**
+ * Sends Messages over SMTP with ESMTP support.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_SmtpTransport extends Swift_Transport_EsmtpTransport
+{
+
+ /**
+ * Create a new SmtpTransport, optionally with $host, $port and $security.
+ * @param string $host
+ * @param int $port
+ * @param int $security
+ */
+ public function __construct($host = 'localhost', $port = 25,
+ $security = null)
+ {
+ call_user_func_array(
+ array($this, 'Swift_Transport_EsmtpTransport::__construct'),
+ Swift_DependencyContainer::getInstance()
+ ->createDependenciesFor('transport.smtp')
+ );
+
+ $this->setHost($host);
+ $this->setPort($port);
+ $this->setEncryption($security);
+ }
+
+ /**
+ * Create a new SmtpTransport instance.
+ * @param string $host
+ * @param int $port
+ * @param int $security
+ * @return Swift_SmtpTransport
+ */
+ public static function newInstance($host = 'localhost', $port = 25,
+ $security = null)
+ {
+ return new self($host, $port, $security);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/StreamFilter.php b/External/swiftmailer/lib/classes/Swift/StreamFilter.php
new file mode 100755
index 0000000..6c262ce
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/StreamFilter.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Processes bytes as they pass through a stream and performs filtering.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+interface Swift_StreamFilter
+{
+
+ /**
+ * Based on the buffer given, this returns true if more buffering is needed.
+ * @param mixed $buffer
+ * @return boolean
+ */
+ public function shouldBuffer($buffer);
+
+ /**
+ * Filters $buffer and returns the changes.
+ * @param mixed $buffer
+ * @return mixed
+ */
+ public function filter($buffer);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php b/External/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php
new file mode 100755
index 0000000..2df52be
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/StreamFilter.php';
+
+/**
+ * Processes bytes as they pass through a buffer and replaces sequences in it.
+ * This stream filter deals with Byte arrays rather than simple strings.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_StreamFilters_ByteArrayReplacementFilter
+ implements Swift_StreamFilter
+{
+
+ /** The needle(s) to search for */
+ private $_search;
+
+ /** The replacement(s) to make */
+ private $_replace;
+
+ /** The Index for searching */
+ private $_index;
+
+ /** The Search Tree */
+ private $_tree = array();
+
+ /** Gives the size of the largest search */
+ private $_treeMaxLen = 0;
+
+ private $_repSize;
+
+ /**
+ * Create a new ByteArrayReplacementFilter with $search and $replace.
+ * @param array $search
+ * @param array $replace
+ */
+ public function __construct($search, $replace)
+ {
+ $this->_search = $search;
+ $this->_index = array();
+ $this->_tree = array();
+ $this->_replace = array();
+ $this->_repSize = array();
+
+ $tree = null;
+ $i = null;
+ $last_size = $size = 0;
+ foreach ($search as $i => $search_element)
+ {
+ if ($tree !== null)
+ {
+ $tree[-1] = min (count($replace) - 1, $i - 1);
+ $tree[-2] = $last_size;
+ }
+ $tree = &$this->_tree;
+ if (is_array ($search_element))
+ {
+ foreach ($search_element as $k => $char)
+ {
+ $this->_index[$char] = true;
+ if (!isset($tree[$char]))
+ {
+ $tree[$char] = array();
+ }
+ $tree = &$tree[$char];
+ }
+ $last_size = $k+1;
+ $size = max($size, $last_size);
+ }
+ else
+ {
+ $last_size = 1;
+ if (!isset($tree[$search_element]))
+ {
+ $tree[$search_element] = array();
+ }
+ $tree = &$tree[$search_element];
+ $size = max($last_size, $size);
+ $this->_index[$search_element] = true;
+ }
+ }
+ if ($i !== null)
+ {
+ $tree[-1] = min (count ($replace) - 1, $i);
+ $tree[-2] = $last_size;
+ $this->_treeMaxLen = $size;
+ }
+ foreach ($replace as $rep)
+ {
+ if (!is_array($rep))
+ {
+ $rep = array ($rep);
+ }
+ $this->_replace[] = $rep;
+ }
+ for ($i = count($this->_replace) - 1; $i >= 0; --$i)
+ {
+ $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i);
+ $this->_repSize[$i] = count($rep);
+ }
+ }
+
+ /**
+ * Returns true if based on the buffer passed more bytes should be buffered.
+ * @param array $buffer
+ * @return boolean
+ */
+ public function shouldBuffer($buffer)
+ {
+ $endOfBuffer = end($buffer);
+ return isset ($this->_index[$endOfBuffer]);
+ }
+
+ /**
+ * Perform the actual replacements on $buffer and return the result.
+ * @param array $buffer
+ * @return array
+ */
+ public function filter($buffer, $_minReplaces = -1)
+ {
+ if ($this->_treeMaxLen == 0)
+ {
+ return $buffer;
+ }
+
+ $newBuffer = array();
+ $buf_size = count($buffer);
+ for ($i = 0; $i < $buf_size; ++$i)
+ {
+ $search_pos = $this->_tree;
+ $last_found = PHP_INT_MAX;
+ // We try to find if the next byte is part of a search pattern
+ for ($j = 0; $j <= $this->_treeMaxLen; ++$j)
+ {
+ // We have a new byte for a search pattern
+ if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]]))
+ {
+ $search_pos = $search_pos[$buffer[$p]];
+ // We have a complete pattern, save, in case we don't find a better match later
+ if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found
+ && $search_pos[-1] > $_minReplaces)
+ {
+ $last_found = $search_pos[-1];
+ $last_size = $search_pos[-2];
+ }
+ }
+ // We got a complete pattern
+ elseif ($last_found !== PHP_INT_MAX)
+ {
+ // Adding replacement datas to output buffer
+ $rep_size = $this->_repSize[$last_found];
+ for ($j = 0; $j < $rep_size; ++$j)
+ {
+ $newBuffer[] = $this->_replace[$last_found][$j];
+ }
+ // We Move cursor forward
+ $i += $last_size - 1;
+ // Edge Case, last position in buffer
+ if ($i >= $buf_size)
+ {
+ $newBuffer[] = $buffer[$i];
+ }
+
+ // We start the next loop
+ continue 2;
+ }
+ else
+ {
+ // this byte is not in a pattern and we haven't found another pattern
+ break;
+ }
+ }
+ // Normal byte, move it to output buffer
+ $newBuffer[] = $buffer[$i];
+ }
+
+ return $newBuffer;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php b/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php
new file mode 100755
index 0000000..9ab6c30
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/StreamFilter.php';
+
+/**
+ * Processes bytes as they pass through a buffer and replaces sequences in it.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_StreamFilters_StringReplacementFilter implements Swift_StreamFilter
+{
+
+ /** The needle(s) to search for */
+ private $_search;
+
+ /** The replacement(s) to make */
+ private $_replace;
+
+ /**
+ * Create a new StringReplacementFilter with $search and $replace.
+ * @param string|array $search
+ * @param string|array $replace
+ */
+ public function __construct($search, $replace)
+ {
+ $this->_search = $search;
+ $this->_replace = $replace;
+ }
+
+ /**
+ * Returns true if based on the buffer passed more bytes should be buffered.
+ * @param string $buffer
+ * @return boolean
+ */
+ public function shouldBuffer($buffer)
+ {
+ $endOfBuffer = substr($buffer, -1);
+ foreach ((array) $this->_search as $needle)
+ {
+ if (false !== strpos($needle, $endOfBuffer))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Perform the actual replacements on $buffer and return the result.
+ * @param string $buffer
+ * @return string
+ */
+ public function filter($buffer)
+ {
+ return str_replace($this->_search, $this->_replace, $buffer);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php b/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php
new file mode 100755
index 0000000..fcd4b83
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/StreamFilters/StringReplacementFilter.php';
+//@require 'Swift/StreamFilterFactory.php';
+
+/**
+ * Creates filters for replacing needles in a string buffer.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_StreamFilters_StringReplacementFilterFactory
+ implements Swift_ReplacementFilterFactory
+{
+
+ /** Lazy-loaded filters */
+ private $_filters = array();
+
+ /**
+ * Create a new StreamFilter to replace $search with $replace in a string.
+ * @param string $search
+ * @param string $replace
+ * @return Swift_StreamFilter
+ */
+ public function createFilter($search, $replace)
+ {
+ if (!isset($this->_filters[$search][$replace]))
+ {
+ if (!isset($this->_filters[$search]))
+ {
+ $this->_filters[$search] = array();
+ }
+
+ if (!isset($this->_filters[$search][$replace]))
+ {
+ $this->_filters[$search][$replace] = array();
+ }
+
+ $this->_filters[$search][$replace]
+ = new Swift_StreamFilters_StringReplacementFilter($search, $replace);
+ }
+
+ return $this->_filters[$search][$replace];
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/SwiftException.php b/External/swiftmailer/lib/classes/Swift/SwiftException.php
new file mode 100755
index 0000000..bd3b656
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/SwiftException.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base Exception class.
+ * @package Swift
+ * @author Chris Corbyn
+ */
+class Swift_SwiftException extends Exception
+{
+
+ /**
+ * Create a new SwiftException with $message.
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport.php b/External/swiftmailer/lib/classes/Swift/Transport.php
new file mode 100755
index 0000000..9b54752
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Events/EventListener.php';
+
+/**
+ * Sends Messages via an abstract Transport subsystem.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport
+{
+
+ /**
+ * Test if this Transport mechanism has started.
+ *
+ * @return boolean
+ */
+ public function isStarted();
+
+ /**
+ * Start this Transport mechanism.
+ */
+ public function start();
+
+ /**
+ * Stop this Transport mechanism.
+ */
+ public function stop();
+
+ /**
+ * Send the given Message.
+ *
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null);
+
+ /**
+ * Register a plugin in the Transport.
+ *
+ * @param Swift_Events_EventListener $plugin
+ */
+ public function registerPlugin(Swift_Events_EventListener $plugin);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php
new file mode 100755
index 0000000..3329d34
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php
@@ -0,0 +1,543 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport.php';
+//@require 'Swift/Transport/IoBuffer.php';
+//@require 'Swift/Transport/CommandSentException.php';
+//@require 'Swift/TransportException.php';
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Events/EventDispatcher.php';
+//@require 'Swift/Events/EventListener.php';
+
+/**
+ * Sends Messages over SMTP.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+abstract class Swift_Transport_AbstractSmtpTransport
+ implements Swift_Transport
+{
+
+ /** Input-Output buffer for sending/receiving SMTP commands and responses */
+ protected $_buffer;
+
+ /** Connection status */
+ protected $_started = false;
+
+ /** The domain name to use in HELO command */
+ protected $_domain = '[127.0.0.1]';
+
+ /** The event dispatching layer */
+ protected $_eventDispatcher;
+
+ /** Return an array of params for the Buffer */
+ abstract protected function _getBufferParams();
+
+ /**
+ * Creates a new EsmtpTransport using the given I/O buffer.
+ *
+ * @param Swift_Transport_IoBuffer $buf
+ * @param Swift_Events_EventDispatcher $dispatcher
+ */
+ public function __construct(Swift_Transport_IoBuffer $buf,
+ Swift_Events_EventDispatcher $dispatcher)
+ {
+ $this->_eventDispatcher = $dispatcher;
+ $this->_buffer = $buf;
+ $this->_lookupHostname();
+ }
+
+ /**
+ * Set the name of the local domain which Swift will identify itself as.
+ * This should be a fully-qualified domain name and should be truly the domain
+ * you're using. If your server doesn't have a domain name, use the IP in square
+ * brackets (i.e. [127.0.0.1]).
+ *
+ * @param string $domain
+ */
+ public function setLocalDomain($domain)
+ {
+ $this->_domain = $domain;
+ return $this;
+ }
+
+ /**
+ * Get the name of the domain Swift will identify as.
+ *
+ * @return string
+ */
+ public function getLocalDomain()
+ {
+ return $this->_domain;
+ }
+
+ /**
+ * Start the SMTP connection.
+ */
+ public function start()
+ {
+ if (!$this->_started)
+ {
+ if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStarted');
+ if ($evt->bubbleCancelled())
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ $this->_buffer->initialize($this->_getBufferParams());
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_throwException($e);
+ }
+ $this->_readGreeting();
+ $this->_doHeloCommand();
+
+ if ($evt)
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'transportStarted');
+ }
+
+ $this->_started = true;
+ }
+ }
+
+ /**
+ * Test if an SMTP connection has been established.
+ *
+ * @return boolean
+ */
+ public function isStarted()
+ {
+ return $this->_started;
+ }
+
+ /**
+ * Send the given Message.
+ *
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $sent = 0;
+ $failedRecipients = (array) $failedRecipients;
+
+ if (!$reversePath = $this->_getReversePath($message))
+ {
+ throw new Swift_TransportException(
+ 'Cannot send message without a sender address'
+ );
+ }
+
+ if ($evt = $this->_eventDispatcher->createSendEvent($this, $message))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed');
+ if ($evt->bubbleCancelled())
+ {
+ return 0;
+ }
+ }
+
+ $to = (array) $message->getTo();
+ $cc = (array) $message->getCc();
+ $bcc = (array) $message->getBcc();
+
+ $message->setBcc(array());
+
+ try
+ {
+ $sent += $this->_sendTo($message, $reversePath, $to, $failedRecipients);
+ $sent += $this->_sendCc($message, $reversePath, $cc, $failedRecipients);
+ $sent += $this->_sendBcc($message, $reversePath, $bcc, $failedRecipients);
+ }
+ catch (Exception $e)
+ {
+ $message->setBcc($bcc);
+ throw $e;
+ }
+
+ $message->setBcc($bcc);
+
+ if ($evt)
+ {
+ if ($sent == count($to) + count($cc) + count($bcc))
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS);
+ }
+ elseif ($sent > 0)
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE);
+ }
+ else
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED);
+ }
+ $evt->setFailedRecipients($failedRecipients);
+ $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
+ }
+
+ $message->generateId(); //Make sure a new Message ID is used
+
+ return $sent;
+ }
+
+ /**
+ * Stop the SMTP connection.
+ */
+ public function stop()
+ {
+ if ($this->_started)
+ {
+ if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped');
+ if ($evt->bubbleCancelled())
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ $this->executeCommand("QUIT\r\n", array(221));
+ }
+ catch (Swift_TransportException $e) {}
+
+ try
+ {
+ $this->_buffer->terminate();
+
+ if ($evt)
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped');
+ }
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_throwException($e);
+ }
+ }
+ $this->_started = false;
+ }
+
+ /**
+ * Register a plugin.
+ *
+ * @param Swift_Events_EventListener $plugin
+ */
+ public function registerPlugin(Swift_Events_EventListener $plugin)
+ {
+ $this->_eventDispatcher->bindEventListener($plugin);
+ }
+
+ /**
+ * Reset the current mail transaction.
+ */
+ public function reset()
+ {
+ $this->executeCommand("RSET\r\n", array(250));
+ }
+
+ /**
+ * Get the IoBuffer where read/writes are occurring.
+ *
+ * @return Swift_Transport_IoBuffer
+ */
+ public function getBuffer()
+ {
+ return $this->_buffer;
+ }
+
+ /**
+ * Run a command against the buffer, expecting the given response codes.
+ *
+ * If no response codes are given, the response will not be validated.
+ * If codes are given, an exception will be thrown on an invalid response.
+ *
+ * @param string $command
+ * @param int[] $codes
+ * @param string[] &$failures
+ * @return string
+ */
+ public function executeCommand($command, $codes = array(), &$failures = null)
+ {
+ $failures = (array) $failures;
+ $seq = $this->_buffer->write($command);
+ $response = $this->_getFullResponse($seq);
+ if ($evt = $this->_eventDispatcher->createCommandEvent($this, $command, $codes))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'commandSent');
+ }
+ $this->_assertResponseCode($response, $codes);
+ return $response;
+ }
+
+ // -- Protected methods
+
+ /** Read the opening SMTP greeting */
+ protected function _readGreeting()
+ {
+ $this->_assertResponseCode($this->_getFullResponse(0), array(220));
+ }
+
+ /** Send the HELO welcome */
+ protected function _doHeloCommand()
+ {
+ $this->executeCommand(
+ sprintf("HELO %s\r\n", $this->_domain), array(250)
+ );
+ }
+
+ /** Send the MAIL FROM command */
+ protected function _doMailFromCommand($address)
+ {
+ $this->executeCommand(
+ sprintf("MAIL FROM: <%s>\r\n", $address), array(250)
+ );
+ }
+
+ /** Send the RCPT TO command */
+ protected function _doRcptToCommand($address)
+ {
+ $this->executeCommand(
+ sprintf("RCPT TO: <%s>\r\n", $address), array(250, 251, 252)
+ );
+ }
+
+ /** Send the DATA command */
+ protected function _doDataCommand()
+ {
+ $this->executeCommand("DATA\r\n", array(354));
+ }
+
+ /** Stream the contents of the message over the buffer */
+ protected function _streamMessage(Swift_Mime_Message $message)
+ {
+ $this->_buffer->setWriteTranslations(array("\r\n." => "\r\n.."));
+ try
+ {
+ $message->toByteStream($this->_buffer);
+ $this->_buffer->flushBuffers();
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_throwException($e);
+ }
+ $this->_buffer->setWriteTranslations(array());
+ $this->executeCommand("\r\n.\r\n", array(250));
+ }
+
+ /** Determine the best-use reverse path for this message */
+ protected function _getReversePath(Swift_Mime_Message $message)
+ {
+ $return = $message->getReturnPath();
+ $sender = $message->getSender();
+ $from = $message->getFrom();
+ $path = null;
+ if (!empty($return))
+ {
+ $path = $return;
+ }
+ elseif (!empty($sender))
+ {
+ // Don't use array_keys
+ reset($sender); // Reset Pointer to first pos
+ $path = key($sender); // Get key
+ }
+ elseif (!empty($from))
+ {
+ reset($from); // Reset Pointer to first pos
+ $path = key($from); // Get key
+ }
+ return $path;
+ }
+
+ /** Throw a TransportException, first sending it to any listeners */
+ protected function _throwException(Swift_TransportException $e)
+ {
+ if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown');
+ if (!$evt->bubbleCancelled())
+ {
+ throw $e;
+ }
+ }
+ else
+ {
+ throw $e;
+ }
+ }
+
+ /** Throws an Exception if a response code is incorrect */
+ protected function _assertResponseCode($response, $wanted)
+ {
+ list($code, $separator, $text) = sscanf($response, '%3d%[ -]%s');
+ $valid = (empty($wanted) || in_array($code, $wanted));
+
+ if ($evt = $this->_eventDispatcher->createResponseEvent($this, $response,
+ $valid))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'responseReceived');
+ }
+
+ if (!$valid)
+ {
+ $this->_throwException(
+ new Swift_TransportException(
+ 'Expected response code ' . implode('/', $wanted) . ' but got code ' .
+ '"' . $code . '", with message "' . $response . '"'
+ )
+ );
+ }
+ }
+
+ /** Get an entire multi-line response using its sequence number */
+ protected function _getFullResponse($seq)
+ {
+ $response = '';
+ try
+ {
+ do
+ {
+ $line = $this->_buffer->readLine($seq);
+ $response .= $line;
+ }
+ while (null !== $line && false !== $line && ' ' != $line{3});
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_throwException($e);
+ }
+ return $response;
+ }
+
+ // -- Private methods
+
+ /** Send an email to the given recipients from the given reverse path */
+ private function _doMailTransaction($message, $reversePath,
+ array $recipients, array &$failedRecipients)
+ {
+ $sent = 0;
+ $this->_doMailFromCommand($reversePath);
+ foreach ($recipients as $forwardPath)
+ {
+ try
+ {
+ $this->_doRcptToCommand($forwardPath);
+ $sent++;
+ }
+ catch (Swift_TransportException $e)
+ {
+ $failedRecipients[] = $forwardPath;
+ }
+ }
+
+ if ($sent != 0)
+ {
+ $this->_doDataCommand();
+ $this->_streamMessage($message);
+ }
+ else
+ {
+ $this->reset();
+ }
+
+ return $sent;
+ }
+
+ /** Send a message to the given To: recipients */
+ private function _sendTo(Swift_Mime_Message $message, $reversePath,
+ array $to, array &$failedRecipients)
+ {
+ if (empty($to))
+ {
+ return 0;
+ }
+ return $this->_doMailTransaction($message, $reversePath, array_keys($to),
+ $failedRecipients);
+ }
+
+ /** Send a message to the given Cc: recipients */
+ private function _sendCc(Swift_Mime_Message $message, $reversePath,
+ array $cc, array &$failedRecipients)
+ {
+ if (empty($cc))
+ {
+ return 0;
+ }
+ return $this->_doMailTransaction($message, $reversePath, array_keys($cc),
+ $failedRecipients);
+ }
+
+ /** Send a message to all Bcc: recipients */
+ private function _sendBcc(Swift_Mime_Message $message, $reversePath,
+ array $bcc, array &$failedRecipients)
+ {
+ $sent = 0;
+ foreach ($bcc as $forwardPath => $name)
+ {
+ $message->setBcc(array($forwardPath => $name));
+ $sent += $this->_doMailTransaction(
+ $message, $reversePath, array($forwardPath), $failedRecipients
+ );
+ }
+ return $sent;
+ }
+
+ /** Try to determine the hostname of the server this is run on */
+ private function _lookupHostname()
+ {
+ if (!empty($_SERVER['SERVER_NAME'])
+ && $this->_isFqdn($_SERVER['SERVER_NAME']))
+ {
+ $this->_domain = $_SERVER['SERVER_NAME'];
+ }
+ elseif (!empty($_SERVER['SERVER_ADDR']))
+ {
+ $this->_domain = sprintf('[%s]', $_SERVER['SERVER_ADDR']);
+ }
+ }
+
+ /** Determine is the $hostname is a fully-qualified name */
+ private function _isFqdn($hostname)
+ {
+ //We could do a really thorough check, but there's really no point
+ if (false !== $dotPos = strpos($hostname, '.'))
+ {
+ return ($dotPos > 0) && ($dotPos != strlen($hostname) - 1);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ $this->stop();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php
new file mode 100755
index 0000000..4c7e0f2
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/Esmtp/Authenticator.php';
+//@require 'Swift/Transport/SmtpAgent.php';
+//@require 'Swift/TransportException.php';
+
+/**
+ * Handles CRAM-MD5 authentication.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_Esmtp_Auth_CramMd5Authenticator
+ implements Swift_Transport_Esmtp_Authenticator
+{
+
+ /**
+ * Get the name of the AUTH mechanism this Authenticator handles.
+ * @return string
+ */
+ public function getAuthKeyword()
+ {
+ return 'CRAM-MD5';
+ }
+
+ /**
+ * Try to authenticate the user with $username and $password.
+ * @param Swift_Transport_SmtpAgent $agent
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ public function authenticate(Swift_Transport_SmtpAgent $agent,
+ $username, $password)
+ {
+ try
+ {
+ $challenge = $agent->executeCommand("AUTH CRAM-MD5\r\n", array(334));
+ $challenge = base64_decode(substr($challenge, 4));
+ $message = base64_encode(
+ $username . ' ' . $this->_getResponse($password, $challenge)
+ );
+ $agent->executeCommand(sprintf("%s\r\n", $message), array(235));
+ return true;
+ }
+ catch (Swift_TransportException $e)
+ {
+ $agent->executeCommand("RSET\r\n", array(250));
+ return false;
+ }
+ }
+
+ /**
+ * Generate a CRAM-MD5 response from a server challenge.
+ * @param string $secret
+ * @param string $challenge
+ * @return string
+ */
+ private function _getResponse($secret, $challenge)
+ {
+ if (strlen($secret) > 64)
+ {
+ $secret = pack('H32', md5($secret));
+ }
+
+ if (strlen($secret) < 64)
+ {
+ $secret = str_pad($secret, 64, chr(0));
+ }
+
+ $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64);
+ $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64);
+
+ $inner = pack('H32', md5($k_ipad . $challenge));
+ $digest = md5($k_opad . $inner);
+
+ return $digest;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php
new file mode 100755
index 0000000..bd22617
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/Esmtp/Authenticator.php';
+//@require 'Swift/Transport/SmtpAgent.php';
+//@require 'Swift/TransportException.php';
+
+/**
+ * Handles LOGIN authentication.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_Esmtp_Auth_LoginAuthenticator
+ implements Swift_Transport_Esmtp_Authenticator
+{
+
+ /**
+ * Get the name of the AUTH mechanism this Authenticator handles.
+ * @return string
+ */
+ public function getAuthKeyword()
+ {
+ return 'LOGIN';
+ }
+
+ /**
+ * Try to authenticate the user with $username and $password.
+ * @param Swift_Transport_SmtpAgent $agent
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ public function authenticate(Swift_Transport_SmtpAgent $agent,
+ $username, $password)
+ {
+ try
+ {
+ $agent->executeCommand("AUTH LOGIN\r\n", array(334));
+ $agent->executeCommand(sprintf("%s\r\n", base64_encode($username)), array(334));
+ $agent->executeCommand(sprintf("%s\r\n", base64_encode($password)), array(235));
+ return true;
+ }
+ catch (Swift_TransportException $e)
+ {
+ $agent->executeCommand("RSET\r\n", array(250));
+ return false;
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php
new file mode 100755
index 0000000..ddd8094
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/Esmtp/Authenticator.php';
+//@require 'Swift/Transport/SmtpAgent.php';
+//@require 'Swift/TransportException.php';
+
+/**
+ * Handles PLAIN authentication.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_Esmtp_Auth_PlainAuthenticator
+ implements Swift_Transport_Esmtp_Authenticator
+{
+
+ /**
+ * Get the name of the AUTH mechanism this Authenticator handles.
+ * @return string
+ */
+ public function getAuthKeyword()
+ {
+ return 'PLAIN';
+ }
+
+ /**
+ * Try to authenticate the user with $username and $password.
+ * @param Swift_Transport_SmtpAgent $agent
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ public function authenticate(Swift_Transport_SmtpAgent $agent,
+ $username, $password)
+ {
+ try
+ {
+ $message = base64_encode($username . chr(0) . $username . chr(0) . $password);
+ $agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), array(235));
+ return true;
+ }
+ catch (Swift_TransportException $e)
+ {
+ $agent->executeCommand("RSET\r\n", array(250));
+ return false;
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php
new file mode 100755
index 0000000..a223169
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php
@@ -0,0 +1,262 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/TransportException.php';
+//@require 'Swift/Transport/EsmtpHandler.php';
+//@require 'Swift/Transport/SmtpAgent.php';
+
+/**
+ * An ESMTP handler for AUTH support.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_Esmtp_AuthHandler implements Swift_Transport_EsmtpHandler
+{
+
+ /**
+ * Authenticators available to process the request.
+ * @var Swift_Transport_Esmtp_Authenticator[]
+ * @access private
+ */
+ private $_authenticators = array();
+
+ /**
+ * The username for authentication.
+ * @var string
+ * @access private
+ */
+ private $_username;
+
+ /**
+ * The password for authentication.
+ * @var string
+ * @access private
+ */
+ private $_password;
+
+ /**
+ * The auth mode for authentication.
+ * @var string
+ * @access private
+ */
+ private $_auth_mode;
+
+ /**
+ * The ESMTP AUTH parameters available.
+ * @var string[]
+ * @access private
+ */
+ private $_esmtpParams = array();
+
+ /**
+ * Create a new AuthHandler with $authenticators for support.
+ * @param Swift_Transport_Esmtp_Authenticator[] $authenticators
+ */
+ public function __construct(array $authenticators)
+ {
+ $this->setAuthenticators($authenticators);
+ }
+
+ /**
+ * Set the Authenticators which can process a login request.
+ * @param Swift_Transport_Esmtp_Authenticator[] $authenticators
+ */
+ public function setAuthenticators(array $authenticators)
+ {
+ $this->_authenticators = $authenticators;
+ }
+
+ /**
+ * Get the Authenticators which can process a login request.
+ * @return Swift_Transport_Esmtp_Authenticator[]
+ */
+ public function getAuthenticators()
+ {
+ return $this->_authenticators;
+ }
+
+ /**
+ * Set the username to authenticate with.
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->_username = $username;
+ }
+
+ /**
+ * Get the username to authenticate with.
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->_username;
+ }
+
+ /**
+ * Set the password to authenticate with.
+ * @param string $password
+ */
+ public function setPassword($password)
+ {
+ $this->_password = $password;
+ }
+
+ /**
+ * Get the password to authenticate with.
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->_password;
+ }
+
+ /**
+ * Set the auth mode to use to authenticate.
+ * @param string $mode
+ */
+ public function setAuthMode($mode)
+ {
+ $this->_auth_mode = $mode;
+ }
+
+ /**
+ * Get the auth mode to use to authenticate.
+ * @return string
+ */
+ public function getAuthMode()
+ {
+ return $this->_auth_mode;
+ }
+
+ /**
+ * Get the name of the ESMTP extension this handles.
+ * @return boolean
+ */
+ public function getHandledKeyword()
+ {
+ return 'AUTH';
+ }
+
+ /**
+ * Set the parameters which the EHLO greeting indicated.
+ * @param string[] $parameters
+ */
+ public function setKeywordParams(array $parameters)
+ {
+ $this->_esmtpParams = $parameters;
+ }
+
+ /**
+ * Runs immediately after a EHLO has been issued.
+ * @param Swift_Transport_SmtpAgent $agent to read/write
+ */
+ public function afterEhlo(Swift_Transport_SmtpAgent $agent)
+ {
+ if ($this->_username)
+ {
+ $count = 0;
+ foreach ($this->_getAuthenticatorsForAgent() as $authenticator)
+ {
+ if (in_array(strtolower($authenticator->getAuthKeyword()),
+ array_map('strtolower', $this->_esmtpParams)))
+ {
+ $count++;
+ if ($authenticator->authenticate($agent, $this->_username, $this->_password))
+ {
+ return;
+ }
+ }
+ }
+ throw new Swift_TransportException(
+ 'Failed to authenticate on SMTP server with username "' .
+ $this->_username . '" using ' . $count . ' possible authenticators'
+ );
+ }
+ }
+
+ /**
+ * Not used.
+ */
+ public function getMailParams()
+ {
+ return array();
+ }
+
+ /**
+ * Not used.
+ */
+ public function getRcptParams()
+ {
+ return array();
+ }
+
+ /**
+ * Not used.
+ */
+ public function onCommand(Swift_Transport_SmtpAgent $agent,
+ $command, $codes = array(), &$failedRecipients = null, &$stop = false)
+ {
+ }
+
+ /**
+ * Returns +1, -1 or 0 according to the rules for usort().
+ * This method is called to ensure extensions can be execute in an appropriate order.
+ * @param string $esmtpKeyword to compare with
+ * @return int
+ */
+ public function getPriorityOver($esmtpKeyword)
+ {
+ return 0;
+ }
+
+ /**
+ * Returns an array of method names which are exposed to the Esmtp class.
+ * @return string[]
+ */
+ public function exposeMixinMethods()
+ {
+ return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode');
+ }
+
+ /**
+ * Not used.
+ */
+ public function resetState()
+ {
+ }
+
+ // -- Protected methods
+
+ /**
+ * Returns the authenticator list for the given agent.
+ * @param Swift_Transport_SmtpAgent $agent
+ * @return array
+ * @access protected
+ */
+ protected function _getAuthenticatorsForAgent()
+ {
+ if (!$mode = strtolower($this->_auth_mode))
+ {
+ return $this->_authenticators;
+ }
+
+ foreach ($this->_authenticators as $authenticator)
+ {
+ if (strtolower($authenticator->getAuthKeyword()) == $mode)
+ {
+ return array($authenticator);
+ }
+ }
+
+ throw new Swift_TransportException('Auth mode '.$mode.' is invalid');
+ }
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php
new file mode 100755
index 0000000..bf166d3
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/SmtpAgent.php';
+
+/**
+ * An Authentication mechanism.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport_Esmtp_Authenticator
+{
+
+ /**
+ * Get the name of the AUTH mechanism this Authenticator handles.
+ * @return string
+ */
+ public function getAuthKeyword();
+
+ /**
+ * Try to authenticate the user with $username and $password.
+ * @param Swift_Transport_SmtpAgent $agent
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ public function authenticate(Swift_Transport_SmtpAgent $agent,
+ $username, $password);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php b/External/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php
new file mode 100755
index 0000000..e96f95f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/EsmtpBufferWrapper.php';
+
+/**
+ * An ESMTP handler.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport_EsmtpHandler
+{
+
+ /**
+ * Get the name of the ESMTP extension this handles.
+ * @return boolean
+ */
+ public function getHandledKeyword();
+
+ /**
+ * Set the parameters which the EHLO greeting indicated.
+ * @param string[] $parameters
+ */
+ public function setKeywordParams(array $parameters);
+
+ /**
+ * Runs immediately after a EHLO has been issued.
+ * @param Swift_Transport_SmtpAgent $agent to read/write
+ */
+ public function afterEhlo(Swift_Transport_SmtpAgent $agent);
+
+ /**
+ * Get params which are appended to MAIL FROM:<>.
+ * @return string[]
+ */
+ public function getMailParams();
+
+ /**
+ * Get params which are appended to RCPT TO:<>.
+ * @return string[]
+ */
+ public function getRcptParams();
+
+ /**
+ * Runs when a command is due to be sent.
+ * @param Swift_Transport_SmtpAgent $agent to read/write
+ * @param string $command to send
+ * @param int[] $codes expected in response
+ * @param string[] &$failedRecipients
+ * @param boolean &$stop to be set true if the command is now sent
+ */
+ public function onCommand(Swift_Transport_SmtpAgent $agent,
+ $command, $codes = array(), &$failedRecipients = null, &$stop = false);
+
+ /**
+ * Returns +1, -1 or 0 according to the rules for usort().
+ * This method is called to ensure extensions can be execute in an appropriate order.
+ * @param string $esmtpKeyword to compare with
+ * @return int
+ */
+ public function getPriorityOver($esmtpKeyword);
+
+ /**
+ * Returns an array of method names which are exposed to the Esmtp class.
+ * @return string[]
+ */
+ public function exposeMixinMethods();
+
+ /**
+ * Tells this handler to clear any buffers and reset its state.
+ */
+ public function resetState();
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php
new file mode 100755
index 0000000..c7833c3
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php
@@ -0,0 +1,340 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/AbstractSmtpTransport.php';
+//@require 'Swift/Transport/EsmtpHandler.php';
+//@require 'Swift/Transport/IoBuffer.php';
+//@require 'Swift/Transport/SmtpAgent.php';
+//@require 'Swift/TransportException.php';
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Events/EventDispatcher.php';
+
+/**
+ * Sends Messages over SMTP with ESMTP support.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_EsmtpTransport
+ extends Swift_Transport_AbstractSmtpTransport
+ implements Swift_Transport_SmtpAgent
+{
+
+ /**
+ * ESMTP extension handlers.
+ * @var Swift_Transport_EsmtpHandler[]
+ * @access private
+ */
+ private $_handlers = array();
+
+ /**
+ * ESMTP capabilities.
+ * @var string[]
+ * @access private
+ */
+ private $_capabilities = array();
+
+ /**
+ * Connection buffer parameters.
+ * @var array
+ * @access protected
+ */
+ private $_params = array(
+ 'protocol' => 'tcp',
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'blocking' => 1,
+ 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET
+ );
+
+ /**
+ * Creates a new EsmtpTransport using the given I/O buffer.
+ * @param Swift_Transport_IoBuffer $buf
+ * @param Swift_Transport_EsmtpHandler[] $extensionHandlers
+ * @param Swift_Events_EventDispatcher $dispatcher
+ */
+ public function __construct(Swift_Transport_IoBuffer $buf,
+ array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher)
+ {
+ parent::__construct($buf, $dispatcher);
+ $this->setExtensionHandlers($extensionHandlers);
+ }
+
+ /**
+ * Set the host to connect to.
+ * @param string $host
+ */
+ public function setHost($host)
+ {
+ $this->_params['host'] = $host;
+ return $this;
+ }
+
+ /**
+ * Get the host to connect to.
+ * @return string
+ */
+ public function getHost()
+ {
+ return $this->_params['host'];
+ }
+
+ /**
+ * Set the port to connect to.
+ * @param int $port
+ */
+ public function setPort($port)
+ {
+ $this->_params['port'] = (int) $port;
+ return $this;
+ }
+
+ /**
+ * Get the port to connect to.
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->_params['port'];
+ }
+
+ /**
+ * Set the connection timeout.
+ * @param int $timeout seconds
+ */
+ public function setTimeout($timeout)
+ {
+ $this->_params['timeout'] = (int) $timeout;
+ return $this;
+ }
+
+ /**
+ * Get the connection timeout.
+ * @return int
+ */
+ public function getTimeout()
+ {
+ return $this->_params['timeout'];
+ }
+
+ /**
+ * Set the encryption type (tls or ssl)
+ * @param string $encryption
+ */
+ public function setEncryption($enc)
+ {
+ $this->_params['protocol'] = $enc;
+ return $this;
+ }
+
+ /**
+ * Get the encryption type.
+ * @return string
+ */
+ public function getEncryption()
+ {
+ return $this->_params['protocol'];
+ }
+
+ /**
+ * Set ESMTP extension handlers.
+ * @param Swift_Transport_EsmtpHandler[] $handlers
+ */
+ public function setExtensionHandlers(array $handlers)
+ {
+ $assoc = array();
+ foreach ($handlers as $handler)
+ {
+ $assoc[$handler->getHandledKeyword()] = $handler;
+ }
+ uasort($assoc, array($this, '_sortHandlers'));
+ $this->_handlers = $assoc;
+ $this->_setHandlerParams();
+ return $this;
+ }
+
+ /**
+ * Get ESMTP extension handlers.
+ * @return Swift_Transport_EsmtpHandler[]
+ */
+ public function getExtensionHandlers()
+ {
+ return array_values($this->_handlers);
+ }
+
+ /**
+ * Run a command against the buffer, expecting the given response codes.
+ * If no response codes are given, the response will not be validated.
+ * If codes are given, an exception will be thrown on an invalid response.
+ * @param string $command
+ * @param int[] $codes
+ * @param string[] &$failures
+ * @return string
+ */
+ public function executeCommand($command, $codes = array(), &$failures = null)
+ {
+ $failures = (array) $failures;
+ $stopSignal = false;
+ $response = null;
+ foreach ($this->_getActiveHandlers() as $handler)
+ {
+ $response = $handler->onCommand(
+ $this, $command, $codes, $failures, $stopSignal
+ );
+ if ($stopSignal)
+ {
+ return $response;
+ }
+ }
+ return parent::executeCommand($command, $codes, $failures);
+ }
+
+ // -- Mixin invocation code
+
+ /** Mixin handling method for ESMTP handlers */
+ public function __call($method, $args)
+ {
+ foreach ($this->_handlers as $handler)
+ {
+ if (in_array(strtolower($method),
+ array_map('strtolower', (array) $handler->exposeMixinMethods())
+ ))
+ {
+ $return = call_user_func_array(array($handler, $method), $args);
+ //Allow fluid method calls
+ if (is_null($return) && substr($method, 0, 3) == 'set')
+ {
+ return $this;
+ }
+ else
+ {
+ return $return;
+ }
+ }
+ }
+ trigger_error('Call to undefined method ' . $method, E_USER_ERROR);
+ }
+
+ // -- Protected methods
+
+ /** Get the params to initialize the buffer */
+ protected function _getBufferParams()
+ {
+ return $this->_params;
+ }
+
+ /** Overridden to perform EHLO instead */
+ protected function _doHeloCommand()
+ {
+ try
+ {
+ $response = $this->executeCommand(
+ sprintf("EHLO %s\r\n", $this->_domain), array(250)
+ );
+ }
+ catch (Swift_TransportException $e)
+ {
+ return parent::_doHeloCommand();
+ }
+
+ $this->_capabilities = $this->_getCapabilities($response);
+ $this->_setHandlerParams();
+ foreach ($this->_getActiveHandlers() as $handler)
+ {
+ $handler->afterEhlo($this);
+ }
+ }
+
+ /** Overridden to add Extension support */
+ protected function _doMailFromCommand($address)
+ {
+ $handlers = $this->_getActiveHandlers();
+ $params = array();
+ foreach ($handlers as $handler)
+ {
+ $params = array_merge($params, (array) $handler->getMailParams());
+ }
+ $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
+ $this->executeCommand(
+ sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250)
+ );
+ }
+
+ /** Overridden to add Extension support */
+ protected function _doRcptToCommand($address)
+ {
+ $handlers = $this->_getActiveHandlers();
+ $params = array();
+ foreach ($handlers as $handler)
+ {
+ $params = array_merge($params, (array) $handler->getRcptParams());
+ }
+ $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
+ $this->executeCommand(
+ sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252)
+ );
+ }
+
+ // -- Private methods
+
+ /** Determine ESMTP capabilities by function group */
+ private function _getCapabilities($ehloResponse)
+ {
+ $capabilities = array();
+ $ehloResponse = trim($ehloResponse);
+ $lines = explode("\r\n", $ehloResponse);
+ array_shift($lines);
+ foreach ($lines as $line)
+ {
+ if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches))
+ {
+ $keyword = strtoupper($matches[1]);
+ $paramStr = strtoupper(ltrim($matches[2], ' ='));
+ $params = !empty($paramStr) ? explode(' ', $paramStr) : array();
+ $capabilities[$keyword] = $params;
+ }
+ }
+ return $capabilities;
+ }
+
+ /** Set parameters which are used by each extension handler */
+ private function _setHandlerParams()
+ {
+ foreach ($this->_handlers as $keyword => $handler)
+ {
+ if (array_key_exists($keyword, $this->_capabilities))
+ {
+ $handler->setKeywordParams($this->_capabilities[$keyword]);
+ }
+ }
+ }
+
+ /** Get ESMTP handlers which are currently ok to use */
+ private function _getActiveHandlers()
+ {
+ $handlers = array();
+ foreach ($this->_handlers as $keyword => $handler)
+ {
+ if (array_key_exists($keyword, $this->_capabilities))
+ {
+ $handlers[] = $handler;
+ }
+ }
+ return $handlers;
+ }
+
+ /** Custom sort for extension handler ordering */
+ private function _sortHandlers($a, $b)
+ {
+ return $a->getPriorityOver($b->getHandledKeyword());
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php
new file mode 100755
index 0000000..e62491c
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/LoadBalancedTransport.php';
+//@require 'Swift/Mime/Message.php';
+
+/**
+ * Contains a list of redundant Transports so when one fails, the next is used.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_FailoverTransport
+ extends Swift_Transport_LoadBalancedTransport
+{
+
+ /**
+ * Registered transport curently used.
+ * @var Swift_Transport
+ * @access private
+ */
+ private $_currentTransport;
+
+ /**
+ * Creates a new FailoverTransport.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ /**
+ * Send the given Message.
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $maxTransports = count($this->_transports);
+ $sent = 0;
+
+ for ($i = 0; $i < $maxTransports
+ && $transport = $this->_getNextTransport(); ++$i)
+ {
+ try
+ {
+ if (!$transport->isStarted())
+ {
+ $transport->start();
+ }
+
+ return $transport->send($message, $failedRecipients);
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_killCurrentTransport();
+ }
+ }
+
+ if (count($this->_transports) == 0)
+ {
+ throw new Swift_TransportException(
+ 'All Transports in FailoverTransport failed, or no Transports available'
+ );
+ }
+
+ return $sent;
+ }
+
+ // -- Protected methods
+
+ protected function _getNextTransport()
+ {
+ if (!isset($this->_currentTransport))
+ {
+ $this->_currentTransport = parent::_getNextTransport();
+ }
+ return $this->_currentTransport;
+ }
+
+ protected function _killCurrentTransport()
+ {
+ $this->_currentTransport = null;
+ parent::_killCurrentTransport();
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php b/External/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php
new file mode 100755
index 0000000..ac66ef0
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/InputByteStream.php';
+//@require 'Swift/OutputByteStream.php';
+
+/**
+ * Buffers input and output to a resource.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport_IoBuffer
+ extends Swift_InputByteStream, Swift_OutputByteStream
+{
+
+ /** A socket buffer over TCP */
+ const TYPE_SOCKET = 0x0001;
+
+ /** A process buffer with I/O support */
+ const TYPE_PROCESS = 0x0010;
+
+ /**
+ * Perform any initialization needed, using the given $params.
+ * Parameters will vary depending upon the type of IoBuffer used.
+ * @param array $params
+ */
+ public function initialize(array $params);
+
+ /**
+ * Set an individual param on the buffer (e.g. switching to SSL).
+ * @param string $param
+ * @param mixed $value
+ */
+ public function setParam($param, $value);
+
+ /**
+ * Perform any shutdown logic needed.
+ */
+ public function terminate();
+
+ /**
+ * Set an array of string replacements which should be made on data written
+ * to the buffer. This could replace LF with CRLF for example.
+ * @param string[] $replacements
+ */
+ public function setWriteTranslations(array $replacements);
+
+ /**
+ * Get a line of output (including any CRLF).
+ * The $sequence number comes from any writes and may or may not be used
+ * depending upon the implementation.
+ * @param int $sequence of last write to scan from
+ * @return string
+ */
+ public function readLine($sequence);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php
new file mode 100755
index 0000000..367981b
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport.php';
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Events/EventListener.php';
+
+/**
+ * Redudantly and rotationally uses several Transports when sending.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_LoadBalancedTransport implements Swift_Transport
+{
+
+ /** Transports which are deemed useless */
+ private $_deadTransports = array();
+
+ /**
+ * The Transports which are used in rotation.
+ *
+ * @var array Swift_Transport
+ * @access protected
+ */
+ protected $_transports = array();
+
+ /**
+ * Creates a new LoadBalancedTransport.
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Set $transports to delegate to.
+ *
+ * @param array $transports Swift_Transport
+ */
+ public function setTransports(array $transports)
+ {
+ $this->_transports = $transports;
+ $this->_deadTransports = array();
+ }
+
+ /**
+ * Get $transports to delegate to.
+ *
+ * @return array Swift_Transport
+ */
+ public function getTransports(array $transports)
+ {
+ return array_merge($this->_transports, $this->_deadTransports);
+ }
+
+ /**
+ * Test if this Transport mechanism has started.
+ *
+ * @return boolean
+ */
+ public function isStarted()
+ {
+ return count($this->_transports) > 0;
+ }
+
+ /**
+ * Start this Transport mechanism.
+ */
+ public function start()
+ {
+ $this->_transports = array_merge($this->_transports, $this->_deadTransports);
+ }
+
+ /**
+ * Stop this Transport mechanism.
+ */
+ public function stop()
+ {
+ foreach ($this->_transports as $transport)
+ {
+ $transport->stop();
+ }
+ }
+
+ /**
+ * Send the given Message.
+ *
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $maxTransports = count($this->_transports);
+ $sent = 0;
+
+ for ($i = 0; $i < $maxTransports
+ && $transport = $this->_getNextTransport(); ++$i)
+ {
+ try
+ {
+ if (!$transport->isStarted())
+ {
+ $transport->start();
+ }
+ if ($sent = $transport->send($message, $failedRecipients))
+ {
+ break;
+ }
+ }
+ catch (Swift_TransportException $e)
+ {
+ $this->_killCurrentTransport();
+ }
+ }
+
+ if (count($this->_transports) == 0)
+ {
+ throw new Swift_TransportException(
+ 'All Transports in LoadBalancedTransport failed, or no Transports available'
+ );
+ }
+
+ return $sent;
+ }
+
+ /**
+ * Register a plugin.
+ *
+ * @param Swift_Events_EventListener $plugin
+ */
+ public function registerPlugin(Swift_Events_EventListener $plugin)
+ {
+ foreach ($this->_transports as $transport)
+ {
+ $transport->registerPlugin($plugin);
+ }
+ }
+
+ // -- Protected methods
+
+ /**
+ * Rotates the transport list around and returns the first instance.
+ *
+ * @return Swift_Transport
+ * @access protected
+ */
+ protected function _getNextTransport()
+ {
+ if ($next = array_shift($this->_transports))
+ {
+ $this->_transports[] = $next;
+ }
+ return $next;
+ }
+
+ /**
+ * Tag the currently used (top of stack) transport as dead/useless.
+ *
+ * @access protected
+ */
+ protected function _killCurrentTransport()
+ {
+ if ($transport = array_pop($this->_transports))
+ {
+ try
+ {
+ $transport->stop();
+ }
+ catch (Exception $e)
+ {
+ }
+ $this->_deadTransports[] = $transport;
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php b/External/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php
new file mode 100755
index 0000000..dda882f
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * This interface intercepts calls to the mail() function.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport_MailInvoker
+{
+
+ /**
+ * Send mail via the mail() function.
+ *
+ * This method takes the same arguments as PHP mail().
+ *
+ * @param string $to
+ * @param string $subject
+ * @param string $body
+ * @param string $headers
+ * @param string $extraParams
+ *
+ * @return boolean
+ */
+ public function mail($to, $subject, $body, $headers = null, $extraParams = null);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/MailTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/MailTransport.php
new file mode 100755
index 0000000..eca59e1
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/MailTransport.php
@@ -0,0 +1,242 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport.php';
+//@require 'Swift/Transport/MailInvoker.php';
+//@require 'Swift/Mime/Message.php';
+//@require 'Swift/Events/EventListener.php';
+
+/**
+ * Sends Messages using the mail() function.
+ *
+ * It is advised that users do not use this transport if at all possible
+ * since a number of plugin features cannot be used in conjunction with this
+ * transport due to the internal interface in PHP itself.
+ *
+ * The level of error reporting with this transport is incredibly weak, again
+ * due to limitations of PHP's internal mail() function. You'll get an
+ * all-or-nothing result from sending.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_MailTransport implements Swift_Transport
+{
+
+ /** Addtional parameters to pass to mail() */
+ private $_extraParams = '-f%s';
+
+ /** The event dispatcher from the plugin API */
+ private $_eventDispatcher;
+
+ /** An invoker that calls the mail() function */
+ private $_invoker;
+
+ /**
+ * Create a new MailTransport with the $log.
+ * @param Swift_Transport_Log $log
+ */
+ public function __construct(Swift_Transport_MailInvoker $invoker,
+ Swift_Events_EventDispatcher $eventDispatcher)
+ {
+ $this->_invoker = $invoker;
+ $this->_eventDispatcher = $eventDispatcher;
+ }
+
+ /**
+ * Not used.
+ */
+ public function isStarted()
+ {
+ return false;
+ }
+
+ /**
+ * Not used.
+ */
+ public function start()
+ {
+ }
+
+ /**
+ * Not used.
+ */
+ public function stop()
+ {
+ }
+
+ /**
+ * Set the additional parameters used on the mail() function.
+ *
+ * This string is formatted for sprintf() where %s is the sender address.
+ *
+ * @param string $params
+ */
+ public function setExtraParams($params)
+ {
+ $this->_extraParams = $params;
+ return $this;
+ }
+
+ /**
+ * Get the additional parameters used on the mail() function.
+ *
+ * This string is formatted for sprintf() where %s is the sender address.
+ *
+ * @return string
+ */
+ public function getExtraParams()
+ {
+ return $this->_extraParams;
+ }
+
+ /**
+ * Send the given Message.
+ *
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ *
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $failedRecipients = (array) $failedRecipients;
+
+ if ($evt = $this->_eventDispatcher->createSendEvent($this, $message))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed');
+ if ($evt->bubbleCancelled())
+ {
+ return 0;
+ }
+ }
+
+ $count = (
+ count((array) $message->getTo())
+ + count((array) $message->getCc())
+ + count((array) $message->getBcc())
+ );
+
+ $toHeader = $message->getHeaders()->get('To');
+ $subjectHeader = $message->getHeaders()->get('Subject');
+
+ $to = $toHeader->getFieldBody();
+ $subject = $subjectHeader->getFieldBody();
+
+ $reversePath = $this->_getReversePath($message);
+
+ //Remove headers that would otherwise be duplicated
+ $message->getHeaders()->remove('To');
+ $message->getHeaders()->remove('Subject');
+
+ $messageStr = $message->toString();
+
+ $message->getHeaders()->set($toHeader);
+ $message->getHeaders()->set($subjectHeader);
+
+ //Separate headers from body
+ if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n"))
+ {
+ $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL
+ $body = substr($messageStr, $endHeaders + 4);
+ }
+ else
+ {
+ $headers = $messageStr . "\r\n";
+ $body = '';
+ }
+
+ unset($messageStr);
+
+ if ("\r\n" != PHP_EOL) //Non-windows (not using SMTP)
+ {
+ $headers = str_replace("\r\n", PHP_EOL, $headers);
+ $body = str_replace("\r\n", PHP_EOL, $body);
+ }
+ else //Windows, using SMTP
+ {
+ $headers = str_replace("\r\n.", "\r\n..", $headers);
+ $body = str_replace("\r\n.", "\r\n..", $body);
+ }
+
+ if ($this->_invoker->mail($to, $subject, $body, $headers,
+ sprintf($this->_extraParams, $reversePath)))
+ {
+ if ($evt)
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS);
+ $evt->setFailedRecipients($failedRecipients);
+ $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
+ }
+ }
+ else
+ {
+ $failedRecipients = array_merge(
+ $failedRecipients,
+ array_keys((array) $message->getTo()),
+ array_keys((array) $message->getCc()),
+ array_keys((array) $message->getBcc())
+ );
+
+ if ($evt)
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED);
+ $evt->setFailedRecipients($failedRecipients);
+ $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
+ }
+
+ $message->generateId();
+
+ $count = 0;
+ }
+
+ return $count;
+ }
+
+ /**
+ * Register a plugin.
+ *
+ * @param Swift_Events_EventListener $plugin
+ */
+ public function registerPlugin(Swift_Events_EventListener $plugin)
+ {
+ $this->_eventDispatcher->bindEventListener($plugin);
+ }
+
+ // -- Private methods
+
+ /** Determine the best-use reverse path for this message */
+ private function _getReversePath(Swift_Mime_Message $message)
+ {
+ $return = $message->getReturnPath();
+ $sender = $message->getSender();
+ $from = $message->getFrom();
+ $path = null;
+ if (!empty($return))
+ {
+ $path = $return;
+ }
+ elseif (!empty($sender))
+ {
+ $keys = array_keys($sender);
+ $path = array_shift($keys);
+ }
+ elseif (!empty($from))
+ {
+ $keys = array_keys($from);
+ $path = array_shift($keys);
+ }
+ return $path;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php b/External/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php
new file mode 100755
index 0000000..aae8bde
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php
@@ -0,0 +1,173 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/Transport/EsmtpTransport.php';
+//@require 'Swift/Transport/IoBuffer.php';
+//@require 'Swift/Transport/Log.php';
+//@require 'Swift/Events/EventDispatcher.php';
+
+/**
+ * SendmailTransport for sending mail through a sendmail/postfix (etc..) binary.
+ *
+ * Supported modes are -bs and -t, with any additional flags desired.
+ * It is advised to use -bs mode since error reporting with -t mode is not
+ * possible.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_SendmailTransport
+ extends Swift_Transport_AbstractSmtpTransport
+{
+
+ /**
+ * Connection buffer parameters.
+ * @var array
+ * @access protected
+ */
+ private $_params = array(
+ 'timeout' => 30,
+ 'blocking' => 1,
+ 'command' => '/usr/sbin/sendmail -bs',
+ 'type' => Swift_Transport_IoBuffer::TYPE_PROCESS
+ );
+
+ /**
+ * Create a new SendmailTransport with $buf for I/O.
+ * @param Swift_Transport_IoBuffer $buf
+ * @param Swift_Events_EventDispatcher $dispatcher
+ */
+ public function __construct(Swift_Transport_IoBuffer $buf,
+ Swift_Events_EventDispatcher $dispatcher)
+ {
+ parent::__construct($buf, $dispatcher);
+ }
+
+ /**
+ * Start the standalone SMTP session if running in -bs mode.
+ */
+ public function start()
+ {
+ if (false !== strpos($this->getCommand(), ' -bs'))
+ {
+ parent::start();
+ }
+ }
+
+ /**
+ * Set the command to invoke.
+ * If using -t mode you are strongly advised to include -oi or -i in the
+ * flags. For example: /usr/sbin/sendmail -oi -t
+ * Swift will append a -f<sender> flag if one is not present.
+ * The recommended mode is "-bs" since it is interactive and failure notifications
+ * are hence possible.
+ * @param string $command
+ */
+ public function setCommand($command)
+ {
+ $this->_params['command'] = $command;
+ return $this;
+ }
+
+ /**
+ * Get the sendmail command which will be invoked.
+ * @return string
+ */
+ public function getCommand()
+ {
+ return $this->_params['command'];
+ }
+
+ /**
+ * Send the given Message.
+ * Recipient/sender data will be retreived from the Message API.
+ * The return value is the number of recipients who were accepted for delivery.
+ * NOTE: If using 'sendmail -t' you will not be aware of any failures until
+ * they bounce (i.e. send() will always return 100% success).
+ * @param Swift_Mime_Message $message
+ * @param string[] &$failedRecipients to collect failures by-reference
+ * @return int
+ */
+ public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+ {
+ $failedRecipients = (array) $failedRecipients;
+ $command = $this->getCommand();
+ $buffer = $this->getBuffer();
+
+ if (false !== strpos($command, ' -t'))
+ {
+ if ($evt = $this->_eventDispatcher->createSendEvent($this, $message))
+ {
+ $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed');
+ if ($evt->bubbleCancelled())
+ {
+ return 0;
+ }
+ }
+
+ if (false === strpos($command, ' -f'))
+ {
+ $command .= ' -f' . $this->_getReversePath($message);
+ }
+
+ $buffer->initialize(array_merge($this->_params, array('command' => $command)));
+
+ if (false === strpos($command, ' -i') && false === strpos($command, ' -oi'))
+ {
+ $buffer->setWriteTranslations(array("\r\n" => "\n", "\n." => "\n.."));
+ }
+ else
+ {
+ $buffer->setWriteTranslations(array("\r\n"=>"\n"));
+ }
+
+ $count = count((array) $message->getTo())
+ + count((array) $message->getCc())
+ + count((array) $message->getBcc())
+ ;
+ $message->toByteStream($buffer);
+ $buffer->flushBuffers();
+ $buffer->setWriteTranslations(array());
+ $buffer->terminate();
+
+ if ($evt)
+ {
+ $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS);
+ $evt->setFailedRecipients($failedRecipients);
+ $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
+ }
+
+ $message->generateId();
+ }
+ elseif (false !== strpos($command, ' -bs'))
+ {
+ $count = parent::send($message, $failedRecipients);
+ }
+ else
+ {
+ $this->_throwException(new Swift_TransportException(
+ 'Unsupported sendmail command flags [' . $command . ']. ' .
+ 'Must be one of "-bs" or "-t" but can include additional flags.'
+ ));
+ }
+
+ return $count;
+ }
+
+ // -- Protected methods
+
+ /** Get the params to initialize the buffer */
+ protected function _getBufferParams()
+ {
+ return $this->_params;
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php b/External/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php
new file mode 100755
index 0000000..271ba84
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ Invokes the mail() function in Swift Mailer.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+//@require 'Swift/Transport/MailInvoker.php';
+
+/**
+ * This is the implementation class for {@link Swift_Transport_MailInvoker}.
+ *
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_SimpleMailInvoker implements Swift_Transport_MailInvoker
+{
+
+ /**
+ * Send mail via the mail() function.
+ *
+ * This method takes the same arguments as PHP mail().
+ *
+ * @param string $to
+ * @param string $subject
+ * @param string $body
+ * @param string $headers
+ * @param string $extraParams
+ *
+ * @return boolean
+ */
+ public function mail($to, $subject, $body, $headers = null, $extraParams = null)
+ {
+ if (!ini_get('safe_mode'))
+ {
+ return mail($to, $subject, $body, $headers, $extraParams);
+ }
+ else
+ {
+ return mail($to, $subject, $body, $headers);
+ }
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php b/External/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php
new file mode 100755
index 0000000..ee9b8ed
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wraps an IoBuffer to send/receive SMTP commands/responses.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+interface Swift_Transport_SmtpAgent
+{
+
+ /**
+ * Get the IoBuffer where read/writes are occurring.
+ * @return Swift_Transport_IoBuffer
+ */
+ public function getBuffer();
+
+ /**
+ * Run a command against the buffer, expecting the given response codes.
+ * If no response codes are given, the response will not be validated.
+ * If codes are given, an exception will be thrown on an invalid response.
+ * @param string $command
+ * @param int[] $codes
+ * @param string[] &$failures
+ */
+ public function executeCommand($command, $codes = array(), &$failures = null);
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php b/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
new file mode 100755
index 0000000..01ae8a5
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
@@ -0,0 +1,276 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/ByteStream/AbstractFilterableInputStream.php';
+//@require 'Swift/ReplacementFilterFactory.php';
+//@require 'Swift/Transport/IoBuffer.php';
+//@require 'Swift/TransportException.php';
+
+/**
+ * A generic IoBuffer implementation supporting remote sockets and local processes.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_StreamBuffer
+ extends Swift_ByteStream_AbstractFilterableInputStream
+ implements Swift_Transport_IoBuffer
+{
+
+ /** A primary socket */
+ private $_stream;
+
+ /** The input stream */
+ private $_in;
+
+ /** The output stream */
+ private $_out;
+
+ /** Buffer initialization parameters */
+ private $_params = array();
+
+ /** The ReplacementFilterFactory */
+ private $_replacementFactory;
+
+ /** Translations performed on data being streamed into the buffer */
+ private $_translations = array();
+
+ /**
+ * Create a new StreamBuffer using $replacementFactory for transformations.
+ * @param Swift_ReplacementFilterFactory $replacementFactory
+ */
+ public function __construct(
+ Swift_ReplacementFilterFactory $replacementFactory)
+ {
+ $this->_replacementFactory = $replacementFactory;
+ }
+
+ /**
+ * Perform any initialization needed, using the given $params.
+ * Parameters will vary depending upon the type of IoBuffer used.
+ * @param array $params
+ */
+ public function initialize(array $params)
+ {
+ $this->_params = $params;
+ switch ($params['type'])
+ {
+ case self::TYPE_PROCESS:
+ $this->_establishProcessConnection();
+ break;
+ case self::TYPE_SOCKET:
+ default:
+ $this->_establishSocketConnection();
+ break;
+ }
+ }
+
+ /**
+ * Set an individual param on the buffer (e.g. switching to SSL).
+ * @param string $param
+ * @param mixed $value
+ */
+ public function setParam($param, $value)
+ {
+ if (isset($this->_stream))
+ {
+ switch ($param)
+ {
+ case 'protocol':
+ if (!array_key_exists('protocol', $this->_params)
+ || $value != $this->_params['protocol'])
+ {
+ if ('tls' == $value)
+ {
+ stream_socket_enable_crypto(
+ $this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT
+ );
+ }
+ }
+ break;
+ }
+ }
+ $this->_params[$param] = $value;
+ }
+
+ /**
+ * Perform any shutdown logic needed.
+ */
+ public function terminate()
+ {
+ if (isset($this->_stream))
+ {
+ switch ($this->_params['type'])
+ {
+ case self::TYPE_PROCESS:
+ fclose($this->_in);
+ fclose($this->_out);
+ proc_close($this->_stream);
+ break;
+ case self::TYPE_SOCKET:
+ default:
+ fclose($this->_stream);
+ break;
+ }
+ }
+ $this->_stream = null;
+ $this->_out = null;
+ $this->_in = null;
+ }
+
+ /**
+ * Set an array of string replacements which should be made on data written
+ * to the buffer. This could replace LF with CRLF for example.
+ * @param string[] $replacements
+ */
+ public function setWriteTranslations(array $replacements)
+ {
+ foreach ($this->_translations as $search => $replace)
+ {
+ if (!isset($replacements[$search]))
+ {
+ $this->removeFilter($search);
+ unset($this->_translations[$search]);
+ }
+ }
+
+ foreach ($replacements as $search => $replace)
+ {
+ if (!isset($this->_translations[$search]))
+ {
+ $this->addFilter(
+ $this->_replacementFactory->createFilter($search, $replace), $search
+ );
+ $this->_translations[$search] = true;
+ }
+ }
+ }
+
+ /**
+ * Get a line of output (including any CRLF).
+ * The $sequence number comes from any writes and may or may not be used
+ * depending upon the implementation.
+ * @param int $sequence of last write to scan from
+ * @return string
+ */
+ public function readLine($sequence)
+ {
+ if (isset($this->_out) && !feof($this->_out))
+ {
+ $line = fgets($this->_out);
+ return $line;
+ }
+ }
+
+ /**
+ * Reads $length bytes from the stream into a string and moves the pointer
+ * through the stream by $length. If less bytes exist than are requested the
+ * remaining bytes are given instead. If no bytes are remaining at all, boolean
+ * false is returned.
+ * @param int $length
+ * @return string
+ */
+ public function read($length)
+ {
+ if (isset($this->_out) && !feof($this->_out))
+ {
+ $ret = fread($this->_out, $length);
+ return $ret;
+ }
+ }
+
+ /** Not implemented */
+ public function setReadPointer($byteOffset)
+ {
+ }
+
+ // -- Protected methods
+
+ /** Flush the stream contents */
+ protected function _flush()
+ {
+ if (isset($this->_in))
+ {
+ fflush($this->_in);
+ }
+ }
+
+ /** Write this bytes to the stream */
+ protected function _commit($bytes)
+ {
+ if (isset($this->_in)
+ && fwrite($this->_in, $bytes))
+ {
+ return ++$this->_sequence;
+ }
+ }
+
+ // -- Private methods
+
+ /**
+ * Establishes a connection to a remote server.
+ * @access private
+ */
+ private function _establishSocketConnection()
+ {
+ $host = $this->_params['host'];
+ if (!empty($this->_params['protocol']))
+ {
+ $host = $this->_params['protocol'] . '://' . $host;
+ }
+ $timeout = 15;
+ if (!empty($this->_params['timeout']))
+ {
+ $timeout = $this->_params['timeout'];
+ }
+ if (!$this->_stream = fsockopen($host, $this->_params['port'], $errno, $errstr, $timeout))
+ {
+ throw new Swift_TransportException(
+ 'Connection could not be established with host ' . $this->_params['host'] .
+ ' [' . $errstr . ' #' . $errno . ']'
+ );
+ }
+ if (!empty($this->_params['blocking']))
+ {
+ stream_set_blocking($this->_stream, 1);
+ }
+ else
+ {
+ stream_set_blocking($this->_stream, 0);
+ }
+ $this->_in =& $this->_stream;
+ $this->_out =& $this->_stream;
+ }
+
+ /**
+ * Opens a process for input/output.
+ * @access private
+ */
+ private function _establishProcessConnection()
+ {
+ $command = $this->_params['command'];
+ $descriptorSpec = array(
+ 0 => array('pipe', 'r'),
+ 1 => array('pipe', 'w'),
+ 2 => array('pipe', 'w')
+ );
+ $this->_stream = proc_open($command, $descriptorSpec, $pipes);
+ stream_set_blocking($pipes[2], 0);
+ if ($err = stream_get_contents($pipes[2]))
+ {
+ throw new Swift_TransportException(
+ 'Process could not be started [' . $err . ']'
+ );
+ }
+ $this->_in =& $pipes[0];
+ $this->_out =& $pipes[1];
+ }
+
+}
diff --git a/External/swiftmailer/lib/classes/Swift/TransportException.php b/External/swiftmailer/lib/classes/Swift/TransportException.php
new file mode 100755
index 0000000..b7cd658
--- /dev/null
+++ b/External/swiftmailer/lib/classes/Swift/TransportException.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+//@require 'Swift/IoException.php';
+
+/**
+ * TransportException thrown when an error occurs in the Transport subsystem.
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_TransportException extends Swift_IoException
+{
+
+ /**
+ * Create a new TransportException with $message.
+ * @param string $message
+ */
+ public function __construct($message)
+ {
+ parent::__construct($message);
+ }
+
+}
diff --git a/External/swiftmailer/lib/dependency_maps/cache_deps.php b/External/swiftmailer/lib/dependency_maps/cache_deps.php
new file mode 100755
index 0000000..6058206
--- /dev/null
+++ b/External/swiftmailer/lib/dependency_maps/cache_deps.php
@@ -0,0 +1,25 @@
+<?php
+
+Swift_DependencyContainer::getInstance()
+
+ -> register('cache')
+ -> asAliasOf('cache.array')
+
+ -> register('tempdir')
+ -> asValue('/tmp')
+
+ -> register('cache.null')
+ -> asSharedInstanceOf('Swift_KeyCache_NullKeyCache')
+
+ -> register('cache.array')
+ -> asSharedInstanceOf('Swift_KeyCache_ArrayKeyCache')
+ -> withDependencies(array('cache.inputstream'))
+
+ -> register('cache.disk')
+ -> asSharedInstanceOf('Swift_KeyCache_DiskKeyCache')
+ -> withDependencies(array('cache.inputstream', 'tempdir'))
+
+ -> register('cache.inputstream')
+ -> asNewInstanceOf('Swift_KeyCache_SimpleKeyCacheInputStream')
+
+ ;
diff --git a/External/swiftmailer/lib/dependency_maps/mime_deps.php b/External/swiftmailer/lib/dependency_maps/mime_deps.php
new file mode 100755
index 0000000..e03927a
--- /dev/null
+++ b/External/swiftmailer/lib/dependency_maps/mime_deps.php
@@ -0,0 +1,97 @@
+<?php
+
+require_once dirname(__FILE__) . '/../mime_types.php';
+
+Swift_DependencyContainer::getInstance()
+
+ -> register('properties.charset')
+ -> asValue('utf-8')
+
+ -> register('mime.message')
+ -> asNewInstanceOf('Swift_Mime_SimpleMessage')
+ -> withDependencies(array(
+ 'mime.headerset',
+ 'mime.qpcontentencoder',
+ 'cache',
+ 'properties.charset'
+ ))
+
+ -> register('mime.part')
+ -> asNewInstanceOf('Swift_Mime_MimePart')
+ -> withDependencies(array(
+ 'mime.headerset',
+ 'mime.qpcontentencoder',
+ 'cache',
+ 'properties.charset'
+ ))
+
+ -> register('mime.attachment')
+ -> asNewInstanceOf('Swift_Mime_Attachment')
+ -> withDependencies(array(
+ 'mime.headerset',
+ 'mime.base64contentencoder',
+ 'cache'
+ ))
+ -> addConstructorValue($swift_mime_types)
+
+ -> register('mime.embeddedfile')
+ -> asNewInstanceOf('Swift_Mime_EmbeddedFile')
+ -> withDependencies(array(
+ 'mime.headerset',
+ 'mime.base64contentencoder',
+ 'cache'
+ ))
+ -> addConstructorValue($swift_mime_types)
+
+ -> register('mime.headerfactory')
+ -> asNewInstanceOf('Swift_Mime_SimpleHeaderFactory')
+ -> withDependencies(array(
+ 'mime.qpheaderencoder',
+ 'mime.rfc2231encoder',
+ 'properties.charset'
+ ))
+
+ -> register('mime.headerset')
+ -> asNewInstanceOf('Swift_Mime_SimpleHeaderSet')
+ -> withDependencies(array('mime.headerfactory', 'properties.charset'))
+
+ -> register('mime.qpheaderencoder')
+ -> asNewInstanceOf('Swift_Mime_HeaderEncoder_QpHeaderEncoder')
+ -> withDependencies(array('mime.charstream'))
+
+ -> register('mime.charstream')
+ -> asNewInstanceOf('Swift_CharacterStream_NgCharacterStream')
+ -> withDependencies(array('mime.characterreaderfactory', 'properties.charset'))
+
+ -> register('mime.bytecanonicalizer')
+ -> asSharedInstanceOf('Swift_StreamFilters_ByteArrayReplacementFilter')
+ -> addConstructorValue(array(array(0x0D, 0x0A), array(0x0D), array(0x0A)))
+ -> addConstructorValue(array(array(0x0A), array(0x0A), array(0x0D, 0x0A)))
+
+ -> register('mime.characterreaderfactory')
+ -> asSharedInstanceOf('Swift_CharacterReaderFactory_SimpleCharacterReaderFactory')
+
+ -> register('mime.qpcontentencoder')
+ -> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder')
+ -> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer'))
+
+ -> register('mime.7bitcontentencoder')
+ -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder')
+ -> addConstructorValue('7bit')
+ -> addConstructorValue(true)
+
+ -> register('mime.8bitcontentencoder')
+ -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder')
+ -> addConstructorValue('8bit')
+ -> addConstructorValue(true)
+
+ -> register('mime.base64contentencoder')
+ -> asSharedInstanceOf('Swift_Mime_ContentEncoder_Base64ContentEncoder')
+
+ -> register('mime.rfc2231encoder')
+ -> asNewInstanceOf('Swift_Encoder_Rfc2231Encoder')
+ -> withDependencies(array('mime.charstream'))
+
+ ;
+
+unset($swift_mime_types);
diff --git a/External/swiftmailer/lib/dependency_maps/transport_deps.php b/External/swiftmailer/lib/dependency_maps/transport_deps.php
new file mode 100755
index 0000000..32881d6
--- /dev/null
+++ b/External/swiftmailer/lib/dependency_maps/transport_deps.php
@@ -0,0 +1,62 @@
+<?php
+
+Swift_DependencyContainer::getInstance()
+
+ -> register('transport.smtp')
+ -> asNewInstanceOf('Swift_Transport_EsmtpTransport')
+ -> withDependencies(array(
+ 'transport.buffer',
+ array('transport.authhandler'),
+ 'transport.eventdispatcher'
+ ))
+
+ -> register('transport.sendmail')
+ -> asNewInstanceOf('Swift_Transport_SendmailTransport')
+ -> withDependencies(array(
+ 'transport.buffer',
+ 'transport.eventdispatcher'
+ ))
+
+ -> register('transport.mail')
+ -> asNewInstanceOf('Swift_Transport_MailTransport')
+ -> withDependencies(array('transport.mailinvoker', 'transport.eventdispatcher'))
+
+ -> register('transport.loadbalanced')
+ -> asNewInstanceOf('Swift_Transport_LoadBalancedTransport')
+
+ -> register('transport.failover')
+ -> asNewInstanceOf('Swift_Transport_FailoverTransport')
+
+ -> register('transport.mailinvoker')
+ -> asSharedInstanceOf('Swift_Transport_SimpleMailInvoker')
+
+ -> register('transport.buffer')
+ -> asNewInstanceOf('Swift_Transport_StreamBuffer')
+ -> withDependencies(array('transport.replacementfactory'))
+
+ -> register('transport.authhandler')
+ -> asNewInstanceOf('Swift_Transport_Esmtp_AuthHandler')
+ -> withDependencies(array(
+ array(
+ 'transport.crammd5auth',
+ 'transport.loginauth',
+ 'transport.plainauth'
+ )
+ ))
+
+ -> register('transport.crammd5auth')
+ -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_CramMd5Authenticator')
+
+ -> register('transport.loginauth')
+ -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_LoginAuthenticator')
+
+ -> register('transport.plainauth')
+ -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_PlainAuthenticator')
+
+ -> register('transport.eventdispatcher')
+ -> asNewInstanceOf('Swift_Events_SimpleEventDispatcher')
+
+ -> register('transport.replacementfactory')
+ -> asSharedInstanceOf('Swift_StreamFilters_StringReplacementFilterFactory')
+
+ ;
diff --git a/External/swiftmailer/lib/mime_types.php b/External/swiftmailer/lib/mime_types.php
new file mode 100755
index 0000000..65c9aa0
--- /dev/null
+++ b/External/swiftmailer/lib/mime_types.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/*
+ * List of MIME type automatically detected in Swift Mailer.
+ */
+
+//You may add or take away what you like (lowercase required)
+
+$swift_mime_types = array(
+ 'aif' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'avi' => 'video/avi',
+ 'bmp' => 'image/bmp',
+ 'bz2' => 'application/x-bz2',
+ 'csv' => 'text/csv',
+ 'dmg' => 'application/x-apple-diskimage',
+ 'doc' => 'application/msword',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'eml' => 'message/rfc822',
+ 'aps' => 'application/postscript',
+ 'exe' => 'application/x-ms-dos-executable',
+ 'flv' => 'video/x-flv',
+ 'gif' => 'image/gif',
+ 'gz' => 'application/x-gzip',
+ 'hqx' => 'application/stuffit',
+ 'htm' => 'text/html',
+ 'html' => 'text/html',
+ 'jar' => 'application/x-java-archive',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'm3u' => 'audio/x-mpegurl',
+ 'm4a' => 'audio/mp4',
+ 'mdb' => 'application/x-msaccess',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mov' => 'video/quicktime',
+ 'mp3' => 'audio/mpeg',
+ 'mp4' => 'video/mp4',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'odg' => 'vnd.oasis.opendocument.graphics',
+ 'odp' => 'vnd.oasis.opendocument.presentation',
+ 'odt' => 'vnd.oasis.opendocument.text',
+ 'ods' => 'vnd.oasis.opendocument.spreadsheet',
+ 'ogg' => 'audio/ogg',
+ 'pdf' => 'application/pdf',
+ 'png' => 'image/png',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'ps' => 'application/postscript',
+ 'rar' => 'application/x-rar-compressed',
+ 'rtf' => 'application/rtf',
+ 'tar' => 'application/x-tar',
+ 'sit' => 'application/x-stuffit',
+ 'svg' => 'image/svg+xml',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'ttf' => 'application/x-font-truetype',
+ 'txt' => 'text/plain',
+ 'vcf' => 'text/x-vcard',
+ 'wav' => 'audio/wav',
+ 'wma' => 'audio/x-ms-wma',
+ 'wmv' => 'audio/x-ms-wmv',
+ 'xls' => 'application/excel',
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xml' => 'application/xml',
+ 'zip' => 'application/zip'
+);
diff --git a/External/swiftmailer/lib/preferences.php b/External/swiftmailer/lib/preferences.php
new file mode 100755
index 0000000..0b9e4b1
--- /dev/null
+++ b/External/swiftmailer/lib/preferences.php
@@ -0,0 +1,20 @@
+<?php
+
+/****************************************************************************/
+/* */
+/* YOU MAY WISH TO MODIFY OR REMOVE THE FOLLOWING LINES WHICH SET DEFAULTS */
+/* */
+/****************************************************************************/
+
+// Sets the default charset so that setCharset() is not needed elsewhere
+Swift_Preferences::getInstance()->setCharset('utf-8');
+
+// Without these lines the default caching mechanism is "array" but this uses
+// a lot of memory.
+// If possible, use a disk cache to enable attaching large attachments etc
+if (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()))
+{
+ Swift_Preferences::getInstance()
+ -> setTempDir(sys_get_temp_dir())
+ -> setCacheType('disk');
+}
diff --git a/External/swiftmailer/lib/swift_init.php b/External/swiftmailer/lib/swift_init.php
new file mode 100755
index 0000000..fe624a9
--- /dev/null
+++ b/External/swiftmailer/lib/swift_init.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/*
+ * Dependency injection initialization for Swift Mailer.
+ */
+
+//Load in dependency maps
+require_once dirname(__FILE__) . '/dependency_maps/cache_deps.php';
+require_once dirname(__FILE__) . '/dependency_maps/mime_deps.php';
+require_once dirname(__FILE__) . '/dependency_maps/transport_deps.php';
+
+//Load in global library preferences
+require_once dirname(__FILE__) . '/preferences.php';
diff --git a/External/swiftmailer/lib/swift_required.php b/External/swiftmailer/lib/swift_required.php
new file mode 100755
index 0000000..ad1a4ad
--- /dev/null
+++ b/External/swiftmailer/lib/swift_required.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/*
+ * Autoloader and dependency injection initialization for Swift Mailer.
+ */
+
+//Load Swift utility class
+require_once dirname(__FILE__) . '/classes/Swift.php';
+
+//Start the autoloader
+Swift::registerAutoload();
+
+//Load the init script to set up dependency injection
+require_once dirname(__FILE__) . '/swift_init.php';
diff --git a/External/swiftmailer/lib/swift_required_pear.php b/External/swiftmailer/lib/swift_required_pear.php
new file mode 100755
index 0000000..20a6159
--- /dev/null
+++ b/External/swiftmailer/lib/swift_required_pear.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/*
+ * Autoloader and dependency injection initialization for Swift Mailer.
+ */
+
+//Load Swift utility class
+require_once dirname(__FILE__) . '/Swift.php';
+
+//Start the autoloader
+Swift::registerAutoload();
+
+//Load the init script to set up dependency injection
+require_once dirname(__FILE__) . '/swift_init.php';